|
@@ -166,3 +166,163 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|
#define pgd_ERROR(e) \
|
|
#define pgd_ERROR(e) \
|
|
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e))))
|
|
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e))))
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Certain architectures need to do special things when PTEs
|
|
|
|
+ * within a page table are directly modified. Thus, the following
|
|
|
|
+ * hook is made available.
|
|
|
|
+ */
|
|
|
|
+#define set_pte(pteptr, pteval) \
|
|
|
|
+do { \
|
|
|
|
+ *(pteptr) = (pteval); \
|
|
|
|
+ asm volatile("dcf %M0" :: "U"(*pteptr)); \
|
|
|
|
+} while(0)
|
|
|
|
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * pgd_offset() returns a (pgd_t *)
|
|
|
|
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
|
|
|
|
+ */
|
|
|
|
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * a shortcut which implies the use of the kernel's pgd, instead
|
|
|
|
+ * of a process's
|
|
|
|
+ */
|
|
|
|
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
|
|
|
|
+ * setup: the pud is never bad, and a pud always exists (as it's folded
|
|
|
|
+ * into the pgd entry)
|
|
|
|
+ */
|
|
|
|
+static inline int pgd_none(pgd_t pgd) { return 0; }
|
|
|
|
+static inline int pgd_bad(pgd_t pgd) { return 0; }
|
|
|
|
+static inline int pgd_present(pgd_t pgd) { return 1; }
|
|
|
|
+static inline void pgd_clear(pgd_t *pgd) { }
|
|
|
|
+
|
|
|
|
+#define pgd_populate(mm, pgd, pud) do { } while (0)
|
|
|
|
+/*
|
|
|
|
+ * (puds are folded into pgds so this doesn't get actually called,
|
|
|
|
+ * but the define is needed for a generic inline function.)
|
|
|
|
+ */
|
|
|
|
+#define set_pgd(pgdptr, pgdval) \
|
|
|
|
+do { \
|
|
|
|
+ memcpy((pgdptr), &(pgdval), sizeof(pgd_t)); \
|
|
|
|
+ asm volatile("dcf %M0" :: "U"(*(pgdptr))); \
|
|
|
|
+} while(0)
|
|
|
|
+
|
|
|
|
+static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
|
|
|
|
+{
|
|
|
|
+ return (pud_t *) pgd;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define pgd_page(pgd) (pud_page((pud_t){ pgd }))
|
|
|
|
+#define pgd_page_vaddr(pgd) (pud_page_vaddr((pud_t){ pgd }))
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * allocating and freeing a pud is trivial: the 1-entry pud is
|
|
|
|
+ * inside the pgd, so has no extra memory associated with it.
|
|
|
|
+ */
|
|
|
|
+#define pud_alloc_one(mm, address) NULL
|
|
|
|
+#define pud_free(mm, x) do { } while (0)
|
|
|
|
+#define __pud_free_tlb(tlb, x, address) do { } while (0)
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * The "pud_xxx()" functions here are trivial for a folded two-level
|
|
|
|
+ * setup: the pmd is never bad, and a pmd always exists (as it's folded
|
|
|
|
+ * into the pud entry)
|
|
|
|
+ */
|
|
|
|
+static inline int pud_none(pud_t pud) { return 0; }
|
|
|
|
+static inline int pud_bad(pud_t pud) { return 0; }
|
|
|
|
+static inline int pud_present(pud_t pud) { return 1; }
|
|
|
|
+static inline void pud_clear(pud_t *pud) { }
|
|
|
|
+
|
|
|
|
+#define pud_populate(mm, pmd, pte) do { } while (0)
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * (pmds are folded into puds so this doesn't get actually called,
|
|
|
|
+ * but the define is needed for a generic inline function.)
|
|
|
|
+ */
|
|
|
|
+#define set_pud(pudptr, pudval) set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval })
|
|
|
|
+
|
|
|
|
+#define pud_page(pud) (pmd_page((pmd_t){ pud }))
|
|
|
|
+#define pud_page_vaddr(pud) (pmd_page_vaddr((pmd_t){ pud }))
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * (pmds are folded into pgds so this doesn't get actually called,
|
|
|
|
+ * but the define is needed for a generic inline function.)
|
|
|
|
+ */
|
|
|
|
+extern void __set_pmd(pmd_t *pmdptr, unsigned long __pmd);
|
|
|
|
+
|
|
|
|
+#define set_pmd(pmdptr, pmdval) \
|
|
|
|
+do { \
|
|
|
|
+ __set_pmd((pmdptr), (pmdval).ste[0]); \
|
|
|
|
+} while(0)
|
|
|
|
+
|
|
|
|
+#define __pmd_index(address) 0
|
|
|
|
+
|
|
|
|
+static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address)
|
|
|
|
+{
|
|
|
|
+ return (pmd_t *) dir + __pmd_index(address);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define pte_same(a, b) ((a).pte == (b).pte)
|
|
|
|
+#define pte_page(x) (mem_map + ((unsigned long)(((x).pte >> PAGE_SHIFT))))
|
|
|
|
+#define pte_none(x) (!(x).pte)
|
|
|
|
+#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT)))
|
|
|
|
+#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
|
|
|
|
+#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
|
|
|
|
+
|
|
|
|
+#define VMALLOC_VMADDR(x) ((unsigned long) (x))
|
|
|
|
+
|
|
|
|
+#endif /* !__ASSEMBLY__ */
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * control flags in AMPR registers and TLB entries
|
|
|
|
+ */
|
|
|
|
+#define _PAGE_BIT_PRESENT xAMPRx_V_BIT
|
|
|
|
+#define _PAGE_BIT_WP DAMPRx_WP_BIT
|
|
|
|
+#define _PAGE_BIT_NOCACHE xAMPRx_C_BIT
|
|
|
|
+#define _PAGE_BIT_SUPER xAMPRx_S_BIT
|
|
|
|
+#define _PAGE_BIT_ACCESSED xAMPRx_RESERVED8_BIT
|
|
|
|
+#define _PAGE_BIT_DIRTY xAMPRx_M_BIT
|
|
|
|
+#define _PAGE_BIT_NOTGLOBAL xAMPRx_NG_BIT
|
|
|
|
+
|
|
|
|
+#define _PAGE_PRESENT xAMPRx_V
|
|
|
|
+#define _PAGE_WP DAMPRx_WP
|
|
|
|
+#define _PAGE_NOCACHE xAMPRx_C
|
|
|
|
+#define _PAGE_SUPER xAMPRx_S
|
|
|
|
+#define _PAGE_ACCESSED xAMPRx_RESERVED8 /* accessed if set */
|
|
|
|
+#define _PAGE_DIRTY xAMPRx_M
|
|
|
|
+#define _PAGE_NOTGLOBAL xAMPRx_NG
|
|
|
|
+
|
|
|
|
+#define _PAGE_RESERVED_MASK (xAMPRx_RESERVED8 | xAMPRx_RESERVED13)
|
|
|
|
+
|
|
|
|
+#define _PAGE_FILE 0x002 /* set:pagecache unset:swap */
|
|
|
|
+#define _PAGE_PROTNONE 0x000 /* If not present */
|
|
|
|
+
|
|
|
|
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
|
|
|
|
+
|
|
|
|
+#define __PGPROT_BASE \
|
|
|
|
+ (_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED)
|
|
|
|
+
|
|
|
|
+#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
|
|
|
|
+#define PAGE_SHARED __pgprot(__PGPROT_BASE)
|
|
|
|
+#define PAGE_COPY __pgprot(__PGPROT_BASE | _PAGE_WP)
|
|
|
|
+#define PAGE_READONLY __pgprot(__PGPROT_BASE | _PAGE_WP)
|
|
|
|
+
|
|
|
|
+#define __PAGE_KERNEL (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY)
|
|
|
|
+#define __PAGE_KERNEL_NOCACHE (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE)
|
|
|
|
+#define __PAGE_KERNEL_RO (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP)
|
|
|
|
+
|
|
|
|
+#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL)
|
|
|
|
+
|
|
|
|
+#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
|
|
|
|
+#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
|
|
|
|
+#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
|
|
|
|
+
|
|
|
|
+#define _PAGE_TABLE (_PAGE_PRESENT | xAMPRx_SS_16Kb)
|
|
|
|
+
|
|
|
|
+#ifndef __ASSEMBLY__
|
|
|
|
+
|
|
|
|
+/*
|