trampoline.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. /* $Id: trampoline.S,v 1.26 2002/02/09 19:49:30 davem Exp $
  2. * trampoline.S: Jump start slave processors on sparc64.
  3. *
  4. * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  5. */
  6. #include <linux/init.h>
  7. #include <asm/head.h>
  8. #include <asm/asi.h>
  9. #include <asm/lsu.h>
  10. #include <asm/dcr.h>
  11. #include <asm/dcu.h>
  12. #include <asm/pstate.h>
  13. #include <asm/page.h>
  14. #include <asm/pgtable.h>
  15. #include <asm/spitfire.h>
  16. #include <asm/processor.h>
  17. #include <asm/thread_info.h>
  18. #include <asm/mmu.h>
  19. #include <asm/hypervisor.h>
  20. #include <asm/cpudata.h>
  21. .data
  22. .align 8
  23. call_method:
  24. .asciz "call-method"
  25. .align 8
  26. itlb_load:
  27. .asciz "SUNW,itlb-load"
  28. .align 8
  29. dtlb_load:
  30. .asciz "SUNW,dtlb-load"
  31. /* XXX __cpuinit this thing XXX */
  32. #define TRAMP_STACK_SIZE 1024
  33. .align 16
  34. tramp_stack:
  35. .skip TRAMP_STACK_SIZE
  36. __CPUINIT
  37. .align 8
  38. .globl sparc64_cpu_startup, sparc64_cpu_startup_end
  39. sparc64_cpu_startup:
  40. BRANCH_IF_SUN4V(g1, niagara_startup)
  41. BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
  42. BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
  43. ba,pt %xcc, spitfire_startup
  44. nop
  45. cheetah_plus_startup:
  46. /* Preserve OBP chosen DCU and DCR register settings. */
  47. ba,pt %xcc, cheetah_generic_startup
  48. nop
  49. cheetah_startup:
  50. mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
  51. wr %g1, %asr18
  52. sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
  53. or %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
  54. sllx %g5, 32, %g5
  55. or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
  56. stxa %g5, [%g0] ASI_DCU_CONTROL_REG
  57. membar #Sync
  58. /* fallthru */
  59. cheetah_generic_startup:
  60. mov TSB_EXTENSION_P, %g3
  61. stxa %g0, [%g3] ASI_DMMU
  62. stxa %g0, [%g3] ASI_IMMU
  63. membar #Sync
  64. mov TSB_EXTENSION_S, %g3
  65. stxa %g0, [%g3] ASI_DMMU
  66. membar #Sync
  67. mov TSB_EXTENSION_N, %g3
  68. stxa %g0, [%g3] ASI_DMMU
  69. stxa %g0, [%g3] ASI_IMMU
  70. membar #Sync
  71. /* fallthru */
  72. niagara_startup:
  73. /* Disable STICK_INT interrupts. */
  74. sethi %hi(0x80000000), %g5
  75. sllx %g5, 32, %g5
  76. wr %g5, %asr25
  77. ba,pt %xcc, startup_continue
  78. nop
  79. spitfire_startup:
  80. mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
  81. stxa %g1, [%g0] ASI_LSU_CONTROL
  82. membar #Sync
  83. startup_continue:
  84. mov %o0, %l0
  85. BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
  86. sethi %hi(0x80000000), %g2
  87. sllx %g2, 32, %g2
  88. wr %g2, 0, %tick_cmpr
  89. /* Call OBP by hand to lock KERNBASE into i/d tlbs.
  90. * We lock 2 consequetive entries if we are 'bigkernel'.
  91. */
  92. sethi %hi(prom_entry_lock), %g2
  93. 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
  94. membar #StoreLoad | #StoreStore
  95. brnz,pn %g1, 1b
  96. nop
  97. sethi %hi(p1275buf), %g2
  98. or %g2, %lo(p1275buf), %g2
  99. ldx [%g2 + 0x10], %l2
  100. add %l2, -(192 + 128), %sp
  101. flushw
  102. sethi %hi(call_method), %g2
  103. or %g2, %lo(call_method), %g2
  104. stx %g2, [%sp + 2047 + 128 + 0x00]
  105. mov 5, %g2
  106. stx %g2, [%sp + 2047 + 128 + 0x08]
  107. mov 1, %g2
  108. stx %g2, [%sp + 2047 + 128 + 0x10]
  109. sethi %hi(itlb_load), %g2
  110. or %g2, %lo(itlb_load), %g2
  111. stx %g2, [%sp + 2047 + 128 + 0x18]
  112. sethi %hi(prom_mmu_ihandle_cache), %g2
  113. lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
  114. stx %g2, [%sp + 2047 + 128 + 0x20]
  115. sethi %hi(KERNBASE), %g2
  116. stx %g2, [%sp + 2047 + 128 + 0x28]
  117. sethi %hi(kern_locked_tte_data), %g2
  118. ldx [%g2 + %lo(kern_locked_tte_data)], %g2
  119. stx %g2, [%sp + 2047 + 128 + 0x30]
  120. mov 15, %g2
  121. BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
  122. mov 63, %g2
  123. 1:
  124. stx %g2, [%sp + 2047 + 128 + 0x38]
  125. sethi %hi(p1275buf), %g2
  126. or %g2, %lo(p1275buf), %g2
  127. ldx [%g2 + 0x08], %o1
  128. call %o1
  129. add %sp, (2047 + 128), %o0
  130. sethi %hi(bigkernel), %g2
  131. lduw [%g2 + %lo(bigkernel)], %g2
  132. brz,pt %g2, do_dtlb
  133. nop
  134. sethi %hi(call_method), %g2
  135. or %g2, %lo(call_method), %g2
  136. stx %g2, [%sp + 2047 + 128 + 0x00]
  137. mov 5, %g2
  138. stx %g2, [%sp + 2047 + 128 + 0x08]
  139. mov 1, %g2
  140. stx %g2, [%sp + 2047 + 128 + 0x10]
  141. sethi %hi(itlb_load), %g2
  142. or %g2, %lo(itlb_load), %g2
  143. stx %g2, [%sp + 2047 + 128 + 0x18]
  144. sethi %hi(prom_mmu_ihandle_cache), %g2
  145. lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
  146. stx %g2, [%sp + 2047 + 128 + 0x20]
  147. sethi %hi(KERNBASE + 0x400000), %g2
  148. stx %g2, [%sp + 2047 + 128 + 0x28]
  149. sethi %hi(kern_locked_tte_data), %g2
  150. ldx [%g2 + %lo(kern_locked_tte_data)], %g2
  151. sethi %hi(0x400000), %g1
  152. add %g2, %g1, %g2
  153. stx %g2, [%sp + 2047 + 128 + 0x30]
  154. mov 14, %g2
  155. BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
  156. mov 62, %g2
  157. 1:
  158. stx %g2, [%sp + 2047 + 128 + 0x38]
  159. sethi %hi(p1275buf), %g2
  160. or %g2, %lo(p1275buf), %g2
  161. ldx [%g2 + 0x08], %o1
  162. call %o1
  163. add %sp, (2047 + 128), %o0
  164. do_dtlb:
  165. sethi %hi(call_method), %g2
  166. or %g2, %lo(call_method), %g2
  167. stx %g2, [%sp + 2047 + 128 + 0x00]
  168. mov 5, %g2
  169. stx %g2, [%sp + 2047 + 128 + 0x08]
  170. mov 1, %g2
  171. stx %g2, [%sp + 2047 + 128 + 0x10]
  172. sethi %hi(dtlb_load), %g2
  173. or %g2, %lo(dtlb_load), %g2
  174. stx %g2, [%sp + 2047 + 128 + 0x18]
  175. sethi %hi(prom_mmu_ihandle_cache), %g2
  176. lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
  177. stx %g2, [%sp + 2047 + 128 + 0x20]
  178. sethi %hi(KERNBASE), %g2
  179. stx %g2, [%sp + 2047 + 128 + 0x28]
  180. sethi %hi(kern_locked_tte_data), %g2
  181. ldx [%g2 + %lo(kern_locked_tte_data)], %g2
  182. stx %g2, [%sp + 2047 + 128 + 0x30]
  183. mov 15, %g2
  184. BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
  185. mov 63, %g2
  186. 1:
  187. stx %g2, [%sp + 2047 + 128 + 0x38]
  188. sethi %hi(p1275buf), %g2
  189. or %g2, %lo(p1275buf), %g2
  190. ldx [%g2 + 0x08], %o1
  191. call %o1
  192. add %sp, (2047 + 128), %o0
  193. sethi %hi(bigkernel), %g2
  194. lduw [%g2 + %lo(bigkernel)], %g2
  195. brz,pt %g2, do_unlock
  196. nop
  197. sethi %hi(call_method), %g2
  198. or %g2, %lo(call_method), %g2
  199. stx %g2, [%sp + 2047 + 128 + 0x00]
  200. mov 5, %g2
  201. stx %g2, [%sp + 2047 + 128 + 0x08]
  202. mov 1, %g2
  203. stx %g2, [%sp + 2047 + 128 + 0x10]
  204. sethi %hi(dtlb_load), %g2
  205. or %g2, %lo(dtlb_load), %g2
  206. stx %g2, [%sp + 2047 + 128 + 0x18]
  207. sethi %hi(prom_mmu_ihandle_cache), %g2
  208. lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
  209. stx %g2, [%sp + 2047 + 128 + 0x20]
  210. sethi %hi(KERNBASE + 0x400000), %g2
  211. stx %g2, [%sp + 2047 + 128 + 0x28]
  212. sethi %hi(kern_locked_tte_data), %g2
  213. ldx [%g2 + %lo(kern_locked_tte_data)], %g2
  214. sethi %hi(0x400000), %g1
  215. add %g2, %g1, %g2
  216. stx %g2, [%sp + 2047 + 128 + 0x30]
  217. mov 14, %g2
  218. BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
  219. mov 62, %g2
  220. 1:
  221. stx %g2, [%sp + 2047 + 128 + 0x38]
  222. sethi %hi(p1275buf), %g2
  223. or %g2, %lo(p1275buf), %g2
  224. ldx [%g2 + 0x08], %o1
  225. call %o1
  226. add %sp, (2047 + 128), %o0
  227. do_unlock:
  228. sethi %hi(prom_entry_lock), %g2
  229. stb %g0, [%g2 + %lo(prom_entry_lock)]
  230. membar #StoreStore | #StoreLoad
  231. ba,pt %xcc, after_lock_tlb
  232. nop
  233. niagara_lock_tlb:
  234. mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
  235. sethi %hi(KERNBASE), %o0
  236. clr %o1
  237. sethi %hi(kern_locked_tte_data), %o2
  238. ldx [%o2 + %lo(kern_locked_tte_data)], %o2
  239. mov HV_MMU_IMMU, %o3
  240. ta HV_FAST_TRAP
  241. mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
  242. sethi %hi(KERNBASE), %o0
  243. clr %o1
  244. sethi %hi(kern_locked_tte_data), %o2
  245. ldx [%o2 + %lo(kern_locked_tte_data)], %o2
  246. mov HV_MMU_DMMU, %o3
  247. ta HV_FAST_TRAP
  248. sethi %hi(bigkernel), %g2
  249. lduw [%g2 + %lo(bigkernel)], %g2
  250. brz,pt %g2, after_lock_tlb
  251. nop
  252. mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
  253. sethi %hi(KERNBASE + 0x400000), %o0
  254. clr %o1
  255. sethi %hi(kern_locked_tte_data), %o2
  256. ldx [%o2 + %lo(kern_locked_tte_data)], %o2
  257. sethi %hi(0x400000), %o3
  258. add %o2, %o3, %o2
  259. mov HV_MMU_IMMU, %o3
  260. ta HV_FAST_TRAP
  261. mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
  262. sethi %hi(KERNBASE + 0x400000), %o0
  263. clr %o1
  264. sethi %hi(kern_locked_tte_data), %o2
  265. ldx [%o2 + %lo(kern_locked_tte_data)], %o2
  266. sethi %hi(0x400000), %o3
  267. add %o2, %o3, %o2
  268. mov HV_MMU_DMMU, %o3
  269. ta HV_FAST_TRAP
  270. after_lock_tlb:
  271. wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
  272. wr %g0, 0, %fprs
  273. wr %g0, ASI_P, %asi
  274. mov PRIMARY_CONTEXT, %g7
  275. 661: stxa %g0, [%g7] ASI_DMMU
  276. .section .sun4v_1insn_patch, "ax"
  277. .word 661b
  278. stxa %g0, [%g7] ASI_MMU
  279. .previous
  280. membar #Sync
  281. mov SECONDARY_CONTEXT, %g7
  282. 661: stxa %g0, [%g7] ASI_DMMU
  283. .section .sun4v_1insn_patch, "ax"
  284. .word 661b
  285. stxa %g0, [%g7] ASI_MMU
  286. .previous
  287. membar #Sync
  288. /* Everything we do here, until we properly take over the
  289. * trap table, must be done with extreme care. We cannot
  290. * make any references to %g6 (current thread pointer),
  291. * %g4 (current task pointer), or %g5 (base of current cpu's
  292. * per-cpu area) until we properly take over the trap table
  293. * from the firmware and hypervisor.
  294. *
  295. * Get onto temporary stack which is in the locked kernel image.
  296. */
  297. sethi %hi(tramp_stack), %g1
  298. or %g1, %lo(tramp_stack), %g1
  299. add %g1, TRAMP_STACK_SIZE, %g1
  300. sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
  301. mov 0, %fp
  302. /* Put garbage in these registers to trap any access to them. */
  303. set 0xdeadbeef, %g4
  304. set 0xdeadbeef, %g5
  305. set 0xdeadbeef, %g6
  306. call init_irqwork_curcpu
  307. nop
  308. sethi %hi(tlb_type), %g3
  309. lduw [%g3 + %lo(tlb_type)], %g2
  310. cmp %g2, 3
  311. bne,pt %icc, 1f
  312. nop
  313. call hard_smp_processor_id
  314. nop
  315. call sun4v_register_mondo_queues
  316. nop
  317. 1: call init_cur_cpu_trap
  318. ldx [%l0], %o0
  319. /* Start using proper page size encodings in ctx register. */
  320. sethi %hi(sparc64_kern_pri_context), %g3
  321. ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
  322. mov PRIMARY_CONTEXT, %g1
  323. 661: stxa %g2, [%g1] ASI_DMMU
  324. .section .sun4v_1insn_patch, "ax"
  325. .word 661b
  326. stxa %g2, [%g1] ASI_MMU
  327. .previous
  328. membar #Sync
  329. wrpr %g0, 0, %wstate
  330. /* As a hack, put &init_thread_union into %g6.
  331. * prom_world() loads from here to restore the %asi
  332. * register.
  333. */
  334. sethi %hi(init_thread_union), %g6
  335. or %g6, %lo(init_thread_union), %g6
  336. sethi %hi(is_sun4v), %o0
  337. lduw [%o0 + %lo(is_sun4v)], %o0
  338. brz,pt %o0, 1f
  339. nop
  340. TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
  341. add %g2, TRAP_PER_CPU_FAULT_INFO, %g2
  342. stxa %g2, [%g0] ASI_SCRATCHPAD
  343. /* Compute physical address:
  344. *
  345. * paddr = kern_base + (mmfsa_vaddr - KERNBASE)
  346. */
  347. sethi %hi(KERNBASE), %g3
  348. sub %g2, %g3, %g2
  349. sethi %hi(kern_base), %g3
  350. ldx [%g3 + %lo(kern_base)], %g3
  351. add %g2, %g3, %o1
  352. sethi %hi(sparc64_ttable_tl0), %o0
  353. set prom_set_trap_table_name, %g2
  354. stx %g2, [%sp + 2047 + 128 + 0x00]
  355. mov 2, %g2
  356. stx %g2, [%sp + 2047 + 128 + 0x08]
  357. mov 0, %g2
  358. stx %g2, [%sp + 2047 + 128 + 0x10]
  359. stx %o0, [%sp + 2047 + 128 + 0x18]
  360. stx %o1, [%sp + 2047 + 128 + 0x20]
  361. sethi %hi(p1275buf), %g2
  362. or %g2, %lo(p1275buf), %g2
  363. ldx [%g2 + 0x08], %o1
  364. call %o1
  365. add %sp, (2047 + 128), %o0
  366. ba,pt %xcc, 2f
  367. nop
  368. 1: sethi %hi(sparc64_ttable_tl0), %o0
  369. set prom_set_trap_table_name, %g2
  370. stx %g2, [%sp + 2047 + 128 + 0x00]
  371. mov 1, %g2
  372. stx %g2, [%sp + 2047 + 128 + 0x08]
  373. mov 0, %g2
  374. stx %g2, [%sp + 2047 + 128 + 0x10]
  375. stx %o0, [%sp + 2047 + 128 + 0x18]
  376. sethi %hi(p1275buf), %g2
  377. or %g2, %lo(p1275buf), %g2
  378. ldx [%g2 + 0x08], %o1
  379. call %o1
  380. add %sp, (2047 + 128), %o0
  381. 2: ldx [%l0], %g6
  382. ldx [%g6 + TI_TASK], %g4
  383. mov 1, %g5
  384. sllx %g5, THREAD_SHIFT, %g5
  385. sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
  386. add %g6, %g5, %sp
  387. mov 0, %fp
  388. rdpr %pstate, %o1
  389. or %o1, PSTATE_IE, %o1
  390. wrpr %o1, 0, %pstate
  391. call smp_callin
  392. nop
  393. call cpu_idle
  394. mov 0, %o0
  395. call cpu_panic
  396. nop
  397. 1: b,a,pt %xcc, 1b
  398. .align 8
  399. sparc64_cpu_startup_end: