# 1 "../boot/boot.S"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "../boot/boot.S"
@------------------------------------------------------------------------------
@- 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_ice.sboot.S
@- Object : Boot for simulate Final Application version to be
@- loaded in SRAM. Only change as the internal RAM address
@- and support the Semihosting
@- Compilation flag : SEMIHOSTING => use the semihosting facilities
@-
@- 1.0 17/09/02 GR : Creation
@------------------------------------------------------------------------------

# 1 "../boot/aic.inc" 1
@------------------------------------------
@- AIC User Interface Structure Definition
@------------------------------------------

AIC_SMR = 0 @- Source Mode Register
AIC_SVR = 0x80 @- Source Vector Register
AIC_IVR = 0x100 @- IRQ Vector Register
AIC_FVR = 0x104 @- FIQ Vector Register
AIC_ISR = 0x108 @- Interrupt Status Register
AIC_IPR = 0x10c @- Interrupt Pending Register
AIC_IMR = 0x110 @- Interrupt Mask Register
AIC_CISR = 0x114 @- Core Interrupt Status Register
@ = 0x118 @- Reserved 0
@ = 0x11c @- Reserved 1
AIC_IECR = 0x120 @- Interrupt Enable Command Register
AIC_IDCR = 0x124 @- Interrupt Disable Command Register
AIC_ICCR = 0x128 @- Interrupt Clear Command Register
AIC_ISCR = 0x12c @- Interrupt Set Command Register
AIC_EOICR = 0x130 @- of Interrupt Command Register
AIC_SPU = 0x134 @- Spurious Vector Register

@---------------------------------------------
@- AIC_SMR[]: Interrupt Source Mode Registers
@---------------------------------------------

AIC_PRIOR = 0x07 @- Priority

AIC_SRCTYPE = 0x60 @- Source Type Definition
AIC_SRCTYPE_INT_LEVEL_SENSITIVE = 0x00 @- Level Sensitive
AIC_SRCTYPE_INT_EDGE_TRIGGERED = 0x20 @- Edge Triggered
AIC_SRCTYPE_EXT_LOW_LEVEL = 0x00 @- Low Level
AIC_SRCTYPE_EXT_NEGATIVE_EDGE = 0x20 @- Negative Edge
AIC_SRCTYPE_EXT_HIGH_LEVEL = 0x40 @- High Level
AIC_SRCTYPE_EXT_POSITIVE_EDGE = 0x60 @- Positive Edge

@--------------------------------------
@- AIC_ISR: Interrupt Status Register
@--------------------------------------

AIC_IRQID = 0x1F @- Current source interrupt

@-------------------------------------------
@- AIC_CISR: Interrupt Core Status Register
@-------------------------------------------

AIC_NFIQ = 0x01 @- Core FIQ Status
AIC_NIRQ = 0x02 @- Core IRQ Status

@--------------------------------------------
@- Advanced Interrupt COntroller BAse Address
@--------------------------------------------

AIC_BASE = 0xFFFFF000
# 20 "../boot/boot.S" 2
# 1 "../boot/ebi.inc" 1
@------------------------------------------------------------------------------
@- EBI Initialization Data
@-------------------------
@- The EBI values depend to target choice , Clock, and memories access time.
@- Yous must be define these values in include file
@- The EBI User Interface Image which is copied by the boot.
@- The EBI_CSR_x are defined in the target and hardware depend.
@- That's hardware! Details in the Electrical Datasheet of the AT91 device.'
@- EBI Base Address is added at the end for commodity in copy code.
@- ICE note :For ICE debug no need to set the EBI value these values already set
@- by the boot function.
@------------------------------------------------------------------------------
FLASH_BASE 		= 0x1000000
EXT_SRAM_BASE = 0x2000000
EBI_BASE 			= 0xFFE00000 @- External Bus Interface

EBI_CSR_0 = (FLASH_BASE | 0x2529) @ 0x01000000, 16MB, 2 tdf, 16 bits, 2 WS
EBI_CSR_1 = (EXT_SRAM_BASE | 0x2121) @ 0x02000000, 16MB, 0 hold, 16 bits, 1 WS
EBI_CSR_2 = 0x20000000 @ unused
EBI_CSR_3 = 0x30000000 @ unused
EBI_CSR_4 = 0x40000000 @ unused
EBI_CSR_5 = 0x50000000 @ unused
EBI_CSR_6 = 0x60000000 @ unused
EBI_CSR_7 = 0x70000000 @ unused
# 21 "../boot/boot.S" 2

@------------------------------------------------------------------------------
@- Area Definition
@-----------------
@- Must be defined as function to put first in the code as it must be mapped
@- at SRAM.
@------------------------------------------------------------------------------

        .text

@------------------------------------------------------------------------------
@- Semihosting support
@--------------------------------
@- The C runtime library is the IO functions provided by the semihosting.
@- They are generally costly in code and can be used as the debugger mode (ICE)
@------------------------------------------------------------------------------
@- Define "__main" to ensure that C runtime system is not linked

        .global _start
@------------------------------------------------------------------------------
@- Define the entry point
@------------------------
@- Note on the link address and the Remap command.
@- In order to guarantee that the non position-independant code (the ARM linker
@- armlink doesn't generate position-independant code) can work on the ARM, '
@- it must be linked at address at which it expects to run.
@- In this startup example, we use RAM as base address.
@------------------------------------------------------------------------------
_start:

@------------------------------------------------------------------------------
@- Exception vectors
@--------------------
@- In the ICE function your board as run the boot code and initialize the remap
@- feature. but these code it's location independant and can be emulate the csartup_fash'
@- fonctionnality.
@- These vectors are read at RAM address. in Flash mode these vectors are at 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.
@------------------------------------------------------------------------------

Reset: B InitReset @ reset
undefvec: B undefvec @ Undefined Instruction
swivec: B swivec @ Software Interrupt
pabtvec: B pabtvec @ Prefetch Abort
dabtvec: B dabtvec @ Data Abort
rsvdvec: B rsvdvec @ reserved
irqvec: B irqvec @ reserved
fiqvec: B fiqvec @ reserved

@------------------------------------------------------------------------------
@- Exception vectors ( after cstartup execution )
@------------------------------------
@- These vectors are read at RAM address after the remap command is performed in
@- the EBI. As they will be relocated at address 0x0 to be effective, a
@- relative addressing is forbidden. The only possibility to get an absolute
@- addressing for an ARM vector is to read a PC relative value at a defined
@- offset. It is easy to reserve the locations 0x20 to 0x3C (the 8 next
@- vectors) for storing the absolute exception handler address.
@- The AIC vectoring access vectors are saved in the interrupt and fast
@- interrupt ARM vectors. So, only 5 offsets are required ( reserved vector
@- offset is never used).
@- The provisory handler addresses are defined on infinite loop and can be
@- modified at any time.
@- Note also that the reset is only accessible by a jump from the application
@- to 0. It is an actual software reset.
@- As the 13 first location are used by the vectors, the read/write link
@- address must be defined from 0x34 if internal data mapping is required.
@- (use for that the option -rw- base=0x34
@------------------------------------------------------------------------------

VectorTable:
                ldr pc, [pc, #0x18] @ SoftReset
                ldr pc, [pc, #0x18] @ UndefHandler
                ldr pc, [pc, #0x18] @ SWIHandler
                ldr pc, [pc, #0x18] @ PrefetchAbortHandler
                ldr pc, [pc, #0x18] @ DataAbortHandler
                nop @ Reserved
                ldr pc, [pc,#-0xF20] @ IRQ : read the AIC
                ldr pc, [pc,#-0xF20] @ FIQ : read the AIC

@- There are only 5 offsets as the vectoring is used.
                .word _SoftReset
                .word _UndefHandler
_SWIadress:
                .word SWIHandler
                .word _PrefetchAbortHandler
                .word _DataAbortHandler

@- Vectoring Execution function run at absolut addresss
_SoftReset: b _SoftReset
_UndefHandler: b _UndefHandler
_SWIHandler: b _SWIHandler
_PrefetchAbortHandler: b _PrefetchAbortHandler
_DataAbortHandler: b _DataAbortHandler



InitTableEBI:
            .word EBI_CSR_0
            .word EBI_CSR_1
            .word EBI_CSR_2
            .word EBI_CSR_3
            .word EBI_CSR_4
            .word EBI_CSR_5
            .word EBI_CSR_6
            .word EBI_CSR_7
            .word 0x00000001 @ REMAP command
            .word 0x00000006 @ 6 memory regions, standard read
PtEBIBase:
            .word EBI_BASE @ EBI Base Address

@------------------------------------------------------------------------------
@- The reset handler before Remap
@--------------------------------
@- From here, the code is executed from SRAM address
@------------------------------------------------------------------------------
InitReset:

@------------------------------------------------------------------------------
@- Speed up the Boot sequence
@----------------------------
@- After reset, the number os wait states on chip select 0 is 8. All AT91
@- Evaluation Boards fits fast flash memories, so that the number of wait
@- states can be optimized to fast up the boot sequence.
@- ICE note :For ICE debug no need to set the EBI value these values already set
@- by the boot function.
@------------------------------------------------------------------------------
@- Load System EBI Base address and CSR0 Init Value
                ldr r0, PtEBIBase
                ldr r1, [pc,#-(8+.-InitTableEBI)] @ values (relative)

@- Speed up code execution by disabling wait state on Chip Select 0
                str r1, [r0]

@------------------------------------------------------------------------------
@- low level init
@----------------
@ Call __low_level_init to perform initialization before initializing
@ AIC and calling main.
@----------------------------------------------------------------------

@ bl __low_level_init


@------------------------------------------------------------------------------
@- 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

                add r0, pc,#-(8+.-AicData) @ @ where to read values (relative)

                ldmia r0, {r1-r4}

@- Setup the Spurious Vector
                str r4, [r1, #AIC_SPU] @ r4 = spurious handler


@- ICE note : For ICE debug
@- Perform 8 End Of Interrupt Command to make sure AIC will not lock out nIRQ
                mov r0, #8
LoopAic0:
                str r1, [r1, #AIC_EOICR] @ any value written
                subs r0, r0, #1
                bhi LoopAic0

@- Reset Interrupts
                mov r0, #0
                sub r0, r0, #1 @ all bits set
                str r0, [r1, #AIC_IDCR]
                str r0, [r1, #AIC_ICCR]

@- Set up the default interrupt handler vectors
                str r2, [r1, #AIC_SVR] @ SVR[0] for FIQ
                add r1, r1, #AIC_SVR
                mov r0, #31 @ counter
LoopAic1:
                str r3, [r1, r0, LSL #2] @ SVRs for IRQs
                subs r0, r0, #1 @ do not save FIQ
                bhi LoopAic1

                b EndInitAic

@- Default Interrupt Handlers
AicData:
                .word AIC_BASE @ AIC Base Address
@------------------------------------------------------------------------------
@- Default Interrupt Handler
@---------------------------
@- These function are defined in the AT91 library. If you want to change this
@- you can redifine these function in your appication code
@------------------------------------------------------------------------------

@ IMPORT at91_default_fiq_handler
@ IMPORT at91_default_irq_handler
@ IMPORT at91_spurious_handler
PtDefaultHandler:
                .word at91_default_fiq_handler
                .word at91_default_irq_handler
                .word at91_spurious_handler

at91_default_fiq_handler: B at91_default_fiq_handler
at91_default_irq_handler: B at91_default_irq_handler
at91_spurious_handler: B at91_spurious_handler

EndInitAic:

@------------------------------------------------------------------------------
@- Setup Exception Vectors in Internal RAM before Remap
@------------------------------------------------------
@- That's important to perform this operation before Remap in order to guarantee'
@- that the core has valid vectors at any time during the remap operation.
@- Note: There are only 5 offsets as the vectoring is used.
@- ICE note : In this code only the start address value is changed if you use
@- without Semihosting.
@- Before Remap the internal RAM it's 0x300000'
@- After Remap the internal RAM it's 0x000000'
@- Remap it's already executed it's no possible to write to 0x300000.
@------------------------------------------------------------------------------
@- Copy the ARM exception vectors


                mov r0, #0x28
                add r1, pc,#-(8+.-Init_Vector)
                str r1,[r0]
                mov r0, #0x08
                add r1, pc,#-(8+.-VectorTable-8)
                ldr r1,[r1]
                str r1,[r0]
                swi 0
@ The RAM_BASE = 0 it's specific for ICE'

                RAM_BASE = 0
Init_Vector:
                mov r8, #RAM_BASE @ @ of the hard vector after remap in internal RAM 0x0

                add r9, pc,#-(8+.-VectorTable) @ @ where to read values (relative)
                ldmia r9!, {r0-r7} @ read 8 vectors

                stmia r8!, {r0-r7} @ store them

                ldmia r9!, {r0-r4} @ read 5 absolute handler addresses
                stmia r8!, {r0-r4} @ store them

@------------------------------------------------------------------------------
@- Initialise the Memory Controller
@----------------------------------
@- That's principaly the Remap Command. Actually, all the External Bus '
@- Interface is configured with some instructions and the User Interface Image
@- as described above. The jump "mov pc, r12" could be unread as it is after
@- located after the Remap but actually it is thanks to the Arm core pipeline.
@- The IniTableEBI addressing must be relative .
@- The PtInitRemap must be absolute as the processor jumps at this address
@- immediatly after the Remap is performed.
@- Note also that the EBI base address is loaded in r11 by the "ldmia".
@- ICE note :For ICE debug these values already set by the boot function and the
@- Remap it's already executed it's no need to set still.
@------------------------------------------------------------------------------
@- Copy the Image of the Memory Controller
                sub r10, pc,#(8+.-InitTableEBI) @ get the address of the chip select register image
                ldr r12, PtInitRemap @ get the real jump address ( after remap )

@- Copy Chip Select Register Image to Memory Controller and command remap
                ldmia r10!, {r0-r9,r11} @ load the complete image and the EBI base
                stmia r11!, {r0-r9} @ store the complete image with the remap command

@- Jump to ROM at its new address
                mov pc, r12 @ jump and break the pipeline

PtInitRemap:
                .word InitRemap @ address where to jump after REMAP

@------------------------------------------------------------------------------
@- The Reset Handler after Remap
@-------------------------------
@- From here, the code is continous execute from its link address.
@------------------------------------------------------------------------------

InitRemap:

@--------------------------------
@- ARM Core Mode and Status Bits
@--------------------------------

ARM_MODE_USER = 0x10
ARM_MODE_FIQ = 0x11
ARM_MODE_IRQ = 0x12
ARM_MODE_SVC = 0x13
ARM_MODE_ABORT = 0x17
ARM_MODE_UNDEF = 0x1B
ARM_MODE_SYS = 0x1F

I_BIT = 0x80
F_BIT = 0x40
T_BIT = 0x20

@------------------------------------------------------------------------------
@- Stack Sizes Definition
@------------------------
@- Interrupt Stack requires 3 words x 8 priority level x 4 bytes when using
@- the vectoring. This assume that the IRQ_ENTRY/IRQ_EXIT macro are used.
@- The Interrupt Stack must be adjusted depending on the interrupt handlers.
@- Fast Interrupt is the same than Interrupt without priority level.
@- Other stacks are defined by default to save one word each.
@- The System stack size is not defined and is limited by the free internal
@- SRAM.
@- User stack size is not defined and is limited by the free external SRAM.
@------------------------------------------------------------------------------

IRQ_STACK_SIZE = (3*8*4) @ 3 words per interrupt priority level
FIQ_STACK_SIZE = (3*4) @ 3 words
ABT_STACK_SIZE = (1*4) @ 1 word
UND_STACK_SIZE = (1*4) @ 1 word

@------------------------------------------------------------------------------
@- Top of Stack Definition
@-------------------------
@- Fast Interrupt, Interrupt, Abort, Undefined and Supervisor Stack are located
@- at the top of internal memory in order to speed the exception handling
@- context saving and restoring.
@- User (Application, C) Stack is located at the top of the external memory.
@------------------------------------------------------------------------------
RAM_BASE = 0
RAM_SIZE = (2*1024)
RAM_LIMIT = (RAM_BASE+RAM_SIZE)
EXT_SRAM_BASE = 0x02000000
EXT_SRAM_SIZE = 0x00040000 @ 256Kbytes
EXT_SRAM_LIMIT = (EXT_SRAM_BASE+EXT_SRAM_SIZE)

TOP_EXCEPTION_STACK = RAM_LIMIT @ Defined in part
TOP_APPLICATION_STACK = EXT_SRAM_LIMIT @ Defined in Target

@------------------------------------------------------------------------------
@- Setup the stack for each mode
@-------------------------------
                ldr r0, =TOP_EXCEPTION_STACK

@- Set up Fast Interrupt Mode and set FIQ Mode Stack
                msr CPSR_c, #ARM_MODE_FIQ | I_BIT |F_BIT
                mov r13, r0 @ Init stack FIQ
                sub r0, r0, #FIQ_STACK_SIZE

@- Set up Interrupt Mode and set IRQ Mode Stack
                msr CPSR_c, #ARM_MODE_IRQ | I_BIT |F_BIT
                mov r13, r0 @ Init stack IRQ
                sub r0, r0, #IRQ_STACK_SIZE

@- Set up Abort Mode and set Abort Mode Stack
                msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT
                mov r13, r0 @ Init stack Abort
                sub r0, r0, #ABT_STACK_SIZE

@- Set up Undefined Instruction Mode and set Undef Mode Stack
                msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT
                mov r13, r0 @ Init stack Undef
                sub r0, r0, #UND_STACK_SIZE

@- Set up Supervisor Mode and set Supervisor Mode Stack
                msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
                mov r13, r0 @ Init stack Sup
@------------------------------------------------------------------------------
@- Setup Application Operating Mode and Enable the interrupts
@------------------------------------------------------------
@- System Mode is selected first and the stack is setup. This allows to prevent
@- any interrupt occurence while the User is not initialized. System Mode is
@- used as the interrupt enabling would be avoided from User Mode (CPSR cannot
@- be written while the core is in User Mode).
@------------------------------------------------------------------------------
                msr CPSR_c, #ARM_MODE_USER @ set User mode
                ldr r13, =TOP_APPLICATION_STACK @ Init stack User

@------------------------------------------------------------------------------
@- 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=0x40 or 0x34) 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.
@------------------------------------------------------------------------------
@ IMPORT |Image$$RO$$Limit| @ End of ROM code (=start of ROM data)
@ IMPORT |Image$$RW$$Base| @ Base of RAM to initialise
@ IMPORT |Image$$ZI$$Base| @ Base and limit of area
@ IMPORT |Image$$ZI$$Limit| @ to zero initialise

@ ldr r0, =|Image$$RO$$Limit| @ Get pointer to ROM data
@ ldr r1, =|Image$$RW$$Base| @ and RAM copy
                ldr r3, = __bss_start__ @ Zero init base => top of initialised data
@ cmp r0, r1 @ Check that they are different
@ beq NoRW
@LoopRw: cmp r1, r3 @ Copy init data
@ ldrcc r2, [r0], #4
@ strcc r2, [r1], #4
@ bcc LoopRw
NoRW: ldr r1, = __bss_end__ @ Top of zero init segment
                mov r2, #0
LoopZI: cmp r3, r1 @ Zero init
                strcc r2, [r3], #4
                bcc LoopZI



@------------------------------------------------------------------------------
@- Branch on C code Main function (with interworking)
@----------------------------------------------------
@- Branch must be performed by an interworking call as either an ARM or Thumb
@- main C function must be supported. This makes the code not position-
@- independant. A Branch with link would generate errors
@------------------------------------------------------------------------------
@ IMPORT 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

            .END