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