summaryrefslogtreecommitdiff
path: root/arch/nds32/include/asm/pgalloc.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 19:41:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 19:41:08 -0700
commitc9297d284126b80c9cfd72c690e0da531c99fc48 (patch)
treebec7ce343f2a37def4e99ec556deb3998dbeb041 /arch/nds32/include/asm/pgalloc.h
parent17e3cd222af1c72a750cd83565bb8dfc7bc12335 (diff)
parent6fc61ee69433e7e0433cabd36f78bb5fb3b26524 (diff)
Merge tag 'nds32-for-linus-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux
Pull nds32 architecture support from Greentime Hu: "This contains the core nds32 Linux port (including interrupt controller driver and timer driver), which has been through seven rounds of review on mailing list. It is able to boot to shell and passes most LTP-2017 testsuites in nds32 AE3XX platform: Total Tests: 1901 Total Skipped Tests: 618 Total Failures: 78" Reviewed-by: Arnd Bergmann <arnd@arndb.de> * tag 'nds32-for-linus-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux: (44 commits) nds32: To use the generic dump_stack() nds32: fix building failed if using elf toolchain. nios2: add ioremap_nocache declaration before include asm-generic/io.h. nds32: fix building failed if using older version gcc. dt-bindings: timer: Add andestech atcpit100 timer binding doc clocksource/drivers/atcpit100: VDSO support clocksource/drivers/atcpit100: Add andestech atcpit100 timer net: faraday add nds32 support. irqchip: Andestech Internal Vector Interrupt Controller driver dt-bindings: interrupt-controller: Andestech Internal Vector Interrupt Controller dt-bindings: nds32 SoC Bindings dt-bindings: nds32 L2 cache controller Bindings dt-bindings: nds32 CPU Bindings MAINTAINERS: Add nds32 nds32: Build infrastructure nds32: defconfig nds32: Miscellaneous header files nds32: Device tree support nds32: Generic timers support nds32: Loadable modules ...
Diffstat (limited to 'arch/nds32/include/asm/pgalloc.h')
-rw-r--r--arch/nds32/include/asm/pgalloc.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/arch/nds32/include/asm/pgalloc.h b/arch/nds32/include/asm/pgalloc.h
new file mode 100644
index 000000000000..27448869131a
--- /dev/null
+++ b/arch/nds32/include/asm/pgalloc.h
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef _ASMNDS32_PGALLOC_H
+#define _ASMNDS32_PGALLOC_H
+
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/proc-fns.h>
+
+/*
+ * Since we have only two-level page tables, these are trivial
+ */
+#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
+#define pmd_free(mm, pmd) do { } while (0)
+#define pgd_populate(mm, pmd, pte) BUG()
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+extern pgd_t *pgd_alloc(struct mm_struct *mm);
+extern void pgd_free(struct mm_struct *mm, pgd_t * pgd);
+
+#define check_pgt_cache() do { } while (0)
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long addr)
+{
+ pte_t *pte;
+
+ pte =
+ (pte_t *) __get_free_page(GFP_KERNEL | __GFP_RETRY_MAYFAIL |
+ __GFP_ZERO);
+
+ return pte;
+}
+
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ pgtable_t pte;
+
+ pte = alloc_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_ZERO, 0);
+ if (pte)
+ cpu_dcache_wb_page((unsigned long)page_address(pte));
+
+ return pte;
+}
+
+/*
+ * Free one PTE table.
+ */
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t * pte)
+{
+ if (pte) {
+ free_page((unsigned long)pte);
+ }
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+ __free_page(pte);
+}
+
+/*
+ * Populate the pmdp entry with a pointer to the pte. This pmd is part
+ * of the mm address space.
+ *
+ * Ensure that we always set both PMD entries.
+ */
+static inline void
+pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmdp, pte_t * ptep)
+{
+ unsigned long pte_ptr = (unsigned long)ptep;
+ unsigned long pmdval;
+
+ BUG_ON(mm != &init_mm);
+
+ /*
+ * The pmd must be loaded with the physical
+ * address of the PTE table
+ */
+ pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
+ set_pmd(pmdp, __pmd(pmdval));
+}
+
+static inline void
+pmd_populate(struct mm_struct *mm, pmd_t * pmdp, pgtable_t ptep)
+{
+ unsigned long pmdval;
+
+ BUG_ON(mm == &init_mm);
+
+ pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE;
+ set_pmd(pmdp, __pmd(pmdval));
+}
+
+#endif