diff options
author | cognet <cognet@FreeBSD.org> | 2007-07-27 14:45:04 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2007-07-27 14:45:04 +0000 |
commit | 8b22cea67fcdb76cadb7c4ab11354385ffeafa90 (patch) | |
tree | beb6c44ae86543f3f85dd4f4e2af5bbd14e82185 /sys | |
parent | d9f013dcfb25eafb521de47bfde07fd599bf100a (diff) | |
download | FreeBSD-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.c | 36 | ||||
-rw-r--r-- | sys/arm/include/pmap.h | 24 |
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; |