diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2002-03-13 18:27:38 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2002-03-13 18:27:38 +0000 |
commit | a1860f1123d6ff6c0e2ae4d174a3fb1d3e7af930 (patch) | |
tree | 06b8861b479b041d6e2924d0eeb2a96c4d9bd777 /sys/arch/powerpc/include | |
parent | ade140d2f64c0286ec3f0a8cc5634f5221b420a3 (diff) |
Complete rewrite of the powerpc pmap handling, Instead of keeping
the spill list for each PTEG, the V->P translations are stored in
trees for each pmap. All valid kernel mappings are preallocated
in 1-1 memory so that tlb spill/loads for kernel accesses can be
looked up while physical, user mappings are not guaranteed to
be 1-1 mapped, thus the kernel must go virtual to look up user
mappings. While this is more expensive, the tree search is much
lower cost than the long linked list search. Also on each pmap_remove()
it was necessary to search the linked lists for each possible mapping,
now it just looks up the entry in the tree.
This change gives a 25-36% speedup in 'make build' time. What was
around 2:50 is now around 1:55 on a 733MHz G4.
This change causes a likely existing bug to appear quite often,
it deals with the segment register invalidation in kernel mode.
Because of that problem, currently this change limits the physical
memory used to 256MB. This limitation will be fixed soon, it is not
an error in the pmap code.
* Effort sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F30602-01-2-0537.
Diffstat (limited to 'sys/arch/powerpc/include')
-rw-r--r-- | sys/arch/powerpc/include/param.h | 8 | ||||
-rw-r--r-- | sys/arch/powerpc/include/pmap.h | 52 | ||||
-rw-r--r-- | sys/arch/powerpc/include/pte.h | 10 |
3 files changed, 43 insertions, 27 deletions
diff --git a/sys/arch/powerpc/include/param.h b/sys/arch/powerpc/include/param.h index 3128717c74a..4d6ecbe46ab 100644 --- a/sys/arch/powerpc/include/param.h +++ b/sys/arch/powerpc/include/param.h @@ -1,4 +1,4 @@ -/* $OpenBSD: param.h,v 1.19 2001/12/05 01:57:15 provos Exp $ */ +/* $OpenBSD: param.h,v 1.20 2002/03/13 18:27:36 drahn Exp $ */ /* $NetBSD: param.h,v 1.1 1996/09/30 16:34:28 ws Exp $ */ /*- @@ -122,9 +122,9 @@ */ #define USER_SR 13 #define KERNEL_SR 14 -#define KERNEL_SEGMENT (0xfffff0 + KERNEL_SR) -#define EMPTY_SEGMENT 0xfffff0 -#define USER_ADDR ((void *)(USER_SR << ADDR_SR_SHFT)) +#define KERNEL_SEG0 0xfffff0 +#define KERNEL_SEGMENT (KERNEL_SEG0 + KERNEL_SR) +#define USER_ADDR ((void *)(USER_SR << ADDR_SR_SHIFT)) /* * Some system constants diff --git a/sys/arch/powerpc/include/pmap.h b/sys/arch/powerpc/include/pmap.h index d83abbcd469..077f1544cee 100644 --- a/sys/arch/powerpc/include/pmap.h +++ b/sys/arch/powerpc/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.23 2001/12/05 00:11:51 millert Exp $ */ +/* $OpenBSD: pmap.h,v 1.24 2002/03/13 18:27:36 drahn Exp $ */ /* $NetBSD: pmap.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */ /*- @@ -47,17 +47,27 @@ typedef u_int sr_t; #define SR_SUKEY 0x40000000 #define SR_PRKEY 0x20000000 #define SR_VSID 0x00ffffff - +/* + * bit + * 3 2 2 2 2 1 1 1 1 1 0 + * 1 8 7 4 0 9 6 5 2 1 0 + * |XXXX|XXXX XXXX|XXXX XXXX|XXXX XXXX XXXX + * + * bits 28 - 31 contain SR + * bits 20 - 27 contain L1 for VtoP translation + * bits 12 - 19 contain L2 for VtoP translation + * bits 0 - 11 contain page offset + */ #ifndef _LOCORE /* V->P mapping data */ -typedef int pmapv_t; -#define VP_SR_SIZE 32 +typedef struct pmapvp pmapvp_t; +#define VP_SR_SIZE 16 #define VP_SR_MASK (VP_SR_SIZE-1) -#define VP_SR_POS 27 -#define VP_IDX1_SIZE 1024 +#define VP_SR_POS 28 +#define VP_IDX1_SIZE 256 #define VP_IDX1_MASK (VP_IDX1_SIZE-1) -#define VP_IDX1_POS 17 -#define VP_IDX2_SIZE 32 +#define VP_IDX1_POS 20 +#define VP_IDX2_SIZE 256 #define VP_IDX2_MASK (VP_IDX2_SIZE-1) #define VP_IDX2_POS 12 @@ -74,24 +84,27 @@ void pmap_kenter_cache( vaddr_t va, paddr_t pa, vm_prot_t prot, int cacheable); */ struct pmap { sr_t pm_sr[16]; /* segments used in this pmap */ + pmapvp_t *pm_vp[VP_SR_SIZE]; /* virtual to physical table */ int pm_refs; /* ref count */ - pmapv_t *vps[VP_SR_SIZE]; /* virtual to physical table */ struct pmap_statistics pm_stats; /* pmap statistics */ }; typedef struct pmap *pmap_t; -boolean_t ptemodify(paddr_t pa, u_int mask, u_int val); #ifdef _KERNEL extern struct pmap kernel_pmap_; #define pmap_kernel() (&kernel_pmap_) -int ptebits(paddr_t pa, int bit); +boolean_t pteclrbits(paddr_t pa, u_int mask, u_int clear); -#define pmap_clear_modify(page) (ptemodify(VM_PAGE_TO_PHYS(page), PTE_CHG, 0)) -#define pmap_clear_reference(page) (ptemodify(VM_PAGE_TO_PHYS(page), PTE_REF, 0)) -#define pmap_is_modified(page) (ptebits(VM_PAGE_TO_PHYS(page), PTE_CHG)) -#define pmap_is_referenced(page) (ptebits(VM_PAGE_TO_PHYS(page), PTE_REF)) +#define pmap_clear_modify(page) \ + (pteclrbits(VM_PAGE_TO_PHYS(page), PTE_CHG, TRUE)) +#define pmap_clear_reference(page) \ + (pteclrbits(VM_PAGE_TO_PHYS(page), PTE_REF, TRUE)) +#define pmap_is_modified(page) \ + (pteclrbits(VM_PAGE_TO_PHYS(page), PTE_CHG, FALSE)) +#define pmap_is_referenced(page) \ + (pteclrbits(VM_PAGE_TO_PHYS(page), PTE_REF, FALSE)) #define pmap_unwire(pm, va) #define pmap_phys_address(x) (x) #define pmap_update(pmap) /* nothing (yet) */ @@ -101,10 +114,10 @@ int ptebits(paddr_t pa, int bit); /* * Alternate mapping methods for pool. * Really simple. 0x0->0x80000000 contain 1->1 mappings of the physical - * memory. + * memory. - XXX */ -#define PMAP_MAP_POOLPAGE(pa) ((vaddr_t)pa) -#define PMAP_UNMAP_POOLPAGE(va) ((paddr_t)va) +#define PMAP_MAP_POOLPAGE(pa) ((vaddr_t)pa) +#define PMAP_UNMAP_POOLPAGE(va) ((paddr_t)va) void pmap_bootstrap __P((u_int kernelstart, u_int kernelend)); @@ -114,6 +127,9 @@ void pmap_release __P((struct pmap *)); void pmap_real_memory __P((vm_offset_t *start, vm_size_t *size)); void switchexit __P((struct proc *)); +int pte_spill_v(struct pmap *pm, u_int32_t va, u_int32_t dsisr); +#define pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) ; + #endif /* _KERNEL */ #endif /* _LOCORE */ #endif /* _POWERPC_PMAP_H_ */ diff --git a/sys/arch/powerpc/include/pte.h b/sys/arch/powerpc/include/pte.h index 9775dc3b183..be72e286d2b 100644 --- a/sys/arch/powerpc/include/pte.h +++ b/sys/arch/powerpc/include/pte.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pte.h,v 1.3 2001/09/01 15:49:05 drahn Exp $ */ +/* $OpenBSD: pte.h,v 1.4 2002/03/13 18:27:36 drahn Exp $ */ /* $NetBSD: pte.h,v 1.1 1996/09/30 16:34:32 ws Exp $ */ /*- @@ -48,7 +48,7 @@ struct pte { #endif /* _LOCORE */ /* High word: */ #define PTE_VALID 0x80000000 -#define PTE_VSID_SHFT 7 +#define PTE_VSID_SHIFT 7 #define PTE_HID 0x00000040 #define PTE_API 0x0000003f /* Low word: */ @@ -71,10 +71,10 @@ typedef struct pte pte_t; /* * Extract bits from address */ -#define ADDR_SR_SHFT 28 +#define ADDR_SR_SHIFT 28 #define ADDR_PIDX 0x0ffff000 -#define ADDR_PIDX_SHFT 12 -#define ADDR_API_SHFT 22 +#define ADDR_PIDX_SHIFT 12 +#define ADDR_API_SHIFT 22 #define ADDR_POFF 0x00000fff #ifndef _LOCORE |