powerpc: Merge all pmap struct definitions

Summary:
A few ports fail to build due to missing pmap-related definitions, which are
specific per-pmap type.  This tries to appease those ports, by merging all
pmaps together.

A future change will move the inline page directory out of the Book-E pmap,
to eliminate the last #ifdefs in pmap.h and complete the merge.

Reviewed By: luporl
Differential Revision: https://reviews.freebsd.org/D20119
This commit is contained in:
Justin Hibbits 2019-05-04 02:34:28 +00:00
parent a6e9cd258c
commit 5d67b612d0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=347078
2 changed files with 178 additions and 186 deletions

View File

@ -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 pvo_entry {
struct {
#ifndef __powerpc64__
/* 32-bit fields */
struct pte pte;
pte_t pte;
#endif
/* 64-bit fields */
uintptr_t slot;
@ -136,28 +134,80 @@ RB_PROTOTYPE(pvo_tree, pvo_entry, pvo_plink, pvo_vaddr_compare);
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 {
#ifdef AIM
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;
};
#endif
#ifdef BOOKE
struct {
/* TID to identify this pmap entries in TLB */
tlbtid_t pm_tid[MAXCPU];
#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;
};
#endif
};
};
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.
@ -182,56 +232,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)

View File

@ -70,6 +70,8 @@ struct pate {
u_int64_t proctab;
};
typedef struct pte pte_t;
typedef struct lpte lpte_t;
#endif /* LOCORE */
/* 32-bit PTE definitions */
@ -161,12 +163,6 @@ struct pate {
#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,120 +197,6 @@ typedef struct lpte lpte_t;
#include <machine/tlb.h>
#ifdef __powerpc64__
#include <machine/tlb.h>
/*
* The virtual address is:
*
* 4K page size
* +-----+-----+-----+-------+-------------+-------------+----------------+
* | - |p2d#h| - | p2d#l | dir# | pte# | off in 4K page |
* +-----+-----+-----+-------+-------------+-------------+----------------+
* 63 62 61 60 59 40 39 30 29 ^ 21 20 ^ 12 11 0
* | |
* index in 1 page of pointers
*
* 1st level - pointers to page table directory (pp2d)
*
* 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<<PP2D_L_NUM)-1)
#define PP2D_H_SHIFT (PP2D_H_L-PP2D_L_NUM)
#define PP2D_H_NUM (PP2D_H_H-PP2D_H_L+1)
#define PP2D_H_MASK (((1<<PP2D_H_NUM)-1)<<PP2D_L_NUM)
#define PP2D_IDX(va) (((va >> PP2D_H_SHIFT) & PP2D_H_MASK) | ((va >> PP2D_L_SHIFT) & PP2D_L_MASK))
#define PP2D_NENTRIES (1<<(PP2D_L_NUM+PP2D_H_NUM))
#define PP2D_ENTRY_SHIFT 3 /* log2 (sizeof(struct pte_entry **)) */
/*
* 2nd level - page table directory (pdir)
*
* pdir consists of PDIR_NENTRIES entries, each being a pointer to
* second level entity, i.e. the actual page table (ptbl).
*/
#define PDIR_H (PP2D_L_L-1)
#define PDIR_L 21
#define PDIR_NUM (PDIR_H-PDIR_L+1)
#define PDIR_SIZE (1 << PDIR_L) /* va range mapped by pdir */
#define PDIR_MASK ((1<<PDIR_NUM)-1)
#define PDIR_SHIFT PDIR_L
#define PDIR_NENTRIES (1<<PDIR_NUM)
#define PDIR_IDX(va) (((va) >> PDIR_SHIFT) & PDIR_MASK)
#define PDIR_ENTRY_SHIFT 3 /* log2 (sizeof(struct pte_entry *)) */
#define PDIR_PAGES ((PDIR_NENTRIES * (1<<PDIR_ENTRY_SHIFT)) / PAGE_SIZE)
/*
* 3rd level - page table (ptbl)
*
* Page table covers PTBL_NENTRIES page table entries. Page
* table entry (pte) is 64 bit wide and defines mapping
* for a single page.
*/
#define PTBL_H (PDIR_L-1)
#define PTBL_L PAGE_SHIFT
#define PTBL_NUM (PTBL_H-PTBL_L+1)
#define PTBL_MASK ((1<<PTBL_NUM)-1)
#define PTBL_SHIFT PTBL_L
#define PTBL_SIZE PAGE_SIZE /* va range mapped by ptbl entry */
#define PTBL_NENTRIES (1<<PTBL_NUM)
#define PTBL_IDX(va) ((va >> PTBL_SHIFT) & PTBL_MASK)
#define PTBL_ENTRY_SHIFT 3 /* log2 (sizeof (struct pte_entry)) */
#define PTBL_PAGES ((PTBL_NENTRIES * (1<<PTBL_ENTRY_SHIFT)) / PAGE_SIZE)
#define KERNEL_LINEAR_MAX 0xc000000040000000
#else
/*
* 1st level - page table directory (pdir)
*
* pdir consists of 1024 entries, each being a pointer to
* second level entity, i.e. the actual page table (ptbl).
*/
#define PDIR_SHIFT 22
#define PDIR_SIZE (1 << PDIR_SHIFT) /* va range mapped by pdir */
#define PDIR_MASK (~(PDIR_SIZE - 1))
#define PDIR_NENTRIES 1024 /* number of page tables in pdir */
/* Returns pdir entry number for given va */
#define PDIR_IDX(va) ((va) >> PDIR_SHIFT)
#define PDIR_ENTRY_SHIFT 2 /* entry size is 2^2 = 4 bytes */
/*
* 2nd level - page table (ptbl)
*
* Page table covers 1024 page table entries. Page
* table entry (pte) is 32 bit wide and defines mapping
* for a single page.
*/
#define PTBL_SHIFT PAGE_SHIFT
#define PTBL_SIZE PAGE_SIZE /* va range mapped by ptbl entry */
#define PTBL_MASK ((PDIR_SIZE - 1) & ~((1 << PAGE_SHIFT) - 1))
#define PTBL_NENTRIES 1024 /* number of pages mapped by ptbl */
/* Returns ptbl entry number for given va */
#define PTBL_IDX(va) (((va) & PTBL_MASK) >> PTBL_SHIFT)
/* Size of ptbl in pages, 1024 entries, each sizeof(struct pte_entry). */
#define PTBL_PAGES 2
#define PTBL_ENTRY_SHIFT 3 /* entry size is 2^3 = 8 bytes */
#endif
/*
* Flags for pte_remove() routine.
*/
@ -421,4 +303,114 @@ typedef uint64_t pte_t;
#define PTE_ISREFERENCED(pte) ((*pte) & PTE_REFERENCED)
#endif /* BOOKE */
/* Book-E page table format, broken out for the generic pmap.h. */
#ifdef __powerpc64__
#include <machine/tlb.h>
/*
* The virtual address is:
*
* 4K page size
* +-----+-----+-----+-------+-------------+-------------+----------------+
* | - |p2d#h| - | p2d#l | dir# | pte# | off in 4K page |
* +-----+-----+-----+-------+-------------+-------------+----------------+
* 63 62 61 60 59 40 39 30 29 ^ 21 20 ^ 12 11 0
* | |
* index in 1 page of pointers
*
* 1st level - pointers to page table directory (pp2d)
*
* pp2d consists of PP2D_NENTRIES entries, each being a pointer to
* second level entity, i.e. the page table directory (pdir).
*/
#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 */
#define PP2D_SIZE (1 << PP2D_L_L) /* va range mapped by pp2d */
#define PP2D_L_SHIFT PP2D_L_L
#define PP2D_L_NUM (PP2D_L_H-PP2D_L_L+1)
#define PP2D_L_MASK ((1<<PP2D_L_NUM)-1)
#define PP2D_H_SHIFT (PP2D_H_L-PP2D_L_NUM)
#define PP2D_H_NUM (PP2D_H_H-PP2D_H_L+1)
#define PP2D_H_MASK (((1<<PP2D_H_NUM)-1)<<PP2D_L_NUM)
#define PP2D_IDX(va) (((va >> PP2D_H_SHIFT) & PP2D_H_MASK) | ((va >> PP2D_L_SHIFT) & PP2D_L_MASK))
#define PP2D_NENTRIES (1<<(PP2D_L_NUM+PP2D_H_NUM))
#define PP2D_ENTRY_SHIFT 3 /* log2 (sizeof(struct pte_entry **)) */
/*
* 2nd level - page table directory (pdir)
*
* pdir consists of PDIR_NENTRIES entries, each being a pointer to
* second level entity, i.e. the actual page table (ptbl).
*/
#define PDIR_H (PP2D_L_L-1)
#define PDIR_L 21
#define PDIR_NUM (PDIR_H-PDIR_L+1)
#define PDIR_SIZE (1 << PDIR_L) /* va range mapped by pdir */
#define PDIR_MASK ((1<<PDIR_NUM)-1)
#define PDIR_SHIFT PDIR_L
#define PDIR_NENTRIES (1<<PDIR_NUM)
#define PDIR_IDX(va) (((va) >> PDIR_SHIFT) & PDIR_MASK)
#define PDIR_ENTRY_SHIFT 3 /* log2 (sizeof(struct pte_entry *)) */
#define PDIR_PAGES ((PDIR_NENTRIES * (1<<PDIR_ENTRY_SHIFT)) / PAGE_SIZE)
/*
* 3rd level - page table (ptbl)
*
* Page table covers PTBL_NENTRIES page table entries. Page
* table entry (pte) is 64 bit wide and defines mapping
* for a single page.
*/
#define PTBL_H (PDIR_L-1)
#define PTBL_L PAGE_SHIFT
#define PTBL_NUM (PTBL_H-PTBL_L+1)
#define PTBL_MASK ((1<<PTBL_NUM)-1)
#define PTBL_SHIFT PTBL_L
#define PTBL_SIZE PAGE_SIZE /* va range mapped by ptbl entry */
#define PTBL_NENTRIES (1<<PTBL_NUM)
#define PTBL_IDX(va) ((va >> PTBL_SHIFT) & PTBL_MASK)
#define PTBL_ENTRY_SHIFT 3 /* log2 (sizeof (struct pte_entry)) */
#define PTBL_PAGES ((PTBL_NENTRIES * (1<<PTBL_ENTRY_SHIFT)) / PAGE_SIZE)
#define KERNEL_LINEAR_MAX 0xc000000040000000
#else
/*
* 1st level - page table directory (pdir)
*
* pdir consists of 1024 entries, each being a pointer to
* second level entity, i.e. the actual page table (ptbl).
*/
#define PDIR_SHIFT 22
#define PDIR_SIZE (1 << PDIR_SHIFT) /* va range mapped by pdir */
#define PDIR_MASK (~(PDIR_SIZE - 1))
#define PDIR_NENTRIES 1024 /* number of page tables in pdir */
/* Returns pdir entry number for given va */
#define PDIR_IDX(va) ((va) >> PDIR_SHIFT)
#define PDIR_ENTRY_SHIFT 2 /* entry size is 2^2 = 4 bytes */
/*
* 2nd level - page table (ptbl)
*
* Page table covers 1024 page table entries. Page
* table entry (pte) is 32 bit wide and defines mapping
* for a single page.
*/
#define PTBL_SHIFT PAGE_SHIFT
#define PTBL_SIZE PAGE_SIZE /* va range mapped by ptbl entry */
#define PTBL_MASK ((PDIR_SIZE - 1) & ~((1 << PAGE_SHIFT) - 1))
#define PTBL_NENTRIES 1024 /* number of pages mapped by ptbl */
/* Returns ptbl entry number for given va */
#define PTBL_IDX(va) (((va) & PTBL_MASK) >> PTBL_SHIFT)
/* Size of ptbl in pages, 1024 entries, each sizeof(struct pte_entry). */
#define PTBL_PAGES 2
#define PTBL_ENTRY_SHIFT 3 /* entry size is 2^3 = 8 bytes */
#endif
#endif /* _MACHINE_PTE_H_ */