* MONSTER sky -> devo merge

* ChangeLog / ChangeLog.sky entries were merged with original time stamps;
  a few were moved between the files
This commit is contained in:
Frank Ch. Eigler 1998-10-27 12:48:08 +00:00
parent 63a0e6b527
commit fda83b6795
9 changed files with 2150 additions and 3403 deletions

View File

@ -35,9 +35,9 @@ sky_files="ChangeLog.sky sky-device.c sky-device.h sky-dma.c sky-dma.h sky-bits.
sky_files="$sky_files sky-engine.c sky-gpuif.c sky-gpuif.h"
sky_files="$sky_files sky-gs.c sky-gs.h"
sky_files="$sky_files sky-hardware.c sky-hardware.h sky-gdb.c sky-gdb.h"
sky_files="$sky_files sky-libvpe.c sky-libvpe.h sky-pke.c sky-pke.h"
sky_files="$sky_files sky-libvpe.c sky-libvpe.h sky-vif.c sky-vif.h"
sky_files="$sky_files sky-vpe.h sky-vu.h sky-vu.c sky-vudis.h sky-vudis.c"
sky_files="$sky_files sky-console.h sky-console.c"
sky_files="$sky_files sky-console.h sky-console.c sky-psio.h sky-psio.c"
sky_files="$sky_files sky-interact.h sky-interact.c"
sky_files="$sky_files sky-indebug.h sky-indebug.c"
if ( echo $* | grep keep\-sky > /dev/null ) ; then

View File

@ -3,7 +3,22 @@ Fri Oct 9 18:02:25 1998 Doug Evans <devans@canuck.cygnus.com>
* interp.c: #include "itable.h" if WITH_IGEN.
(get_insn_name): New function.
(sim_open): Initialize CPU_INSN_NAME,CPU_MAX_INSNS.
* sim-main.h (MAX_INSNS,INSN_NAME): Delete.
start-sanitize-sky
Tue Sep 22 10:35:37 1998 Frank Ch. Eigler <fche@cygnus.com>
* sim-main.c (tlb_try_match): Specially match virtual
pages mapped to scratchpad RAM, an unimplemented feature.
end-sanitize-sky
start-sanitize-r5900
Fri Sep 18 11:31:16 1998 Frank Ch. Eigler <fche@cygnus.com>
* r5900.igen (prot3w): Correct rotation sequence; patch
from customer.
end-sanitize-r5900
Mon Sep 14 12:36:44 1998 Frank Ch. Eigler <fche@cygnus.com>
* configure: Rebuilt to inhale new common/aclocal.m4.
@ -13,6 +28,13 @@ Thu Sep 10 11:50:54 1998 Doug Evans <devans@canuck.cygnus.com>
* r5900.igen (plzcw): Make `i' signed.
Wed Sep 9 15:02:10 1998 Doug Evans <devans@canuck.cygnus.com>
* sim-main.h (COP0_COUNT,COP0_COMPARE,status_IM7): New macros.
* sky-engine.c (cpu_issue): Increment COP0_COUNT and signal an
interrupt if == COP0_COMPARE and interrupt masks/enables allow it.
* interp.c (signal_exception, sky version): Handle INT 2.
Wed Sep 9 11:28:20 1998 Ron Unrau <runrau@cygnus.com>
* sim-main.h: track COP0 registers
@ -49,6 +71,13 @@ Tue Aug 25 12:49:46 1998 Frank Ch. Eigler <fche@cygnus.com>
frequent hw-trace messages.
end-sanitize-tx3904
start-sanitize-sky
Tue Aug 11 13:52:16 1998 Frank Ch. Eigler <fche@cygnus.com>
* interp.c (signal_exception): Set IP3 bit in CAUSE on
sky interrupt.
end-sanitize-sky
Fri Jul 31 18:14:16 1998 Andrew Cagney <cagney@b1.cygnus.com>
* vr.igen (MulAcc): Identify as a vr4100 specific function.
@ -67,8 +96,48 @@ end-sanitize-cygnus
start-sanitize-vr4320
* vr4320.igen: Move instructions to vr.igen.
* Makefile.in (IGEN_INCLUDE): Remove vr5320.igen.
end-sanitize-vr4320
end-sanitize-vr4320
start-sanitize-sky
Fri Jul 24 16:01:03 1998 Ian Carmichael <iancarm@cygnus.com>
* interp.c (MONITOR_SIZE): Make 1MB monitor for SKY.
* mips.igen (BREAK): Fix 0xffff2 monitor call. Slightly less
confusing message if not enough --load-next options appear.
* sky-pke.h (VUx_MEMx_SRCADDR_START): Move to 0x19800000 range.
* sim-main.c (GDB_COMM_AREA): Move to 0x19810000.
* sky-gdb.c (init_fifo_bp_cache): Use VIO_BASE when reading GDB area.
(resume_handler): Same.
(suspend_handler): Same.
Wed Jul 22 13:04:13 1998 Frank Ch. Eigler <fche@cygnus.com>
* mips.igen (break): Implement LOAD_INSTRUCTION ("break 0xffff1")
to trigger multi-phase load.
* sim-main.c: Include sim-assert.h for ASSERT macro.
* sim-main.h (PRINTF_INSTRUCTION): Correct bit pattern for
"break 0xffff2".
Tue Jul 21 18:37:36 1998 Ian Carmichael <iancarm@cygnus.com>
MMU support.
* interp.c (sim_open): Initialize TLB.
* interp.c (signal_exceptions): New 5900 handling.
* r5900.igen (TLBWR, TLBWI, TLBR, TLBP): Make these work.
* sim-main.c (tlb_try_match, tlb_lookup): New functions.
(address_translation): Use the TLB.
* sim-main.h (r4000_tlb_entry_t): New type.
(TLB_*): New constants.
(COP0_*): New register names.
Sky character I/O device.
* sky-psio.c: New file.
* sky-psio.h: New file.
* Makefile.in: Add sky-psio.o.
end-sanitize-sky
start-sanitize-r5900
Tue Jul 14 16:10:45 1998 Andrew Cagney <cagney@b1.cygnus.com>

View File

@ -10,13 +10,17 @@ SIM_NO_OBJ =
# start-sanitize-sky
SIM_SKY_OBJS = \
sky-console.o \
sky-device.o \
sky-dma.o \
sky-engine.o \
sky-interact.o \
sky-gpuif.o \
sky-hardware.o \
sky-indebug.o \
sky-libvpe.o \
sky-pke.o \
sky-vif.o \
sky-psio.o \
sky-vu.o \
sky-vudis.o \
sky-gs.o \
@ -29,7 +33,7 @@ SIM_IGEN_OBJ = \
semantics.o \
idecode.o \
icache.o \
engine.o \
@mips_igen_engine@ \
irun.o \
SIM_M16_OBJ = \
@ -128,15 +132,12 @@ IGEN_INCLUDE=\
$(start-sanitize-r5900) \
$(srcdir)/r5900.igen \
$(end-sanitize-r5900) \
$(start-sanitize-vr5400) \
$(srcdir)/vr5400.igen \
$(start-sanitize-cygnus) \
$(srcdir)/mdmx.igen \
$(end-sanitize-vr5400) \
$(start-sanitize-vr4320) \
$(srcdir)/vr4320.igen \
$(end-sanitize-vr4320) \
$(end-sanitize-cygnus) \
$(srcdir)/m16.igen \
$(srcdir)/tx.igen
$(srcdir)/tx.igen \
$(srcdir)/vr.igen \
SIM_IGEN_ALL = tmp-igen

1363
sim/mips/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -59,6 +59,7 @@ case "${target}" in
# start-sanitize-r5900
mips64r59*-*-*) mips_endian=LITTLE_ENDIAN ;;
# end-sanitize-r5900
mips64el*-*-*) mips_endian=LITTLE_ENDIAN ;;
mips64*-*-*) default_endian=BIG_ENDIAN ;;
mips16*-*-*) default_endian=BIG_ENDIAN ;;
mips*-*-*) default_endian=BIG_ENDIAN ;;
@ -79,6 +80,9 @@ case "${target}" in
# start-sanitize-r5900
mips64r59*-*-*) mips_bitsize=64 ; mips_msb=63 ; mips_addr_bitsize=32;;
# end-sanitize-r5900
# start-sanitize-sky
mips64*-sky*-*) mips_bitsize=64 ; mips_msb=63 ; mips_addr_bitsize=32;;
# end-sanitize-sky
mips64*-*-*) mips_bitsize=64 ; mips_msb=63 ;;
mips16*-*-*) mips_bitsize=64 ; mips_msb=63 ;;
mips*-*-*) mips_bitsize=32 ; mips_msb=31 ;;
@ -103,6 +107,9 @@ case "${target}" in
# start-sanitize-r5900
mips64r59*-*-*) mips_fpu=HARD_FLOATING_POINT ; mips_fpu_bitsize=32 ;;
# end-sanitize-r5900
# start-sanitize-sky
mips64*-sky*-*) mips_fpu=HARD_FLOATING_POINT ; mips_fpu_bitsize=32 ;;
# end-sanitize-sky
mips64*-*-*) mips_fpu=HARD_FLOATING_POINT ;;
mips16*-*-*) mips_fpu=HARD_FLOATING_POINT ;;
mips*-*-*) mips_fpu=HARD_FLOATING_POINT ; mips_fpu_bitsize=32 ;;
@ -242,9 +249,13 @@ case "${target}" in
# end-sanitize-tx3904
# start-sanitize-sky
mips64r59*-sky-*)
mips_extra_objs="$mips_extra_objs "'$(SIM_SKY_OBJS)'
mips_extra_objs='$(SIM_SKY_OBJS)'
SIM_SUBTARGET="-DTARGET_SKY -DWITH_DEVICES=1 -DDEVICE_INIT=1"
;;
mips64*-skyb-*)
mips_extra_objs='$(SIM_SKY_OBJS)'
SIM_SUBTARGET="-DTARGET_SKY -DTARGET_SKY_B -DWITH_DEVICES=1 -DDEVICE_INIT=1"
;;
# end-sanitize-sky
*)
mips_extra_objs=""
@ -254,6 +265,22 @@ SIM_AC_OPTION_HARDWARE($hw_enabled,$hw_devices,$hw_extra_devices)
AC_SUBST(mips_extra_objs)
# Choose simulator engine
case "${target}" in
# start-sanitize-sky
mips64r59*-sky-*)
mips_igen_engine=""
;;
mips64*-skyb-*)
mips_igen_engine=""
;;
# end-sanitize-sky
*) mips_igen_engine="engine.o"
;;
esac
AC_SUBST(mips_igen_engine)
AC_PATH_X
mips_extra_libs=""
# start-sanitize-sky
@ -264,9 +291,217 @@ AC_ARG_WITH(sim-gpu2,
then
SIM_SUBTARGET="${SIM_SUBTARGET} -DSKY_GPU2 -I${withval}/include"
mips_extra_libs="-L${withval}/lib -lgpu2 -L${x_libraries} -lX11 -lXext"
WITH_GPU2="yes" ; export WITH_GPU2
# complex X/etc. detection; stolen shamelessly from tcl/tk/gdb configury. --angela
#--------------------------------------------------------------------
# Locate the X11 header files and the X11 library archive. Try
# the ac_path_x macro first, but if it doesn't find the X stuff
# (e.g. because there's no xmkmf program) then check through
# a list of possible directories. Under some conditions the
# autoconf macro will return an include directory that contains
# no include files, so double-check its result just to be safe.
#--------------------------------------------------------------------
AC_PATH_X
not_really_there=""
if test "$no_x" = ""; then
if test "$x_includes" = ""; then
AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
else
if test ! -r $x_includes/X11/Intrinsic.h; then
not_really_there="yes"
fi
fi
fi
if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
AC_MSG_CHECKING(for X11 header files)
XINCLUDES="# no special path needed"
AC_TRY_CPP([#include <X11/Intrinsic.h>], , XINCLUDES="nope")
if test "$XINCLUDES" = nope; then
dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
for i in $dirs ; do
if test -r $i/X11/Intrinsic.h; then
AC_MSG_RESULT($i)
XINCLUDES=" -I$i"
break
fi
done
fi
else
if test "$x_includes" != ""; then
XINCLUDES=-I$x_includes
else
XINCLUDES="# no special path needed"
fi
fi
if test "$XINCLUDES" = nope; then
AC_MSG_RESULT(couldn't find any!)
XINCLUDES="# no include files found"
fi
if test "$no_x" = yes; then
AC_MSG_CHECKING(for X11 libraries)
XLIBSW=nope
dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/lib/X11 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
for i in $dirs ; do
if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then
AC_MSG_RESULT($i)
XLIBSW="-L$i -lX11"
x_libraries="$i"
break
fi
done
else
if test "$x_libraries" = ""; then
XLIBSW=-lX11
else
XLIBSW="-L$x_libraries -lX11"
fi
fi
if test "$XLIBSW" = nope ; then
AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
fi
if test "$XLIBSW" = nope ; then
AC_MSG_RESULT(couldn't find any! Using -lX11.)
XLIBSW=-lX11
fi
#--------------------------------------------------------------------
# Various manipulations on the search path used at runtime to
# find shared libraries:
# 1. If the X library binaries are in a non-standard directory,
# add the X library location into that search path.
# 2. On systems such as AIX and Ultrix that use "-L" as the
# search path option, colons cannot be used to separate
# directories from each other. Change colons to " -L".
# 3. Create two sets of search flags, one for use in cc lines
# and the other for when the linker is invoked directly. In
# the second case, '-Wl,' must be stripped off and commas must
# be replaced by spaces.
#--------------------------------------------------------------------
#
# CYGNUS LOCAL: statically link on Solaris, HPUX & SunOS so that
# we don't have problems with people not having libraries
# installed or not having LD_LIBRARY_PATH set.
#
case "$host" in
#
# gdb linked statically w/ Solaris iff GCC and GNU ld are used,
# otherwise dynamic
#
sparc-sun-solaris2*)
sol_xlibsw=
if test "x$GCC" = "xyes" ; then
# This is probably the simplest way to test for GNU ld.
# It only works with relatively recent versions of GNU
# ld.
gld_text=`$CC -Wl,--version 2>&1 | sed 1q`
case "$gld_text" in
GNU* | *BFD*)
# Why do we link against libX11 twice? Because the
# Openwin X11 and Xext libraries are seriously broken.
sol_xlibsw="-Wl,-Bstatic $XLIBSW -lXext -lX11 -Wl,-Bdynamic"
;;
esac
fi
if test -z "$sol_xlibsw"; then
if test "x$x_libraries" != "x"; then
XLIBSW="$XLIBSW -R$x_libraries"
fi
else
XLIBSW=$sol_xlibsw
suppress_enable_shared=yes
fi
;;
#
# gdb linked statically w/ SunOS or HPUX
#
m68k-hp-hpux*|hppa*-hp-hpux*|sparc-sun-sunos*)
if test "x$x_libraries" != "x" ;
then
XLIBSW="$x_libraries/libX11.a"
else
XLIBSW="/usr/lib/libX11.a"
fi
suppress_enable_shared=yes
;;
#
# default is to link dynamically
#
*)
;;
esac
#
# END CYGNUS LOCAL
#--------------------------------------------------------------------
# Check for the existence of various libraries. The order here
# is important, so that then end up in the right order in the
# command line generated by make. The -lsocket and -lnsl libraries
# require a couple of special tricks:
# 1. Use "connect" and "accept" to check for -lsocket, and
# "gethostbyname" to check for -lnsl.
# 2. Use each function name only once: can't redo a check because
# autoconf caches the results of the last check and won't redo it.
# 3. Use -lnsl and -lsocket only if they supply procedures that
# aren't already present in the normal libraries. This is because
# IRIX 5.2 has libraries, but they aren't needed and they're
# bogus: they goof up name resolution if used.
# 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
# To get around this problem, check for both libraries together
# if -lsocket doesn't work by itself.
#--------------------------------------------------------------------
AC_CHECK_LIB(Xbsd, main, [SOCKLIBSW="$SOCKLIBSW -lXbsd"])
# CYGNUS LOCAL: Store any socket library(ies) in the cache, and don't
# mess up the cache values of the functions we check for.
AC_CACHE_CHECK([for socket libraries], sim_cv_lib_sockets,
[sim_cv_lib_sockets=
sim_checkBoth=0
unset ac_cv_func_connect
AC_CHECK_FUNC(connect, sim_checkSocket=0, sim_checkSocket=1)
if test "$sim_checkSocket" = 1; then
unset ac_cv_func_connect
AC_CHECK_LIB(socket, main, sim_cv_lib_sockets="-lsocket",
sim_checkBoth=1)
fi
if test "$sim_checkBoth" = 1; then
sim_oldLibs=$SOCKLIBSW
SOCKLIBSW="$SOCKLIBSW -lsocket -lnsl"
unset ac_cv_func_accept
AC_CHECK_FUNC(accept,
[sim_checkNsl=0
sim_cv_lib_sockets="-lsocket -lnsl"])
unset ac_cv_func_accept
SOCKLIBSW=$sim_oldLibs
fi
unset ac_cv_func_gethostbyname
sim_oldLibs=$SOCKLIBSW
SOCKLIBSW="$SOCKLIBSW $sim_cv_lib_sockets"
AC_CHECK_FUNC(gethostbyname, ,
[AC_CHECK_LIB(nsl, main,
[sim_cv_lib_sockets="$sim_cv_lib_sockets -lnsl"])])
unset ac_cv_func_gethostbyname
SOCKLIBSW=$sim_oldSOCKLIBSW
])
test -z "$sim_cv_lib_sockets" || SOCKLIBSW="$SOCKLIBSW $sim_cv_lib_sockets"
mips_extra_libs="-L${withval}/lib -lgpu2 -lm $XLIBSW $SOCKLIBSW"
cat > simConfig.sh << --EOF--
mips_extra_libs="$mips_extra_libs"
--EOF--
else
AC_MSG_ERROR("Directory ${withval} does not exist.");
fi])dnl
# Enable target accurate FP library
AC_ARG_WITH(sim-funit,
[ --with-sim-funit=path Use target FP library under given directory],

View File

@ -39,12 +39,16 @@ code on the hardware.
#include "sim-assert.h"
#include "sim-hw.h"
#if WITH_IGEN
#include "itable.h"
#endif
/* start-sanitize-sky */
#ifdef TARGET_SKY
#include "sky-vu.h"
#include "sky-vpe.h"
#include "sky-libvpe.h"
#include "sky-pke.h"
#include "sky-vif.h"
#include "idecode.h"
#include "sky-gdb.h"
#endif
@ -159,6 +163,8 @@ static void ColdReset PARAMS((SIM_DESC sd));
#ifdef TARGET_SKY
#undef MEM_SIZE
#define MEM_SIZE (16 << 20) /* 16 MB */
#undef MONITOR_SIZE
#define MONITOR_SIZE 0x100000 /* 1MB */
#endif
/* end-sanitize-sky */
@ -168,6 +174,10 @@ FILE *tracefh = NULL;
static void open_trace PARAMS((SIM_DESC sd));
#endif /* TRACE */
#if WITH_IGEN
static const char * get_insn_name (sim_cpu *, int);
#endif
/* simulation target board. NULL=canonical */
static char* board = NULL;
@ -329,7 +339,7 @@ interrupt_event (SIM_DESC sd, void *data)
if (SR & status_IE)
{
interrupt_pending = 0;
SignalExceptionInterrupt ();
SignalExceptionInterrupt (1); /* interrupt "1" */
}
else if (!interrupt_pending)
sim_events_schedule (sd, 1, interrupt_event, data);
@ -367,6 +377,12 @@ sim_open (kind, cb, abfd, argv)
STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
#if WITH_IGEN
/* Initialize the mechanism for doing insn profiling. */
CPU_INSN_NAME (cpu) = get_insn_name;
CPU_MAX_INSNS (cpu) = nr_itable_entries;
#endif
STATE = 0;
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
@ -431,6 +447,10 @@ sim_open (kind, cb, abfd, argv)
{
/* match VIRTUAL memory layout of JMR-TX3904 board */
/* --- environment --- */
STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
/* --- memory --- */
/* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
@ -451,18 +471,38 @@ sim_open (kind, cb, abfd, argv)
32 * 1024 * 1024, /* 32 MB */
0xA8000000);
/* Dummy memory regions for unsimulated devices */
sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE010, 0x00c); /* EBIF */
sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
/* --- simulated devices --- */
sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
sim_hw_parse (sd, "/tx3904cpu");
sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
{
/* FIXME: poking at dv-sockser internals, use tcp backend if
--sockser_addr option was given.*/
extern char* sockser_addr;
if(sockser_addr == NULL)
sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
else
sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
}
sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
/* -- device connections --- */
sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
/* add PAL timer & I/O module */
if(! strcmp(board, BOARD_JMR3904_PAL))
@ -559,11 +599,14 @@ sim_open (kind, cb, abfd, argv)
else
cpu->register_widths[rn] = 0;
}
/* start-sanitize-r5900 */
/* start-sanitize-r5900 */
/* set the 5900 "upper" registers to 64 bits */
for( rn = LAST_EMBED_REGNUM+1; rn < NUM_REGS; rn++)
for( rn = LAST_EMBED_REGNUM+1; rn < FIRST_COP0_REG; rn++)
cpu->register_widths[rn] = 64;
for( rn = FIRST_COP0_REG; rn < NUM_REGS; rn++)
cpu->register_widths[rn] = 32;
/* end-sanitize-r5900 */
/* start-sanitize-sky */
@ -601,8 +644,12 @@ sim_open (kind, cb, abfd, argv)
HALT_INSTRUCTION /* BREAK */ };
H2T (halt[0]);
H2T (halt[1]);
sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
}
@ -667,6 +714,31 @@ sim_open (kind, cb, abfd, argv)
}
}
/* start-sanitize-sky */
#ifdef TARGET_SKY
/* Default TLB initialization... */
#define KPAGEMASK 0x001fe000
#define PAGE_MASK_4K 0x00000000
#define PAGE_MASK_16K 0x00006000
#define PAGE_MASK_64K 0x0001e000
#define PAGE_MASK_256K 0x0007e000
#define PAGE_MASK_1M 0x001fe000
#define PAGE_MASK_4M 0x007fe000
#define PAGE_MASK_16M 0x01ffe000
#define SET_TLB(index, page_mask, entry_hi, entry_lo0, entry_lo1) \
TLB[index].mask = page_mask; \
TLB[index].hi = entry_hi; \
TLB[index].lo0 = entry_lo0; \
TLB[index].lo1 = entry_lo1
SET_TLB(0, PAGE_MASK_16M, 0x00000000, 0x0000001e, 0x0004001e);/*0-32M*/
#endif /* TARGET_SKY */
/* end-sanitize-sky */
return sd;
}
@ -684,6 +756,15 @@ open_trace(sd)
}
#endif /* TRACE */
#if WITH_IGEN
/* Return name of an insn, used by insn profiling. */
static const char *
get_insn_name (sim_cpu *cpu, int i)
{
return itable[i].name;
}
#endif
void
sim_close (sd, quitting)
SIM_DESC sd;
@ -821,6 +902,38 @@ sim_store_register (sd,rn,memory,length)
HI1 = T2H_8(*(unsigned64*)memory);
return 8;
}
if (rn >= FIRST_COP0_REG && rn < (FIRST_COP0_REG+NUM_COP0_REGS))
{
switch (rn - FIRST_COP0_REG)
{
case 12: /* Status */
case 13: /* Cause */
return -1; /* Already done in regular register set */
case 14:
EPC = T2H_4(*((unsigned32*) memory));
break;
case 16:
C0_CONFIG = T2H_4(*((unsigned32*) memory));
break;
case 17: /* Debug */
Debug = T2H_4(*((unsigned32*) memory));
break;
case 18: /* Perf */
COP0_GPR[rn - FIRST_COP0_REG + 7] = T2H_4(*((unsigned32*) memory));
break;
case 19: /* TagLo */
case 20: /* TagHi */
case 21: /* ErrorEPC */
COP0_GPR[rn - FIRST_COP0_REG + 9] = T2H_4(*((unsigned32*) memory));
break;
default:
COP0_GPR[rn - FIRST_COP0_REG] = T2H_4(*((unsigned32*) memory));
break;
}
return 4;
}
/* end-sanitize-r5900 */
/* start-sanitize-sky */
@ -831,6 +944,10 @@ sim_store_register (sd,rn,memory,length)
if( rn < NUM_VU_REGS )
{
#ifdef TARGET_SKY_B
sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
return 0;
#else
if (rn < NUM_VU_INTEGER_REGS)
return write_vu_int_reg (&(vu0_device.regs), rn, memory);
else if (rn >= FIRST_VEC_REG)
@ -842,24 +959,34 @@ sim_store_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
return write_vu_special_reg (&vu0_device, VU_REG_CIA,
memory);
case 1:
return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MR,
memory);
case 2: /* VU0 has no P register */
return write_vu_special_reg (&vu0_device, VU_REG_CIA, memory);
case 1: /* Can't write TPC register */
case 2: /* or VPU_STAT */
case 4: /* or MAC */
case 9: /* VU0 has no P register */
return 4;
case 3:
return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
memory);
case 4:
return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ,
memory);
return write_vu_misc_reg(&(vu0_device.regs), VU_REG_MST, memory);
case 5:
return write_vu_misc_reg(&(vu0_device.regs), VU_REG_MCP, memory);
case 6:
return write_vu_special_reg (&vu0_device, VU_REG_CMSAR0, memory);
case 7:
return write_vu_special_reg (&vu0_device, VU_REG_FBRST, memory);
case 8:
return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MR, memory);
case 10:
return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MI, memory);
case 11:
return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ, memory);
default:
return write_vu_acc_reg (&(vu0_device.regs),
rn - (NUM_VU_INTEGER_REGS + 5),
rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
#endif /* ! TARGET_SKY_B */
}
rn = rn - NUM_VU_REGS;
@ -877,23 +1004,35 @@ sim_store_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
return write_vu_special_reg (&vu1_device, VU_REG_CIA,
memory);
case 1:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MR,
memory);
case 2:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MP,
memory);
return write_vu_special_reg (&vu1_device, VU_REG_CIA, memory);
case 1: /* Can't write TPC register */
case 2: /* or VPU_STAT */
case 4: /* or MAC */
case 7: /* VU1 has no FBRST register */
return 4;
case 3:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MI,
memory);
case 4:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ,
memory);
return write_vu_misc_reg(&(vu1_device.regs), VU_REG_MST, memory);
case 5:
return write_vu_misc_reg(&(vu1_device.regs), VU_REG_MCP, memory);
case 6: /* CMSAR1 is actually part of VU0 */
#ifdef TARGET_SKY_B
return 0;
#else
return write_vu_special_reg (&vu0_device, VU_REG_CMSAR1, memory);
#endif /* ! TARGET_SKY_B */
case 8:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MR, memory);
case 9:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MP, memory);
case 10:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MI, memory);
case 11:
return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ, memory);
default:
return write_vu_acc_reg (&(vu1_device.regs),
rn - (NUM_VU_INTEGER_REGS + 5),
rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
}
@ -902,13 +1041,18 @@ sim_store_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
#ifdef TARGET_SKY_B
sim_io_eprintf( sd, "Invalid VIF register (register store ignored)\n" );
return 0;
#else
if (rn < NUM_VIF_REGS-1)
return write_pke_reg (&pke0_device, rn, memory);
return write_vif_reg (&vif0_device, rn, memory);
else
{
sim_io_eprintf( sd, "Can't write vif0_pc (store ignored)\n" );
return 0;
}
#endif /* ! TARGET_SKY_B */
}
rn -= NUM_VIF_REGS; /* VIF1 registers are last */
@ -916,7 +1060,7 @@ sim_store_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
if (rn < NUM_VIF_REGS-1)
return write_pke_reg (&pke1_device, rn, memory);
return write_vif_reg (&vif1_device, rn, memory);
else
{
sim_io_eprintf( sd, "Can't write vif1_pc (store ignored)\n" );
@ -996,6 +1140,38 @@ sim_fetch_register (sd,rn,memory,length)
*((unsigned64*)memory) = H2T_8(HI1);
return 8;
}
if (rn >= FIRST_COP0_REG && rn < (FIRST_COP0_REG+NUM_COP0_REGS))
{
switch (rn - FIRST_COP0_REG)
{
case 12: /* Status */
case 13: /* Cause */
return -1; /* Already done in regular register set */
case 14:
*((unsigned32*) memory) = H2T_4(EPC);
break;
case 16:
*((unsigned32*) memory) = H2T_4(C0_CONFIG);
break;
case 17: /* Debug */
*((unsigned32*) memory) = H2T_4(Debug);
break;
case 18: /* Perf */
*((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG + 7]);
break;
case 19: /* TagLo */
case 20: /* TagHi */
case 21: /* ErrorEPC */
*((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG + 9]);
break;
default:
*((unsigned32*) memory) = H2T_4(COP0_GPR[rn - FIRST_COP0_REG]);
break;
}
return 4;
}
/* end-sanitize-r5900 */
/* start-sanitize-sky */
@ -1006,6 +1182,10 @@ sim_fetch_register (sd,rn,memory,length)
if (rn < NUM_VU_REGS)
{
#ifdef TARGET_SKY_B
sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
return 0;
#else
if (rn < NUM_VU_INTEGER_REGS)
return read_vu_int_reg (&(vu0_device.regs), rn, memory);
else if (rn >= FIRST_VEC_REG)
@ -1017,24 +1197,36 @@ sim_fetch_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
return read_vu_special_reg(&vu0_device, VU_REG_CIA, memory);
return read_vu_special_reg (&vu0_device, VU_REG_CIA, memory);
case 1:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MR,
memory);
case 2: /* VU0 has no P register */
return read_vu_misc_reg(&(vu0_device.regs), VU_REG_MTPC, memory);
case 2:
return read_vu_special_reg (&vu0_device, VU_REG_STAT, memory);
case 3:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MST, memory);
case 4:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MMC, memory);
case 5:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MCP, memory);
case 6:
return read_vu_special_reg (&vu0_device, VU_REG_CMSAR0, memory);
case 7:
return read_vu_special_reg (&vu0_device, VU_REG_FBRST, memory);
case 8:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MR, memory);
case 9: /* VU0 has no P register */
*((int *) memory) = 0;
return 4;
case 3:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
memory);
case 4:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ,
memory);
case 10:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MI, memory);
case 11:
return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ, memory);
default:
return read_vu_acc_reg (&(vu0_device.regs),
rn - (NUM_VU_INTEGER_REGS + 5),
rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
#endif /* ! TARGET_SKY_B */
}
rn -= NUM_VU_REGS; /* VU1 registers are next */
@ -1052,22 +1244,37 @@ sim_fetch_register (sd,rn,memory,length)
else switch (rn - NUM_VU_INTEGER_REGS)
{
case 0:
return read_vu_special_reg(&vu1_device, VU_REG_CIA, memory);
return read_vu_special_reg (&vu1_device, VU_REG_CIA, memory);
case 1:
return read_vu_misc_reg (&(vu1_device.regs),
VU_REG_MR, memory);
return read_vu_misc_reg(&(vu1_device.regs), VU_REG_MTPC, memory);
case 2:
return read_vu_misc_reg (&(vu1_device.regs),
VU_REG_MP, memory);
return read_vu_special_reg (&vu1_device, VU_REG_STAT, memory);
case 3:
return read_vu_misc_reg (&(vu1_device.regs),
VU_REG_MI, memory);
return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MST, memory);
case 4:
return read_vu_misc_reg (&(vu1_device.regs),
VU_REG_MQ, memory);
return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MMC, memory);
case 5:
return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MCP, memory);
case 6: /* CMSAR1 is actually from VU0 */
#ifdef TARGET_SKY_B
return 0;
#else
return read_vu_special_reg (&vu0_device, VU_REG_CMSAR1, memory);
#endif /* ! TARGET_SKY_B */
case 7: /* VU1 has no FBRST register */
*((int *) memory) = 0;
return 4;
case 8:
return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MR, memory);
case 9:
return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MP, memory);
case 10:
return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MI, memory);
case 11:
return read_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ, memory);
default:
return read_vu_acc_reg (&(vu1_device.regs),
rn - (NUM_VU_INTEGER_REGS + 5),
rn - (NUM_VU_INTEGER_REGS + 12),
memory);
}
}
@ -1076,12 +1283,17 @@ sim_fetch_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
#ifdef TARGET_SKY_B
sim_io_eprintf( sd, "Invalid VIF register (register fetch ignored)\n" );
return 0;
#else
if (rn < NUM_VIF_REGS-2)
return read_pke_reg (&pke0_device, rn, memory);
return read_vif_reg (&vif0_device, rn, memory);
else if (rn == NUM_VIF_REGS-2)
return read_pke_pc (&pke0_device, memory);
return read_vif_pc (&vif0_device, memory);
else
return read_pke_pcx (&pke0_device, memory);
return read_vif_pcx (&vif0_device, memory);
#endif /* ! TARGET_SKY_B */
}
rn -= NUM_VIF_REGS; /* VIF1 registers are last */
@ -1089,11 +1301,11 @@ sim_fetch_register (sd,rn,memory,length)
if (rn < NUM_VIF_REGS)
{
if (rn < NUM_VIF_REGS-2)
return read_pke_reg (&pke1_device, rn, memory);
return read_vif_reg (&vif1_device, rn, memory);
else if (rn == NUM_VIF_REGS-2)
return read_pke_pc (&pke1_device, memory);
return read_vif_pc (&vif1_device, memory);
else
return read_pke_pcx (&pke1_device, memory);
return read_vif_pcx (&vif1_device, memory);
}
sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
@ -1205,7 +1417,7 @@ fetch_str (sd, addr)
}
/* Simple monitor interface (currently setup for the IDT and PMON monitors) */
static void
void
sim_monitor (SIM_DESC sd,
sim_cpu *cpu,
address_word cia,
@ -1715,6 +1927,259 @@ ColdReset (SIM_DESC sd)
}
}
/* start-sanitize-sky */
#ifdef TARGET_SKY
/* See ch. 5 of the 5900 Users' Guide. */
void
signal_exception (SIM_DESC sd,
sim_cpu *cpu,
address_word cia,
int cause, ...)
{
/* int vector; */
#ifdef DEBUG
sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",cause,pr_addr(cia));
#endif /* DEBUG */
/* Ensure that any active atomic read/modify/write operation will fail: */
LLBIT = 0;
/* First, handle any simulator specific magic exceptions. These are not "real" exceptions, but
are exceptions which the simulator uses to implement different features. */
switch (cause) {
case SimulatorFault:
{
va_list ap;
char *msg;
va_start(ap,cause);
msg = va_arg(ap,char *);
va_end(ap);
sim_engine_abort (SD, CPU, NULL_CIA,
"FATAL: Simulator error \"%s\"\n",msg);
}
case DebugBreakPoint :
if (! (Debug & Debug_DM))
{
if (INDELAYSLOT())
{
CANCELDELAYSLOT();
Debug |= Debug_DBD; /* signaled from within in delay slot */
DEPC = cia - 4; /* reference the branch instruction */
}
else
{
Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
DEPC = cia;
}
Debug |= Debug_DM; /* in debugging mode */
Debug |= Debug_DBp; /* raising a DBp exception */
PC = 0xBFC00200;
sim_engine_restart (SD, CPU, NULL, NULL_CIA);
}
break;
case ReservedInstruction :
{
va_list ap;
unsigned int instruction;
va_start(ap,cause);
instruction = va_arg(ap,unsigned int);
va_end(ap);
/* Provide simple monitor support using ReservedInstruction
exceptions. The following code simulates the fixed vector
entry points into the IDT monitor by causing a simulator
trap, performing the monitor operation, and returning to
the address held in the $ra register (standard PCS return
address). This means we only need to pre-load the vector
space with suitable instruction values. For systems were
actual trap instructions are used, we would not need to
perform this magic. */
if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
{
sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
/* NOTE: This assumes that a branch-and-link style
instruction was used to enter the vector (which is the
case with the current IDT monitor). */
sim_engine_restart (SD, CPU, NULL, RA);
}
/* Look for the mips16 entry and exit instructions, and
simulate a handler for them. */
else if ((cia & 1) != 0
&& (instruction & 0xf81f) == 0xe809
&& (instruction & 0x0c0) != 0x0c0)
{
mips16_entry (SD, CPU, cia, instruction);
sim_engine_restart (sd, NULL, NULL, NULL_CIA);
}
/* else fall through to normal exception processing */
sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
}
}
/* Now we have the code for processing "real" exceptions. */
if (is5900Level2Exception(cause)) {
switch(cause) {
case NMIReset:
cause_set_EXC2(1);
break;
default:
sim_engine_abort (SD, CPU, NULL_CIA,
"FATAL: Unexpected level 2 exception %d\n", cause);
}
if (STATE & simDELAYSLOT)
{
STATE &= ~simDELAYSLOT;
COP0_ERROREPC = (cia - 4); /* reference the branch instruction */
CAUSE |= cause_BD2;
}
else
{
COP0_ERROREPC = cia;
CAUSE &= ~cause_BD2;
}
SR |= status_ERL;
if (cause == NMIReset)
PC = 0xBFC0000;
else
{
ASSERT(0); /* At the moment, COUNTER, DEBUG never generated. */
}
sim_engine_restart (SD, CPU, NULL, PC);
} else {
/* A level 1 exception. */
int refill, vector_offset;
cause_set_EXC(cause);
if (SR & status_EXL)
vector_offset = 0x180;
else
{
if (cause == TLBLoad || cause == TLBStore) {
va_list ap;
va_start(ap, cause);
refill = va_arg(ap,int);
va_end(ap);
}
if (STATE & simDELAYSLOT)
{
STATE &= ~simDELAYSLOT;
CAUSE |= cause_BD;
COP0_EPC = (cia - 4); /* reference the branch instruction */
}
else
{
COP0_EPC = cia;
CAUSE &= ~cause_BD;
}
SR |= status_EXL;
if ((cause == TLBLoad || cause == TLBStore) && refill == TLB_REFILL)
vector_offset = 0x000;
else if (cause == Interrupt)
vector_offset = 0x200;
else
vector_offset = 0x180;
if (SR & status_BEV)
PC = (signed)0xBFC00200 + vector_offset;
else
PC = (signed)0x80000000 + vector_offset;
}
/* Now, handle the exception. */
switch (cause)
{
case Interrupt:
{
va_list ap;
unsigned int level;
va_start(ap, cause);
level = va_arg(ap,unsigned int);
va_end(ap);
/* Interrupts arrive during event processing, no need to restart.
Hardware interrupts on sky target are INT1 and INT2. */
if ( level == 1 )
CAUSE |= cause_IP3; /* bit 11 */
else if ( level == 2 )
CAUSE |= cause_IP7; /* bit 15 */
else
sim_engine_abort (SD, CPU, NULL_CIA,
"FATAL: Unexpected interrupt level %d\n", level);
return;
}
case NMIReset:
ASSERT(0); /* NMIReset is a level 0 exception. */
return;
case AddressLoad:
case AddressStore:
case InstructionFetch:
case DataReference:
/* The following is so that the simulator will continue from the
exception address on breakpoint operations. */
PC = COP0_EPC;
sim_engine_halt (SD, CPU, NULL, NULL_CIA,
sim_stopped, SIM_SIGBUS);
break;
case ReservedInstruction:
case CoProcessorUnusable:
PC = COP0_EPC;
sim_engine_halt (SD, CPU, NULL, NULL_CIA,
sim_stopped, SIM_SIGILL);
break;
case IntegerOverflow:
case FPE:
PC = COP0_EPC;
sim_engine_halt (SD, CPU, NULL, NULL_CIA,
sim_stopped, SIM_SIGFPE);
break;
case TLBModification:
case TLBLoad:
case TLBStore:
case BreakPoint:
case SystemCall:
case Trap:
sim_engine_restart (SD, CPU, NULL, PC);
break;
case Watch:
PC = COP0_EPC;
sim_engine_halt (SD, CPU, NULL, NULL_CIA,
sim_stopped, SIM_SIGTRAP);
break;
default : /* Unknown internal exception */
PC = COP0_EPC;
sim_engine_halt (SD, CPU, NULL, NULL_CIA,
sim_stopped, SIM_SIGABRT);
break;
}
}
return;
}
#else /* TARGET_SKY */
/* end-sanitize-sky */
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
/* Signal an exception condition. This will result in an exception
that aborts the instruction. The instruction operation pseudocode
@ -1928,6 +2393,11 @@ signal_exception (SIM_DESC sd,
return;
}
/* start-sanitize-sky */
#endif /* ! TARGET_SKY */
/* end-sanitize-sky */
#if defined(WARN_RESULT)
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
/* This function indicates that the result of the operation is
@ -3082,7 +3552,7 @@ cop_ld (SIM_DESC sd,
/* start-sanitize-sky */
#ifdef TARGET_SKY
#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
void
cop_lq (SIM_DESC sd,
sim_cpu *cpu,
@ -3183,7 +3653,7 @@ cop_sd (SIM_DESC sd,
/* start-sanitize-sky */
#ifdef TARGET_SKY
#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
unsigned128
cop_sq (SIM_DESC sd,
sim_cpu *cpu,
@ -3423,7 +3893,7 @@ decode_coproc (SIM_DESC sd,
int handle = 0;
/* start-sanitize-sky */
#ifdef TARGET_SKY
#if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
/* On the R5900, this refers to a "VU" vector co-processor. */
int i_25_21 = (instruction >> 21) & 0x1f;
@ -3595,10 +4065,6 @@ decode_coproc (SIM_DESC sd,
/* NOTREACHED */
}
#undef MY_INDEX
#undef MY_PREFIX
#undef MY_NAME
#endif /* TARGET_SKY */
/* end-sanitize-sky */

View File

@ -36,14 +36,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
typedef address_word sim_cia;
#if (WITH_IGEN)
/* Get the number of instructions. FIXME: must be a more elegant way
of doing this. */
#include "itable.h"
#define MAX_INSNS (nr_itable_entries)
#define INSN_NAME(cpu,i) itable[(i)].name
#endif
#include "sim-base.h"
@ -254,7 +246,25 @@ enum {
R5900_FPMIN = LSMASK32 (31, 0),
};
typedef struct _r4000_tlb_entry {
unsigned32 mask;
unsigned32 hi;
unsigned32 lo0;
unsigned32 lo1;
} r4000_tlb_entry_t;
#define TLB_MASK_MASK_MASK 0x01ffe000
#define TLB_HI_VPN2_MASK 0xffffe000
#define TLB_HI_G_MASK 0x00001000
#define TLB_HI_ASID_MASK 0x000000ff
#define TLB_LO_S_MASK 0x80000000
#define TLB_LO_PFN_MASK 0x03ffffc0
#define TLB_LO_C_MASK 0x00000038
#define TLB_LO_D_MASK 0x00000004
#define TLB_LO_V_MASK 0x00000002
#define TLB_SIZE 48
typedef struct _sim_r5900_cpu {
@ -270,6 +280,7 @@ typedef struct _sim_r5900_cpu {
same register. */
signed_word gpr1[32];
#define GPR1 ((CPU)->r5900.gpr1)
#define GPR1_SET(N,VAL) (GPR1[(N]) = (VAL))
signed_word lo1;
signed_word hi1;
#define LO1 ((CPU)->r5900.lo1)
@ -294,6 +305,9 @@ typedef struct _sim_r5900_cpu {
hilo_history lo1_history;
#define LO1HISTORY (&(CPU)->r5900.lo1_history)
r4000_tlb_entry_t tlb[TLB_SIZE];
#define TLB ((CPU)->r5900.tlb)
} sim_r5900_cpu;
#define BYTES_IN_MMI_REGS (sizeof(signed_word) + sizeof(signed_word))
@ -565,10 +579,14 @@ struct _sim_cpu {
#ifndef TM_MIPS_H
#define LAST_EMBED_REGNUM (89)
#define NUM_REGS (LAST_EMBED_REGNUM + 1)
/* start-sanitize-r5900 */
#define FIRST_COP0_REG 128
#define NUM_COP0_REGS 22
#undef NUM_REGS
#define NUM_REGS (128)
#define NUM_REGS (150)
/* end-sanitize-r5900 */
#endif
/* start-sanitize-sky */
@ -582,7 +600,7 @@ struct _sim_cpu {
#define NUM_VIF_REGS 26
#define NUM_CORE_REGS 128
#define NUM_CORE_REGS 150
#undef NUM_REGS
#define NUM_REGS (NUM_CORE_REGS + 2*(NUM_VU_REGS) + 2*(NUM_VIF_REGS))
@ -667,9 +685,31 @@ enum float_operation
#define COP0_BP ((CPU)->cop0_bp)
#define NR_COP0_P 64
unsigned_word cop0_p[NR_COP0_P];
#define COP0_P ((CPU)->cop0_p)
/* end-sanitize-r5900 */
#define COP0_P ((CPU)->cop0_p)
#define COP0_INDEX ((unsigned32)(COP0_GPR[0]))
#define COP0_RANDOM ((unsigned32)(COP0_GPR[1]))
#define COP0_ENTRYLO0 ((unsigned32)(COP0_GPR[2]))
#define COP0_ENTRYLO1 ((unsigned32)(COP0_GPR[3]))
#define COP0_CONTEXT ((unsigned32)(COP0_GPR[4]))
#define COP0_PAGEMASK ((unsigned32)(COP0_GPR[5]))
#define COP0_WIRED ((unsigned32)(COP0_GPR[6]))
#define COP0_BADVADDR ((unsigned32)(COP0_GPR[8]))
#define COP0_COUNT ((unsigned32)(COP0_GPR[9]))
#define COP0_ENTRYHI ((unsigned32)(COP0_GPR[10]))
#define COP0_COMPARE ((unsigned32)(COP0_GPR[11]))
#define COP0_EPC ((unsigned32)(EPC)) /* 14 */
#define COP0_PRID ((unsigned32)(COP0_GPR[15]))
#define COP0_CONFIG ((unsigned32)(C0_CONFIG)) /* 16 */
#define COP0_TAGLO ((unsigned32)(COP0_GPR[28]))
#define COP0_TAGHI ((unsigned32)(COP0_GPR[29]))
#define COP0_ERROREPC ((unsigned32)(COP0_GPR[30]))
#define COP0_CONTEXT_BADVPN2_MASK 0x007ffff0
#define COP0_CONTEXT_set_BADVPN2(x) \
(COP0_CONTEXT = ((COP0_CONTEXT & 0xff100000) | ((x << 4) & 0x007ffff0)))
/* end-sanitize-r5900 */
/* Keep the current format state for each register: */
FP_formats fpr_state[32];
@ -716,20 +756,20 @@ enum float_operation
/* end-sanitize-branchbug4011 */
/* start-sanitize-r5900 */
sim_r5900_cpu r5900;
/* end-sanitize-r5900 */
/* start-sanitize-cygnus */
/* start-sanitize-cygnus */
/* The MDMX ISA has a very very large accumulator */
unsigned8 acc[3 * 8];
/* end-sanitize-cygnus */
/* start-sanitize-sky */
/* start-sanitize-sky */
#ifdef TARGET_SKY
/* Device on which instruction issue last occured. */
char cur_device;
#endif
/* end-sanitize-sky */
sim_cpu_base base;
};
@ -778,13 +818,15 @@ struct sim_state {
/* TODO : these should be the bitmasks for these bits within the
status register. At the moment the following are VR4300
bit-positions: */
#define status_KSU_mask (0x3) /* mask for KSU bits */
#define status_KSU_mask (0x18) /* mask for KSU bits */
#define status_KSU_shift (3) /* shift for field */
#define ksu_kernel (0x0)
#define ksu_supervisor (0x1)
#define ksu_user (0x2)
#define ksu_unknown (0x3)
#define SR_KSU ((SR & status_KSU_mask) >> status_KSU_shift)
#define status_IE (1 << 0) /* Interrupt enable */
#define status_EIE (1 << 16) /* Enable Interrupt Enable */
#define status_EXL (1 << 1) /* Exception level */
@ -794,6 +836,7 @@ struct sim_state {
#define status_BEV (1 << 22) /* Location of general exception vectors */
#define status_TS (1 << 21) /* TLB shutdown has occurred */
#define status_ERL (1 << 2) /* Error level */
#define status_IM7 (1 << 15) /* Timer Interrupt Mask */
#define status_RP (1 << 27) /* Reduced Power mode */
/* start-sanitize-r5900 */
#define status_CU0 (1 << 28) /* COP0 usable */
@ -813,16 +856,35 @@ struct sim_state {
#define status_NMI (1 << 20) /* NMI */
#define status_NMI (1 << 20) /* NMI */
#define cause_EXC_mask (0x1f) /* Exception code */
#define cause_BD ((unsigned)1 << 31) /* L1 Exception in branch delay slot */
#define cause_BD2 (1 << 30) /* L2 Exception in branch delay slot */
#define cause_CE_mask 0x30000000 /* Coprocessor exception */
#define cause_CE_shift 28
#define cause_EXC2_mask 0x00070000
#define cause_EXC2_shift 16
#define cause_IP7 (1 << 15) /* Interrupt pending */
#define cause_SIOP (1 << 12) /* SIO pending */
#define cause_IP3 (1 << 11) /* Int 0 pending */
#define cause_IP2 (1 << 10) /* Int 1 pending */
/* start-sanitize-sky */
#ifdef TARGET_SKY
#define cause_EXC_mask (0x7c) /* Exception code */
#else
/* end-sanitize-sky */
#define cause_EXC_mask (0x1c) /* Exception code */
/* start-sanitize-sky */
#endif
/* end-sanitize-sky */
#define cause_EXC_shift (2)
#define cause_SW0 (1 << 8) /* Software interrupt 0 */
#define cause_SW1 (1 << 9) /* Software interrupt 1 */
#define cause_IP_mask (0x3f) /* Interrupt pending field */
#define cause_IP_shift (10)
#define cause_CE_mask (0x3) /* Coprocessor error */
#define cause_CE_shift (28)
#define cause_BD ((unsigned)1 << 31) /* Exception in branch delay slot */
#define cause_set_EXC(x) CAUSE = (CAUSE & ~cause_EXC_mask) | ((x << cause_EXC_shift) & cause_EXC_mask)
#define cause_set_EXC2(x) CAUSE = (CAUSE & ~cause_EXC2_mask) | ((x << cause_EXC2_shift) & cause_EXC2_mask)
/* NOTE: We keep the following status flags as bit values (1 for true,
@ -834,7 +896,7 @@ struct sim_state {
#ifdef SUBTARGET_R3900
#define UserMode ((SR & status_KUc) ? 1 : 0)
#else
#define UserMode ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
#define UserMode ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
#endif /* SUBTARGET_R3900 */
/* BigEndianMem */
@ -863,54 +925,72 @@ struct sim_state {
/* NOTE: These numbers depend on the processor architecture being
simulated: */
#define Interrupt (0)
#define TLBModification (1)
#define TLBLoad (2)
#define TLBStore (3)
#define AddressLoad (4)
#define AddressStore (5)
#define InstructionFetch (6)
#define DataReference (7)
#define SystemCall (8)
#define BreakPoint (9)
#define ReservedInstruction (10)
#define CoProcessorUnusable (11)
#define IntegerOverflow (12) /* Arithmetic overflow (IDT monitor raises SIGFPE) */
#define Trap (13)
#define FPE (15)
#define DebugBreakPoint (16)
#define Watch (23)
#define NMIReset (31)
enum ExceptionCause {
Interrupt = 0,
TLBModification = 1,
TLBLoad = 2,
TLBStore = 3,
AddressLoad = 4,
AddressStore = 5,
InstructionFetch = 6,
DataReference = 7,
SystemCall = 8,
BreakPoint = 9,
ReservedInstruction = 10,
CoProcessorUnusable = 11,
IntegerOverflow = 12, /* Arithmetic overflow (IDT monitor raises SIGFPE) */
Trap = 13,
FPE = 15,
DebugBreakPoint = 16,
Watch = 23,
NMIReset = 31,
/* The following exception code is actually private to the simulator
world. It is *NOT* a processor feature, and is used to signal
run-time errors in the simulator. */
#define SimulatorFault (0xFFFFFFFF)
SimulatorFault = 0xFFFFFFFF
};
#define TLB_REFILL (0)
#define TLB_INVALID (1)
/* start-sanitize-r5900 */
/* For the 5900, we have level 1 and level 2 exceptions. The level 2 exceptions
are ColdReset, NMI, Counter, and Debug/SIO. Of these, we support only
the NMIReset exception. */
#define is5900Level2Exception(x) (x == NMIReset)
/* end-sanitize-r5900 */
/* The following break instructions are reserved for use by the
simulator. The first is used to halt the simulation. The second
is used by gdb for break-points. NOTE: Care must be taken, since
this value may be used in later revisions of the MIPS ISA. */
#define HALT_INSTRUCTION_MASK (0x03FFFFC0)
#define HALT_INSTRUCTION_MASK (0x03FFFFC0)
#define HALT_INSTRUCTION (0x03ff000d)
#define HALT_INSTRUCTION2 (0x0000ffcd)
#define HALT_INSTRUCTION (0x03ff000d)
#define HALT_INSTRUCTION2 (0x0000ffcd)
/* start-sanitize-sky */
#define HALT_INSTRUCTION_PASS (0x03fffc0d)
#define HALT_INSTRUCTION_FAIL (0x03ffffcd)
#define HALT_INSTRUCTION_PASS (0x03fffc0d) /* break 0xffff0 */
#define HALT_INSTRUCTION_FAIL (0x03ffffcd) /* break 0xfffff */
/* end-sanitize-sky */
#define BREAKPOINT_INSTRUCTION (0x0005000d)
#define BREAKPOINT_INSTRUCTION2 (0x0000014d)
/* start-sanitize-sky */
#define LOAD_INSTRUCTION (0x03fffc4d) /* break 0xffff1 */
#define PRINTF_INSTRUCTION (0x03fffc8d) /* break 0xffff2 */
/* end-sanitize-sky */
void interrupt_event (SIM_DESC sd, void *data);
void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exception, ...);
#define SignalException(exc,instruction) signal_exception (SD, CPU, cia, (exc), (instruction))
#define SignalExceptionInterrupt() signal_exception (SD, CPU, cia, Interrupt)
#define SignalExceptionInterrupt(level) signal_exception (SD, CPU, cia, Interrupt, level)
#define SignalExceptionInstructionFetch() signal_exception (SD, CPU, cia, InstructionFetch)
#define SignalExceptionAddressStore() signal_exception (SD, CPU, cia, AddressStore)
#define SignalExceptionAddressLoad() signal_exception (SD, CPU, cia, AddressLoad)
@ -919,6 +999,11 @@ void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exceptio
#define SignalExceptionIntegerOverflow() signal_exception (SD, CPU, cia, IntegerOverflow)
#define SignalExceptionCoProcessorUnusable() signal_exception (SD, CPU, cia, CoProcessorUnusable)
#define SignalExceptionNMIReset() signal_exception (SD, CPU, cia, NMIReset)
#define SignalExceptionTLBRefillStore() signal_exception (SD, CPU, cia, TLBStore, TLB_REFILL)
#define SignalExceptionTLBRefillLoad() signal_exception (SD, CPU, cia, TLBLoad, TLB_REFILL)
#define SignalExceptionTLBInvalidStore() signal_exception (SD, CPU, cia, TLBStore, TLB_INVALID)
#define SignalExceptionTLBInvalidLoad() signal_exception (SD, CPU, cia, TLBLoad, TLB_INVALID)
#define SignalExceptionTLBModification() signal_exception (SD, CPU, cia, TLBModification)
/* Co-processor accesses */
@ -1036,6 +1121,7 @@ char* pr_uword64 PARAMS ((uword64 addr));
/* start-sanitize-sky */
#ifdef TARGET_SKY
#ifdef SIM_ENGINE_HALT_HOOK
#undef SIM_ENGINE_HALT_HOOK
#endif
@ -1055,6 +1141,8 @@ SIM_RC sky_sim_module_install PARAMS ((SIM_DESC sd));
#define MODULE_LIST sky_sim_module_install,
void sim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int arg);
#ifndef TM_TXVU_H /* In case GDB hasn't been configured yet */
enum txvu_cpu_context
{
@ -1062,7 +1150,7 @@ enum txvu_cpu_context
TXVU_CPU_MASTER = 0, /* R5900 core */
TXVU_CPU_VU0 = 1, /* Vector units */
TXVU_CPU_VU1 = 2,
TXVU_CPU_VIF0 = 3, /* FIFO's */
TXVU_CPU_VIF0 = 3, /* Vector interface units */
TXVU_CPU_VIF1 = 4,
TXVU_CPU_LAST /* Count of context types */
};

File diff suppressed because it is too large Load Diff

View File

@ -1,495 +0,0 @@
/* Copyright (C) 1998, Cygnus Solutions */
#ifndef H_PKE_H
#define H_PKE_H
#include "sim-main.h"
#include "sky-device.h"
/* External functions */
struct pke_fifo;
struct fifo_quadword;
struct pke_device;
void pke0_attach(SIM_DESC sd);
void pke0_issue(SIM_DESC sd);
void pke1_attach(SIM_DESC sd);
void pke1_issue(SIM_DESC sd);
void pke_options(struct pke_device *device, unsigned_4 option, char *option_string);
int read_pke_reg (struct pke_device *device, int regno, void *buf);
int write_pke_reg (struct pke_device *device, int regno, const void *buf);
int read_pke_pc (struct pke_device *device, void *buf);
int read_pke_pcx (struct pke_device *device, void *buf);
struct fifo_quadword* pke_fifo_access(struct pke_fifo*, unsigned_4 qwnum);
/* Quadword data type */
typedef unsigned_4 quadword[4];
/* truncate address to quadword */
#define ADDR_TRUNC_QW(addr) ((addr) & ~0x0f)
/* extract offset in quadword */
#define ADDR_OFFSET_QW(addr) ((addr) & 0x0f)
/* SCEI memory mapping information */
#define PKE0_REGISTER_WINDOW_START 0x10003800
#define PKE1_REGISTER_WINDOW_START 0x10003C00
#define PKE0_FIFO_ADDR 0x10004000
#define PKE1_FIFO_ADDR 0x10005000
/* VU source-addr tracking tables */ /* changed from 1998-01-22 e-mail plans */
#define VU0_MEM0_SRCADDR_START 0x19800000
#define VU0_MEM1_SRCADDR_START 0x19804000
#define VU1_MEM0_SRCADDR_START 0x19808000
#define VU1_MEM1_SRCADDR_START 0x1980C000
#define VU0_CIA (VU0_REGISTER_WINDOW_START + VU_REG_CIA)
#define VU1_CIA (VU1_REGISTER_WINDOW_START + VU_REG_CIA)
/* GPUIF STAT register */
#define GPUIF_REG_STAT_APATH_E 11
#define GPUIF_REG_STAT_APATH_B 10
/* COP2 STAT register */
#define COP2_REG_STAT_ADDR VPU_STAT_ADDR
#define COP2_REG_STAT_VBS1_E 8
#define COP2_REG_STAT_VBS1_B 8
#define COP2_REG_STAT_VBS0_E 0
#define COP2_REG_STAT_VBS0_B 0
/* Quadword indices of PKE registers. Actual registers sit at bottom
32 bits of each quadword. */
#define PKE_REG_STAT 0x00
#define PKE_REG_FBRST 0x01
#define PKE_REG_ERR 0x02
#define PKE_REG_MARK 0x03
#define PKE_REG_CYCLE 0x04
#define PKE_REG_MODE 0x05
#define PKE_REG_NUM 0x06
#define PKE_REG_MASK 0x07
#define PKE_REG_CODE 0x08
#define PKE_REG_ITOPS 0x09
#define PKE_REG_BASE 0x0a /* pke1 only */
#define PKE_REG_OFST 0x0b /* pke1 only */
#define PKE_REG_TOPS 0x0c /* pke1 only */
#define PKE_REG_ITOP 0x0d
#define PKE_REG_TOP 0x0e /* pke1 only */
#define PKE_REG_DBF 0x0f /* pke1 only */
#define PKE_REG_R0 0x10 /* R0 .. R3 must be contiguous */
#define PKE_REG_R1 0x11
#define PKE_REG_R2 0x12
#define PKE_REG_R3 0x13
#define PKE_REG_C0 0x14 /* C0 .. C3 must be contiguous */
#define PKE_REG_C1 0x15
#define PKE_REG_C2 0x16
#define PKE_REG_C3 0x17
/* one plus last index */
#define PKE_NUM_REGS 0x18
#define PKE_REGISTER_WINDOW_SIZE (sizeof(quadword) * PKE_NUM_REGS)
/* PKE commands */
#define PKE_CMD_PKENOP_MASK 0x7F
#define PKE_CMD_PKENOP_BITS 0x00
#define PKE_CMD_STCYCL_MASK 0x7F
#define PKE_CMD_STCYCL_BITS 0x01
#define PKE_CMD_OFFSET_MASK 0x7F
#define PKE_CMD_OFFSET_BITS 0x02
#define PKE_CMD_BASE_MASK 0x7F
#define PKE_CMD_BASE_BITS 0x03
#define PKE_CMD_ITOP_MASK 0x7F
#define PKE_CMD_ITOP_BITS 0x04
#define PKE_CMD_STMOD_MASK 0x7F
#define PKE_CMD_STMOD_BITS 0x05
#define PKE_CMD_MSKPATH3_MASK 0x7F
#define PKE_CMD_MSKPATH3_BITS 0x06
#define PKE_CMD_PKEMARK_MASK 0x7F
#define PKE_CMD_PKEMARK_BITS 0x07
#define PKE_CMD_FLUSHE_MASK 0x7F
#define PKE_CMD_FLUSHE_BITS 0x10
#define PKE_CMD_FLUSH_MASK 0x7F
#define PKE_CMD_FLUSH_BITS 0x11
#define PKE_CMD_FLUSHA_MASK 0x7F
#define PKE_CMD_FLUSHA_BITS 0x13
#define PKE_CMD_PKEMSCAL_MASK 0x7F /* CAL == "call" */
#define PKE_CMD_PKEMSCAL_BITS 0x14
#define PKE_CMD_PKEMSCNT_MASK 0x7F /* CNT == "continue" */
#define PKE_CMD_PKEMSCNT_BITS 0x17
#define PKE_CMD_PKEMSCALF_MASK 0x7F /* CALF == "call after flush" */
#define PKE_CMD_PKEMSCALF_BITS 0x15
#define PKE_CMD_STMASK_MASK 0x7F
#define PKE_CMD_STMASK_BITS 0x20
#define PKE_CMD_STROW_MASK 0x7F
#define PKE_CMD_STROW_BITS 0x30
#define PKE_CMD_STCOL_MASK 0x7F
#define PKE_CMD_STCOL_BITS 0x31
#define PKE_CMD_MPG_MASK 0x7F
#define PKE_CMD_MPG_BITS 0x4A
#define PKE_CMD_DIRECT_MASK 0x7F
#define PKE_CMD_DIRECT_BITS 0x50
#define PKE_CMD_DIRECTHL_MASK 0x7F
#define PKE_CMD_DIRECTHL_BITS 0x51
#define PKE_CMD_UNPACK_MASK 0x60
#define PKE_CMD_UNPACK_BITS 0x60
/* test given word for particular PKE command bit pattern */
#define IS_PKE_CMD(word,cmd) (((word) & PKE_CMD_##cmd##_MASK) == PKE_CMD_##cmd##_BITS)
/* register bitmasks: bit numbers for end and beginning of fields */
/* PKE opcode */
#define PKE_OPCODE_I_E 31
#define PKE_OPCODE_I_B 31
#define PKE_OPCODE_CMD_E 30
#define PKE_OPCODE_CMD_B 24
#define PKE_OPCODE_NUM_E 23
#define PKE_OPCODE_NUM_B 16
#define PKE_OPCODE_IMM_E 15
#define PKE_OPCODE_IMM_B 0
/* STAT register */
#define PKE_REG_STAT_FQC_E 28
#define PKE_REG_STAT_FQC_B 24
#define PKE_REG_STAT_FDR_E 23
#define PKE_REG_STAT_FDR_B 23
#define PKE_REG_STAT_ER1_E 13
#define PKE_REG_STAT_ER1_B 13
#define PKE_REG_STAT_ER0_E 12
#define PKE_REG_STAT_ER0_B 12
#define PKE_REG_STAT_INT_E 11
#define PKE_REG_STAT_INT_B 11
#define PKE_REG_STAT_PIS_E 10
#define PKE_REG_STAT_PIS_B 10
#define PKE_REG_STAT_PFS_E 9
#define PKE_REG_STAT_PFS_B 9
#define PKE_REG_STAT_PSS_E 8
#define PKE_REG_STAT_PSS_B 8
#define PKE_REG_STAT_DBF_E 7
#define PKE_REG_STAT_DBF_B 7
#define PKE_REG_STAT_MRK_E 6
#define PKE_REG_STAT_MRK_B 6
#define PKE_REG_STAT_PGW_E 3
#define PKE_REG_STAT_PGW_B 3
#define PKE_REG_STAT_PEW_E 2
#define PKE_REG_STAT_PEW_B 2
#define PKE_REG_STAT_PPS_E 1
#define PKE_REG_STAT_PPS_B 0
#define PKE_REG_STAT_PPS_IDLE 0x00 /* ready to execute next instruction */
#define PKE_REG_STAT_PPS_WAIT 0x01 /* not enough words in FIFO */
#define PKE_REG_STAT_PPS_DECODE 0x02 /* decoding instruction */
#define PKE_REG_STAT_PPS_STALL 0x02 /* alias state for stall (e.g., FLUSHE) */
#define PKE_REG_STAT_PPS_XFER 0x03 /* transferring instruction operands */
/* DBF register */
#define PKE_REG_DBF_DF_E 0
#define PKE_REG_DBF_DF_B 0
/* OFST register */
#define PKE_REG_OFST_OFFSET_E 9
#define PKE_REG_OFST_OFFSET_B 0
/* OFST register */
#define PKE_REG_TOPS_TOPS_E 9
#define PKE_REG_TOPS_TOPS_B 0
/* BASE register */
#define PKE_REG_BASE_BASE_E 9
#define PKE_REG_BASE_BASE_B 0
/* ITOPS register */
#define PKE_REG_ITOPS_ITOPS_E 9
#define PKE_REG_ITOPS_ITOPS_B 0
/* MODE register */
#define PKE_REG_MODE_MDE_E 1
#define PKE_REG_MODE_MDE_B 0
/* NUM register */
#define PKE_REG_NUM_NUM_E 9
#define PKE_REG_NUM_NUM_B 0
/* MARK register */
#define PKE_REG_MARK_MARK_E 15
#define PKE_REG_MARK_MARK_B 0
/* ITOP register */
#define PKE_REG_ITOP_ITOP_E 9
#define PKE_REG_ITOP_ITOP_B 0
/* TOP register */
#define PKE_REG_TOP_TOP_E 9
#define PKE_REG_TOP_TOP_B 0
/* MASK register */
#define PKE_REG_MASK_MASK_E 31
#define PKE_REG_MASK_MASK_B 0
/* CYCLE register */
#define PKE_REG_CYCLE_WL_E 15
#define PKE_REG_CYCLE_WL_B 8
#define PKE_REG_CYCLE_CL_E 7
#define PKE_REG_CYCLE_CL_B 0
/* ERR register */
#define PKE_REG_ERR_ME1_E 2
#define PKE_REG_ERR_ME1_B 2
#define PKE_REG_ERR_ME0_E 1
#define PKE_REG_ERR_ME0_B 1
#define PKE_REG_ERR_MII_E 0
#define PKE_REG_ERR_MII_B 0
/* FBRST command bitfields */
#define PKE_REG_FBRST_STC_E 3
#define PKE_REG_FBRST_STC_B 3
#define PKE_REG_FBRST_STP_E 2
#define PKE_REG_FBRST_STP_B 2
#define PKE_REG_FBRST_FBK_E 1
#define PKE_REG_FBRST_FBK_B 1
#define PKE_REG_FBRST_RST_E 0
#define PKE_REG_FBRST_RST_B 0
/* MSKPATH3 command bitfields */
#define PKE_REG_MSKPATH3_E 15
#define PKE_REG_MSKPATH3_B 15
/* UNPACK opcodes */
#define PKE_UNPACK(vn,vl) ((vn) << 2 | (vl))
#define PKE_UNPACK_S_32 PKE_UNPACK(0, 0)
#define PKE_UNPACK_S_16 PKE_UNPACK(0, 1)
#define PKE_UNPACK_S_8 PKE_UNPACK(0, 2)
#define PKE_UNPACK_V2_32 PKE_UNPACK(1, 0)
#define PKE_UNPACK_V2_16 PKE_UNPACK(1, 1)
#define PKE_UNPACK_V2_8 PKE_UNPACK(1, 2)
#define PKE_UNPACK_V3_32 PKE_UNPACK(2, 0)
#define PKE_UNPACK_V3_16 PKE_UNPACK(2, 1)
#define PKE_UNPACK_V3_8 PKE_UNPACK(2, 2)
#define PKE_UNPACK_V4_32 PKE_UNPACK(3, 0)
#define PKE_UNPACK_V4_16 PKE_UNPACK(3, 1)
#define PKE_UNPACK_V4_8 PKE_UNPACK(3, 2)
#define PKE_UNPACK_V4_5 PKE_UNPACK(3, 3)
/* MASK register sub-field definitions */
#define PKE_MASKREG_INPUT 0
#define PKE_MASKREG_ROW 1
#define PKE_MASKREG_COLUMN 2
#define PKE_MASKREG_NOTHING 3
/* STMOD register field definitions */
#define PKE_MODE_INPUT 0
#define PKE_MODE_ADDROW 1
#define PKE_MODE_ACCROW 2
/* extract a MASK register sub-field for row [0..3] and column [0..3] */
/* MASK register is laid out of 2-bit values in this r-c order */
/* m33 m32 m31 m30 m23 m22 m21 m20 m13 m12 m11 m10 m03 m02 m01 m00 */
#define PKE_MASKREG_GET(me,row,col) \
((((me)->regs[PKE_REG_MASK][0]) >> (8*(row) + 2*(col))) & 0x03)
/* operations - replace with those in sim-bits.h when convenient */
/* unsigned 32-bit mask of given width */
#define BIT_MASK(width) ((width) == 31 ? 0xffffffff : (((unsigned_4)1) << (width+1)) - 1)
/* e.g.: BIT_MASK(4) = 00011111 */
/* mask between given given bits numbers (MSB) */
#define BIT_MASK_BTW(begin,end) ((BIT_MASK(end) & ~((begin) == 0 ? 0 : BIT_MASK((begin)-1))))
/* e.g.: BIT_MASK_BTW(4,11) = 0000111111110000 */
/* set bitfield value */
#define BIT_MASK_SET(lvalue,begin,end,value) \
do { \
ASSERT((begin) <= (end)); \
(lvalue) &= ~BIT_MASK_BTW((begin),(end)); \
(lvalue) |= ((value) << (begin)) & BIT_MASK_BTW((begin),(end)); \
} while(0)
/* get bitfield value */
#define BIT_MASK_GET(rvalue,begin,end) \
(((rvalue) & BIT_MASK_BTW(begin,end)) >> (begin))
/* e.g., BIT_MASK_GET(0000111100001111, 2, 8) = 0000000100001100 */
/* These ugly macro hacks allow succinct bitfield accesses */
/* set a bitfield in a register by "name" */
#define PKE_REG_MASK_SET(me,reg,flag,value) \
do { \
unsigned_4 old = BIT_MASK_GET(((me)->regs[PKE_REG_##reg][0]), \
PKE_REG_##reg##_##flag##_B, PKE_REG_##reg##_##flag##_E); \
BIT_MASK_SET(((me)->regs[PKE_REG_##reg][0]), \
PKE_REG_##reg##_##flag##_B, PKE_REG_##reg##_##flag##_E, \
(value)); \
if( indebug ((me)->dev.name)) \
{ \
if (old != (value)) \
{ \
if (((me)->fifo_trace_file == NULL ) && \
((me)->fifo_trace_file_name != NULL )) \
sky_open_file (&((me)->fifo_trace_file), \
(me)->fifo_trace_file_name, \
(char *) NULL, _IOLBF ); \
fprintf (((me)->fifo_trace_file != NULL) ? \
(me)->fifo_trace_file : stdout, \
"# Reg %s:%s = 0x%x\n", #reg, #flag, (unsigned)(value)); \
} \
} \
} while(0)
/* get a bitfield from a register by "name" */
#define PKE_REG_MASK_GET(me,reg,flag) \
BIT_MASK_GET(((me)->regs[PKE_REG_##reg][0]), \
PKE_REG_##reg##_##flag##_B, PKE_REG_##reg##_##flag##_E)
#define PKE_LIMIT(value,max) ((value) > (max) ? (max) : (value))
/* Classify words in a FIFO quadword */
enum wordclass
{
wc_dma = 'D',
wc_pkecode = 'P',
wc_unknown = '?',
wc_pkedata = '.',
wc_gpuiftag = 'g'
};
/* One row in the FIFO */
struct fifo_quadword
{
/* 128 bits of data */
quadword data;
/* source main memory address (or 0: unknown) */
unsigned_4 source_address;
/* classification of words in quadword; wc_dma set on DMA tags at FIFO write */
enum wordclass word_class[4];
};
/* quadword FIFO structure for PKE */
typedef struct pke_fifo
{
struct fifo_quadword** quadwords; /* pointer to fifo quadwords */
unsigned_4 origin; /* quadword serial number of quadwords[0] */
unsigned_4 length; /* length of quadword pointer array: 0..N */
unsigned_4 next; /* relative index of first unfilled quadword: 0..length-1 */
} pke_fifo;
#define PKE_FIFO_GROW_SIZE 1000 /* number of quadword pointers to allocate */
#define PKE_FIFO_ARCHEOLOGY 1000 /* number of old quadwords to keep as history */
/* PKE internal state: FIFOs, registers, handle to VU friend */
struct pke_device
{
/* common device info */
device dev;
/* identity: 0=PKE0, 1=PKE1 */
int pke_number;
int flags;
/* quadword registers: data in [0] word only */
quadword regs[PKE_NUM_REGS];
/* write buffer for FIFO address */
quadword fifo_qw_in_progress;
int fifo_qw_done; /* bitfield */
/* FIFO - private: use only pke_fifo_* routines to access */
struct pke_fifo fifo; /* array of FIFO quadword pointers */
FILE* fifo_trace_file; /* stdio stream open in append mode, or 0 for no trace */
char* fifo_trace_file_name; /* user defined debug trace file name */
/* FIFO cache -- curry last search pke_pcrel_fifo results */
unsigned_4 last_fifo_pc;
unsigned_4 last_qw_pc;
unsigned_4 last_num;
unsigned_4 last_new_fifo_pc;
unsigned_4 last_new_qw_pc;
/* PC */
int fifo_pc; /* 0 .. (fifo_num_elements-1): quadword index of next instruction */
int qw_pc; /* 0 .. 3: word index of next instruction */
/* Disassembly state */
FILE *trace_file;
char *trace_file_name;
};
extern struct pke_device pke0_device;
extern struct pke_device pke1_device;
/* Flags for PKE.flags */
#define PKE_FLAG_NONE 0x00
#define PKE_FLAG_PENDING_PSS 0x01 /* PSS bit written-to; set STAT:PSS after current instruction */
#define PKE_FLAG_INT_NOLOOP 0x02 /* INT PKEcode received; INT/PIS set; suppress loop after resumption */
#define PKE_FLAG_TRACE_ON 0x04 /* Trace file request from command line */
/* Kludge alert */
#define PKE_MEM_READ(me,addr,data,size) \
do { \
sim_cpu* cpu = STATE_CPU(CURRENT_STATE, 0); \
unsigned_##size value = \
sim_core_read_aligned_##size(cpu, CIA_GET(cpu), read_map, \
(SIM_ADDR)(addr)); \
memcpy((unsigned_##size*) (data), (void*) & value, size); \
} while(0)
#define PKE_MEM_WRITE(me,addr,data,size) \
do { sim_cpu* cpu = STATE_CPU(CURRENT_STATE, 0); \
unsigned_##size value; \
memcpy((void*) & value, (unsigned_##size*)(data), size); \
sim_core_write_aligned_##size(cpu, CIA_GET(cpu), write_map, \
(SIM_ADDR)(addr), value); \
if (indebug ((me)->dev.name)) \
{ \
int i; \
unsigned_##size value_te; \
value_te = H2T_##size(value); \
if (((me)->fifo_trace_file == NULL ) && \
((me)->fifo_trace_file_name != NULL )) \
sky_open_file (&((me)->fifo_trace_file), \
(me)->fifo_trace_file_name, \
(char *) NULL, _IOLBF ); \
fprintf (((me)->fifo_trace_file != NULL) ? \
(me)->fifo_trace_file : stdout, \
"# Write %2d bytes to ", size); \
fprintf (((me)->fifo_trace_file != NULL) ? \
(me)->fifo_trace_file : stdout, \
"0x%08lx: ", (unsigned long)(addr)); \
for(i=0; i<size; i++) \
fprintf (((me)->fifo_trace_file != NULL) ? \
(me)->fifo_trace_file : stdout, \
" %02x", ((unsigned_1*)(& value_te))[i]); \
fprintf (((me)->fifo_trace_file != NULL) ? \
(me)->fifo_trace_file : stdout, \
"\n"); \
} \
} while(0)
#endif /* H_PKE_H */