diff --git a/sys/arch/arm26/arm26/cpu.c b/sys/arch/arm26/arm26/cpu.c index f922d77e34f6..0a6e7a537f73 100644 --- a/sys/arch/arm26/arm26/cpu.c +++ b/sys/arch/arm26/arm26/cpu.c @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.2 2000/12/11 23:46:50 bjh21 Exp $ */ +/* $NetBSD: cpu.c,v 1.3 2000/12/23 13:37:03 bjh21 Exp $ */ /*- * Copyright (c) 2000 Ben Harris @@ -33,7 +33,7 @@ #include -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.2 2000/12/11 23:46:50 bjh21 Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.3 2000/12/23 13:37:03 bjh21 Exp $"); #include #include @@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.2 2000/12/11 23:46:50 bjh21 Exp $"); static int cpu_match(struct device *, struct cfdata *, void *); static void cpu_attach(struct device *, struct device *, void *); +static int cpu_search(struct device *, struct cfdata *, void *); static register_t cpu_identify(void); #ifdef CPU_ARM3 static void cpu_arm3_setup(struct device *, int); @@ -115,8 +116,19 @@ cpu_attach(struct device *parent, struct device *self, void *aux) printf("%s: WARNING: CPU type not supported by kernel\n", self->dv_xname); config_interrupts(self, cpu_delay_calibrate); + config_search(cpu_search, self, NULL); } + +static int +cpu_search(struct device *parent, struct cfdata *cf, void *aux) +{ + if ((cf->cf_attach->ca_match)(parent, cf, NULL) > 0) + config_attach(parent, cf, NULL, NULL); + + return 0; +} + static register_t cpu_identify() { diff --git a/sys/arch/arm26/arm26/fpu.c b/sys/arch/arm26/arm26/fpu.c new file mode 100644 index 000000000000..3cf7aa6a0ca0 --- /dev/null +++ b/sys/arch/arm26/arm26/fpu.c @@ -0,0 +1,119 @@ +/* $NetBSD: fpu.c,v 1.1 2000/12/23 13:37:03 bjh21 Exp $ */ + +/*- + * Copyright (c) 2000 Ben Harris + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ +/* This file is part of NetBSD/arm26 -- a port of NetBSD to ARM2/3 machines. */ +/* + * fpu.c - Floating point unit support + */ + +#include + +__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.1 2000/12/23 13:37:03 bjh21 Exp $"); + +#include +#include +#include +#include +#include +#include + +#include "opt_fputypes.h" + +static int fpu_match(struct device *, struct cfdata *, void *); +static void fpu_attach(struct device *, struct device *, void *); +static register_t fpu_identify(void); + +register_t fpu_type; + +struct fpu_softc { + struct device sc_dev; +}; + +struct cfattach fpu_ca = { + sizeof(struct fpu_softc), fpu_match, fpu_attach +}; + +/* cf_flags bits */ +#define CFF_ENABLE 0x00000001 + +static int +fpu_match(struct device *parent, struct cfdata *cf, void *aux) +{ + + if (cf->cf_unit != 0) + return 0; + return fpu_identify() != 0; +} + +static void +fpu_attach(struct device *parent, struct device *self, void *aux) +{ + int supported; + + printf(": "); + fpu_type = fpu_identify(); + supported = 0; + switch (fpu_type) { + case FPSR_SYSID_FPPC: + printf("FPPC/WE32206"); +#ifdef FPU_FPPC + /* XXX Uncomment when we have minimal support. */ + /* supported = 1; */ +#endif + break; + case FPSR_SYSID_FPA: + printf("FPA"); +#ifdef FPU_FPA + /* XXX Uncomment when we have minimal support. */ + /* supported = 1; */ +#endif + break; + default: + printf("Unknown type, ID=0x%02x", fpu_type >> 24); + break; + } + printf("\n"); + if (!supported) + printf("%s: WARNING: FPU type not supported by kernel\n", + self->dv_xname); +} + +static register_t +fpu_identify() +{ + label_t here; + volatile register_t fpsr; + + if (setjmp(&here) == 0) { + curproc->p_addr->u_pcb.pcb_onundef_lj = &here; + fpsr = 0; + asm volatile ("rfs %0" : "=r" (fpsr)); + } + curproc->p_addr->u_pcb.pcb_onundef_lj = NULL; + return fpsr & FPSR_SYSID_MASK; +} diff --git a/sys/arch/arm26/conf/files.arm26 b/sys/arch/arm26/conf/files.arm26 index c05e007e3976..c25987e5faf7 100644 --- a/sys/arch/arm26/conf/files.arm26 +++ b/sys/arch/arm26/conf/files.arm26 @@ -1,4 +1,4 @@ -# $NetBSD: files.arm26,v 1.9 2000/12/20 10:57:38 bjh21 Exp $ +# $NetBSD: files.arm26,v 1.10 2000/12/23 13:37:02 bjh21 Exp $ # Copyright (c) 1997, 1998, 2000 Ben Harris # All rights reserved. @@ -41,11 +41,17 @@ major {sd = 5} major {cd = 6} # CPU -device cpu +device cpu { } attach cpu at root defopt opt_cputypes.h CPU_ARM2 CPU_ARM250 CPU_ARM3 file arch/arm26/arm26/cpu.c cpu +# Floating-point unit +device fpu +attach fpu at cpu +defopt opt_fputypes.h FPU_FPPC FPU_FPA +file arch/arm26/arm26/fpu.c fpu needs-flag + # I/O bus (on the far side of the address and data latches) device iobus { base = -1 } attach iobus at root diff --git a/sys/arch/arm26/include/fpureg.h b/sys/arch/arm26/include/fpureg.h new file mode 100644 index 000000000000..128bdcef84d1 --- /dev/null +++ b/sys/arch/arm26/include/fpureg.h @@ -0,0 +1,61 @@ +/* $NetBSD: fpureg.h,v 1.1 2000/12/23 13:37:03 bjh21 Exp $ */ + +/* + * ARM FPU definitions + */ + +/* System ID byte */ +#define FPSR_SYSID_MASK 0xff000000 +#define FPSR_SYSID_FPPC 0x80000000 +#define FPSR_SYSID_FPA 0x81000000 + +/* Trap enable bits */ +#define FPSR_TE_IVO 0x00010000 /* InValid Operation */ +#define FPSR_TE_DVZ 0x00020000 /* DiVision by Zero */ +#define FPSR_TE_OFL 0x00040000 /* OverFLow */ +#define FPSR_TE_UFL 0x00080000 /* UnderFLow */ +#define FPSR_TE_INX 0x00100000 /* INeXact */ + +/* System control byte (FPA only) */ +#define FPSR_CTL_ND 0x00000100 /* No Denormalised numbers */ +#define FPSR_CTL_NE 0x00000200 /* NaN Exception */ +#define FPSR_CTL_SO 0x00000400 /* Synchronous Operation */ +#define FPSR_CTL_EP 0x00000800 /* Expanded Packed decimal */ +#define FPSR_CTL_AC 0x00001000 /* Alternative C flag */ + +/* Cumulative exception bits */ +#define FPSR_EX_IVO 0x00000001 /* InValid Operation */ +#define FPSR_EX_DVZ 0x00000002 /* DiVision by Zero */ +#define FPSR_EX_OFL 0x00000004 /* OverFLow */ +#define FPSR_EX_UFL 0x00000008 /* UnderFLow */ +#define FPSR_EX_INX 0x00000010 /* INeXact */ + +/* + * FPPC FPCR + */ +#define FPPC_FPCR_DA 0x00000001 /* Disable */ +#define FPPC_FPCR_EX 0x00000002 /* FP exception occurred */ +#define FPPC_FPCR_AS 0x00000004 /* Last exception was async */ +#define FPPC_FPCR_SBM 0x00000010 /* Use supervisor bank 'm' */ +#define FPPC_FPCR_SBN 0x00000020 /* Use supervisor bank 'n' */ +#define FPPC_FPCR_SBD 0x00000040 /* Use supervisor bank 'd' */ +#define FPPC_FPCR_PR 0x00000080 /* Last RMF gave partial remainder */ + +/* + * FPA FPCR + * This is provisional, from the RISC OS 3 PRM + */ +#define FPA_FPCR_S2 0x0000000f /* AU source register 2 */ +#define FPA_FPCR_OP 0x00f08010 /* AU operation code */ +#define FPA_FPCR_RM 0x00000060 /* AU rounding mode */ +#define FPA_FPCR_PR 0x00080080 /* AU precision */ +#define FPA_FPCR_EN 0x00000100 /* Enable FPA */ +#define FPA_FPCR_RE 0x00000200 /* Rounding exception */ +#define FPA_FPCR_AB 0x00000400 /* Asynchronous bounce */ +#define FPA_FPCR_SB 0x00000800 /* Synchronous bounce */ +#define FPA_FPCR_DS 0x00007000 /* AU destination register */ +#define FPA_FPCR_S1 0x00070000 /* AU source register 1 */ +#define FPA_FPCR_EO 0x04000000 /* Exponent overflow */ +#define FPA_FPCR_MO 0x08000000 /* Mantissa overflow */ +#define FPA_FPCR_IE 0x10000000 /* Inexact bit */ +#define FPA_FPCR_RU 0x80000000 /* Rounded up bit */