summaryrefslogtreecommitdiffstats
path: root/arch/unicore32/include
diff options
context:
space:
mode:
authorGuanXuetao <gxt@mprc.pku.edu.cn>2011-01-15 18:16:59 +0800
committerGuanXuetao <gxt@mprc.pku.edu.cn>2011-03-17 09:19:08 +0800
commitb50f1704e9c441c58cf6dc05e72953ca30e1d4d2 (patch)
treebfd7f81c849aa42f6355d9fb383f2167c5f0e087 /arch/unicore32/include
parentf73670e8a55c11d47c28dca35dc4bc7dfbd4e6eb (diff)
downloadlinux-stable-b50f1704e9c441c58cf6dc05e72953ca30e1d4d2.tar.gz
linux-stable-b50f1704e9c441c58cf6dc05e72953ca30e1d4d2.tar.bz2
linux-stable-b50f1704e9c441c58cf6dc05e72953ca30e1d4d2.zip
unicore32 core architecture: mm related: generic codes
This patch includes generic codes for memory management. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/unicore32/include')
-rw-r--r--arch/unicore32/include/asm/cache.h27
-rw-r--r--arch/unicore32/include/asm/memblock.h46
-rw-r--r--arch/unicore32/include/asm/memory.h123
-rw-r--r--arch/unicore32/include/asm/page.h80
-rw-r--r--arch/unicore32/include/asm/tlb.h98
-rw-r--r--arch/unicore32/include/mach/map.h20
-rw-r--r--arch/unicore32/include/mach/memory.h58
7 files changed, 452 insertions, 0 deletions
diff --git a/arch/unicore32/include/asm/cache.h b/arch/unicore32/include/asm/cache.h
new file mode 100644
index 000000000000..ad8f795d86ca
--- /dev/null
+++ b/arch/unicore32/include/asm/cache.h
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/unicore32/include/asm/cache.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __UNICORE_CACHE_H__
+#define __UNICORE_CACHE_H__
+
+#define L1_CACHE_SHIFT (5)
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+/*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+ * sure that all such allocations are cache aligned. Otherwise,
+ * unrelated code may cause parts of the buffer to be read into the
+ * cache before the transfer is done, causing old data to be seen by
+ * the CPU.
+ */
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+
+#endif
diff --git a/arch/unicore32/include/asm/memblock.h b/arch/unicore32/include/asm/memblock.h
new file mode 100644
index 000000000000..a8a5d8d0a26e
--- /dev/null
+++ b/arch/unicore32/include/asm/memblock.h
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/unicore32/include/asm/memblock.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __UNICORE_MEMBLOCK_H__
+#define __UNICORE_MEMBLOCK_H__
+
+/*
+ * Memory map description
+ */
+# define NR_BANKS 8
+
+struct membank {
+ unsigned long start;
+ unsigned long size;
+ unsigned int highmem;
+};
+
+struct meminfo {
+ int nr_banks;
+ struct membank bank[NR_BANKS];
+};
+
+extern struct meminfo meminfo;
+
+#define for_each_bank(iter, mi) \
+ for (iter = 0; iter < (mi)->nr_banks; iter++)
+
+#define bank_pfn_start(bank) __phys_to_pfn((bank)->start)
+#define bank_pfn_end(bank) __phys_to_pfn((bank)->start + (bank)->size)
+#define bank_pfn_size(bank) ((bank)->size >> PAGE_SHIFT)
+#define bank_phys_start(bank) ((bank)->start)
+#define bank_phys_end(bank) ((bank)->start + (bank)->size)
+#define bank_phys_size(bank) ((bank)->size)
+
+extern void uc32_memblock_init(struct meminfo *);
+
+#endif
diff --git a/arch/unicore32/include/asm/memory.h b/arch/unicore32/include/asm/memory.h
new file mode 100644
index 000000000000..5eddb997defe
--- /dev/null
+++ b/arch/unicore32/include/asm/memory.h
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/unicore32/include/asm/memory.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Note: this file should not be included by non-asm/.h files
+ */
+#ifndef __UNICORE_MEMORY_H__
+#define __UNICORE_MEMORY_H__
+
+#include <linux/compiler.h>
+#include <linux/const.h>
+#include <asm/sizes.h>
+#include <mach/memory.h>
+
+/*
+ * Allow for constants defined here to be used from assembly code
+ * by prepending the UL suffix only with actual C code compilation.
+ */
+#define UL(x) _AC(x, UL)
+
+/*
+ * PAGE_OFFSET - the virtual address of the start of the kernel image
+ * TASK_SIZE - the maximum size of a user space task.
+ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
+ */
+#define PAGE_OFFSET UL(0xC0000000)
+#define TASK_SIZE (PAGE_OFFSET - UL(0x41000000))
+#define TASK_UNMAPPED_BASE (PAGE_OFFSET / 3)
+
+/*
+ * The module space lives between the addresses given by TASK_SIZE
+ * and PAGE_OFFSET - it must be within 32MB of the kernel text.
+ */
+#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024)
+#if TASK_SIZE > MODULES_VADDR
+#error Top of user space clashes with start of module space
+#endif
+
+#define MODULES_END (PAGE_OFFSET)
+
+/*
+ * Allow 16MB-aligned ioremap pages
+ */
+#define IOREMAP_MAX_ORDER 24
+
+/*
+ * Physical vs virtual RAM address space conversion. These are
+ * private definitions which should NOT be used outside memory.h
+ * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
+ */
+#ifndef __virt_to_phys
+#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif
+
+/*
+ * Convert a physical address to a Page Frame Number and back
+ */
+#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
+#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
+
+/*
+ * Convert a page to/from a physical address
+ */
+#define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page)))
+#define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys)))
+
+#ifndef __ASSEMBLY__
+
+#ifndef arch_adjust_zones
+#define arch_adjust_zones(size, holes) do { } while (0)
+#endif
+
+/*
+ * PFNs are used to describe any physical page; this means
+ * PFN 0 == physical address 0.
+ *
+ * This is the PFN of the first RAM page in the kernel
+ * direct-mapped view. We assume this is the first page
+ * of RAM in the mem_map as well.
+ */
+#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
+
+/*
+ * Drivers should NOT use these either.
+ */
+#define __pa(x) __virt_to_phys((unsigned long)(x))
+#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+
+/*
+ * Conversion between a struct page and a physical address.
+ *
+ * Note: when converting an unknown physical address to a
+ * struct page, the resulting pointer must be validated
+ * using VALID_PAGE(). It must return an invalid struct page
+ * for any physical address not corresponding to a system
+ * RAM address.
+ *
+ * page_to_pfn(page) convert a struct page * to a PFN number
+ * pfn_to_page(pfn) convert a _valid_ PFN number to struct page *
+ *
+ * virt_to_page(k) convert a _valid_ virtual address to struct page *
+ * virt_addr_valid(k) indicates whether a virtual address is valid
+ */
+#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
+
+#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && \
+ (unsigned long)(kaddr) < (unsigned long)high_memory)
+
+#endif
+
+#include <asm-generic/memory_model.h>
+
+#endif
diff --git a/arch/unicore32/include/asm/page.h b/arch/unicore32/include/asm/page.h
new file mode 100644
index 000000000000..594b3226250e
--- /dev/null
+++ b/arch/unicore32/include/asm/page.h
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/unicore32/include/asm/page.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __UNICORE_PAGE_H__
+#define __UNICORE_PAGE_H__
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#ifndef __ASSEMBLY__
+
+struct page;
+struct vm_area_struct;
+
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+extern void copy_page(void *to, const void *from);
+
+#define clear_user_page(page, vaddr, pg) clear_page(page)
+#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
+
+#undef STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x) ((x).pte)
+#define pgd_val(x) ((x).pgd)
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) })
+#define __pgd(x) ((pgd_t) { (x) })
+#define __pgprot(x) ((pgprot_t) { (x) })
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x) (x)
+#define pgd_val(x) (x)
+#define pgprot_val(x) (x)
+
+#define __pte(x) (x)
+#define __pgd(x) (x)
+#define __pgprot(x) (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+typedef struct page *pgtable_t;
+
+extern int pfn_valid(unsigned long);
+
+#include <asm/memory.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS \
+ (VM_READ | VM_WRITE | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/getorder.h>
+
+#endif
diff --git a/arch/unicore32/include/asm/tlb.h b/arch/unicore32/include/asm/tlb.h
new file mode 100644
index 000000000000..02ee40e47a0d
--- /dev/null
+++ b/arch/unicore32/include/asm/tlb.h
@@ -0,0 +1,98 @@
+/*
+ * linux/arch/unicore32/include/asm/tlb.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __UNICORE_TLB_H__
+#define __UNICORE_TLB_H__
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+/*
+ * TLB handling. This allows us to remove pages from the page
+ * tables, and efficiently handle the TLB issues.
+ */
+struct mmu_gather {
+ struct mm_struct *mm;
+ unsigned int fullmm;
+ unsigned long range_start;
+ unsigned long range_end;
+};
+
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+static inline struct mmu_gather *
+tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+{
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+
+ tlb->mm = mm;
+ tlb->fullmm = full_mm_flush;
+
+ return tlb;
+}
+
+static inline void
+tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+ if (tlb->fullmm)
+ flush_tlb_mm(tlb->mm);
+
+ /* keep the page table cache within bounds */
+ check_pgt_cache();
+
+ put_cpu_var(mmu_gathers);
+}
+
+/*
+ * Memorize the range for the TLB flush.
+ */
+static inline void
+tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr)
+{
+ if (!tlb->fullmm) {
+ if (addr < tlb->range_start)
+ tlb->range_start = addr;
+ if (addr + PAGE_SIZE > tlb->range_end)
+ tlb->range_end = addr + PAGE_SIZE;
+ }
+}
+
+/*
+ * In the case of tlb vma handling, we can optimise these away in the
+ * case where we're doing a full MM flush. When we're doing a munmap,
+ * the vmas are adjusted to only cover the region to be torn down.
+ */
+static inline void
+tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm) {
+ flush_cache_range(vma, vma->vm_start, vma->vm_end);
+ tlb->range_start = TASK_SIZE;
+ tlb->range_end = 0;
+ }
+}
+
+static inline void
+tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm && tlb->range_end > 0)
+ flush_tlb_range(vma, tlb->range_start, tlb->range_end);
+}
+
+#define tlb_remove_page(tlb, page) free_page_and_swap_cache(page)
+#define pte_free_tlb(tlb, ptep, addr) pte_free((tlb)->mm, ptep)
+#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
+#define pud_free_tlb(tlb, x, addr) do { } while (0)
+
+#define tlb_migrate_finish(mm) do { } while (0)
+
+#endif
diff --git a/arch/unicore32/include/mach/map.h b/arch/unicore32/include/mach/map.h
new file mode 100644
index 000000000000..55c936573741
--- /dev/null
+++ b/arch/unicore32/include/mach/map.h
@@ -0,0 +1,20 @@
+/*
+ * linux/arch/unicore32/include/mach/map.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Page table mapping constructs and function prototypes
+ */
+#define MT_DEVICE 0
+#define MT_DEVICE_CACHED 2
+#define MT_KUSER 7
+#define MT_HIGH_VECTORS 8
+#define MT_MEMORY 9
+#define MT_ROM 10
+
diff --git a/arch/unicore32/include/mach/memory.h b/arch/unicore32/include/mach/memory.h
new file mode 100644
index 000000000000..541949dfa5b4
--- /dev/null
+++ b/arch/unicore32/include/mach/memory.h
@@ -0,0 +1,58 @@
+/*
+ * linux/arch/unicore32/include/mach/memory.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __MACH_PUV3_MEMORY_H__
+#define __MACH_PUV3_MEMORY_H__
+
+#include <mach/hardware.h>
+
+/* Physical DRAM offset. */
+#define PHYS_OFFSET UL(0x00000000)
+/* The base address of exception vectors. */
+#define VECTORS_BASE UL(0xffff0000)
+/* The base address of kuser area. */
+#define KUSER_BASE UL(0x80000000)
+
+#ifdef __ASSEMBLY__
+/* The byte offset of the kernel image in RAM from the start of RAM. */
+#define KERNEL_IMAGE_START 0x00408000
+#endif
+
+#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
+
+void puv3_pci_adjust_zones(unsigned long *size, unsigned long *holes);
+
+#define arch_adjust_zones(size, holes) \
+ puv3_pci_adjust_zones(size, holes)
+
+#endif
+
+/*
+ * PCI controller in PKUnity-3 masks highest 5-bit for upstream channel,
+ * so we must limit the DMA allocation within 128M physical memory for
+ * supporting PCI devices.
+ */
+#define PCI_DMA_THRESHOLD (PHYS_OFFSET + SZ_128M - 1)
+
+#define is_pcibus_device(dev) (dev && \
+ (strncmp(dev->bus->name, "pci", 3) == 0))
+
+#define __virt_to_pcibus(x) (__virt_to_phys(x) + PKUNITY_PCIAHB_BASE)
+#define __pcibus_to_virt(x) __phys_to_virt((x) - PKUNITY_PCIAHB_BASE)
+
+/* kuser area */
+#define KUSER_VECPAGE_BASE (KUSER_BASE + UL(0x3fff0000))
+#define KUSER_UNIGFX_BASE (KUSER_BASE + PKUNITY_UNIGFX_MMAP_BASE)
+/* kuser_vecpage (0xbfff0000) is ro, and vectors page (0xffff0000) is rw */
+#define kuser_vecpage_to_vectors(x) ((x) - (KUSER_VECPAGE_BASE) \
+ + (VECTORS_BASE))
+
+#endif