version 1.84, 2008/01/01 14:06:43 |
version 1.84.10.5, 2010/03/11 15:02:06 |
|
|
#include <arm/cpuconf.h> |
#include <arm/cpuconf.h> |
#include <arm/arm32/pte.h> |
#include <arm/arm32/pte.h> |
#ifndef _LOCORE |
#ifndef _LOCORE |
|
#if defined(_KERNEL_OPT) |
|
#include "opt_arm32_pmap.h" |
|
#endif |
#include <arm/cpufunc.h> |
#include <arm/cpufunc.h> |
#include <uvm/uvm_object.h> |
#include <uvm/uvm_object.h> |
#endif |
#endif |
|
|
#define L2_LOG2 ((32 - L1_S_SHIFT) - L2_BUCKET_LOG2) |
#define L2_LOG2 ((32 - L1_S_SHIFT) - L2_BUCKET_LOG2) |
#define L2_SIZE (1 << L2_LOG2) |
#define L2_SIZE (1 << L2_LOG2) |
|
|
|
/* |
|
* tell MI code that the cache is virtually-indexed. |
|
* ARMv6 is physically-tagged but all others are virtually-tagged. |
|
*/ |
|
#if ARM_MMU_V6 > 0 |
|
#define PMAP_CACHE_VIPT |
|
#else |
|
#define PMAP_CACHE_VIVT |
|
#endif |
|
|
#ifndef _LOCORE |
#ifndef _LOCORE |
|
|
struct l1_ttable; |
struct l1_ttable; |
|
|
LIST_ENTRY(pmap) pm_list; |
LIST_ENTRY(pmap) pm_list; |
}; |
}; |
|
|
typedef struct pmap *pmap_t; |
|
|
|
/* |
/* |
* Physical / virtual address structure. In a number of places (particularly |
* Physical / virtual address structure. In a number of places (particularly |
* during bootstrapping) we need to keep track of the physical and virtual |
* during bootstrapping) we need to keep track of the physical and virtual |
Line 194 typedef struct pv_addr { |
|
Line 205 typedef struct pv_addr { |
|
SLIST_ENTRY(pv_addr) pv_list; |
SLIST_ENTRY(pv_addr) pv_list; |
paddr_t pv_pa; |
paddr_t pv_pa; |
vaddr_t pv_va; |
vaddr_t pv_va; |
|
vsize_t pv_size; |
} pv_addr_t; |
} pv_addr_t; |
|
typedef SLIST_HEAD(, pv_addr) pv_addrqh_t; |
|
|
|
extern pv_addrqh_t pmap_freeq; |
|
extern pv_addr_t kernelpages; |
|
extern pv_addr_t systempage; |
|
extern pv_addr_t kernel_l1pt; |
|
|
/* |
/* |
* Determine various modes for PTEs (user vs. kernel, cacheable |
* Determine various modes for PTEs (user vs. kernel, cacheable |
Line 222 typedef struct pv_addr { |
|
Line 240 typedef struct pv_addr { |
|
#define PVF_WIRED 0x04 /* mapping is wired */ |
#define PVF_WIRED 0x04 /* mapping is wired */ |
#define PVF_WRITE 0x08 /* mapping is writable */ |
#define PVF_WRITE 0x08 /* mapping is writable */ |
#define PVF_EXEC 0x10 /* mapping is executable */ |
#define PVF_EXEC 0x10 /* mapping is executable */ |
|
#ifdef PMAP_CACHE_VIVT |
#define PVF_UNC 0x20 /* mapping is 'user' non-cacheable */ |
#define PVF_UNC 0x20 /* mapping is 'user' non-cacheable */ |
#define PVF_KNC 0x40 /* mapping is 'kernel' non-cacheable */ |
#define PVF_KNC 0x40 /* mapping is 'kernel' non-cacheable */ |
#define PVF_NC (PVF_UNC|PVF_KNC) |
#define PVF_NC (PVF_UNC|PVF_KNC) |
|
#endif |
|
#ifdef PMAP_CACHE_VIPT |
|
#define PVF_NC 0x20 /* mapping is 'kernel' non-cacheable */ |
|
#define PVF_MULTCLR 0x40 /* mapping is multi-colored */ |
|
#endif |
|
#define PVF_COLORED 0x80 /* page has or had a color */ |
|
#define PVF_KENTRY 0x0100 /* page entered via pmap_kenter_pa */ |
|
#define PVF_KMPAGE 0x0200 /* page is used for kmem */ |
|
#define PVF_DIRTY 0x0400 /* page may have dirty cache lines */ |
|
#define PVF_KMOD 0x0800 /* unmanaged page is modified */ |
|
#define PVF_KWRITE (PVF_KENTRY|PVF_WRITE) |
|
#define PVF_DMOD (PVF_MOD|PVF_KMOD|PVF_KMPAGE) |
|
|
/* |
/* |
* Commonly referenced structures |
* Commonly referenced structures |
*/ |
*/ |
extern struct pmap kernel_pmap_store; |
|
extern int pmap_debug_level; /* Only exists if PMAP_DEBUG */ |
extern int pmap_debug_level; /* Only exists if PMAP_DEBUG */ |
|
|
/* |
/* |
* Macros that we need to export |
* Macros that we need to export |
*/ |
*/ |
#define pmap_kernel() (&kernel_pmap_store) |
|
#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) |
#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) |
#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) |
#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) |
|
|
#define pmap_remove(pmap,sva,eva) pmap_do_remove((pmap),(sva),(eva),0) |
|
|
|
#define pmap_is_modified(pg) \ |
#define pmap_is_modified(pg) \ |
(((pg)->mdpage.pvh_attrs & PVF_MOD) != 0) |
(((pg)->mdpage.pvh_attrs & PVF_MOD) != 0) |
#define pmap_is_referenced(pg) \ |
#define pmap_is_referenced(pg) \ |
(((pg)->mdpage.pvh_attrs & PVF_REF) != 0) |
(((pg)->mdpage.pvh_attrs & PVF_REF) != 0) |
|
#define pmap_is_page_colored_p(pg) \ |
|
(((pg)->mdpage.pvh_attrs & PVF_COLORED) != 0) |
|
|
#define pmap_copy(dp, sp, da, l, sa) /* nothing */ |
#define pmap_copy(dp, sp, da, l, sa) /* nothing */ |
|
|
Line 259 bool pmap_extract(pmap_t, vaddr_t, paddr |
|
Line 288 bool pmap_extract(pmap_t, vaddr_t, paddr |
|
|
|
#define PMAP_NEED_PROCWR |
#define PMAP_NEED_PROCWR |
#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */ |
#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */ |
|
#define PMAP_ENABLE_PMAP_KMPAGE /* enable the PMAP_KMPAGE flag */ |
|
|
|
#if ARM_MMU_V6 > 0 |
|
#define PMAP_PREFER(hint, vap, sz, td) pmap_prefer((hint), (vap), (td)) |
|
void pmap_prefer(vaddr_t, vaddr_t *, int); |
|
#endif |
|
|
|
void pmap_icache_sync_range(pmap_t, vaddr_t, vaddr_t); |
|
|
/* Functions we use internally. */ |
/* Functions we use internally. */ |
void pmap_bootstrap(pd_entry_t *, vaddr_t, vaddr_t); |
#ifdef PMAP_STEAL_MEMORY |
|
void pmap_boot_pagealloc(psize_t, psize_t, psize_t, pv_addr_t *); |
|
void pmap_boot_pageadd(pv_addr_t *); |
|
vaddr_t pmap_steal_memory(vsize_t, vaddr_t *, vaddr_t *); |
|
#endif |
|
void pmap_bootstrap(vaddr_t, vaddr_t); |
|
|
void pmap_do_remove(pmap_t, vaddr_t, vaddr_t, int); |
void pmap_do_remove(pmap_t, vaddr_t, vaddr_t, int); |
int pmap_fault_fixup(pmap_t, vaddr_t, vm_prot_t, int); |
int pmap_fault_fixup(pmap_t, vaddr_t, vm_prot_t, int); |
Line 348 extern int pmap_needs_pte_sync; |
|
Line 390 extern int pmap_needs_pte_sync; |
|
* we need to do PTE syncs. If only SA-1 is configured, then evaluate |
* we need to do PTE syncs. If only SA-1 is configured, then evaluate |
* this at compile time. |
* this at compile time. |
*/ |
*/ |
#if (ARM_MMU_SA1 == 1) && (ARM_NMMUS == 1) |
#if (ARM_MMU_SA1 + ARM_MMU_V6 != 0) && (ARM_NMMUS == 1) |
#define PMAP_NEEDS_PTE_SYNC 1 |
#define PMAP_NEEDS_PTE_SYNC 1 |
#define PMAP_INCLUDE_PTE_SYNC |
#define PMAP_INCLUDE_PTE_SYNC |
#elif (ARM_MMU_SA1 == 0) |
#elif (ARM_MMU_SA1 == 0) |
|
|
#define l1pte_fpage_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_F) |
#define l1pte_fpage_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_F) |
|
|
#define l2pte_index(v) (((v) & L2_ADDR_BITS) >> L2_S_SHIFT) |
#define l2pte_index(v) (((v) & L2_ADDR_BITS) >> L2_S_SHIFT) |
#define l2pte_valid(pte) ((pte) != 0) |
#define l2pte_valid(pte) (((pte) & L2_TYPE_MASK) != L2_TYPE_INV) |
#define l2pte_pa(pte) ((pte) & L2_S_FRAME) |
#define l2pte_pa(pte) ((pte) & L2_S_FRAME) |
#define l2pte_minidata(pte) (((pte) & \ |
#define l2pte_minidata(pte) (((pte) & \ |
(L2_B | L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X)))\ |
(L2_B | L2_C | L2_XS_T_TEX(TEX_XSCALE_X)))\ |
== (L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X))) |
== (L2_C | L2_XS_T_TEX(TEX_XSCALE_X))) |
|
|
/* L1 and L2 page table macros */ |
/* L1 and L2 page table macros */ |
#define pmap_pde_v(pde) l1pte_valid(*(pde)) |
#define pmap_pde_v(pde) l1pte_valid(*(pde)) |
|
|
|
|
/************************* ARM MMU configuration *****************************/ |
/************************* ARM MMU configuration *****************************/ |
|
|
#if (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 |
#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0 |
void pmap_copy_page_generic(paddr_t, paddr_t); |
void pmap_copy_page_generic(paddr_t, paddr_t); |
void pmap_zero_page_generic(paddr_t); |
void pmap_zero_page_generic(paddr_t); |
|
|
Line 420 void pmap_pte_init_arm9(void); |
|
Line 462 void pmap_pte_init_arm9(void); |
|
#if defined(CPU_ARM10) |
#if defined(CPU_ARM10) |
void pmap_pte_init_arm10(void); |
void pmap_pte_init_arm10(void); |
#endif /* CPU_ARM10 */ |
#endif /* CPU_ARM10 */ |
|
#if defined(CPU_ARM11) |
|
void pmap_pte_init_arm11(void); |
|
#endif /* CPU_ARM11 */ |
#endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 */ |
#endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 */ |
|
|
#if ARM_MMU_SA1 == 1 |
#if ARM_MMU_SA1 == 1 |
Line 467 extern void (*pmap_zero_page_func)(paddr |
|
Line 512 extern void (*pmap_zero_page_func)(paddr |
|
/*****************************************************************************/ |
/*****************************************************************************/ |
|
|
/* |
/* |
* tell MI code that the cache is virtually-indexed *and* virtually-tagged. |
|
*/ |
|
#define PMAP_CACHE_VIVT |
|
|
|
/* |
|
* Definitions for MMU domains |
* Definitions for MMU domains |
*/ |
*/ |
#define PMAP_DOMAINS 15 /* 15 'user' domains (0-14) */ |
#define PMAP_DOMAINS 15 /* 15 'user' domains (0-14) */ |
Line 488 extern void (*pmap_zero_page_func)(paddr |
|
Line 528 extern void (*pmap_zero_page_func)(paddr |
|
#define L1_S_PROT_MASK (L1_S_PROT_U|L1_S_PROT_W) |
#define L1_S_PROT_MASK (L1_S_PROT_U|L1_S_PROT_W) |
|
|
#define L1_S_CACHE_MASK_generic (L1_S_B|L1_S_C) |
#define L1_S_CACHE_MASK_generic (L1_S_B|L1_S_C) |
#define L1_S_CACHE_MASK_xscale (L1_S_B|L1_S_C|L1_S_XSCALE_TEX(TEX_XSCALE_X)) |
#define L1_S_CACHE_MASK_xscale (L1_S_B|L1_S_C|L1_S_XS_TEX(TEX_XSCALE_X)) |
|
|
#define L2_L_PROT_U (L2_AP(AP_U)) |
#define L2_L_PROT_U (L2_AP(AP_U)) |
#define L2_L_PROT_W (L2_AP(AP_W)) |
#define L2_L_PROT_W (L2_AP(AP_W)) |
#define L2_L_PROT_MASK (L2_L_PROT_U|L2_L_PROT_W) |
#define L2_L_PROT_MASK (L2_L_PROT_U|L2_L_PROT_W) |
|
|
#define L2_L_CACHE_MASK_generic (L2_B|L2_C) |
#define L2_L_CACHE_MASK_generic (L2_B|L2_C) |
#define L2_L_CACHE_MASK_xscale (L2_B|L2_C|L2_XSCALE_L_TEX(TEX_XSCALE_X)) |
#define L2_L_CACHE_MASK_xscale (L2_B|L2_C|L2_XS_L_TEX(TEX_XSCALE_X)) |
|
|
#define L2_S_PROT_U_generic (L2_AP(AP_U)) |
#define L2_S_PROT_U_generic (L2_AP(AP_U)) |
#define L2_S_PROT_W_generic (L2_AP(AP_W)) |
#define L2_S_PROT_W_generic (L2_AP(AP_W)) |
Line 506 extern void (*pmap_zero_page_func)(paddr |
|
Line 546 extern void (*pmap_zero_page_func)(paddr |
|
#define L2_S_PROT_MASK_xscale (L2_S_PROT_U|L2_S_PROT_W) |
#define L2_S_PROT_MASK_xscale (L2_S_PROT_U|L2_S_PROT_W) |
|
|
#define L2_S_CACHE_MASK_generic (L2_B|L2_C) |
#define L2_S_CACHE_MASK_generic (L2_B|L2_C) |
#define L2_S_CACHE_MASK_xscale (L2_B|L2_C|L2_XSCALE_T_TEX(TEX_XSCALE_X)) |
#define L2_S_CACHE_MASK_xscale (L2_B|L2_C|L2_XS_T_TEX(TEX_XSCALE_X)) |
|
|
#define L1_S_PROTO_generic (L1_TYPE_S | L1_S_IMP) |
#define L1_S_PROTO_generic (L1_TYPE_S | L1_S_IMP) |
#define L1_S_PROTO_xscale (L1_TYPE_S) |
#define L1_S_PROTO_xscale (L1_TYPE_S) |
Line 517 extern void (*pmap_zero_page_func)(paddr |
|
Line 557 extern void (*pmap_zero_page_func)(paddr |
|
#define L2_L_PROTO (L2_TYPE_L) |
#define L2_L_PROTO (L2_TYPE_L) |
|
|
#define L2_S_PROTO_generic (L2_TYPE_S) |
#define L2_S_PROTO_generic (L2_TYPE_S) |
#define L2_S_PROTO_xscale (L2_TYPE_XSCALE_XS) |
#define L2_S_PROTO_xscale (L2_TYPE_XS) |
|
|
/* |
/* |
* User-visible names for the ones that vary with MMU class. |
* User-visible names for the ones that vary with MMU class. |
Line 539 extern void (*pmap_zero_page_func)(paddr |
|
Line 579 extern void (*pmap_zero_page_func)(paddr |
|
|
|
#define pmap_copy_page(s, d) (*pmap_copy_page_func)((s), (d)) |
#define pmap_copy_page(s, d) (*pmap_copy_page_func)((s), (d)) |
#define pmap_zero_page(d) (*pmap_zero_page_func)((d)) |
#define pmap_zero_page(d) (*pmap_zero_page_func)((d)) |
#elif (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 |
#elif (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0 |
#define L2_S_PROT_U L2_S_PROT_U_generic |
#define L2_S_PROT_U L2_S_PROT_U_generic |
#define L2_S_PROT_W L2_S_PROT_W_generic |
#define L2_S_PROT_W L2_S_PROT_W_generic |
#define L2_S_PROT_MASK L2_S_PROT_MASK_generic |
#define L2_S_PROT_MASK L2_S_PROT_MASK_generic |