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...
Ian Lepore
ian at FreeBSD.org
Sat May 17 00:53:15 UTC 2014
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 <ganbold at gmail.com>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+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 <machine/asm.h>
#include <machine/asmacros.h>
#include <machine/armreg.h>
+#include <machine/vfp.h>
+
__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 <ian at freebsd.org>
* Copyright (c) 2012 Mark Tinguely
*
* All rights reserved.
@@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/kernel.h>
+#include <machine/armreg.h>
#include <machine/frame.h>
#include <machine/fp.h>
#include <machine/pcb.h>
@@ -41,12 +43,8 @@ __FBSDID("$FreeBSD$");
#include <machine/vfp.h>
/* 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 ldc<c>l, not in the UAL form ldcl<c>, 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 ldc<c>l, not in the UAL
- * form ldcl<c>, 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -49,12 +51,6 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91_pmcvar.h>
#include <arm/at91/at91_aicreg.h>
-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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+#include <machine/resource.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_aicreg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#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 ***
More information about the svn-src-all
mailing list