Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Dec 2014 18:38:26 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r276336 - in head/sys: arm/arm conf
Message-ID:  <201412281838.sBSIcQPc004550@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sun Dec 28 18:38:25 2014
New Revision: 276336
URL: https://svnweb.freebsd.org/changeset/base/276336

Log:
  Add cache maintenance functions which will be used by startup code to
  initially set up the MMU.  Some day they may also be useful as part of
  suspend/resume handling, when we get better at power management.
  
  Submitted by: Svatopluk Kraus <onwahe@gmail.com>,
                Michal Meloun <meloun@miracle.cz

Added:
  head/sys/arm/arm/cpu_asm-v6.S   (contents, props changed)
Modified:
  head/sys/conf/files.arm

Added: head/sys/arm/arm/cpu_asm-v6.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/arm/cpu_asm-v6.S	Sun Dec 28 18:38:25 2014	(r276336)
@@ -0,0 +1,200 @@
+/*-
+ * Copyright 2014 Svatopluk Kraus <onwahe@gmail.com>
+ * Copyright 2014 Michal Meloun <meloun@miracle.cz>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/acle-compat.h>
+#include <machine/asm.h>
+#include <machine/asmacros.h>
+#include <machine/armreg.h>
+#include <machine/sysreg.h>
+
+#if __ARM_ARCH >= 7
+
+/* 
+ * Define cache functions used by startup code, which counts on the fact that
+ * only r0-r4,r12 (ip) are modified and no stack space is used. This set
+ * of function must be called with interrupts disabled and don't follow
+ * ARM ABI (cannot be called form C code.
+ * Moreover, it works only with caches integrated to CPU (accessible via CP15).
+ */
+
+/* Invalidate D cache to PoC. (aka all cache levels)*/
+ASENTRY(dcache_inv_poc_all)
+	mrc	CP15_CLIDR(r0)
+	ands	r0, r0, #0x07000000
+	mov	r0, r0, lsr #23		/* Get LoC (naturally aligned) */
+	beq	4f
+
+1:	mcr	CP15_CSSELR(r0)		/* set cache level */
+	isb
+	mrc	CP15_CCSIDR(r0)		/* read CCSIDR */
+
+	ubfx	r2, r0, #13, #15	/* get num sets - 1 from CCSIDR */
+	ubfx	r3, r0, #3, #10		/* get num ways - 1 from CCSIDR */
+	clz	r1, r3			/* number of bits to MSB of way */
+	lsl	r3, r3, r1		/* shift into position  */
+	mov	ip, #1
+	lsl	ip, ip, r1		/* ip now contains the way decr  */
+
+	ubfx	r0, r0, #0, #3		/* get linesize from CCSIDR  */
+	add	r0, r0, #4		/* apply bias  */
+	lsl	r2, r2, r0		/* shift sets by log2(linesize)  */
+	add	r3, r3, r2		/* merge numsets - 1 with numways - 1 */
+	sub	ip, ip, r2		/* subtract numsets - 1 from way decr */
+	mov	r1, #1
+	lsl	r1, r1, r0		/* r1 now contains the set decr */
+	mov	r2, ip			/* r2 now contains set way decr */
+
+	/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
+2:	mcr	CP15_DCISW(r3)		/* invalidate line */
+	movs	r0, r3			/* get current way/set */
+	beq	3f			/* at 0 means we are done */
+	movs	r0, r0, lsl #10		/* clear way 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	2b
+
+3:
+	mrc	CP15_CSSELR(r0)		/* get cache level */
+	add	r0, r0, #2		/* next level */
+	mrc	CP15_CLIDR(r1)
+	ands	r1, r1, #0x07000000
+	mov	r1, r1, lsr #23		/* Get LoC (naturally aligned) */
+	cmp 	r1, r0
+	bgt	1b
+
+4:	dsb				/* wait for stores to finish */
+	mov	r0, #0
+	mcr	CP15_CSSELR(r0)
+	isb
+	bx	lr
+END(dcache_inv_poc_all)
+
+/* Invalidate D cache to PoU. (aka L1 cache only)*/
+ASENTRY(dcache_inv_pou_all)
+	mrc	CP15_CLIDR(r0)
+	ands	r0, r0, #0x07000000
+	mov	r0, r0, lsr #26		/* Get LoUU (naturally aligned) */
+	beq	4f
+
+1:	mcr	CP15_CSSELR(r0)		/* set cache level */
+	isb
+	mrc	CP15_CCSIDR(r0)		/* read CCSIDR */
+
+	ubfx	r2, r0, #13, #15	/* get num sets - 1 from CCSIDR */
+	ubfx	r3, r0, #3, #10		/* get num ways - 1 from CCSIDR */
+	clz	r1, r3			/* number of bits to MSB of way */
+	lsl	r3, r3, r1		/* shift into position  */
+	mov	ip, #1
+	lsl	ip, ip, r1		/* ip now contains the way decr  */
+
+	ubfx	r0, r0, #0, #3		/* get linesize from CCSIDR  */
+	add	r0, r0, #4		/* apply bias  */
+	lsl	r2, r2, r0		/* shift sets by log2(linesize)  */
+	add	r3, r3, r2		/* merge numsets - 1 with numways - 1 */
+	sub	ip, ip, r2		/* subtract numsets - 1 from way decr */
+	mov	r1, #1
+	lsl	r1, r1, r0		/* r1 now contains the set decr */
+	mov	r2, ip			/* r2 now contains set way decr */
+
+	/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
+2:	mcr	CP15_DCISW(r3)		/* clean & invalidate line */
+	movs	r0, r3			/* get current way/set */
+	beq	3f			/* at 0 means we are done */
+	movs	r0, r0, lsl #10		/* clear way 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	2b
+
+3:
+	mrc	CP15_CSSELR(r0)		/* get cache level */
+	add	r0, r0, #2		/* next level */
+	mrc	CP15_CLIDR(r1)
+	ands	r1, r1, #0x07000000
+	mov	r1, r1, lsr #26		/* Get LoUU (naturally aligned) */
+	cmp 	r1, r0
+	bgt	1b
+
+4:	dsb				/* wait for stores to finish */
+	mov	r0, #0
+	mcr	CP15_CSSELR(r0)
+	bx	lr
+END(dcache_inv_pou_all)
+
+/* Write back and Invalidate D cache to PoC. */
+ASENTRY(dcache_wbinv_poc_all)
+	mrc	CP15_CLIDR(r0)
+	ands	r0, r0, #0x07000000
+	mov	r0, r0, lsr #23		/* Get LoC (naturally aligned) */
+	beq	4f
+
+1:	mcr	CP15_CSSELR(r0)		/* set cache level */
+	isb
+	mrc	CP15_CCSIDR(r0)		/* read CCSIDR */
+
+	ubfx	r2, r0, #13, #15	/* get num sets - 1 from CCSIDR */
+	ubfx	r3, r0, #3, #10		/* get num ways - 1 from CCSIDR */
+	clz	r1, r3			/* number of bits to MSB of way */
+	lsl	r3, r3, r1		/* shift into position  */
+	mov	ip, #1
+	lsl	ip, ip, r1		/* ip now contains the way decr  */
+
+	ubfx	r0, r0, #0, #3		/* get linesize from CCSIDR  */
+	add	r0, r0, #4		/* apply bias  */
+	lsl	r2, r2, r0		/* shift sets by log2(linesize)  */
+	add	r3, r3, r2		/* merge numsets - 1 with numways - 1 */
+	sub	ip, ip, r2		/* subtract numsets - 1 from way decr */
+	mov	r1, #1
+	lsl	r1, r1, r0		/* r1 now contains the set decr */
+	mov	r2, ip			/* r2 now contains set way decr */
+
+	/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
+2:	mcr	CP15_DCCISW(r3)		/* clean & invalidate line */
+	movs	r0, r3			/* get current way/set */
+	beq	3f			/* at 0 means we are done */
+	movs	r0, r0, lsl #10		/* clear way 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	2b
+
+3:
+	mrc	CP15_CSSELR(r0)		/* get cache level */
+	add	r0, r0, #2		/* next level */
+	mrc	CP15_CLIDR(r1)
+	ands	r1, r1, #0x07000000
+	mov	r1, r1, lsr #23		/* Get LoC (naturally aligned) */
+	cmp 	r1, r0
+	bgt	1b
+
+4:	dsb				/* wait for stores to finish */
+	mov	r0, #0
+	mcr	CP15_CSSELR(r0)
+	bx	lr
+END(dcache_wbinv_poc_all)
+
+#endif /* __ARM_ARCH >= 7 */

Modified: head/sys/conf/files.arm
==============================================================================
--- head/sys/conf/files.arm	Sun Dec 28 18:26:15 2014	(r276335)
+++ head/sys/conf/files.arm	Sun Dec 28 18:38:25 2014	(r276336)
@@ -12,6 +12,7 @@ arm/arm/cpufunc.c		standard
 arm/arm/cpufunc_asm.S		standard
 arm/arm/cpufunc_asm_armv4.S 	standard
 arm/arm/cpuinfo.c		standard
+arm/arm/cpu_asm-v6.S		optional	armv6
 arm/arm/db_disasm.c		optional	ddb
 arm/arm/db_interface.c		optional	ddb
 arm/arm/db_trace.c		optional	ddb



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412281838.sBSIcQPc004550>