head.S 5.8 KB

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