Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/mips Overhaul the emulation facility. We do this by:



details:   https://anonhg.NetBSD.org/src/rev/95406bb2069b
branches:  trunk
changeset: 533671:95406bb2069b
user:      gmcgarry <gmcgarry%NetBSD.org@localhost>
date:      Sat Jul 06 23:59:18 2002 +0000

description:
Overhaul the emulation facility.  We do this by:

- accumulating all emulation code (including floating-point) in one place
- steal MachFPInterrupt() back from SOFTFLOAT for use only with interrupts
  and traps from *real* FPUs
- introducing MachEmulateInst() as a common dispatch point for all
  emulated instructions
- cleaning up emulation dispatch in trap()

Also, while we're here, implement MIPS2 LL/SC/SYNC emulation for MIPS1.

Tested on r3k with and without SOFTFLOAT enabled.

diffstat:

 sys/arch/mips/conf/files.mips       |    4 +-
 sys/arch/mips/include/cpuregs.h     |    6 +-
 sys/arch/mips/include/mips_opcode.h |    5 +-
 sys/arch/mips/mips/fpemu.c          |  593 ----------------------
 sys/arch/mips/mips/locore.S         |   63 +--
 sys/arch/mips/mips/mips_emul.c      |  932 ++++++++++++++++++++++++++++++++++++
 sys/arch/mips/mips/trap.c           |  176 +-----
 7 files changed, 969 insertions(+), 810 deletions(-)

diffs (truncated from 1938 to 300 lines):

diff -r 90cce489e89b -r 95406bb2069b sys/arch/mips/conf/files.mips
--- a/sys/arch/mips/conf/files.mips     Sat Jul 06 23:15:29 2002 +0000
+++ b/sys/arch/mips/conf/files.mips     Sat Jul 06 23:59:18 2002 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.mips,v 1.41 2002/06/01 11:41:33 simonb Exp $
+#      $NetBSD: files.mips,v 1.42 2002/07/06 23:59:18 gmcgarry Exp $
 #
 
 defflag        opt_cputype.h           NOFPU   # and the rest...
@@ -47,7 +47,7 @@
 file   arch/mips/mips/in_cksum.c               inet
 file   netns/ns_cksum.c                        ns
 
-file   arch/mips/mips/fpemu.c                  softfloat
+file   arch/mips/mips/mips_emul.c
 file   arch/mips/mips/fp.S                     softfloat | !nofpu
 
 file   arch/mips/mips/procfs_machdep.c         procfs
diff -r 90cce489e89b -r 95406bb2069b sys/arch/mips/include/cpuregs.h
--- a/sys/arch/mips/include/cpuregs.h   Sat Jul 06 23:15:29 2002 +0000
+++ b/sys/arch/mips/include/cpuregs.h   Sat Jul 06 23:59:18 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpuregs.h,v 1.53 2002/06/27 03:43:45 simonb Exp $      */
+/*     $NetBSD: cpuregs.h,v 1.54 2002/07/06 23:59:19 gmcgarry Exp $    */
 
 /*
  * Copyright (c) 1992, 1993
@@ -557,10 +557,6 @@
  */
 #define        MIPS_OPCODE_SHIFT       26
 #define        MIPS_OPCODE_C1          0x11
-#define        MIPS_OPCODE_LWC1        0x31
-#define        MIPS_OPCODE_LDC1        0x35
-#define        MIPS_OPCODE_SWC1        0x39
-#define        MIPS_OPCODE_SDC1        0x3d
 
 
 /*
diff -r 90cce489e89b -r 95406bb2069b sys/arch/mips/include/mips_opcode.h
--- a/sys/arch/mips/include/mips_opcode.h       Sat Jul 06 23:15:29 2002 +0000
+++ b/sys/arch/mips/include/mips_opcode.h       Sat Jul 06 23:59:18 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mips_opcode.h,v 1.8 2001/08/13 18:48:48 soda Exp $     */
+/*     $NetBSD: mips_opcode.h,v 1.9 2002/07/06 23:59:19 gmcgarry Exp $ */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -126,6 +126,7 @@
 #define OP_BNE         005
 #define OP_BLEZ                006
 #define OP_BGTZ                007
+#define OP_SYNC                017
 
 #define OP_ADDI                010
 #define OP_ADDIU       011
@@ -178,6 +179,7 @@
 #define OP_LWC2                062
 #define OP_LWC3                063
 #define OP_LLD         064             /* MIPS-II, for r4000 port */
+#define OP_LDC1                065
 #define OP_LD          067             /* MIPS-II, for r4000 port */
 
 #define OP_SC          070
@@ -186,6 +188,7 @@
 #define OP_SWC2                072
 #define OP_SWC3                073
 #define OP_SCD         074             /* MIPS-II, for r4000 port */
+#define OP_SDC1                075
 #define OP_SD          077             /* MIPS-II, for r4000 port */
 
 /*
diff -r 90cce489e89b -r 95406bb2069b sys/arch/mips/mips/fpemu.c
--- a/sys/arch/mips/mips/fpemu.c        Sat Jul 06 23:15:29 2002 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,593 +0,0 @@
-/*     $NetBSD: fpemu.c,v 1.10 2002/03/05 15:46:51 simonb Exp $ */
-
-/*
- * Copyright (c) 1999 Shuichiro URATA.  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.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-
-#include <mips/locore.h>
-#include <mips/mips_opcode.h>
-
-#include <machine/cpu.h>
-#include <mips/reg.h>
-#include <mips/regnum.h>                       /* symbolic register indices */
-#include <mips/vmparam.h>                      /* for VM_MAX_ADDRESS */
-#include <mips/trap.h>
-
-static __inline void   send_sigsegv(u_int32_t, u_int32_t, struct frame *,
-                           u_int32_t);
-static __inline void   update_pc(struct frame *, u_int32_t);
-
-void   MachEmulateLWC1(u_int32_t inst, struct frame *, u_int32_t);
-void   MachEmulateLDC1(u_int32_t inst, struct frame *, u_int32_t);
-void   MachEmulateSWC1(u_int32_t inst, struct frame *, u_int32_t);
-void   MachEmulateSDC1(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_lb(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_lbu(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_lh(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_lhu(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_lw(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_lwl(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_lwr(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_sb(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_sh(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_sw(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_swl(u_int32_t inst, struct frame *, u_int32_t);
-void   bcemul_swr(u_int32_t inst, struct frame *f, u_int32_t);
-
-vaddr_t MachEmulateBranch(struct frame *, vaddr_t, unsigned, int);
-
-static __inline void
-send_sigsegv(u_int32_t vaddr, u_int32_t exccode, struct frame *frame,
-    u_int32_t cause)
-{
-
-       cause = (cause & 0xFFFFFF00) | (exccode << MIPS_CR_EXC_CODE_SHIFT);
-
-       frame->f_regs[CAUSE] = cause;
-       frame->f_regs[BADVADDR] = vaddr;
-       trapsignal(curproc, SIGSEGV, vaddr);
-}
-
-static __inline void
-update_pc(struct frame *frame, u_int32_t cause)
-{
-
-       if (cause & MIPS_CR_BR_DELAY)
-               frame->f_regs[PC] = MachEmulateBranch(frame, frame->f_regs[PC],
-                   PCB_FSR(curpcb), 0);
-       else
-               frame->f_regs[PC] += 4;
-}
-
-#define LWSWC1_MAXLOOP 12
-
-void
-MachEmulateLWC1(u_int32_t inst, struct frame *frame, u_int32_t cause)
-{
-       u_int32_t       vaddr;
-       int16_t         offset;
-       void            *t;
-       mips_reg_t      pc;
-       int             i;
-
-       offset = inst & 0xFFFF;
-       vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
-
-       /* segment and alignment check */
-       if (vaddr > VM_MAX_ADDRESS || vaddr & 0x3) {
-               send_sigsegv(vaddr, T_ADDR_ERR_LD, frame, cause);
-               return;
-       }
-
-       t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
-
-       if (copyin((void *)vaddr, t, 4) != 0) {
-               send_sigsegv(vaddr, T_TLB_LD_MISS, frame, cause);
-               return;
-       }
-
-       pc = frame->f_regs[PC];
-       update_pc(frame, cause);
-
-       if (cause & MIPS_CR_BR_DELAY)
-               return;
-
-       for (i = 1; i < LWSWC1_MAXLOOP; i++) {
-               if (mips_btop(frame->f_regs[PC]) != mips_btop(pc))
-                       return;
-
-               vaddr = frame->f_regs[PC];      /* XXX truncates to 32 bits */
-               inst = fuiword((u_int32_t *)vaddr);
-               if (((InstFmt)inst).FRType.op != OP_LWC1)
-                       return;
-
-               offset = inst & 0xFFFF;
-               vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
-
-               /* segment and alignment check */
-               if (vaddr > VM_MAX_ADDRESS || vaddr & 0x3) {
-                       send_sigsegv(vaddr, T_ADDR_ERR_LD, frame, cause);
-                       return;
-               }
-
-               t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
-
-               if (copyin((void *)vaddr, t, 4) != 0) {
-                       send_sigsegv(vaddr, T_TLB_LD_MISS, frame, cause);
-                       return;
-               }
-
-               pc = frame->f_regs[PC];
-               update_pc(frame, cause);
-       }
-}
-
-void
-MachEmulateLDC1(u_int32_t inst, struct frame *frame, u_int32_t cause)
-{
-       u_int32_t       vaddr;
-       int16_t         offset;
-       void            *t;
-
-       offset = inst & 0xFFFF;
-       vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
-
-       /* segment and alignment check */
-       if (vaddr & 0x80000007) {
-               send_sigsegv(vaddr, T_ADDR_ERR_LD, frame, cause);
-               return;
-       }
-
-       t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1E]);
-
-       if (copyin((void *)vaddr, t, 8) != 0) {
-               send_sigsegv(vaddr, T_TLB_LD_MISS, frame, cause);
-               return;
-       }
-
-       update_pc(frame, cause);
-}
-
-void
-MachEmulateSWC1(u_int32_t inst, struct frame *frame, u_int32_t cause)
-{
-       u_int32_t       vaddr;
-       int16_t         offset;
-       void            *t;
-       mips_reg_t      pc;
-       int             i;
-
-       offset = inst & 0xFFFF;
-       vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
-
-       /* segment and alignment check */
-       if (vaddr > VM_MAX_ADDRESS || vaddr & 0x3) {
-               send_sigsegv(vaddr, T_ADDR_ERR_ST, frame, cause);
-               return;
-       }
-
-       t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
-
-       if (copyout(t, (void *)vaddr, 4) != 0) {
-               send_sigsegv(vaddr, T_TLB_ST_MISS, frame, cause);
-               return;
-       }
-
-       pc = frame->f_regs[PC];
-       update_pc(frame, cause);
-
-       if (cause & MIPS_CR_BR_DELAY)
-               return;
-
-       for (i = 1; i < LWSWC1_MAXLOOP; i++) {
-               if (mips_btop(frame->f_regs[PC]) != mips_btop(pc))
-                       return;
-
-               vaddr = frame->f_regs[PC];      /* XXX truncates to 32 bits */
-               inst = fuiword((u_int32_t *)vaddr);
-               if (((InstFmt)inst).FRType.op != OP_SWC1)
-                       return;
-
-               offset = inst & 0xFFFF;
-               vaddr = frame->f_regs[(inst>>21)&0x1F] + offset;
-
-               /* segment and alignment check */
-               if (vaddr > VM_MAX_ADDRESS || vaddr & 0x3) {
-                       send_sigsegv(vaddr, T_ADDR_ERR_ST, frame, cause);
-                       return;
-               }



Home | Main Index | Thread Index | Old Index