aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Weiner <jw@emlix.com>2009-03-04 10:21:31 -0500
committerChris Zankel <chris@zankel.net>2009-04-03 02:41:50 -0400
commite5083a63b6a8546c5fe1e571fe529e3939787ec2 (patch)
tree5c11db5b0a924f8bcfc404c202630d37ccfd7c3c
parent7789f89af9e8e426d7a7f173cf465a4fcadba7dd (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>
-rw-r--r--arch/xtensa/include/asm/cacheflush.h10
-rw-r--r--arch/xtensa/include/asm/dma.h3
-rw-r--r--arch/xtensa/include/asm/io.h9
-rw-r--r--arch/xtensa/include/asm/mmu.h5
-rw-r--r--arch/xtensa/include/asm/mmu_context.h5
-rw-r--r--arch/xtensa/include/asm/nommu.h3
-rw-r--r--arch/xtensa/include/asm/nommu_context.h25
-rw-r--r--arch/xtensa/include/asm/page.h9
-rw-r--r--arch/xtensa/include/asm/pgtable.h13
-rw-r--r--arch/xtensa/include/asm/processor.h6
-rw-r--r--arch/xtensa/kernel/entry.S3
-rw-r--r--arch/xtensa/kernel/head.S3
-rw-r--r--arch/xtensa/kernel/setup.c7
-rw-r--r--arch/xtensa/kernel/traps.c2
-rw-r--r--arch/xtensa/kernel/vectors.S4
-rw-r--r--arch/xtensa/mm/Makefile3
-rw-r--r--arch/xtensa/mm/init.c62
-rw-r--r--arch/xtensa/mm/misc.S2
-rw-r--r--arch/xtensa/mm/mmu.c70
19 files changed, 169 insertions, 75 deletions
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h
index 94c4c53a099..8fc1c0c8de0 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -65,13 +65,17 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
65# define __flush_invalidate_dcache_range(p,s) __invalidate_dcache_range(p,s) 65# define __flush_invalidate_dcache_range(p,s) __invalidate_dcache_range(p,s)
66#endif 66#endif
67 67
68#if (DCACHE_WAY_SIZE > PAGE_SIZE) 68#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE)
69extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long); 69extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
70#else
71static inline void __flush_invalidate_dcache_page_alias(unsigned long virt,
72 unsigned long phys) { }
70#endif 73#endif
71#if (ICACHE_WAY_SIZE > PAGE_SIZE) 74#if defined(CONFIG_MMU) && (ICACHE_WAY_SIZE > PAGE_SIZE)
72extern void __invalidate_icache_page_alias(unsigned long, unsigned long); 75extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
73#else 76#else
74# define __invalidate_icache_page_alias(v,p) do { } while(0) 77static inline void __invalidate_icache_page_alias(unsigned long virt,
78 unsigned long phys) { }
75#endif 79#endif
76 80
77/* 81/*
diff --git a/arch/xtensa/include/asm/dma.h b/arch/xtensa/include/asm/dma.h
index e30f3abf48f..137ca3945b0 100644
--- a/arch/xtensa/include/asm/dma.h
+++ b/arch/xtensa/include/asm/dma.h
@@ -44,8 +44,9 @@
44 * the value desired). 44 * the value desired).
45 */ 45 */
46 46
47#ifndef MAX_DMA_ADDRESS
47#define MAX_DMA_ADDRESS (PAGE_OFFSET + XCHAL_KIO_SIZE - 1) 48#define MAX_DMA_ADDRESS (PAGE_OFFSET + XCHAL_KIO_SIZE - 1)
48 49#endif
49 50
50/* Reserve and release a DMA channel */ 51/* Reserve and release a DMA channel */
51extern int request_dma(unsigned int dmanr, const char * device_id); 52extern int request_dma(unsigned int dmanr, const char * device_id);
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 07b7299dab2..d04cd3a625f 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -69,21 +69,28 @@ static inline void * phys_to_virt(unsigned long address)
69 69
70static inline void *ioremap(unsigned long offset, unsigned long size) 70static inline void *ioremap(unsigned long offset, unsigned long size)
71{ 71{
72#ifdef CONFIG_MMU
72 if (offset >= XCHAL_KIO_PADDR 73 if (offset >= XCHAL_KIO_PADDR
73 && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE) 74 && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
74 return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR); 75 return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
75
76 else 76 else
77 BUG(); 77 BUG();
78#else
79 return (void *)offset;
80#endif
78} 81}
79 82
80static inline void *ioremap_nocache(unsigned long offset, unsigned long size) 83static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
81{ 84{
85#ifdef CONFIG_MMU
82 if (offset >= XCHAL_KIO_PADDR 86 if (offset >= XCHAL_KIO_PADDR
83 && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE) 87 && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
84 return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR); 88 return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
85 else 89 else
86 BUG(); 90 BUG();
91#else
92 return (void *)offset;
93#endif
87} 94}
88 95
89static inline void iounmap(void *addr) 96static inline void iounmap(void *addr)
diff --git a/arch/xtensa/include/asm/mmu.h b/arch/xtensa/include/asm/mmu.h
index 44c5bb04c55..04890d6e233 100644
--- a/arch/xtensa/include/asm/mmu.h
+++ b/arch/xtensa/include/asm/mmu.h
@@ -11,7 +11,12 @@
11#ifndef _XTENSA_MMU_H 11#ifndef _XTENSA_MMU_H
12#define _XTENSA_MMU_H 12#define _XTENSA_MMU_H
13 13
14#ifndef CONFIG_MMU
15#include <asm/nommu.h>
16#else
17
14/* Default "unsigned long" context */ 18/* Default "unsigned long" context */
15typedef unsigned long mm_context_t; 19typedef unsigned long mm_context_t;
16 20
21#endif /* CONFIG_MMU */
17#endif /* _XTENSA_MMU_H */ 22#endif /* _XTENSA_MMU_H */
diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h
index 6b7c19c8f4c..dbd8731a876 100644
--- a/arch/xtensa/include/asm/mmu_context.h
+++ b/arch/xtensa/include/asm/mmu_context.h
@@ -13,6 +13,10 @@
13#ifndef _XTENSA_MMU_CONTEXT_H 13#ifndef _XTENSA_MMU_CONTEXT_H
14#define _XTENSA_MMU_CONTEXT_H 14#define _XTENSA_MMU_CONTEXT_H
15 15
16#ifndef CONFIG_MMU
17#include <asm/nommu_context.h>
18#else
19
16#include <linux/stringify.h> 20#include <linux/stringify.h>
17#include <linux/sched.h> 21#include <linux/sched.h>
18 22
@@ -133,4 +137,5 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
133 137
134} 138}
135 139
140#endif /* CONFIG_MMU */
136#endif /* _XTENSA_MMU_CONTEXT_H */ 141#endif /* _XTENSA_MMU_CONTEXT_H */
diff --git a/arch/xtensa/include/asm/nommu.h b/arch/xtensa/include/asm/nommu.h
new file mode 100644
index 00000000000..dce2c438c5b
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu.h
@@ -0,0 +1,3 @@
1typedef struct {
2 unsigned long end_brk;
3} mm_context_t;
diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h
new file mode 100644
index 00000000000..599e7a2e729
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu_context.h
@@ -0,0 +1,25 @@
1static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
2{
3}
4
5static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
6{
7 return 0;
8}
9
10static inline void destroy_context(struct mm_struct *mm)
11{
12}
13
14static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
15{
16}
17
18static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
19 struct task_struct *tsk)
20{
21}
22
23static inline void deactivate_mm(struct task_struct *tsk, struct mm_struct *mm)
24{
25}
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h
index a5a5d33c15d..17e0c5383b1 100644
--- a/arch/xtensa/include/asm/page.h
+++ b/arch/xtensa/include/asm/page.h
@@ -33,8 +33,14 @@
33#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) 33#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
34#define PAGE_MASK (~(PAGE_SIZE-1)) 34#define PAGE_MASK (~(PAGE_SIZE-1))
35 35
36#ifdef CONFIG_MMU
36#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR 37#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR
37#define MAX_MEM_PFN XCHAL_KSEG_SIZE 38#define MAX_MEM_PFN XCHAL_KSEG_SIZE
39#else
40#define PAGE_OFFSET 0
41#define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
42#endif
43
38#define PGTABLE_START 0x80000000 44#define PGTABLE_START 0x80000000
39 45
40/* 46/*
@@ -165,8 +171,9 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*);
165#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 171#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
166#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 172#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
167 173
174#ifdef CONFIG_MMU
168#define WANT_PAGE_VIRTUAL 175#define WANT_PAGE_VIRTUAL
169 176#endif
170 177
171#endif /* __ASSEMBLY__ */ 178#endif /* __ASSEMBLY__ */
172 179
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 8014d96b21f..a138770c358 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -183,7 +183,15 @@ extern unsigned long empty_zero_page[1024];
183 183
184#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) 184#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
185 185
186#ifdef CONFIG_MMU
186extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)]; 187extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
188extern void paging_init(void);
189extern void pgtable_cache_init(void);
190#else
191# define swapper_pg_dir NULL
192static inline void paging_init(void) { }
193static inline void pgtable_cache_init(void) { }
194#endif
187 195
188/* 196/*
189 * The pmd contains the kernel virtual address of the pte page. 197 * The pmd contains the kernel virtual address of the pte page.
@@ -383,8 +391,6 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
383 391
384#else 392#else
385 393
386extern void paging_init(void);
387
388#define kern_addr_valid(addr) (1) 394#define kern_addr_valid(addr) (1)
389 395
390extern void update_mmu_cache(struct vm_area_struct * vma, 396extern void update_mmu_cache(struct vm_area_struct * vma,
@@ -398,9 +404,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
398#define io_remap_pfn_range(vma,from,pfn,size,prot) \ 404#define io_remap_pfn_range(vma,from,pfn,size,prot) \
399 remap_pfn_range(vma, from, pfn, size, prot) 405 remap_pfn_range(vma, from, pfn, size, prot)
400 406
401
402extern void pgtable_cache_init(void);
403
404typedef pte_t *pte_addr_t; 407typedef pte_t *pte_addr_t;
405 408
406#endif /* !defined (__ASSEMBLY__) */ 409#endif /* !defined (__ASSEMBLY__) */
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index fba8b7e44a2..0ea4937c0b6 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -13,6 +13,7 @@
13 13
14#include <variant/core.h> 14#include <variant/core.h>
15#include <asm/coprocessor.h> 15#include <asm/coprocessor.h>
16#include <platform/hardware.h>
16 17
17#include <linux/compiler.h> 18#include <linux/compiler.h>
18#include <asm/ptrace.h> 19#include <asm/ptrace.h>
@@ -35,7 +36,12 @@
35 * the 1 GB requirement applies to the stack as well. 36 * the 1 GB requirement applies to the stack as well.
36 */ 37 */
37 38
39#ifdef CONFIG_MMU
38#define TASK_SIZE __XTENSA_UL_CONST(0x40000000) 40#define TASK_SIZE __XTENSA_UL_CONST(0x40000000)
41#else
42#define TASK_SIZE (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
43#endif
44
39#define STACK_TOP TASK_SIZE 45#define STACK_TOP TASK_SIZE
40#define STACK_TOP_MAX STACK_TOP 46#define STACK_TOP_MAX STACK_TOP
41 47
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index a51d36a2738..80d24c485fd 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1463,6 +1463,7 @@ ENTRY(_spill_registers)
1463 callx0 a0 # should not return 1463 callx0 a0 # should not return
14641: j 1b 14641: j 1b
1465 1465
1466#ifdef CONFIG_MMU
1466/* 1467/*
1467 * We should never get here. Bail out! 1468 * We should never get here. Bail out!
1468 */ 1469 */
@@ -1775,7 +1776,7 @@ ENTRY(fast_store_prohibited)
1775 bbsi.l a2, PS_UM_BIT, 1f 1776 bbsi.l a2, PS_UM_BIT, 1f
1776 j _kernel_exception 1777 j _kernel_exception
17771: j _user_exception 17781: j _user_exception
1778 1779#endif /* CONFIG_MMU */
1779 1780
1780/* 1781/*
1781 * System Calls. 1782 * System Calls.
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index 67e69139520..d092c225d5b 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -235,8 +235,9 @@ should_never_return:
235 */ 235 */
236 236
237.section ".bss.page_aligned", "w" 237.section ".bss.page_aligned", "w"
238#ifdef CONFIG_MMU
238ENTRY(swapper_pg_dir) 239ENTRY(swapper_pg_dir)
239 .fill PAGE_SIZE, 1, 0 240 .fill PAGE_SIZE, 1, 0
241#endif
240ENTRY(empty_zero_page) 242ENTRY(empty_zero_page)
241 .fill PAGE_SIZE, 1, 0 243 .fill PAGE_SIZE, 1, 0
242
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 4ec1633c294..1e5a034fe01 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -84,7 +84,13 @@ sysmem_info_t __initdata sysmem;
84int initrd_is_mapped; 84int initrd_is_mapped;
85#endif 85#endif
86 86
87#ifdef CONFIG_MMU
87extern void init_mmu(void); 88extern void init_mmu(void);
89#else
90static inline void init_mmu(void) { }
91#endif
92
93extern void zones_init(void);
88 94
89/* 95/*
90 * Boot parameter parsing. 96 * Boot parameter parsing.
@@ -286,6 +292,7 @@ void __init setup_arch(char **cmdline_p)
286 292
287 293
288 paging_init(); 294 paging_init();
295 zones_init();
289 296
290#ifdef CONFIG_VT 297#ifdef CONFIG_VT
291# if defined(CONFIG_VGA_CONSOLE) 298# if defined(CONFIG_VGA_CONSOLE)
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 6b4a9d79e7b..9f0b71189e9 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -104,6 +104,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
104#endif 104#endif
105{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, 105{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned },
106#endif 106#endif
107#ifdef CONFIG_MMU
107{ EXCCAUSE_ITLB_MISS, 0, do_page_fault }, 108{ EXCCAUSE_ITLB_MISS, 0, do_page_fault },
108{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss}, 109{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss},
109{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit }, 110{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit },
@@ -118,6 +119,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
118{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited }, 119{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited },
119{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault }, 120{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault },
120{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault }, 121{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault },
122#endif /* CONFIG_MMU */
121/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */ 123/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
122#if XTENSA_HAVE_COPROCESSOR(0) 124#if XTENSA_HAVE_COPROCESSOR(0)
123COPROCESSOR(0), 125COPROCESSOR(0),
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index eb2d7bb69ee..74a7518faf1 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -309,6 +309,7 @@ ENTRY(_DoubleExceptionVector)
309 * All other exceptions are unexpected and thus unrecoverable! 309 * All other exceptions are unexpected and thus unrecoverable!
310 */ 310 */
311 311
312#ifdef CONFIG_MMU
312 .extern fast_second_level_miss_double_kernel 313 .extern fast_second_level_miss_double_kernel
313 314
314.Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */ 315.Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
@@ -319,6 +320,9 @@ ENTRY(_DoubleExceptionVector)
319 bnez a3, .Lunrecoverable 320 bnez a3, .Lunrecoverable
3201: movi a3, fast_second_level_miss_double_kernel 3211: movi a3, fast_second_level_miss_double_kernel
321 jx a3 322 jx a3
323#else
324.equ .Lksp, .Lunrecoverable
325#endif
322 326
323 /* Critical! We can't handle this situation. PANIC! */ 327 /* Critical! We can't handle this situation. PANIC! */
324 328
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
index 64e304a2f88..f0b646d2f84 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
5obj-y := init.o fault.o tlb.o misc.o cache.o 5obj-y := init.o cache.o misc.o
6obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 6190988bba1..427e14fa43c 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
35DEFINE_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
163void __init paging_init(void) 156void __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
189void __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
285struct kmem_cache *pgtable_cache __read_mostly;
286
287static 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
297void __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 c885664211d..b048406d875 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
313ENTRY(__tlbtemp_mapping_end) 314ENTRY(__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 00000000000..4bb91a970f1
--- /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
17DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
18
19void __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 */
27void __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
52struct kmem_cache *pgtable_cache __read_mostly;
53
54static 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
64void __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}