From owner-svn-src-all@FreeBSD.ORG Sat May 17 00:53:15 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id BEA4F8F7; Sat, 17 May 2014 00:53:15 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A6E7F2AD8; Sat, 17 May 2014 00:53:15 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4H0rFke050845; Sat, 17 May 2014 00:53:15 GMT (envelope-from ian@svn.freebsd.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4H0rD0f050831; Sat, 17 May 2014 00:53:13 GMT (envelope-from ian@svn.freebsd.org) Message-Id: <201405170053.s4H0rD0f050831@svn.freebsd.org> From: Ian Lepore Date: Sat, 17 May 2014 00:53:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r266277 - in stable/10/sys: arm/allwinner arm/allwinner/a20 arm/arm arm/at91 arm/broadcom/bcm2835 arm/conf arm/freescale/imx arm/include arm/mv arm/rockchip arm/samsung/exynos arm/tegra... X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 May 2014 00:53:15 -0000 Author: ian Date: Sat May 17 00:53:12 2014 New Revision: 266277 URL: http://svnweb.freebsd.org/changeset/base/266277 Log: MFC 257774, 256760, 262916, 262905, 262918, 262919, 262920, 262921, 262924, 262925, 262929, 262932, 262935, 262940, 262941, 262942, 262948, 262949, 262950 Strip arm/conf/DEFAULTS down to just items that are mandatory for running the architecture. Move all the files named foo/common.c to foo/foo_common.c Initial cut for DTS on the hl201 board. Add commented out dts for sam9260ek as well as early printf support. Make clock optional on uart nodes, then back it out ("I don't know what I was thinking, but it is lame.") Set the baud rate if it isn't 0 Make at91_soc_id() public. Properly round at91 resource on unmapping. Move AT91 AIC related stuff to own file. Fix another bug in multicast filtering. i.MX uses 6 bits from MSB in LE CRC32 for the hash value, not the lowest 6 bits in BE CRC32. Follow r262916 with one more config file that references a renamed common.c Remove bogus AT91 define that causes compile errors. Most of the defines for SAM9X are going away soonish anyway (once FDT works), but until then... Remove all dregs of a per-thread undefined-exception-mode stack. Rework the VFP code that handles demand-based save and restore of state. Always call vfp_discard() on thread death. When a thread begins life it doesn't own the VFP hardware state on any cpu. Make undefined exception entry MP-safe. Added: stable/10/sys/arm/allwinner/a10_common.c - copied unchanged from r262916, head/sys/arm/allwinner/a10_common.c stable/10/sys/arm/at91/at91_aic.c - copied unchanged from r262925, head/sys/arm/at91/at91_aic.c stable/10/sys/arm/broadcom/bcm2835/bcm2835_common.c - copied unchanged from r262916, head/sys/arm/broadcom/bcm2835/bcm2835_common.c stable/10/sys/arm/freescale/imx/imx_common.c - copied unchanged from r262916, head/sys/arm/freescale/imx/imx_common.c stable/10/sys/arm/mv/mv_common.c - copied unchanged from r262916, head/sys/arm/mv/mv_common.c stable/10/sys/arm/rockchip/rk30xx_common.c - copied unchanged from r262916, head/sys/arm/rockchip/rk30xx_common.c stable/10/sys/arm/samsung/exynos/exynos5_common.c - copied unchanged from r262916, head/sys/arm/samsung/exynos/exynos5_common.c stable/10/sys/arm/tegra/tegra2_common.c - copied unchanged from r262916, head/sys/arm/tegra/tegra2_common.c stable/10/sys/arm/ti/ti_common.c - copied unchanged from r262916, head/sys/arm/ti/ti_common.c stable/10/sys/arm/versatile/versatile_common.c - copied unchanged from r262916, head/sys/arm/versatile/versatile_common.c stable/10/sys/boot/fdt/dts/arm/hl201.dts - copied unchanged from r262918, head/sys/boot/fdt/dts/arm/hl201.dts Deleted: stable/10/sys/arm/allwinner/common.c stable/10/sys/arm/broadcom/bcm2835/bus_space.c stable/10/sys/arm/broadcom/bcm2835/common.c stable/10/sys/arm/freescale/imx/common.c stable/10/sys/arm/mv/common.c stable/10/sys/arm/rockchip/common.c stable/10/sys/arm/samsung/exynos/common.c stable/10/sys/arm/tegra/common.c stable/10/sys/arm/ti/common.c stable/10/sys/arm/versatile/common.c Modified: stable/10/sys/arm/allwinner/a20/files.a20 stable/10/sys/arm/allwinner/files.a10 stable/10/sys/arm/arm/exception.S stable/10/sys/arm/arm/genassym.c stable/10/sys/arm/arm/machdep.c stable/10/sys/arm/arm/swtch.S stable/10/sys/arm/arm/undefined.c stable/10/sys/arm/arm/vfp.c stable/10/sys/arm/arm/vm_machdep.c stable/10/sys/arm/at91/at91.c stable/10/sys/arm/at91/at91rm9200.c stable/10/sys/arm/at91/at91sam9g20.c stable/10/sys/arm/at91/at91sam9g20reg.h stable/10/sys/arm/at91/at91sam9x5.c stable/10/sys/arm/at91/files.at91 stable/10/sys/arm/broadcom/bcm2835/files.bcm2835 stable/10/sys/arm/conf/AC100 stable/10/sys/arm/conf/ARMADAXP stable/10/sys/arm/conf/ARNDALE stable/10/sys/arm/conf/ATMEL stable/10/sys/arm/conf/AVILA stable/10/sys/arm/conf/BEAGLEBONE stable/10/sys/arm/conf/BWCT stable/10/sys/arm/conf/CAMBRIA stable/10/sys/arm/conf/CNS11XXNAS stable/10/sys/arm/conf/CRB stable/10/sys/arm/conf/CUBIEBOARD stable/10/sys/arm/conf/CUBIEBOARD2 stable/10/sys/arm/conf/DB-78XXX stable/10/sys/arm/conf/DB-88F5XXX stable/10/sys/arm/conf/DB-88F6XXX stable/10/sys/arm/conf/DEFAULTS stable/10/sys/arm/conf/DIGI-CCWMX53 stable/10/sys/arm/conf/DOCKSTAR stable/10/sys/arm/conf/DREAMPLUG-1001 stable/10/sys/arm/conf/EA3250 stable/10/sys/arm/conf/EB9200 stable/10/sys/arm/conf/EFIKA_MX stable/10/sys/arm/conf/EP80219 stable/10/sys/arm/conf/ETHERNUT5 stable/10/sys/arm/conf/GUMSTIX stable/10/sys/arm/conf/HL200 stable/10/sys/arm/conf/HL201 stable/10/sys/arm/conf/IMX53-QSB stable/10/sys/arm/conf/IMX6 stable/10/sys/arm/conf/IQ31244 stable/10/sys/arm/conf/KB920X stable/10/sys/arm/conf/LN2410SBC stable/10/sys/arm/conf/NSLU stable/10/sys/arm/conf/PANDABOARD stable/10/sys/arm/conf/QILA9G20 stable/10/sys/arm/conf/RADXA stable/10/sys/arm/conf/RPI-B stable/10/sys/arm/conf/SAM9260EK stable/10/sys/arm/conf/SAM9G20EK stable/10/sys/arm/conf/SAM9X25EK stable/10/sys/arm/conf/SHEEVAPLUG stable/10/sys/arm/conf/SIMICS stable/10/sys/arm/conf/SN9G45 stable/10/sys/arm/conf/TS7800 stable/10/sys/arm/conf/VERSATILEPB stable/10/sys/arm/conf/VYBRID.common stable/10/sys/arm/conf/ZEDBOARD stable/10/sys/arm/freescale/imx/files.imx51 stable/10/sys/arm/freescale/imx/files.imx53 stable/10/sys/arm/freescale/imx/files.imx6 stable/10/sys/arm/include/param.h stable/10/sys/arm/include/pcb.h stable/10/sys/arm/include/pcpu.h stable/10/sys/arm/include/vfp.h stable/10/sys/arm/mv/files.mv stable/10/sys/arm/mv/mvreg.h stable/10/sys/arm/rockchip/files.rk30xx stable/10/sys/arm/samsung/exynos/files.exynos5 stable/10/sys/arm/tegra/files.tegra2 stable/10/sys/arm/ti/files.ti stable/10/sys/arm/versatile/files.versatile stable/10/sys/dev/ffec/if_ffec.c stable/10/sys/dev/uart/uart_bus_fdt.c Directory Properties: stable/10/ (props changed) Copied: stable/10/sys/arm/allwinner/a10_common.c (from r262916, head/sys/arm/allwinner/a10_common.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/arm/allwinner/a10_common.c Sat May 17 00:53:12 2014 (r266277, copy of r262916, head/sys/arm/allwinner/a10_common.c) @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2012 Ganbold Tsagaankhuu + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +struct fdt_fixup_entry fdt_fixup_table[] = { + { NULL, NULL } +}; + +static int +fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, + int *pol) +{ + int offset; + + if (fdt_is_compatible(node, "allwinner,sun4i-ic")) + offset = 0; + else if (fdt_is_compatible(node, "arm,gic")) + offset = 32; + else + return (ENXIO); + + *interrupt = fdt32_to_cpu(intr[0]) + offset; + *trig = INTR_TRIGGER_CONFORM; + *pol = INTR_POLARITY_CONFORM; + + return (0); +} + +fdt_pic_decode_t fdt_pic_table[] = { + &fdt_aintc_decode_ic, + NULL +}; Modified: stable/10/sys/arm/allwinner/a20/files.a20 ============================================================================== --- stable/10/sys/arm/allwinner/a20/files.a20 Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/allwinner/a20/files.a20 Sat May 17 00:53:12 2014 (r266277) @@ -19,5 +19,5 @@ arm/allwinner/if_emac.c optional emac arm/allwinner/a10_wdog.c standard arm/allwinner/timer.c standard arm/allwinner/bus_space.c standard -arm/allwinner/common.c standard +arm/allwinner/a10_common.c standard arm/allwinner/a10_machdep.c standard Modified: stable/10/sys/arm/allwinner/files.a10 ============================================================================== --- stable/10/sys/arm/allwinner/files.a10 Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/allwinner/files.a10 Sat May 17 00:53:12 2014 (r266277) @@ -9,16 +9,16 @@ arm/arm/cpufunc_asm_arm11.S standard arm/arm/cpufunc_asm_armv7.S standard arm/arm/irq_dispatch.S standard -arm/allwinner/a20/a20_cpu_cfg.c standard arm/allwinner/a10_clk.c standard -arm/allwinner/a10_sramc.c standard +arm/allwinner/a10_common.c standard arm/allwinner/a10_gpio.c optional gpio arm/allwinner/a10_ehci.c optional ehci -arm/allwinner/if_emac.c optional emac +arm/allwinner/a10_machdep.c standard +arm/allwinner/a10_sramc.c standard arm/allwinner/a10_wdog.c standard -arm/allwinner/timer.c standard +arm/allwinner/a20/a20_cpu_cfg.c standard arm/allwinner/aintc.c standard +arm/allwinner/if_emac.c optional emac +arm/allwinner/timer.c standard arm/allwinner/bus_space.c standard -arm/allwinner/common.c standard #arm/allwinner/console.c standard -arm/allwinner/a10_machdep.c standard Modified: stable/10/sys/arm/arm/exception.S ============================================================================== --- stable/10/sys/arm/arm/exception.S Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/arm/exception.S Sat May 17 00:53:12 2014 (r266277) @@ -218,46 +218,25 @@ END(exception_exit) * 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 + sub lr, lr, #0x00000004 /* Adjust the lr */ + PUSHFRAMEINSVC /* Push trap frame and switch */ + /* to SVC32 mode */ + ldr r1, Lundefined_handler_address + adr lr, exception_exit + mov r0, sp /* pass the stack pointer as r0 */ + ldr pc, [r1] END(undefined_entry) -/* - * 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 +ASENTRY_NP(undefinedinstruction_bounce) + b undefinedinstruction +END(undefinedinstruction_bounce) - mov r0, sp - adr lr, exception_exit - b _C_LABEL(undefinedinstruction) +Lundefined_handler_address: + .word _C_LABEL(undefined_handler_address) .data - .align 0 - -/* - * 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) -END(undefinedinstruction_bounce) + .word undefinedinstruction_bounce + Modified: stable/10/sys/arm/arm/genassym.c ============================================================================== --- stable/10/sys/arm/arm/genassym.c Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/arm/genassym.c Sat May 17 00:53:12 2014 (r266277) @@ -60,7 +60,6 @@ ASSYM(PCB_NOALIGNFLT, PCB_NOALIGNFLT); ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr)); ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); -ASSYM(PCB_UND_SP, offsetof(struct pcb, un_32.pcb32_und_sp)); ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir)); ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec)); ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec)); @@ -119,9 +118,7 @@ ASSYM(ARM_RAS_END, ARM_RAS_END); #ifdef VFP ASSYM(PCB_VFPSTATE, offsetof(struct pcb, pcb_vfpstate)); -ASSYM(PCB_VFPCPU, offsetof(struct pcb, pcb_vfpcpu)); -ASSYM(PC_VFPCTHREAD, offsetof(struct pcpu, pc_vfpcthread)); ASSYM(PC_CPU, offsetof(struct pcpu, pc_cpu)); ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap)); Modified: stable/10/sys/arm/arm/machdep.c ============================================================================== --- stable/10/sys/arm/arm/machdep.c Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/arm/machdep.c Sat May 17 00:53:12 2014 (r266277) @@ -379,8 +379,6 @@ cpu_startup(void *dummy) bufinit(); vm_pager_bufferinit(); - pcb->un_32.pcb32_und_sp = (u_int)thread0.td_kstack + - USPACE_UNDEF_STACK_TOP; pcb->un_32.pcb32_sp = (u_int)thread0.td_kstack + USPACE_SVC_STACK_TOP; vector_page_setprot(VM_PROT_READ); @@ -995,6 +993,7 @@ init_proc0(vm_offset_t kstack) thread0.td_pcb = (struct pcb *) (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; thread0.td_pcb->pcb_flags = 0; + thread0.td_pcb->pcb_vfpcpu = -1; thread0.td_frame = &proc0_tf; pcpup->pc_curpcb = thread0.td_pcb; } Modified: stable/10/sys/arm/arm/swtch.S ============================================================================== --- stable/10/sys/arm/arm/swtch.S Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/arm/swtch.S Sat May 17 00:53:12 2014 (r266277) @@ -84,6 +84,8 @@ #include #include #include +#include + __FBSDID("$FreeBSD$"); #define DOMAIN_CLIENT 0x01 @@ -102,6 +104,10 @@ __FBSDID("$FreeBSD$"); ldr tmp, .Lcurpcpu #endif +#ifdef VFP + .fpu vfp /* allow VFP instructions */ +#endif + .Lcurpcpu: .word _C_LABEL(__pcpu) .word PCPU_SIZE @@ -118,20 +124,11 @@ ENTRY(cpu_throw) * r5 = newtd */ - GET_PCPU(r7, r9) - -#ifdef VFP - /* - * vfp_discard will clear pcpu->pc_vfpcthread, and modify - * and modify the control as needed. - */ - ldr r4, [r7, #(PC_VFPCTHREAD)] /* this thread using vfp? */ - cmp r0, r4 - bne 3f - bl _C_LABEL(vfp_discard) /* yes, shut down vfp */ -3: -#endif /* VFP */ +#ifdef VFP /* This thread is dying, disable */ + bl _C_LABEL(vfp_discard) /* VFP without preserving state. */ +#endif + GET_PCPU(r7, r9) ldr r7, [r5, #(TD_PCB)] /* r7 = new thread's PCB */ /* Switch to lwp0 context */ @@ -303,46 +300,19 @@ ENTRY(cpu_switch) /* Get the user structure for the new process in r9 */ ldr r9, [r1, #(TD_PCB)] - mrs r3, cpsr - /* - * We can do that, since - * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE - */ - orr r8, r3, #(PSR_UND32_MODE) - msr cpsr_c, r8 - - str sp, [r2, #(PCB_UND_SP)] - - msr cpsr_c, r3 /* Restore the old mode */ /* rem: r2 = old PCB */ /* rem: r9 = new PCB */ /* rem: interrupts are enabled */ #ifdef VFP - /* - * vfp_store will clear pcpu->pc_vfpcthread, save - * registers and state, and modify the control as needed. - * a future exception will bounce the backup settings in the fp unit. - * XXX vfp_store can't change r4 - */ - GET_PCPU(r7, r8) - ldr r8, [r7, #(PC_VFPCTHREAD)] - cmp r4, r8 /* old thread used vfp? */ - bne 1f /* no, don't save */ - cmp r1, r4 /* same thread ? */ - beq 1f /* yes, skip vfp store */ -#ifdef SMP - ldr r8, [r7, #(PC_CPU)] /* last used on this cpu? */ - ldr r3, [r2, #(PCB_VFPCPU)] - cmp r8, r3 /* last cpu to use these registers? */ - bne 1f /* no. these values are stale */ + fmrx r0, fpexc /* If the VFP is enabled */ + tst r0, #(VFPEXC_EN) /* the current thread has */ + movne r1, #1 /* used it, so go save */ + addne r0, r2, #(PCB_VFPSTATE) /* the state into the PCB */ + blne _C_LABEL(vfp_store) /* and disable the VFP. */ #endif - add r0, r2, #(PCB_VFPSTATE) - bl _C_LABEL(vfp_store) -1: -#endif /* VFP */ - /* r1 now free! */ + /* r0-r3 now free! */ /* Third phase : restore saved context */ @@ -438,10 +408,6 @@ ENTRY(cpu_switch) movne r0, #0 /* We *know* vector_page's VA is 0x0 */ movne lr, pc ldrne pc, [r10, #CF_TLB_FLUSHID_SE] - /* - * We can do that, since - * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE - */ .Lcs_context_switched: @@ -460,17 +426,6 @@ ENTRY(cpu_switch) /* rem: r9 = new PCB */ - mrs r3, cpsr - /* - * We can do that, since - * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE - */ - orr r2, r3, #(PSR_UND32_MODE) - msr cpsr_c, r2 - - ldr sp, [r9, #(PCB_UND_SP)] - - msr cpsr_c, r3 /* Restore the old mode */ /* Restore all the save registers */ #ifndef _ARM_ARCH_5E add r7, r9, #PCB_R8 @@ -520,26 +475,12 @@ ENTRY(savectx) add r2, r0, #(PCB_R8) stmia r2, {r8-r13} #ifdef VFP - /* - * vfp_store will clear pcpu->pc_vfpcthread, save - * registers and state, and modify the control as needed. - * a future exception will bounce the backup settings in the fp unit. - */ - GET_PCPU(r7, r4) - ldr r4, [r7, #(PC_VFPCTHREAD)] /* vfp thread */ - ldr r2, [r7, #(PC_CURTHREAD)] /* current thread */ - cmp r4, r2 - bne 1f -#ifdef SMP - ldr r2, [r7, #(PC_CPU)] /* last used on this cpu? */ - ldr r3, [r0, #(PCB_VFPCPU)] - cmp r2, r3 - bne 1f /* no. these values are stale */ + fmrx r2, fpexc /* If the VFP is enabled */ + tst r2, #(VFPEXC_EN) /* the current thread has */ + movne r1, #1 /* used it, so go save */ + addne r0, r0, #(PCB_VFPSTATE) /* the state into the PCB */ + blne _C_LABEL(vfp_store) /* and disable the VFP. */ #endif - add r0, r0, #(PCB_VFPSTATE) - bl _C_LABEL(vfp_store) -1: -#endif /* VFP */ add sp, sp, #4; ldmfd sp!, {r4-r7, pc} END(savectx) Modified: stable/10/sys/arm/arm/undefined.c ============================================================================== --- stable/10/sys/arm/arm/undefined.c Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/arm/undefined.c Sat May 17 00:53:12 2014 (r266277) @@ -183,7 +183,6 @@ undefinedinstruction(struct trapframe *f if (!(frame->tf_spsr & I32_bit)) enable_interrupts(I32_bit|F32_bit); - frame->tf_pc -= INSN_SIZE; PCPU_INC(cnt.v_trap); fault_pc = frame->tf_pc; Modified: stable/10/sys/arm/arm/vfp.c ============================================================================== --- stable/10/sys/arm/arm/vfp.c Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/arm/vfp.c Sat May 17 00:53:12 2014 (r266277) @@ -1,4 +1,5 @@ -/* +/*- + * Copyright (c) 2014 Ian Lepore * Copyright (c) 2012 Mark Tinguely * * All rights reserved. @@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -41,12 +43,8 @@ __FBSDID("$FreeBSD$"); #include /* function prototypes */ -unsigned int get_coprocessorACR(void); static int vfp_bounce(u_int, u_int, struct trapframe *, int); static void vfp_restore(struct vfp_state *); -void vfp_discard(void); -void vfp_store(struct vfp_state *); -void set_coprocessorACR(u_int); extern int vfp_exists; static struct undefined_handler vfp10_uh, vfp11_uh; @@ -64,7 +62,20 @@ static int is_d32; val; \ }) -u_int +/* + * Work around an issue with GCC where the asm it generates is not unified + * syntax and fails to assemble because it expects the ldcleq instruction in the + * form ldcl, not in the UAL form ldcl, and similar for stcleq. + */ +#ifdef __clang__ +#define LDCLNE "ldclne " +#define STCLNE "stclne " +#else +#define LDCLNE "ldcnel " +#define STCLNE "stcnel " +#endif + +static u_int get_coprocessorACR(void) { u_int val; @@ -72,7 +83,7 @@ get_coprocessorACR(void) return val; } -void +static void set_coprocessorACR(u_int val) { __asm __volatile("mcr p15, 0, %0, c1, c0, 2\n\t" @@ -136,147 +147,105 @@ SYSINIT(vfp, SI_SUB_CPU, SI_ORDER_ANY, v static int vfp_bounce(u_int addr, u_int insn, struct trapframe *frame, int code) { - u_int fpexc; + u_int cpu, fpexc; struct pcb *curpcb; - struct thread *vfptd; - int i; - if (!vfp_exists) - return 1; /* vfp does not exist */ - i = disable_interrupts(I32_bit|F32_bit); - fpexc = fmrx(VFPEXC); /* read the vfp exception reg */ - if (fpexc & VFPEXC_EN) { - vfptd = PCPU_GET(vfpcthread); - /* did the kernel call the vfp or exception that expect us - * to emulate the command. Newer hardware does not require - * emulation, so we don't emulate yet. - */ -#ifdef SMP - /* don't save if newer registers are on another processor */ - if (vfptd /* && (vfptd == curthread) */ && - (vfptd->td_pcb->pcb_vfpcpu == PCPU_GET(cpu))) -#else - /* someone did not save their registers, */ - if (vfptd /* && (vfptd == curthread) */) -#endif - vfp_store(&vfptd->td_pcb->pcb_vfpstate); + if ((code & FAULT_USER) == 0) + panic("undefined floating point instruction in supervisor mode"); - fpexc &= ~VFPEXC_EN; - fmxr(VFPEXC, fpexc); /* turn vfp hardware off */ - if (vfptd == curthread) { - /* kill the process - we do not handle emulation */ - restore_interrupts(i); - killproc(curthread->td_proc, "vfp emulation"); - return 1; - } - /* should not happen. someone did not save their context */ - printf("vfp_bounce: vfpcthread: %p curthread: %p\n", - vfptd, curthread); + critical_enter(); + + /* + * If the VFP is already on and we got an undefined instruction, then + * something tried to executate a truly invalid instruction that maps to + * the VFP. + */ + fpexc = fmrx(VFPEXC); + if (fpexc & VFPEXC_EN) { + /* kill the process - we do not handle emulation */ + critical_exit(); + killproc(curthread->td_proc, "vfp emulation"); + return 1; } - fpexc |= VFPEXC_EN; - fmxr(VFPEXC, fpexc); /* enable the vfp and repeat command */ - curpcb = curthread->td_pcb; - /* If we were the last process to use the VFP, the process did not - * use a VFP on another processor, then the registers in the VFP - * will still be ours and are current. Eventually, we will make the - * restore smarter. + + /* + * If the last time this thread used the VFP it was on this core, and + * the last thread to use the VFP on this core was this thread, then the + * VFP state is valid, otherwise restore this thread's state to the VFP. */ - vfp_restore(&curpcb->pcb_vfpstate); -#ifdef SMP - curpcb->pcb_vfpcpu = PCPU_GET(cpu); -#endif - PCPU_SET(vfpcthread, curthread); - restore_interrupts(i); - return 0; + fmxr(VFPEXC, fpexc | VFPEXC_EN); + curpcb = curthread->td_pcb; + cpu = PCPU_GET(cpu); + if (curpcb->pcb_vfpcpu != cpu || curthread != PCPU_GET(fpcurthread)) { + vfp_restore(&curpcb->pcb_vfpstate); + curpcb->pcb_vfpcpu = cpu; + PCPU_SET(fpcurthread, curthread); + } + + critical_exit(); + return (0); } -/* vfs_store is called from from a VFP command to restore the registers and - * turn on the VFP hardware. - * Eventually we will use the information that this process was the last - * to use the VFP hardware and bypass the restore, just turn on the hardware. +/* + * Restore the given state to the VFP hardware. */ static void vfp_restore(struct vfp_state *vfpsave) { u_int vfpscr = 0; - /* - * Work around an issue with GCC where the asm it generates is - * not unified syntax and fails to assemble because it expects - * the ldcleq instruction in the form ldcl, not in the UAL - * form ldcl, and similar for stcleq. - */ -#ifdef __clang__ -#define ldclne "ldclne" -#define stclne "stclne" -#else -#define ldclne "ldcnel" -#define stclne "stcnel" -#endif - if (vfpsave) { - __asm __volatile("ldc p10, c0, [%1], #128\n" /* d0-d15 */ + __asm __volatile("ldc p10, c0, [%1], #128\n" /* d0-d15 */ "cmp %2, #0\n" /* -D16 or -D32? */ - ldclne" p11, c0, [%1], #128\n" /* d16-d31 */ + LDCLNE "p11, c0, [%1], #128\n" /* d16-d31 */ "addeq %1, %1, #128\n" /* skip missing regs */ "ldr %0, [%1]\n" /* set old vfpscr */ "mcr p10, 7, %0, cr1, c0, 0\n" : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc"); - } } -/* vfs_store is called from switch to save the vfp hardware registers - * into the pcb before switching to another process. - * we already know that the new process is different from this old - * process and that this process last used the VFP registers. - * Below we check to see if the VFP has been enabled since the last - * register save. - * This routine will exit with the VFP turned off. The next VFP user - * will trap to restore its registers and turn on the VFP hardware. +/* + * If the VFP is on, save its current state and turn it off if requested to do + * so. If the VFP is not on, does not change the values at *vfpsave. Caller is + * responsible for preventing a context switch while this is running. */ void -vfp_store(struct vfp_state *vfpsave) +vfp_store(struct vfp_state *vfpsave, boolean_t disable_vfp) { - u_int tmp, vfpscr = 0; + u_int tmp, vfpscr; tmp = fmrx(VFPEXC); /* Is the vfp enabled? */ - if (vfpsave && (tmp & VFPEXC_EN)) { - __asm __volatile("stc p11, c0, [%1], #128\n" /* d0-d15 */ + if (tmp & VFPEXC_EN) { + __asm __volatile( + "stc p11, c0, [%1], #128\n" /* d0-d15 */ "cmp %2, #0\n" /* -D16 or -D32? */ - stclne" p11, c0, [%1], #128\n" /* d16-d31 */ + STCLNE "p11, c0, [%1], #128\n" /* d16-d31 */ "addeq %1, %1, #128\n" /* skip missing regs */ "mrc p10, 7, %0, cr1, c0, 0\n" /* fmxr(VFPSCR) */ "str %0, [%1]\n" /* save vfpscr */ : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc"); + if (disable_vfp) + fmxr(VFPEXC , tmp & ~VFPEXC_EN); } -#undef ldcleq -#undef stcleq - -#ifndef SMP - /* eventually we will use this information for UP also */ - PCPU_SET(vfpcthread, 0); -#endif - tmp &= ~VFPEXC_EN; /* disable the vfp hardware */ - fmxr(VFPEXC , tmp); } -/* discard the registers at cpu_thread_free() when fpcurthread == td. - * Turn off the VFP hardware. +/* + * The current thread is dying. If the state currently in the hardware belongs + * to the current thread, set fpcurthread to NULL to indicate that the VFP + * hardware state does not belong to any thread. If the VFP is on, turn it off. + * Called only from cpu_throw(), so we don't have to worry about a context + * switch here. */ void -vfp_discard() +vfp_discard(struct thread *td) { - u_int tmp = 0; + u_int tmp; + + if (PCPU_GET(fpcurthread) == td) + PCPU_SET(fpcurthread, NULL); - /* - * No need to protect the access to vfpcthread by disabling - * interrupts, since it's called from cpu_throw(), who is called - * with interrupts disabled. - */ - - PCPU_SET(vfpcthread, 0); /* permanent forget about reg */ tmp = fmrx(VFPEXC); - tmp &= ~VFPEXC_EN; /* turn off VFP hardware */ - fmxr(VFPEXC, tmp); + if (tmp & VFPEXC_EN) + fmxr(VFPEXC, tmp & ~VFPEXC_EN); } #endif Modified: stable/10/sys/arm/arm/vm_machdep.c ============================================================================== --- stable/10/sys/arm/arm/vm_machdep.c Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/arm/vm_machdep.c Sat May 17 00:53:12 2014 (r266277) @@ -144,9 +144,9 @@ cpu_fork(register struct thread *td1, re bcopy(td1->td_pcb, pcb2, sizeof(*pcb2)); mdp2 = &p2->p_md; bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2)); - pcb2->un_32.pcb32_und_sp = td2->td_kstack + USPACE_UNDEF_STACK_TOP; pcb2->un_32.pcb32_sp = td2->td_kstack + USPACE_SVC_STACK_TOP - sizeof(*pcb2); + pcb2->pcb_vfpcpu = -1; pmap_activate(td2); td2->td_frame = tf = (struct trapframe *)STACKALIGN( pcb2->un_32.pcb32_sp - sizeof(struct trapframe)); @@ -366,7 +366,6 @@ cpu_set_upcall(struct thread *td, struct tf->tf_spsr &= ~PSR_C_bit; tf->tf_r0 = 0; td->td_pcb->un_32.pcb32_sp = (u_int)sf; - td->td_pcb->un_32.pcb32_und_sp = td->td_kstack + USPACE_UNDEF_STACK_TOP; KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0, ("cpu_set_upcall: Incorrect stack alignment")); Modified: stable/10/sys/arm/at91/at91.c ============================================================================== --- stable/10/sys/arm/at91/at91.c Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/at91/at91.c Sat May 17 00:53:12 2014 (r266277) @@ -24,6 +24,8 @@ * SUCH DAMAGE. */ +#include "opt_platform.h" + #include __FBSDID("$FreeBSD$"); @@ -49,12 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include -static struct at91_softc *at91_softc; - -static void at91_eoi(void *); - -extern const struct arm_devmap_entry at91_devmap[]; - uint32_t at91_master_clock; static int @@ -84,8 +80,12 @@ at91_bs_unmap(void *t, bus_space_handle_ { vm_offset_t va, endva; + if (t == 0) + return; va = trunc_page((vm_offset_t)t); - endva = va + round_page(size); + if (va >= AT91_BASE && va <= AT91_BASE + 0xff00000) + return; + endva = round_page((vm_offset_t)t + size); /* Free the kernel virtual mapping. */ kva_free(va, endva - va); @@ -229,6 +229,12 @@ struct bus_space at91_bs_tag = { NULL, }; +#ifndef FDT + +static struct at91_softc *at91_softc; + +static void at91_eoi(void *); + static int at91_probe(device_t dev) { @@ -260,7 +266,6 @@ static int at91_attach(device_t dev) { struct at91_softc *sc = device_get_softc(dev); - int i; arm_post_filter = at91_eoi; @@ -290,29 +295,6 @@ at91_attach(device_t dev) 0xfffffffful) != 0) panic("at91_attach: failed to set up memory rman"); - /* - * Setup the interrupt table. - */ - if (soc_info.soc_data == NULL || soc_info.soc_data->soc_irq_prio == NULL) - panic("Interrupt priority table missing\n"); - for (i = 0; i < 32; i++) { - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR + - i * 4, i); - /* Priority. */ - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4, - soc_info.soc_data->soc_irq_prio[i]); - if (i < 8) - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR, - 1); - } - - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32); - /* No debug. */ - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0); - /* Disable and clear all interrupts. */ - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff); - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff); - /* * Add this device's children... */ @@ -472,42 +454,6 @@ at91_print_child(device_t dev, device_t return (retval); } -void -arm_mask_irq(uintptr_t nb) -{ - - bus_space_write_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_IDCR, 1 << nb); -} - -int -arm_get_next_irq(int last __unused) -{ - int status; - int irq; - - irq = bus_space_read_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_IVR); - status = bus_space_read_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_ISR); - if (status == 0) { - bus_space_write_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_EOICR, 1); - return (-1); - } - return (irq); -} - -void -arm_unmask_irq(uintptr_t nb) -{ - - bus_space_write_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_IECR, 1 << nb); - bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh, - IC_EOICR, 0); -} - static void at91_eoi(void *unused) { @@ -584,3 +530,4 @@ static driver_t at91_driver = { static devclass_t at91_devclass; DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0); +#endif Copied: stable/10/sys/arm/at91/at91_aic.c (from r262925, head/sys/arm/at91/at91_aic.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/arm/at91/at91_aic.c Sat May 17 00:53:12 2014 (r266277, copy of r262925, head/sys/arm/at91/at91_aic.c) @@ -0,0 +1,188 @@ +/*- + * Copyright (c) 2014 Warner Losh. All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``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 AUTHOR 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. + */ + +#include "opt_platform.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef FDT +#include +#include +#include +#endif + +static struct aic_softc { + struct resource *mem_res; /* Memory resource */ + void *intrhand; /* Interrupt handle */ + device_t sc_dev; +} *sc; + +static inline uint32_t +RD4(struct aic_softc *sc, bus_size_t off) +{ + + return (bus_read_4(sc->mem_res, off)); +} + +static inline void +WR4(struct aic_softc *sc, bus_size_t off, uint32_t val) +{ + + bus_write_4(sc->mem_res, off, val); +} + +void +arm_mask_irq(uintptr_t nb) +{ + + WR4(sc, IC_IDCR, 1 << nb); +} + +int +arm_get_next_irq(int last __unused) +{ + int status; + int irq; + + irq = RD4(sc, IC_IVR); + status = RD4(sc, IC_ISR); + if (status == 0) { + WR4(sc, IC_EOICR, 1); + return (-1); + } + return (irq); +} + +void +arm_unmask_irq(uintptr_t nb) +{ + + WR4(sc, IC_IECR, 1 << nb); + WR4(sc, IC_EOICR, 0); +} + +static int +at91_aic_probe(device_t dev) +{ +#ifdef FDT + if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-aic")) + return (ENXIO); +#endif + device_set_desc(dev, "AIC"); + return (0); +} + +static int +at91_aic_attach(device_t dev) +{ + int i, rid, err = 0; + + device_printf(dev, "Attach %d\n", bus_current_pass); + + sc = device_get_softc(dev); + sc->sc_dev = dev; + + rid = 0; + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + + if (sc->mem_res == NULL) + panic("couldn't allocate register resources"); + + /* + * Setup the interrupt table. + */ + if (soc_info.soc_data == NULL || soc_info.soc_data->soc_irq_prio == NULL) + panic("Interrupt priority table missing\n"); + for (i = 0; i < 32; i++) { + WR4(sc, IC_SVR + i * 4, i); + /* Priority. */ + WR4(sc, IC_SMR + i * 4, soc_info.soc_data->soc_irq_prio[i]); + if (i < 8) + WR4(sc, IC_EOICR, 1); + } + + WR4(sc, IC_SPU, 32); + /* No debug. */ + WR4(sc, IC_DCR, 0); + /* Disable and clear all interrupts. */ + WR4(sc, IC_IDCR, 0xffffffff); + WR4(sc, IC_ICCR, 0xffffffff); + enable_interrupts(I32_bit | F32_bit); + + return (err); +} + +static void +at91_aic_new_pass(device_t dev) +{ + device_printf(dev, "Pass %d\n", bus_current_pass); +} + +static device_method_t at91_aic_methods[] = { + DEVMETHOD(device_probe, at91_aic_probe), + DEVMETHOD(device_attach, at91_aic_attach), + DEVMETHOD(bus_new_pass, at91_aic_new_pass), + DEVMETHOD_END +}; + +static driver_t at91_aic_driver = { + "at91_aic", + at91_aic_methods, + sizeof(struct aic_softc), +}; + +static devclass_t at91_aic_devclass; + +#ifdef FDT +DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass, NULL, + NULL); +#else +DRIVER_MODULE(at91_aic, atmelarm, at91_aic_driver, at91_aic_devclass, NULL, + NULL); +#endif +/* not yet +EARLY_DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass, + NULL, NULL, BUS_PASS_INTERRUPT); +*/ Modified: stable/10/sys/arm/at91/at91rm9200.c ============================================================================== --- stable/10/sys/arm/at91/at91rm9200.c Sat May 17 00:09:12 2014 (r266276) +++ stable/10/sys/arm/at91/at91rm9200.c Sat May 17 00:53:12 2014 (r266277) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***