diff options
author | jake <jake@FreeBSD.org> | 2001-08-06 02:34:20 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2001-08-06 02:34:20 +0000 |
commit | a4c9d3930da86ce541eba1b03a73d8a019737ed8 (patch) | |
tree | 30d3db4529431955e0daefeff0752ab97e2d3175 /sys | |
parent | da5146baa04a5623b0cf1ad7287f3c712da12011 (diff) | |
download | FreeBSD-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.c | 31 |
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); |