102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| Date: Wed, 24 Sep 2014 22:14:07 +0200
 | |
| Subject: [PATCH] ARM: BCM5301X: Disable MMU and Dcache during decompression
 | |
| MIME-Version: 1.0
 | |
| Content-Type: text/plain; charset=UTF-8
 | |
| Content-Transfer-Encoding: 8bit
 | |
| 
 | |
| Broadcom devices have broken CFE (bootloader) that leaves hardware in an
 | |
| invalid state. It causes problems with booting Linux. On Northstar
 | |
| devices kernel was randomly hanging in ~25% of tries during early init.
 | |
| Hangs used to happen at random places in the start_kernel. On BCM53573
 | |
| kernel doesn't even seem to start booting.
 | |
| 
 | |
| To workaround this problem we need to do following very early:
 | |
| 1) Clear 2 following bits in the SCTLR register:
 | |
| #define CR_M    (1 << 0)        /* MMU enable */
 | |
| #define CR_C    (1 << 2)        /* Dcache enable */
 | |
| 2) Flush the whole D-cache
 | |
| 3) Disable L2 cache
 | |
| 
 | |
| Unfortunately this patch is not upstreamable as it does above things
 | |
| unconditionally. We can't check if we are running on Broadcom platform
 | |
| in any safe way and doing such hacks with ARCH_MULTI_V7 is unacceptable
 | |
| as it could break other devices support.
 | |
| 
 | |
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| ---
 | |
| 
 | |
| --- a/arch/arm/boot/compressed/Makefile
 | |
| +++ b/arch/arm/boot/compressed/Makefile
 | |
| @@ -31,6 +31,11 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
 | |
|  OBJS		+= ll_char_wr.o font.o
 | |
|  endif
 | |
|  
 | |
| +ifeq ($(CONFIG_ARCH_BCM_5301X),y)
 | |
| +OBJS		+= head-bcm_5301x-mpcore.o
 | |
| +OBJS		+= cache-v7-min.o
 | |
| +endif
 | |
| +
 | |
|  ifeq ($(CONFIG_ARCH_SA1100),y)
 | |
|  OBJS		+= head-sa1100.o
 | |
|  endif
 | |
| --- /dev/null
 | |
| +++ b/arch/arm/boot/compressed/head-bcm_5301x-mpcore.S
 | |
| @@ -0,0 +1,37 @@
 | |
| +/*
 | |
| + *
 | |
| + * Platform specific tweaks.  This is merged into head.S by the linker.
 | |
| + *
 | |
| + */
 | |
| +
 | |
| +#include <linux/linkage.h>
 | |
| +#include <asm/assembler.h>
 | |
| +#include <asm/cp15.h>
 | |
| +
 | |
| +		.section        ".start", "ax"
 | |
| +
 | |
| +/*
 | |
| + * This code section is spliced into the head code by the linker
 | |
| + */
 | |
| +
 | |
| +__plat_uncompress_start:
 | |
| +
 | |
| +	@ Preserve r8/r7 i.e. kernel entry values
 | |
| +	mov	r12, r8
 | |
| +
 | |
| +	@ Clear MMU enable and Dcache enable bits
 | |
| +	mrc	p15, 0, r0, c1, c0, 0		@ Read SCTLR
 | |
| +	bic	r0, #CR_C|CR_M
 | |
| +	mcr	p15, 0, r0, c1, c0, 0		@ Write SCTLR
 | |
| +	nop
 | |
| +
 | |
| +	@ Call the cache invalidation routine
 | |
| +	bl	v7_flush_dcache_all
 | |
| +	nop
 | |
| +	mov	r0,#0
 | |
| +	ldr	r3, =0x19022000			@ L2 cache controller, control reg
 | |
| +	str	r0, [r3, #0x100]		@ Disable L2 cache
 | |
| +	nop
 | |
| +
 | |
| +	@ Restore
 | |
| +	mov	r8, r12
 | |
| --- a/arch/arm/boot/compressed/cache-v7-min.S
 | |
| +++ b/arch/arm/boot/compressed/cache-v7-min.S
 | |
| @@ -12,6 +12,7 @@
 | |
|  
 | |
|  #include <linux/linkage.h>
 | |
|  #include <linux/init.h>
 | |
| +#include <asm/assembler.h>
 | |
|  
 | |
|  	__INIT
 | |
|  
 | |
| @@ -63,7 +64,7 @@ loop2:
 | |
|   ARM(	orr	r11, r11, r9, lsl r2	)	@ factor index number into r11
 | |
|   THUMB(	lsl	r6, r9, r2		)
 | |
|   THUMB(	orr	r11, r11, r6		)	@ factor index number into r11
 | |
| -	mcr	p15, 0, r11, c7, c14, 2		@ clean & invalidate by set/way
 | |
| +	mcr     p15, 0, r11, c7, c6, 2		@ clean & invalidate by set/way
 | |
|  	subs	r9, r9, #1			@ decrement the index
 | |
|  	bge	loop2
 | |
|  	subs	r4, r4, #1			@ decrement the way
 | 
