* cris/dv-cris.c, cris/dv-rv.c, cris/rvdummy.c: New files.

* cris/Makefile.in (CONFIG_DEVICES): Remove redundant setting.
	(dv-cris.o, dv-rv.o rvdummy$(EXEEXT), rvdummy.o): New rules.
	(all): Depend on rvdummy$(EXEEXT).
	* cris/configure.ac: Call SIM_AC_OPTION_WARNINGS.  Check for
	sys/socket.h and sys/select.h.  Call SIM_AC_OPTION_HARDWARE,
	default off.
	* cris/configure: Regenerate.
	* cris/cris-sim.h (cris_have_900000xxif): Declare here.
	(enum cris_interrupt_type, crisv10deliver_interrupt)
	(crisv32deliver_interrupt: New declarations.
	* cris/cris-tmpl.c [WITH_HW] (MY (f_model_insn_after)): Call
	sim_events_tickn and set state-events member work_pending when it's
	time for the next event.
	[WITH_HW] (MY (f_specific_init)): Set CPU-model-specific
	interrupt-delivery function.
	* cris/crisv10f.c (MY (deliver_interrupt)): New function.
	* cris/crisv32f.c (MY (deliver_interrupt)): New function.
	* cris/devices.c: Include hw-device.h.
	(device_io_read_buffer) [WITH_HW]: Call hw_io_read_buffer.
	(device_io_write_buffer): Only perform 0x900000xx-functions if
	cris_have_900000xxif is nonzero.  Else if WITH_HW defined,
	call hw_io_write_buffer.  Add return 0 last in function.
	* cris/sim-if.c (cris_have_900000xxif): Now global.
	(sim_open) [WITH_HW]: Clear deliver_interrupt cpu member.
	Force "-model" option, effectively.
	* cris/sim-main.h (cris_interrupt_delivery_fn): New type.
	(struct _sim_cpu) [WITH_HW]: New member deliver_interrupt.
This commit is contained in:
Hans-Peter Nilsson 2006-04-03 03:01:45 +00:00
parent 4c3a323bb9
commit aad3b3cbc1
14 changed files with 2649 additions and 13 deletions

View File

@ -1,3 +1,34 @@
2006-04-03 Hans-Peter Nilsson <hp@axis.com>
* cris/dv-cris.c, cris/dv-rv.c, cris/rvdummy.c: New files.
* cris/Makefile.in (CONFIG_DEVICES): Remove redundant setting.
(dv-cris.o, dv-rv.o rvdummy$(EXEEXT), rvdummy.o): New rules.
(all): Depend on rvdummy$(EXEEXT).
* cris/configure.ac: Call SIM_AC_OPTION_WARNINGS. Check for
sys/socket.h and sys/select.h. Call SIM_AC_OPTION_HARDWARE,
default off.
* cris/configure: Regenerate.
* cris/cris-sim.h (cris_have_900000xxif): Declare here.
(enum cris_interrupt_type, crisv10deliver_interrupt)
(crisv32deliver_interrupt: New declarations.
* cris/cris-tmpl.c [WITH_HW] (MY (f_model_insn_after)): Call
sim_events_tickn and set state-events member work_pending when it's
time for the next event.
[WITH_HW] (MY (f_specific_init)): Set CPU-model-specific
interrupt-delivery function.
* cris/crisv10f.c (MY (deliver_interrupt)): New function.
* cris/crisv32f.c (MY (deliver_interrupt)): New function.
* cris/devices.c: Include hw-device.h.
(device_io_read_buffer) [WITH_HW]: Call hw_io_read_buffer.
(device_io_write_buffer): Only perform 0x900000xx-functions if
cris_have_900000xxif is nonzero. Else if WITH_HW defined,
call hw_io_write_buffer. Add return 0 last in function.
* cris/sim-if.c (cris_have_900000xxif): Now global.
(sim_open) [WITH_HW]: Clear deliver_interrupt cpu member.
Force "-model" option, effectively.
* cris/sim-main.h (cris_interrupt_delivery_fn): New type.
(struct _sim_cpu) [WITH_HW]: New member deliver_interrupt.
2006-04-02 Hans-Peter Nilsson <hp@axis.com>
* cris/Makefile.in (CRISV10F_OBJS): Remove semcrisv10f-switch.o.

View File

@ -23,7 +23,6 @@
CRISV10F_OBJS = crisv10f.o cpuv10.o decodev10.o modelv10.o mloopv10f.o
CRISV32F_OBJS = crisv32f.o cpuv32.o decodev32.o modelv32.o mloopv32f.o
CONFIG_DEVICES = dv-sockser.o
CONFIG_DEVICES =
SIM_OBJS = \
@ -62,11 +61,29 @@ arch = cris
sim-if.o: sim-if.c $(SIM_MAIN_DEPS) $(sim-core_h) $(sim-options_h)
# Needs CPU-specific knowledge.
dv-cris.o: dv-cris.c $(SIM_MAIN_DEPS) $(sim-core_h)
# This is the same rule as dv-core.o etc.
dv-rv.o: dv-rv.c $(hw_main_headers) $(sim_main_headers)
arch.o: arch.c $(SIM_MAIN_DEPS)
traps.o: traps.c targ-vals.h $(SIM_MAIN_DEPS) $(sim-options_h)
devices.o: devices.c $(SIM_MAIN_DEPS)
# rvdummy is just used for testing. It does nothing if
# --enable-sim-hardware isn't active.
all: rvdummy$(EXEEXT)
check: rvdummy$(EXEEXT)
rvdummy$(EXEEXT): rvdummy.o $(EXTRA_LIBDEPS)
$(CC) $(ALL_CFLAGS) -o rvdummy$(EXEEXT) rvdummy.o $(EXTRA_LIBS)
rvdummy.o: rvdummy.c config.h tconfig.h $(remote_sim_h) $(callback_h)
# CRISV10 objs
CRISV10F_INCLUDE_DEPS = \

330
sim/cris/configure vendored
View File

@ -861,6 +861,9 @@ Optional Features:
--enable-sim-alignment=align Specify strict, nonstrict or forced alignment of memory accesses.
--enable-sim-hostendian=end Specify host byte endian orientation.
--enable-sim-scache=size Specify simulator execution cache size.
--enable-build-warnings Enable build-time compiler warnings if gcc is used
--enable-gdb-build-warnings Enable SIM specific build-time compiler warnings if gcc is used
--enable-sim-hardware=LIST Specify the hardware to be included in the build.
--enable-sim-default-model=model Specify default model to simulate.
--enable-sim-environment=environment Specify mixed, user, virtual or operating environment.
--enable-sim-inline=inlines Specify which functions should be inlined.
@ -7040,6 +7043,159 @@ sim_link_files="${sim_link_files} ${TARG_VALS_DEF}"
sim_link_links="${sim_link_links} targ-vals.def"
# For dv-rv and rvdummy.
for ac_header in sys/socket.h sys/select.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
# Is the header present?
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------------ ##
## Report this to the AC_PACKAGE_NAME lists. ##
## ------------------------------------------ ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
wire_alignment="NONSTRICT_ALIGNMENT"
default_alignment=""
@ -7367,6 +7523,180 @@ else
fi;
# NOTE: Don't add -Wall or -Wunused, they both include
# -Wunused-parameter which reports bogus warnings.
# NOTE: If you add to this list, remember to update
# gdb/doc/gdbint.texinfo.
build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs \
-Wformat -Wparentheses -Wpointer-arith"
# GCC supports -Wuninitialized only with -O or -On, n != 0.
if test x${CFLAGS+set} = xset; then
case "${CFLAGS}" in
*"-O0"* ) ;;
*"-O"* )
build_warnings="${build_warnings} -Wuninitialized"
;;
esac
else
build_warnings="${build_warnings} -Wuninitialized"
fi
# Up for debate: -Wswitch -Wcomment -trigraphs -Wtrigraphs
# -Wunused-function -Wunused-label -Wunused-variable -Wunused-value
# -Wchar-subscripts -Wtraditional -Wshadow -Wcast-qual
# -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes
# -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls
# -Woverloaded-virtual -Winline -Werror"
# Check whether --enable-build-warnings or --disable-build-warnings was given.
if test "${enable_build_warnings+set}" = set; then
enableval="$enable_build_warnings"
case "${enableval}" in
yes) ;;
no) build_warnings="-w";;
,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
build_warnings="${build_warnings} ${t}";;
*,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
build_warnings="${t} ${build_warnings}";;
*) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
esac
if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
echo "Setting compiler warning flags = $build_warnings" 6>&1
fi
fi; # Check whether --enable-sim-build-warnings or --disable-sim-build-warnings was given.
if test "${enable_sim_build_warnings+set}" = set; then
enableval="$enable_sim_build_warnings"
case "${enableval}" in
yes) ;;
no) build_warnings="-w";;
,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
build_warnings="${build_warnings} ${t}";;
*,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
build_warnings="${t} ${build_warnings}";;
*) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
esac
if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
echo "Setting GDB specific compiler warning flags = $build_warnings" 6>&1
fi
fi; WARN_CFLAGS=""
WERROR_CFLAGS=""
if test "x${build_warnings}" != x -a "x$GCC" = xyes
then
echo "$as_me:$LINENO: checking compiler warning flags" >&5
echo $ECHO_N "checking compiler warning flags... $ECHO_C" >&6
# Separate out the -Werror flag as some files just cannot be
# compiled with it enabled.
for w in ${build_warnings}; do
case $w in
-Werr*) WERROR_CFLAGS=-Werror ;;
*) # Check that GCC accepts it
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $w"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
WARN_CFLAGS="${WARN_CFLAGS} $w"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$saved_CFLAGS"
esac
done
echo "$as_me:$LINENO: result: ${WARN_CFLAGS}${WERROR_CFLAGS}" >&5
echo "${ECHO_T}${WARN_CFLAGS}${WERROR_CFLAGS}" >&6
fi
if test x"no" = x"yes"; then
sim_hw_p=yes
else
sim_hw_p=no
fi
if test ""; then
hardware="core pal glue"
else
hardware="core pal glue rv cris"
fi
sim_hw_cflags="-DWITH_HW=1"
sim_hw="$hardware"
sim_hw_objs="\$(SIM_COMMON_HW_OBJS) `echo $sim_hw | sed -e 's/\([^ ][^ ]*\)/dv-\1.o/g'`"
# Check whether --enable-sim-hardware or --disable-sim-hardware was given.
if test "${enable_sim_hardware+set}" = set; then
enableval="$enable_sim_hardware"
case "${enableval}" in
yes) sim_hw_p=yes;;
no) sim_hw_p=no;;
,*) sim_hw_p=yes; hardware="${hardware} `echo ${enableval} | sed -e 's/,/ /'`";;
*,) sim_hw_p=yes; hardware="`echo ${enableval} | sed -e 's/,/ /'` ${hardware}";;
*) sim_hw_p=yes; hardware="`echo ${enableval} | sed -e 's/,/ /'`"'';;
esac
if test "$sim_hw_p" != yes; then
sim_hw_objs=
sim_hw_cflags="-DWITH_HW=0"
sim_hw=
else
sim_hw_cflags="-DWITH_HW=1"
# remove duplicates
sim_hw=""
sim_hw_objs="\$(SIM_COMMON_HW_OBJS)"
for i in $hardware ; do
case " $sim_hw " in
*" $i "*) ;;
*) sim_hw="$sim_hw $i" ; sim_hw_objs="$sim_hw_objs dv-$i.o";;
esac
done
fi
if test x"$silent" != x"yes" && test "$sim_hw_p" = "yes"; then
echo "Setting hardware to $sim_hw_cflags, $sim_hw, $sim_hw_objs"
fi
else
if test "$sim_hw_p" != yes; then
sim_hw_objs=
sim_hw_cflags="-DWITH_HW=0"
sim_hw=
fi
if test x"$silent" != x"yes"; then
echo "Setting hardware to $sim_hw_cflags, $sim_hw, $sim_hw_objs"
fi
fi;
# The default model shouldn't matter as long as there's a BFD.
default_sim_default_model="crisv32"

View File

@ -9,9 +9,14 @@ sinclude(../common/aclocal.m4)
# it by inlining the macro's contents.
sinclude(../common/common.m4)
# For dv-rv and rvdummy.
AC_CHECK_HEADERS(sys/socket.h sys/select.h)
SIM_AC_OPTION_ALIGNMENT(NONSTRICT_ALIGNMENT)
SIM_AC_OPTION_HOSTENDIAN
SIM_AC_OPTION_SCACHE(16384)
SIM_AC_OPTION_WARNINGS
SIM_AC_OPTION_HARDWARE(no,,rv cris)
# The default model shouldn't matter as long as there's a BFD.
SIM_AC_OPTION_DEFAULT_MODEL(crisv32)

View File

@ -1,5 +1,5 @@
/* Collection of junk for CRIS.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Axis Communications.
This file is part of the GNU simulators.
@ -86,6 +86,14 @@ extern USI crisv10f_break_handler (SIM_CPU *, USI, USI);
extern USI crisv32f_break_handler (SIM_CPU *, USI, USI);
extern USI cris_break_13_handler (SIM_CPU *, USI, USI, USI, USI, USI, USI,
USI, USI);
extern char cris_have_900000xxif;
enum cris_interrupt_type { CRIS_INT_NMI, CRIS_INT_RESET, CRIS_INT_INT };
extern int crisv10deliver_interrupt (SIM_CPU *,
enum cris_interrupt_type,
unsigned int);
extern int crisv32deliver_interrupt (SIM_CPU *,
enum cris_interrupt_type,
unsigned int);
/* Using GNU syntax (not C99) so we can compile this on RH 6.2
(egcs-1.1.2/gcc-2.91.66). */

View File

@ -178,6 +178,18 @@ MY (f_model_insn_after) (SIM_CPU *current_cpu, int last_p ATTRIBUTE_UNUSED,
PROFILE_MODEL_TOTAL_CYCLES (p) += cycles;
CPU_CRIS_MISC_PROFILE (current_cpu)->basic_cycle_count += cycles;
PROFILE_MODEL_CUR_INSN_CYCLES (p) = cycles;
#if WITH_HW
/* For some reason, we don't get to the sim_events_tick call in
cgen-run.c:engine_run_1. Besides, more than one cycle has
passed, so we want sim_events_tickn anyway. The "events we want
to process" is usually to initiate an interrupt, but might also
be other events. We can't do the former until the main loop is
at point where it accepts changing the PC without internal
inconsistency, so just set a flag and wait. */
if (sim_events_tickn (CPU_STATE (current_cpu), cycles))
STATE_EVENTS (CPU_STATE (current_cpu))->work_pending = 1;
#endif
}
/* Initialize cycle counting for an insn.
@ -245,6 +257,9 @@ MY (f_specific_init) (SIM_CPU *current_cpu)
{
current_cpu->make_thread_cpu_data = MY (make_thread_cpu_data);
current_cpu->thread_cpu_data_size = sizeof (current_cpu->cpu_data);
#if WITH_HW
current_cpu->deliver_interrupt = MY (deliver_interrupt);
#endif
}
/* Model function for arbitrary single stall cycles. */

View File

@ -1,5 +1,5 @@
/* CRIS v10 simulator support code
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Axis Communications.
This file is part of the GNU simulators.
@ -40,3 +40,62 @@ MY (XCONCAT3 (f_model_crisv,BASENUM,
}
#endif /* WITH_PROFILE_MODEL_P */
/* Do the interrupt sequence if possible, and return 1. If interrupts
are disabled or some other lockout is active, return 0 and do
nothing.
Beware, the v10 implementation is incomplete and doesn't properly
lock out interrupts e.g. after special-register access and doesn't
handle user-mode. */
int
MY (deliver_interrupt) (SIM_CPU *current_cpu,
enum cris_interrupt_type type,
unsigned int vec)
{
unsigned char entryaddr_le[4];
int was_user;
SIM_DESC sd = CPU_STATE (current_cpu);
unsigned32 entryaddr;
/* We haven't implemented other interrupt-types yet. */
if (type != CRIS_INT_INT)
abort ();
/* We're supposed to be called outside of prefixes and branch
delay-slots etc, but why not check. */
if (GET_H_INSN_PREFIXED_P ())
abort ();
if (!GET_H_IBIT ())
return 0;
/* User mode isn't supported for interrupts. (And we shouldn't see
this as 1 anyway. The user-mode bit isn't visible from user
mode. It doesn't make it into the U bit until the next
interrupt/exception.) */
if (GET_H_UBIT ())
abort ();
SET_H_PBIT (1);
if (sim_core_read_buffer (sd,
current_cpu,
read_map, entryaddr_le,
GET_H_SR (H_SR_PRE_V32_IBR) + vec * 4, 4) == 0)
{
/* Nothing to do actually; either abort or send a signal. */
sim_core_signal (sd, current_cpu, CIA_GET (current_cpu), 0, 4,
GET_H_SR (H_SR_PRE_V32_IBR) + vec * 4,
read_transfer, sim_core_unmapped_signal);
return 0;
}
entryaddr = bfd_getl32 (entryaddr_le);
SET_H_SR (H_SR_PRE_V32_IRP, GET_H_PC ());
SET_H_PC (entryaddr);
return 1;
}

View File

@ -1,5 +1,5 @@
/* CRIS v32 simulator support code
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Axis Communications.
This file is part of the GNU simulators.
@ -556,3 +556,71 @@ MY (XCONCAT3 (f_model_crisv,BASENUM,
}
#endif /* WITH_PROFILE_MODEL_P */
int
MY (deliver_interrupt) (SIM_CPU *current_cpu,
enum cris_interrupt_type type,
unsigned int vec)
{
unsigned32 old_ccs, shifted_ccs, new_ccs;
unsigned char entryaddr_le[4];
int was_user;
SIM_DESC sd = CPU_STATE (current_cpu);
unsigned32 entryaddr;
/* We haven't implemented other interrupt-types yet. */
if (type != CRIS_INT_INT)
abort ();
/* We're called outside of branch delay slots etc, so we don't check
for that. */
if (!GET_H_IBIT_V32 ())
return 0;
old_ccs = GET_H_SR_V32 (H_SR_CCS);
shifted_ccs = (old_ccs << 10) & ((1 << 30) - 1);
/* The M bit is handled by code below and the M bit setter function, but
we need to preserve the Q bit. */
new_ccs = shifted_ccs | (old_ccs & (unsigned32) 0x80000000UL);
was_user = GET_H_UBIT_V32 ();
/* We need to force kernel mode since the setter method doesn't allow
it. Then we can use setter methods at will, since they then
recognize that we're in kernel mode. */
CPU (h_ubit_v32) = 0;
if (was_user)
{
/* These methods require that user mode is unset. */
SET_H_SR (H_SR_USP, GET_H_GR (H_GR_SP));
SET_H_GR (H_GR_SP, GET_H_KERNEL_SP ());
}
/* ERP setting is simplified by not taking interrupts in delay-slots
or when halting. */
/* For all other exceptions than guru and NMI, store the return
address in ERP and set EXS and EXD here. */
SET_H_SR (H_SR_ERP, GET_H_PC ());
/* Simplified by not having exception types (fault indications). */
SET_H_SR_V32 (H_SR_EXS, (vec * 256));
SET_H_SR_V32 (H_SR_EDA, 0);
if (sim_core_read_buffer (sd,
current_cpu,
read_map, entryaddr_le,
GET_H_SR (H_SR_EBP) + vec * 4, 4) == 0)
{
/* Nothing to do actually; either abort or send a signal. */
sim_core_signal (sd, current_cpu, CIA_GET (current_cpu), 0, 4,
GET_H_SR (H_SR_EBP) + vec * 4,
read_transfer, sim_core_unmapped_signal);
return 0;
}
entryaddr = bfd_getl32 (entryaddr_le);
SET_H_PC (entryaddr);
return 1;
}

View File

@ -1,5 +1,5 @@
/* CRIS device support
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Axis Communications.
This file is part of the GNU simulators.
@ -27,6 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "dv-sockser.h"
#endif
#include "hw-device.h"
/* Placeholder definition. */
struct _device { char dummy; } cris_devices;
@ -48,7 +50,11 @@ device_io_read_buffer (device *me ATTRIBUTE_UNUSED,
SIM_CPU *cpu ATTRIBUTE_UNUSED,
sim_cia cia ATTRIBUTE_UNUSED)
{
#if WITH_HW
return hw_io_read_buffer ((struct hw *) me, source, space, addr, nr_bytes);
#else
abort ();
#endif
}
int
@ -61,13 +67,22 @@ device_io_write_buffer (device *me ATTRIBUTE_UNUSED,
static const unsigned char ok[] = { 4, 0, 0, 0x90};
static const unsigned char bad[] = { 8, 0, 0, 0x90};
if (addr == 0x90000004 && memcmp (source, ok, sizeof ok) == 0)
cris_break_13_handler (cpu, 1, 0, 0, 0, 0, 0, 0, cia);
else if (addr == 0x90000008
&& memcmp (source, bad, sizeof bad) == 0)
cris_break_13_handler (cpu, 1, 34, 0, 0, 0, 0, 0, cia);
if (cris_have_900000xxif)
{
if (addr == 0x90000004 && memcmp (source, ok, sizeof ok) == 0)
return cris_break_13_handler (cpu, 1, 0, 0, 0, 0, 0, 0, cia);
else if (addr == 0x90000008
&& memcmp (source, bad, sizeof bad) == 0)
return cris_break_13_handler (cpu, 1, 34, 0, 0, 0, 0, 0, cia);
}
#if WITH_HW
else
return hw_io_write_buffer ((struct hw *) me, source, space, addr, nr_bytes);
#endif
/* If it wasn't one of those, send an invalid-memory signal. */
sim_core_signal (sd, cpu, cia, 0, nr_bytes, addr,
write_transfer, sim_core_unmapped_signal);
return 0;
}

314
sim/cris/dv-cris.c Normal file
View File

@ -0,0 +1,314 @@
/* The CRIS interrupt framework for GDB, the GNU Debugger.
Copyright 2006 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "sim-main.h"
#include "hw-main.h"
/* DEVICE
CRIS cpu virtual device (very rudimental; generic enough for all
currently used CRIS versions).
DESCRIPTION
Implements the external CRIS functionality. This includes the
delivery of interrupts generated from other devices.
PROPERTIES
vec-for-int = <int-a> <vec-a> <int-b> <vec-b> ...
These are the translations to interrupt vector for values appearing
on the "int" port, as pairs of the value and the corresponding
vector. Defaults to no translation. All values that may appear on
the "int" port must be defined, or the device aborts.
multiple-int = ("abort" | "ignore_previous" | <vector>)
If multiple interrupt values are dispatched, this property decides
what to do. The value is either a number corresponding to the
vector to use, or the string "abort" to cause a hard abort, or the
string "ignore_previous", to silently use the new vector instead.
The default is "abort".
PORTS
int (input)
Interrupt port. An event with a non-zero value on this port causes
an interrupt. If, after an event but before the interrupt has been
properly dispatched, a non-zero value appears that is different
after mapping than the previous, then the property multiple_int
decides what to do.
FIXME: reg port so internal registers can be read. Requires
chip-specific versions, though. Ports "nmi" and "reset".
BUGS
When delivering an interrupt, this code assumes that there is only
one processor (number 0).
This code does not attempt to be efficient at handling pending
interrupts. It simply schedules the interrupt delivery handler
every instruction cycle until all pending interrupts go away.
It also works around a bug in sim_events_process when doing so.
*/
/* Keep this an enum for simple addition of "reset" and "nmi". */
enum
{
INT_PORT,
};
static const struct hw_port_descriptor cris_ports[] =
{
{ "int", INT_PORT, 0, input_port },
{ NULL, 0, 0, 0 }
};
struct cris_vec_tr
{
unsigned32 portval, vec;
};
enum cris_multiple_ints
{
cris_multint_abort,
cris_multint_ignore_previous,
cris_multint_vector
};
struct cris_hw
{
struct hw_event *pending_handler;
unsigned32 pending_vector;
struct cris_vec_tr *int_to_vec;
enum cris_multiple_ints multi_int_action;
unsigned32 multiple_int_vector;
};
/* An event function, calling the actual CPU-model-specific
interrupt-delivery function. */
static void
deliver_cris_interrupt (struct hw *me, void *data)
{
struct cris_hw *crishw = hw_data (me);
SIM_DESC simulator = hw_system (me);
sim_cpu *cpu = STATE_CPU (simulator, 0);
unsigned int intno = crishw->pending_vector;
if (CPU_CRIS_DELIVER_INTERRUPT (cpu) (cpu, CRIS_INT_INT, intno))
{
crishw->pending_vector = 0;
crishw->pending_handler = NULL;
return;
}
{
/* Bug workaround: at time T with a pending number of cycles N to
process, if re-scheduling an event at time T+M, M < N,
sim_events_process gets stuck at T (updating the "time" to
before the event rather than after the event, or somesuch).
Hacking this locally is thankfully easy: if we see the same
simulation time, increase the number of cycles. Do this every
time we get here, until a new time is seen (supposedly unstuck
re-delivery). (Fixing in SIM/GDB source will hopefully then
also be easier, having a tangible test-case.) */
static signed64 last_events_time = 0;
static signed64 delta = 1;
signed64 this_events_time = hw_event_queue_time (me);
if (this_events_time == last_events_time)
delta++;
else
{
delta = 1;
last_events_time = this_events_time;
}
crishw->pending_handler
= hw_event_queue_schedule (me, delta, deliver_cris_interrupt, NULL);
}
}
/* A port-event function for events arriving to an interrupt port. */
static void
cris_port_event (struct hw *me,
int my_port,
struct hw *source,
int source_port,
int intparam)
{
struct cris_hw *crishw = hw_data (me);
unsigned32 vec;
/* A few placeholders; only the INT port is implemented. */
switch (my_port)
{
case INT_PORT:
HW_TRACE ((me, "INT value=0x%x", intparam));
break;
default:
hw_abort (me, "bad switch");
break;
}
if (intparam == 0)
return;
if (crishw->int_to_vec != NULL)
{
unsigned int i;
for (i = 0; crishw->int_to_vec[i].portval != 0; i++)
if (crishw->int_to_vec[i].portval == intparam)
break;
if (crishw->int_to_vec[i].portval == 0)
hw_abort (me, "unsupported value for int port: 0x%x", intparam);
vec = crishw->int_to_vec[i].vec;
}
else
vec = (unsigned32) intparam;
if (crishw->pending_vector != 0)
{
if (vec == crishw->pending_vector)
return;
switch (crishw->multi_int_action)
{
case cris_multint_abort:
hw_abort (me, "int 0x%x (0x%x) while int 0x%x hasn't been delivered",
vec, intparam, crishw->pending_vector);
break;
case cris_multint_ignore_previous:
break;
case cris_multint_vector:
vec = crishw->multiple_int_vector;
break;
default:
hw_abort (me, "bad switch");
}
}
crishw->pending_vector = vec;
/* Schedule our event handler *now*. */
if (crishw->pending_handler == NULL)
crishw->pending_handler
= hw_event_queue_schedule (me, 0, deliver_cris_interrupt, NULL);
}
/* Instance initializer function. */
static void
cris_finish (struct hw *me)
{
struct cris_hw *crishw;
const struct hw_property *vec_for_int;
const struct hw_property *multiple_int;
crishw = HW_ZALLOC (me, struct cris_hw);
set_hw_data (me, crishw);
set_hw_ports (me, cris_ports);
set_hw_port_event (me, cris_port_event);
vec_for_int = hw_find_property (me, "vec-for-int");
if (vec_for_int != NULL)
{
unsigned32 vecsize;
unsigned32 i;
if (hw_property_type (vec_for_int) != array_property)
hw_abort (me, "property \"vec-for-int\" has the wrong type");
vecsize = hw_property_sizeof_array (vec_for_int) / sizeof (signed_cell);
if ((vecsize % 2) != 0)
hw_abort (me, "translation vector does not consist of even pairs");
crishw->int_to_vec
= hw_malloc (me, (vecsize/2 + 1) * sizeof (crishw->int_to_vec[0]));
for (i = 0; i < vecsize/2; i++)
{
signed_cell portval_sc;
signed_cell vec_sc;
if (!hw_find_integer_array_property (me, "vec-for-int", i*2,
&portval_sc)
|| !hw_find_integer_array_property (me, "vec-for-int", i*2 + 1,
&vec_sc)
|| portval_sc < 0
|| vec_sc < 0)
hw_abort (me, "no valid vector translation pair %u", i);
crishw->int_to_vec[i].portval = (unsigned32) portval_sc;
crishw->int_to_vec[i].vec = (unsigned32) vec_sc;
}
crishw->int_to_vec[i].portval = 0;
crishw->int_to_vec[i].vec = 0;
}
multiple_int = hw_find_property (me, "multiple-int");
if (multiple_int != NULL)
{
if (hw_property_type (multiple_int) == integer_property)
{
crishw->multiple_int_vector
= hw_find_integer_property (me, "multiple-int");
crishw->multi_int_action = cris_multint_vector;
}
else
{
const char *action = hw_find_string_property (me, "multiple-int");
if (action == NULL)
hw_abort (me, "property \"multiple-int\" has the wrong type");
if (strcmp (action, "abort") == 0)
crishw->multi_int_action = cris_multint_abort;
else if (strcmp (action, "ignore_previous") == 0)
crishw->multi_int_action = cris_multint_ignore_previous;
else
hw_abort (me, "property \"multiple-int\" must be one of <vector number>\n"
"\"abort\" and \"ignore_previous\", not \"%s\"", action);
}
}
else
crishw->multi_int_action = cris_multint_abort;
}
const struct hw_descriptor dv_cris_descriptor[] = {
{ "cris", cris_finish, },
{ NULL },
};

1221
sim/cris/dv-rv.c Normal file

File diff suppressed because it is too large Load Diff

536
sim/cris/rvdummy.c Normal file
View File

@ -0,0 +1,536 @@
/* Test-driver for the remote-virtual-component simulator framework
for GDB, the GNU Debugger.
Copyright 2006 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Avoid any problems whatsoever building this program if we're not
also building hardware support. */
#if !WITH_HW
int
main (int argc, char *argv[])
{
return 2;
}
#else
#ifdef HAVE_CONFIG_H
#include "cconfig.h"
#include "tconfig.h"
#endif
#include "getopt.h"
#include "libiberty.h"
#define _GNU_SOURCE
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
/* Not guarded in dv-sockser.c, so why here. */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
enum rv_command {
RV_READ_CMD = 0,
RV_WRITE_CMD = 1,
RV_IRQ_CMD = 2,
RV_MEM_RD_CMD = 3,
RV_MEM_WR_CMD = 4,
RV_MBOX_HANDLE_CMD = 5,
RV_MBOX_PUT_CMD = 6,
RV_WATCHDOG_CMD = 7
};
enum opts { OPT_PORT = 1, OPT_TIMEOUT, OPT_VERBOSE };
struct option longopts[] =
{
{"port", required_argument, NULL, OPT_PORT},
{"timeout", required_argument, NULL, OPT_TIMEOUT},
{"verbose", no_argument, NULL, OPT_VERBOSE},
{NULL, 0, NULL, 0}
};
int port = 10000;
time_t timeout = 30000;
char *progname = "(unknown)";
int verbose = 0;
/* Required forward-declarations. */
static void handle_input_file (int, char *);
/* Set up a "server" listening to the port in PORT for a raw TCP
connection. Return a file descriptor for the connection or -1 on
error. */
int setupsocket (void)
{
int s;
socklen_t len;
int reuse = 1;
struct sockaddr_in sa_in;
struct sockaddr_in from;
len = sizeof (from);
memset (&from, 0, len);
memset (&sa_in, 0, sizeof (sa_in));
s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0)
return -1;
if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse) != 0)
return -1;
sa_in.sin_port = htons (port);
sa_in.sin_family = AF_INET;
if (bind (s, (struct sockaddr *) & sa_in, sizeof sa_in) < 0)
return -1;
if (listen (s, 1) < 0)
return -1;
return accept (s, (struct sockaddr *) &from, &len);
}
/* Basic host-to-little-endian 32-bit value. Could use the BFD
machinery, but let's avoid it for this only dependency. */
static void
h2le32 (unsigned char *dest, unsigned int val)
{
dest[0] = val & 255;
dest[1] = (val >> 8) & 255;
dest[2] = (val >> 16) & 255;
dest[3] = (val >> 24) & 255;
}
/* Send a blob of data. */
static void
send_output (int fd, unsigned char *buf, int nbytes)
{
while (nbytes > 0)
{
ssize_t written = write (fd, buf, nbytes);
if (written < 0)
{
fprintf (stderr, "%s: write to socket failed: %s\n",
progname, strerror (errno));
exit (2);
}
nbytes -= written;
}
}
/* Receive a blob of data, NBYTES large. Compare to the first NCOMP
bytes of BUF; if not a match, write error message to stderr and
exit (2). Else put it in buf. */
static void
expect_input (int fd, unsigned char *buf, int nbytes, int ncomp)
{
unsigned char byt;
int i;
for (i = 0; i < nbytes; i++)
{
int r;
do
{
errno = 0;
r = read (fd, &byt, 1);
}
while (r <= 0 && (r == 0 || errno == EAGAIN));
if (r != 1)
{
fprintf (stderr, "%s: read from socket failed: %s",
progname, strerror (errno));
exit (2);
}
if (i < ncomp && byt != buf[i])
{
int j;
fprintf (stderr, "%s: unexpected input,\n ", progname);
if (i == 0)
fprintf (stderr, "nothing,");
else
for (j = 0; j < i; j++)
fprintf (stderr, "%02x", buf[j]);
fprintf (stderr, "\nthen %02x instead of %02x\n", byt, buf[i]);
exit (2);
}
else
buf[i] = byt;
}
}
/* Handle everything about a nil-terminated line of input.
Call exit (2) on error with error text on stderr. */
static void
handle_input (int fd, char *buf, char *fname, int lineno)
{
int nbytes = 0;
int n = -1;
char *s = buf + 2;
unsigned int data;
static unsigned char bytes[1024];
int i;
memset (bytes, 0, sizeof bytes);
lineno++;
if (buf[1] != ',')
goto syntax_error;
switch (buf[0])
{
/* Comment characters and empty lines. */
case 0: case '!': case '#':
break;
/* Include another file. */
case '@':
handle_input_file (fd, s);
break;
/* Raw input (to be expected). */
case 'i':
do
{
n = -1;
sscanf (s, "%02x%n", &data, &n);
s += n;
if (n > 0)
bytes[nbytes++] = data;
}
while (n > 0);
expect_input (fd, bytes, nbytes, nbytes);
if (verbose)
{
printf ("i,");
for (i = 0; i < nbytes; i++)
printf ("%02x", bytes[i]);
printf ("\n");
}
break;
/* Raw output (to be written). */
case 'o':
do
{
n = -1;
sscanf (s, "%02x%n", &data, &n);
if (n > 0)
{
s += n;
bytes[nbytes++] = data;
}
}
while (n > 0);
if (*s != 0)
goto syntax_error;
send_output (fd, bytes, nbytes);
if (verbose)
{
printf ("o,");
for (i = 0; i < nbytes; i++)
printf ("%02x", bytes[i]);
printf ("\n");
}
break;
/* Read a register. */
case 'r':
{
unsigned int addr;
sscanf (s, "%x,%x%n", &addr, &data, &n);
if (n < 0 || s[n] != 0)
goto syntax_error;
bytes[0] = 11;
bytes[1] = 0;
bytes[2] = RV_READ_CMD;
h2le32 (bytes + 3, addr);
expect_input (fd, bytes, 11, 7);
h2le32 (bytes + 7, data);
send_output (fd, bytes, 11);
if (verbose)
printf ("r,%x,%x\n", addr, data);
}
break;
/* Write a register. */
case 'w':
{
unsigned int addr;
sscanf (s, "%x,%x%n", &addr, &data, &n);
if (n < 0 || s[n] != 0)
goto syntax_error;
bytes[0] = 11;
bytes[1] = 0;
bytes[2] = RV_WRITE_CMD;
h2le32 (bytes + 3, addr);
h2le32 (bytes + 7, data);
expect_input (fd, bytes, 11, 11);
send_output (fd, bytes, 11);
if (verbose)
printf ("w,%x,%x\n", addr, data);
}
break;
/* Wait for some milliseconds. */
case 't':
{
int del = 0;
struct timeval to;
sscanf (s, "%d%n", &del, &n);
if (n < 0 || s[n] != 0 || del == 0)
goto syntax_error;
to.tv_sec = del / 1000;
to.tv_usec = (del % 1000) * 1000;
if (select (0, NULL, NULL, NULL, &to) != 0)
{
fprintf (stderr, "%s: problem waiting for %d ms:\n %s\n",
progname, del, strerror (errno));
exit (2);
}
if (verbose)
printf ("t,%d\n", del);
}
break;
/* Expect a watchdog command. */
case 'W':
if (*s != 0)
goto syntax_error;
bytes[0] = 3;
bytes[1] = 0;
bytes[2] = RV_WATCHDOG_CMD;
expect_input (fd, bytes, 3, 3);
if (verbose)
printf ("W\n");
break;
/* Send an IRQ notification. */
case 'I':
sscanf (s, "%x%n", &data, &n);
if (n < 0 || s[n] != 0)
goto syntax_error;
bytes[0] = 7;
bytes[1] = 0;
bytes[2] = RV_IRQ_CMD;
h2le32 (bytes + 3, data);
send_output (fd, bytes, 7);
if (verbose)
printf ("I,%x\n", data);
break;
/* DMA store (to CPU). */
case 's':
{
unsigned int addr;
sscanf (s, "%x,%n", &addr, &n);
if (n < 0 || s[n] == 0)
goto syntax_error;
s += n;
do
{
n = -1;
sscanf (s, "%02x%n", &data, &n);
if (n > 0)
{
s += n;
bytes[11 + nbytes++] = data;
}
}
while (n > 0);
if (*s != 0)
goto syntax_error;
h2le32 (bytes, nbytes + 11);
bytes[2] = RV_MEM_WR_CMD;
h2le32 (bytes + 3, addr);
h2le32 (bytes + 7, nbytes);
send_output (fd, bytes, nbytes + 11);
if (verbose)
{
printf ("s,%x,", addr);
for (i = 0; i < nbytes; i++)
printf ("%02x", bytes[i]);
printf ("\n");
}
}
break;
/* DMA load (from CPU). */
case 'l':
{
unsigned int addr;
sscanf (s, "%x,%n", &addr, &n);
if (n < 0 || s[n] == 0)
goto syntax_error;
s += n;
do
{
n = -1;
sscanf (s, "%02x%n", &data, &n);
if (n > 0)
{
s += n;
bytes[11 + nbytes++] = data;
}
}
while (n > 0);
if (*s != 0)
goto syntax_error;
h2le32 (bytes, nbytes + 11);
bytes[0] = 11;
bytes[1] = 0;
bytes[2] = RV_MEM_RD_CMD;
h2le32 (bytes + 3, addr);
h2le32 (bytes + 7, nbytes);
send_output (fd, bytes, 11);
bytes[0] = (nbytes + 11) & 255;
bytes[1] = ((nbytes + 11) >> 8) & 255;
expect_input (fd, bytes, nbytes + 11, nbytes + 11);
if (verbose)
{
printf ("l,%x,", addr);
for (i = 0; i < nbytes; i++)
printf ("%02x", bytes[i]);
printf ("\n");
}
}
break;
syntax_error:
default:
fprintf (stderr, "%s: invalid command line in %s:%d:\n %s",
progname, fname, lineno, strerror (errno));
exit (2);
}
}
/* Loop over the contents of FNAME, using handle_input to parse each line.
Errors to stderr, exit (2). */
static void
handle_input_file (int fd, char *fname)
{
static char buf[2048] = {0};
int lineno = 0;
FILE *f = fopen (fname, "r");
if (f == NULL)
{
fprintf (stderr, "%s: problem opening %s: %s\n",
progname, fname, strerror (errno));
exit (2);
}
/* Let's cut the buffer short, so we always get a newline. */
while (fgets (buf, sizeof (buf) - 1, f) != NULL)
{
buf[strlen (buf) - 1] = 0;
lineno++;
handle_input (fd, buf, fname, lineno);
}
fclose (f);
}
int
main (int argc, char *argv[])
{
int optc;
int fd;
FILE *f;
int i;
progname = argv[0];
while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1)
switch (optc)
{
case OPT_PORT:
port = atoi (optarg);
break;
case OPT_TIMEOUT:
timeout = (time_t) atoi (optarg);
break;
case OPT_VERBOSE:
verbose = 1;
break;
}
fd = setupsocket ();
if (fd < 0)
{
fprintf (stderr, "%s: problem setting up the connection: %s\n",
progname, strerror (errno));
exit (2);
}
for (i = optind; i < argc; i++)
handle_input_file (fd, argv[i]);
/* FIXME: option-controlled test for remaining input? */
close (fd);
return 1;
}
#endif

View File

@ -1,5 +1,5 @@
/* Main simulator entry points specific to the CRIS.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Axis Communications.
This file is part of the GNU simulators.
@ -78,7 +78,7 @@ static CGEN_DISASSEMBLER cris_disassemble_insn;
static char cris_bare_iron = 0;
/* Whether 0x9000000xx have simulator-specific meanings. */
static char cris_have_900000xxif = 0;
char cris_have_900000xxif = 0;
/* Records simulator descriptor so utilities like cris_dump_regs can be
called from gdb. */
@ -506,7 +506,15 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
memset (cpu->sighandler, 0, sizeof (cpu->sighandler));
cpu->make_thread_cpu_data = NULL;
cpu->thread_cpu_data_size = 0;
#if WITH_HW
cpu->deliver_interrupt = NULL;
#endif
}
#if WITH_HW
/* Always be cycle-accurate and call before/after functions if
with-hardware. */
sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "on");
#endif
}
/* Initialize various cgen things not done by common framework.

View File

@ -1,5 +1,5 @@
/* Main header for the CRIS simulator, based on the m32r header.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Axis Communications.
This file is part of the GNU simulators.
@ -117,6 +117,10 @@ struct cris_thread_info {
char sigsuspended;
};
typedef int (*cris_interrupt_delivery_fn) (SIM_CPU *,
enum cris_interrupt_type,
unsigned int);
struct _sim_cpu {
/* sim/common cpu base. */
sim_cpu_base base;
@ -132,6 +136,11 @@ struct _sim_cpu {
CRIS_MISC_PROFILE cris_prev_misc_profile;
#define CPU_CRIS_PREV_MISC_PROFILE(cpu) (& (cpu)->cris_prev_misc_profile)
#if WITH_HW
cris_interrupt_delivery_fn deliver_interrupt;
#define CPU_CRIS_DELIVER_INTERRUPT(cpu) (cpu->deliver_interrupt)
#endif
/* Simulator environment data. */
USI endmem;
USI endbrk;