This patch fix the problem with rootfs on JFFS2 with early printk console turned on. The origin version used TLB63 for temporary early printk mapping. The code expect that kernel is not able to use all 64 TLB entries till early printk console is remapped by ioremap. After that temporary mapping on TLB63 is silently lost. This expectation give the opportunity to have early console pretty early. Microblaze systems with JFFS2 rootfs with early printk console turned on used more than 64 TLB entries before kernel can remap early console. Based on that kernel does access to bad area because early printk mapping is rewritten. This patch introduces tlb_skip variable which dynamically stores number of skipped TLB entries from the TLB0. skip_tlb=2 means that TLB0 and TLB1 should be skipped. MICROBLAZE_TLB_SKIP defines how many TLB is skipped at the kernel start. They can be used for user purpose. TLB 63 is used for temporary LMB mapping (MICROBLAZE_LMB_TLB_ID). Also clean TLBLO when kernel starts. For specific kernel sizes kernel can use just one TLB. Detect this case and use the second TLB for general purpose. Change _tlbia function to flush TLB entries from tlb_skip to TLB_SIZE. Export tlb_skip size through debugfs. Signed-off-by: Michal Simek <monstr@monstr.eu>
		
			
				
	
	
		
			100 lines
		
	
	
	
		
			2.1 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
	
		
			2.1 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/*
 | 
						|
 * Miscellaneous low-level MMU functions.
 | 
						|
 *
 | 
						|
 * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
 | 
						|
 * 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 <linux/linkage.h>
 | 
						|
#include <linux/sys.h>
 | 
						|
#include <asm/unistd.h>
 | 
						|
#include <linux/errno.h>
 | 
						|
#include <asm/mmu.h>
 | 
						|
#include <asm/page.h>
 | 
						|
 | 
						|
	.text
 | 
						|
/*
 | 
						|
 * Flush MMU TLB
 | 
						|
 *
 | 
						|
 * We avoid flushing the pinned 0, 1 and possibly 2 entries.
 | 
						|
 */
 | 
						|
.globl _tlbia;
 | 
						|
.type  _tlbia, @function
 | 
						|
.align 4;
 | 
						|
_tlbia:
 | 
						|
	lwi	r12, r0, tlb_skip;
 | 
						|
	/* isync */
 | 
						|
_tlbia_1:
 | 
						|
	mts	rtlbx, r12
 | 
						|
	nop
 | 
						|
	mts	rtlbhi, r0 /* flush: ensure V is clear */
 | 
						|
	nop
 | 
						|
	rsubi	r11, r12, MICROBLAZE_TLB_SIZE - 1
 | 
						|
	bneid	r11, _tlbia_1 /* loop for all entries */
 | 
						|
	addik	r12, r12, 1
 | 
						|
	/* sync */
 | 
						|
	rtsd	r15, 8
 | 
						|
	nop
 | 
						|
	.size  _tlbia, . - _tlbia
 | 
						|
 | 
						|
/*
 | 
						|
 * Flush MMU TLB for a particular address (in r5)
 | 
						|
 */
 | 
						|
.globl _tlbie;
 | 
						|
.type  _tlbie, @function
 | 
						|
.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
 | 
						|
 | 
						|
	.size  _tlbie, . - _tlbie
 | 
						|
 | 
						|
/*
 | 
						|
 * Allocate TLB entry for early console
 | 
						|
 */
 | 
						|
.globl early_console_reg_tlb_alloc;
 | 
						|
.type  early_console_reg_tlb_alloc, @function
 | 
						|
.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.
 | 
						|
	 */
 | 
						|
	lwi	r4, r0, tlb_skip
 | 
						|
	mts	rtlbx, r4 /* TLB slot 63 */
 | 
						|
 | 
						|
	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
 | 
						|
 | 
						|
	lwi	r5, r0, tlb_skip
 | 
						|
	addik	r5, r5, 1
 | 
						|
	swi	r5, r0, tlb_skip
 | 
						|
 | 
						|
	rtsd	r15, 8
 | 
						|
	nop
 | 
						|
 | 
						|
	.size  early_console_reg_tlb_alloc, . - early_console_reg_tlb_alloc
 |