head.S 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. * linux/arch/m32r/kernel/head.S
  3. *
  4. * M32R startup code.
  5. *
  6. * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata,
  7. * Hitoshi Yamamoto
  8. */
  9. #include <linux/init.h>
  10. __INIT
  11. __INITDATA
  12. .text
  13. #include <linux/linkage.h>
  14. #include <asm/segment.h>
  15. #include <asm/page.h>
  16. #include <asm/pgtable.h>
  17. #include <asm/assembler.h>
  18. #include <asm/m32r.h>
  19. #include <asm/mmu_context.h>
  20. /*
  21. * References to members of the boot_cpu_data structure.
  22. */
  23. .text
  24. .global start_kernel
  25. .global __bss_start
  26. .global _end
  27. ENTRY(stext)
  28. ENTRY(_stext)
  29. ENTRY(startup_32)
  30. /* Setup up the stack pointer */
  31. LDIMM (r0, spi_stack_top)
  32. LDIMM (r1, spu_stack_top)
  33. mvtc r0, spi
  34. mvtc r1, spu
  35. /* Initilalize PSW */
  36. ldi r0, #0x0000 /* use SPI, disable EI */
  37. mvtc r0, psw
  38. /* Set up the stack pointer */
  39. LDIMM (r0, stack_start)
  40. ld r0, @r0
  41. mvtc r0, spi
  42. /*
  43. * Clear BSS first so that there are no surprises...
  44. */
  45. #ifdef CONFIG_ISA_DUAL_ISSUE
  46. LDIMM (r2, __bss_start)
  47. LDIMM (r3, _end)
  48. sub r3, r2 ; BSS size in bytes
  49. ; R4 = BSS size in longwords (rounded down)
  50. mv r4, r3 || ldi r1, #0
  51. srli r4, #4 || addi r2, #-4
  52. beqz r4, .Lendloop1
  53. .Lloop1:
  54. #ifndef CONFIG_CHIP_M32310
  55. ; Touch memory for the no-write-allocating cache.
  56. ld r0, @(4,r2)
  57. #endif
  58. st r1, @+r2 || addi r4, #-1
  59. st r1, @+r2
  60. st r1, @+r2
  61. st r1, @+r2 || cmpeq r1, r4 ; R4 = 0?
  62. bnc .Lloop1
  63. .Lendloop1:
  64. and3 r4, r3, #15
  65. addi r2, #4
  66. beqz r4, .Lendloop2
  67. .Lloop2:
  68. stb r1, @r2 || addi r4, #-1
  69. addi r2, #1
  70. bnez r4, .Lloop2
  71. .Lendloop2:
  72. #else /* not CONFIG_ISA_DUAL_ISSUE */
  73. LDIMM (r2, __bss_start)
  74. LDIMM (r3, _end)
  75. sub r3, r2 ; BSS size in bytes
  76. mv r4, r3
  77. srli r4, #2 ; R4 = BSS size in longwords (rounded down)
  78. ldi r1, #0 ; clear R1 for longwords store
  79. addi r2, #-4 ; account for pre-inc store
  80. beqz r4, .Lendloop1 ; any more to go?
  81. .Lloop1:
  82. st r1, @+r2 ; yep, zero out another longword
  83. addi r4, #-1 ; decrement count
  84. bnez r4, .Lloop1 ; go do some more
  85. .Lendloop1:
  86. and3 r4, r3, #3 ; get no. of remaining BSS bytes to clear
  87. addi r2, #4 ; account for pre-inc store
  88. beqz r4, .Lendloop2 ; any more to go?
  89. .Lloop2:
  90. stb r1, @r2 ; yep, zero out another byte
  91. addi r2, #1 ; bump address
  92. addi r4, #-1 ; decrement count
  93. bnez r4, .Lloop2 ; go do some more
  94. .Lendloop2:
  95. #endif /* not CONFIG_ISA_DUAL_ISSUE */
  96. #if 0 /* M32R_FIXME */
  97. /*
  98. * Copy data segment from ROM to RAM.
  99. */
  100. .global ROM_D, TOP_DATA, END_DATA
  101. LDIMM (r1, ROM_D)
  102. LDIMM (r2, TOP_DATA)
  103. LDIMM (r3, END_DATA)
  104. addi r2, #-4
  105. addi r3, #-4
  106. loop1:
  107. ld r0, @r1+
  108. st r0, @+r2
  109. cmp r2, r3
  110. bc loop1
  111. #endif /* 0 */
  112. /* Jump to kernel */
  113. LDIMM (r2, start_kernel)
  114. jl r2
  115. .fillinsn
  116. 1:
  117. bra 1b ; main should never return here, but
  118. ; just in case, we know what happens.
  119. #ifdef CONFIG_SMP
  120. /*
  121. * AP startup routine
  122. */
  123. .text
  124. .global eit_vector
  125. ENTRY(startup_AP)
  126. ;; setup EVB
  127. LDIMM (r4, eit_vector)
  128. mvtc r4, cr5
  129. ;; enable MMU
  130. LDIMM (r2, init_tlb)
  131. jl r2
  132. seth r4, #high(MATM)
  133. or3 r4, r4, #low(MATM)
  134. ldi r5, #0x01
  135. st r5, @r4 ; Set MATM Reg(T bit ON)
  136. ld r6, @r4 ; MATM Check
  137. LDIMM (r5, 1f)
  138. jmp r5 ; enable MMU
  139. nop
  140. .fillinsn
  141. 1:
  142. ;; ISN check
  143. ld r6, @r4 ; MATM Check
  144. seth r4, #high(M32R_ICU_ISTS_ADDR)
  145. or3 r4, r4, #low(M32R_ICU_ISTS_ADDR)
  146. ld r5, @r4 ; Read ISTSi reg.
  147. mv r6, r5
  148. slli r5, #13 ; PIML check
  149. srli r5, #13 ;
  150. seth r4, #high(M32R_ICU_IMASK_ADDR)
  151. or3 r4, r4, #low(M32R_ICU_IMASK_ADDR)
  152. st r5, @r4 ; Write IMASKi reg.
  153. slli r6, #4 ; ISN check
  154. srli r6, #26 ;
  155. seth r4, #high(M32R_IRQ_IPI5)
  156. or3 r4, r4, #low(M32R_IRQ_IPI5)
  157. bne r4, r6, 2f ; if (ISN != CPU_BOOT_IPI) goto sleep;
  158. ;; check cpu_bootout_map and set cpu_bootin_map
  159. LDIMM (r4, cpu_bootout_map)
  160. ld r4, @r4
  161. seth r5, #high(M32R_CPUID_PORTL)
  162. or3 r5, r5, #low(M32R_CPUID_PORTL)
  163. ld r5, @r5
  164. ldi r6, #1
  165. sll r6, r5
  166. and r4, r6
  167. beqz r4, 2f
  168. LDIMM (r4, cpu_bootin_map)
  169. ld r5, @r4
  170. or r5, r6
  171. st r6, @r4
  172. ;; clear PSW
  173. ldi r4, #0
  174. mvtc r4, psw
  175. ;; setup SPI
  176. LDIMM (r4, stack_start)
  177. ld r4, @r4
  178. mvtc r4, spi
  179. ;; setup BPC (start_secondary)
  180. LDIMM (r4, start_secondary)
  181. mvtc r4, bpc
  182. rte ; goto startup_secondary
  183. nop
  184. nop
  185. .fillinsn
  186. 2:
  187. ;; disable MMU
  188. seth r4, #high(MATM)
  189. or3 r4, r4, #low(MATM)
  190. ldi r5, #0
  191. st r5, @r4 ; Set MATM Reg(T bit OFF)
  192. ld r6, @r4 ; MATM Check
  193. LDIMM (r4, 3f)
  194. seth r5, #high(__PAGE_OFFSET)
  195. or3 r5, r5, #low(__PAGE_OFFSET)
  196. not r5, r5
  197. and r4, r5
  198. jmp r4 ; disable MMU
  199. nop
  200. .fillinsn
  201. 3:
  202. ;; SLEEP and wait IPI
  203. LDIMM (r4, AP_loop)
  204. seth r5, #high(__PAGE_OFFSET)
  205. or3 r5, r5, #low(__PAGE_OFFSET)
  206. not r5, r5
  207. and r4, r5
  208. jmp r4
  209. nop
  210. nop
  211. #endif /* CONFIG_SMP */
  212. ENTRY(stack_start)
  213. .long init_thread_union+8192
  214. .long __KERNEL_DS
  215. /*
  216. * This is initialized to create a identity-mapping at 0-4M (for bootup
  217. * purposes) and another mapping of the 0-4M area at virtual address
  218. * PAGE_OFFSET.
  219. */
  220. .text
  221. #define MOUNT_ROOT_RDONLY 1
  222. #define RAMDISK_FLAGS 0 ; 1024KB
  223. #define ORIG_ROOT_DEV 0x0100 ; /dev/ram0 (major:01, minor:00)
  224. #define LOADER_TYPE 1 ; (??? - non-zero value seems
  225. ; to be needed to boot from initrd)
  226. #define COMMAND_LINE ""
  227. .section .empty_zero_page, "aw"
  228. ENTRY(empty_zero_page)
  229. .long MOUNT_ROOT_RDONLY /* offset: +0x00 */
  230. .long RAMDISK_FLAGS
  231. .long ORIG_ROOT_DEV
  232. .long LOADER_TYPE
  233. .long 0 /* INITRD_START */ /* +0x10 */
  234. .long 0 /* INITRD_SIZE */
  235. .long 0 /* CPU_CLOCK */
  236. .long 0 /* BUS_CLOCK */
  237. .long 0 /* TIMER_DIVIDE */ /* +0x20 */
  238. .balign 256,0
  239. .asciz COMMAND_LINE
  240. .byte 0
  241. .balign 4096,0,4096
  242. /*------------------------------------------------------------------------
  243. * Stack area
  244. */
  245. .section .spi
  246. ALIGN
  247. .global spi_stack_top
  248. .zero 1024
  249. spi_stack_top:
  250. .section .spu
  251. ALIGN
  252. .global spu_stack_top
  253. .zero 1024
  254. spu_stack_top:
  255. .end