|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC v01 2/3] arm: omap: translate iommu mapping to 4K pages
Patch introduces the following algorithm:
- enumerates all first level translation entries
- for each section creates 256 pages, each page is 4096 bytes
- for each supersection creates 4096 pages, each page is 4096 bytes
- flush cache to synchronize Cortex M15 and IOMMU
This algorithm make possible to use 4K mapping only.
Change-Id: Ie2cf45f23e0c170e9ba9d58f8dbb917348fdbd33
Signed-off-by: Andrii Tseglytskyi <andrii.tseglytskyi@xxxxxxxxxxxxxxx>
---
xen/arch/arm/omap_iommu.c | 50 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 4 deletions(-)
diff --git a/xen/arch/arm/omap_iommu.c b/xen/arch/arm/omap_iommu.c
index 4dab30f..7ec03a2 100644
--- a/xen/arch/arm/omap_iommu.c
+++ b/xen/arch/arm/omap_iommu.c
@@ -72,6 +72,9 @@
#define PTRS_PER_IOPTE (1UL << (IOPGD_SHIFT - IOPTE_SMALL_SHIFT))
#define IOPTE_TABLE_SIZE (PTRS_PER_IOPTE * sizeof(u32))
+/* 16 sections in supersection */
+#define IOSECTION_PER_IOSUPER (1UL << (IOSUPER_SHIFT - IOPGD_SHIFT))
+
/*
* some descriptor attributes.
*/
@@ -117,6 +120,9 @@ static struct mmu_info *mmu_list[] = {
&omap_dsp_mmu,
};
+static bool translate_supersections_to_pages = true;
+static bool translate_sections_to_pages = true;
+
#define mmu_for_each(pfunc, data)
\
({
\
u32 __i;
\
@@ -213,6 +219,29 @@ static u32 mmu_translate_pgentry(struct domain *dom, u32
iopgd, u32 da, u32 mask
return vaddr;
}
+static u32 mmu_iopte_alloc(struct mmu_info *mmu, struct domain *dom, u32
iopgd, u32 sect_num)
+{
+ u32 *iopte = NULL;
+ u32 i;
+
+ iopte = xzalloc_bytes(PAGE_SIZE);
+ if (!iopte) {
+ printk("%s Fail to alloc 2nd level table\n", mmu->name);
+ return 0;
+ }
+
+ for (i = 0; i < PTRS_PER_IOPTE; i++) {
+ u32 da, vaddr, iopgd_tmp;
+ da = (sect_num << IOSECTION_SHIFT) + (i << IOPTE_SMALL_SHIFT);
+ iopgd_tmp = (iopgd & IOSECTION_MASK) + (i << IOPTE_SMALL_SHIFT);
+ vaddr = mmu_translate_pgentry(dom, iopgd_tmp, da,
IOPTE_SMALL_MASK);
+ iopte[i] = vaddr | IOPTE_SMALL;
+ }
+
+ flush_xen_dcache_va_range(iopte, PAGE_SIZE);
+ return __pa(iopte) | IOPGD_TABLE;
+}
+
/*
* on boot table is empty
*/
@@ -245,13 +274,26 @@ static int mmu_translate_pagetable(struct domain *dom,
struct mmu_info *mmu)
/* "supersection" 16 Mb */
if (iopgd_is_super(iopgd)) {
- da = i << IOSECTION_SHIFT;
- mmu->pagetable[i] = mmu_translate_pgentry(dom, iopgd,
da, IOSUPER_MASK);
+ if(likely(translate_supersections_to_pages)) {
+ u32 j, iopgd_tmp;
+ for (j = 0 ; j < IOSECTION_PER_IOSUPER; j++) {
+ iopgd_tmp = iopgd + (j *
IOSECTION_SIZE);
+ mmu->pagetable[i + j] =
mmu_iopte_alloc(mmu, dom, iopgd_tmp, i);
+ }
+ i += (j - 1);
+ } else {
+ da = i << IOSECTION_SHIFT;
+ mmu->pagetable[i] = mmu_translate_pgentry(dom,
iopgd, da, IOSUPER_MASK);
+ }
/* "section" 1Mb */
} else if (iopgd_is_section(iopgd)) {
- da = i << IOSECTION_SHIFT;
- mmu->pagetable[i] = mmu_translate_pgentry(dom, iopgd,
da, IOSECTION_MASK);
+ if (likely(translate_sections_to_pages)) {
+ mmu->pagetable[i] = mmu_iopte_alloc(mmu, dom,
iopgd, i);
+ } else {
+ da = i << IOSECTION_SHIFT;
+ mmu->pagetable[i] = mmu_translate_pgentry(dom,
iopgd, da, IOSECTION_MASK);
+ }
/* "table" */
} else if (iopgd_is_table(iopgd)) {
--
1.7.9.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |