mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Merge jmallett@'s n64 work into HEAD - changeset 8
Updated PTE/PDE macros from http://svn.freebsd.org/base/user/jmallett/octeon Introduce pmap_segshift() macro, use pmap_segmap() in place of pmap_pde, and remove pmap_pde(). Approved by: rrs (mentor) Obtained from: jmallett@
This commit is contained in:
parent
900d6c6a00
commit
44fa0bf256
3 changed files with 41 additions and 31 deletions
|
|
@ -50,7 +50,6 @@
|
|||
#include <machine/pte.h>
|
||||
|
||||
#define NKPT 120 /* actual number of kernel page tables */
|
||||
#define NUSERPGTBLS (VM_MAXUSER_ADDRESS >> SEGSHIFT)
|
||||
|
||||
#ifndef LOCORE
|
||||
|
||||
|
|
@ -97,7 +96,6 @@ typedef struct pmap *pmap_t;
|
|||
#ifdef _KERNEL
|
||||
|
||||
pt_entry_t *pmap_pte(pmap_t, vm_offset_t);
|
||||
pd_entry_t pmap_segmap(pmap_t pmap, vm_offset_t va);
|
||||
vm_offset_t pmap_kextract(vm_offset_t va);
|
||||
|
||||
#define vtophys(va) pmap_kextract(((vm_offset_t) (va)))
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@
|
|||
#ifndef _MACHINE_PTE_H_
|
||||
#define _MACHINE_PTE_H_
|
||||
|
||||
#ifndef _LOCORE
|
||||
/* pt_entry_t is 32 bit for now, has to be made 64 bit for n64 */
|
||||
typedef uint32_t pt_entry_t;
|
||||
typedef pt_entry_t *pd_entry_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TLB and PTE management. Most things operate within the context of
|
||||
* EntryLo0,1, and begin with TLBLO_. Things which work with EntryHi
|
||||
|
|
@ -65,25 +71,20 @@
|
|||
#define TLBLO_PTE_TO_PA(pte) (TLBLO_PFN_TO_PA(TLBLO_PTE_TO_PFN((pte))))
|
||||
|
||||
/*
|
||||
* XXX This comment is not correct for anything more modern than R4K.
|
||||
*
|
||||
* VPN for EntryHi register. Upper two bits select user, supervisor,
|
||||
* or kernel. Bits 61 to 40 copy bit 63. VPN2 is bits 39 and down to
|
||||
* as low as 13, down to PAGE_SHIFT, to index 2 TLB pages*. From bit 12
|
||||
* to bit 8 there is a 5-bit 0 field. Low byte is ASID.
|
||||
*
|
||||
* XXX This comment is not correct for FreeBSD.
|
||||
* Note that in FreeBSD, we map 2 TLB pages is equal to 1 VM page.
|
||||
*/
|
||||
#define TLBHI_ASID_MASK (0xff)
|
||||
#define TLBHI_PAGE_MASK (2 * PAGE_SIZE - 1)
|
||||
#define TLBHI_ENTRY(va, asid) (((va) & ~TLBHI_PAGE_MASK) | ((asid) & TLBHI_ASID_MASK))
|
||||
|
||||
#ifndef _LOCORE
|
||||
typedef uint32_t pt_entry_t;
|
||||
typedef pt_entry_t *pd_entry_t;
|
||||
#endif
|
||||
|
||||
#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
|
||||
#define PTESIZE sizeof(pt_entry_t) /* for assembly files */
|
||||
|
||||
/*
|
||||
* TLB flags managed in hardware:
|
||||
* C: Cache attribute.
|
||||
|
|
|
|||
|
|
@ -118,14 +118,25 @@ __FBSDID("$FreeBSD$");
|
|||
|
||||
/*
|
||||
* Get PDEs and PTEs for user/kernel address space
|
||||
*
|
||||
* XXX The & for pmap_segshift() is wrong, as is the fact that it doesn't
|
||||
* trim off gratuitous bits of the address space. By having the &
|
||||
* there, we break defining NUSERPGTBLS below because the address space
|
||||
* is defined such that it ends immediately after NPDEPG*NPTEPG*PAGE_SIZE,
|
||||
* so we end up getting NUSERPGTBLS of 0.
|
||||
*/
|
||||
#define pmap_pde(m, v) (&((m)->pm_segtab[(vm_offset_t)(v) >> SEGSHIFT]))
|
||||
#define segtab_pde(m, v) (m[(vm_offset_t)(v) >> SEGSHIFT])
|
||||
#define pmap_segshift(v) (((v) >> SEGSHIFT) & (NPDEPG - 1))
|
||||
#define segtab_pde(m, v) ((m)[pmap_segshift((v))])
|
||||
|
||||
#define MIPS_SEGSIZE (1L << SEGSHIFT)
|
||||
#define mips_segtrunc(va) ((va) & ~(MIPS_SEGSIZE-1))
|
||||
#define NUSERPGTBLS (pmap_segshift(VM_MAXUSER_ADDRESS))
|
||||
#define mips_segtrunc(va) ((va) & ~SEGOFSET)
|
||||
#define is_kernel_pmap(x) ((x) == kernel_pmap)
|
||||
#define vad_to_pte_offset(adr) (((adr) >> PAGE_SHIFT) & (NPTEPG -1))
|
||||
|
||||
/*
|
||||
* Given a virtual address, get the offset of its PTE within its page
|
||||
* directory page.
|
||||
*/
|
||||
#define PDE_OFFSET(va) (((vm_offset_t)(va) >> PAGE_SHIFT) & (NPTEPG - 1))
|
||||
|
||||
struct pmap kernel_pmap_store;
|
||||
pd_entry_t *kernel_segmap;
|
||||
|
|
@ -246,13 +257,13 @@ static struct local_sysmaps sysmap_lmem[MAXCPU];
|
|||
sysm->valid2 = 0; \
|
||||
intr_restore(intr)
|
||||
|
||||
pd_entry_t
|
||||
static inline pt_entry_t *
|
||||
pmap_segmap(pmap_t pmap, vm_offset_t va)
|
||||
{
|
||||
if (pmap->pm_segtab)
|
||||
return (pmap->pm_segtab[((vm_offset_t)(va) >> SEGSHIFT)]);
|
||||
if (pmap->pm_segtab != NULL)
|
||||
return (segtab_pde(pmap->pm_segtab, va));
|
||||
else
|
||||
return ((pd_entry_t)0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -267,9 +278,9 @@ pmap_pte(pmap_t pmap, vm_offset_t va)
|
|||
pt_entry_t *pdeaddr;
|
||||
|
||||
if (pmap) {
|
||||
pdeaddr = (pt_entry_t *)pmap_segmap(pmap, va);
|
||||
pdeaddr = pmap_segmap(pmap, va);
|
||||
if (pdeaddr) {
|
||||
return pdeaddr + vad_to_pte_offset(va);
|
||||
return pdeaddr + PDE_OFFSET(va);
|
||||
}
|
||||
}
|
||||
return ((pt_entry_t *)0);
|
||||
|
|
@ -878,12 +889,12 @@ pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte)
|
|||
return (0);
|
||||
|
||||
if (mpte == NULL) {
|
||||
ptepindex = (va >> SEGSHIFT);
|
||||
ptepindex = pmap_segshift(va);
|
||||
if (pmap->pm_ptphint &&
|
||||
(pmap->pm_ptphint->pindex == ptepindex)) {
|
||||
mpte = pmap->pm_ptphint;
|
||||
} else {
|
||||
pteva = *pmap_pde(pmap, va);
|
||||
pteva = pmap_segmap(pmap, va);
|
||||
mpte = PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS(pteva));
|
||||
pmap->pm_ptphint = mpte;
|
||||
}
|
||||
|
|
@ -1082,7 +1093,7 @@ pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags)
|
|||
/*
|
||||
* Calculate pagetable page index
|
||||
*/
|
||||
ptepindex = va >> SEGSHIFT;
|
||||
ptepindex = pmap_segshift(va);
|
||||
retry:
|
||||
/*
|
||||
* Get the page directory entry
|
||||
|
|
@ -1205,7 +1216,7 @@ pmap_growkernel(vm_offset_t addr)
|
|||
|
||||
nkpt++;
|
||||
pte = (pt_entry_t *)pageva;
|
||||
segtab_pde(kernel_segmap, kernel_vm_end) = (pd_entry_t)pte;
|
||||
segtab_pde(kernel_segmap, kernel_vm_end) = pte;
|
||||
|
||||
/*
|
||||
* The R[4-7]?00 stores only one copy of the Global bit in
|
||||
|
|
@ -1529,8 +1540,8 @@ pmap_remove(struct pmap *pmap, vm_offset_t sva, vm_offset_t eva)
|
|||
goto out;
|
||||
}
|
||||
for (va = sva; va < eva; va = nva) {
|
||||
if (!*pmap_pde(pmap, va)) {
|
||||
nva = mips_segtrunc(va + MIPS_SEGSIZE);
|
||||
if (pmap_segmap(pmap, va) == NULL) {
|
||||
nva = mips_segtrunc(va + NBSEG);
|
||||
continue;
|
||||
}
|
||||
pmap_remove_page(pmap, va);
|
||||
|
|
@ -1646,8 +1657,8 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
|
|||
/*
|
||||
* If segment table entry is empty, skip this segment.
|
||||
*/
|
||||
if (!*pmap_pde(pmap, sva)) {
|
||||
sva = mips_segtrunc(sva + MIPS_SEGSIZE);
|
||||
if (pmap_segmap(pmap, sva) == NULL) {
|
||||
sva = mips_segtrunc(sva + NBSEG);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
|
|
@ -1934,7 +1945,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
|
|||
/*
|
||||
* Calculate pagetable page index
|
||||
*/
|
||||
ptepindex = va >> SEGSHIFT;
|
||||
ptepindex = pmap_segshift(va);
|
||||
if (mpte && (mpte->pindex == ptepindex)) {
|
||||
mpte->wire_count++;
|
||||
} else {
|
||||
|
|
@ -2619,7 +2630,7 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
|
|||
|
||||
rv = FALSE;
|
||||
PMAP_LOCK(pmap);
|
||||
if (*pmap_pde(pmap, addr)) {
|
||||
if (pmap_segmap(pmap, addr) != NULL) {
|
||||
pte = pmap_pte(pmap, addr);
|
||||
rv = (*pte == 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue