On Mon, Jul 10, 2017 at 04:19:12PM +0300, Artturi Alm wrote:
> Hi,
>
>
> this diff does seem bigger than it is, because this does move the exception
> handler entrys from arm/exceptions.S to arm/vectors.S, while removing
> a round of useless indirection that was needed more before VBAR, which
> can be found supported even on some V6ses w/extensions(ARM11), so this is
> nothing new or anything that anyone should be afraid of, imo.
> i
> +Before anyone goes liek "you just broke FIQs!", no, i didn't, and depending
> on defines to it, the FIQs might try to get ran on .data section, which is not
> OK, imo., and i have some doubt that no-one has ever enabled that FIQ-support
> on OpenBSD/armv7, so no use-case = no fiq fix in this diff,
> which would likely be less than 10lines of code w/some thought.
>
> shortly; i added these +++++ to locore0.S:
>
> mcr CP15_DACR(r0)
>
> + /* set VBAR */
> + ldr r0, =vectors
> + mcr CP15_VBAR(r0)
> +
> /* Enable MMU */
> mrc CP15_SCTLR(r0)
> + bic r0, r0, #CPU_CONTROL_VECRELOC /* our vectors are at VBAR */
> orr r0, r0, #CPU_CONTROL_MMU_ENABLE
> mcr CP15_SCTLR(r0)
> CPWAIT(r0)
>
>
> and removed the initialization/indirection/special-casing that did still exist
> for the exception handlers/vector_page/systempage.
>
>
> Works for me on cubieb2&wandb.
> -Artturi
>
>
Hi,
updated diff below, which does not move/use the C_OBJECT()-define,
and potentially fixes FIQs, if someone was to enable them.
Removes arm/arm/fiq_subr.S as a side-effect to touching FIQs, sry.
-Artturi
diff --git a/sys/arch/arm/arm/arm32_machdep.c b/sys/arch/arm/arm/arm32_machdep.c
index 44ae69fa7f9..09b171373aa 100644
--- a/sys/arch/arm/arm/arm32_machdep.c
+++ b/sys/arch/arm/arm/arm32_machdep.c
@@ -115,62 +115,6 @@ void prefetch_abort_handler (trapframe_t *frame);
extern void configure (void);
/*
- * arm32_vector_init:
- *
- * Initialize the vector page, and select whether or not to
- * relocate the vectors.
- *
- * NOTE: We expect the vector page to be mapped at its expected
- * destination.
- */
-void
-arm32_vector_init(vaddr_t va, int which)
-{
- extern unsigned int page0[], page0_data[];
- unsigned int *vectors = (unsigned int *) va;
- unsigned int *vectors_data = vectors + (page0_data - page0);
- int vec;
-
- /*
- * Loop through the vectors we're taking over, and copy the
- * vector's insn and data word.
- */
- for (vec = 0; vec < ARM_NVEC; vec++) {
- if ((which & (1 << vec)) == 0) {
- /* Don't want to take over this vector. */
- continue;
- }
- vectors[vec] = page0[vec];
- vectors_data[vec] = page0_data[vec];
- }
-
- /* Now sync the vectors. */
- cpu_icache_sync_range(va, (ARM_NVEC * 2) * sizeof(u_int));
-
- vector_page = va;
-
- if (va == ARM_VECTORS_HIGH) {
- /*
- * Assume the MD caller knows what it's doing here, and
- * really does want the vector page relocated.
- *
- * Note: This has to be done here (and not just in
- * cpu_setup()) because the vector page needs to be
- * accessible *before* main() is called.
- * Think ddb(9) ...
- *
- * NOTE: If the CPU control register is not readable,
- * this will totally fail! We'll just assume that
- * any system that has high vector support has a
- * readable CPU control register, for now. If we
- * ever encounter one that does not, we'll have to
- * rethink this.
- */
- cpu_control(CPU_CONTROL_VECRELOC, CPU_CONTROL_VECRELOC);
- }
-}
-
-/*
* Debug function just to park the CPU
*/
@@ -228,9 +172,6 @@ cpu_startup()
paddr_t minaddr;
paddr_t maxaddr;
- /* Lock down zero page */
- vector_page_setprot(PROT_READ | PROT_EXEC);
-
/*
* Give pmap a chance to set up a few more things now the vm
* is initialised
diff --git a/sys/arch/arm/arm/arm_machdep.c b/sys/arch/arm/arm/arm_machdep.c
index f5871f3afb5..041507714cd 100644
--- a/sys/arch/arm/arm/arm_machdep.c
+++ b/sys/arch/arm/arm/arm_machdep.c
@@ -87,18 +87,6 @@
#include <machine/bus.h>
/*
- * The ARM architecture places the vector page at address 0.
- * Later ARM architecture versions, however, allow it to be
- * relocated to a high address (0xffff0000). This is primarily
- * to support the Fast Context Switch Extension.
- *
- * This variable contains the address of the vector page. It
- * defaults to 0; it only needs to be initialized if we enable
- * relocated vectors.
- */
-vaddr_t vector_page;
-
-/*
* Clear registers on exec
*/
diff --git a/sys/arch/arm/arm/cpufunc.c b/sys/arch/arm/arm/cpufunc.c
index c91108e7066..7f77d89045b 100644
--- a/sys/arch/arm/arm/cpufunc.c
+++ b/sys/arch/arm/arm/cpufunc.c
@@ -402,9 +402,6 @@ armv7_setup()
| CPU_CONTROL_IC_ENABLE
| CPU_CONTROL_AFE;
- if (vector_page == ARM_VECTORS_HIGH)
- cpuctrl |= CPU_CONTROL_VECRELOC;
-
/*
* Check for the Virtualization Extensions and enable UWXN of
* those are included.
diff --git a/sys/arch/arm/arm/exception.S b/sys/arch/arm/arm/exception.S
deleted file mode 100644
index f1bceac6864..00000000000
--- a/sys/arch/arm/arm/exception.S
+++ /dev/null
@@ -1,248 +0,0 @@
-/* $OpenBSD: exception.S,v 1.6 2016/09/21 11:33:05 kettenis Exp $ */
-/* $NetBSD: exception.S,v 1.13 2003/10/31 16:30:15 scw Exp $ */
-
-/*
- * Copyright (c) 1994-1997 Mark Brinicombe.
- * Copyright (c) 1994 Brini.
- * All rights reserved.
- *
- * This code is derived from software written for Brini by Mark Brinicombe
- *
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Brini.
- * 4. The name of the company nor the name of the author may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
- *
- * RiscBSD kernel project
- *
- * exception.S
- *
- * Low level handlers for exception vectors
- *
- * Created : 24/09/94
- *
- * Based on kate/display/abort.s
- */
-
-#include <machine/asm.h>
-#include <machine/cpu.h>
-#include <machine/frame.h>
-#include "assym.h"
-
- .text
- .align 2
-
-AST_LOCALS
-
-/*
- * reset_entry:
- *
- * Handler for Reset exception.
- */
-ASENTRY_NP(reset_entry)
- adr r0, Lreset_panicmsg
- mov r1, lr
- bl _C_LABEL(panic)
- /* NOTREACHED */
-Lreset_panicmsg:
- .asciz "Reset vector called, LR = 0x%08x"
- .balign 4
-
-/*
- * swi_entry
- *
- * Handler for the Software Interrupt exception.
- */
-ASENTRY_NP(swi_entry)
- PUSHFRAME
-
- mov r0, sp /* Pass the frame to any function */
- bl _C_LABEL(swi_handler) /* It's a SWI ! */
-
- DO_AST
- PULLFRAME
- movs pc, lr /* Exit */
-
-/*
- * prefetch_abort_entry:
- *
- * Handler for the Prefetch Abort exception.
- */
-ASENTRY_NP(prefetch_abort_entry)
-#ifdef __XSCALE__
- nop /* Make absolutely sure any pending */
- nop /* imprecise aborts have occurred. */
-#endif
- sub lr, lr, #0x00000004 /* Adjust the lr */
-
- PUSHFRAMEINSVC
-
- ldr r1, Lprefetch_abort_handler_address
- adr lr, exception_exit
- mov r0, sp /* pass the stack pointer as r0 */
- ldr pc, [r1]
-
-Lprefetch_abort_handler_address:
- .word _C_LABEL(prefetch_abort_handler_address)
-
- .data
- .global _C_LABEL(prefetch_abort_handler_address)
-
-_C_LABEL(prefetch_abort_handler_address):
- .word abortprefetch
-
- .text
-abortprefetch:
- adr r0, abortprefetchmsg
- b _C_LABEL(panic)
-
-abortprefetchmsg:
- .asciz "abortprefetch"
- .align 2
-
-/*
- * data_abort_entry:
- *
- * Handler for the Data Abort exception.
- */
-ASENTRY_NP(data_abort_entry)
-#ifdef __XSCALE__
- nop /* Make absolutely sure any pending */
- nop /* imprecise aborts have occurred. */
-#endif
- sub lr, lr, #0x00000008 /* Adjust the lr */
-
- PUSHFRAMEINSVC /* Push trap frame and switch */
- /* to SVC32 mode */
-
- ldr r1, Ldata_abort_handler_address
- adr lr, exception_exit
- mov r0, sp /* pass the stack pointer as r0 */
- ldr pc, [r1]
-
-Ldata_abort_handler_address:
- .word _C_LABEL(data_abort_handler_address)
-
- .data
- .global _C_LABEL(data_abort_handler_address)
-_C_LABEL(data_abort_handler_address):
- .word abortdata
-
- .text
-abortdata:
- adr r0, abortdatamsg
- b _C_LABEL(panic)
-
-abortdatamsg:
- .asciz "abortdata"
- .align 2
-
-/*
- * address_exception_entry:
- *
- * Handler for the Address Exception exception.
- *
- * NOTE: This exception isn't really used on arm32. We
- * print a warning message to the console and then treat
- * it like a Data Abort.
- */
-ASENTRY_NP(address_exception_entry)
- mrs r1, cpsr
- mrs r2, spsr
- mov r3, lr
- adr r0, Laddress_exception_msg
- bl _C_LABEL(printf) /* XXX CLOBBERS LR!! */
- b data_abort_entry
-Laddress_exception_msg:
- .asciz "Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
- .balign 4
-
-/*
- * General exception exit handler
- * (Placed here to be within range of all the references to it)
- *
- * It exits straight away if not returning to USR mode.
- * This loops around delivering any pending ASTs.
- * Interrupts are disabled at suitable points to avoid ASTs
- * being posted between testing and exit to user mode.
- *
- * This function uses PULLFRAMEFROMSVCANDEXIT and DO_AST thus should
- * only be called if the exception handler used PUSHFRAMEINSVC.
- */
-
-exception_exit:
- DO_AST
- PULLFRAMEFROMSVCANDEXIT
-
-/*
- * undefined_entry:
- *
- * Handler for the Undefined Instruction exception.
- *
- * We indirect the undefined vector via the handler address
- * in the data area. Entry to the undefined handler must
- * look like direct entry from the vector.
- */
-ASENTRY_NP(undefined_entry)
- stmfd sp!, {r0, r1}
- ldr r0, Lundefined_handler_indirection
- ldr r1, [sp], #0x0004
- str r1, [r0, #0x0000]
- ldr r1, [sp], #0x0004
- str r1, [r0, #0x0004]
- ldmia r0, {r0, r1, pc}
-
-Lundefined_handler_indirection:
- .word Lundefined_handler_indirection_data
-
-/*
- * assembly bounce code for calling the kernel
- * undefined instruction handler. This uses
- * a standard trap frame and is called in SVC mode.
- */
-
-ENTRY_NP(undefinedinstruction_bounce)
- PUSHFRAMEINSVC
-
- mov r0, sp
- adr lr, exception_exit
- b _C_LABEL(undefinedinstruction)
-
- .data
- .align 2
-
-/*
- * Indirection data
- * 2 words use for preserving r0 and r1
- * 3rd word contains the undefined handler address.
- */
-
-Lundefined_handler_indirection_data:
- .word 0
- .word 0
-
- .global _C_LABEL(undefined_handler_address)
-_C_LABEL(undefined_handler_address):
- .word _C_LABEL(undefinedinstruction_bounce)
diff --git a/sys/arch/arm/arm/fault.c b/sys/arch/arm/arm/fault.c
index 7ed4ce466b3..749119d5087 100644
--- a/sys/arch/arm/arm/fault.c
+++ b/sys/arch/arm/arm/fault.c
@@ -261,13 +261,15 @@ data_abort_handler(trapframe_t *tf)
va = trunc_page((vaddr_t)far);
/*
- * It is only a kernel address space fault iff:
- * 1. user == 0 and
- * 2. pcb_onfault not set or
- * 3. pcb_onfault set and not LDRT/LDRBT/STRT/STRBT instruction.
+ * It is only a kernel address space fault if:
+ * 1. user == 0 &&
+ * 2. va >= VM_MIN_KERNEL_ADDRESS && (
+ * 3. pcb_onfault == NULL ||
+ * 4. *(tf->tf_pc) != LDR{B}T/STR{B}T instruction )
+ * (T-suffix = load/store with privileges as unprivileged)
*/
- if (user == 0 && (va >= VM_MIN_KERNEL_ADDRESS ||
- (va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) &&
+ if (user == 0 &&
+ va >= VM_MIN_KERNEL_ADDRESS &&
__predict_true((pcb->pcb_onfault == NULL ||
((*(u_int *)tf->tf_pc) & 0x05200000) != 0x04200000))) {
map = kernel_map;
@@ -590,8 +592,7 @@ prefetch_abort_handler(trapframe_t *tf)
p->p_addr->u_pcb.pcb_tf = tf;
/* Ok validate the address, can only execute in USER space */
- if (__predict_false(far >= VM_MAXUSER_ADDRESS ||
- (far < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
+ if (__predict_false(far >= VM_MAXUSER_ADDRESS)) {
sv.sival_ptr = (u_int32_t *)far;
trapsignal(p, SIGSEGV, 0, SEGV_ACCERR, sv);
goto out;
diff --git a/sys/arch/arm/arm/fiq.c b/sys/arch/arm/arm/fiq.c
index 7201ee5607e..aad531a6c8f 100644
--- a/sys/arch/arm/arm/fiq.c
+++ b/sys/arch/arm/arm/fiq.c
@@ -55,24 +55,15 @@ extern char fiq_nullhandler[], fiq_nullhandler_end[];
* fiq_installhandler:
*
* Actually install the FIQ handler down at the FIQ vector.
- *
- * Note: If the FIQ is invoked via an extra layer of
- * indirection, the actual FIQ code store lives in the
- * data segment, so there is no need to manipulate
- * the vector page's protection.
*/
static void
fiq_installhandler(void *func, size_t size)
{
-#if !defined(__ARM_FIQ_INDIRECT)
- vector_page_setprot(PROT_READ | PROT_WRITE | PROT_EXEC);
-#endif
+ vector_page_setprot(PROT_READ | PROT_WRITE);
memcpy(fiqvector, func, size);
-#if !defined(__ARM_FIQ_INDIRECT)
vector_page_setprot(PROT_READ | PROT_EXEC);
-#endif
cpu_icache_sync_range((vaddr_t) fiqvector, size);
}
diff --git a/sys/arch/arm/arm/fiq_subr.S b/sys/arch/arm/arm/fiq_subr.S
deleted file mode 100644
index 7b805ec06ab..00000000000
--- a/sys/arch/arm/arm/fiq_subr.S
+++ /dev/null
@@ -1,92 +0,0 @@
-/* $OpenBSD: fiq_subr.S,v 1.4 2015/01/18 14:55:02 jsg Exp $ */
-/* $NetBSD: fiq_subr.S,v 1.3 2002/04/12 18:50:31 thorpej Exp $ */
-
-/*
- * Copyright (c) 2001 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
- * 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.
- */
-
-#include "assym.h"
-
-#include <arm/armreg.h>
-#include <arm/asm.h>
-#include <arm/cpuconf.h>
-
-#define SWITCH_TO_FIQ_MODE
\
- mrs r2, cpsr ; \
- mov r3, r2 ; \
- bic r2, r2, #(PSR_MODE) ; \
- orr r2, r2, #(PSR_FIQ32_MODE) ; \
- msr cpsr_c, r2
-
-#define BACK_TO_SVC_MODE
\
- msr cpsr_c, r3
-
-/*
- * fiq_getregs:
- *
- * Fetch the FIQ mode banked registers into the fiqhandler
- * structure.
- */
-ENTRY(fiq_getregs)
- SWITCH_TO_FIQ_MODE
-
- stmia r0, {r8-r13}
-
- BACK_TO_SVC_MODE
- mov pc, lr
-
-/*
- * fiq_setregs:
- *
- * Load the FIQ mode banked registers from the fiqhandler
- * structure.
- */
-ENTRY(fiq_setregs)
- SWITCH_TO_FIQ_MODE
-
- ldmia r0, {r8-r13}
-
- BACK_TO_SVC_MODE
- mov pc, lr
-
-/*
- * 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):
diff --git a/sys/arch/arm/arm/pmap7.c b/sys/arch/arm/arm/pmap7.c
index f99ee582e00..a3eb2046fa2 100644
--- a/sys/arch/arm/arm/pmap7.c
+++ b/sys/arch/arm/arm/pmap7.c
@@ -421,8 +421,6 @@ vaddr_t virtual_avail;
vaddr_t virtual_end;
vaddr_t pmap_curmaxkvaddr;
-extern pv_addr_t systempage;
-
static __inline boolean_t
pmap_is_current(pmap_t pm)
{
@@ -2149,6 +2147,10 @@ vector_page_setprot(int prot)
{
struct l2_bucket *l2b;
pt_entry_t *ptep;
+ vaddr_t vbar, vector_page;
+
+ __asm volatile("mrc p15, 0, %0, c12, c0, 0\n" : "=r"(vbar));
+ vector_page = trunc_page(vbar);
l2b = pmap_get_l2_bucket(pmap_kernel(), vector_page);
KDASSERT(l2b != NULL);
diff --git a/sys/arch/arm/arm/vectors.S b/sys/arch/arm/arm/vectors.S
index 608335d719d..4563f61958f 100644
--- a/sys/arch/arm/arm/vectors.S
+++ b/sys/arch/arm/arm/vectors.S
@@ -34,71 +34,123 @@
#include "assym.h"
#include <machine/asm.h>
+#include <machine/frame.h>
+#include <arm/armreg.h>
+
+ .text
+ .global vectors
+ .p2align 5 /* VBAR(=vector base address) has to be 32bit aligned */
/*
- * These are the exception vectors copied down to page 0.
- *
- * Note that FIQs are special; rather than using a level of
- * indirection, we actually copy the FIQ code down into the
- * vector page.
+ * These are the exception vectors.
*/
-
- .text
- .align 2
- .global _C_LABEL(page0), _C_LABEL(page0_data), _C_LABEL(page0_end)
- .global _C_LABEL(fiqvector)
-
-_C_LABEL(page0):
- ldr pc, .Lreset_target
- ldr pc, .Lundefined_target
- ldr pc, .Lswi_target
- ldr pc, .Lprefetch_abort_target
- ldr pc, .Ldata_abort_target
- ldr pc, .Laddress_exception_target
- ldr pc, .Lirq_target
-#ifdef __ARM_FIQ_INDIRECT
- ldr pc, .Lfiq_target
-#else
-.Lfiqvector:
- .set _C_LABEL(fiqvector), . - _C_LABEL(page0)
+vectors:
+ b reset_entry
+ b undefined_entry
+ b swi_entry
+ b prefetch_abort_entry
+ b data_abort_entry
+ b address_exception_entry
+ b irq_entry
+#ifndef FIQ
subs pc, lr, #4
- .org .Lfiqvector + 0x100
+#else
+ b fiqvector
#endif
-_C_LABEL(page0_data):
-.Lreset_target:
- .word reset_entry
+AST_LOCALS
+
+/*
+ * reset_entry in armv7/armv7/armv7_machdep.c
+ */
-.Lundefined_target:
- .word undefined_entry
+/*
+ * Handler for the Undefined Instruction exception.
+ */
+ASENTRY_NP(undefined_entry)
+ sub lr, lr, #0x00000004 /* Adjust the lr */
+ PUSHFRAMEINSVC
+ adr lr, exception_exit
+ mov r0, sp /* pass the stack pointer as r0 */
+ b undefinedinstruction
-.Lswi_target:
- .word swi_entry
+/*
+ * Handler for the Software Interrupt exception.
+ */
+ASENTRY_NP(swi_entry)
+ PUSHFRAME
-.Lprefetch_abort_target:
- .word prefetch_abort_entry
+ mov r0, sp /* Pass the frame to any function */
+ bl swi_handler /* It's a SWI ! */
-.Ldata_abort_target:
- .word data_abort_entry
+ DO_AST
+ PULLFRAME
+ movs pc, lr /* Exit */
-.Laddress_exception_target:
- .word address_exception_entry
+/*
+ * Handler for the Prefetch Abort exception.
+ */
+ASENTRY_NP(prefetch_abort_entry)
+ sub lr, lr, #0x00000004 /* Adjust the lr */
+ PUSHFRAMEINSVC
-.Lirq_target:
- .word irq_entry
+ adr lr, exception_exit
+ mov r0, sp /* pass the stack pointer as r0 */
+ b prefetch_abort_handler
-#ifdef __ARM_FIQ_INDIRECT
-.Lfiq_target:
- .word _C_LABEL(fiqvector)
-#else
- .word 0 /* pad it out */
-#endif
-_C_LABEL(page0_end):
+/*
+ * Handler for the Data Abort exception.
+ */
+ASENTRY_NP(data_abort_entry)
+ sub lr, lr, #0x00000008 /* Adjust the lr */
+ PUSHFRAMEINSVC /* Push trap frame and switch */
+ /* to SVC32 mode */
-#ifdef __ARM_FIQ_INDIRECT
- .data
- .align 2
-_C_LABEL(fiqvector):
+ adr lr, exception_exit
+ mov r0, sp /* pass the stack pointer as r0 */
+ b data_abort_handler
+
+/*
+ * address_exception_entry in armv7/armv7/armv7_machdep.c
+ */
+
+/*
+ * General exception exit handler
+ * (Placed here to be within range of all the references to it)
+ *
+ * It exits straight away if not returning to USR mode.
+ * This loops around delivering any pending ASTs.
+ * Interrupts are disabled at suitable points to avoid ASTs
+ * being posted between testing and exit to user mode.
+ *
+ * This function uses PULLFRAMEFROMSVCANDEXIT and DO_AST thus should
+ * only be called if the exception handler used PUSHFRAMEINSVC.
+ */
+
+exception_exit:
+ DO_AST
+ PULLFRAMEFROMSVCANDEXIT
+
+/*
+ * irq_entry in arm/arm/irq_dispatch.S
+ */
+
+#ifdef FIQ
+ .text
+ .global fiq_nullhandler, fiq_nullhandler_end
+/*
+ * Null handler copied down to the FIQ vector when the last
+ * FIQ handler is removed.
+ */
+fiq_nullhandler:
subs pc, lr, #4
- .org _C_LABEL(fiqvector) + 0x100
-#endif
+fiq_nullhandler_end:
+
+ .text
+ .global fiqvector
+ /* PAGE_SIZE align, so only single pte needs editing */
+ .align 11 /* from exec to writable and back */
+fiqvector:
+ subs pc, lr, #4
+ .org fiqvector + 0x100
+#endif /* FIQ */
diff --git a/sys/arch/arm/arm/vm_machdep.c b/sys/arch/arm/arm/vm_machdep.c
index 9b2a00a92f5..44f7c9e36c5 100644
--- a/sys/arch/arm/arm/vm_machdep.c
+++ b/sys/arch/arm/arm/vm_machdep.c
@@ -62,8 +62,6 @@
#include <machine/reg.h>
#include <machine/vmparam.h>
-extern pv_addr_t systempage;
-
int process_read_regs (struct proc *p, struct reg *regs);
int process_read_fpregs (struct proc *p, struct fpreg *regs);
diff --git a/sys/arch/arm/conf/files.arm b/sys/arch/arm/conf/files.arm
index 9dae5a17689..36f624a4cfb 100644
--- a/sys/arch/arm/conf/files.arm
+++ b/sys/arch/arm/conf/files.arm
@@ -13,7 +13,6 @@ file arch/arm/arm/disassem.c ddb
# FIQ support
file arch/arm/arm/fiq.c fiq
-file arch/arm/arm/fiq_subr.S fiq
define fdt {[early = 0]}
@@ -59,7 +58,6 @@ file arch/arm/arm/arm32_machdep.c
file arch/arm/arm/bus_dma.c
file arch/arm/arm/cpu.c
file arch/arm/arm/cpuswitch7.S cpu_armv7
-file arch/arm/arm/exception.S
file arch/arm/arm/fault.c
file arch/arm/arm/mem.c
file arch/arm/arm/pmap7.c cpu_armv7
diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h
index 0477b88883f..27cd964be83 100644
--- a/sys/arch/arm/include/cpu.h
+++ b/sys/arch/arm/include/cpu.h
@@ -157,10 +157,6 @@ extern int cpu_do_powersave;
#define PROC_PC(p) ((p)->p_addr->u_pcb.pcb_tf->tf_pc)
#define PROC_STACK(p) ((p)->p_addr->u_pcb.pcb_tf->tf_usr_sp)
-/* The address of the vector page. */
-extern vaddr_t vector_page;
-void arm32_vector_init(vaddr_t, int);
-
#define ARM_VEC_RESET (1 << 0)
#define ARM_VEC_UNDEFINED (1 << 1)
#define ARM_VEC_SWI (1 << 2)
diff --git a/sys/arch/arm/include/cpufunc.h b/sys/arch/arm/include/cpufunc.h
index 65da821b49a..b07cd584a06 100644
--- a/sys/arch/arm/include/cpufunc.h
+++ b/sys/arch/arm/include/cpufunc.h
@@ -299,6 +299,17 @@ __get_cpsr()
#define restore_interrupts(old_cpsr) \
(__set_cpsr_c((PSR_I | PSR_F), (old_cpsr) & (PSR_I | PSR_F)))
+static inline u_int cpu_switch_cpsr(u_int);
+
+u_int
+cpu_switch_cpsr(u_int mode)
+{
+ u_int omode = __get_cpsr();
+ asm volatile("msr cpsr, %0\n"
+ :: "r"((omode & ~PSR_MODE) | mode));
+ return omode;
+}
+
/*
* Functions to manipulate cpu r13
* (in arm/arm/setstack.S)
diff --git a/sys/arch/arm/include/fiq.h b/sys/arch/arm/include/fiq.h
index e246323b57f..9e12393b9e1 100644
--- a/sys/arch/arm/include/fiq.h
+++ b/sys/arch/arm/include/fiq.h
@@ -40,6 +40,7 @@
#define _ARM_FIQ_H_
#include <sys/queue.h>
+#include <arm/cpufunc.h>
struct fiqregs {
u_int fr_r8; /* FIQ mode r8 */
@@ -63,7 +64,35 @@ struct fiqhandler {
int fiq_claim(struct fiqhandler *);
void fiq_release(struct fiqhandler *);
-void fiq_getregs(struct fiqregs *);
-void fiq_setregs(struct fiqregs *);
+static inline void fiq_getregs(struct fiqregs *);
+static inline void fiq_setregs(struct fiqregs *);
+
+/*
+ * Fetch the FIQ mode banked registers into the fiqhandler
+ * structure.
+ */
+void
+fiq_getregs(struct fiqregs *fr)
+{
+ u_int omode = cpu_switch_cpsr(PSR_FIQ32_MODE);
+ asm volatile(
+ "stmia %0, {r8-r13}\n"
+ "msr cpsr, %1\n"
+ :: "r"(fr), "r"(omode));
+}
+
+/*
+ * Load the FIQ mode banked registers from the fiqhandler
+ * structure.
+ */
+void
+fiq_setregs(struct fiqregs *fr)
+{
+ u_int omode = cpu_switch_cpsr(PSR_FIQ32_MODE);
+ asm volatile(
+ "ldmia %0, {r8-r13}\n"
+ "msr cpsr, %1\n"
+ : "=r"(fr) : "r"(omode));
+}
#endif /* _ARM_FIQ_H_ */
diff --git a/sys/arch/arm/include/frame.h b/sys/arch/arm/include/frame.h
index 97382ef521c..4533fcf7481 100644
--- a/sys/arch/arm/include/frame.h
+++ b/sys/arch/arm/include/frame.h
@@ -171,6 +171,8 @@ struct frame {
#else /* _LOCORE */
+#include <arm/armreg.h>
+
#define AST_LOCALS
\
.Laflt_astpending: ;\
.word _C_LABEL(astpending)
diff --git a/sys/arch/armv7/armv7/armv7_machdep.c
b/sys/arch/armv7/armv7/armv7_machdep.c
index aa1c549b29b..22c235a0d2a 100644
--- a/sys/arch/armv7/armv7/armv7_machdep.c
+++ b/sys/arch/armv7/armv7/armv7_machdep.c
@@ -164,7 +164,6 @@ int max_processes = 64; /* Default
number */
#endif /* !PMAP_STATIC_L1S */
/* Physical and virtual addresses for some global pages */
-pv_addr_t systempage;
pv_addr_t irqstack;
pv_addr_t undstack;
pv_addr_t abtstack;
@@ -178,8 +177,7 @@ extern u_int undefined_handler_address;
uint32_t board_id;
-#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero
page */
-#define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */
+#define KERNEL_PT_KERNEL 0 /* Page table for mapping kernel */
#define KERNEL_PT_KERNEL_NUM 32
#define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL+KERNEL_PT_KERNEL_NUM)
/* Page tables for mapping kernel VM */
@@ -543,15 +541,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t
loadaddr)
if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
panic("initarm: Failed to align the kernel page directory");
- /*
- * Allocate a page for the system page mapped to V0x00000000
- * This page will just contain the system vectors and can be
- * shared by all processes.
- */
- vector_page = ARM_VECTORS_HIGH;
- alloc_pages(systempage.pv_pa, 1);
- systempage.pv_va = vector_page;
-
/* Allocate stacks for all modes */
valloc_pages(irqstack, IRQ_STACK_SIZE);
valloc_pages(abtstack, ABT_STACK_SIZE);
@@ -600,9 +589,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t
loadaddr)
l1pagetable = kernel_l1pt.pv_pa;
/* Map the L2 pages tables in the L1 page table */
- pmap_link_l2pt(l1pagetable, vector_page & ~(0x00400000 - 1),
- &kernel_pt_table[KERNEL_PT_SYS]);
-
for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
&kernel_pt_table[KERNEL_PT_KERNEL + loop]);
@@ -664,10 +650,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t
loadaddr)
/* Map the Mini-Data cache clean area. */
- /* Map the vector page. */
- pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
- PROT_READ | PROT_WRITE, PTE_CACHE);
-
/* Map the FDT. */
pmap_map_chunk(l1pagetable, fdt.pv_va, fdt.pv_pa,
round_page(fdt_get_size((void *)fdt.pv_pa)),
@@ -694,8 +676,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t
loadaddr)
proc0paddr = (struct user *)kernelstack.pv_va;
proc0.p_addr = proc0paddr;
- arm32_vector_init(vector_page, ARM_VEC_ALL);
-
/*
* Pages were allocated during the secondary bootstrap for the
* stacks for different CPU modes.
@@ -712,20 +692,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t
loadaddr)
set_stackptr(PSR_UND32_MODE,
undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
- /*
- * Well we should set a data abort handler.
- * Once things get going this will change as we will need a proper
- * handler.
- * Until then we will use a handler that just panics but tells us
- * why.
- * Initialisation of the vectors will just panic on a data abort.
- * This just fills in a slighly better one.
- */
-
- data_abort_handler_address = (u_int)data_abort_handler;
- prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
- undefined_handler_address = (u_int)undefinedinstruction_bounce;
-
/* Now we can reinit the FDT, using the virtual address. */
fdt_init((void *)fdt.pv_va);
@@ -770,8 +736,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t
loadaddr)
pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, KERNEL_VM_BASE,
KERNEL_VM_BASE + KERNEL_VM_SIZE);
- vector_page_setprot(PROT_READ | PROT_EXEC);
-
/*
* Restore proper bus_space operation, now that pmap is initialized.
*/
@@ -929,3 +893,33 @@ board_startup(void)
#endif
}
}
+
+void address_exception_entry(void);
+void reset_entry(void);
+
+void
+address_exception_entry(void)
+{
+ u_int _cpsr, _spsr, _lr;
+
+ __asm volatile(
+ "mrs %0, cpsr\n"
+ "mrs %1, spsr\n"
+ "mov %2, lr\n"
+ : "=&r"(_cpsr), "=&r"(_spsr), "=&r"(_lr));
+
+ printf("Address Exception\ncpsr=%#8x spsr=%#8x lr=%#8x\n",
+ _cpsr, _spsr, _lr);
+
+ __asm volatile(
+ "mov lr, %0\n"
+ "b data_abort_entry\n" :: "r"(_lr));
+}
+
+void
+reset_entry(void)
+{
+ u_int _lr;
+ __asm volatile("mov %0, lr\n" : "=&r"(_lr));
+ panic("Reset Exception\nlr=%#8x", _lr);
+}
diff --git a/sys/arch/armv7/armv7/locore0.S b/sys/arch/armv7/armv7/locore0.S
index 2a4e98cbe8c..85cd961f3b8 100644
--- a/sys/arch/armv7/armv7/locore0.S
+++ b/sys/arch/armv7/armv7/locore0.S
@@ -160,8 +160,13 @@ _C_LABEL(bootstrap_start):
mov r0, #DOMAIN_CLIENT /* We only use domain 0 */
mcr CP15_DACR(r0)
+ /* set VBAR */
+ ldr r0, =vectors
+ mcr CP15_VBAR(r0)
+
/* Enable MMU */
mrc CP15_SCTLR(r0)
+ bic r0, r0, #CPU_CONTROL_VECRELOC /* our vectors are at VBAR */
orr r0, r0, #CPU_CONTROL_MMU_ENABLE
mcr CP15_SCTLR(r0)
CPWAIT(r0)