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
powerpc
mm
40x_mmu.c
Go to the documentation of this file.
1
/*
2
* This file contains the routines for initializing the MMU
3
* on the 4xx series of chips.
4
* -- paulus
5
*
6
* Derived from arch/ppc/mm/init.c:
7
* Copyright (C) 1995-1996 Gary Thomas (
[email protected]
)
8
*
9
* Modifications by Paul Mackerras (PowerMac) (
[email protected]
)
10
* and Cort Dougan (PReP) (
[email protected]
)
11
* Copyright (C) 1996 Paul Mackerras
12
*
13
* Derived from "arch/i386/mm/init.c"
14
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
15
*
16
* This program is free software; you can redistribute it and/or
17
* modify it under the terms of the GNU General Public License
18
* as published by the Free Software Foundation; either version
19
* 2 of the License, or (at your option) any later version.
20
*
21
*/
22
23
#include <linux/signal.h>
24
#include <linux/sched.h>
25
#include <linux/kernel.h>
26
#include <linux/errno.h>
27
#include <linux/string.h>
28
#include <linux/types.h>
29
#include <linux/ptrace.h>
30
#include <linux/mman.h>
31
#include <
linux/mm.h
>
32
#include <
linux/swap.h
>
33
#include <linux/stddef.h>
34
#include <
linux/vmalloc.h
>
35
#include <
linux/init.h
>
36
#include <
linux/delay.h
>
37
#include <
linux/highmem.h
>
38
#include <
linux/memblock.h
>
39
40
#include <asm/pgalloc.h>
41
#include <asm/prom.h>
42
#include <asm/io.h>
43
#include <asm/mmu_context.h>
44
#include <asm/pgtable.h>
45
#include <asm/mmu.h>
46
#include <asm/uaccess.h>
47
#include <asm/smp.h>
48
#include <asm/bootx.h>
49
#include <asm/machdep.h>
50
#include <asm/setup.h>
51
52
#include "
mmu_decl.h
"
53
54
extern
int
__map_without_ltlbs
;
55
/*
56
* MMU_init_hw does the chip-specific initialization of the MMU hardware.
57
*/
58
void
__init
MMU_init_hw
(
void
)
59
{
60
/*
61
* The Zone Protection Register (ZPR) defines how protection will
62
* be applied to every page which is a member of a given zone. At
63
* present, we utilize only two of the 4xx's zones.
64
* The zone index bits (of ZSEL) in the PTE are used for software
65
* indicators, except the LSB. For user access, zone 1 is used,
66
* for kernel access, zone 0 is used. We set all but zone 1
67
* to zero, allowing only kernel access as indicated in the PTE.
68
* For zone 1, we set a 01 binary (a value of 10 will not work)
69
* to allow user access as indicated in the PTE. This also allows
70
* kernel access as indicated in the PTE.
71
*/
72
73
mtspr
(SPRN_ZPR, 0x10000000);
74
75
flush_instruction_cache
();
76
77
/*
78
* Set up the real-mode cache parameters for the exception vector
79
* handlers (which are run in real-mode).
80
*/
81
82
mtspr
(SPRN_DCWR, 0x00000000);
/* All caching is write-back */
83
84
/*
85
* Cache instruction and data space where the exception
86
* vectors and the kernel live in real-mode.
87
*/
88
89
mtspr
(SPRN_DCCR, 0xFFFF0000);
/* 2GByte of data space at 0x0. */
90
mtspr
(SPRN_ICCR, 0xFFFF0000);
/* 2GByte of instr. space at 0x0. */
91
}
92
93
#define LARGE_PAGE_SIZE_16M (1<<24)
94
#define LARGE_PAGE_SIZE_4M (1<<22)
95
96
unsigned
long
__init
mmu_mapin_ram
(
unsigned
long
top
)
97
{
98
unsigned
long
v
,
s
,
mapped
;
99
phys_addr_t
p
;
100
101
v =
KERNELBASE
;
102
p = 0;
103
s =
total_lowmem
;
104
105
if
(
__map_without_ltlbs
)
106
return
0;
107
108
while
(s >=
LARGE_PAGE_SIZE_16M
) {
109
pmd_t
*pmdp;
110
unsigned
long
val
= p | _PMD_SIZE_16M |
_PAGE_EXEC
|
_PAGE_HWWRITE
;
111
112
pmdp =
pmd_offset
(
pud_offset
(
pgd_offset_k
(v), v), v);
113
pmd_val
(*pmdp++) =
val
;
114
pmd_val
(*pmdp++) =
val
;
115
pmd_val
(*pmdp++) =
val
;
116
pmd_val
(*pmdp++) =
val
;
117
118
v +=
LARGE_PAGE_SIZE_16M
;
119
p +=
LARGE_PAGE_SIZE_16M
;
120
s -=
LARGE_PAGE_SIZE_16M
;
121
}
122
123
while
(s >=
LARGE_PAGE_SIZE_4M
) {
124
pmd_t
*pmdp;
125
unsigned
long
val
= p | _PMD_SIZE_4M |
_PAGE_EXEC
|
_PAGE_HWWRITE
;
126
127
pmdp =
pmd_offset
(
pud_offset
(
pgd_offset_k
(v), v), v);
128
pmd_val
(*pmdp) =
val
;
129
130
v +=
LARGE_PAGE_SIZE_4M
;
131
p +=
LARGE_PAGE_SIZE_4M
;
132
s -=
LARGE_PAGE_SIZE_4M
;
133
}
134
135
mapped =
total_lowmem
-
s
;
136
137
/* If the size of RAM is not an exact power of two, we may not
138
* have covered RAM in its entirety with 16 and 4 MiB
139
* pages. Consequently, restrict the top end of RAM currently
140
* allocable so that calls to the MEMBLOCK to allocate PTEs for "tail"
141
* coverage with normal-sized pages (or other reasons) do not
142
* attempt to allocate outside the allowed range.
143
*/
144
memblock_set_current_limit
(mapped);
145
146
return
mapped
;
147
}
148
149
void
setup_initial_memory_limit
(
phys_addr_t
first_memblock_base,
150
phys_addr_t
first_memblock_size)
151
{
152
/* We don't currently support the first MEMBLOCK not mapping 0
153
* physical on those processors
154
*/
155
BUG_ON
(first_memblock_base != 0);
156
157
/* 40x can only access 16MB at the moment (see head_40x.S) */
158
memblock_set_current_limit
(
min_t
(
u64
, first_memblock_size, 0x00800000));
159
}
Generated on Thu Jan 10 2013 13:14:23 for Linux Kernel by
1.8.2