head.S 5.8 KB

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