head.S 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*
  2. * CRISv32 kernel startup code.
  3. *
  4. * Copyright (C) 2003, Axis Communications AB
  5. */
  6. #define ASSEMBLER_MACROS_ONLY
  7. /*
  8. * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so
  9. * -traditional must not be used when assembling this file.
  10. */
  11. #include <arch/memmap.h>
  12. #include <hwregs/reg_rdwr.h>
  13. #include <hwregs/intr_vect.h>
  14. #include <hwregs/asm/mmu_defs_asm.h>
  15. #include <hwregs/asm/reg_map_asm.h>
  16. #include <mach/startup.inc>
  17. #define CRAMFS_MAGIC 0x28cd3d45
  18. #define JHEAD_MAGIC 0x1FF528A6
  19. #define JHEAD_SIZE 8
  20. #define RAM_INIT_MAGIC 0x56902387
  21. #define COMMAND_LINE_MAGIC 0x87109563
  22. #define NAND_BOOT_MAGIC 0x9a9db001
  23. ;; NOTE: R8 and R9 carry information from the decompressor (if the
  24. ;; kernel was compressed). They must not be used in the code below
  25. ;; until they are read!
  26. ;; Exported symbols.
  27. .global etrax_irv
  28. .global romfs_start
  29. .global romfs_length
  30. .global romfs_in_flash
  31. .global nand_boot
  32. .global swapper_pg_dir
  33. ;; Dummy section to make it bootable with current VCS simulator
  34. #ifdef CONFIG_ETRAX_VCS_SIM
  35. .section ".boot", "ax"
  36. ba tstart
  37. nop
  38. #endif
  39. .text
  40. tstart:
  41. ;; This is the entry point of the kernel. The CPU is currently in
  42. ;; supervisor mode.
  43. ;;
  44. ;; 0x00000000 if flash.
  45. ;; 0x40004000 if DRAM.
  46. ;;
  47. di
  48. START_CLOCKS
  49. SETUP_WAIT_STATES
  50. GIO_INIT
  51. #ifdef CONFIG_SMP
  52. secondary_cpu_entry: /* Entry point for secondary CPUs */
  53. di
  54. #endif
  55. ;; Setup and enable the MMU. Use same configuration for both the data
  56. ;; and the instruction MMU.
  57. ;;
  58. ;; Note; 3 cycles is needed for a bank-select to take effect. Further;
  59. ;; bank 1 is the instruction MMU, bank 2 is the data MMU.
  60. #ifdef CONFIG_CRIS_MACH_ARTPEC3
  61. move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
  62. | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
  63. | REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 5) \
  64. | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
  65. #elif !defined(CONFIG_ETRAX_VCS_SIM)
  66. move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
  67. | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
  68. | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
  69. #else
  70. ;; Map the virtual DRAM to the RW eprom area at address 0.
  71. ;; Also map 0xa for the hook calls,
  72. move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
  73. | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
  74. | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \
  75. | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0
  76. #endif
  77. ;; Temporary map of 0x40 -> 0x40 and 0x00 -> 0x00.
  78. move.d REG_FIELD(mmu, rw_mm_kbase_lo, base_4, 4) \
  79. | REG_FIELD(mmu, rw_mm_kbase_lo, base_0, 0), $r1
  80. ;; Enable certain page protections and setup linear mapping
  81. ;; for f,e,c,b,4,0.
  82. ;; ARTPEC-3:
  83. ;; c,d used for linear kernel mapping, up to 512 MB
  84. ;; e used for vmalloc
  85. ;; f unused, but page mapped to get page faults
  86. ;; ETRAX FS:
  87. ;; c used for linear kernel mapping, up to 256 MB
  88. ;; d used for vmalloc
  89. ;; e,f used for memory-mapped NOR flash
  90. #ifdef CONFIG_CRIS_MACH_ARTPEC3
  91. move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
  92. | REG_STATE(mmu, rw_mm_cfg, acc, on) \
  93. | REG_STATE(mmu, rw_mm_cfg, ex, on) \
  94. | REG_STATE(mmu, rw_mm_cfg, inv, on) \
  95. | REG_STATE(mmu, rw_mm_cfg, seg_f, page) \
  96. | REG_STATE(mmu, rw_mm_cfg, seg_e, page) \
  97. | REG_STATE(mmu, rw_mm_cfg, seg_d, linear) \
  98. | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \
  99. | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \
  100. | REG_STATE(mmu, rw_mm_cfg, seg_a, page) \
  101. | REG_STATE(mmu, rw_mm_cfg, seg_9, page) \
  102. | REG_STATE(mmu, rw_mm_cfg, seg_8, page) \
  103. | REG_STATE(mmu, rw_mm_cfg, seg_7, page) \
  104. | REG_STATE(mmu, rw_mm_cfg, seg_6, page) \
  105. | REG_STATE(mmu, rw_mm_cfg, seg_5, page) \
  106. | REG_STATE(mmu, rw_mm_cfg, seg_4, linear) \
  107. | REG_STATE(mmu, rw_mm_cfg, seg_3, page) \
  108. | REG_STATE(mmu, rw_mm_cfg, seg_2, page) \
  109. | REG_STATE(mmu, rw_mm_cfg, seg_1, page) \
  110. | REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
  111. #elif !defined(CONFIG_ETRAX_VCS_SIM)
  112. move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
  113. | REG_STATE(mmu, rw_mm_cfg, acc, on) \
  114. | REG_STATE(mmu, rw_mm_cfg, ex, on) \
  115. | REG_STATE(mmu, rw_mm_cfg, inv, on) \
  116. | REG_STATE(mmu, rw_mm_cfg, seg_f, linear) \
  117. | REG_STATE(mmu, rw_mm_cfg, seg_e, linear) \
  118. | REG_STATE(mmu, rw_mm_cfg, seg_d, page) \
  119. | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \
  120. | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \
  121. | REG_STATE(mmu, rw_mm_cfg, seg_a, page) \
  122. | REG_STATE(mmu, rw_mm_cfg, seg_9, page) \
  123. | REG_STATE(mmu, rw_mm_cfg, seg_8, page) \
  124. | REG_STATE(mmu, rw_mm_cfg, seg_7, page) \
  125. | REG_STATE(mmu, rw_mm_cfg, seg_6, page) \
  126. | REG_STATE(mmu, rw_mm_cfg, seg_5, page) \
  127. | REG_STATE(mmu, rw_mm_cfg, seg_4, linear) \
  128. | REG_STATE(mmu, rw_mm_cfg, seg_3, page) \
  129. | REG_STATE(mmu, rw_mm_cfg, seg_2, page) \
  130. | REG_STATE(mmu, rw_mm_cfg, seg_1, page) \
  131. | REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
  132. #else
  133. move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
  134. | REG_STATE(mmu, rw_mm_cfg, acc, on) \
  135. | REG_STATE(mmu, rw_mm_cfg, ex, on) \
  136. | REG_STATE(mmu, rw_mm_cfg, inv, on) \
  137. | REG_STATE(mmu, rw_mm_cfg, seg_f, linear) \
  138. | REG_STATE(mmu, rw_mm_cfg, seg_e, linear) \
  139. | REG_STATE(mmu, rw_mm_cfg, seg_d, page) \
  140. | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \
  141. | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \
  142. | REG_STATE(mmu, rw_mm_cfg, seg_a, linear) \
  143. | REG_STATE(mmu, rw_mm_cfg, seg_9, page) \
  144. | REG_STATE(mmu, rw_mm_cfg, seg_8, page) \
  145. | REG_STATE(mmu, rw_mm_cfg, seg_7, page) \
  146. | REG_STATE(mmu, rw_mm_cfg, seg_6, page) \
  147. | REG_STATE(mmu, rw_mm_cfg, seg_5, page) \
  148. | REG_STATE(mmu, rw_mm_cfg, seg_4, linear) \
  149. | REG_STATE(mmu, rw_mm_cfg, seg_3, page) \
  150. | REG_STATE(mmu, rw_mm_cfg, seg_2, page) \
  151. | REG_STATE(mmu, rw_mm_cfg, seg_1, page) \
  152. | REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
  153. #endif
  154. ;; Update instruction MMU.
  155. move 1, $srs
  156. nop
  157. nop
  158. nop
  159. move $r0, $s2 ; kbase_hi.
  160. move $r1, $s1 ; kbase_lo.
  161. move $r2, $s0 ; mm_cfg, virtual memory configuration.
  162. ;; Update data MMU.
  163. move 2, $srs
  164. nop
  165. nop
  166. nop
  167. move $r0, $s2 ; kbase_hi.
  168. move $r1, $s1 ; kbase_lo
  169. move $r2, $s0 ; mm_cfg, virtual memory configuration.
  170. ;; Enable data and instruction MMU.
  171. move 0, $srs
  172. moveq 0xf, $r0 ; IMMU, DMMU, DCache, Icache on
  173. nop
  174. nop
  175. nop
  176. move $r0, $s0
  177. nop
  178. nop
  179. nop
  180. #ifdef CONFIG_SMP
  181. ;; Read CPU ID
  182. move 0, $srs
  183. nop
  184. nop
  185. nop
  186. move $s12, $r0
  187. cmpq 0, $r0
  188. beq master_cpu
  189. nop
  190. slave_cpu:
  191. ; Time to boot-up. Get stack location provided by master CPU.
  192. move.d smp_init_current_idle_thread, $r1
  193. move.d [$r1], $sp
  194. add.d 8192, $sp
  195. move.d ebp_start, $r0 ; Defined in linker-script.
  196. move $r0, $ebp
  197. jsr smp_callin
  198. nop
  199. master_cpu:
  200. /* Set up entry point for secondary CPUs. The boot ROM has set up
  201. * EBP at start of internal memory. The CPU will get there
  202. * later when we issue an IPI to them... */
  203. move.d MEM_INTMEM_START + IPI_INTR_VECT * 4, $r0
  204. move.d secondary_cpu_entry, $r1
  205. move.d $r1, [$r0]
  206. #endif
  207. #ifndef CONFIG_ETRAX_VCS_SIM
  208. ; Check if starting from DRAM (network->RAM boot or unpacked
  209. ; compressed kernel), or directly from flash.
  210. lapcq ., $r0
  211. and.d 0x7fffffff, $r0 ; Mask off the non-cache bit.
  212. cmp.d 0x10000, $r0 ; Arbitrary, something above this code.
  213. blo _inflash0
  214. nop
  215. #endif
  216. jump _inram ; Jump to cached RAM.
  217. nop
  218. ;; Jumpgate.
  219. _inflash0:
  220. jump _inflash
  221. nop
  222. ;; Put the following in a section so that storage for it can be
  223. ;; reclaimed after init is finished.
  224. .section ".init.text", "ax"
  225. _inflash:
  226. ;; Initialize DRAM.
  227. cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized?
  228. beq _dram_initialized
  229. nop
  230. #if defined CONFIG_ETRAXFS
  231. #include "../mach-fs/dram_init.S"
  232. #elif defined CONFIG_CRIS_MACH_ARTPEC3
  233. #include "../mach-a3/dram_init.S"
  234. #else
  235. #error Only ETRAXFS and ARTPEC-3 supported!
  236. #endif
  237. _dram_initialized:
  238. ;; Copy the text and data section to DRAM. This depends on that the
  239. ;; variables used below are correctly set up by the linker script.
  240. ;; The calculated value stored in R4 is used below.
  241. ;; Leave the cramfs file system (piggybacked after the kernel) in flash.
  242. moveq 0, $r0 ; Source.
  243. move.d text_start, $r1 ; Destination.
  244. move.d __vmlinux_end, $r2
  245. move.d $r2, $r4
  246. sub.d $r1, $r4
  247. 1: move.w [$r0+], $r3
  248. move.w $r3, [$r1+]
  249. cmp.d $r2, $r1
  250. blo 1b
  251. nop
  252. ;; Check for cramfs.
  253. moveq 0, $r0
  254. move.d romfs_length, $r1
  255. move.d $r0, [$r1]
  256. move.d [$r4], $r0 ; cramfs_super.magic
  257. cmp.d CRAMFS_MAGIC, $r0
  258. bne 1f
  259. nop
  260. ;; Set length and start of cramfs, set romfs_in_flash flag
  261. addoq +4, $r4, $acr
  262. move.d [$acr], $r0
  263. move.d romfs_length, $r1
  264. move.d $r0, [$r1]
  265. add.d 0xf0000000, $r4 ; Add cached flash start in virtual memory.
  266. move.d romfs_start, $r1
  267. move.d $r4, [$r1]
  268. 1: moveq 1, $r0
  269. move.d romfs_in_flash, $r1
  270. move.d $r0, [$r1]
  271. jump _start_it ; Jump to cached code.
  272. nop
  273. _inram:
  274. ;; Check if booting from NAND flash; if so, set appropriate flags
  275. ;; and move on.
  276. cmp.d NAND_BOOT_MAGIC, $r12
  277. bne move_cramfs ; not nand, jump
  278. moveq 1, $r0
  279. move.d nand_boot, $r1 ; tell axisflashmap we're booting from NAND
  280. move.d $r0, [$r1]
  281. moveq 0, $r0 ; tell axisflashmap romfs is not in
  282. move.d romfs_in_flash, $r1 ; (directly accessed) flash
  283. move.d $r0, [$r1]
  284. jump _start_it ; continue with boot
  285. nop
  286. move_cramfs:
  287. ;; kernel is in DRAM.
  288. ;; Must figure out if there is a piggybacked rootfs image or not.
  289. ;; Set romfs_length to 0 => no rootfs image available by default.
  290. moveq 0, $r0
  291. move.d romfs_length, $r1
  292. move.d $r0, [$r1]
  293. #ifndef CONFIG_ETRAX_VCS_SIM
  294. ;; The kernel could have been unpacked to DRAM by the loader, but
  295. ;; the cramfs image could still be in the flash immediately
  296. ;; following the compressed kernel image. The loader passes the address
  297. ;; of the byte succeeding the last compressed byte in the flash in
  298. ;; register R9 when starting the kernel.
  299. cmp.d 0x0ffffff8, $r9
  300. bhs _no_romfs_in_flash ; R9 points outside the flash area.
  301. nop
  302. #else
  303. ba _no_romfs_in_flash
  304. nop
  305. #endif
  306. ;; cramfs rootfs might to be in flash. Check for it.
  307. move.d [$r9], $r0 ; cramfs_super.magic
  308. cmp.d CRAMFS_MAGIC, $r0
  309. bne _no_romfs_in_flash
  310. nop
  311. ;; found cramfs in flash. set address and size, and romfs_in_flash flag.
  312. addoq +4, $r9, $acr
  313. move.d [$acr], $r0
  314. move.d romfs_length, $r1
  315. move.d $r0, [$r1]
  316. add.d 0xf0000000, $r9 ; Add cached flash start in virtual memory.
  317. move.d romfs_start, $r1
  318. move.d $r9, [$r1]
  319. moveq 1, $r0
  320. move.d romfs_in_flash, $r1
  321. move.d $r0, [$r1]
  322. jump _start_it ; Jump to cached code.
  323. nop
  324. _no_romfs_in_flash:
  325. ;; No romfs in flash, so look for cramfs, or jffs2 with jhead,
  326. ;; after kernel in RAM, as is the case with network->RAM boot.
  327. ;; For cramfs, partition starts with magic and length.
  328. ;; For jffs2, a jhead is prepended which contains with magic and length.
  329. ;; The jhead is not part of the jffs2 partition however.
  330. #ifndef CONFIG_ETRAXFS_SIM
  331. move.d __bss_start, $r0
  332. #else
  333. move.d __end, $r0
  334. #endif
  335. move.d [$r0], $r1
  336. cmp.d CRAMFS_MAGIC, $r1 ; cramfs magic?
  337. beq 2f ; yes, jump
  338. nop
  339. cmp.d JHEAD_MAGIC, $r1 ; jffs2 (jhead) magic?
  340. bne 4f ; no, skip copy
  341. nop
  342. addq 4, $r0 ; location of jffs2 size
  343. move.d [$r0+], $r2 ; fetch jffs2 size -> r2
  344. ; r0 now points to start of jffs2
  345. ba 3f
  346. nop
  347. 2:
  348. addoq +4, $r0, $acr ; location of cramfs size
  349. move.d [$acr], $r2 ; fetch cramfs size -> r2
  350. ; r0 still points to start of cramfs
  351. 3:
  352. ;; Now, move the root fs to after kernel's BSS
  353. move.d _end, $r1 ; start of cramfs -> r1
  354. move.d romfs_start, $r3
  355. move.d $r1, [$r3] ; store at romfs_start (for axisflashmap)
  356. move.d romfs_length, $r3
  357. move.d $r2, [$r3] ; store size at romfs_length
  358. #ifndef CONFIG_ETRAX_VCS_SIM
  359. add.d $r2, $r0 ; copy from end and downwards
  360. add.d $r2, $r1
  361. lsrq 1, $r2 ; Size is in bytes, we copy words.
  362. addq 1, $r2
  363. 1:
  364. move.w [$r0], $r3
  365. move.w $r3, [$r1]
  366. subq 2, $r0
  367. subq 2, $r1
  368. subq 1, $r2
  369. bne 1b
  370. nop
  371. #endif
  372. 4:
  373. ;; BSS move done.
  374. ;; Clear romfs_in_flash flag, as we now know romfs is in DRAM
  375. ;; Also clear nand_boot flag; if we got here, we know we've not
  376. ;; booted from NAND flash.
  377. moveq 0, $r0
  378. move.d romfs_in_flash, $r1
  379. move.d $r0, [$r1]
  380. moveq 0, $r0
  381. move.d nand_boot, $r1
  382. move.d $r0, [$r1]
  383. jump _start_it ; Jump to cached code.
  384. nop
  385. _start_it:
  386. ;; Check if kernel command line is supplied
  387. cmp.d COMMAND_LINE_MAGIC, $r10
  388. bne no_command_line
  389. nop
  390. move.d 256, $r13
  391. move.d cris_command_line, $r10
  392. or.d 0x80000000, $r11 ; Make it virtual
  393. 1:
  394. move.b [$r11+], $r1
  395. move.b $r1, [$r10+]
  396. subq 1, $r13
  397. bne 1b
  398. nop
  399. no_command_line:
  400. ;; The kernel stack contains a task structure for each task. This
  401. ;; the initial kernel stack is in the same page as the init_task,
  402. ;; but starts at the top of the page, i.e. + 8192 bytes.
  403. move.d init_thread_union + 8192, $sp
  404. move.d ebp_start, $r0 ; Defined in linker-script.
  405. move $r0, $ebp
  406. move.d etrax_irv, $r1 ; Set the exception base register and pointer.
  407. move.d $r0, [$r1]
  408. #ifndef CONFIG_ETRAX_VCS_SIM
  409. ;; Clear the BSS region from _bss_start to _end.
  410. move.d __bss_start, $r0
  411. move.d _end, $r1
  412. 1: clear.d [$r0+]
  413. cmp.d $r1, $r0
  414. blo 1b
  415. nop
  416. #endif
  417. #ifdef CONFIG_ETRAX_VCS_SIM
  418. /* Set the watchdog timeout to something big. Will be removed when */
  419. /* watchdog can be disabled with command line option */
  420. move.d 0x7fffffff, $r10
  421. jsr CPU_WATCHDOG_TIMEOUT
  422. nop
  423. #endif
  424. ; Initialize registers to increase determinism
  425. move.d __bss_start, $r0
  426. movem [$r0], $r13
  427. #ifdef CONFIG_ETRAX_L2CACHE
  428. jsr l2cache_init
  429. nop
  430. #endif
  431. jump start_kernel ; Jump to start_kernel() in init/main.c.
  432. nop
  433. .data
  434. etrax_irv:
  435. .dword 0
  436. ; Variables for communication with the Axis flash map driver (axisflashmap),
  437. ; and for setting up memory in arch/cris/kernel/setup.c .
  438. ; romfs_start is set to the start of the root file system, if it exists
  439. ; in directly accessible memory (i.e. NOR Flash when booting from Flash,
  440. ; or RAM when booting directly from a network-downloaded RAM image)
  441. romfs_start:
  442. .dword 0
  443. ; romfs_length is set to the size of the root file system image, if it exists
  444. ; in directly accessible memory (see romfs_start). Otherwise it is set to 0.
  445. romfs_length:
  446. .dword 0
  447. ; romfs_in_flash is set to 1 if the root file system resides in directly
  448. ; accessible flash memory (i.e. NOR flash). It is set to 0 for RAM boot
  449. ; or NAND flash boot.
  450. romfs_in_flash:
  451. .dword 0
  452. ; nand_boot is set to 1 when the kernel has been booted from NAND flash
  453. nand_boot:
  454. .dword 0
  455. swapper_pg_dir = 0xc0002000
  456. .section ".init.data", "aw"
  457. #if defined CONFIG_ETRAXFS
  458. #include "../mach-fs/hw_settings.S"
  459. #elif defined CONFIG_CRIS_MACH_ARTPEC3
  460. #include "../mach-a3/hw_settings.S"
  461. #else
  462. #error Only ETRAXFS and ARTPEC-3 supported!
  463. #endif