ultra.S 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /* $Id: ultra.S,v 1.72 2002/02/09 19:49:31 davem Exp $
  2. * ultra.S: Don't expand these all over the place...
  3. *
  4. * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
  5. */
  6. #include <linux/config.h>
  7. #include <asm/asi.h>
  8. #include <asm/pgtable.h>
  9. #include <asm/page.h>
  10. #include <asm/spitfire.h>
  11. #include <asm/mmu_context.h>
  12. #include <asm/mmu.h>
  13. #include <asm/pil.h>
  14. #include <asm/head.h>
  15. #include <asm/thread_info.h>
  16. #include <asm/cacheflush.h>
  17. #include <asm/hypervisor.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: /* 14 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. #if (PAGE_SHIFT == 13)
  118. #define ITAG_MASK 0xfe
  119. #elif (PAGE_SHIFT == 16)
  120. #define ITAG_MASK 0x7fe
  121. #else
  122. #error unsupported PAGE_SIZE
  123. #endif
  124. .section .kprobes.text, "ax"
  125. .align 32
  126. .globl __flush_icache_page
  127. __flush_icache_page: /* %o0 = phys_page */
  128. membar #StoreStore
  129. srlx %o0, PAGE_SHIFT, %o0
  130. sethi %uhi(PAGE_OFFSET), %g1
  131. sllx %o0, PAGE_SHIFT, %o0
  132. sethi %hi(PAGE_SIZE), %g2
  133. sllx %g1, 32, %g1
  134. add %o0, %g1, %o0
  135. 1: subcc %g2, 32, %g2
  136. bne,pt %icc, 1b
  137. flush %o0 + %g2
  138. retl
  139. nop
  140. #ifdef DCACHE_ALIASING_POSSIBLE
  141. #if (PAGE_SHIFT != 13)
  142. #error only page shift of 13 is supported by dcache flush
  143. #endif
  144. #define DTAG_MASK 0x3
  145. /* This routine is Spitfire specific so the hardcoded
  146. * D-cache size and line-size are OK.
  147. */
  148. .align 64
  149. .globl __flush_dcache_page
  150. __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
  151. sethi %uhi(PAGE_OFFSET), %g1
  152. sllx %g1, 32, %g1
  153. sub %o0, %g1, %o0 ! physical address
  154. srlx %o0, 11, %o0 ! make D-cache TAG
  155. sethi %hi(1 << 14), %o2 ! D-cache size
  156. sub %o2, (1 << 5), %o2 ! D-cache line size
  157. 1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG
  158. andcc %o3, DTAG_MASK, %g0 ! Valid?
  159. be,pn %xcc, 2f ! Nope, branch
  160. andn %o3, DTAG_MASK, %o3 ! Clear valid bits
  161. cmp %o3, %o0 ! TAG match?
  162. bne,pt %xcc, 2f ! Nope, branch
  163. nop
  164. stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG
  165. membar #Sync
  166. 2: brnz,pt %o2, 1b
  167. sub %o2, (1 << 5), %o2 ! D-cache line size
  168. /* The I-cache does not snoop local stores so we
  169. * better flush that too when necessary.
  170. */
  171. brnz,pt %o1, __flush_icache_page
  172. sllx %o0, 11, %o0
  173. retl
  174. nop
  175. #endif /* DCACHE_ALIASING_POSSIBLE */
  176. .previous
  177. /* Cheetah specific versions, patched at boot time. */
  178. __cheetah_flush_tlb_mm: /* 19 insns */
  179. rdpr %pstate, %g7
  180. andn %g7, PSTATE_IE, %g2
  181. wrpr %g2, 0x0, %pstate
  182. wrpr %g0, 1, %tl
  183. mov PRIMARY_CONTEXT, %o2
  184. mov 0x40, %g3
  185. ldxa [%o2] ASI_DMMU, %g2
  186. srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o1
  187. sllx %o1, CTX_PGSZ1_NUC_SHIFT, %o1
  188. or %o0, %o1, %o0 /* Preserve nucleus page size fields */
  189. stxa %o0, [%o2] ASI_DMMU
  190. stxa %g0, [%g3] ASI_DMMU_DEMAP
  191. stxa %g0, [%g3] ASI_IMMU_DEMAP
  192. stxa %g2, [%o2] ASI_DMMU
  193. sethi %hi(KERNBASE), %o2
  194. flush %o2
  195. wrpr %g0, 0, %tl
  196. retl
  197. wrpr %g7, 0x0, %pstate
  198. __cheetah_flush_tlb_pending: /* 27 insns */
  199. /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
  200. rdpr %pstate, %g7
  201. sllx %o1, 3, %o1
  202. andn %g7, PSTATE_IE, %g2
  203. wrpr %g2, 0x0, %pstate
  204. wrpr %g0, 1, %tl
  205. mov PRIMARY_CONTEXT, %o4
  206. ldxa [%o4] ASI_DMMU, %g2
  207. srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3
  208. sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3
  209. or %o0, %o3, %o0 /* Preserve nucleus page size fields */
  210. stxa %o0, [%o4] ASI_DMMU
  211. 1: sub %o1, (1 << 3), %o1
  212. ldx [%o2 + %o1], %o3
  213. andcc %o3, 1, %g0
  214. be,pn %icc, 2f
  215. andn %o3, 1, %o3
  216. stxa %g0, [%o3] ASI_IMMU_DEMAP
  217. 2: stxa %g0, [%o3] ASI_DMMU_DEMAP
  218. membar #Sync
  219. brnz,pt %o1, 1b
  220. nop
  221. stxa %g2, [%o4] ASI_DMMU
  222. sethi %hi(KERNBASE), %o4
  223. flush %o4
  224. wrpr %g0, 0, %tl
  225. retl
  226. wrpr %g7, 0x0, %pstate
  227. #ifdef DCACHE_ALIASING_POSSIBLE
  228. __cheetah_flush_dcache_page: /* 11 insns */
  229. sethi %uhi(PAGE_OFFSET), %g1
  230. sllx %g1, 32, %g1
  231. sub %o0, %g1, %o0
  232. sethi %hi(PAGE_SIZE), %o4
  233. 1: subcc %o4, (1 << 5), %o4
  234. stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
  235. membar #Sync
  236. bne,pt %icc, 1b
  237. nop
  238. retl /* I-cache flush never needed on Cheetah, see callers. */
  239. nop
  240. #endif /* DCACHE_ALIASING_POSSIBLE */
  241. /* Hypervisor specific versions, patched at boot time. */
  242. __hypervisor_flush_tlb_mm: /* 8 insns */
  243. mov %o0, %o2 /* ARG2: mmu context */
  244. mov 0, %o0 /* ARG0: CPU lists unimplemented */
  245. mov 0, %o1 /* ARG1: CPU lists unimplemented */
  246. mov HV_MMU_ALL, %o3 /* ARG3: flags */
  247. mov HV_FAST_MMU_DEMAP_CTX, %o5
  248. ta HV_FAST_TRAP
  249. retl
  250. nop
  251. __hypervisor_flush_tlb_pending: /* 15 insns */
  252. /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
  253. sllx %o1, 3, %g1
  254. mov %o2, %g2
  255. mov %o0, %g3
  256. 1: sub %g1, (1 << 3), %g1
  257. ldx [%g2 + %g1], %o0 /* ARG0: vaddr + IMMU-bit */
  258. mov %g3, %o1 /* ARG1: mmu context */
  259. mov HV_MMU_DMMU, %o2
  260. andcc %o0, 1, %g0
  261. movne %icc, HV_MMU_ALL, %o2 /* ARG2: flags */
  262. andn %o0, 1, %o0
  263. ta HV_MMU_UNMAP_ADDR_TRAP
  264. brnz,pt %g1, 1b
  265. nop
  266. retl
  267. nop
  268. __hypervisor_flush_tlb_kernel_range: /* 14 insns */
  269. /* %o0=start, %o1=end */
  270. cmp %o0, %o1
  271. be,pn %xcc, 2f
  272. sethi %hi(PAGE_SIZE), %g3
  273. mov %o0, %g1
  274. sub %o1, %g1, %g2
  275. sub %g2, %g3, %g2
  276. 1: add %g1, %g2, %o0 /* ARG0: virtual address */
  277. mov 0, %o1 /* ARG1: mmu context */
  278. mov HV_MMU_ALL, %o2 /* ARG2: flags */
  279. ta HV_MMU_UNMAP_ADDR_TRAP
  280. brnz,pt %g2, 1b
  281. sub %g2, %g3, %g2
  282. 2: retl
  283. nop
  284. #ifdef DCACHE_ALIASING_POSSIBLE
  285. /* XXX Niagara and friends have an 8K cache, so no aliasing is
  286. * XXX possible, but nothing explicit in the Hypervisor API
  287. * XXX guarantees this.
  288. */
  289. __hypervisor_flush_dcache_page: /* 2 insns */
  290. retl
  291. nop
  292. #endif
  293. tlb_patch_one:
  294. 1: lduw [%o1], %g1
  295. stw %g1, [%o0]
  296. flush %o0
  297. subcc %o2, 1, %o2
  298. add %o1, 4, %o1
  299. bne,pt %icc, 1b
  300. add %o0, 4, %o0
  301. retl
  302. nop
  303. .globl cheetah_patch_cachetlbops
  304. cheetah_patch_cachetlbops:
  305. save %sp, -128, %sp
  306. sethi %hi(__flush_tlb_mm), %o0
  307. or %o0, %lo(__flush_tlb_mm), %o0
  308. sethi %hi(__cheetah_flush_tlb_mm), %o1
  309. or %o1, %lo(__cheetah_flush_tlb_mm), %o1
  310. call tlb_patch_one
  311. mov 19, %o2
  312. sethi %hi(__flush_tlb_pending), %o0
  313. or %o0, %lo(__flush_tlb_pending), %o0
  314. sethi %hi(__cheetah_flush_tlb_pending), %o1
  315. or %o1, %lo(__cheetah_flush_tlb_pending), %o1
  316. call tlb_patch_one
  317. mov 27, %o2
  318. #ifdef DCACHE_ALIASING_POSSIBLE
  319. sethi %hi(__flush_dcache_page), %o0
  320. or %o0, %lo(__flush_dcache_page), %o0
  321. sethi %hi(__cheetah_flush_dcache_page), %o1
  322. or %o1, %lo(__cheetah_flush_dcache_page), %o1
  323. call tlb_patch_one
  324. mov 11, %o2
  325. #endif /* DCACHE_ALIASING_POSSIBLE */
  326. ret
  327. restore
  328. #ifdef CONFIG_SMP
  329. /* These are all called by the slaves of a cross call, at
  330. * trap level 1, with interrupts fully disabled.
  331. *
  332. * Register usage:
  333. * %g5 mm->context (all tlb flushes)
  334. * %g1 address arg 1 (tlb page and range flushes)
  335. * %g7 address arg 2 (tlb range flush only)
  336. *
  337. * %g6 scratch 1
  338. * %g2 scratch 2
  339. * %g3 scratch 3
  340. * %g4 scratch 4
  341. */
  342. .align 32
  343. .globl xcall_flush_tlb_mm
  344. xcall_flush_tlb_mm: /* 18 insns */
  345. mov PRIMARY_CONTEXT, %g2
  346. ldxa [%g2] ASI_DMMU, %g3
  347. srlx %g3, CTX_PGSZ1_NUC_SHIFT, %g4
  348. sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4
  349. or %g5, %g4, %g5 /* Preserve nucleus page size fields */
  350. stxa %g5, [%g2] ASI_DMMU
  351. mov 0x40, %g4
  352. stxa %g0, [%g4] ASI_DMMU_DEMAP
  353. stxa %g0, [%g4] ASI_IMMU_DEMAP
  354. stxa %g3, [%g2] ASI_DMMU
  355. retry
  356. nop
  357. nop
  358. nop
  359. nop
  360. nop
  361. nop
  362. nop
  363. .globl xcall_flush_tlb_pending
  364. xcall_flush_tlb_pending: /* 20 insns */
  365. /* %g5=context, %g1=nr, %g7=vaddrs[] */
  366. sllx %g1, 3, %g1
  367. mov PRIMARY_CONTEXT, %g4
  368. ldxa [%g4] ASI_DMMU, %g2
  369. srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4
  370. sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4
  371. or %g5, %g4, %g5
  372. mov PRIMARY_CONTEXT, %g4
  373. stxa %g5, [%g4] ASI_DMMU
  374. 1: sub %g1, (1 << 3), %g1
  375. ldx [%g7 + %g1], %g5
  376. andcc %g5, 0x1, %g0
  377. be,pn %icc, 2f
  378. andn %g5, 0x1, %g5
  379. stxa %g0, [%g5] ASI_IMMU_DEMAP
  380. 2: stxa %g0, [%g5] ASI_DMMU_DEMAP
  381. membar #Sync
  382. brnz,pt %g1, 1b
  383. nop
  384. stxa %g2, [%g4] ASI_DMMU
  385. retry
  386. .globl xcall_flush_tlb_kernel_range
  387. xcall_flush_tlb_kernel_range: /* 22 insns */
  388. sethi %hi(PAGE_SIZE - 1), %g2
  389. or %g2, %lo(PAGE_SIZE - 1), %g2
  390. andn %g1, %g2, %g1
  391. andn %g7, %g2, %g7
  392. sub %g7, %g1, %g3
  393. add %g2, 1, %g2
  394. sub %g3, %g2, %g3
  395. or %g1, 0x20, %g1 ! Nucleus
  396. 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
  397. stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
  398. membar #Sync
  399. brnz,pt %g3, 1b
  400. sub %g3, %g2, %g3
  401. retry
  402. nop
  403. nop
  404. nop
  405. nop
  406. nop
  407. nop
  408. nop
  409. nop
  410. /* This runs in a very controlled environment, so we do
  411. * not need to worry about BH races etc.
  412. */
  413. .globl xcall_sync_tick
  414. xcall_sync_tick:
  415. 661: rdpr %pstate, %g2
  416. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  417. .section .sun4v_2insn_patch, "ax"
  418. .word 661b
  419. nop
  420. nop
  421. .previous
  422. rdpr %pil, %g2
  423. wrpr %g0, 15, %pil
  424. sethi %hi(109f), %g7
  425. b,pt %xcc, etrap_irq
  426. 109: or %g7, %lo(109b), %g7
  427. call smp_synchronize_tick_client
  428. nop
  429. clr %l6
  430. b rtrap_xcall
  431. ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
  432. /* NOTE: This is SPECIAL!! We do etrap/rtrap however
  433. * we choose to deal with the "BH's run with
  434. * %pil==15" problem (described in asm/pil.h)
  435. * by just invoking rtrap directly past where
  436. * BH's are checked for.
  437. *
  438. * We do it like this because we do not want %pil==15
  439. * lockups to prevent regs being reported.
  440. */
  441. .globl xcall_report_regs
  442. xcall_report_regs:
  443. 661: rdpr %pstate, %g2
  444. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  445. .section .sun4v_2insn_patch, "ax"
  446. .word 661b
  447. nop
  448. nop
  449. .previous
  450. rdpr %pil, %g2
  451. wrpr %g0, 15, %pil
  452. sethi %hi(109f), %g7
  453. b,pt %xcc, etrap_irq
  454. 109: or %g7, %lo(109b), %g7
  455. call __show_regs
  456. add %sp, PTREGS_OFF, %o0
  457. clr %l6
  458. /* Has to be a non-v9 branch due to the large distance. */
  459. b rtrap_xcall
  460. ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
  461. #ifdef DCACHE_ALIASING_POSSIBLE
  462. .align 32
  463. .globl xcall_flush_dcache_page_cheetah
  464. xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
  465. sethi %hi(PAGE_SIZE), %g3
  466. 1: subcc %g3, (1 << 5), %g3
  467. stxa %g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
  468. membar #Sync
  469. bne,pt %icc, 1b
  470. nop
  471. retry
  472. nop
  473. #endif /* DCACHE_ALIASING_POSSIBLE */
  474. .globl xcall_flush_dcache_page_spitfire
  475. xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
  476. %g7 == kernel page virtual address
  477. %g5 == (page->mapping != NULL) */
  478. #ifdef DCACHE_ALIASING_POSSIBLE
  479. srlx %g1, (13 - 2), %g1 ! Form tag comparitor
  480. sethi %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K
  481. sub %g3, (1 << 5), %g3 ! D$ linesize == 32
  482. 1: ldxa [%g3] ASI_DCACHE_TAG, %g2
  483. andcc %g2, 0x3, %g0
  484. be,pn %xcc, 2f
  485. andn %g2, 0x3, %g2
  486. cmp %g2, %g1
  487. bne,pt %xcc, 2f
  488. nop
  489. stxa %g0, [%g3] ASI_DCACHE_TAG
  490. membar #Sync
  491. 2: cmp %g3, 0
  492. bne,pt %xcc, 1b
  493. sub %g3, (1 << 5), %g3
  494. brz,pn %g5, 2f
  495. #endif /* DCACHE_ALIASING_POSSIBLE */
  496. sethi %hi(PAGE_SIZE), %g3
  497. 1: flush %g7
  498. subcc %g3, (1 << 5), %g3
  499. bne,pt %icc, 1b
  500. add %g7, (1 << 5), %g7
  501. 2: retry
  502. nop
  503. nop
  504. .globl __hypervisor_xcall_flush_tlb_mm
  505. __hypervisor_xcall_flush_tlb_mm: /* 18 insns */
  506. /* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */
  507. mov %o0, %g2
  508. mov %o1, %g3
  509. mov %o2, %g4
  510. mov %o3, %g1
  511. mov %o5, %g7
  512. clr %o0 /* ARG0: CPU lists unimplemented */
  513. clr %o1 /* ARG1: CPU lists unimplemented */
  514. mov %g5, %o2 /* ARG2: mmu context */
  515. mov HV_MMU_ALL, %o3 /* ARG3: flags */
  516. mov HV_FAST_MMU_DEMAP_CTX, %o5
  517. ta HV_FAST_TRAP
  518. mov %g2, %o0
  519. mov %g3, %o1
  520. mov %g4, %o2
  521. mov %g1, %o3
  522. mov %g7, %o5
  523. membar #Sync
  524. retry
  525. .globl __hypervisor_xcall_flush_tlb_pending
  526. __hypervisor_xcall_flush_tlb_pending: /* 18 insns */
  527. /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4=scratch, %g6=unusable */
  528. sllx %g1, 3, %g1
  529. mov %o0, %g2
  530. mov %o1, %g3
  531. mov %o2, %g4
  532. 1: sub %g1, (1 << 3), %g1
  533. ldx [%g7 + %g1], %o0 /* ARG0: virtual address */
  534. mov %g5, %o1 /* ARG1: mmu context */
  535. mov HV_MMU_DMMU, %o2
  536. andcc %o0, 1, %g0
  537. movne %icc, HV_MMU_ALL, %o2 /* ARG2: flags */
  538. ta HV_MMU_UNMAP_ADDR_TRAP
  539. brnz,pt %g1, 1b
  540. nop
  541. mov %g2, %o0
  542. mov %g3, %o1
  543. mov %g4, %o2
  544. membar #Sync
  545. retry
  546. .globl __hypervisor_xcall_flush_tlb_kernel_range
  547. __hypervisor_xcall_flush_tlb_kernel_range: /* 22 insns */
  548. /* %g1=start, %g7=end, g2,g3,g4,g5=scratch, g6=unusable */
  549. sethi %hi(PAGE_SIZE - 1), %g2
  550. or %g2, %lo(PAGE_SIZE - 1), %g2
  551. andn %g1, %g2, %g1
  552. andn %g7, %g2, %g7
  553. sub %g7, %g1, %g3
  554. add %g2, 1, %g2
  555. sub %g3, %g2, %g3
  556. mov %o0, %g2
  557. mov %o1, %g4
  558. mov %o2, %g5
  559. 1: add %g1, %g3, %o0 /* ARG0: virtual address */
  560. mov 0, %o1 /* ARG1: mmu context */
  561. mov HV_MMU_ALL, %o2 /* ARG2: flags */
  562. ta HV_MMU_UNMAP_ADDR_TRAP
  563. sethi %hi(PAGE_SIZE), %o2
  564. brnz,pt %g3, 1b
  565. sub %g3, %o2, %g3
  566. mov %g2, %o0
  567. mov %g4, %o1
  568. mov %g5, %o2
  569. membar #Sync
  570. retry
  571. /* These just get rescheduled to PIL vectors. */
  572. .globl xcall_call_function
  573. xcall_call_function:
  574. wr %g0, (1 << PIL_SMP_CALL_FUNC), %set_softint
  575. retry
  576. .globl xcall_receive_signal
  577. xcall_receive_signal:
  578. wr %g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint
  579. retry
  580. .globl xcall_capture
  581. xcall_capture:
  582. wr %g0, (1 << PIL_SMP_CAPTURE), %set_softint
  583. retry
  584. #endif /* CONFIG_SMP */
  585. .globl hypervisor_patch_cachetlbops
  586. hypervisor_patch_cachetlbops:
  587. save %sp, -128, %sp
  588. sethi %hi(__flush_tlb_mm), %o0
  589. or %o0, %lo(__flush_tlb_mm), %o0
  590. sethi %hi(__hypervisor_flush_tlb_mm), %o1
  591. or %o1, %lo(__hypervisor_flush_tlb_mm), %o1
  592. call tlb_patch_one
  593. mov 8, %o2
  594. sethi %hi(__flush_tlb_pending), %o0
  595. or %o0, %lo(__flush_tlb_pending), %o0
  596. sethi %hi(__hypervisor_flush_tlb_pending), %o1
  597. or %o1, %lo(__hypervisor_flush_tlb_pending), %o1
  598. call tlb_patch_one
  599. mov 15, %o2
  600. sethi %hi(__flush_tlb_kernel_range), %o0
  601. or %o0, %lo(__flush_tlb_kernel_range), %o0
  602. sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1
  603. or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1
  604. call tlb_patch_one
  605. mov 14, %o2
  606. #ifdef DCACHE_ALIASING_POSSIBLE
  607. sethi %hi(__flush_dcache_page), %o0
  608. or %o0, %lo(__flush_dcache_page), %o0
  609. sethi %hi(__hypervisor_flush_dcache_page), %o1
  610. or %o1, %lo(__hypervisor_flush_dcache_page), %o1
  611. call tlb_patch_one
  612. mov 2, %o2
  613. #endif /* DCACHE_ALIASING_POSSIBLE */
  614. #ifdef CONFIG_SMP
  615. sethi %hi(xcall_flush_tlb_mm), %o0
  616. or %o0, %lo(xcall_flush_tlb_mm), %o0
  617. sethi %hi(__hypervisor_xcall_flush_tlb_mm), %o1
  618. or %o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1
  619. call tlb_patch_one
  620. mov 18, %o2
  621. sethi %hi(xcall_flush_tlb_pending), %o0
  622. or %o0, %lo(xcall_flush_tlb_pending), %o0
  623. sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1
  624. or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1
  625. call tlb_patch_one
  626. mov 18, %o2
  627. sethi %hi(xcall_flush_tlb_kernel_range), %o0
  628. or %o0, %lo(xcall_flush_tlb_kernel_range), %o0
  629. sethi %hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1
  630. or %o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1
  631. call tlb_patch_one
  632. mov 22, %o2
  633. #endif /* CONFIG_SMP */
  634. ret
  635. restore