uCrouter project forum


dch,2006\05\18 02:20:21,16654 bytes

Answer

Forum

cstartup_gnu_ram.S

I don't now convert utility from ADS assembler to GCC,good startup GNU
code located at the file:

cstartup_gnu_ram.S (http://www.ucrouter.ru/download/AT91RM9200-29lv160d.tgz)

Best Regards, Dmitriy I.Cherkashin.

/*---------------------------------------------------------------------------*/
/* ATMEL Microcontroller Software Support - ROUSSET - */
/*---------------------------------------------------------------------------*/
/* The software is delivered "AS IS" without warranty or condition of any */
/* kind, either express, implied or statutory. This includes without */
/* limitation any warranty or condition with respect to merchantability or */
/* fitness for any particular purpose, or against the infringements of */
/* intellectual property rights of others. */
/*---------------------------------------------------------------------------*/
/* File source : cstartup_boot.arm */
/* Object : Generic CStartup */
/* Compilation flag : None */
/* */
/* 1.0 23/10/02 FB : Creation ARM ADS */
/*---------------------------------------------------------------------------*/

/* modified 2004 by Dmitriy Cherkashin */
/* dch@ucrouter.ru, www.ucrouter.ru */
/* based on ATMEL AT91RM9200-BasicBoot, */
/* AT91RM9200-BasicROM_Services and */
/* BOOTROM code */

#include "AT91RM9200_inc.h"

/*--------------------------------*/
/* ARM Core Mode and Status Bits */
/*--------------------------------*/
#define ARM_MODE_USER 0x10 /* user mode */
#define ARM_MODE_FIQ 0x11 /* FIQ mode */
#define ARM_MODE_IRQ 0x12 /* IRQ mode */
#define ARM_MODE_SVC 0x13 /* supervisor mode */
#define ARM_MODE_ABORT 0x17 /* data abord or prefech */
#define ARM_MODE_UNDEF 0x1B /* undefined instruction mode */
#define ARM_MODE_SYS 0x1F /* system mode */

#define I_BIT 0x80 /* IRQ bit */
#define F_BIT 0x40 /* FIQ bit */
#define T_BIT 0x20 /* trace bit */

#define IRQ_STACK_SIZE 0x100
#define FIQ_STACK_SIZE 0x20
#define ABT_STACK_SIZE 0x20
#define UND_STACK_SIZE 0x20
#define SVC_STACK_SIZE 0x20
#define USER_STACK_SIZE 0x100 /* exectly - SYStem mode stack size */

/*---------------------------------------------------------------------------*/
/* Stack Area Definition */
/*---------------------------------------------------------------------------*/
.bss
.align 4

/* IRQ stack definition */
.globl AT91_IRQ_Stack_End
AT91_IRQ_Stack_End:
.word 0x55AA55AA
.space (IRQ_STACK_SIZE - 4)
#define AT91_IRQ_Stack_Begin (AT91_IRQ_Stack_End + (IRQ_STACK_SIZE - 4))

/* FIQ stack definition */
.globl AT91_FIQ_Stack_End
AT91_FIQ_Stack_End:
.word 0x55AA55AA
.space (FIQ_STACK_SIZE - 4)
#define AT91_FIQ_Stack_Begin (AT91_FIQ_Stack_End + (FIQ_STACK_SIZE - 4))

/* ABORT stack definition */
.globl AT91_ABT_Stack_End
AT91_ABT_Stack_End:
.word 0x55AA55AA
.space (ABT_STACK_SIZE - 4)
#define AT91_ABT_Stack_Begin (AT91_ABT_Stack_End + (ABT_STACK_SIZE - 4))

/* UNDEF stack definition */
.globl AT91_UND_Stack_End
AT91_UND_Stack_End:
.word 0x55AA55AA
.space (UND_STACK_SIZE - 4)
#define AT91_UND_Stack_Begin (AT91_UND_Stack_End + (UND_STACK_SIZE - 4))

/* SVC stack definition */
.globl AT91_SVC_Stack_End
AT91_SVC_Stack_End:
.word 0x55AA55AA
.space (SVC_STACK_SIZE - 4)
#define AT91_SVC_Stack_Begin (AT91_SVC_Stack_End + (SVC_STACK_SIZE - 4))

/* USER and SYSTEM stack definition */
.globl AT91_USER_Stack_End
AT91_USER_Stack_End:
.word 0x55AA55AA
.space (USER_STACK_SIZE - 4)
#define AT91_USER_Stack_Begin (AT91_USER_Stack_End + (USER_STACK_SIZE - 4))

.text
.align 4

/*---------------------------------------------------------------------------*/
/* Exception vectors ( before Remap ) */
/*---------------------------------------------------------------------------*/
/* These vectors are read at address 0. */
/* They absolutely requires to be in relative addresssing mode in order to */
/* guarantee a valid jump. For the moment, all are just looping (what may be */
/* dangerous in a final system). If an exception occurs before remap, this */
/* would result in an infinite loop. */
/*---------------------------------------------------------------------------*/
B InitReset /* reset */
undefvec:
B AT91F_UndefHandler /* Undefined Instruction */
swivec:
B AT91F_SwiHandler /* Software Interrupt */
pabtvec:
B AT91F_FetchAbort /* Prefetch Abort */
dabtvec:
B AT91F_DataAbort /* Data Abort */
rsvdvec:
B rsvdvec /* reserved */
irqvec:
ldr pc, [pc,#-0xF20] /* IRQ - read from AIC */
fiqvec:
ldr pc, [pc,#-0xF20] /* FIQ - read from AIC */

/*---------------------------------------------------------------------------*/
/* The reset handler */
/*---------------------------------------------------------------------------*/
InitReset:
/* disable IRQ and FIQ */
msr CPSR_c, #(ARM_MODE_SYS | I_BIT | F_BIT)
/*---------------------------------------------------------------------------*/
/* PMC initialisation : Enable the Main Oscillator */
/*---------------------------------------------------------------------------*/
/* Slow clock mode init */
/* After reset, only the 32KHz oscillator is enabled. */
/* The ARM7TDMI or ARM9 runs the first instructions at 32768Hz<=>Slow Clock. */
/* The processor clock and master clock are enabled at slow clock. */
/* All the peripheral clocks are disabled. */
/* The main oscillator is disabled. */
/*---------------------------------------------------------------------------*/
ldr r1, =AT91C_BASE_PMC /* Get the PMC Base Address */

/* Interrupt Disable Register */
ldr r0, = 0xFFFFFFFF
str r0, [r1, #PMC_IDR]

/* System clock disable register PMC_SCDR : disable all clocks except CPU clock */
ldr r0, = 0xFFFFFFFE /* bit 0 - CPU clock */
str r0, [r1, #PMC_SCDR]

/* Peripheral clock Disable register : disable all peripheral clocks */
ldr r0, = 0xFFFFFFFC /* bits 0,1 - unused */
str r0, [r1, #PMC_PCDR]

/* Master Clock Register PMC_MCKR : Slow Clock is selected */
ldr r0, =(AT91C_PMC_CSS_SLOW_CLK | AT91C_PMC_PRES_CLK)
str r0, [r1, #PMC_MCKR]

/* Reading the PMC Status register to detect when the Master Clock is commuted */
mov r4, #0x08 /* bit 3 - MCKRDY master clock ready bit */
mov r5, #0x100 /* */
MCKR_Slow_Loop:
subs r5,r5,#1
beq MCKR_Slow_Loop_End

ldr r3, [r1, #PMC_SR]
and r3, r4, r3
cmp r3, r4
bne MCKR_Slow_Loop /* branch if MCKRDY bit not set */
MCKR_Slow_Loop_End:

/* System clock Enable register PMC_SCER : Enable only processor clock */
ldr r0, = 0x01
str r0, [r1, #PMC_SCER]

/*---------------------------------------------------------------------------*/
/* After reset,PLLs are disabled */
/* But in case of a boot already started, PLLs are turned off */
/* Can be cleared if the project is used for a boot execution */
/*---------------------------------------------------------------------------*/
ldr r1, = AT91C_BASE_CKGR /* Get the CKGR Base Address */

/*---------------------------------------------------------------------------*/
/* Enabling the Main Oscillator */
/* Normally First instruction in PMC initialisation */
/*---------------------------------------------------------------------------*/
/* Main oscillator Enable register APMC_MOR : Enable main oscillator, OSCOUNT = 0xFF */

ldr r0, =(AT91C_CKGR_MOSCEN | AT91C_CKGR_OSCOUNT)
str r0, [r1, #CKGR_MOR]

/* wait main oscillator clock ready */
mov r4, #0x10000 /* bit 16 - MAINRDY - main clock ready bit */
mov r5, #0x100
MCKR_MainOsc_Loop:
subs r5, r5, #1
beq MCKR_MainOsc_End

ldr r3, [r1, #CKGR_MCFR]
and r3, r4, r3
cmp r3, r4
bne MCKR_MainOsc_Loop /* */
MCKR_MainOsc_End:

ldr r1, =AT91C_BASE_CKGR /* Get the CKGR Base Address */
/* Master Clock Register PMC_PLLAR : Turned off PLLA */
ldr r0, =AT91C_CKGR_DIVA_0
str r0, [r1, #CKGR_PLLAR]

/* Master Clock Register PMC_PLLBR : Turned off PLLB */
ldr r0, = AT91C_CKGR_DIVB_0
str r0, [r1, #CKGR_PLLBR]

/* Enable clock for system peripheral and PIOA to clear output PA22 */
ldr r1, =AT91C_BASE_PMC /* Get the PMC Base Address */
ldr r0,=0x16 /* Enable System Peripheral clock and PIOA clock */
str r0,[r1,#PMC_PCER] /* */

/*---------------------------------------------------------------------------*/
/* Setup the stack for each mode */
/*---------------------------------------------------------------------------*/
/* The processor will remain in the last initialized mode. */
/*---------------------------------------------------------------------------*/

/* Load the stack base addresses */
/* add r0, pc,#-(8+.-StackData) *//* @ where to read relative) */
adr r0, StackData
ldmia r0, {r1-r6}

/* Set up Supervisor Mode and set SVC Mode Stack */
msr cpsr_c, #(ARM_MODE_SVC | I_BIT | F_BIT)
bic r1, r1, #3 /* Insure word alignement */
mov sp, r1 /* Init stack SYS */

/* Set up Interrupt Mode and set IRQ Mode Stack */
msr CPSR_c, #(ARM_MODE_IRQ | I_BIT | F_BIT)
bic r2, r2, #3 /* Insure word alignement */
mov sp, r2 /* Init stack IRQ */

/* Set up Fast Interrupt Mode and set FIQ Mode Stack */
msr CPSR_c, #(ARM_MODE_FIQ | I_BIT | F_BIT)
bic r3, r3, #3 /* Insure word alignement */
mov sp, r3 /* Init stack FIQ */

/* Set up Abort Mode and set Abort Mode Stack */
msr CPSR_c, #(ARM_MODE_ABORT | I_BIT | F_BIT)
bic r4, r4, #3 /* Insure word alignement */
mov sp, r4 /* Init stack Abort */

/* Set up Undefined Instruction Mode and set Undef Mode Stack */
msr CPSR_c, #(ARM_MODE_UNDEF | I_BIT | F_BIT)
bic r5, r5, #3 /* Insure word alignement */
mov sp, r5 /* Init stack Undef */

/* Set up user Mode and set Undef Mode Stack */
msr CPSR_c, #(ARM_MODE_SYS | I_BIT | F_BIT)
bic r6, r6, #3 /* Insure word alignement */
mov sp, r6 /* Init stack Undef */

b EndInitStack

StackData:
.word AT91_SVC_Stack_Begin
.word AT91_IRQ_Stack_Begin
.word AT91_FIQ_Stack_Begin
.word AT91_ABT_Stack_Begin
.word AT91_UND_Stack_Begin
.word AT91_USER_Stack_Begin
EndInitStack:

/* Add loop to compensate Main Oscillator startup time */
ldr r0, =0x00000010
LoopOsc:
subs r0, r0, #1
bhi LoopOsc


/*----------------------------------------*/
/* Read/modify/write CP15 control register*/
/*----------------------------------------*/
MRC p15, 0, r0, c1, c0, 0 /* read cp15 control registre (cp15 r1) in r0 */
ldr r3, =0xC0000080 /* Reset bit :Little Endian end fast bus mode */
ldr r4, =0xC0000000 /* Set bit :Asynchronous clock mode, Not Fast Bus */
BIC r0, r0, r3
ORR r0, r0, r4
MCR p15, 0, r0, c1, c0, 0 /* write r0 in cp15 control registre (cp15 r1) */

/*---------------------------------------------------------------------------*/
/* Reset the Interrupt Controller */
/*---------------------------------------------------------------------------*/
/* Normally, the code is executed only if a reset has been actually performed*/
/* So, the AIC initialization resumes at setting up the default vectors. */
/*---------------------------------------------------------------------------*/
/* Load the AIC Base Address and the default handler addresses

adr r0, AicData
ldmia r0, {r2-r4}
ldr r1, =AT91C_BASE_AIC

/* r1 = AIC_BASE */
/* r2 = FIQ handler */
/* r3 = IRQ handler */
/* r4 = Spurious handler */


/* Setup the Spurious Vector */
str r4, [r1, #AIC_SPU] /* r4 = spurious handler */

/* Set up the default interrupt handler vectors */
add r1, r1, #AIC_SVR
str r2, [r1] /* SVR[0] for FIQ */
mov r0, #31 /* counter */

AIC_Svr_Loop:
str r3, [r1, r0, LSL #2] /* SVRs for IRQs */
subs r0, r0, #1 /* do not save FIQ */
beq AIC_Svr_Loop_End /* 0 => source vector reg loop end */
b AIC_Svr_Loop
AIC_Svr_Loop_End:

/* set SMR */
ldr r1, =AT91C_BASE_AIC
add r1, r1, #AIC_SMR
mov r3, #0 /* 0 - Low priority, 0 - Level Sensitive */
str r3, [r1] /* SMR for IRQ 0 */
mov r0, #31 /* counter */

AIC_SMR_Loop:
str r3, [r1, r0, LSL #2] /* SVRs for IRQs */
subs r0, r0, #1 /* do not save FIQ */
beq AIC_SMR_Loop_End
b AIC_SMR_Loop
AIC_SMR_Loop_End:

/* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
mov r0, #8
mov r3, #0

AIC_EOICR_Loop:
ldr r1, =AT91C_BASE_AIC
str r3, [r1, #AIC_EOICR]
subs r0,r0, #1
beq AIC_EOICR_Loop_End
b AIC_EOICR_Loop
AIC_EOICR_Loop_End:

mov r3,#0xFFFFFFFF
str r3, [r1, #AIC_IDCR]

b EndInitAic

/*---------------------------------------------------------------------------*/
/* Default Interrupt Handler */
/*---------------------------------------------------------------------------*/

AicData:
.word AT91F_FiqHandler /* FIQ handler */
.word AT91F_IrqHandler /* default IRQ handler */
.word AT91F_SpuriousHandler /* Spurious handler */
EndInitAic:

ldr r1, =AT91C_BASE_PIOA /* PIO_PER PIO enable register */
ldr r0, =0x00400000 /* PA22 - bit 22 */

PA22_PER_set:
str r0, [r1, #PIO_PER] /* PER PIO Enable Register */
ldr r2, [r1, #PIO_PSR] /* PER PIO Enable Register */
and r2, r0, r2
cmp r2, r0
bne PA22_PER_set

PA22_OER_set:
str r0, [r1, #PIO_OER] /* OER output enavble register */
ldr r2, [r1, #PIO_OSR] /* PER PIO Enable Register */
and r2, r0, r2
cmp r2, r0
bne PA22_OER_set

PA22_OWER_set:
str r0, [r1, #PIO_OWER] /* OWER Output Write Enable Register */
ldr r2, [r1, #PIO_OWSR] /* PER PIO Enable Register */
and r2, r0, r2
cmp r2, r0
bne PA22_OWER_set

str r0, [r1, #PIO_CODR] /* CODR Clear Output */

ldr r2, [r1, #PIO_ODSR] /* PER PIO Enable Register */
and r2, r0, r2
cmp r2, r0
bne PA22_ODSR_cleared
PA22_ODSR_cleared:

/*---------------------------------------------------------------------------*/
/* Initialise C variables */
/*---------------------------------------------------------------------------*/
/* Following labels are automatically generated by the linker. */
/* RO: Read-only = the code */
/* RW: Read Write = the data pre-initialized and zero-initialized. */
/* ZI: Zero-Initialized. */
/* Pre-initialization values are located after the code area in the image. */
/* Zero-initialized datas are mapped after the pre-initialized. */
/* Note on the Data position : */
/* If using the ARMSDT, when no -rw-base option is used for the linker, the */
/* data area is mapped after the code.You can map the data either in internal*/
/* SRAM ( -rw-base=0x200000 ) or in external SRAM ( -rw-base=0x2000000 ). */
/* Note also that to improve the code density, the pre_initialized data must */
/* be limited to a minimum. */
/*---------------------------------------------------------------------------*/
/* add r2, pc,#-(8+.-CInitData) *//* @ where to read relative) */
adr r2, CInitData
ldmia r2, {r0, r1, r3, r4}

cmp r0, r1 /* Check that they are different */
beq EndRW

LoopRW:
cmp r1, r3 /* Copy RW data */
ldrcc r2, [r0], #4
strcc r2, [r1], #4
bcc LoopRW
EndRW:

mov r2, #0

LoopZI:
cmp r3, r4 /* Zero init */
strcc r2, [r3], #4
bcc LoopZI

b EndInitC

CInitData:
.word _etext /* end of ROM code (=start of RW data) */
.word _sdata /* Base of RAM to initialise */
.word _sbss /* Base and limit of area */
.word _ebss /* Top of zero init segment */
EndInitC:

/* call low level init function */
ldr r0, = AT91F_LowLevelInit
mov lr, pc
bx r0

/* enable only IRQ's and not FIQ's */
msr cpsr_c, #(ARM_MODE_SYS | F_BIT)

/*---------------------------------------------------------------------------*/
/* Branch on C code Main function */
/*---------------------------------------------------------------------------*/
.globl _main
.globl __main

_main:
__main:
ldr r0, =main
mov lr, pc
bx r0

/*---------------------------------------------------------------------------*/
/* Loop for ever */
/*---------------------------------------------------------------------------*/
/* End of application. Normally, never occur. */
/* Could jump on Software Reset ( B 0x0 ). */
/*---------------------------------------------------------------------------*/
End:
b End

Register Forgot passwd Top

Answer

Name:
Passwd:
Subject:
Message:
Input number : 868


ARM®и Thumb® зарегистрированные торговые марки ARM Limited.
Linux® зарегистрированная торговая марка Linus Torvalds.
µClinux и uClinux торговые марки Arcturus Networks Inc.