* 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:
parent
63a0e6b527
commit
fda83b6795
9 changed files with 2150 additions and 3403 deletions
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
1363
sim/mips/configure
vendored
File diff suppressed because it is too large
Load diff
|
@ -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],
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
2580
sim/mips/sky-pke.c
2580
sim/mips/sky-pke.c
File diff suppressed because it is too large
Load diff
|
@ -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 */
|
Loading…
Reference in a new issue