Wolfrum

Coretex-A8 beagle board xm Startup code

Mar 27th, 2013
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MPASM 14.64 KB | None | 0 0
  1. ;; Bare-metal startup code for Cortex-A8 on Beagle Board
  2. ;;
  3. ;; Vector table, reset handler, stacks, interrupt handler, cache & MMU config, NEON enable.
  4. ;;
  5. ;; Copyright ARM Ltd 2002-2012. All rights reserved.
  6.  
  7.  
  8. ; Standard definitions of mode bits and interrupt (I & F) flags in PSRs
  9.  
  10. Mode_USR        EQU     0x10
  11. Mode_FIQ        EQU     0x11
  12. Mode_IRQ        EQU     0x12
  13. Mode_SVC        EQU     0x13
  14. Mode_ABT        EQU     0x17
  15. Mode_UND        EQU     0x1B
  16. Mode_SYS        EQU     0x1F
  17.  
  18. I_Bit           EQU     0x80 ; when I bit is set, IRQ is disabled
  19. F_Bit           EQU     0x40 ; when F bit is set, FIQ is disabled
  20.  
  21.  
  22.     PRESERVE8
  23.  
  24.     AREA   VECTORS, CODE, READONLY   ; name this block of code
  25.  
  26.     ENTRY
  27.  
  28.  
  29. ; StartHere is the Entry point for the Reset handler
  30.  
  31.     EXPORT StartHere
  32.  
  33. StartHere
  34.  
  35. ;***********************
  36. ; Exception Vector Table
  37. ;***********************
  38.  
  39. ; Note: LDR PC instructions are used here, though branch (B) instructions
  40. ; could also be used, unless the exception handlers are >32MB away.
  41.  
  42. Vectors
  43.     LDR PC, Reset_Addr
  44.     LDR PC, Undefined_Addr
  45.     LDR PC, SVC_Addr
  46.     LDR PC, Prefetch_Addr
  47.     LDR PC, Abort_Addr
  48.     B .                             ; Reserved vector
  49.     LDR PC, IRQ_Addr
  50.     LDR PC, FIQ_Addr
  51.  
  52.  
  53. Reset_Addr      DCD     Reset_Handler
  54. Undefined_Addr  DCD     Undefined_Handler
  55. SVC_Addr        DCD     SVC_Handler
  56. Prefetch_Addr   DCD     Prefetch_Handler
  57. Abort_Addr      DCD     Abort_Handler
  58. IRQ_Addr        DCD     IRQ_Handler
  59. FIQ_Addr        DCD     FIQ_Handler
  60.  
  61.  
  62. ;***********************
  63. ; Exception Handlers
  64. ;***********************
  65.  
  66. ; The following dummy handlers do not do anything useful in this example.
  67. ; They are set up here for completeness.
  68.  
  69. Undefined_Handler
  70.     B   Undefined_Handler
  71. SVC_Handler
  72.     B   SVC_Handler
  73. Prefetch_Handler
  74.     B   Prefetch_Handler
  75. Abort_Handler
  76.     B   Abort_Handler
  77. ;;IRQ_Handler
  78. ;;    implemented below
  79. FIQ_Handler
  80.     B   FIQ_Handler
  81. IRQ_Handler
  82.  B   IRQ_Handler
  83.  
  84.  
  85. ;***********************
  86. ; Interrupt Handler
  87. ;***********************
  88.  
  89. ; This simple example is only able to handle interrupts one after another.
  90. ; For a more complex nested (re-entrant) interrupt handler example, refer to the documentation
  91.  
  92.    ; IMPORT C_interrupt_handler
  93.  
  94. ;IRQ_Handler FUNCTION {r0-r12}
  95.  ;   PUSH {r0-r3, r12, lr}
  96.  
  97.   ;  BL C_interrupt_handler
  98.  
  99.    ; POP {r0-r3, r12, lr}
  100.     ;SUBS pc, lr, #4
  101.  
  102.     ;ENDFUNC
  103.  
  104.  
  105. ;***********************
  106. ; Stack definitions
  107. ;***********************
  108.  
  109. ; Import stack base linker symbols for app and irq from scatter file.  Stacks must be 8 byte aligned.
  110.  
  111.                 IMPORT  ||Image$$ARM_LIB_STACK$$ZI$$Limit||
  112. app_stack_base  DCD     ||Image$$ARM_LIB_STACK$$ZI$$Limit||
  113.                 IMPORT  ||Image$$IRQ_STACK$$ZI$$Limit||
  114. irq_stack_base  DCD     ||Image$$IRQ_STACK$$ZI$$Limit||
  115.  
  116.  
  117. ;***********************
  118. ; Reset Handler
  119. ;***********************
  120.  
  121. ; Disable cache and MMU, invalidate TLBs, fix vector table, setup stack pointers, setup & enable MMU, enable NEON, enter C library via __main(), then enable cache.
  122.  
  123. Reset_Handler   FUNCTION {}
  124.  
  125.     ; Disable caches, MMU and branch prediction in case they were left enabled from an earlier run
  126.     ; This does not need to be done from a cold reset
  127.     MRC     p15, 0, r0, c1, c0, 0       ; Read CP15 System Control register
  128.     BIC     r0, r0, #(0x1 << 12)        ; Clear I bit 12 to disable I Cache
  129.     BIC     r0, r0, #(0x1 <<  2)        ; Clear C bit  2 to disable D Cache
  130.     BIC     r0, r0, #0x1                ; Clear M bit  0 to disable MMU
  131.     BIC     r0, r0, #(0x1 << 11)        ; Clear Z bit 11 to disable branch prediction
  132.     MCR     p15, 0, r0, c1, c0, 0       ; Write value back to CP15 System Control register
  133.  
  134. ; The MMU is enabled later, before calling main().  Caches and branch prediction are enabled inside main(),
  135. ; after the MMU has been enabled and scatterloading has been performed.
  136.  
  137.     ; Invalidate Data and Instruction TLBs and branch predictor
  138.     MOV     r0,#0
  139.     MCR     p15, 0, r0, c8, c7, 0      ; I-TLB and D-TLB invalidation
  140.     MCR     p15, 0, r0, c7, c5, 6      ; BPIALL - Invalidate entire branch predictor array
  141.  
  142.  
  143.     ; Set Vector Base Address Register (VBAR) to point to this application's vector table
  144.     LDR r0, =Vectors
  145.     MCR p15, 0, r0, c12, c0, 0
  146.  
  147.  
  148.     ; Enter each mode used in turn to disable interrupts and set up the stack pointer
  149.     ; In this simple example, only SVC and IRQ modes are used
  150.     ; Stack pointers must be 8 byte aligned
  151.     MSR     CPSR_c, #Mode_IRQ :OR: I_Bit :OR: F_Bit
  152.     LDR     r0, irq_stack_base
  153.     MOV     sp, r0
  154.  
  155.     MSR     CPSR_c, #Mode_SVC :OR: I_Bit :OR: F_Bit
  156.     LDR     r0, app_stack_base
  157.     MOV     sp, r0
  158.  
  159.     ; Continue in SVC mode
  160.  
  161.  
  162. ;==================================================================
  163. ; Cache Invalidation code for Cortex-A8
  164. ;==================================================================
  165.  
  166.         ; Invalidate L1 Instruction Cache
  167.  
  168.         MRC p15, 1, r0, c0, c0, 1   ; Read Cache Level ID Register (CLIDR)
  169.         TST r0, #0x3                ; Harvard Cache?
  170.         MOV r0, #0                  ; SBZ
  171.         MCRNE p15, 0, r0, c7, c5, 0 ; ICIALLU - Invalidate instruction cache and flush branch target cache
  172.  
  173.         ; Invalidate Data/Unified Caches
  174.  
  175.         MRC p15, 1, r0, c0, c0, 1   ; Read CLIDR
  176.         ANDS r3, r0, #0x07000000    ; Extract coherency level
  177.         MOV r3, r3, LSR #23         ; Total cache levels << 1
  178.         BEQ Finished                ; If 0, no need to clean
  179.  
  180.         MOV r10, #0                 ; R10 holds current cache level << 1
  181. Loop1   ADD r2, r10, r10, LSR #1    ; R2 holds cache "Set" position
  182.         MOV r1, r0, LSR r2          ; Bottom 3 bits are the Cache-type for this level
  183.         AND r1, r1, #7              ; Isolate those lower 3 bits
  184.         CMP r1, #2
  185.         BLT Skip                    ; No cache or only instruction cache at this level
  186.  
  187.         MCR p15, 2, r10, c0, c0, 0  ; Write the Cache Size selection register
  188.         ISB                         ; ISB to sync the change to the CacheSizeID reg
  189.         MRC p15, 1, r1, c0, c0, 0   ; Reads current Cache Size ID register
  190.         AND r2, r1, #7              ; Extract the line length field
  191.         ADD r2, r2, #4              ; Add 4 for the line length offset (log2 16 bytes)
  192.         LDR r4, =0x3FF
  193.         ANDS r4, r4, r1, LSR #3     ; R4 is the max number on the way size (right aligned)
  194.         CLZ r5, r4                  ; R5 is the bit position of the way size increment
  195.         LDR r7, =0x7FFF
  196.         ANDS r7, r7, r1, LSR #13    ; R7 is the max number of the index size (right aligned)
  197.  
  198. Loop2   MOV r9, r4                  ; R9 working copy of the max way size (right aligned)
  199.  
  200. Loop3   ORR r11, r10, r9, LSL r5    ; Factor in the Way number and cache number into R11
  201.         ORR r11, r11, r7, LSL r2    ; Factor in the Set number
  202.         MCR p15, 0, r11, c7, c6, 2  ; Invalidate by Set/Way
  203.         SUBS r9, r9, #1             ; Decrement the Way number
  204.         BGE Loop3
  205.         SUBS r7, r7, #1             ; Decrement the Set number
  206.         BGE Loop2
  207. Skip    ADD r10, r10, #2            ; Increment the cache number
  208.         CMP r3, r10
  209.         BGT Loop1
  210.  
  211. Finished
  212.  
  213.  
  214. ;===================================================================
  215. ; Cortex-A8 MMU Configuration
  216. ; Set translation table base
  217. ;===================================================================
  218.  
  219.         IMPORT ||Image$$APP_CODE$$Base||    ; From scatter file
  220.         IMPORT ||Image$$TTB$$ZI$$Base||  ; from scatter file
  221.  
  222.         ; Cortex-A8 supports two translation tables
  223.         ; Configure translation table base (TTB) control register cp15,c2
  224.         ; to a value of all zeros, indicates we are using TTB register 0.
  225.  
  226.         MOV     r0,#0x0
  227.         MCR     p15, 0, r0, c2, c0, 2
  228.  
  229.  
  230.         ; write the address of our page table base to TTB register 0
  231.  
  232.         LDR     r0,=||Image$$TTB$$ZI$$Base||
  233.         MCR     p15, 0, r0, c2, c0, 0
  234.  
  235.  
  236. ;===================================================================
  237. ; Cortex-A8 PAGE TABLE generation, using standard Arch v6 tables
  238. ;
  239. ; AP[11:10]   - Access Permissions = b11, Read/Write Access
  240. ; Domain[8:5] - Domain = b1111, Domain 15
  241. ; Type[1:0]   - Descriptor Type = b10, 1MB descriptors
  242. ;
  243. ; TEX  C  B
  244. ; 000  0  0  Strongly Ordered
  245. ; 000  1  1  Outer and Inner write back, no Write-allocate.
  246. ;===================================================================
  247.  
  248.         LDR     r1,=0xfff                   ; loop counter
  249.         LDR     r2,=2_00000000000000000000110111100010
  250.  
  251.         ; r0 contains the address of the translation table base
  252.         ; r1 is loop counter
  253.         ; r2 is level1 descriptor (bits 19:0)
  254.  
  255.         ; use loop counter to create 4096 individual table entries.
  256.         ; this writes from address 'Image$$TTB$$ZI$$Base' +
  257.         ; offset 0x3FFC down to offset 0x0 in word steps (4 bytes)
  258.  
  259. init_ttb_1
  260.  
  261.         ORR     r3, r2, r1, LSL#20          ; r3 now contains full level1 descriptor to write
  262.         STR     r3, [r0, r1, LSL#2]         ; str table entry at TTB base + loopcount*4
  263.         SUBS    r1, r1, #1                  ; decrement loop counter
  264.         BPL     init_ttb_1
  265.  
  266.         ; In this example, the 1MB section based at '||Image$$APP_CODE$$Base||' is setup specially as cacheable (write back mode).
  267.         ; TEX[14:12]=000 and CB[3:2]= 11, Outer and inner write back, no Write-allocate normal memory.
  268.  
  269.         LDR     r1,=||Image$$APP_CODE$$Base|| ; Base physical address of code segment
  270.         LSR     r1,#20                     ; Shift right to align to 1MB boundaries
  271.         ORR     r3, r2, r1, LSL#20         ; Setup the initial level1 descriptor again
  272.         ORR     r3,r3,#2_0000000001100     ; Set CB bits
  273.         STR     r3, [r0, r1, LSL#2]        ; str table entry
  274.  
  275. ;===================================================================
  276. ; Setup domain control register - Enable all domains to client mode
  277. ;===================================================================
  278.  
  279.         MRC     p15, 0, r0, c3, c0, 0     ; Read Domain Access Control Register
  280.         LDR     r0, =0x55555555           ; Initialize every domain entry to b01 (client)
  281.         MCR     p15, 0, r0, c3, c0, 0     ; Write Domain Access Control Register
  282.  
  283. ;===================================================================
  284. ; Setup L2 Cache - L2 Cache Auxiliary Control
  285. ;===================================================================
  286.  
  287. ;; Seems to undef on Beagle ?
  288. ;;        MOV     r0, #0
  289. ;;        MCR     p15, 1, r0, c9, c0, 2      ; Write L2 Auxilary Control Register
  290.  
  291.  
  292.     IF {TARGET_FEATURE_NEON} || {TARGET_FPU_VFP}
  293. ;==================================================================
  294. ; Enable access to NEON/VFP by enabling access to Coprocessors 10 and 11.
  295. ; Enables Full Access i.e. in both privileged and non privileged modes
  296. ;==================================================================
  297.  
  298.         MRC     p15, 0, r0, c1, c0, 2      ; Read Coprocessor Access Control Register (CPACR)
  299.         ORR     r0, r0, #(0xF << 20)       ; Enable access to CP 10 & 11
  300.         MCR     p15, 0, r0, c1, c0, 2      ; Write Coprocessor Access Control Register (CPACR)
  301.         ISB
  302.  
  303. ;==================================================================
  304. ; Switch on the VFP and NEON hardware
  305. ;=================================================================
  306.  
  307.         MOV     r0, #0x40000000
  308.         VMSR    FPEXC, r0                   ; Write FPEXC register, EN bit set
  309.     ENDIF
  310.  
  311.  
  312. ;===================================================================
  313. ; Enable MMU and Branch to __main
  314. ; Leaving the caches disabled until after scatter loading.
  315. ;===================================================================
  316.  
  317.         IMPORT  __main                      ; Before MMU enabled import label to __main
  318.         LDR     r12,=__main                 ; save this in register for possible long jump
  319.  
  320.  
  321.         MRC     p15, 0, r0, c1, c0, 0       ; Read CP15 System Control register
  322.         BIC     r0, r0, #(0x1 << 12)        ; Clear I bit 12 to disable I Cache
  323.         BIC     r0, r0, #(0x1 <<  2)        ; Clear C bit  2 to disable D Cache
  324.         BIC     r0, r0, #0x2                ; Clear A bit  1 to disable strict alignment fault checking
  325.         ORR     r0, r0, #0x1                ; Set M bit 0 to enable MMU before scatter loading
  326.         MCR     p15, 0, r0, c1, c0, 0       ; Write CP15 System Control register
  327.  
  328.  
  329. ; Now the MMU is enabled, virtual to physical address translations will occur.
  330. ; This will affect the next instruction fetches.
  331. ;
  332. ; The two instructions currently in the ARM pipeline will have been fetched before the MMU was enabled.
  333. ; The branch to __main is safe because the Virtual Address (VA) is the same as the Physical Address (PA)
  334. ; (flat mapping) of this code that enables the MMU and performs the branch
  335.  
  336.         BX      r12                         ; Branch to __main() C library entry point
  337.  
  338.     ENDFUNC
  339.  
  340.  
  341.  
  342. ;==================================================================
  343. ; Enable caches and branch prediction
  344. ; This code must be run from a privileged mode
  345. ;==================================================================
  346.  
  347.         AREA   ENABLECACHES, CODE, READONLY
  348.  
  349.         EXPORT enable_caches
  350.  
  351. enable_caches  FUNCTION
  352.  
  353. ;==================================================================
  354. ; Enable caches and branch prediction
  355. ;==================================================================
  356.  
  357.         MRC     p15, 0, r0, c1, c0, 0      ; Read System Control Register
  358.         ORR     r0, r0, #(0x1 << 12)       ; Set I bit 12 to enable I Cache
  359.         ORR     r0, r0, #(0x1 << 2)        ; Set C bit  2 to enable D Cache
  360.         ORR     r0, r0, #(0x1 << 11)       ; Set Z bit 11 to enable branch prediction
  361.         MCR     p15, 0, r0, c1, c0, 0      ; Write System Control Register
  362.  
  363.  
  364. ;==================================================================
  365. ; Enable Cortex-A8 Level2 Unified Cache
  366. ;==================================================================
  367.  
  368.         MRC     p15, 0, r0, c1, c0, 1      ; Read Auxiliary Control Register
  369.         ORR     r0, #2                     ; L2EN bit, enable L2 cache
  370.         MCR     p15, 0, r0, c1, c0, 1      ; Write Auxiliary Control Register
  371.  
  372.         BX      lr
  373.  
  374.         ENDFUNC
  375.  
  376.  
  377.     EXPORT disable_caches
  378.  
  379. disable_caches FUNCTION
  380.  
  381.         MRC     p15, 0, r0, c1, c0, 0       ; Read CP15 System Control register
  382.         BIC     r0, r0, #(0x1 << 12)        ; Clear I bit 12 to disable I Cache
  383.         BIC     r0, r0, #(0x1 <<  2)        ; Clear C bit  2 to disable D Cache
  384.         MCR     p15, 0, r0, c1, c0, 0       ; Write CP15 System Control register
  385.  
  386.         BX    lr
  387.  
  388.         ENDFUNC
  389.  
  390.  
  391.         END
Advertisement
Add Comment
Please, Sign In to add comment