Index: sys/powerpc/include/pmap.h =================================================================== --- sys/powerpc/include/pmap.h +++ sys/powerpc/include/pmap.h @@ -79,8 +79,6 @@ struct pmap; typedef struct pmap *pmap_t; -#if defined(AIM) - #if !defined(NPMAPS) #define NPMAPS 32768 #endif /* !defined(NPMAPS) */ @@ -96,7 +94,7 @@ struct { #ifndef __powerpc64__ /* 32-bit fields */ - struct pte pte; + pte_t pte; #endif /* 64-bit fields */ uintptr_t slot; @@ -136,28 +134,69 @@ struct pmap { struct pmap_statistics pm_stats; struct mtx pm_mtx; - - #ifdef __powerpc64__ - struct slbtnode *pm_slb_tree_root; - struct slb **pm_slb; - int pm_slb_len; - #else - register_t pm_sr[16]; - #endif cpuset_t pm_active; + union { + struct { + + #ifdef __powerpc64__ + struct slbtnode *pm_slb_tree_root; + struct slb **pm_slb; + int pm_slb_len; + #else + register_t pm_sr[16]; + #endif - struct pmap *pmap_phys; - struct pvo_tree pmap_pvo; + struct pmap *pmap_phys; + struct pvo_tree pmap_pvo; + }; + struct { + tlbtid_t pm_tid[MAXCPU]; /* TID to identify this pmap entries in TLB */ + +#ifdef __powerpc64__ + /* Page table directory, array of pointers to page directories. */ + pte_t **pm_pp2d[PP2D_NENTRIES]; + + /* List of allocated pdir bufs (pdir kva regions). */ + TAILQ_HEAD(, ptbl_buf) pm_pdir_list; +#else + /* Page table directory, array of pointers to page tables. */ + pte_t *pm_pdir[PDIR_NENTRIES]; +#endif + + /* List of allocated ptbl bufs (ptbl kva regions). */ + TAILQ_HEAD(, ptbl_buf) pm_ptbl_list; + }; + }; }; +struct pv_entry { + pmap_t pv_pmap; + vm_offset_t pv_va; + TAILQ_ENTRY(pv_entry) pv_link; +}; +typedef struct pv_entry *pv_entry_t; + struct md_page { - volatile int32_t mdpg_attrs; - vm_memattr_t mdpg_cache_attrs; - struct pvo_head mdpg_pvoh; + union { + struct { + volatile int32_t mdpg_attrs; + vm_memattr_t mdpg_cache_attrs; + struct pvo_head mdpg_pvoh; + }; + struct { + TAILQ_HEAD(, pv_entry) pv_list; + int pv_tracked; + }; + }; }; +#ifdef AIM #define pmap_page_get_memattr(m) ((m)->md.mdpg_cache_attrs) #define pmap_page_is_mapped(m) (!LIST_EMPTY(&(m)->md.mdpg_pvoh)) +#else +#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT +#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) +#endif /* * Return the VSID corresponding to a given virtual address. @@ -181,56 +220,6 @@ void slb_free_tree(pmap_t pm); struct slb **slb_alloc_user_cache(void); void slb_free_user_cache(struct slb **); - -#elif defined(BOOKE) - -struct pmap { - struct pmap_statistics pm_stats; /* pmap statistics */ - struct mtx pm_mtx; /* pmap mutex */ - tlbtid_t pm_tid[MAXCPU]; /* TID to identify this pmap entries in TLB */ - cpuset_t pm_active; /* active on cpus */ - -#ifdef __powerpc64__ - /* Page table directory, array of pointers to page directories. */ - pte_t **pm_pp2d[PP2D_NENTRIES]; - - /* List of allocated pdir bufs (pdir kva regions). */ - TAILQ_HEAD(, ptbl_buf) pm_pdir_list; -#else - /* Page table directory, array of pointers to page tables. */ - pte_t *pm_pdir[PDIR_NENTRIES]; -#endif - - /* List of allocated ptbl bufs (ptbl kva regions). */ - TAILQ_HEAD(, ptbl_buf) pm_ptbl_list; -}; - -struct pv_entry { - pmap_t pv_pmap; - vm_offset_t pv_va; - TAILQ_ENTRY(pv_entry) pv_link; -}; -typedef struct pv_entry *pv_entry_t; - -struct md_page { - TAILQ_HEAD(, pv_entry) pv_list; - int pv_tracked; -}; - -#define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT -#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) - -#else -/* - * Common pmap members between AIM and BOOKE. - * libkvm needs pm_stats at the same location between both, as it doesn't define - * AIM nor BOOKE, and is expected to work across all. - */ -struct pmap { - struct pmap_statistics pm_stats; /* pmap statistics */ - struct mtx pm_mtx; /* pmap mutex */ -}; -#endif /* AIM */ extern struct pmap kernel_pmap_store; #define kernel_pmap (&kernel_pmap_store) Index: sys/powerpc/include/pte.h =================================================================== --- sys/powerpc/include/pte.h +++ sys/powerpc/include/pte.h @@ -70,6 +70,8 @@ u_int64_t proctab; }; +typedef struct pte pte_t; +typedef struct lpte lpte_t; #endif /* LOCORE */ /* 32-bit PTE definitions */ @@ -161,12 +163,6 @@ #define RPDE_NLB_SHIFT 8 #define RPDE_NLS_MASK 0x000000000000001FULL - -#ifndef LOCORE -typedef struct pte pte_t; -typedef struct lpte lpte_t; -#endif /* LOCORE */ - /* * Extract bits from address */ @@ -201,6 +197,114 @@ #include +/* + * Flags for pte_remove() routine. + */ +#define PTBL_HOLD 0x00000001 /* do not unhold ptbl pages */ +#define PTBL_UNHOLD 0x00000002 /* unhold and attempt to free ptbl pages */ + +#define PTBL_HOLD_FLAG(pmap) (((pmap) == kernel_pmap) ? PTBL_HOLD : PTBL_UNHOLD) + +/* + * Page Table Entry definitions and macros. + * + * RPN need only be 32-bit because Book-E has 36-bit addresses, and the smallest + * page size is 4k (12-bit mask), so RPN can really fit into 24 bits. + */ +#ifndef LOCORE +typedef uint64_t pte_t; +#endif + +/* RPN mask, TLB0 4K pages */ +#define PTE_PA_MASK PAGE_MASK + +#if defined(BOOKE_E500) + +/* PTE bits assigned to MAS2, MAS3 flags */ +#define PTE_MAS2_SHIFT 19 +#define PTE_W (MAS2_W << PTE_MAS2_SHIFT) +#define PTE_I (MAS2_I << PTE_MAS2_SHIFT) +#define PTE_M (MAS2_M << PTE_MAS2_SHIFT) +#define PTE_G (MAS2_G << PTE_MAS2_SHIFT) +#define PTE_MAS2_MASK (MAS2_G | MAS2_M | MAS2_I | MAS2_W) + +#define PTE_MAS3_SHIFT 2 +#define PTE_UX (MAS3_UX << PTE_MAS3_SHIFT) +#define PTE_SX (MAS3_SX << PTE_MAS3_SHIFT) +#define PTE_UW (MAS3_UW << PTE_MAS3_SHIFT) +#define PTE_SW (MAS3_SW << PTE_MAS3_SHIFT) +#define PTE_UR (MAS3_UR << PTE_MAS3_SHIFT) +#define PTE_SR (MAS3_SR << PTE_MAS3_SHIFT) +#define PTE_MAS3_MASK ((MAS3_UX | MAS3_SX | MAS3_UW \ + | MAS3_SW | MAS3_UR | MAS3_SR) << PTE_MAS3_SHIFT) + +#define PTE_PS_SHIFT 8 +#define PTE_PS_4KB (2 << PTE_PS_SHIFT) + +#elif defined(BOOKE_PPC4XX) + +#define PTE_WL1 TLB_WL1 +#define PTE_IL2I TLB_IL2I +#define PTE_IL2D TLB_IL2D + +#define PTE_W TLB_W +#define PTE_I TLB_I +#define PTE_M TLB_M +#define PTE_G TLB_G + +#define PTE_UX TLB_UX +#define PTE_SX TLB_SX +#define PTE_UW TLB_UW +#define PTE_SW TLB_SW +#define PTE_UR TLB_UR +#define PTE_SR TLB_SR + +#endif + +/* Other PTE flags */ +#define PTE_VALID 0x00000001 /* Valid */ +#define PTE_MODIFIED 0x00001000 /* Modified */ +#define PTE_WIRED 0x00002000 /* Wired */ +#define PTE_MANAGED 0x00000002 /* Managed */ +#define PTE_REFERENCED 0x00040000 /* Referenced */ + +/* + * Page Table Entry definitions and macros. + * + * We use the hardware page table entry format: + * + * 63 24 23 19 18 17 14 13 12 11 8 7 6 5 4 3 2 1 0 + * --------------------------------------------------------------- + * ARPN(12:51) WIMGE R U0:U3 SW0 C PSIZE UX SX UW SW UR SR SW1 V + * --------------------------------------------------------------- + */ + +/* PTE fields. */ +#define PTE_TSIZE_SHIFT (63-54) +#define PTE_TSIZE_MASK 0x7 +#define PTE_TSIZE_SHIFT_DIRECT (63-55) +#define PTE_TSIZE_MASK_DIRECT 0xf +#define PTE_PS_DIRECT(ps) (ps<> PTE_TSIZE_SHIFT) & PTE_TSIZE_MASK) +#define PTE_TSIZE_DIRECT(pte) (int)((*pte >> PTE_TSIZE_SHIFT_DIRECT) & PTE_TSIZE_MASK_DIRECT) + +/* Macro argument must of pte_t type. */ +#define PTE_ARPN_SHIFT 12 +#define PTE_FLAGS_MASK 0x00ffffff +#define PTE_RPN_FROM_PA(pa) (((pa) & ~PAGE_MASK) << PTE_ARPN_SHIFT) +#define PTE_PA(pte) ((vm_paddr_t)(*pte >> PTE_ARPN_SHIFT) & ~PAGE_MASK) +#define PTE_ISVALID(pte) ((*pte) & PTE_VALID) +#define PTE_ISWIRED(pte) ((*pte) & PTE_WIRED) +#define PTE_ISMANAGED(pte) ((*pte) & PTE_MANAGED) +#define PTE_ISMODIFIED(pte) ((*pte) & PTE_MODIFIED) +#define PTE_ISREFERENCED(pte) ((*pte) & PTE_REFERENCED) + +#endif /* BOOKE */ + +/* Book-E page table format, broken out for the generic pmap.h. */ #ifdef __powerpc64__ #include @@ -221,16 +325,11 @@ * pp2d consists of PP2D_NENTRIES entries, each being a pointer to * second level entity, i.e. the page table directory (pdir). */ -#define HARDWARE_WALKER #define PP2D_H_H 61 #define PP2D_H_L 60 #define PP2D_L_H 39 #define PP2D_L_L 30 /* >30 would work with no page table pool */ -#ifndef LOCORE -#define PP2D_SIZE (1UL << PP2D_L_L) /* va range mapped by pp2d */ -#else #define PP2D_SIZE (1 << PP2D_L_L) /* va range mapped by pp2d */ -#endif #define PP2D_L_SHIFT PP2D_L_L #define PP2D_L_NUM (PP2D_L_H-PP2D_L_L+1) #define PP2D_L_MASK ((1<> PTE_TSIZE_SHIFT) & PTE_TSIZE_MASK) -#define PTE_TSIZE_DIRECT(pte) (int)((*pte >> PTE_TSIZE_SHIFT_DIRECT) & PTE_TSIZE_MASK_DIRECT) - -/* Macro argument must of pte_t type. */ -#define PTE_ARPN_SHIFT 12 -#define PTE_FLAGS_MASK 0x00ffffff -#define PTE_RPN_FROM_PA(pa) (((pa) & ~PAGE_MASK) << PTE_ARPN_SHIFT) -#define PTE_PA(pte) ((vm_paddr_t)(*pte >> PTE_ARPN_SHIFT) & ~PAGE_MASK) -#define PTE_ISVALID(pte) ((*pte) & PTE_VALID) -#define PTE_ISWIRED(pte) ((*pte) & PTE_WIRED) -#define PTE_ISMANAGED(pte) ((*pte) & PTE_MANAGED) -#define PTE_ISMODIFIED(pte) ((*pte) & PTE_MODIFIED) -#define PTE_ISREFERENCED(pte) ((*pte) & PTE_REFERENCED) - -#endif /* BOOKE */ #endif /* _MACHINE_PTE_H_ */