linux/arch/nios2/mm/init.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Altera Corporation
   3 * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
   4 * Copyright (C) 2009 Wind River Systems Inc
   5 *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
   6 * Copyright (C) 2004 Microtronix Datacom Ltd
   7 *
   8 * based on arch/m68k/mm/init.c
   9 *
  10 * This file is subject to the terms and conditions of the GNU General Public
  11 * License. See the file "COPYING" in the main directory of this archive
  12 * for more details.
  13 */
  14
  15#include <linux/signal.h>
  16#include <linux/sched.h>
  17#include <linux/kernel.h>
  18#include <linux/errno.h>
  19#include <linux/string.h>
  20#include <linux/types.h>
  21#include <linux/ptrace.h>
  22#include <linux/mman.h>
  23#include <linux/mm.h>
  24#include <linux/init.h>
  25#include <linux/pagemap.h>
  26#include <linux/memblock.h>
  27#include <linux/slab.h>
  28#include <linux/binfmts.h>
  29
  30#include <asm/setup.h>
  31#include <asm/page.h>
  32#include <asm/pgtable.h>
  33#include <asm/sections.h>
  34#include <asm/tlb.h>
  35#include <asm/mmu_context.h>
  36#include <asm/cpuinfo.h>
  37#include <asm/processor.h>
  38
  39pgd_t *pgd_current;
  40
  41/*
  42 * paging_init() continues the virtual memory environment setup which
  43 * was begun by the code in arch/head.S.
  44 * The parameters are pointers to where to stick the starting and ending
  45 * addresses of available kernel virtual memory.
  46 */
  47void __init paging_init(void)
  48{
  49        unsigned long zones_size[MAX_NR_ZONES];
  50
  51        memset(zones_size, 0, sizeof(zones_size));
  52
  53        pagetable_init();
  54        pgd_current = swapper_pg_dir;
  55
  56        zones_size[ZONE_NORMAL] = max_mapnr;
  57
  58        /* pass the memory from the bootmem allocator to the main allocator */
  59        free_area_init(zones_size);
  60
  61        flush_dcache_range((unsigned long)empty_zero_page,
  62                        (unsigned long)empty_zero_page + PAGE_SIZE);
  63}
  64
  65void __init mem_init(void)
  66{
  67        unsigned long end_mem   = memory_end; /* this must not include
  68                                                kernel stack at top */
  69
  70        pr_debug("mem_init: start=%lx, end=%lx\n", memory_start, memory_end);
  71
  72        end_mem &= PAGE_MASK;
  73        high_memory = __va(end_mem);
  74
  75        /* this will put all memory onto the freelists */
  76        memblock_free_all();
  77        mem_init_print_info(NULL);
  78}
  79
  80void __init mmu_init(void)
  81{
  82        flush_tlb_all();
  83}
  84
  85#define __page_aligned(order) __aligned(PAGE_SIZE << (order))
  86pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER);
  87pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
  88static struct page *kuser_page[1];
  89
  90static int alloc_kuser_page(void)
  91{
  92        extern char __kuser_helper_start[], __kuser_helper_end[];
  93        int kuser_sz = __kuser_helper_end - __kuser_helper_start;
  94        unsigned long vpage;
  95
  96        vpage = get_zeroed_page(GFP_ATOMIC);
  97        if (!vpage)
  98                return -ENOMEM;
  99
 100        /* Copy kuser helpers */
 101        memcpy((void *)vpage, __kuser_helper_start, kuser_sz);
 102
 103        flush_icache_range(vpage, vpage + KUSER_SIZE);
 104        kuser_page[0] = virt_to_page(vpage);
 105
 106        return 0;
 107}
 108arch_initcall(alloc_kuser_page);
 109
 110int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 111{
 112        struct mm_struct *mm = current->mm;
 113        int ret;
 114
 115        down_write(&mm->mmap_sem);
 116
 117        /* Map kuser helpers to user space address */
 118        ret = install_special_mapping(mm, KUSER_BASE, KUSER_SIZE,
 119                                      VM_READ | VM_EXEC | VM_MAYREAD |
 120                                      VM_MAYEXEC, kuser_page);
 121
 122        up_write(&mm->mmap_sem);
 123
 124        return ret;
 125}
 126
 127const char *arch_vma_name(struct vm_area_struct *vma)
 128{
 129        return (vma->vm_start == KUSER_BASE) ? "[kuser]" : NULL;
 130}
 131