[PATCH 11/15] arm: import more linux page table api

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



To use page level descriptors we need some pgd/pud/pmd/pte
methods, and a few more flags defined.

Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx>
---
 lib/arm/asm/mmu.h           | 16 +-------
 lib/arm/asm/pgtable-hwdef.h | 38 ++++++++++++++++++-
 lib/arm/asm/pgtable.h       | 91 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 129 insertions(+), 16 deletions(-)
 create mode 100644 lib/arm/asm/pgtable.h

diff --git a/lib/arm/asm/mmu.h b/lib/arm/asm/mmu.h
index 8090a1b554820..254c29f84fe6f 100644
--- a/lib/arm/asm/mmu.h
+++ b/lib/arm/asm/mmu.h
@@ -5,22 +5,8 @@
  *
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
-#include <asm/setup.h>
+#include <asm/pgtable.h>
 #include <asm/barrier.h>
-#include <alloc.h>
-
-#define PTRS_PER_PGD	4
-#define PGDIR_SHIFT	30
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK	(~((1 << PGDIR_SHIFT) - 1))
-
-#define pgd_free(pgd) free(pgd)
-static inline pgd_t *pgd_alloc(void)
-{
-	pgd_t *pgd = memalign(L1_CACHE_BYTES, PTRS_PER_PGD * sizeof(pgd_t));
-	memset(pgd, 0, PTRS_PER_PGD * sizeof(pgd_t));
-	return pgd;
-}
 
 static inline void local_flush_tlb_all(void)
 {
diff --git a/lib/arm/asm/pgtable-hwdef.h b/lib/arm/asm/pgtable-hwdef.h
index b6850f64b0f52..13a273d36e8fe 100644
--- a/lib/arm/asm/pgtable-hwdef.h
+++ b/lib/arm/asm/pgtable-hwdef.h
@@ -1,9 +1,45 @@
 #ifndef _ASMARM_PGTABLE_HWDEF_H_
 #define _ASMARM_PGTABLE_HWDEF_H_
 /*
- * From arch/arm/include/asm/pgtable-3level-hwdef.h
+ * From arch/arm/include/asm/pgtable-3level.h
+ *      arch/arm/include/asm/pgtable-3level-hwdef.h
  */
 
+#define PTRS_PER_PGD		4
+#define PGDIR_SHIFT		30
+#define PGDIR_SIZE		(_AC(1,UL) << PGDIR_SHIFT)
+#define PGDIR_MASK		(~((1 << PGDIR_SHIFT) - 1))
+
+#define PTRS_PER_PTE		512
+#define PTRS_PER_PMD		512
+
+#define PMD_SHIFT		21
+#define PMD_SIZE		(_AC(1,UL) << PMD_SHIFT)
+#define PMD_MASK		(~((1 << PMD_SHIFT) - 1))
+
+#define L_PMD_SECT_VALID	(_AT(pmdval_t, 1) << 0)
+
+#define L_PTE_VALID		(_AT(pteval_t, 1) << 0)		/* Valid */
+#define L_PTE_PRESENT		(_AT(pteval_t, 3) << 0)		/* Present */
+#define L_PTE_USER		(_AT(pteval_t, 1) << 6)		/* AP[1] */
+#define L_PTE_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
+#define L_PTE_YOUNG		(_AT(pteval_t, 1) << 10)	/* AF */
+#define L_PTE_XN		(_AT(pteval_t, 1) << 54)	/* XN */
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define L_PTE_MT_UNCACHED	(_AT(pteval_t, 0) << 2)	/* strongly ordered */
+#define L_PTE_MT_BUFFERABLE	(_AT(pteval_t, 1) << 2)	/* normal non-cacheable */
+#define L_PTE_MT_WRITETHROUGH	(_AT(pteval_t, 2) << 2)	/* normal inner write-through */
+#define L_PTE_MT_WRITEBACK	(_AT(pteval_t, 3) << 2)	/* normal inner write-back */
+#define L_PTE_MT_WRITEALLOC	(_AT(pteval_t, 7) << 2)	/* normal inner write-alloc */
+#define L_PTE_MT_DEV_SHARED	(_AT(pteval_t, 4) << 2)	/* device */
+#define L_PTE_MT_DEV_NONSHARED	(_AT(pteval_t, 4) << 2)	/* device */
+#define L_PTE_MT_DEV_WC		(_AT(pteval_t, 1) << 2)	/* normal non-cacheable */
+#define L_PTE_MT_DEV_CACHED	(_AT(pteval_t, 3) << 2)	/* normal inner write-back */
+#define L_PTE_MT_MASK		(_AT(pteval_t, 7) << 2)
+
 /*
  * Hardware page table definitions.
  *
diff --git a/lib/arm/asm/pgtable.h b/lib/arm/asm/pgtable.h
new file mode 100644
index 0000000000000..8a730f44e537b
--- /dev/null
+++ b/lib/arm/asm/pgtable.h
@@ -0,0 +1,91 @@
+#ifndef _ASMARM_PGTABLE_H_
+#define _ASMARM_PGTABLE_H_
+/*
+ * Adapted from arch/arm/include/asm/pgtable.h
+ *              arch/arm/include/asm/pgtable-3level.h
+ *              arch/arm/include/asm/pgalloc.h
+ *              include/asm-generic/pgtable-nopud.h
+ *
+ * Note: some Linux function APIs have been modified. Nothing crazy,
+ *       but if a function took, for example, an mm_struct, then
+ *       that was either removed or replaced.
+ */
+#include <alloc.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable-hwdef.h>
+
+#define pgd_none(pgd)		(!pgd_val(pgd))
+#define pud_none(pud)		(!pud_val(pud))
+#define pmd_none(pmd)		(!pmd_val(pmd))
+#define pte_none(pte)		(!pte_val(pte))
+
+#define pgd_index(addr) \
+	(((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+#define pgd_offset(pgtable, addr) ((pgtable) + pgd_index(addr))
+
+#define pgd_free(pgd) free(pgd)
+static inline pgd_t *pgd_alloc(void)
+{
+	pgd_t *pgd = memalign(L1_CACHE_BYTES, PTRS_PER_PGD * sizeof(pgd_t));
+	memset(pgd, 0, PTRS_PER_PGD * sizeof(pgd_t));
+	return pgd;
+}
+
+#define pud_offset(pgd, addr)	((pud_t *)pgd)
+#define pud_free(pud)
+#define pud_alloc(pgd, addr)	pud_offset(pgd, addr)
+
+static inline pmd_t *pud_page_vaddr(pud_t pud)
+{
+	return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
+}
+
+#define pmd_index(addr) \
+	(((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
+#define pmd_offset(pud, addr) \
+	(pud_page_vaddr(*(pud)) + pmd_index(addr))
+
+#define pmd_free(pmd) free(pmd)
+static inline pmd_t *pmd_alloc_one(void)
+{
+	pmd_t *pmd = memalign(PAGE_SIZE, PTRS_PER_PMD * sizeof(pmd_t));
+	memset(pmd, 0, PTRS_PER_PMD * sizeof(pmd_t));
+	return pmd;
+}
+static inline pmd_t *pmd_alloc(pud_t *pud, unsigned long addr)
+{
+	if (pud_none(*pud)) {
+		pmd_t *pmd = pmd_alloc_one();
+		pud_val(*pud) = __pa(pmd) | PMD_TYPE_TABLE;
+	}
+	return pmd_offset(pud, addr);
+}
+
+static inline pte_t *pmd_page_vaddr(pmd_t pmd)
+{
+	return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
+}
+
+#define pte_index(addr) \
+	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset(pmd, addr) \
+	(pmd_page_vaddr(*(pmd)) + pte_index(addr))
+
+#define pte_free(pte) free(pte)
+static inline pte_t *pte_alloc_one(void)
+{
+	pte_t *pte = memalign(PAGE_SIZE, PTRS_PER_PTE * sizeof(pte_t));
+	memset(pte, 0, PTRS_PER_PTE * sizeof(pte_t));
+	return pte;
+}
+static inline pte_t *pte_alloc(pmd_t *pmd, unsigned long addr)
+{
+	if (pmd_none(*pmd)) {
+		pte_t *pte = pte_alloc_one();
+		pmd_val(*pmd) = __pa(pte) | PMD_TYPE_TABLE;
+	}
+	return pte_offset(pmd, addr);
+}
+
+#endif /* _ASMARM_PGTABLE_H_ */
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux