ultra.S 18 KB

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