diff options
author | Guo Ren <ren_guo@c-sky.com> | 2018-09-05 08:25:12 +0200 |
---|---|---|
committer | Guo Ren <ren_guo@c-sky.com> | 2018-10-25 17:36:19 +0200 |
commit | 013de2d6671d89de3397904749c86a69ac0686f7 (patch) | |
tree | a957e4719ccb7f7383bfa17f8937d61409ee9119 /arch/csky/abiv1/mmap.c | |
parent | csky: Cache and TLB routines (diff) | |
download | linux-013de2d6671d89de3397904749c86a69ac0686f7.tar.xz linux-013de2d6671d89de3397904749c86a69ac0686f7.zip |
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/abiv1/mmap.c')
-rw-r--r-- | arch/csky/abiv1/mmap.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c new file mode 100644 index 000000000000..b462fd50b23a --- /dev/null +++ b/arch/csky/abiv1/mmap.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/shm.h> +#include <linux/sched.h> +#include <linux/random.h> +#include <linux/io.h> + +unsigned long shm_align_mask = (0x4000 >> 1) - 1; /* Sane caches */ + +#define COLOUR_ALIGN(addr, pgoff) \ + ((((addr) + shm_align_mask) & ~shm_align_mask) + \ + (((pgoff) << PAGE_SHIFT) & shm_align_mask)) + +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct vm_area_struct *vmm; + int do_color_align; + + if (flags & MAP_FIXED) { + /* + * We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ + if ((flags & MAP_SHARED) && + ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask)) + return -EINVAL; + return addr; + } + + if (len > TASK_SIZE) + return -ENOMEM; + do_color_align = 0; + if (filp || (flags & MAP_SHARED)) + do_color_align = 1; + if (addr) { + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + vmm = find_vma(current->mm, addr); + if (TASK_SIZE - len >= addr && + (!vmm || addr + len <= vmm->vm_start)) + return addr; + } + addr = TASK_UNMAPPED_BASE; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + + for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { + /* At this point: (!vmm || addr < vmm->vm_end). */ + if (TASK_SIZE - len < addr) + return -ENOMEM; + if (!vmm || addr + len <= vmm->vm_start) + return addr; + addr = vmm->vm_end; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + } +} |