From 3f50425c0c9815411b760e36b48e18958819a304 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 26 May 2009 16:30:10 +0200 Subject: microblaze_mmu_v2: TLB low level code Signed-off-by: Michal Simek --- arch/microblaze/kernel/misc.S | 120 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 arch/microblaze/kernel/misc.S (limited to 'arch/microblaze/kernel/misc.S') diff --git a/arch/microblaze/kernel/misc.S b/arch/microblaze/kernel/misc.S new file mode 100644 index 00000000000..d623efc9083 --- /dev/null +++ b/arch/microblaze/kernel/misc.S @@ -0,0 +1,120 @@ +/* + * Miscellaneous low-level MMU functions. + * + * Copyright (C) 2008-2009 Michal Simek + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2007 Xilinx, Inc. All rights reserved. + * + * Derived from arch/ppc/kernel/misc.S + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#include +#include +#include +#include +#include +#include + + .text +/* + * Flush MMU TLB + * + * We avoid flushing the pinned 0, 1 and possibly 2 entries. + */ +.globl _tlbia; +.align 4; +_tlbia: + addik r12, r0, 63 /* flush all entries (63 - 3) */ + /* isync */ +_tlbia_1: + mts rtlbx, r12 + nop + mts rtlbhi, r0 /* flush: ensure V is clear */ + nop + addik r11, r12, -2 + bneid r11, _tlbia_1 /* loop for all entries */ + addik r12, r12, -1 + /* sync */ + rtsd r15, 8 + nop + +/* + * Flush MMU TLB for a particular address (in r5) + */ +.globl _tlbie; +.align 4; +_tlbie: + mts rtlbsx, r5 /* look up the address in TLB */ + nop + mfs r12, rtlbx /* Retrieve index */ + nop + blti r12, _tlbie_1 /* Check if found */ + mts rtlbhi, r0 /* flush: ensure V is clear */ + nop +_tlbie_1: + rtsd r15, 8 + nop + +/* + * Allocate TLB entry for early console + */ +.globl early_console_reg_tlb_alloc; +.align 4; +early_console_reg_tlb_alloc: + /* + * Load a TLB entry for the UART, so that microblaze_progress() can use + * the UARTs nice and early. We use a 4k real==virtual mapping. + */ + ori r4, r0, 2 + mts rtlbx, r4 /* TLB slot 2 */ + + or r4,r5,r0 + andi r4,r4,0xfffff000 + ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G) + + andi r5,r5,0xfffff000 + ori r5,r5,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K)) + + mts rtlblo,r4 /* Load the data portion of the entry */ + nop + mts rtlbhi,r5 /* Load the tag portion of the entry */ + nop + rtsd r15, 8 + nop + +/* + * Copy a whole page (4096 bytes). + */ +#define COPY_16_BYTES \ + lwi r7, r6, 0; \ + lwi r8, r6, 4; \ + lwi r9, r6, 8; \ + lwi r10, r6, 12; \ + swi r7, r5, 0; \ + swi r8, r5, 4; \ + swi r9, r5, 8; \ + swi r10, r5, 12 + + +/* FIXME DCACHE_LINE_BYTES (CONFIG_XILINX_MICROBLAZE0_DCACHE_LINE_LEN * 4)*/ +#define DCACHE_LINE_BYTES (4 * 4) + +.globl copy_page; +.align 4; +copy_page: + ori r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1 +_copy_page_loop: + COPY_16_BYTES +#if DCACHE_LINE_BYTES >= 32 + COPY_16_BYTES +#endif + addik r6, r6, DCACHE_LINE_BYTES + addik r5, r5, DCACHE_LINE_BYTES + bneid r11, _copy_page_loop + addik r11, r11, -1 + rtsd r15, 8 + nop -- cgit v1.2.3 From fee3c55d7fb9486f02d3285678d58e433ffe3c2a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 29 May 2009 14:15:33 +0200 Subject: microblaze: Fix problem with early_printk in startup Problem arise when is incopatibility between kernel/dts/pvr and kernel tries to announce it. Early printk device (uartlite in our case) was in TLB 2 and when kernel extract DTB it necessary to allocate at least one TLB at the end of memory. First free TLB was number two where was early printk. But checking mechanism (kernel/dts/pvr) was after extrahing but TLB 2 was different. This caused that kernel hung up. Moving early printk device to TLB 63 solve it and we don't protect it which means that we can use early_printk messages only for initial parts of kernel then we rewrite TLB 63. Reported-by: Edgar E. Iglesias Signed-off-by: Michal Simek --- arch/microblaze/kernel/misc.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/microblaze/kernel/misc.S') diff --git a/arch/microblaze/kernel/misc.S b/arch/microblaze/kernel/misc.S index d623efc9083..df16c6287a8 100644 --- a/arch/microblaze/kernel/misc.S +++ b/arch/microblaze/kernel/misc.S @@ -69,7 +69,7 @@ early_console_reg_tlb_alloc: * Load a TLB entry for the UART, so that microblaze_progress() can use * the UARTs nice and early. We use a 4k real==virtual mapping. */ - ori r4, r0, 2 + ori r4, r0, 63 mts rtlbx, r4 /* TLB slot 2 */ or r4,r5,r0 -- cgit v1.2.3