Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
unicore32
mm
pgd.c
Go to the documentation of this file.
1
/*
2
* linux/arch/unicore32/mm/pgd.c
3
*
4
* Code specific to PKUnity SoC and UniCore ISA
5
*
6
* Copyright (C) 2001-2010 GUAN Xue-tao
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
11
*/
12
#include <
linux/mm.h
>
13
#include <
linux/gfp.h
>
14
#include <
linux/highmem.h
>
15
16
#include <asm/pgalloc.h>
17
#include <asm/page.h>
18
#include <asm/tlbflush.h>
19
20
#include "
mm.h
"
21
22
#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
23
24
/*
25
* need to get a 4k page for level 1
26
*/
27
pgd_t
*
get_pgd_slow
(
struct
mm_struct
*mm)
28
{
29
pgd_t
*new_pgd, *init_pgd;
30
pmd_t
*new_pmd, *init_pmd;
31
pte_t
*new_pte, *init_pte;
32
33
new_pgd = (
pgd_t
*)
__get_free_pages
(
GFP_KERNEL
, 0);
34
if
(!new_pgd)
35
goto
no_pgd;
36
37
memset
(new_pgd, 0,
FIRST_KERNEL_PGD_NR
*
sizeof
(
pgd_t
));
38
39
/*
40
* Copy over the kernel and IO PGD entries
41
*/
42
init_pgd =
pgd_offset_k
(0);
43
memcpy
(new_pgd +
FIRST_KERNEL_PGD_NR
, init_pgd +
FIRST_KERNEL_PGD_NR
,
44
(
PTRS_PER_PGD
-
FIRST_KERNEL_PGD_NR
) *
sizeof
(
pgd_t
));
45
46
clean_dcache_area
(new_pgd,
PTRS_PER_PGD
*
sizeof
(
pgd_t
));
47
48
if
(!
vectors_high
()) {
49
/*
50
* On UniCore, first page must always be allocated since it
51
* contains the machine vectors.
52
*/
53
new_pmd =
pmd_alloc
(mm, (
pud_t
*)new_pgd, 0);
54
if
(!new_pmd)
55
goto
no_pmd;
56
57
new_pte = pte_alloc_map(mm,
NULL
, new_pmd, 0);
58
if
(!new_pte)
59
goto
no_pte;
60
61
init_pmd =
pmd_offset
((
pud_t
*)init_pgd, 0);
62
init_pte =
pte_offset_map
(init_pmd, 0);
63
set_pte
(new_pte, *init_pte);
64
pte_unmap
(init_pte);
65
pte_unmap
(new_pte);
66
}
67
68
return
new_pgd;
69
70
no_pte:
71
pmd_free
(mm, new_pmd);
72
no_pmd:
73
free_pages
((
unsigned
long
)new_pgd, 0);
74
no_pgd:
75
return
NULL
;
76
}
77
78
void
free_pgd_slow
(
struct
mm_struct
*mm,
pgd_t
*pgd)
79
{
80
pmd_t
*
pmd
;
81
pgtable_t
pte
;
82
83
if
(!pgd)
84
return
;
85
86
/* pgd is always present and good */
87
pmd = pmd_off(pgd, 0);
88
if
(
pmd_none
(*pmd))
89
goto
free
;
90
if
(
pmd_bad
(*pmd)) {
91
pmd_ERROR
(*pmd);
92
pmd_clear
(pmd);
93
goto
free
;
94
}
95
96
pte =
pmd_pgtable
(*pmd);
97
pmd_clear
(pmd);
98
pte_free
(mm, pte);
99
pmd_free
(mm, pmd);
100
free
:
101
free_pages
((
unsigned
long
) pgd, 0);
102
}
Generated on Thu Jan 10 2013 13:02:59 for Linux Kernel by
1.8.2