svn commit: r262980 - in head/sys: arm/arm conf

Ian Lepore ian at FreeBSD.org
Mon Mar 10 19:36:27 UTC 2014


Author: ian
Date: Mon Mar 10 19:36:26 2014
New Revision: 262980
URL: http://svnweb.freebsd.org/changeset/base/262980

Log:
  Move the exception vector table (so-called "page0" data) into exception.S
  and eliminate vectors.S.  All low-level exception handling is now
  consolidated into exception.S.
  
  Along with moving the default FIQ handler, change it to disable FIQs
  before returning.  An FIQ should never happen, but if it does, it's got
  to be disabled as part of ignoring it.
  
  In general, we have hand-wavy support for FIQs that probably hasn't been
  used for 10 years and probably doesn't work (almost certainly doesn't
  work for SMP because it only updates the vector on the current cpu).  This
  change doesn't really make the overall situation any better or worse.

Deleted:
  head/sys/arm/arm/vectors.S
Modified:
  head/sys/arm/arm/exception.S
  head/sys/arm/arm/fiq.c
  head/sys/arm/arm/fiq_subr.S
  head/sys/conf/files.arm

Modified: head/sys/arm/arm/exception.S
==============================================================================
--- head/sys/arm/arm/exception.S	Mon Mar 10 18:10:09 2014	(r262979)
+++ head/sys/arm/arm/exception.S	Mon Mar 10 19:36:26 2014	(r262980)
@@ -148,7 +148,7 @@ _C_LABEL(data_abort_handler_address):
 END(data_abort_entry)
 
 /*
- * address_exception_entry:
+ * addr_exception_entry:
  *
  *	Handler for the Address Exception exception.
  *
@@ -156,17 +156,17 @@ END(data_abort_entry)
  *	print a warning message to the console and then treat
  *	it like a Data Abort.
  */
-ASENTRY_NP(address_exception_entry)
+ASENTRY_NP(addr_exception_entry)
 	mrs	r1, cpsr
 	mrs	r2, spsr
 	mov	r3, lr
-	adr	r0, Laddress_exception_msg
+	adr	r0, Laddr_exception_msg
 	bl	_C_LABEL(printf)	/* XXX CLOBBERS LR!! */
 	b	data_abort_entry
-Laddress_exception_msg:
+Laddr_exception_msg:
 	.asciz	"Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
 	.balign	4
-END(address_exception_entry)
+END(addr_exception_entry)
 
 /*
  * General exception exit handler
@@ -234,3 +234,63 @@ Lundefined_handler_address:
 _C_LABEL(undefined_handler_address):
 	.word	undefinedinstruction_bounce
 
+/*
+ * Entry point for FIQ interrupts.
+ *
+ * We don't currently support FIQ handlers very much.  Something can 
+ * install itself in the FIQ vector using code (that may or may not work
+ * these days) in fiq.c.  If nobody does that and an FIQ happens, this
+ * default handler just disables FIQs and otherwise ignores it.
+ */
+ASENTRY_NP(fiq_entry)
+	mrs	r8, cpsr		/* FIQ handling isn't supported, */
+	bic	r8, #(F32_bit)		/* just disable FIQ and return.  */
+	msr	cpsr_c, r8		/* The r8 we trash here is the  */
+	subs	pc, lr, #4		/* banked FIQ-mode r8. */
+END(fiq_entry)
+
+/*
+ * page0 and page0_data -- An image of the ARM vectors which is copied to
+ * the ARM vectors page (high or low) as part of CPU initialization.  The
+ * code that does the copy assumes that page0_data holds one 32-bit word
+ * of data for each of the predefined ARM vectors.  It also assumes that
+ * page0_data follows the vectors in page0, but other stuff can appear 
+ * between the two.  We currently leave room between the two for some fiq 
+ * handler code to be copied in.
+ */
+	.global	_C_LABEL(page0), _C_LABEL(page0_data)
+
+_C_LABEL(page0):
+	ldr	pc, .Lreset_entry
+	ldr	pc, .Lundefined_entry
+	ldr	pc, .Lswi_entry
+	ldr	pc, .Lprefetch_abort_entry
+	ldr	pc, .Ldata_abort_entry
+	ldr	pc, .Laddr_exception_entry
+	ldr	pc, .Lirq_entry
+.fiqv:	ldr	pc, .Lfiq_entry
+	.space 256	/* room for some fiq handler code */
+
+_C_LABEL(page0_data):
+.Lreset_entry:		.word	reset_entry
+.Lundefined_entry:	.word	undefined_entry
+.Lswi_entry:		.word	swi_entry
+.Lprefetch_abort_entry:	.word	prefetch_abort_entry
+.Ldata_abort_entry:	.word	data_abort_entry
+.Laddr_exception_entry:	.word	addr_exception_entry
+.Lirq_entry:		.word	irq_entry
+.Lfiq_entry:		.word	fiq_entry
+
+/*
+ * These items are used by the code in fiq.c to install what it calls the
+ * "null" handler.  It's actually our default vector entry that just jumps
+ * to the default handler which just disables FIQs and returns.
+ */
+	.global _C_LABEL(fiq_nullhandler_code), _C_LABEL(fiq_nullhandler_size)
+
+_C_LABEL(fiq_nullhandler_code):
+	.word	.fiqv
+_C_LABEL(fiq_nullhandler_size):
+	.word	4
+
+

Modified: head/sys/arm/arm/fiq.c
==============================================================================
--- head/sys/arm/arm/fiq.c	Mon Mar 10 18:10:09 2014	(r262979)
+++ head/sys/arm/arm/fiq.c	Mon Mar 10 19:36:26 2014	(r262980)
@@ -51,8 +51,8 @@ __FBSDID("$FreeBSD$");
 TAILQ_HEAD(, fiqhandler) fiqhandler_stack =
     TAILQ_HEAD_INITIALIZER(fiqhandler_stack);
 
-extern char fiqvector[];
-extern char fiq_nullhandler[], fiq_nullhandler_end[];
+extern char *fiq_nullhandler_code;
+extern uint32_t fiq_nullhandler_size;
 
 #define	IRQ_BIT		I32_bit
 #define	FIQ_BIT		F32_bit
@@ -61,6 +61,9 @@ extern char fiq_nullhandler[], fiq_nullh
  * fiq_installhandler:
  *
  *	Actually install the FIQ handler down at the FIQ vector.
+ *	
+ *	The FIQ vector is fixed by the hardware definition as the
+ *	seventh 32-bit word in the vector page.
  *
  *	Note: If the FIQ is invoked via an extra layer of
  *	indirection, the actual FIQ code store lives in the
@@ -70,11 +73,13 @@ extern char fiq_nullhandler[], fiq_nullh
 static void
 fiq_installhandler(void *func, size_t size)
 {
+	const uint32_t fiqvector = 7 * sizeof(uint32_t);
+
 #if !defined(__ARM_FIQ_INDIRECT)
 	vector_page_setprot(VM_PROT_READ|VM_PROT_WRITE);
 #endif
 
-	memcpy(vector_page + fiqvector, func, size);
+	memcpy((void *)(vector_page + fiqvector), func, size);
 
 #if !defined(__ARM_FIQ_INDIRECT)
 	vector_page_setprot(VM_PROT_READ);
@@ -159,8 +164,7 @@ fiq_release(struct fiqhandler *fh)
 
 	if (TAILQ_FIRST(&fiqhandler_stack) == NULL) {
 		/* Copy the NULL handler back down into the vector. */
-		fiq_installhandler(fiq_nullhandler,
-		    (size_t)(fiq_nullhandler_end - fiq_nullhandler));
+		fiq_installhandler(fiq_nullhandler_code, fiq_nullhandler_size);
 
 		/* Make sure FIQs are disabled when we return. */
 		oldirqstate |= FIQ_BIT;

Modified: head/sys/arm/arm/fiq_subr.S
==============================================================================
--- head/sys/arm/arm/fiq_subr.S	Mon Mar 10 18:10:09 2014	(r262979)
+++ head/sys/arm/arm/fiq_subr.S	Mon Mar 10 19:36:26 2014	(r262980)
@@ -91,13 +91,3 @@ ENTRY(fiq_setregs)
 	RET
 END(fiq_setregs)
 
-/*
- * fiq_nullhandler:
- *
- *	Null handler copied down to the FIQ vector when the last
- *	FIQ handler is removed.
- */
-	.global	_C_LABEL(fiq_nullhandler), _C_LABEL(fiq_nullhandler_end)
-_C_LABEL(fiq_nullhandler):
-	subs	pc, lr, #4
-_C_LABEL(fiq_nullhandler_end):

Modified: head/sys/conf/files.arm
==============================================================================
--- head/sys/conf/files.arm	Mon Mar 10 18:10:09 2014	(r262979)
+++ head/sys/conf/files.arm	Mon Mar 10 19:36:26 2014	(r262980)
@@ -50,7 +50,6 @@ arm/arm/sys_machdep.c		standard
 arm/arm/trap.c			standard
 arm/arm/uio_machdep.c		standard
 arm/arm/undefined.c		standard
-arm/arm/vectors.S		standard
 arm/arm/vm_machdep.c		standard
 arm/arm/vfp.c			standard
 board_id.h			standard				   \


More information about the svn-src-all mailing list