diff options
author | Johannes Weiner <jw@emlix.com> | 2009-03-04 10:21:31 -0500 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2009-04-03 02:41:50 -0400 |
commit | e5083a63b6a8546c5fe1e571fe529e3939787ec2 (patch) | |
tree | 5c11db5b0a924f8bcfc404c202630d37ccfd7c3c /arch/xtensa/mm | |
parent | 7789f89af9e8e426d7a7f173cf465a4fcadba7dd (diff) |
xtensa: nommu support
Add support for !CONFIG_MMU setups.
Signed-off-by: Johannes Weiner <jw@emlix.com>
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa/mm')
-rw-r--r-- | arch/xtensa/mm/Makefile | 3 | ||||
-rw-r--r-- | arch/xtensa/mm/init.c | 62 | ||||
-rw-r--r-- | arch/xtensa/mm/misc.S | 2 | ||||
-rw-r--r-- | arch/xtensa/mm/mmu.c | 70 |
4 files changed, 75 insertions, 62 deletions
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index 64e304a2f884..f0b646d2f843 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile | |||
@@ -2,4 +2,5 @@ | |||
2 | # Makefile for the Linux/Xtensa-specific parts of the memory manager. | 2 | # Makefile for the Linux/Xtensa-specific parts of the memory manager. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := init.o fault.o tlb.o misc.o cache.o | 5 | obj-y := init.o cache.o misc.o |
6 | obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o | ||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 6190988bba17..427e14fa43c5 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -24,15 +24,8 @@ | |||
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | 26 | ||
27 | #include <asm/pgtable.h> | ||
28 | #include <asm/bootparam.h> | 27 | #include <asm/bootparam.h> |
29 | #include <asm/mmu_context.h> | ||
30 | #include <asm/tlb.h> | ||
31 | #include <asm/page.h> | 28 | #include <asm/page.h> |
32 | #include <asm/pgalloc.h> | ||
33 | |||
34 | |||
35 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
36 | 29 | ||
37 | /* References to section boundaries */ | 30 | /* References to section boundaries */ |
38 | 31 | ||
@@ -160,7 +153,7 @@ void __init bootmem_init(void) | |||
160 | } | 153 | } |
161 | 154 | ||
162 | 155 | ||
163 | void __init paging_init(void) | 156 | void __init zones_init(void) |
164 | { | 157 | { |
165 | unsigned long zones_size[MAX_NR_ZONES]; | 158 | unsigned long zones_size[MAX_NR_ZONES]; |
166 | int i; | 159 | int i; |
@@ -175,43 +168,10 @@ void __init paging_init(void) | |||
175 | zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; | 168 | zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; |
176 | #endif | 169 | #endif |
177 | 170 | ||
178 | /* Initialize the kernel's page tables. */ | ||
179 | |||
180 | memset(swapper_pg_dir, 0, PAGE_SIZE); | ||
181 | |||
182 | free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL); | 171 | free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL); |
183 | } | 172 | } |
184 | 173 | ||
185 | /* | 174 | /* |
186 | * Flush the mmu and reset associated register to default values. | ||
187 | */ | ||
188 | |||
189 | void __init init_mmu (void) | ||
190 | { | ||
191 | /* Writing zeros to the <t>TLBCFG special registers ensure | ||
192 | * that valid values exist in the register. For existing | ||
193 | * PGSZID<w> fields, zero selects the first element of the | ||
194 | * page-size array. For nonexistent PGSZID<w> fields, zero is | ||
195 | * the best value to write. Also, when changing PGSZID<w> | ||
196 | * fields, the corresponding TLB must be flushed. | ||
197 | */ | ||
198 | set_itlbcfg_register (0); | ||
199 | set_dtlbcfg_register (0); | ||
200 | flush_tlb_all (); | ||
201 | |||
202 | /* Set rasid register to a known value. */ | ||
203 | |||
204 | set_rasid_register (ASID_USER_FIRST); | ||
205 | |||
206 | /* Set PTEVADDR special register to the start of the page | ||
207 | * table, which is in kernel mappable space (ie. not | ||
208 | * statically mapped). This register's value is undefined on | ||
209 | * reset. | ||
210 | */ | ||
211 | set_ptevaddr_register (PGTABLE_START); | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Initialize memory pages. | 175 | * Initialize memory pages. |
216 | */ | 176 | */ |
217 | 177 | ||
@@ -281,23 +241,3 @@ void free_initmem(void) | |||
281 | printk("Freeing unused kernel memory: %dk freed\n", | 241 | printk("Freeing unused kernel memory: %dk freed\n", |
282 | (&__init_end - &__init_begin) >> 10); | 242 | (&__init_end - &__init_begin) >> 10); |
283 | } | 243 | } |
284 | |||
285 | struct kmem_cache *pgtable_cache __read_mostly; | ||
286 | |||
287 | static void pgd_ctor(void* addr) | ||
288 | { | ||
289 | pte_t* ptep = (pte_t*)addr; | ||
290 | int i; | ||
291 | |||
292 | for (i = 0; i < 1024; i++, ptep++) | ||
293 | pte_clear(NULL, 0, ptep); | ||
294 | |||
295 | } | ||
296 | |||
297 | void __init pgtable_cache_init(void) | ||
298 | { | ||
299 | pgtable_cache = kmem_cache_create("pgd", | ||
300 | PAGE_SIZE, PAGE_SIZE, | ||
301 | SLAB_HWCACHE_ALIGN, | ||
302 | pgd_ctor); | ||
303 | } | ||
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index c885664211d1..b048406d8756 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S | |||
@@ -84,6 +84,7 @@ ENTRY(copy_page) | |||
84 | 84 | ||
85 | retw | 85 | retw |
86 | 86 | ||
87 | #ifdef CONFIG_MMU | ||
87 | /* | 88 | /* |
88 | * If we have to deal with cache aliasing, we use temporary memory mappings | 89 | * If we have to deal with cache aliasing, we use temporary memory mappings |
89 | * to ensure that the source and destination pages have the same color as | 90 | * to ensure that the source and destination pages have the same color as |
@@ -311,6 +312,7 @@ ENTRY(__invalidate_icache_page_alias) | |||
311 | /* End of special treatment in tlb miss exception */ | 312 | /* End of special treatment in tlb miss exception */ |
312 | 313 | ||
313 | ENTRY(__tlbtemp_mapping_end) | 314 | ENTRY(__tlbtemp_mapping_end) |
315 | #endif /* CONFIG_MMU | ||
314 | 316 | ||
315 | /* | 317 | /* |
316 | * void __invalidate_icache_page(ulong start) | 318 | * void __invalidate_icache_page(ulong start) |
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c new file mode 100644 index 000000000000..4bb91a970f1f --- /dev/null +++ b/arch/xtensa/mm/mmu.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * xtensa mmu stuff | ||
3 | * | ||
4 | * Extracted from init.c | ||
5 | */ | ||
6 | #include <linux/percpu.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/string.h> | ||
9 | #include <linux/slab.h> | ||
10 | #include <linux/cache.h> | ||
11 | |||
12 | #include <asm/tlb.h> | ||
13 | #include <asm/tlbflush.h> | ||
14 | #include <asm/mmu_context.h> | ||
15 | #include <asm/page.h> | ||
16 | |||
17 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
18 | |||
19 | void __init paging_init(void) | ||
20 | { | ||
21 | memset(swapper_pg_dir, 0, PAGE_SIZE); | ||
22 | } | ||
23 | |||
24 | /* | ||
25 | * Flush the mmu and reset associated register to default values. | ||
26 | */ | ||
27 | void __init init_mmu(void) | ||
28 | { | ||
29 | /* Writing zeros to the <t>TLBCFG special registers ensure | ||
30 | * that valid values exist in the register. For existing | ||
31 | * PGSZID<w> fields, zero selects the first element of the | ||
32 | * page-size array. For nonexistent PGSZID<w> fields, zero is | ||
33 | * the best value to write. Also, when changing PGSZID<w> | ||
34 | * fields, the corresponding TLB must be flushed. | ||
35 | */ | ||
36 | set_itlbcfg_register(0); | ||
37 | set_dtlbcfg_register(0); | ||
38 | flush_tlb_all(); | ||
39 | |||
40 | /* Set rasid register to a known value. */ | ||
41 | |||
42 | set_rasid_register(ASID_USER_FIRST); | ||
43 | |||
44 | /* Set PTEVADDR special register to the start of the page | ||
45 | * table, which is in kernel mappable space (ie. not | ||
46 | * statically mapped). This register's value is undefined on | ||
47 | * reset. | ||
48 | */ | ||
49 | set_ptevaddr_register(PGTABLE_START); | ||
50 | } | ||
51 | |||
52 | struct kmem_cache *pgtable_cache __read_mostly; | ||
53 | |||
54 | static void pgd_ctor(void *addr) | ||
55 | { | ||
56 | pte_t *ptep = (pte_t *)addr; | ||
57 | int i; | ||
58 | |||
59 | for (i = 0; i < 1024; i++, ptep++) | ||
60 | pte_clear(NULL, 0, ptep); | ||
61 | |||
62 | } | ||
63 | |||
64 | void __init pgtable_cache_init(void) | ||
65 | { | ||
66 | pgtable_cache = kmem_cache_create("pgd", | ||
67 | PAGE_SIZE, PAGE_SIZE, | ||
68 | SLAB_HWCACHE_ALIGN, | ||
69 | pgd_ctor); | ||
70 | } | ||