[U-Boot] [PATCH 7/8] armv7: adapt omap3 to the new cache maintenance framework

Aneesh V aneesh at ti.com
Wed Dec 22 12:54:57 CET 2010


adapt omap3 to the new layered cache maintenance framework

Signed-off-by: Aneesh V <aneesh at ti.com>
---
 arch/arm/cpu/armv7/omap3/Makefile           |    1 -
 arch/arm/cpu/armv7/omap3/board.c            |  151 ++++++++++++++--
 arch/arm/cpu/armv7/omap3/cache.S            |  263 ---------------------------
 arch/arm/cpu/armv7/omap3/lowlevel_init.S    |   30 +++
 arch/arm/include/asm/arch-omap3/omap3.h     |   20 ++
 arch/arm/include/asm/arch-omap3/sys_proto.h |   10 +-
 6 files changed, 190 insertions(+), 285 deletions(-)
 delete mode 100644 arch/arm/cpu/armv7/omap3/cache.S

diff --git a/arch/arm/cpu/armv7/omap3/Makefile b/arch/arm/cpu/armv7/omap3/Makefile
index 7164d50..522bcd2 100644
--- a/arch/arm/cpu/armv7/omap3/Makefile
+++ b/arch/arm/cpu/armv7/omap3/Makefile
@@ -26,7 +26,6 @@ include $(TOPDIR)/config.mk
 LIB	=  $(obj)lib$(SOC).o
 
 SOBJS	:= lowlevel_init.o
-SOBJS	+= cache.o
 
 COBJS	+= board.o
 COBJS	+= clock.o
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index 6c2a132..ea7ac3e 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -37,8 +37,12 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/mem.h>
 #include <asm/cache.h>
+#include <asm/armv7.h>
 
+/* Declarations */
 extern omap3_sysinfo sysinfo;
+static void omap3_setup_aux_cr(void);
+static void omap3_invalidate_l2_cache_secure(void);
 
 /******************************************************************************
  * Routine: delay
@@ -166,27 +170,15 @@ void s_init(void)
 
 	try_unlock_memory();
 
-	/*
-	 * Right now flushing at low MPU speed.
-	 * Need to move after clock init
-	 */
-	invalidate_dcache(get_device_type());
-#ifndef CONFIG_ICACHE_OFF
-	icache_enable();
-#endif
+	/* Errata workarounds */
+	omap3_setup_aux_cr();
 
-#ifdef CONFIG_L2_OFF
-	l2_cache_disable();
-#else
-	l2_cache_enable();
-#endif
+#ifndef CONFIG_L2_OFF
 	/*
-	 * Writing to AuxCR in U-boot using SMI for GP DEV
-	 * Currently SMI in Kernel on ES2 devices seems to have an issue
-	 * Once that is resolved, we can postpone this config to kernel
+	 * Invalidate L2-cache from secure mode
 	 */
-	if (get_device_type() == GP_DEVICE)
-		setup_auxcr();
+	omap3_invalidate_l2_cache_secure();
+#endif
 
 	set_muxconf_regs();
 	delay(100);
@@ -292,3 +284,126 @@ int checkboard (void)
 	return 0;
 }
 #endif	/* CONFIG_DISPLAY_BOARDINFO */
+
+static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
+{
+	u32 i, num_params = *parameters;
+	u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
+	/*
+	 * copy the parameters to an un-cached area to avoid coherency
+	 * issues
+	 */
+	for (i = 0; i < num_params; i++) {
+		__raw_writel(*parameters, sram_scratch_space);
+		parameters++;
+		sram_scratch_space++;
+	}
+	/* Now make the PPA call */
+	do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA);
+}
+
+static void omap3_update_aux_cr_secure(u32 set_bits, u32 clear_bits)
+{
+	u32 acr;
+	/* Read ACR */
+	asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
+	acr &= ~clear_bits;
+	acr |= set_bits;
+
+	if (get_device_type() == GP_DEVICE) {
+		omap3_gp_romcode_call(OMAP3_GP_ROMCODE_API_WRITE_ACR,
+				       acr);
+	} else {
+		struct emu_hal_params emu_romcode_params;
+		emu_romcode_params.num_params = 1;
+		emu_romcode_params.param1 = acr;
+		omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
+				       (u32 *)&emu_romcode_params);
+	}
+}
+
+static void omap3_update_aux_cr(u32 set_bits, u32 clear_bits)
+{
+	u32 acr;
+	/* Read ACR */
+	asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
+	acr &= ~clear_bits;
+	acr |= set_bits;
+	/* Write ACR - affects non-secure banked bits */
+	asm volatile ("mcr p15, 0, %0, c1, c0, 1" : : "r" (acr));
+}
+
+static void omap3_setup_aux_cr(void)
+{
+	/* Workaround for Cortex-A8 errata: #454179 #430973
+	 *	Set "IBE" bit
+	 *	Set "Disable Brach Size Mispredicts" bit
+	 * Workaround for erratum #621766
+	 *	Enable L1NEON bit
+	 * ACR |= (IBE | DBSM | L1NEON) => ACR |= 0xE0
+	 */
+	omap3_update_aux_cr_secure(0xE0, 0);
+}
+
+#ifndef CONFIG_L2_OFF
+/*
+ * Invalidate the entire L2 cache from secure mode
+ * This affects secure entries. Please note that this is needed only
+ * once. After this the regular CP15 based maintenance operations(that
+ * affects only non-secure entries) is enough.
+ * It's assumed that this function is called before D-cache is enabled.
+ * Otherwise there could be coherency issues between secure and
+ * non-secure sw especially in case of EMU where arguments in memory are
+ * passed
+ */
+static void omap3_invalidate_l2_cache_secure(void)
+{
+	if (get_device_type() == GP_DEVICE) {
+		omap3_gp_romcode_call(OMAP3_GP_ROMCODE_API_L2_INVAL,
+				      0);
+	} else {
+		struct emu_hal_params emu_romcode_params;
+		emu_romcode_params.num_params = 1;
+		emu_romcode_params.param1 = 0;
+		omap3_emu_romcode_call(OMAP3_EMU_HAL_API_L2_INVAL,
+				       (u32 *)&emu_romcode_params);
+	}
+}
+
+static void omap3_enable_l2_cache(void)
+{
+	/* Set L2EN */
+	omap3_update_aux_cr_secure(0x2, 0);
+	/*
+	 * On some revisions L2EN bit is banked on some revisions it's not
+	 * No harm in setting both banked bits(in fact this is required
+	 * by an erratum)
+	 */
+	omap3_update_aux_cr(0x2, 0);
+}
+
+static void omap3_disable_l2_cache(void)
+{
+	/* Clear L2EN */
+	omap3_update_aux_cr_secure(0, 0x2);
+	/*
+	 * On some revisions L2EN bit is banked on some revisions it's not
+	 * No harm in setting both banked bits(in fact this is required
+	 * by an erratum)
+	 */
+	omap3_update_aux_cr(0, 0x2);
+}
+#endif /* CONFIG_L2_OFF */
+
+void v7_setup_outer_cache_ops(void)
+{
+	/*
+	 * In OMAP3 L2 cache maintenance is done through CP15.
+	 * Only enabling disabling needs ROM code support and
+	 * is OMAP specific.
+	 */
+#ifndef CONFIG_L2_OFF
+	v7_outer_cache.enable = omap3_enable_l2_cache;
+	v7_outer_cache.disable = omap3_disable_l2_cache;
+#endif
+}
diff --git a/arch/arm/cpu/armv7/omap3/cache.S b/arch/arm/cpu/armv7/omap3/cache.S
deleted file mode 100644
index cda87ba..0000000
--- a/arch/arm/cpu/armv7/omap3/cache.S
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2009 Wind River Systems, Inc.
- * Tom Rix <Tom.Rix at windriver.com>
- *
- * This file is based on and replaces the existing cache.c file
- * The copyrights for the cache.c file are:
- *
- * (C) Copyright 2008 Texas Insturments
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger at sysgo.de>
- *
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <gj at denx.de>
- *
- * 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., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <asm/arch/omap3.h>
-
-/*
- * omap3 cache code
- */
-
-.align 5
-.global invalidate_dcache
-.global l2_cache_enable
-.global l2_cache_disable
-.global setup_auxcr
-
-/*
- *	invalidate_dcache()
- *
- *	Invalidate the whole D-cache.
- *
- *	Corrupted registers: r0-r5, r7, r9-r11
- *
- *	- mm	- mm_struct describing address space
- */
-invalidate_dcache:
-	stmfd	r13!, {r0 - r5, r7, r9 - r12, r14}
-
-	mov	r7, r0				@ take a backup of device type
-	cmp	r0, #0x3			@ check if the device type is
-						@ GP
-	moveq r12, #0x1				@ set up to invalide L2
-smi:	.word 0x01600070			@ Call SMI monitor (smieq)
-	cmp	r7, #0x3			@ compare again in case its
-						@ lost
-	beq	finished_inval			@ if GP device, inval done
-						@ above
-
-	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
-	ands	r3, r0, #0x7000000		@ extract loc from clidr
-	mov	r3, r3, lsr #23			@ left align loc bit field
-	beq	finished_inval			@ if loc is 0, then no need to
-						@ clean
-	mov	r10, #0				@ start clean at cache level 0
-inval_loop1:
-	add	r2, r10, r10, lsr #1		@ work out 3x current cache
-						@ level
-	mov	r1, r0, lsr r2			@ extract cache type bits from
-						@ clidr
-	and	r1, r1, #7			@ mask of the bits for current
-						@ cache only
-	cmp	r1, #2				@ see what cache we have at
-						@ this level
-	blt	skip_inval			@ skip if no cache, or just
-						@ i-cache
-	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level
-						@ in cssr
-	mov	r2, #0				@ operand for mcr SBZ
-	mcr	p15, 0, r2, c7, c5, 4		@ flush prefetch buffer to
-						@ sych the new cssr&csidr,
-						@ with armv7 this is 'isb',
-						@ but we compile with armv5
-	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
-	and	r2, r1, #7			@ extract the length of the
-						@ cache lines
-	add	r2, r2, #4			@ add 4 (line length offset)
-	ldr	r4, =0x3ff
-	ands	r4, r4, r1, lsr #3		@ find maximum number on the
-						@ way size
-	clz	r5, r4				@ find bit position of way
-						@ size increment
-	ldr	r7, =0x7fff
-	ands	r7, r7, r1, lsr #13		@ extract max number of the
-						@ index size
-inval_loop2:
-	mov	r9, r4				@ create working copy of max
-						@ way size
-inval_loop3:
-	orr	r11, r10, r9, lsl r5		@ factor way and cache number
-						@ into r11
-	orr	r11, r11, r7, lsl r2		@ factor index number into r11
-	mcr	p15, 0, r11, c7, c6, 2		@ invalidate by set/way
-	subs	r9, r9, #1			@ decrement the way
-	bge	inval_loop3
-	subs	r7, r7, #1			@ decrement the index
-	bge	inval_loop2
-skip_inval:
-	add	r10, r10, #2			@ increment cache number
-	cmp	r3, r10
-	bgt	inval_loop1
-finished_inval:
-	mov	r10, #0				@ swith back to cache level 0
-	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level
-						@ in cssr
-	mcr	p15, 0, r10, c7, c5, 4		@ flush prefetch buffer,
-						@ with armv7 this is 'isb',
-						@ but we compile with armv5
-
-	ldmfd	r13!, {r0 - r5, r7, r9 - r12, pc}
-
-l2_cache_set:
-	stmfd	r13!, {r4 - r6, lr}
-	mov	r5,  r0
-	bl	get_cpu_rev
-	mov	r4,  r0
-	bl	get_cpu_family
-	@ ES2 onwards we can disable/enable L2 ourselves
-	cmp	r0,  #CPU_OMAP34XX
-	cmpeq	r4,  #CPU_3XX_ES10
-	mrc	15, 0, r0, cr1, cr0, 1
-	bic	r0, r0, #2
-	orr	r0, r0, r5, lsl #1
-	mcreq	15, 0, r0, cr1, cr0, 1
-	@ GP Device ROM code API usage here
-	@ r12 = AUXCR Write function and r0 value
-	mov	ip, #3
-	@ SMCNE instruction to call ROM Code API
-	.word	0x11600070
-	ldmfd	r13!, {r4 - r6, pc}
-
-l2_cache_enable:
-	mov	r0, #1
-	b	l2_cache_set
-
-l2_cache_disable:
-	mov	r0, #0
-	b	l2_cache_set
-
-/******************************************************************************
- * Routine: setup_auxcr()
- * Description: Write to AuxCR desired value using SMI.
- *              general use.
- *****************************************************************************/
-setup_auxcr:
-	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register
-	and	r2, r0, #0x00f00000		@ variant
-	and	r3, r0, #0x0000000f		@ revision
-	orr	r1, r3, r2, lsr #20-4		@ combine variant and revision
-	mov	r12, #0x3
-	mrc	p15, 0, r0, c1, c0, 1
-	orr	r0, r0, #0x10			@ Enable ASA
-	@ Enable L1NEON on pre-r2p1 (erratum 621766 workaround)
-	cmp	r1, #0x21
-	orrlt	r0, r0, #1 << 5
-	.word 0xE1600070			@ SMC
-	mov	r12, #0x2
-	mrc	p15, 1, r0, c9, c0, 2
-	@ Set PLD_FWD bit in L2AUXCR on pre-r2p1 (erratum 725233 workaround)
-	cmp	r1, #0x21
-	orrlt	r0, r0, #1 << 27
-	.word 0xE1600070			@ SMC
-	bx	lr
-
-.align 5
-.global v7_flush_dcache_all
-.global v7_flush_cache_all
-
-/*
- *	v7_flush_dcache_all()
- *
- *	Flush the whole D-cache.
- *
- *	Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
- *
- *	- mm    - mm_struct describing address space
- */
-v7_flush_dcache_all:
-#	dmb					@ ensure ordering with previous memory accesses
-	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
-	ands	r3, r0, #0x7000000		@ extract loc from clidr
-	mov	r3, r3, lsr #23			@ left align loc bit field
-	beq	finished			@ if loc is 0, then no need to clean
-	mov	r10, #0				@ start clean at cache level 0
-loop1:
-	add	r2, r10, r10, lsr #1		@ work out 3x current cache level
-	mov	r1, r0, lsr r2			@ extract cache type bits from clidr
-	and	r1, r1, #7			@ mask of the bits for current cache only
-	cmp	r1, #2				@ see what cache we have at this level
-	blt	skip				@ skip if no cache, or just i-cache
-	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
-	mcr	p15, 0, r10, c7, c5, 4		@ flush prefetch buffer,
-						@ with armv7 this is 'isb',
-						@ but we compile with armv5
-	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
-	and	r2, r1, #7			@ extract the length of the cache lines
-	add	r2, r2, #4			@ add 4 (line length offset)
-	ldr	r4, =0x3ff
-	ands	r4, r4, r1, lsr #3		@ find maximum number on the way size
-	clz	r5, r4				@ find bit position of way size increment
-	ldr	r7, =0x7fff
-	ands	r7, r7, r1, lsr #13		@ extract max number of the index size
-loop2:
-	mov	r9, r4				@ create working copy of max way size
-loop3:
-	orr	r11, r10, r9, lsl r5		@ factor way and cache number into r11
-	orr	r11, r11, r7, lsl r2		@ factor index number into r11
-	mcr	p15, 0, r11, c7, c14, 2		@ clean & invalidate by set/way
-	subs	r9, r9, #1			@ decrement the way
-	bge	loop3
-	subs	r7, r7, #1			@ decrement the index
-	bge	loop2
-skip:
-	add	r10, r10, #2			@ increment cache number
-	cmp	r3, r10
-	bgt	loop1
-finished:
-	mov	r10, #0				@ swith back to cache level 0
-	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
-#	dsb
-	mcr	p15, 0, r10, c7, c5, 4		@ flush prefetch buffer,
-						@ with armv7 this is 'isb',
-						@ but we compile with armv5
-	mov	pc, lr
-
-/*
- *	v7_flush_cache_all()
- *
- *	Flush the entire cache system.
- *  The data cache flush is now achieved using atomic clean / invalidates
- *  working outwards from L1 cache. This is done using Set/Way based cache
- *  maintainance instructions.
- *  The instruction cache can still be invalidated back to the point of
- *  unification in a single instruction.
- *
- */
-v7_flush_cache_all:
-	stmfd	sp!, {r0-r7, r9-r11, lr}
-	bl	v7_flush_dcache_all
-	mov	r0, #0
-	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
-	ldmfd	sp!, {r0-r7, r9-r11, lr}
-	mov	pc, lr
diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
index 109481e..c2feeff 100644
--- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
@@ -35,6 +35,36 @@
 _TEXT_BASE:
 	.word	CONFIG_SYS_TEXT_BASE	/* sdram load addr from config.mk */
 
+.global omap3_gp_romcode_call
+omap3_gp_romcode_call:
+	PUSH {r4-r12, lr} @ Save all registers from ROM code!
+	MOV r12, r0	@ Copy the Service ID in R12
+	MOV r0, r1	@ Copy parameter to R0
+	DSB
+	DMB
+	SMC #0		@ Use the SMI #1 to enter Monitor
+	POP {r4-r12, pc}
+
+/*
+ * Funtion for making PPA HAL API calls in secure devices
+ * Input:
+ *	R0 - Service ID
+ *	R1 - paramer list
+ */
+.global do_omap3_emu_romcode_call
+do_omap3_emu_romcode_call:
+	PUSH {r4-r12, lr} @ Save all registers from ROM code!
+	MOV r12, r0	@ Copy the Secure Service ID in R12
+	MOV r3, r1	@ Copy the pointer to va_list in R3
+	MOV r1, #0	@ Process ID - 0
+	MOV r2, #OMAP3_EMU_HAL_START_HAL_CRITICAL	@ Copy the pointer
+							@ to va_list in R3
+	MOV r6, #0xFF	@ Indicate new Task call
+	DSB
+	DMB
+	SMC #1		@ Use the SMI #1 to enter Monitor
+	POP {r4-r12, pc}
+
 #if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT)
 /**************************************************************************
  * cpy_clk_code: relocates clock code into SRAM where its safer to execute
diff --git a/arch/arm/include/asm/arch-omap3/omap3.h b/arch/arm/include/asm/arch-omap3/omap3.h
index 3957c79..7b861a3 100644
--- a/arch/arm/include/asm/arch-omap3/omap3.h
+++ b/arch/arm/include/asm/arch-omap3/omap3.h
@@ -145,8 +145,14 @@ struct gpio {
 #define SRAM_VECT_CODE			(SRAM_OFFSET0 | SRAM_OFFSET1 | \
 					 SRAM_OFFSET2)
 
+#define OMAP3_PUBLIC_SRAM_BASE		0x40208000 /* Works for GP & EMU */
+#define OMAP3_PUBLIC_SRAM_END		0x40210000
+
 #define LOW_LEVEL_SRAM_STACK		0x4020FFFC
 
+/* scratch area - accessible on both EMU and GP */
+#define OMAP3_PUBLIC_SRAM_SCRATCH_AREA	OMAP3_PUBLIC_SRAM_BASE
+
 #define DEBUG_LED1			149	/* gpio */
 #define DEBUG_LED2			150	/* gpio */
 
@@ -213,4 +219,18 @@ struct gpio {
 
 #define OMAP3730		0x0c00
 
+/*
+ * ROM code API related flags
+ */
+#define OMAP3_GP_ROMCODE_API_L2_INVAL		1
+#define OMAP3_GP_ROMCODE_API_WRITE_ACR		3
+
+/*
+ * EMU device PPA HAL related flags
+ */
+#define OMAP3_EMU_HAL_API_L2_INVAL		40
+#define OMAP3_EMU_HAL_API_WRITE_ACR		42
+
+#define OMAP3_EMU_HAL_START_HAL_CRITICAL	4
+
 #endif
diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h
index 4a28ba1..25f54ea 100644
--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
@@ -27,6 +27,11 @@ typedef struct {
 	char *nand_string;
 } omap3_sysinfo;
 
+struct __attribute__ ((__packed__)) emu_hal_params {
+	u32 num_params;
+	u32 param1;
+};
+
 void prcm_init(void);
 void per_clocks_enable(void);
 
@@ -53,9 +58,7 @@ u32 is_running_in_sdram(void);
 u32 is_running_in_sram(void);
 u32 is_running_in_flash(void);
 u32 get_device_type(void);
-void l2cache_enable(void);
 void secureworld_exit(void);
-void setup_auxcr(void);
 void try_unlock_memory(void);
 u32 get_boot_type(void);
 void invalidate_dcache(u32);
@@ -66,5 +69,6 @@ void make_cs1_contiguous(void);
 void omap_nand_switch_ecc(int);
 void power_init_r(void);
 void dieid_num_r(void);
-
+void do_omap3_emu_romcode_call(u32 service_id, u32 parameters);
+void omap3_gp_romcode_call(u32 service_id, u32 parameter);
 #endif
-- 
1.7.0.4



More information about the U-Boot mailing list