summaryrefslogtreecommitdiffstats
path: root/arch/csky/include/asm/pgalloc.h
diff options
context:
space:
mode:
authorGuo Ren <ren_guo@c-sky.com>2018-09-05 14:25:12 +0800
committerGuo Ren <ren_guo@c-sky.com>2018-10-25 23:36:19 +0800
commit013de2d6671d89de3397904749c86a69ac0686f7 (patch)
treea957e4719ccb7f7383bfa17f8937d61409ee9119 /arch/csky/include/asm/pgalloc.h
parent00a9730e1007c6cc87a7c78af2f24a4105d616ee (diff)
downloadlinux-013de2d6671d89de3397904749c86a69ac0686f7.tar.bz2
csky: MMU and page table management
This patch adds files related to memory management and here is our memory-layout: Fixmap : 0xffc02000 – 0xfffff000 (4 MB - 12KB) Pkmap : 0xff800000 – 0xffc00000 (4 MB) Vmalloc : 0xf0200000 – 0xff000000 (238 MB) Lowmem : 0x80000000 – 0xc0000000 (1GB) abiv1 CPU (CK610) is VIPT cache and it doesn't support highmem. abiv2 CPUs are all PIPT cache and they could support highmem. Lowmem is directly mapped by msa0 & msa1 reg, and we needn't setup memory page table for it. Link:https://lore.kernel.org/lkml/20180518215548.GH17671@n2100.armlinux.org.uk/ Signed-off-by: Guo Ren <ren_guo@c-sky.com> Cc: Christoph Hellwig <hch@infradead.org> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/csky/include/asm/pgalloc.h')
-rw-r--r--arch/csky/include/asm/pgalloc.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h
new file mode 100644
index 000000000000..bf4f4a0e140e
--- /dev/null
+++ b/arch/csky/include/asm/pgalloc.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#ifndef __ASM_CSKY_PGALLOC_H
+#define __ASM_CSKY_PGALLOC_H
+
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+{
+ set_pmd(pmd, __pmd(__pa(pte)));
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+ pgtable_t pte)
+{
+ set_pmd(pmd, __pmd(__pa(page_address(pte))));
+}
+
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+extern void pgd_init(unsigned long *p);
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
+{
+ pte_t *pte;
+ unsigned long *kaddr, i;
+
+ pte = (pte_t *) __get_free_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL,
+ PTE_ORDER);
+ kaddr = (unsigned long *)pte;
+ if (address & 0x80000000)
+ for (i = 0; i < (PAGE_SIZE/4); i++)
+ *(kaddr + i) = 0x1;
+ else
+ clear_page(kaddr);
+
+ return pte;
+}
+
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+{
+ struct page *pte;
+ unsigned long *kaddr, i;
+
+ pte = alloc_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL, PTE_ORDER);
+ if (pte) {
+ kaddr = kmap_atomic(pte);
+ if (address & 0x80000000) {
+ for (i = 0; i < (PAGE_SIZE/4); i++)
+ *(kaddr + i) = 0x1;
+ } else
+ clear_page(kaddr);
+ kunmap_atomic(kaddr);
+ pgtable_page_ctor(pte);
+ }
+ return pte;
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+ free_pages((unsigned long)pte, PTE_ORDER);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+ pgtable_page_dtor(pte);
+ __free_pages(pte, PTE_ORDER);
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+ free_pages((unsigned long)pgd, PGD_ORDER);
+}
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ pgd_t *ret;
+ pgd_t *init;
+
+ ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
+ if (ret) {
+ init = pgd_offset(&init_mm, 0UL);
+ pgd_init((unsigned long *)ret);
+ memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+ /* prevent out of order excute */
+ smp_mb();
+#ifdef CONFIG_CPU_NEED_TLBSYNC
+ dcache_wb_range((unsigned int)ret,
+ (unsigned int)(ret + PTRS_PER_PGD));
+#endif
+ }
+
+ return ret;
+}
+
+#define __pte_free_tlb(tlb, pte, address) \
+do { \
+ pgtable_page_dtor(pte); \
+ tlb_remove_page(tlb, pte); \
+} while (0)
+
+#define check_pgt_cache() do {} while (0)
+
+extern void pagetable_init(void);
+extern void pre_mmu_init(void);
+extern void pre_trap_init(void);
+
+#endif /* __ASM_CSKY_PGALLOC_H */