ultra.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:16k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: ultra.S,v 1.70 2001/11/29 16:42:10 kanoj 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. /* Basically, all this madness has to do with the
  13.  * fact that Cheetah does not support IMMU flushes
  14.  * out of the secondary context.  Someone needs to
  15.  * throw a south lake birthday party for the folks
  16.  * in Microelectronics who refused to fix this shit.
  17.  */
  18. #define BRANCH_IF_CHEETAH(tmp1, tmp2, label)
  19. rdpr %ver, %tmp1;
  20. sethi %hi(0x003e0014), %tmp2;
  21. srlx %tmp1, 32, %tmp1;
  22. or %tmp2, %lo(0x003e0014), %tmp2;
  23. cmp %tmp1, %tmp2;
  24. be,pn %icc, label;
  25.  nop;
  26. nop;
  27. /* This file is meant to be read efficiently by the CPU, not humans.
  28.  * Staraj sie tego nikomu nie pierdolnac...
  29.  */
  30. .text
  31. .align 32
  32. .globl __flush_tlb_page, __flush_tlb_mm, __flush_tlb_range
  33. __flush_tlb_page: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=page&PAGE_MASK, %o2=SECONDARY_CONTEXT */
  34. /*IC1*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_page)
  35. __spitfire_flush_tlb_page:
  36. /*IC2*/ ldxa [%o2] ASI_DMMU, %g2
  37. cmp %g2, %o0
  38. bne,pn %icc, __spitfire_flush_tlb_page_slow
  39.  or %o1, 0x10, %g3
  40. stxa %g0, [%g3] ASI_DMMU_DEMAP
  41. stxa %g0, [%g3] ASI_IMMU_DEMAP
  42. retl
  43.  flush %g6
  44. __cheetah_flush_tlb_page:
  45. /*IC3*/ rdpr %pstate, %g5
  46. andn %g5, PSTATE_IE, %g2
  47. wrpr %g2, 0x0, %pstate
  48. wrpr %g0, 1, %tl
  49. mov PRIMARY_CONTEXT, %o2
  50. ldxa [%o2] ASI_DMMU, %g2
  51. stxa %o0, [%o2] ASI_DMMU
  52. stxa %g0, [%o1] ASI_DMMU_DEMAP
  53. /*IC4*/ stxa %g0, [%o1] ASI_IMMU_DEMAP
  54. stxa %g2, [%o2] ASI_DMMU
  55. flush %g6
  56. wrpr %g0, 0, %tl
  57. retl
  58.  wrpr %g5, 0x0, %pstate
  59. nop
  60. nop
  61. __flush_tlb_mm: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
  62. /*IC5*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_mm)
  63. __spitfire_flush_tlb_mm:
  64. /*IC6*/ ldxa [%o1] ASI_DMMU, %g2
  65. cmp %g2, %o0
  66. bne,pn %icc, __spitfire_flush_tlb_mm_slow
  67.  mov 0x50, %g3
  68. stxa %g0, [%g3] ASI_DMMU_DEMAP
  69. stxa %g0, [%g3] ASI_IMMU_DEMAP
  70. retl
  71.  flush %g6
  72. __cheetah_flush_tlb_mm:
  73. /*IC7*/ rdpr %pstate, %g5
  74. andn %g5, PSTATE_IE, %g2
  75. wrpr %g2, 0x0, %pstate
  76. wrpr %g0, 1, %tl
  77. mov PRIMARY_CONTEXT, %o2
  78. mov 0x40, %g3
  79. ldxa [%o2] ASI_DMMU, %g2
  80. stxa %o0, [%o2] ASI_DMMU
  81. /*IC8*/ stxa %g0, [%g3] ASI_DMMU_DEMAP
  82. stxa %g0, [%g3] ASI_IMMU_DEMAP
  83. stxa %g2, [%o2] ASI_DMMU
  84. flush %g6
  85. wrpr %g0, 0, %tl
  86. retl
  87.  wrpr %g5, 0x0, %pstate
  88. nop
  89. __flush_tlb_range: /* %o0=(ctx&TAG_CONTEXT_BITS), %o1=start&PAGE_MASK, %o2=SECONDARY_CONTEXT,
  90.     * %o3=end&PAGE_MASK, %o4=PAGE_SIZE, %o5=(end - start)
  91.     */
  92. /*IC9*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_range)
  93. __spitfire_flush_tlb_range:
  94. #define TLB_MAGIC 207 /* Students, do you know how I calculated this?  -DaveM */
  95. /*IC10*/cmp %o5, %o4
  96. bleu,pt %xcc, __flush_tlb_page
  97.  srlx %o5, PAGE_SHIFT, %g5
  98. cmp %g5, TLB_MAGIC
  99. bgeu,pn %icc, __spitfire_flush_tlb_range_constant_time
  100.  or %o1, 0x10, %g5
  101. ldxa [%o2] ASI_DMMU, %g2
  102. cmp %g2, %o0
  103. __spitfire_flush_tlb_range_page_by_page:
  104. /*IC11*/bne,pn %icc, __spitfire_flush_tlb_range_pbp_slow
  105.  sub %o5, %o4, %o5
  106. 1: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
  107. stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
  108. brnz,pt %o5, 1b
  109.  sub %o5, %o4, %o5
  110. retl
  111.  flush %g6
  112. __spitfire_flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
  113. /*IC12*/rdpr %pstate, %g1
  114. wrpr %g1, PSTATE_IE, %pstate
  115. mov TLB_TAG_ACCESS, %g3
  116. /* XXX Spitfire dependency... */
  117. mov ((SPITFIRE_HIGHEST_LOCKED_TLBENT-1) << 3), %g2
  118. /* Spitfire Errata #32 workaround. */
  119. mov 0x8, %o4
  120. stxa %g0, [%o4] ASI_DMMU
  121. flush %g6
  122. 1: ldxa [%g2] ASI_ITLB_TAG_READ, %o4
  123. and %o4, TAG_CONTEXT_BITS, %o5
  124. cmp %o5, %o0
  125. bne,pt %icc, 2f
  126. /*IC13*/ andn %o4, TAG_CONTEXT_BITS, %o4
  127. cmp %o4, %o1
  128. blu,pt %xcc, 2f
  129.  cmp %o4, %o3
  130. blu,pn %xcc, 4f
  131. 2:  ldxa [%g2] ASI_DTLB_TAG_READ, %o4
  132. and %o4, TAG_CONTEXT_BITS, %o5
  133. cmp %o5, %o0
  134. /*IC14*/andn %o4, TAG_CONTEXT_BITS, %o4
  135. bne,pt %icc, 3f
  136.  cmp %o4, %o1
  137. blu,pt %xcc, 3f
  138.  cmp %o4, %o3
  139. blu,pn %xcc, 5f
  140.  nop
  141. 3: brnz,pt %g2, 1b
  142. /*IC15*/ sub %g2, (1 << 3), %g2
  143. retl
  144.  wrpr %g1, 0x0, %pstate
  145. 4: stxa %g0, [%g3] ASI_IMMU
  146. stxa %g0, [%g2] ASI_ITLB_DATA_ACCESS
  147. flush %g6
  148. /* Spitfire Errata #32 workaround. */
  149. mov 0x8, %o4
  150. stxa %g0, [%o4] ASI_DMMU
  151. flush %g6
  152. ba,pt %xcc, 2b
  153.  nop
  154. 5: stxa %g0, [%g3] ASI_DMMU
  155. /*IC16*/stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS
  156. flush %g6
  157. /* Spitfire Errata #32 workaround. */
  158. mov 0x8, %o4
  159. stxa %g0, [%o4] ASI_DMMU
  160. flush %g6
  161. ba,pt %xcc, 3b
  162.  nop
  163. .align 32
  164. __cheetah_flush_tlb_range:
  165. cmp %o5, %o4
  166. bleu,pt %xcc, __cheetah_flush_tlb_page
  167.  nop
  168. /*IC17*/rdpr %pstate, %g5
  169. andn %g5, PSTATE_IE, %g2
  170. wrpr %g2, 0x0, %pstate
  171. wrpr %g0, 1, %tl
  172. mov PRIMARY_CONTEXT, %o2
  173. sub %o5, %o4, %o5
  174. ldxa [%o2] ASI_DMMU, %g2
  175. stxa %o0, [%o2] ASI_DMMU
  176. /*IC18*/
  177. 1: stxa %g0, [%o1 + %o5] ASI_DMMU_DEMAP
  178. stxa %g0, [%o1 + %o5] ASI_IMMU_DEMAP
  179. membar #Sync
  180. brnz,pt %o5, 1b
  181.  sub %o5, %o4, %o5
  182. stxa %g2, [%o2] ASI_DMMU
  183. flush %g6
  184. wrpr %g0, 0, %tl
  185. retl
  186. /*IC19*/ wrpr %g5, 0x0, %pstate
  187. __spitfire_flush_tlb_mm_slow:
  188. rdpr %pstate, %g1
  189. wrpr %g1, PSTATE_IE, %pstate
  190. stxa %o0, [%o1] ASI_DMMU
  191. stxa %g0, [%g3] ASI_DMMU_DEMAP
  192. stxa %g0, [%g3] ASI_IMMU_DEMAP
  193. flush %g6
  194. stxa %g2, [%o1] ASI_DMMU
  195. /*IC18*/flush %g6
  196. retl
  197.  wrpr %g1, 0, %pstate
  198. __spitfire_flush_tlb_page_slow:
  199. rdpr %pstate, %g1
  200. wrpr %g1, PSTATE_IE, %pstate
  201. stxa %o0, [%o2] ASI_DMMU
  202. stxa %g0, [%g3] ASI_DMMU_DEMAP
  203. stxa %g0, [%g3] ASI_IMMU_DEMAP
  204. /*IC20*/flush %g6
  205. stxa %g2, [%o2] ASI_DMMU
  206. flush %g6
  207. retl
  208.  wrpr %g1, 0, %pstate
  209. __spitfire_flush_tlb_range_pbp_slow:
  210. rdpr %pstate, %g1
  211. wrpr %g1, PSTATE_IE, %pstate
  212. stxa %o0, [%o2] ASI_DMMU
  213. /*IC21*/
  214. 2: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
  215. stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
  216. brnz,pt %o5, 2b
  217.  sub %o5, %o4, %o5
  218. flush %g6
  219. stxa %g2, [%o2] ASI_DMMU
  220. flush %g6
  221. retl
  222. /*IC22*/ wrpr %g1, 0x0, %pstate
  223. /*
  224.  * The following code flushes one page_size worth.
  225.  */
  226. #if (PAGE_SHIFT == 13)
  227. #define ITAG_MASK 0xfe
  228. #elif (PAGE_SHIFT == 16)
  229. #define ITAG_MASK 0x7fe
  230. #else
  231. #error unsupported PAGE_SIZE
  232. #endif
  233. .align 32
  234. .globl __flush_icache_page
  235. __flush_icache_page: /* %o0 = phys_page */
  236. sethi %hi(1 << 13), %o2 ! IC_set bit
  237. mov 1, %g1
  238. srlx %o0, 5, %o0
  239. clr %o1 ! IC_addr
  240. sllx %g1, 36, %g1
  241. ldda [%o1] ASI_IC_TAG, %o4
  242. sub %g1, 1, %g2
  243. or %o0, %g1, %o0 ! VALID+phys-addr comparitor
  244. sllx %g2, 1, %g2
  245. andn %g2, ITAG_MASK, %g2 ! IC_tag mask
  246. nop
  247. nop
  248. nop
  249. nop
  250. nop
  251. nop
  252. 1: addx %g0, %g0, %g0
  253. ldda [%o1 + %o2] ASI_IC_TAG, %g4
  254. addx %g0, %g0, %g0
  255. and %o5, %g2, %g3
  256. cmp %g3, %o0
  257. add %o1, 0x20, %o1
  258. ldda [%o1] ASI_IC_TAG, %o4
  259. be,pn %xcc, iflush1
  260. 2:  nop
  261. and %g5, %g2, %g5
  262. cmp %g5, %o0
  263. be,pn %xcc, iflush2
  264. 3:  cmp %o1, %o2
  265. bne,pt %xcc, 1b
  266.  addx %g0, %g0, %g0
  267. nop
  268. sethi %uhi(PAGE_OFFSET), %g4
  269. retl
  270.  sllx %g4, 32, %g4
  271. iflush1:sub %o1, 0x20, %g3
  272. stxa %g0, [%g3] ASI_IC_TAG
  273. flush %g6
  274. ba,a,pt %xcc, 2b
  275. iflush2:sub %o1, 0x20, %g3
  276. stxa %g0, [%o1 + %o2] ASI_IC_TAG
  277. flush %g6
  278. ba,a,pt %xcc, 3b
  279. .align 64
  280. .globl __flush_dcache_page
  281. __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
  282. sub %o0, %g4, %o0
  283. rdpr %ver, %g1
  284. sethi %hi(0x003e0014), %g2
  285. srlx %g1, 32, %g1
  286. or %g2, %lo(0x003e0014), %g2
  287. cmp %g1, %g2
  288. bne,pt %icc, flush_dcpage_spitfire
  289.  nop
  290. flush_dcpage_cheetah:
  291. sethi %hi(PAGE_SIZE), %o4
  292. 1: subcc %o4, (1 << 5), %o4
  293. stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
  294. bne,pt %icc, 1b
  295.  nop
  296. membar #Sync
  297. /* I-cache flush never needed on Cheetah, see callers. */
  298. retl
  299.  nop
  300. #if (PAGE_SHIFT == 13)
  301. #define DTAG_MASK 0x3
  302. #elif (PAGE_SHIFT == 16)
  303. #define DTAG_MASK 0x1f
  304. #elif (PAGE_SHIFT == 19)
  305. #define DTAG_MASK 0xff
  306. #elif (PAGE_SHIFT == 22)
  307. #define DTAG_MASK 0x3ff
  308. #endif
  309. flush_dcpage_spitfire:
  310. clr %o4
  311. srlx %o0, 11, %o0
  312. sethi %hi(1 << 14), %o2
  313. 1: ldxa [%o4] ASI_DCACHE_TAG, %o3 ! LSU Group
  314. add %o4, (1 << 5), %o4 ! IEU0
  315. ldxa [%o4] ASI_DCACHE_TAG, %g1 ! LSU Group
  316. add %o4, (1 << 5), %o4 ! IEU0
  317. ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available
  318. add %o4, (1 << 5), %o4 ! IEU0
  319. andn %o3, DTAG_MASK, %o3 ! IEU1
  320. ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group
  321. add %o4, (1 << 5), %o4 ! IEU0
  322. andn %g1, DTAG_MASK, %g1 ! IEU1
  323. cmp %o0, %o3 ! IEU1 Group
  324. be,a,pn %xcc, dflush1 ! CTI
  325.  sub %o4, (4 << 5), %o4 ! IEU0 (Group)
  326. cmp %o0, %g1 ! IEU1 Group
  327. andn %g2, DTAG_MASK, %g2 ! IEU0
  328. be,a,pn %xcc, dflush2 ! CTI
  329.  sub %o4, (3 << 5), %o4 ! IEU0 (Group)
  330. cmp %o0, %g2 ! IEU1 Group
  331. andn %g3, DTAG_MASK, %g3 ! IEU0
  332. be,a,pn %xcc, dflush3 ! CTI
  333.  sub %o4, (2 << 5), %o4 ! IEU0 (Group)
  334. cmp %o0, %g3 ! IEU1 Group
  335. be,a,pn %xcc, dflush4 ! CTI
  336.  sub %o4, (1 << 5), %o4 ! IEU0
  337. 2: cmp %o4, %o2 ! IEU1 Group
  338. bne,pt %xcc, 1b ! CTI
  339.  nop ! IEU0
  340. /* The I-cache does not snoop local stores so we
  341.  * better flush that too when necessary.
  342.  */
  343. brnz,pt %o1, __flush_icache_page
  344.  sllx %o0, 11, %o0
  345. retl
  346.  nop
  347. dflush1:stxa %g0, [%o4] ASI_DCACHE_TAG
  348. add %o4, (1 << 5), %o4
  349. dflush2:stxa %g0, [%o4] ASI_DCACHE_TAG
  350. add %o4, (1 << 5), %o4
  351. dflush3:stxa %g0, [%o4] ASI_DCACHE_TAG
  352. add %o4, (1 << 5), %o4
  353. dflush4:stxa %g0, [%o4] ASI_DCACHE_TAG
  354. add %o4, (1 << 5), %o4
  355. membar #Sync
  356. ba,pt %xcc, 2b
  357.  nop
  358. .align 32
  359. __prefill_dtlb:
  360. rdpr %pstate, %g7
  361. wrpr %g7, PSTATE_IE, %pstate
  362. mov TLB_TAG_ACCESS, %g1
  363. stxa %o0, [%g1] ASI_DMMU
  364. stxa %o1, [%g0] ASI_DTLB_DATA_IN
  365. flush %g6
  366. retl
  367.  wrpr %g7, %pstate
  368. __prefill_itlb:
  369. rdpr %pstate, %g7
  370. wrpr %g7, PSTATE_IE, %pstate
  371. mov TLB_TAG_ACCESS, %g1
  372. stxa %o0, [%g1] ASI_IMMU
  373. stxa %o1, [%g0] ASI_ITLB_DATA_IN
  374. flush %g6
  375. retl
  376.  wrpr %g7, %pstate
  377. .globl __update_mmu_cache
  378. __update_mmu_cache: /* %o0=vma, %o1=address, %o2=pte */
  379. ldub [%g6 + AOFF_task_thread + AOFF_thread_fault_code], %o3
  380. srlx %o1, PAGE_SHIFT, %o1
  381. ldx [%o0 + 0x0], %o4 /* XXX vma->vm_mm */
  382. brz,pn %o3, 1f
  383.  sllx %o1, PAGE_SHIFT, %o0
  384. ldx [%o4 + AOFF_mm_context], %o5
  385. andcc %o3, FAULT_CODE_DTLB, %g0
  386. mov %o2, %o1
  387. and %o5, TAG_CONTEXT_BITS, %o5
  388. bne,pt %xcc, __prefill_dtlb
  389.  or %o0, %o5, %o0
  390. ba,a,pt %xcc, __prefill_itlb
  391. 1: retl
  392.  nop
  393. #ifdef CONFIG_SMP
  394. /* These are all called by the slaves of a cross call, at
  395.  * trap level 1, with interrupts fully disabled.
  396.  *
  397.  * Register usage:
  398.  *   %g5 mm->context (all tlb flushes)
  399.  *   %g1 address arg 1 (tlb page and range flushes)
  400.  *   %g7 address arg 2 (tlb range flush only)
  401.  *
  402.  *   %g6 ivector table, don't touch
  403.  *   %g2 scratch 1
  404.  *   %g3 scratch 2
  405.  *   %g4 scratch 3
  406.  *
  407.  * TODO: Make xcall TLB range flushes use the tricks above... -DaveM
  408.  */
  409. .align 32
  410. .globl xcall_flush_tlb_page, xcall_flush_tlb_mm, xcall_flush_tlb_range
  411. xcall_flush_tlb_page:
  412. mov PRIMARY_CONTEXT, %g2
  413. ldxa [%g2] ASI_DMMU, %g3
  414. stxa %g5, [%g2] ASI_DMMU
  415. stxa %g0, [%g1] ASI_DMMU_DEMAP
  416. stxa %g0, [%g1] ASI_IMMU_DEMAP
  417. stxa %g3, [%g2] ASI_DMMU
  418. retry
  419. nop
  420. xcall_flush_tlb_mm:
  421. mov PRIMARY_CONTEXT, %g2
  422. mov 0x40, %g4
  423. ldxa [%g2] ASI_DMMU, %g3
  424. stxa %g5, [%g2] ASI_DMMU
  425. stxa %g0, [%g4] ASI_DMMU_DEMAP
  426. stxa %g0, [%g4] ASI_IMMU_DEMAP
  427. stxa %g3, [%g2] ASI_DMMU
  428. retry
  429. xcall_flush_tlb_range:
  430. sethi %hi(PAGE_SIZE - 1), %g2
  431. or %g2, %lo(PAGE_SIZE - 1), %g2
  432. andn %g1, %g2, %g1
  433. andn %g7, %g2, %g7
  434. sub %g7, %g1, %g3
  435. add %g2, 1, %g2
  436. srlx %g3, PAGE_SHIFT, %g4
  437. cmp %g4, 96
  438. bgu,pn %icc, xcall_flush_tlb_mm
  439.  mov PRIMARY_CONTEXT, %g4
  440. ldxa [%g4] ASI_DMMU, %g7
  441. sub %g3, %g2, %g3
  442. stxa %g5, [%g4] ASI_DMMU
  443. nop
  444. nop
  445. nop
  446. 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
  447. stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
  448. membar #Sync
  449. brnz,pt %g3, 1b
  450.  sub %g3, %g2, %g3
  451. stxa %g7, [%g4] ASI_DMMU
  452. retry
  453. nop
  454. nop
  455. .globl xcall_report_regs
  456. xcall_report_regs:
  457. rdpr %pstate, %g2
  458. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  459. rdpr %pil, %g2
  460. wrpr %g0, 15, %pil
  461. sethi %hi(109f), %g7
  462. b,pt %xcc, etrap_irq
  463. 109:  or %g7, %lo(109b), %g7
  464. call __show_regs
  465.  add %sp, STACK_BIAS + REGWIN_SZ, %o0
  466. b,pt %xcc, rtrap
  467.  clr %l6
  468. .align 32
  469. .globl xcall_flush_dcache_page_cheetah
  470. xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
  471. sethi %hi(PAGE_SIZE), %g3
  472. 1: subcc %g3, (1 << 5), %g3
  473. stxa %g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
  474. bne,pt %icc, 1b
  475.  nop
  476. membar #Sync
  477. retry
  478. nop
  479. .globl xcall_flush_dcache_page_spitfire
  480. xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
  481.      %g7 == kernel page virtual address
  482.      %g5 == (page->mapping != NULL)  */
  483. #if (L1DCACHE_SIZE > PAGE_SIZE)
  484. srlx %g1, (13 - 2), %g1 ! Form tag comparitor
  485. sethi %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K
  486. sub %g3, (1 << 5), %g3 ! D$ linesize == 32
  487. 1: ldxa [%g3] ASI_DCACHE_TAG, %g2
  488. andcc %g2, 0x3, %g0
  489. be,pn %xcc, 2f
  490.  andn %g2, 0x3, %g2
  491. cmp %g2, %g1
  492. bne,pt %xcc, 2f
  493.  nop
  494. stxa %g0, [%g3] ASI_DCACHE_TAG
  495. membar #Sync
  496. 2: cmp %g3, 0
  497. bne,pt %xcc, 1b
  498.  sub %g3, (1 << 5), %g3
  499. brz,pn %g5, 2f
  500. #endif /* L1DCACHE_SIZE > PAGE_SIZE */
  501.  sethi %hi(PAGE_SIZE), %g3
  502. 1: flush %g7
  503. subcc %g3, (1 << 5), %g3
  504. bne,pt %icc, 1b
  505.  add %g7, (1 << 5), %g7
  506. 2: retry
  507. nop
  508. nop
  509. .globl xcall_capture
  510. xcall_capture:
  511. rdpr %pstate, %g2
  512. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  513. rdpr %pil, %g2
  514. wrpr %g0, 15, %pil
  515. sethi %hi(109f), %g7
  516. b,pt %xcc, etrap_irq
  517. 109:  or %g7, %lo(109b), %g7
  518. call smp_penguin_jailcell
  519.  nop
  520. b,pt %xcc, rtrap
  521.  clr %l6
  522. .globl xcall_promstop
  523. xcall_promstop:
  524. rdpr %pstate, %g2
  525. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  526. rdpr %pil, %g2
  527. wrpr %g0, 15, %pil
  528. sethi %hi(109f), %g7
  529. b,pt %xcc, etrap_irq
  530. 109:  or %g7, %lo(109b), %g7
  531. flushw
  532. call prom_stopself
  533.  nop
  534. /* We should not return, just spin if we do... */
  535. 1: b,a,pt %xcc, 1b
  536. nop
  537. .globl xcall_receive_signal
  538. xcall_receive_signal:
  539. rdpr %pstate, %g2
  540. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  541. rdpr %tstate, %g1
  542. andcc %g1, TSTATE_PRIV, %g0
  543. /* If we did not trap from user space, just ignore. */
  544. bne,pn %xcc, 99f
  545.  sethi %hi(109f), %g7
  546. b,pt %xcc, etrap
  547. 109:  or %g7, %lo(109b), %g7
  548. b,pt %xcc, rtrap
  549.  clr %l6
  550. 99: retry
  551. .data
  552. errata32_hwbug:
  553. .xword 0
  554. .text
  555. /* These two are not performance critical... */
  556. .globl xcall_flush_tlb_all
  557. xcall_flush_tlb_all:
  558. BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_tlb_all)
  559. __spitfire_xcall_flush_tlb_all:
  560. /* Spitfire Errata #32 workaround. */
  561. sethi %hi(errata32_hwbug), %g4
  562. stx %g0, [%g4 + %lo(errata32_hwbug)]
  563. clr %g2
  564. clr %g3
  565. 1: ldxa [%g3] ASI_DTLB_DATA_ACCESS, %g4
  566. and %g4, _PAGE_L, %g5
  567. brnz,pn %g5, 2f
  568.  mov TLB_TAG_ACCESS, %g7
  569. stxa %g0, [%g7] ASI_DMMU
  570. membar #Sync
  571. stxa %g0, [%g3] ASI_DTLB_DATA_ACCESS
  572. membar #Sync
  573. /* Spitfire Errata #32 workaround. */
  574. sethi %hi(errata32_hwbug), %g4
  575. stx %g0, [%g4 + %lo(errata32_hwbug)]
  576. 2: ldxa [%g3] ASI_ITLB_DATA_ACCESS, %g4
  577. and %g4, _PAGE_L, %g5
  578. brnz,pn %g5, 2f
  579.  mov TLB_TAG_ACCESS, %g7
  580. stxa %g0, [%g7] ASI_IMMU
  581. membar #Sync
  582. stxa %g0, [%g3] ASI_ITLB_DATA_ACCESS
  583. membar #Sync
  584. /* Spitfire Errata #32 workaround. */
  585. sethi %hi(errata32_hwbug), %g4
  586. stx %g0, [%g4 + %lo(errata32_hwbug)]
  587. 2: add %g2, 1, %g2
  588. cmp %g2, SPITFIRE_HIGHEST_LOCKED_TLBENT
  589. ble,pt %icc, 1b
  590.  sll %g2, 3, %g3
  591. flush %g6
  592. retry
  593. __cheetah_xcall_flush_tlb_all:
  594. mov 0x80, %g2
  595. stxa %g0, [%g2] ASI_DMMU_DEMAP
  596. stxa %g0, [%g2] ASI_IMMU_DEMAP
  597. retry
  598. .globl xcall_flush_cache_all
  599. xcall_flush_cache_all:
  600. BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_cache_all)
  601. __spitfire_xcall_flush_cache_all:
  602. sethi %hi(16383), %g2
  603. or %g2, %lo(16383), %g2
  604. clr %g3
  605. 1: stxa %g0, [%g3] ASI_IC_TAG
  606. membar #Sync
  607. add %g3, 32, %g3
  608. cmp %g3, %g2
  609. bleu,pt %xcc, 1b
  610.  nop
  611. flush %g6
  612. retry
  613. /* Cheetah's caches are fully coherent in the sense that
  614.  * caches are flushed here.  We need to verify this and
  615.  * really just not even send out the xcall at the top level.
  616.  */
  617. __cheetah_xcall_flush_cache_all:
  618. retry
  619. .globl xcall_call_function
  620. xcall_call_function:
  621. rdpr %pstate, %g2
  622. wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
  623. rdpr %pil, %g2
  624. wrpr %g0, 15, %pil
  625. sethi %hi(109f), %g7
  626. b,pt %xcc, etrap_irq
  627. 109:  or %g7, %lo(109b), %g7
  628. call smp_call_function_client
  629.  nop
  630. b,pt %xcc, rtrap
  631.  clr %l6
  632. #endif /* CONFIG_SMP */