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)