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/pgtable.h>
  14#include <asm/cpuinfo.h>
  15
  16/* pteaddr:
  17 *   ptbase | vpn* | zero
  18 *   31-22  | 21-2 | 1-0
  19 *
  20 *   *vpn is preserved on double fault
  21 *
  22 * tlbacc:
  23 *   IG   |*flags| pfn
  24 *   31-25|24-20 | 19-0
  25 *
  26 *   *crwxg
  27 *
  28 * tlbmisc:
  29 *   resv  |way   |rd | we|pid |dbl|bad|perm|d
  30 *   31-24 |23-20 |19 | 20|17-4|3  |2  |1   |0
  31 *
  32 */
  33
  34/*
  35 * Initialize a new pgd / pmd table with invalid pointers.
  36 */
  37static void pgd_init(pgd_t *pgd)
  38{
  39        unsigned long *p = (unsigned long *) pgd;
  40        int i;
  41
  42        for (i = 0; i < USER_PTRS_PER_PGD; i += 8) {
  43                p[i + 0] = (unsigned long) invalid_pte_table;
  44                p[i + 1] = (unsigned long) invalid_pte_table;
  45                p[i + 2] = (unsigned long) invalid_pte_table;
  46                p[i + 3] = (unsigned long) invalid_pte_table;
  47                p[i + 4] = (unsigned long) invalid_pte_table;
  48                p[i + 5] = (unsigned long) invalid_pte_table;
  49                p[i + 6] = (unsigned long) invalid_pte_table;
  50                p[i + 7] = (unsigned long) invalid_pte_table;
  51        }
  52}
  53
  54pgd_t *pgd_alloc(struct mm_struct *mm)
  55{
  56        pgd_t *ret, *init;
  57
  58        ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
  59        if (ret) {
  60                init = pgd_offset(&init_mm, 0UL);
  61                pgd_init(ret);
  62                memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
  63                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
  64        }
  65
  66        return ret;
  67}
  68
  69void __init pagetable_init(void)
  70{
  71        /* Initialize the entire pgd.  */
  72        pgd_init(swapper_pg_dir);
  73        pgd_init(swapper_pg_dir + USER_PTRS_PER_PGD);
  74}
  75