OpenWrt – Rev 1

Subversion Repositories:
Rev:
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
@@ -35,6 +35,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