head.S 5.8 KB

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