[coreboot] Patch set updated for coreboot: 5748b46 armv7/exynos/snow: set up caches properly
David Hendricks (dhendrix@chromium.org)
gerrit at coreboot.org
Tue Mar 19 05:00:40 CET 2013
David Hendricks (dhendrix at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2729
-gerrit
commit 5748b462f1c22cd5ba41d8c09563fa2d872ef909
Author: David Hendricks <dhendrix at chromium.org>
Date: Thu Mar 14 15:24:57 2013 -0700
armv7/exynos/snow: set up caches properly
** do not submit **
This (hopefully) sets up caches more carefully than we were doing
before. This patch needs a bit more testing before going in.
TODO:
- Get rid of imported CP15ISB and isb() macros. They are wrong for
ARMv7 -- it was assumed in u-boot that the code would be compiled
with -march=armv5 (see comment in armv7.h).
- Clean up. Most of this is now done in a generic manner in
bootblock_simple, so a lot of earlier code can go away.
- Set cache policy explicitly before re-enabling
- Replace imported cache routines (and use BSD license to match libpayload?)
Change-Id: I7390981190e3213f4e1431f8e56746545c5cc7c9
Signed-off-by: David Hendricks <dhendrix at chromium.org>
---
src/arch/armv7/bootblock_simple.c | 71 +++++++++++++++++++++++++++++++
src/arch/armv7/include/arch/io.h | 3 +-
src/arch/armv7/include/cache.h | 56 ------------------------
src/arch/armv7/include/system.h | 8 +++-
src/arch/armv7/lib/Makefile.inc | 6 +++
src/arch/armv7/lib/cache-cp15.c | 3 +-
src/arch/armv7/lib/cache_v7.c | 2 +-
src/cpu/samsung/exynos5250/Makefile.inc | 1 -
src/cpu/samsung/exynos5250/bootblock.c | 2 +
src/cpu/samsung/exynos5250/exynos_cache.c | 8 +---
src/mainboard/google/snow/ramstage.c | 15 -------
src/mainboard/google/snow/romstage.c | 37 +++++-----------
12 files changed, 101 insertions(+), 111 deletions(-)
diff --git a/src/arch/armv7/bootblock_simple.c b/src/arch/armv7/bootblock_simple.c
index 0132b87..7012e17 100644
--- a/src/arch/armv7/bootblock_simple.c
+++ b/src/arch/armv7/bootblock_simple.c
@@ -20,6 +20,7 @@
*/
#include <bootblock_common.h>
+#include <arch/cache.h>
#include <arch/hlt.h>
#include <arch/stages.h>
#include <cbfs.h>
@@ -27,6 +28,58 @@
#include "stages.c"
+static void armv7_invalidate_caches(void)
+{
+ uint32_t clidr;
+ int level;
+
+ /* Invalidate branch predictor */
+ bpiall();
+
+ /* Iterate thru each cache identified in CLIDR and invalidate */
+ clidr = read_clidr();
+ for (level = 0; level < 7; level++) {
+ unsigned int ctype = (clidr >> (level * 3)) & 0x7;
+ uint32_t csselr;
+
+ switch(ctype) {
+ case 0x0:
+ /* no cache */
+ break;
+ case 0x1:
+ /* icache only */
+ csselr = (level << 1) | 1;
+ write_csselr(csselr);
+ icache_invalidate_all();
+ break;
+ case 0x2:
+ case 0x4:
+ /* dcache only or unified cache */
+ dcache_invalidate_all();
+ break;
+ case 0x3:
+ /* separate icache and dcache */
+ csselr = (level << 1) | 1;
+ write_csselr(csselr);
+ icache_invalidate_all();
+
+ csselr = level < 1;
+ write_csselr(csselr);
+ dcache_invalidate_all();
+ break;
+ default:
+ /* reserved */
+ break;
+ }
+ }
+
+ /* Invalidate TLB */
+ /* FIXME: ARMv7 Architecture Ref. Manual claims that the distinction
+ * instruction vs. data TLBs is deprecated in ARMv7. But that doesn't
+ * really seem true for Cortex-A15? */
+ tlb_invalidate_all();
+}
+
static int boot_cpu(void)
{
/*
@@ -41,6 +94,24 @@ void main(void)
{
const char *stage_name = "fallback/romstage";
void *entry;
+ uint32_t sctlr;
+
+ /* Globally disable MMU, caches, and branch prediction (these should
+ * be disabled by default on reset) */
+ sctlr = read_sctlr();
+ sctlr &= ~(SCTLR_M | SCTLR_C | SCTLR_Z | SCTLR_I);
+ write_sctlr(sctlr);
+
+ armv7_invalidate_caches();
+
+ /*
+ * Re-enable caches and branch prediction. MMU will be set up later.
+ * Note: If booting from USB, we need to disable branch prediction
+ * before copying from USB into RAM (FIXME: why?)
+ */
+ sctlr = read_sctlr();
+ sctlr |= SCTLR_C | SCTLR_Z | SCTLR_I;
+ write_sctlr(sctlr);
if (boot_cpu()) {
bootblock_cpu_init();
diff --git a/src/arch/armv7/include/arch/io.h b/src/arch/armv7/include/arch/io.h
index 3bbd529..623c305 100644
--- a/src/arch/armv7/include/arch/io.h
+++ b/src/arch/armv7/include/arch/io.h
@@ -21,6 +21,7 @@
#define __ASM_ARM_IO_H
#include <types.h>
+#include <arch/cache.h> /* for dmb() */
#include <arch/byteorder.h>
static inline void sync(void)
@@ -96,7 +97,7 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
* TODO: The kernel offers some more advanced versions of barriers, it might
* have some advantages to use them instead of the simple one here.
*/
-#define dmb() __asm__ __volatile__ ("" : : : "memory")
+//#define dmb() __asm__ __volatile__ ("" : : : "memory")
#define __iormb() dmb()
#define __iowmb() dmb()
diff --git a/src/arch/armv7/include/cache.h b/src/arch/armv7/include/cache.h
deleted file mode 100644
index cf8fb5a..0000000
--- a/src/arch/armv7/include/cache.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * (C) Copyright 2009
- * Marvell Semiconductor <www.marvell.com>
- * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#ifndef _ASM_CACHE_H
-#define _ASM_CACHE_H
-
-/*
- * Invalidate L2 Cache using co-proc instruction
- */
-static inline void invalidate_l2_cache(void)
-{
- unsigned int val=0;
-
- asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
- : : "r" (val) : "cc");
- isb();
-}
-
-void l2_cache_enable(void);
-void l2_cache_disable(void);
-
-/*
- * The current upper bound for ARM L1 data cache line sizes is 64 bytes. We
- * use that value for aligning DMA buffers unless the board config has specified
- * an alternate cache line size.
- */
-#ifdef CONFIG_SYS_CACHELINE_SIZE
-#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE
-#else
-#define ARCH_DMA_MINALIGN 64
-#endif
-
-inline void dram_bank_mmu_setup(unsigned long start, unsigned long size);
-
-#endif /* _ASM_CACHE_H */
diff --git a/src/arch/armv7/include/system.h b/src/arch/armv7/include/system.h
index 053df8d..d4e778d 100644
--- a/src/arch/armv7/include/system.h
+++ b/src/arch/armv7/include/system.h
@@ -43,13 +43,15 @@
*/
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
-#define isb() __asm__ __volatile__ ("" : : : "memory")
+/* FIXME: conflicts with new implementation in cache.c */
+//#define isb() __asm__ __volatile__ ("" : : : "memory")
#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
#define arch_align_stack(x) (x)
#ifndef __ASSEMBLER__
+#include <arch/cache.h> /* for isb() */
static inline unsigned int get_cr(void)
{
unsigned int val;
@@ -61,7 +63,7 @@ static inline void set_cr(unsigned int val)
{
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
: : "r" (val) : "cc");
- isb();
+ isb(); /* ref: B3.10.2 of ARM Arch Ref. Manual for ARMv7 */
}
/* options available for data cache on each page */
@@ -97,6 +99,8 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop);
void mmu_setup(unsigned long start, unsigned long size);
+void v7_inval_tlb(void);
+
void arm_init_before_mmu(void);
/*
diff --git a/src/arch/armv7/lib/Makefile.inc b/src/arch/armv7/lib/Makefile.inc
index 508f776..0741afa 100644
--- a/src/arch/armv7/lib/Makefile.inc
+++ b/src/arch/armv7/lib/Makefile.inc
@@ -1,8 +1,12 @@
+#FIXME: cache_v7 and cache-cp15 will go away eventually
+
bootblock-y += syslib.c
bootblock-$(CONFIG_EARLY_CONSOLE) += early_console.c
+bootblock-y += cache.c
bootblock-y += cache_v7.c
bootblock-y += cache-cp15.c
+romstage-y += cache.c
romstage-y += cache_v7.c
romstage-y += cache-cp15.c
romstage-y += div0.c
@@ -14,6 +18,8 @@ ramstage-y += div0.c
#ramstage-y += memcpy.S
#ramstage-y += memset.S
ramstage-y += syslib.c
+ramstage-y += cache.c
+ramstage-y += cache-cp15.c
ramstage-y += cache_v7.c
#FIXME(dhendrix): should this be a config option?
diff --git a/src/arch/armv7/lib/cache-cp15.c b/src/arch/armv7/lib/cache-cp15.c
index e08ea57..32f3c79 100644
--- a/src/arch/armv7/lib/cache-cp15.c
+++ b/src/arch/armv7/lib/cache-cp15.c
@@ -123,8 +123,7 @@ inline void mmu_setup(unsigned long start, unsigned long size_mb)
int i;
u32 reg;
- arm_init_before_mmu();
-
+// arm_init_before_mmu();
/* Set up an identity-mapping for all 4GB, rw for everyone */
for (i = 0; i < 4096; i++)
set_section_dcache(i, DCACHE_OFF);
diff --git a/src/arch/armv7/lib/cache_v7.c b/src/arch/armv7/lib/cache_v7.c
index 31072c7..1764351 100644
--- a/src/arch/armv7/lib/cache_v7.c
+++ b/src/arch/armv7/lib/cache_v7.c
@@ -226,7 +226,7 @@ static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op)
}
/* Invalidate TLB */
-static void v7_inval_tlb(void)
+void v7_inval_tlb(void)
{
/* Invalidate entire unified TLB */
asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
diff --git a/src/cpu/samsung/exynos5250/Makefile.inc b/src/cpu/samsung/exynos5250/Makefile.inc
index 2774b12..961b719 100644
--- a/src/cpu/samsung/exynos5250/Makefile.inc
+++ b/src/cpu/samsung/exynos5250/Makefile.inc
@@ -30,7 +30,6 @@ ramstage-y += power.c
ramstage-y += soc.c
ramstage-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c
ramstage-y += cpu.c
-ramstage-y += exynos_cache.c
#ramstage-$(CONFIG_SATA_AHCI) += sata.c
diff --git a/src/cpu/samsung/exynos5250/bootblock.c b/src/cpu/samsung/exynos5250/bootblock.c
index 949468f..4995dc2 100644
--- a/src/cpu/samsung/exynos5250/bootblock.c
+++ b/src/cpu/samsung/exynos5250/bootblock.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <armv7.h>
+
void bootblock_cpu_init(void);
void bootblock_cpu_init(void)
{
diff --git a/src/cpu/samsung/exynos5250/exynos_cache.c b/src/cpu/samsung/exynos5250/exynos_cache.c
index 7f4effe..87eded5 100644
--- a/src/cpu/samsung/exynos5250/exynos_cache.c
+++ b/src/cpu/samsung/exynos5250/exynos_cache.c
@@ -34,15 +34,11 @@ enum l2_cache_params {
};
-/* FIXME(dhendrix): maybe move this to a romstage-specific file? */
-#ifdef __PRE_RAM__
void enable_caches(void)
{
- /* Enable D-cache. I-cache is already enabled in start.S */
- /* can't use it anyway -- it has dependencies we have to fix. */
- //dcache_enable();
+ icache_enable(CONFIG_SYS_SDRAM_BASE, CONFIG_DRAM_SIZE_MB);
+ dcache_enable(CONFIG_SYS_SDRAM_BASE, CONFIG_DRAM_SIZE_MB);
}
-#endif
/*
* Set L2 cache parameters
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index e4d53cf..687f9b1 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -23,22 +23,10 @@
#include <cpu/samsung/exynos5250/clk.h>
#include <cpu/samsung/exynos5250/power.h>
-#include <system.h> /* FIXME: for testing cache */
-static void cp_delay(void)
-{
- volatile int i;
-
- /* copro seems to need some delay between reading and writing */
- for (i = 0; i < 100; i++)
- nop();
- asm volatile("" : : : "memory");
-}
-
static inline uint32_t read_clidr(void)
{
uint32_t val = 0;
asm volatile ("mrc p15, 1, %0, c0, c0, 1" : "=r" (val));
- isb();
return val;
}
@@ -46,7 +34,6 @@ static inline uint32_t read_ccsidr(void)
{
uint32_t val = 0;
asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (val));
- isb();
return val;
}
@@ -54,7 +41,6 @@ static inline uint32_t read_csselr(void)
{
uint32_t val = 0;
asm volatile ("mrc p15, 2, %0, c0, c0, 0" : "=r" (val));
- isb();
return val;
}
@@ -66,7 +52,6 @@ static inline void write_csselr(uint32_t val)
* Bit 0 - 0 = data or unified cache, 1 = instruction cache
*/
asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (val));
- isb();
}
#ifndef __mask
diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c
index ea2feec..c90be6e 100644
--- a/src/mainboard/google/snow/romstage.c
+++ b/src/mainboard/google/snow/romstage.c
@@ -18,12 +18,12 @@
*/
#include <types.h>
-#include <system.h>
-#include <cache.h>
+#include <armv7.h>
#include <cbfs.h>
#include <common.h>
+#include <arch/cache.h>
#include <arch/gpio.h>
#include <cpu/samsung/exynos5250/clk.h>
#include <cpu/samsung/exynos5250/dmc.h>
@@ -52,20 +52,6 @@ static int board_wakeup_permitted(void)
}
#endif
-/*
- * Set/clear program flow prediction and return the previous state.
- */
-static int config_branch_prediction(int set_cr_z)
-{
- unsigned int cr;
-
- /* System Control Register: 11th bit Z Branch prediction enable */
- cr = get_cr();
- set_cr(set_cr_z ? cr | CR_Z : cr & ~CR_Z);
-
- return cr & CR_Z;
-}
-
static void initialize_s5p_mshc(void)
{
/* MMC0: Fixed, 8 bit mode, connected with GPIO. */
@@ -95,12 +81,14 @@ void main(void)
int ret;
void *entry;
- /* FIXME: if we boot from USB, we need to disable branch prediction
- * before copying from USB into RAM */
- config_branch_prediction(1);
-
clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
+ /*
+ * FIXME: Do necessary I2C init so low-level PMIC code doesn't need to.
+ * Also, we should only call power_init() on cold boot.
+ */
+ power_init();
+
/* Clock must be initialized before console_init, otherwise you may need
* to re-initialize serial console drivers again. */
mem = get_mem_timings();
@@ -109,12 +97,6 @@ void main(void)
console_init();
- /*
- * FIXME: Do necessary I2C init so low-level PMIC code doesn't need to.
- * Also, we should only call power_init() on cold boot.
- */
- power_init();
-
if (!mem) {
printk(BIOS_CRIT, "Unable to auto-detect memory timings\n");
while(1);
@@ -132,7 +114,8 @@ void main(void)
while(1);
}
- mmu_setup(CONFIG_SYS_SDRAM_BASE, CONFIG_DRAM_SIZE_MB);
+ /* Set up MMU and caches */
+ mmu_setup_by_mva(CONFIG_SYS_SDRAM_BASE, CONFIG_DRAM_SIZE_MB);
initialize_s5p_mshc();
More information about the coreboot
mailing list