linux/arch/nios2/mm/pgtable.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2009 Wind River Systems Inc
   3 *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
   4 *
   5 * This file is subject to the terms and conditions of the GNU General Public
   6 * License.  See the file "COPYING" in the main directory of this archive
   7 * for more details.
   8 */
   9
  10#include <linux/mm.h>
  11#include <linux/sched.h>
  12
  13#include <asm/cpuinfo.h>
  14
  15/* pteaddr:
  16 *   ptbase | vpn* | zero
  17 *   31-22  | 21-2 | 1-0
  18 *
  19 *   *vpn is preserved on double fault
  20 *
  21 * tlbacc:
  22 *   IG   |*flags| pfn
  23 *   31-25|24-20 | 19-0
  24 *
  25 *   *crwxg
  26 *
  27 * tlbmisc:
  28 *   resv  |way   |rd | we|pid |dbl|bad|perm|d
  29 *   31-24 |23-20 |19 | 20|17-4|3  |2  |1   |0
  30 *
  31 */
  32
  33/*
  34 * Initialize a new pgd / pmd table with invalid pointers.
  35 */
  36static void pgd_init(pgd_t *pgd)
  37{
  38        unsigned long *p = (unsigned long *) pgd;
  39        int i;
  40
  41        for (i = 0; i < USER_PTRS_PER_PGD; i += 8) {
  42                p[i + 0] = (unsigned long) invalid_pte_table;
  43                p[i + 1] = (unsigned long) invalid_pte_table;
  44                p[i + 2] = (unsigned long) invalid_pte_table;
  45                p[i + 3] = (unsigned long) invalid_pte_table;
  46                p[i + 4] = (unsigned long) invalid_pte_table;
  47                p[i + 5] = (unsigned long) invalid_pte_table;
  48                p[i + 6] = (unsigned long) invalid_pte_table;
  49                p[i + 7] = (unsigned long) invalid_pte_table;
  50        }
  51}
  52
  53pgd_t *pgd_alloc(struct mm_struct *mm)
  54{
  55        pgd_t *ret, *init;
  56
  57        ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
  58        if (ret) {
  59                init = pgd_offset(&init_mm, 0UL);
  60                pgd_init(ret);
  61                memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
  62                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
  63        }
  64
  65        return ret;
  66}
  67
  68void __init pagetable_init(void)
  69{
  70        /* Initialize the entire pgd.  */
  71        pgd_init(swapper_pg_dir);
  72        pgd_init(swapper_pg_dir + USER_PTRS_PER_PGD);
  73}
  74