summaryrefslogtreecommitdiff
path: root/sim/bfin
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-03-06 00:20:16 +0000
committerMike Frysinger <vapier@gentoo.org>2011-03-06 00:20:16 +0000
commit274454609d032a0a5ef054e2e61e0fd8805df295 (patch)
treea1725be539c5e7f220c0ad099391bdf04d485182 /sim/bfin
parentb530550b8c6dde9a01b54832e393f63efbbe6051 (diff)
downloadgdb-274454609d032a0a5ef054e2e61e0fd8805df295.tar.gz
sim: bfin: new port
This can boot Das U-Boot and a Linux kernel. It also supports Linux userspace FLAT and FDPIC (dynamic and static) ELFs. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'sim/bfin')
-rw-r--r--sim/bfin/Makefile.in97
-rw-r--r--sim/bfin/TODO28
-rw-r--r--sim/bfin/aclocal.m4171
-rw-r--r--sim/bfin/bfin-sim.c6099
-rw-r--r--sim/bfin/bfin-sim.h350
-rw-r--r--sim/bfin/bfroms/all.h43
-rw-r--r--sim/bfin/bfroms/bf50x-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf51x-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf51x-0.1.h3
-rw-r--r--sim/bfin/bfroms/bf51x-0.2.h3
-rw-r--r--sim/bfin/bfroms/bf526-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf526-0.1.h3
-rw-r--r--sim/bfin/bfroms/bf527-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf527-0.1.h3
-rw-r--r--sim/bfin/bfroms/bf527-0.2.h3
-rw-r--r--sim/bfin/bfroms/bf533-0.1.h3
-rw-r--r--sim/bfin/bfroms/bf533-0.2.h3
-rw-r--r--sim/bfin/bfroms/bf533-0.3.h3
-rw-r--r--sim/bfin/bfroms/bf537-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf537-0.1.h3
-rw-r--r--sim/bfin/bfroms/bf537-0.3.h3
-rw-r--r--sim/bfin/bfroms/bf538-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf54x-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf54x-0.1.h3
-rw-r--r--sim/bfin/bfroms/bf54x-0.2.h3
-rw-r--r--sim/bfin/bfroms/bf54x_l1-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf54x_l1-0.1.h3
-rw-r--r--sim/bfin/bfroms/bf54x_l1-0.2.h3
-rw-r--r--sim/bfin/bfroms/bf561-0.5.h3
-rw-r--r--sim/bfin/bfroms/bf59x-0.0.h3
-rw-r--r--sim/bfin/bfroms/bf59x_l1-0.1.h3
-rw-r--r--sim/bfin/config.in176
-rwxr-xr-xsim/bfin/configure6779
-rw-r--r--sim/bfin/configure.ac75
-rw-r--r--sim/bfin/devices.c163
-rw-r--r--sim/bfin/devices.h156
-rw-r--r--sim/bfin/dv-bfin_cec.c807
-rw-r--r--sim/bfin/dv-bfin_cec.h139
-rw-r--r--sim/bfin/dv-bfin_ctimer.c267
-rw-r--r--sim/bfin/dv-bfin_ctimer.h33
-rw-r--r--sim/bfin/dv-bfin_dma.c553
-rw-r--r--sim/bfin/dv-bfin_dma.h65
-rw-r--r--sim/bfin/dv-bfin_dmac.c469
-rw-r--r--sim/bfin/dv-bfin_dmac.h32
-rw-r--r--sim/bfin/dv-bfin_ebiu_amc.c456
-rw-r--r--sim/bfin/dv-bfin_ebiu_amc.h31
-rw-r--r--sim/bfin/dv-bfin_ebiu_ddrc.c184
-rw-r--r--sim/bfin/dv-bfin_ebiu_ddrc.h26
-rw-r--r--sim/bfin/dv-bfin_ebiu_sdc.c201
-rw-r--r--sim/bfin/dv-bfin_ebiu_sdc.h39
-rw-r--r--sim/bfin/dv-bfin_emac.c603
-rw-r--r--sim/bfin/dv-bfin_emac.h61
-rw-r--r--sim/bfin/dv-bfin_eppi.c271
-rw-r--r--sim/bfin/dv-bfin_eppi.h30
-rw-r--r--sim/bfin/dv-bfin_evt.c153
-rw-r--r--sim/bfin/dv-bfin_evt.h31
-rw-r--r--sim/bfin/dv-bfin_gptimer.c183
-rw-r--r--sim/bfin/dv-bfin_gptimer.h27
-rw-r--r--sim/bfin/dv-bfin_jtag.c157
-rw-r--r--sim/bfin/dv-bfin_jtag.h27
-rw-r--r--sim/bfin/dv-bfin_mmu.c574
-rw-r--r--sim/bfin/dv-bfin_mmu.h94
-rw-r--r--sim/bfin/dv-bfin_nfc.c241
-rw-r--r--sim/bfin/dv-bfin_nfc.h41
-rw-r--r--sim/bfin/dv-bfin_otp.c307
-rw-r--r--sim/bfin/dv-bfin_otp.h100
-rw-r--r--sim/bfin/dv-bfin_pll.c187
-rw-r--r--sim/bfin/dv-bfin_pll.h27
-rw-r--r--sim/bfin/dv-bfin_ppi.c231
-rw-r--r--sim/bfin/dv-bfin_ppi.h32
-rw-r--r--sim/bfin/dv-bfin_rtc.c194
-rw-r--r--sim/bfin/dv-bfin_rtc.h26
-rw-r--r--sim/bfin/dv-bfin_sic.c1439
-rw-r--r--sim/bfin/dv-bfin_sic.h27
-rw-r--r--sim/bfin/dv-bfin_spi.c229
-rw-r--r--sim/bfin/dv-bfin_spi.h54
-rw-r--r--sim/bfin/dv-bfin_trace.c285
-rw-r--r--sim/bfin/dv-bfin_trace.h37
-rw-r--r--sim/bfin/dv-bfin_twi.c227
-rw-r--r--sim/bfin/dv-bfin_twi.h38
-rw-r--r--sim/bfin/dv-bfin_uart.c437
-rw-r--r--sim/bfin/dv-bfin_uart.h49
-rw-r--r--sim/bfin/dv-bfin_uart2.c258
-rw-r--r--sim/bfin/dv-bfin_uart2.h33
-rw-r--r--sim/bfin/dv-bfin_wdog.c206
-rw-r--r--sim/bfin/dv-bfin_wdog.h36
-rw-r--r--sim/bfin/dv-bfin_wp.c188
-rw-r--r--sim/bfin/dv-bfin_wp.h27
-rw-r--r--sim/bfin/dv-eth_phy.c206
-rw-r--r--sim/bfin/gui.c286
-rw-r--r--sim/bfin/gui.h50
-rw-r--r--sim/bfin/insn_list.def62
-rw-r--r--sim/bfin/interp.c1241
-rw-r--r--sim/bfin/linux-fixed-code.h74
-rw-r--r--sim/bfin/linux-fixed-code.s85
-rw-r--r--sim/bfin/linux-targ-map.h1992
-rw-r--r--sim/bfin/machs.c1287
-rw-r--r--sim/bfin/machs.h56
-rw-r--r--sim/bfin/proc_list.def50
-rw-r--r--sim/bfin/sim-main.h117
-rw-r--r--sim/bfin/tconfig.in27
101 files changed, 30214 insertions, 0 deletions
diff --git a/sim/bfin/Makefile.in b/sim/bfin/Makefile.in
new file mode 100644
index 00000000000..64f26d3e59c
--- /dev/null
+++ b/sim/bfin/Makefile.in
@@ -0,0 +1,97 @@
+# Makefile template for Configure for the Blackfin simulator.
+# Copyright (C) 2005-2011 Free Software Foundation, Inc.
+# Written by Analog Devices, Inc.
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# This selects the bfin newlib/libgloss syscall definitions.
+NL_TARGET = -DNL_TARGET_bfin
+
+## COMMON_PRE_CONFIG_FRAG
+
+# List of main object files for `run'.
+SIM_RUN_OBJS = nrun.o
+
+SIM_OBJS = \
+ $(SIM_NEW_COMMON_OBJS) \
+ bfin-sim.o \
+ devices.o \
+ gui.o \
+ interp.o \
+ machs.o \
+ sim-cpu.o \
+ sim-engine.o \
+ sim-hload.o \
+ sim-hrw.o \
+ sim-model.o \
+ sim-reason.o \
+ sim-reg.o \
+ sim-resume.o \
+ sim-stop.o \
+ @BFIN_SIM_EXTRA_OBJS@ \
+ $(SIM_EXTRA_OBJS)
+
+INCLUDE = bfin-sim.h
+
+SIM_EXTRA_CFLAGS = @SDL_CFLAGS@
+SIM_EXTRA_LIBS = @SDL_LIBS@ -lm
+
+## COMMON_POST_CONFIG_FRAG
+
+$(srcdir)/linux-fixed-code.h: $(srcdir)/linux-fixed-code.s Makefile.in
+ $(AS_FOR_TARGET) $< -o linux-fixed-code.o
+ ( set -e; \
+ echo "/* DO NOT EDIT: Autogenerated from linux-fixed-code.s. */"; \
+ echo "static const unsigned char bfin_linux_fixed_code[] = {"; \
+ $(OBJDUMP_FOR_TARGET) -d -z linux-fixed-code.o > $@.dis; \
+ sed -n $@.dis \
+ -e 's:^[^ ]* :0x:' \
+ -e '/^0x/{s: .*::;s: *$$:,:;s: :, 0x:g;p}'; \
+ rm -f $@.dis; \
+ echo "};" \
+ ) > $@.tmp
+ rm -f linux-fixed-code.o
+ mv $@.tmp $@
+
+interp.o: interp.c targ-vals.h linux-targ-map.h linux-fixed-code.h devices.h $(INCLUDE)
+bfin-sim.o: bfin-sim.c $(INCLUDE)
+gui.o: gui.c $(INCLUDE)
+machs.o: machs.c $(INCLUDE)
+dv-bfin_cec.o: dv-bfin_cec.c devices.h $(INCLUDE)
+dv-bfin_ctimer.o: dv-bfin_ctimer.c devices.h $(INCLUDE)
+dv-bfin_dma.o: dv-bfin_dma.c devices.h $(INCLUDE)
+dv-bfin_dma_pmap.o: dv-bfin_dma_pmap.c devices.h $(INCLUDE)
+dv-bfin_ebiu_amc.o: dv-bfin_ebiu_amc.c devices.h $(INCLUDE)
+dv-bfin_ebiu_ddrc.o: dv-bfin_ebiu_ddrc.c devices.h $(INCLUDE)
+dv-bfin_ebiu_sdc.o: dv-bfin_ebiu_sdc.c devices.h $(INCLUDE)
+dv-bfin_emac.o: dv-bfin_emac.c devices.h $(INCLUDE)
+dv-bfin_eppi.o: dv-bfin_eppi.c devices.h $(INCLUDE)
+dv-bfin_evt.o: dv-bfin_evt.c devices.h $(INCLUDE)
+dv-bfin_gptimer.o: dv-bfin_gptimer.c devices.h $(INCLUDE)
+dv-bfin_jtag.o: dv-bfin_jtag.c devices.h $(INCLUDE)
+dv-bfin_mmu.o: dv-bfin_mmu.c devices.h $(INCLUDE)
+dv-bfin_nfc.o: dv-bfin_nfc.c devices.h $(INCLUDE)
+dv-bfin_otp.o: dv-bfin_otp.c devices.h $(INCLUDE)
+dv-bfin_pll.o: dv-bfin_pll.c devices.h $(INCLUDE)
+dv-bfin_ppi.o: dv-bfin_ppi.c devices.h $(INCLUDE)
+dv-bfin_rtc.o: dv-bfin_rtc.c devices.h $(INCLUDE)
+dv-bfin_sic.o: dv-bfin_sic.c devices.h $(INCLUDE)
+dv-bfin_spi.o: dv-bfin_spi.c devices.h $(INCLUDE)
+dv-bfin_trace.o: dv-bfin_trace.c devices.h $(INCLUDE)
+dv-bfin_twi.o: dv-bfin_twi.c devices.h $(INCLUDE)
+dv-bfin_uart.o: dv-bfin_uart.c devices.h $(INCLUDE)
+dv-bfin_uart2.o: dv-bfin_uart2.c devices.h $(INCLUDE)
+dv-bfin_wdog.o: dv-bfin_wdog.c devices.h $(INCLUDE)
+dv-bfin_wp.o: dv-bfin_wp.c devices.h $(INCLUDE)
+dv-eth_phy.o: devices.h $(INCLUDE)
diff --git a/sim/bfin/TODO b/sim/bfin/TODO
new file mode 100644
index 00000000000..d180ab26843
--- /dev/null
+++ b/sim/bfin/TODO
@@ -0,0 +1,28 @@
+need to review ASTAT write behavior
+
+how to model RETE and IVG0 bit in IPEND ...
+
+model the loop buffer ? this means no ifetches because they're cached.
+see page 4-26 in Blackfin PRM under hardware loops.
+
+handle DSPID at 0xffe05000
+
+CEC should handle multiple exceptions at same address. would need
+exception processing to be delayed ? at least needs a stack for
+the CEC to pop things off.
+
+R0 = [SP++]; gets traced as R0 = [P6++];
+
+merge dv-bfin_evt with dv-bfin_cec since the EVT regs are part of the CEC
+
+fix single stepping over debug assert instructions in hardware
+
+exception in IVG5 causes double fault ?
+
+add a "file" option to the async banks to back it
+
+tests:
+ - check AN bits with Dreg subtraction
+ R0 = R1 - R2;
+ - check astat bits with vector add/sub +|+
+ - check acc with VIT_MAX and similiar insns
diff --git a/sim/bfin/aclocal.m4 b/sim/bfin/aclocal.m4
new file mode 100644
index 00000000000..cbe3b5592dd
--- /dev/null
+++ b/sim/bfin/aclocal.m4
@@ -0,0 +1,171 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+# serial 1 (pkg-config-0.24)
+#
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists. Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+# only at the first occurence in configure.ac, so if the first place
+# it's called might be skipped (such as if it is within an "if", you
+# have to call PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])# PKG_CHECK_MODULES
+
diff --git a/sim/bfin/bfin-sim.c b/sim/bfin/bfin-sim.c
new file mode 100644
index 00000000000..6d9361e94cd
--- /dev/null
+++ b/sim/bfin/bfin-sim.c
@@ -0,0 +1,6099 @@
+/* Simulator for Analog Devices Blackfin processors.
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "opcode/bfin.h"
+#include "sim-main.h"
+#include "dv-bfin_cec.h"
+#include "dv-bfin_mmu.h"
+
+#define HOST_LONG_WORD_SIZE (sizeof (long) * 8)
+
+#define SIGNEXTEND(v, n) \
+ (((bs32)(v) << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))
+
+static __attribute__ ((noreturn)) void
+illegal_instruction (SIM_CPU *cpu)
+{
+ TRACE_INSN (cpu, "ILLEGAL INSTRUCTION");
+ while (1)
+ cec_exception (cpu, VEC_UNDEF_I);
+}
+
+static __attribute__ ((noreturn)) void
+illegal_instruction_combination (SIM_CPU *cpu)
+{
+ TRACE_INSN (cpu, "ILLEGAL INSTRUCTION COMBINATION");
+ while (1)
+ cec_exception (cpu, VEC_ILGAL_I);
+}
+
+static __attribute__ ((noreturn)) void
+unhandled_instruction (SIM_CPU *cpu, const char *insn)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ bu16 iw0, iw1;
+ bu32 iw2;
+
+ TRACE_EVENTS (cpu, "unhandled instruction");
+
+ iw0 = IFETCH (PCREG);
+ iw1 = IFETCH (PCREG + 2);
+ iw2 = ((bu32)iw0 << 16) | iw1;
+
+ sim_io_eprintf (sd, "Unhandled instruction at 0x%08x (%s opcode 0x", PCREG, insn);
+ if ((iw0 & 0xc000) == 0xc000)
+ sim_io_eprintf (sd, "%08x", iw2);
+ else
+ sim_io_eprintf (sd, "%04x", iw0);
+
+ sim_io_eprintf (sd, ") ... aborting\n");
+
+ illegal_instruction (cpu);
+}
+
+typedef enum
+{
+ c_0, c_1, c_4, c_2, c_uimm2, c_uimm3, c_imm3, c_pcrel4,
+ c_imm4, c_uimm4s4, c_uimm4s4d, c_uimm4, c_uimm4s2, c_negimm5s4, c_imm5,
+ c_imm5d, c_uimm5, c_imm6, c_imm7, c_imm7d, c_imm8, c_uimm8, c_pcrel8,
+ c_uimm8s4, c_pcrel8s4, c_lppcrel10, c_pcrel10, c_pcrel12, c_imm16s4,
+ c_luimm16, c_imm16, c_imm16d, c_huimm16, c_rimm16, c_imm16s2, c_uimm16s4,
+ c_uimm16s4d, c_uimm16, c_pcrel24, c_uimm32, c_imm32, c_huimm32, c_huimm32e,
+} const_forms_t;
+
+static const struct
+{
+ const char *name;
+ const int nbits;
+ const char reloc;
+ const char issigned;
+ const char pcrel;
+ const char scale;
+ const char offset;
+ const char negative;
+ const char positive;
+ const char decimal;
+ const char leading;
+ const char exact;
+} constant_formats[] =
+{
+ { "0", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "1", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "4", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "2", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm2", 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm3", 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm3", 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel4", 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "imm4", 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm4s4", 4, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0},
+ { "uimm4s4d", 4, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0},
+ { "uimm4", 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm4s2", 4, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},
+ { "negimm5s4", 5, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0},
+ { "imm5", 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm5d", 5, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
+ { "uimm5", 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm6", 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm7", 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm7d", 7, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "imm8", 8, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm8", 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel8", 8, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm8s4", 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "pcrel8s4", 8, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
+ { "lppcrel10", 10, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "pcrel10", 10, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "pcrel12", 12, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "imm16s4", 16, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "luimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16", 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16d", 16, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "huimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "rimm16", 16, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16s2", 16, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm16s4", 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "uimm16s4d", 16, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0},
+ { "uimm16", 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel24", 24, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm32", 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm32", 32, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "huimm32", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "huimm32e", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+};
+
+static const char *
+fmtconst_str (const_forms_t cf, bs32 x, bu32 pc)
+{
+ static char buf[60];
+
+ if (constant_formats[cf].reloc)
+ {
+ bu32 ea = (((constant_formats[cf].pcrel ? SIGNEXTEND (x, constant_formats[cf].nbits)
+ : x) + constant_formats[cf].offset) << constant_formats[cf].scale);
+ if (constant_formats[cf].pcrel)
+ ea += pc;
+ /*if (outf->symbol_at_address_func (ea, outf) || !constant_formats[cf].exact)
+ {
+ outf->print_address_func (ea, outf);
+ return "";
+ }
+ else*/
+ {
+ sprintf (buf, "%#x", x);
+ return buf;
+ }
+ }
+
+ /* Negative constants have an implied sign bit. */
+ if (constant_formats[cf].negative)
+ {
+ int nb = constant_formats[cf].nbits + 1;
+
+ x = x | (1 << constant_formats[cf].nbits);
+ x = SIGNEXTEND (x, nb);
+ }
+ else
+ x = constant_formats[cf].issigned ? SIGNEXTEND (x, constant_formats[cf].nbits) : x;
+
+ if (constant_formats[cf].offset)
+ x += constant_formats[cf].offset;
+
+ if (constant_formats[cf].scale)
+ x <<= constant_formats[cf].scale;
+
+ if (constant_formats[cf].decimal)
+ {
+ if (constant_formats[cf].leading)
+ {
+ char ps[10];
+ sprintf (ps, "%%%ii", constant_formats[cf].leading);
+ sprintf (buf, ps, x);
+ }
+ else
+ sprintf (buf, "%i", x);
+ }
+ else
+ {
+ if (constant_formats[cf].issigned && x < 0)
+ sprintf (buf, "-0x%x", abs (x));
+ else
+ sprintf (buf, "0x%x", x);
+ }
+
+ return buf;
+}
+
+static bu32
+fmtconst_val (const_forms_t cf, bu32 x, bu32 pc)
+{
+ if (0 && constant_formats[cf].reloc)
+ {
+ bu32 ea = (((constant_formats[cf].pcrel
+ ? (bu32)SIGNEXTEND (x, constant_formats[cf].nbits)
+ : x) + constant_formats[cf].offset)
+ << constant_formats[cf].scale);
+ if (constant_formats[cf].pcrel)
+ ea += pc;
+
+ return ea;
+ }
+
+ /* Negative constants have an implied sign bit. */
+ if (constant_formats[cf].negative)
+ {
+ int nb = constant_formats[cf].nbits + 1;
+ x = x | (1 << constant_formats[cf].nbits);
+ x = SIGNEXTEND (x, nb);
+ }
+ else if (constant_formats[cf].issigned)
+ x = SIGNEXTEND (x, constant_formats[cf].nbits);
+
+ x += constant_formats[cf].offset;
+ x <<= constant_formats[cf].scale;
+
+ return x;
+}
+
+#define uimm16s4(x) fmtconst_val (c_uimm16s4, x, 0)
+#define uimm16s4_str(x) fmtconst_str (c_uimm16s4, x, 0)
+#define uimm16s4d(x) fmtconst_val (c_uimm16s4d, x, 0)
+#define pcrel4(x) fmtconst_val (c_pcrel4, x, pc)
+#define pcrel8(x) fmtconst_val (c_pcrel8, x, pc)
+#define pcrel8s4(x) fmtconst_val (c_pcrel8s4, x, pc)
+#define pcrel10(x) fmtconst_val (c_pcrel10, x, pc)
+#define pcrel12(x) fmtconst_val (c_pcrel12, x, pc)
+#define negimm5s4(x) fmtconst_val (c_negimm5s4, x, 0)
+#define negimm5s4_str(x) fmtconst_str (c_negimm5s4, x, 0)
+#define rimm16(x) fmtconst_val (c_rimm16, x, 0)
+#define huimm16(x) fmtconst_val (c_huimm16, x, 0)
+#define imm16(x) fmtconst_val (c_imm16, x, 0)
+#define imm16_str(x) fmtconst_str (c_imm16, x, 0)
+#define imm16d(x) fmtconst_val (c_imm16d, x, 0)
+#define uimm2(x) fmtconst_val (c_uimm2, x, 0)
+#define uimm3(x) fmtconst_val (c_uimm3, x, 0)
+#define uimm3_str(x) fmtconst_str (c_uimm3, x, 0)
+#define luimm16(x) fmtconst_val (c_luimm16, x, 0)
+#define luimm16_str(x) fmtconst_str (c_luimm16, x, 0)
+#define uimm4(x) fmtconst_val (c_uimm4, x, 0)
+#define uimm4_str(x) fmtconst_str (c_uimm4, x, 0)
+#define uimm5(x) fmtconst_val (c_uimm5, x, 0)
+#define uimm5_str(x) fmtconst_str (c_uimm5, x, 0)
+#define imm16s2(x) fmtconst_val (c_imm16s2, x, 0)
+#define imm16s2_str(x) fmtconst_str (c_imm16s2, x, 0)
+#define uimm8(x) fmtconst_val (c_uimm8, x, 0)
+#define imm16s4(x) fmtconst_val (c_imm16s4, x, 0)
+#define imm16s4_str(x) fmtconst_str (c_imm16s4, x, 0)
+#define uimm4s2(x) fmtconst_val (c_uimm4s2, x, 0)
+#define uimm4s2_str(x) fmtconst_str (c_uimm4s2, x, 0)
+#define uimm4s4(x) fmtconst_val (c_uimm4s4, x, 0)
+#define uimm4s4_str(x) fmtconst_str (c_uimm4s4, x, 0)
+#define uimm4s4d(x) fmtconst_val (c_uimm4s4d, x, 0)
+#define lppcrel10(x) fmtconst_val (c_lppcrel10, x, pc)
+#define imm3(x) fmtconst_val (c_imm3, x, 0)
+#define imm3_str(x) fmtconst_str (c_imm3, x, 0)
+#define imm4(x) fmtconst_val (c_imm4, x, 0)
+#define uimm8s4(x) fmtconst_val (c_uimm8s4, x, 0)
+#define imm5(x) fmtconst_val (c_imm5, x, 0)
+#define imm5d(x) fmtconst_val (c_imm5d, x, 0)
+#define imm6(x) fmtconst_val (c_imm6, x, 0)
+#define imm7(x) fmtconst_val (c_imm7, x, 0)
+#define imm7_str(x) fmtconst_str (c_imm7, x, 0)
+#define imm7d(x) fmtconst_val (c_imm7d, x, 0)
+#define imm8(x) fmtconst_val (c_imm8, x, 0)
+#define pcrel24(x) fmtconst_val (c_pcrel24, x, pc)
+#define pcrel24_str(x) fmtconst_str (c_pcrel24, x, pc)
+#define uimm16(x) fmtconst_val (c_uimm16, x, 0)
+#define uimm32(x) fmtconst_val (c_uimm32, x, 0)
+#define imm32(x) fmtconst_val (c_imm32, x, 0)
+#define huimm32(x) fmtconst_val (c_huimm32, x, 0)
+#define huimm32e(x) fmtconst_val (c_huimm32e, x, 0)
+
+/* Table C-4. Core Register Encoding Map. */
+const char * const greg_names[] =
+{
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
+ "P0", "P1", "P2", "P3", "P4", "P5", "SP", "FP",
+ "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3",
+ "B0", "B1", "B2", "B3", "L0", "L1", "L2", "L3",
+ "A0.X", "A0.W", "A1.X", "A1.W", "<res>", "<res>", "ASTAT", "RETS",
+ "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>",
+ "LC0", "LT0", "LB0", "LC1", "LT1", "LB1", "CYCLES", "CYCLES2",
+ "USP", "SEQSTAT", "SYSCFG", "RETI", "RETX", "RETN", "RETE", "EMUDAT",
+};
+static const char *
+get_allreg_name (int grp, int reg)
+{
+ return greg_names[(grp << 3) | reg];
+}
+static const char *
+get_preg_name (int reg)
+{
+ return get_allreg_name (1, reg);
+}
+
+static bool
+reg_is_reserved (int grp, int reg)
+{
+ return (grp == 4 && (reg == 4 || reg == 5)) || (grp == 5);
+}
+
+static bu32 *
+get_allreg (SIM_CPU *cpu, int grp, int reg)
+{
+ int fullreg = (grp << 3) | reg;
+ /* REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
+ REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3,
+ REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,
+ REG_A0x, REG_A0w, REG_A1x, REG_A1w, , , REG_ASTAT, REG_RETS,
+ , , , , , , , ,
+ REG_LC0, REG_LT0, REG_LB0, REG_LC1, REG_LT1, REG_LB1, REG_CYCLES,
+ REG_CYCLES2,
+ REG_USP, REG_SEQSTAT, REG_SYSCFG, REG_RETI, REG_RETX, REG_RETN, REG_RETE,
+ REG_LASTREG */
+ switch (fullreg >> 2)
+ {
+ case 0: case 1: return &DREG (reg);
+ case 2: case 3: return &PREG (reg);
+ case 4: return &IREG (reg & 3);
+ case 5: return &MREG (reg & 3);
+ case 6: return &BREG (reg & 3);
+ case 7: return &LREG (reg & 3);
+ default:
+ switch (fullreg)
+ {
+ case 32: return &AXREG (0);
+ case 33: return &AWREG (0);
+ case 34: return &AXREG (1);
+ case 35: return &AWREG (1);
+ case 39: return &RETSREG;
+ case 48: return &LCREG (0);
+ case 49: return &LTREG (0);
+ case 50: return &LBREG (0);
+ case 51: return &LCREG (1);
+ case 52: return &LTREG (1);
+ case 53: return &LBREG (1);
+ case 54: return &CYCLESREG;
+ case 55: return &CYCLES2REG;
+ case 56: return &USPREG;
+ case 57: return &SEQSTATREG;
+ case 58: return &SYSCFGREG;
+ case 59: return &RETIREG;
+ case 60: return &RETXREG;
+ case 61: return &RETNREG;
+ case 62: return &RETEREG;
+ case 63: return &EMUDAT_INREG;
+ }
+ illegal_instruction (cpu);
+ }
+}
+
+static const char *
+amod0 (int s0, int x0)
+{
+ static const char * const mod0[] = {
+ "", " (S)", " (CO)", " (SCO)",
+ };
+ int i = s0 + (x0 << 1);
+
+ if (i < ARRAY_SIZE (mod0))
+ return mod0[i];
+ else
+ return "";
+}
+
+static const char *
+amod0amod2 (int s0, int x0, int aop0)
+{
+ static const char * const mod02[] = {
+ "", " (S)", " (CO)", " (SCO)",
+ "", "", "", "",
+ " (ASR)", " (S, ASR)", " (CO, ASR)", " (SCO, ASR)",
+ " (ASL)", " (S, ASL)", " (CO, ASL)", " (SCO, ASL)",
+ };
+ int i = s0 + (x0 << 1) + (aop0 << 2);
+
+ if (i < ARRAY_SIZE (mod02))
+ return mod02[i];
+ else
+ return "";
+}
+
+static const char *
+amod1 (int s0, int x0)
+{
+ static const char * const mod1[] = {
+ " (NS)", " (S)",
+ };
+ int i = s0 + (x0 << 1);
+
+ if (i < ARRAY_SIZE (mod1))
+ return mod1[i];
+ else
+ return "";
+}
+
+static const char *
+mac_optmode (int mmod, int MM)
+{
+ static const char * const omode[] = {
+ [(M_S2RND << 1) + 0] = " (S2RND)",
+ [(M_T << 1) + 0] = " (T)",
+ [(M_W32 << 1) + 0] = " (W32)",
+ [(M_FU << 1) + 0] = " (FU)",
+ [(M_TFU << 1) + 0] = " (TFU)",
+ [(M_IS << 1) + 0] = " (IS)",
+ [(M_ISS2 << 1) + 0] = " (ISS2)",
+ [(M_IH << 1) + 0] = " (IH)",
+ [(M_IU << 1) + 0] = " (IU)",
+ [(M_S2RND << 1) + 1] = " (M, S2RND)",
+ [(M_T << 1) + 1] = " (M, T)",
+ [(M_W32 << 1) + 1] = " (M, W32)",
+ [(M_FU << 1) + 1] = " (M, FU)",
+ [(M_TFU << 1) + 1] = " (M, TFU)",
+ [(M_IS << 1) + 1] = " (M, IS)",
+ [(M_ISS2 << 1) + 1] = " (M, ISS2)",
+ [(M_IH << 1) + 1] = " (M, IH)",
+ [(M_IU << 1) + 1] = " (M, IU)",
+ };
+ int i = MM + (mmod << 1);
+
+ if (i < ARRAY_SIZE (omode) && omode[i])
+ return omode[i];
+ else
+ return "";
+}
+
+static const char *
+get_store_name (SIM_CPU *cpu, bu32 *p)
+{
+ if (p >= &DREG (0) && p <= &CYCLESREG)
+ return greg_names[p - &DREG (0)];
+ else if (p == &AXREG (0))
+ return greg_names[4 * 8 + 0];
+ else if (p == &AWREG (0))
+ return greg_names[4 * 8 + 1];
+ else if (p == &AXREG (1))
+ return greg_names[4 * 8 + 2];
+ else if (p == &AWREG (1))
+ return greg_names[4 * 8 + 3];
+ else if (p == &ASTATREG (av0))
+ return "ASTAT[av0]";
+ else if (p == &ASTATREG (av0s))
+ return "ASTAT[av0s]";
+ else if (p == &ASTATREG (av1))
+ return "ASTAT[av1]";
+ else if (p == &ASTATREG (av1s))
+ return "ASTAT[av1s]";
+ else if (p == &ASTATREG (v))
+ return "ASTAT[v]";
+ else if (p == &ASTATREG (vs))
+ return "ASTAT[vs]";
+ else if (p == &ASTATREG (v_copy))
+ return "ASTAT[v_copy]";
+ else if (p == &ASTATREG (az))
+ return "ASTAT[az]";
+ else if (p == &ASTATREG (an))
+ return "ASTAT[an]";
+ else if (p == &ASTATREG (az))
+ return "ASTAT[az]";
+ else if (p == &ASTATREG (ac0))
+ return "ASTAT[ac0]";
+ else if (p == &ASTATREG (ac0_copy))
+ return "ASTAT[ac0_copy]";
+ else
+ {
+ /* Worry about this when we start to STORE() it. */
+ sim_io_eprintf (CPU_STATE (cpu), "STORE(): unknown register\n");
+ abort ();
+ }
+}
+
+static void
+queue_store (SIM_CPU *cpu, bu32 *addr, bu32 val)
+{
+ struct store *s = &BFIN_CPU_STATE.stores[BFIN_CPU_STATE.n_stores];
+ s->addr = addr;
+ s->val = val;
+ TRACE_REGISTER (cpu, "queuing write %s = %#x",
+ get_store_name (cpu, addr), val);
+ ++BFIN_CPU_STATE.n_stores;
+}
+#define STORE(X, Y) \
+ do { \
+ if (BFIN_CPU_STATE.n_stores == 20) abort (); \
+ queue_store (cpu, &(X), (Y)); \
+ } while (0)
+
+static void
+setflags_nz (SIM_CPU *cpu, bu32 val)
+{
+ SET_ASTATREG (az, val == 0);
+ SET_ASTATREG (an, val >> 31);
+}
+
+static void
+setflags_nz_2x16 (SIM_CPU *cpu, bu32 val)
+{
+ SET_ASTATREG (an, (bs16)val < 0 || (bs16)(val >> 16) < 0);
+ SET_ASTATREG (az, (bs16)val == 0 || (bs16)(val >> 16) == 0);
+}
+
+static void
+setflags_logical (SIM_CPU *cpu, bu32 val)
+{
+ setflags_nz (cpu, val);
+ SET_ASTATREG (ac0, 0);
+ SET_ASTATREG (v, 0);
+}
+
+static bu32
+add_brev (bu32 addend1, bu32 addend2)
+{
+ bu32 mask, b, r;
+ int i, cy;
+
+ mask = 0x80000000;
+ r = 0;
+ cy = 0;
+
+ for (i = 31; i >= 0; --i)
+ {
+ b = ((addend1 & mask) >> i) + ((addend2 & mask) >> i);
+ b += cy;
+ cy = b >> 1;
+ b &= 1;
+ r |= b << i;
+ mask >>= 1;
+ }
+
+ return r;
+}
+
+/* This is a bit crazy, but we want to simulate the hardware behavior exactly
+ rather than worry about the circular buffers being used correctly. Which
+ isn't to say there isn't room for improvement here, just that we want to
+ be conservative. See also dagsub(). */
+static bu32
+dagadd (SIM_CPU *cpu, int dagno, bs32 M)
+{
+ bu64 i = IREG (dagno);
+ bu64 l = LREG (dagno);
+ bu64 b = BREG (dagno);
+ bu64 m = (bu32)M;
+
+ bu64 LB, IM, IML;
+ bu32 im32, iml32, lb32, res;
+ bu64 msb, car;
+
+ /* A naïve implementation that mostly works:
+ res = i + m;
+ if (l && res >= b + l)
+ res -= l;
+ STORE (IREG (dagno), res);
+ */
+
+ msb = (bu64)1 << 31;
+ car = (bu64)1 << 32;
+
+ IM = i + m;
+ im32 = IM;
+ LB = l + b;
+ lb32 = LB;
+
+ if (M < 0)
+ {
+ IML = i + m + l;
+ iml32 = IML;
+ if ((i & msb) || (IM & car))
+ res = (im32 < b) ? iml32 : im32;
+ else
+ res = (im32 < b) ? im32 : iml32;
+ }
+ else
+ {
+ IML = i + m - l;
+ iml32 = IML;
+ if ((IM & car) == (LB & car))
+ res = (im32 < lb32) ? im32 : iml32;
+ else
+ res = (im32 < lb32) ? iml32 : im32;
+ }
+
+ STORE (IREG (dagno), res);
+ return res;
+}
+
+/* See dagadd() notes above. */
+static bu32
+dagsub (SIM_CPU *cpu, int dagno, bs32 M)
+{
+ bu64 i = IREG (dagno);
+ bu64 l = LREG (dagno);
+ bu64 b = BREG (dagno);
+ bu64 m = (bu32)M;
+
+ bu64 mbar = (bu32)(~m + 1);
+ bu64 LB, IM, IML;
+ bu32 b32, im32, iml32, lb32, res;
+ bu64 msb, car;
+
+ /* A naïve implementation that mostly works:
+ res = i - m;
+ if (l && newi < b)
+ newi += l;
+ STORE (IREG (dagno), newi);
+ */
+
+ msb = (bu64)1 << 31;
+ car = (bu64)1 << 32;
+
+ IM = i + mbar;
+ im32 = IM;
+ LB = l + b;
+ lb32 = LB;
+
+ if (M < 0)
+ {
+ IML = i + mbar - l;
+ iml32 = IML;
+ if (!!((i & msb) && (IM & car)) == !!(LB & car))
+ res = (im32 < lb32) ? im32 : iml32;
+ else
+ res = (im32 < lb32) ? iml32 : im32;
+ }
+ else
+ {
+ IML = i + mbar + l;
+ iml32 = IML;
+ b32 = b;
+ if (M == 0 || IM & car)
+ res = (im32 < b32) ? iml32 : im32;
+ else
+ res = (im32 < b32) ? im32 : iml32;
+ }
+
+ STORE (IREG (dagno), res);
+ return res;
+}
+
+static bu40
+ashiftrt (SIM_CPU *cpu, bu40 val, int cnt, int size)
+{
+ int real_cnt = cnt > size ? size : cnt;
+ bu40 sgn = ~(((val & 0xFFFFFFFFFFull) >> (size - 1)) - 1);
+ int sgncnt = size - real_cnt;
+ if (sgncnt > 16)
+ sgn <<= 16, sgncnt -= 16;
+ sgn <<= sgncnt;
+ if (real_cnt > 16)
+ val >>= 16, real_cnt -= 16;
+ val >>= real_cnt;
+ val |= sgn;
+ SET_ASTATREG (an, val >> (size - 1));
+ SET_ASTATREG (az, val == 0);
+ /* XXX: Need to check ASTAT[v] behavior here. */
+ SET_ASTATREG (v, 0);
+ return val;
+}
+
+static bu64
+lshiftrt (SIM_CPU *cpu, bu64 val, int cnt, int size)
+{
+ int real_cnt = cnt > size ? size : cnt;
+ if (real_cnt > 16)
+ val >>= 16, real_cnt -= 16;
+ val >>= real_cnt;
+ switch (size)
+ {
+ case 16:
+ val &= 0xFFFF;
+ break;
+ case 32:
+ val &= 0xFFFFFFFF;
+ break;
+ case 40:
+ val &= 0xFFFFFFFFFFull;
+ break;
+ default:
+ illegal_instruction (cpu);
+ break;
+ }
+ SET_ASTATREG (an, val >> (size - 1));
+ SET_ASTATREG (az, val == 0);
+ SET_ASTATREG (v, 0);
+ return val;
+}
+
+static bu64
+lshift (SIM_CPU *cpu, bu64 val, int cnt, int size, bool saturate)
+{
+ int i, j, real_cnt = cnt > size ? size : cnt;
+ bu64 sgn = ~((val >> (size - 1)) - 1);
+ int mask_cnt = size - 1;
+ bu64 masked, new_val = val, tmp;
+ bu64 mask = ~0;
+
+ mask <<= mask_cnt;
+ sgn <<= mask_cnt;
+ masked = val & mask;
+
+ if (real_cnt > 16)
+ new_val <<= 16, real_cnt -= 16;
+
+ new_val <<= real_cnt;
+
+ masked = new_val & mask;
+
+ /* If an operation would otherwise cause a positive value to overflow
+ and become negative, instead, saturation limits the result to the
+ maximum positive value for the size register being used.
+
+ Conversely, if an operation would otherwise cause a negative value
+ to overflow and become positive, saturation limits the result to the
+ maximum negative value for the register size.
+
+ However, it's a little more complex than looking at sign bits, we need
+ to see if we are shifting the sign information away... */
+ tmp = val & ((~mask << 1) | 1);
+
+ j = 0;
+ for (i = 1; i <= real_cnt && saturate; i++)
+ {
+ if ((tmp & ((bu64)1 << (size - 1))) !=
+ (((val >> mask_cnt) & 0x1) << mask_cnt))
+ j++;
+ tmp <<= 1;
+ }
+ saturate &= (!sgn && (new_val & (1 << mask_cnt)))
+ || (sgn && !(new_val & (1 << mask_cnt)));
+
+ switch (size)
+ {
+ case 16:
+ if (j || (saturate && (new_val & mask)))
+ new_val = sgn == 0 ? 0x7fff : 0x8000, saturate = 1;
+ new_val &= 0xFFFF;
+ break;
+ case 32:
+ new_val &= 0xFFFFFFFF;
+ masked &= 0xFFFFFFFF;
+ if (j || (saturate && ((sgn != masked) || (!sgn && new_val == 0))))
+ new_val = sgn == 0 ? 0x7fffffff : 0x80000000, saturate = 1;
+ break;
+ case 40:
+ new_val &= 0xFFFFFFFFFFull;
+ masked &= 0xFFFFFFFFFFull;
+ break;
+ default:
+ illegal_instruction (cpu);
+ break;
+ }
+
+ SET_ASTATREG (an, new_val >> (size - 1));
+ SET_ASTATREG (az, new_val == 0);
+ SET_ASTATREG (v, !!(saturate || j));
+ if (saturate || j)
+ SET_ASTATREG (vs, 1);
+ return new_val;
+}
+
+static bu32
+algn (bu32 l, bu32 h, bu32 aln)
+{
+ if (aln == 0)
+ return l;
+ else
+ return (l >> (8 * aln)) | (h << (32 - 8 * aln));
+}
+
+static bu32
+saturate_s16 (bu64 val, bu32 *overflow)
+{
+ if ((bs64)val < -0x8000ll)
+ {
+ if (overflow)
+ *overflow = 1;
+ return 0x8000;
+ }
+ if ((bs64)val > 0x7fff)
+ {
+ if (overflow)
+ *overflow = 1;
+ return 0x7fff;
+ }
+ return val & 0xffff;
+}
+
+static bu40
+rot40 (bu40 val, int shift, bu32 *cc)
+{
+ const int nbits = 40;
+ bu40 ret;
+
+ shift = CLAMP (shift, -nbits, nbits);
+ if (shift == 0)
+ return val;
+
+ /* Reduce everything to rotate left. */
+ if (shift < 0)
+ shift += nbits + 1;
+
+ ret = shift == nbits ? 0 : val << shift;
+ ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift);
+ ret |= (bu40)*cc << (shift - 1);
+ *cc = (val >> (nbits - shift)) & 1;
+
+ return ret;
+}
+
+static bu32
+rot32 (bu32 val, int shift, bu32 *cc)
+{
+ const int nbits = 32;
+ bu32 ret;
+
+ shift = CLAMP (shift, -nbits, nbits);
+ if (shift == 0)
+ return val;
+
+ /* Reduce everything to rotate left. */
+ if (shift < 0)
+ shift += nbits + 1;
+
+ ret = shift == nbits ? 0 : val << shift;
+ ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift);
+ ret |= (bu32)*cc << (shift - 1);
+ *cc = (val >> (nbits - shift)) & 1;
+
+ return ret;
+}
+
+static bu32
+add32 (SIM_CPU *cpu, bu32 a, bu32 b, int carry, int sat)
+{
+ int flgs = (a >> 31) & 1;
+ int flgo = (b >> 31) & 1;
+ bu32 v = a + b;
+ int flgn = (v >> 31) & 1;
+ int overflow = (flgs ^ flgn) & (flgo ^ flgn);
+
+ if (sat && overflow)
+ {
+ v = (bu32)1 << 31;
+ if (flgn)
+ v -= 1;
+ flgn = (v >> 31) & 1;
+ }
+
+ SET_ASTATREG (an, flgn);
+ if (overflow)
+ SET_ASTATREG (vs, 1);
+ SET_ASTATREG (v, overflow);
+ ASTATREG (v_internal) |= overflow;
+ SET_ASTATREG (az, v == 0);
+ if (carry)
+ SET_ASTATREG (ac0, ~a < b);
+
+ return v;
+}
+
+static bu32
+sub32 (SIM_CPU *cpu, bu32 a, bu32 b, int carry, int sat, int parallel)
+{
+ int flgs = (a >> 31) & 1;
+ int flgo = (b >> 31) & 1;
+ bu32 v = a - b;
+ int flgn = (v >> 31) & 1;
+ int overflow = (flgs ^ flgo) & (flgn ^ flgs);
+
+ if (sat && overflow)
+ {
+ v = (bu32)1 << 31;
+ if (flgn)
+ v -= 1;
+ flgn = (v >> 31) & 1;
+ }
+
+ if (!parallel || flgn)
+ SET_ASTATREG (an, flgn);
+ if (overflow)
+ SET_ASTATREG (vs, 1);
+ if (!parallel || overflow)
+ SET_ASTATREG (v, overflow);
+ if (!parallel || overflow)
+ ASTATREG (v_internal) |= overflow;
+ if (!parallel || v == 0)
+ SET_ASTATREG (az, v == 0);
+ if (carry && (!parallel || b <= a))
+ SET_ASTATREG (ac0, b <= a);
+
+ return v;
+}
+
+static bu32
+add16 (SIM_CPU *cpu, bu16 a, bu16 b, bu32 *carry, bu32 *overfl,
+ bu32 *zero, bu32 *neg, int sat, int scale)
+{
+ int flgs = (a >> 15) & 1;
+ int flgo = (b >> 15) & 1;
+ bs64 v = (bs16)a + (bs16)b;
+ int flgn = (v >> 15) & 1;
+ int overflow = (flgs ^ flgn) & (flgo ^ flgn);
+
+ switch (scale)
+ {
+ case 0:
+ break;
+ case 2:
+ /* (ASR) */
+ v = (a >> 1) + (a & 0x8000) + (b >> 1) + (b & 0x8000)
+ + (((a & 1) + (b & 1)) >> 1);
+ v |= -(v & 0x8000);
+ break;
+ case 3:
+ /* (ASL) */
+ v = (v << 1);
+ break;
+ default:
+ illegal_instruction (cpu);
+ }
+
+ flgn = (v >> 15) & 1;
+ overflow = (flgs ^ flgn) & (flgo ^ flgn);
+
+ if (v > (bs64)0xffff)
+ overflow = 1;
+
+ if (sat)
+ v = saturate_s16 (v, 0);
+
+ if (neg)
+ *neg |= (v >> 15) & 1;
+ if (overfl)
+ *overfl |= overflow;
+ if (zero)
+ *zero |= (v & 0xFFFF) == 0;
+ if (carry)
+ *carry |= ((bu16)~a < (bu16)b);
+
+ return v & 0xffff;
+}
+
+static bu32
+sub16 (SIM_CPU *cpu, bu16 a, bu16 b, bu32 *carry, bu32 *overfl,
+ bu32 *zero, bu32 *neg, int sat, int scale)
+{
+ int flgs = (a >> 15) & 1;
+ int flgo = (b >> 15) & 1;
+ bs64 v = (bs16)a - (bs16)b;
+ int flgn = (v >> 15) & 1;
+ int overflow = (flgs ^ flgo) & (flgn ^ flgs);
+
+ switch (scale)
+ {
+ case 0:
+ break;
+ case 2:
+ /* (ASR) */
+ if (sat)
+ v = ((a >> 1) + (a & 0x8000)) - ( (b >> 1) + (b & 0x8000))
+ + (((a & 1)-(b & 1)));
+ else
+ {
+ v = ((v & 0xFFFF) >> 1);
+ if ((!flgs & !flgo & flgn)
+ || (flgs & !flgo & !flgn)
+ || (flgs & flgo & flgn)
+ || (flgs & !flgo & flgn))
+ v |= 0x8000;
+ }
+ v |= -(v & 0x8000);
+ flgn = (v >> 15) & 1;
+ overflow = (flgs ^ flgo) & (flgn ^ flgs);
+ break;
+ case 3:
+ /* (ASL) */
+ v <<= 1;
+ if (v > (bs64)0x7fff || v < (bs64)-0xffff)
+ overflow = 1;
+ break;
+ default:
+ illegal_instruction (cpu);
+ }
+
+ if (sat)
+ {
+ v = saturate_s16 (v, 0);
+ }
+ if (neg)
+ *neg |= (v >> 15) & 1;
+ if (zero)
+ *zero |= (v & 0xFFFF) == 0;
+ if (overfl)
+ *overfl |= overflow;
+ if (carry)
+ *carry |= (bu16)b <= (bu16)a;
+ return v;
+}
+
+static bu32
+min32 (SIM_CPU *cpu, bu32 a, bu32 b)
+{
+ int val = a;
+ if ((bs32)a > (bs32)b)
+ val = b;
+ setflags_nz (cpu, val);
+ SET_ASTATREG (v, 0);
+ return val;
+}
+
+static bu32
+max32 (SIM_CPU *cpu, bu32 a, bu32 b)
+{
+ int val = a;
+ if ((bs32)a < (bs32)b)
+ val = b;
+ setflags_nz (cpu, val);
+ SET_ASTATREG (v, 0);
+ return val;
+}
+
+static bu32
+min2x16 (SIM_CPU *cpu, bu32 a, bu32 b)
+{
+ int val = a;
+ if ((bs16)a > (bs16)b)
+ val = (val & 0xFFFF0000) | (b & 0xFFFF);
+ if ((bs16)(a >> 16) > (bs16)(b >> 16))
+ val = (val & 0xFFFF) | (b & 0xFFFF0000);
+ setflags_nz_2x16 (cpu, val);
+ SET_ASTATREG (v, 0);
+ return val;
+}
+
+static bu32
+max2x16 (SIM_CPU *cpu, bu32 a, bu32 b)
+{
+ int val = a;
+ if ((bs16)a < (bs16)b)
+ val = (val & 0xFFFF0000) | (b & 0xFFFF);
+ if ((bs16)(a >> 16) < (bs16)(b >> 16))
+ val = (val & 0xFFFF) | (b & 0xFFFF0000);
+ setflags_nz_2x16 (cpu, val);
+ SET_ASTATREG (v, 0);
+ return val;
+}
+
+static bu32
+add_and_shift (SIM_CPU *cpu, bu32 a, bu32 b, int shift)
+{
+ int v;
+ ASTATREG (v_internal) = 0;
+ v = add32 (cpu, a, b, 0, 0);
+ while (shift-- > 0)
+ {
+ int x = (v >> 30) & 0x3;
+ if (x == 1 || x == 2)
+ ASTATREG (v_internal) = 1;
+ v <<= 1;
+ }
+ SET_ASTATREG (az, v == 0);
+ SET_ASTATREG (an, v & 0x80000000);
+ SET_ASTATREG (v, ASTATREG (v_internal));
+ if (ASTATREG (v))
+ SET_ASTATREG (vs, 1);
+ return v;
+}
+
+static bu32
+xor_reduce (bu64 acc0, bu64 acc1)
+{
+ int i;
+ bu32 v = 0;
+ for (i = 0; i < 40; ++i)
+ {
+ v ^= (acc0 & acc1 & 1);
+ acc0 >>= 1;
+ acc1 >>= 1;
+ }
+ return v;
+}
+
+/* DIVS ( Dreg, Dreg ) ;
+ Initialize for DIVQ. Set the AQ status bit based on the signs of
+ the 32-bit dividend and the 16-bit divisor. Left shift the dividend
+ one bit. Copy AQ into the dividend LSB. */
+static bu32
+divs (SIM_CPU *cpu, bu32 pquo, bu16 divisor)
+{
+ bu16 r = pquo >> 16;
+ int aq;
+
+ aq = (r ^ divisor) >> 15; /* Extract msb's and compute quotient bit. */
+ SET_ASTATREG (aq, aq); /* Update global quotient state. */
+
+ pquo <<= 1;
+ pquo |= aq;
+ pquo = (pquo & 0x1FFFF) | (r << 17);
+ return pquo;
+}
+
+/* DIVQ ( Dreg, Dreg ) ;
+ Based on AQ status bit, either add or subtract the divisor from
+ the dividend. Then set the AQ status bit based on the MSBs of the
+ 32-bit dividend and the 16-bit divisor. Left shift the dividend one
+ bit. Copy the logical inverse of AQ into the dividend LSB. */
+static bu32
+divq (SIM_CPU *cpu, bu32 pquo, bu16 divisor)
+{
+ unsigned short af = pquo >> 16;
+ unsigned short r;
+ int aq;
+
+ if (ASTATREG (aq))
+ r = divisor + af;
+ else
+ r = af - divisor;
+
+ aq = (r ^ divisor) >> 15; /* Extract msb's and compute quotient bit. */
+ SET_ASTATREG (aq, aq); /* Update global quotient state. */
+
+ pquo <<= 1;
+ pquo |= !aq;
+ pquo = (pquo & 0x1FFFF) | (r << 17);
+ return pquo;
+}
+
+/* ONES ( Dreg ) ;
+ Count the number of bits set to 1 in the 32bit value. */
+static bu32
+ones (bu32 val)
+{
+ bu32 i;
+ bu32 ret;
+
+ ret = 0;
+ for (i = 0; i < 32; ++i)
+ ret += !!(val & (1 << i));
+
+ return ret;
+}
+
+static void
+reg_check_sup (SIM_CPU *cpu, int grp, int reg)
+{
+ if (grp == 7)
+ cec_require_supervisor (cpu);
+}
+
+static void
+reg_write (SIM_CPU *cpu, int grp, int reg, bu32 value)
+{
+ bu32 *whichreg;
+
+ /* ASTAT is special! */
+ if (grp == 4 && reg == 6)
+ {
+ SET_ASTAT (value);
+ return;
+ }
+
+ /* Check supervisor after get_allreg() so exception order is correct. */
+ whichreg = get_allreg (cpu, grp, reg);
+ reg_check_sup (cpu, grp, reg);
+
+ if (whichreg == &CYCLES2REG)
+ /* Writes to CYCLES2 goes to the shadow. */
+ whichreg = &CYCLES2SHDREG;
+ else if (whichreg == &SEQSTATREG)
+ /* Register is read only -- discard writes. */
+ return;
+ else if (whichreg == &EMUDAT_INREG)
+ /* Writes to EMUDAT goes to the output. */
+ whichreg = &EMUDAT_OUTREG;
+ else if (whichreg == &LTREG (0) || whichreg == &LTREG (1))
+ /* Writes to LT clears LSB automatically. */
+ value &= ~0x1;
+ else if (whichreg == &AXREG (0) || whichreg == &AXREG (1))
+ value &= 0xFF;
+
+ TRACE_REGISTER (cpu, "wrote %s = %#x", get_allreg_name (grp, reg), value);
+
+ *whichreg = value;
+}
+
+static bu32
+reg_read (SIM_CPU *cpu, int grp, int reg)
+{
+ bu32 *whichreg;
+ bu32 value;
+
+ /* ASTAT is special! */
+ if (grp == 4 && reg == 6)
+ return ASTAT;
+
+ /* Check supervisor after get_allreg() so exception order is correct. */
+ whichreg = get_allreg (cpu, grp, reg);
+ reg_check_sup (cpu, grp, reg);
+
+ value = *whichreg;
+
+ if (whichreg == &CYCLESREG)
+ /* Reads of CYCLES reloads CYCLES2 from the shadow. */
+ SET_CYCLES2REG (CYCLES2SHDREG);
+ else if ((whichreg == &AXREG (1) || whichreg == &AXREG (0)) && (value & 0x80))
+ /* Sign extend if necessary. */
+ value |= 0xFFFFFF00;
+
+ return value;
+}
+
+static bu64
+get_extended_cycles (SIM_CPU *cpu)
+{
+ return ((bu64)CYCLES2SHDREG << 32) | CYCLESREG;
+}
+
+/* We can't re-use sim_events_time() because the CYCLES registers may be
+ written/cleared/reset/stopped/started at any time by software. */
+static void
+cycles_inc (SIM_CPU *cpu, bu32 inc)
+{
+ bu64 cycles;
+ bu32 cycles2;
+
+ if (!(SYSCFGREG & SYSCFG_CCEN))
+ return;
+
+ cycles = get_extended_cycles (cpu) + inc;
+ SET_CYCLESREG (cycles);
+ cycles2 = cycles >> 32;
+ if (CYCLES2SHDREG != cycles2)
+ SET_CYCLES2SHDREG (cycles2);
+}
+
+static bu64
+get_unextended_acc (SIM_CPU *cpu, int which)
+{
+ return ((bu64)(AXREG (which) & 0xff) << 32) | AWREG (which);
+}
+
+static bu64
+get_extended_acc (SIM_CPU *cpu, int which)
+{
+ bu64 acc = AXREG (which);
+ /* Sign extend accumulator values before adding. */
+ if (acc & 0x80)
+ acc |= -0x80;
+ else
+ acc &= 0xFF;
+ acc <<= 32;
+ acc |= AWREG (which);
+ return acc;
+}
+
+/* Perform a multiplication of D registers SRC0 and SRC1, sign- or
+ zero-extending the result to 64 bit. H0 and H1 determine whether the
+ high part or the low part of the source registers is used. Store 1 in
+ *PSAT if saturation occurs, 0 otherwise. */
+static bu64
+decode_multfunc (SIM_CPU *cpu, int h0, int h1, int src0, int src1, int mmod,
+ int MM, bu32 *psat)
+{
+ bu32 s0 = DREG (src0), s1 = DREG (src1);
+ bu32 sgn0, sgn1;
+ bu32 val;
+ bu64 val1;
+
+ if (h0)
+ s0 >>= 16;
+
+ if (h1)
+ s1 >>= 16;
+
+ s0 &= 0xffff;
+ s1 &= 0xffff;
+
+ sgn0 = -(s0 & 0x8000);
+ sgn1 = -(s1 & 0x8000);
+
+ if (MM)
+ s0 |= sgn0;
+ else
+ switch (mmod)
+ {
+ case 0:
+ case M_S2RND:
+ case M_T:
+ case M_IS:
+ case M_ISS2:
+ case M_IH:
+ case M_W32:
+ s0 |= sgn0;
+ s1 |= sgn1;
+ break;
+ case M_FU:
+ case M_IU:
+ case M_TFU:
+ break;
+ default:
+ illegal_instruction (cpu);
+ }
+
+ val = s0 * s1;
+ /* Perform shift correction if appropriate for the mode. */
+ *psat = 0;
+ if (!MM && (mmod == 0 || mmod == M_T || mmod == M_S2RND || mmod == M_W32))
+ {
+ if (val == 0x40000000)
+ {
+ if (mmod == M_W32)
+ val = 0x7fffffff;
+ else
+ val = 0x80000000;
+ *psat = 1;
+ }
+ else
+ val <<= 1;
+ }
+ val1 = val;
+
+ if (mmod == 0 || mmod == M_IS || mmod == M_T || mmod == M_S2RND
+ || mmod == M_ISS2 || mmod == M_IH || (MM && mmod == M_FU))
+ val1 |= -(val1 & 0x80000000);
+
+ if (*psat)
+ val1 &= 0xFFFFFFFFull;
+
+ return val1;
+}
+
+static bu40
+saturate_s40_astat (bu64 val, bu32 *v)
+{
+ if ((bs64)val < -((bs64)1 << 39))
+ {
+ *v = 1;
+ return -((bs64)1 << 39);
+ }
+ else if ((bs64)val >= ((bs64)1 << 39) - 1)
+ {
+ *v = 1;
+ return ((bu64)1 << 39) - 1;
+ }
+ *v = 0; /* No overflow. */
+ return val;
+}
+
+static bu40
+saturate_s40 (bu64 val)
+{
+ bu32 v;
+ return saturate_s40_astat (val, &v);
+}
+
+static bu32
+saturate_s32 (bu64 val, bu32 *overflow)
+{
+ if ((bs64)val < -0x80000000ll)
+ {
+ if (overflow)
+ *overflow = 1;
+ return 0x80000000;
+ }
+ if ((bs64)val > 0x7fffffff)
+ {
+ if (overflow)
+ *overflow = 1;
+ return 0x7fffffff;
+ }
+ return val;
+}
+
+static bu32
+saturate_u32 (bu64 val, bu32 *overflow)
+{
+ if (val > 0xffffffff)
+ {
+ if (overflow)
+ *overflow = 1;
+ return 0xffffffff;
+ }
+ return val;
+}
+
+static bu32
+saturate_u16 (bu64 val, bu32 *overflow)
+{
+ if (val > 0xffff)
+ {
+ if (overflow)
+ *overflow = 1;
+ return 0xffff;
+ }
+ return val;
+}
+
+static bu64
+rnd16 (bu64 val)
+{
+ bu64 sgnbits;
+
+ /* FIXME: Should honour rounding mode. */
+ if ((val & 0xffff) > 0x8000
+ || ((val & 0xffff) == 0x8000 && (val & 0x10000)))
+ val += 0x8000;
+
+ sgnbits = val & 0xffff000000000000ull;
+ val >>= 16;
+ return val | sgnbits;
+}
+
+static bu64
+trunc16 (bu64 val)
+{
+ bu64 sgnbits = val & 0xffff000000000000ull;
+ val >>= 16;
+ return val | sgnbits;
+}
+
+static int
+signbits (bu64 val, int size)
+{
+ bu64 mask = (bu64)1 << (size - 1);
+ bu64 bit = val & mask;
+ int count = 0;
+ for (;;)
+ {
+ mask >>= 1;
+ bit >>= 1;
+ if (mask == 0)
+ break;
+ if ((val & mask) != bit)
+ break;
+ count++;
+ }
+ if (size == 40)
+ count -= 8;
+
+ return count;
+}
+
+/* Extract a 16 or 32 bit value from a 64 bit multiplication result.
+ These 64 bits must be sign- or zero-extended properly from the source
+ we want to extract, either a 32 bit multiply or a 40 bit accumulator. */
+
+static bu32
+extract_mult (SIM_CPU *cpu, bu64 res, int mmod, int MM,
+ int fullword, bu32 *overflow)
+{
+ if (fullword)
+ switch (mmod)
+ {
+ case 0:
+ case M_IS:
+ return saturate_s32 (res, overflow);
+ case M_FU:
+ if (MM)
+ return saturate_s32 (res, overflow);
+ return saturate_u32 (res, overflow);
+ case M_S2RND:
+ case M_ISS2:
+ return saturate_s32 (res << 1, overflow);
+ default:
+ illegal_instruction (cpu);
+ }
+ else
+ switch (mmod)
+ {
+ case 0:
+ case M_W32:
+ return saturate_s16 (rnd16 (res), overflow);
+ case M_IH:
+ return saturate_s32 (rnd16 (res), overflow) & 0xFFFF;
+ case M_IS:
+ return saturate_s16 (res, overflow);
+ case M_FU:
+ if (MM)
+ return saturate_s16 (rnd16 (res), overflow);
+ return saturate_u16 (rnd16 (res), overflow);
+ case M_IU:
+ if (MM)
+ return saturate_s16 (res, overflow);
+ return saturate_u16 (res, overflow);
+
+ case M_T:
+ return saturate_s16 (trunc16 (res), overflow);
+ case M_TFU:
+ return saturate_u16 (trunc16 (res), overflow);
+
+ case M_S2RND:
+ return saturate_s16 (rnd16 (res << 1), overflow);
+ case M_ISS2:
+ return saturate_s16 (res << 1, overflow);
+ default:
+ illegal_instruction (cpu);
+ }
+}
+
+static bu32
+decode_macfunc (SIM_CPU *cpu, int which, int op, int h0, int h1, int src0,
+ int src1, int mmod, int MM, int fullword, bu32 *overflow)
+{
+ bu64 acc;
+ bu32 sat = 0, tsat;
+
+ /* Sign extend accumulator if necessary, otherwise unsigned. */
+ if (mmod == 0 || mmod == M_T || mmod == M_IS || mmod == M_ISS2
+ || mmod == M_S2RND || mmod == M_IH || mmod == M_W32)
+ acc = get_extended_acc (cpu, which);
+ else
+ acc = get_unextended_acc (cpu, which);
+
+ if (MM && (mmod == M_T || mmod == M_IS || mmod == M_ISS2
+ || mmod == M_S2RND || mmod == M_IH || mmod == M_W32))
+ acc |= -(acc & 0x80000000);
+
+ if (op != 3)
+ {
+ bu8 sgn0 = (acc >> 31) & 1;
+ /* This can't saturate, so we don't keep track of the sat flag. */
+ bu64 res = decode_multfunc (cpu, h0, h1, src0, src1, mmod,
+ MM, &tsat);
+
+ /* Perform accumulation. */
+ switch (op)
+ {
+ case 0:
+ acc = res;
+ sgn0 = (acc >> 31) & 1;
+ break;
+ case 1:
+ acc = acc + res;
+ break;
+ case 2:
+ acc = acc - res;
+ break;
+ }
+
+ /* Saturate. */
+ switch (mmod)
+ {
+ case 0:
+ case M_T:
+ case M_IS:
+ case M_ISS2:
+ case M_S2RND:
+ if ((bs64)acc < -((bs64)1 << 39))
+ acc = -((bu64)1 << 39), sat = 1;
+ else if ((bs64)acc > 0x7fffffffffll)
+ acc = 0x7fffffffffull, sat = 1;
+ break;
+ case M_TFU:
+ if (!MM && acc > 0xFFFFFFFFFFull)
+ acc = 0x0, sat = 1;
+ if (MM && acc > 0xFFFFFFFF)
+ acc &= 0xFFFFFFFF;
+ break;
+ case M_IU:
+ if (acc & 0x8000000000000000ull)
+ acc = 0x0, sat = 1;
+ if (acc > 0xFFFFFFFFFFull)
+ acc &= 0xFFFFFFFFFFull, sat = 1;
+ if (MM && acc > 0xFFFFFFFF)
+ acc &= 0xFFFFFFFF;
+ if (acc & 0x80000000)
+ acc |= 0xffffffff00000000ull;
+ break;
+ case M_FU:
+ if (!MM && (bs64)acc < 0)
+ acc = 0x0, sat = 1;
+ if (MM && (bs64)acc < -((bs64)1 << 39))
+ acc = -((bu64)1 << 39), sat = 1;
+ if (!MM && (bs64)acc > (bs64)0xFFFFFFFFFFll)
+ acc = 0xFFFFFFFFFFull, sat = 1;
+ if (MM && acc > 0xFFFFFFFFFFull)
+ acc &= 0xFFFFFFFFFFull;
+ if (MM && acc & 0x80000000)
+ acc |= 0xffffffff00000000ull;
+ break;
+ case M_IH:
+ if ((bs64)acc < -0x80000000ll)
+ acc = -0x80000000ull, sat = 1;
+ else if ((bs64)acc >= 0x7fffffffll)
+ acc = 0x7fffffffull, sat = 1;
+ break;
+ case M_W32:
+ if (sgn0 && (sgn0 != ((acc >> 31) & 1))
+ && (((acc >> 32) & 0xFF) == 0xff))
+ acc = 0x80000000;
+ acc &= 0xffffffff;
+ if (acc & 0x80000000)
+ acc |= 0xffffffff00000000ull;
+ break;
+ default:
+ illegal_instruction (cpu);
+ }
+ }
+
+ STORE (AXREG (which), (acc >> 32) & 0xff);
+ STORE (AWREG (which), acc & 0xffffffff);
+ STORE (ASTATREG (av[which]), sat);
+ if (sat)
+ STORE (ASTATREG (avs[which]), sat);
+
+ return extract_mult (cpu, acc, mmod, MM, fullword, overflow);
+}
+
+bu32
+hwloop_get_next_pc (SIM_CPU *cpu, bu32 pc, bu32 insn_len)
+{
+ int i;
+
+ if (insn_len == 0)
+ return pc;
+
+ /* If our PC has reached the bottom of a hardware loop,
+ move back up to the top of the hardware loop. */
+ for (i = 1; i >= 0; --i)
+ if (LCREG (i) > 1 && pc == LBREG (i))
+ {
+ TRACE_BRANCH (cpu, pc, LTREG (i), i, "Hardware loop %i", i);
+ return LTREG (i);
+ }
+
+ return pc + insn_len;
+}
+
+static void
+decode_ProgCtrl_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
+{
+ /* ProgCtrl
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.prgfunc.......|.poprnd........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int poprnd = ((iw0 >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask);
+ int prgfunc = ((iw0 >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask);
+
+ TRACE_EXTRACT (cpu, "%s: poprnd:%i prgfunc:%i", __func__, poprnd, prgfunc);
+
+ if (prgfunc == 0 && poprnd == 0)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_nop);
+ TRACE_INSN (cpu, "NOP;");
+ }
+ else if (prgfunc == 1 && poprnd == 0)
+ {
+ bu32 newpc = RETSREG;
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "RTS;");
+ IFETCH_CHECK (newpc);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ TRACE_BRANCH (cpu, pc, newpc, -1, "RTS");
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 1 && poprnd == 1)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "RTI;");
+ /* Do not do IFETCH_CHECK here -- LSB has special meaning. */
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_return (cpu, -1);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 1 && poprnd == 2)
+ {
+ bu32 newpc = RETXREG;
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "RTX;");
+ /* XXX: Not sure if this is what the hardware does. */
+ IFETCH_CHECK (newpc);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_return (cpu, IVG_EVX);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 1 && poprnd == 3)
+ {
+ bu32 newpc = RETNREG;
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "RTN;");
+ /* XXX: Not sure if this is what the hardware does. */
+ IFETCH_CHECK (newpc);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_return (cpu, IVG_NMI);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 1 && poprnd == 4)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "RTE;");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_return (cpu, IVG_EMU);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 2 && poprnd == 0)
+ {
+ SIM_DESC sd = CPU_STATE (cpu);
+ sim_events *events = STATE_EVENTS (sd);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
+ /* XXX: in supervisor mode, utilizes wake up sources
+ in user mode, it's a NOP ... */
+ TRACE_INSN (cpu, "IDLE;");
+
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ /* Timewarp ! */
+ if (events->queue)
+ CYCLE_DELAY = events->time_from_event;
+ else
+ abort (); /* XXX: Should this ever happen ? */
+ }
+ else if (prgfunc == 2 && poprnd == 3)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
+ /* Just NOP it. */
+ TRACE_INSN (cpu, "CSYNC;");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ CYCLE_DELAY = 10;
+ }
+ else if (prgfunc == 2 && poprnd == 4)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_sync);
+ /* Just NOP it. */
+ TRACE_INSN (cpu, "SSYNC;");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ /* Really 10+, but no model info for this. */
+ CYCLE_DELAY = 10;
+ }
+ else if (prgfunc == 2 && poprnd == 5)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
+ TRACE_INSN (cpu, "EMUEXCPT;");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_exception (cpu, VEC_SIM_TRAP);
+ }
+ else if (prgfunc == 3 && poprnd < 8)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
+ TRACE_INSN (cpu, "CLI R%i;", poprnd);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (poprnd, cec_cli (cpu));
+ }
+ else if (prgfunc == 4 && poprnd < 8)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
+ TRACE_INSN (cpu, "STI R%i;", poprnd);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_sti (cpu, DREG (poprnd));
+ CYCLE_DELAY = 3;
+ }
+ else if (prgfunc == 5 && poprnd < 8)
+ {
+ bu32 newpc = PREG (poprnd);
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "JUMP (%s);", get_preg_name (poprnd));
+ IFETCH_CHECK (newpc);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (Preg)");
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ PROFILE_BRANCH_TAKEN (cpu);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 6 && poprnd < 8)
+ {
+ bu32 newpc = PREG (poprnd);
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "CALL (%s);", get_preg_name (poprnd));
+ IFETCH_CHECK (newpc);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (Preg)");
+ /* If we're at the end of a hardware loop, RETS is going to be
+ the top of the loop rather than the next instruction. */
+ SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ PROFILE_BRANCH_TAKEN (cpu);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 7 && poprnd < 8)
+ {
+ bu32 newpc = pc + PREG (poprnd);
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "CALL (PC + %s);", get_preg_name (poprnd));
+ IFETCH_CHECK (newpc);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (PC + Preg)");
+ SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ PROFILE_BRANCH_TAKEN (cpu);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 8 && poprnd < 8)
+ {
+ bu32 newpc = pc + PREG (poprnd);
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_branch);
+ TRACE_INSN (cpu, "JUMP (PC + %s);", get_preg_name (poprnd));
+ IFETCH_CHECK (newpc);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (PC + Preg)");
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ PROFILE_BRANCH_TAKEN (cpu);
+ CYCLE_DELAY = 5;
+ }
+ else if (prgfunc == 9)
+ {
+ int raise = uimm4 (poprnd);
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
+ TRACE_INSN (cpu, "RAISE %s;", uimm4_str (raise));
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_require_supervisor (cpu);
+ if (raise == IVG_IVHW)
+ cec_hwerr (cpu, HWERR_RAISE_5);
+ else
+ cec_latch (cpu, raise);
+ CYCLE_DELAY = 3; /* XXX: Only if IVG is unmasked. */
+ }
+ else if (prgfunc == 10)
+ {
+ int excpt = uimm4 (poprnd);
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_cec);
+ TRACE_INSN (cpu, "EXCPT %s;", uimm4_str (excpt));
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ cec_exception (cpu, excpt);
+ CYCLE_DELAY = 3;
+ }
+ else if (prgfunc == 11 && poprnd < 6)
+ {
+ bu32 addr = PREG (poprnd);
+ bu8 byte;
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ProgCtrl_atomic);
+ TRACE_INSN (cpu, "TESTSET (%s);", get_preg_name (poprnd));
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ byte = GET_WORD (addr);
+ SET_CCREG (byte == 0);
+ PUT_BYTE (addr, byte | 0x80);
+ /* Also includes memory stalls, but we don't model that. */
+ CYCLE_DELAY = 2;
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_CaCTRL_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* CaCTRL
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int a = ((iw0 >> CaCTRL_a_bits) & CaCTRL_a_mask);
+ int op = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask);
+ int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask);
+ bu32 preg = PREG (reg);
+ const char * const sinsn[] = { "PREFETCH", "FLUSHINV", "FLUSH", "IFLUSH", };
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CaCTRL);
+ TRACE_EXTRACT (cpu, "%s: a:%i op:%i reg:%i", __func__, a, op, reg);
+ TRACE_INSN (cpu, "%s [%s%s];", sinsn[op], get_preg_name (reg), a ? "++" : "");
+
+ if (INSN_LEN == 8)
+ /* None of these can be part of a parallel instruction. */
+ illegal_instruction_combination (cpu);
+
+ /* No cache simulation, so these are (mostly) all NOPs.
+ XXX: The hardware takes care of masking to cache lines, but need
+ to check behavior of the post increment. Should we be aligning
+ the value to the cache line before adding the cache line size, or
+ do we just add the cache line size ? */
+ if (op == 0)
+ { /* PREFETCH */
+ mmu_check_cache_addr (cpu, preg, false, false);
+ }
+ else if (op == 1)
+ { /* FLUSHINV */
+ mmu_check_cache_addr (cpu, preg, true, false);
+ }
+ else if (op == 2)
+ { /* FLUSH */
+ mmu_check_cache_addr (cpu, preg, true, false);
+ }
+ else if (op == 3)
+ { /* IFLUSH */
+ mmu_check_cache_addr (cpu, preg, false, true);
+ }
+
+ if (a)
+ SET_PREG (reg, preg + BFIN_L1_CACHE_BYTES);
+}
+
+static void
+decode_PushPopReg_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* PushPopReg
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.W.|.grp.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int W = ((iw0 >> PushPopReg_W_bits) & PushPopReg_W_mask);
+ int grp = ((iw0 >> PushPopReg_grp_bits) & PushPopReg_grp_mask);
+ int reg = ((iw0 >> PushPopReg_reg_bits) & PushPopReg_reg_mask);
+ const char *reg_name = get_allreg_name (grp, reg);
+ bu32 value;
+ bu32 sp = SPREG;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopReg);
+ TRACE_EXTRACT (cpu, "%s: W:%i grp:%i reg:%i", __func__, W, grp, reg);
+ TRACE_DECODE (cpu, "%s: reg:%s", __func__, reg_name);
+
+ /* Can't push/pop reserved registers */
+ if (reg_is_reserved (grp, reg))
+ illegal_instruction (cpu);
+
+ if (W == 0)
+ {
+ /* Dreg and Preg are not supported by this instruction. */
+ if (grp == 0 || grp == 1)
+ illegal_instruction (cpu);
+ TRACE_INSN (cpu, "%s = [SP++];", reg_name);
+ /* Can't pop USP while in userspace. */
+ if (INSN_LEN == 8 || (grp == 7 && reg == 0 && cec_is_user_mode(cpu)))
+ illegal_instruction_combination (cpu);
+ /* XXX: The valid register check is in reg_write(), so we might
+ incorrectly do a GET_LONG() here ... */
+ value = GET_LONG (sp);
+ reg_write (cpu, grp, reg, value);
+ if (grp == 7 && reg == 3)
+ cec_pop_reti (cpu);
+
+ sp += 4;
+ }
+ else
+ {
+ TRACE_INSN (cpu, "[--SP] = %s;", reg_name);
+ /* Can't push SP. */
+ if (INSN_LEN == 8 || (grp == 1 && reg == 6))
+ illegal_instruction_combination (cpu);
+
+ sp -= 4;
+ value = reg_read (cpu, grp, reg);
+ if (grp == 7 && reg == 3)
+ cec_push_reti (cpu);
+
+ PUT_LONG (sp, value);
+ }
+
+ /* Note: SP update must be delayed until after all reads/writes; see
+ comments in decode_PushPopMultiple_0() for more info. */
+ SET_SPREG (sp);
+}
+
+static void
+decode_PushPopMultiple_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* PushPopMultiple
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.d.|.p.|.W.|.dr........|.pr........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int p = ((iw0 >> PushPopMultiple_p_bits) & PushPopMultiple_p_mask);
+ int d = ((iw0 >> PushPopMultiple_d_bits) & PushPopMultiple_d_mask);
+ int W = ((iw0 >> PushPopMultiple_W_bits) & PushPopMultiple_W_mask);
+ int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask);
+ int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask);
+ int i;
+ bu32 sp = SPREG;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PushPopMultiple);
+ TRACE_EXTRACT (cpu, "%s: d:%i p:%i W:%i dr:%i pr:%i",
+ __func__, d, p, W, dr, pr);
+
+ if ((d == 0 && p == 0) || (p && imm5 (pr) > 5)
+ || (d && !p && pr) || (p && !d && dr))
+ illegal_instruction (cpu);
+
+ if (W == 1)
+ {
+ if (d && p)
+ TRACE_INSN (cpu, "[--SP] = (R7:%i, P5:%i);", dr, pr);
+ else if (d)
+ TRACE_INSN (cpu, "[--SP] = (R7:%i);", dr);
+ else
+ TRACE_INSN (cpu, "[--SP] = (P5:%i);", pr);
+
+ if (d)
+ for (i = dr; i < 8; i++)
+ {
+ sp -= 4;
+ PUT_LONG (sp, DREG (i));
+ }
+ if (p)
+ for (i = pr; i < 6; i++)
+ {
+ sp -= 4;
+ PUT_LONG (sp, PREG (i));
+ }
+
+ CYCLE_DELAY = 14;
+ }
+ else
+ {
+ if (d && p)
+ TRACE_INSN (cpu, "(R7:%i, P5:%i) = [SP++];", dr, pr);
+ else if (d)
+ TRACE_INSN (cpu, "(R7:%i) = [SP++];", dr);
+ else
+ TRACE_INSN (cpu, "(P5:%i) = [SP++];", pr);
+
+ if (p)
+ for (i = 5; i >= pr; i--)
+ {
+ SET_PREG (i, GET_LONG (sp));
+ sp += 4;
+ }
+ if (d)
+ for (i = 7; i >= dr; i--)
+ {
+ SET_DREG (i, GET_LONG (sp));
+ sp += 4;
+ }
+
+ CYCLE_DELAY = 11;
+ }
+
+ /* Note: SP update must be delayed until after all reads/writes so that
+ if an exception does occur, the insn may be re-executed as the
+ SP has not yet changed. */
+ SET_SPREG (sp);
+}
+
+static void
+decode_ccMV_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* ccMV
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.T.|.d.|.s.|.dst.......|.src.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int s = ((iw0 >> CCmv_s_bits) & CCmv_s_mask);
+ int d = ((iw0 >> CCmv_d_bits) & CCmv_d_mask);
+ int T = ((iw0 >> CCmv_T_bits) & CCmv_T_mask);
+ int src = ((iw0 >> CCmv_src_bits) & CCmv_src_mask);
+ int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask);
+ int cond = T ? CCREG : ! CCREG;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ccMV);
+ TRACE_EXTRACT (cpu, "%s: T:%i d:%i s:%i dst:%i src:%i",
+ __func__, T, d, s, dst, src);
+
+ TRACE_INSN (cpu, "IF %sCC %s = %s;", T ? "" : "! ",
+ get_allreg_name (d, dst),
+ get_allreg_name (s, src));
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ if (cond)
+ reg_write (cpu, d, dst, reg_read (cpu, s, src));
+}
+
+static void
+decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* CCflag
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 1 |.I.|.opc.......|.G.|.y.........|.x.........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int x = ((iw0 >> CCflag_x_bits) & CCflag_x_mask);
+ int y = ((iw0 >> CCflag_y_bits) & CCflag_y_mask);
+ int I = ((iw0 >> CCflag_I_bits) & CCflag_I_mask);
+ int G = ((iw0 >> CCflag_G_bits) & CCflag_G_mask);
+ int opc = ((iw0 >> CCflag_opc_bits) & CCflag_opc_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CCflag);
+ TRACE_EXTRACT (cpu, "%s: I:%i opc:%i G:%i y:%i x:%i",
+ __func__, I, opc, G, y, x);
+
+ if (opc > 4)
+ {
+ bs64 acc0 = get_extended_acc (cpu, 0);
+ bs64 acc1 = get_extended_acc (cpu, 1);
+ bs64 diff = acc0 - acc1;
+
+ if (x != 0 || y != 0)
+ illegal_instruction (cpu);
+
+ if (opc == 5 && I == 0 && G == 0)
+ {
+ TRACE_INSN (cpu, "CC = A0 == A1;");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_CCREG (acc0 == acc1);
+ }
+ else if (opc == 6 && I == 0 && G == 0)
+ {
+ TRACE_INSN (cpu, "CC = A0 < A1");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_CCREG (acc0 < acc1);
+ }
+ else if (opc == 7 && I == 0 && G == 0)
+ {
+ TRACE_INSN (cpu, "CC = A0 <= A1");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_CCREG (acc0 <= acc1);
+ }
+ else
+ illegal_instruction (cpu);
+
+ SET_ASTATREG (az, diff == 0);
+ SET_ASTATREG (an, diff < 0);
+ SET_ASTATREG (ac0, (bu40)acc1 <= (bu40)acc0);
+ }
+ else
+ {
+ int issigned = opc < 3;
+ const char *sign = issigned ? "" : " (IU)";
+ bu32 srcop = G ? PREG (x) : DREG (x);
+ char s = G ? 'P' : 'R';
+ bu32 dstop = I ? (issigned ? imm3 (y) : uimm3 (y)) : G ? PREG (y) : DREG (y);
+ const char *op;
+ char d = G ? 'P' : 'R';
+ int flgs = srcop >> 31;
+ int flgo = dstop >> 31;
+
+ bu32 result = srcop - dstop;
+ int cc;
+ int flgn = result >> 31;
+ int overflow = (flgs ^ flgo) & (flgn ^ flgs);
+ int az = result == 0;
+ int ac0 = dstop <= srcop;
+ int an;
+ if (issigned)
+ an = (flgn && !overflow) || (!flgn && overflow);
+ else
+ an = dstop > srcop;
+
+ switch (opc)
+ {
+ default: /* Shutup useless gcc warnings. */
+ case 0: /* signed */
+ op = "==";
+ cc = az;
+ break;
+ case 1: /* signed */
+ op = "<";
+ cc = an;
+ break;
+ case 2: /* signed */
+ op = "<=";
+ cc = an || az;
+ break;
+ case 3: /* unsigned */
+ op = "<";
+ cc = !ac0;
+ break;
+ case 4: /* unsigned */
+ op = "<=";
+ cc = !ac0 || az;
+ break;
+ }
+
+ if (I)
+ TRACE_INSN (cpu, "CC = %c%i %s %s%s;", s, x, op,
+ issigned ? imm3_str (y) : uimm3_str (y), sign);
+ else
+ {
+ TRACE_DECODE (cpu, "%s %c%i:%x %c%i:%x", __func__,
+ s, x, srcop, d, y, dstop);
+ TRACE_INSN (cpu, "CC = %c%i %s %c%i%s;", s, x, op, d, y, sign);
+ }
+
+ SET_CCREG (cc);
+ /* Pointer compares only touch CC. */
+ if (!G)
+ {
+ SET_ASTATREG (az, az);
+ SET_ASTATREG (an, an);
+ SET_ASTATREG (ac0, ac0);
+ }
+ }
+}
+
+static void
+decode_CC2dreg_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* CC2dreg
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask);
+ int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2dreg);
+ TRACE_EXTRACT (cpu, "%s: op:%i reg:%i", __func__, op, reg);
+
+ if (op == 0)
+ {
+ TRACE_INSN (cpu, "R%i = CC;", reg);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (reg, CCREG);
+ }
+ else if (op == 1)
+ {
+ TRACE_INSN (cpu, "CC = R%i;", reg);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_CCREG (DREG (reg) != 0);
+ }
+ else if (op == 3 && reg == 0)
+ {
+ TRACE_INSN (cpu, "CC = !CC;");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_CCREG (!CCREG);
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_CC2stat_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* CC2stat
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int D = ((iw0 >> CC2stat_D_bits) & CC2stat_D_mask);
+ int op = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask);
+ int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask);
+ bu32 pval;
+
+ const char * const op_names[] = { "", "|", "&", "^" } ;
+ const char *astat_name;
+ const char * const astat_names[32] = {
+ [ 0] = "AZ",
+ [ 1] = "AN",
+ [ 2] = "AC0_COPY",
+ [ 3] = "V_COPY",
+ [ 5] = "CC",
+ [ 6] = "AQ",
+ [ 8] = "RND_MOD",
+ [12] = "AC0",
+ [13] = "AC1",
+ [16] = "AV0",
+ [17] = "AV0S",
+ [18] = "AV1",
+ [19] = "AV1S",
+ [24] = "V",
+ [25] = "VS",
+ };
+ astat_name = astat_names[cbit];
+ if (!astat_name)
+ {
+ static char astat_bit[12];
+ sprintf (astat_bit, "ASTAT[%i]", cbit);
+ astat_name = astat_bit;
+ }
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CC2stat);
+ TRACE_EXTRACT (cpu, "%s: D:%i op:%i cbit:%i", __func__, D, op, cbit);
+
+ TRACE_INSN (cpu, "%s %s= %s;", D ? astat_name : "CC",
+ op_names[op], D ? "CC" : astat_name);
+
+ /* CC = CC; is invalid. */
+ if (cbit == 5)
+ illegal_instruction (cpu);
+
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ pval = !!(ASTAT & (1 << cbit));
+ if (D == 0)
+ switch (op)
+ {
+ case 0: SET_CCREG (pval); break;
+ case 1: SET_CCREG (CCREG | pval); break;
+ case 2: SET_CCREG (CCREG & pval); break;
+ case 3: SET_CCREG (CCREG ^ pval); break;
+ }
+ else
+ {
+ switch (op)
+ {
+ case 0: pval = CCREG; break;
+ case 1: pval |= CCREG; break;
+ case 2: pval &= CCREG; break;
+ case 3: pval ^= CCREG; break;
+ }
+ if (astat_names[cbit])
+ TRACE_REGISTER (cpu, "wrote ASTAT[%s] = %i", astat_name, pval);
+ else
+ TRACE_REGISTER (cpu, "wrote %s = %i", astat_name, pval);
+ SET_ASTAT ((ASTAT & ~(1 << cbit)) | (pval << cbit));
+ }
+}
+
+static void
+decode_BRCC_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
+{
+ /* BRCC
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 1 |.T.|.B.|.offset................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int B = ((iw0 >> BRCC_B_bits) & BRCC_B_mask);
+ int T = ((iw0 >> BRCC_T_bits) & BRCC_T_mask);
+ int offset = ((iw0 >> BRCC_offset_bits) & BRCC_offset_mask);
+ int cond = T ? CCREG : ! CCREG;
+ int pcrel = pcrel10 (offset);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_BRCC);
+ TRACE_EXTRACT (cpu, "%s: T:%i B:%i offset:%#x", __func__, T, B, offset);
+ TRACE_DECODE (cpu, "%s: pcrel10:%#x", __func__, pcrel);
+
+ TRACE_INSN (cpu, "IF %sCC JUMP %#x%s;", T ? "" : "! ",
+ pcrel, B ? " (bp)" : "");
+
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ if (cond)
+ {
+ bu32 newpc = pc + pcrel;
+ TRACE_BRANCH (cpu, pc, newpc, -1, "Conditional JUMP");
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ PROFILE_BRANCH_TAKEN (cpu);
+ CYCLE_DELAY = B ? 5 : 9;
+ }
+ else
+ {
+ PROFILE_BRANCH_UNTAKEN (cpu);
+ CYCLE_DELAY = B ? 9 : 1;
+ }
+}
+
+static void
+decode_UJUMP_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc)
+{
+ /* UJUMP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 1 | 0 |.offset........................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask);
+ int pcrel = pcrel12 (offset);
+ bu32 newpc = pc + pcrel;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_UJUMP);
+ TRACE_EXTRACT (cpu, "%s: offset:%#x", __func__, offset);
+ TRACE_DECODE (cpu, "%s: pcrel12:%#x", __func__, pcrel);
+
+ TRACE_INSN (cpu, "JUMP.S %#x;", pcrel);
+
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.S");
+
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ PROFILE_BRANCH_TAKEN (cpu);
+ CYCLE_DELAY = 5;
+}
+
+static void
+decode_REGMV_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* REGMV
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 1 | 1 |.gd........|.gs........|.dst.......|.src.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int gs = ((iw0 >> RegMv_gs_bits) & RegMv_gs_mask);
+ int gd = ((iw0 >> RegMv_gd_bits) & RegMv_gd_mask);
+ int src = ((iw0 >> RegMv_src_bits) & RegMv_src_mask);
+ int dst = ((iw0 >> RegMv_dst_bits) & RegMv_dst_mask);
+ const char *srcreg_name = get_allreg_name (gs, src);
+ const char *dstreg_name = get_allreg_name (gd, dst);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_REGMV);
+ TRACE_EXTRACT (cpu, "%s: gd:%i gs:%i dst:%i src:%i",
+ __func__, gd, gs, dst, src);
+ TRACE_DECODE (cpu, "%s: dst:%s src:%s", __func__, dstreg_name, srcreg_name);
+
+ TRACE_INSN (cpu, "%s = %s;", dstreg_name, srcreg_name);
+
+ /* Reserved slots cannot be a src/dst. */
+ if (reg_is_reserved (gs, src) || reg_is_reserved (gd, dst))
+ goto invalid_move;
+
+ /* Standard register moves. */
+ if ((gs < 2) /* Dregs/Pregs src */
+ || (gd < 2) /* Dregs/Pregs dst */
+ || (gs == 4 && src < 4) /* Accumulators src */
+ || (gd == 4 && dst < 4 && (gs < 4)) /* Accumulators dst */
+ || (gs == 7 && src == 7 && !(gd == 4 && dst < 4)) /* EMUDAT src */
+ || (gd == 7 && dst == 7)) /* EMUDAT dst */
+ goto valid_move;
+
+ /* dareg = dareg (IMBL) */
+ if (gs < 4 && gd < 4)
+ goto valid_move;
+
+ /* USP can be src to sysregs, but not dagregs. */
+ if ((gs == 7 && src == 0) && (gd >= 4))
+ goto valid_move;
+
+ /* USP can move between genregs (only check Accumulators). */
+ if (((gs == 7 && src == 0) && (gd == 4 && dst < 4))
+ || ((gd == 7 && dst == 0) && (gs == 4 && src < 4)))
+ goto valid_move;
+
+ /* Still here ? Invalid reg pair. */
+ invalid_move:
+ illegal_instruction (cpu);
+
+ valid_move:
+ reg_write (cpu, gd, dst, reg_read (cpu, gs, src));
+}
+
+static void
+decode_ALU2op_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* ALU2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> ALU2op_src_bits) & ALU2op_src_mask);
+ int opc = ((iw0 >> ALU2op_opc_bits) & ALU2op_opc_mask);
+ int dst = ((iw0 >> ALU2op_dst_bits) & ALU2op_dst_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ALU2op);
+ TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
+
+ if (opc == 0)
+ {
+ TRACE_INSN (cpu, "R%i >>>= R%i;", dst, src);
+ SET_DREG (dst, ashiftrt (cpu, DREG (dst), DREG (src), 32));
+ }
+ else if (opc == 1)
+ {
+ bu32 val;
+ TRACE_INSN (cpu, "R%i >>= R%i;", dst, src);
+ if (DREG (src) <= 0x1F)
+ val = lshiftrt (cpu, DREG (dst), DREG (src), 32);
+ else
+ val = 0;
+ SET_DREG (dst, val);
+ }
+ else if (opc == 2)
+ {
+ TRACE_INSN (cpu, "R%i <<= R%i;", dst, src);
+ SET_DREG (dst, lshift (cpu, DREG (dst), DREG (src), 32, 0));
+ }
+ else if (opc == 3)
+ {
+ TRACE_INSN (cpu, "R%i *= R%i;", dst, src);
+ SET_DREG (dst, DREG (dst) * DREG (src));
+ CYCLE_DELAY = 3;
+ }
+ else if (opc == 4)
+ {
+ TRACE_INSN (cpu, "R%i = (R%i + R%i) << 1;", dst, dst, src);
+ SET_DREG (dst, add_and_shift (cpu, DREG (dst), DREG (src), 1));
+ }
+ else if (opc == 5)
+ {
+ TRACE_INSN (cpu, "R%i = (R%i + R%i) << 2;", dst, dst, src);
+ SET_DREG (dst, add_and_shift (cpu, DREG (dst), DREG (src), 2));
+ }
+ else if (opc == 8)
+ {
+ TRACE_INSN (cpu, "DIVQ ( R%i, R%i );", dst, src);
+ SET_DREG (dst, divq (cpu, DREG (dst), (bu16)DREG (src)));
+ }
+ else if (opc == 9)
+ {
+ TRACE_INSN (cpu, "DIVS ( R%i, R%i );", dst, src);
+ SET_DREG (dst, divs (cpu, DREG (dst), (bu16)DREG (src)));
+ }
+ else if (opc == 10)
+ {
+ TRACE_INSN (cpu, "R%i = R%i.L (X);", dst, src);
+ SET_DREG (dst, (bs32) (bs16) DREG (src));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 11)
+ {
+ TRACE_INSN (cpu, "R%i = R%i.L (Z);", dst, src);
+ SET_DREG (dst, (bu32) (bu16) DREG (src));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 12)
+ {
+ TRACE_INSN (cpu, "R%i = R%i.B (X);", dst, src);
+ SET_DREG (dst, (bs32) (bs8) DREG (src));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 13)
+ {
+ TRACE_INSN (cpu, "R%i = R%i.B (Z);", dst, src);
+ SET_DREG (dst, (bu32) (bu8) DREG (src));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 14)
+ {
+ bu32 val = DREG (src);
+ TRACE_INSN (cpu, "R%i = - R%i;", dst, src);
+ SET_DREG (dst, -val);
+ setflags_nz (cpu, DREG (dst));
+ SET_ASTATREG (v, val == 0x80000000);
+ if (ASTATREG (v))
+ SET_ASTATREG (vs, 1);
+ SET_ASTATREG (ac0, val == 0x0);
+ /* XXX: Documentation isn't entirely clear about av0 and av1. */
+ }
+ else if (opc == 15)
+ {
+ TRACE_INSN (cpu, "R%i = ~ R%i;", dst, src);
+ SET_DREG (dst, ~DREG (src));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_PTR2op_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* PTR2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 0 | 1 | 0 |.opc.......|.src.......|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> PTR2op_src_bits) & PTR2op_dst_mask);
+ int opc = ((iw0 >> PTR2op_opc_bits) & PTR2op_opc_mask);
+ int dst = ((iw0 >> PTR2op_dst_bits) & PTR2op_dst_mask);
+ const char *src_name = get_preg_name (src);
+ const char *dst_name = get_preg_name (dst);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PTR2op);
+ TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
+
+ if (opc == 0)
+ {
+ TRACE_INSN (cpu, "%s -= %s", dst_name, src_name);
+ SET_PREG (dst, PREG (dst) - PREG (src));
+ }
+ else if (opc == 1)
+ {
+ TRACE_INSN (cpu, "%s = %s << 2", dst_name, src_name);
+ SET_PREG (dst, PREG (src) << 2);
+ }
+ else if (opc == 3)
+ {
+ TRACE_INSN (cpu, "%s = %s >> 2", dst_name, src_name);
+ SET_PREG (dst, PREG (src) >> 2);
+ }
+ else if (opc == 4)
+ {
+ TRACE_INSN (cpu, "%s = %s >> 1", dst_name, src_name);
+ SET_PREG (dst, PREG (src) >> 1);
+ }
+ else if (opc == 5)
+ {
+ TRACE_INSN (cpu, "%s += %s (BREV)", dst_name, src_name);
+ SET_PREG (dst, add_brev (PREG (dst), PREG (src)));
+ }
+ else if (opc == 6)
+ {
+ TRACE_INSN (cpu, "%s = (%s + %s) << 1", dst_name, dst_name, src_name);
+ SET_PREG (dst, (PREG (dst) + PREG (src)) << 1);
+ }
+ else if (opc == 7)
+ {
+ TRACE_INSN (cpu, "%s = (%s + %s) << 2", dst_name, dst_name, src_name);
+ SET_PREG (dst, (PREG (dst) + PREG (src)) << 2);
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_LOGI2op_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* LOGI2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 1 |.opc.......|.src...............|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> LOGI2op_src_bits) & LOGI2op_src_mask);
+ int opc = ((iw0 >> LOGI2op_opc_bits) & LOGI2op_opc_mask);
+ int dst = ((iw0 >> LOGI2op_dst_bits) & LOGI2op_dst_mask);
+ int uimm = uimm5 (src);
+ const char *uimm_str = uimm5_str (uimm);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LOGI2op);
+ TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst);
+ TRACE_DECODE (cpu, "%s: uimm5:%#x", __func__, uimm);
+
+ if (opc == 0)
+ {
+ TRACE_INSN (cpu, "CC = ! BITTST (R%i, %s);", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_CCREG ((~DREG (dst) >> uimm) & 1);
+ }
+ else if (opc == 1)
+ {
+ TRACE_INSN (cpu, "CC = BITTST (R%i, %s);", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_CCREG ((DREG (dst) >> uimm) & 1);
+ }
+ else if (opc == 2)
+ {
+ TRACE_INSN (cpu, "BITSET (R%i, %s);", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (dst, DREG (dst) | (1 << uimm));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 3)
+ {
+ TRACE_INSN (cpu, "BITTGL (R%i, %s);", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (dst, DREG (dst) ^ (1 << uimm));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 4)
+ {
+ TRACE_INSN (cpu, "BITCLR (R%i, %s);", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (dst, DREG (dst) & ~(1 << uimm));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 5)
+ {
+ TRACE_INSN (cpu, "R%i >>>= %s;", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (dst, ashiftrt (cpu, DREG (dst), uimm, 32));
+ }
+ else if (opc == 6)
+ {
+ TRACE_INSN (cpu, "R%i >>= %s;", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (dst, lshiftrt (cpu, DREG (dst), uimm, 32));
+ }
+ else if (opc == 7)
+ {
+ TRACE_INSN (cpu, "R%i <<= %s;", dst, uimm_str);
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_DREG (dst, lshift (cpu, DREG (dst), uimm, 32, 0));
+ }
+}
+
+static void
+decode_COMP3op_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* COMP3op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int opc = ((iw0 >> COMP3op_opc_bits) & COMP3op_opc_mask);
+ int dst = ((iw0 >> COMP3op_dst_bits) & COMP3op_dst_mask);
+ int src0 = ((iw0 >> COMP3op_src0_bits) & COMP3op_src0_mask);
+ int src1 = ((iw0 >> COMP3op_src1_bits) & COMP3op_src1_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMP3op);
+ TRACE_EXTRACT (cpu, "%s: opc:%i dst:%i src1:%i src0:%i",
+ __func__, opc, dst, src1, src0);
+
+ if (opc == 0)
+ {
+ TRACE_INSN (cpu, "R%i = R%i + R%i;", dst, src0, src1);
+ SET_DREG (dst, add32 (cpu, DREG (src0), DREG (src1), 1, 0));
+ }
+ else if (opc == 1)
+ {
+ TRACE_INSN (cpu, "R%i = R%i - R%i;", dst, src0, src1);
+ SET_DREG (dst, sub32 (cpu, DREG (src0), DREG (src1), 1, 0, 0));
+ }
+ else if (opc == 2)
+ {
+ TRACE_INSN (cpu, "R%i = R%i & R%i;", dst, src0, src1);
+ SET_DREG (dst, DREG (src0) & DREG (src1));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 3)
+ {
+ TRACE_INSN (cpu, "R%i = R%i | R%i;", dst, src0, src1);
+ SET_DREG (dst, DREG (src0) | DREG (src1));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else if (opc == 4)
+ {
+ TRACE_INSN (cpu, "R%i = R%i ^ R%i;", dst, src0, src1);
+ SET_DREG (dst, DREG (src0) ^ DREG (src1));
+ setflags_logical (cpu, DREG (dst));
+ }
+ else
+ {
+ int shift = opc - 5;
+ const char *dst_name = get_preg_name (dst);
+ const char *src0_name = get_preg_name (src0);
+ const char *src1_name = get_preg_name (src1);
+
+ /* If src0 == src1 this is disassembled as a shift by 1, but this
+ distinction doesn't matter for our purposes. */
+ if (shift)
+ TRACE_INSN (cpu, "%s = (%s + %s) << %#x;",
+ dst_name, src0_name, src1_name, shift);
+ else
+ TRACE_INSN (cpu, "%s = %s + %s",
+ dst_name, src0_name, src1_name);
+ SET_PREG (dst, PREG (src0) + (PREG (src1) << shift));
+ }
+}
+
+static void
+decode_COMPI2opD_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* COMPI2opD
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 1 | 0 | 0 |.op|..src......................|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> COMPI2opD_op_bits) & COMPI2opD_op_mask);
+ int dst = ((iw0 >> COMPI2opD_dst_bits) & COMPI2opD_dst_mask);
+ int src = ((iw0 >> COMPI2opD_src_bits) & COMPI2opD_src_mask);
+ int imm = imm7 (src);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opD);
+ TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst);
+ TRACE_DECODE (cpu, "%s: imm7:%#x", __func__, imm);
+
+ if (op == 0)
+ {
+ TRACE_INSN (cpu, "R%i = %s (X);", dst, imm7_str (imm));
+ SET_DREG (dst, imm);
+ }
+ else if (op == 1)
+ {
+ TRACE_INSN (cpu, "R%i += %s;", dst, imm7_str (imm));
+ SET_DREG (dst, add32 (cpu, DREG (dst), imm, 1, 0));
+ }
+}
+
+static void
+decode_COMPI2opP_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* COMPI2opP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> COMPI2opP_op_bits) & COMPI2opP_op_mask);
+ int src = ((iw0 >> COMPI2opP_src_bits) & COMPI2opP_src_mask);
+ int dst = ((iw0 >> COMPI2opP_dst_bits) & COMPI2opP_dst_mask);
+ int imm = imm7 (src);
+ const char *dst_name = get_preg_name (dst);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_COMPI2opP);
+ TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst);
+ TRACE_DECODE (cpu, "%s: imm:%#x", __func__, imm);
+
+ if (op == 0)
+ {
+ TRACE_INSN (cpu, "%s = %s;", dst_name, imm7_str (imm));
+ SET_PREG (dst, imm);
+ }
+ else if (op == 1)
+ {
+ TRACE_INSN (cpu, "%s += %s;", dst_name, imm7_str (imm));
+ SET_PREG (dst, PREG (dst) + imm);
+ }
+}
+
+static void
+decode_LDSTpmod_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* LDSTpmod
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
+ int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
+ int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
+ int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
+ int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
+ const char *ptr_name = get_preg_name (ptr);
+ const char *idx_name = get_preg_name (idx);
+ bu32 addr, val;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTpmod);
+ TRACE_EXTRACT (cpu, "%s: W:%i aop:%i reg:%i idx:%i ptr:%i",
+ __func__, W, aop, reg, idx, ptr);
+
+ if (aop == 1 && W == 0 && idx == ptr)
+ {
+ TRACE_INSN (cpu, "R%i.L = W[%s];", reg, ptr_name);
+ addr = PREG (ptr);
+ val = GET_WORD (addr);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val);
+ }
+ else if (aop == 2 && W == 0 && idx == ptr)
+ {
+ TRACE_INSN (cpu, "R%i.H = W[%s];", reg, ptr_name);
+ addr = PREG (ptr);
+ val = GET_WORD (addr);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (val << 16));
+ }
+ else if (aop == 1 && W == 1 && idx == ptr)
+ {
+ TRACE_INSN (cpu, "W[%s] = R%i.L;", ptr_name, reg);
+ addr = PREG (ptr);
+ PUT_WORD (addr, DREG (reg));
+ }
+ else if (aop == 2 && W == 1 && idx == ptr)
+ {
+ TRACE_INSN (cpu, "W[%s] = R%i.H;", ptr_name, reg);
+ addr = PREG (ptr);
+ PUT_WORD (addr, DREG (reg) >> 16);
+ }
+ else if (aop == 0 && W == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [%s ++ %s];", reg, ptr_name, idx_name);
+ addr = PREG (ptr);
+ val = GET_LONG (addr);
+ STORE (DREG (reg), val);
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else if (aop == 1 && W == 0)
+ {
+ TRACE_INSN (cpu, "R%i.L = W[%s ++ %s];", reg, ptr_name, idx_name);
+ addr = PREG (ptr);
+ val = GET_WORD (addr);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | val);
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else if (aop == 2 && W == 0)
+ {
+ TRACE_INSN (cpu, "R%i.H = W[%s ++ %s];", reg, ptr_name, idx_name);
+ addr = PREG (ptr);
+ val = GET_WORD (addr);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (val << 16));
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else if (aop == 3 && W == 0)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s ++ %s] (Z);", reg, ptr_name, idx_name);
+ addr = PREG (ptr);
+ val = GET_WORD (addr);
+ STORE (DREG (reg), val);
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else if (aop == 3 && W == 1)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s ++ %s] (X);", reg, ptr_name, idx_name);
+ addr = PREG (ptr);
+ val = GET_WORD (addr);
+ STORE (DREG (reg), (bs32) (bs16) val);
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else if (aop == 0 && W == 1)
+ {
+ TRACE_INSN (cpu, "[%s ++ %s] = R%i;", ptr_name, idx_name, reg);
+ addr = PREG (ptr);
+ PUT_LONG (addr, DREG (reg));
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else if (aop == 1 && W == 1)
+ {
+ TRACE_INSN (cpu, "W[%s ++ %s] = R%i.L;", ptr_name, idx_name, reg);
+ addr = PREG (ptr);
+ PUT_WORD (addr, DREG (reg));
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else if (aop == 2 && W == 1)
+ {
+ TRACE_INSN (cpu, "W[%s ++ %s] = R%i.H;", ptr_name, idx_name, reg);
+ addr = PREG (ptr);
+ PUT_WORD (addr, DREG (reg) >> 16);
+ if (ptr != idx)
+ STORE (PREG (ptr), addr + PREG (idx));
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_dagMODim_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* dagMODim
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
+ int m = ((iw0 >> DagMODim_m_bits) & DagMODim_m_mask);
+ int br = ((iw0 >> DagMODim_br_bits) & DagMODim_br_mask);
+ int op = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODim);
+ TRACE_EXTRACT (cpu, "%s: br:%i op:%i m:%i i:%i", __func__, br, op, m, i);
+
+ if (op == 0 && br == 1)
+ {
+ TRACE_INSN (cpu, "I%i += M%i (BREV);", i, m);
+ SET_IREG (i, add_brev (IREG (i), MREG (m)));
+ }
+ else if (op == 0)
+ {
+ TRACE_INSN (cpu, "I%i += M%i;", i, m);
+ dagadd (cpu, i, MREG (m));
+ }
+ else if (op == 1 && br == 0)
+ {
+ TRACE_INSN (cpu, "I%i -= M%i;", i, m);
+ dagsub (cpu, i, MREG (m));
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_dagMODik_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* dagMODik
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
+ int op = ((iw0 >> DagMODik_op_bits) & DagMODik_op_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODik);
+ TRACE_EXTRACT (cpu, "%s: op:%i i:%i", __func__, op, i);
+
+ if (op == 0)
+ {
+ TRACE_INSN (cpu, "I%i += 2;", i);
+ dagadd (cpu, i, 2);
+ }
+ else if (op == 1)
+ {
+ TRACE_INSN (cpu, "I%i -= 2;", i);
+ dagsub (cpu, i, 2);
+ }
+ else if (op == 2)
+ {
+ TRACE_INSN (cpu, "I%i += 4;", i);
+ dagadd (cpu, i, 4);
+ }
+ else if (op == 3)
+ {
+ TRACE_INSN (cpu, "I%i -= 4;", i);
+ dagsub (cpu, i, 4);
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_dspLDST_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* dspLDST
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
+ int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
+ int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
+ int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
+ int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
+ bu32 addr;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dspLDST);
+ TRACE_EXTRACT (cpu, "%s: aop:%i m:%i i:%i reg:%i", __func__, aop, m, i, reg);
+
+ if (aop == 0 && W == 0 && m == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [I%i++];", reg, i);
+ addr = IREG (i);
+ if (DIS_ALGN_EXPT & 0x1)
+ addr &= ~3;
+ dagadd (cpu, i, 4);
+ STORE (DREG (reg), GET_LONG (addr));
+ }
+ else if (aop == 0 && W == 0 && m == 1)
+ {
+ TRACE_INSN (cpu, "R%i.L = W[I%i++];", reg, i);
+ addr = IREG (i);
+ dagadd (cpu, i, 2);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
+ }
+ else if (aop == 0 && W == 0 && m == 2)
+ {
+ TRACE_INSN (cpu, "R%i.H = W[I%i++];", reg, i);
+ addr = IREG (i);
+ dagadd (cpu, i, 2);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
+ }
+ else if (aop == 1 && W == 0 && m == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [I%i--];", reg, i);
+ addr = IREG (i);
+ if (DIS_ALGN_EXPT & 0x1)
+ addr &= ~3;
+ dagsub (cpu, i, 4);
+ STORE (DREG (reg), GET_LONG (addr));
+ }
+ else if (aop == 1 && W == 0 && m == 1)
+ {
+ TRACE_INSN (cpu, "R%i.L = W[I%i--];", reg, i);
+ addr = IREG (i);
+ dagsub (cpu, i, 2);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
+ }
+ else if (aop == 1 && W == 0 && m == 2)
+ {
+ TRACE_INSN (cpu, "R%i.H = W[I%i--];", reg, i);
+ addr = IREG (i);
+ dagsub (cpu, i, 2);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
+ }
+ else if (aop == 2 && W == 0 && m == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [I%i];", reg, i);
+ addr = IREG (i);
+ if (DIS_ALGN_EXPT & 0x1)
+ addr &= ~3;
+ STORE (DREG (reg), GET_LONG (addr));
+ }
+ else if (aop == 2 && W == 0 && m == 1)
+ {
+ TRACE_INSN (cpu, "R%i.L = W[I%i];", reg, i);
+ addr = IREG (i);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF0000) | GET_WORD (addr));
+ }
+ else if (aop == 2 && W == 0 && m == 2)
+ {
+ TRACE_INSN (cpu, "R%i.H = W[I%i];", reg, i);
+ addr = IREG (i);
+ STORE (DREG (reg), (DREG (reg) & 0xFFFF) | (GET_WORD (addr) << 16));
+ }
+ else if (aop == 0 && W == 1 && m == 0)
+ {
+ TRACE_INSN (cpu, "[I%i++] = R%i;", i, reg);
+ addr = IREG (i);
+ dagadd (cpu, i, 4);
+ PUT_LONG (addr, DREG (reg));
+ }
+ else if (aop == 0 && W == 1 && m == 1)
+ {
+ TRACE_INSN (cpu, "W[I%i++] = R%i.L;", i, reg);
+ addr = IREG (i);
+ dagadd (cpu, i, 2);
+ PUT_WORD (addr, DREG (reg));
+ }
+ else if (aop == 0 && W == 1 && m == 2)
+ {
+ TRACE_INSN (cpu, "W[I%i++] = R%i.H;", i, reg);
+ addr = IREG (i);
+ dagadd (cpu, i, 2);
+ PUT_WORD (addr, DREG (reg) >> 16);
+ }
+ else if (aop == 1 && W == 1 && m == 0)
+ {
+ TRACE_INSN (cpu, "[I%i--] = R%i;", i, reg);
+ addr = IREG (i);
+ dagsub (cpu, i, 4);
+ PUT_LONG (addr, DREG (reg));
+ }
+ else if (aop == 1 && W == 1 && m == 1)
+ {
+ TRACE_INSN (cpu, "W[I%i--] = R%i.L;", i, reg);
+ addr = IREG (i);
+ dagsub (cpu, i, 2);
+ PUT_WORD (addr, DREG (reg));
+ }
+ else if (aop == 1 && W == 1 && m == 2)
+ {
+ TRACE_INSN (cpu, "W[I%i--] = R%i.H;", i, reg);
+ addr = IREG (i);
+ dagsub (cpu, i, 2);
+ PUT_WORD (addr, DREG (reg) >> 16);
+ }
+ else if (aop == 2 && W == 1 && m == 0)
+ {
+ TRACE_INSN (cpu, "[I%i] = R%i;", i, reg);
+ addr = IREG (i);
+ PUT_LONG (addr, DREG (reg));
+ }
+ else if (aop == 2 && W == 1 && m == 1)
+ {
+ TRACE_INSN (cpu, "W[I%i] = R%i.L;", i, reg);
+ addr = IREG (i);
+ PUT_WORD (addr, DREG (reg));
+ }
+ else if (aop == 2 && W == 1 && m == 2)
+ {
+ TRACE_INSN (cpu, "W[I%i] = R%i.H;", i, reg);
+ addr = IREG (i);
+ PUT_WORD (addr, DREG (reg) >> 16);
+ }
+ else if (aop == 3 && W == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [I%i ++ M%i];", reg, i, m);
+ addr = IREG (i);
+ if (DIS_ALGN_EXPT & 0x1)
+ addr &= ~3;
+ dagadd (cpu, i, MREG (m));
+ STORE (DREG (reg), GET_LONG (addr));
+ }
+ else if (aop == 3 && W == 1)
+ {
+ TRACE_INSN (cpu, "[I%i ++ M%i] = R%i;", i, m, reg);
+ addr = IREG (i);
+ dagadd (cpu, i, MREG (m));
+ PUT_LONG (addr, DREG (reg));
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_LDST_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* LDST
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
+ int W = ((iw0 >> LDST_W_bits) & LDST_W_mask);
+ int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
+ int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
+ int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
+ int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask);
+ const char * const posts[] = { "++", "--", "" };
+ const char *post = posts[aop];
+ const char *ptr_name = get_preg_name (ptr);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDST);
+ TRACE_EXTRACT (cpu, "%s: sz:%i W:%i aop:%i Z:%i ptr:%i reg:%i",
+ __func__, sz, W, aop, Z, ptr, reg);
+
+ if (aop == 3)
+ illegal_instruction (cpu);
+
+ if (W == 0)
+ {
+ if (sz == 0 && Z == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [%s%s];", reg, ptr_name, post);
+ SET_DREG (reg, GET_LONG (PREG (ptr)));
+ }
+ else if (sz == 0 && Z == 1)
+ {
+ TRACE_INSN (cpu, "%s = [%s%s];", get_preg_name (reg), ptr_name, post);
+ if (aop < 2 && ptr == reg)
+ illegal_instruction_combination (cpu);
+ SET_PREG (reg, GET_LONG (PREG (ptr)));
+ }
+ else if (sz == 1 && Z == 0)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s%s] (Z);", reg, ptr_name, post);
+ SET_DREG (reg, GET_WORD (PREG (ptr)));
+ }
+ else if (sz == 1 && Z == 1)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s%s] (X);", reg, ptr_name, post);
+ SET_DREG (reg, (bs32) (bs16) GET_WORD (PREG (ptr)));
+ }
+ else if (sz == 2 && Z == 0)
+ {
+ TRACE_INSN (cpu, "R%i = B[%s%s] (Z);", reg, ptr_name, post);
+ SET_DREG (reg, GET_BYTE (PREG (ptr)));
+ }
+ else if (sz == 2 && Z == 1)
+ {
+ TRACE_INSN (cpu, "R%i = B[%s%s] (X);", reg, ptr_name, post);
+ SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr)));
+ }
+ else
+ illegal_instruction (cpu);
+ }
+ else
+ {
+ if (sz == 0 && Z == 0)
+ {
+ TRACE_INSN (cpu, "[%s%s] = R%i;", ptr_name, post, reg);
+ PUT_LONG (PREG (ptr), DREG (reg));
+ }
+ else if (sz == 0 && Z == 1)
+ {
+ TRACE_INSN (cpu, "[%s%s] = %s;", ptr_name, post, get_preg_name (reg));
+ PUT_LONG (PREG (ptr), PREG (reg));
+ }
+ else if (sz == 1 && Z == 0)
+ {
+ TRACE_INSN (cpu, "W[%s%s] = R%i;", ptr_name, post, reg);
+ PUT_WORD (PREG (ptr), DREG (reg));
+ }
+ else if (sz == 2 && Z == 0)
+ {
+ TRACE_INSN (cpu, "B[%s%s] = R%i;", ptr_name, post, reg);
+ PUT_BYTE (PREG (ptr), DREG (reg));
+ }
+ else
+ illegal_instruction (cpu);
+ }
+
+ if (aop == 0)
+ SET_PREG (ptr, PREG (ptr) + (1 << (2 - sz)));
+ if (aop == 1)
+ SET_PREG (ptr, PREG (ptr) - (1 << (2 - sz)));
+}
+
+static void
+decode_LDSTiiFP_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* LDSTiiFP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ /* This isn't exactly a grp:reg as this insn only supports Dregs & Pregs,
+ but for our usage, its functionality the same thing. */
+ int grp = ((iw0 >> 3) & 0x1);
+ int reg = ((iw0 >> LDSTiiFP_reg_bits) & 0x7 /*LDSTiiFP_reg_mask*/);
+ int offset = ((iw0 >> LDSTiiFP_offset_bits) & LDSTiiFP_offset_mask);
+ int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
+ bu32 imm = negimm5s4 (offset);
+ bu32 ea = FPREG + imm;
+ const char *imm_str = negimm5s4_str (offset);
+ const char *reg_name = get_allreg_name (grp, reg);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTiiFP);
+ TRACE_EXTRACT (cpu, "%s: W:%i offset:%#x grp:%i reg:%i", __func__,
+ W, offset, grp, reg);
+ TRACE_DECODE (cpu, "%s: negimm5s4:%#x", __func__, imm);
+
+ if (W == 0)
+ {
+ TRACE_INSN (cpu, "%s = [FP + %s];", reg_name, imm_str);
+ reg_write (cpu, grp, reg, GET_LONG (ea));
+ }
+ else
+ {
+ TRACE_INSN (cpu, "[FP + %s] = %s;", imm_str, reg_name);
+ PUT_LONG (ea, reg_read (cpu, grp, reg));
+ }
+}
+
+static void
+decode_LDSTii_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* LDSTii
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
+ int ptr = ((iw0 >> LDSTii_ptr_bit) & LDSTii_ptr_mask);
+ int offset = ((iw0 >> LDSTii_offset_bit) & LDSTii_offset_mask);
+ int op = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
+ int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
+ bu32 imm, ea;
+ const char *imm_str;
+ const char *ptr_name = get_preg_name (ptr);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTii);
+ TRACE_EXTRACT (cpu, "%s: W:%i op:%i offset:%#x ptr:%i reg:%i",
+ __func__, W, op, offset, ptr, reg);
+
+ if (op == 0 || op == 3)
+ imm = uimm4s4 (offset), imm_str = uimm4s4_str (offset);
+ else
+ imm = uimm4s2 (offset), imm_str = uimm4s2_str (offset);
+ ea = PREG (ptr) + imm;
+
+ TRACE_DECODE (cpu, "%s: uimm4s4/uimm4s2:%#x", __func__, imm);
+
+ if (W == 1 && op == 2)
+ illegal_instruction (cpu);
+
+ if (W == 0)
+ {
+ if (op == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [%s + %s];", reg, ptr_name, imm_str);
+ SET_DREG (reg, GET_LONG (ea));
+ }
+ else if (op == 1)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s + %s] (Z);", reg, ptr_name, imm_str);
+ SET_DREG (reg, GET_WORD (ea));
+ }
+ else if (op == 2)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s + %s] (X);", reg, ptr_name, imm_str);
+ SET_DREG (reg, (bs32) (bs16) GET_WORD (ea));
+ }
+ else if (op == 3)
+ {
+ TRACE_INSN (cpu, "%s = [%s + %s];",
+ get_preg_name (reg), ptr_name, imm_str);
+ SET_PREG (reg, GET_LONG (ea));
+ }
+ }
+ else
+ {
+ if (op == 0)
+ {
+ TRACE_INSN (cpu, "[%s + %s] = R%i;", ptr_name, imm_str, reg);
+ PUT_LONG (ea, DREG (reg));
+ }
+ else if (op == 1)
+ {
+ TRACE_INSN (cpu, "W[%s + %s] = R%i;", ptr_name, imm_str, reg);
+ PUT_WORD (ea, DREG (reg));
+ }
+ else if (op == 3)
+ {
+ TRACE_INSN (cpu, "[%s + %s] = %s;",
+ ptr_name, imm_str, get_preg_name (reg));
+ PUT_LONG (ea, PREG (reg));
+ }
+ }
+}
+
+static void
+decode_LoopSetup_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
+{
+ /* LoopSetup
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |.rop...|.c.|.soffset.......|
+ |.reg...........| - | - |.eoffset...............................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int c = ((iw0 >> (LoopSetup_c_bits - 16)) & LoopSetup_c_mask);
+ int reg = ((iw1 >> LoopSetup_reg_bits) & LoopSetup_reg_mask);
+ int rop = ((iw0 >> (LoopSetup_rop_bits - 16)) & LoopSetup_rop_mask);
+ int soffset = ((iw0 >> (LoopSetup_soffset_bits - 16)) & LoopSetup_soffset_mask);
+ int eoffset = ((iw1 >> LoopSetup_eoffset_bits) & LoopSetup_eoffset_mask);
+ int spcrel = pcrel4 (soffset);
+ int epcrel = lppcrel10 (eoffset);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LoopSetup);
+ TRACE_EXTRACT (cpu, "%s: rop:%i c:%i soffset:%i reg:%i eoffset:%i",
+ __func__, rop, c, soffset, reg, eoffset);
+ TRACE_DECODE (cpu, "%s: s_pcrel4:%#x e_lppcrel10:%#x",
+ __func__, spcrel, epcrel);
+
+ if (reg > 7)
+ illegal_instruction (cpu);
+
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ if (rop == 0)
+ {
+ TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i;", spcrel, epcrel, c);
+ }
+ else if (rop == 1 && reg <= 7)
+ {
+ TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s;",
+ spcrel, epcrel, c, get_preg_name (reg));
+ SET_LCREG (c, PREG (reg));
+ }
+ else if (rop == 3 && reg <= 7)
+ {
+ TRACE_INSN (cpu, "LSETUP (%#x, %#x) LC%i = %s >> 1;",
+ spcrel, epcrel, c, get_preg_name (reg));
+ SET_LCREG (c, PREG (reg) >> 1);
+ }
+ else
+ illegal_instruction (cpu);
+
+ SET_LTREG (c, pc + spcrel);
+ SET_LBREG (c, pc + epcrel);
+}
+
+static void
+decode_LDIMMhalf_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* LDIMMhalf
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |.Z.|.H.|.S.|.grp...|.reg.......|
+ |.hword.........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int H = ((iw0 >> (LDIMMhalf_H_bits - 16)) & LDIMMhalf_H_mask);
+ int Z = ((iw0 >> (LDIMMhalf_Z_bits - 16)) & LDIMMhalf_Z_mask);
+ int S = ((iw0 >> (LDIMMhalf_S_bits - 16)) & LDIMMhalf_S_mask);
+ int reg = ((iw0 >> (LDIMMhalf_reg_bits - 16)) & LDIMMhalf_reg_mask);
+ int grp = ((iw0 >> (LDIMMhalf_grp_bits - 16)) & LDIMMhalf_grp_mask);
+ int hword = ((iw1 >> LDIMMhalf_hword_bits) & LDIMMhalf_hword_mask);
+ bu32 val;
+ const char *val_str;
+ const char *reg_name = get_allreg_name (grp, reg);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDIMMhalf);
+ TRACE_EXTRACT (cpu, "%s: Z:%i H:%i S:%i grp:%i reg:%i hword:%#x",
+ __func__, Z, H, S, grp, reg, hword);
+
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ if (S == 1)
+ val = imm16 (hword), val_str = imm16_str (hword);
+ else
+ val = luimm16 (hword), val_str = luimm16_str (hword);
+
+ if (H == 0 && S == 1 && Z == 0)
+ {
+ TRACE_INSN (cpu, "%s = %s (X);", reg_name, val_str);
+ }
+ else if (H == 0 && S == 0 && Z == 1)
+ {
+ TRACE_INSN (cpu, "%s = %s (Z);", reg_name, val_str);
+ }
+ else if (H == 0 && S == 0 && Z == 0)
+ {
+ TRACE_INSN (cpu, "%s.L = %s;", reg_name, val_str);
+ val = REG_H_L (reg_read (cpu, grp, reg), val);
+ }
+ else if (H == 1 && S == 0 && Z == 0)
+ {
+ TRACE_INSN (cpu, "%s.H = %s;", reg_name, val_str);
+ val = REG_H_L (val << 16, reg_read (cpu, grp, reg));
+ }
+ else
+ illegal_instruction (cpu);
+
+ reg_write (cpu, grp, reg, val);
+}
+
+static void
+decode_CALLa_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
+{
+ /* CALLa
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 1 |.S.|.msw...........................|
+ |.lsw...........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int S = ((iw0 >> (CALLa_S_bits - 16)) & CALLa_S_mask);
+ int lsw = ((iw1 >> 0) & 0xffff);
+ int msw = ((iw0 >> 0) & 0xff);
+ int pcrel = pcrel24 ((msw << 16) | lsw);
+ bu32 newpc = pc + pcrel;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_CALLa);
+ TRACE_EXTRACT (cpu, "%s: S:%i msw:%#x lsw:%#x", __func__, S, msw, lsw);
+ TRACE_DECODE (cpu, "%s: pcrel24:%#x", __func__, pcrel);
+
+ TRACE_INSN (cpu, "%s %#x;", S ? "CALL" : "JUMP.L", pcrel);
+
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+
+ if (S == 1)
+ {
+ TRACE_BRANCH (cpu, pc, newpc, -1, "CALL");
+ SET_RETSREG (hwloop_get_next_pc (cpu, pc, 4));
+ }
+ else
+ TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.L");
+
+ SET_PCREG (newpc);
+ BFIN_CPU_STATE.did_jump = true;
+ PROFILE_BRANCH_TAKEN (cpu);
+ CYCLE_DELAY = 5;
+}
+
+static void
+decode_LDSTidxI_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* LDSTidxI
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 1 |.W.|.Z.|.sz....|.ptr.......|.reg.......|
+ |.offset........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int Z = ((iw0 >> (LDSTidxI_Z_bits - 16)) & LDSTidxI_Z_mask);
+ int W = ((iw0 >> (LDSTidxI_W_bits - 16)) & LDSTidxI_W_mask);
+ int sz = ((iw0 >> (LDSTidxI_sz_bits - 16)) & LDSTidxI_sz_mask);
+ int reg = ((iw0 >> (LDSTidxI_reg_bits - 16)) & LDSTidxI_reg_mask);
+ int ptr = ((iw0 >> (LDSTidxI_ptr_bits - 16)) & LDSTidxI_ptr_mask);
+ int offset = ((iw1 >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask);
+ const char *ptr_name = get_preg_name (ptr);
+ bu32 imm_16s4 = imm16s4 (offset);
+ bu32 imm_16s2 = imm16s2 (offset);
+ bu32 imm_16 = imm16 (offset);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_LDSTidxI);
+ TRACE_EXTRACT (cpu, "%s: W:%i Z:%i sz:%i ptr:%i reg:%i offset:%#x",
+ __func__, W, Z, sz, ptr, reg, offset);
+
+ if (sz == 3)
+ illegal_instruction (cpu);
+
+ if (W == 0)
+ {
+ if (sz == 0 && Z == 0)
+ {
+ TRACE_INSN (cpu, "R%i = [%s + %s];",
+ reg, ptr_name, imm16s4_str (offset));
+ SET_DREG (reg, GET_LONG (PREG (ptr) + imm_16s4));
+ }
+ else if (sz == 0 && Z == 1)
+ {
+ TRACE_INSN (cpu, "%s = [%s + %s];",
+ get_preg_name (reg), ptr_name, imm16s4_str (offset));
+ SET_PREG (reg, GET_LONG (PREG (ptr) + imm_16s4));
+ }
+ else if (sz == 1 && Z == 0)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s + %s] (Z);",
+ reg, ptr_name, imm16s2_str (offset));
+ SET_DREG (reg, GET_WORD (PREG (ptr) + imm_16s2));
+ }
+ else if (sz == 1 && Z == 1)
+ {
+ TRACE_INSN (cpu, "R%i = W[%s + %s] (X);",
+ reg, ptr_name, imm16s2_str (offset));
+ SET_DREG (reg, (bs32) (bs16) GET_WORD (PREG (ptr) + imm_16s2));
+ }
+ else if (sz == 2 && Z == 0)
+ {
+ TRACE_INSN (cpu, "R%i = B[%s + %s] (Z);",
+ reg, ptr_name, imm16_str (offset));
+ SET_DREG (reg, GET_BYTE (PREG (ptr) + imm_16));
+ }
+ else if (sz == 2 && Z == 1)
+ {
+ TRACE_INSN (cpu, "R%i = B[%s + %s] (X);",
+ reg, ptr_name, imm16_str (offset));
+ SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr) + imm_16));
+ }
+ }
+ else
+ {
+ if (sz != 0 && Z != 0)
+ illegal_instruction (cpu);
+
+ if (sz == 0 && Z == 0)
+ {
+ TRACE_INSN (cpu, "[%s + %s] = R%i;", ptr_name,
+ imm16s4_str (offset), reg);
+ PUT_LONG (PREG (ptr) + imm_16s4, DREG (reg));
+ }
+ else if (sz == 0 && Z == 1)
+ {
+ TRACE_INSN (cpu, "[%s + %s] = %s;",
+ ptr_name, imm16s4_str (offset), get_preg_name (reg));
+ PUT_LONG (PREG (ptr) + imm_16s4, PREG (reg));
+ }
+ else if (sz == 1 && Z == 0)
+ {
+ TRACE_INSN (cpu, "W[%s + %s] = R%i;",
+ ptr_name, imm16s2_str (offset), reg);
+ PUT_WORD (PREG (ptr) + imm_16s2, DREG (reg));
+ }
+ else if (sz == 2 && Z == 0)
+ {
+ TRACE_INSN (cpu, "B[%s + %s] = R%i;",
+ ptr_name, imm16_str (offset), reg);
+ PUT_BYTE (PREG (ptr) + imm_16, DREG (reg));
+ }
+ }
+}
+
+static void
+decode_linkage_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* linkage
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.R.|
+ |.framesize.....................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int R = ((iw0 >> (Linkage_R_bits - 16)) & Linkage_R_mask);
+ int framesize = ((iw1 >> Linkage_framesize_bits) & Linkage_framesize_mask);
+ bu32 sp;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_linkage);
+ TRACE_EXTRACT (cpu, "%s: R:%i framesize:%#x", __func__, R, framesize);
+
+ if (R == 0)
+ {
+ int size = uimm16s4 (framesize);
+ sp = SPREG;
+ TRACE_INSN (cpu, "LINK %s;", uimm16s4_str (framesize));
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ sp -= 4;
+ PUT_LONG (sp, RETSREG);
+ sp -= 4;
+ PUT_LONG (sp, FPREG);
+ SET_FPREG (sp);
+ sp -= size;
+ CYCLE_DELAY = 3;
+ }
+ else
+ {
+ /* Restore SP from FP. */
+ sp = FPREG;
+ TRACE_INSN (cpu, "UNLINK;");
+ if (INSN_LEN == 8)
+ illegal_instruction_combination (cpu);
+ SET_FPREG (GET_LONG (sp));
+ sp += 4;
+ SET_RETSREG (GET_LONG (sp));
+ sp += 4;
+ CYCLE_DELAY = 2;
+ }
+
+ SET_SPREG (sp);
+}
+
+static void
+decode_dsp32mac_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* dsp32mac
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
+ |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
+ int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+ int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+ int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
+ int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+ int M = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
+ int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+ int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
+ int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
+ int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+ int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
+ int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
+ int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
+ int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
+ int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
+
+ bu32 res = DREG (dst);
+ bu32 v_i = 0, zero = 0;
+
+ static const char * const ops[] = { "=", "+=", "-=" };
+ char _buf[128], *buf = _buf;
+ int _MM = MM;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac);
+ TRACE_EXTRACT (cpu, "%s: M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
+ "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
+ __func__, M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
+ dst, src0, src1);
+
+ if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
+ illegal_instruction (cpu);
+
+ if ((w1 || w0) && mmod == M_W32)
+ illegal_instruction (cpu);
+
+ if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
+ illegal_instruction (cpu);
+
+ /* First handle MAC1 side. */
+ if (w1 == 1 || op1 != 3)
+ {
+ bu32 res1 = decode_macfunc (cpu, 1, op1, h01, h11, src0,
+ src1, mmod, MM, P, &v_i);
+
+ if (w1)
+ buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
+
+ if (op1 == 3)
+ {
+ buf += sprintf (buf, " = A1");
+ zero = !!(res1 == 0);
+ }
+ else
+ {
+ if (w1)
+ buf += sprintf (buf, " = (");
+ buf += sprintf (buf, "A1 %s R%i.%c * R%i.%c", ops[op1],
+ src0, h01 ? 'H' : 'L',
+ src1, h11 ? 'H' : 'L');
+ if (w1)
+ buf += sprintf (buf, ")");
+ }
+
+ if (w1)
+ {
+ if (P)
+ STORE (DREG (dst + 1), res1);
+ else
+ {
+ if (res1 & 0xffff0000)
+ illegal_instruction (cpu);
+ res = REG_H_L (res1 << 16, res);
+ }
+ }
+
+ if (w0 == 1 || op0 != 3)
+ {
+ if (_MM)
+ buf += sprintf (buf, " (M)");
+ _MM = 0;
+ buf += sprintf (buf, ", ");
+ }
+ }
+
+ /* Then handle MAC0 side. */
+ if (w0 == 1 || op0 != 3)
+ {
+ bu32 res0 = decode_macfunc (cpu, 0, op0, h00, h10, src0,
+ src1, mmod, 0, P, &v_i);
+
+ if (w0)
+ buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
+
+ if (op0 == 3)
+ {
+ buf += sprintf (buf, " = A0");
+ zero |= !!(res0 == 0);
+ }
+ else
+ {
+ if (w0)
+ buf += sprintf (buf, " = (");
+ buf += sprintf (buf, "A0 %s R%i.%c * R%i.%c", ops[op0],
+ src0, h00 ? 'H' : 'L',
+ src1, h10 ? 'H' : 'L');
+ if (w0)
+ buf += sprintf (buf, ")");
+ }
+
+ if (w0)
+ {
+ if (P)
+ STORE (DREG (dst), res0);
+ else
+ {
+ if (res0 & 0xffff0000)
+ illegal_instruction (cpu);
+ res = REG_H_L (res, res0);
+ }
+ }
+ }
+
+ TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
+
+ if (!P && (w0 || w1))
+ {
+ STORE (DREG (dst), res);
+ SET_ASTATREG (v, v_i);
+ if (v_i)
+ SET_ASTATREG (vs, v_i);
+ }
+ else if (P)
+ {
+ SET_ASTATREG (v, v_i);
+ if (v_i)
+ SET_ASTATREG (vs, v_i);
+ }
+ if (op0 == 3 || op1 == 3)
+ SET_ASTATREG (az, zero);
+}
+
+static void
+decode_dsp32mult_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* dsp32mult
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
+ |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
+ int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+ int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+ int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
+ int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+ int M = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
+ int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+ int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
+ int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
+ int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+ int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
+ int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
+ int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
+ int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
+ int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
+
+ bu32 res = DREG (dst);
+ bu32 sat0 = 0, sat1 = 0;
+ char _buf[128], *buf = _buf;
+ int _MM = MM;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mult);
+ TRACE_EXTRACT (cpu, "%s: M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
+ "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
+ __func__, M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
+ dst, src0, src1);
+
+ if (w1 == 0 && w0 == 0)
+ illegal_instruction (cpu);
+ if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
+ illegal_instruction (cpu);
+ if (P && ((dst & 1) || (op1 != 0) || (op0 != 0) || !is_macmod_pmove (mmod)))
+ illegal_instruction (cpu);
+ if (!P && ((op1 != 0) || (op0 != 0) || !is_macmod_hmove (mmod)))
+ illegal_instruction (cpu);
+
+ /* First handle MAC1 side. */
+ if (w1)
+ {
+ bu64 r = decode_multfunc (cpu, h01, h11, src0, src1, mmod, MM, &sat1);
+ bu32 res1 = extract_mult (cpu, r, mmod, MM, P, NULL);
+
+ buf += sprintf (buf, P ? "R%i" : "R%i.H", dst + P);
+ buf += sprintf (buf, " = R%i.%c * R%i.%c",
+ src0, h01 ? 'H' : 'L',
+ src1, h11 ? 'H' : 'L');
+ if (w0)
+ {
+ if (_MM)
+ buf += sprintf (buf, " (M)");
+ _MM = 0;
+ buf += sprintf (buf, ", ");
+ }
+
+ if (P)
+ STORE (DREG (dst + 1), res1);
+ else
+ {
+ if (res1 & 0xFFFF0000)
+ illegal_instruction (cpu);
+ res = REG_H_L (res1 << 16, res);
+ }
+ }
+
+ /* First handle MAC0 side. */
+ if (w0)
+ {
+ bu64 r = decode_multfunc (cpu, h00, h10, src0, src1, mmod, 0, &sat0);
+ bu32 res0 = extract_mult (cpu, r, mmod, 0, P, NULL);
+
+ buf += sprintf (buf, P ? "R%i" : "R%i.L", dst);
+ buf += sprintf (buf, " = R%i.%c * R%i.%c",
+ src0, h01 ? 'H' : 'L',
+ src1, h11 ? 'H' : 'L');
+
+ if (P)
+ STORE (DREG (dst), res0);
+ else
+ {
+ if (res0 & 0xFFFF0000)
+ illegal_instruction (cpu);
+ res = REG_H_L (res, res0);
+ }
+ }
+
+ TRACE_INSN (cpu, "%s%s;", _buf, mac_optmode (mmod, _MM));
+
+ if (!P && (w0 || w1))
+ STORE (DREG (dst), res);
+
+ if (w0 || w1)
+ {
+ STORE (ASTATREG (v), sat0 | sat1);
+ STORE (ASTATREG (v_copy), sat0 | sat1);
+ if (sat0 | sat1)
+ STORE (ASTATREG (vs), 1);
+ }
+}
+
+static void
+decode_dsp32alu_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* dsp32alu
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
+ |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
+ int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
+ int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
+ int src0 = ((iw1 >> DSP32Alu_src0_bits) & DSP32Alu_src0_mask);
+ int src1 = ((iw1 >> DSP32Alu_src1_bits) & DSP32Alu_src1_mask);
+ int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
+ int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
+ int M = ((iw0 >> (DSP32Alu_M_bits - 16)) & DSP32Alu_M_mask);
+ int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
+ int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32alu);
+ TRACE_EXTRACT (cpu, "%s: M:%i HL:%i aopcde:%i aop:%i s:%i x:%i dst0:%i "
+ "dst1:%i src0:%i src1:%i",
+ __func__, M, HL, aopcde, aop, s, x, dst0, dst1, src0, src1);
+
+ if ((aop == 0 || aop == 2) && aopcde == 9 && HL == 0 && s == 0)
+ {
+ int a = aop >> 1;
+ TRACE_INSN (cpu, "A%i.L = R%i.L;", a, src0);
+ SET_AWREG (a, REG_H_L (AWREG (a), DREG (src0)));
+ }
+ else if ((aop == 0 || aop == 2) && aopcde == 9 && HL == 1 && s == 0)
+ {
+ int a = aop >> 1;
+ TRACE_INSN (cpu, "A%i.H = R%i.H;", a, src0);
+ SET_AWREG (a, REG_H_L (DREG (src0), AWREG (a)));
+ }
+ else if ((aop == 1 || aop == 0) && aopcde == 5)
+ {
+ bs32 val0 = DREG (src0);
+ bs32 val1 = DREG (src1);
+ bs32 res;
+ bs32 signRes;
+ bs32 ovX, sBit1, sBit2, sBitRes1, sBitRes2;
+
+ TRACE_INSN (cpu, "R%i.%s = R%i %s R%i (RND12)", dst0, HL ? "L" : "H",
+ src0, aop & 0x1 ? "-" : "+", src1);
+
+ /* If subtract, just invert and add one. */
+ if (aop & 0x1)
+ val1 = ~val1 + 1;
+
+ /* Get the sign bits, since we need them later. */
+ sBit1 = !!(val0 & 0x80000000);
+ sBit2 = !!(val1 & 0x80000000);
+
+ res = val0 + val1;
+
+ sBitRes1 = !!(res & 0x80000000);
+ /* Round to the 12th bit. */
+ res += 0x0800;
+ sBitRes2 = !!(res & 0x80000000);
+
+ signRes = res;
+ signRes >>= 27;
+
+ /* Overflow if
+ pos + pos = neg
+ neg + neg = pos
+ positive_res + positive_round = neg
+ Shift and upper 4 bits where not the same. */
+ if ((!(sBit1 ^ sBit2) && (sBit1 ^ sBitRes1))
+ || (!sBit1 && !sBit2 && sBitRes2)
+ || ((signRes != 0) && (signRes != -1)))
+ {
+ /* Both X1 and X2 Neg res is neg overflow. */
+ if (sBit1 && sBit2)
+ res = 0x80000000;
+ /* Both X1 and X2 Pos res is pos overflow. */
+ else if (!sBit1 && !sBit2)
+ res = 0x7FFFFFFF;
+ /* Pos+Neg or Neg+Pos take the sign of the result. */
+ else if (sBitRes1)
+ res = 0x80000000;
+ else
+ res = 0x7FFFFFFF;
+
+ ovX = 1;
+ }
+ else
+ {
+ /* Shift up now after overflow detection. */
+ ovX = 0;
+ res <<= 4;
+ }
+
+ res >>= 16;
+
+ if (HL)
+ STORE (DREG (dst0), REG_H_L (res << 16, DREG (dst0)));
+ else
+ STORE (DREG (dst0), REG_H_L (DREG (dst0), res));
+
+ SET_ASTATREG (az, res == 0);
+ SET_ASTATREG (an, res & 0x8000);
+ SET_ASTATREG (v, ovX);
+ if (ovX)
+ SET_ASTATREG (vs, ovX);
+ }
+ else if ((aop == 2 || aop == 3) && aopcde == 5)
+ {
+ bs32 val0 = DREG (src0);
+ bs32 val1 = DREG (src1);
+ bs32 res;
+
+ TRACE_INSN (cpu, "R%i.%s = R%i %s R%i (RND20)", dst0, HL ? "L" : "H",
+ src0, aop & 0x1 ? "-" : "+", src1);
+
+ /* If subtract, just invert and add one. */
+ if (aop & 0x1)
+ val1 = ~val1 + 1;
+
+ res = (val0 >> 4) + (val1 >> 4) + (((val0 & 0xf) + (val1 & 0xf)) >> 4);
+ res += 0x8000;
+ /* Don't sign extend during the shift. */
+ res = ((bu32)res >> 16);
+
+ /* Don't worry about overflows, since we are shifting right. */
+
+ if (HL)
+ STORE (DREG (dst0), REG_H_L (res << 16, DREG (dst0)));
+ else
+ STORE (DREG (dst0), REG_H_L (DREG (dst0), res));
+
+ SET_ASTATREG (az, res == 0);
+ SET_ASTATREG (an, res & 0x8000);
+ SET_ASTATREG (v, 0);
+ }
+ else if (aopcde == 2 || aopcde == 3)
+ {
+ bu32 s1, s2, val, ac0_i = 0, v_i = 0;
+
+ TRACE_INSN (cpu, "R%i.%c = R%i.%c %c R%i.%c%s;",
+ dst0, HL ? 'H' : 'L',
+ src0, aop & 2 ? 'H' : 'L',
+ aopcde == 2 ? '+' : '-',
+ src1, aop & 1 ? 'H' : 'L',
+ amod1 (s, x));
+
+ s1 = DREG (src0);
+ s2 = DREG (src1);
+ if (aop & 1)
+ s2 >>= 16;
+ if (aop & 2)
+ s1 >>= 16;
+
+ if (aopcde == 2)
+ val = add16 (cpu, s1, s2, &ac0_i, &v_i, 0, 0, s, 0);
+ else
+ val = sub16 (cpu, s1, s2, &ac0_i, &v_i, 0, 0, s, 0);
+
+ SET_ASTATREG (ac0, ac0_i);
+ SET_ASTATREG (v, v_i);
+ if (HL)
+ SET_DREG_H (dst0, val << 16);
+ else
+ SET_DREG_L (dst0, val);
+
+ SET_ASTATREG (an, val & 0x8000);
+
+ }
+ else if ((aop == 0 || aop == 2) && aopcde == 9 && s == 1)
+ {
+ int a = aop >> 1;
+ TRACE_INSN (cpu, "A%i = R%i;", a, src0);
+ SET_AREG32 (a, DREG (src0));
+ }
+ else if ((aop == 1 || aop == 3) && aopcde == 9 && s == 0)
+ {
+ int a = aop >> 1;
+ TRACE_INSN (cpu, "A%i.X = R%i.L;", a, src0);
+ SET_AXREG (a, (bs8)DREG (src0));
+ }
+ else if (aop == 3 && aopcde == 11 && (s == 0 || s == 1))
+ {
+ bu64 acc0 = get_extended_acc (cpu, 0);
+ bu64 acc1 = get_extended_acc (cpu, 1);
+ bu32 carry = (bu40)acc1 < (bu40)acc0;
+ bu32 sat = 0;
+
+ TRACE_INSN (cpu, "A0 -= A1%s;", s ? " (W32)" : "");
+
+ acc0 -= acc1;
+ if ((bs64)acc0 < -0x8000000000ll)
+ acc0 = -0x8000000000ull, sat = 1;
+ else if ((bs64)acc0 >= 0x7fffffffffll)
+ acc0 = 0x7fffffffffull, sat = 1;
+
+ if (s == 1)
+ {
+ /* A0 -= A1 (W32) */
+ if (acc0 & (bu64)0x8000000000ll)
+ acc0 &= 0x80ffffffffll, sat = 1;
+ else
+ acc0 &= 0xffffffffll;
+ }
+ STORE (AXREG (0), (acc0 >> 32) & 0xff);
+ STORE (AWREG (0), acc0 & 0xffffffff);
+ STORE (ASTATREG (az), acc0 == 0);
+ STORE (ASTATREG (an), !!(acc0 & (bu64)0x8000000000ll));
+ STORE (ASTATREG (ac0), carry);
+ STORE (ASTATREG (ac0_copy), carry);
+ STORE (ASTATREG (av0), sat);
+ if (sat)
+ STORE (ASTATREG (av0s), sat);
+ }
+ else if ((aop == 0 || aop == 1) && aopcde == 22)
+ {
+ bu32 s0, s0L, s0H, s1, s1L, s1H;
+ bu32 tmp0, tmp1, i;
+ const char * const opts[] = { "rndl", "rndh", "tl", "th" };
+
+ TRACE_INSN (cpu, "R%i = BYTEOP2P (R%i:%i, R%i:%i) (%s%s);", dst0,
+ src0 + 1, src0, src1 + 1, src1, opts[HL + (aop << 1)],
+ s ? ", r" : "");
+
+ if (src0 == src1)
+ illegal_instruction_combination (cpu);
+
+ s0L = DREG (src0);
+ s0H = DREG (src0 + 1);
+ s1L = DREG (src1);
+ s1H = DREG (src1 + 1);
+ if (s)
+ {
+ s0 = algn (s0H, s0L, IREG (0) & 3);
+ s1 = algn (s1H, s1L, IREG (0) & 3);
+ }
+ else
+ {
+ s0 = algn (s0L, s0H, IREG (0) & 3);
+ s1 = algn (s1L, s1H, IREG (0) & 3);
+ }
+
+ i = !aop * 2;
+ tmp0 = ((((s1 >> 8) & 0xff) + ((s1 >> 0) & 0xff) +
+ ((s0 >> 8) & 0xff) + ((s0 >> 0) & 0xff) + i) >> 2) & 0xff;
+ tmp1 = ((((s1 >> 24) & 0xff) + ((s1 >> 16) & 0xff) +
+ ((s0 >> 24) & 0xff) + ((s0 >> 16) & 0xff) + i) >> 2) & 0xff;
+ SET_DREG (dst0, (tmp1 << (16 + (HL * 8))) | (tmp0 << (HL * 8)));
+ }
+ else if ((aop == 0 || aop == 1) && s == 0 && aopcde == 8)
+ {
+ TRACE_INSN (cpu, "A%i = 0;", aop);
+ SET_AREG (aop, 0);
+ }
+ else if (aop == 2 && s == 0 && aopcde == 8)
+ {
+ TRACE_INSN (cpu, "A1 = A0 = 0;");
+ SET_AREG (0, 0);
+ SET_AREG (1, 0);
+ }
+ else if ((aop == 0 || aop == 1 || aop == 2) && s == 1 && aopcde == 8)
+ {
+ bs40 acc0 = get_extended_acc (cpu, 0);
+ bs40 acc1 = get_extended_acc (cpu, 1);
+ bu32 sat;
+
+ if (aop == 0 || aop == 1)
+ TRACE_INSN (cpu, "A%i = A%i (S);", aop, aop);
+ else
+ TRACE_INSN (cpu, "A1 = A1 (S), A0 = A0 (S);");
+
+ if (aop == 0 || aop == 2)
+ {
+ sat = 0;
+ acc0 = saturate_s32 (acc0, &sat);
+ acc0 |= -(acc0 & 0x80000000ull);
+ SET_AXREG (0, (acc0 >> 31) & 0xFF);
+ SET_AWREG (0, acc0 & 0xFFFFFFFF);
+ SET_ASTATREG (av0, sat);
+ if (sat)
+ SET_ASTATREG (av0s, sat);
+ }
+ else
+ acc0 = 1;
+
+ if (aop == 1 || aop == 2)
+ {
+ sat = 0;
+ acc1 = saturate_s32 (acc1, &sat);
+ acc1 |= -(acc1 & 0x80000000ull);
+ SET_AXREG (1, (acc1 >> 31) & 0xFF);
+ SET_AWREG (1, acc1 & 0xFFFFFFFF);
+ SET_ASTATREG (av1, sat);
+ if (sat)
+ SET_ASTATREG (av1s, sat);
+ }
+ else
+ acc1 = 1;
+
+ SET_ASTATREG (az, (acc0 == 0) || (acc1 == 0));
+ SET_ASTATREG (an, ((acc0 >> 31) & 1) || ((acc1 >> 31) & 1));
+ }
+ else if (aop == 3 && (s == 0 || s == 1) && aopcde == 8)
+ {
+ TRACE_INSN (cpu, "A%i = A%i;", s, !s);
+ SET_AXREG (s, AXREG (!s));
+ SET_AWREG (s, AWREG (!s));
+ }
+ else if (aop == 3 && HL == 0 && aopcde == 16)
+ {
+ int i;
+ bu32 az;
+
+ TRACE_INSN (cpu, "A1 = ABS A1 , A0 = ABS A0;");
+
+ az = 0;
+ for (i = 0; i < 2; ++i)
+ {
+ bu32 av;
+ bs40 acc = get_extended_acc (cpu, i);
+
+ if (acc >> 39)
+ acc = -acc;
+ av = acc == ((bs40)1 << 39);
+ if (av)
+ acc = ((bs40)1 << 39) - 1;
+
+ SET_AREG (i, acc);
+ SET_ASTATREG (av[i], av);
+ if (av)
+ SET_ASTATREG (avs[i], av);
+ az |= (acc == 0);
+ }
+ SET_ASTATREG (az, az);
+ SET_ASTATREG (an, 0);
+ }
+ else if (aop == 0 && aopcde == 23)
+ {
+ bu32 s0, s0L, s0H, s1, s1L, s1H;
+ bs32 tmp0, tmp1;
+
+ TRACE_INSN (cpu, "R%i = BYTEOP3P (R%i:%i, R%i:%i) (%s%s);", dst0,
+ src0 + 1, src0, src1 + 1, src1, HL ? "HI" : "LO",
+ s ? ", R" : "");
+
+ if (src0 == src1)
+ illegal_instruction_combination (cpu);
+
+ s0L = DREG (src0);
+ s0H = DREG (src0 + 1);
+ s1L = DREG (src1);
+ s1H = DREG (src1 + 1);
+ if (s)
+ {
+ s0 = algn (s0H, s0L, IREG (0) & 3);
+ s1 = algn (s1H, s1L, IREG (1) & 3);
+ }
+ else
+ {
+ s0 = algn (s0L, s0H, IREG (0) & 3);
+ s1 = algn (s1L, s1H, IREG (1) & 3);
+ }
+
+ tmp0 = (bs32)(bs16)(s0 >> 0) + ((s1 >> ( 0 + (8 * !HL))) & 0xff);
+ tmp1 = (bs32)(bs16)(s0 >> 16) + ((s1 >> (16 + (8 * !HL))) & 0xff);
+ SET_DREG (dst0, (CLAMP (tmp0, 0, 255) << ( 0 + (8 * HL))) |
+ (CLAMP (tmp1, 0, 255) << (16 + (8 * HL))));
+ }
+ else if ((aop == 0 || aop == 1) && aopcde == 16)
+ {
+ bu32 av;
+ bs40 acc;
+
+ TRACE_INSN (cpu, "A%i = ABS A%i;", HL, aop);
+
+ acc = get_extended_acc (cpu, aop);
+ if (acc >> 39)
+ acc = -acc;
+ av = acc == ((bs40)1 << 39);
+ if (av)
+ acc = ((bs40)1 << 39) - 1;
+ SET_AREG (HL, acc);
+
+ SET_ASTATREG (av[HL], av);
+ if (av)
+ SET_ASTATREG (avs[HL], av);
+ SET_ASTATREG (az, acc == 0);
+ SET_ASTATREG (an, 0);
+ }
+ else if (aop == 3 && aopcde == 12)
+ {
+ bs32 res = DREG (src0);
+ bs32 ovX;
+ bool sBit_a, sBit_b;
+
+ TRACE_INSN (cpu, "R%i.%s = R%i (RND);", dst0, HL == 0 ? "L" : "H", src0);
+ TRACE_DECODE (cpu, "R%i.%s = R%i:%#x (RND);", dst0,
+ HL == 0 ? "L" : "H", src0, res);
+
+ sBit_b = !!(res & 0x80000000);
+
+ res += 0x8000;
+ sBit_a = !!(res & 0x80000000);
+
+ /* Overflow if the sign bit changed when we rounded. */
+ if ((res >> 16) && (sBit_b != sBit_a))
+ {
+ ovX = 1;
+ if (!sBit_b)
+ res = 0x7FFF;
+ else
+ res = 0x8000;
+ }
+ else
+ {
+ res = res >> 16;
+ ovX = 0;
+ }
+
+ if (!HL)
+ SET_DREG (dst0, REG_H_L (DREG (dst0), res));
+ else
+ SET_DREG (dst0, REG_H_L (res << 16, DREG (dst0)));
+
+ SET_ASTATREG (az, res == 0);
+ SET_ASTATREG (an, res < 0);
+ SET_ASTATREG (v, ovX);
+ if (ovX)
+ SET_ASTATREG (vs, ovX);
+ }
+ else if (aop == 3 && HL == 0 && aopcde == 15)
+ {
+ bu32 hi = (-(bs16)(DREG (src0) >> 16)) << 16;
+ bu32 lo = (-(bs16)(DREG (src0) & 0xFFFF)) & 0xFFFF;
+ int v, ac0, ac1;
+
+ TRACE_INSN (cpu, "R%i = -R%i (V);", dst0, src0);
+
+ v = ac0 = ac1 = 0;
+
+ if (hi == 0x80000000)
+ {
+ hi = 0x7fff0000;
+ v = 1;
+ }
+ else if (hi == 0)
+ ac1 = 1;
+
+ if (lo == 0x8000)
+ {
+ lo = 0x7fff;
+ v = 1;
+ }
+ else if (lo == 0)
+ ac0 = 1;
+
+ SET_DREG (dst0, hi | lo);
+
+ SET_ASTATREG (v, v);
+ if (v)
+ SET_ASTATREG (vs, 1);
+ SET_ASTATREG (ac0, ac0);
+ SET_ASTATREG (ac1, ac1);
+ setflags_nz_2x16 (cpu, DREG (dst0));
+ }
+ else if (aop == 3 && HL == 0 && aopcde == 14)
+ {
+ TRACE_INSN (cpu, "A1 = - A1 , A0 = - A0;");
+
+ SET_AREG (0, saturate_s40 (-get_extended_acc (cpu, 0)));
+ SET_AREG (1, saturate_s40 (-get_extended_acc (cpu, 1)));
+ /* XXX: what ASTAT flags need updating ? */
+ }
+ else if ((aop == 0 || aop == 1) && (HL == 0 || HL == 1) && aopcde == 14)
+ {
+ bs40 src_acc = get_extended_acc (cpu, aop);
+
+ TRACE_INSN (cpu, "A%i = - A%i;", HL, aop);
+
+ SET_AREG (HL, saturate_s40 (-src_acc));
+
+ SET_ASTATREG (az, AWREG (HL) == 0 && AXREG (HL) == 0);
+ SET_ASTATREG (an, AXREG (HL) >> 7);
+ SET_ASTATREG (ac0, src_acc == 0);
+ if (HL == 0)
+ {
+ SET_ASTATREG (av0, src_acc < 0);
+ if (ASTATREG (av0))
+ SET_ASTATREG (av0s, 1);
+ }
+ else
+ {
+ SET_ASTATREG (av1, src_acc < 0);
+ if (ASTATREG (av1))
+ SET_ASTATREG (av1s, 1);
+ }
+ }
+ else if (aop == 0 && aopcde == 12)
+ {
+ bs16 tmp0_hi = DREG (src0) >> 16;
+ bs16 tmp0_lo = DREG (src0);
+ bs16 tmp1_hi = DREG (src1) >> 16;
+ bs16 tmp1_lo = DREG (src1);
+
+ TRACE_INSN (cpu, "R%i.L = R%i.H = SIGN(R%i.H) * R%i.H + SIGN(R%i.L) * R%i.L;",
+ dst0, dst0, src0, src1, src0, src1);
+
+ if ((tmp0_hi >> 15) & 1)
+ tmp1_hi = ~tmp1_hi + 1;
+
+ if ((tmp0_lo >> 15) & 1)
+ tmp1_lo = ~tmp1_lo + 1;
+
+ tmp1_hi = tmp1_hi + tmp1_lo;
+
+ STORE (DREG (dst0), REG_H_L (tmp1_hi << 16, tmp1_hi));
+ }
+ else if (aopcde == 0)
+ {
+ bu32 s0 = DREG (src0);
+ bu32 s1 = DREG (src1);
+ bu32 s0h = s0 >> 16;
+ bu32 s0l = s0 & 0xFFFF;
+ bu32 s1h = s1 >> 16;
+ bu32 s1l = s1 & 0xFFFF;
+ bu32 t0, t1;
+ bu32 ac1_i = 0, ac0_i = 0, v_i = 0, z_i = 0, n_i = 0;
+
+ TRACE_INSN (cpu, "R%i = R%i %c|%c R%i%s;", dst0, src0,
+ (aop & 2) ? '-' : '+', (aop & 1) ? '-' : '+', src1,
+ amod0 (s, x));
+ if (aop & 2)
+ t0 = sub16 (cpu, s0h, s1h, &ac1_i, &v_i, &z_i, &n_i, s, 0);
+ else
+ t0 = add16 (cpu, s0h, s1h, &ac1_i, &v_i, &z_i, &n_i, s, 0);
+
+ if (aop & 1)
+ t1 = sub16 (cpu, s0l, s1l, &ac0_i, &v_i, &z_i, &n_i, s, 0);
+ else
+ t1 = add16 (cpu, s0l, s1l, &ac0_i, &v_i, &z_i, &n_i, s, 0);
+
+ SET_ASTATREG (ac1, ac1_i);
+ SET_ASTATREG (ac0, ac0_i);
+ SET_ASTATREG (az, z_i);
+ SET_ASTATREG (an, n_i);
+ SET_ASTATREG (v, v_i);
+ if (v_i)
+ SET_ASTATREG (vs, v_i);
+
+ t0 &= 0xFFFF;
+ t1 &= 0xFFFF;
+ if (x)
+ SET_DREG (dst0, (t1 << 16) | t0);
+ else
+ SET_DREG (dst0, (t0 << 16) | t1);
+ }
+ else if (aop == 1 && aopcde == 12)
+ {
+ bu32 val0 = ((AWREG (0) >> 16) + (AWREG (0) & 0xFFFF)) & 0xFFFF;
+ bu32 val1 = ((AWREG (1) >> 16) + (AWREG (1) & 0xFFFF)) & 0xFFFF;
+
+ TRACE_INSN (cpu, "R%i = A1.L + A1.H, R%i = A0.L + A0.H;", dst1, dst0);
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ if (val0 & 0x8000)
+ val0 |= 0xFFFF0000;
+
+ if (val1 & 0x8000)
+ val1 |= 0xFFFF0000;
+
+ SET_DREG (dst0, val0);
+ SET_DREG (dst1, val1);
+ /* XXX: ASTAT ? */
+ }
+ else if (aopcde == 1)
+ {
+ bu32 d0, d1;
+ bu32 x0, x1;
+ bu16 s0L = DREG (src0);
+ bu16 s0H = DREG (src0) >> 16;
+ bu16 s1L = DREG (src1);
+ bu16 s1H = DREG (src1) >> 16;
+ bu32 v_i = 0, n_i = 0, z_i = 0;
+
+ TRACE_INSN (cpu, "R%i = R%i %s R%i, R%i = R%i %s R%i%s;",
+ dst1, src0, HL ? "+|-" : "+|+", src1,
+ dst0, src0, HL ? "-|+" : "-|-", src1,
+ amod0amod2 (s, x, aop));
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ if (HL == 0)
+ {
+ x0 = add16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ x1 = add16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ d1 = (x0 << 16) | x1;
+
+ x0 = sub16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ x1 = sub16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ if (x == 0)
+ d0 = (x0 << 16) | x1;
+ else
+ d0 = (x1 << 16) | x0;
+ }
+ else
+ {
+ x0 = add16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ x1 = sub16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ d1 = (x0 << 16) | x1;
+
+ x0 = sub16 (cpu, s0H, s1H, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ x1 = add16 (cpu, s0L, s1L, 0, &v_i, &z_i, &n_i, s, aop) & 0xffff;
+ if (x == 0)
+ d0 = (x0 << 16) | x1;
+ else
+ d0 = (x1 << 16) | x0;
+ }
+ SET_ASTATREG (az, z_i);
+ SET_ASTATREG (an, n_i);
+ SET_ASTATREG (v, v_i);
+ if (v_i)
+ SET_ASTATREG (vs, v_i);
+
+ STORE (DREG (dst0), d0);
+ STORE (DREG (dst1), d1);
+ }
+ else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 11)
+ {
+ bs40 acc0 = get_extended_acc (cpu, 0);
+ bs40 acc1 = get_extended_acc (cpu, 1);
+ bu32 v, dreg, sat = 0;
+ bu32 carry = !!((bu40)~acc1 < (bu40)acc0);
+
+ if (aop == 0)
+ TRACE_INSN (cpu, "R%i = (A0 += A1);", dst0);
+ else if (aop == 1)
+ TRACE_INSN (cpu, "R%i.%c = (A0 += A1);", dst0, HL ? 'H' : 'L');
+ else
+ TRACE_INSN (cpu, "A0 += A1%s;", s ? " (W32)" : "");
+
+ acc0 += acc1;
+ acc0 = saturate_s40_astat (acc0, &v);
+
+ if (aop == 2 && s == 1) /* A0 += A1 (W32) */
+ {
+ if (acc0 & (bs40)0x8000000000ll)
+ acc0 &= 0x80ffffffffll;
+ else
+ acc0 &= 0xffffffffll;
+ }
+
+ STORE (AXREG (0), acc0 >> 32);
+ STORE (AWREG (0), acc0);
+ SET_ASTATREG (av0, v && acc1);
+ if (v)
+ SET_ASTATREG (av0s, v);
+
+ if (aop == 0 || aop == 1)
+ {
+ if (aop) /* Dregs_lo = A0 += A1 */
+ {
+ dreg = saturate_s32 (rnd16 (acc0) << 16, &sat);
+ if (HL)
+ STORE (DREG (dst0), REG_H_L (dreg, DREG (dst0)));
+ else
+ STORE (DREG (dst0), REG_H_L (DREG (dst0), dreg >> 16));
+ }
+ else /* Dregs = A0 += A1 */
+ {
+ dreg = saturate_s32 (acc0, &sat);
+ STORE (DREG (dst0), dreg);
+ }
+
+ STORE (ASTATREG (az), dreg == 0);
+ STORE (ASTATREG (an), !!(dreg & 0x80000000));
+ STORE (ASTATREG (ac0), carry);
+ STORE (ASTATREG (ac0_copy), carry);
+ STORE (ASTATREG (v), sat);
+ STORE (ASTATREG (v_copy), sat);
+ if (sat)
+ STORE (ASTATREG (vs), sat);
+ }
+ else
+ {
+ STORE (ASTATREG (az), acc0 == 0);
+ STORE (ASTATREG (an), !!(acc0 & 0x8000000000ull));
+ STORE (ASTATREG (ac0), carry);
+ STORE (ASTATREG (ac0_copy), carry);
+ }
+ }
+ else if ((aop == 0 || aop == 1) && aopcde == 10)
+ {
+ TRACE_INSN (cpu, "R%i.L = A%i.X;", dst0, aop);
+ SET_DREG_L (dst0, (bs8)AXREG (aop));
+ }
+ else if (aop == 0 && aopcde == 4)
+ {
+ TRACE_INSN (cpu, "R%i = R%i + R%i%s;", dst0, src0, src1, amod1 (s, x));
+ SET_DREG (dst0, add32 (cpu, DREG (src0), DREG (src1), 1, s));
+ }
+ else if (aop == 1 && aopcde == 4)
+ {
+ TRACE_INSN (cpu, "R%i = R%i - R%i%s;", dst0, src0, src1, amod1 (s, x));
+ SET_DREG (dst0, sub32 (cpu, DREG (src0), DREG (src1), 1, s, 0));
+ }
+ else if (aop == 2 && aopcde == 4)
+ {
+ TRACE_INSN (cpu, "R%i = R%i + R%i, R%i = R%i - R%i%s;",
+ dst1, src0, src1, dst0, src0, src1, amod1 (s, x));
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ STORE (DREG (dst1), add32 (cpu, DREG (src0), DREG (src1), 1, s));
+ STORE (DREG (dst0), sub32 (cpu, DREG (src0), DREG (src1), 1, s, 1));
+ }
+ else if ((aop == 0 || aop == 1) && aopcde == 17)
+ {
+ bs40 acc0 = get_extended_acc (cpu, 0);
+ bs40 acc1 = get_extended_acc (cpu, 1);
+ bs40 val0, val1, sval0, sval1;
+ bu32 sat, sat_i;
+
+ TRACE_INSN (cpu, "R%i = A%i + A%i, R%i = A%i - A%i%s",
+ dst1, !aop, aop, dst0, !aop, aop, amod1 (s, x));
+ TRACE_DECODE (cpu, "R%i = A%i:%#"PRIx64" + A%i:%#"PRIx64", "
+ "R%i = A%i:%#"PRIx64" - A%i:%#"PRIx64"%s",
+ dst1, !aop, aop ? acc0 : acc1, aop, aop ? acc1 : acc0,
+ dst0, !aop, aop ? acc0 : acc1, aop, aop ? acc1 : acc0,
+ amod1 (s, x));
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ val1 = acc0 + acc1;
+ if (aop)
+ val0 = acc0 - acc1;
+ else
+ val0 = acc1 - acc0;
+
+ sval0 = saturate_s32 (val0, &sat);
+ sat_i = sat;
+ sval1 = saturate_s32 (val1, &sat);
+ sat_i |= sat;
+ if (s)
+ {
+ val0 = sval0;
+ val1 = sval1;
+ }
+
+ STORE (DREG (dst0), val0);
+ STORE (DREG (dst1), val1);
+ SET_ASTATREG (v, sat_i);
+ if (sat_i)
+ SET_ASTATREG (vs, sat_i);
+ SET_ASTATREG (an, val0 & 0x80000000 || val1 & 0x80000000);
+ SET_ASTATREG (az, val0 == 0 || val1 == 0);
+ SET_ASTATREG (ac1, (bu40)~acc0 < (bu40)acc1);
+ if (aop)
+ SET_ASTATREG (ac0, !!((bu40)acc1 <= (bu40)acc0));
+ else
+ SET_ASTATREG (ac0, !!((bu40)acc0 <= (bu40)acc1));
+ }
+ else if (aop == 0 && aopcde == 18)
+ {
+ bu40 acc0 = get_extended_acc (cpu, 0);
+ bu40 acc1 = get_extended_acc (cpu, 1);
+ bu32 s0L = DREG (src0);
+ bu32 s0H = DREG (src0 + 1);
+ bu32 s1L = DREG (src1);
+ bu32 s1H = DREG (src1 + 1);
+ bu32 s0, s1;
+ bs16 tmp0, tmp1, tmp2, tmp3;
+
+ /* This instruction is only defined for register pairs R1:0 and R3:2. */
+ if (!((src0 == 0 || src0 == 2) && (src1 == 0 || src1 == 2)))
+ illegal_instruction (cpu);
+
+ TRACE_INSN (cpu, "SAA (R%i:%i, R%i:%i)%s", src0 + 1, src0,
+ src1 + 1, src1, s ? " (R)" :"");
+
+ /* Bit s determines the order of the two registers from a pair:
+ if s=0 the low-order bytes come from the low reg in the pair,
+ and if s=1 the low-order bytes come from the high reg. */
+
+ if (s)
+ {
+ s0 = algn (s0H, s0L, IREG (0) & 3);
+ s1 = algn (s1H, s1L, IREG (1) & 3);
+ }
+ else
+ {
+ s0 = algn (s0L, s0H, IREG (0) & 3);
+ s1 = algn (s1L, s1H, IREG (1) & 3);
+ }
+
+ /* Find the absolute difference between pairs, make it
+ absolute, then add it to the existing accumulator half. */
+ /* Byte 0 */
+ tmp0 = ((s0 << 24) >> 24) - ((s1 << 24) >> 24);
+ tmp1 = ((s0 << 16) >> 24) - ((s1 << 16) >> 24);
+ tmp2 = ((s0 << 8) >> 24) - ((s1 << 8) >> 24);
+ tmp3 = ((s0 << 0) >> 24) - ((s1 << 0) >> 24);
+
+ tmp0 = (tmp0 < 0) ? -tmp0 : tmp0;
+ tmp1 = (tmp1 < 0) ? -tmp1 : tmp1;
+ tmp2 = (tmp2 < 0) ? -tmp2 : tmp2;
+ tmp3 = (tmp3 < 0) ? -tmp3 : tmp3;
+
+ s0L = saturate_u16 ((bu32)tmp0 + ((acc0 >> 0) & 0xffff), 0);
+ s0H = saturate_u16 ((bu32)tmp1 + ((acc0 >> 16) & 0xffff), 0);
+ s1L = saturate_u16 ((bu32)tmp2 + ((acc1 >> 0) & 0xffff), 0);
+ s1H = saturate_u16 ((bu32)tmp3 + ((acc1 >> 16) & 0xffff), 0);
+
+ STORE (AWREG (0), (s0H << 16) | (s0L & 0xFFFF));
+ STORE (AXREG (0), 0);
+ STORE (AWREG (1), (s1H << 16) | (s1L & 0xFFFF));
+ STORE (AXREG (1), 0);
+ }
+ else if (aop == 3 && aopcde == 18)
+ {
+ TRACE_INSN (cpu, "DISALGNEXCPT");
+ DIS_ALGN_EXPT |= 1;
+ }
+ else if ((aop == 0 || aop == 1) && aopcde == 20)
+ {
+ bu32 s0, s0L, s0H, s1, s1L, s1H;
+ const char * const opts[] = { "", " (R)", " (T)", " (T, R)" };
+
+ TRACE_INSN (cpu, "R%i = BYTEOP1P (R%i:%i, R%i:%i)%s;", dst0,
+ src0 + 1, src0, src1 + 1, src1, opts[s + (aop << 1)]);
+
+ if (src0 == src1)
+ illegal_instruction_combination (cpu);
+
+ s0L = DREG (src0);
+ s0H = DREG (src0 + 1);
+ s1L = DREG (src1);
+ s1H = DREG (src1 + 1);
+ if (s)
+ {
+ s0 = algn (s0H, s0L, IREG (0) & 3);
+ s1 = algn (s1H, s1L, IREG (1) & 3);
+ }
+ else
+ {
+ s0 = algn (s0L, s0H, IREG (0) & 3);
+ s1 = algn (s1L, s1H, IREG (1) & 3);
+ }
+
+ SET_DREG (dst0,
+ (((((s0 >> 0) & 0xff) + ((s1 >> 0) & 0xff) + !aop) >> 1) << 0) |
+ (((((s0 >> 8) & 0xff) + ((s1 >> 8) & 0xff) + !aop) >> 1) << 8) |
+ (((((s0 >> 16) & 0xff) + ((s1 >> 16) & 0xff) + !aop) >> 1) << 16) |
+ (((((s0 >> 24) & 0xff) + ((s1 >> 24) & 0xff) + !aop) >> 1) << 24));
+ }
+ else if (aop == 0 && aopcde == 21)
+ {
+ bu32 s0, s0L, s0H, s1, s1L, s1H;
+
+ TRACE_INSN (cpu, "(R%i, R%i) = BYTEOP16P (R%i:%i, R%i:%i)%s;", dst1, dst0,
+ src0 + 1, src0, src1 + 1, src1, s ? " (R)" : "");
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ s0L = DREG (src0);
+ s0H = DREG (src0 + 1);
+ s1L = DREG (src1);
+ s1H = DREG (src1 + 1);
+ if (s)
+ {
+ s0 = algn (s0H, s0L, IREG (0) & 3);
+ s1 = algn (s1H, s1L, IREG (1) & 3);
+ }
+ else
+ {
+ s0 = algn (s0L, s0H, IREG (0) & 3);
+ s1 = algn (s1L, s1H, IREG (1) & 3);
+ }
+
+ SET_DREG (dst0,
+ ((((s0 >> 0) & 0xff) + ((s1 >> 0) & 0xff)) << 0) |
+ ((((s0 >> 8) & 0xff) + ((s1 >> 8) & 0xff)) << 16));
+ SET_DREG (dst1,
+ ((((s0 >> 16) & 0xff) + ((s1 >> 16) & 0xff)) << 0) |
+ ((((s0 >> 24) & 0xff) + ((s1 >> 24) & 0xff)) << 16));
+ }
+ else if (aop == 1 && aopcde == 21)
+ {
+ bu32 s0, s0L, s0H, s1, s1L, s1H;
+
+ TRACE_INSN (cpu, "(R%i, R%i) = BYTEOP16M (R%i:%i, R%i:%i)%s;", dst1, dst0,
+ src0 + 1, src0, src1 + 1, src1, s ? " (R)" : "");
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ s0L = DREG (src0);
+ s0H = DREG (src0 + 1);
+ s1L = DREG (src1);
+ s1H = DREG (src1 + 1);
+ if (s)
+ {
+ s0 = algn (s0H, s0L, IREG (0) & 3);
+ s1 = algn (s1H, s1L, IREG (1) & 3);
+ }
+ else
+ {
+ s0 = algn (s0L, s0H, IREG (0) & 3);
+ s1 = algn (s1L, s1H, IREG (1) & 3);
+ }
+
+ SET_DREG (dst0,
+ (((((s0 >> 0) & 0xff) - ((s1 >> 0) & 0xff)) << 0) & 0xffff) |
+ (((((s0 >> 8) & 0xff) - ((s1 >> 8) & 0xff)) << 16)));
+ SET_DREG (dst1,
+ (((((s0 >> 16) & 0xff) - ((s1 >> 16) & 0xff)) << 0) & 0xffff) |
+ (((((s0 >> 24) & 0xff) - ((s1 >> 24) & 0xff)) << 16)));
+ }
+ else if (aop == 1 && aopcde == 7)
+ {
+ TRACE_INSN (cpu, "R%i = MIN (R%i, R%i);", dst0, src0, src1);
+ SET_DREG (dst0, min32 (cpu, DREG (src0), DREG (src1)));
+ }
+ else if (aop == 0 && aopcde == 7)
+ {
+ TRACE_INSN (cpu, "R%i = MAX (R%i, R%i);", dst0, src0, src1);
+ SET_DREG (dst0, max32 (cpu, DREG (src0), DREG (src1)));
+ }
+ else if (aop == 2 && aopcde == 7)
+ {
+ bu32 val = DREG (src0);
+ int v;
+
+ TRACE_INSN (cpu, "R%i = ABS R%i;", dst0, src0);
+
+ if (val >> 31)
+ val = -val;
+ v = (val == 0x80000000);
+ if (v)
+ val = 0x7fffffff;
+ SET_DREG (dst0, val);
+
+ SET_ASTATREG (v, v);
+ if (v)
+ SET_ASTATREG (vs, 1);
+ setflags_nz (cpu, val);
+ }
+ else if (aop == 3 && aopcde == 7)
+ {
+ bu32 val = DREG (src0);
+
+ TRACE_INSN (cpu, "R%i = - R%i %s;", dst0, src0, amod1 (s, 0));
+
+ if (s && val == 0x80000000)
+ {
+ val = 0x7fffffff;
+ SET_ASTATREG (v, 1);
+ SET_ASTATREG (vs, 1);
+ }
+ else if (val == 0x80000000)
+ val = 0x80000000;
+ else
+ val = -val;
+ SET_DREG (dst0, val);
+
+ SET_ASTATREG (az, val == 0);
+ SET_ASTATREG (an, val & 0x80000000);
+ }
+ else if (aop == 2 && aopcde == 6)
+ {
+ bu32 in = DREG (src0);
+ bu32 hi = (in & 0x80000000 ? (bu32)-(bs16)(in >> 16) : in >> 16) << 16;
+ bu32 lo = (in & 0x8000 ? (bu32)-(bs16)(in & 0xFFFF) : in) & 0xFFFF;
+ int v;
+
+ TRACE_INSN (cpu, "R%i = ABS R%i (V);", dst0, src0);
+
+ v = 0;
+ if (hi == 0x80000000)
+ {
+ hi = 0x7fff0000;
+ v = 1;
+ }
+ if (lo == 0x8000)
+ {
+ lo = 0x7fff;
+ v = 1;
+ }
+ SET_DREG (dst0, hi | lo);
+
+ SET_ASTATREG (v, v);
+ if (v)
+ SET_ASTATREG (vs, 1);
+ setflags_nz_2x16 (cpu, DREG (dst0));
+ }
+ else if (aop == 1 && aopcde == 6)
+ {
+ TRACE_INSN (cpu, "R%i = MIN (R%i, R%i) (V);", dst0, src0, src1);
+ SET_DREG (dst0, min2x16 (cpu, DREG (src0), DREG (src1)));
+ }
+ else if (aop == 0 && aopcde == 6)
+ {
+ TRACE_INSN (cpu, "R%i = MAX (R%i, R%i) (V);", dst0, src0, src1);
+ SET_DREG (dst0, max2x16 (cpu, DREG (src0), DREG (src1)));
+ }
+ else if (aop == 0 && aopcde == 24)
+ {
+ TRACE_INSN (cpu, "R%i = BYTEPACK (R%i, R%i);", dst0, src0, src1);
+ SET_DREG (dst0,
+ (((DREG (src0) >> 0) & 0xff) << 0) |
+ (((DREG (src0) >> 16) & 0xff) << 8) |
+ (((DREG (src1) >> 0) & 0xff) << 16) |
+ (((DREG (src1) >> 16) & 0xff) << 24));
+ }
+ else if (aop == 1 && aopcde == 24)
+ {
+ int order, lo, hi;
+ bu64 comb_src;
+ bu8 bytea, byteb, bytec, byted;
+
+ TRACE_INSN (cpu, "(R%i, R%i) = BYTEUNPACK R%i:%i%s;",
+ dst1, dst0, src0 + 1, src0, s ? " (R)" : "");
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ order = IREG (0) & 0x3;
+ if (s)
+ hi = src0, lo = src0 + 1;
+ else
+ hi = src0 + 1, lo = src0;
+ comb_src = (((bu64)DREG (hi)) << 32) | DREG (lo);
+ bytea = (comb_src >> (0 + 8 * order));
+ byteb = (comb_src >> (8 + 8 * order));
+ bytec = (comb_src >> (16 + 8 * order));
+ byted = (comb_src >> (24 + 8 * order));
+ SET_DREG (dst0, bytea | ((bu32)byteb << 16));
+ SET_DREG (dst1, bytec | ((bu32)byted << 16));
+ }
+ else if (aopcde == 13)
+ {
+ const char *searchmodes[] = { "GT", "GE", "LT", "LE" };
+ bool up_hi, up_lo;
+ bs16 a0_lo, a1_lo, src_hi, src_lo;
+
+ TRACE_INSN (cpu, "(R%i, R%i) = SEARCH R%i (%s);",
+ dst1, dst0, src0, searchmodes[aop]);
+
+ if (dst0 == dst1)
+ illegal_instruction_combination (cpu);
+
+ up_hi = up_lo = false;
+ a0_lo = AWREG (0);
+ a1_lo = AWREG (1);
+ src_lo = DREG (src0);
+ src_hi = DREG (src0) >> 16;
+
+ switch (aop)
+ {
+ case 0:
+ up_hi = (src_hi > a1_lo);
+ up_lo = (src_lo > a0_lo);
+ break;
+ case 1:
+ up_hi = (src_hi >= a1_lo);
+ up_lo = (src_lo >= a0_lo);
+ break;
+ case 2:
+ up_hi = (src_hi < a1_lo);
+ up_lo = (src_lo < a0_lo);
+ break;
+ case 3:
+ up_hi = (src_hi <= a1_lo);
+ up_lo = (src_lo <= a0_lo);
+ break;
+ }
+
+ if (up_hi)
+ {
+ SET_AREG (1, src_hi);
+ SET_DREG (dst1, PREG (0));
+ }
+ if (up_lo)
+ {
+ SET_AREG (0, src_lo);
+ SET_DREG (dst0, PREG (0));
+ }
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_dsp32shift_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* dsp32shift
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
+ |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
+ int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
+ int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
+ int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
+ int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
+ int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
+ int M = ((iw0 >> (DSP32Shift_M_bits - 16)) & DSP32Shift_M_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32shift);
+ TRACE_EXTRACT (cpu, "%s: M:%i sopcde:%i sop:%i HLs:%i dst0:%i src0:%i src1:%i",
+ __func__, M, sopcde, sop, HLs, dst0, src0, src1);
+
+ if ((sop == 0 || sop == 1) && sopcde == 0)
+ {
+ bu16 val;
+ bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+
+ TRACE_INSN (cpu, "R%i.%c = ASHIFT R%i.%c BY R%i.L%s;",
+ dst0, HLs < 2 ? 'L' : 'H',
+ src1, HLs & 1 ? 'H' : 'L',
+ src0, sop == 1 ? " (S)" : "");
+
+ if ((HLs & 1) == 0)
+ val = (bu16)(DREG (src1) & 0xFFFF);
+ else
+ val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
+
+ /* Positive shift magnitudes produce Logical Left shifts.
+ Negative shift magnitudes produce Arithmetic Right shifts. */
+ if (shft <= 0)
+ val = ashiftrt (cpu, val, -shft, 16);
+ else
+ val = lshift (cpu, val, shft, 16, sop == 1);
+
+ if ((HLs & 2) == 0)
+ STORE (DREG (dst0), REG_H_L (DREG (dst0), val));
+ else
+ STORE (DREG (dst0), REG_H_L (val << 16, DREG (dst0)));
+ }
+ else if (sop == 2 && sopcde == 0)
+ {
+ bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+ bu16 val;
+
+ TRACE_INSN (cpu, "R%i.%c = LSHIFT R%i.%c BY R%i.L;",
+ dst0, HLs < 2 ? 'L' : 'H',
+ src1, HLs & 1 ? 'H' : 'L', src0);
+
+ if ((HLs & 1) == 0)
+ val = (bu16)(DREG (src1) & 0xFFFF);
+ else
+ val = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
+
+ if (shft < 0)
+ val = val >> (-1 * shft);
+ else
+ val = val << shft;
+
+ if ((HLs & 2) == 0)
+ SET_DREG (dst0, REG_H_L (DREG (dst0), val));
+ else
+ SET_DREG (dst0, REG_H_L (val << 16, DREG (dst0)));
+
+ SET_ASTATREG (az, !((val & 0xFFFF0000) == 0) || ((val & 0xFFFF) == 0));
+ SET_ASTATREG (an, (!!(val & 0x80000000)) ^ (!!(val & 0x8000)));
+ SET_ASTATREG (v, 0);
+ }
+ else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0))
+ {
+ int shift = imm6 (DREG (src0) & 0xFFFF);
+ bu32 cc = CCREG;
+ bu40 acc = get_unextended_acc (cpu, HLs);
+
+ TRACE_INSN (cpu, "A%i = ROT A%i BY R%i.L;", HLs, HLs, src0);
+ TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc);
+
+ acc = rot40 (acc, shift, &cc);
+ SET_AREG (HLs, acc);
+ if (shift)
+ SET_CCREG (cc);
+ }
+ else if (sop == 0 && sopcde == 3 && (HLs == 0 || HLs == 1))
+ {
+ bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+ bu64 val = get_extended_acc (cpu, HLs);
+
+ HLs = !!HLs;
+ TRACE_INSN (cpu, "A%i = ASHIFT A%i BY R%i.L;", HLs, HLs, src0);
+ TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i", HLs, val, shft);
+
+ if (shft <= 0)
+ val = ashiftrt (cpu, val, -shft, 40);
+ else
+ val = lshift (cpu, val, shft, 40, 0);
+
+ STORE (AXREG (HLs), (val >> 32) & 0xff);
+ STORE (AWREG (HLs), (val & 0xffffffff));
+ }
+ else if (sop == 1 && sopcde == 3 && (HLs == 0 || HLs == 1))
+ {
+ bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+ bu64 val;
+
+ HLs = !!HLs;
+ TRACE_INSN (cpu, "A%i = LSHIFT A%i BY R%i.L;", HLs, HLs, src0);
+ val = get_extended_acc (cpu, HLs);
+
+ if (shft <= 0)
+ val = lshiftrt (cpu, val, -shft, 40);
+ else
+ val = lshift (cpu, val, shft, 40, 0);
+
+ STORE (AXREG (HLs), (val >> 32) & 0xff);
+ STORE (AWREG (HLs), (val & 0xffffffff));
+ }
+ else if ((sop == 0 || sop == 1) && sopcde == 1)
+ {
+ bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+ bu16 val0, val1;
+ bu32 astat;
+
+ TRACE_INSN (cpu, "R%i = ASHIFT R%i BY R%i.L (V%s);",
+ dst0, src1, src0, sop == 1 ? ",S" : "");
+
+ val0 = (bu16)DREG (src1) & 0xFFFF;
+ val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
+
+ if (shft <= 0)
+ {
+ val0 = ashiftrt (cpu, val0, -shft, 16);
+ astat = ASTAT;
+ val1 = ashiftrt (cpu, val1, -shft, 16);
+ }
+ else
+ {
+ val0 = lshift (cpu, val0, shft, 16, sop == 1);
+ astat = ASTAT;
+ val1 = lshift (cpu, val1, shft, 16, sop == 1);
+ }
+ SET_ASTAT (ASTAT | astat);
+ STORE (DREG (dst0), (val1 << 16) | val0);
+ }
+ else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 2)
+ {
+ /* dregs = [LA]SHIFT dregs BY dregs_lo (opt_S) */
+ /* sop == 1 : opt_S */
+ bu32 v = DREG (src1);
+ /* LSHIFT uses sign extended low 6 bits of dregs_lo. */
+ bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+
+ TRACE_INSN (cpu, "R%i = %cSHIFT R%i BY R%i.L%s;", dst0,
+ shft && sop != 2 ? 'A' : 'L', src1, src0,
+ sop == 1 ? " (S)" : "");
+
+ if (shft < 0)
+ {
+ if (sop == 2)
+ STORE (DREG (dst0), lshiftrt (cpu, v, -shft, 32));
+ else
+ STORE (DREG (dst0), ashiftrt (cpu, v, -shft, 32));
+ }
+ else
+ STORE (DREG (dst0), lshift (cpu, v, shft, 32, sop == 1));
+ }
+ else if (sop == 3 && sopcde == 2)
+ {
+ int shift = imm6 (DREG (src0) & 0xFFFF);
+ bu32 src = DREG (src1);
+ bu32 ret, cc = CCREG;
+
+ TRACE_INSN (cpu, "R%i = ROT R%i BY R%i.L;", dst0, src1, src0);
+ TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i",
+ dst0, DREG (dst0), src1, src, shift, cc);
+
+ ret = rot32 (src, shift, &cc);
+ STORE (DREG (dst0), ret);
+ if (shift)
+ SET_CCREG (cc);
+ }
+ else if (sop == 2 && sopcde == 1)
+ {
+ bs32 shft = (bs8)(DREG (src0) << 2) >> 2;
+ bu16 val0, val1;
+ bu32 astat;
+
+ TRACE_INSN (cpu, "R%i = LSHIFT R%i BY R%i.L (V);", dst0, src1, src0);
+
+ val0 = (bu16)DREG (src1) & 0xFFFF;
+ val1 = (bu16)((DREG (src1) & 0xFFFF0000) >> 16);
+
+ if (shft <= 0)
+ {
+ val0 = lshiftrt (cpu, val0, -shft, 16);
+ astat = ASTAT;
+ val1 = lshiftrt (cpu, val1, -shft, 16);
+ }
+ else
+ {
+ val0 = lshift (cpu, val0, shft, 16, 0);
+ astat = ASTAT;
+ val1 = lshift (cpu, val1, shft, 16, 0);
+ }
+ SET_ASTAT (ASTAT | astat);
+ STORE (DREG (dst0), (val1 << 16) | val0);
+ }
+ else if (sopcde == 4)
+ {
+ bu32 sv0 = DREG (src0);
+ bu32 sv1 = DREG (src1);
+ TRACE_INSN (cpu, "R%i = PACK (R%i.%c, R%i.%c);", dst0,
+ src1, sop & 2 ? 'H' : 'L',
+ src0, sop & 1 ? 'H' : 'L');
+ if (sop & 1)
+ sv0 >>= 16;
+ if (sop & 2)
+ sv1 >>= 16;
+ SET_DREG (dst0, (sv1 << 16) | (sv0 & 0xFFFF));
+ }
+ else if (sop == 0 && sopcde == 5)
+ {
+ bu32 sv1 = DREG (src1);
+ TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i;", dst0, src1);
+ SET_DREG_L (dst0, signbits (sv1, 32));
+ }
+ else if (sop == 1 && sopcde == 5)
+ {
+ bu32 sv1 = DREG (src1);
+ TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i.L;", dst0, src1);
+ SET_DREG_L (dst0, signbits (sv1, 16));
+ }
+ else if (sop == 2 && sopcde == 5)
+ {
+ bu32 sv1 = DREG (src1);
+ TRACE_INSN (cpu, "R%i.L = SIGNBITS R%i.H;", dst0, src1);
+ SET_DREG_L (dst0, signbits (sv1 >> 16, 16));
+ }
+ else if ((sop == 0 || sop == 1) && sopcde == 6)
+ {
+ bu64 acc = AXREG (sop);
+ TRACE_INSN (cpu, "R%i.L = SIGNBITS A%i;", dst0, sop);
+ acc <<= 32;
+ acc |= AWREG (sop);
+ SET_DREG_L (dst0, signbits (acc, 40) & 0xFFFF);
+ }
+ else if (sop == 3 && sopcde == 6)
+ {
+ bu32 v = ones (DREG (src1));
+ TRACE_INSN (cpu, "R%i.L = ONES R%i;", dst0, src1);
+ SET_DREG_L (dst0, v);
+ }
+ else if (sop == 0 && sopcde == 7)
+ {
+ bu16 sv1 = (bu16)signbits (DREG (src1), 32);
+ bu16 sv0 = (bu16)DREG (src0);
+ bu16 dst_lo;
+
+ TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i, R%i.L);", dst0, src1, src0);
+
+ if ((sv1 & 0x1f) < (sv0 & 0x1f))
+ dst_lo = sv1;
+ else
+ dst_lo = sv0;
+ STORE (DREG (dst0), REG_H_L (DREG (dst0), dst_lo));
+ }
+ else if (sop == 1 && sopcde == 7)
+ {
+ /* Exponent adjust on two 16-bit inputs. Select
+ smallest norm among 3 inputs. */
+ bs16 src1_hi = (DREG (src1) & 0xFFFF0000) >> 16;
+ bs16 src1_lo = (DREG (src1) & 0xFFFF);
+ bu16 src0_lo = (DREG (src0) & 0xFFFF);
+ bu16 tmp_hi, tmp_lo, tmp;
+
+ TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i, R%i.L) (V);", dst0, src1, src0);
+
+ tmp_hi = signbits (src1_hi, 16);
+ tmp_lo = signbits (src1_lo, 16);
+
+ if ((tmp_hi & 0xf) < (tmp_lo & 0xf))
+ if ((tmp_hi & 0xf) < (src0_lo & 0xf))
+ tmp = tmp_hi;
+ else
+ tmp = src0_lo;
+ else
+ if ((tmp_lo & 0xf) < (src0_lo & 0xf))
+ tmp = tmp_lo;
+ else
+ tmp = src0_lo;
+ STORE (DREG (dst0), REG_H_L (DREG (dst0), tmp));
+ }
+ else if (sop == 2 && sopcde == 7)
+ {
+ /* Exponent adjust on single 16-bit register. */
+ bu16 tmp;
+ bu16 src0_lo = (bu16)(DREG (src0) & 0xFFFF);
+
+ TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i.L, R%i.L);", dst0, src1, src0);
+
+ tmp = signbits (DREG (src1) & 0xFFFF, 16);
+
+ if ((tmp & 0xf) < (src0_lo & 0xf))
+ SET_DREG_L (dst0, tmp);
+ else
+ SET_DREG_L (dst0, src0_lo);
+ }
+ else if (sop == 3 && sopcde == 7)
+ {
+ bu16 tmp;
+ bu16 src0_lo = (bu16)(DREG (src0) & 0xFFFF);
+
+ TRACE_INSN (cpu, "R%i.L = EXPADJ (R%i.H, R%i.L);", dst0, src1, src0);
+
+ tmp = signbits ((DREG (src1) & 0xFFFF0000) >> 16, 16);
+
+ if ((tmp & 0xf) < (src0_lo & 0xf))
+ SET_DREG_L (dst0, tmp);
+ else
+ SET_DREG_L (dst0, src0_lo);
+ }
+ else if (sop == 0 && sopcde == 8)
+ {
+ bu64 acc = get_unextended_acc (cpu, 0);
+ bu32 s0, s1;
+
+ TRACE_INSN (cpu, "BITMUX (R%i, R%i, A0) (ASR);", src0, src1);
+
+ if (src0 == src1)
+ illegal_instruction_combination (cpu);
+
+ s0 = DREG (src0);
+ s1 = DREG (src1);
+ acc = (acc >> 2) |
+ (((bu64)s0 & 1) << 38) |
+ (((bu64)s1 & 1) << 39);
+ SET_DREG (src0, s0 >> 1);
+ SET_DREG (src1, s1 >> 1);
+
+ SET_AREG (0, acc);
+ }
+ else if (sop == 1 && sopcde == 8)
+ {
+ bu64 acc = get_unextended_acc (cpu, 0);
+ bu32 s0, s1;
+
+ TRACE_INSN (cpu, "BITMUX (R%i, R%i, A0) (ASL);", src0, src1);
+
+ if (src0 == src1)
+ illegal_instruction_combination (cpu);
+
+ s0 = DREG (src0);
+ s1 = DREG (src1);
+ acc = (acc << 2) |
+ ((s0 >> 31) & 1) |
+ ((s1 >> 30) & 2);
+ SET_DREG (src0, s0 << 1);
+ SET_DREG (src1, s1 << 1);
+
+ SET_AREG (0, acc);
+ }
+ else if ((sop == 0 || sop == 1) && sopcde == 9)
+ {
+ bs40 acc0 = get_extended_acc (cpu, 0);
+ bs16 sL, sH, out;
+
+ TRACE_INSN (cpu, "R%i.L = VIT_MAX (R%i) (AS%c);",
+ dst0, src1, sop & 1 ? 'R' : 'L');
+
+ sL = DREG (src1);
+ sH = DREG (src1) >> 16;
+
+ if (sop & 1)
+ acc0 >>= 1;
+ else
+ acc0 <<= 1;
+
+ if (((sH - sL) & 0x8000) == 0)
+ {
+ out = sH;
+ acc0 |= (sop & 1) ? 0x80000000 : 1;
+ }
+ else
+ out = sL;
+
+ SET_AREG (0, acc0);
+ SET_DREG (dst0, REG_H_L (DREG (dst0), out));
+ }
+ else if ((sop == 2 || sop == 3) && sopcde == 9)
+ {
+ bs40 acc0 = get_extended_acc (cpu, 0);
+ bs16 s0L, s0H, s1L, s1H, out0, out1;
+
+ TRACE_INSN (cpu, "R%i = VIT_MAX (R%i, R%i) (AS%c);",
+ dst0, src1, src0, sop & 1 ? 'R' : 'L');
+
+ s0L = DREG (src0);
+ s0H = DREG (src0) >> 16;
+ s1L = DREG (src1);
+ s1H = DREG (src1) >> 16;
+
+ if (sop & 1)
+ acc0 >>= 2;
+ else
+ acc0 <<= 2;
+
+ if (((s0H - s0L) & 0x8000) == 0)
+ {
+ out0 = s0H;
+ acc0 |= (sop & 1) ? 0x40000000 : 2;
+ }
+ else
+ out0 = s0L;
+
+ if (((s1H - s1L) & 0x8000) == 0)
+ {
+ out1 = s1H;
+ acc0 |= (sop & 1) ? 0x80000000 : 1;
+ }
+ else
+ out1 = s1L;
+
+ SET_AREG (0, acc0);
+ SET_DREG (dst0, REG_H_L (out1 << 16, out0));
+ }
+ else if (sop == 0 && sopcde == 10)
+ {
+ bu32 v = DREG (src0);
+ bu32 x = DREG (src1);
+ bu32 mask = (1 << (v & 0x1f)) - 1;
+ TRACE_INSN (cpu, "R%i = EXTRACT (R%i, R%i.L) (Z);", dst0, src1, src0);
+ x >>= ((v >> 8) & 0x1f);
+ SET_DREG (dst0, x & mask);
+ setflags_logical (cpu, DREG (dst0));
+ }
+ else if (sop == 1 && sopcde == 10)
+ {
+ bu32 v = DREG (src0);
+ bu32 x = DREG (src1);
+ bu32 sgn = (1 << (v & 0x1f)) >> 1;
+ bu32 mask = (1 << (v & 0x1f)) - 1;
+ TRACE_INSN (cpu, "R%i = EXTRACT (R%i, R%i.L) (X);", dst0, src1, src0);
+ x >>= ((v >> 8) & 0x1f);
+ x &= mask;
+ if (x & sgn)
+ x |= ~mask;
+ SET_DREG (dst0, x);
+ setflags_logical (cpu, DREG (dst0));
+ }
+ else if ((sop == 2 || sop == 3) && sopcde == 10)
+ {
+ /* The first dregs is the "background" while the second dregs is the
+ "foreground". The fg reg is used to overlay the bg reg and is:
+ | nnnn nnnn | nnnn nnnn | xxxp pppp | xxxL LLLL |
+ n = the fg bit field
+ p = bit position in bg reg to start LSB of fg field
+ L = number of fg bits to extract
+ Using (X) sign-extends the fg bit field. */
+ bu32 fg = DREG (src0);
+ bu32 bg = DREG (src1);
+ bu32 len = fg & 0x1f;
+ bu32 mask = (1 << MIN (16, len)) - 1;
+ bu32 fgnd = (fg >> 16) & mask;
+ int shft = ((fg >> 8) & 0x1f);
+
+ TRACE_INSN (cpu, "R%i = DEPOSIT (R%i, R%i)%s;", dst0, src1, src0,
+ sop == 3 ? " (X)" : "");
+
+ if (sop == 3)
+ {
+ /* Sign extend the fg bit field. */
+ mask = -1;
+ fgnd = ((bs32)(bs16)(fgnd << (16 - len))) >> (16 - len);
+ }
+ fgnd <<= shft;
+ mask <<= shft;
+ bg &= ~mask;
+
+ SET_DREG (dst0, bg | fgnd);
+ setflags_logical (cpu, DREG (dst0));
+ }
+ else if (sop == 0 && sopcde == 11)
+ {
+ bu64 acc0 = get_unextended_acc (cpu, 0);
+
+ TRACE_INSN (cpu, "R%i.L = CC = BXORSHIFT (A0, R%i);", dst0, src0);
+
+ acc0 <<= 1;
+ SET_CCREG (xor_reduce (acc0, DREG (src0)));
+ SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
+ SET_AREG (0, acc0);
+ }
+ else if (sop == 1 && sopcde == 11)
+ {
+ bu64 acc0 = get_unextended_acc (cpu, 0);
+
+ TRACE_INSN (cpu, "R%i.L = CC = BXOR (A0, R%i);", dst0, src0);
+
+ SET_CCREG (xor_reduce (acc0, DREG (src0)));
+ SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
+ }
+ else if (sop == 0 && sopcde == 12)
+ {
+ bu64 acc0 = get_unextended_acc (cpu, 0);
+ bu64 acc1 = get_unextended_acc (cpu, 1);
+
+ TRACE_INSN (cpu, "A0 = BXORSHIFT (A0, A1, CC);");
+
+ acc0 = (acc0 << 1) | (CCREG ^ xor_reduce (acc0, acc1));
+ SET_AREG (0, acc0);
+ }
+ else if (sop == 1 && sopcde == 12)
+ {
+ bu64 acc0 = get_unextended_acc (cpu, 0);
+ bu64 acc1 = get_unextended_acc (cpu, 1);
+
+ TRACE_INSN (cpu, "R%i.L = CC = BXOR (A0, A1, CC);", dst0);
+
+ SET_CCREG (CCREG ^ xor_reduce (acc0, acc1));
+ acc0 = (acc0 << 1) | CCREG;
+ SET_DREG (dst0, REG_H_L (DREG (dst0), CCREG));
+ }
+ else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 13)
+ {
+ int shift = (sop + 1) * 8;
+ TRACE_INSN (cpu, "R%i = ALIGN%i (R%i, R%i);", dst0, shift, src1, src0);
+ SET_DREG (dst0, (DREG (src1) << (32 - shift)) | (DREG (src0) >> shift));
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_dsp32shiftimm_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1)
+{
+ /* dsp32shiftimm
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
+ |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src1 = ((iw1 >> DSP32ShiftImm_src1_bits) & DSP32ShiftImm_src1_mask);
+ int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
+ int bit8 = ((iw1 >> 8) & 0x1);
+ int immag = ((iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
+ int newimmag = (-(iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
+ int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
+ int M = ((iw0 >> (DSP32ShiftImm_M_bits - 16)) & DSP32ShiftImm_M_mask);
+ int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
+ int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32shiftimm);
+ TRACE_EXTRACT (cpu, "%s: M:%i sopcde:%i sop:%i HLs:%i dst0:%i immag:%#x src1:%i",
+ __func__, M, sopcde, sop, HLs, dst0, immag, src1);
+
+ if (sopcde == 0)
+ {
+ bu16 in = DREG (src1) >> ((HLs & 1) ? 16 : 0);
+ bu16 result;
+ bu32 v;
+
+ if (sop == 0)
+ {
+ TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i;",
+ dst0, (HLs & 2) ? 'H' : 'L',
+ src1, (HLs & 1) ? 'H' : 'L', newimmag);
+ result = ashiftrt (cpu, in, newimmag, 16);
+ }
+ else if (sop == 1 && bit8 == 0)
+ {
+ TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i (S);",
+ dst0, (HLs & 2) ? 'H' : 'L',
+ src1, (HLs & 1) ? 'H' : 'L', immag);
+ result = lshift (cpu, in, immag, 16, 1);
+ }
+ else if (sop == 1 && bit8)
+ {
+ TRACE_INSN (cpu, "R%i.%c = R%i.%c >>> %i (S);",
+ dst0, (HLs & 2) ? 'H' : 'L',
+ src1, (HLs & 1) ? 'H' : 'L', immag);
+ result = lshift (cpu, in, immag, 16, 1);
+ }
+ else if (sop == 2 && bit8)
+ {
+ TRACE_INSN (cpu, "R%i.%c = R%i.%c >> %i;",
+ dst0, (HLs & 2) ? 'H' : 'L',
+ src1, (HLs & 1) ? 'H' : 'L', newimmag);
+ result = lshiftrt (cpu, in, newimmag, 16);
+ }
+ else if (sop == 2 && bit8 == 0)
+ {
+ TRACE_INSN (cpu, "R%i.%c = R%i.%c << %i;",
+ dst0, (HLs & 2) ? 'H' : 'L',
+ src1, (HLs & 1) ? 'H' : 'L', immag);
+ result = lshift (cpu, in, immag, 16, 0);
+ }
+ else
+ illegal_instruction (cpu);
+
+ v = DREG (dst0);
+ if (HLs & 2)
+ STORE (DREG (dst0), (v & 0xFFFF) | (result << 16));
+ else
+ STORE (DREG (dst0), (v & 0xFFFF0000) | result);
+ }
+ else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0))
+ {
+ int shift = imm6 (immag);
+ bu32 cc = CCREG;
+ bu40 acc = get_unextended_acc (cpu, HLs);
+
+ TRACE_INSN (cpu, "A%i = ROT A%i BY %i;", HLs, HLs, shift);
+ TRACE_DECODE (cpu, "A%i:%#"PRIx64" shift:%i CC:%i", HLs, acc, shift, cc);
+
+ acc = rot40 (acc, shift, &cc);
+ SET_AREG (HLs, acc);
+ if (shift)
+ SET_CCREG (cc);
+ }
+ else if (sop == 0 && sopcde == 3 && bit8 == 1)
+ {
+ /* Arithmetic shift, so shift in sign bit copies. */
+ bu64 acc;
+ int shift = uimm5 (newimmag);
+ HLs = !!HLs;
+
+ TRACE_INSN (cpu, "A%i = A%i >>> %i;", HLs, HLs, shift);
+
+ acc = get_extended_acc (cpu, HLs);
+ acc >>= shift;
+ /* Sign extend again. */
+ if (acc & (1ULL << 39))
+ acc |= -(1ULL << 39);
+ else
+ acc &= ~(-(1ULL << 39));
+
+ STORE (AXREG (HLs), (acc >> 32) & 0xFF);
+ STORE (AWREG (HLs), acc & 0xFFFFFFFF);
+ }
+ else if ((sop == 0 && sopcde == 3 && bit8 == 0)
+ || (sop == 1 && sopcde == 3))
+ {
+ bu64 acc;
+ int shiftup = uimm5 (immag);
+ int shiftdn = uimm5 (newimmag);
+ HLs = !!HLs;
+
+ TRACE_INSN (cpu, "A%i = A%i %s %i;", HLs, HLs,
+ sop == 0 ? "<<" : ">>",
+ sop == 0 ? shiftup : shiftdn);
+
+ acc = AXREG (HLs);
+ /* Logical shift, so shift in zeroes. */
+ acc &= 0xFF;
+ acc <<= 32;
+ acc |= AWREG (HLs);
+
+ if (sop == 0)
+ acc <<= shiftup;
+ else
+ acc >>= shiftdn;
+
+ SET_AREG (HLs, acc);
+ SET_ASTATREG (an, !!(acc & 0x8000000000ull));
+ SET_ASTATREG (az, acc == 0);
+ }
+ else if (sop == 1 && sopcde == 1 && bit8 == 0)
+ {
+ int count = imm5 (immag);
+ bu16 val0 = DREG (src1) >> 16;
+ bu16 val1 = DREG (src1) & 0xFFFF;
+ bu32 astat;
+
+ TRACE_INSN (cpu, "R%i = R%i << %i (V,S);", dst0, src1, count);
+ val0 = lshift (cpu, val0, count, 16, 1);
+ astat = ASTAT;
+ val1 = lshift (cpu, val1, count, 16, 1);
+ SET_ASTAT (ASTAT | astat);
+
+ STORE (DREG (dst0), (val0 << 16) | val1);
+ }
+ else if (sop == 2 && sopcde == 1 && bit8 == 1)
+ {
+ int count = imm5 (newimmag);
+ bu16 val0 = DREG (src1) & 0xFFFF;
+ bu16 val1 = DREG (src1) >> 16;
+ bu32 astat;
+
+ TRACE_INSN (cpu, "R%i = R%i >> %i (V);", dst0, src1, count);
+ val0 = lshiftrt (cpu, val0, count, 16);
+ astat = ASTAT;
+ val1 = lshiftrt (cpu, val1, count, 16);
+ SET_ASTAT (ASTAT | astat);
+
+ STORE (DREG (dst0), val0 | (val1 << 16));
+ }
+ else if (sop == 2 && sopcde == 1 && bit8 == 0)
+ {
+ int count = imm5 (immag);
+ bu16 val0 = DREG (src1) & 0xFFFF;
+ bu16 val1 = DREG (src1) >> 16;
+ bu32 astat;
+
+ TRACE_INSN (cpu, "R%i = R%i << %i (V);", dst0, src1, count);
+ val0 = lshift (cpu, val0, count, 16, 0);
+ astat = ASTAT;
+ val1 = lshift (cpu, val1, count, 16, 0);
+ SET_ASTAT (ASTAT | astat);
+
+ STORE (DREG (dst0), val0 | (val1 << 16));
+ }
+ else if (sopcde == 1 && (sop == 0 || (sop == 1 && bit8 == 1)))
+ {
+ int count = uimm5 (newimmag);
+ bu16 val0 = DREG (src1) & 0xFFFF;
+ bu16 val1 = DREG (src1) >> 16;
+ bu32 astat;
+
+ TRACE_INSN (cpu, "R%i = R%i >>> %i %s;", dst0, src1, count,
+ sop == 0 ? "(V)" : "(V,S)");
+
+ val0 = ashiftrt (cpu, val0, count, 16);
+ astat = ASTAT;
+ val1 = ashiftrt (cpu, val1, count, 16);
+ SET_ASTAT (ASTAT | astat);
+
+ STORE (DREG (dst0), REG_H_L (val1 << 16, val0));
+ }
+ else if (sop == 1 && sopcde == 2)
+ {
+ int count = imm6 (immag);
+
+ TRACE_INSN (cpu, "R%i = R%i << %i (S);", dst0, src1, count);
+ STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1));
+ }
+ else if (sop == 2 && sopcde == 2)
+ {
+ int count = imm6 (newimmag);
+
+ TRACE_INSN (cpu, "R%i = R%i >> %i;", dst0, src1, count);
+
+ if (count < 0)
+ STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0));
+ else
+ STORE (DREG (dst0), lshiftrt (cpu, DREG (src1), count, 32));
+ }
+ else if (sop == 3 && sopcde == 2)
+ {
+ int shift = imm6 (immag);
+ bu32 src = DREG (src1);
+ bu32 ret, cc = CCREG;
+
+ TRACE_INSN (cpu, "R%i = ROT R%i BY %i;", dst0, src1, shift);
+ TRACE_DECODE (cpu, "R%i:%#x R%i:%#x shift:%i CC:%i",
+ dst0, DREG (dst0), src1, src, shift, cc);
+
+ ret = rot32 (src, shift, &cc);
+ STORE (DREG (dst0), ret);
+ if (shift)
+ SET_CCREG (cc);
+ }
+ else if (sop == 0 && sopcde == 2)
+ {
+ int count = imm6 (newimmag);
+
+ TRACE_INSN (cpu, "R%i = R%i >>> %i;", dst0, src1, count);
+
+ if (count < 0)
+ STORE (DREG (dst0), lshift (cpu, DREG (src1), -count, 32, 0));
+ else
+ STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), count, 32));
+ }
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+outc (SIM_CPU *cpu, char ch)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ sim_io_printf (sd, "%c", ch);
+ if (ch == '\n')
+ sim_io_flush_stdout (sd);
+}
+
+static void
+decode_psedoDEBUG_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* psedoDEBUG
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |.fn....|.grp.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ SIM_DESC sd = CPU_STATE (cpu);
+ int fn = ((iw0 >> PseudoDbg_fn_bits) & PseudoDbg_fn_mask);
+ int grp = ((iw0 >> PseudoDbg_grp_bits) & PseudoDbg_grp_mask);
+ int reg = ((iw0 >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedoDEBUG);
+ TRACE_EXTRACT (cpu, "%s: fn:%i grp:%i reg:%i", __func__, fn, grp, reg);
+
+ if ((reg == 0 || reg == 1) && fn == 3)
+ {
+ TRACE_INSN (cpu, "DBG A%i;", reg);
+ sim_io_printf (sd, "DBG : A%i = %#"PRIx64"\n", reg,
+ get_unextended_acc (cpu, reg));
+ }
+ else if (reg == 3 && fn == 3)
+ {
+ TRACE_INSN (cpu, "ABORT;");
+ cec_exception (cpu, VEC_SIM_ABORT);
+ SET_DREG (0, 1);
+ }
+ else if (reg == 4 && fn == 3)
+ {
+ TRACE_INSN (cpu, "HLT;");
+ cec_exception (cpu, VEC_SIM_HLT);
+ SET_DREG (0, 0);
+ }
+ else if (reg == 5 && fn == 3)
+ unhandled_instruction (cpu, "DBGHALT");
+ else if (reg == 6 && fn == 3)
+ unhandled_instruction (cpu, "DBGCMPLX (dregs)");
+ else if (reg == 7 && fn == 3)
+ unhandled_instruction (cpu, "DBG");
+ else if (grp == 0 && fn == 2)
+ {
+ TRACE_INSN (cpu, "OUTC R%i;", reg);
+ outc (cpu, DREG (reg));
+ }
+ else if (fn == 0)
+ {
+ const char *reg_name = get_allreg_name (grp, reg);
+ TRACE_INSN (cpu, "DBG %s;", reg_name);
+ sim_io_printf (sd, "DBG : %s = 0x%08x\n", reg_name,
+ reg_read (cpu, grp, reg));
+ }
+ else if (fn == 1)
+ unhandled_instruction (cpu, "PRNT allregs");
+ else
+ illegal_instruction (cpu);
+}
+
+static void
+decode_psedoOChar_0 (SIM_CPU *cpu, bu16 iw0)
+{
+ /* psedoOChar
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int ch = ((iw0 >> PseudoChr_ch_bits) & PseudoChr_ch_mask);
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedoOChar);
+ TRACE_EXTRACT (cpu, "%s: ch:%#x", __func__, ch);
+ TRACE_INSN (cpu, "OUTC %#x;", ch);
+
+ outc (cpu, ch);
+}
+
+static void
+decode_psedodbg_assert_0 (SIM_CPU *cpu, bu16 iw0, bu16 iw1, bu32 pc)
+{
+ /* psedodbg_assert
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 0 | - | - | - | dbgop |.grp.......|.regtest...|
+ |.expected......................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ SIM_DESC sd = CPU_STATE (cpu);
+ int expected = ((iw1 >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask);
+ int dbgop = ((iw0 >> (PseudoDbg_Assert_dbgop_bits - 16)) & PseudoDbg_Assert_dbgop_mask);
+ int grp = ((iw0 >> (PseudoDbg_Assert_grp_bits - 16)) & PseudoDbg_Assert_grp_mask);
+ int regtest = ((iw0 >> (PseudoDbg_Assert_regtest_bits - 16)) & PseudoDbg_Assert_regtest_mask);
+ bu16 actual;
+ bu32 val = reg_read (cpu, grp, regtest);
+ const char *reg_name = get_allreg_name (grp, regtest);
+ const char *dbg_name, *dbg_appd;
+
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_psedodbg_assert);
+ TRACE_EXTRACT (cpu, "%s: dbgop:%i grp:%i regtest:%i expected:%#x",
+ __func__, dbgop, grp, regtest, expected);
+
+ if (dbgop == 0 || dbgop == 2)
+ {
+ dbg_name = dbgop == 0 ? "DBGA" : "DBGAL";
+ dbg_appd = dbgop == 0 ? ".L" : "";
+ actual = val;
+ }
+ else if (dbgop == 1 || dbgop == 3)
+ {
+ dbg_name = dbgop == 1 ? "DBGA" : "DBGAH";
+ dbg_appd = dbgop == 1 ? ".H" : "";
+ actual = val >> 16;
+ }
+ else
+ illegal_instruction (cpu);
+
+ TRACE_INSN (cpu, "%s (%s%s, 0x%x);", dbg_name, reg_name, dbg_appd, expected);
+ if (actual != expected)
+ {
+ sim_io_printf (sd, "FAIL at %#x: %s (%s%s, 0x%04x), actual value %#x\n",
+ pc, dbg_name, reg_name, dbg_appd, expected, actual);
+ cec_exception (cpu, VEC_SIM_DBGA);
+ SET_DREG (0, 1);
+ }
+}
+
+static bu32
+_interp_insn_bfin (SIM_CPU *cpu, bu32 pc)
+{
+ bu32 insn_len;
+ bu16 iw0, iw1;
+
+ BFIN_CPU_STATE.multi_pc = pc;
+ iw0 = IFETCH (pc);
+ if ((iw0 & 0xc000) != 0xc000)
+ {
+ /* 16-bit opcode. */
+ insn_len = 2;
+ if (INSN_LEN == 0)
+ INSN_LEN = insn_len;
+
+ TRACE_EXTRACT (cpu, "%s: iw0:%#x", __func__, iw0);
+ if ((iw0 & 0xFF00) == 0x0000)
+ decode_ProgCtrl_0 (cpu, iw0, pc);
+ else if ((iw0 & 0xFFC0) == 0x0240)
+ decode_CaCTRL_0 (cpu, iw0);
+ else if ((iw0 & 0xFF80) == 0x0100)
+ decode_PushPopReg_0 (cpu, iw0);
+ else if ((iw0 & 0xFE00) == 0x0400)
+ decode_PushPopMultiple_0 (cpu, iw0);
+ else if ((iw0 & 0xFE00) == 0x0600)
+ decode_ccMV_0 (cpu, iw0);
+ else if ((iw0 & 0xF800) == 0x0800)
+ decode_CCflag_0 (cpu, iw0);
+ else if ((iw0 & 0xFFE0) == 0x0200)
+ decode_CC2dreg_0 (cpu, iw0);
+ else if ((iw0 & 0xFF00) == 0x0300)
+ decode_CC2stat_0 (cpu, iw0);
+ else if ((iw0 & 0xF000) == 0x1000)
+ decode_BRCC_0 (cpu, iw0, pc);
+ else if ((iw0 & 0xF000) == 0x2000)
+ decode_UJUMP_0 (cpu, iw0, pc);
+ else if ((iw0 & 0xF000) == 0x3000)
+ decode_REGMV_0 (cpu, iw0);
+ else if ((iw0 & 0xFC00) == 0x4000)
+ decode_ALU2op_0 (cpu, iw0);
+ else if ((iw0 & 0xFE00) == 0x4400)
+ decode_PTR2op_0 (cpu, iw0);
+ else if ((iw0 & 0xF800) == 0x4800)
+ decode_LOGI2op_0 (cpu, iw0);
+ else if ((iw0 & 0xF000) == 0x5000)
+ decode_COMP3op_0 (cpu, iw0);
+ else if ((iw0 & 0xF800) == 0x6000)
+ decode_COMPI2opD_0 (cpu, iw0);
+ else if ((iw0 & 0xF800) == 0x6800)
+ decode_COMPI2opP_0 (cpu, iw0);
+ else if ((iw0 & 0xF000) == 0x8000)
+ decode_LDSTpmod_0 (cpu, iw0);
+ else if ((iw0 & 0xFF60) == 0x9E60)
+ decode_dagMODim_0 (cpu, iw0);
+ else if ((iw0 & 0xFFF0) == 0x9F60)
+ decode_dagMODik_0 (cpu, iw0);
+ else if ((iw0 & 0xFC00) == 0x9C00)
+ decode_dspLDST_0 (cpu, iw0);
+ else if ((iw0 & 0xF000) == 0x9000)
+ decode_LDST_0 (cpu, iw0);
+ else if ((iw0 & 0xFC00) == 0xB800)
+ decode_LDSTiiFP_0 (cpu, iw0);
+ else if ((iw0 & 0xE000) == 0xA000)
+ decode_LDSTii_0 (cpu, iw0);
+ else
+ {
+ TRACE_EXTRACT (cpu, "%s: no matching 16-bit pattern", __func__);
+ illegal_instruction (cpu);
+ }
+ return insn_len;
+ }
+
+ /* Grab the next 16 bits to determine if it's a 32-bit or 64-bit opcode. */
+ iw1 = IFETCH (pc + 2);
+ if ((iw0 & BIT_MULTI_INS) && (iw0 & 0xe800) != 0xe800 /* not linkage */)
+ {
+ SIM_DESC sd = CPU_STATE (cpu);
+ trace_prefix (sd, cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu),
+ NULL, 0, "|| %#"PRIx64, sim_events_time (sd));
+ insn_len = 8;
+ }
+ else
+ insn_len = 4;
+
+ TRACE_EXTRACT (cpu, "%s: iw0:%#x iw1:%#x insn_len:%i", __func__,
+ iw0, iw1, insn_len);
+
+ /* Only cache on first run through (in case of parallel insns). */
+ if (INSN_LEN == 0)
+ INSN_LEN = insn_len;
+
+ if ((iw0 & 0xf7ff) == 0xc003 && (iw1 & 0xfe00) == 0x1800)
+ {
+ PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dsp32mac);
+ TRACE_INSN (cpu, "MNOP;");
+ }
+ else if (((iw0 & 0xFF80) == 0xE080) && ((iw1 & 0x0C00) == 0x0000))
+ decode_LoopSetup_0 (cpu, iw0, iw1, pc);
+ else if (((iw0 & 0xFF00) == 0xE100) && ((iw1 & 0x0000) == 0x0000))
+ decode_LDIMMhalf_0 (cpu, iw0, iw1);
+ else if (((iw0 & 0xFE00) == 0xE200) && ((iw1 & 0x0000) == 0x0000))
+ decode_CALLa_0 (cpu, iw0, iw1, pc);
+ else if (((iw0 & 0xFC00) == 0xE400) && ((iw1 & 0x0000) == 0x0000))
+ decode_LDSTidxI_0 (cpu, iw0, iw1);
+ else if (((iw0 & 0xFFFE) == 0xE800) && ((iw1 & 0x0000) == 0x0000))
+ decode_linkage_0 (cpu, iw0, iw1);
+ else if (((iw0 & 0xF600) == 0xC000) && ((iw1 & 0x0000) == 0x0000))
+ decode_dsp32mac_0 (cpu, iw0, iw1);
+ else if (((iw0 & 0xF600) == 0xC200) && ((iw1 & 0x0000) == 0x0000))
+ decode_dsp32mult_0 (cpu, iw0, iw1);
+ else if (((iw0 & 0xF7C0) == 0xC400) && ((iw1 & 0x0000) == 0x0000))
+ decode_dsp32alu_0 (cpu, iw0, iw1);
+ else if (((iw0 & 0xF7E0) == 0xC600) && ((iw1 & 0x01C0) == 0x0000))
+ decode_dsp32shift_0 (cpu, iw0, iw1);
+ else if (((iw0 & 0xF7E0) == 0xC680) && ((iw1 & 0x0000) == 0x0000))
+ decode_dsp32shiftimm_0 (cpu, iw0, iw1);
+ else if ((iw0 & 0xFF00) == 0xF800)
+ decode_psedoDEBUG_0 (cpu, iw0), insn_len = 2;
+ else if ((iw0 & 0xFF00) == 0xF900)
+ decode_psedoOChar_0 (cpu, iw0), insn_len = 2;
+ else if (((iw0 & 0xFF00) == 0xF000) && ((iw1 & 0x0000) == 0x0000))
+ decode_psedodbg_assert_0 (cpu, iw0, iw1, pc);
+ else
+ {
+ TRACE_EXTRACT (cpu, "%s: no matching 32-bit pattern", __func__);
+ illegal_instruction (cpu);
+ }
+
+ return insn_len;
+}
+
+bu32
+interp_insn_bfin (SIM_CPU *cpu, bu32 pc)
+{
+ int i;
+ bu32 insn_len;
+
+ BFIN_CPU_STATE.n_stores = 0;
+ DIS_ALGN_EXPT &= ~1;
+ CYCLE_DELAY = 1;
+ INSN_LEN = 0;
+
+ insn_len = _interp_insn_bfin (cpu, pc);
+
+ /* Proper display of multiple issue instructions. */
+ if (insn_len == 8)
+ {
+ _interp_insn_bfin (cpu, pc + 4);
+ _interp_insn_bfin (cpu, pc + 6);
+ }
+ for (i = 0; i < BFIN_CPU_STATE.n_stores; i++)
+ {
+ bu32 *addr = BFIN_CPU_STATE.stores[i].addr;
+ *addr = BFIN_CPU_STATE.stores[i].val;
+ TRACE_REGISTER (cpu, "dequeuing write %s = %#x",
+ get_store_name (cpu, addr), *addr);
+ }
+
+ cycles_inc (cpu, CYCLE_DELAY);
+
+ /* Set back to zero in case a pending CEC event occurs
+ after this this insn. */
+ INSN_LEN = 0;
+
+ return insn_len;
+}
diff --git a/sim/bfin/bfin-sim.h b/sim/bfin/bfin-sim.h
new file mode 100644
index 00000000000..d61e7fe1f7b
--- /dev/null
+++ b/sim/bfin/bfin-sim.h
@@ -0,0 +1,350 @@
+/* Simulator for Analog Devices Blackfin processors.
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _BFIN_SIM_H_
+#define _BFIN_SIM_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef uint8_t bu8;
+typedef uint16_t bu16;
+typedef uint32_t bu32;
+typedef uint64_t bu40;
+typedef uint64_t bu64;
+typedef int8_t bs8;
+typedef int16_t bs16;
+typedef int32_t bs32;
+typedef int64_t bs40;
+typedef int64_t bs64;
+
+/* For dealing with parallel instructions, we must avoid changing our register
+ file until all parallel insns have been simulated. This queue of stores
+ can be used to delay a modification.
+ XXX: Should go and convert all 32 bit insns to use this. */
+struct store {
+ bu32 *addr;
+ bu32 val;
+};
+
+/* The KSP/USP handling wrt SP may not follow the hardware exactly (the hw
+ looks at current mode and uses either SP or USP based on that. We instead
+ always operate on SP and mirror things in KSP and USP. During a CEC
+ transition, we take care of syncing the values. This lowers the simulation
+ complexity and speeds things up a bit. */
+struct bfin_cpu_state
+{
+ bu32 dpregs[16], iregs[4], mregs[4], bregs[4], lregs[4], cycles[3];
+ bu32 ax[2], aw[2];
+ bu32 lt[2], lc[2], lb[2];
+ bu32 ksp, usp, seqstat, syscfg, rets, reti, retx, retn, rete;
+ bu32 pc, emudat[2];
+ /* These ASTAT flags need not be bu32, but it makes pointers easier. */
+ bu32 ac0, ac0_copy, ac1, an, aq;
+ union { struct { bu32 av0; bu32 av1; }; bu32 av [2]; };
+ union { struct { bu32 av0s; bu32 av1s; }; bu32 avs[2]; };
+ bu32 az, cc, v, v_copy, vs;
+ bu32 rnd_mod;
+ bu32 v_internal;
+ bu32 astat_reserved;
+
+ /* Set by an instruction emulation function if we performed a jump. We
+ cannot compare oldpc to newpc as this ignores the "jump 0;" case. */
+ bool did_jump;
+
+ /* Used by the CEC to figure out where to return to. */
+ bu32 insn_len;
+
+ /* How many cycles did this insn take to complete ? */
+ bu32 cycle_delay;
+
+ /* The pc currently being interpreted in parallel insns. */
+ bu32 multi_pc;
+
+ /* Needed for supporting the DISALGNEXCPT instruction */
+ int dis_algn_expt;
+
+ /* See notes above for struct store. */
+ struct store stores[20];
+ int n_stores;
+
+#if (WITH_HW)
+ /* Cache heavily used CPU-specific device pointers. */
+ void *cec_cache;
+ void *evt_cache;
+ void *mmu_cache;
+ void *trace_cache;
+#endif
+};
+
+#define REG_H_L(h, l) (((h) & 0xffff0000) | ((l) & 0x0000ffff))
+
+#define DREG(x) (BFIN_CPU_STATE.dpregs[x])
+#define PREG(x) (BFIN_CPU_STATE.dpregs[x + 8])
+#define SPREG PREG (6)
+#define FPREG PREG (7)
+#define IREG(x) (BFIN_CPU_STATE.iregs[x])
+#define MREG(x) (BFIN_CPU_STATE.mregs[x])
+#define BREG(x) (BFIN_CPU_STATE.bregs[x])
+#define LREG(x) (BFIN_CPU_STATE.lregs[x])
+#define AXREG(x) (BFIN_CPU_STATE.ax[x])
+#define AWREG(x) (BFIN_CPU_STATE.aw[x])
+#define CCREG (BFIN_CPU_STATE.cc)
+#define LCREG(x) (BFIN_CPU_STATE.lc[x])
+#define LTREG(x) (BFIN_CPU_STATE.lt[x])
+#define LBREG(x) (BFIN_CPU_STATE.lb[x])
+#define CYCLESREG (BFIN_CPU_STATE.cycles[0])
+#define CYCLES2REG (BFIN_CPU_STATE.cycles[1])
+#define CYCLES2SHDREG (BFIN_CPU_STATE.cycles[2])
+#define KSPREG (BFIN_CPU_STATE.ksp)
+#define USPREG (BFIN_CPU_STATE.usp)
+#define SEQSTATREG (BFIN_CPU_STATE.seqstat)
+#define SYSCFGREG (BFIN_CPU_STATE.syscfg)
+#define RETSREG (BFIN_CPU_STATE.rets)
+#define RETIREG (BFIN_CPU_STATE.reti)
+#define RETXREG (BFIN_CPU_STATE.retx)
+#define RETNREG (BFIN_CPU_STATE.retn)
+#define RETEREG (BFIN_CPU_STATE.rete)
+#define PCREG (BFIN_CPU_STATE.pc)
+#define EMUDAT_INREG (BFIN_CPU_STATE.emudat[0])
+#define EMUDAT_OUTREG (BFIN_CPU_STATE.emudat[1])
+#define INSN_LEN (BFIN_CPU_STATE.insn_len)
+#define CYCLE_DELAY (BFIN_CPU_STATE.cycle_delay)
+#define DIS_ALGN_EXPT (BFIN_CPU_STATE.dis_algn_expt)
+
+#define EXCAUSE_SHIFT 0
+#define EXCAUSE_MASK (0x3f << EXCAUSE_SHIFT)
+#define EXCAUSE ((SEQSTATREG & EXCAUSE_MASK) >> EXCAUSE_SHIFT)
+#define HWERRCAUSE_SHIFT 14
+#define HWERRCAUSE_MASK (0x1f << HWERRCAUSE_SHIFT)
+#define HWERRCAUSE ((SEQSTATREG & HWERRCAUSE_MASK) >> HWERRCAUSE_SHIFT)
+
+#define _SET_CORE32REG_IDX(reg, p, x, val) \
+ do { \
+ bu32 __v = (val); \
+ TRACE_REGISTER (cpu, "wrote "#p"%i = %#x", x, __v); \
+ reg = __v; \
+ } while (0)
+#define SET_DREG(x, val) _SET_CORE32REG_IDX (DREG (x), R, x, val)
+#define SET_PREG(x, val) _SET_CORE32REG_IDX (PREG (x), P, x, val)
+#define SET_IREG(x, val) _SET_CORE32REG_IDX (IREG (x), I, x, val)
+#define SET_MREG(x, val) _SET_CORE32REG_IDX (MREG (x), M, x, val)
+#define SET_BREG(x, val) _SET_CORE32REG_IDX (BREG (x), B, x, val)
+#define SET_LREG(x, val) _SET_CORE32REG_IDX (LREG (x), L, x, val)
+#define SET_LCREG(x, val) _SET_CORE32REG_IDX (LCREG (x), LC, x, val)
+#define SET_LTREG(x, val) _SET_CORE32REG_IDX (LTREG (x), LT, x, val)
+#define SET_LBREG(x, val) _SET_CORE32REG_IDX (LBREG (x), LB, x, val)
+
+#define SET_DREG_L_H(x, l, h) SET_DREG (x, REG_H_L (h, l))
+#define SET_DREG_L(x, l) SET_DREG (x, REG_H_L (DREG (x), l))
+#define SET_DREG_H(x, h) SET_DREG (x, REG_H_L (h, DREG (x)))
+
+#define _SET_CORE32REG_ALU(reg, p, x, val) \
+ do { \
+ bu32 __v = (val); \
+ TRACE_REGISTER (cpu, "wrote A%i"#p" = %#x", x, __v); \
+ reg = __v; \
+ } while (0)
+#define SET_AXREG(x, val) _SET_CORE32REG_ALU (AXREG (x), X, x, val)
+#define SET_AWREG(x, val) _SET_CORE32REG_ALU (AWREG (x), W, x, val)
+
+#define SET_AREG(x, val) \
+ do { \
+ bu40 __a = (val); \
+ SET_AXREG (x, (__a >> 32) & 0xff); \
+ SET_AWREG (x, __a); \
+ } while (0)
+#define SET_AREG32(x, val) \
+ do { \
+ SET_AWREG (x, val); \
+ SET_AXREG (x, -(AWREG (x) >> 31)); \
+ } while (0)
+
+#define _SET_CORE32REG(reg, val) \
+ do { \
+ bu32 __v = (val); \
+ TRACE_REGISTER (cpu, "wrote "#reg" = %#x", __v); \
+ reg##REG = __v; \
+ } while (0)
+#define SET_FPREG(val) _SET_CORE32REG (FP, val)
+#define SET_SPREG(val) _SET_CORE32REG (SP, val)
+#define SET_CYCLESREG(val) _SET_CORE32REG (CYCLES, val)
+#define SET_CYCLES2REG(val) _SET_CORE32REG (CYCLES2, val)
+#define SET_CYCLES2SHDREG(val) _SET_CORE32REG (CYCLES2SHD, val)
+#define SET_KSPREG(val) _SET_CORE32REG (KSP, val)
+#define SET_USPREG(val) _SET_CORE32REG (USP, val)
+#define SET_SYSCFGREG(val) _SET_CORE32REG (SYSCFG, val)
+#define SET_RETSREG(val) _SET_CORE32REG (RETS, val)
+#define SET_RETIREG(val) _SET_CORE32REG (RETI, val)
+#define SET_RETXREG(val) _SET_CORE32REG (RETX, val)
+#define SET_RETNREG(val) _SET_CORE32REG (RETN, val)
+#define SET_RETEREG(val) _SET_CORE32REG (RETE, val)
+#define SET_PCREG(val) _SET_CORE32REG (PC, val)
+
+#define _SET_CORE32REGFIELD(reg, field, val, mask, shift) \
+ do { \
+ bu32 __f = (val); \
+ bu32 __v = ((reg##REG) & ~(mask)) | (__f << (shift)); \
+ TRACE_REGISTER (cpu, "wrote "#field" = %#x ("#reg" = %#x)", __f, __v); \
+ reg##REG = __v; \
+ } while (0)
+#define SET_SEQSTATREG(val) _SET_CORE32REG (SEQSTAT, val)
+#define SET_EXCAUSE(excp) _SET_CORE32REGFIELD (SEQSTAT, EXCAUSE, excp, EXCAUSE_MASK, EXCAUSE_SHIFT)
+#define SET_HWERRCAUSE(hwerr) _SET_CORE32REGFIELD (SEQSTAT, HWERRCAUSE, hwerr, HWERRCAUSE_MASK, HWERRCAUSE_SHIFT)
+
+#define AZ_BIT 0
+#define AN_BIT 1
+#define AC0_COPY_BIT 2
+#define V_COPY_BIT 3
+#define CC_BIT 5
+#define AQ_BIT 6
+#define RND_MOD_BIT 8
+#define AC0_BIT 12
+#define AC1_BIT 13
+#define AV0_BIT 16
+#define AV0S_BIT 17
+#define AV1_BIT 18
+#define AV1S_BIT 19
+#define V_BIT 24
+#define VS_BIT 25
+#define ASTAT_DEFINED_BITS \
+ ((1 << AZ_BIT) | (1 << AN_BIT) | (1 << AC0_COPY_BIT) | (1 << V_COPY_BIT) \
+ |(1 << CC_BIT) | (1 << AQ_BIT) \
+ |(1 << RND_MOD_BIT) \
+ |(1 << AC0_BIT) | (1 << AC1_BIT) \
+ |(1 << AV0_BIT) | (1 << AV0S_BIT) | (1 << AV1_BIT) | (1 << AV1S_BIT) \
+ |(1 << V_BIT) | (1 << VS_BIT))
+
+#define ASTATREG(field) (BFIN_CPU_STATE.field)
+#define ASTAT_DEPOSIT(field, bit) (ASTATREG(field) << (bit))
+#define ASTAT \
+ (ASTAT_DEPOSIT(az, AZ_BIT) \
+ |ASTAT_DEPOSIT(an, AN_BIT) \
+ |ASTAT_DEPOSIT(ac0_copy, AC0_COPY_BIT) \
+ |ASTAT_DEPOSIT(v_copy, V_COPY_BIT) \
+ |ASTAT_DEPOSIT(cc, CC_BIT) \
+ |ASTAT_DEPOSIT(aq, AQ_BIT) \
+ |ASTAT_DEPOSIT(rnd_mod, RND_MOD_BIT) \
+ |ASTAT_DEPOSIT(ac0, AC0_BIT) \
+ |ASTAT_DEPOSIT(ac1, AC1_BIT) \
+ |ASTAT_DEPOSIT(av0, AV0_BIT) \
+ |ASTAT_DEPOSIT(av0s, AV0S_BIT) \
+ |ASTAT_DEPOSIT(av1, AV1_BIT) \
+ |ASTAT_DEPOSIT(av1s, AV1S_BIT) \
+ |ASTAT_DEPOSIT(v, V_BIT) \
+ |ASTAT_DEPOSIT(vs, VS_BIT) \
+ |ASTATREG(astat_reserved))
+
+#define ASTAT_EXTRACT(a, bit) (((a) >> bit) & 1)
+#define _SET_ASTAT(a, field, bit) (ASTATREG(field) = ASTAT_EXTRACT(a, bit))
+#define SET_ASTAT(a) \
+ do { \
+ TRACE_REGISTER (cpu, "wrote ASTAT = %#x", a); \
+ _SET_ASTAT(a, az, AZ_BIT); \
+ _SET_ASTAT(a, an, AN_BIT); \
+ _SET_ASTAT(a, ac0_copy, AC0_COPY_BIT); \
+ _SET_ASTAT(a, v_copy, V_COPY_BIT); \
+ _SET_ASTAT(a, cc, CC_BIT); \
+ _SET_ASTAT(a, aq, AQ_BIT); \
+ _SET_ASTAT(a, rnd_mod, RND_MOD_BIT); \
+ _SET_ASTAT(a, ac0, AC0_BIT); \
+ _SET_ASTAT(a, ac1, AC1_BIT); \
+ _SET_ASTAT(a, av0, AV0_BIT); \
+ _SET_ASTAT(a, av0s, AV0S_BIT); \
+ _SET_ASTAT(a, av1, AV1_BIT); \
+ _SET_ASTAT(a, av1s, AV1S_BIT); \
+ _SET_ASTAT(a, v, V_BIT); \
+ _SET_ASTAT(a, vs, VS_BIT); \
+ ASTATREG(astat_reserved) = (a) & ~ASTAT_DEFINED_BITS; \
+ } while (0)
+#define SET_ASTATREG(field, val) \
+ do { \
+ int __v = !!(val); \
+ TRACE_REGISTER (cpu, "wrote ASTAT["#field"] = %i", __v); \
+ ASTATREG (field) = __v; \
+ if (&ASTATREG (field) == &ASTATREG (ac0)) \
+ { \
+ TRACE_REGISTER (cpu, "wrote ASTAT["#field"_copy] = %i", __v); \
+ ASTATREG (ac0_copy) = __v; \
+ } \
+ else if (&ASTATREG (field) == &ASTATREG (v)) \
+ { \
+ TRACE_REGISTER (cpu, "wrote ASTAT["#field"_copy] = %i", __v); \
+ ASTATREG (v_copy) = __v; \
+ } \
+ } while (0)
+#define SET_CCREG(val) SET_ASTATREG (cc, val)
+
+#define SYSCFG_SSSTEP (1 << 0)
+#define SYSCFG_CCEN (1 << 1)
+#define SYSCFG_SNEN (1 << 2)
+
+#define __PUT_MEM(taddr, v, size) \
+do { \
+ bu##size __v = (v); \
+ bu32 __taddr = (taddr); \
+ int __cnt, __bytes = size / 8; \
+ mmu_check_addr (cpu, __taddr, true, false, __bytes); \
+ __cnt = sim_core_write_buffer (CPU_STATE(cpu), cpu, write_map, \
+ (void *)&__v, __taddr, __bytes); \
+ if (__cnt != __bytes) \
+ mmu_process_fault (cpu, __taddr, true, false, false, true); \
+ TRACE_CORE (cpu, __taddr, __bytes, write_map, __v); \
+} while (0)
+#define PUT_BYTE(taddr, v) __PUT_MEM(taddr, v, 8)
+#define PUT_WORD(taddr, v) __PUT_MEM(taddr, v, 16)
+#define PUT_LONG(taddr, v) __PUT_MEM(taddr, v, 32)
+
+#define __GET_MEM(taddr, size, inst, map) \
+({ \
+ bu##size __ret; \
+ bu32 __taddr = (taddr); \
+ int __cnt, __bytes = size / 8; \
+ mmu_check_addr (cpu, __taddr, false, inst, __bytes); \
+ __cnt = sim_core_read_buffer (CPU_STATE(cpu), cpu, map, \
+ (void *)&__ret, __taddr, __bytes); \
+ if (__cnt != __bytes) \
+ mmu_process_fault (cpu, __taddr, false, inst, false, true); \
+ TRACE_CORE (cpu, __taddr, __bytes, map, __ret); \
+ __ret; \
+})
+#define _GET_MEM(taddr, size) __GET_MEM(taddr, size, false, read_map)
+#define GET_BYTE(taddr) _GET_MEM(taddr, 8)
+#define GET_WORD(taddr) _GET_MEM(taddr, 16)
+#define GET_LONG(taddr) _GET_MEM(taddr, 32)
+
+#define IFETCH(taddr) __GET_MEM(taddr, 16, true, exec_map)
+#define IFETCH_CHECK(taddr) mmu_check_addr (cpu, taddr, false, true, 2)
+
+extern void bfin_syscall (SIM_CPU *);
+extern bu32 interp_insn_bfin (SIM_CPU *, bu32);
+extern bu32 hwloop_get_next_pc (SIM_CPU *, bu32, bu32);
+
+/* Defines for Blackfin memory layouts. */
+#define BFIN_ASYNC_BASE 0x20000000
+#define BFIN_SYSTEM_MMR_BASE 0xFFC00000
+#define BFIN_CORE_MMR_BASE 0xFFE00000
+#define BFIN_L1_SRAM_SCRATCH 0xFFB00000
+#define BFIN_L1_SRAM_SCRATCH_SIZE 0x1000
+#define BFIN_L1_SRAM_SCRATCH_END (BFIN_L1_SRAM_SCRATCH + BFIN_L1_SRAM_SCRATCH_SIZE)
+
+#define BFIN_L1_CACHE_BYTES 32
+
+#endif
diff --git a/sim/bfin/bfroms/all.h b/sim/bfin/bfroms/all.h
new file mode 100644
index 00000000000..1b562d9df40
--- /dev/null
+++ b/sim/bfin/bfroms/all.h
@@ -0,0 +1,43 @@
+#include "bf50x-0.0.h"
+
+#include "bf51x-0.0.h"
+#include "bf51x-0.1.h"
+#include "bf51x-0.2.h"
+
+#include "bf526-0.0.h"
+#include "bf526-0.1.h"
+#include "bf527-0.0.h"
+#include "bf527-0.1.h"
+#include "bf527-0.2.h"
+
+#include "bf533-0.1.h"
+#include "bf533-0.2.h"
+#include "bf533-0.3.h"
+#define bfrom_bf533_0_4 bfrom_bf533_0_3
+#define bfrom_bf533_0_5 bfrom_bf533_0_3
+#define bfrom_bf533_0_6 bfrom_bf533_0_3
+
+#include "bf537-0.0.h"
+#include "bf537-0.1.h"
+#define bfrom_bf537_0_2 bfrom_bf537_0_1
+#include "bf537-0.3.h"
+
+#include "bf538-0.0.h"
+#define bfrom_bf538_0_1 bfrom_bf538_0_0
+#define bfrom_bf538_0_2 bfrom_bf538_0_0
+#define bfrom_bf538_0_3 bfrom_bf538_0_0
+#define bfrom_bf538_0_4 bfrom_bf538_0_0
+#define bfrom_bf538_0_5 bfrom_bf538_0_0
+
+#include "bf54x-0.0.h"
+#include "bf54x-0.1.h"
+#include "bf54x-0.2.h"
+#include "bf54x_l1-0.0.h"
+#include "bf54x_l1-0.1.h"
+#include "bf54x_l1-0.2.h"
+
+#include "bf561-0.5.h"
+
+#include "bf59x-0.0.h"
+#define bfrom_bf59x_0_1 bfrom_bf59x_0_0
+#include "bf59x_l1-0.1.h"
diff --git a/sim/bfin/bfroms/bf50x-0.0.h b/sim/bfin/bfroms/bf50x-0.0.h
new file mode 100644
index 00000000000..00dcc104c9a
--- /dev/null
+++ b/sim/bfin/bfroms/bf50x-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf50x_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf51x-0.0.h b/sim/bfin/bfroms/bf51x-0.0.h
new file mode 100644
index 00000000000..62b5682b498
--- /dev/null
+++ b/sim/bfin/bfroms/bf51x-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf51x_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf51x-0.1.h b/sim/bfin/bfroms/bf51x-0.1.h
new file mode 100644
index 00000000000..ab82f8f8b67
--- /dev/null
+++ b/sim/bfin/bfroms/bf51x-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf51x_0_1[] = {
+};
diff --git a/sim/bfin/bfroms/bf51x-0.2.h b/sim/bfin/bfroms/bf51x-0.2.h
new file mode 100644
index 00000000000..6cd8dbcb6a9
--- /dev/null
+++ b/sim/bfin/bfroms/bf51x-0.2.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf51x_0_2[] = {
+};
diff --git a/sim/bfin/bfroms/bf526-0.0.h b/sim/bfin/bfroms/bf526-0.0.h
new file mode 100644
index 00000000000..8b60b479ca9
--- /dev/null
+++ b/sim/bfin/bfroms/bf526-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf526_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf526-0.1.h b/sim/bfin/bfroms/bf526-0.1.h
new file mode 100644
index 00000000000..4d53e0b3fb6
--- /dev/null
+++ b/sim/bfin/bfroms/bf526-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf526_0_1[] = {
+};
diff --git a/sim/bfin/bfroms/bf527-0.0.h b/sim/bfin/bfroms/bf527-0.0.h
new file mode 100644
index 00000000000..9e23e90f74b
--- /dev/null
+++ b/sim/bfin/bfroms/bf527-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf527_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf527-0.1.h b/sim/bfin/bfroms/bf527-0.1.h
new file mode 100644
index 00000000000..1d0c0a977a5
--- /dev/null
+++ b/sim/bfin/bfroms/bf527-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf527_0_1[] = {
+};
diff --git a/sim/bfin/bfroms/bf527-0.2.h b/sim/bfin/bfroms/bf527-0.2.h
new file mode 100644
index 00000000000..e0066f3bba2
--- /dev/null
+++ b/sim/bfin/bfroms/bf527-0.2.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf527_0_2[] = {
+};
diff --git a/sim/bfin/bfroms/bf533-0.1.h b/sim/bfin/bfroms/bf533-0.1.h
new file mode 100644
index 00000000000..1f1fd6660c3
--- /dev/null
+++ b/sim/bfin/bfroms/bf533-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf533_0_1[] = {
+};
diff --git a/sim/bfin/bfroms/bf533-0.2.h b/sim/bfin/bfroms/bf533-0.2.h
new file mode 100644
index 00000000000..00aba572ef9
--- /dev/null
+++ b/sim/bfin/bfroms/bf533-0.2.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf533_0_2[] = {
+};
diff --git a/sim/bfin/bfroms/bf533-0.3.h b/sim/bfin/bfroms/bf533-0.3.h
new file mode 100644
index 00000000000..829485b05d5
--- /dev/null
+++ b/sim/bfin/bfroms/bf533-0.3.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf533_0_3[] = {
+};
diff --git a/sim/bfin/bfroms/bf537-0.0.h b/sim/bfin/bfroms/bf537-0.0.h
new file mode 100644
index 00000000000..ec945d26a84
--- /dev/null
+++ b/sim/bfin/bfroms/bf537-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf537_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf537-0.1.h b/sim/bfin/bfroms/bf537-0.1.h
new file mode 100644
index 00000000000..4c6d46d9a0b
--- /dev/null
+++ b/sim/bfin/bfroms/bf537-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf537_0_1[] = {
+};
diff --git a/sim/bfin/bfroms/bf537-0.3.h b/sim/bfin/bfroms/bf537-0.3.h
new file mode 100644
index 00000000000..4483a9f7caf
--- /dev/null
+++ b/sim/bfin/bfroms/bf537-0.3.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf537_0_3[] = {
+};
diff --git a/sim/bfin/bfroms/bf538-0.0.h b/sim/bfin/bfroms/bf538-0.0.h
new file mode 100644
index 00000000000..a5dff38542a
--- /dev/null
+++ b/sim/bfin/bfroms/bf538-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf538_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf54x-0.0.h b/sim/bfin/bfroms/bf54x-0.0.h
new file mode 100644
index 00000000000..9141b29f033
--- /dev/null
+++ b/sim/bfin/bfroms/bf54x-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf54x_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf54x-0.1.h b/sim/bfin/bfroms/bf54x-0.1.h
new file mode 100644
index 00000000000..9d82c58a8da
--- /dev/null
+++ b/sim/bfin/bfroms/bf54x-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf54x_0_1[] = {
+};
diff --git a/sim/bfin/bfroms/bf54x-0.2.h b/sim/bfin/bfroms/bf54x-0.2.h
new file mode 100644
index 00000000000..ea5722576dd
--- /dev/null
+++ b/sim/bfin/bfroms/bf54x-0.2.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf54x_0_2[] = {
+};
diff --git a/sim/bfin/bfroms/bf54x_l1-0.0.h b/sim/bfin/bfroms/bf54x_l1-0.0.h
new file mode 100644
index 00000000000..afeaf74411d
--- /dev/null
+++ b/sim/bfin/bfroms/bf54x_l1-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf54x_l1_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf54x_l1-0.1.h b/sim/bfin/bfroms/bf54x_l1-0.1.h
new file mode 100644
index 00000000000..7a1ff33064f
--- /dev/null
+++ b/sim/bfin/bfroms/bf54x_l1-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf54x_l1_0_1[] = {
+};
diff --git a/sim/bfin/bfroms/bf54x_l1-0.2.h b/sim/bfin/bfroms/bf54x_l1-0.2.h
new file mode 100644
index 00000000000..ad138cf82ab
--- /dev/null
+++ b/sim/bfin/bfroms/bf54x_l1-0.2.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf54x_l1_0_2[] = {
+};
diff --git a/sim/bfin/bfroms/bf561-0.5.h b/sim/bfin/bfroms/bf561-0.5.h
new file mode 100644
index 00000000000..1d271415fae
--- /dev/null
+++ b/sim/bfin/bfroms/bf561-0.5.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf561_0_5[] = {
+};
diff --git a/sim/bfin/bfroms/bf59x-0.0.h b/sim/bfin/bfroms/bf59x-0.0.h
new file mode 100644
index 00000000000..737f6440090
--- /dev/null
+++ b/sim/bfin/bfroms/bf59x-0.0.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf59x_0_0[] = {
+};
diff --git a/sim/bfin/bfroms/bf59x_l1-0.1.h b/sim/bfin/bfroms/bf59x_l1-0.1.h
new file mode 100644
index 00000000000..3be46eeee81
--- /dev/null
+++ b/sim/bfin/bfroms/bf59x_l1-0.1.h
@@ -0,0 +1,3 @@
+/* DO NOT EDIT: Autogenerated. */
+static const char bfrom_bf59x_l1_0_1[] = {
+};
diff --git a/sim/bfin/config.in b/sim/bfin/config.in
new file mode 100644
index 00000000000..b44011d7e80
--- /dev/null
+++ b/sim/bfin/config.in
@@ -0,0 +1,176 @@
+/* config.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+#undef ENABLE_NLS
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if dv-sockser is usable. */
+#undef HAVE_DV_SOCKSER
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <fpu_control.h> header file. */
+#undef HAVE_FPU_CONTROL_H
+
+/* Define to 1 if you have the `getegid' function. */
+#undef HAVE_GETEGID
+
+/* Define to 1 if you have the `geteuid' function. */
+#undef HAVE_GETEUID
+
+/* Define to 1 if you have the `getgid' function. */
+#undef HAVE_GETGID
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `getuid' function. */
+#undef HAVE_GETUID
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the <linux/if_tun.h> header file. */
+#undef HAVE_LINUX_IF_TUN_H
+
+/* Define to 1 if you have the <linux/mii.h> header file. */
+#undef HAVE_LINUX_MII_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#undef HAVE_NET_IF_H
+
+/* Define to 1 if you have the `setgid' function. */
+#undef HAVE_SETGID
+
+/* Define to 1 if you have the `setuid' function. */
+#undef HAVE_SETUID
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `time' function. */
+#undef HAVE_TIME
+
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define to 1 if you have the `__setfpucw' function. */
+#undef HAVE___SETFPUCW
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Additional package description */
+#undef PKGVERSION
+
+/* Bug reporting address */
+#undef REPORT_BUGS_TO
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
diff --git a/sim/bfin/configure b/sim/bfin/configure
new file mode 100755
index 00000000000..ff71b591f55
--- /dev/null
+++ b/sim/bfin/configure
@@ -0,0 +1,6779 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="Makefile.in"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+cgen_breaks
+SDL_LIBS
+SDL_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
+BFIN_SIM_EXTRA_OBJS
+REPORT_BUGS_TEXI
+REPORT_BUGS_TO
+PKGVERSION
+sim_profile
+sim_trace
+sim_stdio
+sim_debug
+sim_cflags
+sim_bswap
+MAINT
+EGREP
+GREP
+CPP
+CATOBJEXT
+GENCAT
+INSTOBJEXT
+DATADIRNAME
+CATALOGS
+POSUB
+GMSGFMT
+XGETTEXT
+INCINTL
+LIBINTL_DEP
+LIBINTL
+USE_NLS
+RANLIB
+AR
+HDEFINES
+CC_FOR_BUILD
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+WERROR_CFLAGS
+WARN_CFLAGS
+sim_xor_endian
+sim_stdcall
+sim_smp
+sim_reserved_bits
+sim_regparm
+sim_packages
+sim_inline
+sim_hw
+sim_hw_objs
+sim_hw_cflags
+sim_default_model
+sim_scache
+sim_float
+sim_hostendian
+sim_endian
+sim_bitsize
+sim_assert
+sim_alignment
+sim_environment
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_zlib
+enable_maintainer_mode
+enable_sim_bswap
+enable_sim_cflags
+enable_sim_debug
+enable_sim_stdio
+enable_sim_trace
+enable_sim_profile
+with_pkgversion
+with_bugurl
+enable_sim_endian
+enable_sim_alignment
+enable_sim_hostendian
+enable_sim_default_model
+enable_sim_environment
+enable_sim_inline
+enable_build_warnings
+enable_sim_build_warnings
+enable_sim_hardware
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+SDL_CFLAGS
+SDL_LIBS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+ --target=TARGET configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode Enable developer functionality.
+ --enable-sim-bswap Use Host specific BSWAP instruction.
+ --enable-sim-cflags=opts Extra CFLAGS for use in building simulator
+ --enable-sim-debug=opts Enable debugging flags
+ --enable-sim-stdio Specify whether to use stdio for console input/output.
+ --enable-sim-trace=opts Enable tracing flags
+ --enable-sim-profile=opts Enable profiling flags
+ --enable-sim-endian=endian Specify target byte endian orientation.
+ --enable-sim-alignment=align Specify strict, nonstrict or forced alignment of memory accesses.
+ --enable-sim-hostendian=end Specify host byte endian orientation.
+ --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.
+ --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.
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-zlib include zlib support (auto/yes/no) default=auto
+ --with-pkgversion=PKG Use PKG in the version string in place of "GDB"
+ --with-bugurl=URL Direct users to URL to report a bug
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ PKG_CONFIG path to pkg-config utility
+ PKG_CONFIG_PATH
+ directories to add to pkg-config's search path
+ PKG_CONFIG_LIBDIR
+ path overriding pkg-config's built-in search path
+ SDL_CFLAGS C compiler flags for SDL, overriding pkg-config
+ SDL_LIBS linker flags for SDL, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h:config.in"
+
+
+# This file contains common code used by all simulators.
+#
+# SIM_AC_COMMON invokes AC macros used by all simulators and by the common
+# directory. It is intended to be invoked before any target specific stuff.
+# SIM_AC_OUTPUT is a cover function to AC_OUTPUT to generate the Makefile.
+# It is intended to be invoked last.
+#
+# The simulator's configure.in should look like:
+#
+# dnl Process this file with autoconf to produce a configure script.
+# sinclude(../common/aclocal.m4)
+# AC_PREREQ(2.5)dnl
+# AC_INIT(Makefile.in)
+#
+# SIM_AC_COMMON
+#
+# ... target specific stuff ...
+#
+# SIM_AC_OUTPUT
+
+# Include global overrides and fixes for Autoconf.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# _AC_CHECK_DECL_BODY
+# -------------------
+# Shell function body for AC_CHECK_DECL.
+# _AC_CHECK_DECL_BODY
+
+# _AC_CHECK_DECLS(SYMBOL, ACTION-IF_FOUND, ACTION-IF-NOT-FOUND,
+# INCLUDES)
+# -------------------------------------------------------------
+# Helper to AC_CHECK_DECLS, which generates the check for a single
+# SYMBOL with INCLUDES, performs the AC_DEFINE, then expands
+# ACTION-IF-FOUND or ACTION-IF-NOT-FOUND.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+sim_inline="-DDEFAULT_INLINE=0"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# intl sister-directory configuration rules.
+#
+
+# The idea behind this macro is that there's no need to repeat all the
+# autoconf probes done by the intl directory - it's already done them
+# for us. In fact, there's no need even to look at the cache for the
+# answers. All we need to do is nab a few pieces of information.
+# The intl directory is set up to make this easy, by generating a
+# small file which can be sourced as a shell script; then we produce
+# the necessary substitutions and definitions for this directory.
+
+
+
+# Autoconf M4 include file defining utility macros for complex Canadian
+# cross builds.
+
+
+
+
+
+
+
+
+
+####
+# _NCN_TOOL_PREFIXES: Some stuff that oughtta be done in AC_CANONICAL_SYSTEM
+# or AC_INIT.
+# These demand that AC_CANONICAL_SYSTEM be called beforehand.
+
+####
+# NCN_STRICT_CHECK_TOOLS(variable, progs-to-check-for,[value-if-not-found],[path])
+# Like plain AC_CHECK_TOOLS, but require prefix if build!=host.
+
+
+####
+# NCN_STRICT_CHECK_TARGET_TOOLS(variable, progs-to-check-for,[value-if-not-found],[path])
+# Like CVS Autoconf AC_CHECK_TARGET_TOOLS, but require prefix if build!=target.
+
+
+
+# Backported from Autoconf 2.5x; can go away when and if
+# we switch. Put the OS path separator in $PATH_SEPARATOR.
+
+
+
+
+# ACX_HAVE_GCC_FOR_TARGET
+# Check if the variable GCC_FOR_TARGET really points to a GCC binary.
+
+
+# ACX_CHECK_INSTALLED_TARGET_TOOL(VAR, PROG)
+# Searching for installed target binutils. We need to take extra care,
+# else we may find the wrong assembler, linker, etc., and lose.
+#
+# First try --with-build-time-tools, if specified.
+#
+# For build != host, we ask the installed GCC for the name of the tool it
+# uses, and accept it if it is an absolute path. This is because the
+# only good choice for a compiler is the same GCC version that is being
+# installed (or we couldn't make target libraries), and we assume that
+# on the host system we'll have not only the same GCC version, but also
+# the same binutils version.
+#
+# For build == host, search the same directories that the installed
+# compiler will search. We used to do this for the assembler, linker,
+# and nm only; for simplicity of configuration, however, we extend this
+# criterion to tools (such as ar and ranlib) that are never invoked by
+# the compiler, to avoid mismatches.
+#
+# Also note we have to check MD_EXEC_PREFIX before checking the user's path
+# if build == target. This makes the most sense only when bootstrapping,
+# but we also do so when build != host. In this case, we hope that the
+# build and host systems will have similar contents of MD_EXEC_PREFIX.
+#
+# If we do not find a suitable binary, then try the user's path.
+
+
+###
+# AC_PROG_CPP_WERROR
+# Used for autoconf 2.5x to force AC_PREPROC_IFELSE to reject code which
+# triggers warnings from the preprocessor. Will be in autoconf 2.58.
+# For now, using this also overrides header checks to use only the
+# preprocessor (matches 2.13 behavior; matching 2.58's behavior is a
+# bit harder from here).
+# Eventually autoconf will default to checking headers with the compiler
+# instead, and we'll have to do this differently.
+
+# AC_PROG_CPP_WERROR
+
+# Test for GNAT.
+# We require the gnatbind program, and a compiler driver that
+# understands Ada. We use the user's CC setting, already found,
+# and possibly add $1 to the command-line parameters.
+#
+# Sets the shell variable have_gnat to yes or no as appropriate, and
+# substitutes GNATBIND and GNATMAKE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around
+# it by inlining the macro's contents.
+# This file contains common code used by all simulators.
+#
+# common.m4 invokes AC macros used by all simulators and by the common
+# directory. It is intended to be included before any target specific
+# stuff. SIM_AC_OUTPUT is a cover function to AC_OUTPUT to generate
+# the Makefile. It is intended to be invoked last.
+#
+# The simulator's configure.in should look like:
+#
+# dnl Process this file with autoconf to produce a configure script.
+# AC_PREREQ(2.5)dnl
+# AC_INIT(Makefile.in)
+# AC_CONFIG_HEADER(config.h:config.in)
+#
+# sinclude(../common/aclocal.m4)
+# sinclude(../common/common.m4)
+#
+# ... target specific stuff ...
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if test "${ac_cv_target+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$target_alias" = x; then
+ ac_cv_target=$ac_cv_host
+else
+ ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+else
+ CC_FOR_BUILD=gcc
+fi
+
+
+
+
+AR=${AR-ar}
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+ALL_LINGUAS=
+# If we haven't got the data from the intl directory,
+# assume NLS is disabled.
+USE_NLS=no
+LIBINTL=
+LIBINTL_DEP=
+INCINTL=
+XGETTEXT=
+GMSGFMT=
+POSUB=
+
+if test -f ../../intl/config.intl; then
+ . ../../intl/config.intl
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
+$as_echo_n "checking whether NLS is requested... " >&6; }
+if test x"$USE_NLS" != xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define ENABLE_NLS 1" >>confdefs.h
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5
+$as_echo_n "checking for catalogs to be installed... " >&6; }
+ # Look for .po and .gmo files in the source directory.
+ CATALOGS=
+ XLINGUAS=
+ for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do
+ # If there aren't any .gmo files the shell will give us the
+ # literal string "../path/to/srcdir/po/*.gmo" which has to be
+ # weeded out.
+ case "$cat" in *\**)
+ continue;;
+ esac
+ # The quadruple backslash is collapsed to a double backslash
+ # by the backticks, then collapsed again by the double quotes,
+ # leaving us with one backslash in the sed expression (right
+ # before the dot that mustn't act as a wildcard).
+ cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"`
+ lang=`echo $cat | sed -e "s!\\\\.gmo!!"`
+ # The user is allowed to set LINGUAS to a list of languages to
+ # install catalogs for. If it's empty that means "all of them."
+ if test "x$LINGUAS" = x; then
+ CATALOGS="$CATALOGS $cat"
+ XLINGUAS="$XLINGUAS $lang"
+ else
+ case "$LINGUAS" in *$lang*)
+ CATALOGS="$CATALOGS $cat"
+ XLINGUAS="$XLINGUAS $lang"
+ ;;
+ esac
+ fi
+ done
+ LINGUAS="$XLINGUAS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5
+$as_echo "$LINGUAS" >&6; }
+
+
+ DATADIRNAME=share
+
+ INSTOBJEXT=.mo
+
+ GENCAT=gencat
+
+ CATOBJEXT=.gmo
+
+fi
+
+# Check for common headers.
+# FIXME: Seems to me this can cause problems for i386-windows hosts.
+# At one point there were hardcoded AC_DEFINE's if ${host} = i386-*-windows*.
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in stdlib.h string.h strings.h unistd.h time.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/time.h sys/resource.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in fcntl.h fpu_control.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in dlfcn.h errno.h sys/stat.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in getrusage time sigaction __setfpucw
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Check for socket libraries
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bind in -lsocket" >&5
+$as_echo_n "checking for bind in -lsocket... " >&6; }
+if test "${ac_cv_lib_socket_bind+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char bind ();
+int
+main ()
+{
+return bind ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_bind=yes
+else
+ ac_cv_lib_socket_bind=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_bind" >&5
+$as_echo "$ac_cv_lib_socket_bind" >&6; }
+if test "x$ac_cv_lib_socket_bind" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSOCKET 1
+_ACEOF
+
+ LIBS="-lsocket $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_gethostbyname=yes
+else
+ ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSL 1
+_ACEOF
+
+ LIBS="-lnsl $LIBS"
+
+fi
+
+
+# BFD conditionally uses zlib, so we must link it in if libbfd does, by
+# using the same condition.
+
+ # See if the user specified whether he wants zlib support or not.
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then :
+ withval=$with_zlib;
+else
+ with_zlib=auto
+fi
+
+
+ if test "$with_zlib" != "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing zlibVersion" >&5
+$as_echo_n "checking for library containing zlibVersion... " >&6; }
+if test "${ac_cv_search_zlibVersion+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char zlibVersion ();
+int
+main ()
+{
+return zlibVersion ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' z; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_zlibVersion=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_zlibVersion+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_zlibVersion+set}" = set; then :
+
+else
+ ac_cv_search_zlibVersion=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_zlibVersion" >&5
+$as_echo "$ac_cv_search_zlibVersion" >&6; }
+ac_res=$ac_cv_search_zlibVersion
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ for ac_header in zlib.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ZLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+ if test "$with_zlib" = "yes" -a "$ac_cv_header_zlib_h" != "yes"; then
+ as_fn_error "zlib (libz) library was explicitly requested but not found" "$LINENO" 5
+ fi
+ fi
+
+
+. ${srcdir}/../../bfd/configure.host
+
+
+
+USE_MAINTAINER_MODE=no
+# Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; case "${enableval}" in
+ yes) MAINT="" USE_MAINTAINER_MODE=yes ;;
+ no) MAINT="#" ;;
+ *) as_fn_error "\"--enable-maintainer-mode does not take a value\"" "$LINENO" 5; MAINT="#" ;;
+esac
+if test x"$silent" != x"yes" && test x"$MAINT" = x""; then
+ echo "Setting maintainer mode" 6>&1
+fi
+else
+ MAINT="#"
+fi
+
+
+
+# Check whether --enable-sim-bswap was given.
+if test "${enable_sim_bswap+set}" = set; then :
+ enableval=$enable_sim_bswap; case "${enableval}" in
+ yes) sim_bswap="-DWITH_BSWAP=1 -DUSE_BSWAP=1";;
+ no) sim_bswap="-DWITH_BSWAP=0";;
+ *) as_fn_error "\"--enable-sim-bswap does not take a value\"" "$LINENO" 5; sim_bswap="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_bswap" != x""; then
+ echo "Setting bswap flags = $sim_bswap" 6>&1
+fi
+else
+ sim_bswap=""
+fi
+
+
+
+# Check whether --enable-sim-cflags was given.
+if test "${enable_sim_cflags+set}" = set; then :
+ enableval=$enable_sim_cflags; case "${enableval}" in
+ yes) sim_cflags="-O2 -fomit-frame-pointer";;
+ trace) as_fn_error "\"Please use --enable-sim-debug instead.\"" "$LINENO" 5; sim_cflags="";;
+ no) sim_cflags="";;
+ *) sim_cflags=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_cflags" != x""; then
+ echo "Setting sim cflags = $sim_cflags" 6>&1
+fi
+else
+ sim_cflags=""
+fi
+
+
+
+# Check whether --enable-sim-debug was given.
+if test "${enable_sim_debug+set}" = set; then :
+ enableval=$enable_sim_debug; case "${enableval}" in
+ yes) sim_debug="-DDEBUG=7 -DWITH_DEBUG=7";;
+ no) sim_debug="-DDEBUG=0 -DWITH_DEBUG=0";;
+ *) sim_debug="-DDEBUG='(${enableval})' -DWITH_DEBUG='(${enableval})'";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_debug" != x""; then
+ echo "Setting sim debug = $sim_debug" 6>&1
+fi
+else
+ sim_debug=""
+fi
+
+
+
+# Check whether --enable-sim-stdio was given.
+if test "${enable_sim_stdio+set}" = set; then :
+ enableval=$enable_sim_stdio; case "${enableval}" in
+ yes) sim_stdio="-DWITH_STDIO=DO_USE_STDIO";;
+ no) sim_stdio="-DWITH_STDIO=DONT_USE_STDIO";;
+ *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-stdio\"" "$LINENO" 5; sim_stdio="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_stdio" != x""; then
+ echo "Setting stdio flags = $sim_stdio" 6>&1
+fi
+else
+ sim_stdio=""
+fi
+
+
+
+# Check whether --enable-sim-trace was given.
+if test "${enable_sim_trace+set}" = set; then :
+ enableval=$enable_sim_trace; case "${enableval}" in
+ yes) sim_trace="-DTRACE=1 -DWITH_TRACE=-1";;
+ no) sim_trace="-DTRACE=0 -DWITH_TRACE=0";;
+ [-0-9]*)
+ sim_trace="-DTRACE='(${enableval})' -DWITH_TRACE='(${enableval})'";;
+ [a-z]*)
+ sim_trace=""
+ for x in `echo "$enableval" | sed -e "s/,/ /g"`; do
+ if test x"$sim_trace" = x; then
+ sim_trace="-DWITH_TRACE='(TRACE_$x"
+ else
+ sim_trace="${sim_trace}|TRACE_$x"
+ fi
+ done
+ sim_trace="$sim_trace)'" ;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_trace" != x""; then
+ echo "Setting sim trace = $sim_trace" 6>&1
+fi
+else
+ sim_trace=""
+fi
+
+
+
+# Check whether --enable-sim-profile was given.
+if test "${enable_sim_profile+set}" = set; then :
+ enableval=$enable_sim_profile; case "${enableval}" in
+ yes) sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1";;
+ no) sim_profile="-DPROFILE=0 -DWITH_PROFILE=0";;
+ [-0-9]*)
+ sim_profile="-DPROFILE='(${enableval})' -DWITH_PROFILE='(${enableval})'";;
+ [a-z]*)
+ sim_profile=""
+ for x in `echo "$enableval" | sed -e "s/,/ /g"`; do
+ if test x"$sim_profile" = x; then
+ sim_profile="-DWITH_PROFILE='(PROFILE_$x"
+ else
+ sim_profile="${sim_profile}|PROFILE_$x"
+ fi
+ done
+ sim_profile="$sim_profile)'" ;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_profile" != x""; then
+ echo "Setting sim profile = $sim_profile" 6>&1
+fi
+else
+ sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1"
+fi
+
+
+
+
+# Check whether --with-pkgversion was given.
+if test "${with_pkgversion+set}" = set; then :
+ withval=$with_pkgversion; case "$withval" in
+ yes) as_fn_error "package version not specified" "$LINENO" 5 ;;
+ no) PKGVERSION= ;;
+ *) PKGVERSION="($withval) " ;;
+ esac
+else
+ PKGVERSION="(GDB) "
+
+fi
+
+
+
+
+
+# Check whether --with-bugurl was given.
+if test "${with_bugurl+set}" = set; then :
+ withval=$with_bugurl; case "$withval" in
+ yes) as_fn_error "bug URL not specified" "$LINENO" 5 ;;
+ no) BUGURL=
+ ;;
+ *) BUGURL="$withval"
+ ;;
+ esac
+else
+ BUGURL="http://www.gnu.org/software/gdb/bugs/"
+
+fi
+
+ case ${BUGURL} in
+ "")
+ REPORT_BUGS_TO=
+ REPORT_BUGS_TEXI=
+ ;;
+ *)
+ REPORT_BUGS_TO="<$BUGURL>"
+ REPORT_BUGS_TEXI=@uref{`echo "$BUGURL" | sed 's/@/@@/g'`}
+ ;;
+ esac;
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define PKGVERSION "$PKGVERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define REPORT_BUGS_TO "$REPORT_BUGS_TO"
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if test "${ac_cv_type_signal+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_type_signal=int
+else
+ ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+
+
+sim_link_files=
+sim_link_links=
+
+sim_link_links=tconfig.h
+if test -f ${srcdir}/tconfig.in
+then
+ sim_link_files=tconfig.in
+else
+ sim_link_files=../common/tconfig.in
+fi
+
+# targ-vals.def points to the libc macro description file.
+case "${target}" in
+*-*-*) TARG_VALS_DEF=../common/nltvals.def ;;
+esac
+sim_link_files="${sim_link_files} ${TARG_VALS_DEF}"
+sim_link_links="${sim_link_links} targ-vals.def"
+
+
+
+wire_endian="LITTLE_ENDIAN"
+default_endian=""
+# Check whether --enable-sim-endian was given.
+if test "${enable_sim_endian+set}" = set; then :
+ enableval=$enable_sim_endian; case "${enableval}" in
+ b*|B*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";;
+ l*|L*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";;
+ yes) if test x"$wire_endian" != x; then
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}"
+ else
+ if test x"$default_endian" != x; then
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=${default_endian}"
+ else
+ echo "No hard-wired endian for target $target" 1>&6
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=0"
+ fi
+ fi;;
+ no) if test x"$default_endian" != x; then
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}"
+ else
+ if test x"$wire_endian" != x; then
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${wire_endian}"
+ else
+ echo "No default endian for target $target" 1>&6
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=0"
+ fi
+ fi;;
+ *) as_fn_error "\"Unknown value $enableval for --enable-sim-endian\"" "$LINENO" 5; sim_endian="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_endian" != x""; then
+ echo "Setting endian flags = $sim_endian" 6>&1
+fi
+else
+ if test x"$default_endian" != x; then
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}"
+else
+ if test x"$wire_endian" != x; then
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}"
+ else
+ sim_endian=
+ fi
+fi
+fi
+
+wire_alignment="STRICT_ALIGNMENT"
+default_alignment="STRICT_ALIGNMENT"
+
+# Check whether --enable-sim-alignment was given.
+if test "${enable_sim_alignment+set}" = set; then :
+ enableval=$enable_sim_alignment; case "${enableval}" in
+ strict | STRICT) sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";;
+ nonstrict | NONSTRICT) sim_alignment="-DWITH_ALIGNMENT=NONSTRICT_ALIGNMENT";;
+ forced | FORCED) sim_alignment="-DWITH_ALIGNMENT=FORCED_ALIGNMENT";;
+ yes) if test x"$wire_alignment" != x; then
+ sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}"
+ else
+ if test x"$default_alignment" != x; then
+ sim_alignment="-DWITH_ALIGNMENT=${default_alignment}"
+ else
+ echo "No hard-wired alignment for target $target" 1>&6
+ sim_alignment="-DWITH_ALIGNMENT=0"
+ fi
+ fi;;
+ no) if test x"$default_alignment" != x; then
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}"
+ else
+ if test x"$wire_alignment" != x; then
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${wire_alignment}"
+ else
+ echo "No default alignment for target $target" 1>&6
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=0"
+ fi
+ fi;;
+ *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-alignment\"" "$LINENO" 5; sim_alignment="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_alignment" != x""; then
+ echo "Setting alignment flags = $sim_alignment" 6>&1
+fi
+else
+ if test x"$default_alignment" != x; then
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}"
+else
+ if test x"$wire_alignment" != x; then
+ sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}"
+ else
+ sim_alignment=
+ fi
+fi
+fi
+
+
+# Check whether --enable-sim-hostendian was given.
+if test "${enable_sim_hostendian+set}" = set; then :
+ enableval=$enable_sim_hostendian; case "${enableval}" in
+ no) sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";;
+ b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";;
+ l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";;
+ *) as_fn_error "\"Unknown value $enableval for --enable-sim-hostendian\"" "$LINENO" 5; sim_hostendian="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_hostendian" != x""; then
+ echo "Setting hostendian flags = $sim_hostendian" 6>&1
+fi
+else
+
+if test "x$cross_compiling" = "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ if test $ac_cv_c_bigendian = yes; then
+ sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN"
+ else
+ sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN"
+ fi
+else
+ sim_hostendian="-DWITH_HOST_BYTE_ORDER=0"
+fi
+fi
+
+
+default_sim_default_model="bf537"
+# Check whether --enable-sim-default-model was given.
+if test "${enable_sim_default_model+set}" = set; then :
+ enableval=$enable_sim_default_model; case "${enableval}" in
+ yes|no) as_fn_error "\"Missing argument to --enable-sim-default-model\"" "$LINENO" 5;;
+ *) sim_default_model="-DWITH_DEFAULT_MODEL='\"${enableval}\"'";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_default_model" != x""; then
+ echo "Setting default model = $sim_default_model" 6>&1
+fi
+else
+ sim_default_model="-DWITH_DEFAULT_MODEL='\"${default_sim_default_model}\"'"
+fi
+
+
+
+# Check whether --enable-sim-environment was given.
+if test "${enable_sim_environment+set}" = set; then :
+ enableval=$enable_sim_environment; case "${enableval}" in
+ all | ALL) sim_environment="-DWITH_ENVIRONMENT=ALL_ENVIRONMENT";;
+ user | USER) sim_environment="-DWITH_ENVIRONMENT=USER_ENVIRONMENT";;
+ virtual | VIRTUAL) sim_environment="-DWITH_ENVIRONMENT=VIRTUAL_ENVIRONMENT";;
+ operating | OPERATING) sim_environment="-DWITH_ENVIRONMENT=OPERATING_ENVIRONMENT";;
+ *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-environment\"" "$LINENO" 5;
+ sim_environment="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_environment" != x""; then
+ echo "Setting sim environment = $sim_environment" 6>&1
+fi
+else
+ sim_environment="-DWITH_ENVIRONMENT=ALL_ENVIRONMENT"
+fi
+
+
+default_sim_inline=""
+# Check whether --enable-sim-inline was given.
+if test "${enable_sim_inline+set}" = set; then :
+ enableval=$enable_sim_inline; sim_inline=""
+case "$enableval" in
+ no) sim_inline="-DDEFAULT_INLINE=0";;
+ 0) sim_inline="-DDEFAULT_INLINE=0";;
+ yes | 2) sim_inline="-DDEFAULT_INLINE=ALL_C_INLINE";;
+ 1) sim_inline="-DDEFAULT_INLINE=INLINE_LOCALS";;
+ *) for x in `echo "$enableval" | sed -e "s/,/ /g"`; do
+ new_flag=""
+ case "$x" in
+ *_INLINE=*) new_flag="-D$x";;
+ *=*) new_flag=`echo "$x" | sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;;
+ *_INLINE) new_flag="-D$x=ALL_C_INLINE";;
+ *) new_flag="-D$x""_INLINE=ALL_C_INLINE";;
+ esac
+ if test x"$sim_inline" = x""; then
+ sim_inline="$new_flag"
+ else
+ sim_inline="$sim_inline $new_flag"
+ fi
+ done;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_inline" != x""; then
+ echo "Setting inline flags = $sim_inline" 6>&1
+fi
+else
+
+if test "x$cross_compiling" = "xno"; then
+ if test x"$GCC" != "x" -a x"${default_sim_inline}" != "x" ; then
+ sim_inline="${default_sim_inline}"
+ if test x"$silent" != x"yes"; then
+ echo "Setting inline flags = $sim_inline" 6>&1
+ fi
+ else
+ sim_inline=""
+ fi
+else
+ sim_inline="-DDEFAULT_INLINE=0"
+fi
+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 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 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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler warning flags" >&5
+$as_echo_n "checking compiler warning flags... " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ WARN_CFLAGS="${WARN_CFLAGS} $w"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$saved_CFLAGS"
+ esac
+ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${WARN_CFLAGS}${WERROR_CFLAGS}" >&5
+$as_echo "${WARN_CFLAGS}${WERROR_CFLAGS}" >&6; }
+fi
+
+
+if test x"yes" = x"yes"; then
+ sim_hw_p=yes
+else
+ sim_hw_p=no
+fi
+if test ""; then
+ hardware=""
+else
+ hardware="core pal glue"
+fi
+hardware="$hardware \
+ bfin_cec \
+ bfin_ctimer \
+ bfin_dma \
+ bfin_dmac \
+ bfin_ebiu_amc \
+ bfin_ebiu_ddrc \
+ bfin_ebiu_sdc \
+ bfin_emac \
+ bfin_eppi \
+ bfin_evt \
+ bfin_gptimer \
+ bfin_jtag \
+ bfin_mmu \
+ bfin_nfc \
+ bfin_otp \
+ bfin_pll \
+ bfin_ppi \
+ bfin_rtc \
+ bfin_sic \
+ bfin_spi \
+ bfin_trace \
+ bfin_twi \
+ bfin_uart \
+ bfin_uart2 \
+ bfin_wdog \
+ bfin_wp \
+ eth_phy \
+"
+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 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
+
+
+for ac_func in getuid getgid geteuid getegid setuid setgid mmap munmap
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_header in sys/ioctl.h sys/mman.h net/if.h linux/if_tun.h linux/mii.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+BFIN_SIM_EXTRA_OBJS=
+
+case ${host} in
+ *mingw32*) ;;
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DV_SOCKSER 1
+_ACEOF
+
+ BFIN_SIM_EXTRA_OBJS="${BFIN_SIM_EXTRA_OBJS} dv-sockser.o"
+ ;;
+esac
+
+BFIN_SIM_EXTRA_OBJS=${BFIN_SIM_EXTRA_OBJS}
+
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+ ac_pt_PKG_CONFIG=$PKG_CONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_PKG_CONFIG" = x; then
+ PKG_CONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PKG_CONFIG=$ac_pt_PKG_CONFIG
+ fi
+else
+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=0.9.0
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PKG_CONFIG=""
+ fi
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5
+$as_echo_n "checking for SDL... " >&6; }
+
+if test -n "$SDL_CFLAGS"; then
+ pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl" 2>/dev/null`
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SDL_LIBS"; then
+ pkg_cv_SDL_LIBS="$SDL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl" 2>/dev/null`
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "sdl" 2>&1`
+ else
+ SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors "sdl" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SDL_PKG_ERRORS" >&5
+
+ :
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ :
+else
+ SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
+ SDL_LIBS=$pkg_cv_SDL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+
+ SDL_CFLAGS="${SDL_CFLAGS} -DHAVE_SDL"
+ SDL_LIBS="-ldl"
+
+else
+ SDL_CFLAGS= SDL_LIBS=
+fi
+
+
+fi
+
+
+
+
+ac_sources="$sim_link_files"
+ac_dests="$sim_link_links"
+while test -n "$ac_sources"; do
+ set $ac_dests; ac_dest=$1; shift; ac_dests=$*
+ set $ac_sources; ac_source=$1; shift; ac_sources=$*
+ ac_config_links_1="$ac_config_links_1 $ac_dest:$ac_source"
+done
+ac_config_links="$ac_config_links $ac_config_links_1"
+
+cgen_breaks=""
+if grep CGEN_MAINT $srcdir/Makefile.in >/dev/null; then
+cgen_breaks="break cgen_rtx_error";
+fi
+
+ac_config_files="$ac_config_files Makefile.sim:Makefile.in"
+
+ac_config_files="$ac_config_files Make-common.sim:../common/Make-common.in"
+
+ac_config_files="$ac_config_files .gdbinit:../common/gdbinit.in"
+
+ac_config_commands="$ac_config_commands Makefile"
+
+ac_config_commands="$ac_config_commands stamp-h"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.64,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
+ "$ac_config_links_1") CONFIG_LINKS="$CONFIG_LINKS $ac_config_links_1" ;;
+ "Makefile.sim") CONFIG_FILES="$CONFIG_FILES Makefile.sim:Makefile.in" ;;
+ "Make-common.sim") CONFIG_FILES="$CONFIG_FILES Make-common.sim:../common/Make-common.in" ;;
+ ".gdbinit") CONFIG_FILES="$CONFIG_FILES .gdbinit:../common/gdbinit.in" ;;
+ "Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;;
+ "stamp-h") CONFIG_COMMANDS="$CONFIG_COMMANDS stamp-h" ;;
+
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error "could not create -" "$LINENO" 5
+ fi
+ ;;
+ :L)
+ #
+ # CONFIG_LINK
+ #
+
+ if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then
+ :
+ else
+ # Prefer the file from the source tree if names are identical.
+ if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then
+ ac_source=$srcdir/$ac_source
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5
+$as_echo "$as_me: linking $ac_source to $ac_file" >&6;}
+
+ if test ! -r "$ac_source"; then
+ as_fn_error "$ac_source: file not found" "$LINENO" 5
+ fi
+ rm -f "$ac_file"
+
+ # Try a relative symlink, then a hard link, then a copy.
+ case $srcdir in
+ [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;;
+ *) ac_rel_source=$ac_top_build_prefix$ac_source ;;
+ esac
+ ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
+ ln "$ac_source" "$ac_file" 2>/dev/null ||
+ cp -p "$ac_source" "$ac_file" ||
+ as_fn_error "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
+ fi
+ ;;
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "Makefile":C) echo "Merging Makefile.sim+Make-common.sim into Makefile ..."
+ rm -f Makesim1.tmp Makesim2.tmp Makefile
+ sed -n -e '/^## COMMON_PRE_/,/^## End COMMON_PRE_/ p' <Make-common.sim >Makesim1.tmp
+ sed -n -e '/^## COMMON_POST_/,/^## End COMMON_POST_/ p' <Make-common.sim >Makesim2.tmp
+ sed -e '/^## COMMON_PRE_/ r Makesim1.tmp' \
+ -e '/^## COMMON_POST_/ r Makesim2.tmp' \
+ <Makefile.sim >Makefile
+ rm -f Makefile.sim Make-common.sim Makesim1.tmp Makesim2.tmp
+ ;;
+ "stamp-h":C) echo > stamp-h ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
diff --git a/sim/bfin/configure.ac b/sim/bfin/configure.ac
new file mode 100644
index 00000000000..736a212458f
--- /dev/null
+++ b/sim/bfin/configure.ac
@@ -0,0 +1,75 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.59)dnl
+AC_INIT(Makefile.in)
+AC_CONFIG_HEADER(config.h:config.in)
+
+sinclude(../common/aclocal.m4)
+
+# Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around
+# it by inlining the macro's contents.
+sinclude(../common/common.m4)
+
+SIM_AC_OPTION_ENDIAN(LITTLE_ENDIAN)
+SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT,STRICT_ALIGNMENT)
+SIM_AC_OPTION_HOSTENDIAN
+SIM_AC_OPTION_DEFAULT_MODEL(bf537)
+SIM_AC_OPTION_ENVIRONMENT
+SIM_AC_OPTION_INLINE
+SIM_AC_OPTION_WARNINGS
+SIM_AC_OPTION_HARDWARE(yes,,\
+ bfin_cec \
+ bfin_ctimer \
+ bfin_dma \
+ bfin_dmac \
+ bfin_ebiu_amc \
+ bfin_ebiu_ddrc \
+ bfin_ebiu_sdc \
+ bfin_emac \
+ bfin_eppi \
+ bfin_evt \
+ bfin_gptimer \
+ bfin_jtag \
+ bfin_mmu \
+ bfin_nfc \
+ bfin_otp \
+ bfin_pll \
+ bfin_ppi \
+ bfin_rtc \
+ bfin_sic \
+ bfin_spi \
+ bfin_trace \
+ bfin_twi \
+ bfin_uart \
+ bfin_uart2 \
+ bfin_wdog \
+ bfin_wp \
+ eth_phy \
+)
+
+AC_CHECK_FUNCS([getuid getgid geteuid getegid setuid setgid mmap munmap])
+AC_CHECK_HEADERS([sys/ioctl.h sys/mman.h net/if.h linux/if_tun.h linux/mii.h])
+
+BFIN_SIM_EXTRA_OBJS=
+
+dnl make sure the dv-sockser code can be supported (i.e. windows)
+case ${host} in
+ *mingw32*) ;;
+ *)
+ AC_DEFINE_UNQUOTED([HAVE_DV_SOCKSER], 1, [Define if dv-sockser is usable.])
+ BFIN_SIM_EXTRA_OBJS="${BFIN_SIM_EXTRA_OBJS} dv-sockser.o"
+ ;;
+esac
+
+AC_SUBST([BFIN_SIM_EXTRA_OBJS], ${BFIN_SIM_EXTRA_OBJS})
+
+PKG_PROG_PKG_CONFIG
+PKG_CHECK_MODULES(SDL, sdl, [
+ AC_CHECK_LIB(dl, dlopen, [
+ SDL_CFLAGS="${SDL_CFLAGS} -DHAVE_SDL"
+ SDL_LIBS="-ldl"
+ ], [SDL_CFLAGS= SDL_LIBS=])
+ ], [:])
+AC_SUBST(SDL_CFLAGS)
+AC_SUBST(SDL_LIBS)
+
+SIM_AC_OUTPUT
diff --git a/sim/bfin/devices.c b/sim/bfin/devices.c
new file mode 100644
index 00000000000..50c53d10445
--- /dev/null
+++ b/sim/bfin/devices.c
@@ -0,0 +1,163 @@
+/* Blackfin device support.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "sim-hw.h"
+#include "hw-device.h"
+#include "dv-bfin_cec.h"
+#include "dv-bfin_mmu.h"
+
+static void
+bfin_mmr_invalid (struct hw *me, SIM_CPU *cpu, address_word addr,
+ unsigned nr_bytes, bool write)
+{
+ if (!cpu)
+ cpu = hw_system_cpu (me);
+
+ /* Only throw a fit if the cpu is doing the access. DMA/GDB simply
+ go unnoticed. Not exactly hardware behavior, but close enough. */
+ if (!cpu)
+ {
+ sim_io_eprintf (hw_system (me), "%s: invalid MMR access @ %#x\n",
+ hw_path (me), addr);
+ return;
+ }
+
+ HW_TRACE ((me, "invalid MMR %s to 0x%08lx length %u",
+ write ? "write" : "read", (unsigned long) addr, nr_bytes));
+
+ /* XXX: is this what hardware does ? */
+ if (addr >= BFIN_CORE_MMR_BASE)
+ /* XXX: This should be setting up CPLB fault addrs ? */
+ mmu_process_fault (cpu, addr, write, false, false, true);
+ else
+ /* XXX: Newer parts set up an interrupt from EBIU and program
+ EBIU_ERRADDR with the address. */
+ cec_hwerr (cpu, HWERR_SYSTEM_MMR);
+}
+
+void
+dv_bfin_mmr_invalid (struct hw *me, address_word addr, unsigned nr_bytes,
+ bool write)
+{
+ bfin_mmr_invalid (me, NULL, addr, nr_bytes, write);
+}
+
+void
+dv_bfin_mmr_require (struct hw *me, address_word addr, unsigned nr_bytes,
+ unsigned size, bool write)
+{
+ if (nr_bytes != size)
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, write);
+}
+
+static bool
+bfin_mmr_check (struct hw *me, SIM_CPU *cpu, address_word addr,
+ unsigned nr_bytes, bool write)
+{
+ if (addr >= BFIN_CORE_MMR_BASE)
+ {
+ /* All Core MMRs are aligned 32bits. */
+ if ((addr & 3) == 0 && nr_bytes == 4)
+ return true;
+ }
+ else if (addr >= BFIN_SYSTEM_MMR_BASE)
+ {
+ /* All System MMRs are 32bit aligned, but can be 16bits or 32bits. */
+ if ((addr & 0x3) == 0 && (nr_bytes == 2 || nr_bytes == 4))
+ return true;
+ }
+ else
+ return true;
+
+ /* Still here ? Must be crap. */
+ bfin_mmr_invalid (me, cpu, addr, nr_bytes, write);
+
+ return false;
+}
+
+bool
+dv_bfin_mmr_check (struct hw *me, address_word addr, unsigned nr_bytes,
+ bool write)
+{
+ return bfin_mmr_check (me, NULL, addr, nr_bytes, write);
+}
+
+int
+device_io_read_buffer (device *me, void *source, int space,
+ address_word addr, unsigned nr_bytes,
+ SIM_DESC sd, SIM_CPU *cpu, sim_cia cia)
+{
+ struct hw *dv_me = (struct hw *) me;
+
+ if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+ return nr_bytes;
+
+ if (bfin_mmr_check (dv_me, cpu, addr, nr_bytes, false))
+ if (cpu)
+ {
+ sim_cpu_hw_io_read_buffer (cpu, cia, dv_me, source, space,
+ addr, nr_bytes);
+ return nr_bytes;
+ }
+ else
+ return sim_hw_io_read_buffer (sd, dv_me, source, space, addr, nr_bytes);
+ else
+ return 0;
+}
+
+int
+device_io_write_buffer (device *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes,
+ SIM_DESC sd, SIM_CPU *cpu, sim_cia cia)
+{
+ struct hw *dv_me = (struct hw *) me;
+
+ if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+ return nr_bytes;
+
+ if (bfin_mmr_check (dv_me, cpu, addr, nr_bytes, true))
+ if (cpu)
+ {
+ sim_cpu_hw_io_write_buffer (cpu, cia, dv_me, source, space,
+ addr, nr_bytes);
+ return nr_bytes;
+ }
+ else
+ return sim_hw_io_write_buffer (sd, dv_me, source, space, addr, nr_bytes);
+ else
+ return 0;
+}
+
+void device_error (device *me, const char *message, ...)
+{
+ /* Don't bother doing anything here -- any place in common code that
+ calls device_error() follows it with sim_hw_abort(). Since the
+ device isn't bound to the system yet, we can't call any common
+ hardware error funcs on it or we'll hit a NULL pointer. */
+}
+
+unsigned int dv_get_bus_num (struct hw *me)
+{
+ const hw_unit *unit = hw_unit_address (me);
+ return unit->cells[unit->nr_cells - 1];
+}
diff --git a/sim/bfin/devices.h b/sim/bfin/devices.h
new file mode 100644
index 00000000000..76854ed33a4
--- /dev/null
+++ b/sim/bfin/devices.h
@@ -0,0 +1,156 @@
+/* Common Blackfin device stuff.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DEVICES_H
+#define DEVICES_H
+
+#include "hw-base.h"
+#include "hw-main.h"
+#include "hw-device.h"
+#include "hw-tree.h"
+
+/* We keep the same inital structure layout with DMA enabled devices. */
+struct dv_bfin {
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+};
+
+#define BFIN_MMR_16(mmr) mmr, __pad_##mmr
+
+/* Most peripherals have either one interrupt or these three. */
+#define DV_PORT_TX 0
+#define DV_PORT_RX 1
+#define DV_PORT_STAT 2
+
+unsigned int dv_get_bus_num (struct hw *);
+
+static inline bu8 dv_load_1 (const void *ptr)
+{
+ const unsigned char *c = ptr;
+ return c[0];
+}
+
+static inline void dv_store_1 (void *ptr, bu8 val)
+{
+ unsigned char *c = ptr;
+ c[0] = val;
+}
+
+static inline bu16 dv_load_2 (const void *ptr)
+{
+ const unsigned char *c = ptr;
+ return (c[1] << 8) | dv_load_1 (ptr);
+}
+
+static inline void dv_store_2 (void *ptr, bu16 val)
+{
+ unsigned char *c = ptr;
+ c[1] = val >> 8;
+ dv_store_1 (ptr, val);
+}
+
+static inline bu32 dv_load_4 (const void *ptr)
+{
+ const unsigned char *c = ptr;
+ return (c[3] << 24) | (c[2] << 16) | dv_load_2 (ptr);
+}
+
+static inline void dv_store_4 (void *ptr, bu32 val)
+{
+ unsigned char *c = ptr;
+ c[3] = val >> 24;
+ c[2] = val >> 16;
+ dv_store_2 (ptr, val);
+}
+
+/* Helpers for MMRs where all bits are W1C except for the specified
+ bits -- those ones are RO. */
+#define dv_w1c(ptr, val, bits) (*(ptr) &= ~((val) & (bits)))
+static inline void dv_w1c_2 (bu16 *ptr, bu16 val, bu16 bits)
+{
+ dv_w1c (ptr, val, bits);
+}
+static inline void dv_w1c_4 (bu32 *ptr, bu32 val, bu32 bits)
+{
+ dv_w1c (ptr, val, bits);
+}
+
+/* Helpers for MMRs where all bits are RW except for the specified
+ bits -- those ones are W1C. */
+#define dv_w1c_partial(ptr, val, bits) \
+ (*(ptr) = ((val) | (*(ptr) & (bits))) & ~((val) & (bits)))
+static inline void dv_w1c_2_partial (bu16 *ptr, bu16 val, bu16 bits)
+{
+ dv_w1c_partial (ptr, val, bits);
+}
+static inline void dv_w1c_4_partial (bu32 *ptr, bu32 val, bu32 bits)
+{
+ dv_w1c_partial (ptr, val, bits);
+}
+
+/* XXX: Grubbing around in device internals is probably wrong, but
+ until someone shows me what's right ... */
+static inline struct hw *
+dv_get_device (SIM_CPU *cpu, const char *device_name)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ void *root = STATE_HW (sd);
+ return hw_tree_find_device (root, device_name);
+}
+
+static inline void *
+dv_get_state (SIM_CPU *cpu, const char *device_name)
+{
+ return hw_data (dv_get_device (cpu, device_name));
+}
+
+#define DV_STATE(cpu, dv) dv_get_state (cpu, "/core/bfin_"#dv)
+
+#define DV_STATE_CACHED(cpu, dv) \
+ ({ \
+ struct bfin_##dv *__##dv = BFIN_CPU_STATE.dv##_cache; \
+ if (!__##dv) \
+ BFIN_CPU_STATE.dv##_cache = __##dv = dv_get_state (cpu, "/core/bfin_"#dv); \
+ __##dv; \
+ })
+
+void dv_bfin_mmr_invalid (struct hw *, address_word, unsigned nr_bytes, bool write);
+void dv_bfin_mmr_require (struct hw *, address_word, unsigned nr_bytes, unsigned size, bool write);
+bool dv_bfin_mmr_check (struct hw *, address_word, unsigned nr_bytes, bool write);
+
+#define dv_bfin_mmr_require_16(hw, addr, nr_bytes, write) dv_bfin_mmr_require (hw, addr, nr_bytes, 2, write)
+#define dv_bfin_mmr_require_32(hw, addr, nr_bytes, write) dv_bfin_mmr_require (hw, addr, nr_bytes, 4, write)
+
+#define HW_TRACE_WRITE() \
+ HW_TRACE ((me, "write 0x%08lx (%s) length %u with 0x%x", \
+ (unsigned long) addr, mmr_name (mmr_off), nr_bytes, value))
+#define HW_TRACE_READ() \
+ HW_TRACE ((me, "read 0x%08lx (%s) length %u", \
+ (unsigned long) addr, mmr_name (mmr_off), nr_bytes))
+
+#define HW_TRACE_DMA_WRITE() \
+ HW_TRACE ((me, "dma write 0x%08lx length %u", \
+ (unsigned long) addr, nr_bytes))
+#define HW_TRACE_DMA_READ() \
+ HW_TRACE ((me, "dma read 0x%08lx length %u", \
+ (unsigned long) addr, nr_bytes))
+
+#endif
diff --git a/sim/bfin/dv-bfin_cec.c b/sim/bfin/dv-bfin_cec.c
new file mode 100644
index 00000000000..88fe9ddeabd
--- /dev/null
+++ b/sim/bfin/dv-bfin_cec.c
@@ -0,0 +1,807 @@
+/* Blackfin Core Event Controller (CEC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_cec.h"
+#include "dv-bfin_evt.h"
+#include "dv-bfin_mmu.h"
+
+struct bfin_cec
+{
+ bu32 base;
+ SIM_CPU *cpu;
+ struct hw *me;
+ struct hw_event *pending;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 evt_override, imask, ipend, ilat, iprio;
+};
+#define mmr_base() offsetof(struct bfin_cec, evt_override)
+#define mmr_offset(mmr) (offsetof(struct bfin_cec, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "EVT_OVERRIDE", "IMASK", "IPEND", "ILAT", "IPRIO",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static void _cec_raise (SIM_CPU *, struct bfin_cec *, int);
+
+static void
+bfin_cec_hw_event_callback (struct hw *me, void *data)
+{
+ struct bfin_cec *cec = data;
+ hw_event_queue_deschedule (me, cec->pending);
+ _cec_raise (cec->cpu, cec, -1);
+ cec->pending = NULL;
+}
+static void
+bfin_cec_check_pending (struct hw *me, struct bfin_cec *cec)
+{
+ if (cec->pending)
+ return;
+ cec->pending = hw_event_queue_schedule (me, 0, bfin_cec_hw_event_callback, cec);
+}
+static void
+_cec_check_pending (SIM_CPU *cpu, struct bfin_cec *cec)
+{
+ bfin_cec_check_pending (cec->me, cec);
+}
+
+static void
+_cec_imask_write (struct bfin_cec *cec, bu32 value)
+{
+ cec->imask = (value & IVG_MASKABLE_B) | (cec->imask & IVG_UNMASKABLE_B);
+}
+
+static unsigned
+bfin_cec_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_cec *cec = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+
+ value = dv_load_4 (source);
+ mmr_off = addr - cec->base;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(evt_override):
+ cec->evt_override = value;
+ break;
+ case mmr_offset(imask):
+ _cec_imask_write (cec, value);
+ bfin_cec_check_pending (me, cec);
+ break;
+ case mmr_offset(ipend):
+ /* Read-only register. */
+ break;
+ case mmr_offset(ilat):
+ dv_w1c_4 (&cec->ilat, value, 0);
+ break;
+ case mmr_offset(iprio):
+ cec->iprio = (value & IVG_UNMASKABLE_B);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_cec_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_cec *cec = hw_data (me);
+ bu32 mmr_off;
+ bu32 *valuep;
+
+ mmr_off = addr - cec->base;
+ valuep = (void *)((unsigned long)cec + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ dv_store_4 (dest, *valuep);
+
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_cec_ports[] = {
+ { "emu", IVG_EMU, 0, input_port, },
+ { "rst", IVG_RST, 0, input_port, },
+ { "nmi", IVG_NMI, 0, input_port, },
+ { "evx", IVG_EVX, 0, input_port, },
+ { "ivhw", IVG_IVHW, 0, input_port, },
+ { "ivtmr", IVG_IVTMR, 0, input_port, },
+ { "ivg7", IVG7, 0, input_port, },
+ { "ivg8", IVG8, 0, input_port, },
+ { "ivg9", IVG9, 0, input_port, },
+ { "ivg10", IVG10, 0, input_port, },
+ { "ivg11", IVG11, 0, input_port, },
+ { "ivg12", IVG12, 0, input_port, },
+ { "ivg13", IVG13, 0, input_port, },
+ { "ivg14", IVG14, 0, input_port, },
+ { "ivg15", IVG15, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_cec_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ struct bfin_cec *cec = hw_data (me);
+ _cec_raise (cec->cpu, cec, my_port);
+}
+
+static void
+attach_bfin_cec_regs (struct hw *me, struct bfin_cec *cec)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_COREMMR_CEC_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_CEC_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ cec->base = attach_address;
+ /* XXX: should take from the device tree. */
+ cec->cpu = STATE_CPU (hw_system (me), 0);
+ cec->me = me;
+}
+
+static void
+bfin_cec_finish (struct hw *me)
+{
+ struct bfin_cec *cec;
+
+ cec = HW_ZALLOC (me, struct bfin_cec);
+
+ set_hw_data (me, cec);
+ set_hw_io_read_buffer (me, bfin_cec_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_cec_io_write_buffer);
+ set_hw_ports (me, bfin_cec_ports);
+ set_hw_port_event (me, bfin_cec_port_event);
+
+ attach_bfin_cec_regs (me, cec);
+
+ /* Initialize the CEC. */
+ cec->imask = IVG_UNMASKABLE_B;
+ cec->ipend = IVG_RST_B | IVG_IRPTEN_B;
+}
+
+const struct hw_descriptor dv_bfin_cec_descriptor[] = {
+ {"bfin_cec", bfin_cec_finish,},
+ {NULL, NULL},
+};
+
+static const char * const excp_decoded[] = {
+ [VEC_SYS ] = "Custom exception 0 (system call)",
+ [VEC_EXCPT01 ] = "Custom exception 1 (software breakpoint)",
+ [VEC_EXCPT02 ] = "Custom exception 2 (KGDB hook)",
+ [VEC_EXCPT03 ] = "Custom exception 3 (userspace stack overflow)",
+ [VEC_EXCPT04 ] = "Custom exception 4 (dump trace buffer)",
+ [VEC_EXCPT05 ] = "Custom exception 5",
+ [VEC_EXCPT06 ] = "Custom exception 6",
+ [VEC_EXCPT07 ] = "Custom exception 7",
+ [VEC_EXCPT08 ] = "Custom exception 8",
+ [VEC_EXCPT09 ] = "Custom exception 9",
+ [VEC_EXCPT10 ] = "Custom exception 10",
+ [VEC_EXCPT11 ] = "Custom exception 11",
+ [VEC_EXCPT12 ] = "Custom exception 12",
+ [VEC_EXCPT13 ] = "Custom exception 13",
+ [VEC_EXCPT14 ] = "Custom exception 14",
+ [VEC_EXCPT15 ] = "Custom exception 15",
+ [VEC_STEP ] = "Hardware single step",
+ [VEC_OVFLOW ] = "Trace buffer overflow",
+ [VEC_UNDEF_I ] = "Undefined instruction",
+ [VEC_ILGAL_I ] = "Illegal instruction combo (multi-issue)",
+ [VEC_CPLB_VL ] = "DCPLB protection violation",
+ [VEC_MISALI_D ] = "Unaligned data access",
+ [VEC_UNCOV ] = "Unrecoverable event (double fault)",
+ [VEC_CPLB_M ] = "DCPLB miss",
+ [VEC_CPLB_MHIT ] = "Multiple DCPLB hit",
+ [VEC_WATCH ] = "Watchpoint match",
+ [VEC_ISTRU_VL ] = "ADSP-BF535 only",
+ [VEC_MISALI_I ] = "Unaligned instruction access",
+ [VEC_CPLB_I_VL ] = "ICPLB protection violation",
+ [VEC_CPLB_I_M ] = "ICPLB miss",
+ [VEC_CPLB_I_MHIT] = "Multiple ICPLB hit",
+ [VEC_ILL_RES ] = "Illegal supervisor resource",
+};
+
+#define CEC_STATE(cpu) DV_STATE_CACHED (cpu, cec)
+
+#define __cec_get_ivg(val) (ffs ((val) & ~IVG_IRPTEN_B) - 1)
+#define _cec_get_ivg(cec) __cec_get_ivg ((cec)->ipend & ~IVG_EMU_B)
+
+int
+cec_get_ivg (SIM_CPU *cpu)
+{
+ switch (STATE_ENVIRONMENT (CPU_STATE (cpu)))
+ {
+ case OPERATING_ENVIRONMENT:
+ return _cec_get_ivg (CEC_STATE (cpu));
+ default:
+ return IVG_USER;
+ }
+}
+
+static bool
+_cec_is_supervisor_mode (struct bfin_cec *cec)
+{
+ return (cec->ipend & ~(IVG_EMU_B | IVG_IRPTEN_B));
+}
+bool
+cec_is_supervisor_mode (SIM_CPU *cpu)
+{
+ switch (STATE_ENVIRONMENT (CPU_STATE (cpu)))
+ {
+ case OPERATING_ENVIRONMENT:
+ return _cec_is_supervisor_mode (CEC_STATE (cpu));
+ case USER_ENVIRONMENT:
+ return false;
+ default:
+ return true;
+ }
+}
+static bool
+_cec_is_user_mode (struct bfin_cec *cec)
+{
+ return !_cec_is_supervisor_mode (cec);
+}
+bool
+cec_is_user_mode (SIM_CPU *cpu)
+{
+ return !cec_is_supervisor_mode (cpu);
+}
+static void
+_cec_require_supervisor (SIM_CPU *cpu, struct bfin_cec *cec)
+{
+ if (_cec_is_user_mode (cec))
+ cec_exception (cpu, VEC_ILL_RES);
+}
+void
+cec_require_supervisor (SIM_CPU *cpu)
+{
+ /* Do not call _cec_require_supervisor() to avoid CEC_STATE()
+ as that macro requires OS operating mode. */
+ if (cec_is_user_mode (cpu))
+ cec_exception (cpu, VEC_ILL_RES);
+}
+
+#define excp_to_sim_halt(reason, sigrc) \
+ sim_engine_halt (CPU_STATE (cpu), cpu, NULL, PCREG, reason, sigrc)
+void
+cec_exception (SIM_CPU *cpu, int excp)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ int sigrc = -1;
+
+ TRACE_EVENTS (cpu, "processing exception %#x in EVT%i", excp,
+ cec_get_ivg (cpu));
+
+ /* Ideally what would happen here for real hardware exceptions (not
+ fake sim ones) is that:
+ - For service exceptions (excp <= 0x11):
+ RETX is the _next_ PC which can be tricky with jumps/hardware loops/...
+ - For error exceptions (excp > 0x11):
+ RETX is the _current_ PC (i.e. the one causing the exception)
+ - PC is loaded with EVT3 MMR
+ - ILAT/IPEND in CEC is updated depending on current IVG level
+ - the fault address MMRs get updated with data/instruction info
+ - Execution continues on in the EVT3 handler */
+
+ /* Handle simulator exceptions first. */
+ switch (excp)
+ {
+ case VEC_SIM_HLT:
+ excp_to_sim_halt (sim_exited, 0);
+ return;
+ case VEC_SIM_ABORT:
+ excp_to_sim_halt (sim_exited, 1);
+ return;
+ case VEC_SIM_TRAP:
+ /* GDB expects us to step over EMUEXCPT. */
+ /* XXX: What about hwloops and EMUEXCPT at the end?
+ Pretty sure gdb doesn't handle this already... */
+ SET_PCREG (PCREG + 2);
+ /* Only trap when we are running in gdb. */
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ excp_to_sim_halt (sim_stopped, SIM_SIGTRAP);
+ return;
+ case VEC_SIM_DBGA:
+ /* If running in gdb, simply trap. */
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ excp_to_sim_halt (sim_stopped, SIM_SIGTRAP);
+ else
+ excp_to_sim_halt (sim_exited, 2);
+ }
+
+ if (excp <= 0x3f)
+ {
+ SET_EXCAUSE (excp);
+ if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
+ {
+ /* ICPLB regs always get updated. */
+ /* XXX: Should optimize this call path ... */
+ if (excp != VEC_MISALI_I && excp != VEC_MISALI_D
+ && excp != VEC_CPLB_I_M && excp != VEC_CPLB_M
+ && excp != VEC_CPLB_I_VL && excp != VEC_CPLB_VL
+ && excp != VEC_CPLB_I_MHIT && excp != VEC_CPLB_MHIT)
+ mmu_log_ifault (cpu);
+ _cec_raise (cpu, CEC_STATE (cpu), IVG_EVX);
+ /* We need to restart the engine so that we don't return
+ and continue processing this bad insn. */
+ if (EXCAUSE >= 0x20)
+ sim_engine_restart (sd, cpu, NULL, PCREG);
+ return;
+ }
+ }
+
+ TRACE_EVENTS (cpu, "running virtual exception handler");
+
+ switch (excp)
+ {
+ case VEC_SYS:
+ bfin_syscall (cpu);
+ break;
+
+ case VEC_EXCPT01: /* Userspace gdb breakpoint. */
+ sigrc = SIM_SIGTRAP;
+ break;
+
+ case VEC_UNDEF_I: /* Undefined instruction. */
+ sigrc = SIM_SIGILL;
+ break;
+
+ case VEC_ILL_RES: /* Illegal supervisor resource. */
+ case VEC_MISALI_I: /* Misaligned instruction. */
+ sigrc = SIM_SIGBUS;
+ break;
+
+ case VEC_CPLB_M:
+ case VEC_CPLB_I_M:
+ sigrc = SIM_SIGSEGV;
+ break;
+
+ default:
+ sim_io_eprintf (sd, "Unhandled exception %#x at 0x%08x (%s)\n",
+ excp, PCREG, excp_decoded[excp]);
+ sigrc = SIM_SIGILL;
+ break;
+ }
+
+ if (sigrc != -1)
+ excp_to_sim_halt (sim_stopped, sigrc);
+}
+
+bu32 cec_cli (SIM_CPU *cpu)
+{
+ struct bfin_cec *cec;
+ bu32 old_mask;
+
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) != OPERATING_ENVIRONMENT)
+ return 0;
+
+ cec = CEC_STATE (cpu);
+ _cec_require_supervisor (cpu, cec);
+
+ /* XXX: what about IPEND[4] ? */
+ old_mask = cec->imask;
+ _cec_imask_write (cec, 0);
+
+ TRACE_EVENTS (cpu, "CLI changed IMASK from %#x to %#x", old_mask, cec->imask);
+
+ return old_mask;
+}
+
+void cec_sti (SIM_CPU *cpu, bu32 ints)
+{
+ struct bfin_cec *cec;
+ bu32 old_mask;
+
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) != OPERATING_ENVIRONMENT)
+ return;
+
+ cec = CEC_STATE (cpu);
+ _cec_require_supervisor (cpu, cec);
+
+ /* XXX: what about IPEND[4] ? */
+ old_mask = cec->imask;
+ _cec_imask_write (cec, ints);
+
+ TRACE_EVENTS (cpu, "STI changed IMASK from %#x to %#x", old_mask, cec->imask);
+
+ /* Check for pending interrupts that are now enabled. */
+ _cec_check_pending (cpu, cec);
+}
+
+static void
+cec_irpten_enable (SIM_CPU *cpu, struct bfin_cec *cec)
+{
+ /* Globally mask interrupts. */
+ TRACE_EVENTS (cpu, "setting IPEND[4] to globally mask interrupts");
+ cec->ipend |= IVG_IRPTEN_B;
+}
+
+static void
+cec_irpten_disable (SIM_CPU *cpu, struct bfin_cec *cec)
+{
+ /* Clear global interrupt mask. */
+ TRACE_EVENTS (cpu, "clearing IPEND[4] to not globally mask interrupts");
+ cec->ipend &= ~IVG_IRPTEN_B;
+}
+
+static void
+_cec_raise (SIM_CPU *cpu, struct bfin_cec *cec, int ivg)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ int curr_ivg = _cec_get_ivg (cec);
+ bool snen;
+ bool irpten;
+
+ TRACE_EVENTS (cpu, "processing request for EVT%i while at EVT%i",
+ ivg, curr_ivg);
+
+ irpten = (cec->ipend & IVG_IRPTEN_B);
+ snen = (SYSCFGREG & SYSCFG_SNEN);
+
+ if (curr_ivg == -1)
+ curr_ivg = IVG_USER;
+
+ /* Just check for higher latched interrupts. */
+ if (ivg == -1)
+ {
+ if (irpten)
+ goto done; /* All interrupts are masked anyways. */
+
+ ivg = __cec_get_ivg (cec->ilat & cec->imask);
+ if (ivg < 0)
+ goto done; /* Nothing latched. */
+
+ if (ivg > curr_ivg)
+ goto done; /* Nothing higher latched. */
+
+ if (!snen && ivg == curr_ivg)
+ goto done; /* Self nesting disabled. */
+
+ /* Still here, so fall through to raise to higher pending. */
+ }
+
+ cec->ilat |= (1 << ivg);
+
+ if (ivg <= IVG_EVX)
+ {
+ /* These two are always processed. */
+ if (ivg == IVG_EMU || ivg == IVG_RST)
+ goto process_int;
+
+ /* Anything lower might trigger a double fault. */
+ if (curr_ivg <= ivg)
+ {
+ /* Double fault ! :( */
+ SET_EXCAUSE (VEC_UNCOV);
+ /* XXX: SET_RETXREG (...); */
+ sim_io_error (sd, "%s: double fault at 0x%08x ! :(", __func__, PCREG);
+ excp_to_sim_halt (sim_stopped, SIM_SIGABRT);
+ }
+
+ /* No double fault -> always process. */
+ goto process_int;
+ }
+ else if (irpten && curr_ivg != IVG_USER)
+ {
+ /* Interrupts are globally masked. */
+ }
+ else if (!(cec->imask & (1 << ivg)))
+ {
+ /* This interrupt is masked. */
+ }
+ else if (ivg < curr_ivg || (snen && ivg == curr_ivg))
+ {
+ /* Do transition! */
+ bu32 oldpc;
+
+ process_int:
+ cec->ipend |= (1 << ivg);
+ cec->ilat &= ~(1 << ivg);
+
+ /* Interrupts are processed in between insns which means the return
+ point is the insn-to-be-executed (which is the current PC). But
+ exceptions are handled while executing an insn, so we may have to
+ advance the PC ourselves when setting RETX.
+ XXX: Advancing the PC should only be for "service" exceptions, and
+ handling them after executing the insn should be OK, which
+ means we might be able to use the event interface for it. */
+
+ oldpc = PCREG;
+ switch (ivg)
+ {
+ case IVG_EMU:
+ /* Signal the JTAG ICE. */
+ /* XXX: what happens with 'raise 0' ? */
+ SET_RETEREG (oldpc);
+ excp_to_sim_halt (sim_stopped, SIM_SIGTRAP);
+ /* XXX: Need an easy way for gdb to signal it isnt here. */
+ cec->ipend &= ~IVG_EMU_B;
+ break;
+ case IVG_RST:
+ /* Have the core reset simply exit (i.e. "shutdown"). */
+ excp_to_sim_halt (sim_exited, 0);
+ break;
+ case IVG_NMI:
+ /* XXX: Should check this. */
+ SET_RETNREG (oldpc);
+ break;
+ case IVG_EVX:
+ /* Non-service exceptions point to the excepting instruction. */
+ if (EXCAUSE >= 0x20)
+ SET_RETXREG (oldpc);
+ else
+ {
+ bu32 nextpc = hwloop_get_next_pc (cpu, oldpc, INSN_LEN);
+ SET_RETXREG (nextpc);
+ }
+
+ break;
+ case IVG_IRPTEN:
+ /* XXX: what happens with 'raise 4' ? */
+ sim_io_error (sd, "%s: what to do with 'raise 4' ?", __func__);
+ break;
+ default:
+ SET_RETIREG (oldpc | (ivg == curr_ivg ? 1 : 0));
+ break;
+ }
+
+ /* If EVT_OVERRIDE is in effect (IVG7+), use the reset address. */
+ if ((cec->evt_override & 0xff80) & (1 << ivg))
+ SET_PCREG (cec_get_reset_evt (cpu));
+ else
+ SET_PCREG (cec_get_evt (cpu, ivg));
+
+ TRACE_BRANCH (cpu, oldpc, PCREG, -1, "CEC changed PC (to EVT%i):", ivg);
+ BFIN_CPU_STATE.did_jump = true;
+
+ /* Enable the global interrupt mask upon interrupt entry. */
+ if (ivg >= IVG_IVHW)
+ cec_irpten_enable (cpu, cec);
+ }
+
+ /* When moving between states, don't let internal states bleed through. */
+ DIS_ALGN_EXPT &= ~1;
+
+ /* When going from user to super, we set LSB in LB regs to avoid
+ misbehavior and/or malicious code.
+ Also need to load SP alias with KSP. */
+ if (curr_ivg == IVG_USER)
+ {
+ int i;
+ for (i = 0; i < 2; ++i)
+ if (!(LBREG (i) & 1))
+ SET_LBREG (i, LBREG (i) | 1);
+ SET_USPREG (SPREG);
+ SET_SPREG (KSPREG);
+ }
+
+ done:
+ TRACE_EVENTS (cpu, "now at EVT%i", _cec_get_ivg (cec));
+}
+
+static bu32
+cec_read_ret_reg (SIM_CPU *cpu, int ivg)
+{
+ switch (ivg)
+ {
+ case IVG_EMU: return RETEREG;
+ case IVG_NMI: return RETNREG;
+ case IVG_EVX: return RETXREG;
+ default: return RETIREG;
+ }
+}
+
+void
+cec_latch (SIM_CPU *cpu, int ivg)
+{
+ struct bfin_cec *cec;
+
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) != OPERATING_ENVIRONMENT)
+ {
+ bu32 oldpc = PCREG;
+ SET_PCREG (cec_read_ret_reg (cpu, ivg));
+ TRACE_BRANCH (cpu, oldpc, PCREG, -1, "CEC changed PC");
+ return;
+ }
+
+ cec = CEC_STATE (cpu);
+ cec->ilat |= (1 << ivg);
+ _cec_check_pending (cpu, cec);
+}
+
+void
+cec_hwerr (SIM_CPU *cpu, int hwerr)
+{
+ SET_HWERRCAUSE (hwerr);
+ cec_latch (cpu, IVG_IVHW);
+}
+
+void
+cec_return (SIM_CPU *cpu, int ivg)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ struct bfin_cec *cec;
+ bool snen;
+ int curr_ivg;
+ bu32 oldpc, newpc;
+
+ oldpc = PCREG;
+
+ BFIN_CPU_STATE.did_jump = true;
+ if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+ {
+ SET_PCREG (cec_read_ret_reg (cpu, ivg));
+ TRACE_BRANCH (cpu, oldpc, PCREG, -1, "CEC changed PC");
+ return;
+ }
+
+ cec = CEC_STATE (cpu);
+
+ /* XXX: This isn't entirely correct ... */
+ cec->ipend &= ~IVG_EMU_B;
+
+ curr_ivg = _cec_get_ivg (cec);
+ if (curr_ivg == -1)
+ curr_ivg = IVG_USER;
+ if (ivg == -1)
+ ivg = curr_ivg;
+
+ TRACE_EVENTS (cpu, "returning from EVT%i (should be EVT%i)", curr_ivg, ivg);
+
+ /* Not allowed to return from usermode. */
+ if (curr_ivg == IVG_USER)
+ cec_exception (cpu, VEC_ILL_RES);
+
+ if (ivg > IVG15 || ivg < 0)
+ sim_io_error (sd, "%s: ivg %i out of range !", __func__, ivg);
+
+ _cec_require_supervisor (cpu, cec);
+
+ switch (ivg)
+ {
+ case IVG_EMU:
+ /* RTE -- only valid in emulation mode. */
+ /* XXX: What does the hardware do ? */
+ if (curr_ivg != IVG_EMU)
+ cec_exception (cpu, VEC_ILL_RES);
+ break;
+ case IVG_NMI:
+ /* RTN -- only valid in NMI. */
+ /* XXX: What does the hardware do ? */
+ if (curr_ivg != IVG_NMI)
+ cec_exception (cpu, VEC_ILL_RES);
+ break;
+ case IVG_EVX:
+ /* RTX -- only valid in exception. */
+ /* XXX: What does the hardware do ? */
+ if (curr_ivg != IVG_EVX)
+ cec_exception (cpu, VEC_ILL_RES);
+ break;
+ default:
+ /* RTI -- not valid in emulation, nmi, exception, or user. */
+ /* XXX: What does the hardware do ? */
+ if (curr_ivg == IVG_EMU || curr_ivg == IVG_NMI
+ || curr_ivg == IVG_EVX || curr_ivg == IVG_USER)
+ cec_exception (cpu, VEC_ILL_RES);
+ break;
+ case IVG_IRPTEN:
+ /* XXX: Is this even possible ? */
+ excp_to_sim_halt (sim_stopped, SIM_SIGABRT);
+ break;
+ }
+ newpc = cec_read_ret_reg (cpu, ivg);
+
+ /* XXX: Does this nested trick work on EMU/NMI/EVX ? */
+ snen = (newpc & 1);
+ /* XXX: Delayed clear shows bad PCREG register trace above ? */
+ SET_PCREG (newpc & ~1);
+
+ TRACE_BRANCH (cpu, oldpc, PCREG, -1, "CEC changed PC (from EVT%i)", ivg);
+
+ /* Update ipend after the TRACE_BRANCH so dv-bfin_trace
+ knows current CEC state wrt overflow. */
+ if (!snen)
+ cec->ipend &= ~(1 << ivg);
+
+ /* Disable global interrupt mask to let any interrupt take over, but
+ only when we were already in a RTI level. Only way we could have
+ raised at that point is if it was cleared in the first place. */
+ if (ivg >= IVG_IVHW || ivg == IVG_RST)
+ cec_irpten_disable (cpu, cec);
+
+ /* When going from super to user, we clear LSB in LB regs in case
+ it was set on the transition up.
+ Also need to load SP alias with USP. */
+ if (_cec_get_ivg (cec) == -1)
+ {
+ int i;
+ for (i = 0; i < 2; ++i)
+ if (LBREG (i) & 1)
+ SET_LBREG (i, LBREG (i) & ~1);
+ SET_KSPREG (SPREG);
+ SET_SPREG (USPREG);
+ }
+
+ /* Check for pending interrupts before we return to usermode. */
+ _cec_check_pending (cpu, cec);
+}
+
+void
+cec_push_reti (SIM_CPU *cpu)
+{
+ /* XXX: Need to check hardware with popped RETI value
+ and bit 1 is set (when handling nested interrupts).
+ Also need to check behavior wrt SNEN in SYSCFG. */
+ struct bfin_cec *cec;
+
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) != OPERATING_ENVIRONMENT)
+ return;
+
+ TRACE_EVENTS (cpu, "pushing RETI");
+
+ cec = CEC_STATE (cpu);
+ cec_irpten_disable (cpu, cec);
+ /* Check for pending interrupts. */
+ _cec_check_pending (cpu, cec);
+}
+
+void
+cec_pop_reti (SIM_CPU *cpu)
+{
+ /* XXX: Need to check hardware with popped RETI value
+ and bit 1 is set (when handling nested interrupts).
+ Also need to check behavior wrt SNEN in SYSCFG. */
+ struct bfin_cec *cec;
+
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) != OPERATING_ENVIRONMENT)
+ return;
+
+ TRACE_EVENTS (cpu, "popping RETI");
+
+ cec = CEC_STATE (cpu);
+ cec_irpten_enable (cpu, cec);
+}
diff --git a/sim/bfin/dv-bfin_cec.h b/sim/bfin/dv-bfin_cec.h
new file mode 100644
index 00000000000..027c89389bc
--- /dev/null
+++ b/sim/bfin/dv-bfin_cec.h
@@ -0,0 +1,139 @@
+/* Blackfin Core Event Controller (CEC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_CEC_H
+#define DV_BFIN_CEC_H
+
+#include "sim-main.h"
+
+#define BFIN_COREMMR_CEC_BASE 0xFFE02100
+#define BFIN_COREMMR_CEC_SIZE (4 * 5)
+
+/* 0xFFE02100 ... 0xFFE02110 */
+#define BFIN_COREMMR_EVT_OVERRIDE (BFIN_COREMMR_CEC_BASE + (4 * 0))
+#define BFIN_COREMMR_IMASK (BFIN_COREMMR_CEC_BASE + (4 * 1))
+#define BFIN_COREMMR_IPEND (BFIN_COREMMR_CEC_BASE + (4 * 2))
+#define BFIN_COREMMR_ILAT (BFIN_COREMMR_CEC_BASE + (4 * 3))
+#define BFIN_COREMMR_IPRIO (BFIN_COREMMR_CEC_BASE + (4 * 4))
+
+#define IVG_EMU 0
+#define IVG_RST 1
+#define IVG_NMI 2
+#define IVG_EVX 3
+#define IVG_IRPTEN 4 /* Global is Reserved */
+#define IVG_IVHW 5
+#define IVG_IVTMR 6
+#define IVG7 7
+#define IVG8 8
+#define IVG9 9
+#define IVG10 10
+#define IVG11 11
+#define IVG12 12
+#define IVG13 13
+#define IVG14 14
+#define IVG15 15
+#define IVG_USER 16 /* Not real; for internal use */
+
+#define IVG_EMU_B (1 << IVG_EMU)
+#define IVG_RST_B (1 << IVG_RST)
+#define IVG_NMI_B (1 << IVG_NMI)
+#define IVG_EVX_B (1 << IVG_EVX)
+#define IVG_IRPTEN_B (1 << IVG_IRPTEN)
+#define IVG_IVHW_B (1 << IVG_IVHW)
+#define IVG_IVTMR_B (1 << IVG_IVTMR)
+#define IVG7_B (1 << IVG7)
+#define IVG8_B (1 << IVG8)
+#define IVG9_B (1 << IVG9)
+#define IVG10_B (1 << IVG10)
+#define IVG11_B (1 << IVG11)
+#define IVG12_B (1 << IVG12)
+#define IVG13_B (1 << IVG13)
+#define IVG14_B (1 << IVG14)
+#define IVG15_B (1 << IVG15)
+#define IVG_UNMASKABLE_B \
+ (IVG_EMU_B | IVG_RST_B | IVG_NMI_B | IVG_EVX_B | IVG_IRPTEN_B)
+#define IVG_MASKABLE_B \
+ (IVG_IVHW_B | IVG_IVTMR_B | IVG7_B | IVG8_B | IVG9_B | \
+ IVG10_B | IVG11_B | IVG12_B | IVG13_B | IVG14_B | IVG15_B)
+
+#define VEC_SYS 0x0
+#define VEC_EXCPT01 0x1
+#define VEC_EXCPT02 0x2
+#define VEC_EXCPT03 0x3
+#define VEC_EXCPT04 0x4
+#define VEC_EXCPT05 0x5
+#define VEC_EXCPT06 0x6
+#define VEC_EXCPT07 0x7
+#define VEC_EXCPT08 0x8
+#define VEC_EXCPT09 0x9
+#define VEC_EXCPT10 0xa
+#define VEC_EXCPT11 0xb
+#define VEC_EXCPT12 0xc
+#define VEC_EXCPT13 0xd
+#define VEC_EXCPT14 0xe
+#define VEC_EXCPT15 0xf
+#define VEC_STEP 0x10 /* single step */
+#define VEC_OVFLOW 0x11 /* trace buffer overflow */
+#define VEC_UNDEF_I 0x21 /* undefined instruction */
+#define VEC_ILGAL_I 0x22 /* illegal instruction combo (multi-issue) */
+#define VEC_CPLB_VL 0x23 /* DCPLB protection violation */
+#define VEC_MISALI_D 0x24 /* unaligned data access */
+#define VEC_UNCOV 0x25 /* unrecoverable event (double fault) */
+#define VEC_CPLB_M 0x26 /* DCPLB miss */
+#define VEC_CPLB_MHIT 0x27 /* multiple DCPLB hit */
+#define VEC_WATCH 0x28 /* watchpoint match */
+#define VEC_ISTRU_VL 0x29 /* ADSP-BF535 only */
+#define VEC_MISALI_I 0x2a /* unaligned instruction access */
+#define VEC_CPLB_I_VL 0x2b /* ICPLB protection violation */
+#define VEC_CPLB_I_M 0x2c /* ICPLB miss */
+#define VEC_CPLB_I_MHIT 0x2d /* multiple ICPLB hit */
+#define VEC_ILL_RES 0x2e /* illegal supervisor resource */
+/*
+ * The hardware reserves 63+ for future use - we use it to tell our
+ * normal exception handling code we have a hardware error
+ */
+#define VEC_HWERR 63
+#define VEC_SIM_BASE 64
+#define VEC_SIM_HLT (VEC_SIM_BASE + 1)
+#define VEC_SIM_ABORT (VEC_SIM_BASE + 2)
+#define VEC_SIM_TRAP (VEC_SIM_BASE + 3)
+#define VEC_SIM_DBGA (VEC_SIM_BASE + 4)
+extern void cec_exception (SIM_CPU *, int vec_excp);
+
+#define HWERR_SYSTEM_MMR 0x02
+#define HWERR_EXTERN_ADDR 0x03
+#define HWERR_PERF_FLOW 0x12
+#define HWERR_RAISE_5 0x18
+extern void cec_hwerr (SIM_CPU *, int hwerr);
+extern void cec_latch (SIM_CPU *, int ivg);
+extern void cec_return (SIM_CPU *, int ivg);
+
+extern int cec_get_ivg (SIM_CPU *);
+extern bool cec_is_supervisor_mode (SIM_CPU *);
+extern bool cec_is_user_mode (SIM_CPU *);
+extern void cec_require_supervisor (SIM_CPU *);
+
+extern bu32 cec_cli (SIM_CPU *);
+extern void cec_sti (SIM_CPU *, bu32 ints);
+
+extern void cec_push_reti (SIM_CPU *);
+extern void cec_pop_reti (SIM_CPU *);
+
+#endif
diff --git a/sim/bfin/dv-bfin_ctimer.c b/sim/bfin/dv-bfin_ctimer.c
new file mode 100644
index 00000000000..b6d575c1148
--- /dev/null
+++ b/sim/bfin/dv-bfin_ctimer.c
@@ -0,0 +1,267 @@
+/* Blackfin Core Timer model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_cec.h"
+#include "dv-bfin_ctimer.h"
+
+struct bfin_ctimer
+{
+ bu32 base;
+ struct hw_event *handler;
+ signed64 timeout;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 tcntl, tperiod, tscale, tcount;
+};
+#define mmr_base() offsetof(struct bfin_ctimer, tcntl)
+#define mmr_offset(mmr) (offsetof(struct bfin_ctimer, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "TCNTL", "TPERIOD", "TSCALE", "TCOUNT",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static bool
+bfin_ctimer_enabled (struct bfin_ctimer *ctimer)
+{
+ return (ctimer->tcntl & TMPWR) && (ctimer->tcntl & TMREN);
+}
+
+static bu32
+bfin_ctimer_scale (struct bfin_ctimer *ctimer)
+{
+ /* Only low 8 bits are actually checked. */
+ return (ctimer->tscale & 0xff) + 1;
+}
+
+static void
+bfin_ctimer_schedule (struct hw *me, struct bfin_ctimer *ctimer);
+
+static void
+bfin_ctimer_expire (struct hw *me, void *data)
+{
+ struct bfin_ctimer *ctimer = data;
+
+ ctimer->tcntl |= TINT;
+ if (ctimer->tcntl & TAUTORLD)
+ {
+ ctimer->tcount = ctimer->tperiod;
+ bfin_ctimer_schedule (me, ctimer);
+ }
+ else
+ {
+ ctimer->tcount = 0;
+ ctimer->handler = NULL;
+ }
+
+ hw_port_event (me, IVG_IVTMR, 1);
+}
+
+static void
+bfin_ctimer_update_count (struct hw *me, struct bfin_ctimer *ctimer)
+{
+ bu32 scale, ticks;
+ signed64 timeout;
+
+ /* If the timer was enabled w/out autoreload and has expired, then
+ there's nothing to calculate here. */
+ if (ctimer->handler == NULL)
+ return;
+
+ scale = bfin_ctimer_scale (ctimer);
+ timeout = hw_event_remain_time (me, ctimer->handler);
+ ticks = ctimer->timeout - timeout;
+ ctimer->tcount -= (scale * ticks);
+ ctimer->timeout = timeout;
+}
+
+static void
+bfin_ctimer_deschedule (struct hw *me, struct bfin_ctimer *ctimer)
+{
+ if (ctimer->handler)
+ {
+ hw_event_queue_deschedule (me, ctimer->handler);
+ ctimer->handler = NULL;
+ }
+}
+
+static void
+bfin_ctimer_schedule (struct hw *me, struct bfin_ctimer *ctimer)
+{
+ bu32 scale = bfin_ctimer_scale (ctimer);
+ ctimer->timeout = (ctimer->tcount / scale) + !!(ctimer->tcount % scale);
+ ctimer->handler = hw_event_queue_schedule (me, ctimer->timeout,
+ bfin_ctimer_expire,
+ ctimer);
+}
+
+static unsigned
+bfin_ctimer_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ctimer *ctimer = hw_data (me);
+ bool curr_enabled;
+ bu32 mmr_off;
+ bu32 value;
+ bu32 *valuep;
+
+ value = dv_load_4 (source);
+ mmr_off = addr - ctimer->base;
+ valuep = (void *)((unsigned long)ctimer + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ curr_enabled = bfin_ctimer_enabled (ctimer);
+ switch (mmr_off)
+ {
+ case mmr_offset(tcntl):
+ /* HRM describes TINT as sticky, but it isn't W1C. */
+ *valuep = value;
+
+ if (bfin_ctimer_enabled (ctimer) == curr_enabled)
+ {
+ /* Do nothing. */
+ }
+ else if (curr_enabled)
+ {
+ bfin_ctimer_update_count (me, ctimer);
+ bfin_ctimer_deschedule (me, ctimer);
+ }
+ else
+ bfin_ctimer_schedule (me, ctimer);
+
+ break;
+ case mmr_offset(tcount):
+ /* HRM says writes are discarded when enabled. */
+ /* XXX: But hardware seems to be writeable all the time ? */
+ /* if (!curr_enabled) */
+ *valuep = value;
+ break;
+ case mmr_offset(tperiod):
+ /* HRM says writes are discarded when enabled. */
+ /* XXX: But hardware seems to be writeable all the time ? */
+ /* if (!curr_enabled) */
+ {
+ /* Writes are mirrored into TCOUNT. */
+ ctimer->tcount = value;
+ *valuep = value;
+ }
+ break;
+ case mmr_offset(tscale):
+ if (curr_enabled)
+ {
+ bfin_ctimer_update_count (me, ctimer);
+ bfin_ctimer_deschedule (me, ctimer);
+ }
+ *valuep = value;
+ if (curr_enabled)
+ bfin_ctimer_schedule (me, ctimer);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_ctimer_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ctimer *ctimer = hw_data (me);
+ bu32 mmr_off;
+ bu32 *valuep;
+
+ mmr_off = addr - ctimer->base;
+ valuep = (void *)((unsigned long)ctimer + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(tcount):
+ /* Since we're optimizing events here, we need to calculate
+ the new tcount value. */
+ if (bfin_ctimer_enabled (ctimer))
+ bfin_ctimer_update_count (me, ctimer);
+ break;
+ }
+
+ dv_store_4 (dest, *valuep);
+
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_ctimer_ports[] = {
+ { "ivtmr", IVG_IVTMR, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_ctimer_regs (struct hw *me, struct bfin_ctimer *ctimer)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_COREMMR_CTIMER_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_CTIMER_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ ctimer->base = attach_address;
+}
+
+static void
+bfin_ctimer_finish (struct hw *me)
+{
+ struct bfin_ctimer *ctimer;
+
+ ctimer = HW_ZALLOC (me, struct bfin_ctimer);
+
+ set_hw_data (me, ctimer);
+ set_hw_io_read_buffer (me, bfin_ctimer_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_ctimer_io_write_buffer);
+ set_hw_ports (me, bfin_ctimer_ports);
+
+ attach_bfin_ctimer_regs (me, ctimer);
+
+ /* Initialize the Core Timer. */
+}
+
+const struct hw_descriptor dv_bfin_ctimer_descriptor[] = {
+ {"bfin_ctimer", bfin_ctimer_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_ctimer.h b/sim/bfin/dv-bfin_ctimer.h
new file mode 100644
index 00000000000..c097588fec6
--- /dev/null
+++ b/sim/bfin/dv-bfin_ctimer.h
@@ -0,0 +1,33 @@
+/* Blackfin Core Timer model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_CTIMER_H
+#define DV_BFIN_CTIMER_H
+
+#define BFIN_COREMMR_CTIMER_BASE 0xFFE03000
+#define BFIN_COREMMR_CTIMER_SIZE (4 * 4)
+
+/* TCNTL Masks */
+#define TMPWR (1 << 0)
+#define TMREN (1 << 1)
+#define TAUTORLD (1 << 2)
+#define TINT (1 << 3)
+
+#endif
diff --git a/sim/bfin/dv-bfin_dma.c b/sim/bfin/dv-bfin_dma.c
new file mode 100644
index 00000000000..e61348af87c
--- /dev/null
+++ b/sim/bfin/dv-bfin_dma.c
@@ -0,0 +1,553 @@
+/* Blackfin Direct Memory Access (DMA) Channel model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "hw-device.h"
+#include "dv-bfin_dma.h"
+#include "dv-bfin_dmac.h"
+
+/* Note: This DMA implementation requires the producer to be the master when
+ the peer is MDMA. The source is always a slave. This way we don't
+ have the two DMA devices thrashing each other with one trying to
+ write and the other trying to read. */
+
+struct bfin_dma
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ unsigned ele_size;
+ struct hw *hw_peer;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ union {
+ struct { bu16 ndpl, ndph; };
+ bu32 next_desc_ptr;
+ };
+ union {
+ struct { bu16 sal, sah; };
+ bu32 start_addr;
+ };
+ bu16 BFIN_MMR_16 (config);
+ bu32 _pad0;
+ bu16 BFIN_MMR_16 (x_count);
+ bs16 BFIN_MMR_16 (x_modify);
+ bu16 BFIN_MMR_16 (y_count);
+ bs16 BFIN_MMR_16 (y_modify);
+ bu32 curr_desc_ptr, curr_addr;
+ bu16 BFIN_MMR_16 (irq_status);
+ bu16 BFIN_MMR_16 (peripheral_map);
+ bu16 BFIN_MMR_16 (curr_x_count);
+ bu32 _pad1;
+ bu16 BFIN_MMR_16 (curr_y_count);
+ bu32 _pad2;
+};
+#define mmr_base() offsetof(struct bfin_dma, next_desc_ptr)
+#define mmr_offset(mmr) (offsetof(struct bfin_dma, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "NEXT_DESC_PTR", "START_ADDR", "CONFIG", "<INV>", "X_COUNT", "X_MODIFY",
+ "Y_COUNT", "Y_MODIFY", "CURR_DESC_PTR", "CURR_ADDR", "IRQ_STATUS",
+ "PERIPHERAL_MAP", "CURR_X_COUNT", "<INV>", "CURR_Y_COUNT", "<INV>",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static bool
+bfin_dma_enabled (struct bfin_dma *dma)
+{
+ return (dma->config & DMAEN);
+}
+
+static bool
+bfin_dma_running (struct bfin_dma *dma)
+{
+ return (dma->irq_status & DMA_RUN);
+}
+
+static struct hw *
+bfin_dma_get_peer (struct hw *me, struct bfin_dma *dma)
+{
+ if (dma->hw_peer)
+ return dma->hw_peer;
+ return dma->hw_peer = bfin_dmac_get_peer (me, dma->peripheral_map);
+}
+
+static void
+bfin_dma_process_desc (struct hw *me, struct bfin_dma *dma)
+{
+ bu8 ndsize = (dma->config & NDSIZE) >> NDSIZE_SHIFT;
+ bu16 _flows[9], *flows = _flows;
+
+ HW_TRACE ((me, "dma starting up %#x", dma->config));
+
+ switch (dma->config & WDSIZE)
+ {
+ case WDSIZE_32:
+ dma->ele_size = 4;
+ break;
+ case WDSIZE_16:
+ dma->ele_size = 2;
+ break;
+ default:
+ dma->ele_size = 1;
+ break;
+ }
+
+ /* Address has to be mutiple of transfer size. */
+ if (dma->start_addr & (dma->ele_size - 1))
+ dma->irq_status |= DMA_ERR;
+
+ if (dma->ele_size != (unsigned) abs (dma->x_modify))
+ hw_abort (me, "DMA config (striding) %#x not supported (x_modify: %d)",
+ dma->config, dma->x_modify);
+
+ switch (dma->config & DMAFLOW)
+ {
+ case DMAFLOW_AUTO:
+ case DMAFLOW_STOP:
+ if (ndsize)
+ hw_abort (me, "DMA config error: DMAFLOW_{AUTO,STOP} requires NDSIZE_0");
+ break;
+ case DMAFLOW_ARRAY:
+ if (ndsize == 0 || ndsize > 7)
+ hw_abort (me, "DMA config error: DMAFLOW_ARRAY requires NDSIZE 1...7");
+ sim_read (hw_system (me), dma->curr_desc_ptr, (void *)flows, ndsize * 2);
+ break;
+ case DMAFLOW_SMALL:
+ if (ndsize == 0 || ndsize > 8)
+ hw_abort (me, "DMA config error: DMAFLOW_SMALL requires NDSIZE 1...8");
+ sim_read (hw_system (me), dma->next_desc_ptr, (void *)flows, ndsize * 2);
+ break;
+ case DMAFLOW_LARGE:
+ if (ndsize == 0 || ndsize > 9)
+ hw_abort (me, "DMA config error: DMAFLOW_LARGE requires NDSIZE 1...9");
+ sim_read (hw_system (me), dma->next_desc_ptr, (void *)flows, ndsize * 2);
+ break;
+ default:
+ hw_abort (me, "DMA config error: invalid DMAFLOW %#x", dma->config);
+ }
+
+ if (ndsize)
+ {
+ bu8 idx;
+ bu16 *stores[] = {
+ &dma->sal,
+ &dma->sah,
+ &dma->config,
+ &dma->x_count,
+ (void *) &dma->x_modify,
+ &dma->y_count,
+ (void *) &dma->y_modify,
+ };
+
+ switch (dma->config & DMAFLOW)
+ {
+ case DMAFLOW_LARGE:
+ dma->ndph = _flows[1];
+ --ndsize;
+ ++flows;
+ case DMAFLOW_SMALL:
+ dma->ndpl = _flows[0];
+ --ndsize;
+ ++flows;
+ break;
+ }
+
+ for (idx = 0; idx < ndsize; ++idx)
+ *stores[idx] = flows[idx];
+ }
+
+ dma->curr_desc_ptr = dma->next_desc_ptr;
+ dma->curr_addr = dma->start_addr;
+ dma->curr_x_count = dma->x_count ? : 0xffff;
+ dma->curr_y_count = dma->y_count ? : 0xffff;
+}
+
+static int
+bfin_dma_finish_x (struct hw *me, struct bfin_dma *dma)
+{
+ /* XXX: This would be the time to process the next descriptor. */
+ /* XXX: Should this toggle Enable in dma->config ? */
+
+ if (dma->config & DI_EN)
+ hw_port_event (me, 0, 1);
+
+ if ((dma->config & DMA2D) && dma->curr_y_count > 1)
+ {
+ dma->curr_y_count -= 1;
+ dma->curr_x_count = dma->x_count;
+
+ /* With 2D, last X transfer does not modify curr_addr. */
+ dma->curr_addr = dma->curr_addr - dma->x_modify + dma->y_modify;
+
+ return 1;
+ }
+
+ switch (dma->config & DMAFLOW)
+ {
+ case DMAFLOW_STOP:
+ HW_TRACE ((me, "dma is complete"));
+ dma->irq_status = (dma->irq_status & ~DMA_RUN) | DMA_DONE;
+ return 0;
+ default:
+ bfin_dma_process_desc (me, dma);
+ return 1;
+ }
+}
+
+static void bfin_dma_hw_event_callback (struct hw *, void *);
+
+static void
+bfin_dma_reschedule (struct hw *me, unsigned delay)
+{
+ struct bfin_dma *dma = hw_data (me);
+ if (dma->handler)
+ {
+ hw_event_queue_deschedule (me, dma->handler);
+ dma->handler = NULL;
+ }
+ if (!delay)
+ return;
+ HW_TRACE ((me, "scheduling next process in %u", delay));
+ dma->handler = hw_event_queue_schedule (me, delay,
+ bfin_dma_hw_event_callback, dma);
+}
+
+/* Chew through the DMA over and over. */
+static void
+bfin_dma_hw_event_callback (struct hw *me, void *data)
+{
+ struct bfin_dma *dma = data;
+ struct hw *peer;
+ struct dv_bfin *bfin_peer;
+ bu8 buf[4096];
+ unsigned ret, nr_bytes, ele_count;
+
+ dma->handler = NULL;
+ peer = bfin_dma_get_peer (me, dma);
+ bfin_peer = hw_data (peer);
+ ret = 0;
+ if (dma->x_modify < 0)
+ /* XXX: This sucks performance wise. */
+ nr_bytes = dma->ele_size;
+ else
+ nr_bytes = MIN (sizeof (buf), dma->curr_x_count * dma->ele_size);
+
+ /* Pumping a chunk! */
+ bfin_peer->dma_master = me;
+ bfin_peer->acked = false;
+ if (dma->config & WNR)
+ {
+ HW_TRACE ((me, "dma transfer to 0x%08lx length %u",
+ (unsigned long) dma->curr_addr, nr_bytes));
+
+ ret = hw_dma_read_buffer (peer, buf, 0, dma->curr_addr, nr_bytes);
+ /* Has the DMA stalled ? abort for now. */
+ if (ret == 0)
+ goto reschedule;
+ /* XXX: How to handle partial DMA transfers ? */
+ if (ret % dma->ele_size)
+ goto error;
+ ret = sim_write (hw_system (me), dma->curr_addr, buf, ret);
+ }
+ else
+ {
+ HW_TRACE ((me, "dma transfer from 0x%08lx length %u",
+ (unsigned long) dma->curr_addr, nr_bytes));
+
+ ret = sim_read (hw_system (me), dma->curr_addr, buf, nr_bytes);
+ if (ret == 0)
+ goto reschedule;
+ /* XXX: How to handle partial DMA transfers ? */
+ if (ret % dma->ele_size)
+ goto error;
+ ret = hw_dma_write_buffer (peer, buf, 0, dma->curr_addr, ret, 0);
+ if (ret == 0)
+ goto reschedule;
+ }
+
+ /* Ignore partial writes. */
+ ele_count = ret / dma->ele_size;
+ dma->curr_addr += ele_count * dma->x_modify;
+ dma->curr_x_count -= ele_count;
+
+ if ((!dma->acked && dma->curr_x_count) || bfin_dma_finish_x (me, dma))
+ /* Still got work to do, so schedule again. */
+ reschedule:
+ bfin_dma_reschedule (me, ret ? 1 : 5000);
+
+ return;
+
+ error:
+ /* Don't reschedule on errors ... */
+ dma->irq_status |= DMA_ERR;
+}
+
+static unsigned
+bfin_dma_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_dma *dma = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr % dma->base;
+ valuep = (void *)((unsigned long)dma + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ /* XXX: All registers are RO when DMA is enabled (except IRQ_STATUS).
+ But does the HW discard writes or send up IVGHW ? The sim
+ simply discards atm ... */
+ switch (mmr_off)
+ {
+ case mmr_offset(next_desc_ptr):
+ case mmr_offset(start_addr):
+ case mmr_offset(curr_desc_ptr):
+ case mmr_offset(curr_addr):
+ /* Don't require 32bit access as all DMA MMRs can be used as 16bit. */
+ if (!bfin_dma_running (dma))
+ {
+ if (nr_bytes == 4)
+ *value32p = value;
+ else
+ *value16p = value;
+ }
+ else
+ HW_TRACE ((me, "discarding write while dma running"));
+ break;
+ case mmr_offset(x_count):
+ case mmr_offset(x_modify):
+ case mmr_offset(y_count):
+ case mmr_offset(y_modify):
+ if (!bfin_dma_running (dma))
+ *value16p = value;
+ break;
+ case mmr_offset(peripheral_map):
+ if (!bfin_dma_running (dma))
+ {
+ *value16p = (*value16p & CTYPE) | (value & ~CTYPE);
+ /* Clear peripheral peer so it gets looked up again. */
+ dma->hw_peer = NULL;
+ }
+ else
+ HW_TRACE ((me, "discarding write while dma running"));
+ break;
+ case mmr_offset(config):
+ /* XXX: How to handle updating CONFIG of a running channel ? */
+ if (nr_bytes == 4)
+ *value32p = value;
+ else
+ *value16p = value;
+
+ if (bfin_dma_enabled (dma))
+ {
+ dma->irq_status |= DMA_RUN;
+ bfin_dma_process_desc (me, dma);
+ /* The writer is the master. */
+ if (!(dma->peripheral_map & CTYPE) || (dma->config & WNR))
+ bfin_dma_reschedule (me, 1);
+ }
+ else
+ {
+ dma->irq_status &= ~DMA_RUN;
+ bfin_dma_reschedule (me, 0);
+ }
+ break;
+ case mmr_offset(irq_status):
+ dv_w1c_2 (value16p, value, DMA_DONE | DMA_ERR);
+ break;
+ case mmr_offset(curr_x_count):
+ case mmr_offset(curr_y_count):
+ if (!bfin_dma_running (dma))
+ *value16p = value;
+ else
+ HW_TRACE ((me, "discarding write while dma running"));
+ break;
+ default:
+ /* XXX: The HW lets the pad regions be read/written ... */
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_dma_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_dma *dma = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr % dma->base;
+ valuep = (void *)((unsigned long)dma + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ /* Hardware lets you read all MMRs as 16 or 32 bits, even reserved. */
+ if (nr_bytes == 4)
+ dv_store_4 (dest, *value32p);
+ else
+ dv_store_2 (dest, *value16p);
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_dma_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ struct bfin_dma *dma = hw_data (me);
+ unsigned ret, ele_count;
+
+ HW_TRACE_DMA_READ ();
+
+ /* If someone is trying to read from me, I have to be enabled. */
+ if (!bfin_dma_enabled (dma) && !bfin_dma_running (dma))
+ return 0;
+
+ /* XXX: handle x_modify ... */
+ ret = sim_read (hw_system (me), dma->curr_addr, dest, nr_bytes);
+ /* Ignore partial writes. */
+ ele_count = ret / dma->ele_size;
+ /* Has the DMA stalled ? abort for now. */
+ if (!ele_count)
+ return 0;
+
+ dma->curr_addr += ele_count * dma->x_modify;
+ dma->curr_x_count -= ele_count;
+
+ if (dma->curr_x_count == 0)
+ bfin_dma_finish_x (me, dma);
+
+ return ret;
+}
+
+static unsigned
+bfin_dma_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ struct bfin_dma *dma = hw_data (me);
+ unsigned ret, ele_count;
+
+ HW_TRACE_DMA_WRITE ();
+
+ /* If someone is trying to write to me, I have to be enabled. */
+ if (!bfin_dma_enabled (dma) && !bfin_dma_running (dma))
+ return 0;
+
+ /* XXX: handle x_modify ... */
+ ret = sim_write (hw_system (me), dma->curr_addr, source, nr_bytes);
+ /* Ignore partial writes. */
+ ele_count = ret / dma->ele_size;
+ /* Has the DMA stalled ? abort for now. */
+ if (!ele_count)
+ return 0;
+
+ dma->curr_addr += ele_count * dma->x_modify;
+ dma->curr_x_count -= ele_count;
+
+ if (dma->curr_x_count == 0)
+ bfin_dma_finish_x (me, dma);
+
+ return ret;
+}
+
+static const struct hw_port_descriptor bfin_dma_ports[] = {
+ { "di", 0, 0, output_port, }, /* DMA Interrupt */
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_dma_regs (struct hw *me, struct bfin_dma *dma)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_DMA_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_DMA_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ dma->base = attach_address;
+}
+
+static void
+bfin_dma_finish (struct hw *me)
+{
+ struct bfin_dma *dma;
+
+ dma = HW_ZALLOC (me, struct bfin_dma);
+
+ set_hw_data (me, dma);
+ set_hw_io_read_buffer (me, bfin_dma_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_dma_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_dma_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_dma_dma_write_buffer);
+ set_hw_ports (me, bfin_dma_ports);
+
+ attach_bfin_dma_regs (me, dma);
+
+ /* Initialize the DMA Channel. */
+ dma->peripheral_map = bfin_dmac_default_pmap (me);
+}
+
+const struct hw_descriptor dv_bfin_dma_descriptor[] = {
+ {"bfin_dma", bfin_dma_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_dma.h b/sim/bfin/dv-bfin_dma.h
new file mode 100644
index 00000000000..03d412b7e9d
--- /dev/null
+++ b/sim/bfin/dv-bfin_dma.h
@@ -0,0 +1,65 @@
+/* Blackfin Direct Memory Access (DMA) Channel model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_DMA_H
+#define DV_BFIN_DMA_H
+
+#define BFIN_MMR_DMA_SIZE (4 * 16)
+
+/* DMA_CONFIG Masks */
+#define DMAEN 0x0001 /* DMA Channel Enable */
+#define WNR 0x0002 /* Channel Direction (W/R*) */
+#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */
+#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */
+#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */
+#define WDSIZE 0x000c /* Transfer Word Size */
+#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */
+#define RESTART 0x0020 /* DMA Buffer Clear */
+#define DI_SEL 0x0040 /* Data Interrupt Timing Select */
+#define DI_EN 0x0080 /* Data Interrupt Enable */
+#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */
+#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */
+#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */
+#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */
+#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */
+#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */
+#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */
+#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */
+#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */
+#define NDSIZE 0x0f00 /* Next Descriptor Size */
+#define NDSIZE_SHIFT 8
+#define DMAFLOW 0x7000 /* Flow Control */
+#define DMAFLOW_STOP 0x0000 /* Stop Mode */
+#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */
+#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */
+#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */
+#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */
+
+/* DMA_IRQ_STATUS Masks */
+#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */
+#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */
+#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */
+#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */
+
+/* DMA_PERIPHERAL_MAP Masks */
+#define CTYPE (1 << 6)
+
+#endif
diff --git a/sim/bfin/dv-bfin_dmac.c b/sim/bfin/dv-bfin_dmac.c
new file mode 100644
index 00000000000..f0f3c8cd067
--- /dev/null
+++ b/sim/bfin/dv-bfin_dmac.c
@@ -0,0 +1,469 @@
+/* Blackfin Direct Memory Access (DMA) Controller model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "sim-hw.h"
+#include "devices.h"
+#include "hw-device.h"
+#include "dv-bfin_dma.h"
+#include "dv-bfin_dmac.h"
+
+struct bfin_dmac
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ const char **pmap;
+ unsigned int pmap_count;
+};
+
+struct hw *
+bfin_dmac_get_peer (struct hw *dma, bu16 pmap)
+{
+ struct hw *ret, *me;
+ struct bfin_dmac *dmac;
+ char peer[100];
+
+ me = hw_parent (dma);
+ dmac = hw_data (me);
+ if (pmap & CTYPE)
+ {
+ /* MDMA channel. */
+ unsigned int chan_num = dv_get_bus_num (dma);
+ if (chan_num & 1)
+ chan_num &= ~1;
+ else
+ chan_num |= 1;
+ sprintf (peer, "%s/bfin_dma@%u", hw_path (me), chan_num);
+ }
+ else
+ {
+ unsigned int idx = pmap >> 12;
+ if (idx >= dmac->pmap_count)
+ hw_abort (me, "Invalid DMA peripheral_map %#x", pmap);
+ else
+ sprintf (peer, "/core/bfin_%s", dmac->pmap[idx]);
+ }
+
+ ret = hw_tree_find_device (me, peer);
+ if (!ret)
+ hw_abort (me, "Unable to locate peer for %s (pmap:%#x %s)",
+ hw_name (dma), pmap, peer);
+ return ret;
+}
+
+bu16
+bfin_dmac_default_pmap (struct hw *dma)
+{
+ unsigned int chan_num = dv_get_bus_num (dma);
+
+ if (chan_num < BFIN_DMAC_MDMA_BASE)
+ return (chan_num % 12) << 12;
+ else
+ return CTYPE; /* MDMA */
+}
+
+static const char *bfin_dmac_50x_pmap[] = {
+ "ppi@0", "rsi", "sport@0", "sport@0", "sport@1", "sport@1",
+ "spi@0", "spi@1", "uart2@0", "uart2@0", "uart2@1", "uart2@1",
+};
+
+/* XXX: Need to figure out how to handle portmuxed DMA channels. */
+static const struct hw_port_descriptor bfin_dmac_50x_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+ { "rsi", 1, 0, input_port, },
+ { "sport@0_rx", 2, 0, input_port, },
+ { "sport@0_tx", 3, 0, input_port, },
+ { "sport@1_tx", 4, 0, input_port, },
+ { "sport@1_rx", 5, 0, input_port, },
+ { "spi@0", 6, 0, input_port, },
+ { "spi@1", 7, 0, input_port, },
+ { "uart2@0_rx", 8, 0, input_port, },
+ { "uart2@0_tx", 9, 0, input_port, },
+ { "uart2@1_rx", 10, 0, input_port, },
+ { "uart2@1_tx", 11, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac_51x_pmap[] = {
+ "ppi@0", "emac", "emac", "sport@0", "sport@0", "sport@1",
+ "sport@1", "spi@0", "uart@0", "uart@0", "uart@1", "uart@1",
+};
+
+/* XXX: Need to figure out how to handle portmuxed DMA channels. */
+static const struct hw_port_descriptor bfin_dmac_51x_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+ { "emac_rx", 1, 0, input_port, },
+ { "emac_tx", 2, 0, input_port, },
+ { "sport@0_rx", 3, 0, input_port, },
+ { "sport@0_tx", 4, 0, input_port, },
+/*{ "rsi", 4, 0, input_port, },*/
+ { "sport@1_tx", 5, 0, input_port, },
+/*{ "spi@1", 5, 0, input_port, },*/
+ { "sport@1_rx", 6, 0, input_port, },
+ { "spi@0", 7, 0, input_port, },
+ { "uart@0_rx", 8, 0, input_port, },
+ { "uart@0_tx", 9, 0, input_port, },
+ { "uart@1_rx", 10, 0, input_port, },
+ { "uart@1_tx", 11, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac_52x_pmap[] = {
+ "ppi@0", "emac", "emac", "sport@0", "sport@0", "sport@1",
+ "sport@1", "spi", "uart@0", "uart@0", "uart@1", "uart@1",
+};
+
+/* XXX: Need to figure out how to handle portmuxed DMA channels
+ like PPI/NFC here which share DMA0. */
+static const struct hw_port_descriptor bfin_dmac_52x_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+/*{ "nfc", 0, 0, input_port, },*/
+ { "emac_rx", 1, 0, input_port, },
+/*{ "hostdp", 1, 0, input_port, },*/
+ { "emac_tx", 2, 0, input_port, },
+/*{ "nfc", 2, 0, input_port, },*/
+ { "sport@0_tx", 3, 0, input_port, },
+ { "sport@0_rx", 4, 0, input_port, },
+ { "sport@1_tx", 5, 0, input_port, },
+ { "sport@1_rx", 6, 0, input_port, },
+ { "spi", 7, 0, input_port, },
+ { "uart@0_tx", 8, 0, input_port, },
+ { "uart@0_rx", 9, 0, input_port, },
+ { "uart@1_tx", 10, 0, input_port, },
+ { "uart@1_rx", 11, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac_533_pmap[] = {
+ "ppi@0", "sport@0", "sport@0", "sport@1", "sport@1", "spi",
+ "uart@0", "uart@0",
+};
+
+static const struct hw_port_descriptor bfin_dmac_533_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+ { "sport@0_tx", 1, 0, input_port, },
+ { "sport@0_rx", 2, 0, input_port, },
+ { "sport@1_tx", 3, 0, input_port, },
+ { "sport@1_rx", 4, 0, input_port, },
+ { "spi", 5, 0, input_port, },
+ { "uart@0_tx", 6, 0, input_port, },
+ { "uart@0_rx", 7, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac_537_pmap[] = {
+ "ppi@0", "emac", "emac", "sport@0", "sport@0", "sport@1",
+ "sport@1", "spi", "uart@0", "uart@0", "uart@1", "uart@1",
+};
+
+static const struct hw_port_descriptor bfin_dmac_537_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+ { "emac_rx", 1, 0, input_port, },
+ { "emac_tx", 2, 0, input_port, },
+ { "sport@0_tx", 3, 0, input_port, },
+ { "sport@0_rx", 4, 0, input_port, },
+ { "sport@1_tx", 5, 0, input_port, },
+ { "sport@1_rx", 6, 0, input_port, },
+ { "spi", 7, 0, input_port, },
+ { "uart@0_tx", 8, 0, input_port, },
+ { "uart@0_rx", 9, 0, input_port, },
+ { "uart@1_tx", 10, 0, input_port, },
+ { "uart@1_rx", 11, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac0_538_pmap[] = {
+ "ppi@0", "sport@0", "sport@0", "sport@1", "sport@1", "spi@0",
+ "uart@0", "uart@0",
+};
+
+static const struct hw_port_descriptor bfin_dmac0_538_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+ { "sport@0_rx", 1, 0, input_port, },
+ { "sport@0_tx", 2, 0, input_port, },
+ { "sport@1_rx", 3, 0, input_port, },
+ { "sport@1_tx", 4, 0, input_port, },
+ { "spi@0", 5, 0, input_port, },
+ { "uart@0_rx", 6, 0, input_port, },
+ { "uart@0_tx", 7, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac1_538_pmap[] = {
+ "sport@2", "sport@2", "sport@3", "sport@3", NULL, NULL,
+ "spi@1", "spi@2", "uart@1", "uart@1", "uart@2", "uart@2",
+};
+
+static const struct hw_port_descriptor bfin_dmac1_538_ports[] = {
+ { "sport@2_rx", 0, 0, input_port, },
+ { "sport@2_tx", 1, 0, input_port, },
+ { "sport@3_rx", 2, 0, input_port, },
+ { "sport@3_tx", 3, 0, input_port, },
+ { "spi@1", 6, 0, input_port, },
+ { "spi@2", 7, 0, input_port, },
+ { "uart@1_rx", 8, 0, input_port, },
+ { "uart@1_tx", 9, 0, input_port, },
+ { "uart@2_rx", 10, 0, input_port, },
+ { "uart@2_tx", 11, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac0_54x_pmap[] = {
+ "sport@0", "sport@0", "sport@1", "sport@1", "spi@0", "spi@1",
+ "uart2@0", "uart2@0", "uart2@1", "uart2@1", "atapi", "atapi",
+};
+
+static const struct hw_port_descriptor bfin_dmac0_54x_ports[] = {
+ { "sport@0_rx", 0, 0, input_port, },
+ { "sport@0_tx", 1, 0, input_port, },
+ { "sport@1_rx", 2, 0, input_port, },
+ { "sport@1_tx", 3, 0, input_port, },
+ { "spi@0", 4, 0, input_port, },
+ { "spi@1", 5, 0, input_port, },
+ { "uart2@0_rx", 6, 0, input_port, },
+ { "uart2@0_tx", 7, 0, input_port, },
+ { "uart2@1_rx", 8, 0, input_port, },
+ { "uart2@1_tx", 9, 0, input_port, },
+ { "atapi", 10, 0, input_port, },
+ { "atapi", 11, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac1_54x_pmap[] = {
+ "eppi@0", "eppi@1", "eppi@2", "pixc", "pixc", "pixc",
+ "sport@2", "sport@2", "sport@3", "sport@3", "sdh",
+ "spi@2", "uart2@2", "uart2@2", "uart2@3", "uart2@3",
+};
+
+static const struct hw_port_descriptor bfin_dmac1_54x_ports[] = {
+ { "eppi@0", 0, 0, input_port, },
+ { "eppi@1", 1, 0, input_port, },
+ { "eppi@2", 2, 0, input_port, },
+ { "pixc", 3, 0, input_port, },
+ { "pixc", 4, 0, input_port, },
+ { "pixc", 5, 0, input_port, },
+ { "sport@2_rx", 6, 0, input_port, },
+ { "sport@2_tx", 7, 0, input_port, },
+ { "sport@3_rx", 8, 0, input_port, },
+ { "sport@3_tx", 9, 0, input_port, },
+ { "sdh", 10, 0, input_port, },
+/*{ "nfc", 10, 0, input_port, },*/
+ { "spi@2", 11, 0, input_port, },
+ { "uart2@2_rx", 12, 0, input_port, },
+ { "uart2@2_tx", 13, 0, input_port, },
+ { "uart2@3_rx", 14, 0, input_port, },
+ { "uart2@3_tx", 15, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac0_561_pmap[] = {
+ "sport@0", "sport@0", "sport@1", "sport@1", "spi", "uart@0", "uart@0",
+};
+
+static const struct hw_port_descriptor bfin_dmac0_561_ports[] = {
+ { "sport@0_rx", 0, 0, input_port, },
+ { "sport@0_tx", 1, 0, input_port, },
+ { "sport@1_rx", 2, 0, input_port, },
+ { "sport@1_tx", 3, 0, input_port, },
+ { "spi@0", 4, 0, input_port, },
+ { "uart@0_rx", 5, 0, input_port, },
+ { "uart@0_tx", 6, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac1_561_pmap[] = {
+ "ppi@0", "ppi@1",
+};
+
+static const struct hw_port_descriptor bfin_dmac1_561_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+ { "ppi@1", 1, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const char *bfin_dmac_59x_pmap[] = {
+ "ppi@0", "sport@0", "sport@0", "sport@1", "sport@1", "spi@0",
+ "spi@1", "uart@0", "uart@0",
+};
+
+static const struct hw_port_descriptor bfin_dmac_59x_ports[] = {
+ { "ppi@0", 0, 0, input_port, },
+ { "sport@0_tx", 1, 0, input_port, },
+ { "sport@0_rx", 2, 0, input_port, },
+ { "sport@1_tx", 3, 0, input_port, },
+ { "sport@1_rx", 4, 0, input_port, },
+ { "spi@0", 5, 0, input_port, },
+ { "spi@1", 6, 0, input_port, },
+ { "uart@0_rx", 7, 0, input_port, },
+ { "uart@0_tx", 8, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_dmac_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ SIM_DESC sd = hw_system (me);
+ struct bfin_dmac *dmac = hw_data (me);
+ struct hw *dma = hw_child (me);
+
+ while (dma)
+ {
+ bu16 pmap;
+ sim_hw_io_read_buffer (sd, dma, &pmap, 0, 0x2c, sizeof (pmap));
+ pmap >>= 12;
+ if (pmap == my_port)
+ break;
+ dma = hw_sibling (dma);
+ }
+
+ if (!dma)
+ hw_abort (me, "no valid dma mapping found for %s", dmac->pmap[my_port]);
+
+ /* Have the DMA channel raise its interrupt to the SIC. */
+ hw_port_event (dma, 0, 1);
+}
+
+static void
+bfin_dmac_finish (struct hw *me)
+{
+ struct bfin_dmac *dmac;
+ unsigned int dmac_num = dv_get_bus_num (me);
+
+ dmac = HW_ZALLOC (me, struct bfin_dmac);
+
+ set_hw_data (me, dmac);
+ set_hw_port_event (me, bfin_dmac_port_event);
+
+ /* Initialize the DMA Controller. */
+ if (hw_find_property (me, "type") == NULL)
+ hw_abort (me, "Missing \"type\" property");
+
+ switch (hw_find_integer_property (me, "type"))
+ {
+ case 500 ... 509:
+ if (dmac_num != 0)
+ hw_abort (me, "this Blackfin only has a DMAC0");
+ dmac->pmap = bfin_dmac_50x_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac_50x_pmap);
+ set_hw_ports (me, bfin_dmac_50x_ports);
+ break;
+ case 510 ... 519:
+ if (dmac_num != 0)
+ hw_abort (me, "this Blackfin only has a DMAC0");
+ dmac->pmap = bfin_dmac_51x_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac_51x_pmap);
+ set_hw_ports (me, bfin_dmac_51x_ports);
+ break;
+ case 522 ... 527:
+ if (dmac_num != 0)
+ hw_abort (me, "this Blackfin only has a DMAC0");
+ dmac->pmap = bfin_dmac_52x_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac_52x_pmap);
+ set_hw_ports (me, bfin_dmac_52x_ports);
+ break;
+ case 531 ... 533:
+ if (dmac_num != 0)
+ hw_abort (me, "this Blackfin only has a DMAC0");
+ dmac->pmap = bfin_dmac_533_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac_533_pmap);
+ set_hw_ports (me, bfin_dmac_533_ports);
+ break;
+ case 534:
+ case 536:
+ case 537:
+ if (dmac_num != 0)
+ hw_abort (me, "this Blackfin only has a DMAC0");
+ dmac->pmap = bfin_dmac_537_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac_537_pmap);
+ set_hw_ports (me, bfin_dmac_537_ports);
+ break;
+ case 538 ... 539:
+ switch (dmac_num)
+ {
+ case 0:
+ dmac->pmap = bfin_dmac0_538_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac0_538_pmap);
+ set_hw_ports (me, bfin_dmac0_538_ports);
+ break;
+ case 1:
+ dmac->pmap = bfin_dmac1_538_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac1_538_pmap);
+ set_hw_ports (me, bfin_dmac1_538_ports);
+ break;
+ default:
+ hw_abort (me, "this Blackfin only has a DMAC0 & DMAC1");
+ }
+ break;
+ case 540 ... 549:
+ switch (dmac_num)
+ {
+ case 0:
+ dmac->pmap = bfin_dmac0_54x_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac0_54x_pmap);
+ set_hw_ports (me, bfin_dmac0_54x_ports);
+ break;
+ case 1:
+ dmac->pmap = bfin_dmac1_54x_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac1_54x_pmap);
+ set_hw_ports (me, bfin_dmac1_54x_ports);
+ break;
+ default:
+ hw_abort (me, "this Blackfin only has a DMAC0 & DMAC1");
+ }
+ break;
+ case 561:
+ switch (dmac_num)
+ {
+ case 0:
+ dmac->pmap = bfin_dmac0_561_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac0_561_pmap);
+ set_hw_ports (me, bfin_dmac0_561_ports);
+ break;
+ case 1:
+ dmac->pmap = bfin_dmac1_561_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac1_561_pmap);
+ set_hw_ports (me, bfin_dmac1_561_ports);
+ break;
+ default:
+ hw_abort (me, "this Blackfin only has a DMAC0 & DMAC1");
+ }
+ break;
+ case 590 ... 599:
+ if (dmac_num != 0)
+ hw_abort (me, "this Blackfin only has a DMAC0");
+ dmac->pmap = bfin_dmac_59x_pmap;
+ dmac->pmap_count = ARRAY_SIZE (bfin_dmac_59x_pmap);
+ set_hw_ports (me, bfin_dmac_59x_ports);
+ break;
+ default:
+ hw_abort (me, "no support for DMAC on this Blackfin model yet");
+ }
+}
+
+const struct hw_descriptor dv_bfin_dmac_descriptor[] = {
+ {"bfin_dmac", bfin_dmac_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_dmac.h b/sim/bfin/dv-bfin_dmac.h
new file mode 100644
index 00000000000..dfe953575e6
--- /dev/null
+++ b/sim/bfin/dv-bfin_dmac.h
@@ -0,0 +1,32 @@
+/* Blackfin Direct Memory Access (DMA) Controller model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_DMAC_H
+#define DV_BFIN_DMAC_H
+
+#define BFIN_MMR_DMAC0_BASE 0xFFC00C00
+#define BFIN_MMR_DMAC1_BASE 0xFFC01C00
+
+#define BFIN_DMAC_MDMA_BASE 0x100
+
+struct hw *bfin_dmac_get_peer (struct hw *dma, bu16 pmap);
+bu16 bfin_dmac_default_pmap (struct hw *dma);
+
+#endif
diff --git a/sim/bfin/dv-bfin_ebiu_amc.c b/sim/bfin/dv-bfin_ebiu_amc.c
new file mode 100644
index 00000000000..504e33ba66f
--- /dev/null
+++ b/sim/bfin/dv-bfin_ebiu_amc.c
@@ -0,0 +1,456 @@
+/* Blackfin External Bus Interface Unit (EBIU) Asynchronous Memory Controller
+ (AMC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_ebiu_amc.h"
+
+struct bfin_ebiu_amc
+{
+ bu32 base;
+ int type;
+ bu32 bank_size;
+ unsigned (*io_write) (struct hw *, const void *, int, address_word,
+ unsigned, struct bfin_ebiu_amc *, bu32, bu32);
+ unsigned (*io_read) (struct hw *, void *, int, address_word, unsigned,
+ struct bfin_ebiu_amc *, bu32, void *, bu16 *, bu32 *);
+ struct hw *slaves[4];
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(amgctl);
+ union {
+ struct {
+ bu32 ambctl0, ambctl1;
+ bu32 _pad0[5];
+ bu16 BFIN_MMR_16(mode);
+ bu16 BFIN_MMR_16(fctl);
+ } bf50x;
+ struct {
+ bu32 ambctl0, ambctl1;
+ } bf53x;
+ struct {
+ bu32 ambctl0, ambctl1;
+ bu32 mbsctl, arbstat, mode, fctl;
+ } bf54x;
+ };
+};
+#define mmr_base() offsetof(struct bfin_ebiu_amc, amgctl)
+#define mmr_offset(mmr) (offsetof(struct bfin_ebiu_amc, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const bf50x_mmr_names[] = {
+ "EBIU_AMGCTL", "EBIU_AMBCTL0", "EBIU_AMBCTL1",
+ [mmr_idx (bf50x.mode)] = "EBIU_MODE", "EBIU_FCTL",
+};
+static const char * const bf53x_mmr_names[] = {
+ "EBIU_AMGCTL", "EBIU_AMBCTL0", "EBIU_AMBCTL1",
+};
+static const char * const bf54x_mmr_names[] = {
+ "EBIU_AMGCTL", "EBIU_AMBCTL0", "EBIU_AMBCTL1",
+ "EBIU_MSBCTL", "EBIU_ARBSTAT", "EBIU_MODE", "EBIU_FCTL",
+};
+static const char * const *mmr_names;
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static void
+bfin_ebiu_amc_write_amgctl (struct hw *me, struct bfin_ebiu_amc *amc,
+ bu16 amgctl)
+{
+ bu32 amben_old, amben, addr, i;
+
+ amben_old = MIN ((amc->amgctl >> 1) & 0x7, 4);
+ amben = MIN ((amgctl >> 1) & 0x7, 4);
+
+ HW_TRACE ((me, "reattaching banks: AMGCTL 0x%04x[%u] -> 0x%04x[%u]",
+ amc->amgctl, amben_old, amgctl, amben));
+
+ for (i = 0; i < 4; ++i)
+ {
+ addr = BFIN_EBIU_AMC_BASE + i * amc->bank_size;
+
+ if (i < amben_old)
+ {
+ HW_TRACE ((me, "detaching bank %u (%#x base)", i, addr));
+ sim_core_detach (hw_system (me), NULL, 0, 0, addr);
+ }
+
+ if (i < amben)
+ {
+ struct hw *slave = amc->slaves[i];
+
+ HW_TRACE ((me, "attaching bank %u (%#x base) to %s", i, addr,
+ slave ? hw_path (slave) : "<floating pins>"));
+
+ sim_core_attach (hw_system (me), NULL, 0, access_read_write_exec,
+ 0, addr, amc->bank_size, 0, slave, NULL);
+ }
+ }
+
+ amc->amgctl = amgctl;
+}
+
+static unsigned
+bf50x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes,
+ struct bfin_ebiu_amc *amc, bu32 mmr_off,
+ bu32 value)
+{
+ switch (mmr_off)
+ {
+ case mmr_offset(amgctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ bfin_ebiu_amc_write_amgctl (me, amc, value);
+ break;
+ case mmr_offset(bf50x.ambctl0):
+ amc->bf50x.ambctl0 = value;
+ break;
+ case mmr_offset(bf50x.ambctl1):
+ amc->bf50x.ambctl1 = value;
+ break;
+ case mmr_offset(bf50x.mode):
+ /* XXX: implement this. */
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ break;
+ case mmr_offset(bf50x.fctl):
+ /* XXX: implement this. */
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bf53x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes,
+ struct bfin_ebiu_amc *amc, bu32 mmr_off,
+ bu32 value)
+{
+ switch (mmr_off)
+ {
+ case mmr_offset(amgctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ bfin_ebiu_amc_write_amgctl (me, amc, value);
+ break;
+ case mmr_offset(bf53x.ambctl0):
+ amc->bf53x.ambctl0 = value;
+ break;
+ case mmr_offset(bf53x.ambctl1):
+ amc->bf53x.ambctl1 = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bf54x_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes,
+ struct bfin_ebiu_amc *amc, bu32 mmr_off,
+ bu32 value)
+{
+ switch (mmr_off)
+ {
+ case mmr_offset(amgctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ bfin_ebiu_amc_write_amgctl (me, amc, value);
+ break;
+ case mmr_offset(bf54x.ambctl0):
+ amc->bf54x.ambctl0 = value;
+ break;
+ case mmr_offset(bf54x.ambctl1):
+ amc->bf54x.ambctl1 = value;
+ break;
+ case mmr_offset(bf54x.mbsctl):
+ /* XXX: implement this. */
+ break;
+ case mmr_offset(bf54x.arbstat):
+ /* XXX: implement this. */
+ break;
+ case mmr_offset(bf54x.mode):
+ /* XXX: implement this. */
+ break;
+ case mmr_offset(bf54x.fctl):
+ /* XXX: implement this. */
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_ebiu_amc_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ebiu_amc *amc = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+
+ value = dv_load_4 (source);
+ mmr_off = addr - amc->base;
+
+ HW_TRACE_WRITE ();
+
+ return amc->io_write (me, source, space, addr, nr_bytes,
+ amc, mmr_off, value);
+}
+
+static unsigned
+bf50x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes,
+ struct bfin_ebiu_amc *amc, bu32 mmr_off,
+ void *valuep, bu16 *value16, bu32 *value32)
+{
+ switch (mmr_off)
+ {
+ case mmr_offset(amgctl):
+ case mmr_offset(bf50x.fctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16);
+ break;
+ case mmr_offset(bf50x.ambctl0):
+ case mmr_offset(bf50x.ambctl1):
+ case mmr_offset(bf50x.mode):
+ dv_store_4 (dest, *value32);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bf53x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes,
+ struct bfin_ebiu_amc *amc, bu32 mmr_off,
+ void *valuep, bu16 *value16, bu32 *value32)
+{
+ switch (mmr_off)
+ {
+ case mmr_offset(amgctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16);
+ break;
+ case mmr_offset(bf53x.ambctl0):
+ case mmr_offset(bf53x.ambctl1):
+ dv_store_4 (dest, *value32);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bf54x_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes,
+ struct bfin_ebiu_amc *amc, bu32 mmr_off,
+ void *valuep, bu16 *value16, bu32 *value32)
+{
+ switch (mmr_off)
+ {
+ case mmr_offset(amgctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16);
+ break;
+ case mmr_offset(bf54x.ambctl0):
+ case mmr_offset(bf54x.ambctl1):
+ case mmr_offset(bf54x.mbsctl):
+ case mmr_offset(bf54x.arbstat):
+ case mmr_offset(bf54x.mode):
+ case mmr_offset(bf54x.fctl):
+ dv_store_4 (dest, *value32);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_ebiu_amc_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ebiu_amc *amc = hw_data (me);
+ bu32 mmr_off;
+ void *valuep;
+
+ mmr_off = addr - amc->base;
+ valuep = (void *)((unsigned long)amc + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ return amc->io_read (me, dest, space, addr, nr_bytes, amc,
+ mmr_off, valuep, valuep, valuep);
+}
+
+static void
+bfin_ebiu_amc_attach_address_callback (struct hw *me,
+ int level,
+ int space,
+ address_word addr,
+ address_word nr_bytes,
+ struct hw *client)
+{
+ struct bfin_ebiu_amc *amc = hw_data (me);
+
+ HW_TRACE ((me, "attach - level=%d, space=%d, addr=0x%lx, nr_bytes=%lu, client=%s",
+ level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_path (client)));
+
+ if (addr + nr_bytes > 4)
+ hw_abort (me, "ebiu amc attaches are done in terms of banks");
+
+ while (nr_bytes--)
+ amc->slaves[addr + nr_bytes] = client;
+
+ bfin_ebiu_amc_write_amgctl (me, amc, amc->amgctl);
+}
+
+static void
+attach_bfin_ebiu_amc_regs (struct hw *me, struct bfin_ebiu_amc *amc,
+ unsigned reg_size)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ if (hw_find_property (me, "type") == NULL)
+ hw_abort (me, "Missing \"type\" property");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != reg_size)
+ hw_abort (me, "\"reg\" size must be %#x", reg_size);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ amc->base = attach_address;
+}
+
+static void
+bfin_ebiu_amc_finish (struct hw *me)
+{
+ struct bfin_ebiu_amc *amc;
+ bu32 amgctl;
+ unsigned reg_size;
+
+ amc = HW_ZALLOC (me, struct bfin_ebiu_amc);
+
+ set_hw_data (me, amc);
+ set_hw_io_read_buffer (me, bfin_ebiu_amc_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_ebiu_amc_io_write_buffer);
+ set_hw_attach_address (me, bfin_ebiu_amc_attach_address_callback);
+
+ amc->type = hw_find_integer_property (me, "type");
+
+ switch (amc->type)
+ {
+ case 500 ... 509:
+ amc->io_write = bf50x_ebiu_amc_io_write_buffer;
+ amc->io_read = bf50x_ebiu_amc_io_read_buffer;
+ mmr_names = bf50x_mmr_names;
+ reg_size = sizeof (amc->bf50x) + 4;
+
+ /* Initialize the AMC. */
+ amc->bank_size = 1 * 1024 * 1024;
+ amgctl = 0x00F3;
+ amc->bf50x.ambctl0 = 0x0000FFC2;
+ amc->bf50x.ambctl1 = 0x0000FFC2;
+ amc->bf50x.mode = 0x0001;
+ amc->bf50x.fctl = 0x0002;
+ break;
+ case 540 ... 549:
+ amc->io_write = bf54x_ebiu_amc_io_write_buffer;
+ amc->io_read = bf54x_ebiu_amc_io_read_buffer;
+ mmr_names = bf54x_mmr_names;
+ reg_size = sizeof (amc->bf54x) + 4;
+
+ /* Initialize the AMC. */
+ amc->bank_size = 64 * 1024 * 1024;
+ amgctl = 0x0002;
+ amc->bf54x.ambctl0 = 0xFFC2FFC2;
+ amc->bf54x.ambctl1 = 0xFFC2FFC2;
+ amc->bf54x.fctl = 0x0006;
+ break;
+ case 510 ... 519:
+ case 522 ... 527:
+ case 531 ... 533:
+ case 534:
+ case 536:
+ case 537:
+ case 538 ... 539:
+ case 561:
+ amc->io_write = bf53x_ebiu_amc_io_write_buffer;
+ amc->io_read = bf53x_ebiu_amc_io_read_buffer;
+ mmr_names = bf53x_mmr_names;
+ reg_size = sizeof (amc->bf53x) + 4;
+
+ /* Initialize the AMC. */
+ if (amc->type == 561)
+ amc->bank_size = 64 * 1024 * 1024;
+ else
+ amc->bank_size = 1 * 1024 * 1024;
+ amgctl = 0x00F2;
+ amc->bf53x.ambctl0 = 0xFFC2FFC2;
+ amc->bf53x.ambctl1 = 0xFFC2FFC2;
+ break;
+ case 590 ... 599: /* BF59x has no AMC. */
+ default:
+ hw_abort (me, "no support for EBIU AMC on this Blackfin model yet");
+ }
+
+ attach_bfin_ebiu_amc_regs (me, amc, reg_size);
+
+ bfin_ebiu_amc_write_amgctl (me, amc, amgctl);
+}
+
+const struct hw_descriptor dv_bfin_ebiu_amc_descriptor[] = {
+ {"bfin_ebiu_amc", bfin_ebiu_amc_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_ebiu_amc.h b/sim/bfin/dv-bfin_ebiu_amc.h
new file mode 100644
index 00000000000..e47fd1177e9
--- /dev/null
+++ b/sim/bfin/dv-bfin_ebiu_amc.h
@@ -0,0 +1,31 @@
+/* Blackfin External Bus Interface Unit (EBIU) Asynchronous Memory Controller
+ (AMC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_EBIU_AMC_H
+#define DV_BFIN_EBIU_AMC_H
+
+#define BFIN_MMR_EBIU_AMC_SIZE (4 * 3)
+#define BF50X_MMR_EBIU_AMC_SIZE 0x28
+#define BF54X_MMR_EBIU_AMC_SIZE (4 * 7)
+
+#define BFIN_EBIU_AMC_BASE 0x20000000
+
+#endif
diff --git a/sim/bfin/dv-bfin_ebiu_ddrc.c b/sim/bfin/dv-bfin_ebiu_ddrc.c
new file mode 100644
index 00000000000..fa54c8e95fc
--- /dev/null
+++ b/sim/bfin/dv-bfin_ebiu_ddrc.c
@@ -0,0 +1,184 @@
+/* Blackfin External Bus Interface Unit (EBIU) DDR Controller (DDRC) Model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_ebiu_ddrc.h"
+
+struct bfin_ebiu_ddrc
+{
+ bu32 base, reg_size, bank_size;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ union {
+ struct { bu32 ddrctl0, ddrctl1, ddrctl2, ddrctl3; };
+ bu32 ddrctl[4];
+ };
+ bu32 ddrque, erradd;
+ bu16 BFIN_MMR_16(errmst);
+ bu16 BFIN_MMR_16(rstctl);
+ bu32 ddrbrc[8], ddrbwc[8];
+ bu32 ddracct, ddrtact, ddrarct;
+ bu32 ddrgc[4];
+ bu32 ddrmcen, ddrmccl;
+};
+#define mmr_base() offsetof(struct bfin_ebiu_ddrc, ddrctl0)
+#define mmr_offset(mmr) (offsetof(struct bfin_ebiu_ddrc, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "EBIU_DDRCTL0", "EBIU_DDRCTL1", "EBIU_DDRCTL2", "EBIU_DDRCTL3", "EBIU_DDRQUE",
+ "EBIU_ERRADD", "EBIU_ERRMST", "EBIU_RSTCTL", "EBIU_DDRBRC0", "EBIU_DDRBRC1",
+ "EBIU_DDRBRC2", "EBIU_DDRBRC3", "EBIU_DDRBRC4", "EBIU_DDRBRC5",
+ "EBIU_DDRBRC6", "EBIU_DDRBRC7", "EBIU_DDRBWC0", "EBIU_DDRBWC1"
+ "EBIU_DDRBWC2", "EBIU_DDRBWC3", "EBIU_DDRBWC4", "EBIU_DDRBWC5",
+ "EBIU_DDRBWC6", "EBIU_DDRBWC7", "EBIU_DDRACCT", "EBIU_DDRTACT",
+ "EBIU_ARCT", "EBIU_DDRGC0", "EBIU_DDRGC1", "EBIU_DDRGC2", "EBIU_DDRGC3",
+ "EBIU_DDRMCEN", "EBIU_DDRMCCL",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static unsigned
+bfin_ebiu_ddrc_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ebiu_ddrc *ddrc = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - ddrc->base;
+ valuep = (void *)((unsigned long)ddrc + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(errmst):
+ case mmr_offset(rstctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ *value16p = value;
+ break;
+ default:
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+ *value32p = value;
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_ebiu_ddrc_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ebiu_ddrc *ddrc = hw_data (me);
+ bu32 mmr_off;
+ bu32 *value32p;
+ bu16 *value16p;
+ void *valuep;
+
+ mmr_off = addr - ddrc->base;
+ valuep = (void *)((unsigned long)ddrc + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(errmst):
+ case mmr_offset(rstctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ break;
+ default:
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+ dv_store_4 (dest, *value32p);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_ebiu_ddrc_regs (struct hw *me, struct bfin_ebiu_ddrc *ddrc)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_EBIU_DDRC_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_EBIU_DDRC_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ ddrc->base = attach_address;
+}
+
+static void
+bfin_ebiu_ddrc_finish (struct hw *me)
+{
+ struct bfin_ebiu_ddrc *ddrc;
+
+ ddrc = HW_ZALLOC (me, struct bfin_ebiu_ddrc);
+
+ set_hw_data (me, ddrc);
+ set_hw_io_read_buffer (me, bfin_ebiu_ddrc_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_ebiu_ddrc_io_write_buffer);
+
+ attach_bfin_ebiu_ddrc_regs (me, ddrc);
+
+ /* Initialize the DDRC. */
+ ddrc->ddrctl0 = 0x098E8411;
+ ddrc->ddrctl1 = 0x10026223;
+ ddrc->ddrctl2 = 0x00000021;
+ ddrc->ddrctl3 = 0x00000003; /* XXX: MDDR is 0x20 ... */
+ ddrc->ddrque = 0x00001115;
+ ddrc->rstctl = 0x0002;
+}
+
+const struct hw_descriptor dv_bfin_ebiu_ddrc_descriptor[] = {
+ {"bfin_ebiu_ddrc", bfin_ebiu_ddrc_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_ebiu_ddrc.h b/sim/bfin/dv-bfin_ebiu_ddrc.h
new file mode 100644
index 00000000000..ac970bf5317
--- /dev/null
+++ b/sim/bfin/dv-bfin_ebiu_ddrc.h
@@ -0,0 +1,26 @@
+/* Blackfin External Bus Interface Unit (EBIU) DDR Controller (DDRC) Model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_EBIU_DDRC_H
+#define DV_BFIN_EBIU_DDRC_H
+
+#define BFIN_MMR_EBIU_DDRC_SIZE 0xb0
+
+#endif
diff --git a/sim/bfin/dv-bfin_ebiu_sdc.c b/sim/bfin/dv-bfin_ebiu_sdc.c
new file mode 100644
index 00000000000..710f2f8f9a8
--- /dev/null
+++ b/sim/bfin/dv-bfin_ebiu_sdc.c
@@ -0,0 +1,201 @@
+/* Blackfin External Bus Interface Unit (EBIU) SDRAM Controller (SDC) Model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_ebiu_sdc.h"
+
+struct bfin_ebiu_sdc
+{
+ bu32 base;
+ int type;
+ bu32 reg_size, bank_size;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 sdgctl;
+ bu32 sdbctl; /* 16bit on most parts ... */
+ bu16 BFIN_MMR_16(sdrrc);
+ bu16 BFIN_MMR_16(sdstat);
+};
+#define mmr_base() offsetof(struct bfin_ebiu_sdc, sdgctl)
+#define mmr_offset(mmr) (offsetof(struct bfin_ebiu_sdc, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "EBIU_SDGCTL", "EBIU_SDBCTL", "EBIU_SDRRC", "EBIU_SDSTAT",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static unsigned
+bfin_ebiu_sdc_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ebiu_sdc *sdc = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - sdc->base;
+ valuep = (void *)((unsigned long)sdc + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(sdgctl):
+ /* XXX: SRFS should make external mem unreadable. */
+ *value32p = value;
+ break;
+ case mmr_offset(sdbctl):
+ if (sdc->type == 561)
+ {
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+ *value32p = value;
+ }
+ else
+ {
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ *value16p = value;
+ }
+ break;
+ case mmr_offset(sdrrc):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ *value16p = value;
+ break;
+ case mmr_offset(sdstat):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ /* XXX: Some bits are W1C ... */
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_ebiu_sdc_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ebiu_sdc *sdc = hw_data (me);
+ bu32 mmr_off;
+ bu32 *value32p;
+ bu16 *value16p;
+ void *valuep;
+
+ mmr_off = addr - sdc->base;
+ valuep = (void *)((unsigned long)sdc + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(sdgctl):
+ dv_store_4 (dest, *value32p);
+ break;
+ case mmr_offset(sdbctl):
+ if (sdc->type == 561)
+ {
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+ dv_store_4 (dest, *value32p);
+ }
+ else
+ {
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ }
+ break;
+ case mmr_offset(sdrrc):
+ case mmr_offset(sdstat):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_ebiu_sdc_regs (struct hw *me, struct bfin_ebiu_sdc *sdc)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_EBIU_SDC_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_EBIU_SDC_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ sdc->base = attach_address;
+}
+
+static void
+bfin_ebiu_sdc_finish (struct hw *me)
+{
+ struct bfin_ebiu_sdc *sdc;
+
+ sdc = HW_ZALLOC (me, struct bfin_ebiu_sdc);
+
+ set_hw_data (me, sdc);
+ set_hw_io_read_buffer (me, bfin_ebiu_sdc_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_ebiu_sdc_io_write_buffer);
+
+ attach_bfin_ebiu_sdc_regs (me, sdc);
+
+ sdc->type = hw_find_integer_property (me, "type");
+
+ /* Initialize the SDC. */
+ sdc->sdgctl = 0xE0088849;
+ sdc->sdbctl = 0x00000000;
+ sdc->sdrrc = 0x081A;
+ sdc->sdstat = 0x0008;
+
+ /* XXX: We boot with 64M external memory by default ... */
+ sdc->sdbctl |= EBE | EBSZ_64 | EBCAW_10;
+}
+
+const struct hw_descriptor dv_bfin_ebiu_sdc_descriptor[] = {
+ {"bfin_ebiu_sdc", bfin_ebiu_sdc_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_ebiu_sdc.h b/sim/bfin/dv-bfin_ebiu_sdc.h
new file mode 100644
index 00000000000..7849806d936
--- /dev/null
+++ b/sim/bfin/dv-bfin_ebiu_sdc.h
@@ -0,0 +1,39 @@
+/* Blackfin External Bus Interface Unit (EBIU) SDRAM Controller (SDC) Model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_EBIU_SDC_H
+#define DV_BFIN_EBIU_SDC_H
+
+#define BFIN_MMR_EBIU_SDC_SIZE (4 * 4)
+
+/* EBIU_SDBCTL Masks */
+#define EBE 0x0001 /* Enable SDRAM External Bank */
+#define EBSZ_16 0x0000 /* Size = 16MB */
+#define EBSZ_32 0x0002 /* Size = 32MB */
+#define EBSZ_64 0x0004 /* Size = 64MB */
+#define EBSZ_128 0x0006 /* Size = 128MB */
+#define EBSZ_256 0x0008 /* Size = 256MB */
+#define EBSZ_512 0x000A /* Size = 512MB */
+#define EBCAW_8 0x0000 /* Column Address Width = 8 Bits */
+#define EBCAW_9 0x0010 /* Column Address Width = 9 Bits */
+#define EBCAW_10 0x0020 /* Column Address Width = 10 Bits */
+#define EBCAW_11 0x0030 /* Column Address Width = 11 Bits */
+
+#endif
diff --git a/sim/bfin/dv-bfin_emac.c b/sim/bfin/dv-bfin_emac.c
new file mode 100644
index 00000000000..bfd8dc926bc
--- /dev/null
+++ b/sim/bfin/dv-bfin_emac.c
@@ -0,0 +1,603 @@
+/* Blackfin Ethernet Media Access Controller (EMAC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_LINUX_IF_TUN_H
+#include <linux/if_tun.h>
+#endif
+
+#ifdef HAVE_LINUX_IF_TUN_H
+# define WITH_TUN 1
+#else
+# define WITH_TUN 0
+#endif
+
+#include "sim-main.h"
+#include "sim-hw.h"
+#include "devices.h"
+#include "dv-bfin_emac.h"
+
+/* XXX: This doesn't support partial DMA transfers. */
+/* XXX: The TUN pieces should be pushed to the PHY so that we work with
+ multiple "networks" and the PHY takes care of it. */
+
+struct bfin_emac
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ int tap;
+#if WITH_TUN
+ struct ifreq ifr;
+#endif
+ bu32 rx_crc;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 opmode, addrlo, addrhi, hashlo, hashhi, staadd, stadat, flc, vlan1, vlan2;
+ bu32 _pad0;
+ bu32 wkup_ctl, wkup_ffmsk0, wkup_ffmsk1, wkup_ffmsk2, wkup_ffmsk3;
+ bu32 wkup_ffcmd, wkup_ffoff, wkup_ffcrc0, wkup_ffcrc1;
+ bu32 _pad1[4];
+ bu32 sysctl, systat, rx_stat, rx_stky, rx_irqe, tx_stat, tx_stky, tx_irqe;
+ bu32 mmc_ctl, mmc_rirqs, mmc_rirqe, mmc_tirqs, mmc_tirqe;
+ bu32 _pad2[3];
+ bu16 BFIN_MMR_16(ptp_ctl);
+ bu16 BFIN_MMR_16(ptp_ie);
+ bu16 BFIN_MMR_16(ptp_istat);
+ bu32 ptp_foff, ptp_fv1, ptp_fv2, ptp_fv3, ptp_addend, ptp_accr, ptp_offset;
+ bu32 ptp_timelo, ptp_timehi, ptp_rxsnaplo, ptp_rxsnaphi, ptp_txsnaplo;
+ bu32 ptp_txsnaphi, ptp_alarmlo, ptp_alarmhi, ptp_id_off, ptp_id_snap;
+ bu32 ptp_pps_startlo, ptp_pps_starthi, ptp_pps_period;
+ bu32 _pad3[1];
+ bu32 rxc_ok, rxc_fcs, rxc_lign, rxc_octet, rxc_dmaovf, rxc_unicst, rxc_multi;
+ bu32 rxc_broad, rxc_lnerri, rxc_lnerro, rxc_long, rxc_macctl, rxc_opcode;
+ bu32 rxc_pause, rxc_allfrm, rxc_alloct, rxc_typed, rxc_short, rxc_eq64;
+ bu32 rxc_lt128, rxc_lt256, rxc_lt512, rxc_lt1024, rxc_ge1024;
+ bu32 _pad4[8];
+ bu32 txc_ok, txc_1col, txc_gt1col, txc_octet, txc_defer, txc_latecl;
+ bu32 txc_xs_col, txc_dmaund, txc_crserr, txc_unicst, txc_multi, txc_broad;
+ bu32 txc_xs_dfr, txc_macctl, txc_allfrm, txc_alloct, txc_eq64, txc_lt128;
+ bu32 txc_lt256, txc_lt512, txc_lt1024, txc_ge1024, txc_abort;
+};
+#define mmr_base() offsetof(struct bfin_emac, opmode)
+#define mmr_offset(mmr) (offsetof(struct bfin_emac, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const mmr_names[BFIN_MMR_EMAC_SIZE / 4] = {
+ "EMAC_OPMODE", "EMAC_ADDRLO", "EMAC_ADDRHI", "EMAC_HASHLO", "EMAC_HASHHI",
+ "EMAC_STAADD", "EMAC_STADAT", "EMAC_FLC", "EMAC_VLAN1", "EMAC_VLAN2", NULL,
+ "EMAC_WKUP_CTL", "EMAC_WKUP_FFMSK0", "EMAC_WKUP_FFMSK1", "EMAC_WKUP_FFMSK2",
+ "EMAC_WKUP_FFMSK3", "EMAC_WKUP_FFCMD", "EMAC_WKUP_FFOFF", "EMAC_WKUP_FFCRC0",
+ "EMAC_WKUP_FFCRC1", [mmr_idx (sysctl)] = "EMAC_SYSCTL", "EMAC_SYSTAT",
+ "EMAC_RX_STAT", "EMAC_RX_STKY", "EMAC_RX_IRQE", "EMAC_TX_STAT",
+ "EMAC_TX_STKY", "EMAC_TX_IRQE", "EMAC_MMC_CTL", "EMAC_MMC_RIRQS",
+ "EMAC_MMC_RIRQE", "EMAC_MMC_TIRQS", "EMAC_MMC_TIRQE",
+ [mmr_idx (ptp_ctl)] = "EMAC_PTP_CTL", "EMAC_PTP_IE", "EMAC_PTP_ISTAT",
+ "EMAC_PTP_FOFF", "EMAC_PTP_FV1", "EMAC_PTP_FV2", "EMAC_PTP_FV3",
+ "EMAC_PTP_ADDEND", "EMAC_PTP_ACCR", "EMAC_PTP_OFFSET", "EMAC_PTP_TIMELO",
+ "EMAC_PTP_TIMEHI", "EMAC_PTP_RXSNAPLO", "EMAC_PTP_RXSNAPHI",
+ "EMAC_PTP_TXSNAPLO", "EMAC_PTP_TXSNAPHI", "EMAC_PTP_ALARMLO",
+ "EMAC_PTP_ALARMHI", "EMAC_PTP_ID_OFF", "EMAC_PTP_ID_SNAP",
+ "EMAC_PTP_PPS_STARTLO", "EMAC_PTP_PPS_STARTHI", "EMAC_PTP_PPS_PERIOD",
+ [mmr_idx (rxc_ok)] = "EMAC_RXC_OK", "EMAC_RXC_FCS", "EMAC_RXC_LIGN",
+ "EMAC_RXC_OCTET", "EMAC_RXC_DMAOVF", "EMAC_RXC_UNICST", "EMAC_RXC_MULTI",
+ "EMAC_RXC_BROAD", "EMAC_RXC_LNERRI", "EMAC_RXC_LNERRO", "EMAC_RXC_LONG",
+ "EMAC_RXC_MACCTL", "EMAC_RXC_OPCODE", "EMAC_RXC_PAUSE", "EMAC_RXC_ALLFRM",
+ "EMAC_RXC_ALLOCT", "EMAC_RXC_TYPED", "EMAC_RXC_SHORT", "EMAC_RXC_EQ64",
+ "EMAC_RXC_LT128", "EMAC_RXC_LT256", "EMAC_RXC_LT512", "EMAC_RXC_LT1024",
+ "EMAC_RXC_GE1024",
+ [mmr_idx (txc_ok)] = "EMAC_TXC_OK", "EMAC_TXC_1COL", "EMAC_TXC_GT1COL",
+ "EMAC_TXC_OCTET", "EMAC_TXC_DEFER", "EMAC_TXC_LATECL", "EMAC_TXC_XS_COL",
+ "EMAC_TXC_DMAUND", "EMAC_TXC_CRSERR", "EMAC_TXC_UNICST", "EMAC_TXC_MULTI",
+ "EMAC_TXC_BROAD", "EMAC_TXC_XS_DFR", "EMAC_TXC_MACCTL", "EMAC_TXC_ALLFRM",
+ "EMAC_TXC_ALLOCT", "EMAC_TXC_EQ64", "EMAC_TXC_LT128", "EMAC_TXC_LT256",
+ "EMAC_TXC_LT512", "EMAC_TXC_LT1024", "EMAC_TXC_GE1024", "EMAC_TXC_ABORT",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static struct hw *
+mii_find_phy (struct hw *me, bu8 addr)
+{
+ struct hw *phy = hw_child (me);
+ while (phy && --addr)
+ phy = hw_sibling (phy);
+ return phy;
+}
+
+static void
+mii_write (struct hw *me)
+{
+ SIM_DESC sd = hw_system (me);
+ struct bfin_emac *emac = hw_data (me);
+ struct hw *phy;
+ bu8 addr = PHYAD (emac->staadd);
+ bu8 reg = REGAD (emac->staadd);
+ bu16 data = emac->stadat;
+
+ phy = mii_find_phy (me, addr);
+ if (!phy)
+ return;
+ sim_hw_io_write_buffer (sd, phy, &data, 1, reg, 2);
+}
+
+static void
+mii_read (struct hw *me)
+{
+ SIM_DESC sd = hw_system (me);
+ struct bfin_emac *emac = hw_data (me);
+ struct hw *phy;
+ bu8 addr = PHYAD (emac->staadd);
+ bu8 reg = REGAD (emac->staadd);
+ bu16 data;
+
+ phy = mii_find_phy (me, addr);
+ if (!phy || sim_hw_io_read_buffer (sd, phy, &data, 1, reg, 2) != 2)
+ data = 0xffff;
+
+ emac->stadat = data;
+}
+
+static unsigned
+bfin_emac_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_emac *emac = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu32 *valuep;
+
+ /* XXX: 16bit accesses are allowed ... */
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+ value = dv_load_4 (source);
+
+ mmr_off = addr - emac->base;
+ valuep = (void *)((unsigned long)emac + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(hashlo):
+ case mmr_offset(hashhi):
+ case mmr_offset(stadat):
+ case mmr_offset(flc):
+ case mmr_offset(vlan1):
+ case mmr_offset(vlan2):
+ case mmr_offset(wkup_ffmsk0):
+ case mmr_offset(wkup_ffmsk1):
+ case mmr_offset(wkup_ffmsk2):
+ case mmr_offset(wkup_ffmsk3):
+ case mmr_offset(wkup_ffcmd):
+ case mmr_offset(wkup_ffoff):
+ case mmr_offset(wkup_ffcrc0):
+ case mmr_offset(wkup_ffcrc1):
+ case mmr_offset(sysctl):
+ case mmr_offset(rx_irqe):
+ case mmr_offset(tx_irqe):
+ case mmr_offset(mmc_rirqe):
+ case mmr_offset(mmc_tirqe):
+ *valuep = value;
+ break;
+ case mmr_offset(opmode):
+ if (!(*valuep & RE) && (value & RE))
+ emac->rx_stat &= ~RX_COMP;
+ if (!(*valuep & TE) && (value & TE))
+ emac->tx_stat &= ~TX_COMP;
+ *valuep = value;
+ break;
+ case mmr_offset(addrlo):
+ case mmr_offset(addrhi):
+ *valuep = value;
+ break;
+ case mmr_offset(wkup_ctl):
+ dv_w1c_4_partial (valuep, value, 0xf20);
+ break;
+ case mmr_offset(systat):
+ dv_w1c_4 (valuep, value, 0x1e);
+ break;
+ case mmr_offset(staadd):
+ *valuep = value | STABUSY;
+ if (value & STAOP)
+ mii_write (me);
+ else
+ mii_read (me);
+ *valuep &= ~STABUSY;
+ break;
+ case mmr_offset(rx_stat):
+ case mmr_offset(tx_stat):
+ /* Discard writes to these. */
+ break;
+ case mmr_offset(rx_stky):
+ case mmr_offset(tx_stky):
+ case mmr_offset(mmc_rirqs):
+ case mmr_offset(mmc_tirqs):
+ dv_w1c_4 (valuep, value, 0);
+ break;
+ case mmr_offset(mmc_ctl):
+ /* Writing to bit 0 clears all counters. */
+ *valuep = value & ~1;
+ if (value & 1)
+ {
+ memset (&emac->rxc_ok, 0, mmr_offset (rxc_ge1024) - mmr_offset (rxc_ok) + 4);
+ memset (&emac->txc_ok, 0, mmr_offset (txc_abort) - mmr_offset (txc_ok) + 4);
+ }
+ break;
+ case mmr_offset(rxc_ok) ... mmr_offset(rxc_ge1024):
+ case mmr_offset(txc_ok) ... mmr_offset(txc_abort):
+ /* XXX: Are these supposed to be read-only ? */
+ *valuep = value;
+ break;
+ case mmr_offset(ptp_ctl) ... mmr_offset(ptp_pps_period):
+ /* XXX: Only on some models; ignore for now. */
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_emac_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_emac *emac = hw_data (me);
+ bu32 mmr_off;
+ bu32 *valuep;
+
+ /* XXX: 16bit accesses are allowed ... */
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+
+ mmr_off = addr - emac->base;
+ valuep = (void *)((unsigned long)emac + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(opmode):
+ case mmr_offset(addrlo):
+ case mmr_offset(addrhi):
+ case mmr_offset(hashlo):
+ case mmr_offset(hashhi):
+ case mmr_offset(staadd):
+ case mmr_offset(stadat):
+ case mmr_offset(flc):
+ case mmr_offset(vlan1):
+ case mmr_offset(vlan2):
+ case mmr_offset(wkup_ctl):
+ case mmr_offset(wkup_ffmsk0):
+ case mmr_offset(wkup_ffmsk1):
+ case mmr_offset(wkup_ffmsk2):
+ case mmr_offset(wkup_ffmsk3):
+ case mmr_offset(wkup_ffcmd):
+ case mmr_offset(wkup_ffoff):
+ case mmr_offset(wkup_ffcrc0):
+ case mmr_offset(wkup_ffcrc1):
+ case mmr_offset(sysctl):
+ case mmr_offset(systat):
+ case mmr_offset(rx_stat):
+ case mmr_offset(rx_stky):
+ case mmr_offset(rx_irqe):
+ case mmr_offset(tx_stat):
+ case mmr_offset(tx_stky):
+ case mmr_offset(tx_irqe):
+ case mmr_offset(mmc_rirqs):
+ case mmr_offset(mmc_rirqe):
+ case mmr_offset(mmc_tirqs):
+ case mmr_offset(mmc_tirqe):
+ case mmr_offset(mmc_ctl):
+ case mmr_offset(rxc_ok) ... mmr_offset(rxc_ge1024):
+ case mmr_offset(txc_ok) ... mmr_offset(txc_abort):
+ dv_store_4 (dest, *valuep);
+ break;
+ case mmr_offset(ptp_ctl) ... mmr_offset(ptp_pps_period):
+ /* XXX: Only on some models; ignore for now. */
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_emac_regs (struct hw *me, struct bfin_emac *emac)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_EMAC_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_EMAC_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ emac->base = attach_address;
+}
+
+static struct dv_bfin *dma_tx;
+
+static unsigned
+bfin_emac_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ struct bfin_emac *emac = hw_data (me);
+ struct dv_bfin *dma = hw_data (emac->dma_master);
+ unsigned char *data = dest;
+ static bool flop; /* XXX: This sucks. */
+ bu16 len;
+ ssize_t ret;
+
+ HW_TRACE_DMA_READ ();
+
+ if (dma_tx == dma)
+ {
+ /* Handle the TX turn around and write the status. */
+ emac->tx_stat |= TX_OK;
+ emac->tx_stky |= TX_OK;
+
+ memcpy (data, &emac->tx_stat, 4);
+
+ dma->acked = true;
+ return 4;
+ }
+
+ if (!(emac->opmode & RE))
+ return 0;
+
+ if (!flop)
+ {
+ ssize_t pad_ret;
+ /* Outgoing DMA buffer has 16bit len prepended to it. */
+ data += 2;
+
+ /* This doesn't seem to work.
+ if (emac->sysctl & RXDWA)
+ {
+ memset (data, 0, 2);
+ data += 2;
+ } */
+
+ ret = read (emac->tap, data, nr_bytes);
+ if (ret < 0)
+ return 0;
+ ret += 4; /* include crc */
+ pad_ret = MAX (ret + 4, 64);
+ len = pad_ret;
+ memcpy (dest, &len, 2);
+
+ pad_ret = (pad_ret + 3) & ~3;
+ if (ret < pad_ret)
+ memset (data + ret, 0, pad_ret - ret);
+ pad_ret += 4;
+
+ /* XXX: Need to check -- u-boot doesn't look at this. */
+ if (emac->sysctl & RXCKS)
+ {
+ pad_ret += 4;
+ emac->rx_crc = 0;
+ }
+ ret = pad_ret;
+
+ /* XXX: Don't support promiscuous yet. */
+ emac->rx_stat |= RX_ACCEPT;
+ emac->rx_stat = (emac->rx_stat & ~RX_FRLEN) | len;
+
+ emac->rx_stat |= RX_COMP;
+ emac->rx_stky |= RX_COMP;
+ }
+ else
+ {
+ /* Write the RX status and crc info. */
+ emac->rx_stat |= RX_OK;
+ emac->rx_stky |= RX_OK;
+
+ ret = 4;
+ if (emac->sysctl & RXCKS)
+ {
+ memcpy (data, &emac->rx_crc, 4);
+ data += 4;
+ ret += 4;
+ }
+ memcpy (data, &emac->rx_stat, 4);
+ }
+
+ flop = !flop;
+ dma->acked = true;
+ return ret;
+}
+
+static unsigned
+bfin_emac_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ struct bfin_emac *emac = hw_data (me);
+ struct dv_bfin *dma = hw_data (emac->dma_master);
+ const unsigned char *data = source;
+ bu16 len;
+ ssize_t ret;
+
+ HW_TRACE_DMA_WRITE ();
+
+ if (!(emac->opmode & TE))
+ return 0;
+
+ /* Incoming DMA buffer has 16bit len prepended to it. */
+ memcpy (&len, data, 2);
+ if (!len)
+ return 0;
+
+ ret = write (emac->tap, data + 2, len);
+ if (ret < 0)
+ return 0;
+ ret += 2;
+
+ emac->tx_stat |= TX_COMP;
+ emac->tx_stky |= TX_COMP;
+
+ dma_tx = dma;
+ dma->acked = true;
+ return ret;
+}
+
+static const struct hw_port_descriptor bfin_emac_ports[] = {
+ { "tx", DV_PORT_TX, 0, output_port, },
+ { "rx", DV_PORT_RX, 0, output_port, },
+ { "stat", DV_PORT_STAT, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_emac_attach_address_callback (struct hw *me,
+ int level,
+ int space,
+ address_word addr,
+ address_word nr_bytes,
+ struct hw *client)
+{
+ const hw_unit *unit = hw_unit_address (client);
+ HW_TRACE ((me, "attach - level=%d, space=%d, addr=0x%lx, nr_bytes=%lu, client=%s",
+ level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_path (client)));
+ /* NOTE: At preset the space is assumed to be zero. Perhaphs the
+ space should be mapped onto something for instance: space0 -
+ unified memory; space1 - IO memory; ... */
+ sim_core_attach (hw_system (me),
+ NULL, /*cpu*/
+ level + 10 + unit->cells[unit->nr_cells - 1],
+ access_read_write_exec,
+ space, addr,
+ nr_bytes,
+ 0, /* modulo */
+ client,
+ NULL);
+}
+
+static void
+bfin_emac_delete (struct hw *me)
+{
+ struct bfin_emac *emac = hw_data (me);
+ close (emac->tap);
+}
+
+static void
+bfin_emac_tap_init (struct hw *me)
+{
+#if WITH_TUN
+ struct bfin_emac *emac = hw_data (me);
+ const hw_unit *unit;
+ int flags;
+
+ unit = hw_unit_address (me);
+
+ emac->tap = open ("/dev/net/tun", O_RDWR);
+ if (emac->tap == -1)
+ {
+ HW_TRACE ((me, "unable to open /dev/net/tun: %s", strerror (errno)));
+ return;
+ }
+
+ memset (&emac->ifr, 0, sizeof (emac->ifr));
+ emac->ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ strcpy (emac->ifr.ifr_name, "tap-gdb");
+
+ flags = 1 * 1024 * 1024;
+ if (ioctl (emac->tap, TUNSETIFF, &emac->ifr) < 0
+#ifdef TUNSETNOCSUM
+ || ioctl (emac->tap, TUNSETNOCSUM) < 0
+#endif
+#ifdef TUNSETSNDBUF
+ || ioctl (emac->tap, TUNSETSNDBUF, &flags) < 0
+#endif
+ )
+ {
+ HW_TRACE ((me, "tap ioctl setup failed: %s", strerror (errno)));
+ close (emac->tap);
+ return;
+ }
+
+ flags = fcntl (emac->tap, F_GETFL);
+ fcntl (emac->tap, F_SETFL, flags | O_NONBLOCK);
+#endif
+}
+
+static void
+bfin_emac_finish (struct hw *me)
+{
+ struct bfin_emac *emac;
+
+ emac = HW_ZALLOC (me, struct bfin_emac);
+
+ set_hw_data (me, emac);
+ set_hw_io_read_buffer (me, bfin_emac_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_emac_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_emac_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_emac_dma_write_buffer);
+ set_hw_ports (me, bfin_emac_ports);
+ set_hw_attach_address (me, bfin_emac_attach_address_callback);
+ set_hw_delete (me, bfin_emac_delete);
+
+ attach_bfin_emac_regs (me, emac);
+
+ /* Initialize the EMAC. */
+ emac->addrlo = 0xffffffff;
+ emac->addrhi = 0x0000ffff;
+ emac->vlan1 = 0x0000ffff;
+ emac->vlan2 = 0x0000ffff;
+ emac->sysctl = 0x00003f00;
+ emac->mmc_ctl = 0x0000000a;
+
+ bfin_emac_tap_init (me);
+}
+
+const struct hw_descriptor dv_bfin_emac_descriptor[] = {
+ {"bfin_emac", bfin_emac_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_emac.h b/sim/bfin/dv-bfin_emac.h
new file mode 100644
index 00000000000..2522292c764
--- /dev/null
+++ b/sim/bfin/dv-bfin_emac.h
@@ -0,0 +1,61 @@
+/* Blackfin Ethernet Media Access Controller (EMAC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_EMAC_H
+#define DV_BFIN_EMAC_H
+
+#define BFIN_MMR_EMAC_BASE 0xFFC03000
+#define BFIN_MMR_EMAC_SIZE 0x200
+
+/* EMAC_OPMODE Masks */
+#define RE (1 << 0)
+#define ASTP (1 << 1)
+#define PR (1 << 7)
+#define TE (1 << 16)
+
+/* EMAC_STAADD Masks */
+#define STABUSY (1 << 0)
+#define STAOP (1 << 1)
+#define STADISPRE (1 << 2)
+#define STAIE (1 << 3)
+#define REGAD_SHIFT 6
+#define REGAD_MASK (0x1f << REGAD_SHIFT)
+#define REGAD(val) (((val) & REGAD_MASK) >> REGAD_SHIFT)
+#define PHYAD_SHIFT 11
+#define PHYAD_MASK (0x1f << PHYAD_SHIFT)
+#define PHYAD(val) (((val) & PHYAD_MASK) >> PHYAD_SHIFT)
+
+/* EMAC_SYSCTL Masks */
+#define PHYIE (1 << 0)
+#define RXDWA (1 << 1)
+#define RXCKS (1 << 2)
+#define TXDWA (1 << 4)
+
+/* EMAC_RX_STAT Masks */
+#define RX_FRLEN 0x7ff
+#define RX_COMP (1 << 12)
+#define RX_OK (1 << 13)
+#define RX_ACCEPT (1 << 31)
+
+/* EMAC_TX_STAT Masks */
+#define TX_COMP (1 << 0)
+#define TX_OK (1 << 1)
+
+#endif
diff --git a/sim/bfin/dv-bfin_eppi.c b/sim/bfin/dv-bfin_eppi.c
new file mode 100644
index 00000000000..7a1d6dbc438
--- /dev/null
+++ b/sim/bfin/dv-bfin_eppi.c
@@ -0,0 +1,271 @@
+/* Blackfin Enhanced Parallel Port Interface (EPPI) model
+ For "new style" PPIs on BF54x/etc... parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_eppi.h"
+#include "gui.h"
+
+/* XXX: TX is merely a stub. */
+
+struct bfin_eppi
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ /* GUI state. */
+ void *gui_state;
+ int color;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(status);
+ bu16 BFIN_MMR_16(hcount);
+ bu16 BFIN_MMR_16(hdelay);
+ bu16 BFIN_MMR_16(vcount);
+ bu16 BFIN_MMR_16(vdelay);
+ bu16 BFIN_MMR_16(frame);
+ bu16 BFIN_MMR_16(line);
+ bu16 BFIN_MMR_16(clkdiv);
+ bu32 control, fs1w_hbl, fs1p_avpl, fsw2_lvb, fs2p_lavf, clip, err;
+};
+#define mmr_base() offsetof(struct bfin_eppi, status)
+#define mmr_offset(mmr) (offsetof(struct bfin_eppi, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "EPPI_STATUS", "EPPI_HCOUNT", "EPPI_HDELAY", "EPPI_VCOUNT", "EPPI_VDELAY",
+ "EPPI_FRAME", "EPPI_LINE", "EPPI_CLKDIV", "EPPI_CONTROL", "EPPI_FS1W_HBL",
+ "EPPI_FS1P_AVPL", "EPPI_FS2W_LVB", "EPPI_FS2P_LAVF", "EPPI_CLIP", "EPPI_ERR",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static void
+bfin_eppi_gui_setup (struct bfin_eppi *eppi)
+{
+ /* If we are in RX mode, nothing to do. */
+ if (!(eppi->control & PORT_DIR))
+ return;
+
+ eppi->gui_state = bfin_gui_setup (eppi->gui_state,
+ eppi->control & PORT_EN,
+ eppi->hcount,
+ eppi->vcount,
+ eppi->color);
+}
+
+static unsigned
+bfin_eppi_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_eppi *eppi = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - eppi->base;
+ valuep = (void *)((unsigned long)eppi + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(status):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ dv_w1c_2 (value16p, value, 0);
+ break;
+ case mmr_offset(hcount):
+ case mmr_offset(hdelay):
+ case mmr_offset(vcount):
+ case mmr_offset(vdelay):
+ case mmr_offset(frame):
+ case mmr_offset(line):
+ case mmr_offset(clkdiv):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ *value16p = value;
+ break;
+ case mmr_offset(control):
+ *value32p = value;
+ bfin_eppi_gui_setup (eppi);
+ break;
+ case mmr_offset(fs1w_hbl):
+ case mmr_offset(fs1p_avpl):
+ case mmr_offset(fsw2_lvb):
+ case mmr_offset(fs2p_lavf):
+ case mmr_offset(clip):
+ case mmr_offset(err):
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+ *value32p = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_eppi_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_eppi *eppi = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - eppi->base;
+ valuep = (void *)((unsigned long)eppi + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(status):
+ case mmr_offset(hcount):
+ case mmr_offset(hdelay):
+ case mmr_offset(vcount):
+ case mmr_offset(vdelay):
+ case mmr_offset(frame):
+ case mmr_offset(line):
+ case mmr_offset(clkdiv):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ break;
+ case mmr_offset(control):
+ case mmr_offset(fs1w_hbl):
+ case mmr_offset(fs1p_avpl):
+ case mmr_offset(fsw2_lvb):
+ case mmr_offset(fs2p_lavf):
+ case mmr_offset(clip):
+ case mmr_offset(err):
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_eppi_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ HW_TRACE_DMA_READ ();
+ return 0;
+}
+
+static unsigned
+bfin_eppi_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ struct bfin_eppi *eppi = hw_data (me);
+
+ HW_TRACE_DMA_WRITE ();
+
+ return bfin_gui_update (eppi->gui_state, source, nr_bytes);
+}
+
+static const struct hw_port_descriptor bfin_eppi_ports[] = {
+ { "stat", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_eppi_regs (struct hw *me, struct bfin_eppi *eppi)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_EPPI_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_EPPI_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ eppi->base = attach_address;
+}
+
+static void
+bfin_eppi_finish (struct hw *me)
+{
+ struct bfin_eppi *eppi;
+ const char *color;
+
+ eppi = HW_ZALLOC (me, struct bfin_eppi);
+
+ set_hw_data (me, eppi);
+ set_hw_io_read_buffer (me, bfin_eppi_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_eppi_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_eppi_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_eppi_dma_write_buffer);
+ set_hw_ports (me, bfin_eppi_ports);
+
+ attach_bfin_eppi_regs (me, eppi);
+
+ /* Initialize the EPPI. */
+ if (hw_find_property (me, "color"))
+ color = hw_find_string_property (me, "color");
+ else
+ color = NULL;
+ eppi->color = bfin_gui_color (color);
+}
+
+const struct hw_descriptor dv_bfin_eppi_descriptor[] = {
+ {"bfin_eppi", bfin_eppi_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_eppi.h b/sim/bfin/dv-bfin_eppi.h
new file mode 100644
index 00000000000..1856800aacd
--- /dev/null
+++ b/sim/bfin/dv-bfin_eppi.h
@@ -0,0 +1,30 @@
+/* Blackfin Enhanced Parallel Port Interface (EPPI) model
+ For "new style" PPIs on BF54x/etc... parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_EPPI_H
+#define DV_BFIN_EPPI_H
+
+#include "dv-bfin_ppi.h"
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_EPPI_SIZE 0x40
+
+#endif
diff --git a/sim/bfin/dv-bfin_evt.c b/sim/bfin/dv-bfin_evt.c
new file mode 100644
index 00000000000..3af0717286e
--- /dev/null
+++ b/sim/bfin/dv-bfin_evt.c
@@ -0,0 +1,153 @@
+/* Blackfin Event Vector Table (EVT) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_cec.h"
+#include "dv-bfin_evt.h"
+
+struct bfin_evt
+{
+ bu32 base;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 evt[16];
+};
+#define mmr_base() offsetof(struct bfin_evt, evt[0])
+#define mmr_offset(mmr) (offsetof(struct bfin_evt, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "EVT0", "EVT1", "EVT2", "EVT3", "EVT4", "EVT5", "EVT6", "EVT7", "EVT8",
+ "EVT9", "EVT10", "EVT11", "EVT12", "EVT13", "EVT14", "EVT15",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static unsigned
+bfin_evt_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_evt *evt = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+
+ value = dv_load_4 (source);
+ mmr_off = addr - evt->base;
+
+ HW_TRACE_WRITE ();
+
+ evt->evt[mmr_off / 4] = value;
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_evt_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_evt *evt = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+
+ mmr_off = addr - evt->base;
+
+ HW_TRACE_READ ();
+
+ value = evt->evt[mmr_off / 4];
+
+ dv_store_4 (dest, value);
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_evt_regs (struct hw *me, struct bfin_evt *evt)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_COREMMR_EVT_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_EVT_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ evt->base = attach_address;
+}
+
+static void
+bfin_evt_finish (struct hw *me)
+{
+ struct bfin_evt *evt;
+
+ evt = HW_ZALLOC (me, struct bfin_evt);
+
+ set_hw_data (me, evt);
+ set_hw_io_read_buffer (me, bfin_evt_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_evt_io_write_buffer);
+
+ attach_bfin_evt_regs (me, evt);
+}
+
+const struct hw_descriptor dv_bfin_evt_descriptor[] = {
+ {"bfin_evt", bfin_evt_finish,},
+ {NULL, NULL},
+};
+
+#define EVT_STATE(cpu) DV_STATE_CACHED (cpu, evt)
+
+void
+cec_set_evt (SIM_CPU *cpu, int ivg, bu32 handler_addr)
+{
+ if (ivg > IVG15 || ivg < 0)
+ sim_io_error (CPU_STATE (cpu), "%s: ivg %i out of range !", __func__, ivg);
+
+ EVT_STATE (cpu)->evt[ivg] = handler_addr;
+}
+
+bu32
+cec_get_evt (SIM_CPU *cpu, int ivg)
+{
+ if (ivg > IVG15 || ivg < 0)
+ sim_io_error (CPU_STATE (cpu), "%s: ivg %i out of range !", __func__, ivg);
+
+ return EVT_STATE (cpu)->evt[ivg];
+}
+
+bu32
+cec_get_reset_evt (SIM_CPU *cpu)
+{
+ /* XXX: This should tail into the model to get via BMODE pins. */
+ return 0xef000000;
+}
diff --git a/sim/bfin/dv-bfin_evt.h b/sim/bfin/dv-bfin_evt.h
new file mode 100644
index 00000000000..defa0826c06
--- /dev/null
+++ b/sim/bfin/dv-bfin_evt.h
@@ -0,0 +1,31 @@
+/* Blackfin Event Vector Table (EVT) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_EVT_H
+#define DV_BFIN_EVT_H
+
+#define BFIN_COREMMR_EVT_BASE 0xFFE02000
+#define BFIN_COREMMR_EVT_SIZE (4 * 16)
+
+extern void cec_set_evt (SIM_CPU *, int ivg, bu32 handler_addr);
+extern bu32 cec_get_evt (SIM_CPU *, int ivg);
+extern bu32 cec_get_reset_evt (SIM_CPU *);
+
+#endif
diff --git a/sim/bfin/dv-bfin_gptimer.c b/sim/bfin/dv-bfin_gptimer.c
new file mode 100644
index 00000000000..23c906fa95e
--- /dev/null
+++ b/sim/bfin/dv-bfin_gptimer.c
@@ -0,0 +1,183 @@
+/* Blackfin General Purpose Timers (GPtimer) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_gptimer.h"
+
+/* XXX: This is merely a stub. */
+
+struct bfin_gptimer
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(config);
+ bu32 counter, period, width;
+};
+#define mmr_base() offsetof(struct bfin_gptimer, config)
+#define mmr_offset(mmr) (offsetof(struct bfin_gptimer, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "TIMER_CONFIG", "TIMER_COUNTER", "TIMER_PERIOD", "TIMER_WIDTH",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static unsigned
+bfin_gptimer_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_gptimer *gptimer = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - gptimer->base;
+ valuep = (void *)((unsigned long)gptimer + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(config):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ *value16p = value;
+ break;
+ case mmr_offset(counter):
+ case mmr_offset(period):
+ case mmr_offset(width):
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+ *value32p = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_gptimer_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_gptimer *gptimer = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - gptimer->base;
+ valuep = (void *)((unsigned long)gptimer + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(config):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ break;
+ case mmr_offset(counter):
+ case mmr_offset(period):
+ case mmr_offset(width):
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_gptimer_ports[] = {
+ { "stat", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_gptimer_regs (struct hw *me, struct bfin_gptimer *gptimer)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_GPTIMER_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_GPTIMER_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ gptimer->base = attach_address;
+}
+
+static void
+bfin_gptimer_finish (struct hw *me)
+{
+ struct bfin_gptimer *gptimer;
+
+ gptimer = HW_ZALLOC (me, struct bfin_gptimer);
+
+ set_hw_data (me, gptimer);
+ set_hw_io_read_buffer (me, bfin_gptimer_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_gptimer_io_write_buffer);
+ set_hw_ports (me, bfin_gptimer_ports);
+
+ attach_bfin_gptimer_regs (me, gptimer);
+}
+
+const struct hw_descriptor dv_bfin_gptimer_descriptor[] = {
+ {"bfin_gptimer", bfin_gptimer_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_gptimer.h b/sim/bfin/dv-bfin_gptimer.h
new file mode 100644
index 00000000000..2c7c149e497
--- /dev/null
+++ b/sim/bfin/dv-bfin_gptimer.h
@@ -0,0 +1,27 @@
+/* Blackfin General Purpose Timers (GPtimer) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_GPTIMER_H
+#define DV_BFIN_GPTIMER_H
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_GPTIMER_SIZE (4 * 4)
+
+#endif
diff --git a/sim/bfin/dv-bfin_jtag.c b/sim/bfin/dv-bfin_jtag.c
new file mode 100644
index 00000000000..76b59acccee
--- /dev/null
+++ b/sim/bfin/dv-bfin_jtag.c
@@ -0,0 +1,157 @@
+/* Blackfin JTAG model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_jtag.h"
+
+/* XXX: This is mostly a stub. There are more registers, but they're only
+ accessible via the JTAG scan chain and not the MMR interface. */
+
+struct bfin_jtag
+{
+ bu32 base;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 dspid;
+ bu32 _pad0;
+ bu32 dbgstat;
+};
+#define mmr_base() offsetof(struct bfin_jtag, dspid)
+#define mmr_offset(mmr) (offsetof(struct bfin_jtag, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "DSPID", NULL, "DBGSTAT",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static unsigned
+bfin_jtag_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_jtag *jtag = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu32 *valuep;
+
+ value = dv_load_4 (source);
+ mmr_off = addr - jtag->base;
+ valuep = (void *)((unsigned long)jtag + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(dbgstat):
+ dv_w1c_4 (valuep, value, ~0xc);
+ break;
+ case mmr_offset(dspid):
+ /* Discard writes to these. */
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_jtag_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_jtag *jtag = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu32 *valuep;
+
+ mmr_off = addr - jtag->base;
+ valuep = (void *)((unsigned long)jtag + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(dbgstat):
+ case mmr_offset(dspid):
+ value = *valuep;
+ break;
+ default:
+ while (1) /* Core MMRs -> exception -> doesn't return. */
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ dv_store_4 (dest, value);
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_jtag_regs (struct hw *me, struct bfin_jtag *jtag)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_COREMMR_JTAG_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_JTAG_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ jtag->base = attach_address;
+}
+
+static void
+bfin_jtag_finish (struct hw *me)
+{
+ struct bfin_jtag *jtag;
+
+ jtag = HW_ZALLOC (me, struct bfin_jtag);
+
+ set_hw_data (me, jtag);
+ set_hw_io_read_buffer (me, bfin_jtag_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_jtag_io_write_buffer);
+
+ attach_bfin_jtag_regs (me, jtag);
+
+ /* Initialize the JTAG state. */
+ jtag->dspid = bfin_model_get_dspid (hw_system (me));
+}
+
+const struct hw_descriptor dv_bfin_jtag_descriptor[] = {
+ {"bfin_jtag", bfin_jtag_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_jtag.h b/sim/bfin/dv-bfin_jtag.h
new file mode 100644
index 00000000000..65c1d3be577
--- /dev/null
+++ b/sim/bfin/dv-bfin_jtag.h
@@ -0,0 +1,27 @@
+/* Blackfin JTAG model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_JTAG_H
+#define DV_BFIN_JTAG_H
+
+#define BFIN_COREMMR_JTAG_BASE 0xFFE05000
+#define BFIN_COREMMR_JTAG_SIZE (4 * 3)
+
+#endif
diff --git a/sim/bfin/dv-bfin_mmu.c b/sim/bfin/dv-bfin_mmu.c
new file mode 100644
index 00000000000..9f27636c76a
--- /dev/null
+++ b/sim/bfin/dv-bfin_mmu.c
@@ -0,0 +1,574 @@
+/* Blackfin Memory Management Unit (MMU) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "sim-options.h"
+#include "devices.h"
+#include "dv-bfin_mmu.h"
+#include "dv-bfin_cec.h"
+
+/* XXX: Should this really be two blocks of registers ? PRM describes
+ these as two Content Addressable Memory (CAM) blocks. */
+
+struct bfin_mmu
+{
+ bu32 base;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 sram_base_address;
+
+ bu32 dmem_control, dcplb_fault_status, dcplb_fault_addr;
+ char _dpad0[0x100 - 0x0 - (4 * 4)];
+ bu32 dcplb_addr[16];
+ char _dpad1[0x200 - 0x100 - (4 * 16)];
+ bu32 dcplb_data[16];
+ char _dpad2[0x300 - 0x200 - (4 * 16)];
+ bu32 dtest_command;
+ char _dpad3[0x400 - 0x300 - (4 * 1)];
+ bu32 dtest_data[2];
+
+ char _dpad4[0x1000 - 0x400 - (4 * 2)];
+
+ bu32 idk; /* Filler MMR; hardware simply ignores. */
+ bu32 imem_control, icplb_fault_status, icplb_fault_addr;
+ char _ipad0[0x100 - 0x0 - (4 * 4)];
+ bu32 icplb_addr[16];
+ char _ipad1[0x200 - 0x100 - (4 * 16)];
+ bu32 icplb_data[16];
+ char _ipad2[0x300 - 0x200 - (4 * 16)];
+ bu32 itest_command;
+ char _ipad3[0x400 - 0x300 - (4 * 1)];
+ bu32 itest_data[2];
+};
+#define mmr_base() offsetof(struct bfin_mmu, sram_base_address)
+#define mmr_offset(mmr) (offsetof(struct bfin_mmu, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const mmr_names[BFIN_COREMMR_MMU_SIZE / 4] = {
+ "SRAM_BASE_ADDRESS", "DMEM_CONTROL", "DCPLB_FAULT_STATUS", "DCPLB_FAULT_ADDR",
+ [mmr_idx (dcplb_addr[0])] = "DCPLB_ADDR0",
+ "DCPLB_ADDR1", "DCPLB_ADDR2", "DCPLB_ADDR3", "DCPLB_ADDR4", "DCPLB_ADDR5",
+ "DCPLB_ADDR6", "DCPLB_ADDR7", "DCPLB_ADDR8", "DCPLB_ADDR9", "DCPLB_ADDR10",
+ "DCPLB_ADDR11", "DCPLB_ADDR12", "DCPLB_ADDR13", "DCPLB_ADDR14", "DCPLB_ADDR15",
+ [mmr_idx (dcplb_data[0])] = "DCPLB_DATA0",
+ "DCPLB_DATA1", "DCPLB_DATA2", "DCPLB_DATA3", "DCPLB_DATA4", "DCPLB_DATA5",
+ "DCPLB_DATA6", "DCPLB_DATA7", "DCPLB_DATA8", "DCPLB_DATA9", "DCPLB_DATA10",
+ "DCPLB_DATA11", "DCPLB_DATA12", "DCPLB_DATA13", "DCPLB_DATA14", "DCPLB_DATA15",
+ [mmr_idx (dtest_command)] = "DTEST_COMMAND",
+ [mmr_idx (dtest_data[0])] = "DTEST_DATA0", "DTEST_DATA1",
+ [mmr_idx (imem_control)] = "IMEM_CONTROL", "ICPLB_FAULT_STATUS", "ICPLB_FAULT_ADDR",
+ [mmr_idx (icplb_addr[0])] = "ICPLB_ADDR0",
+ "ICPLB_ADDR1", "ICPLB_ADDR2", "ICPLB_ADDR3", "ICPLB_ADDR4", "ICPLB_ADDR5",
+ "ICPLB_ADDR6", "ICPLB_ADDR7", "ICPLB_ADDR8", "ICPLB_ADDR9", "ICPLB_ADDR10",
+ "ICPLB_ADDR11", "ICPLB_ADDR12", "ICPLB_ADDR13", "ICPLB_ADDR14", "ICPLB_ADDR15",
+ [mmr_idx (icplb_data[0])] = "ICPLB_DATA0",
+ "ICPLB_DATA1", "ICPLB_DATA2", "ICPLB_DATA3", "ICPLB_DATA4", "ICPLB_DATA5",
+ "ICPLB_DATA6", "ICPLB_DATA7", "ICPLB_DATA8", "ICPLB_DATA9", "ICPLB_DATA10",
+ "ICPLB_DATA11", "ICPLB_DATA12", "ICPLB_DATA13", "ICPLB_DATA14", "ICPLB_DATA15",
+ [mmr_idx (itest_command)] = "ITEST_COMMAND",
+ [mmr_idx (itest_data[0])] = "ITEST_DATA0", "ITEST_DATA1",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static bool bfin_mmu_skip_cplbs = false;
+
+static unsigned
+bfin_mmu_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_mmu *mmu = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu32 *valuep;
+
+ value = dv_load_4 (source);
+
+ mmr_off = addr - mmu->base;
+ valuep = (void *)((unsigned long)mmu + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(dmem_control):
+ case mmr_offset(imem_control):
+ /* XXX: IMC/DMC bit should add/remove L1 cache regions ... */
+ case mmr_offset(dtest_data[0]) ... mmr_offset(dtest_data[1]):
+ case mmr_offset(itest_data[0]) ... mmr_offset(itest_data[1]):
+ case mmr_offset(dcplb_addr[0]) ... mmr_offset(dcplb_addr[15]):
+ case mmr_offset(dcplb_data[0]) ... mmr_offset(dcplb_data[15]):
+ case mmr_offset(icplb_addr[0]) ... mmr_offset(icplb_addr[15]):
+ case mmr_offset(icplb_data[0]) ... mmr_offset(icplb_data[15]):
+ *valuep = value;
+ break;
+ case mmr_offset(sram_base_address):
+ case mmr_offset(dcplb_fault_status):
+ case mmr_offset(dcplb_fault_addr):
+ case mmr_offset(idk):
+ case mmr_offset(icplb_fault_status):
+ case mmr_offset(icplb_fault_addr):
+ /* Discard writes to these. */
+ break;
+ case mmr_offset(itest_command):
+ /* XXX: Not supported atm. */
+ if (value)
+ hw_abort (me, "ITEST_COMMAND unimplemented");
+ break;
+ case mmr_offset(dtest_command):
+ /* Access L1 memory indirectly. */
+ *valuep = value;
+ if (value)
+ {
+ bu32 addr = mmu->sram_base_address |
+ ((value >> (26 - 11)) & (1 << 11)) | /* addr bit 11 (Way0/Way1) */
+ ((value >> (24 - 21)) & (1 << 21)) | /* addr bit 21 (Data/Inst) */
+ ((value >> (23 - 15)) & (1 << 15)) | /* addr bit 15 (Data Bank) */
+ ((value >> (16 - 12)) & (3 << 12)) | /* addr bits 13:12 (Subbank) */
+ (value & 0x47F8); /* addr bits 14 & 10:3 */
+
+ if (!(value & TEST_DATA_ARRAY))
+ hw_abort (me, "DTEST_COMMAND tag array unimplemented");
+ if (value & 0xfa7cb801)
+ hw_abort (me, "DTEST_COMMAND bits undefined");
+
+ if (value & TEST_WRITE)
+ sim_write (hw_system (me), addr, (void *)mmu->dtest_data, 8);
+ else
+ sim_read (hw_system (me), addr, (void *)mmu->dtest_data, 8);
+ }
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_mmu_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_mmu *mmu = hw_data (me);
+ bu32 mmr_off;
+ bu32 *valuep;
+
+ mmr_off = addr - mmu->base;
+ valuep = (void *)((unsigned long)mmu + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(dmem_control):
+ case mmr_offset(imem_control):
+ case mmr_offset(dtest_command):
+ case mmr_offset(dtest_data[0]) ... mmr_offset(dtest_data[2]):
+ case mmr_offset(itest_command):
+ case mmr_offset(itest_data[0]) ... mmr_offset(itest_data[2]):
+ /* XXX: should do something here. */
+ case mmr_offset(dcplb_addr[0]) ... mmr_offset(dcplb_addr[15]):
+ case mmr_offset(dcplb_data[0]) ... mmr_offset(dcplb_data[15]):
+ case mmr_offset(icplb_addr[0]) ... mmr_offset(icplb_addr[15]):
+ case mmr_offset(icplb_data[0]) ... mmr_offset(icplb_data[15]):
+ case mmr_offset(sram_base_address):
+ case mmr_offset(dcplb_fault_status):
+ case mmr_offset(dcplb_fault_addr):
+ case mmr_offset(idk):
+ case mmr_offset(icplb_fault_status):
+ case mmr_offset(icplb_fault_addr):
+ dv_store_4 (dest, *valuep);
+ break;
+ default:
+ while (1) /* Core MMRs -> exception -> doesn't return. */
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_mmu_regs (struct hw *me, struct bfin_mmu *mmu)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_COREMMR_MMU_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_MMU_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ mmu->base = attach_address;
+}
+
+static void
+bfin_mmu_finish (struct hw *me)
+{
+ struct bfin_mmu *mmu;
+
+ mmu = HW_ZALLOC (me, struct bfin_mmu);
+
+ set_hw_data (me, mmu);
+ set_hw_io_read_buffer (me, bfin_mmu_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_mmu_io_write_buffer);
+
+ attach_bfin_mmu_regs (me, mmu);
+
+ /* Initialize the MMU. */
+ mmu->sram_base_address = 0xff800000 - 0;
+ /*(4 * 1024 * 1024 * CPU_INDEX (hw_system_cpu (me)));*/
+ mmu->dmem_control = 0x00000001;
+ mmu->imem_control = 0x00000001;
+}
+
+const struct hw_descriptor dv_bfin_mmu_descriptor[] = {
+ {"bfin_mmu", bfin_mmu_finish,},
+ {NULL, NULL},
+};
+
+/* Device option parsing. */
+
+static DECLARE_OPTION_HANDLER (bfin_mmu_option_handler);
+
+enum {
+ OPTION_MMU_SKIP_TABLES = OPTION_START,
+};
+
+const OPTION bfin_mmu_options[] =
+{
+ { {"mmu-skip-cplbs", no_argument, NULL, OPTION_MMU_SKIP_TABLES },
+ '\0', NULL, "Skip parsing of CPLB tables (big speed increase)",
+ bfin_mmu_option_handler, NULL },
+
+ { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
+};
+
+static SIM_RC
+bfin_mmu_option_handler (SIM_DESC sd, sim_cpu *current_cpu, int opt,
+ char *arg, int is_command)
+{
+ switch (opt)
+ {
+ case OPTION_MMU_SKIP_TABLES:
+ bfin_mmu_skip_cplbs = true;
+ return SIM_RC_OK;
+
+ default:
+ sim_io_eprintf (sd, "Unknown Blackfin MMU option %d\n", opt);
+ return SIM_RC_FAIL;
+ }
+}
+
+#define MMU_STATE(cpu) DV_STATE_CACHED (cpu, mmu)
+
+static void
+_mmu_log_ifault (SIM_CPU *cpu, struct bfin_mmu *mmu, bu32 pc, bool supv)
+{
+ mmu->icplb_fault_addr = pc;
+ mmu->icplb_fault_status = supv << 17;
+}
+
+void
+mmu_log_ifault (SIM_CPU *cpu)
+{
+ _mmu_log_ifault (cpu, MMU_STATE (cpu), PCREG, cec_get_ivg (cpu) >= 0);
+}
+
+static void
+_mmu_log_fault (SIM_CPU *cpu, struct bfin_mmu *mmu, bu32 addr, bool write,
+ bool inst, bool miss, bool supv, bool dag1, bu32 faults)
+{
+ bu32 *fault_status, *fault_addr;
+
+ /* No logging in non-OS mode. */
+ if (!mmu)
+ return;
+
+ fault_status = inst ? &mmu->icplb_fault_status : &mmu->dcplb_fault_status;
+ fault_addr = inst ? &mmu->icplb_fault_addr : &mmu->dcplb_fault_addr;
+ /* ICPLB regs always get updated. */
+ if (!inst)
+ _mmu_log_ifault (cpu, mmu, PCREG, supv);
+
+ *fault_addr = addr;
+ *fault_status =
+ (miss << 19) |
+ (dag1 << 18) |
+ (supv << 17) |
+ (write << 16) |
+ faults;
+}
+
+static void
+_mmu_process_fault (SIM_CPU *cpu, struct bfin_mmu *mmu, bu32 addr, bool write,
+ bool inst, bool unaligned, bool miss, bool supv, bool dag1)
+{
+ int excp;
+
+ /* See order in mmu_check_addr() */
+ if (unaligned)
+ excp = inst ? VEC_MISALI_I : VEC_MISALI_D;
+ else if (addr >= BFIN_SYSTEM_MMR_BASE)
+ excp = VEC_ILL_RES;
+ else if (!mmu)
+ excp = inst ? VEC_CPLB_I_M : VEC_CPLB_M;
+ else
+ {
+ /* Misses are hardware errors. */
+ cec_hwerr (cpu, HWERR_EXTERN_ADDR);
+ return;
+ }
+
+ _mmu_log_fault (cpu, mmu, addr, write, inst, miss, supv, dag1, 0);
+ cec_exception (cpu, excp);
+}
+
+void
+mmu_process_fault (SIM_CPU *cpu, bu32 addr, bool write, bool inst,
+ bool unaligned, bool miss)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ struct bfin_mmu *mmu;
+
+ if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+ mmu = NULL;
+ else
+ mmu = MMU_STATE (cpu);
+
+ _mmu_process_fault (cpu, mmu, addr, write, inst, unaligned, miss,
+ cec_is_supervisor_mode (cpu),
+ BFIN_CPU_STATE.multi_pc == PCREG + 6);
+}
+
+/* Return values:
+ -2: no known problems
+ -1: valid
+ 0: miss
+ 1: protection violation
+ 2: multiple hits
+ 3: unaligned
+ 4: miss; hwerr */
+static int
+mmu_check_implicit_addr (SIM_CPU *cpu, bu32 addr, bool inst, int size,
+ bool supv, bool dag1)
+{
+ bool l1 = ((addr & 0xFF000000) == 0xFF000000);
+ bu32 amask = (addr & 0xFFF00000);
+
+ if (addr & (size - 1))
+ return 3;
+
+ /* MMRs may never be executable or accessed from usermode. */
+ if (addr >= BFIN_SYSTEM_MMR_BASE)
+ {
+ if (inst)
+ return 0;
+ else if (!supv || dag1)
+ return 1;
+ else
+ return -1;
+ }
+ else if (inst)
+ {
+ /* Some regions are not executable. */
+ /* XXX: Should this be in the model data ? Core B 561 ? */
+ if (l1)
+ return (amask == 0xFFA00000) ? -1 : 1;
+ }
+ else
+ {
+ /* Some regions are not readable. */
+ /* XXX: Should this be in the model data ? Core B 561 ? */
+ if (l1)
+ return (amask != 0xFFA00000) ? -1 : 4;
+ }
+
+ return -2;
+}
+
+/* Exception order per the PRM (first has highest):
+ Inst Multiple CPLB Hits
+ Inst Misaligned Access
+ Inst Protection Violation
+ Inst CPLB Miss
+ Only the alignment matters in non-OS mode though. */
+static int
+_mmu_check_addr (SIM_CPU *cpu, bu32 addr, bool write, bool inst, int size)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ struct bfin_mmu *mmu;
+ bu32 *fault_status, *fault_addr, *mem_control, *cplb_addr, *cplb_data;
+ bu32 faults;
+ bool supv, do_excp, dag1;
+ int i, hits;
+
+ supv = cec_is_supervisor_mode (cpu);
+ dag1 = (BFIN_CPU_STATE.multi_pc == PCREG + 6);
+
+ if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT || bfin_mmu_skip_cplbs)
+ {
+ int ret = mmu_check_implicit_addr (cpu, addr, inst, size, supv, dag1);
+ /* Valid hits and misses are OK in non-OS envs. */
+ if (ret < 0)
+ return 0;
+ _mmu_process_fault (cpu, NULL, addr, write, inst, (ret == 3), false, supv, dag1);
+ }
+
+ mmu = MMU_STATE (cpu);
+ fault_status = inst ? &mmu->icplb_fault_status : &mmu->dcplb_fault_status;
+ fault_addr = inst ? &mmu->icplb_fault_addr : &mmu->dcplb_fault_addr;
+ mem_control = inst ? &mmu->imem_control : &mmu->dmem_control;
+ cplb_addr = inst ? &mmu->icplb_addr[0] : &mmu->dcplb_addr[0];
+ cplb_data = inst ? &mmu->icplb_data[0] : &mmu->dcplb_data[0];
+
+ faults = 0;
+ hits = 0;
+ do_excp = false;
+
+ /* CPLBs disabled -> little to do. */
+ if (!(*mem_control & ENCPLB))
+ {
+ hits = 1;
+ goto implicit_check;
+ }
+
+ /* Check all the CPLBs first. */
+ for (i = 0; i < 16; ++i)
+ {
+ const bu32 pages[4] = { 0x400, 0x1000, 0x100000, 0x400000 };
+ bu32 addr_lo, addr_hi;
+
+ /* Skip invalid entries. */
+ if (!(cplb_data[i] & CPLB_VALID))
+ continue;
+
+ /* See if this entry covers this address. */
+ addr_lo = cplb_addr[i];
+ addr_hi = cplb_addr[i] + pages[(cplb_data[i] & PAGE_SIZE) >> 16];
+ if (addr < addr_lo || addr >= addr_hi)
+ continue;
+
+ ++hits;
+ faults |= (1 << i);
+ if (write)
+ {
+ if (!supv && !(cplb_data[i] & CPLB_USER_WR))
+ do_excp = true;
+ if (supv && !(cplb_data[i] & CPLB_SUPV_WR))
+ do_excp = true;
+ if ((cplb_data[i] & (CPLB_WT | CPLB_L1_CHBL | CPLB_DIRTY)) == CPLB_L1_CHBL)
+ do_excp = true;
+ }
+ else
+ {
+ if (!supv && !(cplb_data[i] & CPLB_USER_RD))
+ do_excp = true;
+ }
+ }
+
+ /* Handle default/implicit CPLBs. */
+ if (!do_excp && hits < 2)
+ {
+ int ihits;
+ implicit_check:
+ ihits = mmu_check_implicit_addr (cpu, addr, inst, size, supv, dag1);
+ switch (ihits)
+ {
+ /* No faults and one match -> good to go. */
+ case -1: return 0;
+ case -2:
+ if (hits == 1)
+ return 0;
+ break;
+ case 4:
+ cec_hwerr (cpu, HWERR_EXTERN_ADDR);
+ return 0;
+ default:
+ hits = ihits;
+ }
+ }
+ else
+ /* Normalize hit count so hits==2 is always multiple hit exception. */
+ hits = MIN (2, hits);
+
+ _mmu_log_fault (cpu, mmu, addr, write, inst, hits == 0, supv, dag1, faults);
+
+ if (inst)
+ {
+ int iexcps[] = { VEC_CPLB_I_M, VEC_CPLB_I_VL, VEC_CPLB_I_MHIT, VEC_MISALI_I };
+ return iexcps[hits];
+ }
+ else
+ {
+ int dexcps[] = { VEC_CPLB_M, VEC_CPLB_VL, VEC_CPLB_MHIT, VEC_MISALI_D };
+ return dexcps[hits];
+ }
+}
+
+void
+mmu_check_addr (SIM_CPU *cpu, bu32 addr, bool write, bool inst, int size)
+{
+ int excp = _mmu_check_addr (cpu, addr, write, inst, size);
+ if (excp)
+ cec_exception (cpu, excp);
+}
+
+void
+mmu_check_cache_addr (SIM_CPU *cpu, bu32 addr, bool write, bool inst)
+{
+ bu32 cacheaddr;
+ int excp;
+
+ cacheaddr = addr & ~(BFIN_L1_CACHE_BYTES - 1);
+ excp = _mmu_check_addr (cpu, cacheaddr, write, inst, BFIN_L1_CACHE_BYTES);
+ if (excp == 0)
+ return;
+
+ /* Most exceptions are ignored with cache funcs. */
+ /* XXX: Not sure if we should be ignoring CPLB misses. */
+ if (inst)
+ {
+ if (excp == VEC_CPLB_I_VL)
+ return;
+ }
+ else
+ {
+ if (excp == VEC_CPLB_VL)
+ return;
+ }
+ cec_exception (cpu, excp);
+}
diff --git a/sim/bfin/dv-bfin_mmu.h b/sim/bfin/dv-bfin_mmu.h
new file mode 100644
index 00000000000..e03a327f839
--- /dev/null
+++ b/sim/bfin/dv-bfin_mmu.h
@@ -0,0 +1,94 @@
+/* Blackfin Memory Management Unit (MMU) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_MMU_H
+#define DV_BFIN_MMU_H
+
+#define BFIN_COREMMR_MMU_BASE 0xFFE00000
+#define BFIN_COREMMR_MMU_SIZE 0x2000
+
+void mmu_check_addr (SIM_CPU *, bu32 addr, bool write, bool inst, int size);
+void mmu_check_cache_addr (SIM_CPU *, bu32 addr, bool write, bool inst);
+void mmu_process_fault (SIM_CPU *, bu32 addr, bool write, bool inst, bool unaligned, bool miss);
+void mmu_log_ifault (SIM_CPU *);
+
+/* MEM_CONTROL */
+#define ENM (1 << 0)
+#define ENCPLB (1 << 1)
+#define MC (1 << 2)
+
+#define ENDM ENM
+#define ENDCPLB ENCPLB
+#define DMC_AB_SRAM 0x0
+#define DMC_AB_CACHE 0xc
+#define DMC_ACACHE_BSRAM 0x8
+
+/* CPLB_DATA */
+#define CPLB_VALID (1 << 0)
+#define CPLB_USER_RD (1 << 2)
+#define CPLB_USER_WR (1 << 3)
+#define CPLB_USER_RW (CPLB_USER_RD | CPLB_USER_WR)
+#define CPLB_SUPV_WR (1 << 4)
+#define CPLB_L1SRAM (1 << 5)
+#define CPLB_DA0ACC (1 << 6)
+#define CPLB_DIRTY (1 << 7)
+#define CPLB_L1_CHBL (1 << 12)
+#define CPLB_WT (1 << 14)
+#define PAGE_SIZE (3 << 16)
+#define PAGE_SIZE_1K (0 << 16)
+#define PAGE_SIZE_4K (1 << 16)
+#define PAGE_SIZE_1M (2 << 16)
+#define PAGE_SIZE_4M (3 << 16)
+
+/* CPLB_STATUS */
+#define FAULT_CPLB0 (1 << 0)
+#define FAULT_CPLB1 (1 << 1)
+#define FAULT_CPLB2 (1 << 2)
+#define FAULT_CPLB3 (1 << 3)
+#define FAULT_CPLB4 (1 << 4)
+#define FAULT_CPLB5 (1 << 5)
+#define FAULT_CPLB6 (1 << 6)
+#define FAULT_CPLB7 (1 << 7)
+#define FAULT_CPLB8 (1 << 8)
+#define FAULT_CPLB9 (1 << 9)
+#define FAULT_CPLB10 (1 << 10)
+#define FAULT_CPLB11 (1 << 11)
+#define FAULT_CPLB12 (1 << 12)
+#define FAULT_CPLB13 (1 << 13)
+#define FAULT_CPLB14 (1 << 14)
+#define FAULT_CPLB15 (1 << 15)
+#define FAULT_READ (0 << 16)
+#define FAULT_WRITE (1 << 16)
+#define FAULT_USER (0 << 17)
+#define FAULT_SUPV (1 << 17)
+#define FAULT_DAG0 (0 << 18)
+#define FAULT_DAG1 (1 << 18)
+#define FAULT_ILLADDR (1 << 19)
+
+/* DTEST_COMMAND */
+#define TEST_READ (0 << 1)
+#define TEST_WRITE (1 << 1)
+#define TEST_TAG_ARRAY (0 << 2)
+#define TEST_DATA_ARRAY (1 << 2)
+#define TEST_DBANK (1 << 23)
+#define TEST_DATA_SRAM (0 << 24)
+#define TEST_INST_SRAM (1 << 24)
+
+#endif
diff --git a/sim/bfin/dv-bfin_nfc.c b/sim/bfin/dv-bfin_nfc.c
new file mode 100644
index 00000000000..48990ee76a3
--- /dev/null
+++ b/sim/bfin/dv-bfin_nfc.c
@@ -0,0 +1,241 @@
+/* Blackfin NAND Flash Memory Controller (NFC) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_nfc.h"
+
+/* XXX: This is merely a stub. */
+
+struct bfin_nfc
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(ctl);
+ bu16 BFIN_MMR_16(stat);
+ bu16 BFIN_MMR_16(irqstat);
+ bu16 BFIN_MMR_16(irqmask);
+ bu16 BFIN_MMR_16(ecc0);
+ bu16 BFIN_MMR_16(ecc1);
+ bu16 BFIN_MMR_16(ecc2);
+ bu16 BFIN_MMR_16(ecc3);
+ bu16 BFIN_MMR_16(count);
+ bu16 BFIN_MMR_16(rst);
+ bu16 BFIN_MMR_16(pgctl);
+ bu16 BFIN_MMR_16(read);
+ bu32 _pad0[4];
+ bu16 BFIN_MMR_16(addr);
+ bu16 BFIN_MMR_16(cmd);
+ bu16 BFIN_MMR_16(data_wr);
+ bu16 BFIN_MMR_16(data_rd);
+};
+#define mmr_base() offsetof(struct bfin_nfc, ctl)
+#define mmr_offset(mmr) (offsetof(struct bfin_nfc, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const mmr_names[] = {
+ "NFC_CTL", "NFC_STAT", "NFC_IRQSTAT", "NFC_IRQMASK", "NFC_ECC0", "NFC_ECC1",
+ "NFC_ECC2", "NFC_ECC3", "NFC_COUNT", "NFC_RST", "NFC_PGCTL", "NFC_READ",
+ [mmr_idx (addr)] = "NFC_ADDR", "NFC_CMD", "NFC_DATA_WR", "NFC_DATA_RD",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static unsigned
+bfin_nfc_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_nfc *nfc = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *valuep;
+
+ value = dv_load_2 (source);
+ mmr_off = addr - nfc->base;
+ valuep = (void *)((unsigned long)nfc + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(ctl):
+ case mmr_offset(stat):
+ case mmr_offset(irqmask):
+ case mmr_offset(ecc0):
+ case mmr_offset(ecc1):
+ case mmr_offset(ecc2):
+ case mmr_offset(ecc3):
+ case mmr_offset(count):
+ case mmr_offset(rst):
+ case mmr_offset(pgctl):
+ case mmr_offset(read):
+ case mmr_offset(addr):
+ case mmr_offset(cmd):
+ case mmr_offset(data_wr):
+ *valuep = value;
+ break;
+ case mmr_offset(data_rd):
+ nfc->irqstat |= RD_RDY;
+ *valuep = value;
+ break;
+ case mmr_offset(irqstat):
+ dv_w1c_2 (valuep, value, 0);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_nfc_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_nfc *nfc = hw_data (me);
+ bu32 mmr_off;
+ bu16 *valuep;
+
+ mmr_off = addr - nfc->base;
+ valuep = (void *)((unsigned long)nfc + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(ctl):
+ case mmr_offset(stat):
+ case mmr_offset(irqstat):
+ case mmr_offset(irqmask):
+ case mmr_offset(ecc0):
+ case mmr_offset(ecc1):
+ case mmr_offset(ecc2):
+ case mmr_offset(ecc3):
+ case mmr_offset(count):
+ case mmr_offset(rst):
+ case mmr_offset(read):
+ dv_store_2 (dest, *valuep);
+ break;
+ case mmr_offset(pgctl):
+ case mmr_offset(addr):
+ case mmr_offset(cmd):
+ case mmr_offset(data_wr):
+ case mmr_offset(data_rd):
+ /* These regs are write only. */
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_nfc_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ HW_TRACE_DMA_READ ();
+ return 0;
+}
+
+static unsigned
+bfin_nfc_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ HW_TRACE_DMA_WRITE ();
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_nfc_ports[] = {
+ { "stat", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_nfc_regs (struct hw *me, struct bfin_nfc *nfc)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_NFC_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_NFC_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ nfc->base = attach_address;
+}
+
+static void
+bfin_nfc_finish (struct hw *me)
+{
+ struct bfin_nfc *nfc;
+
+ nfc = HW_ZALLOC (me, struct bfin_nfc);
+
+ set_hw_data (me, nfc);
+ set_hw_io_read_buffer (me, bfin_nfc_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_nfc_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_nfc_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_nfc_dma_write_buffer);
+ set_hw_ports (me, bfin_nfc_ports);
+
+ attach_bfin_nfc_regs (me, nfc);
+
+ /* Initialize the NFC. */
+ nfc->ctl = 0x0200;
+ nfc->stat = 0x0011;
+ nfc->irqstat = 0x0004;
+ nfc->irqmask = 0x001F;
+}
+
+const struct hw_descriptor dv_bfin_nfc_descriptor[] = {
+ {"bfin_nfc", bfin_nfc_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_nfc.h b/sim/bfin/dv-bfin_nfc.h
new file mode 100644
index 00000000000..42dbec6b43f
--- /dev/null
+++ b/sim/bfin/dv-bfin_nfc.h
@@ -0,0 +1,41 @@
+/* Blackfin NAND Flash Memory Controller (NFC) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_NFC_H
+#define DV_BFIN_NFC_H
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_NFC_SIZE 0x50
+
+/* NFC_STAT masks. */
+#define NBUSY (1 << 0)
+#define WB_FULL (1 << 1)
+#define PG_WR_STAT (1 << 2)
+#define PG_RD_STAT (1 << 3)
+#define WB_EMPTY (1 << 4)
+
+/* NFC_IRQSTAT masks. */
+#define NBUSYIRQ (1 << 0)
+#define WB_OVF (1 << 1)
+#define WB_EDGE (1 << 2)
+#define RD_RDY (1 << 3)
+#define WR_DONE (1 << 4)
+
+#endif
diff --git a/sim/bfin/dv-bfin_otp.c b/sim/bfin/dv-bfin_otp.c
new file mode 100644
index 00000000000..d30a4140435
--- /dev/null
+++ b/sim/bfin/dv-bfin_otp.c
@@ -0,0 +1,307 @@
+/* Blackfin One-Time Programmable Memory (OTP) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_otp.h"
+
+/* XXX: No public documentation on this interface. This seems to work
+ with the on-chip ROM functions though and was figured out by
+ disassembling & walking that code. */
+/* XXX: About only thing that should be done here are CRC fields. And
+ supposedly there is an interrupt that could be generated. */
+
+struct bfin_otp
+{
+ bu32 base;
+
+ /* The actual OTP storage -- 0x200 pages, each page is 128bits.
+ While certain pages have predefined and/or secure access, we don't
+ bother trying to implement that coverage. All pages are open for
+ reading & writing. */
+ bu32 mem[0x200 * 4];
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(control);
+ bu16 BFIN_MMR_16(ben);
+ bu16 BFIN_MMR_16(status);
+ bu32 timing;
+ bu32 _pad0[28];
+ bu32 data0, data1, data2, data3;
+};
+#define mmr_base() offsetof(struct bfin_otp, control)
+#define mmr_offset(mmr) (offsetof(struct bfin_otp, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const mmr_names[] = {
+ "OTP_CONTROL", "OTP_BEN", "OTP_STATUS", "OTP_TIMING",
+ [mmr_idx (data0)] = "OTP_DATA0", "OTP_DATA1", "OTP_DATA2", "OTP_DATA3",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+/* XXX: This probably misbehaves with big endian hosts. */
+static void
+bfin_otp_transfer (struct bfin_otp *otp, void *vdst, void *vsrc)
+{
+ bu8 *dst = vdst, *src = vsrc;
+ int bidx;
+ for (bidx = 0; bidx < 16; ++bidx)
+ if (otp->ben & (1 << bidx))
+ dst[bidx] = src[bidx];
+}
+
+static void
+bfin_otp_read_page (struct bfin_otp *otp, bu16 page)
+{
+ bfin_otp_transfer (otp, &otp->data0, &otp->mem[page * 4]);
+}
+
+static void
+bfin_otp_write_page_val (struct bfin_otp *otp, bu16 page, bu64 val[2])
+{
+ bfin_otp_transfer (otp, &otp->mem[page * 4], val);
+}
+static void
+bfin_otp_write_page_val2 (struct bfin_otp *otp, bu16 page, bu64 lo, bu64 hi)
+{
+ bu64 val[2] = { lo, hi };
+ bfin_otp_write_page_val (otp, page, val);
+}
+static void
+bfin_otp_write_page (struct bfin_otp *otp, bu16 page)
+{
+ bfin_otp_write_page_val (otp, page, (void *)&otp->data0);
+}
+
+static unsigned
+bfin_otp_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_otp *otp = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - otp->base;
+ valuep = (void *)((unsigned long)otp + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(control):
+ {
+ int page;
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ /* XXX: Seems like these bits aren't writable. */
+ *value16p = value & 0x39FF;
+
+ /* Low bits seem to be the page address. */
+ page = value & PAGE_ADDR;
+
+ /* Write operation. */
+ if (value & DO_WRITE)
+ bfin_otp_write_page (otp, page);
+
+ /* Read operation. */
+ if (value & DO_READ)
+ bfin_otp_read_page (otp, page);
+
+ otp->status |= STATUS_DONE;
+
+ break;
+ }
+ case mmr_offset(ben):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ /* XXX: All bits seem to be writable. */
+ *value16p = value;
+ break;
+ case mmr_offset(status):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ /* XXX: All bits seem to be W1C. */
+ dv_w1c_2 (value16p, value, 0);
+ break;
+ case mmr_offset(timing):
+ case mmr_offset(data0):
+ case mmr_offset(data1):
+ case mmr_offset(data2):
+ case mmr_offset(data3):
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, true);
+ *value32p = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_otp_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_otp *otp = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - otp->base;
+ valuep = (void *)((unsigned long)otp + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(control):
+ case mmr_offset(ben):
+ case mmr_offset(status):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ break;
+ case mmr_offset(timing):
+ case mmr_offset(data0):
+ case mmr_offset(data1):
+ case mmr_offset(data2):
+ case mmr_offset(data3):
+ dv_bfin_mmr_require_32 (me, addr, nr_bytes, false);
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_otp_regs (struct hw *me, struct bfin_otp *otp)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_OTP_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_OTP_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ otp->base = attach_address;
+}
+
+static void
+bfin_otp_finish (struct hw *me)
+{
+ char part_str[16];
+ struct bfin_otp *otp;
+ unsigned int fps03;
+ int type = hw_find_integer_property (me, "type");
+
+ otp = HW_ZALLOC (me, struct bfin_otp);
+
+ set_hw_data (me, otp);
+ set_hw_io_read_buffer (me, bfin_otp_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_otp_io_write_buffer);
+
+ attach_bfin_otp_regs (me, otp);
+
+ /* Initialize the OTP. */
+ otp->ben = 0xFFFF;
+ otp->timing = 0x00001485;
+
+ /* Semi-random value for unique chip id. */
+ bfin_otp_write_page_val2 (otp, FPS00, (unsigned long)otp, ~(unsigned long)otp);
+
+ memset (part_str, 0, sizeof (part_str));
+ sprintf (part_str, "ADSP-BF%iX", type);
+ switch (type)
+ {
+ case 512:
+ fps03 = FPS03_BF512;
+ break;
+ case 514:
+ fps03 = FPS03_BF514;
+ break;
+ case 516:
+ fps03 = FPS03_BF516;
+ break;
+ case 518:
+ fps03 = FPS03_BF518;
+ break;
+ case 522:
+ fps03 = FPS03_BF522;
+ break;
+ case 523:
+ fps03 = FPS03_BF523;
+ break;
+ case 524:
+ fps03 = FPS03_BF524;
+ break;
+ case 525:
+ fps03 = FPS03_BF525;
+ break;
+ case 526:
+ fps03 = FPS03_BF526;
+ break;
+ case 527:
+ fps03 = FPS03_BF527;
+ break;
+ default:
+ fps03 = 0;
+ break;
+ }
+ part_str[14] = (fps03 >> 0);
+ part_str[15] = (fps03 >> 8);
+ bfin_otp_write_page_val (otp, FPS03, (void *)part_str);
+}
+
+const struct hw_descriptor dv_bfin_otp_descriptor[] = {
+ {"bfin_otp", bfin_otp_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_otp.h b/sim/bfin/dv-bfin_otp.h
new file mode 100644
index 00000000000..bbb49ce4211
--- /dev/null
+++ b/sim/bfin/dv-bfin_otp.h
@@ -0,0 +1,100 @@
+/* Blackfin One-Time Programmable Memory (OTP) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_OTP_H
+#define DV_BFIN_OTP_H
+
+/* XXX: This should be pushed into the model data. */
+/* XXX: Not exactly true; it's two sets of 4 regs near each other:
+ 0xFFC03600 0x10 - Control
+ 0xFFC03680 0x10 - Data */
+#define BFIN_MMR_OTP_SIZE 0xa0
+
+/* OTP Defined Pages. */
+#define FPS00 0x004
+#define FPS01 0x005
+#define FPS02 0x006
+#define FPS03 0x007
+#define FPS04 0x008
+#define FPS05 0x009
+#define FPS06 0x00A
+#define FPS07 0x00B
+#define FPS08 0x00C
+#define FPS09 0x00D
+#define FPS10 0x00E
+#define FPS11 0x00F
+#define CPS00 0x010
+#define CPS01 0x011
+#define CPS02 0x012
+#define CPS03 0x013
+#define CPS04 0x014
+#define CPS05 0x015
+#define CPS06 0x016
+#define CPS07 0x017
+#define PBS00 0x018
+#define PBS01 0x019
+#define PBS02 0x01A
+#define PBS03 0x01B
+#define PUB000 0x01C
+#define PUBCRC000 0x0E0
+#define PRIV000 0x110
+#define PRIVCRC000 0x1E0
+
+/* FPS03 Part values. */
+#define FPS03_BF51XF(n) (FPS03_BF##n | 0xF000)
+#define FPS03_BF512 0x0200
+#define FPS03_BF512F FPS03_BF51XF(512)
+#define FPS03_BF514 0x0202
+#define FPS03_BF514F FPS03_BF51XF(514)
+#define FPS03_BF516 0x0204
+#define FPS03_BF516F FPS03_BF51XF(516)
+#define FPS03_BF518 0x0206
+#define FPS03_BF518F FPS03_BF51XF(518)
+#define FPS03_BF52X_C1(n) (FPS03_BF##n | 0x8000)
+#define FPS03_BF52X_C2(n) (FPS03_BF##n | 0x4000)
+#define FPS03_BF522 0x020A
+#define FPS03_BF522_C1 FPS03_BF52X_C1(522)
+#define FPS03_BF522_C2 FPS03_BF52X_C2(522)
+#define FPS03_BF523 0x020B
+#define FPS03_BF523_C1 FPS03_BF52X_C1(523)
+#define FPS03_BF523_C2 FPS03_BF52X_C2(523)
+#define FPS03_BF524 0x020C
+#define FPS03_BF524_C1 FPS03_BF52X_C1(524)
+#define FPS03_BF524_C2 FPS03_BF52X_C2(524)
+#define FPS03_BF525 0x020D
+#define FPS03_BF525_C1 FPS03_BF52X_C1(525)
+#define FPS03_BF525_C2 FPS03_BF52X_C2(525)
+#define FPS03_BF526 0x020E
+#define FPS03_BF526_C1 FPS03_BF52X_C1(526)
+#define FPS03_BF526_C2 FPS03_BF52X_C2(526)
+#define FPS03_BF527 0x020F
+#define FPS03_BF527_C1 FPS03_BF52X_C1(527)
+#define FPS03_BF527_C2 FPS03_BF52X_C2(527)
+
+/* OTP_CONTROL masks. */
+#define PAGE_ADDR (0x1FF)
+#define DO_READ (1 << 14)
+#define DO_WRITE (1 << 15)
+
+/* OTP_STATUS masks. */
+#define STATUS_DONE (1 << 0)
+#define STATUS_ERR (1 << 1)
+
+#endif
diff --git a/sim/bfin/dv-bfin_pll.c b/sim/bfin/dv-bfin_pll.c
new file mode 100644
index 00000000000..b6e110a7ee5
--- /dev/null
+++ b/sim/bfin/dv-bfin_pll.c
@@ -0,0 +1,187 @@
+/* Blackfin Phase Lock Loop (PLL) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "machs.h"
+#include "devices.h"
+#include "dv-bfin_pll.h"
+
+struct bfin_pll
+{
+ bu32 base;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(pll_ctl);
+ bu16 BFIN_MMR_16(pll_div);
+ bu16 BFIN_MMR_16(vr_ctl);
+ bu16 BFIN_MMR_16(pll_stat);
+ bu16 BFIN_MMR_16(pll_lockcnt);
+
+ /* XXX: Not really the best place for this ... */
+ bu32 chipid;
+};
+#define mmr_base() offsetof(struct bfin_pll, pll_ctl)
+#define mmr_offset(mmr) (offsetof(struct bfin_pll, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "PLL_CTL", "PLL_DIV", "VR_CTL", "PLL_STAT", "PLL_LOCKCNT", "CHIPID",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static unsigned
+bfin_pll_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_pll *pll = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - pll->base;
+ valuep = (void *)((unsigned long)pll + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(pll_stat):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ case mmr_offset(chipid):
+ /* Discard writes. */
+ break;
+ default:
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+ *value16p = value;
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_pll_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_pll *pll = hw_data (me);
+ bu32 mmr_off;
+ bu32 *value32p;
+ bu16 *value16p;
+ void *valuep;
+
+ mmr_off = addr - pll->base;
+ valuep = (void *)((unsigned long)pll + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(chipid):
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_pll_ports[] = {
+ { "pll", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_pll_regs (struct hw *me, struct bfin_pll *pll)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_PLL_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_PLL_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ pll->base = attach_address;
+}
+
+static void
+bfin_pll_finish (struct hw *me)
+{
+ struct bfin_pll *pll;
+
+ pll = HW_ZALLOC (me, struct bfin_pll);
+
+ set_hw_data (me, pll);
+ set_hw_io_read_buffer (me, bfin_pll_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_pll_io_write_buffer);
+ set_hw_ports (me, bfin_pll_ports);
+
+ attach_bfin_pll_regs (me, pll);
+
+ /* Initialize the PLL. */
+ /* XXX: Depends on part ? */
+ pll->pll_ctl = 0x1400;
+ pll->pll_div = 0x0005;
+ pll->vr_ctl = 0x40DB;
+ pll->pll_stat = 0x00A2;
+ pll->pll_lockcnt = 0x0200;
+ pll->chipid = bfin_model_get_chipid (hw_system (me));
+
+ /* XXX: slow it down! */
+ pll->pll_ctl = 0xa800;
+ pll->pll_div = 0x4;
+ pll->vr_ctl = 0x40fb;
+ pll->pll_stat = 0xa2;
+ pll->pll_lockcnt = 0x300;
+}
+
+const struct hw_descriptor dv_bfin_pll_descriptor[] = {
+ {"bfin_pll", bfin_pll_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_pll.h b/sim/bfin/dv-bfin_pll.h
new file mode 100644
index 00000000000..b63104a6f3f
--- /dev/null
+++ b/sim/bfin/dv-bfin_pll.h
@@ -0,0 +1,27 @@
+/* Blackfin Phase Lock Loop (PLL) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_PLL_H
+#define DV_BFIN_PLL_H
+
+#define BFIN_MMR_PLL_BASE 0xFFC00000
+#define BFIN_MMR_PLL_SIZE (4 * 6)
+
+#endif
diff --git a/sim/bfin/dv-bfin_ppi.c b/sim/bfin/dv-bfin_ppi.c
new file mode 100644
index 00000000000..fc72b947b39
--- /dev/null
+++ b/sim/bfin/dv-bfin_ppi.c
@@ -0,0 +1,231 @@
+/* Blackfin Parallel Port Interface (PPI) model
+ For "old style" PPIs on BF53x/etc... parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_ppi.h"
+#include "gui.h"
+
+/* XXX: TX is merely a stub. */
+
+struct bfin_ppi
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ /* GUI state. */
+ void *gui_state;
+ int color;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(control);
+ bu16 BFIN_MMR_16(status);
+ bu16 BFIN_MMR_16(count);
+ bu16 BFIN_MMR_16(delay);
+ bu16 BFIN_MMR_16(frame);
+};
+#define mmr_base() offsetof(struct bfin_ppi, control)
+#define mmr_offset(mmr) (offsetof(struct bfin_ppi, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "PPI_CONTROL", "PPI_STATUS", "PPI_COUNT", "PPI_DELAY", "PPI_FRAME",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static void
+bfin_ppi_gui_setup (struct bfin_ppi *ppi)
+{
+ int bpp;
+
+ /* If we are in RX mode, nothing to do. */
+ if (!(ppi->control & PORT_DIR))
+ return;
+
+ bpp = bfin_gui_color_depth (ppi->color);
+ ppi->gui_state = bfin_gui_setup (ppi->gui_state,
+ ppi->control & PORT_EN,
+ (ppi->count + 1) / (bpp / 8),
+ ppi->frame,
+ ppi->color);
+}
+
+static unsigned
+bfin_ppi_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ppi *ppi = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *valuep;
+
+ value = dv_load_2 (source);
+ mmr_off = addr - ppi->base;
+ valuep = (void *)((unsigned long)ppi + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(control):
+ *valuep = value;
+ bfin_ppi_gui_setup (ppi);
+ break;
+ case mmr_offset(count):
+ case mmr_offset(delay):
+ case mmr_offset(frame):
+ *valuep = value;
+ break;
+ case mmr_offset(status):
+ dv_w1c_2 (valuep, value, (1 << 10));
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_ppi_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_ppi *ppi = hw_data (me);
+ bu32 mmr_off;
+ bu16 *valuep;
+
+ mmr_off = addr - ppi->base;
+ valuep = (void *)((unsigned long)ppi + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(control):
+ case mmr_offset(count):
+ case mmr_offset(delay):
+ case mmr_offset(frame):
+ case mmr_offset(status):
+ dv_store_2 (dest, *valuep);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_ppi_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ HW_TRACE_DMA_READ ();
+ return 0;
+}
+
+static unsigned
+bfin_ppi_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ struct bfin_ppi *ppi = hw_data (me);
+
+ HW_TRACE_DMA_WRITE ();
+
+ return bfin_gui_update (ppi->gui_state, source, nr_bytes);
+}
+
+static const struct hw_port_descriptor bfin_ppi_ports[] = {
+ { "stat", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_ppi_regs (struct hw *me, struct bfin_ppi *ppi)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_PPI_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_PPI_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ ppi->base = attach_address;
+}
+
+static void
+bfin_ppi_finish (struct hw *me)
+{
+ struct bfin_ppi *ppi;
+ const char *color;
+
+ ppi = HW_ZALLOC (me, struct bfin_ppi);
+
+ set_hw_data (me, ppi);
+ set_hw_io_read_buffer (me, bfin_ppi_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_ppi_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_ppi_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_ppi_dma_write_buffer);
+ set_hw_ports (me, bfin_ppi_ports);
+
+ attach_bfin_ppi_regs (me, ppi);
+
+ /* Initialize the PPI. */
+ if (hw_find_property (me, "color"))
+ color = hw_find_string_property (me, "color");
+ else
+ color = NULL;
+ ppi->color = bfin_gui_color (color);
+}
+
+const struct hw_descriptor dv_bfin_ppi_descriptor[] = {
+ {"bfin_ppi", bfin_ppi_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_ppi.h b/sim/bfin/dv-bfin_ppi.h
new file mode 100644
index 00000000000..24e8fd9eb35
--- /dev/null
+++ b/sim/bfin/dv-bfin_ppi.h
@@ -0,0 +1,32 @@
+/* Blackfin Parallel Port Interface (PPI) model
+ For "old style" PPIs on BF53x/etc... parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_PPI_H
+#define DV_BFIN_PPI_H
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_PPI_SIZE (4 * 5)
+
+/* PPI_CONTROL Masks. */
+#define PORT_EN (1 << 0)
+#define PORT_DIR (1 << 1)
+
+#endif
diff --git a/sim/bfin/dv-bfin_rtc.c b/sim/bfin/dv-bfin_rtc.c
new file mode 100644
index 00000000000..6d8aa3d5a4e
--- /dev/null
+++ b/sim/bfin/dv-bfin_rtc.c
@@ -0,0 +1,194 @@
+/* Blackfin Real Time Clock (RTC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include <time.h>
+#include "sim-main.h"
+#include "dv-sockser.h"
+#include "devices.h"
+#include "dv-bfin_rtc.h"
+
+/* XXX: This read-only stub setup is based on host system clock. */
+
+struct bfin_rtc
+{
+ bu32 base;
+ bu32 stat_shadow;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 stat;
+ bu16 BFIN_MMR_16(ictl);
+ bu16 BFIN_MMR_16(istat);
+ bu16 BFIN_MMR_16(swcnt);
+ bu32 alarm;
+ bu16 BFIN_MMR_16(pren);
+};
+#define mmr_base() offsetof(struct bfin_rtc, stat)
+#define mmr_offset(mmr) (offsetof(struct bfin_rtc, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "RTC_STAT", "RTC_ICTL", "RTC_ISTAT", "RTC_SWCNT", "RTC_ALARM", "RTC_PREN",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static unsigned
+bfin_rtc_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_rtc *rtc = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - rtc->base;
+ valuep = (void *)((unsigned long)rtc + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ /* XXX: These probably need more work. */
+ switch (mmr_off)
+ {
+ case mmr_offset(stat):
+ /* XXX: Ignore these since we are wired to host. */
+ break;
+ case mmr_offset(istat):
+ dv_w1c_2 (value16p, value, 1 << 14);
+ break;
+ case mmr_offset(alarm):
+ break;
+ case mmr_offset(ictl):
+ /* XXX: This should schedule an event handler. */
+ case mmr_offset(swcnt):
+ case mmr_offset(pren):
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_rtc_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_rtc *rtc = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - rtc->base;
+ valuep = (void *)((unsigned long)rtc + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(stat):
+ {
+ time_t t = time (NULL);
+ struct tm *tm = localtime (&t);
+ bu32 value =
+ (((tm->tm_year - 70) * 365 + tm->tm_yday) << 17) |
+ (tm->tm_hour << 12) |
+ (tm->tm_min << 6) |
+ (tm->tm_sec << 0);
+ dv_store_4 (dest, value);
+ break;
+ }
+ case mmr_offset(alarm):
+ dv_store_4 (dest, *value32p);
+ break;
+ case mmr_offset(istat):
+ case mmr_offset(ictl):
+ case mmr_offset(swcnt):
+ case mmr_offset(pren):
+ dv_store_2 (dest, *value16p);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_rtc_ports[] = {
+ { "rtc", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_rtc_regs (struct hw *me, struct bfin_rtc *rtc)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_RTC_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_RTC_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ rtc->base = attach_address;
+}
+
+static void
+bfin_rtc_finish (struct hw *me)
+{
+ struct bfin_rtc *rtc;
+
+ rtc = HW_ZALLOC (me, struct bfin_rtc);
+
+ set_hw_data (me, rtc);
+ set_hw_io_read_buffer (me, bfin_rtc_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_rtc_io_write_buffer);
+ set_hw_ports (me, bfin_rtc_ports);
+
+ attach_bfin_rtc_regs (me, rtc);
+
+ /* Initialize the RTC. */
+}
+
+const struct hw_descriptor dv_bfin_rtc_descriptor[] = {
+ {"bfin_rtc", bfin_rtc_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_rtc.h b/sim/bfin/dv-bfin_rtc.h
new file mode 100644
index 00000000000..04ffde14496
--- /dev/null
+++ b/sim/bfin/dv-bfin_rtc.h
@@ -0,0 +1,26 @@
+/* Blackfin Real Time Clock (RTC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_RTC_H
+#define DV_BFIN_RTC_H
+
+#define BFIN_MMR_RTC_SIZE (4 * 6)
+
+#endif
diff --git a/sim/bfin/dv-bfin_sic.c b/sim/bfin/dv-bfin_sic.c
new file mode 100644
index 00000000000..0cc2e407e1b
--- /dev/null
+++ b/sim/bfin/dv-bfin_sic.c
@@ -0,0 +1,1439 @@
+/* Blackfin System Interrupt Controller (SIC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_sic.h"
+#include "dv-bfin_cec.h"
+
+struct bfin_sic
+{
+ /* We assume first element is the base. */
+ bu32 base;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(swrst);
+ bu16 BFIN_MMR_16(syscr);
+ bu16 BFIN_MMR_16(rvect); /* XXX: BF59x has a 32bit AUX_REVID here. */
+ union {
+ struct {
+ bu32 imask0;
+ bu32 iar0, iar1, iar2, iar3;
+ bu32 isr0, iwr0;
+ bu32 _pad0[9];
+ bu32 imask1;
+ bu32 iar4, iar5, iar6, iar7;
+ bu32 isr1, iwr1;
+ } bf52x;
+ struct {
+ bu32 imask;
+ bu32 iar0, iar1, iar2, iar3;
+ bu32 isr, iwr;
+ } bf537;
+ struct {
+ bu32 imask0, imask1, imask2;
+ bu32 isr0, isr1, isr2;
+ bu32 iwr0, iwr1, iwr2;
+ bu32 iar0, iar1, iar2, iar3;
+ bu32 iar4, iar5, iar6, iar7;
+ bu32 iar8, iar9, iar10, iar11;
+ } bf54x;
+ struct {
+ bu32 imask0, imask1;
+ bu32 iar0, iar1, iar2, iar3;
+ bu32 iar4, iar5, iar6, iar7;
+ bu32 isr0, isr1;
+ bu32 iwr0, iwr1;
+ } bf561;
+ };
+};
+#define mmr_base() offsetof(struct bfin_sic, swrst)
+#define mmr_offset(mmr) (offsetof(struct bfin_sic, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const bf52x_mmr_names[] = {
+ "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IAR0", "SIC_IAR1",
+ "SIC_IAR2", "SIC_IAR3", "SIC_ISR0", "SIC_IWR0",
+ [mmr_idx (bf52x.imask1)] = "SIC_IMASK1", "SIC_IAR4", "SIC_IAR5",
+ "SIC_IAR6", "SIC_IAR7", "SIC_ISR1", "SIC_IWR1",
+};
+static const char * const bf537_mmr_names[] = {
+ "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK", "SIC_IAR0", "SIC_IAR1",
+ "SIC_IAR2", "SIC_IAR3", "SIC_ISR", "SIC_IWR",
+};
+static const char * const bf54x_mmr_names[] = {
+ "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1", "SIC_IMASK2",
+ "SIC_ISR0", "SIC_ISR1", "SIC_ISR2", "SIC_IWR0", "SIC_IWR1", "SIC_IWR2",
+ "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
+ "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
+ "SIC_IAR8", "SIC_IAR9", "SIC_IAR10", "SIC_IAR11",
+};
+static const char * const bf561_mmr_names[] = {
+ "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK0", "SIC_IMASK1",
+ "SIC_IAR0", "SIC_IAR1", "SIC_IAR2", "SIC_IAR3",
+ "SIC_IAR4", "SIC_IAR5", "SIC_IAR6", "SIC_IAR7",
+ "SIC_ISR0", "SIC_ISR1", "SIC_IWR0", "SIC_IWR1",
+};
+static const char * const *mmr_names;
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static void
+bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
+{
+ int my_port;
+ bu32 ipend;
+
+ /* Process pending and unmasked interrupts. */
+ ipend = *isr & *imask;
+
+ /* Usually none are pending unmasked, so avoid bit twiddling. */
+ if (!ipend)
+ return;
+
+ for (my_port = 0; my_port < 32; ++my_port)
+ {
+ bu32 iar_idx, iar_off, iar_val;
+ bu32 bit = (1 << my_port);
+
+ /* This bit isn't pending, so check next one. */
+ if (!(ipend & bit))
+ continue;
+
+ /* The IAR registers map the System input to the Core output.
+ Every 4 bits in the IAR are used to map to IVG{7..15}. */
+ iar_idx = my_port / 8;
+ iar_off = (my_port % 8) * 4;
+ iar_val = (iar[iar_idx] & (0xf << iar_off)) >> iar_off;
+ hw_port_event (me, IVG7 + iar_val, 1);
+ }
+}
+
+static void
+bfin_sic_52x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
+{
+ bfin_sic_forward_interrupts (me, &sic->bf52x.isr0, &sic->bf52x.imask0, &sic->bf52x.iar0);
+ bfin_sic_forward_interrupts (me, &sic->bf52x.isr1, &sic->bf52x.imask1, &sic->bf52x.iar4);
+}
+
+static unsigned
+bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ /* XXX: Discard all SIC writes for now. */
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ /* XXX: This should trigger a software reset ... */
+ break;
+ case mmr_offset(syscr):
+ /* XXX: what to do ... */
+ break;
+ case mmr_offset(bf52x.imask0):
+ case mmr_offset(bf52x.imask1):
+ bfin_sic_52x_forward_interrupts (me, sic);
+ *value32p = value;
+ break;
+ case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
+ case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
+ case mmr_offset(bf52x.iwr0):
+ case mmr_offset(bf52x.iwr1):
+ *value32p = value;
+ break;
+ case mmr_offset(bf52x.isr0):
+ case mmr_offset(bf52x.isr1):
+ /* ISR is read-only. */
+ break;
+ default:
+ /* XXX: Should discard other writes. */
+ ;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_sic_52x_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ case mmr_offset(syscr):
+ case mmr_offset(rvect):
+ dv_store_2 (dest, *value16p);
+ break;
+ case mmr_offset(bf52x.imask0):
+ case mmr_offset(bf52x.imask1):
+ case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
+ case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
+ case mmr_offset(bf52x.iwr0):
+ case mmr_offset(bf52x.iwr1):
+ case mmr_offset(bf52x.isr0):
+ case mmr_offset(bf52x.isr1):
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ if (nr_bytes == 2)
+ dv_store_2 (dest, 0);
+ else
+ dv_store_4 (dest, 0);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+bfin_sic_537_forward_interrupts (struct hw *me, struct bfin_sic *sic)
+{
+ bfin_sic_forward_interrupts (me, &sic->bf537.isr, &sic->bf537.imask, &sic->bf537.iar0);
+}
+
+static unsigned
+bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ /* XXX: Discard all SIC writes for now. */
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ /* XXX: This should trigger a software reset ... */
+ break;
+ case mmr_offset(syscr):
+ /* XXX: what to do ... */
+ break;
+ case mmr_offset(bf537.imask):
+ bfin_sic_537_forward_interrupts (me, sic);
+ *value32p = value;
+ break;
+ case mmr_offset(bf537.iar0):
+ case mmr_offset(bf537.iar1):
+ case mmr_offset(bf537.iar2):
+ case mmr_offset(bf537.iar3):
+ case mmr_offset(bf537.iwr):
+ *value32p = value;
+ break;
+ case mmr_offset(bf537.isr):
+ /* ISR is read-only. */
+ break;
+ default:
+ /* XXX: Should discard other writes. */
+ ;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ case mmr_offset(syscr):
+ case mmr_offset(rvect):
+ dv_store_2 (dest, *value16p);
+ break;
+ case mmr_offset(bf537.imask):
+ case mmr_offset(bf537.iar0):
+ case mmr_offset(bf537.iar1):
+ case mmr_offset(bf537.iar2):
+ case mmr_offset(bf537.iar3):
+ case mmr_offset(bf537.isr):
+ case mmr_offset(bf537.iwr):
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ if (nr_bytes == 2)
+ dv_store_2 (dest, 0);
+ else
+ dv_store_4 (dest, 0);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+bfin_sic_54x_forward_interrupts (struct hw *me, struct bfin_sic *sic)
+{
+ bfin_sic_forward_interrupts (me, &sic->bf54x.isr0, &sic->bf54x.imask0, &sic->bf54x.iar0);
+ bfin_sic_forward_interrupts (me, &sic->bf54x.isr1, &sic->bf54x.imask1, &sic->bf54x.iar4);
+ bfin_sic_forward_interrupts (me, &sic->bf54x.isr2, &sic->bf54x.imask2, &sic->bf54x.iar8);
+}
+
+static unsigned
+bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ /* XXX: Discard all SIC writes for now. */
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ /* XXX: This should trigger a software reset ... */
+ break;
+ case mmr_offset(syscr):
+ /* XXX: what to do ... */
+ break;
+ case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
+ bfin_sic_54x_forward_interrupts (me, sic);
+ *value32p = value;
+ break;
+ case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
+ case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
+ *value32p = value;
+ break;
+ case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
+ /* ISR is read-only. */
+ break;
+ default:
+ /* XXX: Should discard other writes. */
+ ;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_sic_54x_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ case mmr_offset(syscr):
+ case mmr_offset(rvect):
+ dv_store_2 (dest, *value16p);
+ break;
+ case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
+ case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
+ case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
+ case mmr_offset(bf54x.isr0) ... mmr_offset(bf54x.isr2):
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ if (nr_bytes == 2)
+ dv_store_2 (dest, 0);
+ else
+ dv_store_4 (dest, 0);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+bfin_sic_561_forward_interrupts (struct hw *me, struct bfin_sic *sic)
+{
+ bfin_sic_forward_interrupts (me, &sic->bf561.isr0, &sic->bf561.imask0, &sic->bf561.iar0);
+ bfin_sic_forward_interrupts (me, &sic->bf561.isr1, &sic->bf561.imask1, &sic->bf561.iar4);
+}
+
+static unsigned
+bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ /* XXX: Discard all SIC writes for now. */
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ /* XXX: This should trigger a software reset ... */
+ break;
+ case mmr_offset(syscr):
+ /* XXX: what to do ... */
+ break;
+ case mmr_offset(bf561.imask0):
+ case mmr_offset(bf561.imask1):
+ bfin_sic_561_forward_interrupts (me, sic);
+ *value32p = value;
+ break;
+ case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
+ case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
+ case mmr_offset(bf561.iwr0):
+ case mmr_offset(bf561.iwr1):
+ *value32p = value;
+ break;
+ case mmr_offset(bf561.isr0):
+ case mmr_offset(bf561.isr1):
+ /* ISR is read-only. */
+ break;
+ default:
+ /* XXX: Should discard other writes. */
+ ;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_sic_561_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - sic->base;
+ valuep = (void *)((unsigned long)sic + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(swrst):
+ case mmr_offset(syscr):
+ case mmr_offset(rvect):
+ dv_store_2 (dest, *value16p);
+ break;
+ case mmr_offset(bf561.imask0):
+ case mmr_offset(bf561.imask1):
+ case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
+ case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
+ case mmr_offset(bf561.iwr0):
+ case mmr_offset(bf561.iwr1):
+ case mmr_offset(bf561.isr0):
+ case mmr_offset(bf561.isr1):
+ dv_store_4 (dest, *value32p);
+ break;
+ default:
+ if (nr_bytes == 2)
+ dv_store_2 (dest, 0);
+ else
+ dv_store_4 (dest, 0);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+/* XXX: This doesn't handle DMA<->peripheral mappings. */
+#define BFIN_SIC_TO_CEC_PORTS \
+ { "ivg7", IVG7, 0, output_port, }, \
+ { "ivg8", IVG8, 0, output_port, }, \
+ { "ivg9", IVG9, 0, output_port, }, \
+ { "ivg10", IVG10, 0, output_port, }, \
+ { "ivg11", IVG11, 0, output_port, }, \
+ { "ivg12", IVG12, 0, output_port, }, \
+ { "ivg13", IVG13, 0, output_port, }, \
+ { "ivg14", IVG14, 0, output_port, }, \
+ { "ivg15", IVG15, 0, output_port, },
+
+static const struct hw_port_descriptor bfin_sic_50x_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ /* SIC0 */
+ { "pll", 0, 0, input_port, },
+ { "dma_stat", 1, 0, input_port, },
+ { "ppi@0", 2, 0, input_port, },
+ { "sport@0_stat", 3, 0, input_port, },
+ { "sport@1_stat", 4, 0, input_port, },
+ { "uart2@0_stat", 5, 0, input_port, },
+ { "uart2@1_stat", 6, 0, input_port, },
+ { "spi@0", 7, 0, input_port, },
+ { "spi@1", 8, 0, input_port, },
+ { "can_stat", 9, 0, input_port, },
+ { "rsi_int0", 10, 0, input_port, },
+/*{ "reserved", 11, 0, input_port, },*/
+ { "counter@0", 12, 0, input_port, },
+ { "counter@1", 13, 0, input_port, },
+ { "dma@0", 14, 0, input_port, },
+ { "dma@1", 15, 0, input_port, },
+ { "dma@2", 16, 0, input_port, },
+ { "dma@3", 17, 0, input_port, },
+ { "dma@4", 18, 0, input_port, },
+ { "dma@5", 19, 0, input_port, },
+ { "dma@6", 20, 0, input_port, },
+ { "dma@7", 21, 0, input_port, },
+ { "dma@8", 22, 0, input_port, },
+ { "dma@9", 23, 0, input_port, },
+ { "dma@10", 24, 0, input_port, },
+ { "dma@11", 25, 0, input_port, },
+ { "can_rx", 26, 0, input_port, },
+ { "can_tx", 27, 0, input_port, },
+ { "twi@0", 28, 0, input_port, },
+ { "portf_irq_a", 29, 0, input_port, },
+ { "portf_irq_b", 30, 0, input_port, },
+/*{ "reserved", 31, 0, input_port, },*/
+ /* SIC1 */
+ { "gptimer@0", 100, 0, input_port, },
+ { "gptimer@1", 101, 0, input_port, },
+ { "gptimer@2", 102, 0, input_port, },
+ { "gptimer@3", 103, 0, input_port, },
+ { "gptimer@4", 104, 0, input_port, },
+ { "gptimer@5", 105, 0, input_port, },
+ { "gptimer@6", 106, 0, input_port, },
+ { "gptimer@7", 107, 0, input_port, },
+ { "portg_irq_a", 108, 0, input_port, },
+ { "portg_irq_b", 109, 0, input_port, },
+ { "mdma@0", 110, 0, input_port, },
+ { "mdma@1", 111, 0, input_port, },
+ { "wdog", 112, 0, input_port, },
+ { "porth_irq_a", 113, 0, input_port, },
+ { "porth_irq_b", 114, 0, input_port, },
+ { "acm_stat", 115, 0, input_port, },
+ { "acm_int", 116, 0, input_port, },
+/*{ "reserved", 117, 0, input_port, },*/
+/*{ "reserved", 118, 0, input_port, },*/
+ { "pwm@0_trip", 119, 0, input_port, },
+ { "pwm@0_sync", 120, 0, input_port, },
+ { "pwm@1_trip", 121, 0, input_port, },
+ { "pwm@1_sync", 122, 0, input_port, },
+ { "rsi_int1", 123, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const struct hw_port_descriptor bfin_sic_51x_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ /* SIC0 */
+ { "pll", 0, 0, input_port, },
+ { "dma_stat", 1, 0, input_port, },
+ { "dmar0_block", 2, 0, input_port, },
+ { "dmar1_block", 3, 0, input_port, },
+ { "dmar0_over", 4, 0, input_port, },
+ { "dmar1_over", 5, 0, input_port, },
+ { "ppi@0", 6, 0, input_port, },
+ { "emac_stat", 7, 0, input_port, },
+ { "sport@0_stat", 8, 0, input_port, },
+ { "sport@1_stat", 9, 0, input_port, },
+ { "ptp_err", 10, 0, input_port, },
+/*{ "reserved", 11, 0, input_port, },*/
+ { "uart@0_stat", 12, 0, input_port, },
+ { "uart@1_stat", 13, 0, input_port, },
+ { "rtc", 14, 0, input_port, },
+ { "dma@0", 15, 0, input_port, },
+ { "dma@3", 16, 0, input_port, },
+ { "dma@4", 17, 0, input_port, },
+ { "dma@5", 18, 0, input_port, },
+ { "dma@6", 19, 0, input_port, },
+ { "twi@0", 20, 0, input_port, },
+ { "dma@7", 21, 0, input_port, },
+ { "dma@8", 22, 0, input_port, },
+ { "dma@9", 23, 0, input_port, },
+ { "dma@10", 24, 0, input_port, },
+ { "dma@11", 25, 0, input_port, },
+ { "otp", 26, 0, input_port, },
+ { "counter", 27, 0, input_port, },
+ { "dma@1", 28, 0, input_port, },
+ { "porth_irq_a", 29, 0, input_port, },
+ { "dma@2", 30, 0, input_port, },
+ { "porth_irq_b", 31, 0, input_port, },
+ /* SIC1 */
+ { "gptimer@0", 100, 0, input_port, },
+ { "gptimer@1", 101, 0, input_port, },
+ { "gptimer@2", 102, 0, input_port, },
+ { "gptimer@3", 103, 0, input_port, },
+ { "gptimer@4", 104, 0, input_port, },
+ { "gptimer@5", 105, 0, input_port, },
+ { "gptimer@6", 106, 0, input_port, },
+ { "gptimer@7", 107, 0, input_port, },
+ { "portg_irq_a", 108, 0, input_port, },
+ { "portg_irq_b", 109, 0, input_port, },
+ { "mdma@0", 110, 0, input_port, },
+ { "mdma@1", 111, 0, input_port, },
+ { "wdog", 112, 0, input_port, },
+ { "portf_irq_a", 113, 0, input_port, },
+ { "portf_irq_b", 114, 0, input_port, },
+ { "spi@0", 115, 0, input_port, },
+ { "spi@1", 116, 0, input_port, },
+/*{ "reserved", 117, 0, input_port, },*/
+/*{ "reserved", 118, 0, input_port, },*/
+ { "rsi_int0", 119, 0, input_port, },
+ { "rsi_int1", 120, 0, input_port, },
+ { "pwm_trip", 121, 0, input_port, },
+ { "pwm_sync", 122, 0, input_port, },
+ { "ptp_stat", 123, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const struct hw_port_descriptor bfin_sic_52x_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ /* SIC0 */
+ { "pll", 0, 0, input_port, },
+ { "dma_stat", 1, 0, input_port, },
+ { "dmar0_block", 2, 0, input_port, },
+ { "dmar1_block", 3, 0, input_port, },
+ { "dmar0_over", 4, 0, input_port, },
+ { "dmar1_over", 5, 0, input_port, },
+ { "ppi@0", 6, 0, input_port, },
+ { "emac_stat", 7, 0, input_port, },
+ { "sport@0_stat", 8, 0, input_port, },
+ { "sport@1_stat", 9, 0, input_port, },
+/*{ "reserved", 10, 0, input_port, },*/
+/*{ "reserved", 11, 0, input_port, },*/
+ { "uart@0_stat", 12, 0, input_port, },
+ { "uart@1_stat", 13, 0, input_port, },
+ { "rtc", 14, 0, input_port, },
+ { "dma@0", 15, 0, input_port, },
+ { "dma@3", 16, 0, input_port, },
+ { "dma@4", 17, 0, input_port, },
+ { "dma@5", 18, 0, input_port, },
+ { "dma@6", 19, 0, input_port, },
+ { "twi@0", 20, 0, input_port, },
+ { "dma@7", 21, 0, input_port, },
+ { "dma@8", 22, 0, input_port, },
+ { "dma@9", 23, 0, input_port, },
+ { "dma@10", 24, 0, input_port, },
+ { "dma@11", 25, 0, input_port, },
+ { "otp", 26, 0, input_port, },
+ { "counter", 27, 0, input_port, },
+ { "dma@1", 28, 0, input_port, },
+ { "porth_irq_a", 29, 0, input_port, },
+ { "dma@2", 30, 0, input_port, },
+ { "porth_irq_b", 31, 0, input_port, },
+ /* SIC1 */
+ { "gptimer@0", 100, 0, input_port, },
+ { "gptimer@1", 101, 0, input_port, },
+ { "gptimer@2", 102, 0, input_port, },
+ { "gptimer@3", 103, 0, input_port, },
+ { "gptimer@4", 104, 0, input_port, },
+ { "gptimer@5", 105, 0, input_port, },
+ { "gptimer@6", 106, 0, input_port, },
+ { "gptimer@7", 107, 0, input_port, },
+ { "portg_irq_a", 108, 0, input_port, },
+ { "portg_irq_b", 109, 0, input_port, },
+ { "mdma@0", 110, 0, input_port, },
+ { "mdma@1", 111, 0, input_port, },
+ { "wdog", 112, 0, input_port, },
+ { "portf_irq_a", 113, 0, input_port, },
+ { "portf_irq_b", 114, 0, input_port, },
+ { "spi@0", 115, 0, input_port, },
+ { "nfc_stat", 116, 0, input_port, },
+ { "hostdp_stat", 117, 0, input_port, },
+ { "hostdp_done", 118, 0, input_port, },
+ { "usb_int0", 120, 0, input_port, },
+ { "usb_int1", 121, 0, input_port, },
+ { "usb_int2", 122, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_sic_52x_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 idx = my_port / 100;
+ bu32 bit = (1 << (my_port & 0x1f));
+
+ /* SIC only exists to forward interrupts from the system to the CEC. */
+ switch (idx)
+ {
+ case 0: sic->bf52x.isr0 |= bit; break;
+ case 1: sic->bf52x.isr1 |= bit; break;
+ }
+
+ /* XXX: Handle SIC wakeup source ?
+ if (sic->bf52x.iwr0 & bit)
+ What to do ?;
+ if (sic->bf52x.iwr1 & bit)
+ What to do ?;
+ */
+
+ bfin_sic_52x_forward_interrupts (me, sic);
+}
+
+static const struct hw_port_descriptor bfin_sic_533_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ { "pll", 0, 0, input_port, },
+ { "dma_stat", 1, 0, input_port, },
+ { "ppi@0", 2, 0, input_port, },
+ { "sport@0_stat", 3, 0, input_port, },
+ { "sport@1_stat", 4, 0, input_port, },
+ { "spi@0", 5, 0, input_port, },
+ { "uart@0_stat", 6, 0, input_port, },
+ { "rtc", 7, 0, input_port, },
+ { "dma@0", 8, 0, input_port, },
+ { "dma@1", 9, 0, input_port, },
+ { "dma@2", 10, 0, input_port, },
+ { "dma@3", 11, 0, input_port, },
+ { "dma@4", 12, 0, input_port, },
+ { "dma@5", 13, 0, input_port, },
+ { "dma@6", 14, 0, input_port, },
+ { "dma@7", 15, 0, input_port, },
+ { "gptimer@0", 16, 0, input_port, },
+ { "gptimer@1", 17, 0, input_port, },
+ { "gptimer@2", 18, 0, input_port, },
+ { "portf_irq_a", 19, 0, input_port, },
+ { "portf_irq_b", 20, 0, input_port, },
+ { "mdma@0", 21, 0, input_port, },
+ { "mdma@1", 22, 0, input_port, },
+ { "wdog", 23, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_sic_533_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 bit = (1 << my_port);
+
+ /* SIC only exists to forward interrupts from the system to the CEC. */
+ sic->bf537.isr |= bit;
+
+ /* XXX: Handle SIC wakeup source ?
+ if (sic->bf537.iwr & bit)
+ What to do ?;
+ */
+
+ bfin_sic_537_forward_interrupts (me, sic);
+}
+
+static const struct hw_port_descriptor bfin_sic_537_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ { "pll", 0, 0, input_port, },
+ { "dma_stat", 10, 0, input_port, },
+ { "dmar0_block", 11, 0, input_port, },
+ { "dmar1_block", 12, 0, input_port, },
+ { "dmar0_over", 13, 0, input_port, },
+ { "dmar1_over", 14, 0, input_port, },
+ { "can_stat", 20, 0, input_port, },
+ { "emac_stat", 21, 0, input_port, },
+ { "sport@0_stat", 22, 0, input_port, },
+ { "sport@1_stat", 23, 0, input_port, },
+ { "ppi@0", 24, 0, input_port, },
+ { "spi@0", 25, 0, input_port, },
+ { "uart@0_stat", 26, 0, input_port, },
+ { "uart@1_stat", 27, 0, input_port, },
+ { "rtc", 30, 0, input_port, },
+ { "dma@0", 40, 0, input_port, },
+ { "dma@3", 50, 0, input_port, },
+ { "dma@4", 60, 0, input_port, },
+ { "dma@5", 70, 0, input_port, },
+ { "dma@6", 80, 0, input_port, },
+ { "twi@0", 90, 0, input_port, },
+ { "dma@7", 100, 0, input_port, },
+ { "dma@8", 110, 0, input_port, },
+ { "dma@9", 120, 0, input_port, },
+ { "dma@10", 130, 0, input_port, },
+ { "dma@11", 140, 0, input_port, },
+ { "can_rx", 150, 0, input_port, },
+ { "can_tx", 160, 0, input_port, },
+ { "dma@1", 170, 0, input_port, },
+ { "porth_irq_a", 171, 0, input_port, },
+ { "dma@2", 180, 0, input_port, },
+ { "porth_irq_b", 181, 0, input_port, },
+ { "gptimer@0", 190, 0, input_port, },
+ { "gptimer@1", 200, 0, input_port, },
+ { "gptimer@2", 210, 0, input_port, },
+ { "gptimer@3", 220, 0, input_port, },
+ { "gptimer@4", 230, 0, input_port, },
+ { "gptimer@5", 240, 0, input_port, },
+ { "gptimer@6", 250, 0, input_port, },
+ { "gptimer@7", 260, 0, input_port, },
+ { "portf_irq_a", 270, 0, input_port, },
+ { "portg_irq_a", 271, 0, input_port, },
+ { "portg_irq_b", 280, 0, input_port, },
+ { "mdma@0", 290, 0, input_port, },
+ { "mdma@1", 300, 0, input_port, },
+ { "wdog", 310, 0, input_port, },
+ { "portf_irq_b", 311, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_sic_537_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 bit = (1 << (my_port / 10));
+
+ /* SIC only exists to forward interrupts from the system to the CEC. */
+ sic->bf537.isr |= bit;
+
+ /* XXX: Handle SIC wakeup source ?
+ if (sic->bf537.iwr & bit)
+ What to do ?;
+ */
+
+ bfin_sic_537_forward_interrupts (me, sic);
+}
+
+static const struct hw_port_descriptor bfin_sic_538_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ /* SIC0 */
+ { "pll", 0, 0, input_port, },
+ { "dmac@0_stat", 1, 0, input_port, },
+ { "ppi@0", 2, 0, input_port, },
+ { "sport@0_stat", 3, 0, input_port, },
+ { "sport@1_stat", 4, 0, input_port, },
+ { "spi@0", 5, 0, input_port, },
+ { "uart@0_stat", 6, 0, input_port, },
+ { "rtc", 7, 0, input_port, },
+ { "dma@0", 8, 0, input_port, },
+ { "dma@1", 9, 0, input_port, },
+ { "dma@2", 10, 0, input_port, },
+ { "dma@3", 11, 0, input_port, },
+ { "dma@4", 12, 0, input_port, },
+ { "dma@5", 13, 0, input_port, },
+ { "dma@6", 14, 0, input_port, },
+ { "dma@7", 15, 0, input_port, },
+ { "gptimer@0", 16, 0, input_port, },
+ { "gptimer@1", 17, 0, input_port, },
+ { "gptimer@2", 18, 0, input_port, },
+ { "portf_irq_a", 19, 0, input_port, },
+ { "portf_irq_b", 20, 0, input_port, },
+ { "mdma@0", 21, 0, input_port, },
+ { "mdma@1", 22, 0, input_port, },
+ { "wdog", 23, 0, input_port, },
+ { "dmac@1_stat", 24, 0, input_port, },
+ { "sport@2_stat", 25, 0, input_port, },
+ { "sport@3_stat", 26, 0, input_port, },
+/*{ "reserved", 27, 0, input_port, },*/
+ { "spi@1", 28, 0, input_port, },
+ { "spi@2", 29, 0, input_port, },
+ { "uart@1_stat", 30, 0, input_port, },
+ { "uart@2_stat", 31, 0, input_port, },
+ /* SIC1 */
+ { "can_stat", 100, 0, input_port, },
+ { "dma@8", 101, 0, input_port, },
+ { "dma@9", 102, 0, input_port, },
+ { "dma@10", 103, 0, input_port, },
+ { "dma@11", 104, 0, input_port, },
+ { "dma@12", 105, 0, input_port, },
+ { "dma@13", 106, 0, input_port, },
+ { "dma@14", 107, 0, input_port, },
+ { "dma@15", 108, 0, input_port, },
+ { "dma@16", 109, 0, input_port, },
+ { "dma@17", 110, 0, input_port, },
+ { "dma@18", 111, 0, input_port, },
+ { "dma@19", 112, 0, input_port, },
+ { "twi@0", 113, 0, input_port, },
+ { "twi@1", 114, 0, input_port, },
+ { "can_rx", 115, 0, input_port, },
+ { "can_tx", 116, 0, input_port, },
+ { "mdma@2", 117, 0, input_port, },
+ { "mdma@3", 118, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static const struct hw_port_descriptor bfin_sic_54x_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ /* SIC0 */
+ { "pll", 0, 0, input_port, },
+ { "dmac@0_stat", 1, 0, input_port, },
+ { "eppi@0", 2, 0, input_port, },
+ { "sport@0_stat", 3, 0, input_port, },
+ { "sport@1_stat", 4, 0, input_port, },
+ { "spi@0", 5, 0, input_port, },
+ { "uart2@0_stat", 6, 0, input_port, },
+ { "rtc", 7, 0, input_port, },
+ { "dma@12", 8, 0, input_port, },
+ { "dma@0", 9, 0, input_port, },
+ { "dma@1", 10, 0, input_port, },
+ { "dma@2", 11, 0, input_port, },
+ { "dma@3", 12, 0, input_port, },
+ { "dma@4", 13, 0, input_port, },
+ { "dma@6", 14, 0, input_port, },
+ { "dma@7", 15, 0, input_port, },
+ { "gptimer@8", 16, 0, input_port, },
+ { "gptimer@9", 17, 0, input_port, },
+ { "gptimer@10", 18, 0, input_port, },
+ { "pint@0", 19, 0, input_port, },
+ { "pint@1", 20, 0, input_port, },
+ { "mdma@0", 21, 0, input_port, },
+ { "mdma@1", 22, 0, input_port, },
+ { "wdog", 23, 0, input_port, },
+ { "dmac@1_stat", 24, 0, input_port, },
+ { "sport@2_stat", 25, 0, input_port, },
+ { "sport@3_stat", 26, 0, input_port, },
+ { "mxvr", 27, 0, input_port, },
+ { "spi@1", 28, 0, input_port, },
+ { "spi@2", 29, 0, input_port, },
+ { "uart2@1_stat", 30, 0, input_port, },
+ { "uart2@2_stat", 31, 0, input_port, },
+ /* SIC1 */
+ { "can@0_stat", 32, 0, input_port, },
+ { "dma@18", 33, 0, input_port, },
+ { "dma@19", 34, 0, input_port, },
+ { "dma@20", 35, 0, input_port, },
+ { "dma@21", 36, 0, input_port, },
+ { "dma@13", 37, 0, input_port, },
+ { "dma@14", 38, 0, input_port, },
+ { "dma@5", 39, 0, input_port, },
+ { "dma@23", 40, 0, input_port, },
+ { "dma@8", 41, 0, input_port, },
+ { "dma@9", 42, 0, input_port, },
+ { "dma@10", 43, 0, input_port, },
+ { "dma@11", 44, 0, input_port, },
+ { "twi@0", 45, 0, input_port, },
+ { "twi@1", 46, 0, input_port, },
+ { "can@0_rx", 47, 0, input_port, },
+ { "can@0_tx", 48, 0, input_port, },
+ { "mdma@2", 49, 0, input_port, },
+ { "mdma@3", 50, 0, input_port, },
+ { "mxvr_stat", 51, 0, input_port, },
+ { "mxvr_message", 52, 0, input_port, },
+ { "mxvr_packet", 53, 0, input_port, },
+ { "eppi@1", 54, 0, input_port, },
+ { "eppi@2", 55, 0, input_port, },
+ { "uart2@3_stat", 56, 0, input_port, },
+ { "hostdp", 57, 0, input_port, },
+/*{ "reserved", 58, 0, input_port, },*/
+ { "pixc_stat", 59, 0, input_port, },
+ { "nfc", 60, 0, input_port, },
+ { "atapi", 61, 0, input_port, },
+ { "can@1_stat", 62, 0, input_port, },
+ { "dmar", 63, 0, input_port, },
+ /* SIC2 */
+ { "dma@15", 64, 0, input_port, },
+ { "dma@16", 65, 0, input_port, },
+ { "dma@17", 66, 0, input_port, },
+ { "dma@22", 67, 0, input_port, },
+ { "counter", 68, 0, input_port, },
+ { "key", 69, 0, input_port, },
+ { "can@1_rx", 70, 0, input_port, },
+ { "can@1_tx", 71, 0, input_port, },
+ { "sdh_mask0", 72, 0, input_port, },
+ { "sdh_mask1", 73, 0, input_port, },
+/*{ "reserved", 74, 0, input_port, },*/
+ { "usb_int0", 75, 0, input_port, },
+ { "usb_int1", 76, 0, input_port, },
+ { "usb_int2", 77, 0, input_port, },
+ { "usb_dma", 78, 0, input_port, },
+ { "otpsec", 79, 0, input_port, },
+/*{ "reserved", 80, 0, input_port, },*/
+/*{ "reserved", 81, 0, input_port, },*/
+/*{ "reserved", 82, 0, input_port, },*/
+/*{ "reserved", 83, 0, input_port, },*/
+/*{ "reserved", 84, 0, input_port, },*/
+/*{ "reserved", 85, 0, input_port, },*/
+ { "gptimer@0", 86, 0, input_port, },
+ { "gptimer@1", 87, 0, input_port, },
+ { "gptimer@2", 88, 0, input_port, },
+ { "gptimer@3", 89, 0, input_port, },
+ { "gptimer@4", 90, 0, input_port, },
+ { "gptimer@5", 91, 0, input_port, },
+ { "gptimer@6", 92, 0, input_port, },
+ { "gptimer@7", 93, 0, input_port, },
+ { "pint2", 94, 0, input_port, },
+ { "pint3", 95, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_sic_54x_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 idx = my_port / 100;
+ bu32 bit = (1 << (my_port & 0x1f));
+
+ /* SIC only exists to forward interrupts from the system to the CEC. */
+ switch (idx)
+ {
+ case 0: sic->bf54x.isr0 |= bit; break;
+ case 1: sic->bf54x.isr1 |= bit; break;
+ case 2: sic->bf54x.isr2 |= bit; break;
+ }
+
+ /* XXX: Handle SIC wakeup source ?
+ if (sic->bf54x.iwr0 & bit)
+ What to do ?;
+ if (sic->bf54x.iwr1 & bit)
+ What to do ?;
+ if (sic->bf54x.iwr2 & bit)
+ What to do ?;
+ */
+
+ bfin_sic_54x_forward_interrupts (me, sic);
+}
+
+static const struct hw_port_descriptor bfin_sic_561_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ /* SIC0 */
+ { "pll", 0, 0, input_port, },
+ { "dmac@0_stat", 1, 0, input_port, },
+ { "dmac@1_stat", 2, 0, input_port, },
+ { "imdma_stat", 3, 0, input_port, },
+ { "ppi@0", 4, 0, input_port, },
+ { "ppi@1", 5, 0, input_port, },
+ { "sport@0_stat", 6, 0, input_port, },
+ { "sport@1_stat", 7, 0, input_port, },
+ { "spi@0", 8, 0, input_port, },
+ { "uart@0_stat", 9, 0, input_port, },
+/*{ "reserved", 10, 0, input_port, },*/
+ { "dma@12", 11, 0, input_port, },
+ { "dma@13", 12, 0, input_port, },
+ { "dma@14", 13, 0, input_port, },
+ { "dma@15", 14, 0, input_port, },
+ { "dma@16", 15, 0, input_port, },
+ { "dma@17", 16, 0, input_port, },
+ { "dma@18", 17, 0, input_port, },
+ { "dma@19", 18, 0, input_port, },
+ { "dma@20", 19, 0, input_port, },
+ { "dma@21", 20, 0, input_port, },
+ { "dma@22", 21, 0, input_port, },
+ { "dma@23", 22, 0, input_port, },
+ { "dma@0", 23, 0, input_port, },
+ { "dma@1", 24, 0, input_port, },
+ { "dma@2", 25, 0, input_port, },
+ { "dma@3", 26, 0, input_port, },
+ { "dma@4", 27, 0, input_port, },
+ { "dma@5", 28, 0, input_port, },
+ { "dma@6", 29, 0, input_port, },
+ { "dma@7", 30, 0, input_port, },
+ { "dma@8", 31, 0, input_port, },
+ /* SIC1 */
+ { "dma@9", 100, 0, input_port, },
+ { "dma@10", 101, 0, input_port, },
+ { "dma@11", 102, 0, input_port, },
+ { "gptimer@0", 103, 0, input_port, },
+ { "gptimer@1", 104, 0, input_port, },
+ { "gptimer@2", 105, 0, input_port, },
+ { "gptimer@3", 106, 0, input_port, },
+ { "gptimer@4", 107, 0, input_port, },
+ { "gptimer@5", 108, 0, input_port, },
+ { "gptimer@6", 109, 0, input_port, },
+ { "gptimer@7", 110, 0, input_port, },
+ { "gptimer@8", 111, 0, input_port, },
+ { "gptimer@9", 112, 0, input_port, },
+ { "gptimer@10", 113, 0, input_port, },
+ { "gptimer@11", 114, 0, input_port, },
+ { "portf_irq_a", 115, 0, input_port, },
+ { "portf_irq_b", 116, 0, input_port, },
+ { "portg_irq_a", 117, 0, input_port, },
+ { "portg_irq_b", 118, 0, input_port, },
+ { "porth_irq_a", 119, 0, input_port, },
+ { "porth_irq_b", 120, 0, input_port, },
+ { "mdma@0", 121, 0, input_port, },
+ { "mdma@1", 122, 0, input_port, },
+ { "mdma@2", 123, 0, input_port, },
+ { "mdma@3", 124, 0, input_port, },
+ { "imdma@0", 125, 0, input_port, },
+ { "imdma@1", 126, 0, input_port, },
+ { "wdog", 127, 0, input_port, },
+/*{ "reserved", 128, 0, input_port, },*/
+/*{ "reserved", 129, 0, input_port, },*/
+ { "sup_irq_0", 130, 0, input_port, },
+ { "sup_irq_1", 131, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_sic_561_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ struct bfin_sic *sic = hw_data (me);
+ bu32 idx = my_port / 100;
+ bu32 bit = (1 << (my_port & 0x1f));
+
+ /* SIC only exists to forward interrupts from the system to the CEC. */
+ switch (idx)
+ {
+ case 0: sic->bf561.isr0 |= bit; break;
+ case 1: sic->bf561.isr1 |= bit; break;
+ }
+
+ /* XXX: Handle SIC wakeup source ?
+ if (sic->bf561.iwr0 & bit)
+ What to do ?;
+ if (sic->bf561.iwr1 & bit)
+ What to do ?;
+ */
+
+ bfin_sic_561_forward_interrupts (me, sic);
+}
+
+static const struct hw_port_descriptor bfin_sic_59x_ports[] = {
+ BFIN_SIC_TO_CEC_PORTS
+ { "pll", 0, 0, input_port, },
+ { "dma_stat", 1, 0, input_port, },
+ { "ppi@0", 2, 0, input_port, },
+ { "sport@0_stat", 3, 0, input_port, },
+ { "sport@1_stat", 4, 0, input_port, },
+ { "spi@0", 5, 0, input_port, },
+ { "spi@1", 6, 0, input_port, },
+ { "uart@0_stat", 7, 0, input_port, },
+ { "dma@0", 8, 0, input_port, },
+ { "dma@1", 9, 0, input_port, },
+ { "dma@2", 10, 0, input_port, },
+ { "dma@3", 11, 0, input_port, },
+ { "dma@4", 12, 0, input_port, },
+ { "dma@5", 13, 0, input_port, },
+ { "dma@6", 14, 0, input_port, },
+ { "dma@7", 15, 0, input_port, },
+ { "dma@8", 16, 0, input_port, },
+ { "portf_irq_a", 17, 0, input_port, },
+ { "portf_irq_b", 18, 0, input_port, },
+ { "gptimer@0", 19, 0, input_port, },
+ { "gptimer@1", 20, 0, input_port, },
+ { "gptimer@2", 21, 0, input_port, },
+ { "portg_irq_a", 22, 0, input_port, },
+ { "portg_irq_b", 23, 0, input_port, },
+ { "twi@0", 24, 0, input_port, },
+/* XXX: 25 - 28 are supposed to be reserved; see comment in machs.c:bf592_dmac[] */
+ { "dma@9", 25, 0, input_port, },
+ { "dma@10", 26, 0, input_port, },
+ { "dma@11", 27, 0, input_port, },
+ { "dma@12", 28, 0, input_port, },
+/*{ "reserved", 25, 0, input_port, },*/
+/*{ "reserved", 26, 0, input_port, },*/
+/*{ "reserved", 27, 0, input_port, },*/
+/*{ "reserved", 28, 0, input_port, },*/
+ { "mdma@0", 29, 0, input_port, },
+ { "mdma@1", 30, 0, input_port, },
+ { "wdog", 31, 0, input_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_sic_regs (struct hw *me, struct bfin_sic *sic)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_SIC_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SIC_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ sic->base = attach_address;
+}
+
+static void
+bfin_sic_finish (struct hw *me)
+{
+ struct bfin_sic *sic;
+
+ sic = HW_ZALLOC (me, struct bfin_sic);
+
+ set_hw_data (me, sic);
+ attach_bfin_sic_regs (me, sic);
+
+ switch (hw_find_integer_property (me, "type"))
+ {
+ case 500 ... 509:
+ set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
+ set_hw_ports (me, bfin_sic_50x_ports);
+ set_hw_port_event (me, bfin_sic_52x_port_event);
+ mmr_names = bf52x_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
+ sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
+ sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
+ sic->bf52x.iar0 = 0x00000000;
+ sic->bf52x.iar1 = 0x22111000;
+ sic->bf52x.iar2 = 0x33332222;
+ sic->bf52x.iar3 = 0x44444433;
+ sic->bf52x.iar4 = 0x55555555;
+ sic->bf52x.iar5 = 0x06666655;
+ sic->bf52x.iar6 = 0x33333003;
+ sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
+ break;
+ case 510 ... 519:
+ set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
+ set_hw_ports (me, bfin_sic_51x_ports);
+ set_hw_port_event (me, bfin_sic_52x_port_event);
+ mmr_names = bf52x_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
+ sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
+ sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
+ sic->bf52x.iar0 = 0x00000000;
+ sic->bf52x.iar1 = 0x11000000;
+ sic->bf52x.iar2 = 0x33332222;
+ sic->bf52x.iar3 = 0x44444433;
+ sic->bf52x.iar4 = 0x55555555;
+ sic->bf52x.iar5 = 0x06666655;
+ sic->bf52x.iar6 = 0x33333000;
+ sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
+ break;
+ case 522 ... 527:
+ set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
+ set_hw_ports (me, bfin_sic_52x_ports);
+ set_hw_port_event (me, bfin_sic_52x_port_event);
+ mmr_names = bf52x_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
+ sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
+ sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
+ sic->bf52x.iar0 = 0x00000000;
+ sic->bf52x.iar1 = 0x11000000;
+ sic->bf52x.iar2 = 0x33332222;
+ sic->bf52x.iar3 = 0x44444433;
+ sic->bf52x.iar4 = 0x55555555;
+ sic->bf52x.iar5 = 0x06666655;
+ sic->bf52x.iar6 = 0x33333000;
+ sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
+ break;
+ case 531 ... 533:
+ set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
+ set_hw_ports (me, bfin_sic_533_ports);
+ set_hw_port_event (me, bfin_sic_533_port_event);
+ mmr_names = bf537_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf537.imask = 0;
+ sic->bf537.isr = 0;
+ sic->bf537.iwr = 0xFFFFFFFF;
+ sic->bf537.iar0 = 0x10000000;
+ sic->bf537.iar1 = 0x33322221;
+ sic->bf537.iar2 = 0x66655444;
+ sic->bf537.iar3 = 0; /* XXX: fix this */
+ break;
+ case 534:
+ case 536:
+ case 537:
+ set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
+ set_hw_ports (me, bfin_sic_537_ports);
+ set_hw_port_event (me, bfin_sic_537_port_event);
+ mmr_names = bf537_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf537.imask = 0;
+ sic->bf537.isr = 0;
+ sic->bf537.iwr = 0xFFFFFFFF;
+ sic->bf537.iar0 = 0x22211000;
+ sic->bf537.iar1 = 0x43333332;
+ sic->bf537.iar2 = 0x55555444;
+ sic->bf537.iar3 = 0x66655555;
+ break;
+ case 538 ... 539:
+ set_hw_io_read_buffer (me, bfin_sic_52x_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_52x_io_write_buffer);
+ set_hw_ports (me, bfin_sic_538_ports);
+ set_hw_port_event (me, bfin_sic_52x_port_event);
+ mmr_names = bf52x_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf52x.imask0 = sic->bf52x.imask1 = 0;
+ sic->bf52x.isr0 = sic->bf52x.isr1 = 0;
+ sic->bf52x.iwr0 = sic->bf52x.iwr1 = 0xFFFFFFFF;
+ sic->bf52x.iar0 = 0x10000000;
+ sic->bf52x.iar1 = 0x33322221;
+ sic->bf52x.iar2 = 0x66655444;
+ sic->bf52x.iar3 = 0x00000000;
+ sic->bf52x.iar4 = 0x32222220;
+ sic->bf52x.iar5 = 0x44433333;
+ sic->bf52x.iar6 = 0x00444664;
+ sic->bf52x.iar7 = 0x00000000; /* XXX: Find and fix */
+ break;
+ case 540 ... 549:
+ set_hw_io_read_buffer (me, bfin_sic_54x_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_54x_io_write_buffer);
+ set_hw_ports (me, bfin_sic_54x_ports);
+ set_hw_port_event (me, bfin_sic_54x_port_event);
+ mmr_names = bf54x_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf54x.imask0 = sic->bf54x.imask1 = sic->bf54x.imask2 = 0;
+ sic->bf54x.isr0 = sic->bf54x.isr1 = sic->bf54x.isr2 = 0;
+ sic->bf54x.iwr0 = sic->bf54x.iwr1 = sic->bf54x.iwr1 = 0xFFFFFFFF;
+ sic->bf54x.iar0 = 0x10000000;
+ sic->bf54x.iar1 = 0x33322221;
+ sic->bf54x.iar2 = 0x66655444;
+ sic->bf54x.iar3 = 0x00000000;
+ sic->bf54x.iar4 = 0x32222220;
+ sic->bf54x.iar5 = 0x44433333;
+ sic->bf54x.iar6 = 0x00444664;
+ sic->bf54x.iar7 = 0x00000000;
+ sic->bf54x.iar8 = 0x44111111;
+ sic->bf54x.iar9 = 0x44444444;
+ sic->bf54x.iar10 = 0x44444444;
+ sic->bf54x.iar11 = 0x55444444;
+ break;
+ case 561:
+ set_hw_io_read_buffer (me, bfin_sic_561_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_561_io_write_buffer);
+ set_hw_ports (me, bfin_sic_561_ports);
+ set_hw_port_event (me, bfin_sic_561_port_event);
+ mmr_names = bf561_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf561.imask0 = sic->bf561.imask1 = 0;
+ sic->bf561.isr0 = sic->bf561.isr1 = 0;
+ sic->bf561.iwr0 = sic->bf561.iwr1 = 0xFFFFFFFF;
+ sic->bf561.iar0 = 0x00000000;
+ sic->bf561.iar1 = 0x11111000;
+ sic->bf561.iar2 = 0x21111111;
+ sic->bf561.iar3 = 0x22222222;
+ sic->bf561.iar4 = 0x33333222;
+ sic->bf561.iar5 = 0x43333333;
+ sic->bf561.iar6 = 0x21144444;
+ sic->bf561.iar7 = 0x00006552;
+ break;
+ case 590 ... 599:
+ set_hw_io_read_buffer (me, bfin_sic_537_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_sic_537_io_write_buffer);
+ set_hw_ports (me, bfin_sic_59x_ports);
+ set_hw_port_event (me, bfin_sic_533_port_event);
+ mmr_names = bf537_mmr_names;
+
+ /* Initialize the SIC. */
+ sic->bf537.imask = 0;
+ sic->bf537.isr = 0;
+ sic->bf537.iwr = 0xFFFFFFFF;
+ sic->bf537.iar0 = 0x00000000;
+ sic->bf537.iar1 = 0x33322221;
+ sic->bf537.iar2 = 0x55444443;
+ sic->bf537.iar3 = 0x66600005;
+ break;
+ default:
+ hw_abort (me, "no support for SIC on this Blackfin model yet");
+ }
+}
+
+const struct hw_descriptor dv_bfin_sic_descriptor[] = {
+ {"bfin_sic", bfin_sic_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_sic.h b/sim/bfin/dv-bfin_sic.h
new file mode 100644
index 00000000000..e70a749c9bc
--- /dev/null
+++ b/sim/bfin/dv-bfin_sic.h
@@ -0,0 +1,27 @@
+/* Blackfin System Interrupt Controller (SIC) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_SIC_H
+#define DV_BFIN_SIC_H
+
+#define BFIN_MMR_SIC_BASE 0xFFC00100
+#define BFIN_MMR_SIC_SIZE 0x100
+
+#endif
diff --git a/sim/bfin/dv-bfin_spi.c b/sim/bfin/dv-bfin_spi.c
new file mode 100644
index 00000000000..4c783d05855
--- /dev/null
+++ b/sim/bfin/dv-bfin_spi.c
@@ -0,0 +1,229 @@
+/* Blackfin Serial Peripheral Interface (SPI) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_spi.h"
+
+/* XXX: This is merely a stub. */
+
+struct bfin_spi
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(ctl);
+ bu16 BFIN_MMR_16(flg);
+ bu16 BFIN_MMR_16(stat);
+ bu16 BFIN_MMR_16(tdbr);
+ bu16 BFIN_MMR_16(rdbr);
+ bu16 BFIN_MMR_16(baud);
+ bu16 BFIN_MMR_16(shadow);
+};
+#define mmr_base() offsetof(struct bfin_spi, ctl)
+#define mmr_offset(mmr) (offsetof(struct bfin_spi, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "SPI_CTL", "SPI_FLG", "SPI_STAT", "SPI_TDBR",
+ "SPI_RDBR", "SPI_BAUD", "SPI_SHADOW",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static bool
+bfin_spi_enabled (struct bfin_spi *spi)
+{
+ return (spi->ctl & SPE);
+}
+
+static bu16
+bfin_spi_timod (struct bfin_spi *spi)
+{
+ return (spi->ctl & TIMOD);
+}
+
+static unsigned
+bfin_spi_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_spi *spi = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *valuep;
+
+ value = dv_load_2 (source);
+ mmr_off = addr - spi->base;
+ valuep = (void *)((unsigned long)spi + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(stat):
+ dv_w1c_2 (valuep, value, SPIF | TXS | RXS);
+ break;
+ case mmr_offset(tdbr):
+ *valuep = value;
+ if (bfin_spi_enabled (spi) && bfin_spi_timod (spi) == TDBR_CORE)
+ {
+ spi->stat |= RXS;
+ spi->stat &= ~TXS;
+ }
+ break;
+ case mmr_offset(rdbr):
+ case mmr_offset(ctl):
+ case mmr_offset(flg):
+ case mmr_offset(baud):
+ case mmr_offset(shadow):
+ *valuep = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_spi_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_spi *spi = hw_data (me);
+ bu32 mmr_off;
+ bu16 *valuep;
+
+ mmr_off = addr - spi->base;
+ valuep = (void *)((unsigned long)spi + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(rdbr):
+ dv_store_2 (dest, *valuep);
+ if (bfin_spi_enabled (spi) && bfin_spi_timod (spi) == RDBR_CORE)
+ spi->stat &= ~(RXS | TXS);
+ break;
+ case mmr_offset(ctl):
+ case mmr_offset(stat):
+ case mmr_offset(flg):
+ case mmr_offset(tdbr):
+ case mmr_offset(baud):
+ case mmr_offset(shadow):
+ dv_store_2 (dest, *valuep);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_spi_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ HW_TRACE_DMA_READ ();
+ return 0;
+}
+
+static unsigned
+bfin_spi_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ HW_TRACE_DMA_WRITE ();
+ return 0;
+}
+
+static const struct hw_port_descriptor bfin_spi_ports[] = {
+ { "stat", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_spi_regs (struct hw *me, struct bfin_spi *spi)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_SPI_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_SPI_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ spi->base = attach_address;
+}
+
+static void
+bfin_spi_finish (struct hw *me)
+{
+ struct bfin_spi *spi;
+
+ spi = HW_ZALLOC (me, struct bfin_spi);
+
+ set_hw_data (me, spi);
+ set_hw_io_read_buffer (me, bfin_spi_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_spi_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_spi_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_spi_dma_write_buffer);
+ set_hw_ports (me, bfin_spi_ports);
+
+ attach_bfin_spi_regs (me, spi);
+
+ /* Initialize the SPI. */
+ spi->ctl = 0x0400;
+ spi->flg = 0xFF00;
+ spi->stat = 0x0001;
+}
+
+const struct hw_descriptor dv_bfin_spi_descriptor[] = {
+ {"bfin_spi", bfin_spi_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_spi.h b/sim/bfin/dv-bfin_spi.h
new file mode 100644
index 00000000000..5e216bf0414
--- /dev/null
+++ b/sim/bfin/dv-bfin_spi.h
@@ -0,0 +1,54 @@
+/* Blackfin Serial Peripheral Interface (SPI) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_SPI_H
+#define DV_BFIN_SPI_H
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_SPI_SIZE (4 * 7)
+
+/* SPI_CTL Masks. */
+#define TIMOD (3 << 0)
+#define RDBR_CORE (0 << 0)
+#define TDBR_CORE (1 << 0)
+#define RDBR_DMA (2 << 0)
+#define TDBR_DMA (3 << 0)
+#define SZ (1 << 2)
+#define GM (1 << 3)
+#define PSSE (1 << 4)
+#define EMISO (1 << 5)
+#define SZE (1 << 8)
+#define LSBF (1 << 9)
+#define CPHA (1 << 10)
+#define CPOL (1 << 11)
+#define MSTR (1 << 12)
+#define WOM (1 << 13)
+#define SPE (1 << 14)
+
+/* SPI_STAT Masks. */
+#define SPIF (1 << 0)
+#define MODF (1 << 1)
+#define TXE (1 << 2)
+#define TXS (1 << 3)
+#define RBSY (1 << 4)
+#define RXS (1 << 5)
+#define TXCOL (1 << 6)
+
+#endif
diff --git a/sim/bfin/dv-bfin_trace.c b/sim/bfin/dv-bfin_trace.c
new file mode 100644
index 00000000000..a77dd646a40
--- /dev/null
+++ b/sim/bfin/dv-bfin_trace.c
@@ -0,0 +1,285 @@
+/* Blackfin Trace (TBUF) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_cec.h"
+#include "dv-bfin_trace.h"
+
+/* Note: The circular buffering here might look a little buggy wrt mid-reads
+ and consuming the top entry, but this is simulating hardware behavior.
+ The hardware is simple, dumb, and fast. Don't write dumb Blackfin
+ software and you won't have a problem. */
+
+/* The hardware is limited to 16 entries and defines TBUFCTL. Let's extend it ;). */
+#ifndef SIM_BFIN_TRACE_DEPTH
+#define SIM_BFIN_TRACE_DEPTH 6
+#endif
+#define SIM_BFIN_TRACE_LEN (1 << SIM_BFIN_TRACE_DEPTH)
+#define SIM_BFIN_TRACE_LEN_MASK (SIM_BFIN_TRACE_LEN - 1)
+
+struct bfin_trace_entry
+{
+ bu32 src, dst;
+};
+struct bfin_trace
+{
+ bu32 base;
+ struct bfin_trace_entry buffer[SIM_BFIN_TRACE_LEN];
+ int top, bottom;
+ bool mid;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 tbufctl, tbufstat;
+ char _pad[0x100 - 0x8];
+ bu32 tbuf;
+};
+#define mmr_base() offsetof(struct bfin_trace, tbufctl)
+#define mmr_offset(mmr) (offsetof(struct bfin_trace, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "TBUFCTL", "TBUFSTAT", [mmr_offset (tbuf) / 4] = "TBUF",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+/* Ugh, circular buffers. */
+#define TBUF_LEN(t) ((t)->top - (t)->bottom)
+#define TBUF_IDX(i) ((i) & SIM_BFIN_TRACE_LEN_MASK)
+/* TOP is the next slot to fill. */
+#define TBUF_TOP(t) (&(t)->buffer[TBUF_IDX ((t)->top)])
+/* LAST is the latest valid slot. */
+#define TBUF_LAST(t) (&(t)->buffer[TBUF_IDX ((t)->top - 1)])
+/* LAST_LAST is the second-to-last valid slot. */
+#define TBUF_LAST_LAST(t) (&(t)->buffer[TBUF_IDX ((t)->top - 2)])
+
+static unsigned
+bfin_trace_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_trace *trace = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+
+ value = dv_load_4 (source);
+ mmr_off = addr - trace->base;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(tbufctl):
+ trace->tbufctl = value;
+ break;
+ case mmr_offset(tbufstat):
+ case mmr_offset(tbuf):
+ /* Discard writes to these. */
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_trace_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_trace *trace = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+
+ mmr_off = addr - trace->base;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(tbufctl):
+ value = trace->tbufctl;
+ break;
+ case mmr_offset(tbufstat):
+ /* Hardware is limited to 16 entries, so to stay compatible with
+ software, limit the value to 16. For software algorithms that
+ keep reading while (TBUFSTAT != 0), they'll get all of it. */
+ value = MIN (TBUF_LEN (trace), 16);
+ break;
+ case mmr_offset(tbuf):
+ {
+ struct bfin_trace_entry *e;
+
+ if (TBUF_LEN (trace) == 0)
+ {
+ value = 0;
+ break;
+ }
+
+ e = TBUF_LAST (trace);
+ if (trace->mid)
+ {
+ value = e->src;
+ --trace->top;
+ }
+ else
+ value = e->dst;
+ trace->mid = !trace->mid;
+
+ break;
+ }
+ default:
+ while (1) /* Core MMRs -> exception -> doesn't return. */
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ dv_store_4 (dest, value);
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_trace_regs (struct hw *me, struct bfin_trace *trace)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_COREMMR_TRACE_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_TRACE_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ trace->base = attach_address;
+}
+
+static void
+bfin_trace_finish (struct hw *me)
+{
+ struct bfin_trace *trace;
+
+ trace = HW_ZALLOC (me, struct bfin_trace);
+
+ set_hw_data (me, trace);
+ set_hw_io_read_buffer (me, bfin_trace_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_trace_io_write_buffer);
+
+ attach_bfin_trace_regs (me, trace);
+}
+
+const struct hw_descriptor dv_bfin_trace_descriptor[] = {
+ {"bfin_trace", bfin_trace_finish,},
+ {NULL, NULL},
+};
+
+#define TRACE_STATE(cpu) DV_STATE_CACHED (cpu, trace)
+
+/* This is not re-entrant, but neither is the cpu state, so this shouldn't
+ be a big deal ... */
+void bfin_trace_queue (SIM_CPU *cpu, bu32 src_pc, bu32 dst_pc, int hwloop)
+{
+ struct bfin_trace *trace = TRACE_STATE (cpu);
+ struct bfin_trace_entry *e;
+ int len, ivg;
+
+ /* Only queue if powered. */
+ if (!(trace->tbufctl & TBUFPWR))
+ return;
+
+ /* Only queue if enabled. */
+ if (!(trace->tbufctl & TBUFEN))
+ return;
+
+ /* Ignore hardware loops.
+ XXX: This is what the hardware does, but an option to ignore
+ could be useful for debugging ... */
+ if (hwloop >= 0)
+ return;
+
+ /* Only queue if at right level. */
+ ivg = cec_get_ivg (cpu);
+ if (ivg == IVG_RST)
+ /* XXX: This is what the hardware does, but an option to ignore
+ could be useful for debugging ... */
+ return;
+ if (ivg <= IVG_EVX && (trace->tbufctl & TBUFOVF))
+ /* XXX: This is what the hardware does, but an option to ignore
+ could be useful for debugging ... just don't throw an
+ exception when full and in EVT{0..3}. */
+ return;
+
+ /* Are we full ? */
+ len = TBUF_LEN (trace);
+ if (len == SIM_BFIN_TRACE_LEN)
+ {
+ if (trace->tbufctl & TBUFOVF)
+ {
+ cec_exception (cpu, VEC_OVFLOW);
+ return;
+ }
+
+ /* Overwrite next entry. */
+ ++trace->bottom;
+ }
+
+ /* One level compression. */
+ if (len >= 1 && (trace->tbufctl & TBUFCMPLP))
+ {
+ e = TBUF_LAST (trace);
+ if (src_pc == (e->src & ~1) && dst_pc == (e->dst & ~1))
+ {
+ /* Hardware sets LSB when level is compressed. */
+ e->dst |= 1;
+ return;
+ }
+ }
+
+ /* Two level compression. */
+ if (len >= 2 && (trace->tbufctl & TBUFCMPLP_DOUBLE))
+ {
+ e = TBUF_LAST_LAST (trace);
+ if (src_pc == (e->src & ~1) && dst_pc == (e->dst & ~1))
+ {
+ /* Hardware sets LSB when level is compressed. */
+ e->src |= 1;
+ return;
+ }
+ }
+
+ e = TBUF_TOP (trace);
+ e->dst = dst_pc;
+ e->src = src_pc;
+ ++trace->top;
+}
diff --git a/sim/bfin/dv-bfin_trace.h b/sim/bfin/dv-bfin_trace.h
new file mode 100644
index 00000000000..3acfddf037b
--- /dev/null
+++ b/sim/bfin/dv-bfin_trace.h
@@ -0,0 +1,37 @@
+/* Blackfin Trace (TBUF) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_TRACE_H
+#define DV_BFIN_TRACE_H
+
+#define BFIN_COREMMR_TRACE_BASE 0xFFE06000
+#define BFIN_COREMMR_TRACE_SIZE (4 * 65)
+
+/* TBUFCTL Masks */
+#define TBUFPWR 0x0001
+#define TBUFEN 0x0002
+#define TBUFOVF 0x0004
+#define TBUFCMPLP_SINGLE 0x0008
+#define TBUFCMPLP_DOUBLE 0x0010
+#define TBUFCMPLP (TBUFCMPLP_SINGLE | TBUFCMPLP_DOUBLE)
+
+void bfin_trace_queue (SIM_CPU *, bu32 src_pc, bu32 dst_pc, int hwloop);
+
+#endif
diff --git a/sim/bfin/dv-bfin_twi.c b/sim/bfin/dv-bfin_twi.c
new file mode 100644
index 00000000000..4e6783ded5c
--- /dev/null
+++ b/sim/bfin/dv-bfin_twi.c
@@ -0,0 +1,227 @@
+/* Blackfin Two Wire Interface (TWI) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_twi.h"
+
+/* XXX: This is merely a stub. */
+
+struct bfin_twi
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ bu16 xmt_fifo, rcv_fifo;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(clkdiv);
+ bu16 BFIN_MMR_16(control);
+ bu16 BFIN_MMR_16(slave_ctl);
+ bu16 BFIN_MMR_16(slave_stat);
+ bu16 BFIN_MMR_16(slave_addr);
+ bu16 BFIN_MMR_16(master_ctl);
+ bu16 BFIN_MMR_16(master_stat);
+ bu16 BFIN_MMR_16(master_addr);
+ bu16 BFIN_MMR_16(int_stat);
+ bu16 BFIN_MMR_16(int_mask);
+ bu16 BFIN_MMR_16(fifo_ctl);
+ bu16 BFIN_MMR_16(fifo_stat);
+ bu32 _pad0[20];
+ bu16 BFIN_MMR_16(xmt_data8);
+ bu16 BFIN_MMR_16(xmt_data16);
+ bu16 BFIN_MMR_16(rcv_data8);
+ bu16 BFIN_MMR_16(rcv_data16);
+};
+#define mmr_base() offsetof(struct bfin_twi, clkdiv)
+#define mmr_offset(mmr) (offsetof(struct bfin_twi, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const mmr_names[] = {
+ "TWI_CLKDIV", "TWI_CONTROL", "TWI_SLAVE_CTL", "TWI_SLAVE_STAT",
+ "TWI_SLAVE_ADDR", "TWI_MASTER_CTL", "TWI_MASTER_STAT", "TWI_MASTER_ADDR",
+ "TWI_INT_STAT", "TWI_INT_MASK", "TWI_FIFO_CTL", "TWI_FIFO_STAT",
+ [mmr_idx (xmt_data8)] = "TWI_XMT_DATA8", "TWI_XMT_DATA16", "TWI_RCV_DATA8",
+ "TWI_RCV_DATA16",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static unsigned
+bfin_twi_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_twi *twi = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *valuep;
+
+ value = dv_load_2 (source);
+ mmr_off = addr - twi->base;
+ valuep = (void *)((unsigned long)twi + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(clkdiv):
+ case mmr_offset(control):
+ case mmr_offset(slave_ctl):
+ case mmr_offset(slave_addr):
+ case mmr_offset(master_ctl):
+ case mmr_offset(master_addr):
+ case mmr_offset(int_mask):
+ case mmr_offset(fifo_ctl):
+ *valuep = value;
+ break;
+ case mmr_offset(int_stat):
+ dv_w1c_2 (valuep, value, 0);
+ break;
+ case mmr_offset(master_stat):
+ dv_w1c_2 (valuep, value, MPROG | SDASEN | SCLSEN | BUSBUSY);
+ break;
+ case mmr_offset(slave_stat):
+ case mmr_offset(fifo_stat):
+ case mmr_offset(rcv_data8):
+ case mmr_offset(rcv_data16):
+ /* These are all RO. XXX: Does these throw error ? */
+ break;
+ case mmr_offset(xmt_data8):
+ value &= 0xff;
+ case mmr_offset(xmt_data16):
+ twi->xmt_fifo = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_twi_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_twi *twi = hw_data (me);
+ bu32 mmr_off;
+ bu16 *valuep;
+
+ mmr_off = addr - twi->base;
+ valuep = (void *)((unsigned long)twi + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(clkdiv):
+ case mmr_offset(control):
+ case mmr_offset(slave_ctl):
+ case mmr_offset(slave_stat):
+ case mmr_offset(slave_addr):
+ case mmr_offset(master_ctl):
+ case mmr_offset(master_stat):
+ case mmr_offset(master_addr):
+ case mmr_offset(int_stat):
+ case mmr_offset(int_mask):
+ case mmr_offset(fifo_ctl):
+ case mmr_offset(fifo_stat):
+ dv_store_2 (dest, *valuep);
+ break;
+ case mmr_offset(rcv_data8):
+ case mmr_offset(rcv_data16):
+ dv_store_2 (dest, twi->rcv_fifo);
+ break;
+ case mmr_offset(xmt_data8):
+ case mmr_offset(xmt_data16):
+ /* These always read as 0. */
+ dv_store_2 (dest, 0);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_twi_ports[] = {
+ { "stat", 0, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_twi_regs (struct hw *me, struct bfin_twi *twi)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_TWI_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_TWI_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ twi->base = attach_address;
+}
+
+static void
+bfin_twi_finish (struct hw *me)
+{
+ struct bfin_twi *twi;
+
+ twi = HW_ZALLOC (me, struct bfin_twi);
+
+ set_hw_data (me, twi);
+ set_hw_io_read_buffer (me, bfin_twi_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_twi_io_write_buffer);
+ set_hw_ports (me, bfin_twi_ports);
+
+ attach_bfin_twi_regs (me, twi);
+}
+
+const struct hw_descriptor dv_bfin_twi_descriptor[] = {
+ {"bfin_twi", bfin_twi_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_twi.h b/sim/bfin/dv-bfin_twi.h
new file mode 100644
index 00000000000..91899994959
--- /dev/null
+++ b/sim/bfin/dv-bfin_twi.h
@@ -0,0 +1,38 @@
+/* Blackfin Two Wire Interface (TWI) model
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_TWI_H
+#define DV_BFIN_TWI_H
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_TWI_SIZE 0x90
+
+/* TWI_MASTER_STAT Masks */
+#define MPROG (1 << 0)
+#define LOSTARG (1 << 1)
+#define ANAK (1 << 2)
+#define DNAK (1 << 3)
+#define BUFRDERR (1 << 4)
+#define BUFWRERR (1 << 5)
+#define SDASEN (1 << 6)
+#define SCLSEN (1 << 7)
+#define BUSBUSY (1 << 8)
+
+#endif
diff --git a/sim/bfin/dv-bfin_uart.c b/sim/bfin/dv-bfin_uart.c
new file mode 100644
index 00000000000..be9038d3998
--- /dev/null
+++ b/sim/bfin/dv-bfin_uart.c
@@ -0,0 +1,437 @@
+/* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
+ For "old style" UARTs on BF53x/etc... parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "dv-sockser.h"
+#include "devices.h"
+#include "dv-bfin_uart.h"
+
+/* XXX: Should we bother emulating the TX/RX FIFOs ? */
+
+/* Internal state needs to be the same as bfin_uart2. */
+struct bfin_uart
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ /* This is aliased to DLH. */
+ bu16 ier;
+ /* These are aliased to DLL. */
+ bu16 thr, rbr;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(dll);
+ bu16 BFIN_MMR_16(dlh);
+ bu16 BFIN_MMR_16(iir);
+ bu16 BFIN_MMR_16(lcr);
+ bu16 BFIN_MMR_16(mcr);
+ bu16 BFIN_MMR_16(lsr);
+ bu16 BFIN_MMR_16(msr);
+ bu16 BFIN_MMR_16(scr);
+ bu16 _pad0[2];
+ bu16 BFIN_MMR_16(gctl);
+};
+#define mmr_base() offsetof(struct bfin_uart, dll)
+#define mmr_offset(mmr) (offsetof(struct bfin_uart, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "UART_RBR/UART_THR", "UART_IER", "UART_IIR", "UART_LCR", "UART_MCR",
+ "UART_LSR", "UART_MSR", "UART_SCR", "<INV>", "UART_GCTL",
+};
+static const char *mmr_name (struct bfin_uart *uart, bu32 idx)
+{
+ if (uart->lcr & DLAB)
+ if (idx < 2)
+ return idx == 0 ? "UART_DLL" : "UART_DLH";
+ return mmr_names[idx];
+}
+#define mmr_name(off) mmr_name (uart, (off) / 4)
+
+#ifndef HAVE_DV_SOCKSER
+# define dv_sockser_status(sd) -1
+# define dv_sockser_write(sd, byte) do { ; } while (0)
+# define dv_sockser_read(sd) 0xff
+#endif
+
+static void
+bfin_uart_poll (struct hw *me, void *data)
+{
+ struct bfin_uart *uart = data;
+ bu16 lsr;
+
+ uart->handler = NULL;
+
+ lsr = bfin_uart_get_status (me);
+ if (lsr & DR)
+ hw_port_event (me, DV_PORT_RX, 1);
+
+ bfin_uart_reschedule (me);
+}
+
+void
+bfin_uart_reschedule (struct hw *me)
+{
+ struct bfin_uart *uart = hw_data (me);
+
+ if (uart->ier & ERBFI)
+ {
+ if (!uart->handler)
+ uart->handler = hw_event_queue_schedule (me, 10000,
+ bfin_uart_poll, uart);
+ }
+ else
+ {
+ if (uart->handler)
+ {
+ hw_event_queue_deschedule (me, uart->handler);
+ uart->handler = NULL;
+ }
+ }
+}
+
+bu16
+bfin_uart_write_byte (struct hw *me, bu16 thr)
+{
+ unsigned char ch = thr;
+ bfin_uart_write_buffer (me, &ch, 1);
+ return thr;
+}
+
+static unsigned
+bfin_uart_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_uart *uart = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *valuep;
+
+ value = dv_load_2 (source);
+ mmr_off = addr - uart->base;
+ valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+
+ /* XXX: All MMRs are "8bit" ... what happens to high 8bits ? */
+ switch (mmr_off)
+ {
+ case mmr_offset(dll):
+ if (uart->lcr & DLAB)
+ uart->dll = value;
+ else
+ {
+ uart->thr = bfin_uart_write_byte (me, value);
+
+ if (uart->ier & ETBEI)
+ hw_port_event (me, DV_PORT_TX, 1);
+ }
+ break;
+ case mmr_offset(dlh):
+ if (uart->lcr & DLAB)
+ uart->dlh = value;
+ else
+ {
+ uart->ier = value;
+ bfin_uart_reschedule (me);
+ }
+ break;
+ case mmr_offset(iir):
+ case mmr_offset(lsr):
+ /* XXX: Writes are ignored ? */
+ break;
+ case mmr_offset(lcr):
+ case mmr_offset(mcr):
+ case mmr_offset(scr):
+ case mmr_offset(gctl):
+ *valuep = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+/* Switch between socket and stdin on the fly. */
+bu16
+bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bool *fresh)
+{
+ SIM_DESC sd = hw_system (me);
+ struct bfin_uart *uart = hw_data (me);
+ int status = dv_sockser_status (sd);
+ bool _fresh;
+
+ /* NB: The "uart" here may only use interal state. */
+
+ if (!fresh)
+ fresh = &_fresh;
+
+ *fresh = false;
+ if (status & DV_SOCKSER_DISCONNECTED)
+ {
+ if (uart->saved_count > 0)
+ {
+ *fresh = true;
+ rbr = uart->saved_byte;
+ --uart->saved_count;
+ }
+ else
+ {
+ char byte;
+ int ret = sim_io_poll_read (sd, 0/*STDIN*/, &byte, 1);
+ if (ret > 0)
+ {
+ *fresh = true;
+ rbr = byte;
+ }
+ }
+ }
+ else
+ rbr = dv_sockser_read (sd);
+
+ return rbr;
+}
+
+bu16
+bfin_uart_get_status (struct hw *me)
+{
+ SIM_DESC sd = hw_system (me);
+ struct bfin_uart *uart = hw_data (me);
+ int status = dv_sockser_status (sd);
+ bu16 lsr = 0;
+
+ if (status & DV_SOCKSER_DISCONNECTED)
+ {
+ if (uart->saved_count <= 0)
+ uart->saved_count = sim_io_poll_read (sd, 0/*STDIN*/,
+ &uart->saved_byte, 1);
+ lsr |= TEMT | THRE | (uart->saved_count > 0 ? DR : 0);
+ }
+ else
+ lsr |= (status & DV_SOCKSER_INPUT_EMPTY ? 0 : DR) |
+ (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0);
+
+ return lsr;
+}
+
+static unsigned
+bfin_uart_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_uart *uart = hw_data (me);
+ bu32 mmr_off;
+ bu16 *valuep;
+
+ mmr_off = addr - uart->base;
+ valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(dll):
+ if (uart->lcr & DLAB)
+ dv_store_2 (dest, uart->dll);
+ else
+ {
+ uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, NULL);
+ dv_store_2 (dest, uart->rbr);
+ }
+ break;
+ case mmr_offset(dlh):
+ if (uart->lcr & DLAB)
+ dv_store_2 (dest, uart->dlh);
+ else
+ dv_store_2 (dest, uart->ier);
+ break;
+ case mmr_offset(lsr):
+ /* XXX: Reads are destructive on most parts, but not all ... */
+ uart->lsr |= bfin_uart_get_status (me);
+ dv_store_2 (dest, *valuep);
+ uart->lsr = 0;
+ break;
+ case mmr_offset(iir):
+ /* XXX: Reads are destructive ... */
+ case mmr_offset(lcr):
+ case mmr_offset(mcr):
+ case mmr_offset(scr):
+ case mmr_offset(gctl):
+ dv_store_2 (dest, *valuep);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+unsigned
+bfin_uart_read_buffer (struct hw *me, unsigned char *buffer, unsigned nr_bytes)
+{
+ SIM_DESC sd = hw_system (me);
+ struct bfin_uart *uart = hw_data (me);
+ int status = dv_sockser_status (sd);
+ unsigned i = 0;
+
+ if (status & DV_SOCKSER_DISCONNECTED)
+ {
+ int ret;
+
+ while (uart->saved_count > 0 && i < nr_bytes)
+ {
+ buffer[i++] = uart->saved_byte;
+ --uart->saved_count;
+ }
+
+ ret = sim_io_poll_read (sd, 0/*STDIN*/, (char *) buffer, nr_bytes - i);
+ if (ret > 0)
+ i += ret;
+ }
+ else
+ buffer[i++] = dv_sockser_read (sd);
+
+ return i;
+}
+
+static unsigned
+bfin_uart_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ HW_TRACE_DMA_READ ();
+ return bfin_uart_read_buffer (me, dest, nr_bytes);
+}
+
+unsigned
+bfin_uart_write_buffer (struct hw *me, const unsigned char *buffer,
+ unsigned nr_bytes)
+{
+ SIM_DESC sd = hw_system (me);
+ int status = dv_sockser_status (sd);
+
+ if (status & DV_SOCKSER_DISCONNECTED)
+ {
+ sim_io_write_stdout (sd, (const char *) buffer, nr_bytes);
+ sim_io_flush_stdout (sd);
+ }
+ else
+ {
+ /* Normalize errors to a value of 0. */
+ int ret = dv_sockser_write_buffer (sd, buffer, nr_bytes);
+ nr_bytes = CLAMP (ret, 0, nr_bytes);
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_uart_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ struct bfin_uart *uart = hw_data (me);
+ unsigned ret;
+
+ HW_TRACE_DMA_WRITE ();
+
+ ret = bfin_uart_write_buffer (me, source, nr_bytes);
+
+ if (ret == nr_bytes && (uart->ier & ETBEI))
+ hw_port_event (me, DV_PORT_TX, 1);
+
+ return ret;
+}
+
+static const struct hw_port_descriptor bfin_uart_ports[] = {
+ { "tx", DV_PORT_TX, 0, output_port, },
+ { "rx", DV_PORT_RX, 0, output_port, },
+ { "stat", DV_PORT_STAT, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_uart_regs (struct hw *me, struct bfin_uart *uart)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_UART_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_UART_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ uart->base = attach_address;
+}
+
+static void
+bfin_uart_finish (struct hw *me)
+{
+ struct bfin_uart *uart;
+
+ uart = HW_ZALLOC (me, struct bfin_uart);
+
+ set_hw_data (me, uart);
+ set_hw_io_read_buffer (me, bfin_uart_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_uart_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_uart_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_uart_dma_write_buffer);
+ set_hw_ports (me, bfin_uart_ports);
+
+ attach_bfin_uart_regs (me, uart);
+
+ /* Initialize the UART. */
+ uart->dll = 0x0001;
+ uart->iir = 0x0001;
+ uart->lsr = 0x0060;
+}
+
+const struct hw_descriptor dv_bfin_uart_descriptor[] = {
+ {"bfin_uart", bfin_uart_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_uart.h b/sim/bfin/dv-bfin_uart.h
new file mode 100644
index 00000000000..1d144d49048
--- /dev/null
+++ b/sim/bfin/dv-bfin_uart.h
@@ -0,0 +1,49 @@
+/* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
+ For "old style" UARTs on BF53x/etc... parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_UART_H
+#define DV_BFIN_UART_H
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_UART_SIZE 0x30
+
+struct bfin_uart;
+bu16 bfin_uart_get_next_byte (struct hw *, bu16, bool *fresh);
+bu16 bfin_uart_write_byte (struct hw *, bu16);
+bu16 bfin_uart_get_status (struct hw *);
+unsigned bfin_uart_write_buffer (struct hw *, const unsigned char *, unsigned);
+unsigned bfin_uart_read_buffer (struct hw *, unsigned char *, unsigned);
+void bfin_uart_reschedule (struct hw *);
+
+/* UART_LCR */
+#define DLAB (1 << 7)
+
+/* UART_LSR */
+#define TEMT (1 << 6)
+#define THRE (1 << 5)
+#define DR (1 << 0)
+
+/* UART_IER */
+#define ERBFI (1 << 0)
+#define ETBEI (1 << 1)
+#define ELSI (1 << 2)
+
+#endif
diff --git a/sim/bfin/dv-bfin_uart2.c b/sim/bfin/dv-bfin_uart2.c
new file mode 100644
index 00000000000..dd09c5e5750
--- /dev/null
+++ b/sim/bfin/dv-bfin_uart2.c
@@ -0,0 +1,258 @@
+/* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
+ For "new style" UARTs on BF50x/BF54x parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_uart2.h"
+
+/* XXX: Should we bother emulating the TX/RX FIFOs ? */
+
+/* Internal state needs to be the same as bfin_uart. */
+struct bfin_uart
+{
+ /* This top portion matches common dv_bfin struct. */
+ bu32 base;
+ struct hw *dma_master;
+ bool acked;
+
+ struct hw_event *handler;
+ char saved_byte;
+ int saved_count;
+
+ /* Accessed indirectly by ier_{set,clear}. */
+ bu16 ier;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(dll);
+ bu16 BFIN_MMR_16(dlh);
+ bu16 BFIN_MMR_16(gctl);
+ bu16 BFIN_MMR_16(lcr);
+ bu16 BFIN_MMR_16(mcr);
+ bu16 BFIN_MMR_16(lsr);
+ bu16 BFIN_MMR_16(msr);
+ bu16 BFIN_MMR_16(scr);
+ bu16 BFIN_MMR_16(ier_set);
+ bu16 BFIN_MMR_16(ier_clear);
+ bu16 BFIN_MMR_16(thr);
+ bu16 BFIN_MMR_16(rbr);
+};
+#define mmr_base() offsetof(struct bfin_uart, dll)
+#define mmr_offset(mmr) (offsetof(struct bfin_uart, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "UART_DLL", "UART_DLH", "UART_GCTL", "UART_LCR", "UART_MCR", "UART_LSR",
+ "UART_MSR", "UART_SCR", "UART_IER_SET", "UART_IER_CLEAR", "UART_THR",
+ "UART_RBR",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static unsigned
+bfin_uart_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_uart *uart = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *valuep;
+
+ value = dv_load_2 (source);
+ mmr_off = addr - uart->base;
+ valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, true);
+
+ /* XXX: All MMRs are "8bit" ... what happens to high 8bits ? */
+
+ switch (mmr_off)
+ {
+ case mmr_offset(thr):
+ uart->thr = bfin_uart_write_byte (me, value);
+ if (uart->ier & ETBEI)
+ hw_port_event (me, DV_PORT_TX, 1);
+ break;
+ case mmr_offset(ier_set):
+ uart->ier |= value;
+ break;
+ case mmr_offset(ier_clear):
+ dv_w1c_2 (&uart->ier, value, 0);
+ break;
+ case mmr_offset(lsr):
+ dv_w1c_2 (valuep, value, TEMT | THRE | DR);
+ break;
+ case mmr_offset(rbr):
+ /* XXX: Writes are ignored ? */
+ break;
+ case mmr_offset(msr):
+ dv_w1c_2 (valuep, value, SCTS);
+ break;
+ case mmr_offset(dll):
+ case mmr_offset(dlh):
+ case mmr_offset(gctl):
+ case mmr_offset(lcr):
+ case mmr_offset(mcr):
+ case mmr_offset(scr):
+ *valuep = value;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_uart_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_uart *uart = hw_data (me);
+ bu32 mmr_off;
+ bu16 *valuep;
+
+ mmr_off = addr - uart->base;
+ valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+
+ switch (mmr_off)
+ {
+ case mmr_offset(rbr):
+ uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, NULL);
+ dv_store_2 (dest, uart->rbr);
+ break;
+ case mmr_offset(ier_set):
+ case mmr_offset(ier_clear):
+ dv_store_2 (dest, uart->ier);
+ bfin_uart_reschedule (me);
+ break;
+ case mmr_offset(lsr):
+ uart->lsr |= bfin_uart_get_status (me);
+ case mmr_offset(thr):
+ case mmr_offset(msr):
+ case mmr_offset(dll):
+ case mmr_offset(dlh):
+ case mmr_offset(gctl):
+ case mmr_offset(lcr):
+ case mmr_offset(mcr):
+ case mmr_offset(scr):
+ dv_store_2 (dest, *valuep);
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_uart_dma_read_buffer (struct hw *me, void *dest, int space,
+ unsigned_word addr, unsigned nr_bytes)
+{
+ HW_TRACE_DMA_READ ();
+ return bfin_uart_read_buffer (me, dest, nr_bytes);
+}
+
+static unsigned
+bfin_uart_dma_write_buffer (struct hw *me, const void *source,
+ int space, unsigned_word addr,
+ unsigned nr_bytes,
+ int violate_read_only_section)
+{
+ struct bfin_uart *uart = hw_data (me);
+ unsigned ret;
+
+ HW_TRACE_DMA_WRITE ();
+
+ ret = bfin_uart_write_buffer (me, source, nr_bytes);
+
+ if (ret == nr_bytes && (uart->ier & ETBEI))
+ hw_port_event (me, DV_PORT_TX, 1);
+
+ return ret;
+}
+
+static const struct hw_port_descriptor bfin_uart_ports[] = {
+ { "tx", DV_PORT_TX, 0, output_port, },
+ { "rx", DV_PORT_RX, 0, output_port, },
+ { "stat", DV_PORT_STAT, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+attach_bfin_uart_regs (struct hw *me, struct bfin_uart *uart)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_UART2_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_UART2_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ uart->base = attach_address;
+}
+
+static void
+bfin_uart_finish (struct hw *me)
+{
+ struct bfin_uart *uart;
+
+ uart = HW_ZALLOC (me, struct bfin_uart);
+
+ set_hw_data (me, uart);
+ set_hw_io_read_buffer (me, bfin_uart_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_uart_io_write_buffer);
+ set_hw_dma_read_buffer (me, bfin_uart_dma_read_buffer);
+ set_hw_dma_write_buffer (me, bfin_uart_dma_write_buffer);
+ set_hw_ports (me, bfin_uart_ports);
+
+ attach_bfin_uart_regs (me, uart);
+
+ /* Initialize the UART. */
+ uart->dll = 0x0001;
+ uart->lsr = 0x0060;
+}
+
+const struct hw_descriptor dv_bfin_uart2_descriptor[] = {
+ {"bfin_uart2", bfin_uart_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_uart2.h b/sim/bfin/dv-bfin_uart2.h
new file mode 100644
index 00000000000..f8269a404c5
--- /dev/null
+++ b/sim/bfin/dv-bfin_uart2.h
@@ -0,0 +1,33 @@
+/* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
+ For "new style" UARTs on BF50x/BF54x parts.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_UART2_H
+#define DV_BFIN_UART2_H
+
+#include "dv-bfin_uart.h"
+
+/* XXX: This should be pushed into the model data. */
+#define BFIN_MMR_UART2_SIZE 0x30
+
+/* UART_MSR */
+#define SCTS (1 << 0)
+
+#endif
diff --git a/sim/bfin/dv-bfin_wdog.c b/sim/bfin/dv-bfin_wdog.c
new file mode 100644
index 00000000000..4aada471708
--- /dev/null
+++ b/sim/bfin/dv-bfin_wdog.c
@@ -0,0 +1,206 @@
+/* Blackfin Watchdog (WDOG) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "dv-sockser.h"
+#include "devices.h"
+#include "dv-bfin_wdog.h"
+
+/* XXX: Should we bother emulating the TX/RX FIFOs ? */
+
+struct bfin_wdog
+{
+ bu32 base;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu16 BFIN_MMR_16(ctl);
+ bu32 cnt, stat;
+};
+#define mmr_base() offsetof(struct bfin_wdog, ctl)
+#define mmr_offset(mmr) (offsetof(struct bfin_wdog, mmr) - mmr_base())
+
+static const char * const mmr_names[] = {
+ "WDOG_CTL", "WDOG_CNT", "WDOG_STAT",
+};
+#define mmr_name(off) mmr_names[(off) / 4]
+
+static bool
+bfin_wdog_enabled (struct bfin_wdog *wdog)
+{
+ return ((wdog->ctl & WDEN) != WDDIS);
+}
+
+static unsigned
+bfin_wdog_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_wdog *wdog = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ if (nr_bytes == 4)
+ value = dv_load_4 (source);
+ else
+ value = dv_load_2 (source);
+
+ mmr_off = addr - wdog->base;
+ valuep = (void *)((unsigned long)wdog + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(ctl):
+ dv_w1c_2_partial (value16p, value, WDRO);
+ /* XXX: Should enable an event here to handle timeouts. */
+ break;
+
+ case mmr_offset(cnt):
+ /* Writes are discarded when enabeld. */
+ if (!bfin_wdog_enabled (wdog))
+ {
+ *value32p = value;
+ /* Writes to CNT preloads the STAT. */
+ wdog->stat = wdog->cnt;
+ }
+ break;
+
+ case mmr_offset(stat):
+ /* When enabled, writes to STAT reload the counter. */
+ if (bfin_wdog_enabled (wdog))
+ wdog->stat = wdog->cnt;
+ /* XXX: When disabled, are writes just ignored ? */
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_wdog_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct bfin_wdog *wdog = hw_data (me);
+ bu32 mmr_off;
+ bu16 *value16p;
+ bu32 *value32p;
+ void *valuep;
+
+ mmr_off = addr - wdog->base;
+ valuep = (void *)((unsigned long)wdog + mmr_base() + mmr_off);
+ value16p = valuep;
+ value32p = valuep;
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(ctl):
+ dv_bfin_mmr_require_16 (me, addr, nr_bytes, false);
+ dv_store_2 (dest, *value16p);
+ break;
+
+ case mmr_offset(cnt):
+ case mmr_offset(stat):
+ dv_store_4 (dest, *value32p);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static const struct hw_port_descriptor bfin_wdog_ports[] = {
+ { "reset", WDEV_RESET, 0, output_port, },
+ { "nmi", WDEV_NMI, 0, output_port, },
+ { "gpi", WDEV_GPI, 0, output_port, },
+ { NULL, 0, 0, 0, },
+};
+
+static void
+bfin_wdog_port_event (struct hw *me, int my_port, struct hw *source,
+ int source_port, int level)
+{
+ struct bfin_wdog *wdog = hw_data (me);
+ bu16 wdev;
+
+ wdog->ctl |= WDRO;
+ wdev = (wdog->ctl & WDEV);
+ if (wdev != WDEV_NONE)
+ hw_port_event (me, wdev, 1);
+}
+
+static void
+attach_bfin_wdog_regs (struct hw *me, struct bfin_wdog *wdog)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_MMR_WDOG_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_WDOG_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ wdog->base = attach_address;
+}
+
+static void
+bfin_wdog_finish (struct hw *me)
+{
+ struct bfin_wdog *wdog;
+
+ wdog = HW_ZALLOC (me, struct bfin_wdog);
+
+ set_hw_data (me, wdog);
+ set_hw_io_read_buffer (me, bfin_wdog_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_wdog_io_write_buffer);
+ set_hw_ports (me, bfin_wdog_ports);
+ set_hw_port_event (me, bfin_wdog_port_event);
+
+ attach_bfin_wdog_regs (me, wdog);
+
+ /* Initialize the Watchdog. */
+ wdog->ctl = WDDIS;
+}
+
+const struct hw_descriptor dv_bfin_wdog_descriptor[] = {
+ {"bfin_wdog", bfin_wdog_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_wdog.h b/sim/bfin/dv-bfin_wdog.h
new file mode 100644
index 00000000000..9be602dbd3b
--- /dev/null
+++ b/sim/bfin/dv-bfin_wdog.h
@@ -0,0 +1,36 @@
+/* Blackfin Watchdog (WDOG) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_WDOG_H
+#define DV_BFIN_WDOG_H
+
+#define BFIN_MMR_WDOG_SIZE (4 * 3)
+
+/* WDOG_CTL */
+#define WDEV 0x0006 /* event generated on roll over */
+#define WDEV_RESET 0x0000 /* generate reset event on roll over */
+#define WDEV_NMI 0x0002 /* generate NMI event on roll over */
+#define WDEV_GPI 0x0004 /* generate GP IRQ on roll over */
+#define WDEV_NONE 0x0006 /* no event on roll over */
+#define WDEN 0x0FF0 /* enable watchdog */
+#define WDDIS 0x0AD0 /* disable watchdog */
+#define WDRO 0x8000 /* watchdog rolled over latch */
+
+#endif
diff --git a/sim/bfin/dv-bfin_wp.c b/sim/bfin/dv-bfin_wp.c
new file mode 100644
index 00000000000..efa0804fe66
--- /dev/null
+++ b/sim/bfin/dv-bfin_wp.c
@@ -0,0 +1,188 @@
+/* Blackfin Watchpoint (WP) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+#include "dv-bfin_wp.h"
+
+/* XXX: This is mostly a stub. */
+
+#define WPI_NUM 6 /* 6 instruction watchpoints. */
+#define WPD_NUM 2 /* 2 data watchpoints. */
+
+struct bfin_wp
+{
+ bu32 base;
+
+ /* Order after here is important -- matches hardware MMR layout. */
+ bu32 iactl;
+ bu32 _pad0[15];
+ bu32 ia[WPI_NUM];
+ bu32 _pad1[16 - WPI_NUM];
+ bu32 iacnt[WPI_NUM];
+ bu32 _pad2[32 - WPI_NUM];
+
+ bu32 dactl;
+ bu32 _pad3[15];
+ bu32 da[WPD_NUM];
+ bu32 _pad4[16 - WPD_NUM];
+ bu32 dacnt[WPD_NUM];
+ bu32 _pad5[32 - WPD_NUM];
+
+ bu32 stat;
+};
+#define mmr_base() offsetof(struct bfin_wp, iactl)
+#define mmr_offset(mmr) (offsetof(struct bfin_wp, mmr) - mmr_base())
+#define mmr_idx(mmr) (mmr_offset (mmr) / 4)
+
+static const char * const mmr_names[] = {
+ [mmr_idx (iactl)] = "WPIACTL",
+ [mmr_idx (ia)] = "WPIA0", "WPIA1", "WPIA2", "WPIA3", "WPIA4", "WPIA5",
+ [mmr_idx (iacnt)] = "WPIACNT0", "WPIACNT1", "WPIACNT2",
+ "WPIACNT3", "WPIACNT4", "WPIACNT5",
+ [mmr_idx (dactl)] = "WPDACTL",
+ [mmr_idx (da)] = "WPDA0", "WPDA1", "WPDA2", "WPDA3", "WPDA4", "WPDA5",
+ [mmr_idx (dacnt)] = "WPDACNT0", "WPDACNT1", "WPDACNT2",
+ "WPDACNT3", "WPDACNT4", "WPDACNT5",
+ [mmr_idx (stat)] = "WPSTAT",
+};
+#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
+
+static unsigned
+bfin_wp_io_write_buffer (struct hw *me, const void *source, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_wp *wp = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu32 *valuep;
+
+ value = dv_load_4 (source);
+ mmr_off = addr - wp->base;
+ valuep = (void *)((unsigned long)wp + mmr_base() + mmr_off);
+
+ HW_TRACE_WRITE ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(iactl):
+ case mmr_offset(ia[0]) ... mmr_offset(ia[WPI_NUM - 1]):
+ case mmr_offset(iacnt[0]) ... mmr_offset(iacnt[WPI_NUM - 1]):
+ case mmr_offset(dactl):
+ case mmr_offset(da[0]) ... mmr_offset(da[WPD_NUM - 1]):
+ case mmr_offset(dacnt[0]) ... mmr_offset(dacnt[WPD_NUM - 1]):
+ *valuep = value;
+ break;
+ case mmr_offset(stat):
+ /* Yes, the hardware is this dumb -- clear all bits on any write. */
+ *valuep = 0;
+ break;
+ default:
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+bfin_wp_io_read_buffer (struct hw *me, void *dest, int space,
+ address_word addr, unsigned nr_bytes)
+{
+ struct bfin_wp *wp = hw_data (me);
+ bu32 mmr_off;
+ bu32 value;
+ bu32 *valuep;
+
+ mmr_off = addr - wp->base;
+ valuep = (void *)((unsigned long)wp + mmr_base() + mmr_off);
+
+ HW_TRACE_READ ();
+
+ switch (mmr_off)
+ {
+ case mmr_offset(iactl):
+ case mmr_offset(ia[0]) ... mmr_offset(ia[WPI_NUM - 1]):
+ case mmr_offset(iacnt[0]) ... mmr_offset(iacnt[WPI_NUM - 1]):
+ case mmr_offset(dactl):
+ case mmr_offset(da[0]) ... mmr_offset(da[WPD_NUM - 1]):
+ case mmr_offset(dacnt[0]) ... mmr_offset(dacnt[WPD_NUM - 1]):
+ case mmr_offset(stat):
+ value = *valuep;
+ break;
+ default:
+ while (1) /* Core MMRs -> exception -> doesn't return. */
+ dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
+ break;
+ }
+
+ dv_store_4 (dest, value);
+
+ return nr_bytes;
+}
+
+static void
+attach_bfin_wp_regs (struct hw *me, struct bfin_wp *wp)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != BFIN_COREMMR_WP_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_WP_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ wp->base = attach_address;
+}
+
+static void
+bfin_wp_finish (struct hw *me)
+{
+ struct bfin_wp *wp;
+
+ wp = HW_ZALLOC (me, struct bfin_wp);
+
+ set_hw_data (me, wp);
+ set_hw_io_read_buffer (me, bfin_wp_io_read_buffer);
+ set_hw_io_write_buffer (me, bfin_wp_io_write_buffer);
+
+ attach_bfin_wp_regs (me, wp);
+}
+
+const struct hw_descriptor dv_bfin_wp_descriptor[] = {
+ {"bfin_wp", bfin_wp_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/dv-bfin_wp.h b/sim/bfin/dv-bfin_wp.h
new file mode 100644
index 00000000000..f6c0d80df57
--- /dev/null
+++ b/sim/bfin/dv-bfin_wp.h
@@ -0,0 +1,27 @@
+/* Blackfin Watchpoint (WP) model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DV_BFIN_WP_H
+#define DV_BFIN_WP_H
+
+#define BFIN_COREMMR_WP_BASE 0xFFE07000
+#define BFIN_COREMMR_WP_SIZE 0x204
+
+#endif
diff --git a/sim/bfin/dv-eth_phy.c b/sim/bfin/dv-eth_phy.c
new file mode 100644
index 00000000000..59eaecec98e
--- /dev/null
+++ b/sim/bfin/dv-eth_phy.c
@@ -0,0 +1,206 @@
+/* Ethernet Physical Receiver model.
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "devices.h"
+
+#ifdef HAVE_LINUX_MII_H
+
+/* Workaround old/broken linux headers. */
+#define _LINUX_TYPES_H
+#define __u16 unsigned short
+#include <linux/mii.h>
+
+#define REG_PHY_SIZE 0x20
+
+struct eth_phy
+{
+ bu32 base;
+ bu16 regs[REG_PHY_SIZE];
+};
+#define reg_base() offsetof(struct eth_phy, regs[0])
+#define reg_offset(reg) (offsetof(struct eth_phy, reg) - reg_base())
+#define reg_idx(reg) (reg_offset (reg) / 4)
+
+static const char * const reg_names[] = {
+ [MII_BMCR ] = "MII_BMCR",
+ [MII_BMSR ] = "MII_BMSR",
+ [MII_PHYSID1 ] = "MII_PHYSID1",
+ [MII_PHYSID2 ] = "MII_PHYSID2",
+ [MII_ADVERTISE ] = "MII_ADVERTISE",
+ [MII_LPA ] = "MII_LPA",
+ [MII_EXPANSION ] = "MII_EXPANSION",
+#ifdef MII_CTRL1000
+ [MII_CTRL1000 ] = "MII_CTRL1000",
+#endif
+#ifdef MII_STAT1000
+ [MII_STAT1000 ] = "MII_STAT1000",
+#endif
+#ifdef MII_ESTATUS
+ [MII_ESTATUS ] = "MII_ESTATUS",
+#endif
+ [MII_DCOUNTER ] = "MII_DCOUNTER",
+ [MII_FCSCOUNTER ] = "MII_FCSCOUNTER",
+ [MII_NWAYTEST ] = "MII_NWAYTEST",
+ [MII_RERRCOUNTER] = "MII_RERRCOUNTER",
+ [MII_SREVISION ] = "MII_SREVISION",
+ [MII_RESV1 ] = "MII_RESV1",
+ [MII_LBRERROR ] = "MII_LBRERROR",
+ [MII_PHYADDR ] = "MII_PHYADDR",
+ [MII_RESV2 ] = "MII_RESV2",
+ [MII_TPISTATUS ] = "MII_TPISTATUS",
+ [MII_NCONFIG ] = "MII_NCONFIG",
+};
+#define mmr_name(off) (reg_names[off] ? : "<INV>")
+#define mmr_off reg_off
+
+static unsigned
+eth_phy_io_write_buffer (struct hw *me, const void *source,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct eth_phy *phy = hw_data (me);
+ bu16 reg_off;
+ bu16 value;
+ bu16 *valuep;
+
+ value = dv_load_2 (source);
+
+ reg_off = addr - phy->base;
+ valuep = (void *)((unsigned long)phy + reg_base() + reg_off);
+
+ HW_TRACE_WRITE ();
+
+ switch (reg_off)
+ {
+ case MII_BMCR:
+ *valuep = value;
+ break;
+ case MII_PHYSID1:
+ case MII_PHYSID2:
+ /* Discard writes to these. */
+ break;
+ default:
+ /* XXX: Discard writes to unknown regs ? */
+ *valuep = value;
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static unsigned
+eth_phy_io_read_buffer (struct hw *me, void *dest,
+ int space, address_word addr, unsigned nr_bytes)
+{
+ struct eth_phy *phy = hw_data (me);
+ bu16 reg_off;
+ bu16 *valuep;
+
+ reg_off = addr - phy->base;
+ valuep = (void *)((unsigned long)phy + reg_base() + reg_off);
+
+ HW_TRACE_READ ();
+
+ switch (reg_off)
+ {
+ case MII_BMCR:
+ dv_store_2 (dest, *valuep);
+ break;
+ case MII_BMSR:
+ /* XXX: Let people control this ? */
+ *valuep = BMSR_100FULL | BMSR_100HALF | BMSR_10FULL | BMSR_10HALF |
+ BMSR_ANEGCOMPLETE | BMSR_ANEGCAPABLE | BMSR_LSTATUS;
+ dv_store_2 (dest, *valuep);
+ break;
+ case MII_LPA:
+ /* XXX: Let people control this ? */
+ *valuep = LPA_100FULL | LPA_100HALF | LPA_10FULL | LPA_10HALF;
+ dv_store_2 (dest, *valuep);
+ break;
+ default:
+ dv_store_2 (dest, *valuep);
+ break;
+ }
+
+ return nr_bytes;
+}
+
+static void
+attach_eth_phy_regs (struct hw *me, struct eth_phy *phy)
+{
+ address_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space, &attach_address, me);
+ hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+
+ if (attach_size != REG_PHY_SIZE)
+ hw_abort (me, "\"reg\" size must be %#x", REG_PHY_SIZE);
+
+ hw_attach_address (hw_parent (me),
+ 0, attach_space, attach_address, attach_size, me);
+
+ phy->base = attach_address;
+}
+
+static void
+eth_phy_finish (struct hw *me)
+{
+ struct eth_phy *phy;
+
+ phy = HW_ZALLOC (me, struct eth_phy);
+
+ set_hw_data (me, phy);
+ set_hw_io_read_buffer (me, eth_phy_io_read_buffer);
+ set_hw_io_write_buffer (me, eth_phy_io_write_buffer);
+
+ attach_eth_phy_regs (me, phy);
+
+ /* Initialize the PHY. */
+ phy->regs[MII_PHYSID1] = 0; /* Unassigned Vendor */
+ phy->regs[MII_PHYSID2] = 0xAD; /* Product */
+}
+
+#else
+
+static void
+eth_phy_finish (struct hw *me)
+{
+ HW_TRACE ((me, "No linux/mii.h support found"));
+}
+
+#endif
+
+const struct hw_descriptor dv_eth_phy_descriptor[] = {
+ {"eth_phy", eth_phy_finish,},
+ {NULL, NULL},
+};
diff --git a/sim/bfin/gui.c b/sim/bfin/gui.c
new file mode 100644
index 00000000000..65f37355bcd
--- /dev/null
+++ b/sim/bfin/gui.c
@@ -0,0 +1,286 @@
+/* Blackfin GUI (SDL) helper code
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#ifdef HAVE_SDL
+# include <SDL.h>
+#endif
+#ifdef HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
+#include "libiberty.h"
+#include "gui.h"
+
+#ifdef HAVE_SDL
+
+static struct {
+ void *handle;
+ int (*Init) (Uint32 flags);
+ void (*Quit) (void);
+ SDL_Surface *(*SetVideoMode) (int width, int height, int bpp, Uint32 flags);
+ void (*WM_SetCaption) (const char *title, const char *icon);
+ int (*ShowCursor) (int toggle);
+ int (*LockSurface) (SDL_Surface *surface);
+ void (*UnlockSurface) (SDL_Surface *surface);
+ void (*GetRGB) (Uint32 pixel, const SDL_PixelFormat * const fmt, Uint8 *r, Uint8 *g, Uint8 *b);
+ Uint32 (*MapRGB) (const SDL_PixelFormat * const format, const Uint8 r, const Uint8 g, const Uint8 b);
+ void (*UpdateRect) (SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h);
+} sdl;
+
+static const char * const sdl_syms[] = {
+ "SDL_Init",
+ "SDL_Quit",
+ "SDL_SetVideoMode",
+ "SDL_WM_SetCaption",
+ "SDL_ShowCursor",
+ "SDL_LockSurface",
+ "SDL_UnlockSurface",
+ "SDL_GetRGB",
+ "SDL_MapRGB",
+ "SDL_UpdateRect",
+};
+
+struct gui_state {
+ SDL_Surface *screen;
+ const SDL_PixelFormat *format;
+ int throttle, throttle_limit;
+ enum gui_color color;
+ int curr_line;
+};
+
+/* Load the SDL lib on the fly to avoid hard linking against it. */
+static int
+bfin_gui_sdl_setup (void)
+{
+ int i;
+ uintptr_t **funcs;
+
+ if (sdl.handle)
+ return 0;
+
+ sdl.handle = dlopen ("libSDL-1.2.so.0", RTLD_LAZY);
+ if (sdl.handle == NULL)
+ return -1;
+
+ funcs = (void *) &sdl.Init;
+ for (i = 0; i < ARRAY_SIZE (sdl_syms); ++i)
+ {
+ funcs[i] = dlsym (sdl.handle, sdl_syms[i]);
+ if (funcs[i] == NULL)
+ {
+ dlclose (sdl.handle);
+ sdl.handle = NULL;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static const SDL_PixelFormat *bfin_gui_color_format (enum gui_color color);
+
+void *
+bfin_gui_setup (void *state, int enabled, int width, int height,
+ enum gui_color color)
+{
+ if (bfin_gui_sdl_setup ())
+ return NULL;
+
+ /* Create an SDL window if enabled and we don't have one yet. */
+ if (enabled && !state)
+ {
+ struct gui_state *gui = xmalloc (sizeof (*gui));
+ if (!gui)
+ return NULL;
+
+ if (sdl.Init (SDL_INIT_VIDEO))
+ goto error;
+
+ gui->color = color;
+ gui->format = bfin_gui_color_format (gui->color);
+ gui->screen = sdl.SetVideoMode (width, height, 32,
+ SDL_ANYFORMAT|SDL_HWSURFACE);
+ if (!gui->screen)
+ {
+ sdl.Quit();
+ goto error;
+ }
+
+ sdl.WM_SetCaption ("GDB Blackfin Simulator", NULL);
+ sdl.ShowCursor (0);
+ gui->curr_line = 0;
+ gui->throttle = 0;
+ gui->throttle_limit = 0xf; /* XXX: let people control this ? */
+ return gui;
+
+ error:
+ free (gui);
+ return NULL;
+ }
+
+ /* Else break down a window if disabled and we had one. */
+ else if (!enabled && state)
+ {
+ sdl.Quit();
+ free (state);
+ return NULL;
+ }
+
+ /* Retain existing state, whatever that may be. */
+ return state;
+}
+
+static int
+SDL_ConvertBlitLineFrom (const Uint8 *src, const SDL_PixelFormat * const format,
+ SDL_Surface *dst, int dsty)
+{
+ Uint8 r, g, b;
+ Uint32 *pixels;
+ unsigned i, j;
+
+ if (SDL_MUSTLOCK (dst))
+ if (sdl.LockSurface (dst))
+ return 1;
+
+ pixels = dst->pixels;
+ pixels += (dsty * dst->pitch / 4);
+
+ for (i = 0; i < dst->w; ++i)
+ {
+ /* Exract the packed source pixel; RGB or BGR. */
+ Uint32 pix = 0;
+ for (j = 0; j < format->BytesPerPixel; ++j)
+ if (format->Rshift)
+ pix = (pix << 8) | src[j];
+ else
+ pix = pix | ((Uint32)src[j] << (j * 8));
+
+ /* Unpack the source pixel into its components. */
+ sdl.GetRGB (pix, format, &r, &g, &b);
+ /* Translate into the screen pixel format. */
+ *pixels++ = sdl.MapRGB (dst->format, r, g, b);
+
+ src += format->BytesPerPixel;
+ }
+
+ if (SDL_MUSTLOCK (dst))
+ sdl.UnlockSurface (dst);
+
+ sdl.UpdateRect (dst, 0, dsty, dst->w, 1);
+
+ return 0;
+}
+
+unsigned
+bfin_gui_update (void *state, const void *source, unsigned nr_bytes)
+{
+ struct gui_state *gui = state;
+ int ret;
+
+ if (!gui)
+ return 0;
+
+ /* XXX: Make this an option ? */
+ gui->throttle = (gui->throttle + 1) & gui->throttle_limit;
+ if (gui->throttle)
+ return 0;
+
+ ret = SDL_ConvertBlitLineFrom (source, gui->format, gui->screen,
+ gui->curr_line);
+ if (ret)
+ return 0;
+
+ gui->curr_line = (gui->curr_line + 1) % gui->screen->h;
+
+ return nr_bytes;
+}
+
+#define FMASK(cnt, shift) (((1 << (cnt)) - 1) << (shift))
+#define _FORMAT(bpp, rcnt, gcnt, bcnt, acnt, rsh, gsh, bsh, ash) \
+ NULL, bpp, (bpp)/8, 8-(rcnt), 8-(gcnt), 8-(bcnt), 8-(acnt), rsh, gsh, bsh, ash, \
+ FMASK (rcnt, rsh), FMASK (gcnt, gsh), FMASK (bcnt, bsh), FMASK (acnt, ash),
+#define FORMAT(rcnt, gcnt, bcnt, acnt, rsh, gsh, bsh, ash) \
+ _FORMAT(((((rcnt) + (gcnt) + (bcnt) + (acnt)) + 7) / 8) * 8, \
+ rcnt, gcnt, bcnt, acnt, rsh, gsh, bsh, ash)
+
+static const SDL_PixelFormat sdl_rgb_565 = {
+ FORMAT (5, 6, 5, 0, 11, 5, 0, 0)
+};
+static const SDL_PixelFormat sdl_bgr_565 = {
+ FORMAT (5, 6, 5, 0, 0, 5, 11, 0)
+};
+static const SDL_PixelFormat sdl_rgb_888 = {
+ FORMAT (8, 8, 8, 0, 16, 8, 0, 0)
+};
+static const SDL_PixelFormat sdl_bgr_888 = {
+ FORMAT (8, 8, 8, 0, 0, 8, 16, 0)
+};
+static const SDL_PixelFormat sdl_rgba_8888 = {
+ FORMAT (8, 8, 8, 8, 24, 16, 8, 0)
+};
+
+static const struct {
+ const char *name;
+ const SDL_PixelFormat *format;
+ enum gui_color color;
+} color_spaces[] = {
+ { "rgb565", &sdl_rgb_565, GUI_COLOR_RGB_565, },
+ { "bgr565", &sdl_bgr_565, GUI_COLOR_BGR_565, },
+ { "rgb888", &sdl_rgb_888, GUI_COLOR_RGB_888, },
+ { "bgr888", &sdl_bgr_888, GUI_COLOR_BGR_888, },
+ { "rgba8888", &sdl_rgba_8888, GUI_COLOR_RGBA_8888, },
+};
+
+enum gui_color bfin_gui_color (const char *color)
+{
+ int i;
+
+ if (!color)
+ goto def;
+
+ for (i = 0; i < ARRAY_SIZE (color_spaces); ++i)
+ if (!strcmp (color, color_spaces[i].name))
+ return color_spaces[i].color;
+
+ /* Pick a random default. */
+ def:
+ return GUI_COLOR_RGB_888;
+}
+
+static const SDL_PixelFormat *bfin_gui_color_format (enum gui_color color)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE (color_spaces); ++i)
+ if (color == color_spaces[i].color)
+ return color_spaces[i].format;
+
+ return NULL;
+}
+
+int bfin_gui_color_depth (enum gui_color color)
+{
+ const SDL_PixelFormat *format = bfin_gui_color_format (color);
+ return format ? format->BitsPerPixel : 0;
+}
+
+#endif
diff --git a/sim/bfin/gui.h b/sim/bfin/gui.h
new file mode 100644
index 00000000000..3456ac903d2
--- /dev/null
+++ b/sim/bfin/gui.h
@@ -0,0 +1,50 @@
+/* Blackfin GUI (SDL) helper code
+
+ Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef BFIN_GUI_H
+#define BFIN_GUI_H
+
+#ifdef HAVE_SDL
+
+enum gui_color {
+ GUI_COLOR_RGB_565,
+ GUI_COLOR_BGR_565,
+ GUI_COLOR_RGB_888,
+ GUI_COLOR_BGR_888,
+ GUI_COLOR_RGBA_8888,
+};
+enum gui_color bfin_gui_color (const char *color);
+int bfin_gui_color_depth (enum gui_color color);
+
+void *bfin_gui_setup (void *state, int enabled, int height, int width,
+ enum gui_color color);
+
+unsigned bfin_gui_update (void *state, const void *source, unsigned nr_bytes);
+
+#else
+
+# define bfin_gui_color(...) 0
+# define bfin_gui_color_depth(...) 0
+# define bfin_gui_setup(...) NULL
+# define bfin_gui_update(...) 0
+
+#endif
+
+#endif
diff --git a/sim/bfin/insn_list.def b/sim/bfin/insn_list.def
new file mode 100644
index 00000000000..41ff91ca119
--- /dev/null
+++ b/sim/bfin/insn_list.def
@@ -0,0 +1,62 @@
+/* Blackfin instruction classes list
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+/* Only bother with insn groups rather than exact insn (for now?). */
+I(ProgCtrl_nop)
+I(ProgCtrl_branch)
+I(ProgCtrl_sync)
+I(ProgCtrl_cec)
+I(ProgCtrl_atomic)
+I(CaCTRL)
+I(PushPopReg)
+I(PushPopMultiple)
+I(ccMV)
+I(CCflag)
+I(CC2dreg)
+I(CC2stat)
+I(BRCC)
+I(UJUMP)
+I(REGMV)
+I(ALU2op)
+I(PTR2op)
+I(LOGI2op)
+I(COMP3op)
+I(COMPI2opD)
+I(COMPI2opP)
+I(LDSTpmod)
+I(dagMODim)
+I(dagMODik)
+I(dspLDST)
+I(LDST)
+I(LDSTiiFP)
+I(LDSTii)
+I(LoopSetup)
+I(LDIMMhalf)
+I(CALLa)
+I(LDSTidxI)
+I(linkage)
+I(dsp32mac)
+I(dsp32mult)
+I(dsp32alu)
+I(dsp32shift)
+I(dsp32shiftimm)
+I(psedoDEBUG)
+I(psedoOChar)
+I(psedodbg_assert)
diff --git a/sim/bfin/interp.c b/sim/bfin/interp.c
new file mode 100644
index 00000000000..1f8681df16a
--- /dev/null
+++ b/sim/bfin/interp.c
@@ -0,0 +1,1241 @@
+/* Simulator for Analog Devices Blackfin processors.
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "gdb/callback.h"
+#include "gdb/signals.h"
+#include "sim-main.h"
+#include "sim-hw.h"
+
+#include "targ-vals.h"
+
+/* The numbers here do not matter. They just need to be unique. */
+#define CB_SYS_ioctl 201
+#define CB_SYS_mmap2 202
+#define CB_SYS_munmap 203
+#define CB_SYS_dup2 204
+#define CB_SYS_getuid 205
+#define CB_SYS_getuid32 206
+#define CB_SYS_getgid 207
+#define CB_SYS_getgid32 208
+#define CB_SYS_setuid 209
+#define CB_SYS_setuid32 210
+#define CB_SYS_setgid 211
+#define CB_SYS_setgid32 212
+#define CB_SYS_pread 213
+#define CB_SYS__llseek 214
+#define CB_SYS_getcwd 215
+#define CB_SYS_stat64 216
+#define CB_SYS_lstat64 217
+#define CB_SYS_fstat64 218
+#define CB_SYS_ftruncate64 219
+#define CB_SYS_gettimeofday 220
+#define CB_SYS_access 221
+#include "linux-targ-map.h"
+#include "linux-fixed-code.h"
+
+#include "elf/common.h"
+#include "elf/external.h"
+#include "elf/internal.h"
+#include "elf/bfin.h"
+#include "elf-bfd.h"
+
+#include "dv-bfin_cec.h"
+#include "dv-bfin_mmu.h"
+
+#ifndef HAVE_GETUID
+# define getuid() 0
+#endif
+#ifndef HAVE_GETGID
+# define getgid() 0
+#endif
+#ifndef HAVE_GETEUID
+# define geteuid() 0
+#endif
+#ifndef HAVE_GETEGID
+# define getegid() 0
+#endif
+#ifndef HAVE_SETUID
+# define setuid(uid) -1
+#endif
+#ifndef HAVE_SETGID
+# define setgid(gid) -1
+#endif
+
+static const char stat_map_32[] =
+/* Linux kernel 32bit layout: */
+"st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
+"space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
+"st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
+/* uClibc public ABI 32bit layout:
+"st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
+"st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
+"st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
+"space,4"; */
+static const char stat_map_64[] =
+"st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
+"space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
+"st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
+
+/* Count the number of arguments in an argv. */
+static int
+count_argc (const char * const *argv)
+{
+ int i;
+
+ if (! argv)
+ return -1;
+
+ for (i = 0; argv[i] != NULL; ++i)
+ continue;
+ return i;
+}
+
+/* Read/write functions for system call interface. */
+
+static int
+syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
+ unsigned long taddr, char *buf, int bytes)
+{
+ SIM_DESC sd = (SIM_DESC) sc->p1;
+ SIM_CPU *cpu = (SIM_CPU *) sc->p2;
+
+ MAYBE_TRACE (CORE, cpu, "DBUS FETCH (syscall) %i bytes @ 0x%08lx", bytes, taddr);
+
+ return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
+}
+
+static int
+syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
+ unsigned long taddr, const char *buf, int bytes)
+{
+ SIM_DESC sd = (SIM_DESC) sc->p1;
+ SIM_CPU *cpu = (SIM_CPU *) sc->p2;
+
+ MAYBE_TRACE (CORE, cpu, "DBUS STORE (syscall) %i bytes @ 0x%08lx", bytes, taddr);
+
+ return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
+}
+
+/* Simulate a monitor trap, put the result into r0 and errno into r1
+ return offset by which to adjust pc. */
+
+void
+bfin_syscall (SIM_CPU *cpu)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ const char * const *argv = (void *)STATE_PROG_ARGV (sd);
+ host_callback *cb = STATE_CALLBACK (sd);
+ bu32 args[6];
+ CB_SYSCALL sc;
+ char *p;
+ char _tbuf[512], *tbuf = _tbuf;
+ int fmt_ret_hex = 0;
+
+ CB_SYSCALL_INIT (&sc);
+
+ if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
+ {
+ /* Linux syscall. */
+ sc.func = PREG (0);
+ sc.arg1 = args[0] = DREG (0);
+ sc.arg2 = args[1] = DREG (1);
+ sc.arg3 = args[2] = DREG (2);
+ sc.arg4 = args[3] = DREG (3);
+ /*sc.arg5 =*/ args[4] = DREG (4);
+ /*sc.arg6 =*/ args[5] = DREG (5);
+ }
+ else
+ {
+ /* libgloss syscall. */
+ sc.func = PREG (0);
+ sc.arg1 = args[0] = GET_LONG (DREG (0));
+ sc.arg2 = args[1] = GET_LONG (DREG (0) + 4);
+ sc.arg3 = args[2] = GET_LONG (DREG (0) + 8);
+ sc.arg4 = args[3] = GET_LONG (DREG (0) + 12);
+ /*sc.arg5 =*/ args[4] = GET_LONG (DREG (0) + 16);
+ /*sc.arg6 =*/ args[5] = GET_LONG (DREG (0) + 20);
+ }
+ sc.p1 = (PTR) sd;
+ sc.p2 = (PTR) cpu;
+ sc.read_mem = syscall_read_mem;
+ sc.write_mem = syscall_write_mem;
+
+ /* Common cb_syscall() handles most functions. */
+ switch (cb_target_to_host_syscall (cb, sc.func))
+ {
+ case CB_SYS_exit:
+ tbuf += sprintf (tbuf, "exit(%i)", args[0]);
+ sim_engine_halt (sd, cpu, NULL, PCREG, sim_exited, sc.arg1);
+
+#ifdef CB_SYS_argc
+ case CB_SYS_argc:
+ tbuf += sprintf (tbuf, "argc()");
+ sc.result = count_argc (argv);
+ break;
+ case CB_SYS_argnlen:
+ {
+ tbuf += sprintf (tbuf, "argnlen(%u)", args[0]);
+ if (sc.arg1 < count_argc (argv))
+ sc.result = strlen (argv[sc.arg1]);
+ else
+ sc.result = -1;
+ }
+ break;
+ case CB_SYS_argn:
+ {
+ tbuf += sprintf (tbuf, "argn(%u)", args[0]);
+ if (sc.arg1 < count_argc (argv))
+ {
+ const char *argn = argv[sc.arg1];
+ int len = strlen (argn);
+ int written = sc.write_mem (cb, &sc, sc.arg2, argn, len + 1);
+ if (written == len + 1)
+ sc.result = sc.arg2;
+ else
+ sc.result = -1;
+ }
+ else
+ sc.result = -1;
+ }
+ break;
+#endif
+
+ case CB_SYS_gettimeofday:
+ {
+ struct timeval _tv, *tv = &_tv;
+ struct timezone _tz, *tz = &_tz;
+
+ tbuf += sprintf (tbuf, "gettimeofday(%#x, %#x)", args[0], args[1]);
+
+ if (sc.arg1 == 0)
+ tv = NULL;
+ if (sc.arg2 == 0)
+ tz = NULL;
+ sc.result = gettimeofday (tv, tz);
+
+ if (sc.result == 0)
+ {
+ bu32 t;
+
+ if (tv)
+ {
+ t = tv->tv_sec;
+ sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
+ t = tv->tv_usec;
+ sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
+ }
+
+ if (sc.arg2)
+ {
+ t = tz->tz_minuteswest;
+ sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
+ t = tz->tz_dsttime;
+ sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
+ }
+ }
+ else
+ goto sys_finish;
+ }
+ break;
+
+ case CB_SYS_ioctl:
+ /* XXX: hack just enough to get basic stdio w/uClibc ... */
+ tbuf += sprintf (tbuf, "ioctl(%i, %#x, %u)", args[0], args[1], args[2]);
+ if (sc.arg2 == 0x5401)
+ {
+ sc.result = !isatty (sc.arg1);
+ sc.errcode = 0;
+ }
+ else
+ {
+ sc.result = -1;
+ sc.errcode = TARGET_EINVAL;
+ }
+ break;
+
+ case CB_SYS_mmap2:
+ {
+ static bu32 heap = BFIN_DEFAULT_MEM_SIZE / 2;
+
+ fmt_ret_hex = 1;
+ tbuf += sprintf (tbuf, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
+ args[0], args[1], args[2], args[3], args[4], args[5]);
+
+ sc.errcode = 0;
+
+ if (sc.arg4 & 0x20 /*MAP_ANONYMOUS*/)
+ /* XXX: We don't handle zeroing, but default is all zeros. */;
+ else if (args[4] >= MAX_CALLBACK_FDS)
+ sc.errcode = TARGET_ENOSYS;
+ else
+ {
+ char *data = xmalloc (sc.arg2);
+
+ /* XXX: Should add a cb->pread. */
+ if (pread (cb->fdmap[args[4]], data, sc.arg2, args[5] << 12) == sc.arg2)
+ sc.write_mem (cb, &sc, heap, data, sc.arg2);
+ else
+ sc.errcode = TARGET_EINVAL;
+
+ free (data);
+ }
+
+ if (sc.errcode)
+ {
+ sc.result = -1;
+ break;
+ }
+
+ sc.result = heap;
+ heap += sc.arg2;
+ /* Keep it page aligned. */
+ heap = ALIGN (heap, 4096);
+
+ break;
+ }
+
+ case CB_SYS_munmap:
+ /* XXX: meh, just lie for mmap(). */
+ tbuf += sprintf (tbuf, "munmap(%#x, %u)", args[0], args[1]);
+ sc.result = 0;
+ break;
+
+ case CB_SYS_dup2:
+ tbuf += sprintf (tbuf, "dup2(%i, %i)", args[0], args[1]);
+ if (sc.arg1 >= MAX_CALLBACK_FDS || sc.arg2 >= MAX_CALLBACK_FDS)
+ {
+ sc.result = -1;
+ sc.errcode = TARGET_EINVAL;
+ }
+ else
+ {
+ sc.result = dup2 (cb->fdmap[sc.arg1], cb->fdmap[sc.arg2]);
+ goto sys_finish;
+ }
+ break;
+
+ case CB_SYS__llseek:
+ tbuf += sprintf (tbuf, "llseek(%i, %u, %u, %#x, %u)",
+ args[0], args[1], args[2], args[3], args[4]);
+ sc.func = TARGET_LINUX_SYS_lseek;
+ if (sc.arg2)
+ {
+ sc.result = -1;
+ sc.errcode = TARGET_EINVAL;
+ }
+ else
+ {
+ sc.arg2 = sc.arg3;
+ sc.arg3 = args[4];
+ cb_syscall (cb, &sc);
+ if (sc.result != -1)
+ {
+ bu32 z = 0;
+ sc.write_mem (cb, &sc, args[3], (void *)&sc.result, 4);
+ sc.write_mem (cb, &sc, args[3] + 4, (void *)&z, 4);
+ }
+ }
+ break;
+
+ /* XXX: Should add a cb->pread. */
+ case CB_SYS_pread:
+ tbuf += sprintf (tbuf, "pread(%i, %#x, %u, %i)",
+ args[0], args[1], args[2], args[3]);
+ if (sc.arg1 >= MAX_CALLBACK_FDS)
+ {
+ sc.result = -1;
+ sc.errcode = TARGET_EINVAL;
+ }
+ else
+ {
+ long old_pos, read_result, read_errcode;
+
+ /* Get current filepos. */
+ sc.func = TARGET_LINUX_SYS_lseek;
+ sc.arg2 = 0;
+ sc.arg3 = SEEK_CUR;
+ cb_syscall (cb, &sc);
+ if (sc.result == -1)
+ break;
+ old_pos = sc.result;
+
+ /* Move to the new pos. */
+ sc.func = TARGET_LINUX_SYS_lseek;
+ sc.arg2 = args[3];
+ sc.arg3 = SEEK_SET;
+ cb_syscall (cb, &sc);
+ if (sc.result == -1)
+ break;
+
+ /* Read the data. */
+ sc.func = TARGET_LINUX_SYS_read;
+ sc.arg2 = args[1];
+ sc.arg3 = args[2];
+ cb_syscall (cb, &sc);
+ read_result = sc.result;
+ read_errcode = sc.errcode;
+
+ /* Move back to the old pos. */
+ sc.func = TARGET_LINUX_SYS_lseek;
+ sc.arg2 = old_pos;
+ sc.arg3 = SEEK_SET;
+ cb_syscall (cb, &sc);
+
+ sc.result = read_result;
+ sc.errcode = read_errcode;
+ }
+ break;
+
+ case CB_SYS_getcwd:
+ tbuf += sprintf (tbuf, "getcwd(%#x, %u)", args[0], args[1]);
+
+ p = alloca (sc.arg2);
+ if (getcwd (p, sc.arg2) == NULL)
+ {
+ sc.result = -1;
+ sc.errcode = TARGET_EINVAL;
+ }
+ else
+ {
+ sc.write_mem (cb, &sc, sc.arg1, p, sc.arg2);
+ sc.result = sc.arg1;
+ }
+ break;
+
+ case CB_SYS_stat64:
+ tbuf += sprintf (tbuf, "stat64(%#x, %u)", args[0], args[1]);
+ cb->stat_map = stat_map_64;
+ sc.func = TARGET_LINUX_SYS_stat;
+ cb_syscall (cb, &sc);
+ cb->stat_map = stat_map_32;
+ break;
+ case CB_SYS_lstat64:
+ tbuf += sprintf (tbuf, "lstat64(%#x, %u)", args[0], args[1]);
+ cb->stat_map = stat_map_64;
+ sc.func = TARGET_LINUX_SYS_lstat;
+ cb_syscall (cb, &sc);
+ cb->stat_map = stat_map_32;
+ break;
+ case CB_SYS_fstat64:
+ tbuf += sprintf (tbuf, "fstat64(%#x, %u)", args[0], args[1]);
+ cb->stat_map = stat_map_64;
+ sc.func = TARGET_LINUX_SYS_fstat;
+ cb_syscall (cb, &sc);
+ cb->stat_map = stat_map_32;
+ break;
+
+ case CB_SYS_ftruncate64:
+ tbuf += sprintf (tbuf, "ftruncate64(%u, %u)", args[0], args[1]);
+ sc.func = TARGET_LINUX_SYS_ftruncate;
+ cb_syscall (cb, &sc);
+ break;
+
+ case CB_SYS_getuid:
+ case CB_SYS_getuid32:
+ tbuf += sprintf (tbuf, "getuid()");
+ sc.result = getuid ();
+ goto sys_finish;
+ case CB_SYS_getgid:
+ case CB_SYS_getgid32:
+ tbuf += sprintf (tbuf, "getgid()");
+ sc.result = getgid ();
+ goto sys_finish;
+ case CB_SYS_setuid:
+ sc.arg1 &= 0xffff;
+ case CB_SYS_setuid32:
+ tbuf += sprintf (tbuf, "setuid(%u)", args[0]);
+ sc.result = setuid (sc.arg1);
+ goto sys_finish;
+ case CB_SYS_setgid:
+ sc.arg1 &= 0xffff;
+ case CB_SYS_setgid32:
+ tbuf += sprintf (tbuf, "setgid(%u)", args[0]);
+ sc.result = setgid (sc.arg1);
+ goto sys_finish;
+
+ case CB_SYS_getpid:
+ tbuf += sprintf (tbuf, "getpid()");
+ sc.result = getpid ();
+ goto sys_finish;
+ case CB_SYS_kill:
+ tbuf += sprintf (tbuf, "kill(%u, %i)", args[0], args[1]);
+ /* Only let the app kill itself. */
+ if (sc.arg1 != getpid ())
+ {
+ sc.result = -1;
+ sc.errcode = TARGET_EPERM;
+ }
+ else
+ {
+ sc.result = kill (sc.arg1, sc.arg2);
+ goto sys_finish;
+ }
+ break;
+
+ case CB_SYS_open:
+ tbuf += sprintf (tbuf, "open(%#x, %#x, %o)", args[0], args[1], args[2]);
+ goto case_default;
+ case CB_SYS_close:
+ tbuf += sprintf (tbuf, "close(%i)", args[0]);
+ goto case_default;
+ case CB_SYS_read:
+ tbuf += sprintf (tbuf, "read(%i, %#x, %u)", args[0], args[1], args[2]);
+ goto case_default;
+ case CB_SYS_write:
+ tbuf += sprintf (tbuf, "write(%i, %#x, %u)", args[0], args[1], args[2]);
+ goto case_default;
+ case CB_SYS_lseek:
+ tbuf += sprintf (tbuf, "lseek(%i, %i, %i)", args[0], args[1], args[2]);
+ goto case_default;
+ case CB_SYS_unlink:
+ tbuf += sprintf (tbuf, "unlink(%#x)", args[0]);
+ goto case_default;
+ case CB_SYS_truncate:
+ tbuf += sprintf (tbuf, "truncate(%#x, %i)", args[0], args[1]);
+ goto case_default;
+ case CB_SYS_ftruncate:
+ tbuf += sprintf (tbuf, "ftruncate(%i, %i)", args[0], args[1]);
+ goto case_default;
+ case CB_SYS_rename:
+ tbuf += sprintf (tbuf, "rename(%#x, %#x)", args[0], args[1]);
+ goto case_default;
+ case CB_SYS_stat:
+ tbuf += sprintf (tbuf, "stat(%#x, %#x)", args[0], args[1]);
+ goto case_default;
+ case CB_SYS_fstat:
+ tbuf += sprintf (tbuf, "fstat(%i, %#x)", args[0], args[1]);
+ goto case_default;
+ case CB_SYS_lstat:
+ tbuf += sprintf (tbuf, "lstat(%i, %#x)", args[0], args[1]);
+ goto case_default;
+ case CB_SYS_pipe:
+ tbuf += sprintf (tbuf, "pipe(%#x, %#x)", args[0], args[1]);
+ goto case_default;
+
+ default:
+ tbuf += sprintf (tbuf, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc.func,
+ args[0], args[1], args[2], args[3], args[4], args[5]);
+ case_default:
+ cb_syscall (cb, &sc);
+ break;
+
+ sys_finish:
+ if (sc.result == -1)
+ {
+ cb->last_errno = errno;
+ sc.errcode = cb->get_errno (cb);
+ }
+ }
+
+ TRACE_EVENTS (cpu, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
+ sc.func, args[0], args[1], args[2], args[3], args[4], args[5],
+ sc.result, sc.errcode);
+
+ tbuf += sprintf (tbuf, " = ");
+ if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
+ {
+ if (sc.result == -1)
+ {
+ tbuf += sprintf (tbuf, "-1 (error = %i)", sc.errcode);
+ if (sc.errcode == cb_host_to_target_errno (cb, ENOSYS))
+ {
+ sim_io_eprintf (sd, "bfin-sim: %#x: unimplemented syscall %i\n",
+ PCREG, sc.func);
+ }
+ SET_DREG (0, -sc.errcode);
+ }
+ else
+ {
+ if (fmt_ret_hex)
+ tbuf += sprintf (tbuf, "%#lx", sc.result);
+ else
+ tbuf += sprintf (tbuf, "%lu", sc.result);
+ SET_DREG (0, sc.result);
+ }
+ }
+ else
+ {
+ tbuf += sprintf (tbuf, "%lu (error = %i)", sc.result, sc.errcode);
+ SET_DREG (0, sc.result);
+ /* Blackfin libgloss only expects R0 to be updated, not R1. */
+ /*SET_DREG (1, sc.errcode);*/
+ }
+
+ TRACE_SYSCALL (cpu, "%s", _tbuf);
+}
+
+void
+trace_register (SIM_DESC sd,
+ sim_cpu *cpu,
+ const char *fmt,
+ ...)
+{
+ va_list ap;
+ trace_printf (sd, cpu, "%s %s",
+ "reg: ",
+ TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
+ va_start (ap, fmt);
+ trace_vprintf (sd, cpu, fmt, ap);
+ va_end (ap);
+ trace_printf (sd, cpu, "\n");
+}
+
+/* Execute a single instruction. */
+
+static sim_cia
+step_once (SIM_CPU *cpu)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ bu32 insn_len, oldpc = PCREG;
+ int i;
+ bool ssstep;
+
+ if (TRACE_ANY_P (cpu))
+ trace_prefix (sd, cpu, NULL_CIA, oldpc, TRACE_LINENUM_P (cpu),
+ NULL, 0, " "); /* Use a space for gcc warnings. */
+
+ /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
+ has already had the SSSTEP bit enabled. */
+ ssstep = false;
+ if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT
+ && (SYSCFGREG & SYSCFG_SSSTEP))
+ {
+ int ivg = cec_get_ivg (cpu);
+ if (ivg == -1 || ivg > 3)
+ ssstep = true;
+ }
+
+#if 0
+ /* XXX: Is this what happens on the hardware ? */
+ if (cec_get_ivg (cpu) == EVT_EMU)
+ cec_return (cpu, EVT_EMU);
+#endif
+
+ BFIN_CPU_STATE.did_jump = false;
+
+ insn_len = interp_insn_bfin (cpu, oldpc);
+
+ /* If we executed this insn successfully, then we always decrement
+ the loop counter. We don't want to update the PC though if the
+ last insn happened to be a change in code flow (jump/etc...). */
+ if (!BFIN_CPU_STATE.did_jump)
+ SET_PCREG (hwloop_get_next_pc (cpu, oldpc, insn_len));
+ for (i = 1; i >= 0; --i)
+ if (LCREG (i) && oldpc == LBREG (i))
+ {
+ SET_LCREG (i, LCREG (i) - 1);
+ if (LCREG (i))
+ break;
+ }
+
+ ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu));
+
+ /* Handle hardware single stepping only if we're still lower than EVT3.
+ XXX: May not be entirely correct wrt EXCPT insns. */
+ if (ssstep)
+ {
+ int ivg = cec_get_ivg (cpu);
+ if (ivg == -1 || ivg > 3)
+ {
+ INSN_LEN = 0;
+ cec_exception (cpu, VEC_STEP);
+ }
+ }
+
+ return oldpc;
+}
+
+void
+sim_engine_run (SIM_DESC sd,
+ int next_cpu_nr, /* ignore */
+ int nr_cpus, /* ignore */
+ int siggnal) /* ignore */
+{
+ bu32 ticks;
+ SIM_CPU *cpu;
+
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ cpu = STATE_CPU (sd, 0);
+
+ while (1)
+ {
+ step_once (cpu);
+ /* Process any events -- can't use tickn because it may
+ advance right over the next event. */
+ for (ticks = 0; ticks < CYCLE_DELAY; ++ticks)
+ if (sim_events_tick (sd))
+ sim_events_process (sd);
+ }
+}
+
+/* Cover function of sim_state_free to free the cpu buffers as well. */
+
+static void
+free_state (SIM_DESC sd)
+{
+ if (STATE_MODULES (sd) != NULL)
+ sim_module_uninstall (sd);
+ sim_cpu_free_all (sd);
+ sim_state_free (sd);
+}
+
+/* Create an instance of the simulator. */
+
+static void
+bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
+{
+ memset (&cpu->state, 0, sizeof (cpu->state));
+
+ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = 0;
+
+ bfin_model_cpu_init (sd, cpu);
+
+ /* Set default stack to top of scratch pad. */
+ SET_SPREG (BFIN_DEFAULT_MEM_SIZE);
+ SET_KSPREG (BFIN_DEFAULT_MEM_SIZE);
+ SET_USPREG (BFIN_DEFAULT_MEM_SIZE);
+
+ /* This is what the hardware likes. */
+ SET_SYSCFGREG (0x30);
+}
+
+SIM_DESC
+sim_open (SIM_OPEN_KIND kind, host_callback *callback,
+ struct bfd *abfd, char **argv)
+{
+ char c;
+ int i;
+ SIM_DESC sd = sim_state_alloc (kind, callback);
+
+ /* The cpu data is kept in a separately allocated chunk of memory. */
+ if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ {
+ /* XXX: Only first core gets profiled ? */
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+ STATE_WATCHPOINTS (sd)->pc = &PCREG;
+ STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PCREG);
+ }
+
+ if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ /* XXX: Default to the Virtual environment. */
+ if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
+ STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
+
+ /* These options override any module options.
+ Obviously ambiguity should be avoided, however the caller may wish to
+ augment the meaning of an option. */
+#define e_sim_add_option_table(sd, options) \
+ do { \
+ extern const OPTION options[]; \
+ sim_add_option_table (sd, NULL, options); \
+ } while (0)
+ e_sim_add_option_table (sd, bfin_mmu_options);
+ e_sim_add_option_table (sd, bfin_mach_options);
+
+ /* getopt will print the error message so we just have to exit if this fails.
+ FIXME: Hmmm... in the case of gdb we need getopt to call
+ print_filtered. */
+ if (sim_parse_args (sd, argv) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ /* Allocate external memory if none specified by user.
+ Use address 4 here in case the user wanted address 0 unmapped. */
+ if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
+ {
+ bu16 emuexcpt = 0x25;
+ sim_do_commandf (sd, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE);
+ sim_write (sd, 0, (void *)&emuexcpt, 2);
+ }
+
+ /* Check for/establish the a reference program image. */
+ if (sim_analyze_program (sd,
+ (STATE_PROG_ARGV (sd) != NULL
+ ? *STATE_PROG_ARGV (sd)
+ : NULL), abfd) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ /* Establish any remaining configuration options. */
+ if (sim_config (sd) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ if (sim_post_argv_init (sd) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ /* CPU specific initialization. */
+ for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+ {
+ SIM_CPU *cpu = STATE_CPU (sd, i);
+ bfin_initialize_cpu (sd, cpu);
+ }
+
+ return sd;
+}
+
+void
+sim_close (SIM_DESC sd, int quitting)
+{
+ sim_module_uninstall (sd);
+}
+
+/* Some utils don't like having a NULL environ. */
+static const char * const simple_env[] = { "HOME=/", "PATH=/bin", NULL };
+
+static bu32 fdpic_load_offset;
+
+static bool
+bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp,
+ bu32 *elf_addrs, char **ldso_path)
+{
+ bool ret;
+ int i;
+
+ Elf_Internal_Ehdr *iehdr;
+ Elf32_External_Ehdr ehdr;
+ Elf_Internal_Phdr *phdrs;
+ unsigned char *data;
+ long phdr_size;
+ int phdrc;
+ bu32 nsegs;
+
+ bu32 max_load_addr;
+
+ unsigned char null[4] = { 0, 0, 0, 0 };
+
+ ret = false;
+ *ldso_path = NULL;
+
+ /* See if this an FDPIC ELF. */
+ phdrs = NULL;
+ if (!abfd)
+ goto skip_fdpic_init;
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ goto skip_fdpic_init;
+ if (bfd_bread (&ehdr, sizeof (ehdr), abfd) != sizeof (ehdr))
+ goto skip_fdpic_init;
+ iehdr = elf_elfheader (abfd);
+ if (!(iehdr->e_flags & EF_BFIN_FDPIC))
+ goto skip_fdpic_init;
+
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ sim_io_printf (sd, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
+ bfd_get_filename (abfd), fdpic_load_offset, elf_addrs[0]);
+
+ /* Grab the Program Headers to set up the loadsegs on the stack. */
+ phdr_size = bfd_get_elf_phdr_upper_bound (abfd);
+ if (phdr_size == -1)
+ goto skip_fdpic_init;
+ phdrs = xmalloc (phdr_size);
+ phdrc = bfd_get_elf_phdrs (abfd, phdrs);
+ if (phdrc == -1)
+ goto skip_fdpic_init;
+
+ /* Push the Ehdr onto the stack. */
+ *sp -= sizeof (ehdr);
+ elf_addrs[3] = *sp;
+ sim_write (sd, *sp, (void *)&ehdr, sizeof (ehdr));
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ sim_io_printf (sd, " Elf_Ehdr: %#x\n", *sp);
+
+ /* Since we're relocating things ourselves, we need to relocate
+ the start address as well. */
+ elf_addrs[0] = bfd_get_start_address (abfd) + fdpic_load_offset;
+
+ /* And the Exec's Phdrs onto the stack. */
+ if (STATE_PROG_BFD (sd) == abfd)
+ {
+ elf_addrs[4] = elf_addrs[0];
+
+ phdr_size = iehdr->e_phentsize * iehdr->e_phnum;
+ if (bfd_seek (abfd, iehdr->e_phoff, SEEK_SET) != 0)
+ goto skip_fdpic_init;
+ data = xmalloc (phdr_size);
+ if (bfd_bread (data, phdr_size, abfd) != phdr_size)
+ goto skip_fdpic_init;
+ *sp -= phdr_size;
+ elf_addrs[1] = *sp;
+ elf_addrs[2] = phdrc;
+ sim_write (sd, *sp, data, phdr_size);
+ free (data);
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ sim_io_printf (sd, " Elf_Phdrs: %#x\n", *sp);
+ }
+
+ /* Now push all the loadsegs. */
+ nsegs = 0;
+ max_load_addr = 0;
+ for (i = phdrc; i >= 0; --i)
+ if (phdrs[i].p_type == PT_LOAD)
+ {
+ Elf_Internal_Phdr *p = &phdrs[i];
+ bu32 paddr, vaddr, memsz, filesz;
+
+ paddr = p->p_paddr + fdpic_load_offset;
+ vaddr = p->p_vaddr;
+ memsz = p->p_memsz;
+ filesz = p->p_filesz;
+
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ sim_io_printf (sd, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
+ i, vaddr, paddr, filesz, memsz);
+
+ data = xmalloc (memsz);
+ if (memsz != filesz)
+ memset (data + filesz, 0, memsz - filesz);
+
+ if (bfd_seek (abfd, p->p_offset, SEEK_SET) == 0
+ && bfd_bread (data, filesz, abfd) == filesz)
+ sim_write (sd, paddr, data, memsz);
+
+ free (data);
+
+ max_load_addr = MAX (paddr + memsz, max_load_addr);
+
+ *sp -= 12;
+ sim_write (sd, *sp+0, (void *)&paddr, 4); /* loadseg.addr */
+ sim_write (sd, *sp+4, (void *)&vaddr, 4); /* loadseg.p_vaddr */
+ sim_write (sd, *sp+8, (void *)&memsz, 4); /* loadseg.p_memsz */
+ ++nsegs;
+ }
+ else if (phdrs[i].p_type == PT_DYNAMIC)
+ {
+ elf_addrs[5] = phdrs[i].p_paddr + fdpic_load_offset;
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ sim_io_printf (sd, " PT_DYNAMIC: %#x\n", elf_addrs[5]);
+ }
+ else if (phdrs[i].p_type == PT_INTERP)
+ {
+ uint32_t off = phdrs[i].p_offset;
+ uint32_t len = phdrs[i].p_filesz;
+
+ *ldso_path = xmalloc (len);
+ if (bfd_seek (abfd, off, SEEK_SET) != 0
+ || bfd_bread (*ldso_path, len, abfd) != len)
+ {
+ free (*ldso_path);
+ *ldso_path = NULL;
+ }
+ else if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ sim_io_printf (sd, " PT_INTERP: %s\n", *ldso_path);
+ }
+
+ /* Update the load offset with a few extra pages. */
+ fdpic_load_offset = ALIGN (MAX (max_load_addr, fdpic_load_offset), 0x10000);
+ fdpic_load_offset += 0x10000;
+
+ /* Push the summary loadmap info onto the stack last. */
+ *sp -= 4;
+ sim_write (sd, *sp+0, null, 2); /* loadmap.version */
+ sim_write (sd, *sp+2, (void *)&nsegs, 2); /* loadmap.nsegs */
+
+ ret = true;
+ skip_fdpic_init:
+ free (phdrs);
+
+ return ret;
+}
+
+static void
+bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
+ const char * const *argv, const char * const *env)
+{
+ /* XXX: Missing host -> target endian ... */
+ /* Linux starts the user app with the stack:
+ argc
+ argv[0] -- pointers to the actual strings
+ argv[1..N]
+ NULL
+ env[0]
+ env[1..N]
+ NULL
+ auxvt[0].type -- ELF Auxiliary Vector Table
+ auxvt[0].value
+ auxvt[1..N]
+ AT_NULL
+ 0
+ argv[0..N][0..M] -- actual argv/env strings
+ env[0..N][0..M]
+ FDPIC loadmaps -- for FDPIC apps
+ So set things up the same way. */
+ int i, argc, envc;
+ bu32 argv_flat, env_flat;
+
+ bu32 sp, sp_flat;
+
+ /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
+ bu32 elf_addrs[6];
+ bu32 auxvt, auxvt_size;
+ bu32 exec_loadmap, ldso_loadmap;
+ char *ldso_path;
+
+ unsigned char null[4] = { 0, 0, 0, 0 };
+
+ host_callback *cb = STATE_CALLBACK (sd);
+
+ elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
+ elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;
+
+ /* Keep the load addresses consistent between runs. Also make sure we make
+ space for the fixed code region (part of the Blackfin Linux ABI). */
+ fdpic_load_offset = 0x1000;
+
+ /* First try to load this as an FDPIC executable. */
+ sp = SPREG;
+ if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path))
+ goto skip_fdpic_init;
+ exec_loadmap = sp;
+
+ /* If that worked, then load the fixed code region. We only do this for
+ FDPIC ELFs atm because they are PIEs and let us relocate them without
+ manual fixups. FLAT files however require location processing which
+ we do not do ourselves, and they link with a VMA of 0. */
+ sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code));
+
+ /* If the FDPIC needs an interpreter, then load it up too. */
+ if (ldso_path)
+ {
+ const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL);
+ struct bfd *ldso_bfd;
+
+ ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd));
+ if (!ldso_bfd)
+ {
+ sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path);
+ goto static_fdpic;
+ }
+ if (!bfd_check_format (ldso_bfd, bfd_object))
+ sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path);
+ bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd));
+
+ if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path))
+ sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path);
+ if (ldso_path)
+ sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
+ ldso_full_path, ldso_path);
+
+ ldso_loadmap = sp;
+ }
+ else
+ static_fdpic:
+ ldso_loadmap = 0;
+
+ /* Finally setup the registers required by the FDPIC ABI. */
+ SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
+ SET_PREG (0, exec_loadmap); /* Exec loadmap addr. */
+ SET_PREG (1, ldso_loadmap); /* Interp loadmap addr. */
+ SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr. */
+
+ auxvt = 1;
+ SET_SPREG (sp);
+ skip_fdpic_init:
+ sim_pc_set (cpu, elf_addrs[0]);
+
+ /* Figure out how much storage the argv/env strings need. */
+ argc = count_argc (argv);
+ if (argc == -1)
+ argc = 0;
+ argv_flat = argc; /* NUL bytes */
+ for (i = 0; i < argc; ++i)
+ argv_flat += strlen (argv[i]);
+
+ if (!env)
+ env = simple_env;
+ envc = count_argc (env);
+ env_flat = envc; /* NUL bytes */
+ for (i = 0; i < envc; ++i)
+ env_flat += strlen (env[i]);
+
+ /* Push the Auxiliary Vector Table between argv/env and actual strings. */
+ sp_flat = sp = ALIGN (SPREG - argv_flat - env_flat - 4, 4);
+ if (auxvt)
+ {
+# define AT_PUSH(at, val) \
+ auxvt_size += 8; \
+ sp -= 4; \
+ auxvt = (val); \
+ sim_write (sd, sp, (void *)&auxvt, 4); \
+ sp -= 4; \
+ auxvt = (at); \
+ sim_write (sd, sp, (void *)&auxvt, 4)
+ auxvt_size = 0;
+ unsigned int egid = getegid (), gid = getgid ();
+ unsigned int euid = geteuid (), uid = getuid ();
+ AT_PUSH (AT_NULL, 0);
+ AT_PUSH (AT_SECURE, egid != gid || euid != uid);
+ AT_PUSH (AT_EGID, egid);
+ AT_PUSH (AT_GID, gid);
+ AT_PUSH (AT_EUID, euid);
+ AT_PUSH (AT_UID, uid);
+ AT_PUSH (AT_ENTRY, elf_addrs[4]);
+ AT_PUSH (AT_FLAGS, 0);
+ AT_PUSH (AT_BASE, elf_addrs[3]);
+ AT_PUSH (AT_PHNUM, elf_addrs[2]);
+ AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr));
+ AT_PUSH (AT_PHDR, elf_addrs[1]);
+ AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ? */
+ AT_PUSH (AT_PAGESZ, 4096);
+ AT_PUSH (AT_HWCAP, 0);
+#undef AT_PUSH
+ }
+ SET_SPREG (sp);
+
+ /* Push the argc/argv/env after the auxvt. */
+ sp -= ((1 + argc + 1 + envc + 1) * 4);
+ SET_SPREG (sp);
+
+ /* First push the argc value. */
+ sim_write (sd, sp, (void *)&argc, 4);
+ sp += 4;
+
+ /* Then the actual argv strings so we know where to point argv[]. */
+ for (i = 0; i < argc; ++i)
+ {
+ unsigned len = strlen (argv[i]) + 1;
+ sim_write (sd, sp_flat, (void *)argv[i], len);
+ sim_write (sd, sp, (void *)&sp_flat, 4);
+ sp_flat += len;
+ sp += 4;
+ }
+ sim_write (sd, sp, null, 4);
+ sp += 4;
+
+ /* Then the actual env strings so we know where to point env[]. */
+ for (i = 0; i < envc; ++i)
+ {
+ unsigned len = strlen (env[i]) + 1;
+ sim_write (sd, sp_flat, (void *)env[i], len);
+ sim_write (sd, sp, (void *)&sp_flat, 4);
+ sp_flat += len;
+ sp += 4;
+ }
+
+ /* Set some callbacks. */
+ cb->syscall_map = cb_linux_syscall_map;
+ cb->errno_map = cb_linux_errno_map;
+ cb->open_map = cb_linux_open_map;
+ cb->signal_map = cb_linux_signal_map;
+ cb->stat_map = stat_map_32;
+}
+
+static void
+bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, const char * const *argv)
+{
+ /* Pass the command line via a string in R0 like Linux expects. */
+ int i;
+ bu8 byte;
+ bu32 cmdline = BFIN_L1_SRAM_SCRATCH;
+
+ SET_DREG (0, cmdline);
+ if (argv && argv[0])
+ {
+ i = 1;
+ byte = ' ';
+ while (argv[i])
+ {
+ bu32 len = strlen (argv[i]);
+ sim_write (sd, cmdline, (void *)argv[i], len);
+ cmdline += len;
+ sim_write (sd, cmdline, &byte, 1);
+ ++cmdline;
+ ++i;
+ }
+ }
+ byte = 0;
+ sim_write (sd, cmdline, &byte, 1);
+}
+
+SIM_RC
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
+ char **argv, char **env)
+{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+ SIM_ADDR addr;
+
+ /* Set the PC. */
+ if (abfd != NULL)
+ addr = bfd_get_start_address (abfd);
+ else
+ addr = 0;
+ sim_pc_set (cpu, addr);
+
+ /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
+ for us in sim_open() -> sim_parse_args(). But in debug mode (i.e.
+ 'target sim' with `bfin-...-gdb`), we need to handle it. */
+ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ {
+ free (STATE_PROG_ARGV (sd));
+ STATE_PROG_ARGV (sd) = dupargv (argv);
+ }
+
+ switch (STATE_ENVIRONMENT (sd))
+ {
+ case USER_ENVIRONMENT:
+ bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env);
+ break;
+ case OPERATING_ENVIRONMENT:
+ bfin_os_init (sd, cpu, (void *)argv);
+ break;
+ default:
+ /* Nothing to do for virtual/all envs. */
+ break;
+ }
+
+ return SIM_RC_OK;
+}
+
+void
+sim_do_command (SIM_DESC sd, char *cmd)
+{
+ if (sim_args_command (sd, cmd) != SIM_RC_OK)
+ sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
+}
diff --git a/sim/bfin/linux-fixed-code.h b/sim/bfin/linux-fixed-code.h
new file mode 100644
index 00000000000..7b42ed37d88
--- /dev/null
+++ b/sim/bfin/linux-fixed-code.h
@@ -0,0 +1,74 @@
+/* DO NOT EDIT: Autogenerated from linux-fixed-code.s. */
+static const unsigned char bfin_linux_fixed_code[] = {
+0x28, 0xe1, 0xad, 0x00,
+0xa0, 0x00,
+0x00, 0x20,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x91,
+0x01, 0x93,
+0x10, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x91,
+0x08, 0x08,
+0x02, 0x10,
+0x02, 0x93,
+0x10, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x01, 0x91,
+0x01, 0x50,
+0x00, 0x93,
+0x10, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x01, 0x91,
+0x01, 0x52,
+0x00, 0x93,
+0x10, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x01, 0x91,
+0x01, 0x56,
+0x00, 0x93,
+0x10, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x01, 0x91,
+0x01, 0x54,
+0x00, 0x93,
+0x10, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x01, 0x91,
+0x01, 0x58,
+0x00, 0x93,
+0x10, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0xa4, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+0x00, 0x00,
+};
diff --git a/sim/bfin/linux-fixed-code.s b/sim/bfin/linux-fixed-code.s
new file mode 100644
index 00000000000..c1dd358852e
--- /dev/null
+++ b/sim/bfin/linux-fixed-code.s
@@ -0,0 +1,85 @@
+/* Linux fixed code userspace ABI
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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, see <http://www.gnu.org/licenses/>. */
+
+/* For more info, see this page:
+ http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:fixed-code */
+
+.text
+
+.align 16
+_sigreturn_stub:
+ P0 = 173;
+ EXCPT 0;
+0: JUMP.S 0b;
+
+.align 16
+_atomic_xchg32:
+ R0 = [P0];
+ [P0] = R1;
+ rts;
+
+.align 16
+_atomic_cas32:
+ R0 = [P0];
+ CC = R0 == R1;
+ IF !CC JUMP 1f;
+ [P0] = R2;
+1:
+ rts;
+
+.align 16
+_atomic_add32:
+ R1 = [P0];
+ R0 = R1 + R0;
+ [P0] = R0;
+ rts;
+
+.align 16
+_atomic_sub32:
+ R1 = [P0];
+ R0 = R1 - R0;
+ [P0] = R0;
+ rts;
+
+.align 16
+_atomic_ior32:
+ R1 = [P0];
+ R0 = R1 | R0;
+ [P0] = R0;
+ rts;
+
+.align 16
+_atomic_and32:
+ R1 = [P0];
+ R0 = R1 & R0;
+ [P0] = R0;
+ rts;
+
+.align 16
+_atomic_xor32:
+ R1 = [P0];
+ R0 = R1 ^ R0;
+ [P0] = R0;
+ rts;
+
+.align 16
+_safe_user_instruction:
+ NOP; NOP; NOP; NOP;
+ EXCPT 0x4;
diff --git a/sim/bfin/linux-targ-map.h b/sim/bfin/linux-targ-map.h
new file mode 100644
index 00000000000..ca340d5136f
--- /dev/null
+++ b/sim/bfin/linux-targ-map.h
@@ -0,0 +1,1992 @@
+#if 0 /* Auto generated: sh ./targ-linux.h
+
+sed -n '1,/^#endif/p' targ-linux.h
+echo
+
+echo '#include <sys/syscall.h>' | \
+bfin-uclinux-gcc -E -dD -P - | \
+sed -r -n \
+ -e '1istatic CB_TARGET_DEFS_MAP cb_linux_syscall_map[] = {' \
+ -e '$i\ \ { -1, -1 }\n};' \
+ -e '/#define __NR_/{s:^.* __NR_(.*) (.*):#ifdef CB_SYS_\1\n# define TARGET_LINUX_SYS_\1 \2\n { CB_SYS_\1, TARGET_LINUX_SYS_\1 },\n#endif:;p;}'
+echo
+
+echo '#include <errno.h>' | \
+bfin-uclinux-gcc -E -dD -P - | \
+sed -r -n \
+ -e '1istatic CB_TARGET_DEFS_MAP cb_linux_errno_map[] = {' \
+ -e '$i\ \ { 0, 0 }\n};' \
+ -e '/#define E.* [0-9]/{s:^.* (E.*) (.*):#ifdef \1\n# define TARGET_LINUX_\1 \2\n { \1, TARGET_LINUX_\1 },\n#endif:;p;}'
+echo
+
+echo '#include <fcntl.h>' | \
+bfin-uclinux-gcc -E -dD -P - | \
+sed -r -n \
+ -e '1istatic CB_TARGET_DEFS_MAP cb_linux_open_map[] = {' \
+ -e '$i\ \ { -1, -1 }\n};' \
+ -e '/#define O.* [0-9]/{s:^.* (O_.*) (.*):#ifdef \1\n# define TARGET_LINUX_\1 \2\n { \1, TARGET_LINUX_\1 },\n#endif:;p;}'
+echo
+
+# XXX: nothing uses this ?
+echo '#include <signal.h>' | \
+bfin-uclinux-gcc -E -dD -P - | \
+sed -r -n \
+ -e '1istatic CB_TARGET_DEFS_MAP cb_linux_signal_map[] = {' \
+ -e '$i\ \ { -1, -1 }\n};' \
+ -e '/#define SIG.* [0-9]+$/{s:^.* (SIG.*) (.*):#ifdef \1\n# define TARGET_LINUX_\1 \2\n { \1, TARGET_LINUX_\1 },\n#endif:;p;}'
+
+exit 0
+*/
+#endif
+
+static CB_TARGET_DEFS_MAP cb_linux_syscall_map[] = {
+#ifdef CB_SYS_restart_syscall
+# define TARGET_LINUX_SYS_restart_syscall 0
+ { CB_SYS_restart_syscall, TARGET_LINUX_SYS_restart_syscall },
+#endif
+#ifdef CB_SYS_exit
+# define TARGET_LINUX_SYS_exit 1
+ { CB_SYS_exit, TARGET_LINUX_SYS_exit },
+#endif
+#ifdef CB_SYS_fork
+# define TARGET_LINUX_SYS_fork 2
+ { CB_SYS_fork, TARGET_LINUX_SYS_fork },
+#endif
+#ifdef CB_SYS_read
+# define TARGET_LINUX_SYS_read 3
+ { CB_SYS_read, TARGET_LINUX_SYS_read },
+#endif
+#ifdef CB_SYS_write
+# define TARGET_LINUX_SYS_write 4
+ { CB_SYS_write, TARGET_LINUX_SYS_write },
+#endif
+#ifdef CB_SYS_open
+# define TARGET_LINUX_SYS_open 5
+ { CB_SYS_open, TARGET_LINUX_SYS_open },
+#endif
+#ifdef CB_SYS_close
+# define TARGET_LINUX_SYS_close 6
+ { CB_SYS_close, TARGET_LINUX_SYS_close },
+#endif
+#ifdef CB_SYS_creat
+# define TARGET_LINUX_SYS_creat 8
+ { CB_SYS_creat, TARGET_LINUX_SYS_creat },
+#endif
+#ifdef CB_SYS_link
+# define TARGET_LINUX_SYS_link 9
+ { CB_SYS_link, TARGET_LINUX_SYS_link },
+#endif
+#ifdef CB_SYS_unlink
+# define TARGET_LINUX_SYS_unlink 10
+ { CB_SYS_unlink, TARGET_LINUX_SYS_unlink },
+#endif
+#ifdef CB_SYS_execve
+# define TARGET_LINUX_SYS_execve 11
+ { CB_SYS_execve, TARGET_LINUX_SYS_execve },
+#endif
+#ifdef CB_SYS_chdir
+# define TARGET_LINUX_SYS_chdir 12
+ { CB_SYS_chdir, TARGET_LINUX_SYS_chdir },
+#endif
+#ifdef CB_SYS_time
+# define TARGET_LINUX_SYS_time 13
+ { CB_SYS_time, TARGET_LINUX_SYS_time },
+#endif
+#ifdef CB_SYS_mknod
+# define TARGET_LINUX_SYS_mknod 14
+ { CB_SYS_mknod, TARGET_LINUX_SYS_mknod },
+#endif
+#ifdef CB_SYS_chmod
+# define TARGET_LINUX_SYS_chmod 15
+ { CB_SYS_chmod, TARGET_LINUX_SYS_chmod },
+#endif
+#ifdef CB_SYS_chown
+# define TARGET_LINUX_SYS_chown 16
+ { CB_SYS_chown, TARGET_LINUX_SYS_chown },
+#endif
+#ifdef CB_SYS_lseek
+# define TARGET_LINUX_SYS_lseek 19
+ { CB_SYS_lseek, TARGET_LINUX_SYS_lseek },
+#endif
+#ifdef CB_SYS_getpid
+# define TARGET_LINUX_SYS_getpid 20
+ { CB_SYS_getpid, TARGET_LINUX_SYS_getpid },
+#endif
+#ifdef CB_SYS_mount
+# define TARGET_LINUX_SYS_mount 21
+ { CB_SYS_mount, TARGET_LINUX_SYS_mount },
+#endif
+#ifdef CB_SYS_setuid
+# define TARGET_LINUX_SYS_setuid 23
+ { CB_SYS_setuid, TARGET_LINUX_SYS_setuid },
+#endif
+#ifdef CB_SYS_getuid
+# define TARGET_LINUX_SYS_getuid 24
+ { CB_SYS_getuid, TARGET_LINUX_SYS_getuid },
+#endif
+#ifdef CB_SYS_stime
+# define TARGET_LINUX_SYS_stime 25
+ { CB_SYS_stime, TARGET_LINUX_SYS_stime },
+#endif
+#ifdef CB_SYS_ptrace
+# define TARGET_LINUX_SYS_ptrace 26
+ { CB_SYS_ptrace, TARGET_LINUX_SYS_ptrace },
+#endif
+#ifdef CB_SYS_alarm
+# define TARGET_LINUX_SYS_alarm 27
+ { CB_SYS_alarm, TARGET_LINUX_SYS_alarm },
+#endif
+#ifdef CB_SYS_pause
+# define TARGET_LINUX_SYS_pause 29
+ { CB_SYS_pause, TARGET_LINUX_SYS_pause },
+#endif
+#ifdef CB_SYS_access
+# define TARGET_LINUX_SYS_access 33
+ { CB_SYS_access, TARGET_LINUX_SYS_access },
+#endif
+#ifdef CB_SYS_nice
+# define TARGET_LINUX_SYS_nice 34
+ { CB_SYS_nice, TARGET_LINUX_SYS_nice },
+#endif
+#ifdef CB_SYS_sync
+# define TARGET_LINUX_SYS_sync 36
+ { CB_SYS_sync, TARGET_LINUX_SYS_sync },
+#endif
+#ifdef CB_SYS_kill
+# define TARGET_LINUX_SYS_kill 37
+ { CB_SYS_kill, TARGET_LINUX_SYS_kill },
+#endif
+#ifdef CB_SYS_rename
+# define TARGET_LINUX_SYS_rename 38
+ { CB_SYS_rename, TARGET_LINUX_SYS_rename },
+#endif
+#ifdef CB_SYS_mkdir
+# define TARGET_LINUX_SYS_mkdir 39
+ { CB_SYS_mkdir, TARGET_LINUX_SYS_mkdir },
+#endif
+#ifdef CB_SYS_rmdir
+# define TARGET_LINUX_SYS_rmdir 40
+ { CB_SYS_rmdir, TARGET_LINUX_SYS_rmdir },
+#endif
+#ifdef CB_SYS_dup
+# define TARGET_LINUX_SYS_dup 41
+ { CB_SYS_dup, TARGET_LINUX_SYS_dup },
+#endif
+#ifdef CB_SYS_pipe
+# define TARGET_LINUX_SYS_pipe 42
+ { CB_SYS_pipe, TARGET_LINUX_SYS_pipe },
+#endif
+#ifdef CB_SYS_times
+# define TARGET_LINUX_SYS_times 43
+ { CB_SYS_times, TARGET_LINUX_SYS_times },
+#endif
+#ifdef CB_SYS_brk
+# define TARGET_LINUX_SYS_brk 45
+ { CB_SYS_brk, TARGET_LINUX_SYS_brk },
+#endif
+#ifdef CB_SYS_setgid
+# define TARGET_LINUX_SYS_setgid 46
+ { CB_SYS_setgid, TARGET_LINUX_SYS_setgid },
+#endif
+#ifdef CB_SYS_getgid
+# define TARGET_LINUX_SYS_getgid 47
+ { CB_SYS_getgid, TARGET_LINUX_SYS_getgid },
+#endif
+#ifdef CB_SYS_geteuid
+# define TARGET_LINUX_SYS_geteuid 49
+ { CB_SYS_geteuid, TARGET_LINUX_SYS_geteuid },
+#endif
+#ifdef CB_SYS_getegid
+# define TARGET_LINUX_SYS_getegid 50
+ { CB_SYS_getegid, TARGET_LINUX_SYS_getegid },
+#endif
+#ifdef CB_SYS_acct
+# define TARGET_LINUX_SYS_acct 51
+ { CB_SYS_acct, TARGET_LINUX_SYS_acct },
+#endif
+#ifdef CB_SYS_umount2
+# define TARGET_LINUX_SYS_umount2 52
+ { CB_SYS_umount2, TARGET_LINUX_SYS_umount2 },
+#endif
+#ifdef CB_SYS_ioctl
+# define TARGET_LINUX_SYS_ioctl 54
+ { CB_SYS_ioctl, TARGET_LINUX_SYS_ioctl },
+#endif
+#ifdef CB_SYS_fcntl
+# define TARGET_LINUX_SYS_fcntl 55
+ { CB_SYS_fcntl, TARGET_LINUX_SYS_fcntl },
+#endif
+#ifdef CB_SYS_setpgid
+# define TARGET_LINUX_SYS_setpgid 57
+ { CB_SYS_setpgid, TARGET_LINUX_SYS_setpgid },
+#endif
+#ifdef CB_SYS_umask
+# define TARGET_LINUX_SYS_umask 60
+ { CB_SYS_umask, TARGET_LINUX_SYS_umask },
+#endif
+#ifdef CB_SYS_chroot
+# define TARGET_LINUX_SYS_chroot 61
+ { CB_SYS_chroot, TARGET_LINUX_SYS_chroot },
+#endif
+#ifdef CB_SYS_ustat
+# define TARGET_LINUX_SYS_ustat 62
+ { CB_SYS_ustat, TARGET_LINUX_SYS_ustat },
+#endif
+#ifdef CB_SYS_dup2
+# define TARGET_LINUX_SYS_dup2 63
+ { CB_SYS_dup2, TARGET_LINUX_SYS_dup2 },
+#endif
+#ifdef CB_SYS_getppid
+# define TARGET_LINUX_SYS_getppid 64
+ { CB_SYS_getppid, TARGET_LINUX_SYS_getppid },
+#endif
+#ifdef CB_SYS_getpgrp
+# define TARGET_LINUX_SYS_getpgrp 65
+ { CB_SYS_getpgrp, TARGET_LINUX_SYS_getpgrp },
+#endif
+#ifdef CB_SYS_setsid
+# define TARGET_LINUX_SYS_setsid 66
+ { CB_SYS_setsid, TARGET_LINUX_SYS_setsid },
+#endif
+#ifdef CB_SYS_sgetmask
+# define TARGET_LINUX_SYS_sgetmask 68
+ { CB_SYS_sgetmask, TARGET_LINUX_SYS_sgetmask },
+#endif
+#ifdef CB_SYS_ssetmask
+# define TARGET_LINUX_SYS_ssetmask 69
+ { CB_SYS_ssetmask, TARGET_LINUX_SYS_ssetmask },
+#endif
+#ifdef CB_SYS_setreuid
+# define TARGET_LINUX_SYS_setreuid 70
+ { CB_SYS_setreuid, TARGET_LINUX_SYS_setreuid },
+#endif
+#ifdef CB_SYS_setregid
+# define TARGET_LINUX_SYS_setregid 71
+ { CB_SYS_setregid, TARGET_LINUX_SYS_setregid },
+#endif
+#ifdef CB_SYS_sethostname
+# define TARGET_LINUX_SYS_sethostname 74
+ { CB_SYS_sethostname, TARGET_LINUX_SYS_sethostname },
+#endif
+#ifdef CB_SYS_setrlimit
+# define TARGET_LINUX_SYS_setrlimit 75
+ { CB_SYS_setrlimit, TARGET_LINUX_SYS_setrlimit },
+#endif
+#ifdef CB_SYS_getrusage
+# define TARGET_LINUX_SYS_getrusage 77
+ { CB_SYS_getrusage, TARGET_LINUX_SYS_getrusage },
+#endif
+#ifdef CB_SYS_gettimeofday
+# define TARGET_LINUX_SYS_gettimeofday 78
+ { CB_SYS_gettimeofday, TARGET_LINUX_SYS_gettimeofday },
+#endif
+#ifdef CB_SYS_settimeofday
+# define TARGET_LINUX_SYS_settimeofday 79
+ { CB_SYS_settimeofday, TARGET_LINUX_SYS_settimeofday },
+#endif
+#ifdef CB_SYS_getgroups
+# define TARGET_LINUX_SYS_getgroups 80
+ { CB_SYS_getgroups, TARGET_LINUX_SYS_getgroups },
+#endif
+#ifdef CB_SYS_setgroups
+# define TARGET_LINUX_SYS_setgroups 81
+ { CB_SYS_setgroups, TARGET_LINUX_SYS_setgroups },
+#endif
+#ifdef CB_SYS_symlink
+# define TARGET_LINUX_SYS_symlink 83
+ { CB_SYS_symlink, TARGET_LINUX_SYS_symlink },
+#endif
+#ifdef CB_SYS_readlink
+# define TARGET_LINUX_SYS_readlink 85
+ { CB_SYS_readlink, TARGET_LINUX_SYS_readlink },
+#endif
+#ifdef CB_SYS_reboot
+# define TARGET_LINUX_SYS_reboot 88
+ { CB_SYS_reboot, TARGET_LINUX_SYS_reboot },
+#endif
+#ifdef CB_SYS_munmap
+# define TARGET_LINUX_SYS_munmap 91
+ { CB_SYS_munmap, TARGET_LINUX_SYS_munmap },
+#endif
+#ifdef CB_SYS_truncate
+# define TARGET_LINUX_SYS_truncate 92
+ { CB_SYS_truncate, TARGET_LINUX_SYS_truncate },
+#endif
+#ifdef CB_SYS_ftruncate
+# define TARGET_LINUX_SYS_ftruncate 93
+ { CB_SYS_ftruncate, TARGET_LINUX_SYS_ftruncate },
+#endif
+#ifdef CB_SYS_fchmod
+# define TARGET_LINUX_SYS_fchmod 94
+ { CB_SYS_fchmod, TARGET_LINUX_SYS_fchmod },
+#endif
+#ifdef CB_SYS_fchown
+# define TARGET_LINUX_SYS_fchown 95
+ { CB_SYS_fchown, TARGET_LINUX_SYS_fchown },
+#endif
+#ifdef CB_SYS_getpriority
+# define TARGET_LINUX_SYS_getpriority 96
+ { CB_SYS_getpriority, TARGET_LINUX_SYS_getpriority },
+#endif
+#ifdef CB_SYS_setpriority
+# define TARGET_LINUX_SYS_setpriority 97
+ { CB_SYS_setpriority, TARGET_LINUX_SYS_setpriority },
+#endif
+#ifdef CB_SYS_statfs
+# define TARGET_LINUX_SYS_statfs 99
+ { CB_SYS_statfs, TARGET_LINUX_SYS_statfs },
+#endif
+#ifdef CB_SYS_fstatfs
+# define TARGET_LINUX_SYS_fstatfs 100
+ { CB_SYS_fstatfs, TARGET_LINUX_SYS_fstatfs },
+#endif
+#ifdef CB_SYS_syslog
+# define TARGET_LINUX_SYS_syslog 103
+ { CB_SYS_syslog, TARGET_LINUX_SYS_syslog },
+#endif
+#ifdef CB_SYS_setitimer
+# define TARGET_LINUX_SYS_setitimer 104
+ { CB_SYS_setitimer, TARGET_LINUX_SYS_setitimer },
+#endif
+#ifdef CB_SYS_getitimer
+# define TARGET_LINUX_SYS_getitimer 105
+ { CB_SYS_getitimer, TARGET_LINUX_SYS_getitimer },
+#endif
+#ifdef CB_SYS_stat
+# define TARGET_LINUX_SYS_stat 106
+ { CB_SYS_stat, TARGET_LINUX_SYS_stat },
+#endif
+#ifdef CB_SYS_lstat
+# define TARGET_LINUX_SYS_lstat 107
+ { CB_SYS_lstat, TARGET_LINUX_SYS_lstat },
+#endif
+#ifdef CB_SYS_fstat
+# define TARGET_LINUX_SYS_fstat 108
+ { CB_SYS_fstat, TARGET_LINUX_SYS_fstat },
+#endif
+#ifdef CB_SYS_vhangup
+# define TARGET_LINUX_SYS_vhangup 111
+ { CB_SYS_vhangup, TARGET_LINUX_SYS_vhangup },
+#endif
+#ifdef CB_SYS_wait4
+# define TARGET_LINUX_SYS_wait4 114
+ { CB_SYS_wait4, TARGET_LINUX_SYS_wait4 },
+#endif
+#ifdef CB_SYS_sysinfo
+# define TARGET_LINUX_SYS_sysinfo 116
+ { CB_SYS_sysinfo, TARGET_LINUX_SYS_sysinfo },
+#endif
+#ifdef CB_SYS_fsync
+# define TARGET_LINUX_SYS_fsync 118
+ { CB_SYS_fsync, TARGET_LINUX_SYS_fsync },
+#endif
+#ifdef CB_SYS_clone
+# define TARGET_LINUX_SYS_clone 120
+ { CB_SYS_clone, TARGET_LINUX_SYS_clone },
+#endif
+#ifdef CB_SYS_setdomainname
+# define TARGET_LINUX_SYS_setdomainname 121
+ { CB_SYS_setdomainname, TARGET_LINUX_SYS_setdomainname },
+#endif
+#ifdef CB_SYS_uname
+# define TARGET_LINUX_SYS_uname 122
+ { CB_SYS_uname, TARGET_LINUX_SYS_uname },
+#endif
+#ifdef CB_SYS_adjtimex
+# define TARGET_LINUX_SYS_adjtimex 124
+ { CB_SYS_adjtimex, TARGET_LINUX_SYS_adjtimex },
+#endif
+#ifdef CB_SYS_mprotect
+# define TARGET_LINUX_SYS_mprotect 125
+ { CB_SYS_mprotect, TARGET_LINUX_SYS_mprotect },
+#endif
+#ifdef CB_SYS_init_module
+# define TARGET_LINUX_SYS_init_module 128
+ { CB_SYS_init_module, TARGET_LINUX_SYS_init_module },
+#endif
+#ifdef CB_SYS_delete_module
+# define TARGET_LINUX_SYS_delete_module 129
+ { CB_SYS_delete_module, TARGET_LINUX_SYS_delete_module },
+#endif
+#ifdef CB_SYS_quotactl
+# define TARGET_LINUX_SYS_quotactl 131
+ { CB_SYS_quotactl, TARGET_LINUX_SYS_quotactl },
+#endif
+#ifdef CB_SYS_getpgid
+# define TARGET_LINUX_SYS_getpgid 132
+ { CB_SYS_getpgid, TARGET_LINUX_SYS_getpgid },
+#endif
+#ifdef CB_SYS_fchdir
+# define TARGET_LINUX_SYS_fchdir 133
+ { CB_SYS_fchdir, TARGET_LINUX_SYS_fchdir },
+#endif
+#ifdef CB_SYS_bdflush
+# define TARGET_LINUX_SYS_bdflush 134
+ { CB_SYS_bdflush, TARGET_LINUX_SYS_bdflush },
+#endif
+#ifdef CB_SYS_personality
+# define TARGET_LINUX_SYS_personality 136
+ { CB_SYS_personality, TARGET_LINUX_SYS_personality },
+#endif
+#ifdef CB_SYS_setfsuid
+# define TARGET_LINUX_SYS_setfsuid 138
+ { CB_SYS_setfsuid, TARGET_LINUX_SYS_setfsuid },
+#endif
+#ifdef CB_SYS_setfsgid
+# define TARGET_LINUX_SYS_setfsgid 139
+ { CB_SYS_setfsgid, TARGET_LINUX_SYS_setfsgid },
+#endif
+#ifdef CB_SYS__llseek
+# define TARGET_LINUX_SYS__llseek 140
+ { CB_SYS__llseek, TARGET_LINUX_SYS__llseek },
+#endif
+#ifdef CB_SYS_getdents
+# define TARGET_LINUX_SYS_getdents 141
+ { CB_SYS_getdents, TARGET_LINUX_SYS_getdents },
+#endif
+#ifdef CB_SYS_flock
+# define TARGET_LINUX_SYS_flock 143
+ { CB_SYS_flock, TARGET_LINUX_SYS_flock },
+#endif
+#ifdef CB_SYS_readv
+# define TARGET_LINUX_SYS_readv 145
+ { CB_SYS_readv, TARGET_LINUX_SYS_readv },
+#endif
+#ifdef CB_SYS_writev
+# define TARGET_LINUX_SYS_writev 146
+ { CB_SYS_writev, TARGET_LINUX_SYS_writev },
+#endif
+#ifdef CB_SYS_getsid
+# define TARGET_LINUX_SYS_getsid 147
+ { CB_SYS_getsid, TARGET_LINUX_SYS_getsid },
+#endif
+#ifdef CB_SYS_fdatasync
+# define TARGET_LINUX_SYS_fdatasync 148
+ { CB_SYS_fdatasync, TARGET_LINUX_SYS_fdatasync },
+#endif
+#ifdef CB_SYS__sysctl
+# define TARGET_LINUX_SYS__sysctl 149
+ { CB_SYS__sysctl, TARGET_LINUX_SYS__sysctl },
+#endif
+#ifdef CB_SYS_sched_setparam
+# define TARGET_LINUX_SYS_sched_setparam 154
+ { CB_SYS_sched_setparam, TARGET_LINUX_SYS_sched_setparam },
+#endif
+#ifdef CB_SYS_sched_getparam
+# define TARGET_LINUX_SYS_sched_getparam 155
+ { CB_SYS_sched_getparam, TARGET_LINUX_SYS_sched_getparam },
+#endif
+#ifdef CB_SYS_sched_setscheduler
+# define TARGET_LINUX_SYS_sched_setscheduler 156
+ { CB_SYS_sched_setscheduler, TARGET_LINUX_SYS_sched_setscheduler },
+#endif
+#ifdef CB_SYS_sched_getscheduler
+# define TARGET_LINUX_SYS_sched_getscheduler 157
+ { CB_SYS_sched_getscheduler, TARGET_LINUX_SYS_sched_getscheduler },
+#endif
+#ifdef CB_SYS_sched_yield
+# define TARGET_LINUX_SYS_sched_yield 158
+ { CB_SYS_sched_yield, TARGET_LINUX_SYS_sched_yield },
+#endif
+#ifdef CB_SYS_sched_get_priority_max
+# define TARGET_LINUX_SYS_sched_get_priority_max 159
+ { CB_SYS_sched_get_priority_max, TARGET_LINUX_SYS_sched_get_priority_max },
+#endif
+#ifdef CB_SYS_sched_get_priority_min
+# define TARGET_LINUX_SYS_sched_get_priority_min 160
+ { CB_SYS_sched_get_priority_min, TARGET_LINUX_SYS_sched_get_priority_min },
+#endif
+#ifdef CB_SYS_sched_rr_get_interval
+# define TARGET_LINUX_SYS_sched_rr_get_interval 161
+ { CB_SYS_sched_rr_get_interval, TARGET_LINUX_SYS_sched_rr_get_interval },
+#endif
+#ifdef CB_SYS_nanosleep
+# define TARGET_LINUX_SYS_nanosleep 162
+ { CB_SYS_nanosleep, TARGET_LINUX_SYS_nanosleep },
+#endif
+#ifdef CB_SYS_mremap
+# define TARGET_LINUX_SYS_mremap 163
+ { CB_SYS_mremap, TARGET_LINUX_SYS_mremap },
+#endif
+#ifdef CB_SYS_setresuid
+# define TARGET_LINUX_SYS_setresuid 164
+ { CB_SYS_setresuid, TARGET_LINUX_SYS_setresuid },
+#endif
+#ifdef CB_SYS_getresuid
+# define TARGET_LINUX_SYS_getresuid 165
+ { CB_SYS_getresuid, TARGET_LINUX_SYS_getresuid },
+#endif
+#ifdef CB_SYS_nfsservctl
+# define TARGET_LINUX_SYS_nfsservctl 169
+ { CB_SYS_nfsservctl, TARGET_LINUX_SYS_nfsservctl },
+#endif
+#ifdef CB_SYS_setresgid
+# define TARGET_LINUX_SYS_setresgid 170
+ { CB_SYS_setresgid, TARGET_LINUX_SYS_setresgid },
+#endif
+#ifdef CB_SYS_getresgid
+# define TARGET_LINUX_SYS_getresgid 171
+ { CB_SYS_getresgid, TARGET_LINUX_SYS_getresgid },
+#endif
+#ifdef CB_SYS_prctl
+# define TARGET_LINUX_SYS_prctl 172
+ { CB_SYS_prctl, TARGET_LINUX_SYS_prctl },
+#endif
+#ifdef CB_SYS_rt_sigreturn
+# define TARGET_LINUX_SYS_rt_sigreturn 173
+ { CB_SYS_rt_sigreturn, TARGET_LINUX_SYS_rt_sigreturn },
+#endif
+#ifdef CB_SYS_rt_sigaction
+# define TARGET_LINUX_SYS_rt_sigaction 174
+ { CB_SYS_rt_sigaction, TARGET_LINUX_SYS_rt_sigaction },
+#endif
+#ifdef CB_SYS_rt_sigprocmask
+# define TARGET_LINUX_SYS_rt_sigprocmask 175
+ { CB_SYS_rt_sigprocmask, TARGET_LINUX_SYS_rt_sigprocmask },
+#endif
+#ifdef CB_SYS_rt_sigpending
+# define TARGET_LINUX_SYS_rt_sigpending 176
+ { CB_SYS_rt_sigpending, TARGET_LINUX_SYS_rt_sigpending },
+#endif
+#ifdef CB_SYS_rt_sigtimedwait
+# define TARGET_LINUX_SYS_rt_sigtimedwait 177
+ { CB_SYS_rt_sigtimedwait, TARGET_LINUX_SYS_rt_sigtimedwait },
+#endif
+#ifdef CB_SYS_rt_sigqueueinfo
+# define TARGET_LINUX_SYS_rt_sigqueueinfo 178
+ { CB_SYS_rt_sigqueueinfo, TARGET_LINUX_SYS_rt_sigqueueinfo },
+#endif
+#ifdef CB_SYS_rt_sigsuspend
+# define TARGET_LINUX_SYS_rt_sigsuspend 179
+ { CB_SYS_rt_sigsuspend, TARGET_LINUX_SYS_rt_sigsuspend },
+#endif
+#ifdef CB_SYS_pread
+# define TARGET_LINUX_SYS_pread 180
+ { CB_SYS_pread, TARGET_LINUX_SYS_pread },
+#endif
+#ifdef CB_SYS_pwrite
+# define TARGET_LINUX_SYS_pwrite 181
+ { CB_SYS_pwrite, TARGET_LINUX_SYS_pwrite },
+#endif
+#ifdef CB_SYS_lchown
+# define TARGET_LINUX_SYS_lchown 182
+ { CB_SYS_lchown, TARGET_LINUX_SYS_lchown },
+#endif
+#ifdef CB_SYS_getcwd
+# define TARGET_LINUX_SYS_getcwd 183
+ { CB_SYS_getcwd, TARGET_LINUX_SYS_getcwd },
+#endif
+#ifdef CB_SYS_capget
+# define TARGET_LINUX_SYS_capget 184
+ { CB_SYS_capget, TARGET_LINUX_SYS_capget },
+#endif
+#ifdef CB_SYS_capset
+# define TARGET_LINUX_SYS_capset 185
+ { CB_SYS_capset, TARGET_LINUX_SYS_capset },
+#endif
+#ifdef CB_SYS_sigaltstack
+# define TARGET_LINUX_SYS_sigaltstack 186
+ { CB_SYS_sigaltstack, TARGET_LINUX_SYS_sigaltstack },
+#endif
+#ifdef CB_SYS_sendfile
+# define TARGET_LINUX_SYS_sendfile 187
+ { CB_SYS_sendfile, TARGET_LINUX_SYS_sendfile },
+#endif
+#ifdef CB_SYS_vfork
+# define TARGET_LINUX_SYS_vfork 190
+ { CB_SYS_vfork, TARGET_LINUX_SYS_vfork },
+#endif
+#ifdef CB_SYS_getrlimit
+# define TARGET_LINUX_SYS_getrlimit 191
+ { CB_SYS_getrlimit, TARGET_LINUX_SYS_getrlimit },
+#endif
+#ifdef CB_SYS_mmap2
+# define TARGET_LINUX_SYS_mmap2 192
+ { CB_SYS_mmap2, TARGET_LINUX_SYS_mmap2 },
+#endif
+#ifdef CB_SYS_truncate64
+# define TARGET_LINUX_SYS_truncate64 193
+ { CB_SYS_truncate64, TARGET_LINUX_SYS_truncate64 },
+#endif
+#ifdef CB_SYS_ftruncate64
+# define TARGET_LINUX_SYS_ftruncate64 194
+ { CB_SYS_ftruncate64, TARGET_LINUX_SYS_ftruncate64 },
+#endif
+#ifdef CB_SYS_stat64
+# define TARGET_LINUX_SYS_stat64 195
+ { CB_SYS_stat64, TARGET_LINUX_SYS_stat64 },
+#endif
+#ifdef CB_SYS_lstat64
+# define TARGET_LINUX_SYS_lstat64 196
+ { CB_SYS_lstat64, TARGET_LINUX_SYS_lstat64 },
+#endif
+#ifdef CB_SYS_fstat64
+# define TARGET_LINUX_SYS_fstat64 197
+ { CB_SYS_fstat64, TARGET_LINUX_SYS_fstat64 },
+#endif
+#ifdef CB_SYS_chown32
+# define TARGET_LINUX_SYS_chown32 198
+ { CB_SYS_chown32, TARGET_LINUX_SYS_chown32 },
+#endif
+#ifdef CB_SYS_getuid32
+# define TARGET_LINUX_SYS_getuid32 199
+ { CB_SYS_getuid32, TARGET_LINUX_SYS_getuid32 },
+#endif
+#ifdef CB_SYS_getgid32
+# define TARGET_LINUX_SYS_getgid32 200
+ { CB_SYS_getgid32, TARGET_LINUX_SYS_getgid32 },
+#endif
+#ifdef CB_SYS_geteuid32
+# define TARGET_LINUX_SYS_geteuid32 201
+ { CB_SYS_geteuid32, TARGET_LINUX_SYS_geteuid32 },
+#endif
+#ifdef CB_SYS_getegid32
+# define TARGET_LINUX_SYS_getegid32 202
+ { CB_SYS_getegid32, TARGET_LINUX_SYS_getegid32 },
+#endif
+#ifdef CB_SYS_setreuid32
+# define TARGET_LINUX_SYS_setreuid32 203
+ { CB_SYS_setreuid32, TARGET_LINUX_SYS_setreuid32 },
+#endif
+#ifdef CB_SYS_setregid32
+# define TARGET_LINUX_SYS_setregid32 204
+ { CB_SYS_setregid32, TARGET_LINUX_SYS_setregid32 },
+#endif
+#ifdef CB_SYS_getgroups32
+# define TARGET_LINUX_SYS_getgroups32 205
+ { CB_SYS_getgroups32, TARGET_LINUX_SYS_getgroups32 },
+#endif
+#ifdef CB_SYS_setgroups32
+# define TARGET_LINUX_SYS_setgroups32 206
+ { CB_SYS_setgroups32, TARGET_LINUX_SYS_setgroups32 },
+#endif
+#ifdef CB_SYS_fchown32
+# define TARGET_LINUX_SYS_fchown32 207
+ { CB_SYS_fchown32, TARGET_LINUX_SYS_fchown32 },
+#endif
+#ifdef CB_SYS_setresuid32
+# define TARGET_LINUX_SYS_setresuid32 208
+ { CB_SYS_setresuid32, TARGET_LINUX_SYS_setresuid32 },
+#endif
+#ifdef CB_SYS_getresuid32
+# define TARGET_LINUX_SYS_getresuid32 209
+ { CB_SYS_getresuid32, TARGET_LINUX_SYS_getresuid32 },
+#endif
+#ifdef CB_SYS_setresgid32
+# define TARGET_LINUX_SYS_setresgid32 210
+ { CB_SYS_setresgid32, TARGET_LINUX_SYS_setresgid32 },
+#endif
+#ifdef CB_SYS_getresgid32
+# define TARGET_LINUX_SYS_getresgid32 211
+ { CB_SYS_getresgid32, TARGET_LINUX_SYS_getresgid32 },
+#endif
+#ifdef CB_SYS_lchown32
+# define TARGET_LINUX_SYS_lchown32 212
+ { CB_SYS_lchown32, TARGET_LINUX_SYS_lchown32 },
+#endif
+#ifdef CB_SYS_setuid32
+# define TARGET_LINUX_SYS_setuid32 213
+ { CB_SYS_setuid32, TARGET_LINUX_SYS_setuid32 },
+#endif
+#ifdef CB_SYS_setgid32
+# define TARGET_LINUX_SYS_setgid32 214
+ { CB_SYS_setgid32, TARGET_LINUX_SYS_setgid32 },
+#endif
+#ifdef CB_SYS_setfsuid32
+# define TARGET_LINUX_SYS_setfsuid32 215
+ { CB_SYS_setfsuid32, TARGET_LINUX_SYS_setfsuid32 },
+#endif
+#ifdef CB_SYS_setfsgid32
+# define TARGET_LINUX_SYS_setfsgid32 216
+ { CB_SYS_setfsgid32, TARGET_LINUX_SYS_setfsgid32 },
+#endif
+#ifdef CB_SYS_pivot_root
+# define TARGET_LINUX_SYS_pivot_root 217
+ { CB_SYS_pivot_root, TARGET_LINUX_SYS_pivot_root },
+#endif
+#ifdef CB_SYS_getdents64
+# define TARGET_LINUX_SYS_getdents64 220
+ { CB_SYS_getdents64, TARGET_LINUX_SYS_getdents64 },
+#endif
+#ifdef CB_SYS_fcntl64
+# define TARGET_LINUX_SYS_fcntl64 221
+ { CB_SYS_fcntl64, TARGET_LINUX_SYS_fcntl64 },
+#endif
+#ifdef CB_SYS_gettid
+# define TARGET_LINUX_SYS_gettid 224
+ { CB_SYS_gettid, TARGET_LINUX_SYS_gettid },
+#endif
+#ifdef CB_SYS_readahead
+# define TARGET_LINUX_SYS_readahead 225
+ { CB_SYS_readahead, TARGET_LINUX_SYS_readahead },
+#endif
+#ifdef CB_SYS_setxattr
+# define TARGET_LINUX_SYS_setxattr 226
+ { CB_SYS_setxattr, TARGET_LINUX_SYS_setxattr },
+#endif
+#ifdef CB_SYS_lsetxattr
+# define TARGET_LINUX_SYS_lsetxattr 227
+ { CB_SYS_lsetxattr, TARGET_LINUX_SYS_lsetxattr },
+#endif
+#ifdef CB_SYS_fsetxattr
+# define TARGET_LINUX_SYS_fsetxattr 228
+ { CB_SYS_fsetxattr, TARGET_LINUX_SYS_fsetxattr },
+#endif
+#ifdef CB_SYS_getxattr
+# define TARGET_LINUX_SYS_getxattr 229
+ { CB_SYS_getxattr, TARGET_LINUX_SYS_getxattr },
+#endif
+#ifdef CB_SYS_lgetxattr
+# define TARGET_LINUX_SYS_lgetxattr 230
+ { CB_SYS_lgetxattr, TARGET_LINUX_SYS_lgetxattr },
+#endif
+#ifdef CB_SYS_fgetxattr
+# define TARGET_LINUX_SYS_fgetxattr 231
+ { CB_SYS_fgetxattr, TARGET_LINUX_SYS_fgetxattr },
+#endif
+#ifdef CB_SYS_listxattr
+# define TARGET_LINUX_SYS_listxattr 232
+ { CB_SYS_listxattr, TARGET_LINUX_SYS_listxattr },
+#endif
+#ifdef CB_SYS_llistxattr
+# define TARGET_LINUX_SYS_llistxattr 233
+ { CB_SYS_llistxattr, TARGET_LINUX_SYS_llistxattr },
+#endif
+#ifdef CB_SYS_flistxattr
+# define TARGET_LINUX_SYS_flistxattr 234
+ { CB_SYS_flistxattr, TARGET_LINUX_SYS_flistxattr },
+#endif
+#ifdef CB_SYS_removexattr
+# define TARGET_LINUX_SYS_removexattr 235
+ { CB_SYS_removexattr, TARGET_LINUX_SYS_removexattr },
+#endif
+#ifdef CB_SYS_lremovexattr
+# define TARGET_LINUX_SYS_lremovexattr 236
+ { CB_SYS_lremovexattr, TARGET_LINUX_SYS_lremovexattr },
+#endif
+#ifdef CB_SYS_fremovexattr
+# define TARGET_LINUX_SYS_fremovexattr 237
+ { CB_SYS_fremovexattr, TARGET_LINUX_SYS_fremovexattr },
+#endif
+#ifdef CB_SYS_tkill
+# define TARGET_LINUX_SYS_tkill 238
+ { CB_SYS_tkill, TARGET_LINUX_SYS_tkill },
+#endif
+#ifdef CB_SYS_sendfile64
+# define TARGET_LINUX_SYS_sendfile64 239
+ { CB_SYS_sendfile64, TARGET_LINUX_SYS_sendfile64 },
+#endif
+#ifdef CB_SYS_futex
+# define TARGET_LINUX_SYS_futex 240
+ { CB_SYS_futex, TARGET_LINUX_SYS_futex },
+#endif
+#ifdef CB_SYS_sched_setaffinity
+# define TARGET_LINUX_SYS_sched_setaffinity 241
+ { CB_SYS_sched_setaffinity, TARGET_LINUX_SYS_sched_setaffinity },
+#endif
+#ifdef CB_SYS_sched_getaffinity
+# define TARGET_LINUX_SYS_sched_getaffinity 242
+ { CB_SYS_sched_getaffinity, TARGET_LINUX_SYS_sched_getaffinity },
+#endif
+#ifdef CB_SYS_io_setup
+# define TARGET_LINUX_SYS_io_setup 245
+ { CB_SYS_io_setup, TARGET_LINUX_SYS_io_setup },
+#endif
+#ifdef CB_SYS_io_destroy
+# define TARGET_LINUX_SYS_io_destroy 246
+ { CB_SYS_io_destroy, TARGET_LINUX_SYS_io_destroy },
+#endif
+#ifdef CB_SYS_io_getevents
+# define TARGET_LINUX_SYS_io_getevents 247
+ { CB_SYS_io_getevents, TARGET_LINUX_SYS_io_getevents },
+#endif
+#ifdef CB_SYS_io_submit
+# define TARGET_LINUX_SYS_io_submit 248
+ { CB_SYS_io_submit, TARGET_LINUX_SYS_io_submit },
+#endif
+#ifdef CB_SYS_io_cancel
+# define TARGET_LINUX_SYS_io_cancel 249
+ { CB_SYS_io_cancel, TARGET_LINUX_SYS_io_cancel },
+#endif
+#ifdef CB_SYS_exit_group
+# define TARGET_LINUX_SYS_exit_group 252
+ { CB_SYS_exit_group, TARGET_LINUX_SYS_exit_group },
+#endif
+#ifdef CB_SYS_lookup_dcookie
+# define TARGET_LINUX_SYS_lookup_dcookie 253
+ { CB_SYS_lookup_dcookie, TARGET_LINUX_SYS_lookup_dcookie },
+#endif
+#ifdef CB_SYS_bfin_spinlock
+# define TARGET_LINUX_SYS_bfin_spinlock 254
+ { CB_SYS_bfin_spinlock, TARGET_LINUX_SYS_bfin_spinlock },
+#endif
+#ifdef CB_SYS_epoll_create
+# define TARGET_LINUX_SYS_epoll_create 255
+ { CB_SYS_epoll_create, TARGET_LINUX_SYS_epoll_create },
+#endif
+#ifdef CB_SYS_epoll_ctl
+# define TARGET_LINUX_SYS_epoll_ctl 256
+ { CB_SYS_epoll_ctl, TARGET_LINUX_SYS_epoll_ctl },
+#endif
+#ifdef CB_SYS_epoll_wait
+# define TARGET_LINUX_SYS_epoll_wait 257
+ { CB_SYS_epoll_wait, TARGET_LINUX_SYS_epoll_wait },
+#endif
+#ifdef CB_SYS_set_tid_address
+# define TARGET_LINUX_SYS_set_tid_address 259
+ { CB_SYS_set_tid_address, TARGET_LINUX_SYS_set_tid_address },
+#endif
+#ifdef CB_SYS_timer_create
+# define TARGET_LINUX_SYS_timer_create 260
+ { CB_SYS_timer_create, TARGET_LINUX_SYS_timer_create },
+#endif
+#ifdef CB_SYS_timer_settime
+# define TARGET_LINUX_SYS_timer_settime 261
+ { CB_SYS_timer_settime, TARGET_LINUX_SYS_timer_settime },
+#endif
+#ifdef CB_SYS_timer_gettime
+# define TARGET_LINUX_SYS_timer_gettime 262
+ { CB_SYS_timer_gettime, TARGET_LINUX_SYS_timer_gettime },
+#endif
+#ifdef CB_SYS_timer_getoverrun
+# define TARGET_LINUX_SYS_timer_getoverrun 263
+ { CB_SYS_timer_getoverrun, TARGET_LINUX_SYS_timer_getoverrun },
+#endif
+#ifdef CB_SYS_timer_delete
+# define TARGET_LINUX_SYS_timer_delete 264
+ { CB_SYS_timer_delete, TARGET_LINUX_SYS_timer_delete },
+#endif
+#ifdef CB_SYS_clock_settime
+# define TARGET_LINUX_SYS_clock_settime 265
+ { CB_SYS_clock_settime, TARGET_LINUX_SYS_clock_settime },
+#endif
+#ifdef CB_SYS_clock_gettime
+# define TARGET_LINUX_SYS_clock_gettime 266
+ { CB_SYS_clock_gettime, TARGET_LINUX_SYS_clock_gettime },
+#endif
+#ifdef CB_SYS_clock_getres
+# define TARGET_LINUX_SYS_clock_getres 267
+ { CB_SYS_clock_getres, TARGET_LINUX_SYS_clock_getres },
+#endif
+#ifdef CB_SYS_clock_nanosleep
+# define TARGET_LINUX_SYS_clock_nanosleep 268
+ { CB_SYS_clock_nanosleep, TARGET_LINUX_SYS_clock_nanosleep },
+#endif
+#ifdef CB_SYS_statfs64
+# define TARGET_LINUX_SYS_statfs64 269
+ { CB_SYS_statfs64, TARGET_LINUX_SYS_statfs64 },
+#endif
+#ifdef CB_SYS_fstatfs64
+# define TARGET_LINUX_SYS_fstatfs64 270
+ { CB_SYS_fstatfs64, TARGET_LINUX_SYS_fstatfs64 },
+#endif
+#ifdef CB_SYS_tgkill
+# define TARGET_LINUX_SYS_tgkill 271
+ { CB_SYS_tgkill, TARGET_LINUX_SYS_tgkill },
+#endif
+#ifdef CB_SYS_utimes
+# define TARGET_LINUX_SYS_utimes 272
+ { CB_SYS_utimes, TARGET_LINUX_SYS_utimes },
+#endif
+#ifdef CB_SYS_fadvise64_64
+# define TARGET_LINUX_SYS_fadvise64_64 273
+ { CB_SYS_fadvise64_64, TARGET_LINUX_SYS_fadvise64_64 },
+#endif
+#ifdef CB_SYS_mq_open
+# define TARGET_LINUX_SYS_mq_open 278
+ { CB_SYS_mq_open, TARGET_LINUX_SYS_mq_open },
+#endif
+#ifdef CB_SYS_mq_unlink
+# define TARGET_LINUX_SYS_mq_unlink 279
+ { CB_SYS_mq_unlink, TARGET_LINUX_SYS_mq_unlink },
+#endif
+#ifdef CB_SYS_mq_timedsend
+# define TARGET_LINUX_SYS_mq_timedsend 280
+ { CB_SYS_mq_timedsend, TARGET_LINUX_SYS_mq_timedsend },
+#endif
+#ifdef CB_SYS_mq_timedreceive
+# define TARGET_LINUX_SYS_mq_timedreceive 281
+ { CB_SYS_mq_timedreceive, TARGET_LINUX_SYS_mq_timedreceive },
+#endif
+#ifdef CB_SYS_mq_notify
+# define TARGET_LINUX_SYS_mq_notify 282
+ { CB_SYS_mq_notify, TARGET_LINUX_SYS_mq_notify },
+#endif
+#ifdef CB_SYS_mq_getsetattr
+# define TARGET_LINUX_SYS_mq_getsetattr 283
+ { CB_SYS_mq_getsetattr, TARGET_LINUX_SYS_mq_getsetattr },
+#endif
+#ifdef CB_SYS_kexec_load
+# define TARGET_LINUX_SYS_kexec_load 284
+ { CB_SYS_kexec_load, TARGET_LINUX_SYS_kexec_load },
+#endif
+#ifdef CB_SYS_waitid
+# define TARGET_LINUX_SYS_waitid 285
+ { CB_SYS_waitid, TARGET_LINUX_SYS_waitid },
+#endif
+#ifdef CB_SYS_add_key
+# define TARGET_LINUX_SYS_add_key 286
+ { CB_SYS_add_key, TARGET_LINUX_SYS_add_key },
+#endif
+#ifdef CB_SYS_request_key
+# define TARGET_LINUX_SYS_request_key 287
+ { CB_SYS_request_key, TARGET_LINUX_SYS_request_key },
+#endif
+#ifdef CB_SYS_keyctl
+# define TARGET_LINUX_SYS_keyctl 288
+ { CB_SYS_keyctl, TARGET_LINUX_SYS_keyctl },
+#endif
+#ifdef CB_SYS_ioprio_set
+# define TARGET_LINUX_SYS_ioprio_set 289
+ { CB_SYS_ioprio_set, TARGET_LINUX_SYS_ioprio_set },
+#endif
+#ifdef CB_SYS_ioprio_get
+# define TARGET_LINUX_SYS_ioprio_get 290
+ { CB_SYS_ioprio_get, TARGET_LINUX_SYS_ioprio_get },
+#endif
+#ifdef CB_SYS_inotify_init
+# define TARGET_LINUX_SYS_inotify_init 291
+ { CB_SYS_inotify_init, TARGET_LINUX_SYS_inotify_init },
+#endif
+#ifdef CB_SYS_inotify_add_watch
+# define TARGET_LINUX_SYS_inotify_add_watch 292
+ { CB_SYS_inotify_add_watch, TARGET_LINUX_SYS_inotify_add_watch },
+#endif
+#ifdef CB_SYS_inotify_rm_watch
+# define TARGET_LINUX_SYS_inotify_rm_watch 293
+ { CB_SYS_inotify_rm_watch, TARGET_LINUX_SYS_inotify_rm_watch },
+#endif
+#ifdef CB_SYS_openat
+# define TARGET_LINUX_SYS_openat 295
+ { CB_SYS_openat, TARGET_LINUX_SYS_openat },
+#endif
+#ifdef CB_SYS_mkdirat
+# define TARGET_LINUX_SYS_mkdirat 296
+ { CB_SYS_mkdirat, TARGET_LINUX_SYS_mkdirat },
+#endif
+#ifdef CB_SYS_mknodat
+# define TARGET_LINUX_SYS_mknodat 297
+ { CB_SYS_mknodat, TARGET_LINUX_SYS_mknodat },
+#endif
+#ifdef CB_SYS_fchownat
+# define TARGET_LINUX_SYS_fchownat 298
+ { CB_SYS_fchownat, TARGET_LINUX_SYS_fchownat },
+#endif
+#ifdef CB_SYS_futimesat
+# define TARGET_LINUX_SYS_futimesat 299
+ { CB_SYS_futimesat, TARGET_LINUX_SYS_futimesat },
+#endif
+#ifdef CB_SYS_fstatat64
+# define TARGET_LINUX_SYS_fstatat64 300
+ { CB_SYS_fstatat64, TARGET_LINUX_SYS_fstatat64 },
+#endif
+#ifdef CB_SYS_unlinkat
+# define TARGET_LINUX_SYS_unlinkat 301
+ { CB_SYS_unlinkat, TARGET_LINUX_SYS_unlinkat },
+#endif
+#ifdef CB_SYS_renameat
+# define TARGET_LINUX_SYS_renameat 302
+ { CB_SYS_renameat, TARGET_LINUX_SYS_renameat },
+#endif
+#ifdef CB_SYS_linkat
+# define TARGET_LINUX_SYS_linkat 303
+ { CB_SYS_linkat, TARGET_LINUX_SYS_linkat },
+#endif
+#ifdef CB_SYS_symlinkat
+# define TARGET_LINUX_SYS_symlinkat 304
+ { CB_SYS_symlinkat, TARGET_LINUX_SYS_symlinkat },
+#endif
+#ifdef CB_SYS_readlinkat
+# define TARGET_LINUX_SYS_readlinkat 305
+ { CB_SYS_readlinkat, TARGET_LINUX_SYS_readlinkat },
+#endif
+#ifdef CB_SYS_fchmodat
+# define TARGET_LINUX_SYS_fchmodat 306
+ { CB_SYS_fchmodat, TARGET_LINUX_SYS_fchmodat },
+#endif
+#ifdef CB_SYS_faccessat
+# define TARGET_LINUX_SYS_faccessat 307
+ { CB_SYS_faccessat, TARGET_LINUX_SYS_faccessat },
+#endif
+#ifdef CB_SYS_pselect6
+# define TARGET_LINUX_SYS_pselect6 308
+ { CB_SYS_pselect6, TARGET_LINUX_SYS_pselect6 },
+#endif
+#ifdef CB_SYS_ppoll
+# define TARGET_LINUX_SYS_ppoll 309
+ { CB_SYS_ppoll, TARGET_LINUX_SYS_ppoll },
+#endif
+#ifdef CB_SYS_unshare
+# define TARGET_LINUX_SYS_unshare 310
+ { CB_SYS_unshare, TARGET_LINUX_SYS_unshare },
+#endif
+#ifdef CB_SYS_sram_alloc
+# define TARGET_LINUX_SYS_sram_alloc 311
+ { CB_SYS_sram_alloc, TARGET_LINUX_SYS_sram_alloc },
+#endif
+#ifdef CB_SYS_sram_free
+# define TARGET_LINUX_SYS_sram_free 312
+ { CB_SYS_sram_free, TARGET_LINUX_SYS_sram_free },
+#endif
+#ifdef CB_SYS_dma_memcpy
+# define TARGET_LINUX_SYS_dma_memcpy 313
+ { CB_SYS_dma_memcpy, TARGET_LINUX_SYS_dma_memcpy },
+#endif
+#ifdef CB_SYS_accept
+# define TARGET_LINUX_SYS_accept 314
+ { CB_SYS_accept, TARGET_LINUX_SYS_accept },
+#endif
+#ifdef CB_SYS_bind
+# define TARGET_LINUX_SYS_bind 315
+ { CB_SYS_bind, TARGET_LINUX_SYS_bind },
+#endif
+#ifdef CB_SYS_connect
+# define TARGET_LINUX_SYS_connect 316
+ { CB_SYS_connect, TARGET_LINUX_SYS_connect },
+#endif
+#ifdef CB_SYS_getpeername
+# define TARGET_LINUX_SYS_getpeername 317
+ { CB_SYS_getpeername, TARGET_LINUX_SYS_getpeername },
+#endif
+#ifdef CB_SYS_getsockname
+# define TARGET_LINUX_SYS_getsockname 318
+ { CB_SYS_getsockname, TARGET_LINUX_SYS_getsockname },
+#endif
+#ifdef CB_SYS_getsockopt
+# define TARGET_LINUX_SYS_getsockopt 319
+ { CB_SYS_getsockopt, TARGET_LINUX_SYS_getsockopt },
+#endif
+#ifdef CB_SYS_listen
+# define TARGET_LINUX_SYS_listen 320
+ { CB_SYS_listen, TARGET_LINUX_SYS_listen },
+#endif
+#ifdef CB_SYS_recv
+# define TARGET_LINUX_SYS_recv 321
+ { CB_SYS_recv, TARGET_LINUX_SYS_recv },
+#endif
+#ifdef CB_SYS_recvfrom
+# define TARGET_LINUX_SYS_recvfrom 322
+ { CB_SYS_recvfrom, TARGET_LINUX_SYS_recvfrom },
+#endif
+#ifdef CB_SYS_recvmsg
+# define TARGET_LINUX_SYS_recvmsg 323
+ { CB_SYS_recvmsg, TARGET_LINUX_SYS_recvmsg },
+#endif
+#ifdef CB_SYS_send
+# define TARGET_LINUX_SYS_send 324
+ { CB_SYS_send, TARGET_LINUX_SYS_send },
+#endif
+#ifdef CB_SYS_sendmsg
+# define TARGET_LINUX_SYS_sendmsg 325
+ { CB_SYS_sendmsg, TARGET_LINUX_SYS_sendmsg },
+#endif
+#ifdef CB_SYS_sendto
+# define TARGET_LINUX_SYS_sendto 326
+ { CB_SYS_sendto, TARGET_LINUX_SYS_sendto },
+#endif
+#ifdef CB_SYS_setsockopt
+# define TARGET_LINUX_SYS_setsockopt 327
+ { CB_SYS_setsockopt, TARGET_LINUX_SYS_setsockopt },
+#endif
+#ifdef CB_SYS_shutdown
+# define TARGET_LINUX_SYS_shutdown 328
+ { CB_SYS_shutdown, TARGET_LINUX_SYS_shutdown },
+#endif
+#ifdef CB_SYS_socket
+# define TARGET_LINUX_SYS_socket 329
+ { CB_SYS_socket, TARGET_LINUX_SYS_socket },
+#endif
+#ifdef CB_SYS_socketpair
+# define TARGET_LINUX_SYS_socketpair 330
+ { CB_SYS_socketpair, TARGET_LINUX_SYS_socketpair },
+#endif
+#ifdef CB_SYS_semctl
+# define TARGET_LINUX_SYS_semctl 331
+ { CB_SYS_semctl, TARGET_LINUX_SYS_semctl },
+#endif
+#ifdef CB_SYS_semget
+# define TARGET_LINUX_SYS_semget 332
+ { CB_SYS_semget, TARGET_LINUX_SYS_semget },
+#endif
+#ifdef CB_SYS_semop
+# define TARGET_LINUX_SYS_semop 333
+ { CB_SYS_semop, TARGET_LINUX_SYS_semop },
+#endif
+#ifdef CB_SYS_msgctl
+# define TARGET_LINUX_SYS_msgctl 334
+ { CB_SYS_msgctl, TARGET_LINUX_SYS_msgctl },
+#endif
+#ifdef CB_SYS_msgget
+# define TARGET_LINUX_SYS_msgget 335
+ { CB_SYS_msgget, TARGET_LINUX_SYS_msgget },
+#endif
+#ifdef CB_SYS_msgrcv
+# define TARGET_LINUX_SYS_msgrcv 336
+ { CB_SYS_msgrcv, TARGET_LINUX_SYS_msgrcv },
+#endif
+#ifdef CB_SYS_msgsnd
+# define TARGET_LINUX_SYS_msgsnd 337
+ { CB_SYS_msgsnd, TARGET_LINUX_SYS_msgsnd },
+#endif
+#ifdef CB_SYS_shmat
+# define TARGET_LINUX_SYS_shmat 338
+ { CB_SYS_shmat, TARGET_LINUX_SYS_shmat },
+#endif
+#ifdef CB_SYS_shmctl
+# define TARGET_LINUX_SYS_shmctl 339
+ { CB_SYS_shmctl, TARGET_LINUX_SYS_shmctl },
+#endif
+#ifdef CB_SYS_shmdt
+# define TARGET_LINUX_SYS_shmdt 340
+ { CB_SYS_shmdt, TARGET_LINUX_SYS_shmdt },
+#endif
+#ifdef CB_SYS_shmget
+# define TARGET_LINUX_SYS_shmget 341
+ { CB_SYS_shmget, TARGET_LINUX_SYS_shmget },
+#endif
+#ifdef CB_SYS_splice
+# define TARGET_LINUX_SYS_splice 342
+ { CB_SYS_splice, TARGET_LINUX_SYS_splice },
+#endif
+#ifdef CB_SYS_sync_file_range
+# define TARGET_LINUX_SYS_sync_file_range 343
+ { CB_SYS_sync_file_range, TARGET_LINUX_SYS_sync_file_range },
+#endif
+#ifdef CB_SYS_tee
+# define TARGET_LINUX_SYS_tee 344
+ { CB_SYS_tee, TARGET_LINUX_SYS_tee },
+#endif
+#ifdef CB_SYS_vmsplice
+# define TARGET_LINUX_SYS_vmsplice 345
+ { CB_SYS_vmsplice, TARGET_LINUX_SYS_vmsplice },
+#endif
+#ifdef CB_SYS_epoll_pwait
+# define TARGET_LINUX_SYS_epoll_pwait 346
+ { CB_SYS_epoll_pwait, TARGET_LINUX_SYS_epoll_pwait },
+#endif
+#ifdef CB_SYS_utimensat
+# define TARGET_LINUX_SYS_utimensat 347
+ { CB_SYS_utimensat, TARGET_LINUX_SYS_utimensat },
+#endif
+#ifdef CB_SYS_signalfd
+# define TARGET_LINUX_SYS_signalfd 348
+ { CB_SYS_signalfd, TARGET_LINUX_SYS_signalfd },
+#endif
+#ifdef CB_SYS_timerfd_create
+# define TARGET_LINUX_SYS_timerfd_create 349
+ { CB_SYS_timerfd_create, TARGET_LINUX_SYS_timerfd_create },
+#endif
+#ifdef CB_SYS_eventfd
+# define TARGET_LINUX_SYS_eventfd 350
+ { CB_SYS_eventfd, TARGET_LINUX_SYS_eventfd },
+#endif
+#ifdef CB_SYS_pread64
+# define TARGET_LINUX_SYS_pread64 351
+ { CB_SYS_pread64, TARGET_LINUX_SYS_pread64 },
+#endif
+#ifdef CB_SYS_pwrite64
+# define TARGET_LINUX_SYS_pwrite64 352
+ { CB_SYS_pwrite64, TARGET_LINUX_SYS_pwrite64 },
+#endif
+#ifdef CB_SYS_fadvise64
+# define TARGET_LINUX_SYS_fadvise64 353
+ { CB_SYS_fadvise64, TARGET_LINUX_SYS_fadvise64 },
+#endif
+#ifdef CB_SYS_set_robust_list
+# define TARGET_LINUX_SYS_set_robust_list 354
+ { CB_SYS_set_robust_list, TARGET_LINUX_SYS_set_robust_list },
+#endif
+#ifdef CB_SYS_get_robust_list
+# define TARGET_LINUX_SYS_get_robust_list 355
+ { CB_SYS_get_robust_list, TARGET_LINUX_SYS_get_robust_list },
+#endif
+#ifdef CB_SYS_fallocate
+# define TARGET_LINUX_SYS_fallocate 356
+ { CB_SYS_fallocate, TARGET_LINUX_SYS_fallocate },
+#endif
+#ifdef CB_SYS_semtimedop
+# define TARGET_LINUX_SYS_semtimedop 357
+ { CB_SYS_semtimedop, TARGET_LINUX_SYS_semtimedop },
+#endif
+#ifdef CB_SYS_timerfd_settime
+# define TARGET_LINUX_SYS_timerfd_settime 358
+ { CB_SYS_timerfd_settime, TARGET_LINUX_SYS_timerfd_settime },
+#endif
+#ifdef CB_SYS_timerfd_gettime
+# define TARGET_LINUX_SYS_timerfd_gettime 359
+ { CB_SYS_timerfd_gettime, TARGET_LINUX_SYS_timerfd_gettime },
+#endif
+#ifdef CB_SYS_signalfd4
+# define TARGET_LINUX_SYS_signalfd4 360
+ { CB_SYS_signalfd4, TARGET_LINUX_SYS_signalfd4 },
+#endif
+#ifdef CB_SYS_eventfd2
+# define TARGET_LINUX_SYS_eventfd2 361
+ { CB_SYS_eventfd2, TARGET_LINUX_SYS_eventfd2 },
+#endif
+#ifdef CB_SYS_epoll_create1
+# define TARGET_LINUX_SYS_epoll_create1 362
+ { CB_SYS_epoll_create1, TARGET_LINUX_SYS_epoll_create1 },
+#endif
+#ifdef CB_SYS_dup3
+# define TARGET_LINUX_SYS_dup3 363
+ { CB_SYS_dup3, TARGET_LINUX_SYS_dup3 },
+#endif
+#ifdef CB_SYS_pipe2
+# define TARGET_LINUX_SYS_pipe2 364
+ { CB_SYS_pipe2, TARGET_LINUX_SYS_pipe2 },
+#endif
+#ifdef CB_SYS_inotify_init1
+# define TARGET_LINUX_SYS_inotify_init1 365
+ { CB_SYS_inotify_init1, TARGET_LINUX_SYS_inotify_init1 },
+#endif
+#ifdef CB_SYS_preadv
+# define TARGET_LINUX_SYS_preadv 366
+ { CB_SYS_preadv, TARGET_LINUX_SYS_preadv },
+#endif
+#ifdef CB_SYS_pwritev
+# define TARGET_LINUX_SYS_pwritev 367
+ { CB_SYS_pwritev, TARGET_LINUX_SYS_pwritev },
+#endif
+#ifdef CB_SYS_rt_tgsigqueueinfo
+# define TARGET_LINUX_SYS_rt_tgsigqueueinfo 368
+ { CB_SYS_rt_tgsigqueueinfo, TARGET_LINUX_SYS_rt_tgsigqueueinfo },
+#endif
+#ifdef CB_SYS_perf_event_open
+# define TARGET_LINUX_SYS_perf_event_open 369
+ { CB_SYS_perf_event_open, TARGET_LINUX_SYS_perf_event_open },
+#endif
+#ifdef CB_SYS_recvmmsg
+# define TARGET_LINUX_SYS_recvmmsg 370
+ { CB_SYS_recvmmsg, TARGET_LINUX_SYS_recvmmsg },
+#endif
+#ifdef CB_SYS_fanotify_init
+# define TARGET_LINUX_SYS_fanotify_init 371
+ { CB_SYS_fanotify_init, TARGET_LINUX_SYS_fanotify_init },
+#endif
+#ifdef CB_SYS_fanotify_mark
+# define TARGET_LINUX_SYS_fanotify_mark 372
+ { CB_SYS_fanotify_mark, TARGET_LINUX_SYS_fanotify_mark },
+#endif
+#ifdef CB_SYS_prlimit64
+# define TARGET_LINUX_SYS_prlimit64 373
+ { CB_SYS_prlimit64, TARGET_LINUX_SYS_prlimit64 },
+#endif
+#ifdef CB_SYS_cacheflush
+# define TARGET_LINUX_SYS_cacheflush 374
+ { CB_SYS_cacheflush, TARGET_LINUX_SYS_cacheflush },
+#endif
+#ifdef CB_SYS_syscall
+# define TARGET_LINUX_SYS_syscall 375
+ { CB_SYS_syscall, TARGET_LINUX_SYS_syscall },
+#endif
+ { -1, -1 }
+};
+
+static CB_TARGET_DEFS_MAP cb_linux_errno_map[] = {
+#ifdef EPERM
+# define TARGET_LINUX_EPERM 1
+ { EPERM, TARGET_LINUX_EPERM },
+#endif
+#ifdef ENOENT
+# define TARGET_LINUX_ENOENT 2
+ { ENOENT, TARGET_LINUX_ENOENT },
+#endif
+#ifdef ESRCH
+# define TARGET_LINUX_ESRCH 3
+ { ESRCH, TARGET_LINUX_ESRCH },
+#endif
+#ifdef EINTR
+# define TARGET_LINUX_EINTR 4
+ { EINTR, TARGET_LINUX_EINTR },
+#endif
+#ifdef EIO
+# define TARGET_LINUX_EIO 5
+ { EIO, TARGET_LINUX_EIO },
+#endif
+#ifdef ENXIO
+# define TARGET_LINUX_ENXIO 6
+ { ENXIO, TARGET_LINUX_ENXIO },
+#endif
+#ifdef E2BIG
+# define TARGET_LINUX_E2BIG 7
+ { E2BIG, TARGET_LINUX_E2BIG },
+#endif
+#ifdef ENOEXEC
+# define TARGET_LINUX_ENOEXEC 8
+ { ENOEXEC, TARGET_LINUX_ENOEXEC },
+#endif
+#ifdef EBADF
+# define TARGET_LINUX_EBADF 9
+ { EBADF, TARGET_LINUX_EBADF },
+#endif
+#ifdef ECHILD
+# define TARGET_LINUX_ECHILD 10
+ { ECHILD, TARGET_LINUX_ECHILD },
+#endif
+#ifdef EAGAIN
+# define TARGET_LINUX_EAGAIN 11
+ { EAGAIN, TARGET_LINUX_EAGAIN },
+#endif
+#ifdef ENOMEM
+# define TARGET_LINUX_ENOMEM 12
+ { ENOMEM, TARGET_LINUX_ENOMEM },
+#endif
+#ifdef EACCES
+# define TARGET_LINUX_EACCES 13
+ { EACCES, TARGET_LINUX_EACCES },
+#endif
+#ifdef EFAULT
+# define TARGET_LINUX_EFAULT 14
+ { EFAULT, TARGET_LINUX_EFAULT },
+#endif
+#ifdef ENOTBLK
+# define TARGET_LINUX_ENOTBLK 15
+ { ENOTBLK, TARGET_LINUX_ENOTBLK },
+#endif
+#ifdef EBUSY
+# define TARGET_LINUX_EBUSY 16
+ { EBUSY, TARGET_LINUX_EBUSY },
+#endif
+#ifdef EEXIST
+# define TARGET_LINUX_EEXIST 17
+ { EEXIST, TARGET_LINUX_EEXIST },
+#endif
+#ifdef EXDEV
+# define TARGET_LINUX_EXDEV 18
+ { EXDEV, TARGET_LINUX_EXDEV },
+#endif
+#ifdef ENODEV
+# define TARGET_LINUX_ENODEV 19
+ { ENODEV, TARGET_LINUX_ENODEV },
+#endif
+#ifdef ENOTDIR
+# define TARGET_LINUX_ENOTDIR 20
+ { ENOTDIR, TARGET_LINUX_ENOTDIR },
+#endif
+#ifdef EISDIR
+# define TARGET_LINUX_EISDIR 21
+ { EISDIR, TARGET_LINUX_EISDIR },
+#endif
+#ifdef EINVAL
+# define TARGET_LINUX_EINVAL 22
+ { EINVAL, TARGET_LINUX_EINVAL },
+#endif
+#ifdef ENFILE
+# define TARGET_LINUX_ENFILE 23
+ { ENFILE, TARGET_LINUX_ENFILE },
+#endif
+#ifdef EMFILE
+# define TARGET_LINUX_EMFILE 24
+ { EMFILE, TARGET_LINUX_EMFILE },
+#endif
+#ifdef ENOTTY
+# define TARGET_LINUX_ENOTTY 25
+ { ENOTTY, TARGET_LINUX_ENOTTY },
+#endif
+#ifdef ETXTBSY
+# define TARGET_LINUX_ETXTBSY 26
+ { ETXTBSY, TARGET_LINUX_ETXTBSY },
+#endif
+#ifdef EFBIG
+# define TARGET_LINUX_EFBIG 27
+ { EFBIG, TARGET_LINUX_EFBIG },
+#endif
+#ifdef ENOSPC
+# define TARGET_LINUX_ENOSPC 28
+ { ENOSPC, TARGET_LINUX_ENOSPC },
+#endif
+#ifdef ESPIPE
+# define TARGET_LINUX_ESPIPE 29
+ { ESPIPE, TARGET_LINUX_ESPIPE },
+#endif
+#ifdef EROFS
+# define TARGET_LINUX_EROFS 30
+ { EROFS, TARGET_LINUX_EROFS },
+#endif
+#ifdef EMLINK
+# define TARGET_LINUX_EMLINK 31
+ { EMLINK, TARGET_LINUX_EMLINK },
+#endif
+#ifdef EPIPE
+# define TARGET_LINUX_EPIPE 32
+ { EPIPE, TARGET_LINUX_EPIPE },
+#endif
+#ifdef EDOM
+# define TARGET_LINUX_EDOM 33
+ { EDOM, TARGET_LINUX_EDOM },
+#endif
+#ifdef ERANGE
+# define TARGET_LINUX_ERANGE 34
+ { ERANGE, TARGET_LINUX_ERANGE },
+#endif
+#ifdef EDEADLK
+# define TARGET_LINUX_EDEADLK 35
+ { EDEADLK, TARGET_LINUX_EDEADLK },
+#endif
+#ifdef ENAMETOOLONG
+# define TARGET_LINUX_ENAMETOOLONG 36
+ { ENAMETOOLONG, TARGET_LINUX_ENAMETOOLONG },
+#endif
+#ifdef ENOLCK
+# define TARGET_LINUX_ENOLCK 37
+ { ENOLCK, TARGET_LINUX_ENOLCK },
+#endif
+#ifdef ENOSYS
+# define TARGET_LINUX_ENOSYS 38
+ { ENOSYS, TARGET_LINUX_ENOSYS },
+#endif
+#ifdef ENOTEMPTY
+# define TARGET_LINUX_ENOTEMPTY 39
+ { ENOTEMPTY, TARGET_LINUX_ENOTEMPTY },
+#endif
+#ifdef ELOOP
+# define TARGET_LINUX_ELOOP 40
+ { ELOOP, TARGET_LINUX_ELOOP },
+#endif
+#ifdef ENOMSG
+# define TARGET_LINUX_ENOMSG 42
+ { ENOMSG, TARGET_LINUX_ENOMSG },
+#endif
+#ifdef EIDRM
+# define TARGET_LINUX_EIDRM 43
+ { EIDRM, TARGET_LINUX_EIDRM },
+#endif
+#ifdef ECHRNG
+# define TARGET_LINUX_ECHRNG 44
+ { ECHRNG, TARGET_LINUX_ECHRNG },
+#endif
+#ifdef EL2NSYNC
+# define TARGET_LINUX_EL2NSYNC 45
+ { EL2NSYNC, TARGET_LINUX_EL2NSYNC },
+#endif
+#ifdef EL3HLT
+# define TARGET_LINUX_EL3HLT 46
+ { EL3HLT, TARGET_LINUX_EL3HLT },
+#endif
+#ifdef EL3RST
+# define TARGET_LINUX_EL3RST 47
+ { EL3RST, TARGET_LINUX_EL3RST },
+#endif
+#ifdef ELNRNG
+# define TARGET_LINUX_ELNRNG 48
+ { ELNRNG, TARGET_LINUX_ELNRNG },
+#endif
+#ifdef EUNATCH
+# define TARGET_LINUX_EUNATCH 49
+ { EUNATCH, TARGET_LINUX_EUNATCH },
+#endif
+#ifdef ENOCSI
+# define TARGET_LINUX_ENOCSI 50
+ { ENOCSI, TARGET_LINUX_ENOCSI },
+#endif
+#ifdef EL2HLT
+# define TARGET_LINUX_EL2HLT 51
+ { EL2HLT, TARGET_LINUX_EL2HLT },
+#endif
+#ifdef EBADE
+# define TARGET_LINUX_EBADE 52
+ { EBADE, TARGET_LINUX_EBADE },
+#endif
+#ifdef EBADR
+# define TARGET_LINUX_EBADR 53
+ { EBADR, TARGET_LINUX_EBADR },
+#endif
+#ifdef EXFULL
+# define TARGET_LINUX_EXFULL 54
+ { EXFULL, TARGET_LINUX_EXFULL },
+#endif
+#ifdef ENOANO
+# define TARGET_LINUX_ENOANO 55
+ { ENOANO, TARGET_LINUX_ENOANO },
+#endif
+#ifdef EBADRQC
+# define TARGET_LINUX_EBADRQC 56
+ { EBADRQC, TARGET_LINUX_EBADRQC },
+#endif
+#ifdef EBADSLT
+# define TARGET_LINUX_EBADSLT 57
+ { EBADSLT, TARGET_LINUX_EBADSLT },
+#endif
+#ifdef EBFONT
+# define TARGET_LINUX_EBFONT 59
+ { EBFONT, TARGET_LINUX_EBFONT },
+#endif
+#ifdef ENOSTR
+# define TARGET_LINUX_ENOSTR 60
+ { ENOSTR, TARGET_LINUX_ENOSTR },
+#endif
+#ifdef ENODATA
+# define TARGET_LINUX_ENODATA 61
+ { ENODATA, TARGET_LINUX_ENODATA },
+#endif
+#ifdef ETIME
+# define TARGET_LINUX_ETIME 62
+ { ETIME, TARGET_LINUX_ETIME },
+#endif
+#ifdef ENOSR
+# define TARGET_LINUX_ENOSR 63
+ { ENOSR, TARGET_LINUX_ENOSR },
+#endif
+#ifdef ENONET
+# define TARGET_LINUX_ENONET 64
+ { ENONET, TARGET_LINUX_ENONET },
+#endif
+#ifdef ENOPKG
+# define TARGET_LINUX_ENOPKG 65
+ { ENOPKG, TARGET_LINUX_ENOPKG },
+#endif
+#ifdef EREMOTE
+# define TARGET_LINUX_EREMOTE 66
+ { EREMOTE, TARGET_LINUX_EREMOTE },
+#endif
+#ifdef ENOLINK
+# define TARGET_LINUX_ENOLINK 67
+ { ENOLINK, TARGET_LINUX_ENOLINK },
+#endif
+#ifdef EADV
+# define TARGET_LINUX_EADV 68
+ { EADV, TARGET_LINUX_EADV },
+#endif
+#ifdef ESRMNT
+# define TARGET_LINUX_ESRMNT 69
+ { ESRMNT, TARGET_LINUX_ESRMNT },
+#endif
+#ifdef ECOMM
+# define TARGET_LINUX_ECOMM 70
+ { ECOMM, TARGET_LINUX_ECOMM },
+#endif
+#ifdef EPROTO
+# define TARGET_LINUX_EPROTO 71
+ { EPROTO, TARGET_LINUX_EPROTO },
+#endif
+#ifdef EMULTIHOP
+# define TARGET_LINUX_EMULTIHOP 72
+ { EMULTIHOP, TARGET_LINUX_EMULTIHOP },
+#endif
+#ifdef EDOTDOT
+# define TARGET_LINUX_EDOTDOT 73
+ { EDOTDOT, TARGET_LINUX_EDOTDOT },
+#endif
+#ifdef EBADMSG
+# define TARGET_LINUX_EBADMSG 74
+ { EBADMSG, TARGET_LINUX_EBADMSG },
+#endif
+#ifdef EOVERFLOW
+# define TARGET_LINUX_EOVERFLOW 75
+ { EOVERFLOW, TARGET_LINUX_EOVERFLOW },
+#endif
+#ifdef ENOTUNIQ
+# define TARGET_LINUX_ENOTUNIQ 76
+ { ENOTUNIQ, TARGET_LINUX_ENOTUNIQ },
+#endif
+#ifdef EBADFD
+# define TARGET_LINUX_EBADFD 77
+ { EBADFD, TARGET_LINUX_EBADFD },
+#endif
+#ifdef EREMCHG
+# define TARGET_LINUX_EREMCHG 78
+ { EREMCHG, TARGET_LINUX_EREMCHG },
+#endif
+#ifdef ELIBACC
+# define TARGET_LINUX_ELIBACC 79
+ { ELIBACC, TARGET_LINUX_ELIBACC },
+#endif
+#ifdef ELIBBAD
+# define TARGET_LINUX_ELIBBAD 80
+ { ELIBBAD, TARGET_LINUX_ELIBBAD },
+#endif
+#ifdef ELIBSCN
+# define TARGET_LINUX_ELIBSCN 81
+ { ELIBSCN, TARGET_LINUX_ELIBSCN },
+#endif
+#ifdef ELIBMAX
+# define TARGET_LINUX_ELIBMAX 82
+ { ELIBMAX, TARGET_LINUX_ELIBMAX },
+#endif
+#ifdef ELIBEXEC
+# define TARGET_LINUX_ELIBEXEC 83
+ { ELIBEXEC, TARGET_LINUX_ELIBEXEC },
+#endif
+#ifdef EILSEQ
+# define TARGET_LINUX_EILSEQ 84
+ { EILSEQ, TARGET_LINUX_EILSEQ },
+#endif
+#ifdef ERESTART
+# define TARGET_LINUX_ERESTART 85
+ { ERESTART, TARGET_LINUX_ERESTART },
+#endif
+#ifdef ESTRPIPE
+# define TARGET_LINUX_ESTRPIPE 86
+ { ESTRPIPE, TARGET_LINUX_ESTRPIPE },
+#endif
+#ifdef EUSERS
+# define TARGET_LINUX_EUSERS 87
+ { EUSERS, TARGET_LINUX_EUSERS },
+#endif
+#ifdef ENOTSOCK
+# define TARGET_LINUX_ENOTSOCK 88
+ { ENOTSOCK, TARGET_LINUX_ENOTSOCK },
+#endif
+#ifdef EDESTADDRREQ
+# define TARGET_LINUX_EDESTADDRREQ 89
+ { EDESTADDRREQ, TARGET_LINUX_EDESTADDRREQ },
+#endif
+#ifdef EMSGSIZE
+# define TARGET_LINUX_EMSGSIZE 90
+ { EMSGSIZE, TARGET_LINUX_EMSGSIZE },
+#endif
+#ifdef EPROTOTYPE
+# define TARGET_LINUX_EPROTOTYPE 91
+ { EPROTOTYPE, TARGET_LINUX_EPROTOTYPE },
+#endif
+#ifdef ENOPROTOOPT
+# define TARGET_LINUX_ENOPROTOOPT 92
+ { ENOPROTOOPT, TARGET_LINUX_ENOPROTOOPT },
+#endif
+#ifdef EPROTONOSUPPORT
+# define TARGET_LINUX_EPROTONOSUPPORT 93
+ { EPROTONOSUPPORT, TARGET_LINUX_EPROTONOSUPPORT },
+#endif
+#ifdef ESOCKTNOSUPPORT
+# define TARGET_LINUX_ESOCKTNOSUPPORT 94
+ { ESOCKTNOSUPPORT, TARGET_LINUX_ESOCKTNOSUPPORT },
+#endif
+#ifdef EOPNOTSUPP
+# define TARGET_LINUX_EOPNOTSUPP 95
+ { EOPNOTSUPP, TARGET_LINUX_EOPNOTSUPP },
+#endif
+#ifdef EPFNOSUPPORT
+# define TARGET_LINUX_EPFNOSUPPORT 96
+ { EPFNOSUPPORT, TARGET_LINUX_EPFNOSUPPORT },
+#endif
+#ifdef EAFNOSUPPORT
+# define TARGET_LINUX_EAFNOSUPPORT 97
+ { EAFNOSUPPORT, TARGET_LINUX_EAFNOSUPPORT },
+#endif
+#ifdef EADDRINUSE
+# define TARGET_LINUX_EADDRINUSE 98
+ { EADDRINUSE, TARGET_LINUX_EADDRINUSE },
+#endif
+#ifdef EADDRNOTAVAIL
+# define TARGET_LINUX_EADDRNOTAVAIL 99
+ { EADDRNOTAVAIL, TARGET_LINUX_EADDRNOTAVAIL },
+#endif
+#ifdef ENETDOWN
+# define TARGET_LINUX_ENETDOWN 100
+ { ENETDOWN, TARGET_LINUX_ENETDOWN },
+#endif
+#ifdef ENETUNREACH
+# define TARGET_LINUX_ENETUNREACH 101
+ { ENETUNREACH, TARGET_LINUX_ENETUNREACH },
+#endif
+#ifdef ENETRESET
+# define TARGET_LINUX_ENETRESET 102
+ { ENETRESET, TARGET_LINUX_ENETRESET },
+#endif
+#ifdef ECONNABORTED
+# define TARGET_LINUX_ECONNABORTED 103
+ { ECONNABORTED, TARGET_LINUX_ECONNABORTED },
+#endif
+#ifdef ECONNRESET
+# define TARGET_LINUX_ECONNRESET 104
+ { ECONNRESET, TARGET_LINUX_ECONNRESET },
+#endif
+#ifdef ENOBUFS
+# define TARGET_LINUX_ENOBUFS 105
+ { ENOBUFS, TARGET_LINUX_ENOBUFS },
+#endif
+#ifdef EISCONN
+# define TARGET_LINUX_EISCONN 106
+ { EISCONN, TARGET_LINUX_EISCONN },
+#endif
+#ifdef ENOTCONN
+# define TARGET_LINUX_ENOTCONN 107
+ { ENOTCONN, TARGET_LINUX_ENOTCONN },
+#endif
+#ifdef ESHUTDOWN
+# define TARGET_LINUX_ESHUTDOWN 108
+ { ESHUTDOWN, TARGET_LINUX_ESHUTDOWN },
+#endif
+#ifdef ETOOMANYREFS
+# define TARGET_LINUX_ETOOMANYREFS 109
+ { ETOOMANYREFS, TARGET_LINUX_ETOOMANYREFS },
+#endif
+#ifdef ETIMEDOUT
+# define TARGET_LINUX_ETIMEDOUT 110
+ { ETIMEDOUT, TARGET_LINUX_ETIMEDOUT },
+#endif
+#ifdef ECONNREFUSED
+# define TARGET_LINUX_ECONNREFUSED 111
+ { ECONNREFUSED, TARGET_LINUX_ECONNREFUSED },
+#endif
+#ifdef EHOSTDOWN
+# define TARGET_LINUX_EHOSTDOWN 112
+ { EHOSTDOWN, TARGET_LINUX_EHOSTDOWN },
+#endif
+#ifdef EHOSTUNREACH
+# define TARGET_LINUX_EHOSTUNREACH 113
+ { EHOSTUNREACH, TARGET_LINUX_EHOSTUNREACH },
+#endif
+#ifdef EALREADY
+# define TARGET_LINUX_EALREADY 114
+ { EALREADY, TARGET_LINUX_EALREADY },
+#endif
+#ifdef EINPROGRESS
+# define TARGET_LINUX_EINPROGRESS 115
+ { EINPROGRESS, TARGET_LINUX_EINPROGRESS },
+#endif
+#ifdef ESTALE
+# define TARGET_LINUX_ESTALE 116
+ { ESTALE, TARGET_LINUX_ESTALE },
+#endif
+#ifdef EUCLEAN
+# define TARGET_LINUX_EUCLEAN 117
+ { EUCLEAN, TARGET_LINUX_EUCLEAN },
+#endif
+#ifdef ENOTNAM
+# define TARGET_LINUX_ENOTNAM 118
+ { ENOTNAM, TARGET_LINUX_ENOTNAM },
+#endif
+#ifdef ENAVAIL
+# define TARGET_LINUX_ENAVAIL 119
+ { ENAVAIL, TARGET_LINUX_ENAVAIL },
+#endif
+#ifdef EISNAM
+# define TARGET_LINUX_EISNAM 120
+ { EISNAM, TARGET_LINUX_EISNAM },
+#endif
+#ifdef EREMOTEIO
+# define TARGET_LINUX_EREMOTEIO 121
+ { EREMOTEIO, TARGET_LINUX_EREMOTEIO },
+#endif
+#ifdef EDQUOT
+# define TARGET_LINUX_EDQUOT 122
+ { EDQUOT, TARGET_LINUX_EDQUOT },
+#endif
+#ifdef ENOMEDIUM
+# define TARGET_LINUX_ENOMEDIUM 123
+ { ENOMEDIUM, TARGET_LINUX_ENOMEDIUM },
+#endif
+#ifdef EMEDIUMTYPE
+# define TARGET_LINUX_EMEDIUMTYPE 124
+ { EMEDIUMTYPE, TARGET_LINUX_EMEDIUMTYPE },
+#endif
+#ifdef ECANCELED
+# define TARGET_LINUX_ECANCELED 125
+ { ECANCELED, TARGET_LINUX_ECANCELED },
+#endif
+#ifdef EOWNERDEAD
+# define TARGET_LINUX_EOWNERDEAD 130
+ { EOWNERDEAD, TARGET_LINUX_EOWNERDEAD },
+#endif
+#ifdef ENOTRECOVERABLE
+# define TARGET_LINUX_ENOTRECOVERABLE 131
+ { ENOTRECOVERABLE, TARGET_LINUX_ENOTRECOVERABLE },
+#endif
+ { 0, 0 }
+};
+
+static CB_TARGET_DEFS_MAP cb_linux_open_map[] = {
+#ifdef O_ACCMODE
+# define TARGET_LINUX_O_ACCMODE 0003
+ { O_ACCMODE, TARGET_LINUX_O_ACCMODE },
+#endif
+#ifdef O_RDONLY
+# define TARGET_LINUX_O_RDONLY 00
+ { O_RDONLY, TARGET_LINUX_O_RDONLY },
+#endif
+#ifdef O_WRONLY
+# define TARGET_LINUX_O_WRONLY 01
+ { O_WRONLY, TARGET_LINUX_O_WRONLY },
+#endif
+#ifdef O_RDWR
+# define TARGET_LINUX_O_RDWR 02
+ { O_RDWR, TARGET_LINUX_O_RDWR },
+#endif
+#ifdef O_CREAT
+# define TARGET_LINUX_O_CREAT 0100
+ { O_CREAT, TARGET_LINUX_O_CREAT },
+#endif
+#ifdef O_EXCL
+# define TARGET_LINUX_O_EXCL 0200
+ { O_EXCL, TARGET_LINUX_O_EXCL },
+#endif
+#ifdef O_NOCTTY
+# define TARGET_LINUX_O_NOCTTY 0400
+ { O_NOCTTY, TARGET_LINUX_O_NOCTTY },
+#endif
+#ifdef O_TRUNC
+# define TARGET_LINUX_O_TRUNC 01000
+ { O_TRUNC, TARGET_LINUX_O_TRUNC },
+#endif
+#ifdef O_APPEND
+# define TARGET_LINUX_O_APPEND 02000
+ { O_APPEND, TARGET_LINUX_O_APPEND },
+#endif
+#ifdef O_NONBLOCK
+# define TARGET_LINUX_O_NONBLOCK 04000
+ { O_NONBLOCK, TARGET_LINUX_O_NONBLOCK },
+#endif
+#ifdef O_SYNC
+# define TARGET_LINUX_O_SYNC 010000
+ { O_SYNC, TARGET_LINUX_O_SYNC },
+#endif
+#ifdef O_ASYNC
+# define TARGET_LINUX_O_ASYNC 020000
+ { O_ASYNC, TARGET_LINUX_O_ASYNC },
+#endif
+ { -1, -1 }
+};
+
+static CB_TARGET_DEFS_MAP cb_linux_signal_map[] = {
+#ifdef SIGHUP
+# define TARGET_LINUX_SIGHUP 1
+ { SIGHUP, TARGET_LINUX_SIGHUP },
+#endif
+#ifdef SIGINT
+# define TARGET_LINUX_SIGINT 2
+ { SIGINT, TARGET_LINUX_SIGINT },
+#endif
+#ifdef SIGQUIT
+# define TARGET_LINUX_SIGQUIT 3
+ { SIGQUIT, TARGET_LINUX_SIGQUIT },
+#endif
+#ifdef SIGILL
+# define TARGET_LINUX_SIGILL 4
+ { SIGILL, TARGET_LINUX_SIGILL },
+#endif
+#ifdef SIGTRAP
+# define TARGET_LINUX_SIGTRAP 5
+ { SIGTRAP, TARGET_LINUX_SIGTRAP },
+#endif
+#ifdef SIGABRT
+# define TARGET_LINUX_SIGABRT 6
+ { SIGABRT, TARGET_LINUX_SIGABRT },
+#endif
+#ifdef SIGIOT
+# define TARGET_LINUX_SIGIOT 6
+ { SIGIOT, TARGET_LINUX_SIGIOT },
+#endif
+#ifdef SIGBUS
+# define TARGET_LINUX_SIGBUS 7
+ { SIGBUS, TARGET_LINUX_SIGBUS },
+#endif
+#ifdef SIGFPE
+# define TARGET_LINUX_SIGFPE 8
+ { SIGFPE, TARGET_LINUX_SIGFPE },
+#endif
+#ifdef SIGKILL
+# define TARGET_LINUX_SIGKILL 9
+ { SIGKILL, TARGET_LINUX_SIGKILL },
+#endif
+#ifdef SIGUSR1
+# define TARGET_LINUX_SIGUSR1 10
+ { SIGUSR1, TARGET_LINUX_SIGUSR1 },
+#endif
+#ifdef SIGSEGV
+# define TARGET_LINUX_SIGSEGV 11
+ { SIGSEGV, TARGET_LINUX_SIGSEGV },
+#endif
+#ifdef SIGUSR2
+# define TARGET_LINUX_SIGUSR2 12
+ { SIGUSR2, TARGET_LINUX_SIGUSR2 },
+#endif
+#ifdef SIGPIPE
+# define TARGET_LINUX_SIGPIPE 13
+ { SIGPIPE, TARGET_LINUX_SIGPIPE },
+#endif
+#ifdef SIGALRM
+# define TARGET_LINUX_SIGALRM 14
+ { SIGALRM, TARGET_LINUX_SIGALRM },
+#endif
+#ifdef SIGTERM
+# define TARGET_LINUX_SIGTERM 15
+ { SIGTERM, TARGET_LINUX_SIGTERM },
+#endif
+#ifdef SIGSTKFLT
+# define TARGET_LINUX_SIGSTKFLT 16
+ { SIGSTKFLT, TARGET_LINUX_SIGSTKFLT },
+#endif
+#ifdef SIGCHLD
+# define TARGET_LINUX_SIGCHLD 17
+ { SIGCHLD, TARGET_LINUX_SIGCHLD },
+#endif
+#ifdef SIGCONT
+# define TARGET_LINUX_SIGCONT 18
+ { SIGCONT, TARGET_LINUX_SIGCONT },
+#endif
+#ifdef SIGSTOP
+# define TARGET_LINUX_SIGSTOP 19
+ { SIGSTOP, TARGET_LINUX_SIGSTOP },
+#endif
+#ifdef SIGTSTP
+# define TARGET_LINUX_SIGTSTP 20
+ { SIGTSTP, TARGET_LINUX_SIGTSTP },
+#endif
+#ifdef SIGTTIN
+# define TARGET_LINUX_SIGTTIN 21
+ { SIGTTIN, TARGET_LINUX_SIGTTIN },
+#endif
+#ifdef SIGTTOU
+# define TARGET_LINUX_SIGTTOU 22
+ { SIGTTOU, TARGET_LINUX_SIGTTOU },
+#endif
+#ifdef SIGURG
+# define TARGET_LINUX_SIGURG 23
+ { SIGURG, TARGET_LINUX_SIGURG },
+#endif
+#ifdef SIGXCPU
+# define TARGET_LINUX_SIGXCPU 24
+ { SIGXCPU, TARGET_LINUX_SIGXCPU },
+#endif
+#ifdef SIGXFSZ
+# define TARGET_LINUX_SIGXFSZ 25
+ { SIGXFSZ, TARGET_LINUX_SIGXFSZ },
+#endif
+#ifdef SIGVTALRM
+# define TARGET_LINUX_SIGVTALRM 26
+ { SIGVTALRM, TARGET_LINUX_SIGVTALRM },
+#endif
+#ifdef SIGPROF
+# define TARGET_LINUX_SIGPROF 27
+ { SIGPROF, TARGET_LINUX_SIGPROF },
+#endif
+#ifdef SIGWINCH
+# define TARGET_LINUX_SIGWINCH 28
+ { SIGWINCH, TARGET_LINUX_SIGWINCH },
+#endif
+#ifdef SIGIO
+# define TARGET_LINUX_SIGIO 29
+ { SIGIO, TARGET_LINUX_SIGIO },
+#endif
+#ifdef SIGPWR
+# define TARGET_LINUX_SIGPWR 30
+ { SIGPWR, TARGET_LINUX_SIGPWR },
+#endif
+#ifdef SIGSYS
+# define TARGET_LINUX_SIGSYS 31
+ { SIGSYS, TARGET_LINUX_SIGSYS },
+#endif
+#ifdef SIGUNUSED
+# define TARGET_LINUX_SIGUNUSED 31
+ { SIGUNUSED, TARGET_LINUX_SIGUNUSED },
+#endif
+#ifdef SIG_BLOCK
+# define TARGET_LINUX_SIG_BLOCK 0
+ { SIG_BLOCK, TARGET_LINUX_SIG_BLOCK },
+#endif
+#ifdef SIG_UNBLOCK
+# define TARGET_LINUX_SIG_UNBLOCK 1
+ { SIG_UNBLOCK, TARGET_LINUX_SIG_UNBLOCK },
+#endif
+#ifdef SIG_SETMASK
+# define TARGET_LINUX_SIG_SETMASK 2
+ { SIG_SETMASK, TARGET_LINUX_SIG_SETMASK },
+#endif
+#ifdef SIGSTKSZ
+# define TARGET_LINUX_SIGSTKSZ 8192
+ { SIGSTKSZ, TARGET_LINUX_SIGSTKSZ },
+#endif
+ { -1, -1 }
+};
diff --git a/sim/bfin/machs.c b/sim/bfin/machs.c
new file mode 100644
index 00000000000..e60e8c94ccc
--- /dev/null
+++ b/sim/bfin/machs.c
@@ -0,0 +1,1287 @@
+/* Simulator for Analog Devices Blackfin processors.
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include "sim-main.h"
+#include "gdb/sim-bfin.h"
+#include "bfd.h"
+
+#include "sim-hw.h"
+#include "devices.h"
+#include "dv-bfin_cec.h"
+#include "dv-bfin_ctimer.h"
+#include "dv-bfin_dma.h"
+#include "dv-bfin_dmac.h"
+#include "dv-bfin_ebiu_amc.h"
+#include "dv-bfin_ebiu_ddrc.h"
+#include "dv-bfin_ebiu_sdc.h"
+#include "dv-bfin_emac.h"
+#include "dv-bfin_eppi.h"
+#include "dv-bfin_evt.h"
+#include "dv-bfin_gptimer.h"
+#include "dv-bfin_jtag.h"
+#include "dv-bfin_mmu.h"
+#include "dv-bfin_nfc.h"
+#include "dv-bfin_otp.h"
+#include "dv-bfin_ppi.h"
+#include "dv-bfin_pll.h"
+#include "dv-bfin_rtc.h"
+#include "dv-bfin_sic.h"
+#include "dv-bfin_spi.h"
+#include "dv-bfin_trace.h"
+#include "dv-bfin_twi.h"
+#include "dv-bfin_uart.h"
+#include "dv-bfin_uart2.h"
+#include "dv-bfin_wdog.h"
+#include "dv-bfin_wp.h"
+
+static const MACH bfin_mach;
+
+struct bfin_memory_layout {
+ address_word addr, len;
+ unsigned mask; /* see mapmask in sim_core_attach() */
+};
+struct bfin_dev_layout {
+ address_word base, len;
+ unsigned int dmac;
+ const char *dev;
+};
+struct bfin_dmac_layout {
+ address_word base;
+ unsigned int dma_count;
+};
+struct bfin_model_data {
+ bu32 chipid;
+ int model_num;
+ const struct bfin_memory_layout *mem;
+ size_t mem_count;
+ const struct bfin_dev_layout *dev;
+ size_t dev_count;
+ const struct bfin_dmac_layout *dmac;
+ size_t dmac_count;
+};
+
+#define LAYOUT(_addr, _len, _mask) { .addr = _addr, .len = _len, .mask = access_##_mask, }
+#define _DEVICE(_base, _len, _dev, _dmac) { .base = _base, .len = _len, .dev = _dev, .dmac = _dmac, }
+#define DEVICE(_base, _len, _dev) _DEVICE(_base, _len, _dev, 0)
+
+/* [1] Common sim code can't model exec-only memory.
+ http://sourceware.org/ml/gdb/2010-02/msg00047.html */
+
+#define bf000_chipid 0
+static const struct bfin_memory_layout bf000_mem[] = {};
+static const struct bfin_dev_layout bf000_dev[] = {};
+static const struct bfin_dmac_layout bf000_dmac[] = {};
+
+#define bf50x_chipid 0x2800
+#define bf504_chipid bf50x_chipid
+#define bf506_chipid bf50x_chipid
+static const struct bfin_memory_layout bf50x_mem[] = {
+ LAYOUT (0xFFC00700, 0x50, read_write), /* PORTF stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC01700, 0x50, read_write), /* PORTH stub */
+ LAYOUT (0xFFC03200, 0x50, read_write), /* PORT_MUX stub */
+ LAYOUT (0xFFC03800, 0x100, read_write), /* RSI stub */
+ LAYOUT (0xFFC0328C, 0xC, read_write), /* Flash stub */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFFA00000, 0x4000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA04000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+#define bf504_mem bf50x_mem
+#define bf506_mem bf50x_mem
+static const struct bfin_dev_layout bf50x_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART2_SIZE, "bfin_uart2@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BF50X_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART2_SIZE, "bfin_uart2@1"),
+ DEVICE (0xFFC03400, BFIN_MMR_SPI_SIZE, "bfin_spi@1"),
+};
+#define bf504_dev bf50x_dev
+#define bf506_dev bf50x_dev
+static const struct bfin_dmac_layout bf50x_dmac[] = {
+ { BFIN_MMR_DMAC0_BASE, 12, },
+};
+#define bf504_dmac bf50x_dmac
+#define bf506_dmac bf50x_dmac
+
+#define bf51x_chipid 0x27e8
+#define bf512_chipid bf51x_chipid
+#define bf514_chipid bf51x_chipid
+#define bf516_chipid bf51x_chipid
+#define bf518_chipid bf51x_chipid
+static const struct bfin_memory_layout bf51x_mem[] = {
+ LAYOUT (0xFFC00680, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* PORTF stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC01700, 0x50, read_write), /* PORTH stub */
+ LAYOUT (0xFFC03200, 0x50, read_write), /* PORT_MUX stub */
+ LAYOUT (0xFFC03800, 0xD0, read_write), /* RSI stub */
+ LAYOUT (0xFFC03FE0, 0x20, read_write), /* RSI peripheral stub */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+#define bf512_mem bf51x_mem
+#define bf514_mem bf51x_mem
+#define bf516_mem bf51x_mem
+#define bf518_mem bf51x_mem
+static const struct bfin_dev_layout bf512_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART_SIZE, "bfin_uart@1"),
+ DEVICE (0xFFC03400, BFIN_MMR_SPI_SIZE, "bfin_spi@1"),
+ DEVICE (0xFFC03600, BFIN_MMR_OTP_SIZE, "bfin_otp"),
+};
+#define bf514_dev bf512_dev
+static const struct bfin_dev_layout bf516_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART_SIZE, "bfin_uart@1"),
+ DEVICE (0xFFC03000, BFIN_MMR_EMAC_SIZE, "bfin_emac"),
+ DEVICE (0, 0x20, "bfin_emac/eth_phy"),
+ DEVICE (0xFFC03400, BFIN_MMR_SPI_SIZE, "bfin_spi@1"),
+ DEVICE (0xFFC03600, BFIN_MMR_OTP_SIZE, "bfin_otp"),
+};
+#define bf518_dev bf516_dev
+#define bf512_dmac bf50x_dmac
+#define bf514_dmac bf50x_dmac
+#define bf516_dmac bf50x_dmac
+#define bf518_dmac bf50x_dmac
+
+#define bf522_chipid 0x27e4
+#define bf523_chipid 0x27e0
+#define bf524_chipid bf522_chipid
+#define bf525_chipid bf523_chipid
+#define bf526_chipid bf522_chipid
+#define bf527_chipid bf523_chipid
+static const struct bfin_memory_layout bf52x_mem[] = {
+ LAYOUT (0xFFC00680, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* PORTF stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC01700, 0x50, read_write), /* PORTH stub */
+ LAYOUT (0xFFC03200, 0x50, read_write), /* PORT_MUX stub */
+ LAYOUT (0xFFC03800, 0x500, read_write), /* MUSB stub */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+#define bf522_mem bf52x_mem
+#define bf523_mem bf52x_mem
+#define bf524_mem bf52x_mem
+#define bf525_mem bf52x_mem
+#define bf526_mem bf52x_mem
+#define bf527_mem bf52x_mem
+static const struct bfin_dev_layout bf522_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART_SIZE, "bfin_uart@1"),
+ DEVICE (0xFFC03600, BFIN_MMR_OTP_SIZE, "bfin_otp"),
+ DEVICE (0xFFC03700, BFIN_MMR_NFC_SIZE, "bfin_nfc"),
+};
+#define bf523_dev bf522_dev
+#define bf524_dev bf522_dev
+#define bf525_dev bf522_dev
+static const struct bfin_dev_layout bf526_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART_SIZE, "bfin_uart@1"),
+ DEVICE (0xFFC03000, BFIN_MMR_EMAC_SIZE, "bfin_emac"),
+ DEVICE (0, 0x20, "bfin_emac/eth_phy"),
+ DEVICE (0xFFC03600, BFIN_MMR_OTP_SIZE, "bfin_otp"),
+ DEVICE (0xFFC03700, BFIN_MMR_NFC_SIZE, "bfin_nfc"),
+};
+#define bf527_dev bf526_dev
+#define bf522_dmac bf50x_dmac
+#define bf523_dmac bf50x_dmac
+#define bf524_dmac bf50x_dmac
+#define bf525_dmac bf50x_dmac
+#define bf526_dmac bf50x_dmac
+#define bf527_dmac bf50x_dmac
+
+#define bf531_chipid 0x27a5
+#define bf532_chipid bf531_chipid
+#define bf533_chipid bf531_chipid
+static const struct bfin_memory_layout bf531_mem[] = {
+ LAYOUT (0xFFC00640, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* GPIO stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+static const struct bfin_memory_layout bf532_mem[] = {
+ LAYOUT (0xFFC00640, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* GPIO stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA0C000, 0x4000, read_write_exec), /* Inst C [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+static const struct bfin_memory_layout bf533_mem[] = {
+ LAYOUT (0xFFC00640, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* GPIO stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA0C000, 0x4000, read_write_exec), /* Inst C [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+static const struct bfin_dev_layout bf533_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+};
+#define bf531_dev bf533_dev
+#define bf532_dev bf533_dev
+static const struct bfin_dmac_layout bf533_dmac[] = {
+ { BFIN_MMR_DMAC0_BASE, 8, },
+};
+#define bf531_dmac bf533_dmac
+#define bf532_dmac bf533_dmac
+
+#define bf534_chipid 0x27c6
+#define bf536_chipid 0x27c8
+#define bf537_chipid bf536_chipid
+static const struct bfin_memory_layout bf534_mem[] = {
+ LAYOUT (0xFFC00680, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* PORTF stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC01700, 0x50, read_write), /* PORTH stub */
+ LAYOUT (0xFFC03200, 0x10, read_write), /* PORT_MUX stub */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+static const struct bfin_memory_layout bf536_mem[] = {
+ LAYOUT (0xFFC00680, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* PORTF stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC01700, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC03200, 0x10, read_write), /* PORT_MUX stub */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+static const struct bfin_memory_layout bf537_mem[] = {
+ LAYOUT (0xFFC00680, 0xC, read_write), /* TIMER stub */
+ LAYOUT (0xFFC00700, 0x50, read_write), /* PORTF stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC01700, 0x50, read_write), /* PORTG stub */
+ LAYOUT (0xFFC03200, 0x10, read_write), /* PORT_MUX stub */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+static const struct bfin_dev_layout bf534_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART_SIZE, "bfin_uart@1"),
+};
+static const struct bfin_dev_layout bf537_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART_SIZE, "bfin_uart@1"),
+ DEVICE (0xFFC03000, BFIN_MMR_EMAC_SIZE, "bfin_emac"),
+ DEVICE (0, 0x20, "bfin_emac/eth_phy"),
+};
+#define bf536_dev bf537_dev
+#define bf534_dmac bf50x_dmac
+#define bf536_dmac bf50x_dmac
+#define bf537_dmac bf50x_dmac
+
+#define bf538_chipid 0x27c4
+#define bf539_chipid bf538_chipid
+static const struct bfin_memory_layout bf538_mem[] = {
+ LAYOUT (0xFFC00700, 0x50, read_write), /* PORTF stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x70, read_write), /* PORTC/D/E stub */
+ LAYOUT (0xFFC02500, 0x60, read_write), /* SPORT2 stub */
+ LAYOUT (0xFFC02600, 0x60, read_write), /* SPORT3 stub */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA0C000, 0x4000, read_write_exec), /* Inst C [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+#define bf539_mem bf538_mem
+static const struct bfin_dev_layout bf538_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ _DEVICE (0xFFC02000, BFIN_MMR_UART_SIZE, "bfin_uart@1", 1),
+ _DEVICE (0xFFC02100, BFIN_MMR_UART_SIZE, "bfin_uart@2", 1),
+ DEVICE (0xFFC02200, BFIN_MMR_TWI_SIZE, "bfin_twi@1"),
+ _DEVICE (0xFFC02300, BFIN_MMR_SPI_SIZE, "bfin_spi@1", 1),
+ _DEVICE (0xFFC02400, BFIN_MMR_SPI_SIZE, "bfin_spi@2", 1),
+};
+#define bf539_dev bf538_dev
+static const struct bfin_dmac_layout bf538_dmac[] = {
+ { BFIN_MMR_DMAC0_BASE, 8, },
+ { BFIN_MMR_DMAC1_BASE, 12, },
+};
+#define bf539_dmac bf538_dmac
+
+#define bf54x_chipid 0x27de
+#define bf542_chipid bf54x_chipid
+#define bf544_chipid bf54x_chipid
+#define bf547_chipid bf54x_chipid
+#define bf548_chipid bf54x_chipid
+#define bf549_chipid bf54x_chipid
+static const struct bfin_memory_layout bf54x_mem[] = {
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub XXX: not on BF542/4 */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01400, 0x200, read_write), /* PORT/GPIO stub */
+ LAYOUT (0xFFC02500, 0x60, read_write), /* SPORT2 stub */
+ LAYOUT (0xFFC02600, 0x60, read_write), /* SPORT3 stub */
+ LAYOUT (0xFFC03800, 0x70, read_write), /* ATAPI stub */
+ LAYOUT (0xFFC03900, 0x100, read_write), /* RSI stub */
+ LAYOUT (0xFFC03C00, 0x500, read_write), /* MUSB stub */
+ LAYOUT (0xFEB00000, 0x20000, read_write_exec), /* L2 */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x8000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA08000, 0x4000, read_write_exec), /* Inst B [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+#define bf542_mem bf54x_mem
+#define bf544_mem bf54x_mem
+#define bf547_mem bf54x_mem
+#define bf548_mem bf54x_mem
+#define bf549_mem bf54x_mem
+static const struct bfin_dev_layout bf542_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART2_SIZE, "bfin_uart2@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00700, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC00A00, BF54X_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A20, BFIN_MMR_EBIU_DDRC_SIZE, "bfin_ebiu_ddrc"),
+ _DEVICE (0xFFC01300, BFIN_MMR_EPPI_SIZE, "bfin_eppi@1", 1),
+ DEVICE (0xFFC01600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC01610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC01620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC01630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC01640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC01650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC01660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC01670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART2_SIZE, "bfin_uart2@1"),
+ _DEVICE (0xFFC02100, BFIN_MMR_UART2_SIZE, "bfin_uart2@2", 1),
+ DEVICE (0xFFC02300, BFIN_MMR_SPI_SIZE, "bfin_spi@1"),
+ _DEVICE (0xFFC02900, BFIN_MMR_EPPI_SIZE, "bfin_eppi@2", 1),
+ _DEVICE (0xFFC03100, BFIN_MMR_UART2_SIZE, "bfin_uart2@3", 1),
+ DEVICE (0xFFC03B00, BFIN_MMR_NFC_SIZE, "bfin_nfc"),
+ DEVICE (0xFFC04300, BFIN_MMR_OTP_SIZE, "bfin_otp"),
+};
+static const struct bfin_dev_layout bf544_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART2_SIZE, "bfin_uart2@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@8"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@9"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@10"),
+ DEVICE (0xFFC00700, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC00A00, BF54X_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A20, BFIN_MMR_EBIU_DDRC_SIZE, "bfin_ebiu_ddrc"),
+ _DEVICE (0xFFC01000, BFIN_MMR_EPPI_SIZE, "bfin_eppi@0", 1),
+ _DEVICE (0xFFC01300, BFIN_MMR_EPPI_SIZE, "bfin_eppi@1", 1),
+ DEVICE (0xFFC01600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC01610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC01620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC01630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC01640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC01650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC01660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC01670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART2_SIZE, "bfin_uart2@1"),
+ _DEVICE (0xFFC02100, BFIN_MMR_UART2_SIZE, "bfin_uart2@2", 1),
+ DEVICE (0xFFC02200, BFIN_MMR_TWI_SIZE, "bfin_twi@1"),
+ DEVICE (0xFFC02300, BFIN_MMR_SPI_SIZE, "bfin_spi@1"),
+ _DEVICE (0xFFC02900, BFIN_MMR_EPPI_SIZE, "bfin_eppi@2", 1),
+ _DEVICE (0xFFC03100, BFIN_MMR_UART2_SIZE, "bfin_uart2@3", 1),
+ DEVICE (0xFFC03B00, BFIN_MMR_NFC_SIZE, "bfin_nfc"),
+ DEVICE (0xFFC04300, BFIN_MMR_OTP_SIZE, "bfin_otp"),
+};
+static const struct bfin_dev_layout bf547_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00300, BFIN_MMR_RTC_SIZE, "bfin_rtc"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART2_SIZE, "bfin_uart2@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@8"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@9"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@10"),
+ DEVICE (0xFFC00700, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+ DEVICE (0xFFC00A00, BF54X_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A20, BFIN_MMR_EBIU_DDRC_SIZE, "bfin_ebiu_ddrc"),
+ _DEVICE (0xFFC01000, BFIN_MMR_EPPI_SIZE, "bfin_eppi@0", 1),
+ _DEVICE (0xFFC01300, BFIN_MMR_EPPI_SIZE, "bfin_eppi@1", 1),
+ DEVICE (0xFFC01600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC01610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC01620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC01630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC01640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC01650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC01660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC01670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC02000, BFIN_MMR_UART2_SIZE, "bfin_uart2@1"),
+ _DEVICE (0xFFC02100, BFIN_MMR_UART2_SIZE, "bfin_uart2@2", 1),
+ DEVICE (0xFFC02200, BFIN_MMR_TWI_SIZE, "bfin_twi@1"),
+ DEVICE (0xFFC02300, BFIN_MMR_SPI_SIZE, "bfin_spi@1"),
+ _DEVICE (0xFFC02400, BFIN_MMR_SPI_SIZE, "bfin_spi@2", 1),
+ _DEVICE (0xFFC02900, BFIN_MMR_EPPI_SIZE, "bfin_eppi@2", 1),
+ _DEVICE (0xFFC03100, BFIN_MMR_UART2_SIZE, "bfin_uart2@3", 1),
+ DEVICE (0xFFC03B00, BFIN_MMR_NFC_SIZE, "bfin_nfc"),
+};
+#define bf548_dev bf547_dev
+#define bf549_dev bf547_dev
+static const struct bfin_dmac_layout bf54x_dmac[] = {
+ { BFIN_MMR_DMAC0_BASE, 12, },
+ { BFIN_MMR_DMAC1_BASE, 12, },
+};
+#define bf542_dmac bf54x_dmac
+#define bf544_dmac bf54x_dmac
+#define bf547_dmac bf54x_dmac
+#define bf548_dmac bf54x_dmac
+#define bf549_dmac bf54x_dmac
+
+/* This is only Core A of course ... */
+#define bf561_chipid 0x27bb
+static const struct bfin_memory_layout bf561_mem[] = {
+ LAYOUT (0xFFC00700, 0x50, read_write), /* GPIO0 stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* GPIO1 stub */
+ LAYOUT (0xFFC01700, 0x50, read_write), /* GPIO2 stub */
+ LAYOUT (0xFEB00000, 0x20000, read_write_exec), /* L2 */
+ LAYOUT (0xFF800000, 0x4000, read_write), /* Data A */
+ LAYOUT (0xFF804000, 0x4000, read_write), /* Data A Cache */
+ LAYOUT (0xFF900000, 0x4000, read_write), /* Data B */
+ LAYOUT (0xFF904000, 0x4000, read_write), /* Data B Cache */
+ LAYOUT (0xFFA00000, 0x4000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA10000, 0x4000, read_write_exec), /* Inst Cache [1] */
+};
+static const struct bfin_dev_layout bf561_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC00630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@3"),
+ DEVICE (0xFFC00640, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@4"),
+ DEVICE (0xFFC00650, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@5"),
+ DEVICE (0xFFC00660, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@6"),
+ DEVICE (0xFFC00670, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@7"),
+ DEVICE (0xFFC00A00, BFIN_MMR_EBIU_AMC_SIZE, "bfin_ebiu_amc"),
+ DEVICE (0xFFC00A10, BFIN_MMR_EBIU_SDC_SIZE, "bfin_ebiu_sdc"),
+ _DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0", 1),
+ DEVICE (0xFFC01200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@1"),
+ _DEVICE (0xFFC01300, BFIN_MMR_PPI_SIZE, "bfin_ppi@1", 1),
+ DEVICE (0xFFC01600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@8"),
+ DEVICE (0xFFC01610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@9"),
+ DEVICE (0xFFC01620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@10"),
+ DEVICE (0xFFC01630, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@11"),
+};
+static const struct bfin_dmac_layout bf561_dmac[] = {
+ { BFIN_MMR_DMAC0_BASE, 12, },
+ { BFIN_MMR_DMAC1_BASE, 12, },
+ /* XXX: IMDMA: { 0xFFC01800, 4, }, */
+};
+
+#define bf592_chipid 0x20cb
+static const struct bfin_memory_layout bf592_mem[] = {
+ LAYOUT (0xFFC00700, 0x50, read_write), /* GPIO0 stub */
+ LAYOUT (0xFFC00800, 0x60, read_write), /* SPORT0 stub */
+ LAYOUT (0xFFC00900, 0x60, read_write), /* SPORT1 stub */
+ LAYOUT (0xFFC01500, 0x50, read_write), /* GPIO1 stub */
+ LAYOUT (0xFF800000, 0x8000, read_write), /* Data A */
+ LAYOUT (0xFFA00000, 0x4000, read_write_exec), /* Inst A [1] */
+ LAYOUT (0xFFA04000, 0x4000, read_write_exec), /* Inst B [1] */
+};
+static const struct bfin_dev_layout bf592_dev[] = {
+ DEVICE (0xFFC00200, BFIN_MMR_WDOG_SIZE, "bfin_wdog@0"),
+ DEVICE (0xFFC00400, BFIN_MMR_UART_SIZE, "bfin_uart@0"),
+ DEVICE (0xFFC00500, BFIN_MMR_SPI_SIZE, "bfin_spi@0"),
+ DEVICE (0xFFC00600, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@0"),
+ DEVICE (0xFFC00610, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@1"),
+ DEVICE (0xFFC00620, BFIN_MMR_GPTIMER_SIZE, "bfin_gptimer@2"),
+ DEVICE (0xFFC01000, BFIN_MMR_PPI_SIZE, "bfin_ppi@0"),
+ DEVICE (0xFFC01300, BFIN_MMR_SPI_SIZE, "bfin_spi@1"),
+ DEVICE (0xFFC01400, BFIN_MMR_TWI_SIZE, "bfin_twi@0"),
+};
+static const struct bfin_dmac_layout bf592_dmac[] = {
+ /* XXX: there are only 9 channels, but mdma code below assumes that they
+ start right after the dma channels ... */
+ { BFIN_MMR_DMAC0_BASE, 12, },
+};
+
+static const struct bfin_model_data bfin_model_data[] =
+{
+#define P(n) \
+ [MODEL_BF##n] = { \
+ bf##n##_chipid, n, \
+ bf##n##_mem , ARRAY_SIZE (bf##n##_mem ), \
+ bf##n##_dev , ARRAY_SIZE (bf##n##_dev ), \
+ bf##n##_dmac, ARRAY_SIZE (bf##n##_dmac), \
+ },
+#include "proc_list.def"
+#undef P
+};
+
+#define CORE_DEVICE(dev, DEV) \
+ DEVICE (BFIN_COREMMR_##DEV##_BASE, BFIN_COREMMR_##DEV##_SIZE, "bfin_"#dev)
+static const struct bfin_dev_layout bfin_core_dev[] = {
+ CORE_DEVICE (cec, CEC),
+ CORE_DEVICE (ctimer, CTIMER),
+ CORE_DEVICE (evt, EVT),
+ CORE_DEVICE (jtag, JTAG),
+ CORE_DEVICE (mmu, MMU),
+ CORE_DEVICE (trace, TRACE),
+ CORE_DEVICE (wp, WP),
+};
+
+#define dv_bfin_hw_parse(sd, dv, DV) \
+ do { \
+ bu32 base = BFIN_MMR_##DV##_BASE; \
+ bu32 size = BFIN_MMR_##DV##_SIZE; \
+ sim_hw_parse (sd, "/core/bfin_"#dv"/reg %#x %i", base, size); \
+ sim_hw_parse (sd, "/core/bfin_"#dv"/type %i", mdata->model_num); \
+ } while (0)
+
+static void
+bfin_model_hw_tree_init (SIM_DESC sd, SIM_CPU *cpu)
+{
+ const MODEL *model = CPU_MODEL (cpu);
+ const struct bfin_model_data *mdata = CPU_MODEL_DATA (cpu);
+ const struct bfin_board_data *board = STATE_BOARD_DATA (sd);
+ int mnum = MODEL_NUM (model);
+ unsigned i, j, dma_chan;
+
+ /* Map the core devices. */
+ for (i = 0; i < ARRAY_SIZE (bfin_core_dev); ++i)
+ {
+ const struct bfin_dev_layout *dev = &bfin_core_dev[i];
+ sim_hw_parse (sd, "/core/%s/reg %#x %i", dev->dev, dev->base, dev->len);
+ }
+ sim_hw_parse (sd, "/core/bfin_ctimer > ivtmr ivtmr /core/bfin_cec");
+
+ if (mnum == MODEL_BF000)
+ goto done;
+
+ /* Map the system devices. */
+ dv_bfin_hw_parse (sd, sic, SIC);
+ sim_hw_parse (sd, "/core/bfin_sic/type %i", mdata->model_num);
+ for (i = 7; i < 16; ++i)
+ sim_hw_parse (sd, "/core/bfin_sic > ivg%i ivg%i /core/bfin_cec", i, i);
+
+ dv_bfin_hw_parse (sd, pll, PLL);
+ sim_hw_parse (sd, "/core/bfin_pll > pll pll /core/bfin_sic");
+
+ dma_chan = 0;
+ for (i = 0; i < mdata->dmac_count; ++i)
+ {
+ const struct bfin_dmac_layout *dmac = &mdata->dmac[i];
+
+ sim_hw_parse (sd, "/core/bfin_dmac@%u/type %i", i, mdata->model_num);
+
+ /* Hook up the non-mdma channels. */
+ for (j = 0; j < dmac->dma_count; ++j)
+ {
+ sim_hw_parse (sd, "/core/bfin_dmac@%u/bfin_dma@%u/reg %#x %i", i,
+ dma_chan, dmac->base + j * BFIN_MMR_DMA_SIZE,
+ BFIN_MMR_DMA_SIZE);
+
+ /* Could route these into the bfin_dmac and let that
+ forward it to the SIC, but not much value. */
+ sim_hw_parse (sd, "/core/bfin_dmac@%u/bfin_dma@%u > di dma@%u /core/bfin_sic",
+ i, dma_chan, dma_chan);
+
+ ++dma_chan;
+ }
+
+ /* Hook up the mdma channels -- assume every DMAC has 4. */
+ for (j = 0; j < 4; ++j)
+ {
+ sim_hw_parse (sd, "/core/bfin_dmac@%u/bfin_dma@%u/reg %#x %i",
+ i, j + BFIN_DMAC_MDMA_BASE,
+ dmac->base + (j + dmac->dma_count) * BFIN_MMR_DMA_SIZE,
+ BFIN_MMR_DMA_SIZE);
+ sim_hw_parse (sd, "/core/bfin_dmac@%u/bfin_dma@%u > di mdma@%u /core/bfin_sic",
+ i, j + BFIN_DMAC_MDMA_BASE, (2 * i) + (j / 2));
+ }
+ }
+
+ for (i = 0; i < mdata->dev_count; ++i)
+ {
+ const struct bfin_dev_layout *dev = &mdata->dev[i];
+ sim_hw_parse (sd, "/core/%s/reg %#x %i", dev->dev, dev->base, dev->len);
+ sim_hw_parse (sd, "/core/%s/type %i", dev->dev, mdata->model_num);
+ if (strchr (dev->dev, '/'))
+ continue;
+ if (!strncmp (dev->dev, "bfin_uart", 9)
+ || !strncmp (dev->dev, "bfin_emac", 9)
+ || !strncmp (dev->dev, "bfin_sport", 10))
+ {
+ const char *sint = dev->dev + 5;
+ sim_hw_parse (sd, "/core/%s > tx %s_tx /core/bfin_dmac@%u", dev->dev, sint, dev->dmac);
+ sim_hw_parse (sd, "/core/%s > rx %s_rx /core/bfin_dmac@%u", dev->dev, sint, dev->dmac);
+ sim_hw_parse (sd, "/core/%s > stat %s_stat /core/bfin_sic", dev->dev, sint);
+ }
+ else if (!strncmp (dev->dev, "bfin_gptimer", 12)
+ || !strncmp (dev->dev, "bfin_ppi", 8)
+ || !strncmp (dev->dev, "bfin_spi", 8)
+ || !strncmp (dev->dev, "bfin_twi", 8))
+ {
+ const char *sint = dev->dev + 5;
+ sim_hw_parse (sd, "/core/%s > stat %s /core/bfin_sic", dev->dev, sint);
+ }
+ else if (!strncmp (dev->dev, "bfin_rtc", 8))
+ {
+ const char *sint = dev->dev + 5;
+ sim_hw_parse (sd, "/core/%s > %s %s /core/bfin_sic", dev->dev, sint, sint);
+ }
+ else if (!strncmp (dev->dev, "bfin_wdog", 9))
+ {
+ sim_hw_parse (sd, "/core/%s > reset rst /core/bfin_cec", dev->dev);
+ sim_hw_parse (sd, "/core/%s > nmi nmi /core/bfin_cec", dev->dev);
+ sim_hw_parse (sd, "/core/%s > gpi wdog /core/bfin_sic", dev->dev);
+ }
+ }
+
+ done:
+ /* Add any additional user board content. */
+ if (board->hw_file)
+ sim_do_commandf (sd, "hw-file %s", board->hw_file);
+
+ /* Trigger all the new devices' finish func. */
+ hw_tree_finish (dv_get_device (cpu, "/"));
+}
+
+#include "bfroms/all.h"
+
+struct bfrom {
+ bu32 addr, len, alias_len;
+ int sirev;
+ const char *buf;
+};
+
+#define BFROMA(addr, rom, sirev, alias_len) \
+ { addr, sizeof (bfrom_bf##rom##_0_##sirev), alias_len, \
+ sirev, bfrom_bf##rom##_0_##sirev, }
+#define BFROM(rom, sirev, alias_len) BFROMA (0xef000000, rom, sirev, alias_len)
+#define BFROM_STUB { 0, 0, 0, 0, NULL, }
+static const struct bfrom bf50x_roms[] = {
+ BFROM (50x, 0, 0x1000000),
+ BFROM_STUB,
+};
+static const struct bfrom bf51x_roms[] = {
+ BFROM (51x, 2, 0x1000000),
+ BFROM (51x, 1, 0x1000000),
+ BFROM (51x, 0, 0x1000000),
+ BFROM_STUB,
+};
+static const struct bfrom bf526_roms[] = {
+ BFROM (526, 1, 0x1000000),
+ BFROM (526, 0, 0x1000000),
+ BFROM_STUB,
+};
+static const struct bfrom bf527_roms[] = {
+ BFROM (527, 2, 0x1000000),
+ BFROM (527, 1, 0x1000000),
+ BFROM (527, 0, 0x1000000),
+ BFROM_STUB,
+};
+static const struct bfrom bf533_roms[] = {
+ BFROM (533, 6, 0x1000000),
+ BFROM (533, 5, 0x1000000),
+ BFROM (533, 4, 0x1000000),
+ BFROM (533, 3, 0x1000000),
+ BFROM (533, 2, 0x1000000),
+ BFROM (533, 1, 0x1000000),
+ BFROM_STUB,
+};
+static const struct bfrom bf537_roms[] = {
+ BFROM (537, 3, 0x100000),
+ BFROM (537, 2, 0x100000),
+ BFROM (537, 1, 0x100000),
+ BFROM (537, 0, 0x100000),
+ BFROM_STUB,
+};
+static const struct bfrom bf538_roms[] = {
+ BFROM (538, 5, 0x1000000),
+ BFROM (538, 4, 0x1000000),
+ BFROM (538, 3, 0x1000000),
+ BFROM (538, 2, 0x1000000),
+ BFROM (538, 1, 0x1000000),
+ BFROM (538, 0, 0x1000000),
+ BFROM_STUB,
+};
+static const struct bfrom bf54x_roms[] = {
+ BFROM (54x, 2, 0),
+ BFROM (54x, 1, 0),
+ BFROM (54x, 0, 0),
+ BFROMA (0xffa14000, 54x_l1, 2, 0),
+ BFROMA (0xffa14000, 54x_l1, 1, 0),
+ BFROMA (0xffa14000, 54x_l1, 0, 0),
+ BFROM_STUB,
+};
+static const struct bfrom bf561_roms[] = {
+ /* XXX: No idea what the actual wrap limit is here. */
+ BFROM (561, 5, 0),
+ BFROM_STUB,
+};
+static const struct bfrom bf59x_roms[] = {
+ BFROM (59x, 1, 0x1000000),
+ BFROM (59x, 0, 0x1000000),
+ BFROMA (0xffa10000, 59x_l1, 1, 0),
+ BFROM_STUB,
+};
+
+static void
+bfin_model_map_bfrom (SIM_DESC sd, SIM_CPU *cpu)
+{
+ const struct bfin_model_data *mdata = CPU_MODEL_DATA (cpu);
+ const struct bfin_board_data *board = STATE_BOARD_DATA (sd);
+ int mnum = mdata->model_num;
+ const struct bfrom *bfrom;
+ unsigned int sirev;
+
+ if (mnum >= 500 && mnum <= 509)
+ bfrom = bf50x_roms;
+ else if (mnum >= 510 && mnum <= 519)
+ bfrom = bf51x_roms;
+ else if (mnum >= 520 && mnum <= 529)
+ bfrom = (mnum & 1) ? bf527_roms : bf526_roms;
+ else if (mnum >= 531 && mnum <= 533)
+ bfrom = bf533_roms;
+ else if (mnum == 535)
+ /* Stub. */;
+ else if (mnum >= 534 && mnum <= 537)
+ bfrom = bf537_roms;
+ else if (mnum >= 538 && mnum <= 539)
+ bfrom = bf538_roms;
+ else if (mnum >= 540 && mnum <= 549)
+ bfrom = bf54x_roms;
+ else if (mnum == 561)
+ bfrom = bf561_roms;
+ else if (mnum >= 590 && mnum <= 599)
+ bfrom = bf59x_roms;
+ else
+ return;
+
+ if (board->sirev_valid)
+ sirev = board->sirev;
+ else
+ sirev = bfrom->sirev;
+ while (bfrom->buf)
+ {
+ /* Map all the ranges for this model/sirev. */
+ if (bfrom->sirev == sirev)
+ sim_core_attach (sd, NULL, 0, access_read_exec, 0, bfrom->addr,
+ bfrom->alias_len ? : bfrom->len, bfrom->len, NULL,
+ (char *)bfrom->buf);
+ ++bfrom;
+ }
+}
+
+void
+bfin_model_cpu_init (SIM_DESC sd, SIM_CPU *cpu)
+{
+ const MODEL *model = CPU_MODEL (cpu);
+ const struct bfin_model_data *mdata = CPU_MODEL_DATA (cpu);
+ int mnum = MODEL_NUM (model);
+ size_t idx;
+
+ /* These memory maps are supposed to be cpu-specific, but the common sim
+ code does not yet allow that (2nd arg is "cpu" rather than "NULL". */
+ sim_core_attach (sd, NULL, 0, access_read_write, 0, BFIN_L1_SRAM_SCRATCH,
+ BFIN_L1_SRAM_SCRATCH_SIZE, 0, NULL, NULL);
+
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) != OPERATING_ENVIRONMENT)
+ return;
+
+ if (mnum == MODEL_BF000)
+ goto core_only;
+
+ /* Map in the on-chip memories (SRAMs). */
+ mdata = &bfin_model_data[MODEL_NUM (model)];
+ for (idx = 0; idx < mdata->mem_count; ++idx)
+ {
+ const struct bfin_memory_layout *mem = &mdata->mem[idx];
+ sim_core_attach (sd, NULL, 0, mem->mask, 0, mem->addr,
+ mem->len, 0, NULL, NULL);
+ }
+
+ /* Map the on-chip ROMs. */
+ bfin_model_map_bfrom (sd, cpu);
+
+ core_only:
+ /* Finally, build up the tree for this cpu model. */
+ bfin_model_hw_tree_init (sd, cpu);
+}
+
+bu32
+bfin_model_get_chipid (SIM_DESC sd)
+{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+ const struct bfin_model_data *mdata = CPU_MODEL_DATA (cpu);
+ const struct bfin_board_data *board = STATE_BOARD_DATA (sd);
+ return
+ (board->sirev << 28) |
+ (mdata->chipid << 12) |
+ (((0xE5 << 1) | 1) & 0xFF);
+}
+
+bu32
+bfin_model_get_dspid (SIM_DESC sd)
+{
+ const struct bfin_board_data *board = STATE_BOARD_DATA (sd);
+ return
+ (0xE5 << 24) |
+ (0x04 << 16) |
+ (board->sirev);
+}
+
+static void
+bfin_model_init (SIM_CPU *cpu)
+{
+ CPU_MODEL_DATA (cpu) = (void *) &bfin_model_data[MODEL_NUM (CPU_MODEL (cpu))];
+}
+
+static bu32
+bfin_extract_unsigned_integer (unsigned char *addr, int len)
+{
+ bu32 retval;
+ unsigned char * p;
+ unsigned char * startaddr = (unsigned char *)addr;
+ unsigned char * endaddr = startaddr + len;
+
+ retval = 0;
+
+ for (p = endaddr; p > startaddr;)
+ retval = (retval << 8) | *--p;
+
+ return retval;
+}
+
+static void
+bfin_store_unsigned_integer (unsigned char *addr, int len, bu32 val)
+{
+ unsigned char *p;
+ unsigned char *startaddr = addr;
+ unsigned char *endaddr = startaddr + len;
+
+ for (p = startaddr; p < endaddr;)
+ {
+ *p++ = val & 0xff;
+ val >>= 8;
+ }
+}
+
+static bu32 *
+bfin_get_reg (SIM_CPU *cpu, int rn)
+{
+ switch (rn)
+ {
+ case SIM_BFIN_R0_REGNUM: return &DREG (0);
+ case SIM_BFIN_R1_REGNUM: return &DREG (1);
+ case SIM_BFIN_R2_REGNUM: return &DREG (2);
+ case SIM_BFIN_R3_REGNUM: return &DREG (3);
+ case SIM_BFIN_R4_REGNUM: return &DREG (4);
+ case SIM_BFIN_R5_REGNUM: return &DREG (5);
+ case SIM_BFIN_R6_REGNUM: return &DREG (6);
+ case SIM_BFIN_R7_REGNUM: return &DREG (7);
+ case SIM_BFIN_P0_REGNUM: return &PREG (0);
+ case SIM_BFIN_P1_REGNUM: return &PREG (1);
+ case SIM_BFIN_P2_REGNUM: return &PREG (2);
+ case SIM_BFIN_P3_REGNUM: return &PREG (3);
+ case SIM_BFIN_P4_REGNUM: return &PREG (4);
+ case SIM_BFIN_P5_REGNUM: return &PREG (5);
+ case SIM_BFIN_SP_REGNUM: return &SPREG;
+ case SIM_BFIN_FP_REGNUM: return &FPREG;
+ case SIM_BFIN_I0_REGNUM: return &IREG (0);
+ case SIM_BFIN_I1_REGNUM: return &IREG (1);
+ case SIM_BFIN_I2_REGNUM: return &IREG (2);
+ case SIM_BFIN_I3_REGNUM: return &IREG (3);
+ case SIM_BFIN_M0_REGNUM: return &MREG (0);
+ case SIM_BFIN_M1_REGNUM: return &MREG (1);
+ case SIM_BFIN_M2_REGNUM: return &MREG (2);
+ case SIM_BFIN_M3_REGNUM: return &MREG (3);
+ case SIM_BFIN_B0_REGNUM: return &BREG (0);
+ case SIM_BFIN_B1_REGNUM: return &BREG (1);
+ case SIM_BFIN_B2_REGNUM: return &BREG (2);
+ case SIM_BFIN_B3_REGNUM: return &BREG (3);
+ case SIM_BFIN_L0_REGNUM: return &LREG (0);
+ case SIM_BFIN_L1_REGNUM: return &LREG (1);
+ case SIM_BFIN_L2_REGNUM: return &LREG (2);
+ case SIM_BFIN_L3_REGNUM: return &LREG (3);
+ case SIM_BFIN_RETS_REGNUM: return &RETSREG;
+ case SIM_BFIN_A0_DOT_X_REGNUM: return &AXREG (0);
+ case SIM_BFIN_A0_DOT_W_REGNUM: return &AWREG (0);
+ case SIM_BFIN_A1_DOT_X_REGNUM: return &AXREG (1);
+ case SIM_BFIN_A1_DOT_W_REGNUM: return &AWREG (1);
+ case SIM_BFIN_LC0_REGNUM: return &LCREG (0);
+ case SIM_BFIN_LT0_REGNUM: return &LTREG (0);
+ case SIM_BFIN_LB0_REGNUM: return &LBREG (0);
+ case SIM_BFIN_LC1_REGNUM: return &LCREG (1);
+ case SIM_BFIN_LT1_REGNUM: return &LTREG (1);
+ case SIM_BFIN_LB1_REGNUM: return &LBREG (1);
+ case SIM_BFIN_CYCLES_REGNUM: return &CYCLESREG;
+ case SIM_BFIN_CYCLES2_REGNUM: return &CYCLES2REG;
+ case SIM_BFIN_USP_REGNUM: return &USPREG;
+ case SIM_BFIN_SEQSTAT_REGNUM: return &SEQSTATREG;
+ case SIM_BFIN_SYSCFG_REGNUM: return &SYSCFGREG;
+ case SIM_BFIN_RETI_REGNUM: return &RETIREG;
+ case SIM_BFIN_RETX_REGNUM: return &RETXREG;
+ case SIM_BFIN_RETN_REGNUM: return &RETNREG;
+ case SIM_BFIN_RETE_REGNUM: return &RETEREG;
+ case SIM_BFIN_PC_REGNUM: return &PCREG;
+ default: return NULL;
+ }
+}
+
+static int
+bfin_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *buf, int len)
+{
+ bu32 value, *reg;
+
+ reg = bfin_get_reg (cpu, rn);
+ if (reg)
+ value = *reg;
+ else if (rn == SIM_BFIN_ASTAT_REGNUM)
+ value = ASTAT;
+ else if (rn == SIM_BFIN_CC_REGNUM)
+ value = CCREG;
+ else
+ return 0; // will be an error in gdb
+
+ /* Handle our KSP/USP shadowing in SP. While in supervisor mode, we
+ have the normal SP/USP behavior. User mode is tricky though. */
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) == OPERATING_ENVIRONMENT
+ && cec_is_user_mode (cpu))
+ {
+ if (rn == SIM_BFIN_SP_REGNUM)
+ value = KSPREG;
+ else if (rn == SIM_BFIN_USP_REGNUM)
+ value = SPREG;
+ }
+
+ bfin_store_unsigned_integer (buf, 4, value);
+
+ return -1; // disables size checking in gdb
+}
+
+static int
+bfin_reg_store (SIM_CPU *cpu, int rn, unsigned char *buf, int len)
+{
+ bu32 value, *reg;
+
+ value = bfin_extract_unsigned_integer (buf, 4);
+ reg = bfin_get_reg (cpu, rn);
+
+ if (reg)
+ /* XXX: Need register trace ? */
+ *reg = value;
+ else if (rn == SIM_BFIN_ASTAT_REGNUM)
+ SET_ASTAT (value);
+ else if (rn == SIM_BFIN_CC_REGNUM)
+ SET_CCREG (value);
+ else
+ return 0; // will be an error in gdb
+
+ return -1; // disables size checking in gdb
+}
+
+static sim_cia
+bfin_pc_get (SIM_CPU *cpu)
+{
+ return PCREG;
+}
+
+static void
+bfin_pc_set (SIM_CPU *cpu, sim_cia newpc)
+{
+ SET_PCREG (newpc);
+}
+
+static const char *
+bfin_insn_name (SIM_CPU *cpu, int i)
+{
+ static const char * const insn_name[] = {
+#define I(insn) #insn,
+#include "insn_list.def"
+#undef I
+ };
+ return insn_name[i];
+}
+
+static void
+bfin_init_cpu (SIM_CPU *cpu)
+{
+ CPU_REG_FETCH (cpu) = bfin_reg_fetch;
+ CPU_REG_STORE (cpu) = bfin_reg_store;
+ CPU_PC_FETCH (cpu) = bfin_pc_get;
+ CPU_PC_STORE (cpu) = bfin_pc_set;
+ CPU_MAX_INSNS (cpu) = BFIN_INSN_MAX;
+ CPU_INSN_NAME (cpu) = bfin_insn_name;
+}
+
+static void
+bfin_prepare_run (SIM_CPU *cpu)
+{
+}
+
+static const MODEL bfin_models[] =
+{
+#define P(n) { "bf"#n, & bfin_mach, MODEL_BF##n, NULL, bfin_model_init },
+#include "proc_list.def"
+#undef P
+ { 0, NULL, 0, NULL, NULL, }
+};
+
+static const MACH_IMP_PROPERTIES bfin_imp_properties =
+{
+ sizeof (SIM_CPU),
+ 0,
+};
+
+static const MACH bfin_mach =
+{
+ "bfin", "bfin", MACH_BFIN,
+ 32, 32, & bfin_models[0], & bfin_imp_properties,
+ bfin_init_cpu,
+ bfin_prepare_run
+};
+
+const MACH *sim_machs[] =
+{
+ & bfin_mach,
+ NULL
+};
+
+/* Device option parsing. */
+
+static DECLARE_OPTION_HANDLER (bfin_mach_option_handler);
+
+enum {
+ OPTION_MACH_SIREV = OPTION_START,
+ OPTION_MACH_HW_BOARD_FILE,
+};
+
+const OPTION bfin_mach_options[] =
+{
+ { {"sirev", required_argument, NULL, OPTION_MACH_SIREV },
+ '\0', "NUMBER", "Set CPU silicon revision",
+ bfin_mach_option_handler, NULL },
+
+ { {"hw-board-file", required_argument, NULL, OPTION_MACH_HW_BOARD_FILE },
+ '\0', "FILE", "Add the supplemental devices listed in the file",
+ bfin_mach_option_handler, NULL },
+
+ { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
+};
+
+static SIM_RC
+bfin_mach_option_handler (SIM_DESC sd, sim_cpu *current_cpu, int opt,
+ char *arg, int is_command)
+{
+ struct bfin_board_data *board = STATE_BOARD_DATA (sd);
+
+ switch (opt)
+ {
+ case OPTION_MACH_SIREV:
+ board->sirev_valid = 1;
+ /* Accept (and throw away) a leading "0." in the version. */
+ if (!strncmp (arg, "0.", 2))
+ arg += 2;
+ board->sirev = atoi (arg);
+ if (board->sirev > 0xf)
+ {
+ sim_io_eprintf (sd, "sirev '%s' needs to fit into 4 bits\n", arg);
+ return SIM_RC_FAIL;
+ }
+ return SIM_RC_OK;
+
+ case OPTION_MACH_HW_BOARD_FILE:
+ board->hw_file = xstrdup (arg);
+ return SIM_RC_OK;
+
+ default:
+ sim_io_eprintf (sd, "Unknown Blackfin option %d\n", opt);
+ return SIM_RC_FAIL;
+ }
+}
diff --git a/sim/bfin/machs.h b/sim/bfin/machs.h
new file mode 100644
index 00000000000..ac16adb21f1
--- /dev/null
+++ b/sim/bfin/machs.h
@@ -0,0 +1,56 @@
+/* Simulator for Analog Devices Blackfin processors.
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _BFIN_MACHS_H_
+#define _BFIN_MACHS_H_
+
+typedef enum model_type {
+#define P(n) MODEL_BF##n,
+#include "proc_list.def"
+#undef P
+ MODEL_MAX
+} MODEL_TYPE;
+
+typedef enum mach_attr {
+ MACH_BASE,
+ MACH_BFIN,
+ MACH_MAX
+} MACH_ATTR;
+
+#define CPU_MODEL_NUM(cpu) MODEL_NUM (CPU_MODEL (cpu))
+
+/* XXX: Some of this probably belongs in CPU_MODEL. */
+struct bfin_board_data {
+ unsigned int sirev, sirev_valid;
+ const char *hw_file;
+};
+
+void bfin_model_cpu_init (SIM_DESC, SIM_CPU *);
+bu32 bfin_model_get_chipid (SIM_DESC);
+bu32 bfin_model_get_dspid (SIM_DESC);
+
+enum {
+#define I(insn) BFIN_INSN_##insn,
+#include "insn_list.def"
+#undef I
+ BFIN_INSN_MAX
+};
+
+#endif
diff --git a/sim/bfin/proc_list.def b/sim/bfin/proc_list.def
new file mode 100644
index 00000000000..aa9d33764ed
--- /dev/null
+++ b/sim/bfin/proc_list.def
@@ -0,0 +1,50 @@
+/* Blackfin processor list
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+/* First entry is the default model. */
+P(537)
+P(504)
+P(506)
+P(512)
+P(514)
+P(516)
+P(518)
+P(522)
+P(523)
+P(524)
+P(525)
+P(526)
+P(527)
+P(531)
+P(532)
+P(533)
+P(534)
+/*P(535)*/
+P(536)
+P(538)
+P(539)
+P(542)
+P(544)
+P(547)
+P(548)
+P(549)
+P(561)
+P(592)
+P(000)
diff --git a/sim/bfin/sim-main.h b/sim/bfin/sim-main.h
new file mode 100644
index 00000000000..3a937034817
--- /dev/null
+++ b/sim/bfin/sim-main.h
@@ -0,0 +1,117 @@
+/* Simulator for Analog Devices Blackfin processors.
+
+ Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _BFIN_MAIN_SIM_H_
+#define _BFIN_MAIN_SIM_H_
+
+#include "sim-basics.h"
+#include "sim-signal.h"
+
+typedef unsigned32 sim_cia;
+
+#define CIA_GET(cpu) CPU_PC_GET (cpu)
+#define CIA_SET(cpu,val) CPU_PC_SET ((cpu), (val))
+
+typedef struct _sim_cpu SIM_CPU;
+
+#include "bfin-sim.h"
+
+#include "machs.h"
+
+#include "sim-base.h"
+
+struct _sim_cpu {
+ /* ... simulator specific members ... */
+ struct bfin_cpu_state state;
+ sim_cpu_base base;
+};
+#define BFIN_CPU_STATE ((cpu)->state)
+
+struct sim_state {
+ sim_cpu *cpu[MAX_NR_PROCESSORS];
+#if (WITH_SMP)
+#define STATE_CPU(sd,n) ((sd)->cpu[n])
+#else
+#define STATE_CPU(sd,n) ((sd)->cpu[0])
+#endif
+ /* ... simulator specific members ... */
+ struct bfin_board_data board;
+#define STATE_BOARD_DATA(sd) (&(sd)->board)
+ sim_state_base base;
+};
+
+#include "sim-config.h"
+#include "sim-types.h"
+#include "sim-engine.h"
+#include "sim-options.h"
+#include "run-sim.h"
+#include "dv-bfin_trace.h"
+
+#undef MAX
+#undef MIN
+#undef CLAMP
+#undef ALIGN
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define CLAMP(a, b, c) MIN (MAX (a, b), c)
+#define ALIGN(addr, size) (((addr) + ((size)-1)) & ~((size)-1))
+
+#define MAYBE_TRACE(type, cpu, fmt, ...) \
+ do { \
+ if (TRACE_##type##_P (cpu)) \
+ trace_generic (CPU_STATE (cpu), cpu, TRACE_##type##_IDX, \
+ fmt, ## __VA_ARGS__); \
+ } while (0)
+#define TRACE_INSN(cpu, fmt, ...) MAYBE_TRACE (INSN, cpu, fmt, ## __VA_ARGS__)
+#define TRACE_DECODE(cpu, fmt, ...) MAYBE_TRACE (DECODE, cpu, fmt, ## __VA_ARGS__)
+#define TRACE_EXTRACT(cpu, fmt, ...) MAYBE_TRACE (EXTRACT, cpu, fmt, ## __VA_ARGS__)
+#define TRACE_SYSCALL(cpu, fmt, ...) MAYBE_TRACE (EVENTS, cpu, fmt, ## __VA_ARGS__)
+#define TRACE_CORE(cpu, addr, size, map, val) \
+ do { \
+ MAYBE_TRACE (CORE, cpu, "%cBUS %s %i bytes @ 0x%08x: 0x%0*x", \
+ map == exec_map ? 'I' : 'D', \
+ map == write_map ? "STORE" : "FETCH", \
+ size, addr, size * 2, val); \
+ PROFILE_COUNT_CORE (cpu, addr, size, map); \
+ } while (0)
+#define TRACE_EVENTS(cpu, fmt, ...) MAYBE_TRACE (EVENTS, cpu, fmt, ## __VA_ARGS__)
+#define TRACE_BRANCH(cpu, oldpc, newpc, hwloop, fmt, ...) \
+ do { \
+ MAYBE_TRACE (BRANCH, cpu, fmt " to %#x", ## __VA_ARGS__, newpc); \
+ if (STATE_ENVIRONMENT (CPU_STATE (cpu)) == OPERATING_ENVIRONMENT) \
+ bfin_trace_queue (cpu, oldpc, newpc, hwloop); \
+ } while (0)
+
+extern void trace_register PARAMS ((SIM_DESC sd,
+ sim_cpu *cpu,
+ const char *fmt,
+ ...))
+ __attribute__((format (printf, 3, 4)));
+#define TRACE_REGISTER(cpu, fmt, ...) \
+ do { \
+ if (TRACE_CORE_P (cpu)) \
+ trace_register (CPU_STATE (cpu), cpu, fmt, ## __VA_ARGS__); \
+ } while (0)
+#define TRACE_REG(cpu, reg, val) TRACE_REGISTER (cpu, "wrote "#reg" = %#x", val)
+
+/* Default memory size. */
+#define BFIN_DEFAULT_MEM_SIZE (128 * 1024 * 1024)
+
+#endif
diff --git a/sim/bfin/tconfig.in b/sim/bfin/tconfig.in
new file mode 100644
index 00000000000..130707a90a8
--- /dev/null
+++ b/sim/bfin/tconfig.in
@@ -0,0 +1,27 @@
+/* Blackfin target configuration file. -*- C -*- */
+
+/* See sim-hload.c. We properly handle LMA. -- TODO: check this */
+#define SIM_HANDLES_LMA 1
+
+/* We use this so that we are passed the requesting CPU for HW acesses.
+ Common sim core by default sets hw_system_cpu to NULL for WITH_HW. */
+#define WITH_DEVICES 1
+
+/* FIXME: This is unnecessarily necessary: */
+#include "ansidecl.h"
+#include "gdb/callback.h"
+#include "gdb/remote-sim.h"
+#include "sim-module.h"
+
+/* FIXME: Revisit. */
+#ifdef HAVE_DV_SOCKSER
+MODULE_INSTALL_FN dv_sockser_install;
+#define MODULE_LIST dv_sockser_install,
+#endif
+
+/* ??? Temporary hack until model support unified. */
+#define SIM_HAVE_MODEL
+
+/* Allows us to do the memory aliasing that some bfroms have:
+ {0xef000000 - 0xef100000} => {0xef000000 - 0xef000800} */
+#define WITH_MODULO_MEMORY 1