]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/cris/arch-v10/mm/init.c | |
3 | * | |
4 | */ | |
1da177e4 LT |
5 | #include <linux/mmzone.h> |
6 | #include <linux/init.h> | |
7 | #include <linux/bootmem.h> | |
8 | #include <linux/mm.h> | |
9 | #include <asm/pgtable.h> | |
10 | #include <asm/page.h> | |
11 | #include <asm/types.h> | |
12 | #include <asm/mmu.h> | |
13 | #include <asm/io.h> | |
14 | #include <asm/mmu_context.h> | |
556dcee7 | 15 | #include <arch/svinto.h> |
1da177e4 LT |
16 | |
17 | extern void tlb_init(void); | |
18 | ||
19 | /* | |
20 | * The kernel is already mapped with a kernel segment at kseg_c so | |
21 | * we don't need to map it with a page table. However head.S also | |
22 | * temporarily mapped it at kseg_4 so we should set up the ksegs again, | |
23 | * clear the TLB and do some other paging setup stuff. | |
24 | */ | |
25 | ||
26 | void __init | |
27 | paging_init(void) | |
28 | { | |
29 | int i; | |
30 | unsigned long zones_size[MAX_NR_ZONES]; | |
31 | ||
32 | printk("Setting up paging and the MMU.\n"); | |
33 | ||
34 | /* clear out the init_mm.pgd that will contain the kernel's mappings */ | |
35 | ||
36 | for(i = 0; i < PTRS_PER_PGD; i++) | |
37 | swapper_pg_dir[i] = __pgd(0); | |
38 | ||
39 | /* make sure the current pgd table points to something sane | |
40 | * (even if it is most probably not used until the next | |
41 | * switch_mm) | |
42 | */ | |
43 | ||
8d20a541 | 44 | per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd; |
1da177e4 LT |
45 | |
46 | /* initialise the TLB (tlb.c) */ | |
47 | ||
48 | tlb_init(); | |
49 | ||
50 | /* see README.mm for details on the KSEG setup */ | |
51 | ||
52 | #ifdef CONFIG_CRIS_LOW_MAP | |
53 | /* Etrax-100 LX version 1 has a bug so that we cannot map anything | |
54 | * across the 0x80000000 boundary, so we need to shrink the user-virtual | |
55 | * area to 0x50000000 instead of 0xb0000000 and map things slightly | |
56 | * different. The unused areas are marked as paged so that we can catch | |
57 | * freak kernel accesses there. | |
58 | * | |
59 | * The ARTPEC chip is mapped at 0xa so we pass that segment straight | |
60 | * through. We cannot vremap it because the vmalloc area is below 0x8 | |
61 | * and Juliette needs an uncached area above 0x8. | |
62 | * | |
63 | * Same thing with 0xc and 0x9, which is memory-mapped I/O on some boards. | |
64 | * We map them straight over in LOW_MAP, but use vremap in LX version 2. | |
65 | */ | |
66 | ||
67 | #define CACHED_BOOTROM (KSEG_F | 0x08000000UL) | |
68 | ||
69 | *R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg ) | /* bootrom */ | |
70 | IO_STATE(R_MMU_KSEG, seg_e, page ) | | |
71 | IO_STATE(R_MMU_KSEG, seg_d, page ) | | |
72 | IO_STATE(R_MMU_KSEG, seg_c, page ) | | |
73 | IO_STATE(R_MMU_KSEG, seg_b, seg ) | /* kernel reg area */ | |
74 | #ifdef CONFIG_JULIETTE | |
75 | IO_STATE(R_MMU_KSEG, seg_a, seg ) | /* ARTPEC etc. */ | |
76 | #else | |
77 | IO_STATE(R_MMU_KSEG, seg_a, page ) | | |
78 | #endif | |
79 | IO_STATE(R_MMU_KSEG, seg_9, seg ) | /* LED's on some boards */ | |
80 | IO_STATE(R_MMU_KSEG, seg_8, seg ) | /* CSE0/1, flash and I/O */ | |
81 | IO_STATE(R_MMU_KSEG, seg_7, page ) | /* kernel vmalloc area */ | |
82 | IO_STATE(R_MMU_KSEG, seg_6, seg ) | /* kernel DRAM area */ | |
83 | IO_STATE(R_MMU_KSEG, seg_5, seg ) | /* cached flash */ | |
84 | IO_STATE(R_MMU_KSEG, seg_4, page ) | /* user area */ | |
85 | IO_STATE(R_MMU_KSEG, seg_3, page ) | /* user area */ | |
86 | IO_STATE(R_MMU_KSEG, seg_2, page ) | /* user area */ | |
87 | IO_STATE(R_MMU_KSEG, seg_1, page ) | /* user area */ | |
88 | IO_STATE(R_MMU_KSEG, seg_0, page ) ); /* user area */ | |
89 | ||
90 | *R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x3 ) | | |
91 | IO_FIELD(R_MMU_KBASE_HI, base_e, 0x0 ) | | |
92 | IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) | | |
93 | IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) | | |
94 | IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) | | |
95 | #ifdef CONFIG_JULIETTE | |
96 | IO_FIELD(R_MMU_KBASE_HI, base_a, 0xa ) | | |
97 | #else | |
98 | IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) | | |
99 | #endif | |
100 | IO_FIELD(R_MMU_KBASE_HI, base_9, 0x9 ) | | |
101 | IO_FIELD(R_MMU_KBASE_HI, base_8, 0x8 ) ); | |
102 | ||
103 | *R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) | | |
104 | IO_FIELD(R_MMU_KBASE_LO, base_6, 0x4 ) | | |
105 | IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) | | |
106 | IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) | | |
107 | IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) | | |
108 | IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) | | |
109 | IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) | | |
110 | IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) ); | |
111 | #else | |
112 | /* This code is for the corrected Etrax-100 LX version 2... */ | |
113 | ||
114 | #define CACHED_BOOTROM (KSEG_A | 0x08000000UL) | |
115 | ||
116 | *R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg ) | /* cached flash */ | |
117 | IO_STATE(R_MMU_KSEG, seg_e, seg ) | /* uncached flash */ | |
118 | IO_STATE(R_MMU_KSEG, seg_d, page ) | /* vmalloc area */ | |
119 | IO_STATE(R_MMU_KSEG, seg_c, seg ) | /* kernel area */ | |
120 | IO_STATE(R_MMU_KSEG, seg_b, seg ) | /* kernel reg area */ | |
121 | IO_STATE(R_MMU_KSEG, seg_a, seg ) | /* bootrom */ | |
122 | IO_STATE(R_MMU_KSEG, seg_9, page ) | /* user area */ | |
123 | IO_STATE(R_MMU_KSEG, seg_8, page ) | | |
124 | IO_STATE(R_MMU_KSEG, seg_7, page ) | | |
125 | IO_STATE(R_MMU_KSEG, seg_6, page ) | | |
126 | IO_STATE(R_MMU_KSEG, seg_5, page ) | | |
127 | IO_STATE(R_MMU_KSEG, seg_4, page ) | | |
128 | IO_STATE(R_MMU_KSEG, seg_3, page ) | | |
129 | IO_STATE(R_MMU_KSEG, seg_2, page ) | | |
130 | IO_STATE(R_MMU_KSEG, seg_1, page ) | | |
131 | IO_STATE(R_MMU_KSEG, seg_0, page ) ); | |
132 | ||
133 | *R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) | | |
134 | IO_FIELD(R_MMU_KBASE_HI, base_e, 0x8 ) | | |
135 | IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) | | |
136 | IO_FIELD(R_MMU_KBASE_HI, base_c, 0x4 ) | | |
137 | IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) | | |
138 | IO_FIELD(R_MMU_KBASE_HI, base_a, 0x3 ) | | |
139 | IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) | | |
140 | IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) ); | |
141 | ||
142 | *R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) | | |
143 | IO_FIELD(R_MMU_KBASE_LO, base_6, 0x0 ) | | |
144 | IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) | | |
145 | IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) | | |
146 | IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) | | |
147 | IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) | | |
148 | IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) | | |
149 | IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) ); | |
150 | #endif | |
151 | ||
152 | *R_MMU_CONTEXT = ( IO_FIELD(R_MMU_CONTEXT, page_id, 0 ) ); | |
153 | ||
154 | /* The MMU has been enabled ever since head.S but just to make | |
155 | * it totally obvious we do it here as well. | |
156 | */ | |
157 | ||
158 | *R_MMU_CTRL = ( IO_STATE(R_MMU_CTRL, inv_excp, enable ) | | |
159 | IO_STATE(R_MMU_CTRL, acc_excp, enable ) | | |
160 | IO_STATE(R_MMU_CTRL, we_excp, enable ) ); | |
161 | ||
162 | *R_MMU_ENABLE = IO_STATE(R_MMU_ENABLE, mmu_enable, enable); | |
163 | ||
164 | /* | |
165 | * initialize the bad page table and bad page to point | |
166 | * to a couple of allocated pages | |
167 | */ | |
168 | ||
169 | empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); | |
170 | memset((void *)empty_zero_page, 0, PAGE_SIZE); | |
171 | ||
172 | /* All pages are DMA'able in Etrax, so put all in the DMA'able zone */ | |
173 | ||
174 | zones_size[0] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; | |
175 | ||
176 | for (i = 1; i < MAX_NR_ZONES; i++) | |
177 | zones_size[i] = 0; | |
178 | ||
179 | /* Use free_area_init_node instead of free_area_init, because the former | |
180 | * is designed for systems where the DRAM starts at an address substantially | |
181 | * higher than 0, like us (we start at PAGE_OFFSET). This saves space in the | |
182 | * mem_map page array. | |
183 | */ | |
184 | ||
9109fb7b | 185 | free_area_init_node(0, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0); |
1da177e4 LT |
186 | } |
187 | ||
188 | /* Initialize remaps of some I/O-ports. It is important that this | |
189 | * is called before any driver is initialized. | |
190 | */ | |
191 | ||
192 | static int | |
193 | __init init_ioremap(void) | |
194 | { | |
195 | ||
196 | /* Give the external I/O-port addresses their values */ | |
197 | ||
198 | #ifdef CONFIG_CRIS_LOW_MAP | |
199 | /* Simply a linear map (see the KSEG map above in paging_init) */ | |
200 | port_cse1_addr = (volatile unsigned long *)(MEM_CSE1_START | | |
201 | MEM_NON_CACHEABLE); | |
202 | port_csp0_addr = (volatile unsigned long *)(MEM_CSP0_START | | |
203 | MEM_NON_CACHEABLE); | |
204 | port_csp4_addr = (volatile unsigned long *)(MEM_CSP4_START | | |
205 | MEM_NON_CACHEABLE); | |
206 | #else | |
207 | /* Note that nothing blows up just because we do this remapping | |
208 | * it's ok even if the ports are not used or connected | |
209 | * to anything (or connected to a non-I/O thing) */ | |
210 | port_cse1_addr = (volatile unsigned long *) | |
211 | ioremap((unsigned long)(MEM_CSE1_START | MEM_NON_CACHEABLE), 16); | |
212 | port_csp0_addr = (volatile unsigned long *) | |
213 | ioremap((unsigned long)(MEM_CSP0_START | MEM_NON_CACHEABLE), 16); | |
214 | port_csp4_addr = (volatile unsigned long *) | |
215 | ioremap((unsigned long)(MEM_CSP4_START | MEM_NON_CACHEABLE), 16); | |
216 | #endif | |
217 | return 0; | |
218 | } | |
219 | ||
220 | __initcall(init_ioremap); | |
221 | ||
222 | /* Helper function for the two below */ | |
223 | ||
224 | static inline void | |
225 | flush_etrax_cacherange(void *startadr, int length) | |
226 | { | |
227 | /* CACHED_BOOTROM is mapped to the boot-rom area (cached) which | |
228 | * we can use to get fast dummy-reads of cachelines | |
229 | */ | |
230 | ||
231 | volatile short *flushadr = (volatile short *)(((unsigned long)startadr & ~PAGE_MASK) | | |
232 | CACHED_BOOTROM); | |
233 | ||
234 | length = length > 8192 ? 8192 : length; /* No need to flush more than cache size */ | |
235 | ||
236 | while(length > 0) { | |
237 | *flushadr; /* dummy read to flush */ | |
238 | flushadr += (32/sizeof(short)); /* a cacheline is 32 bytes */ | |
239 | length -= 32; | |
240 | } | |
241 | } | |
242 | ||
243 | /* Due to a bug in Etrax100(LX) all versions, receiving DMA buffers | |
c23cf8ba | 244 | * will occasionally corrupt certain CPU writes if the DMA buffers |
1da177e4 LT |
245 | * happen to be hot in the cache. |
246 | * | |
247 | * As a workaround, we have to flush the relevant parts of the cache | |
248 | * before (re) inserting any receiving descriptor into the DMA HW. | |
249 | */ | |
250 | ||
251 | void | |
252 | prepare_rx_descriptor(struct etrax_dma_descr *desc) | |
253 | { | |
254 | flush_etrax_cacherange((void *)desc->buf, desc->sw_len ? desc->sw_len : 65536); | |
255 | } | |
256 | ||
257 | /* Do the same thing but flush the entire cache */ | |
258 | ||
259 | void | |
260 | flush_etrax_cache(void) | |
261 | { | |
262 | flush_etrax_cacherange(0, 8192); | |
263 | } |