ultra.S 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. /*
  2. * ultra.S: Don't expand these all over the place...
  3. *
  4. * Copyright (C) 1997, 2000, 2008 David S. Miller (davem@davemloft.net)
  5. */
  6. #include <asm/asi.h>
  7. #include <asm/pgtable.h>
  8. #include <asm/page.h>
  9. #include <asm/spitfire.h>
  10. #include <asm/mmu_context.h>
  11. #include <asm/mmu.h>
  12. #include <asm/pil.h>
  13. #include <asm/head.h>
  14. #include <asm/thread_info.h>
  15. #include <asm/cacheflush.h>
  16. #include <asm/hypervisor.h>
  17. #include <asm/cpudata.h>
  18. /* Basically, most of the Spitfire vs. Cheetah madness
  19. * has to do with the fact that Cheetah does not support
  20. * IMMU flushes out of the secondary context. Someone needs
  21. * to throw a south lake birthday party for the folks
  22. * in Microelectronics who refused to fix this shit.
  23. */
  24. /* This file is meant to be read efficiently by the CPU, not humans.
  25. * Staraj sie tego nikomu nie pierdolnac...
  26. */
  27. .text
  28. .align 32
  29. .globl __flush_tlb_mm
  30. __flush_tlb_mm: /* 18 insns */
  31. /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
  32. ldxa [%o1] ASI_DMMU, %g2
  33. cmp %g2, %o0
  34. bne,pn %icc, __spitfire_flush_tlb_mm_slow
  35. mov 0x50, %g3
  36. stxa %g0, [%g3] ASI_DMMU_DEMAP
  37. stxa %g0, [%g3] ASI_IMMU_DEMAP
  38. sethi %hi(KERNBASE), %g3
  39. flush %g3
  40. retl
  41. nop
  42. nop
  43. nop
  44. nop
  45. nop
  46. nop
  47. nop
  48. nop
  49. nop
  50. nop
  51. .align 32
  52. .globl __flush_tlb_pending
  53. __flush_tlb_pending: /* 26 insns */
  54. /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
  55. rdpr %pstate, %g7
  56. sllx %o1, 3, %o1
  57. andn %g7, PSTATE_IE, %g2
  58. wrpr %g2, %pstate
  59. mov SECONDARY_CONTEXT, %o4
  60. ldxa [%o4] ASI_DMMU, %g2
  61. stxa %o0, [%o4] ASI_DMMU
  62. 1: sub %o1, (1 << 3), %o1
  63. ldx [%o2 + %o1], %o3
  64. andcc %o3, 1, %g0
  65. andn %o3, 1, %o3
  66. be,pn %icc, 2f
  67. or %o3, 0x10, %o3
  68. stxa %g0, [%o3] ASI_IMMU_DEMAP
  69. 2: stxa %g0, [%o3] ASI_DMMU_DEMAP
  70. membar #Sync
  71. brnz,pt %o1, 1b
  72. nop
  73. stxa %g2, [%o4] ASI_DMMU
  74. sethi %hi(KERNBASE), %o4
  75. flush %o4
  76. retl
  77. wrpr %g7, 0x0, %pstate
  78. nop
  79. nop
  80. nop
  81. nop
  82. .align 32
  83. .globl __flush_tlb_kernel_range
  84. __flush_tlb_kernel_range: /* 16 insns */
  85. /* %o0=start, %o1=end */
  86. cmp %o0, %o1
  87. be,pn %xcc, 2f
  88. sethi %hi(PAGE_SIZE), %o4
  89. sub %o1, %o0, %o3
  90. sub %o3, %o4, %o3
  91. or %o0, 0x20, %o0 ! Nucleus
  92. 1: stxa %g0, [%o0 + %o3] ASI_DMMU_DEMAP
  93. stxa %g0, [%o0 + %o3] ASI_IMMU_DEMAP
  94. membar #Sync
  95. brnz,pt %o3, 1b
  96. sub %o3, %o4, %o3
  97. 2: sethi %hi(KERNBASE), %o3
  98. flush %o3
  99. retl
  100. nop
  101. nop
  102. __spitfire_flush_tlb_mm_slow:
  103. rdpr %pstate, %g1
  104. wrpr %g1, PSTATE_IE, %pstate
  105. stxa %o0, [%o1] ASI_DMMU
  106. stxa %g0, [%g3] ASI_DMMU_DEMAP
  107. stxa %g0, [%g3] ASI_IMMU_DEMAP
  108. flush %g6
  109. stxa %g2, [%o1] ASI_DMMU
  110. sethi %hi(KERNBASE), %o1
  111. flush %o1
  112. retl
  113. wrpr %g1, 0, %pstate
  114. /*
  115. * The following code flushes one page_size worth.
  116. */
  117. .section .kprobes.text, "ax"
  118. .align 32
  119. .globl __flush_icache_page
  120. __flush_icache_page: /* %o0 = phys_page */
  121. srlx %o0, PAGE_SHIFT, %o0
  122. sethi %uhi(PAGE_OFFSET), %g1
  123. sllx %o0, PAGE_SHIFT, %o0
  124. sethi %hi(PAGE_SIZE), %g2
  125. sllx %g1, 32, %g1
  126. add %o0, %g1, %o0
  127. 1: subcc %g2, 32, %g2
  128. bne,pt %icc, 1b
  129. flush %o0 + %g2
  130. retl
  131. nop
  132. #ifdef DCACHE_ALIASING_POSSIBLE
  133. #if (PAGE_SHIFT != 13)
  134. #error only page shift of 13 is supported by dcache flush
  135. #endif
  136. #define DTAG_MASK 0x3
  137. /* This routine is Spitfire specific so the hardcoded
  138. * D-cache size and line-size are OK.
  139. */
  140. .align 64
  141. .globl __flush_dcache_page
  142. __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
  143. sethi %uhi(PAGE_OFFSET), %g1
  144. sllx %g1, 32, %g1
  145. sub %o0, %g1, %o0 ! physical address
  146. srlx %o0, 11, %o0 ! make D-cache TAG
  147. sethi %hi(1 << 14), %o2 ! D-cache size
  148. sub %o2, (1 << 5), %o2 ! D-cache line size
  149. 1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG
  150. andcc %o3, DTAG_MASK, %g0 ! Valid?
  151. be,pn %xcc, 2f ! Nope, branch
  152. andn %o3, DTAG_MASK, %o3 ! Clear valid bits
  153. cmp %o3, %o0 ! TAG match?
  154. bne,pt %xcc, 2f ! Nope, branch
  155. nop
  156. stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG
  157. membar #Sync
  158. 2: brnz,pt %o2, 1b
  159. sub %o2, (1 << 5), %o2 ! D-cache line size
  160. /* The I-cache does not snoop local stores so we
  161. * better flush that too when necessary.
  162. */
  163. brnz,pt %o1, __flush_icache_page
  164. sllx %o0, 11, %o0
  165. retl
  166. nop
  167. #endif /* DCACHE_ALIASING_POSSIBLE */
  168. .previous
  169. /* Cheetah specific versions, patched at boot time. */
  170. __cheetah_flush_tlb_mm: /* 19 insns */
  171. rdpr %pstate, %g7
  172. andn %g7, PSTATE_IE, %g2
  173. wrpr %g2, 0x0, %pstate
  174. wrpr %g0, 1, %tl
  175. mov PRIMARY_CONTEXT, %o2
  176. mov 0x40, %g3
  177. ldxa [%o2] ASI_DMMU, %g2
  178. srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o1
  179. sllx %o1, CTX_PGSZ1_NUC_SHIFT, %o1
  180. or %o0, %o1, %o0 /* Preserve nucleus page size fields */
  181. stxa %o0, [%o2] ASI_DMMU
  182. stxa %g0, [%g3] ASI_DMMU_DEMAP
  183. stxa %g0, [%g3] ASI_IMMU_DEMAP
  184. stxa %g2, [%o2] ASI_DMMU
  185. sethi %hi(KERNBASE), %o2
  186. flush %o2
  187. wrpr %g0, 0, %tl
  188. retl
  189. wrpr %g7, 0x0, %pstate
  190. __cheetah_flush_tlb_pending: /* 27 insns */
  191. /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
  192. rdpr %pstate, %g7
  193. sllx %o1, 3, %o1
  194. andn %g7, PSTATE_IE, %g2
  195. wrpr %g2, 0x0, %pstate
  196. wrpr %g0, 1, %tl
  197. mov PRIMARY_CONTEXT, %o4
  198. ldxa [%o4] ASI_DMMU, %g2
  199. srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3
  200. sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3
  201. or %o0, %o3, %o0 /* Preserve nucleus page size fields */
  202. stxa %o0, [%o4] ASI_DMMU
  203. 1: sub %o1, (1 << 3), %o1
  204. ldx [%o2 + %o1], %o3
  205. andcc %o3, 1, %g0
  206. be,pn %icc, 2f
  207. andn %o3, 1, %o3
  208. stxa %g0, [%o3] ASI_IMMU_DEMAP
  209. 2: stxa %g0, [%o3] ASI_DMMU_DEMAP
  210. membar #Sync
  211. brnz,pt %o1, 1b
  212. nop
  213. stxa %g2, [%o4] ASI_DMMU
  214. sethi %hi(KERNBASE), %o4
  215. flush %o4
  216. wrpr %g0, 0, %tl
  217. retl
  218. wrpr %g7, 0x0, %pstate
  219. #ifdef DCACHE_ALIASING_POSSIBLE
  220. __cheetah_flush_dcache_page: /* 11 insns */
  221. sethi %uhi(PAGE_OFFSET), %g1
  222. sllx %g1, 32, %g1
  223. sub %o0, %g1, %o0
  224. sethi %hi(PAGE_SIZE), %o4
  225. 1: subcc %o4, (1 << 5), %o4
  226. stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
  227. membar #Sync
  228. bne,pt %icc, 1b
  229. nop
  230. retl /* I-cache flush never needed on Cheetah, see callers. */
  231. nop
  232. #endif /* DCACHE_ALIASING_POSSIBLE */
  233. /* Hypervisor specific versions, patched at boot time. */
  234. __hypervisor_tlb_tl0_error:
  235. save %sp, -192, %sp
  236. mov %i0, %o0
  237. call hypervisor_tlbop_error
  238. mov %i1, %o1
  239. ret
  240. restore
  241. __hypervisor_flush_tlb_mm: /* 10 insns */
  242. mov %o0, %o2 /* ARG2: mmu context */
  243. mov 0, %o0 /* ARG0: CPU lists unimplemented */
  244. mov 0, %o1 /* ARG1: CPU lists unimplemented */
  245. mov HV_MMU_ALL, %o3 /* ARG3: flags */
  246. mov HV_FAST_MMU_DEMAP_CTX, %o5
  247. ta HV_FAST_TRAP
  248. brnz,pn %o0, __hypervisor_tlb_tl0_error
  249. mov HV_FAST_MMU_DEMAP_CTX, %o1
  250. retl
  251. nop
  252. __hypervisor_flush_tlb_pending: /* 16 insns */
  253. /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
  254. sllx %o1, 3, %g1
  255. mov %o2, %g2
  256. mov %o0, %g3
  257. 1: sub %g1, (1 << 3), %g1
  258. ldx [%g2 + %g1], %o0 /* ARG0: vaddr + IMMU-bit */
  259. mov %g3, %o1 /* ARG1: mmu context */
  260. mov HV_MMU_ALL, %o2 /* ARG2: flags */
  261. srlx %o0, PAGE_SHIFT, %o0
  262. sllx %o0, PAGE_SHIFT, %o0
  263. ta HV_MMU_UNMAP_ADDR_TRAP
  264. brnz,pn %o0, __hypervisor_tlb_tl0_error
  265. mov HV_MMU_UNMAP_ADDR_TRAP, %o1
  266. brnz,pt %g1, 1b
  267. nop
  268. retl
  269. nop
  270. __hypervisor_flush_tlb_kernel_range: /* 16 insns */
  271. /* %o0=start, %o1=end */
  272. cmp %o0, %o1
  273. be,pn %xcc, 2f
  274. sethi %hi(PAGE_SIZE), %g3
  275. mov %o0, %g1
  276. sub %o1, %g1, %g2
  277. sub %g2, %g3, %g2
  278. 1: add %g1, %g2, %o0 /* ARG0: virtual address */
  279. mov 0, %o1 /* ARG1: mmu context */
  280. mov HV_MMU_ALL, %o2 /* ARG2: flags */
  281. ta HV_MMU_UNMAP_ADDR_TRAP
  282. brnz,pn %o0, __hypervisor_tlb_tl0_error
  283. mov HV_MMU_UNMAP_ADDR_TRAP, %o1
  284. brnz,pt %g2, 1b
  285. sub %g2, %g3, %g2
  286. 2: retl
  287. nop
  288. #ifdef DCACHE_ALIASING_POSSIBLE
  289. /* XXX Niagara and friends have an 8K cache, so no aliasing is
  290. * XXX possible, but nothing explicit in the Hypervisor API
  291. * XXX guarantees this.
  292. */
  293. __hypervisor_flush_dcache_page: /* 2 insns */
  294. retl
  295. nop
  296. #endif
  297. tlb_patch_one:
  298. 1: lduw [%o1], %g1
  299. stw %g1, [%o0]
  300. flush %o0
  301. subcc %o2, 1, %o2
  302. add %o1, 4, %o1
  303. bne,pt %icc, 1b
  304. add %o0, 4, %o0
  305. retl
  306. nop
  307. .globl cheetah_patch_cachetlbops
  308. cheetah_patch_cachetlbops:
  309. save %sp, -128, %sp
  310. sethi %hi(__flush_tlb_mm), %o0
  311. or %o0, %lo(__flush_tlb_mm), %o0
  312. sethi %hi(__cheetah_flush_tlb_mm), %o1
  313. or %o1, %lo(__cheetah_flush_tlb_mm), %o1
  314. call tlb_patch_one
  315. mov 19, %o2
  316. sethi %hi(__flush_tlb_pending), %o0
  317. or %o0, %lo(__flush_tlb_pending), %o0
  318. sethi %hi(__cheetah_flush_tlb_pending), %o1
  319. or %o1, %lo(__cheetah_flush_tlb_pending), %o1
  320. call tlb_patch_one
  321. mov 27, %o2
  322. #ifdef DCACHE_ALIASING_POSSIBLE
  323. sethi %hi(__flush_dcache_page), %o0
  324. or %o0, %lo(__flush_dcache_page), %o0
  325. sethi %hi(__cheetah_flush_dcache_page), %o1
  326. or %o1, %lo(__cheetah_flush_dcache_page), %o1
  327. call tlb_patch_one
  328. mov 11, %o2
  329. #endif /* DCACHE_ALIASING_POSSIBLE */
  330. ret
  331. restore
  332. #ifdef CONFIG_SMP
  333. /* These are all called by the slaves of a cross call, at
  334. * trap level 1, with interrupts fully disabled.
  335. *
  336. * Register usage:
  337. * %g5 mm->context (all tlb flushes)
  338. * %g1 address arg 1 (tlb page and range flushes)
  339. * %g7 address arg 2 (tlb range flush only)
  340. *
  341. * %g6 scratch 1
  342. * %g2 scratch 2
  343. * %g3 scratch 3
  344. * %g4 scratch 4
  345. */
  346. .align 32
  347. .globl xcall_flush_tlb_mm
  348. xcall_flush_tlb_mm: /* 21 insns */
  349. mov PRIMARY_CONTEXT, %g2
  350. ldxa [%g2] ASI_DMMU, %g3
  351. srlx %g3, CTX_PGSZ1_NUC_SHIFT, %g4
  352. sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4
  353. or %g5, %g4, %g5 /* Preserve nucleus page size fields */
  354. stxa %g5, [%g2] ASI_DMMU
  355. mov 0x40, %g4
  356. stxa %g0, [%g4] ASI_DMMU_DEMAP
  357. stxa %g0, [%g4] ASI_IMMU_DEMAP
  358. stxa %g3, [%g2] ASI_DMMU
  359. retry
  360. nop
  361. nop
  362. nop
  363. nop
  364. nop
  365. nop
  366. nop
  367. nop
  368. nop
  369. nop
  370. .globl xcall_flush_tlb_pending
  371. xcall_flush_tlb_pending: /* 21 insns */
  372. /* %g5=context, %g1=nr, %g7=vaddrs[] */
  373. sllx %g1, 3, %g1
  374. mov PRIMARY_CONTEXT, %g4
  375. ldxa [%g4] ASI_DMMU, %g2
  376. srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4
  377. sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4
  378. or %g5, %g4, %g5
  379. mov PRIMARY_CONTEXT, %g4
  380. stxa %g5, [%g4] ASI_DMMU
  381. 1: sub %g1, (1 << 3), %g1
  382. ldx [%g7 + %g1], %g5
  383. andcc %g5, 0x1, %g0
  384. be,pn %icc, 2f
  385. andn %g5, 0x1, %g5
  386. stxa %g0, [%g5] ASI_IMMU_DEMAP
  387. 2: stxa %g0, [%g5] ASI_DMMU_DEMAP
  388. membar #Sync
  389. brnz,pt %g1, 1b
  390. nop
  391. stxa %g2, [%g4] ASI_DMMU
  392. retry
  393. nop
  394. .globl xcall_flush_tlb_kernel_range
  395. xcall_flush_tlb_kernel_range: /* 25 insns */
  396. sethi %hi(PAGE_SIZE - 1), %g2
  397. or %g2, %lo(PAGE_SIZE - 1), %g2
  398. andn %g1, %g2, %g1
  399. andn %g7, %g2, %g7
  400. sub %g7, %g1, %g3
  401. add %g2, 1, %g2
  402. sub %g3, %g2, %g3
  403. or %g1, 0x20, %g1 ! Nucleus
  404. 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
  405. stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
  406. membar #Sync
  407. brnz,pt %g3, 1b
  408. sub %g3, %g2, %g3
  409. retry
  410. nop
  411. nop
  412. nop
  413. nop
  414. nop
  415. nop
  416. nop
  417. nop
  418. nop
  419. nop
  420. nop
  421. /* This runs in a very controlled environment, so we do
  422. * not need to worry about BH races etc.
  423. */
  424. .globl xcall_sync_tick
  425. xcall_sync_tick:
  426. 661: rdpr %pstate, %g2
  427. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  428. .section .sun4v_2insn_patch, "ax"
  429. .word 661b
  430. nop
  431. nop
  432. .previous
  433. rdpr %pil, %g2
  434. wrpr %g0, PIL_NORMAL_MAX, %pil
  435. sethi %hi(109f), %g7
  436. b,pt %xcc, etrap_irq
  437. 109: or %g7, %lo(109b), %g7
  438. #ifdef CONFIG_TRACE_IRQFLAGS
  439. call trace_hardirqs_off
  440. nop
  441. #endif
  442. call smp_synchronize_tick_client
  443. nop
  444. b rtrap_xcall
  445. ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
  446. .globl xcall_fetch_glob_regs
  447. xcall_fetch_glob_regs:
  448. sethi %hi(global_reg_snapshot), %g1
  449. or %g1, %lo(global_reg_snapshot), %g1
  450. __GET_CPUID(%g2)
  451. sllx %g2, 6, %g3
  452. add %g1, %g3, %g1
  453. rdpr %tstate, %g7
  454. stx %g7, [%g1 + GR_SNAP_TSTATE]
  455. rdpr %tpc, %g7
  456. stx %g7, [%g1 + GR_SNAP_TPC]
  457. rdpr %tnpc, %g7
  458. stx %g7, [%g1 + GR_SNAP_TNPC]
  459. stx %o7, [%g1 + GR_SNAP_O7]
  460. stx %i7, [%g1 + GR_SNAP_I7]
  461. /* Don't try this at home kids... */
  462. rdpr %cwp, %g2
  463. sub %g2, 1, %g7
  464. wrpr %g7, %cwp
  465. mov %i7, %g7
  466. wrpr %g2, %cwp
  467. stx %g7, [%g1 + GR_SNAP_RPC]
  468. sethi %hi(trap_block), %g7
  469. or %g7, %lo(trap_block), %g7
  470. sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2
  471. add %g7, %g2, %g7
  472. ldx [%g7 + TRAP_PER_CPU_THREAD], %g3
  473. stx %g3, [%g1 + GR_SNAP_THREAD]
  474. retry
  475. #ifdef DCACHE_ALIASING_POSSIBLE
  476. .align 32
  477. .globl xcall_flush_dcache_page_cheetah
  478. xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
  479. sethi %hi(PAGE_SIZE), %g3
  480. 1: subcc %g3, (1 << 5), %g3
  481. stxa %g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
  482. membar #Sync
  483. bne,pt %icc, 1b
  484. nop
  485. retry
  486. nop
  487. #endif /* DCACHE_ALIASING_POSSIBLE */
  488. .globl xcall_flush_dcache_page_spitfire
  489. xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
  490. %g7 == kernel page virtual address
  491. %g5 == (page->mapping != NULL) */
  492. #ifdef DCACHE_ALIASING_POSSIBLE
  493. srlx %g1, (13 - 2), %g1 ! Form tag comparitor
  494. sethi %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K
  495. sub %g3, (1 << 5), %g3 ! D$ linesize == 32
  496. 1: ldxa [%g3] ASI_DCACHE_TAG, %g2
  497. andcc %g2, 0x3, %g0
  498. be,pn %xcc, 2f
  499. andn %g2, 0x3, %g2
  500. cmp %g2, %g1
  501. bne,pt %xcc, 2f
  502. nop
  503. stxa %g0, [%g3] ASI_DCACHE_TAG
  504. membar #Sync
  505. 2: cmp %g3, 0
  506. bne,pt %xcc, 1b
  507. sub %g3, (1 << 5), %g3
  508. brz,pn %g5, 2f
  509. #endif /* DCACHE_ALIASING_POSSIBLE */
  510. sethi %hi(PAGE_SIZE), %g3
  511. 1: flush %g7
  512. subcc %g3, (1 << 5), %g3
  513. bne,pt %icc, 1b
  514. add %g7, (1 << 5), %g7
  515. 2: retry
  516. nop
  517. nop
  518. /* %g5: error
  519. * %g6: tlb op
  520. */
  521. __hypervisor_tlb_xcall_error:
  522. mov %g5, %g4
  523. mov %g6, %g5
  524. ba,pt %xcc, etrap
  525. rd %pc, %g7
  526. mov %l4, %o0
  527. call hypervisor_tlbop_error_xcall
  528. mov %l5, %o1
  529. ba,a,pt %xcc, rtrap
  530. .globl __hypervisor_xcall_flush_tlb_mm
  531. __hypervisor_xcall_flush_tlb_mm: /* 21 insns */
  532. /* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */
  533. mov %o0, %g2
  534. mov %o1, %g3
  535. mov %o2, %g4
  536. mov %o3, %g1
  537. mov %o5, %g7
  538. clr %o0 /* ARG0: CPU lists unimplemented */
  539. clr %o1 /* ARG1: CPU lists unimplemented */
  540. mov %g5, %o2 /* ARG2: mmu context */
  541. mov HV_MMU_ALL, %o3 /* ARG3: flags */
  542. mov HV_FAST_MMU_DEMAP_CTX, %o5
  543. ta HV_FAST_TRAP
  544. mov HV_FAST_MMU_DEMAP_CTX, %g6
  545. brnz,pn %o0, __hypervisor_tlb_xcall_error
  546. mov %o0, %g5
  547. mov %g2, %o0
  548. mov %g3, %o1
  549. mov %g4, %o2
  550. mov %g1, %o3
  551. mov %g7, %o5
  552. membar #Sync
  553. retry
  554. .globl __hypervisor_xcall_flush_tlb_pending
  555. __hypervisor_xcall_flush_tlb_pending: /* 21 insns */
  556. /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */
  557. sllx %g1, 3, %g1
  558. mov %o0, %g2
  559. mov %o1, %g3
  560. mov %o2, %g4
  561. 1: sub %g1, (1 << 3), %g1
  562. ldx [%g7 + %g1], %o0 /* ARG0: virtual address */
  563. mov %g5, %o1 /* ARG1: mmu context */
  564. mov HV_MMU_ALL, %o2 /* ARG2: flags */
  565. srlx %o0, PAGE_SHIFT, %o0
  566. sllx %o0, PAGE_SHIFT, %o0
  567. ta HV_MMU_UNMAP_ADDR_TRAP
  568. mov HV_MMU_UNMAP_ADDR_TRAP, %g6
  569. brnz,a,pn %o0, __hypervisor_tlb_xcall_error
  570. mov %o0, %g5
  571. brnz,pt %g1, 1b
  572. nop
  573. mov %g2, %o0
  574. mov %g3, %o1
  575. mov %g4, %o2
  576. membar #Sync
  577. retry
  578. .globl __hypervisor_xcall_flush_tlb_kernel_range
  579. __hypervisor_xcall_flush_tlb_kernel_range: /* 25 insns */
  580. /* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */
  581. sethi %hi(PAGE_SIZE - 1), %g2
  582. or %g2, %lo(PAGE_SIZE - 1), %g2
  583. andn %g1, %g2, %g1
  584. andn %g7, %g2, %g7
  585. sub %g7, %g1, %g3
  586. add %g2, 1, %g2
  587. sub %g3, %g2, %g3
  588. mov %o0, %g2
  589. mov %o1, %g4
  590. mov %o2, %g7
  591. 1: add %g1, %g3, %o0 /* ARG0: virtual address */
  592. mov 0, %o1 /* ARG1: mmu context */
  593. mov HV_MMU_ALL, %o2 /* ARG2: flags */
  594. ta HV_MMU_UNMAP_ADDR_TRAP
  595. mov HV_MMU_UNMAP_ADDR_TRAP, %g6
  596. brnz,pn %o0, __hypervisor_tlb_xcall_error
  597. mov %o0, %g5
  598. sethi %hi(PAGE_SIZE), %o2
  599. brnz,pt %g3, 1b
  600. sub %g3, %o2, %g3
  601. mov %g2, %o0
  602. mov %g4, %o1
  603. mov %g7, %o2
  604. membar #Sync
  605. retry
  606. /* These just get rescheduled to PIL vectors. */
  607. .globl xcall_call_function
  608. xcall_call_function:
  609. wr %g0, (1 << PIL_SMP_CALL_FUNC), %set_softint
  610. retry
  611. .globl xcall_call_function_single
  612. xcall_call_function_single:
  613. wr %g0, (1 << PIL_SMP_CALL_FUNC_SNGL), %set_softint
  614. retry
  615. .globl xcall_receive_signal
  616. xcall_receive_signal:
  617. wr %g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint
  618. retry
  619. .globl xcall_capture
  620. xcall_capture:
  621. wr %g0, (1 << PIL_SMP_CAPTURE), %set_softint
  622. retry
  623. .globl xcall_new_mmu_context_version
  624. xcall_new_mmu_context_version:
  625. wr %g0, (1 << PIL_SMP_CTX_NEW_VERSION), %set_softint
  626. retry
  627. #ifdef CONFIG_KGDB
  628. .globl xcall_kgdb_capture
  629. xcall_kgdb_capture:
  630. wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint
  631. retry
  632. #endif
  633. #endif /* CONFIG_SMP */
  634. .globl hypervisor_patch_cachetlbops
  635. hypervisor_patch_cachetlbops:
  636. save %sp, -128, %sp
  637. sethi %hi(__flush_tlb_mm), %o0
  638. or %o0, %lo(__flush_tlb_mm), %o0
  639. sethi %hi(__hypervisor_flush_tlb_mm), %o1
  640. or %o1, %lo(__hypervisor_flush_tlb_mm), %o1
  641. call tlb_patch_one
  642. mov 10, %o2
  643. sethi %hi(__flush_tlb_pending), %o0
  644. or %o0, %lo(__flush_tlb_pending), %o0
  645. sethi %hi(__hypervisor_flush_tlb_pending), %o1
  646. or %o1, %lo(__hypervisor_flush_tlb_pending), %o1
  647. call tlb_patch_one
  648. mov 16, %o2
  649. sethi %hi(__flush_tlb_kernel_range), %o0
  650. or %o0, %lo(__flush_tlb_kernel_range), %o0
  651. sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1
  652. or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1
  653. call tlb_patch_one
  654. mov 16, %o2
  655. #ifdef DCACHE_ALIASING_POSSIBLE
  656. sethi %hi(__flush_dcache_page), %o0
  657. or %o0, %lo(__flush_dcache_page), %o0
  658. sethi %hi(__hypervisor_flush_dcache_page), %o1
  659. or %o1, %lo(__hypervisor_flush_dcache_page), %o1
  660. call tlb_patch_one
  661. mov 2, %o2
  662. #endif /* DCACHE_ALIASING_POSSIBLE */
  663. #ifdef CONFIG_SMP
  664. sethi %hi(xcall_flush_tlb_mm), %o0
  665. or %o0, %lo(xcall_flush_tlb_mm), %o0
  666. sethi %hi(__hypervisor_xcall_flush_tlb_mm), %o1
  667. or %o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1
  668. call tlb_patch_one
  669. mov 21, %o2
  670. sethi %hi(xcall_flush_tlb_pending), %o0
  671. or %o0, %lo(xcall_flush_tlb_pending), %o0
  672. sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1
  673. or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1
  674. call tlb_patch_one
  675. mov 21, %o2
  676. sethi %hi(xcall_flush_tlb_kernel_range), %o0
  677. or %o0, %lo(xcall_flush_tlb_kernel_range), %o0
  678. sethi %hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1
  679. or %o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1
  680. call tlb_patch_one
  681. mov 25, %o2
  682. #endif /* CONFIG_SMP */
  683. ret
  684. restore