aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/microblaze/include/asm/mmu.h13
-rw-r--r--arch/microblaze/kernel/early_printk.c14
-rw-r--r--arch/microblaze/kernel/head.S42
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S10
-rw-r--r--arch/microblaze/kernel/misc.S13
-rw-r--r--arch/microblaze/kernel/setup.c13
6 files changed, 83 insertions, 22 deletions
diff --git a/arch/microblaze/include/asm/mmu.h b/arch/microblaze/include/asm/mmu.h
index 5198de8b1224..1f9edddf7f4b 100644
--- a/arch/microblaze/include/asm/mmu.h
+++ b/arch/microblaze/include/asm/mmu.h
@@ -56,6 +56,12 @@ typedef struct _SEGREG {
56 56
57extern void _tlbie(unsigned long va); /* invalidate a TLB entry */ 57extern void _tlbie(unsigned long va); /* invalidate a TLB entry */
58extern void _tlbia(void); /* invalidate all TLB entries */ 58extern void _tlbia(void); /* invalidate all TLB entries */
59
60/*
61 * tlb_skip size stores actual number skipped TLBs from TLB0 - every directy TLB
62 * mapping has to increase tlb_skip size.
63 */
64extern u32 tlb_skip;
59# endif /* __ASSEMBLY__ */ 65# endif /* __ASSEMBLY__ */
60 66
61/* 67/*
@@ -68,7 +74,12 @@ extern void _tlbia(void); /* invalidate all TLB entries */
68 */ 74 */
69 75
70# define MICROBLAZE_TLB_SIZE 64 76# define MICROBLAZE_TLB_SIZE 64
71# define MICROBLAZE_TLB_SKIP 2 77
78/* For cases when you want to skip some TLB entries */
79# define MICROBLAZE_TLB_SKIP 0
80
81/* Use the last TLB for temporary access to LMB */
82# define MICROBLAZE_LMB_TLB_ID 63
72 83
73/* 84/*
74 * TLB entries are defined by a "high" tag portion and a "low" data 85 * TLB entries are defined by a "high" tag portion and a "low" data
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index 742c247792ce..ec485876d0d0 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -175,6 +175,20 @@ void __init remap_early_printk(void)
175 base_addr); 175 base_addr);
176 base_addr = (u32) ioremap(base_addr, PAGE_SIZE); 176 base_addr = (u32) ioremap(base_addr, PAGE_SIZE);
177 printk(KERN_CONT "0x%x\n", base_addr); 177 printk(KERN_CONT "0x%x\n", base_addr);
178
179 /*
180 * Early console is on the top of skipped TLB entries
181 * decrease tlb_skip size ensure that hardcoded TLB entry will be
182 * used by generic algorithm
183 * FIXME check if early console mapping is on the top by rereading
184 * TLB entry and compare baseaddr
185 * mts rtlbx, (tlb_skip - 1)
186 * nop
187 * mfs rX, rtlblo
188 * nop
189 * cmp rX, orig_base_addr
190 */
191 tlb_skip -= 1;
178} 192}
179 193
180void __init disable_early_printk(void) 194void __init disable_early_printk(void)
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index 49dd48f9e6ec..98b17f9f904b 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -149,6 +149,7 @@ _copy_bram:
149_invalidate: 149_invalidate:
150 mts rtlbx, r3 150 mts rtlbx, r3
151 mts rtlbhi, r0 /* flush: ensure V is clear */ 151 mts rtlbhi, r0 /* flush: ensure V is clear */
152 mts rtlblo, r0
152 bgtid r3, _invalidate /* loop for all entries */ 153 bgtid r3, _invalidate /* loop for all entries */
153 addik r3, r3, -1 154 addik r3, r3, -1
154 /* sync */ 155 /* sync */
@@ -224,8 +225,14 @@ tlb_end:
224 andi r4,r4,0xfffffc00 /* Mask off the real page number */ 225 andi r4,r4,0xfffffc00 /* Mask off the real page number */
225 ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */ 226 ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
226 227
227 /* TLB0 can be zeroes that's why we not setup it */ 228 /*
228 beqi r9, jump_over 229 * TLB0 is always used - check if is not zero (r9 stores TLB0 value)
230 * if is use TLB1 value and clear it (r10 stores TLB1 value)
231 */
232 bnei r9, tlb0_not_zero
233 add r9, r10, r0
234 add r10, r0, r0
235tlb0_not_zero:
229 236
230 /* look at the code below */ 237 /* look at the code below */
231 ori r30, r0, 0x200 238 ori r30, r0, 0x200
@@ -239,18 +246,21 @@ tlb_end:
239 bneid r29, 1f 246 bneid r29, 1f
240 addik r30, r30, 0x80 247 addik r30, r30, 0x80
2411: 2481:
242 ori r11, r30, 0
243
244 andi r3,r3,0xfffffc00 /* Mask off the effective page number */ 249 andi r3,r3,0xfffffc00 /* Mask off the effective page number */
245 ori r3,r3,(TLB_VALID) 250 ori r3,r3,(TLB_VALID)
246 or r3, r3, r11 251 or r3, r3, r30
247 252
248 mts rtlbx,r0 /* TLB slow 0 */ 253 /* Load tlb_skip size value which is index to first unused TLB entry */
254 lwi r11, r0, TOPHYS(tlb_skip)
255 mts rtlbx,r11 /* TLB slow 0 */
249 256
250 mts rtlblo,r4 /* Load the data portion of the entry */ 257 mts rtlblo,r4 /* Load the data portion of the entry */
251 mts rtlbhi,r3 /* Load the tag portion of the entry */ 258 mts rtlbhi,r3 /* Load the tag portion of the entry */
252 259
253jump_over: 260 /* Increase tlb_skip size */
261 addik r11, r11, 1
262 swi r11, r0, TOPHYS(tlb_skip)
263
254 /* TLB1 can be zeroes that's why we not setup it */ 264 /* TLB1 can be zeroes that's why we not setup it */
255 beqi r10, jump_over2 265 beqi r10, jump_over2
256 266
@@ -266,27 +276,30 @@ jump_over:
266 bneid r29, 1f 276 bneid r29, 1f
267 addik r30, r30, 0x80 277 addik r30, r30, 0x80
2681: 2781:
269 ori r12, r30, 0
270
271 addk r4, r4, r9 /* previous addr + TLB0 size */ 279 addk r4, r4, r9 /* previous addr + TLB0 size */
272 addk r3, r3, r9 280 addk r3, r3, r9
273 281
274 andi r3,r3,0xfffffc00 /* Mask off the effective page number */ 282 andi r3,r3,0xfffffc00 /* Mask off the effective page number */
275 ori r3,r3,(TLB_VALID) 283 ori r3,r3,(TLB_VALID)
276 or r3, r3, r12 284 or r3, r3, r30
277 285
278 ori r6,r0,1 /* TLB slot 1 */ 286 lwi r11, r0, TOPHYS(tlb_skip)
279 mts rtlbx,r6 287 mts rtlbx, r11 /* r11 is used from TLB0 */
280 288
281 mts rtlblo,r4 /* Load the data portion of the entry */ 289 mts rtlblo,r4 /* Load the data portion of the entry */
282 mts rtlbhi,r3 /* Load the tag portion of the entry */ 290 mts rtlbhi,r3 /* Load the tag portion of the entry */
283 291
292 /* Increase tlb_skip size */
293 addik r11, r11, 1
294 swi r11, r0, TOPHYS(tlb_skip)
295
284jump_over2: 296jump_over2:
285 /* 297 /*
286 * Load a TLB entry for LMB, since we need access to 298 * Load a TLB entry for LMB, since we need access to
287 * the exception vectors, using a 4k real==virtual mapping. 299 * the exception vectors, using a 4k real==virtual mapping.
288 */ 300 */
289 ori r6,r0,3 /* TLB slot 3 */ 301 /* Use temporary TLB_ID for LMB - clear this temporary mapping later */
302 ori r6, r0, MICROBLAZE_LMB_TLB_ID
290 mts rtlbx,r6 303 mts rtlbx,r6
291 304
292 ori r4,r0,(TLB_WR | TLB_EX) 305 ori r4,r0,(TLB_WR | TLB_EX)
@@ -355,8 +368,7 @@ start_here:
355 368
356 /* Load up the kernel context */ 369 /* Load up the kernel context */
357kernel_load_context: 370kernel_load_context:
358 # Keep entry 0 and 1 valid. Entry 3 mapped to LMB can go away. 371 ori r5, r0, MICROBLAZE_LMB_TLB_ID
359 ori r5,r0,3
360 mts rtlbx,r5 372 mts rtlbx,r5
361 nop 373 nop
362 mts rtlbhi,r0 374 mts rtlbhi,r0
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index b7249f4215a2..aa510f450ac6 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -820,9 +820,15 @@ ex_handler_done:
820 * Upon exit, we reload everything and RFI. 820 * Upon exit, we reload everything and RFI.
821 * A common place to load the TLB. 821 * A common place to load the TLB.
822 */ 822 */
823.section .data
824.align 4
825.global tlb_skip
826 tlb_skip:
827 .long MICROBLAZE_TLB_SKIP
823 tlb_index: 828 tlb_index:
824 /* MS: storing last used tlb index */ 829 /* MS: storing last used tlb index */
825 .long (MICROBLAZE_TLB_SKIP - 1) 830 .long MICROBLAZE_TLB_SIZE/2
831.previous
826 finish_tlb_load: 832 finish_tlb_load:
827 /* MS: load the last used TLB index. */ 833 /* MS: load the last used TLB index. */
828 lwi r5, r0, TOPHYS(tlb_index) 834 lwi r5, r0, TOPHYS(tlb_index)
@@ -833,7 +839,7 @@ ex_handler_done:
833 ori r6, r0, 1 839 ori r6, r0, 1
834 cmp r31, r5, r6 840 cmp r31, r5, r6
835 blti r31, ex12 841 blti r31, ex12
836 addik r5, r6, MICROBLAZE_TLB_SKIP - 1 842 lwi r5, r0, TOPHYS(tlb_skip)
837 ex12: 843 ex12:
838 /* MS: save back current TLB index */ 844 /* MS: save back current TLB index */
839 swi r5, r0, TOPHYS(tlb_index) 845 swi r5, r0, TOPHYS(tlb_index)
diff --git a/arch/microblaze/kernel/misc.S b/arch/microblaze/kernel/misc.S
index c9090d7973f6..1dafddeb8a0b 100644
--- a/arch/microblaze/kernel/misc.S
+++ b/arch/microblaze/kernel/misc.S
@@ -29,16 +29,16 @@
29.type _tlbia, @function 29.type _tlbia, @function
30.align 4; 30.align 4;
31_tlbia: 31_tlbia:
32 addik r12, r0, MICROBLAZE_TLB_SIZE - 1 /* flush all entries (63 - 3) */ 32 lwi r12, r0, tlb_skip;
33 /* isync */ 33 /* isync */
34_tlbia_1: 34_tlbia_1:
35 mts rtlbx, r12 35 mts rtlbx, r12
36 nop 36 nop
37 mts rtlbhi, r0 /* flush: ensure V is clear */ 37 mts rtlbhi, r0 /* flush: ensure V is clear */
38 nop 38 nop
39 addik r11, r12, -MICROBLAZE_TLB_SKIP 39 rsubi r11, r12, MICROBLAZE_TLB_SIZE - 1
40 bneid r11, _tlbia_1 /* loop for all entries */ 40 bneid r11, _tlbia_1 /* loop for all entries */
41 addik r12, r12, -1 41 addik r12, r12, 1
42 /* sync */ 42 /* sync */
43 rtsd r15, 8 43 rtsd r15, 8
44 nop 44 nop
@@ -75,7 +75,7 @@ early_console_reg_tlb_alloc:
75 * Load a TLB entry for the UART, so that microblaze_progress() can use 75 * Load a TLB entry for the UART, so that microblaze_progress() can use
76 * the UARTs nice and early. We use a 4k real==virtual mapping. 76 * the UARTs nice and early. We use a 4k real==virtual mapping.
77 */ 77 */
78 ori r4, r0, 63 78 lwi r4, r0, tlb_skip
79 mts rtlbx, r4 /* TLB slot 63 */ 79 mts rtlbx, r4 /* TLB slot 63 */
80 80
81 or r4,r5,r0 81 or r4,r5,r0
@@ -89,6 +89,11 @@ early_console_reg_tlb_alloc:
89 nop 89 nop
90 mts rtlbhi,r5 /* Load the tag portion of the entry */ 90 mts rtlbhi,r5 /* Load the tag portion of the entry */
91 nop 91 nop
92
93 lwi r5, r0, tlb_skip
94 addik r5, r5, 1
95 swi r5, r0, tlb_skip
96
92 rtsd r15, 8 97 rtsd r15, 8
93 nop 98 nop
94 99
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index a1fa2a5813bf..e4f5956ee13c 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -208,6 +208,19 @@ static int microblaze_debugfs_init(void)
208 return of_debugfs_root == NULL; 208 return of_debugfs_root == NULL;
209} 209}
210arch_initcall(microblaze_debugfs_init); 210arch_initcall(microblaze_debugfs_init);
211
212static int __init debugfs_tlb(void)
213{
214 struct dentry *d;
215
216 if (!of_debugfs_root)
217 return -ENODEV;
218
219 d = debugfs_create_u32("tlb_skip", S_IRUGO, of_debugfs_root, &tlb_skip);
220 if (!d)
221 return -ENOMEM;
222}
223device_initcall(debugfs_tlb);
211#endif 224#endif
212 225
213static int dflt_bus_notify(struct notifier_block *nb, 226static int dflt_bus_notify(struct notifier_block *nb,