From 6189064e69ca7d7b0152fef5e430be92dcede0b7 Mon Sep 17 00:00:00 2001 From: bjh21 Date: Fri, 12 Jan 2001 13:23:49 +0000 Subject: [PATCH] More FPU-state-saving infrastructure. Not useful yet. --- sys/arch/arm26/arm26/fpu.c | 54 +++++++---- sys/arch/arm26/arm26/fpu_asm.S | 162 +++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 sys/arch/arm26/arm26/fpu_asm.S diff --git a/sys/arch/arm26/arm26/fpu.c b/sys/arch/arm26/arm26/fpu.c index 3cf7aa6a0ca0..6e2954ec56d3 100644 --- a/sys/arch/arm26/arm26/fpu.c +++ b/sys/arch/arm26/arm26/fpu.c @@ -1,7 +1,7 @@ -/* $NetBSD: fpu.c,v 1.1 2000/12/23 13:37:03 bjh21 Exp $ */ +/* $NetBSD: fpu.c,v 1.2 2001/01/12 13:23:49 bjh21 Exp $ */ /*- - * Copyright (c) 2000 Ben Harris + * Copyright (c) 2000, 2001 Ben Harris * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ #include -__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.1 2000/12/23 13:37:03 bjh21 Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.2 2001/01/12 13:23:49 bjh21 Exp $"); #include #include @@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.1 2000/12/23 13:37:03 bjh21 Exp $"); #include #include #include +#include #include "opt_fputypes.h" @@ -48,53 +49,54 @@ 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 +struct fpu_softc *the_fpu; static int fpu_match(struct device *parent, struct cfdata *cf, void *aux) { - if (cf->cf_unit != 0) - return 0; - return fpu_identify() != 0; + return the_fpu == NULL && fpu_identify() != 0; } static void fpu_attach(struct device *parent, struct device *self, void *aux) { int supported; + struct fpu_softc *sc = (void *)self; + the_fpu = sc; printf(": "); - fpu_type = fpu_identify(); + sc->sc_fputype = fpu_identify(); supported = 0; - switch (fpu_type) { + switch (sc->sc_fputype) { case FPSR_SYSID_FPPC: printf("FPPC/WE32206"); #ifdef FPU_FPPC /* XXX Uncomment when we have minimal support. */ - /* supported = 1; */ + supported = 1; + sc->sc_ctxload = fpctx_load_fppc; + sc->sc_ctxsave = fpctx_save_fppc; + sc->sc_enable = fpu_enable_fppc; + sc->sc_disable = fpu_disable_fppc; #endif break; case FPSR_SYSID_FPA: printf("FPA"); #ifdef FPU_FPA /* XXX Uncomment when we have minimal support. */ - /* supported = 1; */ + supported = 1; + sc->sc_ctxload = fpctx_load_fpa; + sc->sc_ctxsave = fpctx_save_fpa; + sc->sc_enable = fpu_enable_fpa; + sc->sc_disable = fpu_disable_fpa; #endif break; default: - printf("Unknown type, ID=0x%02x", fpu_type >> 24); + printf("Unknown type, ID=0x%02x", sc->sc_fputype >> 24); break; } printf("\n"); @@ -117,3 +119,17 @@ fpu_identify() curproc->p_addr->u_pcb.pcb_onundef_lj = NULL; return fpsr & FPSR_SYSID_MASK; } + +void +fpu_swapout(struct proc *p) +{ + struct pcb *pcb; + + pcb = &p->p_addr->u_pcb; + if (pcb->pcb_flags & PCB_OWNFPU) { + the_fpu->sc_ctxsave(&pcb->pcb_ff); + the_fpu->sc_disable(); + the_fpu->sc_owner = NULL; + pcb->pcb_flags &= ~PCB_OWNFPU; + } +} diff --git a/sys/arch/arm26/arm26/fpu_asm.S b/sys/arch/arm26/arm26/fpu_asm.S new file mode 100644 index 000000000000..2aaf933e40e4 --- /dev/null +++ b/sys/arch/arm26/arm26/fpu_asm.S @@ -0,0 +1,162 @@ +/* $NetBSD: fpu_asm.S,v 1.1 2001/01/12 13:23:49 bjh21 Exp $ */ + +/*- + * Copyright (c) 2001 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_asm.S - Floating point unit support + */ + +#include + +RCSID("$NetBSD: fpu_asm.S,v 1.1 2001/01/12 13:23:49 bjh21 Exp $") + +#include + +#include "opt_fputypes.h" + +#ifdef FPU_FPA +/* + * void fpctx_save_fpa(struct fpframe *); + */ +ENTRY(fpctx_save_fpa) + rfs r1 + str r1, [r0] + sfm f0, 4, [r0, #(4 + 12 * 0)] + sfm f4, 4, [r0, #(4 + 12 * 4)] +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +/* + * void fpctx_load_fpa(struct fpframe *); + */ +ENTRY(fpctx_load_fpa) + lfm f0, 4, [r0, #(4 + 12 * 0)] + lfm f4, 4, [r0, #(4 + 12 * 4)] + ldr r1, [r0] + wfs r1 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +/* + * void fpu_enable_fpa(void); + */ +ENTRY(fpu_enable_fpa) + mov r0, #FPA_FPCR_EN + wfc r0 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif +#endif + +/* + * void fpu_disable_fpa(void); + */ +ENTRY(fpu_disable_fpa) + mov r0, #0 + wfc r0 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +#ifdef FPU_FPPC +/* + * void fpctx_save_fppc(struct fpframe *); + */ +ENTRY(fpctx_save_fppc) + rfs r1 + str r1, [r0] + stfe f0, [r0, #(4 + 12 * 0)] + stfe f1, [r0, #(4 + 12 * 1)] + stfe f2, [r0, #(4 + 12 * 2)] + stfe f3, [r0, #(4 + 12 * 3)] + stfe f4, [r0, #(4 + 12 * 4)] + stfe f5, [r0, #(4 + 12 * 5)] + stfe f6, [r0, #(4 + 12 * 6)] + stfe f7, [r0, #(4 + 12 * 7)] +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +/* + * void fpctx_load_fppc(struct fpframe *); + */ +ENTRY(fpctx_load_fppc) + ldfe f0, [r0, #(4 + 12 * 0)] + ldfe f1, [r0, #(4 + 12 * 1)] + ldfe f2, [r0, #(4 + 12 * 2)] + ldfe f3, [r0, #(4 + 12 * 3)] + ldfe f4, [r0, #(4 + 12 * 4)] + ldfe f5, [r0, #(4 + 12 * 5)] + ldfe f6, [r0, #(4 + 12 * 6)] + ldfe f7, [r0, #(4 + 12 * 7)] + ldr r1, [r0] + wfs r1 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif + +/* + * void fpu_enable_fppc(void); + */ +ENTRY(fpu_enable_fppc) + rfc r0 + orr r0, r0, #FPPC_FPCR_DA + wfc r0 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif +#endif + +/* + * void fpu_disable_fppc(void); + */ +ENTRY(fpu_disable_fppc) + rfc r0 + bic r0, r0, #FPPC_FPCR_DA + wfc r0 +#ifdef __APCS_26__ + movs pc, lr +#else + mov pc, lr +#endif