[coreboot-gerrit] Patch set updated for coreboot: aa2eb43 arm: Import armv7_dcache_wbinv_all function from NetBSD

Isaac Christensen (isaac.christensen@se-eng.com) gerrit at coreboot.org
Wed Sep 24 23:41:39 CEST 2014


Isaac Christensen (isaac.christensen at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6931

-gerrit

commit aa2eb4347c4a19458a5e33429c064d49b7171085
Author: Julius Werner <jwerner at chromium.org>
Date:   Mon Jan 13 11:13:23 2014 -0800

    arm: Import armv7_dcache_wbinv_all function from NetBSD
    
    This patch pulls in NetBSD's full cache flushing algorithm for ARM, to
    replace our old, slow and slightly overzealous C-only implementation.
    It's a beautiful piece of code that manages to run on only caller-saved
    registers (meaning it doesn't need to write to memory) in a very tight
    loop, and it's BSD-licensed to boot (which we need for libpayload).
    Unfortunately it's also not quite correct, but I can fix that. Pulling
    the original in a separate commit to make it more obvious what changes
    are mine.
    
    Change-Id: I7a71c9e570866a6e25f756cb09ae2b6445048d83
    Signed-off-by: Julius Werner <jwerner at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/183878
    Reviewed-by: Stefan Reinauer <reinauer at google.com>
    Reviewed-by: Vincent Palatin <vpalatin at chromium.org>
    Reviewed-by: David Hendricks <dhendrix at chromium.org>
    (cherry picked from commit 4698467320613d7ddc39714f40aacbc990af9399)
    Signed-off-by: Isaac Christensen <isaac.christensen at se-eng.com>
---
 src/arch/arm/armv7/cpu.S | 99 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/src/arch/arm/armv7/cpu.S b/src/arch/arm/armv7/cpu.S
new file mode 100644
index 0000000..42e2354
--- /dev/null
+++ b/src/arch/arm/armv7/cpu.S
@@ -0,0 +1,99 @@
+/*
+ * Optimized assembly for low-level CPU operations on ARMv7 processors.
+ *
+ * Cache flushing code based off sys/arch/arm/arm/cpufunc_asm_armv7.S in NetBSD
+ *
+ * Copyright (c) 2010 Per Odlund <per.odlund at armagedon.se>
+ * Copyright (c) 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * These work very hard to not push registers onto the stack and to limit themselves
+ * to use r0-r3 and ip.
+ */
+
+/* * LINTSTUB: void armv7_dcache_wbinv_all(void); */
+ENTRY_NP(armv7_dcache_wbinv_all)
+	mrc	p15, 1, r0, c0, c0, 1	@ read CLIDR
+	ands	r3, r0, #0x07000000
+	beq	.Ldone_wbinv
+	lsr	r3, r3, #23		@ left align loc (low 4 bits)
+
+	mov	r1, #0
+.Lstart_wbinv:
+	add	r2, r3, r3, lsr #1	@ r2 = level * 3 / 2
+	mov	r1, r0, lsr r2		@ r1 = cache type
+	bfc	r1, #3, #28
+	cmp	r1, #2			@ is it data or i&d?
+	blt	.Lnext_level_wbinv	@ nope, skip level
+
+	mcr	p15, 2, r3, c0, c0, 0	@ select cache level
+	isb
+	mrc	p15, 1, r0, c0, c0, 0	@ read CCSIDR
+
+	ubfx	ip, r0, #0, #3		@ get linesize from CCSIDR
+	add	ip, ip, #4		@ apply bias
+	ubfx	r2, r0, #13, #15	@ get numsets - 1 from CCSIDR
+	lsl	r2, r2, ip		@ shift to set position
+	orr	r3, r3, r2		@ merge set into way/set/level
+	mov	r1, #1
+	lsl	r1, r1, ip		@ r1 = set decr
+
+	ubfx	ip, r0, #3, #10		@ get numways - 1 from [to be discarded] CCSIDR
+	clz	r2, ip			@ number of bits to MSB of way
+	lsl	ip, ip, r2		@ shift by that into way position
+	mov	r0, #1			@
+	lsl	r2, r0, r2		@ r2 now contains the way decr
+	mov	r0, r3 			@ get sets/level (no way yet)
+	orr	r3, r3, ip		@ merge way into way/set/level
+	bfc	r0, #0, #4		@ clear low 4 bits (level) to get numset - 1
+	sub	r2, r2, r0		@ subtract from way decr
+
+	/* r3 = ways/sets/level, r2 = way decr, r1 = set decr, r0 and ip are free */
+1:	mcr	p15, 0, r3, c7, c14, 2	@ writeback and invalidate line
+	cmp	r3, #15			@ are we done with this level (way/set == 0)
+	bls	.Lnext_level_wbinv	@ yes, go to next level
+	lsl	r0, r3, #10		@ clear way bits leaving only set/level bits
+	lsr	r0, r0, #4		@ clear level bits leaving only set bits
+	subne	r3, r3, r1		@ non-zero?, decrement set #
+	subeq	r3, r3, r2		@ zero?, decrement way # and restore set count
+	b	1b
+
+.Lnext_level_wbinv:
+	mrc	p15, 1, r0, c0, c0, 1	@ read CLIDR
+	and	ip, r0, #0x07000000	@ narrow to LoC
+	lsr	ip, ip, #23		@ left align LoC (low 4 bits)
+	add	r3, r3, #2		@ go to next level
+	cmp	r3, ip			@ compare
+	blt	.Lstart_wbinv		@ not done, next level (r0 == CLIDR)
+
+.Ldone_wbinv:
+	mov	r0, #0			@ default back to cache level 0
+	mcr	p15, 2, r0, c0, c0, 0	@ select cache level
+	dsb
+	isb
+	bx	lr
+END(armv7_dcache_wbinv_all)



More information about the coreboot-gerrit mailing list