Boot.s 10 KB

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