summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2007-07-27 14:45:04 +0000
committercognet <cognet@FreeBSD.org>2007-07-27 14:45:04 +0000
commit8b22cea67fcdb76cadb7c4ab11354385ffeafa90 (patch)
treebeb6c44ae86543f3f85dd4f4e2af5bbd14e82185 /sys
parentd9f013dcfb25eafb521de47bfde07fd599bf100a (diff)
downloadFreeBSD-src-8b22cea67fcdb76cadb7c4ab11354385ffeafa90.zip
FreeBSD-src-8b22cea67fcdb76cadb7c4ab11354385ffeafa90.tar.gz
Properly handle supersections.
Make sure we cache entries in the L2 cache. Approved by: re (blanket)
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/arm/pmap.c36
-rw-r--r--sys/arm/include/pmap.h24
2 files changed, 46 insertions, 14 deletions
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index 7e0fb56..f201b0a 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -676,8 +676,14 @@ pmap_pte_init_xscale(void)
pmap_copy_page_func = pmap_copy_page_generic;
pmap_zero_page_func = pmap_zero_page_generic;
xscale_use_minidata = 0;
- pte_l1_s_cache_mode_pt = pte_l2_l_cache_mode_pt =
- pte_l2_s_cache_mode_pt = 0;
+ /* Make sure it is L2-cachable */
+ pte_l1_s_cache_mode |= L1_S_XSCALE_TEX(TEX_XSCALE_T);
+ pte_l1_s_cache_mode_pt = pte_l1_s_cache_mode &~ L1_S_XSCALE_P;
+ pte_l2_l_cache_mode |= L2_XSCALE_L_TEX(TEX_XSCALE_T) ;
+ pte_l2_l_cache_mode_pt = pte_l1_s_cache_mode;
+ pte_l2_s_cache_mode |= L2_XSCALE_T_TEX(TEX_XSCALE_T);
+ pte_l2_s_cache_mode_pt = pte_l2_s_cache_mode;
+
#else
pmap_copy_page_func = pmap_copy_page_xscale;
pmap_zero_page_func = pmap_zero_page_xscale;
@@ -2818,33 +2824,35 @@ pmap_remove_pages(pmap_t pmap)
* Low level mapping routines.....
***************************************************/
+#ifdef ARM_HAVE_SUPERSECTIONS
/* Map a super section into the KVA. */
void
pmap_kenter_supersection(vm_offset_t va, uint64_t pa, int flags)
{
- pd_entry_t pd = L1_S_PROTO | L1_S_SUPERSEC | (pa & L1_SUP_OFFSET) |
- (((pa >> 32) & 0x8) << 20) | L1_S_PROT(PTE_KERNEL,
+ pd_entry_t pd = L1_S_PROTO | L1_S_SUPERSEC | (pa & L1_SUP_FRAME) |
+ (((pa >> 32) & 0xf) << 20) | L1_S_PROT(PTE_KERNEL,
VM_PROT_READ|VM_PROT_WRITE) | L1_S_DOM(PMAP_DOMAIN_KERNEL);
struct l1_ttable *l1;
- vm_offset_t va_end;
+ vm_offset_t va0, va_end;
KASSERT(((va | pa) & L1_SUP_OFFSET) == 0,
- ("Not a valid section mapping"));
+ ("Not a valid super section mapping"));
if (flags & SECTION_CACHE)
pd |= pte_l1_s_cache_mode;
else if (flags & SECTION_PT)
pd |= pte_l1_s_cache_mode_pt;
- va = va & L1_SUP_OFFSET;
+ va0 = va & L1_SUP_FRAME;
va_end = va + L1_SUP_SIZE;
SLIST_FOREACH(l1, &l1_list, l1_link) {
+ va = va0;
for (; va < va_end; va += L1_S_SIZE) {
l1->l1_kva[L1_IDX(va)] = pd;
PTE_SYNC(&l1->l1_kva[L1_IDX(va)]);
}
}
-
}
+#endif
/* Map a section into the KVA. */
@@ -3681,7 +3689,11 @@ pmap_extract(pmap_t pm, vm_offset_t va)
* These should only happen for pmap_kernel()
*/
KASSERT(pm == pmap_kernel(), ("huh"));
- pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+ /* XXX: what to do about the bits > 32 ? */
+ if (l1pd & L1_S_SUPERSEC)
+ pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+ else
+ pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
} else {
/*
* Note that we can't rely on the validity of the L1
@@ -3744,7 +3756,11 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
* These should only happen for pmap_kernel()
*/
KASSERT(pmap == pmap_kernel(), ("huh"));
- pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+ /* XXX: what to do about the bits > 32 ? */
+ if (l1pd & L1_S_SUPERSEC)
+ pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+ else
+ pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
if (l1pd & L1_S_PROT_W || (prot & VM_PROT_WRITE) == 0) {
m = PHYS_TO_VM_PAGE(pa);
vm_page_hold(m);
diff --git a/sys/arm/include/pmap.h b/sys/arm/include/pmap.h
index 081499d..906b03f 100644
--- a/sys/arm/include/pmap.h
+++ b/sys/arm/include/pmap.h
@@ -264,14 +264,16 @@ extern int pmap_needs_pte_sync;
#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_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_XSCALE_TEX(TEX_XSCALE_X)|\
+ L1_S_XSCALE_TEX(TEX_XSCALE_T))
#define L2_L_PROT_U (L2_AP(AP_U))
#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_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_XSCALE_L_TEX(TEX_XSCALE_X) | \
+ L2_XSCALE_L_TEX(TEX_XSCALE_T))
#define L2_S_PROT_U_generic (L2_AP(AP_U))
#define L2_S_PROT_W_generic (L2_AP(AP_W))
@@ -282,7 +284,8 @@ extern int pmap_needs_pte_sync;
#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_xscale (L2_B|L2_C|L2_XSCALE_T_TEX(TEX_XSCALE_X))
+#define L2_S_CACHE_MASK_xscale (L2_B|L2_C|L2_XSCALE_T_TEX(TEX_XSCALE_X)| \
+ L2_XSCALE_T_TEX(TEX_XSCALE_X))
#define L1_S_PROTO_generic (L1_TYPE_S | L1_S_IMP)
#define L1_S_PROTO_xscale (L1_TYPE_S)
@@ -348,6 +351,9 @@ extern int pmap_needs_pte_sync;
#if (ARM_MMU_SA1 == 1) && (ARM_NMMUS == 1)
#define PMAP_NEEDS_PTE_SYNC 1
#define PMAP_INCLUDE_PTE_SYNC
+#elif defined(CPU_XSCALE_81342)
+#define PMAP_NEEDS_PTE_SYNC 1
+#define PMAP_INCLUDE_PTE_SYNC
#elif (ARM_MMU_SA1 == 0)
#define PMAP_NEEDS_PTE_SYNC 0
#endif
@@ -387,8 +393,10 @@ extern int pmap_needs_pte_sync;
#define PTE_SYNC(pte) \
do { \
- if (PMAP_NEEDS_PTE_SYNC) \
+ if (PMAP_NEEDS_PTE_SYNC) { \
cpu_dcache_wb_range((vm_offset_t)(pte), sizeof(pt_entry_t));\
+ cpu_l2cache_wb_range((vm_offset_t)(pte), sizeof(pt_entry_t));\
+ }\
} while (/*CONSTCOND*/0)
#define PTE_SYNC_RANGE(pte, cnt) \
@@ -396,6 +404,8 @@ do { \
if (PMAP_NEEDS_PTE_SYNC) { \
cpu_dcache_wb_range((vm_offset_t)(pte), \
(cnt) << 2); /* * sizeof(pt_entry_t) */ \
+ cpu_l2cache_wb_range((vm_offset_t)(pte), \
+ (cnt) << 2); /* * sizeof(pt_entry_t) */ \
} \
} while (/*CONSTCOND*/0)
@@ -453,6 +463,10 @@ void xscale_setup_minidata(vm_offset_t, vm_offset_t, vm_offset_t);
void pmap_use_minicache(vm_offset_t, vm_size_t);
#endif /* ARM_MMU_XSCALE == 1 */
+#if defined(CPU_XSCALE_81342)
+#define ARM_HAVE_SUPERSECTIONS
+#endif
+
#define PTE_KERNEL 0
#define PTE_USER 1
#define l1pte_valid(pde) ((pde) != 0)
@@ -521,7 +535,9 @@ void pmap_devmap_register(const struct pmap_devmap *);
#define SECTION_CACHE 0x1
#define SECTION_PT 0x2
void pmap_kenter_section(vm_offset_t, vm_paddr_t, int flags);
+#ifdef ARM_HAVE_SUPERSECTIONS
void pmap_kenter_supersection(vm_offset_t, uint64_t, int flags);
+#endif
extern char *_tmppt;
OpenPOWER on IntegriCloud