summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsm142603 <none@none>2008-02-29 22:27:40 -0800
committersm142603 <none@none>2008-02-29 22:27:40 -0800
commit1426d65aa9264a283c76d271972aeb7f6a070be3 (patch)
tree2c6841fcdfc96a814f7482ad298951ceaf40d99b
parent0358d3a672326bc66debe0a1c3a2372cd9f0f662 (diff)
downloadillumos-joyent-1426d65aa9264a283c76d271972aeb7f6a070be3.tar.gz
6642758 Support Shared Context for SPARC64-VII
-rw-r--r--usr/src/uts/sfmmu/ml/sfmmu_asm.s352
-rw-r--r--usr/src/uts/sfmmu/vm/hat_sfmmu.c18
-rw-r--r--usr/src/uts/sfmmu/vm/hat_sfmmu.h187
-rw-r--r--usr/src/uts/sun4/ml/swtch.s8
-rw-r--r--usr/src/uts/sun4u/cpu/opl_olympus.c34
-rw-r--r--usr/src/uts/sun4u/cpu/us3_common_mmu.c8
-rw-r--r--usr/src/uts/sun4u/ml/mach_offsets.in93
-rw-r--r--usr/src/uts/sun4u/ml/trap_table.s88
-rw-r--r--usr/src/uts/sun4u/os/mach_cpu_states.c4
-rw-r--r--usr/src/uts/sun4u/sys/machparam.h3
-rw-r--r--usr/src/uts/sun4u/sys/mmu.h13
-rw-r--r--usr/src/uts/sun4u/sys/opl_olympus_regs.h9
-rw-r--r--usr/src/uts/sun4u/vm/mach_sfmmu.h423
-rw-r--r--usr/src/uts/sun4u/vm/mach_sfmmu_asm.s317
-rw-r--r--usr/src/uts/sun4v/vm/mach_sfmmu.h198
15 files changed, 972 insertions, 783 deletions
diff --git a/usr/src/uts/sfmmu/ml/sfmmu_asm.s b/usr/src/uts/sfmmu/ml/sfmmu_asm.s
index 9922254c2a..8c370d099f 100644
--- a/usr/src/uts/sfmmu/ml/sfmmu_asm.s
+++ b/usr/src/uts/sfmmu/ml/sfmmu_asm.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -831,11 +831,12 @@ sfmmu_panic10:
ldub [%o0 + SFMMU_CEXT], %o2
sll %o2, CTXREG_EXT_SHIFT, %o2
or %o1, %o2, %o1
-#endif
- SET_SECCTX(%o1, %g1, %o4, %o5)
-
- retl
- mov %g4, %o0 ! %o0 = ret
+#endif /* sun4u */
+
+ SET_SECCTX(%o1, %g1, %o4, %o5, alloc_ctx_lbl1)
+
+ retl
+ mov %g4, %o0 ! %o0 = ret
SET_SIZE(sfmmu_alloc_ctx)
@@ -1196,7 +1197,7 @@ sfmmu_kpm_unload_tsb(caddr_t addr, int vpshift)
sethi %hi(tsb_kernel_patch_asi), %o0
call sfmmu_fixup_or
or %o0, %lo(tsb_kernel_patch_asi), %o0
-#endif
+#endif /* !sun4v */
ldx [%o5], %o4 ! load ktsb base addr (VA or PA)
@@ -1466,7 +1467,7 @@ sfmmu_kpm_unload_tsb(caddr_t addr, int vpshift)
ld [%o4 + %lo(ktsb_phys)], %o4
movrnz %o4, ASI_MEM, %o3
mov %o3, %asi
-#endif
+#endif /* !sun4v */
mov %o0, %g1 ! %g1 = vaddr
/* GET_KPM_TSBE_POINTER(vpshift, tsbp, vaddr (clobbers), tmp1, tmp2) */
@@ -1498,7 +1499,7 @@ sfmmu_kpm_unload_tsb(caddr_t addr, int vpshift)
ld [%o4 + %lo(ktsb_phys)], %o4
movrnz %o4, ASI_MEM, %o3
mov %o3, %asi
-#endif
+#endif /* !sun4v */
mov %o0, %g1 ! %g1 = vaddr
/* GET_KPM_TSBE_POINTER(vpshift, tsbp, vaddr (clobbers), tmp1, tmp2) */
@@ -2701,7 +2702,7 @@ sfmmu_kprot_patch_ktsb4m_szcode:
* g4 - g7 = scratch registers
*/
ALTENTRY(sfmmu_uprot_trap)
-#ifdef sun4v
+#ifdef sun4v
GET_1ST_TSBE_PTR(%g2, %g1, %g4, %g5)
/* %g1 = first TSB entry ptr now, %g2 preserved */
@@ -2715,7 +2716,7 @@ sfmmu_kprot_patch_ktsb4m_szcode:
#else /* sun4v */
#ifdef UTSB_PHYS
/* g1 = first TSB entry ptr */
- GET_2ND_TSBREG(%g3)
+ GET_UTSBREG(SCRATCHPAD_UTSBREG2, %g3)
brlz,pt %g3, 9f /* check for 2nd TSB */
nop
@@ -2938,7 +2939,7 @@ dktsb4m_kpmcheck:
*/
.align 64
ALTENTRY(sfmmu_uitlb_fastpath)
-
+
PROBE_1ST_ITSB(%g1, %g7, uitlb_fast_8k_probefail)
/* g4 - g5 = clobbered by PROBE_1ST_ITSB */
ba,pn %xcc, sfmmu_tsb_miss_tt
@@ -2998,7 +2999,15 @@ dktsb4m_kpmcheck:
* User instruction miss w/ multiple TSBs (sun4u).
* The first probe covers 8K, 64K, and 512K page sizes,
* because 64K and 512K mappings are replicated off 8K
- * pointer. Second probe covers 4M page size only.
+ * pointer. Probe of 1st TSB has already been done prior to entry
+ * into this routine. For the UTSB_PHYS case we probe up to 3
+ * valid other TSBs in the following order:
+ * 1) shared TSB for 4M-256M pages
+ * 2) private TSB for 4M-256M pages
+ * 3) shared TSB for 8K-512K pages
+ *
+ * For the non UTSB_PHYS case we probe the 2nd TSB here that backs
+ * 4M-256M pages.
*
* Just like sfmmu_udtlb_slowpath, except:
* o Uses ASI_ITLB_IN
@@ -3007,7 +3016,6 @@ dktsb4m_kpmcheck:
*
* g1 = tsb8k pointer register
* g2 = tag access register
- * g3 = 2nd tsbreg if defined UTSB_PHYS, else scratch
* g4 - g6 = scratch registers
* g7 = TSB tag to match
*/
@@ -3015,51 +3023,157 @@ dktsb4m_kpmcheck:
ALTENTRY(sfmmu_uitlb_slowpath)
#ifdef UTSB_PHYS
- /*
- * g1 = 1st TSB entry pointer
- * g3 = 2nd TSB base register
- * Need 2nd TSB entry pointer for 2nd probe.
- */
- PROBE_1ST_ITSB(%g1, %g7, uitlb_8k_probefail)
- GET_2ND_TSBE_PTR(%g2, %g3, %g4, %g5)
+ GET_UTSBREG(SCRATCHPAD_UTSBREG4, %g6)
+ brlz,pt %g6, 1f
+ nop
+ GET_4TH_TSBE_PTR(%g2, %g6, %g4, %g5)
+ PROBE_4TH_ITSB(%g6, %g7, uitlb_4m_scd_probefail)
+1:
+ GET_UTSBREG(SCRATCHPAD_UTSBREG2, %g3)
+ brlz,pt %g3, 2f
+ nop
+ GET_2ND_TSBE_PTR(%g2, %g3, %g4, %g5)
+ PROBE_2ND_ITSB(%g3, %g7, uitlb_4m_probefail)
+2:
+ GET_UTSBREG(SCRATCHPAD_UTSBREG3, %g6)
+ brlz,pt %g6, sfmmu_tsb_miss_tt
+ nop
+ GET_3RD_TSBE_PTR(%g2, %g6, %g4, %g5)
+ PROBE_3RD_ITSB(%g6, %g7, uitlb_8K_scd_probefail)
+ ba,pn %xcc, sfmmu_tsb_miss_tt
+ nop
+
#else /* UTSB_PHYS */
mov %g1, %g3 /* save tsb8k reg in %g3 */
GET_1ST_TSBE_PTR(%g3, %g1, %g5, sfmmu_uitlb)
PROBE_1ST_ITSB(%g1, %g7, uitlb_8k_probefail)
-
mov %g2, %g6 /* GET_2ND_TSBE_PTR clobbers tagacc */
mov %g3, %g7 /* copy tsb8k reg in %g7 */
GET_2ND_TSBE_PTR(%g6, %g7, %g3, %g4, %g5, sfmmu_uitlb)
+ /* g1 = first TSB pointer, g3 = second TSB pointer */
+ srlx %g2, TAG_VALO_SHIFT, %g7
+ PROBE_2ND_ITSB(%g3, %g7, isynth)
+ ba,pn %xcc, sfmmu_tsb_miss_tt
+ nop
+
#endif /* UTSB_PHYS */
- /* g1 = first TSB pointer, g3 = second TSB pointer */
- srlx %g2, TAG_VALO_SHIFT, %g7
- PROBE_2ND_ITSB(%g3, %g7, isynth)
- /* NOT REACHED */
#endif /* sun4v */
+#if defined(sun4u) && defined(UTSB_PHYS)
+
+ /*
+ * We come here for ism predict DTLB_MISS case or if
+ * if probe in first TSB failed.
+ */
+
+ .align 64
+ ALTENTRY(sfmmu_udtlb_slowpath_noismpred)
+
/*
- * User data miss w/ multiple TSBs.
- * The first probe covers 8K, 64K, and 512K page sizes,
- * because 64K and 512K mappings are replicated off 8K
- * pointer. Second probe covers 4M page size only.
- *
- * We consider probing for 4M pages first if the VA falls
- * in a range that's likely to be ISM.
- *
- * g1 = tsb8k pointer register
- * g2 = tag access register
- * g3 = 2nd tsbreg if defined UTSB_PHYS, else scratch
- * g4 - g6 = scratch registers
- * g7 = TSB tag to match
+ * g1 = tsb8k pointer register
+ * g2 = tag access register
+ * g4 - %g6 = scratch registers
+ * g7 = TSB tag to match
*/
+
+ /*
+ * ISM non-predict probe order
+ * probe 1ST_TSB (8K index)
+ * probe 2ND_TSB (4M index)
+ * probe 4TH_TSB (4M index)
+ * probe 3RD_TSB (8K index)
+ *
+ * We already probed first TSB in DTLB_MISS handler.
+ */
+
+ /*
+ * Private 2ND TSB 4M-256 pages
+ */
+ GET_UTSBREG(SCRATCHPAD_UTSBREG2, %g3)
+ brlz,pt %g3, 1f
+ nop
+ GET_2ND_TSBE_PTR(%g2, %g3, %g4, %g5)
+ PROBE_2ND_DTSB(%g3, %g7, udtlb_4m_probefail)
+
+ /*
+ * Shared Context 4TH TSB 4M-256 pages
+ */
+1:
+ GET_UTSBREG(SCRATCHPAD_UTSBREG4, %g6)
+ brlz,pt %g6, 2f
+ nop
+ GET_4TH_TSBE_PTR(%g2, %g6, %g4, %g5)
+ PROBE_4TH_DTSB(%g6, %g7, udtlb_4m_shctx_probefail)
+
+ /*
+ * Shared Context 3RD TSB 8K-512K pages
+ */
+2:
+ GET_UTSBREG(SCRATCHPAD_UTSBREG3, %g6)
+ brlz,pt %g6, sfmmu_tsb_miss_tt
+ nop
+ GET_3RD_TSBE_PTR(%g2, %g6, %g4, %g5)
+ PROBE_3RD_DTSB(%g6, %g7, udtlb_8k_shctx_probefail)
+ ba,pn %xcc, sfmmu_tsb_miss_tt
+ nop
+
.align 64
- ALTENTRY(sfmmu_udtlb_slowpath)
+ ALTENTRY(sfmmu_udtlb_slowpath_ismpred)
+
+ /*
+ * g1 = tsb8k pointer register
+ * g2 = tag access register
+ * g4 - g6 = scratch registers
+ * g7 = TSB tag to match
+ */
+
+ /*
+ * ISM predict probe order
+ * probe 4TH_TSB (4M index)
+ * probe 2ND_TSB (4M index)
+ * probe 1ST_TSB (8K index)
+ * probe 3RD_TSB (8K index)
/*
- * Check for ISM. If it exists, look for 4M mappings in the second TSB
- * first, then probe for other mappings in the first TSB if that fails.
+ * Shared Context 4TH TSB 4M-256 pages
*/
+ GET_UTSBREG(SCRATCHPAD_UTSBREG4, %g6)
+ brlz,pt %g6, 4f
+ nop
+ GET_4TH_TSBE_PTR(%g2, %g6, %g4, %g5)
+ PROBE_4TH_DTSB(%g6, %g7, udtlb_4m_shctx_probefail2)
+
+ /*
+ * Private 2ND TSB 4M-256 pages
+ */
+4:
+ GET_UTSBREG(SCRATCHPAD_UTSBREG2, %g3)
+ brlz,pt %g3, 5f
+ nop
+ GET_2ND_TSBE_PTR(%g2, %g3, %g4, %g5)
+ PROBE_2ND_DTSB(%g3, %g7, udtlb_4m_probefail2)
+
+5:
+ PROBE_1ST_DTSB(%g1, %g7, udtlb_8k_first_probefail2)
+
+ /*
+ * Shared Context 3RD TSB 8K-512K pages
+ */
+ GET_UTSBREG(SCRATCHPAD_UTSBREG3, %g6)
+ brlz,pt %g6, 6f
+ nop
+ GET_3RD_TSBE_PTR(%g2, %g6, %g4, %g5)
+ PROBE_3RD_DTSB(%g6, %g7, udtlb_8k_shctx_probefail2)
+6:
+ ba,pn %xcc, sfmmu_tsb_miss_tt /* ISM Predict and ISM non-predict path */
+ nop
+
+#else /* sun4u && UTSB_PHYS */
+
+ .align 64
+ ALTENTRY(sfmmu_udtlb_slowpath)
+
srax %g2, PREDISM_BASESHIFT, %g6 /* g6 > 0 : ISM predicted */
brgz,pn %g6, udtlb_miss_probesecond /* check for ISM */
mov %g1, %g3
@@ -3085,10 +3199,8 @@ udtlb_miss_probefirst:
brgz,pn %g6, sfmmu_tsb_miss_tt
nop
#else /* sun4v */
-#ifndef UTSB_PHYS
mov %g1, %g4
GET_1ST_TSBE_PTR(%g4, %g1, %g5, sfmmu_udtlb)
-#endif UTSB_PHYS
PROBE_1ST_DTSB(%g1, %g7, udtlb_first_probefail)
/*
@@ -3099,9 +3211,7 @@ udtlb_miss_probefirst:
*/
brgz,pn %g6, sfmmu_tsb_miss_tt
nop
-#ifndef UTSB_PHYS
ldxa [%g0]ASI_DMMU_TSB_8K, %g3
-#endif UTSB_PHYS
/* fall through in 8K->4M probe order */
#endif /* sun4v */
@@ -3119,17 +3229,11 @@ udtlb_miss_probesecond:
GET_2ND_TSBE_PTR(%g2, %g3, %g4, %g5)
/* %g2 is okay, no need to reload, %g3 = second tsbe ptr */
#else /* sun4v */
-#ifdef UTSB_PHYS
- GET_2ND_TSBREG(%g3)
- GET_2ND_TSBE_PTR(%g2, %g3, %g4, %g5)
- /* tagacc (%g2) is okay, no need to reload, %g3 = second tsbe ptr */
-#else /* UTSB_PHYS */
mov %g3, %g7
GET_2ND_TSBE_PTR(%g2, %g7, %g3, %g4, %g5, sfmmu_udtlb)
/* %g2 clobbered, %g3 =second tsbe ptr */
mov MMU_TAG_ACCESS, %g2
ldxa [%g2]ASI_DMMU, %g2
-#endif /* UTSB_PHYS */
#endif /* sun4v */
srlx %g2, TAG_VALO_SHIFT, %g7
@@ -3139,6 +3243,8 @@ udtlb_miss_probesecond:
nop
/* fall through to sfmmu_tsb_miss_tt */
+#endif /* sun4u && UTSB_PHYS */
+
ALTENTRY(sfmmu_tsb_miss_tt)
TT_TRACE(trace_tsbmiss)
@@ -3175,9 +3281,8 @@ udtlb_miss_probesecond:
wrpr %g7, %tnpc
0:
CPU_TSBMISS_AREA(%g6, %g7)
-
- stn %g1, [%g6 + TSBMISS_TSBPTR] /* save first tsb pointer */
- stn %g3, [%g6 + TSBMISS_TSBPTR4M] /* save second tsb pointer */
+ stn %g1, [%g6 + TSBMISS_TSBPTR] /* save 1ST tsb pointer */
+ stn %g3, [%g6 + TSBMISS_TSBPTR4M] /* save 2ND tsb pointer */
sllx %g2, TAGACC_CTX_LSHIFT, %g3
brz,a,pn %g3, 1f /* skip ahead if kernel */
@@ -3191,11 +3296,11 @@ udtlb_miss_probesecond:
be,pn %icc, tsb_tl0_noctxt /* no ctx miss exception */
stn %g7, [%g6 + (TSBMISS_SCRATCH + TSBMISS_HATID)]
-#ifdef sun4v
+#if defined(sun4v) || defined(UTSB_PHYS)
ldub [%g6 + TSBMISS_URTTEFLAGS], %g7 /* clear ctx1 flag set from */
andn %g7, HAT_CHKCTX1_FLAG, %g7 /* the previous tsb miss */
stub %g7, [%g6 + TSBMISS_URTTEFLAGS]
-#endif
+#endif /* sun4v || UTSB_PHYS */
ISM_CHECK(%g2, %g6, %g3, %g4, %g5, %g7, %g1, tsb_l1, tsb_ism)
/*
@@ -3268,11 +3373,11 @@ tsb_4M:
tsb_32M:
sllx %g2, TAGACC_CTX_LSHIFT, %g5
-#ifdef sun4v
+#ifdef sun4v
brz,pn %g5, 6f
-#else
- brz,pn %g5, tsb_pagefault
-#endif
+#else
+ brz,pn %g5, tsb_pagefault
+#endif
ldub [%g6 + TSBMISS_UTTEFLAGS], %g4
and %g4, HAT_32M_FLAG, %g5
brz,pn %g5, tsb_256M
@@ -3286,8 +3391,8 @@ tsb_32M:
MMU_PAGESHIFT32M, TTE32M, tsb_l32M, tsb_checktte,
sfmmu_suspend_tl, tsb_256M)
/* NOT REACHED */
-
-#ifdef sun4u
+
+#if defined(sun4u) && !defined(UTSB_PHYS)
#define tsb_shme tsb_pagefault
#endif
tsb_256M:
@@ -3318,11 +3423,11 @@ tsb_checktte:
brlz,a,pt %g3, tsb_validtte
rdpr %tt, %g7
-#ifdef sun4u
+#if defined(sun4u) && !defined(UTSB_PHYS)
#undef tsb_shme
- ba tsb_pagefault
- nop
-#else
+ ba tsb_pagefault
+ nop
+#else /* sun4u && !UTSB_PHYS */
tsb_shme:
/*
@@ -3419,8 +3524,8 @@ tsb_shme_checktte:
or %g1, HAT_CHKCTX1_FLAG, %g1
stub %g1, [%g6 + TSBMISS_URTTEFLAGS]
- SAVE_CTX1(%g7, %g2, %g1, tsb_shmel)
-#endif /* sun4u */
+ SAVE_CTX1(%g7, %g2, %g1, tsb_shmel)
+#endif /* sun4u && !UTSB_PHYS */
tsb_validtte:
/*
@@ -3441,15 +3546,16 @@ tsb_validtte:
TTE_SET_REFMOD_ML(%g3, %g4, %g5, %g6, %g7, tsb_lset_refmod,
tsb_protfault)
- rdpr %tt, %g5
GET_MMU_D_TTARGET(%g2, %g7) /* %g2 = ttarget */
#ifdef sun4v
MMU_FAULT_STATUS_AREA(%g7)
- ldx [%g7 + MMFSA_D_ADDR], %g5 /* save fault addr for later */
-#endif
+ ldx [%g7 + MMFSA_D_ADDR], %g5 /* load fault addr for later */
+#else /* sun4v */
+ mov MMU_TAG_ACCESS, %g5
+ ldxa [%g5]ASI_DMMU, %g5
+#endif /* sun4v */
ba,pt %xcc, tsb_update_tl1
- nop
-
+ nop
4:
/*
* If ITLB miss check exec bit.
@@ -3477,13 +3583,13 @@ tsb_validtte:
* g4 = patte
* g6 = tsbmiss area
*/
- rdpr %tt, %g5
+ rdpr %tt, %g7
#ifdef sun4v
MMU_FAULT_STATUS_AREA(%g2)
- cmp %g5, T_INSTR_MMU_MISS
+ cmp %g7, T_INSTR_MMU_MISS
be,a,pt %icc, 9f
nop
- cmp %g5, FAST_IMMU_MISS_TT
+ cmp %g7, FAST_IMMU_MISS_TT
be,a,pt %icc, 9f
nop
add %g2, MMFSA_D_, %g2
@@ -3491,23 +3597,29 @@ tsb_validtte:
ldx [%g2 + MMFSA_CTX_], %g7
sllx %g7, TTARGET_CTX_SHIFT, %g7
ldx [%g2 + MMFSA_ADDR_], %g2
- mov %g2, %g5 ! save the fault addr for later use
+ mov %g2, %g5 ! load the fault addr for later use
srlx %g2, TTARGET_VA_SHIFT, %g2
or %g2, %g7, %g2
-#else
- cmp %g5, FAST_IMMU_MISS_TT
- be,a,pt %icc, tsb_update_tl1
- ldxa [%g0]ASI_IMMU, %g2
- ldxa [%g0]ASI_DMMU, %g2
-#endif
+#else /* sun4v */
+ mov MMU_TAG_ACCESS, %g5
+ cmp %g7, FAST_IMMU_MISS_TT
+ be,a,pt %icc, 9f
+ ldxa [%g0]ASI_IMMU, %g2
+ ldxa [%g0]ASI_DMMU, %g2
+ ba,pt %icc, tsb_update_tl1
+ ldxa [%g5]ASI_DMMU, %g5
+9:
+ ldxa [%g5]ASI_IMMU, %g5
+#endif /* sun4v */
+
tsb_update_tl1:
srlx %g2, TTARGET_CTX_SHIFT, %g7
brz,pn %g7, tsb_kernel
#ifdef sun4v
and %g3, TTE_SZ_BITS, %g7 ! assumes TTE_SZ_SHFT is 0
-#else
+#else /* sun4v */
srlx %g3, TTE_SZ_SHFT, %g7
-#endif
+#endif /* sun4v */
tsb_user:
#ifdef sun4v
@@ -3524,35 +3636,34 @@ tsb_user:
nop
#else /* ITLB_32M_256M_SUPPORT */
bnz,a,pn %icc, tsb_user_pn_synth
- cmp %g5, FAST_IMMU_MISS_TT
+ nop
#endif /* ITLB_32M_256M_SUPPORT */
#endif /* sun4v */
tsb_user8k:
-#ifdef sun4v
+#if defined(sun4v) || defined(UTSB_PHYS)
ldub [%g6 + TSBMISS_URTTEFLAGS], %g7
and %g7, HAT_CHKCTX1_FLAG, %g1
brz,a,pn %g1, 1f
- ldn [%g6 + TSBMISS_TSBPTR], %g1 ! g1 = first TSB ptr
+ ldn [%g6 + TSBMISS_TSBPTR], %g1 ! g1 = 1ST TSB ptr
GET_UTSBREG_SHCTX(%g6, TSBMISS_TSBSCDPTR, %g1)
- brlz,a,pn %g1, ptl1_panic ! if no shared tsb
+ brlz,a,pn %g1, ptl1_panic ! if no shared 3RD tsb
mov PTL1_NO_SCDTSB8K, %g1 ! panic
- GET_3RD_TSBE_PTR(%g5, %g1, %g6, %g7)
+ GET_3RD_TSBE_PTR(%g5, %g1, %g6, %g7)
1:
-#else
- ldn [%g6 + TSBMISS_TSBPTR], %g1 ! g1 = first TSB ptr
+#else /* defined(sun4v) || defined(UTSB_PHYS) */
+ ldn [%g6 + TSBMISS_TSBPTR], %g1 ! g1 = 1ST TSB ptr
+#endif /* defined(sun4v) || defined(UTSB_PHYS) */
#ifndef UTSB_PHYS
mov ASI_N, %g7 ! user TSBs accessed by VA
mov %g7, %asi
-#endif /* UTSB_PHYS */
-
-#endif /* sun4v */
+#endif /* !UTSB_PHYS */
TSB_UPDATE_TL(%g1, %g3, %g2, %g4, %g7, %g6, 5)
-#ifdef sun4v
rdpr %tt, %g5
+#ifdef sun4v
cmp %g5, T_INSTR_MMU_MISS
be,a,pn %xcc, 9f
mov %g3, %g5
@@ -3570,19 +3681,19 @@ tsb_user8k:
retry
tsb_user4m:
-#ifdef sun4v
+#if defined(sun4v) || defined(UTSB_PHYS)
ldub [%g6 + TSBMISS_URTTEFLAGS], %g7
and %g7, HAT_CHKCTX1_FLAG, %g1
brz,a,pn %g1, 4f
- ldn [%g6 + TSBMISS_TSBPTR4M], %g1 ! g1 = TSB ptr
- GET_UTSBREG_SHCTX(%g6, TSBMISS_TSBSCDPTR4M, %g1)
- brlz,a,pn %g1, 5f ! if no shared 2nd tsb
+ ldn [%g6 + TSBMISS_TSBPTR4M], %g1 ! g1 = 2ND TSB ptr
+ GET_UTSBREG_SHCTX(%g6, TSBMISS_TSBSCDPTR4M, %g1)! g1 = 4TH TSB ptr
+ brlz,a,pn %g1, 5f ! if no shared 4TH TSB
nop
- GET_4TH_TSBE_PTR(%g5, %g1, %g6, %g7)
-#else
- ldn [%g6 + TSBMISS_TSBPTR4M], %g1 ! g1 = TSB ptr
-#endif
+ GET_4TH_TSBE_PTR(%g5, %g1, %g6, %g7)
4:
+#else /* defined(sun4v) || defined(UTSB_PHYS) */
+ ldn [%g6 + TSBMISS_TSBPTR4M], %g1 ! g1 = 2ND TSB ptr
+#endif /* defined(sun4v) || defined(UTSB_PHYS) */
brlz,pn %g1, 5f /* Check to see if we have 2nd TSB programmed */
nop
@@ -3594,8 +3705,8 @@ tsb_user4m:
TSB_UPDATE_TL(%g1, %g3, %g2, %g4, %g7, %g6, 6)
5:
-#ifdef sun4v
rdpr %tt, %g5
+#ifdef sun4v
cmp %g5, T_INSTR_MMU_MISS
be,a,pn %xcc, 9f
mov %g3, %g5
@@ -3631,6 +3742,8 @@ tsb_user4m:
* g6 = tsbmiss area
*/
tsb_user_pn_synth:
+ rdpr %tt, %g5
+ cmp %g5, FAST_IMMU_MISS_TT
be,pt %xcc, tsb_user_itlb_synth /* ITLB miss */
andcc %g3, TTE_EXECPRM_INT, %g0 /* is execprm bit set */
bz,pn %icc, 4b /* if not, been here before */
@@ -3650,7 +3763,7 @@ tsb_user_pn_synth:
retry
tsb_user_itlb_synth:
- ldn [%g6 + TSBMISS_TSBPTR4M], %g1 /* g1 = tsbp */
+ ldn [%g6 + TSBMISS_TSBPTR4M], %g1 /* g1 = 2ND TSB */
mov MMU_TAG_ACCESS, %g7
ldxa [%g7]ASI_IMMU, %g6 /* get tag access va */
@@ -3668,21 +3781,21 @@ tsb_user_itlb_synth:
#endif /* sun4v && ITLB_32M_256M_SUPPORT */
tsb_kernel:
-#ifdef sun4v
rdpr %tt, %g5
+#ifdef sun4v
cmp %g7, TTE4M
bge,pn %icc, 5f
#else
cmp %g7, TTESZ_VALID | TTE4M ! no 32M or 256M support
be,pn %icc, 5f
-#endif
+#endif /* sun4v */
nop
- ldn [%g6 + TSBMISS_TSBPTR], %g1 ! g1 = 8k tsbptr
+ ldn [%g6 + TSBMISS_TSBPTR], %g1 ! g1 = 8K TSB ptr
ba,pt %xcc, 6f
nop
5:
- ldn [%g6 + TSBMISS_TSBPTR4M], %g1 ! g1 = 4m tsbptr
- brlz,pn %g1, 3f /* skip programming if 4m TSB ptr is -1 */
+ ldn [%g6 + TSBMISS_TSBPTR4M], %g1 ! g1 = 4M TSB ptr
+ brlz,pn %g1, 3f /* skip programming if 4M TSB ptr is -1 */
nop
6:
#ifndef sun4v
@@ -3734,7 +3847,7 @@ tsb_ism:
or %g2, %g4, %g2 /* g2 = (pseudo-)tagacc */
sub %g5, (IMAP_VB_SHIFT - IMAP_HATFLAGS), %g5
lduha [%g5]ASI_MEM, %g4 /* g5 = pa of imap_hatflags */
-#ifdef sun4v
+#if defined(sun4v) || defined(UTSB_PHYS)
and %g4, HAT_CTX1_FLAG, %g5 /* g5 = imap_hatflags */
brz,pt %g5, tsb_chk4M_ism
nop
@@ -3743,7 +3856,8 @@ tsb_ism:
stub %g5, [%g6 + TSBMISS_URTTEFLAGS]
rdpr %tt, %g5
SAVE_CTX1(%g5, %g3, %g1, tsb_shctxl)
-#endif
+#endif /* defined(sun4v) || defined(UTSB_PHYS) */
+
/*
* ISM pages are always locked down.
* If we can't find the tte then pagefault
@@ -3859,7 +3973,7 @@ tsb_protfault:
cmp %g7, T_INSTR_MMU_MISS
move %icc, %g5, %g2
sllx %g2, TAGACC_CTX_LSHIFT, %g4
-#endif
+#endif /* sun4v */
brnz,pn %g4, 3f /* skip if not kernel */
rdpr %tl, %g5
@@ -3988,7 +4102,7 @@ tsb_protfault:
ldxa [%g2]ASI_IMMU, %g3
ldxa [%g2]ASI_DMMU, %g3
2: sllx %g3, TAGACC_CTX_LSHIFT, %g3
-#endif
+#endif /* sun4v */
brz,a,pn %g3, ptl1_panic ! panic if called for kernel
mov PTL1_BAD_CTX_STEAL, %g1 ! since kernel ctx was stolen
rdpr %tl, %g5
@@ -3999,7 +4113,7 @@ tsb_protfault:
ba,pt %icc, sfmmu_window_trap
nop
SET_SIZE(sfmmu_tsb_miss)
-#endif /* lint */
+#endif /* lint */
#if defined (lint)
/*
@@ -4110,7 +4224,7 @@ kvtop_nohblk:
cmp %g5, MAX_HASHCNT
#else
cmp %g5, DEFAULT_MAX_HASHCNT /* no 32/256M kernel pages */
-#endif
+#endif /* sun4v */
be,a,pn %icc, 6f
mov -1, %o0 /* output = -1 (PFN_INVALID) */
mov %o1, %o4 /* restore hatid */
@@ -4126,7 +4240,7 @@ kvtop_nohblk:
move %icc, MMU_PAGESHIFT512K, %g6
ba,pt %icc, 1b
movne %icc, MMU_PAGESHIFT4M, %g6
-#endif
+#endif /* sun4v */
6:
retl
wrpr %g0, %o3, %pstate /* re-enable interrupts */
diff --git a/usr/src/uts/sfmmu/vm/hat_sfmmu.c b/usr/src/uts/sfmmu/vm/hat_sfmmu.c
index b81464137f..79dfe1b7d5 100644
--- a/usr/src/uts/sfmmu/vm/hat_sfmmu.c
+++ b/usr/src/uts/sfmmu/vm/hat_sfmmu.c
@@ -2967,6 +2967,12 @@ sfmmu_tteload_addentry(sfmmu_t *sfmmup, struct hme_blk *hmeblkp, tte_t *ttep,
panic("sfmmu_tteload: non cacheable memory tte");
#endif /* DEBUG */
+ /* don't simulate dirty bit for writeable ISM/DISM mappings */
+ if ((flags & HAT_LOAD_SHARE) && TTE_IS_WRITABLE(ttep)) {
+ TTE_SET_REF(ttep);
+ TTE_SET_MOD(ttep);
+ }
+
if ((flags & HAT_LOAD_SHARE) || !TTE_IS_REF(ttep) ||
!TTE_IS_MOD(ttep)) {
/*
@@ -9678,9 +9684,7 @@ sfmmu_get_ctx(sfmmu_t *sfmmup)
{
mmu_ctx_t *mmu_ctxp;
uint_t pstate_save;
-#ifdef sun4v
int ret;
-#endif
ASSERT(sfmmu_hat_lock_held(sfmmup));
ASSERT(sfmmup != ksfmmup);
@@ -9721,9 +9725,6 @@ sfmmu_get_ctx(sfmmu_t *sfmmup)
*/
pstate_save = sfmmu_disable_intrs();
-#ifdef sun4u
- (void) sfmmu_alloc_ctx(sfmmup, 1, CPU, SFMMU_PRIVATE);
-#else
if (sfmmu_alloc_ctx(sfmmup, 1, CPU, SFMMU_PRIVATE) &&
sfmmup->sfmmu_scdp != NULL) {
sf_scd_t *scdp = sfmmup->sfmmu_scdp;
@@ -9733,7 +9734,6 @@ sfmmu_get_ctx(sfmmu_t *sfmmup)
ASSERT(!ret || scsfmmup->sfmmu_ctxs[CPU_MMU_IDX(CPU)].cnum
!= INVALID_CONTEXT);
}
-#endif
sfmmu_load_mmustate(sfmmup);
sfmmu_enable_intrs(pstate_save);
@@ -13953,9 +13953,11 @@ hat_join_region(struct hat *sfmmup,
r_type = (r_type == HAT_REGION_ISM) ? SFMMU_REGION_ISM :
SFMMU_REGION_HME;
/*
- * Currently only support shared hmes for the main text region.
+ * Currently only support shared hmes for the read only main text
+ * region.
*/
- if (r_type == SFMMU_REGION_HME && r_obj != srdp->srd_evp) {
+ if (r_type == SFMMU_REGION_HME && ((r_obj != srdp->srd_evp) ||
+ (r_perm & PROT_WRITE))) {
return (HAT_INVALID_REGION_COOKIE);
}
diff --git a/usr/src/uts/sfmmu/vm/hat_sfmmu.h b/usr/src/uts/sfmmu/vm/hat_sfmmu.h
index 16ea7bcfae..92f238aafa 100644
--- a/usr/src/uts/sfmmu/vm/hat_sfmmu.h
+++ b/usr/src/uts/sfmmu/vm/hat_sfmmu.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,6 +56,7 @@ extern "C" {
* Don't alter these without considering changes to ism_map_t.
*/
#define DEFAULT_ISM_PAGESIZE MMU_PAGESIZE4M
+#define DEFAULT_ISM_PAGESZC TTE4M
#define ISM_PG_SIZE(ism_vbshift) (1 << ism_vbshift)
#define ISM_SZ_MASK(ism_vbshift) (ISM_PG_SIZE(ism_vbshift) - 1)
#define ISM_MAP_SLOTS 8 /* Change this carefully. */
@@ -859,6 +860,188 @@ struct ctx_trace {
#ifdef sun4v
#define USER_CONTEXT_TYPE NUM_LOCKED_CTXS
#endif
+#if defined(sun4v) || defined(UTSB_PHYS)
+/*
+ * Get the location in the 4MB base TSB of the tsbe for this fault.
+ * Assumes that the second TSB only contains 4M mappings.
+ *
+ * In:
+ * tagacc = tag access register (not clobbered)
+ * tsbe = 2nd TSB base register
+ * tmp1, tmp2 = scratch registers
+ * Out:
+ * tsbe = pointer to the tsbe in the 2nd TSB
+ */
+
+#define GET_4MBASE_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
+ and tsbe, TSB_SOFTSZ_MASK, tmp2; /* tmp2=szc */ \
+ andn tsbe, TSB_SOFTSZ_MASK, tsbe; /* tsbbase */ \
+ mov TSB_ENTRIES(0), tmp1; /* nentries in TSB size 0 */ \
+ sllx tmp1, tmp2, tmp1; /* tmp1 = nentries in TSB */ \
+ sub tmp1, 1, tmp1; /* mask = nentries - 1 */ \
+ srlx tagacc, MMU_PAGESHIFT4M, tmp2; \
+ and tmp2, tmp1, tmp1; /* tsbent = virtpage & mask */ \
+ sllx tmp1, TSB_ENTRY_SHIFT, tmp1; /* entry num --> ptr */ \
+ add tsbe, tmp1, tsbe /* add entry offset to TSB base */
+
+#define GET_2ND_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
+ GET_4MBASE_TSBE_PTR(tagacc, tsbe, tmp1, tmp2)
+
+/*
+ * Get the location in the 3rd TSB of the tsbe for this fault.
+ * The 3rd TSB corresponds to the shared context, and is used
+ * for 8K - 512k pages.
+ *
+ * In:
+ * tagacc = tag access register (not clobbered)
+ * tsbe, tmp1, tmp2 = scratch registers
+ * Out:
+ * tsbe = pointer to the tsbe in the 3rd TSB
+ */
+
+#define GET_3RD_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
+ and tsbe, TSB_SOFTSZ_MASK, tmp2; /* tmp2=szc */ \
+ andn tsbe, TSB_SOFTSZ_MASK, tsbe; /* tsbbase */ \
+ mov TSB_ENTRIES(0), tmp1; /* nentries in TSB size 0 */ \
+ sllx tmp1, tmp2, tmp1; /* tmp1 = nentries in TSB */ \
+ sub tmp1, 1, tmp1; /* mask = nentries - 1 */ \
+ srlx tagacc, MMU_PAGESHIFT, tmp2; \
+ and tmp2, tmp1, tmp1; /* tsbent = virtpage & mask */ \
+ sllx tmp1, TSB_ENTRY_SHIFT, tmp1; /* entry num --> ptr */ \
+ add tsbe, tmp1, tsbe /* add entry offset to TSB base */
+
+#define GET_4TH_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
+ GET_4MBASE_TSBE_PTR(tagacc, tsbe, tmp1, tmp2)
+/*
+ * Copy the sfmmu_region_map or scd_region_map to the tsbmiss
+ * shmermap or scd_shmermap, from sfmmu_load_mmustate.
+ */
+#define SET_REGION_MAP(rgn_map, tsbmiss_map, cnt, tmp, label) \
+ /* BEGIN CSTYLED */ \
+label: ;\
+ ldx [rgn_map], tmp ;\
+ dec cnt ;\
+ add rgn_map, CLONGSIZE, rgn_map ;\
+ stx tmp, [tsbmiss_map] ;\
+ brnz,pt cnt, label ;\
+ add tsbmiss_map, CLONGSIZE, tsbmiss_map \
+ /* END CSTYLED */
+
+/*
+ * If there is no scd, then zero the tsbmiss scd_shmermap,
+ * from sfmmu_load_mmustate.
+ */
+#define ZERO_REGION_MAP(tsbmiss_map, cnt, label) \
+ /* BEGIN CSTYLED */ \
+label: ;\
+ dec cnt ;\
+ stx %g0, [tsbmiss_map] ;\
+ brnz,pt cnt, label ;\
+ add tsbmiss_map, CLONGSIZE, tsbmiss_map
+ /* END CSTYLED */
+
+/*
+ * Set hmemisc to 1 if the shared hme is also part of an scd.
+ * In:
+ * tsbarea = tsbmiss area (not clobbered)
+ * hmeblkpa = hmeblkpa + hmentoff + SFHME_TTE (not clobbered)
+ * hmentoff = hmentoff + SFHME_TTE = tte offset(clobbered)
+ * Out:
+ * use_shctx = 1 if shme is in scd and 0 otherwise
+ */
+#define GET_SCDSHMERMAP(tsbarea, hmeblkpa, hmentoff, use_shctx) \
+ /* BEGIN CSTYLED */ \
+ sub hmeblkpa, hmentoff, hmentoff /* hmentofff = hmeblkpa */ ;\
+ add hmentoff, HMEBLK_TAG, hmentoff ;\
+ ldxa [hmentoff]ASI_MEM, hmentoff /* read 1st part of tag */ ;\
+ and hmentoff, HTAG_RID_MASK, hmentoff /* mask off rid */ ;\
+ and hmentoff, BT_ULMASK, use_shctx /* mask bit index */ ;\
+ srlx hmentoff, BT_ULSHIFT, hmentoff /* extract word */ ;\
+ sllx hmentoff, CLONGSHIFT, hmentoff /* index */ ;\
+ add tsbarea, hmentoff, hmentoff /* add to tsbarea */ ;\
+ ldx [hmentoff + TSBMISS_SCDSHMERMAP], hmentoff /* scdrgn */ ;\
+ srlx hmentoff, use_shctx, use_shctx ;\
+ and use_shctx, 0x1, use_shctx \
+ /* END CSTYLED */
+
+/*
+ * Synthesize a TSB base register contents for a process.
+ *
+ * In:
+ * tsbinfo = TSB info pointer (ro)
+ * tsbreg, tmp1 = scratch registers
+ * Out:
+ * tsbreg = value to program into TSB base register
+ */
+
+#define MAKE_UTSBREG(tsbinfo, tsbreg, tmp1) \
+ ldx [tsbinfo + TSBINFO_PADDR], tsbreg; \
+ lduh [tsbinfo + TSBINFO_SZCODE], tmp1; \
+ and tmp1, TSB_SOFTSZ_MASK, tmp1; \
+ or tsbreg, tmp1, tsbreg;
+
+
+/*
+ * Load TSB base register to TSBMISS area for privte contexts.
+ * This register contains utsb_pabase in bits 63:13, and TSB size
+ * code in bits 2:0.
+ *
+ * For private context
+ * In:
+ * tsbreg = value to load (ro)
+ * regnum = constant or register
+ * tmp1 = scratch register
+ * Out:
+ * Specified scratchpad register updated
+ *
+ */
+#define SET_UTSBREG(regnum, tsbreg, tmp1) \
+ mov regnum, tmp1; \
+ stxa tsbreg, [tmp1]ASI_SCRATCHPAD /* save tsbreg */
+/*
+ * Get TSB base register from the scratchpad for private contexts
+ *
+ * In:
+ * regnum = constant or register
+ * tsbreg = scratch
+ * Out:
+ * tsbreg = tsbreg from the specified scratchpad register
+ */
+#define GET_UTSBREG(regnum, tsbreg) \
+ mov regnum, tsbreg; \
+ ldxa [tsbreg]ASI_SCRATCHPAD, tsbreg
+
+/*
+ * Load TSB base register to TSBMISS area for shared contexts.
+ * This register contains utsb_pabase in bits 63:13, and TSB size
+ * code in bits 2:0.
+ *
+ * In:
+ * tsbmiss = pointer to tsbmiss area
+ * tsbmissoffset = offset to right tsb pointer
+ * tsbreg = value to load (ro)
+ * Out:
+ * Specified tsbmiss area updated
+ *
+ */
+#define SET_UTSBREG_SHCTX(tsbmiss, tsbmissoffset, tsbreg) \
+ stx tsbreg, [tsbmiss + tsbmissoffset] /* save tsbreg */
+
+/*
+ * Get TSB base register from the scratchpad for
+ * shared contexts
+ *
+ * In:
+ * tsbmiss = pointer to tsbmiss area
+ * tsbmissoffset = offset to right tsb pointer
+ * tsbreg = scratch
+ * Out:
+ * tsbreg = tsbreg from the specified scratchpad register
+ */
+#define GET_UTSBREG_SHCTX(tsbmiss, tsbmissoffset, tsbreg) \
+ ldx [tsbmiss + tsbmissoffset], tsbreg
+
+#endif /* defined(sun4v) || defined(UTSB_PHYS) */
#ifndef _ASM
@@ -1744,7 +1927,7 @@ extern size_t tsb_slab_mask;
* sun4u platforms that define UTSB_PHYS use physical addressing to access
* the user TSBs at TL>0. The first user TSB base is in the MMU I/D TSB Base
* registers. The second TSB base uses a dedicated scratchpad register which
- * requires a definition of SCRATCHPAD_UTSBREG in mach_sfmmu.h. The layout for
+ * requires a definition of SCRATCHPAD_UTSBREG2 in mach_sfmmu.h. The layout for
* both registers is equivalent to sun4v below, except the TSB PA range is
* [46..13] for sun4u.
*
diff --git a/usr/src/uts/sun4/ml/swtch.s b/usr/src/uts/sun4/ml/swtch.s
index f8892bd0c7..d19606ee84 100644
--- a/usr/src/uts/sun4/ml/swtch.s
+++ b/usr/src/uts/sun4/ml/swtch.s
@@ -19,10 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
+
#pragma ident "%Z%%M% %I% %E% SMI"
/*
@@ -263,7 +263,7 @@ resume(kthread_id_t t)
set SFMMU_PRIVATE, %o3 ! %o3 = sfmmu private flag
call sfmmu_alloc_ctx
mov %g0, %o1 ! %o1 = allocate flag = 0
-#ifdef sun4v
+
brz,a,pt %o0, 4f ! %o0 == 0, no private alloc'ed
nop
@@ -277,8 +277,6 @@ resume(kthread_id_t t)
call sfmmu_alloc_ctx
mov 1, %o1 ! %o1 = allocate flag = 1
-#endif
-
4:
call sfmmu_load_mmustate ! program MMU registers
mov %i5, %o0
diff --git a/usr/src/uts/sun4u/cpu/opl_olympus.c b/usr/src/uts/sun4u/cpu/opl_olympus.c
index 349b198ec3..3a76531e82 100644
--- a/usr/src/uts/sun4u/cpu/opl_olympus.c
+++ b/usr/src/uts/sun4u/cpu/opl_olympus.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -103,6 +103,11 @@ int cpu_berr_to_verbose = 0;
*/
int cpu_alljupiter = 0;
+/*
+ * The sfmmu_cext field to be used by processes in a shared context domain.
+ */
+static uchar_t shctx_cext = TAGACCEXT_MKSZPAIR(DEFAULT_ISM_PAGESZC, TTE8K);
+
static int min_ecache_size;
static uint_t priv_hcl_1;
static uint_t priv_hcl_2;
@@ -303,6 +308,11 @@ cpu_fix_alljupiter(void)
* hwcap semantics.
*/
cpu_hwcap_flags |= AV_SPARC_IMA;
+
+ /*
+ * Enable shared context support.
+ */
+ shctx_on = 1;
}
#ifdef OLYMPUS_C_REV_B_ERRATA_XCALL
@@ -803,7 +813,7 @@ mmu_large_pages_disabled(uint_t flag)
/*
* mmu_init_large_pages is called with the desired ism_pagesize parameter.
- * It may be called from set_platform_defaults, if some value other than 32M
+ * It may be called from set_platform_defaults, if some value other than 4M
* is desired. mmu_ism_pagesize is the tunable. If it has a bad value,
* then only warn, since it would be bad form to panic due to a user typo.
*
@@ -812,12 +822,14 @@ mmu_large_pages_disabled(uint_t flag)
void
mmu_init_large_pages(size_t ism_pagesize)
{
+
switch (ism_pagesize) {
case MMU_PAGESIZE4M:
mmu_disable_ism_large_pages = ((1 << TTE64K) |
(1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M));
mmu_disable_auto_data_large_pages = ((1 << TTE64K) |
(1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M));
+ shctx_cext = TAGACCEXT_MKSZPAIR(TTE4M, TTE8K);
break;
case MMU_PAGESIZE32M:
mmu_disable_ism_large_pages = ((1 << TTE64K) |
@@ -825,6 +837,7 @@ mmu_init_large_pages(size_t ism_pagesize)
mmu_disable_auto_data_large_pages = ((1 << TTE64K) |
(1 << TTE512K) | (1 << TTE4M) | (1 << TTE256M));
adjust_data_maxlpsize(ism_pagesize);
+ shctx_cext = TAGACCEXT_MKSZPAIR(TTE32M, TTE8K);
break;
case MMU_PAGESIZE256M:
mmu_disable_ism_large_pages = ((1 << TTE64K) |
@@ -832,6 +845,7 @@ mmu_init_large_pages(size_t ism_pagesize)
mmu_disable_auto_data_large_pages = ((1 << TTE64K) |
(1 << TTE512K) | (1 << TTE4M) | (1 << TTE32M));
adjust_data_maxlpsize(ism_pagesize);
+ shctx_cext = TAGACCEXT_MKSZPAIR(TTE256M, TTE8K);
break;
default:
cmn_err(CE_WARN, "Unrecognized mmu_ism_pagesize value 0x%lx",
@@ -844,7 +858,7 @@ mmu_init_large_pages(size_t ism_pagesize)
* Function to reprogram the TLBs when page sizes used
* by a process change significantly.
*/
-void
+static void
mmu_setup_page_sizes(struct hat *hat, uint64_t *ttecnt, uint8_t *tmp_pgsz)
{
uint8_t pgsz0, pgsz1;
@@ -909,11 +923,15 @@ mmu_set_ctx_page_sizes(struct hat *hat)
/*
* If supported, reprogram the TLBs to a larger pagesize.
*/
- pgsz0 = hat->sfmmu_pgsz[0];
- pgsz1 = hat->sfmmu_pgsz[1];
- ASSERT(pgsz0 < mmu_page_sizes);
- ASSERT(pgsz1 < mmu_page_sizes);
- new_cext = TAGACCEXT_MKSZPAIR(pgsz1, pgsz0);
+ if (hat->sfmmu_scdp != NULL) {
+ new_cext = shctx_cext;
+ } else {
+ pgsz0 = hat->sfmmu_pgsz[0];
+ pgsz1 = hat->sfmmu_pgsz[1];
+ ASSERT(pgsz0 < mmu_page_sizes);
+ ASSERT(pgsz1 < mmu_page_sizes);
+ new_cext = TAGACCEXT_MKSZPAIR(pgsz1, pgsz0);
+ }
if (hat->sfmmu_cext != new_cext) {
#ifdef DEBUG
int i;
diff --git a/usr/src/uts/sun4u/cpu/us3_common_mmu.c b/usr/src/uts/sun4u/cpu/us3_common_mmu.c
index 892be30295..157d6f7ec9 100644
--- a/usr/src/uts/sun4u/cpu/us3_common_mmu.c
+++ b/usr/src/uts/sun4u/cpu/us3_common_mmu.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -134,7 +134,7 @@ int init_mmu_page_sizes = 0;
/*
* mmu_init_large_pages is called with the desired ism_pagesize parameter,
* for Panther-only systems. It may be called from set_platform_defaults,
- * if some value other than 32M is desired, for Panther-only systems.
+ * if some value other than 4M is desired, for Panther-only systems.
* mmu_ism_pagesize is the tunable. If it has a bad value, then only warn,
* since it would be bad form to panic due
* to a user typo.
@@ -252,7 +252,7 @@ static uint64_t ttecnt_threshold[MMU_PAGE_SIZES] = {
* didn't fault any pages in. This allows the t512_1 to be reprogrammed,
* because the T16 does not support the two giant page sizes. ouch.
*/
-void
+static void
mmu_fixup_large_pages(struct hat *hat, uint64_t *ttecnt, uint8_t *tmp_pgsz)
{
uint_t pgsz0 = tmp_pgsz[0];
@@ -318,7 +318,7 @@ mmu_fixup_large_pages(struct hat *hat, uint64_t *ttecnt, uint8_t *tmp_pgsz)
* Function to set up the page size values used to reprogram the DTLBs,
* when page sizes used by a process change significantly.
*/
-void
+static void
mmu_setup_page_sizes(struct hat *hat, uint64_t *ttecnt, uint8_t *tmp_pgsz)
{
uint_t pgsz0, pgsz1;
diff --git a/usr/src/uts/sun4u/ml/mach_offsets.in b/usr/src/uts/sun4u/ml/mach_offsets.in
index 9ce9aea4fb..7d8df8a635 100644
--- a/usr/src/uts/sun4u/ml/mach_offsets.in
+++ b/usr/src/uts/sun4u/ml/mach_offsets.in
@@ -18,7 +18,7 @@
\
\ CDDL HEADER END
\
-\ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+\ Copyright 2008 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
\ offsets.in: input file to produce assym.h using the stabs program
@@ -99,47 +99,60 @@ trap_trace_record TRAP_ENT_SIZE
tt_f3 TRAP_ENT_F3
tt_f4 TRAP_ENT_F4
-hat HAT_SIZE
- sfmmu_cpusran
- sfmmu_tsb
- sfmmu_ismblkpa
- sfmmu_tteflags
- sfmmu_cext
- sfmmu_ctx_lock
- sfmmu_ctxs
+hat HAT_SIZE
+ sfmmu_cpusran
+ sfmmu_tsb
+ sfmmu_ismblkpa
+ sfmmu_tteflags
+ sfmmu_rtteflags
+ sfmmu_srdp
+ sfmmu_region_map.h_rmap_s.hmeregion_map SFMMU_HMERMAP
+ sfmmu_scdp
+ sfmmu_cext
+ sfmmu_ctx_lock
+ sfmmu_ctxs
+
+sf_scd SCD_SIZE
+ scd_sfmmup
+ scd_region_map.h_rmap_s.hmeregion_map SCD_HMERMAP
sfmmu_global_stat HATSTAT_SIZE
- sf_pagefaults HATSTAT_PAGEFAULT
- sf_uhash_searches HATSTAT_UHASH_SEARCH
- sf_uhash_links HATSTAT_UHASH_LINKS
- sf_khash_searches HATSTAT_KHASH_SEARCH
- sf_khash_links HATSTAT_KHASH_LINKS
-
-sf_hment SFHME_SIZE SFHME_SHIFT
- hme_tte SFHME_TTE
-
-tsbmiss TSBMISS_SIZE
- ksfmmup TSBMISS_KHATID
- usfmmup TSBMISS_UHATID
- tsbptr TSBMISS_TSBPTR
- tsbptr4m TSBMISS_TSBPTR4M
- ismblkpa TSBMISS_ISMBLKPA
- khashstart TSBMISS_KHASHSTART
- uhashstart TSBMISS_UHASHSTART
- khashsz TSBMISS_KHASHSZ
- uhashsz TSBMISS_UHASHSZ
- dcache_line_mask TSBMISS_DMASK
- uhat_tteflags TSBMISS_UTTEFLAGS
- uhat_rtteflags TSBMISS_URTTEFLAGS
- utsb_misses TSBMISS_UTSBMISS
- ktsb_misses TSBMISS_KTSBMISS
- uprot_traps TSBMISS_UPROTS
- kprot_traps TSBMISS_KPROTS
- scratch TSBMISS_SCRATCH
-
-\#define TSB_TAGACC (0 * TSBMISS_SCRATCH_INCR)
-\#define TSBMISS_HMEBP (1 * TSBMISS_SCRATCH_INCR)
-\#define TSBMISS_HATID (2 * TSBMISS_SCRATCH_INCR)
+ sf_pagefaults HATSTAT_PAGEFAULT
+ sf_uhash_searches HATSTAT_UHASH_SEARCH
+ sf_uhash_links HATSTAT_UHASH_LINKS
+ sf_khash_searches HATSTAT_KHASH_SEARCH
+ sf_khash_links HATSTAT_KHASH_LINKS
+
+sf_hment SFHME_SIZE SFHME_SHIFT
+ hme_tte SFHME_TTE
+
+tsbmiss TSBMISS_SIZE
+ ksfmmup TSBMISS_KHATID
+ usfmmup TSBMISS_UHATID
+ usrdp TSBMISS_SHARED_UHATID
+ tsbptr TSBMISS_TSBPTR
+ tsbptr4m TSBMISS_TSBPTR4M
+ tsbscdptr TSBMISS_TSBSCDPTR
+ tsbscdptr4m TSBMISS_TSBSCDPTR4M
+ ismblkpa TSBMISS_ISMBLKPA
+ khashstart TSBMISS_KHASHSTART
+ uhashstart TSBMISS_UHASHSTART
+ khashsz TSBMISS_KHASHSZ
+ uhashsz TSBMISS_UHASHSZ
+ dcache_line_mask TSBMISS_DMASK
+ uhat_tteflags TSBMISS_UTTEFLAGS
+ uhat_rtteflags TSBMISS_URTTEFLAGS
+ utsb_misses TSBMISS_UTSBMISS
+ ktsb_misses TSBMISS_KTSBMISS
+ uprot_traps TSBMISS_UPROTS
+ kprot_traps TSBMISS_KPROTS
+ scratch TSBMISS_SCRATCH
+ shmermap TSBMISS_SHMERMAP
+ scd_shmermap TSBMISS_SCDSHMERMAP
+
+\#define TSB_TAGACC (0 * TSBMISS_SCRATCH_INCR)
+\#define TSBMISS_HMEBP (1 * TSBMISS_SCRATCH_INCR)
+\#define TSBMISS_HATID (2 * TSBMISS_SCRATCH_INCR)
kpmtsbm KPMTSBM_SIZE KPMTSBM_SHIFT
vbase KPMTSBM_VBASE
diff --git a/usr/src/uts/sun4u/ml/trap_table.s b/usr/src/uts/sun4u/ml/trap_table.s
index bc20d95bee..8b8e15d926 100644
--- a/usr/src/uts/sun4u/ml/trap_table.s
+++ b/usr/src/uts/sun4u/ml/trap_table.s
@@ -19,10 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
+
#pragma ident "%Z%%M% %I% %E% SMI"
#if !defined(lint)
@@ -1076,15 +1076,13 @@ table_name/**/_dtlbmiss: ;\
srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\
cmp %g3, INVALID_CONTEXT ;\
ble,pn %xcc, sfmmu_kdtlb_miss ;\
+ srax %g2, PREDISM_BASESHIFT, %g6 /* g6 > 0 ISM predicted */ ;\
+ brgz,pn %g6, sfmmu_udtlb_slowpath_ismpred ;\
srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\
- mov SCRATCHPAD_UTSBREG, %g3 ;\
- ldxa [%g3]ASI_SCRATCHPAD, %g3 /* g3 = 2nd tsb reg */ ;\
- brgez,pn %g3, sfmmu_udtlb_slowpath /* branch if 2 TSBs */ ;\
- nop ;\
ldda [%g1]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, %g5 data */;\
cmp %g4, %g7 ;\
- bne,pn %xcc, sfmmu_tsb_miss_tt /* no 4M TSB, miss */ ;\
- mov -1, %g3 /* set 4M tsbe ptr to -1 */ ;\
+ bne,pn %xcc, sfmmu_udtlb_slowpath_noismpred ;\
+ nop ;\
TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\
stxa %g5, [%g0]ASI_DTLB_IN /* trapstat expects TTE */ ;\
retry /* in %g5 */ ;\
@@ -1097,10 +1095,13 @@ table_name/**/_dtlbmiss: ;\
unimp 0 ;\
unimp 0 ;\
unimp 0 ;\
- unimp 0 ;\
- unimp 0 ;\
- unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
.align 128
+
#else /* UTSB_PHYS */
#define DTLB_MISS(table_name) ;\
.global table_name/**/_dtlbmiss ;\
@@ -1158,41 +1159,42 @@ tt1_itlbmiss:
* MUST be EXACTLY 32 instructions or we'll break.
*/
#ifdef UTSB_PHYS
-#define ITLB_MISS(table_name) \
- .global table_name/**/_itlbmiss ;\
-table_name/**/_itlbmiss: ;\
- mov MMU_TAG_ACCESS, %g6 /* select tag acc */ ;\
- ldxa [%g0]ASI_IMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\
- ldxa [%g6]ASI_IMMU, %g2 /* g2 = tag access */ ;\
- sllx %g2, TAGACC_CTX_LSHIFT, %g3 ;\
- srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\
- cmp %g3, INVALID_CONTEXT ;\
- ble,pn %xcc, sfmmu_kitlb_miss ;\
- srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\
- mov SCRATCHPAD_UTSBREG, %g3 ;\
- ldxa [%g3]ASI_SCRATCHPAD, %g3 /* g3 = 2nd tsb reg */ ;\
- brgez,pn %g3, sfmmu_uitlb_slowpath /* branch if 2 TSBs */ ;\
- nop ;\
- ldda [%g1]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, g5 = data */ ;\
- cmp %g4, %g7 ;\
- bne,pn %xcc, sfmmu_tsb_miss_tt /* br if 8k ptr miss */ ;\
- mov -1, %g3 /* set 4M TSB ptr to -1 */ ;\
- andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
- bz,pn %icc, exec_fault ;\
- nop ;\
- TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\
- stxa %g5, [%g0]ASI_ITLB_IN /* trapstat expects %g5 */ ;\
- retry ;\
- unimp 0 ;\
- unimp 0 ;\
- unimp 0 ;\
- unimp 0 ;\
- unimp 0 ;\
- unimp 0 ;\
+#define ITLB_MISS(table_name) \
+ .global table_name/**/_itlbmiss ;\
+table_name/**/_itlbmiss: ;\
+ mov MMU_TAG_ACCESS, %g6 /* select tag acc */ ;\
+ ldxa [%g0]ASI_IMMU_TSB_8K, %g1 /* g1 = tsbe ptr */ ;\
+ ldxa [%g6]ASI_IMMU, %g2 /* g2 = tag access */ ;\
+ sllx %g2, TAGACC_CTX_LSHIFT, %g3 ;\
+ srlx %g3, TAGACC_CTX_LSHIFT, %g3 /* g3 = ctx */ ;\
+ cmp %g3, INVALID_CONTEXT ;\
+ ble,pn %xcc, sfmmu_kitlb_miss ;\
+ srlx %g2, TAG_VALO_SHIFT, %g7 /* g7 = tsb tag */ ;\
+ ldda [%g1]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, g5 = data */ ;\
+ cmp %g4, %g7 ;\
+ bne,pn %xcc, sfmmu_uitlb_slowpath ;\
+ andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
+ bz,pn %icc, exec_fault ;\
+ nop ;\
+ TT_TRACE(trace_tsbhit) /* 2 instr ifdef TRAPTRACE */ ;\
+ stxa %g5, [%g0]ASI_ITLB_IN /* trapstat expects %g5 */ ;\
+ retry ;\
unimp 0 ;\
unimp 0 ;\
unimp 0 ;\
- .align 128
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ unimp 0 ;\
+ .align 128
+
#else /* UTSB_PHYS */
#define ITLB_MISS(table_name) \
.global table_name/**/_itlbmiss ;\
diff --git a/usr/src/uts/sun4u/os/mach_cpu_states.c b/usr/src/uts/sun4u/os/mach_cpu_states.c
index 50c34ed97c..9e14ff1930 100644
--- a/usr/src/uts/sun4u/os/mach_cpu_states.c
+++ b/usr/src/uts/sun4u/os/mach_cpu_states.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -396,6 +396,8 @@ ptl1_panic_handler(ptl1_state_t *pstate)
"CPU ECC error loop", /* PTL1_BAD_ECC */
"non-kernel context in sys/priv_trap() below or",
/* PTL1_BAD_CTX */
+ "error raising a TSB exception", /* PTL1_BAD_RAISE_TSBEXCP */
+ "missing shared TSB" /* PTL1_NO_SCDTSB8K */
};
uint_t reason = pstate->ptl1_regs.ptl1_g1;
diff --git a/usr/src/uts/sun4u/sys/machparam.h b/usr/src/uts/sun4u/sys/machparam.h
index c53632a5eb..df9b11b794 100644
--- a/usr/src/uts/sun4u/sys/machparam.h
+++ b/usr/src/uts/sun4u/sys/machparam.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -325,6 +325,7 @@ extern "C" {
#define PTL1_BAD_ECC 13
#define PTL1_BAD_CTX 14
#define PTL1_BAD_RAISE_TSBEXCP 20
+#define PTL1_NO_SCDTSB8K 21
/*
* Defines used for ptl1 related data structs.
diff --git a/usr/src/uts/sun4u/sys/mmu.h b/usr/src/uts/sun4u/sys/mmu.h
index 8f0f8eb214..98db90182e 100644
--- a/usr/src/uts/sun4u/sys/mmu.h
+++ b/usr/src/uts/sun4u/sys/mmu.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -219,6 +219,17 @@ extern "C" {
#define CTXREG_NEXT_SHIFT 58
/*
+ * SPARC64-VII MMU SHARED CONTEXT register Layout
+ *
+ * +-----+----+-----+--------------------+-----+----+----+-------------------+
+ * | --- | IV | -- | Ishared ctx[44:32] | --- | DV | -- | Dshared ctx[12:0] |
+ * +-----+----+-----+--------------------+-----+----+----+-------------------+
+ * 63 48 47 46 45 44 32 31 16 15 14 13 12 0
+ */
+#define SHCTXREG_VALID_BIT 0x8000
+#define SHCTXREG_CTX_LSHIFT 51
+
+/*
* The kernel always runs in KCONTEXT, and no user mappings
* are ever valid in it (so any user access pagefaults).
*/
diff --git a/usr/src/uts/sun4u/sys/opl_olympus_regs.h b/usr/src/uts/sun4u/sys/opl_olympus_regs.h
index ff482ce8a6..89d9689816 100644
--- a/usr/src/uts/sun4u/sys/opl_olympus_regs.h
+++ b/usr/src/uts/sun4u/sys/opl_olympus_regs.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -213,7 +213,6 @@ extern "C" {
#define ASI_EIDR 0x6E /* Urgent errors */
#define ASI_CACHE_INV 0x74 /* Cache invalidation */
#define ASI_ERR_INJCT 0x76 /* Error injection */
-
/*
* Address of ASI scratch register. ASI 0x4F
*/
@@ -222,9 +221,9 @@ extern "C" {
#define OPL_SCRATCHPAD_SAVE_AG3 0x10 /* used for saving global registers */
#define OPL_SCRATCHPAD_ERRLOG 0x18 /* keeps EIDR, log's PA & err counter */
#define OPL_SCRATCHPAD_UTSBREG4 0x20
-#define OPL_SCRATCHPAD_UNUSED5 0x28
-#define OPL_SCRATCHPAD_UNUSED6 0x30
-#define OPL_SCRATCHPAD_UNUSED7 0x38
+#define OPL_SCRATCHPAD_UTSBREG5 0x28
+#define OPL_SCRATCHPAD_UTSBREG6 0x30
+#define OPL_SCRATCHPAD_UNUSED7 0x38
/*
* Error log scratchpad register format.
diff --git a/usr/src/uts/sun4u/vm/mach_sfmmu.h b/usr/src/uts/sun4u/vm/mach_sfmmu.h
index 3c5e43f24b..ced9a5729b 100644
--- a/usr/src/uts/sun4u/vm/mach_sfmmu.h
+++ b/usr/src/uts/sun4u/vm/mach_sfmmu.h
@@ -40,6 +40,7 @@
#include <sys/cheetahregs.h>
#include <sys/spitregs.h>
#include <sys/opl_olympus_regs.h>
+#include <sys/mmu.h>
#ifdef __cplusplus
extern "C" {
@@ -51,7 +52,7 @@ extern "C" {
* platform Makefile to access user TSBs via physical address but must also
* designate one ASI_SCRATCHPAD register to hold the second user TSB. To
* designate the user TSB scratchpad register, platforms must provide a
- * definition for SCRATCHPAD_UTSBREG below.
+ * definition for SCRATCHPAD_UTSBREG2 below.
*
* Platforms that use UTSB_PHYS do not allocate 2 locked TLB entries to access
* the user TSBs.
@@ -59,10 +60,12 @@ extern "C" {
#if defined(UTSB_PHYS)
#if defined(_OPL)
-#define SCRATCHPAD_UTSBREG OPL_SCRATCHPAD_UTSBREG4
+#define SCRATCHPAD_UTSBREG2 OPL_SCRATCHPAD_UTSBREG4 /* 4M-256M pages */
+#define SCRATCHPAD_UTSBREG3 OPL_SCRATCHPAD_UTSBREG5 /* 8K-512K pages */
+#define SCRATCHPAD_UTSBREG4 OPL_SCRATCHPAD_UTSBREG6 /* 4M-256M pages */
#else
-#error "Compiling UTSB_PHYS but no SCRATCHPAD_UTSBREG specified"
-#endif
+#error "Compiling UTSB_PHYS but no SCRATCHPAD_UTSBREG2 specified"
+#endif /* _OPL */
#endif /* UTSB_PHYS */
@@ -70,17 +73,45 @@ extern "C" {
#ifdef _ASM
/*
- * This macro is used to set private secondary context register in
+ * This macro is used to set private/shared secondary context register in
* sfmmu_alloc_ctx().
+ * if is_shctx = 0 then we set the SCONTEXT to cnum and invalidate the
+ * SHARED_CONTEXT register. If is_shctx = 1 then only the SHARED_CONTEXT
+ * register is set.
+ * (See additional comments in sfmmu_alloc_ctx)
* Input:
- * cnum : cnum
- * arg2 : unused
- */
-#define SET_SECCTX(cnum, arg2, tmp1, tmp2) \
- mov MMU_SCONTEXT, tmp1; \
- sethi %hi(FLUSH_ADDR), tmp2; \
- stxa cnum, [tmp1]ASI_MMU_CTX; \
- flush tmp2
+ * cnum = cnum
+ * is_shctx = sfmmu private/shared flag (0: private, 1: shared)
+ * tmp1 : %o4 scratch
+ * tmp2 : %o5 scratch
+ * label: used as local branch targets
+ */
+#define SET_SECCTX(cnum, is_shctx, tmp1, tmp2, label) \
+ /* BEGIN CSTYLED */ \
+ brnz,pn is_shctx, label/**/1 ;\
+ sethi %hi(FLUSH_ADDR), tmp2 ;\
+ mov MMU_SCONTEXT, tmp1 ;\
+ stxa cnum, [tmp1]ASI_MMU_CTX ;\
+ flush tmp2 ;\
+ sethi %hi(shctx_on), tmp1 ;\
+ ld [tmp1 + %lo(shctx_on)], tmp1 ;\
+ brz,pt tmp1, label/**/3 ;\
+ mov %g0, cnum ;\
+ ba,pt %xcc, label/**/2 ;\
+label/**/1: ;\
+ set SHCTXREG_VALID_BIT, tmp1 ;\
+ sllx cnum, CTXREG_CTX_SHIFT, cnum ;\
+ srlx cnum, CTXREG_CTX_SHIFT, cnum ;\
+ or cnum, tmp1, cnum ;\
+ mov cnum, tmp1 ;\
+ sllx cnum, 32, cnum ;\
+ or cnum, tmp1, cnum ;\
+label/**/2: ;\
+ mov MMU_SHARED_CONTEXT, tmp1 ;\
+ stxa cnum, [tmp1]ASI_MMU_CTX ;\
+ flush tmp2 ;\
+label/**/3:
+ /* END CSTYLED */
/*
* This macro is used in the MMU code to check if TL should be lowered from
@@ -94,7 +125,7 @@ extern "C" {
or scr2, %lo(KERNELBASE), scr2; \
cmp scr1, scr2; \
bgeu %xcc, 9f; \
- nop; \
+ nop; \
ba label; \
wrpr %g0, 1, %tl; \
9:
@@ -537,60 +568,9 @@ label/**/_get_2nd_tsb_base: ;\
/* tmp1 = TSB size code */ \
GET_TSBE_POINTER(MMU_PAGESHIFT4M, tsbe_ptr, tagacc, tmp1, tmp2)
-#endif /* UTSB_PHYS */
-
-
-#ifdef UTSB_PHYS
-
-/*
- * Synthesize a TSB base register contents for a process.
- *
- * In:
- * tsbinfo = TSB info pointer (ro)
- * tsbreg, tmp1 = scratch registers
- * Out:
- * tsbreg = value to program into TSB base register
- */
-
-#define MAKE_UTSBREG_PHYS(tsbinfo, tsbreg, tmp1) \
- ldx [tsbinfo + TSBINFO_PADDR], tsbreg; \
- lduh [tsbinfo + TSBINFO_SZCODE], tmp1; \
- and tmp1, TSB_SOFTSZ_MASK, tmp1; \
- or tsbreg, tmp1, tsbreg; \
-
-/*
- * Load TSB base register into a dedicated scratchpad register.
- * This register contains utsb_pabase in bits 63:13, and TSB size
- * code in bits 2:0.
- *
- * In:
- * tsbreg = value to load (ro)
- * regnum = constant or register
- * tmp1 = scratch register
- * Out:
- * Specified scratchpad register updated
- *
- * Note: If this is enabled on Panther, a membar #Sync is required
- * following an ASI store to the scratchpad registers.
- */
-
-#define SET_UTSBREG(regnum, tsbreg, tmp1) \
- mov regnum, tmp1; \
- stxa tsbreg, [tmp1]ASI_SCRATCHPAD; /* save tsbreg */ \
-/*
- * Get TSB base register from the scratchpad
- *
- * In:
- * regnum = constant or register
- * tsbreg = scratch
- * Out:
- * tsbreg = tsbreg from the specified scratchpad register
- */
+#else /* !UTSB_PHYS */
-#define GET_UTSBREG(regnum, tsbreg) \
- mov regnum, tsbreg; \
- ldxa [tsbreg]ASI_SCRATCHPAD, tsbreg
/*
* Determine the pointer of the entry in the first TSB to probe given
@@ -610,55 +590,7 @@ label/**/_get_2nd_tsb_base: ;\
#define GET_1ST_TSBE_PTR(tagacc, tsbe_ptr, tmp1, tmp2)
-/*
- * Get the location in the 2nd TSB of the tsbe for this fault.
- * Assumes that the second TSB only contains 4M mappings.
- *
- * In:
- * tagacc = tag access register (not clobbered)
- * tsbe = 2nd TSB base register
- * tmp1, tmp2 = scratch registers
- * Out:
- * tsbe = pointer to the tsbe in the 2nd TSB
- */
-
-#define GET_2ND_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
- and tsbe, TSB_SOFTSZ_MASK, tmp2; /* tmp2=szc */ \
- andn tsbe, TSB_SOFTSZ_MASK, tsbe; /* tsbbase */ \
- mov TSB_ENTRIES(0), tmp1; /* nentries in TSB size 0 */ \
- sllx tmp1, tmp2, tmp1; /* tmp1 = nentries in TSB */ \
- sub tmp1, 1, tmp1; /* mask = nentries - 1 */ \
- srlx tagacc, MMU_PAGESHIFT4M, tmp2; \
- and tmp2, tmp1, tmp1; /* tsbent = virtpage & mask */ \
- sllx tmp1, TSB_ENTRY_SHIFT, tmp1; /* entry num --> ptr */ \
- add tsbe, tmp1, tsbe /* add entry offset to TSB base */
-
-/*
- * Read the 2nd TSB base register. This is not done in GET_2ND_TSBE_PTR as
- * an optimization since the TLB miss trap handler entries have potentially
- * already loaded the 2nd TSB base reg when we invoke GET_2ND_TSBE_PTR.
- *
- * Out:
- * tsbreg = contents of the 2nd TSB base register
- */
-#define GET_2ND_TSBREG(tsbreg) \
- GET_UTSBREG(SCRATCHPAD_UTSBREG, tsbreg);
-
-/*
- * Load the 2nd TSB base into a dedicated scratchpad register which
- * is used as a pseudo TSB base register.
- *
- * In:
- * tsbreg = value to load (ro)
- * regnum = constant or register
- * tmp1 = scratch register
- * Out:
- * Specified scratchpad register updated
- */
-#define LOAD_2ND_TSBREG(tsbreg, tmp1) \
- SET_UTSBREG(SCRATCHPAD_UTSBREG, tsbreg, tmp1);
-
-#endif /* UTSB_PHYS */
+#endif /* !UTSB_PHYS */
/*
@@ -682,135 +614,180 @@ label/**/_get_2nd_tsb_base: ;\
#else
#define UTSB_PROBE_ASI ASI_NQUAD_LD
#endif
-
+#define PROBE_TSB(tsbe_ptr, tag, tsbtag, label) \
+ /* BEGIN CSTYLED */ \
+ ldda [tsbe_ptr]UTSB_PROBE_ASI, tsbtag ;\
+ cmp tsbtag, tag /* compare tag w/ TSB */ ;\
+ bne,pn %xcc, label/**/1 /* branch if !match */ ;\
+ nop \
+ /* END CSTYLED */
/*
- * Will probe the first TSB, and if it finds a match, will insert it
- * into the TLB and retry.
+ * Probe a TSB. If miss continue from the end of the macro for most probes
+ * except jump to TSB miss for 3rd ITSB probe. If hit retry faulted
+ * instruction for DTSB probes. For ITSB probes in case of TSB hit check
+ * execute bit and branch to exec_fault if the bit is not set otherwise retry
+ * faulted instruction. Do ITLB synthesis in case of hit in second ITSB if
+ * synthesis bit is set.
*
- * tsbe_ptr = precomputed first TSB entry pointer (in, ro)
+ * tsbe_ptr = precomputed TSB entry pointer (in, ro)
* vpg_4m = 4M virtual page number for tag matching (in, ro)
* label = where to branch to if this is a miss (text)
- * %asi = atomic ASI to use for the TSB access
*
* For trapstat, we have to explicily use these registers.
* g4 = location tag will be retrieved into from TSB (out)
* g5 = location data(tte) will be retrieved into from TSB (out)
+ *
+ * In case of first tsb probe tsbe_ptr is %g1. For other tsb probes
+ * move tsbe_ptr into %g1 in case of hit for traptrace.
+ *
+ * If the probe fails and we continue from call site %g4-%g5 are clobbered.
+ * 2nd ITSB probe macro will also clobber %g6 in this case.
*/
-#define PROBE_1ST_DTSB(tsbe_ptr, vpg_4m, label) /* g4/g5 clobbered */ \
- /* BEGIN CSTYLED */ \
- ldda [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\
- cmp %g4, vpg_4m /* compare tag w/ TSB */ ;\
- bne,pn %xcc, label/**/1 /* branch if !match */ ;\
- nop ;\
- TT_TRACE(trace_tsbhit) ;\
- DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
- /* trapstat expects tte in %g5 */ ;\
- retry /* retry faulted instruction */ ;\
-label/**/1: \
+#define PROBE_1ST_DTSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\
+ TT_TRACE(trace_tsbhit) ;\
+ DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
+ retry /* retry faulted instruction */ ;\
+label/**/1: \
/* END CSTYLED */
-/*
- * Same as above, only if the TTE doesn't have the execute
- * bit set, will branch to exec_fault directly.
- */
-#define PROBE_1ST_ITSB(tsbe_ptr, vpg_4m, label) \
- /* BEGIN CSTYLED */ \
- ldda [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\
- cmp %g4, vpg_4m /* compare tag w/ TSB */ ;\
- bne,pn %xcc, label/**/1 /* branch if !match */ ;\
- nop ;\
- andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
- bz,pn %icc, exec_fault ;\
- nop ;\
- TT_TRACE(trace_tsbhit) ;\
- ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
- retry /* retry faulted instruction */ ;\
-label/**/1: \
+#define PROBE_2ND_DTSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\
+ mov tsbe_ptr, %g1 /* trace_tsbhit wants ptr in %g1 */ ;\
+ TT_TRACE(trace_tsbhit) ;\
+ DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
+ retry /* retry faulted instruction */ ;\
+label/**/1: \
/* END CSTYLED */
-/*
- * vpg_4m = 4M virtual page number for tag matching (in)
- * tsbe_ptr = precomputed second TSB entry pointer (in)
- * label = label to use to make branch targets unique (text)
- *
- * For trapstat, we have to explicity use these registers.
- * g4 = tag portion of TSBE (out)
- * g5 = data portion of TSBE (out)
- */
-#define PROBE_2ND_DTSB(tsbe_ptr, vpg_4m, label) \
- /* BEGIN CSTYLED */ \
- ldda [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\
- /* since we are looking at 2nd tsb, if it's valid, it must be 4M */ ;\
- cmp %g4, vpg_4m ;\
- bne,pn %xcc, label/**/1 ;\
- nop ;\
- mov tsbe_ptr, %g1 /* trace_tsbhit wants ptr in %g1 */ ;\
- TT_TRACE(trace_tsbhit) ;\
- DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
- /* trapstat expects tte in %g5 */ ;\
- retry /* retry faulted instruction */ ;\
-label/**/1: \
+#define PROBE_1ST_ITSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\
+ andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
+ bz,pn %icc, exec_fault ;\
+ nop ;\
+ TT_TRACE(trace_tsbhit) ;\
+ ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
+ retry /* retry faulted instruction */ ;\
+label/**/1: \
/* END CSTYLED */
-/*
- * Macro to get SCD shared hme map on sun4v platforms
- * (not applicable to sun4u platforms)
- */
-#define GET_SCDSHMERMAP(tsbarea, hmeblkpa, hatid, hmemisc)
+#define PROBE_2ND_ITSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ ldda [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\
+ cmp %g4, vpg_4m /* compare tag w/ TSB */ ;\
+ bne,pn %xcc, label/**/2 /* branch if !match */ ;\
+ or %g0, TTE4M, %g6 ;\
+ andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
+ bz,a,pn %icc, label/**/1 ;\
+ sllx %g6, TTE_SZ_SHFT, %g6 ;\
+ mov tsbe_ptr, %g1 /* trap trace wants ptr in %g1 */ ;\
+ TT_TRACE(trace_tsbhit) ;\
+ ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
+ retry /* retry faulted instruction */ ;\
+label/**/1: ;\
+ andcc %g5, TTE_E_SYNTH_INT, %g0 ;\
+ bz,pn %icc, exec_fault ;\
+ mov tsbe_ptr, %g1 /* trap trace wants ptr in %g1 */ ;\
+ or %g5, %g6, %g5 ;\
+ TT_TRACE(trace_tsbhit) ;\
+ ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
+ retry /* retry faulted instruction */ ;\
+label/**/2:
+ /* END CSTYLED */
+
+#ifdef UTSB_PHYS
-#ifndef TRAPTRACE
/*
- * Same as above, with the following additions:
- * If the TTE found is not executable, branch directly
- * to exec_fault after checking for ITLB synthesis.
- * If a TSB miss, branch to TSB miss handler.
- */
-#define PROBE_2ND_ITSB(tsbe_ptr, vpg_4m, label) \
- /* BEGIN CSTYLED */ \
- ldda [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\
- cmp %g4, vpg_4m /* compare tag w/ TSB */ ;\
- bne,pn %xcc, sfmmu_tsb_miss_tt /* branch if !match */ ;\
- or %g0, TTE4M, %g6 ;\
- andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
- bz,a,pn %icc, label/**/1 ;\
- sllx %g6, TTE_SZ_SHFT, %g6 ;\
- ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
- retry /* retry faulted instruction */ ;\
-label/**/1: ;\
- andcc %g5, TTE_E_SYNTH_INT, %g0 ;\
- bz,pn %icc, exec_fault ;\
- or %g5, %g6, %g5 ;\
- ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
- retry /* retry faulted instruction */ \
+ * Updates the context filed in the tagaccess register with the shared
+ * context to force the next i/DTLB_STUFF() to load this mapping into
+ * the TLB with the shared context.
+ */
+#define SET_SHCTX_TAGACC(tmp1, tmp2, asi) \
+ /* BEGIN CSTYLED */ \
+ mov MMU_TAG_ACCESS, tmp2 ;\
+ ldxa [tmp2]asi, tmp2 /* tmp2 = VA|CTX */ ;\
+ srlx tmp2, TAGACC_SHIFT, tmp2 ;\
+ sllx tmp2, TAGACC_SHIFT, tmp2 /* tmp2 = VA */ ;\
+ mov MMU_SHARED_CONTEXT, tmp1 /* clobber tsbe_ptr */ ;\
+ ldxa [tmp1]ASI_MMU_CTX, tmp1 /* tmp2 = shctx reg */ ;\
+ sllx tmp1, SHCTXREG_CTX_LSHIFT, tmp1 ;\
+ srlx tmp1, SHCTXREG_CTX_LSHIFT, tmp1 /* tmp1 = SHCTX */ ;\
+ or tmp1, tmp2, tmp1 /* tmp1 = VA|SHCTX */ ;\
+ mov MMU_TAG_ACCESS, tmp2 ;\
+ stxa tmp1, [tmp2]asi /* asi = VA|SHCTX */
+ /* END CSTYLED */
+
+#define PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\
+ mov tsbe_ptr, %g1 /* trace_tsbhit wants ptr in %g1 */ ;\
+ TT_TRACE(trace_tsbhit) ;\
+ SET_SHCTX_TAGACC(%g3, %g4, ASI_DMMU) ;\
+ DTLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
+ retry /* retry faulted instruction */ ;\
+label/**/1: \
+ /* END CSTYLED */
+
+#define PROBE_3RD_DTSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label) ;\
+ /* END CSTYLED */
+
+#define PROBE_4TH_DTSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_SHCTX_DTSB(tsbe_ptr, vpg_4m, label) ;\
/* END CSTYLED */
-#else /* TRAPTRACE */
+
+#define PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_TSB(tsbe_ptr, vpg_4m, %g4, label) ;\
+ andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
+ bz,pn %icc, exec_fault ;\
+ mov tsbe_ptr, %g1 /* for traptrace sake */ ;\
+ TT_TRACE(trace_tsbhit) ;\
+ SET_SHCTX_TAGACC(%g3, %g4, ASI_IMMU) ;\
+ ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
+ retry /* retry faulted instruction */ ;\
+label/**/1:
+ /* END CSTYLED */
+
+#define PROBE_3RD_ITSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, sfmmu_tsb_miss_tt) ;\
+ /* END CSTYLED */
+
+#define PROBE_4TH_ITSB(tsbe_ptr, vpg_4m, label) \
+ /* BEGIN CSTYLED */ \
+ PROBE_SHCTX_ITSB(tsbe_ptr, vpg_4m, label) ;\
+ /* END CSTYLED */
+
/*
- * Same as above, with the TT_TRACE and mov tsbe_ptr, %g1 additions.
- */
-#define PROBE_2ND_ITSB(tsbe_ptr, vpg_4m, label) \
- /* BEGIN CSTYLED */ \
- ldda [tsbe_ptr]UTSB_PROBE_ASI, %g4 /* g4 = tag, g5 = data */ ;\
- cmp %g4, vpg_4m /* compare tag w/ TSB */ ;\
- bne,pn %xcc, sfmmu_tsb_miss_tt /* branch if !match */ ;\
- or %g0, TTE4M, %g6 ;\
- andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */ ;\
- bz,a,pn %icc, label/**/1 ;\
- sllx %g6, TTE_SZ_SHFT, %g6 ;\
- mov tsbe_ptr, %g1 /* trap trace wants ptr in %g1 */ ;\
- TT_TRACE(trace_tsbhit) ;\
- ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
- retry /* retry faulted instruction */ ;\
-label/**/1: ;\
- andcc %g5, TTE_E_SYNTH_INT, %g0 ;\
- bz,pn %icc, exec_fault ;\
- mov tsbe_ptr, %g1 /* trap trace wants ptr in %g1 */ ;\
- or %g5, %g6, %g5 ;\
- TT_TRACE(trace_tsbhit) ;\
- ITLB_STUFF(%g5, %g1, %g2, %g3, %g4) ;\
- retry /* retry faulted instruction */ \
+ * The traptype is supplied by caller.
+ *
+ * If iTSB miss, store shctx into IMMU TAG ACCESS REG
+ * If dTSB miss, store shctx into DMMU TAG ACCESS REG
+ * Thus the [D|I]TLB_STUFF will work as expected.
+ */
+#define SAVE_CTX1(traptype, tmp1, tmp2, label) \
+ /* BEGIN CSTYLED */ \
+ cmp traptype, FAST_IMMU_MISS_TT ;\
+ be,pn %icc, label/**/1 ;\
+ nop ;\
+ SET_SHCTX_TAGACC(tmp1, tmp2, ASI_DMMU) ;\
+ membar #Sync ;\
+ ba,a label/**/2 ;\
+label/**/1: ;\
+ SET_SHCTX_TAGACC(tmp1, tmp2, ASI_IMMU) ;\
+ sethi %hi(FLUSH_ADDR), tmp1 ;\
+ flush tmp1 ;\
+label/**/2:
/* END CSTYLED */
-#endif /* TRAPTRACE */
+#endif /* UTSB_PHYS */
+
#endif /* _ASM */
#ifdef __cplusplus
diff --git a/usr/src/uts/sun4u/vm/mach_sfmmu_asm.s b/usr/src/uts/sun4u/vm/mach_sfmmu_asm.s
index a9737b13e1..43df08b89e 100644
--- a/usr/src/uts/sun4u/vm/mach_sfmmu_asm.s
+++ b/usr/src/uts/sun4u/vm/mach_sfmmu_asm.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -96,7 +96,7 @@ sfmmu_load_mmustate(sfmmu_t *sfmmup)
}
#else /* lint */
-
+
/*
* Invalidate either the context of a specific victim or any process
* currently running on this CPU.
@@ -107,91 +107,71 @@ sfmmu_load_mmustate(sfmmu_t *sfmmup)
*/
ENTRY(sfmmu_raise_tsb_exception)
!
- ! if (victim == INVALID_CONTEXT) {
+ ! if (victim == INVALID_CONTEXT ||
+ ! current CPU tsbmiss->usfmmup == victim sfmmup) {
+ ! if (shctx_on) {
+ ! shctx = INVALID;
+ ! }
! if (sec-ctx > INVALID_CONTEXT) {
! write INVALID_CONTEXT to sec-ctx
! }
! if (pri-ctx > INVALID_CONTEXT) {
! write INVALID_CONTEXT to pri-ctx
! }
- ! } else if (current CPU tsbmiss->usfmmup != victim sfmmup) {
- ! return
- ! } else {
- ! if (sec-ctx > INVALID_CONTEXT)
- ! write INVALID_CONTEXT to sec-ctx
- !
- ! if (pri-ctx > INVALID_CONTEXT)
- ! write INVALID_CONTEXT to pri-ctx
! }
- !
sethi %hi(ksfmmup), %g3
ldx [%g3 + %lo(ksfmmup)], %g3
cmp %g1, %g3
- be,a,pn %xcc, ptl1_panic /* can't invalidate kernel ctx */
+ be,a,pn %xcc, ptl1_panic /* can't invalidate kernel ctx */
mov PTL1_BAD_RAISE_TSBEXCP, %g1
set INVALID_CONTEXT, %g2
-
cmp %g1, INVALID_CONTEXT
- bne,pt %xcc, 1f /* called from wrap_around? */
+ be,pn %xcc, 0f /* called from wrap_around? */
mov MMU_SCONTEXT, %g3
+ CPU_TSBMISS_AREA(%g5, %g6) /* load cpu tsbmiss area */
+ ldx [%g5 + TSBMISS_UHATID], %g5 /* load usfmmup */
+ cmp %g5, %g1 /* hat toBe-invalid running? */
+ bne,pt %xcc, 3f
+ nop
+
+0:
+ sethi %hi(shctx_on), %g5
+ ld [%g5 + %lo(shctx_on)], %g5
+ brz %g5, 1f
+ mov MMU_SHARED_CONTEXT, %g5
+ sethi %hi(FLUSH_ADDR), %g4
+ stxa %g0, [%g5]ASI_MMU_CTX
+ flush %g4
+
+1:
ldxa [%g3]ASI_MMU_CTX, %g5 /* %g5 = pgsz | sec-ctx */
set CTXREG_CTX_MASK, %g4
and %g5, %g4, %g5 /* %g5 = sec-ctx */
cmp %g5, INVALID_CONTEXT /* kernel ctx or invald ctx? */
- ble,pn %xcc, 0f /* yes, no need to change */
- mov MMU_PCONTEXT, %g7
+ ble,pn %xcc, 2f /* yes, no need to change */
+ mov MMU_PCONTEXT, %g7
stxa %g2, [%g3]ASI_MMU_CTX /* set invalid ctx */
membar #Sync
-0:
+2:
ldxa [%g7]ASI_MMU_CTX, %g3 /* get pgz | pri-ctx */
and %g3, %g4, %g5 /* %g5 = pri-ctx */
cmp %g5, INVALID_CONTEXT /* kernel ctx or invald ctx? */
- ble,pn %xcc, 2f /* yes, no need to change */
+ ble,pn %xcc, 3f /* yes, no need to change */
srlx %g3, CTXREG_NEXT_SHIFT, %g3 /* %g3 = nucleus pgsz */
sllx %g3, CTXREG_NEXT_SHIFT, %g3 /* need to preserve nucleus pgsz */
or %g3, %g2, %g2 /* %g2 = nucleus pgsz | INVALID_CONTEXT */
stxa %g2, [%g7]ASI_MMU_CTX /* set pri-ctx to invalid */
- retry
-
-1:
- /* %g3 = MMU_SCONTEXT */
- CPU_TSBMISS_AREA(%g5, %g6) /* load cpu tsbmiss area */
- ldx [%g5 + TSBMISS_UHATID], %g5 /* load usfmmup */
-
- cmp %g5, %g1 /* hat toBe-invalid running? */
- bne,pt %xcc, 2f
- nop
-
- ldxa [%g3]ASI_MMU_CTX, %g5 /* %g5 = pgsz | sec-ctx */
- set CTXREG_CTX_MASK, %g4
- and %g5, %g4, %g5 /* %g5 = sec-ctx */
- cmp %g5, INVALID_CONTEXT /* kernel or invalid ctx ? */
- ble,pn %xcc, 0f /* yes, no need to change */
- mov MMU_PCONTEXT, %g7
-
- stxa %g2, [%g3]ASI_MMU_CTX /* set sec-ctx to invalid */
- membar #Sync
-
-0:
- ldxa [%g7]ASI_MMU_CTX, %g3 /* %g3 = pgsz | pri-ctx */
- set CTXREG_CTX_MASK, %g6
- and %g3, %g6, %g4 /* %g4 = pri-ctx */
- cmp %g4, INVALID_CONTEXT /* is pri-ctx the victim? */
- ble %icc, 2f /* no, no need to change it */
- srlx %g3, CTXREG_NEXT_SHIFT, %g3 /* %g3 = nucleus pgsz */
- sllx %g3, CTXREG_NEXT_SHIFT, %g3 /* need to preserve nucleus pgsz */
- or %g3, %g2, %g2 /* %g2 = nucleus pgsz | INVALID_CONTEXT */
- stxa %g2, [%g7]ASI_MMU_CTX /* set pri-ctx to invalid */
- /* next instruction is retry so no membar sync */
-2:
+3:
retry
SET_SIZE(sfmmu_raise_tsb_exception)
+
+
/*
* %o0 = virtual address
@@ -389,16 +369,28 @@ sfmmu_load_mmustate(sfmmu_t *sfmmup)
sethi %hi(FLUSH_ADDR), %o4
stxa %o0, [%o1]ASI_MMU_CTX /* set 2nd context reg. */
flush %o4
+ sethi %hi(shctx_on), %g3
+ ld [%g3 + %lo(shctx_on)], %g3
+ brz %g3, 2f
+ nop
+ set CTXREG_CTX_MASK, %o4
+ and %o0,%o4,%o1
+ cmp %o1, INVALID_CONTEXT
+ bne,pn %icc, 2f
+ mov MMU_SHARED_CONTEXT, %o1
+ sethi %hi(FLUSH_ADDR), %o4
+ stxa %g0, [%o1]ASI_MMU_CTX /* set 2nd context reg. */
+ flush %o4
/*
* if the routine was entered with intr enabled, then enable intr now.
* otherwise, keep intr disabled, return without enabing intr.
* %g1 - old intr state
*/
- btst PSTATE_IE, %g1
- bnz,a,pt %icc, 2f
+2: btst PSTATE_IE, %g1
+ bnz,a,pt %icc, 3f
wrpr %g0, %g1, %pstate /* enable interrupts */
-2: retl
+3: retl
nop
SET_SIZE(sfmmu_setctx_sec)
@@ -433,93 +425,167 @@ sfmmu_load_mmustate(sfmmu_t *sfmmup)
* only be called from TL=0.
*
* %o0 - hat pointer
+ *
*/
ENTRY_NP(sfmmu_load_mmustate)
#ifdef DEBUG
- PANIC_IF_INTR_ENABLED_PSTR(msfmmu_ei_l3, %g1)
+ PANIC_IF_INTR_ENABLED_PSTR(msfmmu_ei_l3, %g1)
#endif /* DEBUG */
- sethi %hi(ksfmmup), %o3
- ldx [%o3 + %lo(ksfmmup)], %o3
- cmp %o3, %o0
- be,pn %xcc, 3f ! if kernel as, do nothing
- nop
-
- /*
- * We need to set up the TSB base register, tsbmiss
- * area, and load locked TTE(s) for the TSB.
- */
- ldx [%o0 + SFMMU_TSB], %o1 ! %o1 = first tsbinfo
- ldx [%o1 + TSBINFO_NEXTPTR], %g2 ! %g2 = second tsbinfo
+ sethi %hi(ksfmmup), %o3
+ ldx [%o3 + %lo(ksfmmup)], %o3
+ cmp %o3, %o0
+ be,pn %xcc, 8f ! if kernel as, do nothing
+ nop
+ /*
+ * We need to set up the TSB base register, tsbmiss
+ * area, and load locked TTE(s) for the TSB.
+ */
+ ldx [%o0 + SFMMU_TSB], %o1 ! %o1 = first tsbinfo
+ ldx [%o1 + TSBINFO_NEXTPTR], %g2 ! %g2 = second tsbinfo
#ifdef UTSB_PHYS
- /*
- * UTSB_PHYS accesses user TSBs via physical addresses. The first
- * TSB is in the MMU I/D TSB Base registers. The second TSB uses a
- * designated ASI_SCRATCHPAD register as a pseudo TSB base register.
+ /*
+ * UTSB_PHYS accesses user TSBs via physical addresses. The first
+ * TSB is in the MMU I/D TSB Base registers. The 2nd, 3rd and
+ * 4th TSBs use designated ASI_SCRATCHPAD regs as pseudo TSB base regs.
*/
- MAKE_UTSBREG_PHYS(%o1, %o2, %o3) ! %o2 = first utsbreg
- LOAD_TSBREG(%o2, %o3, %o4) ! write TSB base register
+
+ /* create/set first UTSBREG actually loaded into MMU_TSB */
+ MAKE_UTSBREG(%o1, %o2, %o3) ! %o2 = first utsbreg
+ LOAD_TSBREG(%o2, %o3, %o4) ! write TSB base register
- brz,a,pt %g2, 2f
- mov -1, %o2 ! use -1 if no second TSB
+ brz,a,pt %g2, 2f
+ mov -1, %o2 ! use -1 if no second TSB
- MAKE_UTSBREG_PHYS(%g2, %o2, %o3) ! %o2 = second utsbreg
+ MAKE_UTSBREG(%g2, %o2, %o3) ! %o2 = second utsbreg
2:
- LOAD_2ND_TSBREG(%o2, %o3) ! write 2nd pseudo TSB base register
-#else /* UTSB_PHYS */
- brz,pt %g2, 4f
- nop
- /*
- * We have a second TSB for this process, so we need to
- * encode data for both the first and second TSB in our single
- * TSB base register. See hat_sfmmu.h for details on what bits
- * correspond to which TSB.
- * We also need to load a locked TTE into the TLB for the second TSB
- * in this case.
- */
- MAKE_TSBREG_SECTSB(%o2, %o1, %g2, %o3, %o4, %g3, sfmmu_tsb_2nd)
- ! %o2 = tsbreg
- sethi %hi(utsb4m_dtlb_ttenum), %o3
- sethi %hi(utsb4m_vabase), %o4
- ld [%o3 + %lo(utsb4m_dtlb_ttenum)], %o3
- ldx [%o4 + %lo(utsb4m_vabase)], %o4 ! %o4 = TLB tag for sec TSB
- sll %o3, DTACC_SHIFT, %o3 ! %o3 = sec TSB TLB index
- RESV_OFFSET(%g2, %o4, %g3, sfmmu_tsb_2nd) ! or-in bits of TSB VA
- LOAD_TSBTTE(%g2, %o3, %o4, %g3) ! load sec TSB locked TTE
- sethi %hi(utsb_vabase), %g3
- ldx [%g3 + %lo(utsb_vabase)], %g3 ! %g3 = TLB tag for first TSB
- ba,pt %xcc, 5f
- nop
+ SET_UTSBREG(SCRATCHPAD_UTSBREG2, %o2, %o3)
-4: sethi %hi(utsb_vabase), %g3
- ldx [%g3 + %lo(utsb_vabase)], %g3 ! %g3 = TLB tag for first TSB
- MAKE_TSBREG(%o2, %o1, %g3, %o3, %o4, sfmmu_tsb_1st) ! %o2 = tsbreg
+ /* make 3rd and 4th TSB */
+ CPU_TSBMISS_AREA(%o4, %o3) ! %o4 = tsbmiss area
-5: LOAD_TSBREG(%o2, %o3, %o4) ! write TSB base register
+ ldx [%o0 + SFMMU_SCDP], %g2 ! %g2 = sfmmu_scd
+ brz,pt %g2, 3f
+ mov -1, %o2 ! use -1 if no third TSB
- /*
- * Load the TTE for the first TSB at the appropriate location in
- * the TLB
- */
- sethi %hi(utsb_dtlb_ttenum), %o2
- ld [%o2 + %lo(utsb_dtlb_ttenum)], %o2
- sll %o2, DTACC_SHIFT, %o2 ! %o1 = first TSB TLB index
- RESV_OFFSET(%o1, %g3, %o3, sfmmu_tsb_1st) ! or-in bits of TSB VA
- LOAD_TSBTTE(%o1, %o2, %g3, %o4) ! load first TSB locked TTE
-#endif /* UTSB_PHYS */
+ ldx [%g2 + SCD_SFMMUP], %g3 ! %g3 = scdp->scd_sfmmup
+ ldx [%g3 + SFMMU_TSB], %o1 ! %o1 = first scd tsbinfo
+ brz,pn %o1, 5f
+ nop ! panic if no third TSB
-6: ldx [%o0 + SFMMU_ISMBLKPA], %o1 ! copy members of sfmmu
- CPU_TSBMISS_AREA(%o2, %o3) ! we need to access from
- stx %o1, [%o2 + TSBMISS_ISMBLKPA] ! sfmmu_tsb_miss into the
- ldub [%o0 + SFMMU_TTEFLAGS], %o3 ! per-CPU tsbmiss area.
- stx %o0, [%o2 + TSBMISS_UHATID]
- stub %o3, [%o2 + TSBMISS_UTTEFLAGS]
+ /* make 3rd UTSBREG */
+ MAKE_UTSBREG(%o1, %o2, %o3) ! %o2 = third utsbreg
+3:
+ SET_UTSBREG(SCRATCHPAD_UTSBREG3, %o2, %o3)
+ stn %o2, [%o4 + TSBMISS_TSBSCDPTR]
-3: retl
+ brz,pt %g2, 4f
+ mov -1, %o2 ! use -1 if no 3rd or 4th TSB
+
+ ldx [%o1 + TSBINFO_NEXTPTR], %g2 ! %g2 = second scd tsbinfo
+ brz,pt %g2, 4f
+ mov -1, %o2 ! use -1 if no 4th TSB
+
+ /* make 4th UTSBREG */
+ MAKE_UTSBREG(%g2, %o2, %o3) ! %o2 = fourth utsbreg
+4:
+ SET_UTSBREG(SCRATCHPAD_UTSBREG4, %o2, %o3)
+ stn %o2, [%o4 + TSBMISS_TSBSCDPTR4M]
+ ba,pt %icc, 6f
+ mov %o4, %o2 ! %o2 = tsbmiss area
+5:
+ sethi %hi(panicstr), %g1 ! panic if no 3rd TSB
+ ldx [%g1 + %lo(panicstr)], %g1
+ tst %g1
+
+ bnz,pn %xcc, 8f
+ nop
+
+ sethi %hi(sfmmu_panic10), %o0
+ call panic
+ or %o0, %lo(sfmmu_panic10), %o0
+
+#else /* UTSBREG_PHYS */
+
+ brz,pt %g2, 4f
+ nop
+ /*
+ * We have a second TSB for this process, so we need to
+ * encode data for both the first and second TSB in our single
+ * TSB base register. See hat_sfmmu.h for details on what bits
+ * correspond to which TSB.
+ * We also need to load a locked TTE into the TLB for the second TSB
+ * in this case.
+ */
+ MAKE_TSBREG_SECTSB(%o2, %o1, %g2, %o3, %o4, %g3, sfmmu_tsb_2nd)
+ ! %o2 = tsbreg
+ sethi %hi(utsb4m_dtlb_ttenum), %o3
+ sethi %hi(utsb4m_vabase), %o4
+ ld [%o3 + %lo(utsb4m_dtlb_ttenum)], %o3
+ ldx [%o4 + %lo(utsb4m_vabase)], %o4 ! %o4 = TLB tag for sec TSB
+ sll %o3, DTACC_SHIFT, %o3 ! %o3 = sec TSB TLB index
+ RESV_OFFSET(%g2, %o4, %g3, sfmmu_tsb_2nd) ! or-in bits of TSB VA
+ LOAD_TSBTTE(%g2, %o3, %o4, %g3) ! load sec TSB locked TTE
+ sethi %hi(utsb_vabase), %g3
+ ldx [%g3 + %lo(utsb_vabase)], %g3 ! %g3 = TLB tag for first TSB
+ ba,pt %xcc, 5f
+ nop
+
+4: sethi %hi(utsb_vabase), %g3
+ ldx [%g3 + %lo(utsb_vabase)], %g3 ! %g3 = TLB tag for first TSB
+ MAKE_TSBREG(%o2, %o1, %g3, %o3, %o4, sfmmu_tsb_1st) ! %o2 = tsbreg
+
+5: LOAD_TSBREG(%o2, %o3, %o4) ! write TSB base register
+
+ /*
+ * Load the TTE for the first TSB at the appropriate location in
+ * the TLB
+ */
+ sethi %hi(utsb_dtlb_ttenum), %o2
+ ld [%o2 + %lo(utsb_dtlb_ttenum)], %o2
+ sll %o2, DTACC_SHIFT, %o2 ! %o1 = first TSB TLB index
+ RESV_OFFSET(%o1, %g3, %o3, sfmmu_tsb_1st) ! or-in bits of TSB VA
+ LOAD_TSBTTE(%o1, %o2, %g3, %o4) ! load first TSB locked TTE
+ CPU_TSBMISS_AREA(%o2, %o3)
+#endif /* UTSB_PHYS */
+6:
+ ldx [%o0 + SFMMU_ISMBLKPA], %o1 ! copy members of sfmmu
+ ! we need to access from
+ stx %o1, [%o2 + TSBMISS_ISMBLKPA] ! sfmmu_tsb_miss into the
+ ldub [%o0 + SFMMU_TTEFLAGS], %o3 ! per-CPU tsbmiss area.
+ stx %o0, [%o2 + TSBMISS_UHATID]
+ stub %o3, [%o2 + TSBMISS_UTTEFLAGS]
+#ifdef UTSB_PHYS
+ ldx [%o0 + SFMMU_SRDP], %o1
+ ldub [%o0 + SFMMU_RTTEFLAGS], %o4
+ stub %o4, [%o2 + TSBMISS_URTTEFLAGS]
+ stx %o1, [%o2 + TSBMISS_SHARED_UHATID]
+ brz,pn %o1, 8f ! check for sfmmu_srdp
+ add %o0, SFMMU_HMERMAP, %o1
+ add %o2, TSBMISS_SHMERMAP, %o2
+ mov SFMMU_HMERGNMAP_WORDS, %o3
+ ! set tsbmiss shmermap
+ SET_REGION_MAP(%o1, %o2, %o3, %o4, load_shme_mmustate)
+
+ ldx [%o0 + SFMMU_SCDP], %o4 ! %o4 = sfmmu_scd
+ CPU_TSBMISS_AREA(%o2, %o3) ! %o2 = tsbmiss area
+ mov SFMMU_HMERGNMAP_WORDS, %o3
+ brnz,pt %o4, 7f ! check for sfmmu_scdp else
+ add %o2, TSBMISS_SCDSHMERMAP, %o2 ! zero tsbmiss scd_shmermap
+ ZERO_REGION_MAP(%o2, %o3, zero_scd_mmustate)
+ ba 8f
nop
- SET_SIZE(sfmmu_load_mmustate)
+7:
+ add %o4, SCD_HMERMAP, %o1
+ SET_REGION_MAP(%o1, %o2, %o3, %o4, load_scd_mmustate)
+#endif /* UTSB_PHYS */
+
+8:
+ retl
+ nop
+ SET_SIZE(sfmmu_load_mmustate)
#endif /* lint */
@@ -657,6 +723,3 @@ prefetch_tsbe_write(struct tsbe *tsbep)
SET_SIZE(prefetch_tsbe_write)
#endif /* lint */
-
-#ifndef lint
-#endif /* lint */
diff --git a/usr/src/uts/sun4v/vm/mach_sfmmu.h b/usr/src/uts/sun4v/vm/mach_sfmmu.h
index 06ae00fc32..8c6ccbd268 100644
--- a/usr/src/uts/sun4v/vm/mach_sfmmu.h
+++ b/usr/src/uts/sun4v/vm/mach_sfmmu.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -73,7 +73,7 @@ struct hv_tsb_block {
* cnum = cnum
* is_shctx = sfmmu private/shared flag (0: private, 1: shared)
*/
-#define SET_SECCTX(cnum, is_shctx, tmp1, tmp2) \
+#define SET_SECCTX(cnum, is_shctx, tmp1, tmp2, label) \
mov MMU_SCONTEXT, tmp1; \
movrnz is_shctx, MMU_SCONTEXT1, tmp1; \
sethi %hi(FLUSH_ADDR), tmp2; \
@@ -376,75 +376,6 @@ label/**/1: \
or tte, TTE_HWWR_INT | TTE_REF_INT, tte; \
label/**/2: \
/* END CSTYLED */
-
-
-/*
- * Synthesize a TSB base register contents for a process.
- *
- * In:
- * tsbinfo = TSB info pointer (ro)
- * tsbreg, tmp1 = scratch registers
- * Out:
- * tsbreg = value to program into TSB base register
- */
-
-#define MAKE_UTSBREG(tsbinfo, tsbreg, tmp1) \
- ldx [tsbinfo + TSBINFO_PADDR], tsbreg; \
- lduh [tsbinfo + TSBINFO_SZCODE], tmp1; \
- and tmp1, TSB_SOFTSZ_MASK, tmp1; \
- or tsbreg, tmp1, tsbreg;
-
-
-/*
- * Load TSB base register into a dedicated scratchpad register
- * for private contexts.
- * Load TSB base register to TSBMISS area for shared contexts.
- * This register contains utsb_pabase in bits 63:13, and TSB size
- * code in bits 2:0.
- *
- * For private context
- * In:
- * tsbreg = value to load (ro)
- * regnum = constant or register
- * tmp1 = scratch register
- * Out:
- * Specified scratchpad register updated
- *
- */
-#define SET_UTSBREG(regnum, tsbreg, tmp1) \
- mov regnum, tmp1; \
- stxa tsbreg, [tmp1]ASI_SCRATCHPAD /* save tsbreg */
-
-/*
- * Load TSB base register to TSBMISS area for shared contexts.
- * This register contains utsb_pabase in bits 63:13, and TSB size
- * code in bits 2:0.
- *
- * In:
- * tsbmiss = pointer to tsbmiss area
- * tsbmissoffset = offset to right tsb pointer
- * tsbreg = value to load (ro)
- * Out:
- * Specified tsbmiss area updated
- *
- */
-#define SET_UTSBREG_SHCTX(tsbmiss, tsbmissoffset, tsbreg) \
- stx tsbreg, [tsbmiss + tsbmissoffset] /* save tsbreg */
-
-/*
- * Get TSB base register from the scratchpad for
- * private contexts
- *
- * In:
- * regnum = constant or register
- * tsbreg = scratch
- * Out:
- * tsbreg = tsbreg from the specified scratchpad register
- */
-#define GET_UTSBREG(regnum, tsbreg) \
- mov regnum, tsbreg; \
- ldxa [tsbreg]ASI_SCRATCHPAD, tsbreg
-
/*
* Get TSB base register from the scratchpad for
* shared contexts
@@ -536,32 +467,6 @@ label/**/1: \
label/**/1: \
/* END CSTYLED */
-
-/*
- * Get the location in the 2nd TSB of the tsbe for this fault.
- * Assumes that the second TSB only contains 4M mappings.
- *
- * In:
- * tagacc = tag access register (not clobbered)
- * tsbe, tmp1, tmp2 = scratch registers
- * Out:
- * tsbe = pointer to the tsbe in the 2nd TSB
- */
-
-#define GET_2ND_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
- mov SCRATCHPAD_UTSBREG2, tmp1; \
- ldxa [tmp1]ASI_SCRATCHPAD, tsbe; /* get tsbreg */ \
- and tsbe, TSB_SOFTSZ_MASK, tmp2; /* tmp2=szc */ \
- andn tsbe, TSB_SOFTSZ_MASK, tsbe; /* tsbbase */ \
- mov TSB_ENTRIES(0), tmp1; /* nentries in TSB size 0 */ \
- sllx tmp1, tmp2, tmp1; /* tmp1 = nentries in TSB */ \
- sub tmp1, 1, tmp1; /* mask = nentries - 1 */ \
- srlx tagacc, MMU_PAGESHIFT4M, tmp2; \
- and tmp2, tmp1, tmp1; /* tsbent = virtpage & mask */ \
- sllx tmp1, TSB_ENTRY_SHIFT, tmp1; /* entry num --> ptr */ \
- add tsbe, tmp1, tsbe /* add entry offset to TSB base */
-
-
/*
* vpg_4m = 4M virtual page number for tag matching (in)
* tsbe_ptr = precomputed second TSB entry pointer (in)
@@ -610,105 +515,6 @@ label/**/1: \
retry /* retry faulted instruction */ \
/* END CSTYLED */
-
-/*
- * Get the location in the 3rd TSB of the tsbe for this fault.
- * The 3rd TSB corresponds to the shared context, and is used
- * for 8K - 512k pages.
- *
- * In:
- * tagacc = tag access register (not clobbered)
- * tsbe = TSB base register
- * tmp1, tmp2 = scratch registers
- * Out:
- * tsbe = pointer to the tsbe in the 3rd TSB
- */
-#define GET_3RD_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
- and tsbe, TSB_SOFTSZ_MASK, tmp2; /* tmp2=szc */ \
- andn tsbe, TSB_SOFTSZ_MASK, tsbe; /* tsbbase */ \
- mov TSB_ENTRIES(0), tmp1; /* nentries in TSB size 0 */ \
- sllx tmp1, tmp2, tmp1; /* tmp1 = nentries in TSB */ \
- sub tmp1, 1, tmp1; /* mask = nentries - 1 */ \
- srlx tagacc, MMU_PAGESHIFT, tmp2; \
- and tmp2, tmp1, tmp1; /* tsbent = virtpage & mask */ \
- sllx tmp1, TSB_ENTRY_SHIFT, tmp1; /* entry num --> ptr */ \
- add tsbe, tmp1, tsbe /* add entry offset to TSB base */
-
-
-/*
- * Get the location in the 4th TSB of the tsbe for this fault.
- * The 4th TSB is for the shared context. It is used for 4M - 256M pages.
- *
- * In:
- * tagacc = tag access register (not clobbered)
- * tsbe = TSB base register
- * tmp1, tmp2 = scratch registers
- * Out:
- * tsbe = pointer to the tsbe in the 4th TSB
- */
-#define GET_4TH_TSBE_PTR(tagacc, tsbe, tmp1, tmp2) \
- and tsbe, TSB_SOFTSZ_MASK, tmp2; /* tmp2=szc */ \
- andn tsbe, TSB_SOFTSZ_MASK, tsbe; /* tsbbase */ \
- mov TSB_ENTRIES(0), tmp1; /* nentries in TSB size 0 */ \
- sllx tmp1, tmp2, tmp1; /* tmp1 = nentries in TSB */ \
- sub tmp1, 1, tmp1; /* mask = nentries - 1 */ \
- srlx tagacc, MMU_PAGESHIFT4M, tmp2; \
- and tmp2, tmp1, tmp1; /* tsbent = virtpage & mask */ \
- sllx tmp1, TSB_ENTRY_SHIFT, tmp1; /* entry num --> ptr */ \
- add tsbe, tmp1, tsbe /* add entry offset to TSB base */
-
-/*
- * Copy the sfmmu_region_map or scd_region_map to the tsbmiss
- * shmermap or scd_shmermap, from sfmmu_load_mmustate.
- */
-#define SET_REGION_MAP(rgn_map, tsbmiss_map, cnt, tmp, label) \
- /* BEGIN CSTYLED */ \
-label: ;\
- ldx [rgn_map], tmp ;\
- dec cnt ;\
- add rgn_map, CLONGSIZE, rgn_map ;\
- stx tmp, [tsbmiss_map] ;\
- brnz,pt cnt, label ;\
- add tsbmiss_map, CLONGSIZE, tsbmiss_map \
- /* END CSTYLED */
-
-/*
- * If there is no scd, then zero the tsbmiss scd_shmermap,
- * from sfmmu_load_mmustate.
- */
-#define ZERO_REGION_MAP(tsbmiss_map, cnt, label) \
- /* BEGIN CSTYLED */ \
-label: ;\
- dec cnt ;\
- stx %g0, [tsbmiss_map] ;\
- brnz,pt cnt, label ;\
- add tsbmiss_map, CLONGSIZE, tsbmiss_map \
- /* END CSTYLED */
-
-/*
- * Set hmemisc to 1 if the shared hme is also part of an scd.
- * In:
- * tsbarea = tsbmiss area (not clobbered)
- * hmeblkpa = hmeblkpa + hmentoff + SFHME_TTE (not clobbered)
- * hmentoff = hmentoff + SFHME_TTE = tte offset(clobbered)
- * Out:
- * use_shctx = 1 if shme is in scd and 0 otherwise
- */
-#define GET_SCDSHMERMAP(tsbarea, hmeblkpa, hmentoff, use_shctx) \
- /* BEGIN CSTYLED */ \
- sub hmeblkpa, hmentoff, hmentoff /* hmentofff = hmeblkpa */ ;\
- add hmentoff, HMEBLK_TAG, hmentoff ;\
- ldxa [hmentoff]ASI_MEM, hmentoff /* read 1st part of tag */ ;\
- and hmentoff, HTAG_RID_MASK, hmentoff /* mask off rid */ ;\
- and hmentoff, BT_ULMASK, use_shctx /* mask bit index */ ;\
- srlx hmentoff, BT_ULSHIFT, hmentoff /* extract word */ ;\
- sllx hmentoff, CLONGSHIFT, hmentoff /* index */ ;\
- add tsbarea, hmentoff, hmentoff /* add to tsbarea */ ;\
- ldx [hmentoff + TSBMISS_SCDSHMERMAP], hmentoff /* scdrgn */ ;\
- srlx hmentoff, use_shctx, use_shctx ;\
- and use_shctx, 0x1, use_shctx \
- /* END CSTYLED */
-
/*
* 1. Get ctx1. The traptype is supplied by caller.
* 2. If iTSB miss, store in MMFSA_I_CTX