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)

Reply via email to