Boot.s 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. MODULE ?cstartup
  2. ;; Forward declaration of sections.
  3. SECTION IRQ_STACK:DATA:NOROOT(3)
  4. SECTION FIQ_STACK:DATA:NOROOT(3)
  5. SECTION SVC_STACK:DATA:NOROOT(3)
  6. SECTION ABT_STACK:DATA:NOROOT(3)
  7. SECTION UND_STACK:DATA:NOROOT(3)
  8. SECTION CSTACK:DATA:NOROOT(3)
  9. //------------------------------------------------------------------------------
  10. // Headers
  11. //------------------------------------------------------------------------------
  12. #define __ASSEMBLY__
  13. //------------------------------------------------------------------------------
  14. // Definitions
  15. //------------------------------------------------------------------------------
  16. #define IRAM_BASE 0x300000
  17. #define SYS_CPU_CTL 0xe4900208
  18. #define AIC 0xFFFFF000
  19. #define AIC_IVR 0x10
  20. #define AIC_EOICR 0x38
  21. #define ARM_MODE_ABT 0x17
  22. #define ARM_MODE_FIQ 0x11
  23. #define ARM_MODE_IRQ 0x12
  24. #define ARM_MODE_SVC 0x13
  25. #define ARM_MODE_SYS 0x1F
  26. #define I_BIT 0x80
  27. #define F_BIT 0x40
  28. //------------------------------------------------------------------------------
  29. // Startup routine
  30. //------------------------------------------------------------------------------
  31. /*
  32. Exception vectors
  33. */
  34. // SECTION .vectors:CODE:NOROOT(2)
  35. SECTION .intvec:CODE:NOROOT(2)
  36. PUBLIC __vector
  37. PUBLIC __iar_program_start
  38. ARM ; Always ARM mode after reset
  39. __vector:
  40. ldr pc, Reset
  41. LDR PC, Undefined_Addr
  42. LDR PC, SWI_Addr
  43. LDR PC, Prefetch_Addr
  44. LDR PC, Abort_Addr
  45. NOP ; Reserved vector
  46. LDR PC, IRQ_Addr
  47. LDR PC, FIQ_Addr
  48. IMPORT undef_handler
  49. IMPORT swi_handler
  50. IMPORT prefetch_handler
  51. IMPORT data_abort_handler
  52. IMPORT AIC_IrqHandler
  53. IMPORT fiq_handler
  54. Reset: dc32 __iar_program_start
  55. Undefined_Addr: dc32 undef_handler ;Undefined_Handler
  56. SWI_Addr: dc32 swi_handler ;SWI_Handler
  57. Prefetch_Addr: dc32 prefetch_handler ;ExceptionPAB
  58. Abort_Addr: dc32 data_abort_handler ;ExceptionDAB
  59. Reserved_Addr: dc32 0 ;ExceptionREV
  60. IRQ_Addr: dc32 irqHandler
  61. FIQ_Addr: dc32 fiq_handler
  62. MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR
  63. USR_MODE DEFINE 0x10 ; User mode
  64. FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
  65. IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
  66. SVC_MODE DEFINE 0x13 ; Supervisor mode
  67. ABT_MODE DEFINE 0x17 ; Abort mode
  68. UND_MODE DEFINE 0x1B ; Undefined Instruction mode
  69. SYS_MODE DEFINE 0x1F ; System mode
  70. CP_DIS_MASK DEFINE 0xFFFFEFFA
  71. SECTION .text:CODE:NOROOT(2)
  72. EXTERN ?main
  73. REQUIRE __vector
  74. __iar_program_start:
  75. b reset_handler
  76. // DCD 0x424b5241
  77. // DCD 0
  78. // DCD 0
  79. reset_handler:
  80. ;==================================================================
  81. ; Reset registers
  82. ;==================================================================
  83. MOV r2, #0
  84. MOV r3, #0
  85. MOV r4, #0
  86. MOV r5, #0
  87. MOV r6, #0
  88. MOV r7, #0
  89. MOV r8, #0
  90. MOV r9, #0
  91. MOV r10, #0
  92. MOV r11, #0
  93. MOV r12, #0
  94. ;==================================================================
  95. ; Disable caches, MMU and branch prediction in case they were left enabled from an earlier run
  96. ; This does not need to be done from a cold reset
  97. ;==================================================================
  98. MRC p15, 0, r0, c1, c0, 0 ; Read CP15 System Control register
  99. BIC r0, r0, #(0x1 << 12) ; Clear I bit 12 to disable I Cache
  100. ;ORR r0, r0, #(0x1 << 12) ; Set I bit 12 to enable I Cache
  101. BIC r0, r0, #(0x1 << 2) ; Clear C bit 2 to disable D Cache
  102. BIC r0, r0, #0x1 ; Clear M bit 0 to disable MMU
  103. BIC r0, r0, #(0x1 << 11) ; Clear Z bit 11 to disable branch prediction
  104. MCR p15, 0, r0, c1, c0, 0 ; Write value back to CP15 System Control register
  105. ;==================================================================
  106. ; Cache Invalidation code for Cortex-A7
  107. ; NOTE: Neither Caches, nor MMU, nor BTB need post-reset invalidation on Cortex-A7,
  108. ; but forcing a cache invalidation, makes the code more portable to other CPUs (e.g. Cortex-A9)
  109. ;==================================================================
  110. ; Invalidate L1 Instruction Cache
  111. MRC p15, 1, r0, c0, c0, 1 ; Read Cache Level ID Register (CLIDR)
  112. TST r0, #0x3 ; Harvard Cache?
  113. MOV r0, #0 ; SBZ
  114. MCRNE p15, 0, r0, c7, c5, 0 ; ICIALLU - Invalidate instruction cache and flush branch target cache
  115. ; Invalidate Data/Unified Caches
  116. MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR
  117. ANDS r3, r0, #0x07000000 ; Extract coherency level
  118. MOV r3, r3, LSR #23 ; Total cache levels << 1
  119. BEQ Finished ; If 0, no need to clean
  120. MOV r10, #0 ; R10 holds current cache level << 1
  121. Loop1 ADD r2, r10, r10, LSR #1 ; R2 holds cache "Set" position
  122. MOV r1, r0, LSR r2 ; Bottom 3 bits are the Cache-type for this level
  123. AND r1, r1, #7 ; Isolate those lower 3 bits
  124. CMP r1, #2
  125. BLT Skip ; No cache or only instruction cache at this level
  126. MCR p15, 2, r10, c0, c0, 0 ; Write the Cache Size selection register
  127. ISB ; ISB to sync the change to the CacheSizeID reg
  128. MRC p15, 1, r1, c0, c0, 0 ; Reads current Cache Size ID register
  129. AND r2, r1, #7 ; Extract the line length field
  130. ADD r2, r2, #4 ; Add 4 for the line length offset (log2 16 bytes)
  131. LDR r4, =0x3FF
  132. ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned)
  133. CLZ r5, r4 ; R5 is the bit position of the way size increment
  134. LDR r7, =0x7FFF
  135. ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned)
  136. Loop2 MOV r9, r4 ; R9 working copy of the max way size (right aligned)
  137. Loop3 ORR r11, r10, r9, LSL r5 ; Factor in the Way number and cache number into R11
  138. ORR r11, r11, r7, LSL r2 ; Factor in the Set number
  139. MCR p15, 0, r11, c7, c6, 2 ; Invalidate by Set/Way
  140. SUBS r9, r9, #1 ; Decrement the Way number
  141. BGE Loop3
  142. SUBS r7, r7, #1 ; Decrement the Set number
  143. BGE Loop2
  144. Skip ADD r10, r10, #2 ; increment the cache number
  145. CMP r3, r10
  146. BGT Loop1
  147. Finished
  148. ;==================================================================
  149. ; Invalidate TLB
  150. ;==================================================================
  151. MOV r0, #0
  152. MCR p15, 0, r0, c8, c7, 0
  153. ;==================================================================
  154. ; Branch Prediction Enable
  155. ;==================================================================
  156. ;MOV r1, #0
  157. ;MRC p15, 0, r1, c1, c0, 0 /* Read Control Register configuration data */
  158. ;ORR r1, r1, #(0x1 << 11) /* Global BP Enable bit */
  159. ;MCR p15, 0, r1, c1, c0, 0 /* Write Control Register configuration data */
  160. ; Initialize the stack pointers.
  161. ; The pattern below can be used for any of the exception stacks:
  162. ; FIQ, IRQ, SVC, ABT, UND, SYS.
  163. ; The USR mode uses the same stack as SYS.
  164. ; The stack segments must be defined in the linker command file,
  165. ; and be declared above.
  166. mrs r0,cpsr ; Original PSR value
  167. bic r0,r0,#MODE_MSK ; Clear the mode bits
  168. orr r0,r0,#SVC_MODE ; Set Supervisor mode bits
  169. msr cpsr_c,r0 ; Change the mode
  170. ldr sp,=SFE(SVC_STACK) ; End of SVC_STACK
  171. bic r0,r0,#MODE_MSK ; Clear the mode bits
  172. orr r0,r0,#ABT_MODE ; Set Abort mode bits
  173. msr cpsr_c,r0 ; Change the mode
  174. ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK
  175. bic r0,r0,#MODE_MSK ; Clear the mode bits
  176. orr r0,r0,#UND_MODE ; Set Undefined mode bits
  177. msr cpsr_c,r0 ; Change the mode
  178. ldr sp,=SFE(UND_STACK) ; End of UND_STACK
  179. bic r0,r0,#MODE_MSK ; Clear the mode bits
  180. orr r0,r0,#FIQ_MODE ; Set FIR mode bits
  181. msr cpsr_c,r0 ; Change the mode
  182. ldr sp,=SFE(FIQ_STACK) ; End of FIQ_STACK
  183. bic r0,r0,#MODE_MSK ; Clear the mode bits
  184. orr r0,r0,#IRQ_MODE ; Set IRQ mode bits
  185. msr cpsr_c,r0 ; Change the mode
  186. ldr sp,=SFE(IRQ_STACK) ; End of IRQ_STACK
  187. bic r0,r0,#MODE_MSK ; Clear the mode bits
  188. orr r0,r0,#SYS_MODE ; Set System mode bits
  189. msr cpsr_c,r0 ; Change the mode
  190. ldr sp,=SFE(CSTACK) ; End of CSTACK
  191. /* Branch to main() */
  192. LDR r0, =?main
  193. BLX r0
  194. /* Loop indefinitely when program is finished */
  195. loop4:
  196. B loop4
  197. /*
  198. Handles incoming interrupt requests by branching to the corresponding
  199. handler, as defined in the AIC. Supports interrupt nesting.
  200. */
  201. irqHandler:
  202. NOP
  203. NOP
  204. ;/* IRQ entry {{{ */ /* save r0 in r13_IRQ */
  205. SUB lr,lr,#4 /* put return address in r0_SYS */
  206. STMFD sp!,{lr} /* save r1 in r14_IRQ (lr) */
  207. MRS lr,spsr /* put the SPSR in r1_SYS */
  208. STMFD sp!,{r0,lr}
  209. ldr r0, = AIC_IrqHandler
  210. ; ldr r0, [r0];
  211. MSR cpsr_c,#(ARM_MODE_SYS | I_BIT) /* SYSTEM, no IRQ, but FIQ enabled! */ /* save SPSR and PC on SYS stack */
  212. // mcr p15, 0, r0, c7, c10, 5
  213. STMFD sp!, {r1-r3, r4, r12, lr} /* save all other regs on SYS stack */
  214. AND r1, sp, #4
  215. SUB sp, sp, r1
  216. STMFD sp!, {r1, lr}
  217. BLX r0
  218. LDMIA sp!, {r1, lr}
  219. ADD sp, sp, r1
  220. LDMIA sp!, {r1-r3, r4, r12, lr}
  221. MSR CPSR_c, #ARM_MODE_IRQ | I_BIT
  222. LDMIA sp!, {r0, lr}
  223. MSR SPSR_cxsf, lr
  224. LDMIA sp!, {pc}^
  225. END