Module Name:    src
Committed By:   matt
Date:           Wed Aug 29 07:09:13 UTC 2012

Modified Files:
        src/sys/arch/arm/arm32: genassym.cf vm_machdep.c
        src/sys/arch/arm/include/arm32: frame.h

Log Message:
Use ARMV6+ cpsi{d,f} instructions whenever possible.  Use r7 to hold previous
mode and avoid recomputing it.  Add support for obtaining kernel_lock on
exception entry and exit.


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/arm/arm32/genassym.cf
cvs rdiff -u -r1.59 -r1.60 src/sys/arch/arm/arm32/vm_machdep.c
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/arm/include/arm32/frame.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/arm32/genassym.cf
diff -u src/sys/arch/arm/arm32/genassym.cf:1.49 src/sys/arch/arm/arm32/genassym.cf:1.50
--- src/sys/arch/arm/arm32/genassym.cf:1.49	Thu Aug 16 17:35:01 2012
+++ src/sys/arch/arm/arm32/genassym.cf	Wed Aug 29 07:09:12 2012
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.49 2012/08/16 17:35:01 matt Exp $
+#	$NetBSD: genassym.cf,v 1.50 2012/08/29 07:09:12 matt Exp $
 
 # Copyright (c) 1982, 1990 The Regents of the University of California.
 # All rights reserved.
@@ -140,6 +140,7 @@ define	PR_SCALE		offsetof(struct uprof, 
 define	SIGTRAP			SIGTRAP
 define	SIGEMT			SIGEMT
 
+define	TF_FILL			offsetof(struct trapframe, tf_fill)
 define	TF_R0			offsetof(struct trapframe, tf_r0)
 define	TF_R10			offsetof(struct trapframe, tf_r10)
 define	TF_PC			offsetof(struct trapframe, tf_pc)
@@ -155,9 +156,8 @@ define	CF_SLEEP		offsetof(struct cpu_fun
 define	CF_CONTROL		offsetof(struct cpu_functions, cf_control)
 
 define	CI_CURPRIORITY		offsetof(struct cpu_info, ci_schedstate.spc_curpriority)
-ifndef PROCESS_ID_IS_CURLWP
+define	CI_ARM_CPUID		offsetof(struct cpu_info, ci_arm_cpuid)
 define	CI_CURLWP		offsetof(struct cpu_info, ci_curlwp)
-endif
 define	CI_CPL			offsetof(struct cpu_info, ci_cpl)
 define	CI_ASTPENDING		offsetof(struct cpu_info, ci_astpending)
 define	CI_WANT_RESCHED		offsetof(struct cpu_info, ci_want_resched)

Index: src/sys/arch/arm/arm32/vm_machdep.c
diff -u src/sys/arch/arm/arm32/vm_machdep.c:1.59 src/sys/arch/arm/arm32/vm_machdep.c:1.60
--- src/sys/arch/arm/arm32/vm_machdep.c:1.59	Thu Aug 16 17:35:01 2012
+++ src/sys/arch/arm/arm32/vm_machdep.c	Wed Aug 29 07:09:12 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.59 2012/08/16 17:35:01 matt Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.60 2012/08/29 07:09:12 matt Exp $	*/
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.59 2012/08/16 17:35:01 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.60 2012/08/29 07:09:12 matt Exp $");
 
 #include "opt_armfpe.h"
 #include "opt_pmap_debug.h"
@@ -184,6 +184,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
 	sf = (struct switchframe *)tf - 1;
 	sf->sf_r4 = (u_int)func;
 	sf->sf_r5 = (u_int)arg;
+	sf->sf_r7 = PSR_USR32_MODE;		/* for returning to userspace */
 	sf->sf_sp = (u_int)tf;
 	sf->sf_pc = (u_int)lwp_trampoline;
 	pcb2->pcb_sp = (u_int)sf;

Index: src/sys/arch/arm/include/arm32/frame.h
diff -u src/sys/arch/arm/include/arm32/frame.h:1.32 src/sys/arch/arm/include/arm32/frame.h:1.33
--- src/sys/arch/arm/include/arm32/frame.h:1.32	Sat Aug 25 14:08:17 2012
+++ src/sys/arch/arm/include/arm32/frame.h	Wed Aug 29 07:09:12 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: frame.h,v 1.32 2012/08/25 14:08:17 matt Exp $	*/
+/*	$NetBSD: frame.h,v 1.33 2012/08/29 07:09:12 matt Exp $	*/
 
 /*
  * Copyright (c) 1994-1997 Mark Brinicombe.
@@ -102,20 +102,53 @@ void validate_trapframe(trapframe_t *, i
  * This macro is used by DO_AST_AND_RESTORE_ALIGNMENT_FAULTS to process
  * any pending softints.
  */
-#ifdef __HAVE_FAST_SOFTINTS
+#if defined(__HAVE_FAST_SOFTINTS) && !defined(__HAVE_PIC_FAST_SOFTINTS)
 #define	DO_PENDING_SOFTINTS						\
 	ldr	r0, [r4, #CI_INTR_DEPTH]/* Get current intr depth */	;\
 	teq	r0, #0			/* Test for 0. */		;\
 	bne	10f			/*   skip softints if != 0 */	;\
 	ldr	r0, [r4, #CI_CPL]	/* Get current priority level */;\
 	ldr	r1, [r4, #CI_SOFTINTS]	/* Get pending softint mask */	;\
-	movs	r0, r1, lsr r0		/* shift mask by cpl */		;\
+	lsrs	r0, r1, r0		/* shift mask by cpl */		;\
 	blne	_C_LABEL(dosoftints)	/* dosoftints(void) */		;\
 10:
 #else
 #define	DO_PENDING_SOFTINTS		/* nothing */
 #endif
 
+#ifdef MULTIPROCESSOR
+#define	KERNEL_LOCK							\
+	mov	r0, #1							;\
+	mov	r1, #0							;\
+	bl	_C_LABEL(_kernel_lock)
+
+#define	KERNEL_UNLOCK							\
+	mov	r0, #1							;\
+	mov	r1, #0							;\
+	mov	r2, #0							;\
+	bl	_C_LABEL(_kernel_unlock)
+#else
+#define	KERNEL_LOCK			/* nothing */
+#define	KERNEL_UNLOCK			/* nothing */
+#endif
+
+#ifdef _ARM_ARCH_6
+#define	GET_CPSR(rb)			/* nothing */
+#define	CPSID_I(ra,rb)			cpsid	i
+#define	CPSIE_I(ra,rb)			cpsie	i
+#else
+#define	GET_CPSR(rb)							\
+	mrs	rb, cpsr		/* fetch CPSR */
+
+#define	CPSID_I(ra,rb)							\
+	orr	ra, rb, #(IF32_bits)					;\
+	msr	cpsr_c, ra		/* Disable interrupts */
+
+#define	CPSIE_I(ra,rb)							\
+	bic	ra, rb, #(IF32_bits)					;\
+	msr	cpsr_c, ra		/* Restore interrupts */
+#endif
+
 /*
  * AST_ALIGNMENT_FAULT_LOCALS and ENABLE_ALIGNMENT_FAULTS
  * These are used in order to support dynamic enabling/disabling of
@@ -139,8 +172,8 @@ void validate_trapframe(trapframe_t *, i
  * is invoked immediately after PUSHFRAMEINSVC or PUSHFRAME.
  */
 #define	ENABLE_ALIGNMENT_FAULTS						\
-	and	r0, r0, #(PSR_MODE)	/* Test for USR32 mode */	;\
-	teq	r0, #(PSR_USR32_MODE)					;\
+	and	r7, r0, #(PSR_MODE)	/* Test for USR32 mode */	;\
+	teq	r7, #(PSR_USR32_MODE)					;\
 	GET_CURCPU(r4)			/* r4 = cpuinfo */		;\
 	bne	1f			/* Not USR mode skip AFLT */	;\
 	ldr	r1, [r4, #CI_CURLWP]	/* get curlwp from cpu_info */	;\
@@ -152,7 +185,7 @@ void validate_trapframe(trapframe_t *, i
 	mov	r0, #-1							;\
 	mov	lr, pc							;\
 	ldr	pc, [r2, #CF_CONTROL]	/* Enable alignment faults */	;\
-1:
+1:	KERNEL_LOCK
 
 /*
  * This macro must be invoked just before PULLFRAMEFROMSVCANDEXIT or
@@ -162,12 +195,9 @@ void validate_trapframe(trapframe_t *, i
  */
 #define	DO_AST_AND_RESTORE_ALIGNMENT_FAULTS				\
 	DO_PENDING_SOFTINTS						;\
-	ldr	r0, [sp]		/* Get the SPSR from stack */	;\
-	mrs	r5, cpsr		/* save CPSR */			;\
-	orr	r1, r5, #(IF32_bits)					;\
-	msr	cpsr_c, r1		/* Disable interrupts */	;\
-	and	r0, r0, #(PSR_MODE)	/* Returning to USR mode? */	;\
-	teq	r0, #(PSR_USR32_MODE)					;\
+	GET_CPSR(r5)			/* save CPSR */			;\
+	CPSID_I(r1, r5)			/* Disable interrupts */	;\
+	teq	r7, #(PSR_USR32_MODE)	/* Returning to USR mode? */	;\
 	bne	3f			/* Nope, get out now */		;\
 1:	ldr	r1, [r4, #CI_ASTPENDING] /* Pending AST? */		;\
 	teq	r1, #0x00000000						;\
@@ -185,43 +215,39 @@ void validate_trapframe(trapframe_t *, i
 	/* NOTREACHED */						\
 2:	mov	r1, #0x00000000						;\
 	str	r1, [r4, #CI_ASTPENDING] /* Clear astpending */		;\
-	bic	r5, r5, #(IF32_bits)				;\
-	msr	cpsr_c, r5		/* Restore interrupts */	;\
+	CPSIE_I(r5, r5)			/* Restore interrupts */	;\
 	mov	r0, sp							;\
 	bl	_C_LABEL(ast)		/* ast(frame) */		;\
-	orr	r0, r5, #(IF32_bits)	/* Disable IRQs */		;\
-	msr	cpsr_c, r0						;\
+	CPSID_I(r0, r5)			/* Disable interrupts */	;\
 	b	1b			/* Back around again */		;\
-3:
+3:	KERNEL_UNLOCK
 
 #else	/* !EXEC_AOUT */
 
 #define	AST_ALIGNMENT_FAULT_LOCALS
 
-#define	ENABLE_ALIGNMENT_FAULTS		GET_CURCPU(r4)
+#define	ENABLE_ALIGNMENT_FAULTS						\
+	and	r7, r0, #(PSR_MODE)	/* Test for USR32 mode */	;\
+	GET_CURCPU(r4)			/* r4 = cpuinfo */		;\
+	KERNEL_LOCK
 
 #define	DO_AST_AND_RESTORE_ALIGNMENT_FAULTS				\
 	DO_PENDING_SOFTINTS						;\
-	ldr	r0, [sp]		/* Get the SPSR from stack */	;\
-	mrs	r5, cpsr		/* save CPSR */			;\
-	orr	r1, r5, #(IF32_bits)					;\
-	msr	cpsr_c, r1		/* Disable interrupts */	;\
-	and	r0, r0, #(PSR_MODE)	/* Returning to USR mode? */	;\
-	teq	r0, #(PSR_USR32_MODE)					;\
+	GET_CPSR(r5)			/* save CPSR */			;\
+	CPSID_I(r1, r5)			/* Disable interrupts */	;\
+	teq	r7, #(PSR_USR32_MODE)					;\
 	bne	2f			/* Nope, get out now */		;\
 1:	ldr	r1, [r4, #CI_ASTPENDING] /* Pending AST? */		;\
 	teq	r1, #0x00000000						;\
 	beq	2f			/* Nope. Just bail */		;\
 	mov	r1, #0x00000000						;\
 	str	r1, [r4, #CI_ASTPENDING] /* Clear astpending */		;\
-	bic	r5, r5, #(IF32_bits)					;\
-	msr	cpsr_c, r5		/* Restore interrupts */	;\
+	CPSIE_I(r5, r5)			/* Restore interrupts */	;\
 	mov	r0, sp							;\
 	bl	_C_LABEL(ast)		/* ast(frame) */		;\
-	orr	r0, r5, #(IF32_bits)	/* Disable IRQs */		;\
-	msr	cpsr_c, r0						;\
+	CPSID_I(r0, r5)			/* Disable interrupts */	;\
 	b	1b							;\
-2:
+2:	KERNEL_UNLOCK			/* unlock the kernel */
 #endif /* EXEC_AOUT */
 
 #ifndef _ARM_ARCH_6

Reply via email to