summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormmel <mmel@FreeBSD.org>2017-05-23 12:03:59 +0000
committermmel <mmel@FreeBSD.org>2017-05-23 12:03:59 +0000
commitec6744a8aa29e6f78a6680cfc47e0fcf8a164b85 (patch)
tree1e6e3515ec3017a980b509ae6508954255c860d2
parent4e495f5663f0b8fe6796934ab90f087931c2b9d1 (diff)
downloadFreeBSD-src-ec6744a8aa29e6f78a6680cfc47e0fcf8a164b85.zip
FreeBSD-src-ec6744a8aa29e6f78a6680cfc47e0fcf8a164b85.tar.gz
MFC r318021,r318251:
r318021: Introduce pmap_remap_vm_attr(), it allows to remap one VM memattr class to another. r318251: Clarify usage rules for pmap_remap_vm_attr(). Not a functional change.
-rw-r--r--sys/arm/arm/pmap-v6.c36
-rw-r--r--sys/arm/include/pmap-v6.h1
2 files changed, 37 insertions, 0 deletions
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index 1293147..3f41192 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -497,6 +497,42 @@ pmap_set_tex(void)
}
/*
+ * Remap one vm_meattr class to another one. This can be useful as
+ * workaround for SOC errata, e.g. if devices must be accessed using
+ * SO memory class.
+ *
+ * !!! Please note that this function is absolutely last resort thing.
+ * It should not be used under normal circumstances. !!!
+ *
+ * Usage rules:
+ * - it shall be called after pmap_bootstrap_prepare() and before
+ * cpu_mp_start() (thus only on boot CPU). In practice, it's expected
+ * to be called from platform_attach() or platform_late_init().
+ *
+ * - if remapping doesn't change caching mode, or until uncached class
+ * is remapped to any kind of cached one, then no other restriction exists.
+ *
+ * - if pmap_remap_vm_attr() changes caching mode, but both (original and
+ * remapped) remain cached, then caller is resposible for calling
+ * of dcache_wbinv_poc_all().
+ *
+ * - remapping of any kind of cached class to uncached is not permitted.
+ */
+void
+pmap_remap_vm_attr(vm_memattr_t old_attr, vm_memattr_t new_attr)
+{
+ int old_idx, new_idx;
+
+ /* Map VM memattrs to indexes to tex_class table. */
+ old_idx = pte2_attr_tab[(int)old_attr];
+ new_idx = pte2_attr_tab[(int)new_attr];
+
+ /* Replace TEX attribute and apply it. */
+ tex_class[old_idx] = tex_class[new_idx];
+ pmap_set_tex();
+}
+
+/*
* KERNBASE must be multiple of NPT2_IN_PG * PTE1_SIZE. In other words,
* KERNBASE is mapped by first L2 page table in L2 page table page. It
* meets same constrain due to PT2MAP being placed just under KERNBASE.
diff --git a/sys/arm/include/pmap-v6.h b/sys/arm/include/pmap-v6.h
index 10296db..e25f7f0 100644
--- a/sys/arm/include/pmap-v6.h
+++ b/sys/arm/include/pmap-v6.h
@@ -189,6 +189,7 @@ vm_offset_t pmap_preboot_reserve_pages(u_int);
vm_offset_t pmap_preboot_get_vpages(u_int);
void pmap_preboot_map_attr(vm_paddr_t, vm_offset_t, vm_size_t, vm_prot_t,
vm_memattr_t);
+void pmap_remap_vm_attr(vm_memattr_t old_attr, vm_memattr_t new_attr);
#endif /* _KERNEL */
#endif /* !_MACHINE_PMAP_V6_H_ */
OpenPOWER on IntegriCloud