summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-08-06 02:34:20 +0000
committerjake <jake@FreeBSD.org>2001-08-06 02:34:20 +0000
commita4c9d3930da86ce541eba1b03a73d8a019737ed8 (patch)
tree30d3db4529431955e0daefeff0752ab97e2d3175 /sys
parentda5146baa04a5623b0cf1ad7287f3c712da12011 (diff)
downloadFreeBSD-src-a4c9d3930da86ce541eba1b03a73d8a019737ed8.zip
FreeBSD-src-a4c9d3930da86ce541eba1b03a73d8a019737ed8.tar.gz
Handle dmmu protection faults as well as misses. Enable tracking of
the modify and reference tte bits. Implementing allocating of tsb pages. Make tsb_stte_lookup do the right thing with the kernel pmap.
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/sparc64/tsb.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/sys/sparc64/sparc64/tsb.c b/sys/sparc64/sparc64/tsb.c
index 1a7af7b..1aea590 100644
--- a/sys/sparc64/sparc64/tsb.c
+++ b/sys/sparc64/sparc64/tsb.c
@@ -95,13 +95,25 @@ int
tsb_miss(pmap_t pm, u_int type, struct mmuframe *mf)
{
struct stte *stp;
+ struct tte tte;
vm_offset_t va;
- va = mf->mf_tar;
+ va = TLB_TAR_VA(mf->mf_tar);
if ((stp = tsb_stte_lookup(pm, va)) == NULL)
return (EFAULT);
switch (type) {
- case T_DMMU_MISS:
+ case T_DMMU_MISS | T_KERNEL:
+ stp->st_tte.tte_data |= TD_REF;
+ tte = stp->st_tte;
+ if ((tte.tte_data & TD_MOD) == 0)
+ tte.tte_data &= ~TD_W;
+ tlb_store(TLB_DTLB, va, tte);
+ break;
+ case T_DMMU_PROT | T_KERNEL:
+ if ((stp->st_tte.tte_data & TD_W) == 0)
+ return (EFAULT);
+ tlb_page_demap(TLB_DTLB, TLB_CTX_KERNEL, va);
+ stp->st_tte.tte_data |= TD_MOD;
tlb_store(TLB_DTLB, va, stp->st_tte);
break;
default:
@@ -114,10 +126,16 @@ struct tte
tsb_page_alloc(pmap_t pm, vm_offset_t va)
{
struct tte tte;
+ vm_offset_t pa;
+ vm_page_t m;
- /* XXX */
- tte.tte_tag = 0;
- tte.tte_data = 0;
+ m = vm_page_alloc(pm->pm_object, pm->pm_pages++, VM_ALLOC_SYSTEM);
+ if (m == NULL)
+ panic("tsb_page_alloc: vm_page_alloc\n");
+ pa = VM_PAGE_TO_PHYS(m);
+ tte.tte_tag = TT_CTX(TLB_CTX_KERNEL) | TT_VA(va);
+ tte.tte_data = TD_V | TD_8K | TD_VA_LOW(va) | TD_PA(pa) | TD_L |
+ TD_MOD | TD_REF | TD_CP | TD_P | TD_W;
return (tte);
}
@@ -160,6 +178,9 @@ tsb_stte_lookup(pmap_t pm, vm_offset_t va)
u_int level;
u_int i;
+ if (pm == kernel_pmap)
+ return tsb_kvtostte(va);
+
va = trunc_page(va);
for (level = 0; level < TSB_DEPTH; level++) {
bucket = tsb_get_bucket(pm, level, va, 0);
OpenPOWER on IntegriCloud