aboutsummaryrefslogtreecommitdiff
path: root/gdb/rdi-share
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>1998-01-08 11:12:39 +0000
committerNick Clifton <nickc@redhat.com>1998-01-08 11:12:39 +0000
commit3a9c3d120fe4b7cd24f75f275e4b1034577ce056 (patch)
treeb0c06fea2896a37889cdb272d9acbe476689e6e1 /gdb/rdi-share
parentd7ab10784a26a2d5f2174afa9c17450851abbb75 (diff)
downloadgdb-3a9c3d120fe4b7cd24f75f275e4b1034577ce056.zip
gdb-3a9c3d120fe4b7cd24f75f275e4b1034577ce056.tar.gz
gdb-3a9c3d120fe4b7cd24f75f275e4b1034577ce056.tar.bz2
Applied patches from Tony.Thompson@arm.com to implement the Angel remote
debugging interface and resurrected associated RDI files.
Diffstat (limited to 'gdb/rdi-share')
-rw-r--r--gdb/rdi-share/Makefile.in165
-rw-r--r--gdb/rdi-share/README.CYGNUS6
-rw-r--r--gdb/rdi-share/adp.h2528
-rw-r--r--gdb/rdi-share/adperr.h74
-rw-r--r--gdb/rdi-share/angel.h177
-rw-r--r--gdb/rdi-share/ardi.c2672
-rw-r--r--gdb/rdi-share/ardi.h85
-rw-r--r--gdb/rdi-share/armdbg.h1452
-rw-r--r--gdb/rdi-share/buffers.h111
-rw-r--r--gdb/rdi-share/bytesex.c57
-rw-r--r--gdb/rdi-share/bytesex.h42
-rw-r--r--gdb/rdi-share/chandefs.h50
-rw-r--r--gdb/rdi-share/channels.h384
-rw-r--r--gdb/rdi-share/chanpriv.h57
-rw-r--r--gdb/rdi-share/configure.in44
-rw-r--r--gdb/rdi-share/crc.c257
-rw-r--r--gdb/rdi-share/crc.h90
-rw-r--r--gdb/rdi-share/dbg_conf.h54
-rw-r--r--gdb/rdi-share/dbg_cp.h62
-rw-r--r--gdb/rdi-share/dbg_hif.h56
-rw-r--r--gdb/rdi-share/dbg_rdi.h511
-rw-r--r--gdb/rdi-share/devclnt.h260
-rw-r--r--gdb/rdi-share/devices.h104
-rw-r--r--gdb/rdi-share/devsw.c400
-rw-r--r--gdb/rdi-share/devsw.h268
-rw-r--r--gdb/rdi-share/drivers.c34
-rw-r--r--gdb/rdi-share/drivers.h193
-rw-r--r--gdb/rdi-share/endian.h125
-rw-r--r--gdb/rdi-share/etherdrv.c725
-rw-r--r--gdb/rdi-share/ethernet.h99
-rw-r--r--gdb/rdi-share/host.h222
-rw-r--r--gdb/rdi-share/hostchan.c1060
-rw-r--r--gdb/rdi-share/hostchan.h300
-rw-r--r--gdb/rdi-share/hsys.c915
-rw-r--r--gdb/rdi-share/hsys.h101
-rw-r--r--gdb/rdi-share/logging.c369
-rw-r--r--gdb/rdi-share/logging.h121
-rw-r--r--gdb/rdi-share/msgbuild.c282
-rw-r--r--gdb/rdi-share/msgbuild.h75
-rw-r--r--gdb/rdi-share/params.c325
-rw-r--r--gdb/rdi-share/params.h181
-rw-r--r--gdb/rdi-share/rx.c361
-rw-r--r--gdb/rdi-share/rxtx.h263
-rw-r--r--gdb/rdi-share/serdrv.c649
-rw-r--r--gdb/rdi-share/serpardr.c730
-rw-r--r--gdb/rdi-share/sys.h319
-rw-r--r--gdb/rdi-share/tx.c176
-rw-r--r--gdb/rdi-share/unixcomm.c535
-rw-r--r--gdb/rdi-share/unixcomm.h212
49 files changed, 18338 insertions, 0 deletions
diff --git a/gdb/rdi-share/Makefile.in b/gdb/rdi-share/Makefile.in
new file mode 100644
index 0000000..45a9204
--- /dev/null
+++ b/gdb/rdi-share/Makefile.in
@@ -0,0 +1,165 @@
+prefix = /usr/local
+
+program_transform_name =
+exec_prefix = $(prefix)
+bindir = $(exec_prefix)/bin
+libdir = $(exec_prefix)/lib
+tooldir = $(libdir)/$(target_alias)
+
+datadir = $(prefix)/share
+mandir = $(prefix)/man
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = $(prefix)/info
+includedir = $(prefix)/include
+
+ARM_RELEASE='"Berkeley Licence for Cygnus"'
+
+SHELL = /bin/sh
+
+INSTALL = `cd $(srcdir)/../..;pwd`/install.sh -c
+INSTALL_PROGRAM = $(INSTALL)
+INSTALL_DATA = $(INSTALL)
+INSTALL_XFORM = $(INSTALL) -t='$(program_transform_name)'
+INSTALL_XFORM1 = $(INSTALL_XFORM) -b=.1
+
+AR = ar
+AR_FLAGS = qv
+RANLIB = ranlib
+
+LD = ld
+
+# If you are compiling with GCC, make sure that either 1) You use the
+# -traditional flag, or 2) You have the fixed include files where GCC
+# can reach them. Otherwise the ioctl calls in inflow.c
+# will be incorrectly compiled. The "fixincludes" script in the gcc
+# distribution will fix your include files up.
+#CC=cc
+#CC=gcc -traditional
+GCC=gcc
+
+# Directory containing source files. Don't clean up the spacing,
+# this exact string is matched for by the "configure" script.
+srcdir = .
+
+# It is also possible that you will need to add -I/usr/include/sys to the
+# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which
+# is where it should be according to Posix).
+
+# Set this up with gcc if you have gnu ld and the loader will print out
+# line numbers for undefinded refs.
+#CC-LD=gcc -static
+CC-LD=${CC}
+
+# All the includes used for CFLAGS and for lint.
+# -I. for config files.
+# -I${srcdir} possibly for regex.h also.
+# -I${srcdir}/config for more generic config files.
+INCLUDE_CFLAGS = -I. -I${srcdir}
+
+# M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS
+# from the config/ directory.
+GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS} -DRETRANS -DARM_RELEASE=$(ARM_RELEASE)
+#PROFILE_CFLAGS = -pg
+
+# CFLAGS is specifically reserved for setting from the command line
+# when running make. I.E. "make CFLAGS=-Wmissing-prototypes".
+CFLAGS = -g
+
+# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} \
+ ${BFD_CFLAGS} ${MMALLOC_CFLAGS} ${INCLUDE_CFLAGS}
+
+# LDFLAGS is specifically reserved for setting from the command line
+# when running make.
+
+# Host and target-dependent makefile fragments come in here.
+####
+# End of host and target-dependent makefile fragments
+
+# All source files that go into linking GDB remote server.
+
+SFILES = $(srcdir)/
+
+DEPFILES =
+
+SOURCES = $(SFILES) $(ALLDEPFILES)
+TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
+
+OBS = hostchan.o drivers.o devsw.o rx.o tx.o params.o hsys.o crc.o \
+logging.o msgbuild.o ardi.o serdrv.o serpardr.o etherdrv.o bytesex.o \
+unixcomm.o
+
+# Prevent Sun make from putting in the machine type. Setting
+# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
+.c.o:
+ ${CC} -c ${INTERNAL_CFLAGS} $<
+
+all: libangsd.a
+
+libangsd.a: $(OBS)
+ rm -f libangsd.a
+ $(AR) $(AR_FLAGS) libangsd.a $(OBS)
+ $(RANLIB) libangsd.a
+
+# Traditionally "install" depends on "all". But it may be useful
+# not to; for example, if the user has made some trivial change to a
+# source file and doesn't care about rebuilding or just wants to save the
+# time it takes for make to check that all is up to date.
+# install-only is intended to address that need.
+install: all install-only
+install-only:
+
+uninstall:
+
+installcheck:
+check:
+info dvi:
+install-info:
+clean-info:
+
+config.status:
+ @echo "You must configure rdi-share. Look at the README file for details."
+ @false
+
+clean:
+ rm -f *.o ${ADD_FILES} *~
+ rm -f gdbserver core make.log
+
+distclean: clean
+ rm -f config.status
+ rm -f Makefile
+
+maintainer-clean realclean: clean
+ rm -f config.status
+ rm -f Makefile
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
+ $(SHELL) ./config.status
+
+force:
+
+# GNU Make has an annoying habit of putting *all* the Makefile variables
+# into the environment, unless you include this target as a circumvention.
+# Rumor is that this will be fixed (and this target can be removed)
+# in GNU Make 4.0.
+.NOEXPORT:
+
+# GNU Make 3.63 has a different problem: it keeps tacking command line
+# overrides onto the definition of $(MAKE). This variable setting
+# will remove them.
+MAKEOVERRIDES=
+
+## This is ugly, but I don't want GNU make to put these variables in
+## the environment. Older makes will see this as a set of targets
+## with no dependencies and no actions.
+unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
+
+# This is the end of "Makefile.in".
diff --git a/gdb/rdi-share/README.CYGNUS b/gdb/rdi-share/README.CYGNUS
new file mode 100644
index 0000000..4bf06c9
--- /dev/null
+++ b/gdb/rdi-share/README.CYGNUS
@@ -0,0 +1,6 @@
+This is a version of ARM's RDI library which has been been put under a
+free software license.
+
+See ARM's Software Development Tools Reference Manual (Remote
+Debugging chapter), and the file gdb/remote-rdi.c for information
+about how to use it.
diff --git a/gdb/rdi-share/adp.h b/gdb/rdi-share/adp.h
new file mode 100644
index 0000000..099fa4d
--- /dev/null
+++ b/gdb/rdi-share/adp.h
@@ -0,0 +1,2528 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ *
+ * INTRODUCTION
+ * ------------
+ * The early RDP message definitions were held in an ARM Ltd "armdbg"
+ * source file. Since the relevant header files were not exported
+ * publicly as part of an ARM Ltd core tools release, it was a problem
+ * for developers manipulating the target side of the protocol.
+ *
+ * For Angel, this new (ANSI 'C' clean) header file defines the ADP
+ * protocol. The header should be useable by both host and target
+ * systems, thus avoiding problems that can arise from duplicate
+ * definitions. Care has been taken in the construction of this header
+ * file to avoid any host/target differences.
+ *
+ * MESSAGE FORMAT
+ * --------------
+ * Format of the "data" section of debug and boot agent messages. This is
+ * the standard ADP (Angel Debug Protocol) message format:
+ *
+ * unsigned32 reason - Main debug reason code.
+ * unsigned32 debugID - Information describing host debug world;
+ * - private to host and used in any target initiated
+ * messages.
+ * unsigned32 OSinfo1 \ Target OS information to identify process/thread
+ * unsigned32 OSinfo2 / memory/world, etc. These two fields are target
+ * defined.
+ * byte args[n] - Data for message "reason" code.
+ *
+ * NOTE: The message format is the same for single threaded debugging,
+ * except that the "OSinfo" fields should be -1 (0xFFFFFFFF). Even
+ * single-threaded debugging *MAY* have different host specified
+ * debugID values, so the Angel debug system will preserve the "debugID"
+ * information for replies, and the relevant asynchronous target-to-host
+ * messages. The "debugID" is defined by the host-end of the
+ * protocol, and is used by the host to ensure that messages are
+ * routed to the correct handler program/veneer.
+ *
+ * The reason there are two target specified "OSinfo" words is because
+ * thread identifiers may not be unique when processes/tasks have
+ * private virtual address spaces. It allows more flexibility when
+ * supporting multi-threaded or O/S aware debugging.
+ *
+ * NOTE: The reason that there is no "size" information, is that the
+ * message IDs themselves encode the format of any arguments. Also it
+ * would be a duplication of information used by the physical
+ * transport layer (which is distinct from this logical message
+ * layer). Any routing of messages through programs, hosts,
+ * etc. should be performed at the physical layer, or the boundaries
+ * between physical layers. i.e. packet received on socket in host,
+ * and transferred to serial packet for passing on down the line.
+ *
+ * NOTE: Pointers aren't passed in messages because they are dangerous in
+ * a multi-threaded environment.
+ *
+ * ADP REASON CODE
+ * ---------------
+ * The message reason codes contain some information that ties them to
+ * the channel and direction that the message will be used with. This
+ * will ensure that even if the message "#define name" is not
+ * completely descriptive, the message reason code is.
+ *
+ * b31 = direction. 0=Host-to-Target; 1=Target-to-Host;
+ * b30-28 = debug agent multi-threaded control (see below)
+ * b27-24 = reserved. should be zero.
+ * b23-16 = channelid. The fixed Angel channel number
+ * (see "channels.h").
+ * b15-0 = message reason code.
+ *
+ * It is unfortunate that to aid the error-checking capabilities of
+ * the Angel communications we have changed the message numbers from
+ * the original ARM Ltd RDP. However this also has benefits, in that
+ * the Angel work is meant to be a clean break.
+ *
+ * However, it isn't so bad since even though the numbers are
+ * different, the majority of the reason codes have exactly the same
+ * functionality as the original RDP messages.
+ *
+ * NOTES
+ * -----
+ * It would be ideal to use "rpcgen" (or some equivalent) to
+ * automatically maintain compatibility between the target and host
+ * ends of the protocol. However, ARM Ltd expressed that the message
+ * handling should be hand-coded, to avoid dependance on external
+ * tools.
+ *
+ * All other channels have undefined data formats and are purely
+ * application defined. The C library "_sys_" support will provide a
+ * veneer to perform message block operations as required.
+ *
+ * It is IMPLIED that all of the ADP messages will fit within the
+ * buffer DATASIZE. This has a minimum value, calculated from
+ * BUFFERMINSIZE.
+ *
+ * All messages are passed and received to the channel system in little
+ * endian order (ie. use little endian order when writing a word as
+ * a sequence of bytes within a message).
+ *
+ * A reply / acknowledgement to an ADP message is always sent and has the
+ * same reason code as the original except that the TtoH / HtoT bit is
+ * reversed. This makes it simple to check that the reply really
+ * is a reply to the message which was just sent! [Boot Channel messages
+ * also require that this protocol is used].
+ */
+
+#ifndef angel_adp_h
+#define angel_adp_h
+
+#include "chandefs.h"
+
+
+/*
+ * Buffer minimum sizes
+ */
+
+/* the minimum target internal size */
+#define ADP_BUFFER_MIN_SIZE (256)
+
+/* a word is always reserved for internal use in the target */
+#define ADP_BUFFER_MAX_INTERNAL (sizeof(word))
+
+/* the minimum available data portion */
+#define ADP_BUFFER_MIN_DATASIZE \
+ (ADP_BUFFER_MIN_SIZE - ADP_BUFFER_MAX_INTERNAL - CHAN_HEADER_SIZE)
+
+/*
+ * the space taken up by the standard ADP header
+ * (reason, debugID, OSinfo1, OSinfo2)
+ */
+#define ADP_DEFAULT_HEADER_SIZE (4*sizeof(word))
+
+
+/* 8bit ADP version identification */
+#define ADPVSN (0x03)
+/* This value can be used to identify the protocol version supported
+ * by target or host systems. This version number should only be
+ * changed if the protocol undergoes a non-backward compatible
+ * change. It should *NOT* be used to reflect extensions to the
+ * protocol. Such extensions can be added to the existing protocol
+ * version by allocating new reason codes, and by extending the
+ * ADP_Info message to identify new features.
+ */
+
+/* The following value is used in the OSinfo fields for
+ * single-threaded messages, or where the host wants to alter the
+ * global CPU state. NOTE: The "debugID" field should always be
+ * defined by the host, and returned in target initiated messages. The
+ * only exception to this rule is the ADP_Booted message at the
+ * start-of-day.
+ */
+#define ADP_HandleUnknown (-1)
+
+/******************************************************************
+ *
+ * ADP reason code subfields
+ *
+ */
+
+/* The following bits are used to describe the basic direction of
+ * messages. This allows some extra checking of message validity to be
+ * performed, as well as providing a description of the message that
+ * may not be available in the "cpp" macro:
+ */
+#define HtoT ((unsigned)0 << 31) /* Host-to-Target message */
+#define TtoH ((unsigned)1 << 31) /* Target-to-Host message */
+
+/* The following bits are used to control how the target system
+ * executes whilst processing messages. This allows for O/S specific
+ * host-based debug programs to interrogate system structures whilst
+ * ensuring that the access is atomic within the constraints imposed
+ * by the target O/S.
+ *
+ * NOTE: That only the channel is inserted into the reason code
+ * automatically. Thus both direction and multi thread control bits
+ * must be added by the host / target.
+ */
+/* Disable FIQ whilst processing message */
+#define DisableFIQ (1 << 30)
+/* Disable IRQ whilst processing message */
+#define DisableIRQ (1 << 29)
+/* Disable O/S pre-emption whilst processing message */
+#define DisablePreemption (1 << 28)
+
+/* The channel identification number is held in the reason code as a
+ * check:
+ */
+#define ADPCHANNEL(b) (((b) & 0xFF) << 16)
+
+/* The following macro constructs the reason code number, from the
+ * various fields - note that the direction is NOT inlcuded since
+ * this depends on whether the Host or Target system is including
+ * this file!
+ */
+#define ADPREASON(c,r) (ADPCHANNEL(c) | ((r) & 0xFFFF))
+
+/* This macros is used when constructing manifests for sub-reason
+ * codes. At the moment it is identical to the main reason macro. If
+ * desired we could add a new bit that explicitly identifies the value
+ * as a sub-reason code, where the corresponding bit in the main
+ * message ID would be zero.
+ */
+#define ADPSUBREASON(c,r) (ADPCHANNEL(c) | ((r) & 0xFFFF))
+
+/* All other undefined bits are reserved, and should be zero. */
+
+
+
+/*****************************************************************
+ *
+ * channel_BOOT messages
+ *
+ */
+
+/* The BOOT agent only supports a few messages. They are used purely
+ * to control the "start-of-day" connection to a host program. All
+ * Angel systems with host communications *MUST* provide the BOOT
+ * agent, even if they don't have support for either the single- or
+ * multi-threaded debug agents.
+ *
+ * The way the BOOT channel will be used on startup will be as follows:
+ *
+ * a) Target board is powered up before host debugger is invoked
+ *
+ * After switching on the target and initialisation is completed the
+ * target will send an ADP_Booted or ADP_Reset message. The debugger
+ * has not been started yet so this message will not be received. In
+ * a serial world this makes it important that any buffers on the host
+ * side are flushed during initialisation of the debugger, and in an
+ * Ethernet world it makes it important that the target can cope with the
+ * message not being received.
+ *
+ * Eventually the Debugger will be started up and will send an
+ * ADP_Reboot or ADP_Reset request. The target will respond to this with
+ * an ADP_Reboot or ADP_Reset acknowldege and will then reboot, finally
+ * sending an ADP_Rebooted when it has done all it needs to do (very little
+ * in the case of ADP_Reset, but completely rebooting in the case of
+ * ADP_Reboot). Note that it is important that an ADP_Rebooted message is
+ * sent so that the Debugger does not attempt to send any data after it has
+ * made a request to ADP_Reboot and before it receives an ADP_Rebooted, as
+ * data can be lost be the target during this time.
+ *
+ * The target and host are now ready to start a debug session.
+ *
+ * b) Target board is powered up after host debugger is invoked
+ *
+ * The debugger will send an ADP_Reboot or ADP_Reset request, but will
+ * receive no reply until the target is powered up.
+/ *
+ * When the target is powered up then it will send an ADP_Rebooted
+ * message to the debugger. The debugger should accept this message
+ * even though it has received no ADP_Reboot or ADP_Reset acknowldege message
+ * from the target.
+ *
+ * The target and host are now ready to start a debug session.
+ *
+ *
+ * If at any point during the bootup sequence and ADP messages are
+ * sent down the S_DBG channel then they should be responded to with a
+ * RDI_NotInitialised error. [This should never happen however].
+ *
+ * An ADP_Boot or ADP Rebooted message should be accepted at
+ * any point, since it is possible for a catastrophe to occur (such as
+ * disconnecteing the host and target during a debug message) which
+ * requires that one or other end be reset.
+ *
+ */
+
+/*
+ * A list of parameter types - for now just baud rate
+ */
+typedef enum ADP_Parameter {
+ AP_PARAMS_START = 0xC000,
+ AP_BAUD_RATE = AP_PARAMS_START,
+ /* extra parameters go in here */
+#ifdef TEST_PARAMS
+ AP_CAFE_MENU, /* extra just for testing */
+#endif
+ AP_PARAMS_END
+} ADP_Parameter;
+
+#define AP_NUM_PARAMS (AP_PARAMS_END - AP_PARAMS_START)
+
+/*
+ * Parameter types should have associated semantics which can be represented
+ * within one word per parameter, or an associated enum for choices.
+ *
+ * AP_BAUD_RATE: the word contains the exact baud rate, eg. 9600, 38400.
+ */
+
+/* this is not strictly necessary, but it's an example */
+typedef enum ADP_BaudRate {
+ AB_9600 = 9600,
+ AB_19200 = 19200,
+ AB_38400 = 38400,
+ AB_57600 = 57600,
+ AB_115200 = 115200
+} ADP_BaudRate;
+
+#define AB_NUM_BAUD_RATES 5 /* this is more useful, for sizing arrays */
+
+/* This must be set to the max number of options per parameter type */
+#define AP_MAX_OPTIONS (AB_NUM_BAUD_RATES)
+
+
+#define ADP_Booted ADPREASON(CI_TBOOT,0)
+/* This message is sent by the target after the Angel system has been
+ * initialised. This message also contains information describing the
+ * Angel world. The information can then be used to check that the
+ * target debug agent and source debugger are compatible.
+ *
+ * Message arguments:
+ * word Angel message default buffer size.
+ * word Angel message large buffer size (may be same as default)
+ * word Angel version ; inc. type (e.g. boot ROM) See (1)
+ * word ADP version. See (2)
+ * word ARM Architecture info See (3)
+ * word ARM CPU information ; including target endianness. See (4)
+ * word Target hardware status. See (5)
+ * word Number of bytes in banner message
+ * bytes Startup banner message (single-threaded readable
+ * descriptive text - NOT NULL terminated).
+ *
+ * Reply:
+ * word status
+ *
+ * 'status' returns RDIError_NoError for success, and otherwise
+ * indicates an error.
+ */
+
+/* Angel version word [Reference(1)] : */
+/* Angel version number is a 16bit BCD value */
+#define ADP_ANGELVSN_MASK (0x0000FFFF)
+#define ADP_ANGELVSN_SHIFT (0)
+
+/* Type of Angel system */
+#define ADP_ANGELVSN_TYPE_MASK (0x00FF0000)
+#define ADP_ANGELVSN_TYPE_SHIFT (16)
+
+typedef enum {
+ ADP_AngelType_bootROM, /* Simple ROM system providing download capability */
+ ADP_AngelType_appROM, /* ROM based application */
+ ADP_AngelType_appDLOAD,/* Downloaded Angel based application */
+ ADP_AngelType_Last /* Unknown type. This typedef can be extended */
+ /* but if the host and target vsns differ */
+ /* Then one will spot that it dies not understand */
+} ADP_Angel_Types ; /* this field and can whinge appropriately */
+
+/* First unknown ADP_AngelType */
+#define ADP_ANGELVSN_UNKTYPE_MASK (0xFF000000)
+#define ADP_ANGELVSN_UNKYPE_SHIFT (24)
+
+/* Currently only 8 bits are used in the word: */
+/* ADP protocol supported by target [Reference (2)] */
+#define ADP_ANGELVSN_ADP_MASK (0x000000FF)
+#define ADP_ANGELVSN_ADP_SHIFT (0)
+
+/* ARM Architecture info: [Reference (3)] */
+/* ARM Architecture Verson of target CPU */
+#define ADP_ARM_ARCH_VSN_MASK (0x000000FF)
+#define ADP_ARM_ARCH_VSN_SHIFT (0)
+/* Does the processor support the Thumb Instruction Set */
+#define ADP_ARM_ARCH_THUMB (0x80000000)
+/* Does the processor support Long Multiplies */
+#define ADP_ARM_ARCH_LONGMUL (0x40000000)
+/* All other flags are current undefined, and should be zero. */
+
+/* The following flags describe the feature set of the processor: */
+/* Set if cpu supports little-endian model [Reference (4)] */
+#define ADP_CPU_LE (1 << 0)
+/* Set if cpu supports big-endian model */
+#define ADP_CPU_BE (1 << 1)
+/* Set if processor has a cache */
+#define ADP_CPU_CACHE (1 << 2)
+/* Set if processor has a MMU */
+#define ADP_CPU_MMU (1 << 3)
+/* All other flags are current undefined, and should be zero. */
+
+/* The following flags reflect current Target hardware status: */
+/* [Reference (5)] */
+/* 0 = no MMU or MMU off; 1 = MMU on */
+#define ADP_CPU_MMUOn (1 << 29)
+/* 0 = no cache or cache off; 1 = cache on */
+#define ADP_CPU_CacheOn (1 << 30)
+/* 0 = little-endian; 1 = big-endian */
+#define ADP_CPU_BigEndian (1U << 31)
+/* All other flags are current undefined, and should be zero. */
+
+
+#ifdef LINK_RECOVERY
+
+#define ADP_TargetResetIndication ADPREASON(CI_TBOOT, 1)
+/*
+ * If parameter negotiation is enabled at the target, it configures itself
+ * to various likely parameter settings and sends this message at each
+ * configuration. The message describes the default settings, and after
+ * sending at each configuration the target sets itself to the defaults
+ * it has just broadcast, to await either an ack on TBOOT or a request
+ * or reset indication on HBOOT.
+ *
+ * If the host receives this message successfully, it should reset to the
+ * indicated parameters and send a reply.
+ *
+ * Message arguments:
+ * word status (always 0, makes body same as
+ * ADP_ParamNegotiate response)
+ * word n-parameters
+ * n-parameters * {
+ * word ADP_Parameter
+ * word parameter-value
+ * }
+ *
+ * Reply:
+ * - empty acknowledgement
+ */
+
+#endif /* def LINK_RECOVERY */
+
+typedef enum ADP_Boot_Ack {
+ AB_NORMAL_ACK, /* will comply, immediate booted message */
+ AB_LATE_ACK, /* will comply, late startup */
+ AB_ERROR /* cannot comply */
+} ADP_Boot_Ack;
+
+/* If the host sets neither of these in the word sent on a Reset / Reboot
+ * then it doesn;t care about the endianess of the target
+ */
+#define ADP_BootHostFeature_LittleEnd 0x80000000
+#define ADP_BootHostFeature_BigEnd 0x40000000
+
+#define ADP_Reboot ADPREASON(CI_HBOOT,2)
+/* This message is sent when the host wants the target system to be
+ * completely reset, back to the boot monitor Angel. This is the
+ * method of the host forcing a cold-reboot.
+ * Note that an acknowledgement message will be sent immediately and
+ * that this must be sent before the target can reset.
+ *
+ * The parameter to this function is a bitset of host supported
+ * features. (in fact the same as ADP_Reset below. This can be used by
+ * the target system to avoid using debug channel bandwidth raising
+ * messages that will be ignored by the host.
+ *
+ * Parameters:
+ * word host supported features (see above)
+ *
+ * Reply:
+ * word status, one of enum ADP_Boot_Ack above.
+ *
+ * Currently there are no such features defined, so the word indicating
+ * host supported features should be set to 0.
+ */
+
+
+
+#define ADP_Reset ADPREASON(CI_HBOOT,3)
+/* This message is a request from the host, which should eventually
+ * result in the "ADP_Booted" message being sent by the target.
+ * Note that an acknowledgement message will be sent immediately and
+ * that this must be sent before the target can reset.
+ * This reset message is *ALWAYS* treated as a warm boot, with the target
+ * preserving as much state as possible.
+ *
+ * The parameter to this function is a bitset of host supported
+ * features. This can be used by the target system to avoid using
+ * debug channel bandwitdth raising messages that will be ignored by
+ * the host.
+ *
+ * Parameters:
+ * word host supported features (see above)
+ *
+ * Reply:
+ * word status, one of enum ADP_Boot_Ack above.
+ *
+ * Currently there are no such features defined, so the word indicating
+ * host supported features should be set to 0.
+ */
+
+
+#ifdef LINK_RECOVERY
+
+#define ADP_HostResetIndication ADPREASON(CI_HBOOT, 4)
+/*
+ * This is as for ADP_TargetResetIndication, but is sent by the host when
+ * it first starts up in case the target is listening at a non-default
+ * setting. Having sent at various configurations, the host then listens
+ * at the defaults it has just broadcast, to await either an ack on HBOOT
+ * or a reset indication on TBOOT.
+ *
+ * For arguments and reply, see ADP_TargetResetIndication.
+ */
+
+#endif /* def LINK_RECOVERY */
+
+
+#define ADP_ParamNegotiate ADPREASON(CI_HBOOT, 5)
+/*
+ * The host sends this messages to negotiate new parameters with the target.
+ * For each parameter the host specifies a range of possibilities, starting
+ * with the most favoured. All possible combinations of parameters
+ * must be valid.
+ *
+ * If the target can operate at a combination of the offered parameters,
+ * it will reply with the parameters it is willing to use. AFTER sending
+ * the reply, the target switches to this combination. On receiving the
+ * reply, the host will switch to the new combination and send a LinkCheck
+ * message (see below).
+ *
+ * If the target cannot operate at any combination of the offered parameters,
+ * it will reply with an error status.
+ *
+ * Message arguments:
+ * word n-parameter-blocks
+ * n-parameter-blocks * {
+ * word ADP_Parameter
+ * word n-options
+ * n-options * { word parameter-value }
+ * }
+ *
+ * Reply:
+ * word status
+ * if (status == RDIError_NoError) {
+ * word n-parameters
+ * n-parameters * {
+ * word ADP_Parameter
+ * word chosen-value
+ * }
+ * }
+ */
+
+#define ADP_LinkCheck ADPREASON(CI_HBOOT, 6)
+/*
+ * This should be the first message that the host sends after a successful
+ * parameter negotiation. It is really just a 'ping'.
+ *
+ * Message arguments:
+ * - empty message
+ *
+ * Reply:
+ * - empty acknowledgement
+ */
+
+
+/********************************************************************
+ *
+ * CI_HADP messages
+ *
+ */
+
+#define ADP_HADPUnrecognised ADPREASON(CI_HADP,0)
+/* This message is unusual in that it is normally sent in reply to
+ * another message which is not understood. This is an exception
+ * to the normal protocol which says that a reply must have the
+ * same base reason code as the original. There is a single reply
+ * parameter which is the reason code which was not understood.
+ *
+ * As well as being a reply this message can also be sent and will
+ * return as if this message were unrecognised!
+ *
+ * Parameters:
+ * none
+ *
+ * Reply:
+ * word reason code which was not recognised
+ */
+
+
+#define ADP_Info ADPREASON(CI_HADP,1)
+/* This is the new ADP information message. It is used to interrogate
+ * the target debug agent. It provides information on the processor,
+ * as well as the state of the debug world. This allows the host to
+ * configure itself to the capabilities of the target.
+ *
+ * We try not to use feature bitsets, since we could quickly run out
+ * of known bits. Thus when the feature set is extended, this can be
+ * done in a couple of supported ways:
+ *
+ * If an undivided reason code is to be added (no reason subcodes)
+ * then add a new ADP_Info code which responds with a flag indicating
+ * whether that feature is supported by the target. If this has not
+ * even been implemented then the reply will be ADP_HADPUnrecognised
+ *
+ * If a reason code which is subdivided into reason subcodes is
+ * added then reason subcode 0 should be set aside to indicate
+ * whether the functionality of that reason code is supported
+ * by the target. If it is not even implemented then the reply will
+ * be ADP_Unrecognised.
+ *
+ * The first parameter to ADP_Info is a reason subcode, and subsequent
+ * parameters are defined by that subcode
+ *
+ * Parameters:
+ * word reason subcode
+ * other arguments as reason subcode determines.
+ *
+ * Reply:
+ * word reason subcode
+ * other argument as reason subcode determines
+ */
+
+/* ADP_Info reason subcodes: */
+
+
+
+#define ADP_Info_NOP ADPSUBREASON(CI_HADP,0)
+/* ADP_Info_NOP
+ * ------------
+ * Summary: This message is used to check for ADP_Info being supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError for success, non-zero indicates an error.
+ * If an error is returned then there is no handler for the ADP_Info
+ * message. The normal action will be to return an OK status.
+ */
+
+
+#define ADP_Info_Target ADPSUBREASON(CI_HADP,1)
+/* ADP_Info_Target
+ * ---------------
+ * Summary:
+ * This reason code is used to interrogate target system details.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word bitset, word model)
+ *
+ * 'status' is RDIError_NoError to indicate OK, or non-zero to indicate
+ * some sort of error.
+ * 'bitset' is described in more detail below, and is mostly compatible
+ * with the old RDI/RDP system to avoid gratuitous changes to the debugger
+ * toolbox.
+ * 'model' is the target hardware ID word, as returned by the ADP_Booted
+ * message.
+ *
+ * NOTE: The minimum and maximum protocol levels are no longer supported.
+ * It is the Angel view that debugging complexity should be shifted to the
+ * host if at all possible. This means that the host debugger should
+ * always try to configure itself to the features available in the target
+ * debug agent. This can be done by checking individual messages, rather
+ * than by a blanket version number dictating the feature set.
+ */
+
+/* 'bitset':- */
+/* Target speed in instructions per second = 10**(bits0..3). */
+#define ADP_Info_Target_LogSpeedMask (0xF)
+
+/* Target is running on [0 = emulator / 1 = hardware] */
+#define ADP_Info_Target_HW (1 << 4)
+
+/* Bits 5..10 are currently undefined and should be zero. */
+/* Other bis are kept the same as the RDP in order to */
+/* eliminate the need to change the position of some bits */
+
+/* If set then the debug agent can be reloaded. */
+#define ADP_Info_Target_CanReloadAgent (1 << 11)
+
+/* Can request AngelBufferSize information. */
+#define ADP_Info_Target_CanInquireBufferSize (1 << 12)
+
+/* Bit 13 is no longer required as it inquired whether
+ * a special RDP Interrupt code was supported
+ */
+
+/* Debug agent can perform profiling. */
+#define ADP_Info_Target_Profiling (1 << 14)
+
+/* Debug agent can support Thumb code. */
+#define ADP_Info_Target_Thumb (1 << 15)
+
+/* Bit 16 was the communications channel check.
+ * This is always available on Angel systems.
+ */
+
+#define ADP_Info_Points ADPSUBREASON(CI_HADP,2)
+/* ADP_Info_Points
+ * ---------------
+ * Summary: Returns a 32bit wide bitset of break- and watch-point
+ * features supported by the target debug agent.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word breakinfo)
+ *
+ * 'status' returns RDIError_NoError on success or non-zero to indicate
+ * some sort of error.
+ * 'breakinfo' is a 32bit wide bitset described in detail below. Note
+ * that only bits 1..12 are used.
+ */
+
+/* 'breakinfo':- */
+/* Can trap on address equality. */
+#define ADP_Info_Points_Comparison (1 << 0)
+
+/* Can trap on address range. */
+#define ADP_Info_Points_Range (1 << 1)
+
+/* Can trap on 8bit memory reads. */
+#define ADP_Info_Points_ReadByteWatch (1 << 2)
+
+/* Can trap on 16bit memory reads. */
+#define ADP_Info_Points_ReadHalfWatch (1 << 3)
+
+/* Can trap on 32bit memory reads. */
+#define ADP_Info_Points_ReadWordWatch (1 << 4)
+
+/* Can trap on 8bit write accesses. */
+#define ADP_Info_Points_WriteByteWatch (1 << 5)
+
+/* Can trap on 16bit write accesses. */
+#define ADP_Info_Points_WriteHalfWatch (1 << 6)
+
+/* Can trap on 32bit write accesses. */
+#define ADP_Info_Points_WriteWordWatch (1 << 7)
+
+/* Like range, but based on address bitmask<. */
+#define ADP_Info_Points_Mask (1 << 8)
+
+/* Multi-threaded support only - thread specific breakpoints. */
+#define ADP_Info_Points_ThreadBreak (1 << 9)
+
+/* Multi-threaded support only - thread specific watchpoints. */
+#define ADP_Info_Points_ThreadWatch (1 << 10)
+
+/* Allows conditional breakpoints. */
+#define ADP_Info_Points_Conditionals (1 << 11)
+
+/* Break- and watch-points can be interrogated */
+#define ADP_Info_Points_Status (1 << 12)
+
+
+#define ADP_Info_Step ADPSUBREASON(CI_HADP,3)
+/* ADP_Info_Step
+ * -------------
+ * Summary: Returns a 32bit wide bitmask of the single-stepping
+ * capabilities of the target debug agent.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word stepinfo)
+ *
+ * 'status' returns RDIError_NoError on success, or non-zero to indicate
+ * some kind of error.
+ * 'stepinfo' is a 32bit wide bitmask described in detail below. Note that
+ * only 3 bits are used.
+ */
+
+/* 'stepinfo':- */
+/* Single-stepping of more than one instruction is possible. */
+#define ADP_Info_Step_Multiple (1 << 0)
+
+/* Single-stepping until next direct PC change is possible. */
+#define ADP_Info_Step_PCChange (1 << 1)
+
+/* Single-stepping of a single instruction is possible. */
+#define ADP_Info_Step_Single (1 << 2)
+
+
+#define ADP_Info_MMU ADPSUBREASON(CI_HADP,4)
+/* ADP_Info_MMU
+ * ------------
+ * Summary: Returns information about the memory management system (if
+ * any).
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word meminfo)
+ *
+ * 'status' returns RDIError_NoError to indicate success or non-zero to
+ * indicate some kind of error.
+ * 'meminfo' should be a 32bit unique ID, or zero if there is no MMU
+ * support on the target.
+ */
+
+
+#define ADP_Info_SemiHosting ADPSUBREASON(CI_HADP,5)
+/* ADP_Info_SemiHosting
+ * --------------------
+ * Summary: This message is used to check whether semi-hosting info calls
+ * are available on the target.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError if semi-hosting info calls are available,
+ * non-zero otherwise.
+ */
+
+
+#define ADP_Info_CoPro ADPSUBREASON(CI_HADP,6)
+/* ADP_Info_CoPro
+ * --------------
+ * Summary: This message checks whether CoProcessor info calls are
+ * supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError to indicate these facilities
+ * are supported, non-zero otherwise.
+ */
+
+
+#define ADP_Info_Cycles ADPSUBREASON(CI_HADP,7)
+/* ADP_Info_Cycles
+ * ---------------
+ * Summary: Returns the number of instructions and cycles executed since
+ * the target was initialised.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ninstr, word Scycles, word Ncycles,
+ * word Icycles, word Ccycles, word Fcycles)
+ *
+ * 'status' is RDIError_NoError to indicate success, or non-zero if there
+ * is no target support for gathering cycle count information.
+ * 'ninstr' is the number of instructions executed.
+ * 'Scycles' is the number of S-cycles executed.
+ * 'Ncycles' is the number of N-cycles executed.
+ * 'Icycles' is the number of I-cycles executed.
+ * 'Ccycles' is the number of C-cycles executed.
+ * 'Fcycles' is the number of F-cycles executed.
+ */
+
+
+#define ADP_Info_DescribeCoPro ADPSUBREASON(CI_HADP,8)
+/* ADP_Info_DescribeCoPro
+ * ----------------------
+ * Summary: Describe the registers of a coprocessor. Use only if
+ * ADP_Info_CoPro return RDIError_NoError.
+ *
+ * Arguments:
+ * Send: Arguments of the form:
+ * (byte cpno, byte rmin, byte rmax, byte nbytes, byte access,
+ * byte cprt_r_b0, byte cprt_r_b1, byte cprt_w_b0, byte cprt_w_b1)
+ * And a terminating byte = 0xff. Must be within maximum buffer size.
+ * Return: (word status)
+ *
+ * 'cpno' is the number of the coprocessor to be described.
+ * 'rmin' is the bottom of a range of registers with the same description.
+ * 'rmax' is the top of a range of registers with the same description.
+ * 'nbytes' is the size of the register.
+ * 'access' describes access to the register and is described in more detail
+ * below.
+ *
+ * If bit 2 of access is set:-
+ * 'cprt_r0' provides bits 0 to 7, and
+ * 'cprt_r1' provides bits 16 to 23 of a CPRT instruction to read the
+ * register.
+ * 'cprt_w0' provides bits 0 to 7, and
+ * 'cprt_w1' provides bits 16 to 23 of a CPRT instruction to write the
+ * register.
+ *
+ * Otherwise, 'cprt_r0' provides bits 12 to 15, and 'cprt_r1' bit 22 of CPDT
+ * instructions to read and write the register ('cprt_w0' and 'cprt_w1' are
+ * junk).
+ */
+
+/* 'access':- */
+/* Readable. */
+#define ADP_Info_DescribeCoPro_Readable (1 << 0)
+
+/* Writeable. */
+#define ADP_Info_DescribeCoPro_Writeable (1 << 1)
+
+/* Registers read or written via CPDT instructions (else CPRT) with this
+ bit set. */
+#define ADP_Info_DescribeCoPro_CPDT (1 << 2)
+
+#define ADP_Info_RequestCoProDesc ADPSUBREASON(CI_HADP,9)
+/* ADP_Info_RequestCoProDesc
+ * -------------------------
+ * Summary: Requests a description of the registers of a coprocessor. Use
+ * only if ADP_Info_CoPro return RDIError_NoError.
+ *
+ * Arguments:
+ * Send: (byte cpno)
+ * Return: Arguments of the form:-
+ * (word status, byte rmin, byte rmax, byte nbytes, byte access)
+ * Followed by a terminating byte = 0xFF. Must be within maximum
+ * buffer size.
+ * 'cpno' is the number of the coprocessor to describe.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'rmin' is the bottom of a range of registers with the same description.
+ * 'rmax' is the top of a range of registers with the same description.
+ * 'nbytes' is the size in bytes of the register(s).
+ * 'access' is as above in ADP_Info_DescribeCoPro.
+ */
+
+
+#define ADP_Info_AngelBufferSize ADPSUBREASON(CI_HADP,10)
+/* ADP_Info_AngelBufferSize
+ * ------------------------
+ * Summary: Returns the Angel buffer sizes.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word defaultsize, word maxsize)
+ *
+ * 'status' returns RDIError_NoError to indicate success or non-zero to
+ * indicate some kind of error.
+ * 'defaultsize' is the default Angel ADP buffer size in bytes. This is
+ * at least 256 bytes.
+ * 'maxsize' is the largest Angel ADP buffer size in bytes. This will be
+ * greater than or equal to defaultsize. The target will accept ADP messages
+ * of up to this length for download, etc.
+ *
+ * Was DownLoadSize in RDP/RDI world. This is the amount that the target
+ * should transmit in a single operation. This should now be the Angel
+ * buffer size. This information is also given in the ADP_Booted message.
+ *
+ * NOTE: The value returned should be the DATASIZE and *NOT* BUFFERDEFSIZE.
+ * This is needed to ensure that the transport protocol information
+ * can be wrapped around the data.
+ */
+
+#define ADP_Info_ChangeableSHSWI ADPSUBREASON(CI_HADP,11)
+/* ADP_Info_ChangeableSHSWI
+ * ------------------------
+ * Summary: This message is used to check whether it is possible to change
+ * which SWI's are used for semihosting.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError if semi-hosting info calls are available,
+ * non-zero otherwise.
+ */
+
+#define ADP_Info_CanTargetExecute ADPSUBREASON(CI_HADP,12)
+/* ADP_Info_CanTargetExecute
+ * -------------------------
+ * Summary: This message is used to see if the target is currently in
+ * an executable state. Typically this is called after the debugger
+ * initialises. If a non-error statis is returned then the user is
+ * allowed to 'go' immediately.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' returns RDIError_NoError if target is ready to execute.
+ * other values indicate why it cannot execute.
+ */
+
+#define ADP_Info_AgentEndianess ADPSUBREASON(CI_HADP,13)
+/* ADP_Info_AgentEndianess
+ * -------------------------
+ * Summary: This message is used to determine the endianess of the
+ * debug agent
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * status should be RDIError_LittleEndian or RDIError_BigEndian
+ * any other value indicates the target does not support this
+ * request, so the debugger will have to make a best guess, which
+ * probably means only allow little endian loadagenting.
+ */
+
+
+#define ADP_Control ADPREASON(CI_HADP,2)
+/* This message allows for the state of the debug agent to be
+ * manipulated by the host.
+ */
+
+/* The following are sub reason codes to ADP control, the first parameter
+ * is the sub reason code which defines the format of subsequent parameters.
+ *
+ * word sub reason code
+ */
+
+#define ADP_Ctrl_NOP ADPSUBREASON(CI_HADP,0)
+/* ADP_Ctrl_NOP
+ * ------------
+ * Summary: This message is used to check that ADP_Ctrl messages are
+ * supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate ADP_Ctrl messages are
+ * supported, non-zero otherwise.
+ */
+
+#define ADP_Ctrl_VectorCatch ADPSUBREASON(CI_HADP,1)
+/* ADP_Ctrl_VectorCatch
+ * --------------------
+ * Summary: Specifies which hardware exceptions should be reported to the
+ * debugger.
+ *
+ * Arguments:
+ * Send: (word bitmap)
+ * Return: (word status)
+ *
+ * 'bitmap' is a bit-mask of exceptions to be reported, described in more
+ * detail below. A set bit indicates that the exception should be
+ * reported to the debugger, a clear bit indicates that the corresponding
+ * exception vector should be taken.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+/* 'bitmap':- */
+/* Reset(branch through zero). */
+#define ADP_Ctrl_VectorCatch_BranchThroughZero (1 << 0)
+
+/* Undefined Instruction. */
+#define ADP_Ctrl_VectorCatch_UndefinedInstr (1 << 1)
+
+/* Software Interrupt. */
+#define ADP_Ctrl_VectorCatch_SWI (1 << 2)
+
+/* Prefetch Abort. */
+#define ADP_Ctrl_VectorCatch_PrefetchAbort (1 << 3)
+
+/* Data Abort. */
+#define ADP_Ctrl_VectorCatch_DataAbort (1 << 4)
+
+/* Address Exception. */
+#define ADP_Ctrl_VectorCatch_AddressException (1 << 5)
+
+/* Interrupt Request. */
+#define ADP_Ctrl_VectorCatch_IRQ (1 << 6)
+
+/* Fast Interrupt Request. */
+#define ADP_Ctrl_VectorCatch_FIQ (1 << 7)
+
+/* Error. */
+#define ADP_Ctrl_VectorCatch_Error (1 << 8)
+
+
+#define ADP_Ctrl_PointStatus_Watch ADPSUBREASON(CI_HADP,2)
+/* ADP_Ctrl_PointStatus_Watch
+ * --------------------------
+ * Summary: Returns the hardware resource number and the type of that
+ * resource when given a watchpoint handle. Should only be called if
+ * the value returned by ADP_Info_Points had ADP_Info_Points_Status set.
+ *
+ * Arguments:
+ * Send: (word handle)
+ * Return: (word status, word hwresource, word type)
+ *
+ * 'handle' is a handle to a watchpoint.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'hwresource' is the hardware resource number. !!!!!
+ * 'type' is the type of the resource.
+ */
+
+
+#define ADP_Ctrl_PointStatus_Break ADPSUBREASON(CI_HADP,3)
+/* ADP_Ctrl_PointStatus_Break
+ * --------------------------
+ * Summary: Returns the hardware resource number and the type of that
+ * resource when given a breakpoint handle. Should only be called if
+ * the value returned by ADP_Info_Points had ADP_Info_Points_Status set.
+ *
+ * Arguments:
+ * Send: (word handle)
+ * Return: (word status, word hwresource, word type)
+ *
+ * 'handle' is a handle to a breakpoint.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'hwresource' is the hardware resource number.
+ * 'type' is the type of the resource.
+ */
+
+#define ADP_Ctrl_SemiHosting_SetState ADPSUBREASON(CI_HADP,4)
+/* ADP_Ctrl_SemiHosting_SetState
+ * -----------------------------
+ * Summary: Sets whether or not semi-hosting is enabled.
+ *
+ * Arguments:
+ * Send: (word semihostingstate)
+ * Return: (word status)
+ *
+ * 'semihostingstate' sets semi-hosting to enabled if zero, otherwise
+ * it disables semi-hosting.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetState ADPSUBREASON(CI_HADP,5)
+/* ADP_Ctrl_SemiHosting_GetState
+ * -----------------------------
+ * Summary: Reads whether or not semi-hosting is enabled.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word semihostingstate)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'semihostingstate' is zero if semi-hosting is enabled, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_SetVector ADPSUBREASON(CI_HADP,6)
+/* ADP_Ctrl_SemiHosting_SetVector
+ * ------------------------------
+ * Summary: Sets the semi-hosting vector.
+ *
+ * Arguments:
+ * Send: (word semihostingvector)
+ * Return: (word status)
+ *
+ * 'semihostingvector' holds the value the vector is to be set to.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetVector ADPSUBREASON(CI_HADP,7)
+/* ADP_Ctrl_SemiHosting_GetVector
+ * ------------------------------
+ * Summary: Gets the value of the semi-hosting vector.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word semihostingvector)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'semihostingvector' holds the value of the vector.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_Log ADPSUBREASON(CI_HADP,8)
+/* ADP_Ctrl_Log
+ * ------------
+ * Summary: Returns the logging state.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word logsetting)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'logsetting' is a bitmap specifying the level of logging desired,
+ * described in more detail below. The bits can be ORed together
+ */
+
+/* 'logsetting':- */
+
+/* No logging. */
+#define ADP_Ctrl_Log_NoLogging (0)
+/* RDI level logging. */
+#define ADP_Ctrl_Log_RDI (1 << 0)
+/* ADP byte level logging. */
+#define ADP_Ctrl_Log_ADP (1 << 1)
+
+
+#define ADP_Ctrl_SetLog ADPSUBREASON(CI_HADP,9)
+/* ADP_Ctrl_SetLog
+ * ---------------
+ * Summary: Sets the logging state.
+ *
+ * Arguments:
+ * Send: (word logsetting)
+ * Return: (word status)
+ *
+ * 'logsetting' is the same as in ADP_Ctrl_Log above.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+#define ADP_Ctrl_SemiHosting_SetARMSWI ADPSUBREASON(CI_HADP,10)
+/* ADP_Ctrl_SemiHosting_SetARMSWI
+ * ------------------------------
+ * Summary: Sets the number of the ARM SWI used for semihosting
+ *
+ * Arguments:
+ * Send: (word ARM_SWI_number)
+ * Return: (word status)
+ *
+ * The debug agent will interpret ARM SWI's with the SWI number specified
+ * as semihosting SWI's.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_ChangeableSHSWI didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetARMSWI ADPSUBREASON(CI_HADP,11)
+/* ADP_Ctrl_SemiHosting_GetARMSWI
+ * ------------------------------
+ * Summary: Reads the number of the ARM SWI used for semihosting
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ARM_SWI_number)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * ARM_SWI_number is the SWI number which is used for semihosting.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+#define ADP_Ctrl_SemiHosting_SetThumbSWI ADPSUBREASON(CI_HADP,12)
+/* ADP_Ctrl_SemiHosting_SetThumbSWI
+ * --------------------------------
+ * Summary: Sets the number of the Thumb SWI used for semihosting
+ *
+ * Arguments:
+ * Send: (word Thumb_SWI_number)
+ * Return: (word status)
+ *
+ * The debug agent will interpret Thumb SWI's with the SWI number specified
+ * as semihosting SWI's.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: This should only be called if ADP_Info_ChangeableSHSWI didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_SemiHosting_GetThumbSWI ADPSUBREASON(CI_HADP,13)
+/* ADP_Ctrl_SemiHosting_GetThumbSWI
+ * --------------------------------
+ * Summary: Reads the number of the Thumb SWI used for semihosting
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ARM_Thumb_number)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * Thumb_SWI_number is the SWI number which is used for semihosting.
+ *
+ * NOTE: This should only be called if ADP_Info_SemiHosting didn't return
+ * an error.
+ */
+
+
+#define ADP_Ctrl_Download_Supported ADPSUBREASON(CI_HADP,14)
+/* ADP_Ctrl_Download_Supported
+ * ---------------------------
+ * Summary: Can configuration be downloaded?
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError if the configuration can be downloaded,
+ * non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIInfo_DownLoad.
+ */
+
+
+#define ADP_Ctrl_Download_Data ADPSUBREASON(CI_HADP,15)
+/* ADP_Ctrl_Download_Data
+ * ----------------------
+ * Summary: Loads configuration data.
+ *
+ * Arguments:
+ * Send: (word nbytes, words data)
+ * Return: (word status)
+ *
+ * 'nbytes' is the number of *bytes* being sent.
+ * 'data' is the configuration data. NOTE: data must not cause the buffer
+ * size to exceed the maximum allowed buffer size.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDP_LoadConfigData. Should only be used if
+ * ADP_ICEM_AddConfig didn't return an error.
+ */
+
+
+#define ADP_Ctrl_Download_Agent ADPSUBREASON(CI_HADP,16)
+/* ADP_Ctrl_Download_Agent
+ * -----------------------
+ * Summary: Prepares Debug Agent to receive configuration data which it
+ * should interpret as a new version of the Debug Agent code.
+ *
+ * Arguments:
+ * Send: (word loadaddress, word size)
+ * Return: (word status)
+ *
+ * 'loadaddress' is the address where the new Debug Agent code should be
+ * loaded.
+ * 'size' is the number of bytes of Debug Agent code to be loaded.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDP_LoadAgent. The data will be downloaded using
+ * ADP_Ctrl_Download_Data. The new agent is started with ADP_Ctrl_Start_Agent
+ */
+
+
+#define ADP_Ctrl_Start_Agent ADPSUBREASON(CI_HADP,17)
+/* ADP_Ctrl_Start_Agent
+ * -----------------------
+ * Summary: Instruct Debug Agent to begin execution of new agent,
+ * which has been downloaded by ADP_Ctrl_Download_Agent.
+ *
+ * Arguments:
+ * Send: (word startaddress)
+ * Return: (word status)
+ *
+ * 'startaddress' is the address where the new Debug Agent code should be
+ * entered, and must satisfy:
+ * (loadaddress <= startaddress <= (loadaddress + size))
+ * where 'loadaddress' and 'size' were specified in the
+ * ADP_Ctrl_Download_Agent message.
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+#define ADP_Ctrl_SetTopMem ADPSUBREASON(CI_HADP,18)
+/* ADP_Ctrl_SetTopMem
+ * ------------------
+ * Summary: Sets the top of memory for ICEman2 systems, so that the C Library
+ * can allocate the stack in the correct place on startup.
+ *
+ * Arguments:
+ * Send: (word mem_top)
+ * Return: (word status)
+ *
+ * This request should only be supported by ICEman2. Standard Angel systems
+ * should return an error (unrecognised is fine).
+ */
+
+
+#define ADP_Read ADPREASON(CI_HADP,3)
+#define ADP_ReadHeaderSize (ADP_DEFAULT_HEADER_SIZE + 2*sizeof(word))
+
+/* ADP_Read
+ * --------
+ * Summary: Request for a transer of memory contents from the target to the
+ * debugger.
+ *
+ * Arguments:
+ * Send: (word address, word nbytes)
+ * Return: (word status, word rnbytes [, bytes data])
+ *
+ * 'address' is the address from which memory transer should start.
+ * 'nbytes' is the number of bytes to transfer.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'rnbytes' holds the number of requested bytes NOT read (i.e. zero
+ * indicates success, non-zero indicates an error).
+ * 'data' is the number of bytes requested minus 'rnbytes'.
+ */
+
+
+
+#define ADP_Write ADPREASON(CI_HADP,4)
+#define ADP_WriteHeaderSize (ADP_DEFAULT_HEADER_SIZE + 2*sizeof(word))
+
+/* ADP_Write
+ * ---------
+ * Summary: Request for a transfer of memory contents from the debugger to
+ * the target.
+ *
+ * Arguments:
+ * Send: (word address, word nbytes, bytes data)
+ * Return: (word status [, word rnbytes])
+ *
+ * 'address' is the address from which memory transer should start.
+ * 'nbytes' is the number of bytes to transfer.
+ * 'data' holds the bytes to be transferred.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'rnbytes' holds the number of requested bytes NOT written (i.e. zero
+ * indicates success, non-zero indicates an error) if status indicated an
+ * error.
+ */
+
+
+
+#define ADP_CPUread ADPREASON(CI_HADP,5)
+/* ADP_CPUread
+ * -----------
+ * Summary: This is a request to read values in the CPU.
+ *
+ * Arguments:
+ * Send: (byte mode, word mask)
+ * Return: (word status, words data)
+ *
+ * 'mode' defines the processor mode from which the transfer should be made.
+ * It is described in more detail below.
+ * 'mask' indicates which registers should be transferred. Setting a bit to
+ * one will cause the designated register to be transferred. The details
+ * of mask are specified below.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'data' holds the values of the registers on successful completion,
+ * otherwise it just holds rubbish. The lowest numbered register is
+ * transferred first. NOTE: data must not cause the buffer size to exceed
+ * the maximum allowed buffer size.
+ */
+
+/* 'mode':- */
+/* The mode number is the same as the mode number used by an ARM; a value of
+ 255 indicates the current mode. */
+#define ADP_CPUmode_Current (255)
+
+/* 26bit user mode. */
+#define ADP_CPUread_26bitUser (0x0)
+
+/* 26bit FIQ mode. */
+#define ADP_CPUread_26bitFIQ (0x1)
+
+/* 26bit IRQ mode. */
+#define ADP_CPUread_26bitIRQ (0x2)
+
+/* 26bit Supervisor mode. */
+#define ADP_CPUread_26bitSVC (0x3)
+
+/* 32bit user mode. */
+#define ADP_CPUread_32bitUser (0x10)
+
+/* 32bit FIQ mode. */
+#define ADP_CPUread_32bitFIQ (0x11)
+
+/* 32bit IRQ mode. */
+#define ADP_CPUread_32bitIRQ (0x12)
+
+/* 32bit Supervisor mode. */
+#define ADP_CPUread_32bitSVC (0x13)
+
+/* 32bit Abort mode. */
+#define ADP_CPUread_32bitAbort (0x17)
+
+/* 32bit Undefined mode. */
+#define ADP_CPUread_32bitUndef (0x1B)
+
+/* #32bit System mode - Added in Architecture 4 ARMs e.g.ARM7TDMI */
+#define ADP_CPUread_32bitSystem (0x1F)
+
+/* 'mask':- */
+/* Request registers RO-R14. */
+#define ADP_CPUread_RegsMask (0x7FFF)
+
+/* Request Program Counter (including mode and flag bits in 26-bit modes. */
+#define ADP_CPUread_PCmode (1 << 15)
+
+/* Request Program Counter (without mode and flag bits in 26-bit modes. */
+#define ADP_CPUread_PCnomode (1 << 16)
+
+/* Requests the transfer of the CPSR */
+#define ADP_CPUread_CPSR (1 << 17)
+
+/* In processor modes with an SPSR(non-user modes), bit 19 requests its
+ transfer */
+#define ADP_CPUread_SPSR (1 << 18)
+
+
+
+#define ADP_CPUwrite ADPREASON(CI_HADP,6)
+/* ADP_CPUwrite
+ * ------------
+ * Summary: This is a request to write values to the CPU.
+ *
+ * Arguments:
+ * Send: (byte mode, word mask, words data)
+ * Return: (word status)
+ *
+ * 'mode' defines the processor mode to which the transfer should be made.
+ * The mode number is the same as the mode number used by ARM; a value of
+ * 255 indicates the current mode. See ADP_CPUread above for more detail.
+ * 'mask' indicates which registers should be transferred. Setting a bit to
+ * one will cause the designated register to be transferred. The details
+ * of mask are specified above in ADP_CPUread.
+ * 'data' holds the values of the registers to be transferred. The first
+ * value is written to the lowest numbered register. NOTE: data must not
+ * cause the buffer size to exceed the maximum allowed buffer size.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+
+#define ADP_CPread ADPREASON(CI_HADP,7)
+/* ADP_CPread
+ * ----------
+ * Summary: This message requests a co-processors internal state.
+ *
+ * Arguments:
+ * Send: (byte CPnum, word mask)
+ * Return: (word status, words data)
+ *
+ * 'CPnum' is the number of the co-processor to transfer values from.
+ * 'mask' specifies which registers to transfer and is co-processor
+ * specific.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'data' holds the registers specified in 'mask' if successful, otherwise
+ * just rubbish. The lowest numbered register is transferred first.
+ * NOTE: data must not cause the buffer size to exceed the maximum allowed
+ * buffer size.
+ */
+
+
+
+#define ADP_CPwrite ADPREASON(CI_HADP,8)
+/* ADP_CPwrite
+ * -----------
+ * Summary: This message requests a write to a co-processors internal state.
+ *
+ * Arguments:
+ * Send: (byte CPnum, word mask, words data)
+ * Return: (word status)
+ *
+ * 'CPnum' is the number of the co-processor to transfer values to.
+ * 'mask' specifies which registers to transfer and is co-processor
+ * specific.
+ * 'data' holds the values to transfer to the registers specified in 'mask'.
+ * The first value is written to the lowest numbered register.
+ * NOTE: data must not cause the buffer size to exceed the maximum allowed
+ * buffer size.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+
+#define ADP_SetBreak ADPREASON(CI_HADP,9)
+/* ADP_SetBreak
+ * ------------
+ * Summary: Sets a breakpoint.
+ *
+ * Arguments:
+ * Send: (word address, byte type [, word bound])
+ * Return: (word status, word pointhandle, word raddress, word rbound)
+ *
+ * 'address' is the address of the instruction to set the breakpoint on.
+ * 'type' specifies the sort of breakpoint and is described in more detail
+ * below.
+ * 'bound' is included if the least significant 4 bits of type are set to
+ * 5 or above (see below for more detail).
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'pointhandle' returns a handle to the breakpoint, it will be valid if bit
+ * 7 of 'type' is set. See below for more detail.
+ * 'raddress' is valid depending on 'type', see below for more detail.
+ * 'rbound' is valid depending on 'type', see below for more detail.
+ */
+
+/* 'type':- */
+/* The least significant 4 bits define the sort of breakpoint to set:- */
+/* Halt if the pc is equal to 'address'. */
+#define ADP_SetBreak_EqualsAddress (0)
+
+/* Halt if the pc is greater than 'address'. */
+#define ADP_SetBreak_GreaterAddress (1)
+
+/* Halt if the pc is greater than or equal to 'address'. */
+#define ADP_SetBreak_GEqualsAddress (2)
+
+/* Halt if the pc is less than 'address'. */
+#define ADP_SetBreak_LessAddress (3)
+
+/* Halt if the pc is less than or equal to 'address'. */
+#define ADP_SetBreak_LEqualsAddress (4)
+
+/* Halt if the pc is in the range from 'address' to 'bound' inclusive. */
+#define ADP_SetBreak_Range (5)
+
+/* Halt if the pc is not in the range from 'address' to 'bound' inclusive. */
+#define ADP_SetBreak_NotRange (6)
+
+/* Halt if (pc & 'bound') = 'address'. */
+#define ADP_SetBreak_AndBound (7)
+
+/* Bits 5,6 and 7 are used as follows :- */
+/* If set this indicates that the breakpoint is on a 16bit (Thumb)
+ instruction rather than a 32bit (ARM) instruction. */
+#define ADP_SetBreak_Thumb (1 << 4)
+
+/* This requests that the breakpoint should be conditional (execution halts
+ only if the breakpointed instruction is executed, not if it is
+ conditionally skipped). If bit 5 is not set, execution halts whenever
+ the breakpointed instruction is reached (whether executed or skipped). */
+#define ADP_SetBreak_Cond (1 << 5)
+
+/* This requests a dry run: the breakpoint is not set and the 'raddress', and
+ if appropriate the 'rbound', that would be used, are returned (for
+ comparison and range breakpoints the address and bound used need not be
+ exactly as requested). A RDIError_NoError 'status' byte indicates that
+ resources are currently available to set the breakpoint, non-zero
+ indicates an error. RDIError_NoMorePoints indicates that the required
+ breakpoint resources are not currently available. */
+#define ADP_SetBreak_DryRun (1 << 6)
+
+/* If the request is successful, but there are no more breakpoint registers
+ (of the requested type), then the value RDIError_NoMorePoints is
+ returned. */
+
+/* If a breakpoint is set on a location which already has a breakpoint, the
+ first breakpoint will be removed before the new breakpoint is set. */
+
+
+
+#define ADP_ClearBreak ADPREASON(CI_HADP,10)
+/* ADP_ClearBreak
+ * --------------
+ * Summary: Clears a breakpoint.
+ *
+ * Arguments:
+ * Send: (word pointhandle)
+ * Return: (word status)
+ *
+ * 'pointhandle' is a handle returned by a previous ADP_SetBreak.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+#define ADP_SetWatch ADPREASON(CI_HADP,11)
+/* ADP_SetWatch
+ * ------------
+ * Summary: Sets a watchpoint.
+ *
+ * Arguments:
+ * Send: (word address, byte type, byte datatype [,word bound])
+ * Return: (word status, word pointhandle, word raddress, word rbound)
+ *
+ * 'address' is the address at which to set the watchpoint.
+ * 'type' is the type of watchpoint to set and is described in detail below.
+ * 'datatype' defines the sort of data access to watch for and is described
+ * in more detail below.
+ * 'bound' is included depending on the value of type (see description of
+ * type below).
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'pointhandle' is valid depending on the value of type (see description
+ * of type below).
+ * 'raddress' is valid depending on the value of type (see description
+ * of type below).
+ * 'rbound' is valid depending on the value of type (see description
+ * of type below).
+ */
+
+/* 'type':- */
+/* The least significant 4 bits of 'type' define the sort of watchpoint to
+ set:- */
+/* Halt on a data access to the address equal to 'address'. */
+#define ADP_SetWatch_EqualsAddress (0)
+
+/* Halt on a data access to an address greater than 'address'. */
+#define ADP_SetWatch_GreaterAddress (1)
+
+/* Halt on a data access to an address greater than or equal to 'address'. */
+#define ADP_SetWatch_GEqualsAddress (2)
+
+/* Halt on a data access to an address less than 'address'. */
+#define ADP_SetWatch_LessAddress (3)
+
+/* Halt on a data access to an address less than or equal to 'address'. */
+#define ADP_SetWatch_LEqualsAddress (4)
+
+/* Halt on a data access to an address in the range from 'address' to
+ 'bound' inclusive. */
+#define ADP_SetWatch_Range (5)
+
+/* Halt on a data access to an address not in the range from 'address' to
+ 'bound' inclusive. */
+#define ADP_SetWatch_NotRange (6)
+
+/* Halt if (data-access-address & 'bound')='address'. */
+#define ADP_SetWatch_AndBound (7)
+
+/* Bits 6 and 7 of 'type' also have further significance:-
+ NOTE: they must not be simulataneously set. */
+
+/* Bit 6 of 'type' set: Requests a dry run: the watchpoint is not set and
+ the 'address' and, if appropriate, the 'bound', that would be used are
+ returned (for range and comparison watchpoints, the 'address' and 'bound'
+ used need not be exactly as requested). A RDIError_NoError status byte
+ indicates that resources are currently available to set the watchpoint;
+ RDIError_NoMorePoints indicates that the required watchpoint resources
+ are not currently available. */
+
+/* Bit 7 of 'type' set: Requests that a handle should be returned for the
+ watchpoint by which it will be identified subsequently. If bit 7 is
+ set, a handle will be returned ('pointhandle'), whether or not the
+ request succeeds or fails (but, obviously, it will only be meaningful
+ if the request succeesd). */
+
+/* 'datatype':- */
+/* The 'datatype' argument defines the sort of data access to watch for,
+ values can be summed or ORed together to halt on any set of sorts of
+ memory access. */
+
+/* Watch for byte reads. */
+#define ADP_SetWatch_ByteReads (1)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_HalfWordReads (2)
+
+/* Watch for word reads. */
+#define ADP_SetWatch_WordReads (4)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_ByteWrites (8)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_HalfWordWrites (16)
+
+/* Watch for half-word reads. */
+#define ADP_SetWatch_WordWrites (32)
+
+/* On successful completion a RDIError_NoError 'status' byte is returned. On
+ unsuccessful completion, a non-zero error code byte is returned. If the
+ request is successful, but there are now no more watchpoint registers
+ (of the requested type), then the value RDIError_NoMorePoints is
+ returned. */
+
+/* If a watchpoint is set on a location which already has a watchpoint, the
+ first watchpoint will be removed before the new watchpoint is set. */
+
+
+#define ADP_ClearWatch ADPREASON(CI_HADP,12)
+/* ADP_ClearWatch
+ * --------------
+ * Summary: Clears a watchpoint.
+ *
+ * Arguments:
+ * Send: (word pointhandle)
+ * Return: (word status)
+ *
+ * 'pointhandle' is a handle to a watchpoint returned by a previous
+ * ADP_SetWatch.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+
+
+#define ADP_Execute ADPREASON(CI_HADP,13)
+/* ADP_Execute
+ * -----------
+ * Summary: This message requests that the target starts executing from
+ * the stored CPU state.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * The message will *ALWAYS* respond immediately with an ACK (unlike the
+ * old RDI definition, which allowed asynchronous message replies).
+ *
+ * Execution will stop when allowed system events occur. The host will
+ * be notified via a ADP_Stopped message (described below).
+ */
+
+
+
+#define ADP_Step ADPREASON(CI_HADP,14)
+/* ADP_Step
+ * --------
+ * Summary: Execute 'ninstr' instructions.
+ *
+ * Arguments:
+ * Send: (word ninstr)
+ * Return: (word status)
+ *
+ * 'ninstr' is the number of instructions to execute, starting at the
+ * address currently loaded into the CPU program counter. If it is zero,
+ * the target should execute instructions upto the next instruction that
+ * explicitly alters the Program Counter. i.e. a branch or ALU operation
+ * with the PC as the destination.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * The ADP_Step function (unlike the earlier RDI system) will *ALWAYS*
+ * return an ACK immediately. A subsequent ADP_Stopped message will be
+ * delivered from the target to the host when the ADP_Step operation
+ * has completed.
+ */
+
+
+
+#define ADP_InterruptRequest ADPREASON(CI_HADP,15)
+/* ADP_InterruptRequest
+ * --------------------
+ * Summary: Interrupt execution.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * On receiving this message the target should attempt to stop execution.
+ */
+
+
+
+#define ADP_HW_Emulation ADPREASON(CI_HADP,16)
+/* ADP_HW_Emulation
+ * ----------------
+ * The first parameter to ADP_HW_Emulation is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP__HW_Emulation sub-reason codes: */
+
+#define ADP_HW_Emul_Supported ADPSUBREASON(CI_HADP,0)
+/* ADP_HW_Emul_Supported
+ * ---------------------
+ * Summary: Enquires whether calls to the next 4 messages are available
+ * (MemoryAccess, MemoryMap, Set_CPUspeed, ReadClock).
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate the messages are available,
+ * non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDI_Info_Memory_Stats.
+ */
+
+
+#define ADP_HW_Emul_MemoryAccess ADPSUBREASON(CI_HADP,1)
+/* ADP_HW_Emul_MemoryAccess
+ * ------------------------
+ * Summary: Get memory access information for memory block with specified
+ * handle.
+ *
+ * Arguments:
+ * Send: (word handle)
+ * Return: (word status, word nreads, word nwrites, word sreads,
+ * word swrites, word ns, word s)
+ *
+ * 'handle' is a handle to a memory block.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'nreads' is the number of non-sequential reads.
+ * 'nwrites' is the number of non-sequential writes.
+ * 'sreads' is the number of sequential reads.
+ * 'swrites' is the number of sequential writes.
+ * 'ns' is time in nano seconds.
+ * 's' is time in seconds.
+ *
+ * NOTE: Equivalent to RDIMemory_Access.
+ */
+
+
+#define ADP_HW_Emul_MemoryMap ADPSUBREASON(CI_HADP,2)
+/* ADP_HW_Emul_MemoryMap
+ * ---------------------
+ * Summary: Sets memory characteristics.
+ *
+ * Arguments:
+ * Send: (word n,
+ Then 'n' sets of arguments of the form:-
+ word handle, word start, word limit, byte width,
+ byte access, word Nread_ns, word Nwrite_ns, word Sread_ns,
+ word Swrite_ns)
+ * Return: (word status)
+ *
+ * 'n' is the number of sets of arguments.
+ * 'handle' is a handle to the region.
+ * 'start' is the start of this region.
+ * 'limit' is the limit of this region.
+ * 'width' is the memory width, described in detail below.
+ * 'access' is described in detail below.
+ * 'Nread_ns' is the access time for N read cycles in nano seconds.
+ * 'Nwrite_ns' is the access time for N write cycles in nano seconds.
+ * 'Sread_ns' is the access time for S read cycles in nano seconds.
+ * 'Swrite_ns' is the access time for S write cycles in nano seconds.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * NOTE: Equivalent to RDIMemory_Map.
+ */
+
+/* 'width':- */
+/* 8 bit memory width. */
+#define ADP_HW_Emul_MemoryMap_Width8 (0)
+
+/* 16 bit memory width. */
+#define ADP_HW_Emul_MemoryMap_Width16 (1)
+
+/* 32 bit memory width. */
+#define ADP_HW_Emul_MemoryMap_Width32 (2)
+
+/* 'access':- */
+/* Bit 0 - read access. */
+#define ADP_HW_Emul_MemoryMap_Access_Read (1 << 0)
+
+/* Bit 1 - write access. */
+#define ADP_HW_Emul_MemoryMap_Access_Write (1 << 1)
+
+/* Bit 2 - latched 32 bit memory. */
+#define ADP_HW_Emul_MemoryMap_Access_Latched (1 << 2)
+
+
+#define ADP_HW_Emul_SetCPUSpeed ADPSUBREASON(CI_HADP,3)
+/* ADP_HW_Emul_SetCPUSpeed
+ * -----------------------
+ * Summary: Sets the speed of the CPU.
+ *
+ * Arguments:
+ * Send: (word speed)
+ * Return: (word status)
+ *
+ * 'speed' is the CPU speed in nano seconds.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDISet_CPUSpeed.
+ */
+
+
+#define ADP_HW_Emul_ReadClock ADPSUBREASON(CI_HADP,4)
+/* ADP_HW_Emul_ReadClock
+ * ---------------------
+ * Summary: Reads simulated time.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word ns, word s)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'ns' is time in nano seconds.
+ * 's' is time in seconds.
+ *
+ * NOTE: Equivalent to RDIRead_Clock.
+ */
+
+
+#define ADP_ICEbreakerHADP ADPREASON(CI_HADP,17)
+
+/* The first parameter to ADP_ICEbreaker is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP_ICEbreaker sub-reason codes: */
+
+#define ADP_ICEB_Exists ADPSUBREASON(CI_HADP,0)
+/* ADP_ICEB_Exists
+ * ---------------
+ * Summary: Is there an ICEbreaker in the system?
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate there is an ICEbreaker,
+ * non-zero otherwise.
+ */
+
+
+#define ADP_ICEB_GetLocks ADPSUBREASON(CI_HADP,1)
+/* ADP_ICEB_GetLocks
+ * -----------------
+ * Summary: Returns which ICEbreaker registers are locked.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word lockedstate)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'lockedstate' is a bitmap if the ICEbreaker registers locked against use
+ * by IceMan (because explicitly written by the user). Bit n represents
+ * hardware breakpoint n, and if set the register is locked.
+ *
+ * NOTE: Equivalent to RDIIcebreaker_GetLocks. Should only be used if
+ * ADP_ICEB_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_SetLocks ADPSUBREASON(CI_HADP,2)
+/* ADP_ICEB_SetLocks
+ * -----------------
+ * Summary: Sets which ICEbreaker registers are locked.
+ *
+ * Arguments:
+ * Send: (word lockedstate)
+ * Return: (word status)
+ *
+ * 'lockedstate' is the same as in ADP_ICEB_GetLocks above.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIIcebreaker_SetLocks. Should only be used if
+ * ADP_ICEB_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_CC_Exists ADPSUBREASON(CI_HADP,3)
+/* ADP_ICEB_CC_Exists
+ * ------------------
+ * Summary: Is there an ICEbreaker Comms Channel?
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate there is a Comms Channel,
+ * non-zero otherwise.
+ *
+ * NOTE: Should only be used if ADP_ICEB_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_CC_Connect_ToHost ADPSUBREASON(CI_HADP,4)
+/* ADP_ICEB_CC_Connect_ToHost
+ * --------------------------
+ * Summary: Connect Comms Channel in ToHost direction.
+ *
+ * Arguments:
+ * Send: (byte connect)
+ * Return: (word status)
+ *
+ * 'connect' !!!!!
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDICommsChannel_ToHost. Should only be used if
+ * ADP_ICEB_CC_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEB_CC_Connect_FromHost ADPSUBREASON(CI_HADP,5)
+/* ADP_ICEB_CC_Connect_FromHost
+ * ----------------------------
+ * Summary: Connect Comms Channel in FromHost direction.
+ *
+ * Arguments:
+ * Send: (byte connect)
+ * Return: (word status)
+ *
+ * 'connect' is the same as in ADP_ICEB_CC_Connect_ToHost above.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDICommsChannel_FromHost. Should only be used if
+ * ADP_ICEB_CC_Exists didn't return an error.
+ */
+
+
+#define ADP_ICEman ADPREASON(CI_HADP,18)
+
+/* The first parameter to ADP_ICEman is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP_ICEman sub-reason codes: */
+
+
+#define ADP_ICEM_AddConfig ADPSUBREASON(CI_HADP,0)
+/* ADP_ICEM_AddConfig
+ * ------------------
+ * Summary: Prepares target to receive configuration data block.
+ *
+ * Arguments:
+ * Send: (word nbytes)
+ * Return: (word status)
+ *
+ * 'nbytes' is the number of bytes in the configuration block.
+ * 'status' is RDIError_NoError to indicate success, non-zero if a
+ * configuration block of this size can't be accepted.
+ *
+ * NOTE: Equivalent to RDP_AddConfig.
+ */
+
+
+#define ADP_ICEM_SelectConfig ADPSUBREASON(CI_HADP,1)
+/* ADP_ICEM_SelectConfig
+ * ---------------------
+ * Summary: Selects one of the sets of configuration data blocks and
+ * reinitialises to use the new configuration.
+ *
+ * Arguments:
+ * Send: (byte aspect, byte namelen, byte matchtype, word vsn_req,
+ bytes name)
+ * Return: (word status, word vsn_sel)
+ *
+ * 'aspect' is one of two values defined below.
+ * 'namelen' is the number of bytes in 'name'.
+ * 'matchtype' specifies how the selected version must match that specified,
+ * and takes one of the values defined below.
+ * 'vsn_req' is the requested version of the named configuration.
+ * 'name' is the name of the configuration.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'vsn_sel' is the version number of the configuration selected on success.
+ *
+ * NOTE: Equivalent to RDP_SelectConfig.
+ */
+
+/* 'aspect':- */
+#define ADP_ICEM_SelectConfig_ConfigCPU (0)
+#define ADP_ICEM_SelectConfig_ConfigSystem (1)
+
+/* 'matchtype':- */
+#define ADP_ICEM_SelectConfig_MatchAny (0)
+#define ADP_ICEM_SelectConfig_MatchExactly (1)
+#define ADP_ICEM_SelectConfig_MatchNoEarlier (2)
+
+
+#define ADP_ICEM_ConfigCount ADPSUBREASON(CI_HADP,2)
+/* ADP_ICEM_ConfigCount
+ * --------------------
+ * Summary: Return number of configurations.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status [, word count])
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'count' returns the number of configurations if status is zero.
+ *
+ * NOTE: Equivalent to RDIConfig_Count.
+ */
+
+
+#define ADP_ICEM_ConfigNth ADPSUBREASON(CI_HADP,3)
+/* ADP_ICEM_ConfigNth
+ * ------------------
+ * Summary: Gets the nth configuration details.
+ *
+ * Arguments:
+ * Send: (word confign)
+ * Return: (word status, word version, byte namelen, bytes name)
+ *
+ * 'confign' is the number of the configuration.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'version' is the configuration version number.
+ * 'namelen' is the number of bytes in 'name'.
+ * 'name' is the name of the configuration.
+ *
+ * NOTE: Equivalent to RDIConfig_Nth.
+ */
+
+
+
+#define ADP_Profile ADPREASON(CI_HADP,19)
+
+/* The first parameter to ADP_Profile is a Reason Subcode, and
+ * subsequent parameters are defined by that subcode
+ *
+ * word reason subcode
+ * other arguments as reason subcode determines
+ *
+ */
+
+/* ADP_Profile sub-reason codes: */
+
+
+#define ADP_Profile_Supported ADPSUBREASON(CI_HADP,0)
+/* ADP_Profile_Supported
+ * ---------------------
+ * Summary: Checks whether profiling is supported.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError if profiling is supported, non-zero otherwise.
+ *
+ * NOTE: Can also be determined using Info_Target.
+ */
+
+
+#define ADP_Profile_Stop ADPSUBREASON(CI_HADP,1)
+/* ADP_Profile_Stop
+ * ----------------
+ * Summary: Stops profiling.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_Stop.
+ */
+
+
+#define ADP_Profile_Start ADPSUBREASON(CI_HADP,2)
+/* ADP_Profile_Start
+ * -----------------
+ * Summary: Starts profiling (PC sampling).
+ *
+ * Arguments:
+ * Send: (word interval)
+ * Return: (word status)
+ *
+ * 'interval' is the period of PC sampling in micro seconds.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_Start.
+ */
+
+
+#define ADP_Profile_WriteMap ADPSUBREASON(CI_HADP,3)
+#define ADP_ProfileWriteHeaderSize (ADP_DEFAULT_HEADER_SIZE + 4*sizeof(word))
+
+/* ADP_Profile_WriteMap
+ * --------------------
+ * Summary: Downloads a map array, which describes the PC ranges for profiling.
+ *
+ * Arguments: A number of messages each of form:-
+ * Send: (word len, word size, word offset, words map_data)
+ * Return: (word status)
+ *
+ * 'len' is the number of elements in the entire map array being downloaded.
+ * 'size' is the number of words being downloaded in this message, i.e. the
+ * length of 'map_data'.
+ * 'offset' is the offset into the entire map array which this message starts
+ * from, in words.
+ * 'map_data' consists of 'size' words of map data.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_WriteMap.
+ */
+
+
+#define ADP_Profile_ReadMap ADPSUBREASON(CI_HADP,4)
+#define ADP_ProfileReadHeaderSize (ADP_DEFAULT_HEADER_SIZE + 2*sizeof(word))
+
+/* ADP_Profile_ReadMap
+ * -------------------
+ * Summary: Uploads a set of profile counts which correspond to the current
+ * profile map.
+ *
+ * Arguments: A number of messages, each of the form:
+ * Send: (word offset, word size)
+ * Return: (word status, words counts)
+ *
+ * 'offset' is the offset in the entire array of counts that this message
+ * starts from, in words.
+ * 'size' is the number of words uploaded in this message (in counts).
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'counts' is 'size' words of profile counts.
+ *
+ * NOTE: Equivalent to RDIProfile_ReadMap.
+ */
+
+
+#define ADP_Profile_ClearCounts ADPSUBREASON(CI_HADP,5)
+/* ADP_Profile_ClearCounts
+ * -----------------------
+ * Summary: Requests that PC sample counts be set to zero.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDIProfile_ClearCounts.
+ */
+
+#define ADP_InitialiseApplication ADPREASON(CI_HADP,20)
+/* ADP_InitialiseApplication
+ * -------------------------
+ * Summary: Requests that OS setup up the thread/task so that it can be
+ * executed.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+#define ADP_End ADPREASON(CI_HADP,21)
+/* ADP_End
+ * -------
+ * Summary: Sent by the host debugger to tell angel this debugging session
+ * is is finished
+ * Arguments:
+ * Send: ()
+ * Return: (word status)
+ * status' is RDIError_NoError to indicate success, non-zero otherwise.
+ */
+
+/******************************************************************
+ *
+ * CI_TADP messages
+ *
+ */
+
+#define ADP_TADPUnrecognised ADPREASON(CI_TADP,0)
+/* This message is unusual in that it is normally sent in reply to
+ * another message which is not understood. This is an exception
+ * to the normal protocol which says that a reply must have the
+ * same base reason code as the original. There is a single reply
+ * parameter which is the reason code which was not understood.
+ *
+ * As well as being a reply this message can also be sent and will
+ * return as if this message were unrecognised!
+ *
+ * Parameters:
+ * none
+ *
+ * Reply:
+ * word reason code which was not recognised
+ */
+
+/*-------------------------------------------------------------------------*/
+
+#define ADP_Stopped ADPREASON(CI_TADP,1)
+/* ADP_Stopped
+ * -----------
+ * Summary: This message is sent to the host when the application stops,
+ * either naturally or due to an exception.
+ *
+ * Parameters:
+ * word reason subcode
+ * other arguments as reason subcode determines.
+ * Unless stated otherwise (below) there will be none.
+ *
+ * Reply:
+ * word status unless reason subcode says otherwise
+ *
+ * This message is sent to the host when execution has stopped. This
+ * can be when the end of the application has been reached, or as the
+ * result of an exception. It can also be the return from an ADP_Step
+ * process, when the requested number of instructions have been
+ * executed., or a breakpoint or watchpoint has been hit etc.
+ */
+
+/* The first set of Stopped subreason codes are for the ARM hardware
+ * vectors. These events will be raised if the
+ * ADP_Control_Vector_Catch allows, or if the target application has
+ * not provided its own handlers.
+ */
+#define ADP_Stopped_BranchThroughZero ADPSUBREASON(CI_TADP,0)
+#define ADP_Stopped_UndefinedInstr ADPSUBREASON(CI_TADP,1)
+#define ADP_Stopped_SoftwareInterrupt ADPSUBREASON(CI_TADP,2)
+#define ADP_Stopped_PrefetchAbort ADPSUBREASON(CI_TADP,3)
+#define ADP_Stopped_DataAbort ADPSUBREASON(CI_TADP,4)
+#define ADP_Stopped_AddressException ADPSUBREASON(CI_TADP,5)
+#define ADP_Stopped_IRQ ADPSUBREASON(CI_TADP,6)
+#define ADP_Stopped_FIQ ADPSUBREASON(CI_TADP,7)
+
+/* We leave the rest of what would be the bits in the VectorCatch
+ * bitmask free for future expansion.
+ */
+
+/* The following are software reasons for execution stopping: */
+#define ADP_Stopped_BreakPoint ADPSUBREASON(CI_TADP,32)
+/* Breakpoint was reached
+ * extra send parameter: word handle - indicates which breakpoint
+ */
+
+#define ADP_Stopped_WatchPoint ADPSUBREASON(CI_TADP,33)
+/* Watchpoint was triggered
+ * extra send parameter: word handle - indicates which watchpoint
+ */
+
+#define ADP_Stopped_StepComplete ADPSUBREASON(CI_TADP,34)
+/* End of ADP_Step request */
+
+#define ADP_Stopped_RunTimeErrorUnknown ADPSUBREASON(CI_TADP,35)
+/*
+ * non-specific fatal runtime support error
+ */
+
+#define ADP_Stopped_InternalError ADPSUBREASON(CI_TADP,36)
+/* extra send parameter: word error - indicates the nature of the error
+ *
+ * An Angel internal error has happened. The error number should be
+ * displayed for the user to report to his software supplier. Once
+ * this error has been received the internal state of Angel can no longer
+ * be trusted.
+ */
+
+#define ADP_Stopped_UserInterruption ADPSUBREASON(CI_TADP,37)
+/* Host requested interruption */
+
+#define ADP_Stopped_ApplicationExit ADPSUBREASON(CI_TADP,38)
+/* extra send parameter: word exitcode
+ * This indicates that the application has exited via exit(), an exitcode
+ * of zero indiactes successful termination.
+ */
+
+#define ADP_Stopped_StackOverflow ADPSUBREASON(CI_TADP, 39)
+/*
+ * Software stack overflow has occurred
+ */
+
+#define ADP_Stopped_DivisionByZero ADPSUBREASON(CI_TADP, 40)
+/*
+ * Division by zero has occurred
+ */
+
+#define ADP_Stopped_OSSpecific ADPSUBREASON(CI_TADP, 41)
+/*
+ * The OS has requested that execution stops. The OS will know
+ * why this has happened.
+ */
+
+
+
+/******************************************************************
+ *
+ * CI_TTDCC messages (Target-initiated debug comms channel)
+ *
+ */
+
+#define ADP_TDCC_ToHost ADPREASON(CI_TTDCC,0)
+/* ADP_TDCC_ToHost
+ * ------------------
+ * Summary: Send Data down Comms Channel in ToHost direction.
+ *
+ * Arguments:
+ * Send: (word nbytes, words data)
+ * Return: (word status)
+ *
+ * 'nbytes' is number of BYTES to be transferred from the target to the
+ * host via the Debug Comms channel.
+ * 'data' is (nbytes/sizeof(word)) WORDS of data to be transferred from
+ * the target to the host via the Debug Comms channel.
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ *
+ * NOTE: Equivalent to RDP_CCToHost and RDP_CCToHostReply (just set the
+ * direction bit).
+ * NOTE II: Current implementations only support single word transfers
+ * (nbytes = 4).
+ */
+
+
+#define ADP_TDCC_FromHost ADPREASON(CI_TTDCC,1)
+/* ADP_TDCC_FromHost
+ * --------------------
+ * Summary: Send Data down Comms Channel in FromHost direction.
+ *
+ * Arguments:
+ * Send: ()
+ * Return: (word status, word nbytes, words data)
+ *
+ * 'status' is RDIError_NoError to indicate success, non-zero otherwise.
+ * 'nbytes' is number of BYTES to be transferred from the host to the
+ * target via the Debug Comms channel, or zero if the host has no data
+ * to transfer.
+ * 'data' is (nbytes/sizeof(word)) WORDS of transferred data.
+ *
+ * NOTE: Equivalent to RDP_CCFromHost and RDP_CCFromHostReply (just set the
+ * direction bit).
+ * NOTE II: Current implementations only support single word transfers
+ * (nbytes = 4).
+ */
+
+
+/*******************************************************************
+ *
+ * Error Codes
+ *
+ */
+
+#define RDIError_NoError 0
+
+#define RDIError_Reset 1
+#define RDIError_UndefinedInstruction 2
+#define RDIError_SoftwareInterrupt 3
+#define RDIError_PrefetchAbort 4
+#define RDIError_DataAbort 5
+#define RDIError_AddressException 6
+#define RDIError_IRQ 7
+#define RDIError_FIQ 8
+#define RDIError_Error 9
+#define RDIError_BranchThrough0 10
+
+#define RDIError_NotInitialised 128
+#define RDIError_UnableToInitialise 129
+#define RDIError_WrongByteSex 130
+#define RDIError_UnableToTerminate 131
+#define RDIError_BadInstruction 132
+#define RDIError_IllegalInstruction 133
+#define RDIError_BadCPUStateSetting 134
+#define RDIError_UnknownCoPro 135
+#define RDIError_UnknownCoProState 136
+#define RDIError_BadCoProState 137
+#define RDIError_BadPointType 138
+#define RDIError_UnimplementedType 139
+#define RDIError_BadPointSize 140
+#define RDIError_UnimplementedSize 141
+#define RDIError_NoMorePoints 142
+#define RDIError_BreakpointReached 143
+#define RDIError_WatchpointAccessed 144
+#define RDIError_NoSuchPoint 145
+#define RDIError_ProgramFinishedInStep 146
+#define RDIError_UserInterrupt 147
+#define RDIError_CantSetPoint 148
+#define RDIError_IncompatibleRDILevels 149
+
+#define RDIError_CantLoadConfig 150
+#define RDIError_BadConfigData 151
+#define RDIError_NoSuchConfig 152
+#define RDIError_BufferFull 153
+#define RDIError_OutOfStore 154
+#define RDIError_NotInDownload 155
+#define RDIError_PointInUse 156
+#define RDIError_BadImageFormat 157
+#define RDIError_TargetRunning 158
+#define RDIError_DeviceWouldNotOpen 159
+#define RDIError_NoSuchHandle 160
+#define RDIError_ConflictingPoint 161
+
+#define RDIError_LittleEndian 240
+#define RDIError_BigEndian 241
+#define RDIError_SoftInitialiseError 242
+
+#define RDIError_InsufficientPrivilege 253
+#define RDIError_UnimplementedMessage 254
+#define RDIError_UndefinedMessage 255
+
+
+#endif
+
+/* EOF adp_h */
diff --git a/gdb/rdi-share/adperr.h b/gdb/rdi-share/adperr.h
new file mode 100644
index 0000000..f90f1dc
--- /dev/null
+++ b/gdb/rdi-share/adperr.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Definitions of ADP error codes
+ */
+
+#ifndef angsd_adperrs_h
+#define angsd_adperrs_h
+/*
+ * ADP failure codes start at 256 to distinguish them for debug purposes
+ */
+enum AdpErrs
+{
+ adp_ok = 0,
+ adp_failed = 256,
+ adp_malloc_failure,
+ adp_illegal_args,
+ adp_device_not_found,
+ adp_device_open_failed,
+ adp_device_already_open,
+ adp_device_not_open,
+ adp_bad_channel_id,
+ adp_callback_already_registered,
+ adp_write_busy,
+ adp_bad_packet,
+ adp_seq_high,
+ adp_seq_low,
+ adp_timeout_on_open,
+ adp_abandon_boot_wait,
+ adp_late_startup,
+ adp_new_agent_starting
+};
+
+#ifndef __cplusplus
+typedef enum AdpErrs AdpErrs;
+#endif
+
+#define AdpMess_Failed "ADP Error - unspecific failure"
+#define AdpMess_MallocFailed "ADP Error - malloc failed"
+#define AdpMess_IllegalArgs "ADP Error - illegal arguments"
+#define AdpMess_DeviceNotFound "ADP Error - invalid device specified"
+#define AdpMess_DeviceOpenFailed "ADP Error - specified device failed to open"
+#define AdpMess_DeviceAlreadyOpen "ADP Error - device already open"
+#define AdpMess_DeviceNotOpen "ADP Error - device not open"
+#define AdpMess_BadChannelId "ADP Error - bad channel Id"
+#define AdpMess_CBAlreadyRegd "ADP Error - callback already registered"
+#define AdpMess_WriteBusy "ADP Error - write busy"
+#define AdpMess_BadPacket "ADP Error - bad packet"
+#define AdpMess_SeqHigh "ADP Error - sequence number too high"
+#define AdpMess_SeqLow "ADP Error - sequence number too low"
+#define AdpMess_TimeoutOnOpen "ADP Error - target did not respond"
+#define AdpMess_AbandonBootWait "abandoned wait for late startup"
+#define AdpMess_LateStartup "Target compiled with LATE_STARTUP set.\n" \
+ "Waiting for target...\n" \
+ "Press <Ctrl-C> to abort.\n"
+#define AdpMessLen_LateStartup (3*80)
+#define AdpMess_NewAgentStarting "New Debug Agent about to start.\n"
+
+#endif /* ndef angsd_adperr_h */
+
+/* EOF adperr.h */
diff --git a/gdb/rdi-share/angel.h b/gdb/rdi-share/angel.h
new file mode 100644
index 0000000..60a5f31
--- /dev/null
+++ b/gdb/rdi-share/angel.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*> angel.h <*/
+/*---------------------------------------------------------------------------*/
+/* This header file is the main holder for the declarations and
+ * prototypes for the core Angel system. Some Angel concepts are
+ * described at the start of this file to ensure that a complete view
+ * of the Angel world can be derived purely from the source.
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * NOTE: Currently the Angel source is designed to be simple,
+ * understandable and easy to port to new hardware platforms. However,
+ * this does not always yield the highest performing system. The
+ * current layered approach introduces an overhead to the performance
+ * of the system. In a true commercial target, this code should be
+ * re-designed to build a system where the Angel logical message
+ * system, device driver and hardware accesses are merged to provide
+ * the best performance.
+ */
+/*---------------------------------------------------------------------------*/
+/* Angel overview:
+
+... some comments describing Angel ...
+
+ * Angel is designed as a kit-of-parts that can be used to provide
+ * run-time support for the development of ARM applications. The main
+ * core of Angel is in providing support for the "debug" message
+ * communication with a host system. These messages do not just cover
+ * debugging ARM processes, but also the process of downloading ARM
+ * programs or attaching to executing processes on the target.
+ *
+ * A stand-alone ROM based Angel world is the basic starting point for
+ * a system, since it will allow programs to be downloaded to the
+ * target. The ROM version of Angel will provide the generic debug
+ * support, but no system specific routines. The preferred method of
+ * using Angel is as a link library. This ensures that applications
+ * carry with them the Angel routines necessary to support debugging
+ * (and also ensure that the Angel version is up-to-date, independant
+ * of the version in the target ROM). Eventually, once a program has
+ * been fully debugged, a ROMmed version of the program can be
+ * generated with the Angel code being provided in the application.
+
+.. more comments ..
+
+ * The standard Angel routines do *NOT* perform any dynamic memory
+ * allocation. To simplify the source, and aid the porting to a non C
+ * library world, memory is either pre-allocated (as build-time
+ * globals) or actually given to the particular Angel routine by the
+ * active run-time. This ensures that the interaction between Angel
+ * and the target O/S is minimised.
+ *
+ * Notes: We sub-include more header files to keep the source
+ * modular. Since Angel is a kit-of-parts alternative systems may need
+ * to change the prototypes of particular functions, whilst
+ * maintaining a fixed external interface. e.g. using the standard
+ * DEBUG messages, but with a different communications world.
+ */
+/*---------------------------------------------------------------------------*/
+
+#ifndef __angel_h
+#define __angel_h
+
+/*---------------------------------------------------------------------------*/
+/*-- Global Angel definitions and manifests ---------------------------------*/
+/*---------------------------------------------------------------------------*/
+/* When building Angel we may not include the standard library
+ * headers. However, it is useful coding using standard macro names
+ * since it makes the code easier to understand.
+ */
+
+typedef unsigned int word ;
+typedef unsigned char byte ;
+
+/* The following typedefs can be used to access I/O registers: */
+typedef volatile unsigned int vuword ;
+typedef volatile unsigned char vubyte ;
+
+/*
+ * The following typedefs are used when defining objects that may also
+ * be created on a host system, where the word size is not
+ * 32bits. This ensures that the same data values are manipulated.
+ */
+#ifdef TARGET
+typedef unsigned int unsigned32;
+typedef signed int signed32;
+typedef int int32;
+
+typedef unsigned short int unsigned16;
+typedef signed short int signed16;
+
+/*
+ * yet another solution for the bool/boolean problem, this one is
+ * copied from Scott's modifications to clx/host.h
+ */
+# ifdef IMPLEMENT_BOOL_AS_ENUM
+ enum _bool { _false, _true };
+# define _bool enum _bool
+# elif defined(IMPLEMENT_BOOL_AS_INT) || !defined(__cplusplus)
+# define _bool int
+# define _false 0
+# define _true 1
+# endif
+
+# ifdef _bool
+# define bool _bool
+# endif
+
+# ifndef true
+# define true _true
+# define false _false
+# endif
+
+# ifndef YES
+# define YES true
+# define NO false
+# endif
+
+# undef TRUE /* some OSF headers define as 1 */
+# define TRUE true
+
+# undef FALSE /* some OSF headers define as 1 */
+# define FALSE false
+
+# ifndef NULL
+# define NULL 0
+# endif
+
+#else
+
+# include "host.h"
+
+#endif
+
+#ifndef IGNORE
+# define IGNORE(x) ((x)=(x))
+#endif
+
+/* The following typedef allows us to cast between integral and
+ * function pointers. This isn't allowed by direct casting when
+ * conforming to the ANSI spec.
+ */
+typedef union ansibodge
+{
+ word w ;
+ word *wp ;
+ void *vp ;
+ byte *bp ;
+ void (*vfn)(void) ;
+ word (*wfn)(void) ;
+ int (*ifn)(void) ;
+ byte (*bfn)(void) ;
+} ansibodge ;
+
+/*---------------------------------------------------------------------------*/
+
+/* The amount setup aside by the run-time system for stack overflow
+ * handlers to execute in. This must be at least 256bytes, since that
+ * value is assumed by the current ARM Ltd compiler.
+ * This space is _only_ kept for the USR stack, not any of the privileged
+ * mode stacks, as stack overflow on these is always fatal - there is
+ * no point attemptingto recover. In addition is is important that
+ * Angel should keep privileged stack space requirements to a minimum.
+ */
+#define APCS_STACKGUARD 256
+
+#endif /* __angel_h */
+
+/* EOF angel.h */
diff --git a/gdb/rdi-share/ardi.c b/gdb/rdi-share/ardi.c
new file mode 100644
index 0000000..f61f724
--- /dev/null
+++ b/gdb/rdi-share/ardi.c
@@ -0,0 +1,2672 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARDI.c
+ * Angel Remote Debug Interface
+ *
+ *
+ * $Revision$
+ * $Date$
+ *
+ * This file is based on /plg/pisd/rdi.c, but instead of using RDP it uses
+ * ADP messages.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define uint HIDE_HPs_uint
+#include <signal.h>
+#undef uint
+
+
+#include "endian.h"
+#include "ardi.h"
+#include "buffers.h"
+#include "channels.h"
+#include "hostchan.h"
+#include "host.h"
+#include "bytesex.h"
+#include "dbg_cp.h"
+#include "adp.h"
+#include "hsys.h"
+#include "logging.h"
+#include "msgbuild.h"
+#include "rxtx.h"
+#include "devsw.h"
+#include "params.h"
+
+#ifdef COMPILING_ON_WINDOWS
+# define IGNORE(x) (x = x) /* must go after #includes to work on Windows */
+#endif
+#define NOT(x) (!(x))
+
+#define ADP_INITIAL_TIMEOUT_PERIOD 5
+
+static volatile int executing;
+static int rdi_log = 0 ; /* debugging ? */
+
+/* we need a starting point for our first buffers, this is a safe one */
+int Armsd_BufferSize = ADP_BUFFER_MIN_SIZE;
+int Armsd_LongBufSize = ADP_BUFFER_MIN_SIZE;
+
+#ifdef WIN32
+ extern int interrupted;
+ extern int swiprocessing;
+#endif
+
+static char dummycline = 0;
+char *ardi_commandline = &dummycline ; /* exported in ardi.h */
+
+extern unsigned int heartbeat_enabled;
+
+static unsigned char *cpwords[16];
+
+typedef struct stoppedProcListElement {
+ struct stoppedProcListElement *next;
+ angel_RDI_TargetStoppedProc *fn;
+ void *arg;
+} stoppedProcListElement;
+
+static stoppedProcListElement *stopped_proc_list=NULL;
+
+const struct Dbg_HostosInterface *angel_hostif;
+static hsys_state *hstate;
+
+static void angel_DebugPrint(const char *format, ...)
+{ va_list ap;
+ va_start(ap, format);
+ angel_hostif->dbgprint(angel_hostif->dbgarg, format, ap);
+ va_end(ap);
+}
+
+#ifdef RDI_VERBOSE
+#define TracePrint(s) \
+ if (rdi_log & 2) angel_DebugPrint("\n"); \
+ if (rdi_log & 1) angel_DebugPrint s
+#else
+#define TracePrint(s)
+#endif
+
+typedef struct receive_dbgmsg_state {
+ volatile int received;
+ Packet *packet;
+} receive_dbgmsg_state;
+
+static receive_dbgmsg_state dbgmsg_state;
+
+static void receive_debug_packet(Packet *packet, void *stateptr)
+{
+ receive_dbgmsg_state *state = stateptr;
+
+ state->packet = packet;
+ state->received = 1;
+}
+
+static int register_debug_message_handler(void)
+{
+ int err;
+ dbgmsg_state.received = 0;
+
+ err = Adp_ChannelRegisterRead(CI_HADP, receive_debug_packet, &dbgmsg_state);
+#ifdef DEBUG
+ if (err!=adp_ok) angel_DebugPrint("register_debug_message_handler failed %i\n", err);
+#endif
+ return err;
+}
+
+
+static int wait_for_debug_message(int *rcode, int *debugID,
+ int *OSinfo1, int *OSinfo2,
+ int *status, Packet **packet)
+{
+ unsigned int reason;
+
+#ifdef DEBUG
+ angel_DebugPrint("wait_for_debug_message waiting for %X\n", *rcode);
+#endif
+
+ for ( ; dbgmsg_state.received == 0 ; )
+ Adp_AsynchronousProcessing(async_block_on_read);
+
+#ifdef DEBUG
+ angel_DebugPrint("wait_for_debug_message got packet\n");
+#endif
+
+ *packet = dbgmsg_state.packet;
+
+ Adp_ChannelRegisterRead(CI_HADP, NULL, NULL);
+
+ /*
+ * TODO:
+ * If ADP_Unrecognised return error.
+ * If ADP_Acknowledge - handle appropriately.
+ * If expected message read arguments and return RDIError_NoError.
+ * Note: if RDIError occurs then the data values returned are junk
+ */
+
+ unpack_message(BUFFERDATA((*packet)->pk_buffer), "%w%w%w%w%w", &reason, debugID,
+ OSinfo1, OSinfo2, status);
+ if (reason&0xffffff == ADP_HADPUnrecognised)
+ return RDIError_UnimplementedMessage;
+ if (reason != (unsigned ) *rcode) {
+ if((reason&0xffffff) == ADP_HADPUnrecognised)
+ return RDIError_UnimplementedMessage;
+ else {
+ angel_DebugPrint("ARDI ERROR: Expected reasoncode %x got reasoncode %x.\n",
+ *rcode, reason);
+ return RDIError_Error;
+ }
+ }
+ else
+ return RDIError_NoError;
+ return RDIError_Error; /* stop a pesky ANSI compiler warning */
+}
+
+
+/*
+ * Handler and registration for logging messages from target
+ */
+static void TargetLogCallback( Packet *packet, void *state )
+{
+ p_Buffer reply = BUFFERDATA(packet->pk_buffer);
+ unsigned int len = packet->pk_length;
+ IGNORE(state);
+ angel_hostif->write(angel_hostif->hostosarg,
+ (char *)reply, len - CHAN_HEADER_SIZE);
+ DevSW_FreePacket(packet);
+
+ packet = DevSW_AllocatePacket(4); /* better not ask for 0 */
+ /* the reply is the ACK - any contents are ignored */
+ if (packet != NULL)
+ Adp_ChannelWrite( CI_TLOG, packet );
+}
+
+static void TargetLogInit( void )
+{
+ AdpErrs err = Adp_ChannelRegisterRead( CI_TLOG, TargetLogCallback, NULL );
+
+#ifdef DEBUG
+ if (err != adp_ok)
+ angel_DebugPrint("CI_TLOG RegisterRead failed %d\n", err);
+#else
+ IGNORE(err);
+#endif
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_open-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+typedef struct NegotiateState {
+ bool negotiate_resp;
+ bool negotiate_ack;
+ bool link_check_resp;
+ ParameterConfig *accepted_config;
+} NegotiateState;
+
+static void receive_negotiate(Packet *packet, void *stateptr)
+{
+ unsigned reason, debugID, OSinfo1, OSinfo2, status;
+ NegotiateState *n_state = (NegotiateState *)stateptr;
+ p_Buffer reply = BUFFERDATA(packet->pk_buffer);
+
+ unpack_message( reply, "%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2 );
+ reply += ADP_DEFAULT_HEADER_SIZE;
+
+#ifdef DEBUG
+ angel_DebugPrint( "receive_negotiate: reason %x\n", reason );
+#endif
+
+ switch ( reason )
+ {
+ case ADP_ParamNegotiate | TtoH:
+ {
+ n_state->negotiate_resp = TRUE;
+
+ status = GET32LE( reply );
+ reply += sizeof(word);
+#ifdef DEBUG
+ angel_DebugPrint( "ParamNegotiate status %u\n", status );
+#endif
+ if ( status == RDIError_NoError )
+ {
+ if ( Angel_ReadParamConfigMessage(
+ reply, n_state->accepted_config ) )
+ n_state->negotiate_ack = TRUE;
+ }
+ break;
+ }
+
+ case ADP_LinkCheck | TtoH:
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "PONG!\n" );
+#endif
+ n_state->link_check_resp = TRUE;
+ break;
+ }
+
+ default:
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Unexpected!\n" );
+#endif
+ break;
+ }
+ }
+ DevSW_FreePacket( packet );
+}
+
+# include <sys/types.h>
+#ifdef __unix
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+/*
+ * convert a config into a single-valued options list
+ */
+static ParameterOptions *config_to_options( const ParameterConfig *config )
+{
+ unsigned int num_params;
+ size_t size;
+ ParameterOptions *base_p;
+
+ num_params = config->num_parameters;
+ size =
+ sizeof(ParameterOptions)
+ + num_params*(sizeof(ParameterList) + sizeof(unsigned int));
+ base_p = malloc( size );
+
+ if ( base_p != NULL )
+ {
+ unsigned int u;
+ ParameterList *list_p =
+ (ParameterList *)((char *)base_p + sizeof(ParameterOptions));
+ unsigned int *option_p =
+ (unsigned int *)(list_p + num_params);
+
+ base_p->num_param_lists = num_params;
+ base_p->param_list = list_p;
+
+ for ( u = 0; u < num_params; ++u )
+ {
+ option_p[u] = config->param[u].value;
+ list_p[u].type = config->param[u].type;
+ list_p[u].num_options = 1;
+ list_p[u].option = &option_p[u];
+ }
+ }
+
+ return base_p;
+}
+
+static AdpErrs negotiate_params( const ParameterOptions *user_options )
+{
+ Packet *packet;
+ unsigned int count;
+ static Parameter params[AP_NUM_PARAMS];
+ static ParameterConfig accepted_config = { AP_NUM_PARAMS, params };
+
+ time_t t;
+
+ static volatile NegotiateState n_state = {
+ FALSE, FALSE, FALSE, &accepted_config };
+
+#ifdef DEBUG
+ angel_DebugPrint( "negotiate_params\n" );
+#endif
+
+ Adp_ChannelRegisterRead( CI_HBOOT, receive_negotiate, (void *)&n_state );
+
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
+ count = msgbuild( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
+ ADP_ParamNegotiate | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown );
+ count += Angel_BuildParamOptionsMessage(
+ BUFFERDATA(packet->pk_buffer) + count, user_options );
+ packet->pk_length = count;
+ Adp_ChannelWriteAsync( CI_HBOOT, packet );
+
+#ifdef DEBUG
+ angel_DebugPrint( "sent negotiate packet\n" );
+#endif
+
+ t=time(NULL);
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+
+ if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD) {
+ return adp_timeout_on_open;
+ }
+ } while ( ! n_state.negotiate_resp );
+
+ if ( n_state.negotiate_ack )
+ {
+ /* select accepted config */
+ Adp_Ioctl( DC_SET_PARAMS, (void *)n_state.accepted_config );
+
+ /*
+ * 960430 KWelton
+ *
+ * There is a race in the renegotiation protocol: the
+ * target has to have had time to load new config before
+ * we send the link check packet - insert a deliberate
+ * pause (100ms) to give the target some time
+ */
+ Adp_delay(100000);
+
+ /* do link check */
+ msgsend( CI_HBOOT, "%w%w%w%w", ADP_LinkCheck | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown );
+#ifdef DEBUG
+ angel_DebugPrint("sent link check\n");
+#endif
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_read);
+ } while ( ! n_state.link_check_resp );
+ Adp_initSeq();
+ }
+ return adp_ok;
+}
+
+static int late_booted = FALSE;
+static bool ardi_handler_installed = FALSE;
+
+#ifdef __unix
+static struct sigaction old_action;
+#else
+static void (*old_handler)();
+#endif
+
+static bool boot_interrupted = FALSE;
+
+static void ardi_sigint_handler(int sig) {
+#ifdef DEBUG
+ if (sig != SIGINT)
+ angel_DebugPrint("Expecting SIGINT got %d.\n", sig);
+#else
+ IGNORE(sig);
+#endif
+ boot_interrupted = TRUE;
+#ifndef __unix
+ signal(SIGINT, ardi_sigint_handler);
+#endif
+}
+
+static void install_ardi_handler( void ) {
+ if (!ardi_handler_installed) {
+ /* install a new Ctrl-C handler so we can abandon waiting */
+#ifdef __unix
+ struct sigaction new_action;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_handler = ardi_sigint_handler;
+ new_action.sa_flags = 0;
+ sigaction(SIGINT, &new_action, &old_action);
+#else
+ old_handler = signal(SIGINT, ardi_sigint_handler);
+#endif
+ ardi_handler_installed = TRUE;
+ }
+}
+
+static int angel_RDI_errmess(char *buf, int blen, int errnum);
+
+static void receive_reset_acknowledge(Packet *packet, void *stateptr) {
+ unsigned reason, debugID, OSinfo1, OSinfo2, status;
+ IGNORE(stateptr);
+
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ if (reason==(ADP_Reset | TtoH) && status==AB_NORMAL_ACK) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Successfully received normal reset acknowledgement\n");
+ late_booted = FALSE;
+#endif
+ } else if (reason==(ADP_Reset | TtoH) && status==AB_LATE_ACK) {
+ char late_msg[AdpMessLen_LateStartup];
+ int late_len;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Successfully received LATE reset acknowledgement\n");
+#endif
+ late_booted = TRUE;
+ install_ardi_handler();
+ late_len = angel_RDI_errmess(late_msg,
+ AdpMessLen_LateStartup, adp_late_startup);
+ angel_hostif->write(angel_hostif->hostosarg, late_msg, late_len);
+ } else {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Bad reset ack: reason=%8X, status=%8X\n", reason, status);
+#endif
+ }
+ DevSW_FreePacket(packet);
+}
+
+static int booted_not_received;
+static unsigned int angel_version;
+static unsigned int adp_version;
+static unsigned int arch_info;
+static unsigned int cpu_info;
+static unsigned int hw_status;
+
+static void receive_booted(Packet *packet, void *stateptr) {
+ unsigned reason, debugID, OSinfo1, OSinfo2, banner_length, bufsiz, longsiz;
+ unsigned i, count;
+
+ IGNORE(stateptr);
+
+ count = unpack_message(BUFFERDATA(packet->pk_buffer),
+ "%w%w%w%w%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &bufsiz, &longsiz,
+ &angel_version, &adp_version,
+ &arch_info, &cpu_info, &hw_status, &banner_length);
+ if (reason==(ADP_Booted | TtoH)) {
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("DEBUG: Successfully received Booted\n");
+ angel_DebugPrint(" cpu_info=%8X, hw_status=%8X, bufsiz=%d, longsiz=%d\n",
+ cpu_info, hw_status, bufsiz, longsiz);
+#endif
+ /* Get the banner from the booted message */
+ for (i=0; i<banner_length; i++)
+ angel_hostif->writec(angel_hostif->hostosarg,
+ (BUFFERDATA(packet->pk_buffer)+count)[i]);
+
+ booted_not_received=0;
+#ifndef NO_HEARTBEAT
+ heartbeat_enabled = TRUE;
+#endif
+ Armsd_BufferSize = bufsiz + CHAN_HEADER_SIZE;
+ Armsd_LongBufSize = longsiz + CHAN_HEADER_SIZE;
+ } else {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Bad Booted msg: reason=%8X\n", reason);
+#endif
+ }
+ DevSW_FreePacket(packet);
+}
+
+
+/* forward declaration */
+static int angel_negotiate_defaults( void );
+
+/* Open communications. */
+int angel_RDI_open(
+ unsigned type, Dbg_ConfigBlock const *config,
+ Dbg_HostosInterface const *hostif, struct Dbg_MCState *dbg_state)
+{
+ Packet *packet;
+ int status, reasoncode, debugID, OSinfo1, OSinfo2, err;
+ ParameterOptions *user_options = NULL;
+
+ time_t t;
+
+ IGNORE( dbg_state );
+
+ if ((type & 1) == 0) {
+ /* cold start */
+ if (hostif != NULL) {
+ angel_hostif = hostif;
+ err = HostSysInit(hostif, &ardi_commandline, &hstate);
+ if (err != RDIError_NoError) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: HostSysInit error %i\n",err);
+#endif
+ return err;
+ }
+ }
+ TargetLogInit();
+ }
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Buffer allocated in angel_RDI_open(type=%i).\n",type);
+#endif
+
+ if ((type & 1) == 0) {
+ /* cold start */
+ unsigned endian;
+ Adp_Ioctl( DC_GET_USER_PARAMS, (void *)&user_options );
+ if ( user_options != NULL ) {
+ err = negotiate_params( user_options );
+ if (err != adp_ok) return err;
+ }
+ else {
+ ParameterConfig *default_config = NULL;
+ Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
+ if ( default_config != NULL ) {
+ ParameterOptions *default_options = config_to_options(default_config);
+ err = negotiate_params( default_options );
+ if (err != adp_ok) return err;
+ }
+ }
+
+ /* Register handlers before sending any messages */
+ booted_not_received=1;
+ Adp_ChannelRegisterRead(CI_HBOOT, receive_reset_acknowledge, NULL);
+ Adp_ChannelRegisterRead(CI_TBOOT, receive_booted, NULL);
+ endian = 0;
+ if (config!=NULL) {
+ if (config->bytesex & RDISex_Little) endian |= ADP_BootHostFeature_LittleEnd;
+ if (config->bytesex & RDISex_Big) endian |= ADP_BootHostFeature_BigEnd;
+ }
+ msgsend(CI_HBOOT,"%w%w%w%w%w", ADP_Reset | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, endian);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted Reset message in angel_RDI_open.\n");
+#endif
+
+ /* We will now either get an acknowledgement for the Reset message
+ * or if the target was started after the host, we will get a
+ * rebooted message first.
+ */
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: waiting for a booted message\n");
+#endif
+
+ {
+ boot_interrupted = FALSE;
+
+ if (late_booted)
+ install_ardi_handler();
+
+ t=time(NULL);
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+ if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD && !late_booted) {
+ return adp_timeout_on_open;
+ }
+ } while (booted_not_received && !boot_interrupted);
+
+ if (ardi_handler_installed)
+ {
+ /* uninstall our Ctrl-C handler */
+#ifdef __unix
+ sigaction(SIGINT, &old_action, NULL);
+#else
+ signal(SIGINT, old_handler);
+#endif
+ }
+
+ if (boot_interrupted) {
+ angel_negotiate_defaults();
+ return adp_abandon_boot_wait;
+ }
+ }
+
+ booted_not_received=1;
+ Adp_ChannelRegisterRead(CI_HBOOT, NULL, NULL);
+
+ /* Leave the booted handler installed */
+ msgsend(CI_TBOOT, "%w%w%w%w%w", ADP_Booted | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, 0);
+ Adp_initSeq();
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted ADP_Booted acknowledgement.\n");
+ angel_DebugPrint("DEBUG: Boot sequence completed, leaving angel_RDI_open.\n");
+#endif
+
+ return (hw_status & ADP_CPU_BigEndian )? RDIError_BigEndian :
+ RDIError_LittleEndian;
+ }
+ else {
+ /* warm start */
+ register_debug_message_handler();
+
+ msgsend(CI_HADP, "%w%w%w%w",
+ ADP_InitialiseApplication | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted Initialise Application\n");
+#endif
+ reasoncode=ADP_InitialiseApplication | TtoH;
+ err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) return err;
+ return status;
+ }
+ return -1;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_close----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+static int angel_negotiate_defaults( void ) {
+ int err = adp_ok;
+ ParameterConfig *default_config = NULL;
+ Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
+ if ( default_config != NULL ) {
+ ParameterOptions *default_options = config_to_options(default_config);
+ err = negotiate_params( default_options );
+ free( default_options );
+ }
+ return err;
+}
+
+int angel_RDI_close(void) {
+/*Angel host exit */
+ int err;
+ int status,debugID, OSinfo1,OSinfo2;
+ int reason;
+ Packet *packet = NULL;;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_Close.\n");
+#endif
+
+ register_debug_message_handler();
+
+ heartbeat_enabled = FALSE;
+
+ err = msgsend(CI_HADP,"%w%w%w%w",ADP_End | HtoT,0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+ if (err != RDIError_NoError) return err;
+ reason = ADP_End | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError) return err;
+ if (status == RDIError_NoError) {
+ err = angel_negotiate_defaults();
+ if (err != adp_ok) return err;
+ Adp_Ioctl( DC_RESET, NULL ); /* just to be safe */
+ return HostSysExit(hstate);
+ }
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_read-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Read memory contents from target to host: use ADP_Read */
+int angel_RDI_read(ARMword source, void *dest, unsigned *nbytes)
+{
+ Packet *packet=NULL;
+ int len; /* Integer to hold message length. */
+ unsigned int nbtogo = *nbytes, nbinpacket, nbdone=0;
+ int rnbytes = 0, status, reason, debugID, OSinfo1, OSinfo2, err;
+ unsigned int maxlen = Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ReadHeaderSize;
+
+ /* Print debug trace information, this is just copied straight from rdi.c
+ and I can see no reason why it should have to be changed. */
+ TracePrint(("angel_RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
+ (unsigned long)source, dest, *nbytes));
+ if (*nbytes == 0) return RDIError_NoError; /* Read nothing - easy! */
+ /* check the buffer size */
+ while (nbtogo >0) {
+ register_debug_message_handler();
+
+ nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
+ len = msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Read | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, source+nbdone,
+ nbinpacket);
+ reason=ADP_Read | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ TracePrint(("angel_RDI_read: nbinpacket =%d status=%08x err = %d\n",
+ nbinpacket,status,err));
+ if (err != RDIError_NoError) return err; /* Was there an error? */
+ if (status == RDIError_NoError){
+ rnbytes += PREAD(LE,(unsigned int *)(BUFFERDATA(packet->pk_buffer)+20));
+ TracePrint(("angel_RDI_read: rnbytes = %d\n",rnbytes));
+ memcpy(((unsigned char *)dest)+nbdone, BUFFERDATA(packet->pk_buffer)+24,
+ nbinpacket);
+ }
+ nbdone += nbinpacket;
+ nbtogo -= nbinpacket;
+ }
+ *nbytes -= rnbytes;
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_write----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Transfer memory block from host to target. Use ADP_Write>. */
+int angel_RDI_write(const void *source, ARMword dest, unsigned *nbytes)
+{
+ Packet *packet;/* Message buffers. */
+ unsigned int len, nbtogo = *nbytes, nboffset = 0, nbinpacket;
+ int status, reason, debugID, OSinfo1, OSinfo2, err;
+ unsigned int maxlen = Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_WriteHeaderSize;
+
+ TracePrint(("angel_RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
+ source, (unsigned long)dest, *nbytes));
+
+ if (*nbytes == 0) return RDIError_NoError;
+
+ *nbytes = 0;
+ while (nbtogo > 0) {
+ packet = (Packet *) DevSW_AllocatePacket(Armsd_LongBufSize);
+ nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ ADP_Write | HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, dest+nboffset, nbinpacket);
+ /* Copy the data into the packet. */
+
+ memcpy(BUFFERDATA(packet->pk_buffer)+len,
+ ((const unsigned char *) source)+nboffset, nbinpacket);
+ nboffset += nbinpacket;
+ packet->pk_length = nbinpacket+len;
+
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("angel_RDI_write packet size=%i, bytes done=%i\n",
+ nbinpacket, nboffset);
+#endif
+
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_Write | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ nbtogo -= nbinpacket;
+ if (err != RDIError_NoError) return err;
+ if (status == RDIError_NoError)
+ *nbytes += nbinpacket;
+
+ DevSW_FreePacket(packet);
+ }
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPUread--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Reads the values of registers in the CPU, uses ADP_CPUwrite. */
+int angel_RDI_CPUread(unsigned mode, unsigned long mask, ARMword *buffer)
+{
+ unsigned int i, j;
+ Packet *packet = NULL;
+ int err, status, reason, debugID, OSinfo1, OSinfo2;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_CPUread.\n");
+#endif
+ for (i=0, j=0 ; i < RDINumCPURegs ; i++)
+ if (mask & (1L << i)) j++; /* Count the number of registers. */
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%c%w", ADP_CPUread | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
+ reason = ADP_CPUread | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ if(status == RDIError_NoError) {
+ for (i=0; i<j; i++)
+ buffer[i] = GET32LE(BUFFERDATA(packet->pk_buffer)+20+(i*4));
+ TracePrint(("angel_RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask));
+ DevSW_FreePacket(packet);
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ unsigned k;
+ for (k = 0, j = 0 ; j <= 20 ; j++)
+ if (mask & (1L << j)) {
+ angel_DebugPrint("%c%.8lx",k%4==0?'\n':' ',
+ (unsigned long)buffer[k]);
+ k++ ;
+ }
+ angel_DebugPrint("\n") ;
+ }
+#endif
+
+ }
+ return status;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPUwrite-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Write CPU registers: use ADP_CPUwrite. */
+int angel_RDI_CPUwrite(unsigned mode, unsigned long mask,
+ ARMword const *buffer){
+
+ unsigned i, j, c;
+ Packet *packet;
+ int status, reason, debugID, OSinfo1, OSinfo2, err, len;
+
+ TracePrint(("angel_RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (j = 0, i = 0 ; i <= 20 ; i++)
+ if (mask & (1L << i)) {
+ angel_DebugPrint("%c%.8lx",j%4==0?'\n':' ',
+ (unsigned long)buffer[j]);
+ j++ ;
+ }
+ angel_DebugPrint("\n") ;
+ }
+#endif
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
+ for (i=0, j=0; i < RDINumCPURegs ; i++)
+ if (mask & (1L << i)) j++; /* count the number of registers */
+
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%b%w",
+ ADP_CPUwrite | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
+ for(c=0; c<j; c++)
+ PUT32LE(BUFFERDATA(packet->pk_buffer)+len+(c*4), buffer[c]);
+ packet->pk_length = len+(j*4);
+ register_debug_message_handler();
+
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ADP_CPUwrite | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError)
+ return err; /* Was there an error? */
+ else
+ return status;
+ }
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPread---------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Read coprocessor's internal state. See dbg_cp.h for help.
+ * Use ADP_CPRead.
+ * It would appear that the correct behaviour at this point is to leave
+ * the unpacking to a the caller and to simply copy the stream of data
+ * words into the buffer
+ */
+
+int angel_RDI_CPread(unsigned CPnum, unsigned long mask, ARMword *buffer){
+ Packet *packet = NULL;
+ int i, j, status, reasoncode, OSinfo1, OSinfo2, err, debugID;
+ unsigned char *rmap = cpwords[CPnum];
+ int n;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_CPread.\n");
+#endif
+ if (rmap == NULL) return RDIError_UnknownCoPro;
+
+ register_debug_message_handler();
+ n = rmap[-1];
+ msgsend(CI_HADP, "%w%w%w%w%b%w", ADP_CPread | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
+ reasoncode=ADP_CPread | TtoH;
+ err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ for (j=i=0; i < n ; i++) /* count the number of registers */
+ if (mask & (1L << i)) {
+ j++;
+ }
+ for (i=0; i<j; i++)
+ buffer[i] = PREAD32(LE, BUFFERDATA(packet->pk_buffer) + 20 + (i*4));
+ DevSW_FreePacket(packet);
+ TracePrint(("angel_RDI_CPread: CPnum=%.8x mask=%.8lx\n", CPnum, mask));
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (i = 0, j = 0; j < n ; j++) {
+ if (mask & (1L << j)) {
+ int nw = rmap[j];
+ angel_DebugPrint("%2d ", j);
+ while (--nw > 0)
+ angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
+ angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
+ }
+ }
+ }
+#endif
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPwrite--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Write coprocessor's internal state. See dbg_cp.h for help. Use
+ * ADP_CPwrite.
+ */
+
+int angel_RDI_CPwrite(unsigned CPnum, unsigned long mask,
+ ARMword const *buffer)
+{
+ Packet *packet = NULL;
+ int i, j, len, status, reason, OSinfo1, OSinfo2, err, debugID;
+ unsigned char *rmap = cpwords[CPnum];
+ int n;
+
+ if (rmap == NULL) return RDIError_UnknownCoPro;
+ n = rmap[-1];
+
+ TracePrint(("angel_RDI_CPwrite: CPnum=%d mask=%.8lx\n", CPnum, mask));
+
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (i = 0, j = 0; j < n ; j++)
+ if (mask & (1L << j)) {
+ int nw = rmap[j];
+ angel_DebugPrint("%2d ", j);
+ while (--nw > 0)
+ angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
+ angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
+ }
+ }
+#endif
+
+ for (j=i=0; i < n ; i++) /* Count the number of registers. */
+ if (mask & (1L << i)) j++;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%c%w",
+ ADP_CPwrite | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
+ for(i=0; i<j; i++)
+ len+=msgbuild(BUFFERDATA(packet->pk_buffer) + len, "%w", buffer[i]);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason=ADP_CPwrite | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError)
+ return err;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_pointinq-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Do test calls to ADP_SetBreak/ADP_SetWatch to see if resources exist to
+ carry out request. */
+int angel_RDI_pointinq(ARMword *address, unsigned type, unsigned datatype,
+ ARMword *bound)
+{
+ Packet *packet = NULL;
+ int len, status, reason, OSinfo1, OSinfo2, err=RDIError_NoError;
+ /* stop a compiler warning */
+ int debugID, pointhandle;
+ TracePrint(
+ ("angel_RDI_pointinq: address=%.8lx type=%d datatype=%d bound=%.8lx ",
+ (unsigned long)*address, type, datatype, (unsigned long)*bound));
+ /* for a buffer. */
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b",
+ ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch) | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, address, type);
+ if (datatype == 0)
+ len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%w", bound);
+ else
+ len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%b%w", datatype, bound);
+
+ register_debug_message_handler();
+ packet->pk_length = len;
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch | TtoH);
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ &pointhandle, &address, &bound);
+ DevSW_FreePacket(packet);
+ return err;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_setbreak-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Set a breakpoint: Use ADP_SetBreak */
+int angel_RDI_setbreak(ARMword address, unsigned type, ARMword bound,
+ PointHandle *handle)
+{
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+ int tmpval, tmpaddr, tmpbnd;
+ Packet *packet;
+ TracePrint(("angel_RDI_setbreak address=%.8lx type=%d bound=%.8lx \n",
+ (unsigned long)address, type, (unsigned long)bound));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b%w",
+ ADP_SetBreak| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, address, type, bound);
+ reason = ADP_SetBreak |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ /* Work around varargs problem... -sts */
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ &tmpval, &tmpaddr, &tmpbnd);
+ *handle = tmpval;
+ address = tmpaddr;
+ bound = tmpbnd;
+ DevSW_FreePacket(packet);
+ if (status != RDIError_NoError) return status;
+ TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
+ return RDIError_NoError;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_clearbreak-----------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Clear a breakpoint: Use ADP_ClearBreak. */
+int angel_RDI_clearbreak(PointHandle handle)
+{
+ Packet *packet = NULL;
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+
+ TracePrint(("angel_RDI_clearbreak: handle=%.8lx\n", (unsigned long)handle));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w",
+ ADP_ClearBreak| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, handle);
+ reason = ADP_ClearBreak|TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ angel_DebugPrint("***RECEIVE DEBUG MESSAGE RETURNED ERR = %d.\n", err);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Clear Break completed OK.\n");
+#endif
+ return RDIError_NoError;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_setwatch-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Set a watchpoint: use ADP_SetWatch. */
+int angel_RDI_setwatch(ARMword address, unsigned type, unsigned datatype,
+ ARMword bound, PointHandle *handle)
+{
+ Packet *packet = NULL;
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+
+ TracePrint(("angel_RDI_setwatch: address=%.8lx type=%d bound=%.8lx ",
+ (unsigned long)address, type, (unsigned long)bound));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b%b%w",
+ ADP_SetWatch| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, address, type, datatype, bound);
+
+ reason = ADP_SetWatch | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ handle, &address, &bound);
+ DevSW_FreePacket(packet);
+ TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
+ return RDIError_NoError;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_clearwatch-----------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Clear a watchpoint: use ADP_ClearWatch. */
+int angel_RDI_clearwatch(PointHandle handle) {
+
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+ Packet *packet = NULL;
+
+ TracePrint(("angel_RDI_clearwatch: handle=%.8lx\n", (unsigned long)handle));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w",
+ ADP_ClearWatch| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, handle);
+ reason = ADP_ClearWatch|TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+ return RDIError_NoError;
+}
+
+typedef struct {
+ unsigned stopped_reason;
+ int stopped_status;
+ int data;
+} adp_stopped_struct;
+
+
+int angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc *fn,
+ void *arg)
+{
+ stoppedProcListElement **lptr = &stopped_proc_list;
+
+ /* Find the address of the NULL ptr at the end of the list */
+ for (; *lptr!=NULL ; lptr = &((*lptr)->next))
+ ; /* Do nothing */
+
+ *lptr = (stoppedProcListElement *) malloc(sizeof(stoppedProcListElement));
+ if (*lptr == NULL) return RDIError_OutOfStore;
+ (*lptr)->fn = fn;
+ (*lptr)->arg = arg;
+
+ return RDIError_NoError;
+}
+
+static int CallStoppedProcs(unsigned reason)
+{
+ stoppedProcListElement *p = stopped_proc_list;
+ int err=RDIError_NoError;
+
+ for (; p!=NULL ; p=p->next) {
+ int local_err = p->fn(reason, p->arg);
+ if (local_err != RDIError_NoError) err=local_err;
+ }
+
+ return err;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_execute--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+static int HandleStoppedMessage(Packet *packet, void *stateptr) {
+ unsigned int err, reason, debugID, OSinfo1, OSinfo2, count;
+ adp_stopped_struct *stopped_info;
+ stopped_info = (adp_stopped_struct *) stateptr;
+ IGNORE(stateptr);
+ count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ &reason, &debugID,
+ &OSinfo1, &OSinfo2,
+ &stopped_info->stopped_reason, &stopped_info->data);
+ DevSW_FreePacket(packet);
+
+ if (reason != (ADP_Stopped | TtoH)) {
+#ifdef DEBUG
+ angel_DebugPrint("Expecting stopped message, got %x", reason);
+#endif
+ return RDIError_Error;
+ }
+ else {
+ executing = FALSE;
+#ifdef DEBUG
+ angel_DebugPrint("Received stopped message.\n");
+#endif
+ }
+
+ err = msgsend(CI_TADP, "%w%w%w%w%w", (ADP_Stopped | HtoT), 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, RDIError_NoError);
+#ifdef DEBUG
+ angel_DebugPrint("Transmiting stopped acknowledge.\n");
+#endif
+ if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Stopped reason : %x\n", stopped_info->stopped_reason);
+#endif
+ switch (stopped_info->stopped_reason) {
+ case ADP_Stopped_BranchThroughZero:
+ stopped_info->stopped_status = RDIError_BranchThrough0;
+ break;
+ case ADP_Stopped_UndefinedInstr:
+ stopped_info->stopped_status = RDIError_UndefinedInstruction;
+ break;
+ case ADP_Stopped_SoftwareInterrupt:
+ stopped_info->stopped_status = RDIError_SoftwareInterrupt;
+ break;
+ case ADP_Stopped_PrefetchAbort:
+ stopped_info->stopped_status = RDIError_PrefetchAbort;
+ break;
+ case ADP_Stopped_DataAbort:
+ stopped_info->stopped_status = RDIError_DataAbort;
+ break;
+ case ADP_Stopped_AddressException:
+ stopped_info->stopped_status = RDIError_AddressException;
+ break;
+ case ADP_Stopped_IRQ:
+ stopped_info->stopped_status = RDIError_IRQ;
+ break;
+ case ADP_Stopped_BreakPoint:
+ stopped_info->stopped_status = RDIError_BreakpointReached;
+ break;
+ case ADP_Stopped_WatchPoint:
+ stopped_info->stopped_status = RDIError_WatchpointAccessed;
+ break;
+ case ADP_Stopped_StepComplete:
+ stopped_info->stopped_status = RDIError_ProgramFinishedInStep;
+ break;
+ case ADP_Stopped_RunTimeErrorUnknown:
+ case ADP_Stopped_StackOverflow:
+ case ADP_Stopped_DivisionByZero:
+ stopped_info->stopped_status = RDIError_Error;
+ break;
+ case ADP_Stopped_FIQ:
+ stopped_info->stopped_status = RDIError_FIQ;
+ break;
+ case ADP_Stopped_UserInterruption:
+ case ADP_Stopped_OSSpecific:
+ stopped_info->stopped_status = RDIError_UserInterrupt;
+ break;
+ case ADP_Stopped_ApplicationExit:
+ stopped_info->stopped_status = RDIError_NoError;
+ break;
+ default:
+ stopped_info->stopped_status = RDIError_NoError;
+ break;
+ }
+ return RDIError_NoError;
+}
+
+static volatile bool interrupt_request = FALSE;
+
+static void interrupt_target( void )
+{
+ Packet *packet = NULL;
+ int err;
+ int reason, debugID, OSinfo1, OSinfo2, status;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: interrupt_target.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w", ADP_InterruptRequest | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+
+ reason = ADP_InterruptRequest |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: got interrupt ack ok err = %d, status=%i\n",
+ err, status);
+#endif
+
+ return;
+}
+
+#ifdef TEST_DC_APPL
+ extern void test_dc_appl_handler( const DeviceDescr *device,
+ Packet *packet );
+#endif
+
+/* Core functionality for execute and step */
+static int angel_RDI_ExecuteOrStep(PointHandle *handle, word type,
+ unsigned ninstr)
+{
+ int err;
+ adp_stopped_struct stopped_info;
+ void* stateptr = (void *)&stopped_info;
+ ChannelCallback HandleStoppedMessageFPtr=(ChannelCallback) HandleStoppedMessage;
+ int status, reasoncode, debugID, OSinfo1, OSinfo2;
+ Packet *packet = NULL;
+
+ TracePrint(("angel_RDI_ExecuteOrStep\n"));
+
+ err = Adp_ChannelRegisterRead(CI_TADP,
+ HandleStoppedMessageFPtr, stateptr);
+ if (err != RDIError_NoError) {
+#ifdef DEBUG
+ angel_DebugPrint("TADP Register failed.\n");
+#endif
+ return err;
+ }
+ /* Set executing TRUE here, as it must be set up before the target has
+ * had any chance at all to execute, or it may send its stopped message
+ * before we get round to setting executing = TRUE !!!
+ */
+ executing = TRUE;
+
+ register_debug_message_handler();
+
+#ifdef TEST_DC_APPL
+ Adp_Install_DC_Appl_Handler( test_dc_appl_handler );
+#endif
+
+#ifdef DEBUG
+ angel_DebugPrint("Transmiting %s message.\n",
+ type == ADP_Execute ? "execute": "step");
+#endif
+
+ register_debug_message_handler();
+ /* Extra ninstr parameter for execute message will simply be ignored */
+ err = msgsend(CI_HADP,"%w%w%w%w%w", type | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ninstr);
+#if DEBUG
+ if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
+#endif
+
+ reasoncode = type | TtoH;
+ err = wait_for_debug_message( &reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet );
+ if (err != RDIError_NoError)
+ return err;
+ else if (status != RDIError_NoError)
+ return status;
+
+#ifdef DEBUG
+ angel_DebugPrint("Waiting for program to finish...\n");
+#endif
+
+ while( executing )
+ {
+ if (interrupt_request)
+ {
+ interrupt_target();
+ interrupt_request = FALSE;
+ }
+ Adp_AsynchronousProcessing( async_block_on_nothing );
+ }
+
+#ifdef TEST_DC_APPL
+ Adp_Install_DC_Appl_Handler( NULL );
+#endif
+
+ (void)Adp_ChannelRegisterRead(CI_TADP, NULL, NULL);
+
+ *handle = (PointHandle)stopped_info.data;
+
+ CallStoppedProcs(stopped_info.stopped_reason);
+
+ return stopped_info.stopped_status;
+}
+
+/* Request that the target starts executing from the stored CPU state: use
+ ADP_Execute. */
+int angel_RDI_execute(PointHandle *handle)
+{
+ return angel_RDI_ExecuteOrStep(handle, ADP_Execute, 0);
+}
+
+#ifdef __WATCOMC__
+typedef void handlertype(int);
+
+static int interrupted=0;
+
+static void myhandler(int sig) {
+ IGNORE(sig);
+ interrupted=1;
+ signal(SIGINT, myhandler);
+}
+#endif
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_step-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Step 'ninstr' through the code: use ADP_Step. */
+int angel_RDI_step(unsigned ninstr, PointHandle *handle)
+{
+ int err = angel_RDI_ExecuteOrStep(handle, ADP_Step, ninstr);
+ if (err == RDIError_ProgramFinishedInStep)
+ return RDIError_NoError;
+ else
+ return err;
+}
+
+
+static void SetCPWords(int cpnum, struct Dbg_CoProDesc const *cpd) {
+ int i, rmax = 0;
+ for (i = 0; i < cpd->entries; i++)
+ if (cpd->regdesc[i].rmax > rmax)
+ rmax = cpd->regdesc[i].rmax;
+
+ { unsigned char *rmap = (unsigned char *)malloc(rmax + 2);
+ *rmap++ = rmax + 1;
+ for (i = 0; i < cpd->entries; i++) {
+ int r;
+ for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++)
+ rmap[r] = (cpd->regdesc[i].nbytes+3) / 4;
+ }
+/* if (cpwords[cpnum] != NULL) free(cpwords[cpnum]); */
+ cpwords[cpnum] = rmap;
+ }
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_info-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Use ADP_Info, ADP_Ctrl and ADP_Profile calls to implement these,
+ see adp.h for more details. */
+
+static int angel_cc_exists( void )
+{
+ Packet *packet = NULL;
+ int err;
+ int reason, debugID, OSinfo1, OSinfo2, subreason, status;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Exists.\n");
+#endif
+
+ if ( angel_RDI_info( RDIInfo_Icebreaker, NULL, NULL ) == RDIError_NoError ) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Exists );
+ reason = ADP_ICEbreakerHADP |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_ICEB_CC_Exists) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+ }
+ else
+ return RDIError_UnimplementedMessage;
+}
+
+typedef struct {
+ RDICCProc_ToHost *tohost; void *tohostarg;
+ RDICCProc_FromHost *fromhost; void *fromhostarg;
+ bool registered;
+} CCState;
+static CCState ccstate = { NULL, NULL, NULL, NULL, FALSE };
+
+static void HandleDCCMessage( Packet *packet, void *stateptr )
+{
+ unsigned int reason, debugID, OSinfo1, OSinfo2;
+ int count;
+ CCState *ccstate_p = (CCState *)stateptr;
+
+ count = unpack_message( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2 );
+ switch ( reason )
+ {
+ case ADP_TDCC_ToHost | TtoH:
+ {
+ /* only handles a single word of data, for now */
+
+ unsigned int nbytes, data;
+
+ unpack_message( BUFFERDATA(packet->pk_buffer)+count, "%w%w",
+ &nbytes, &data );
+#ifdef DEBUG
+ angel_DebugPrint( "DEBUG: received CC_ToHost message: nbytes %d data %08x.\n",
+ nbytes, data );
+#endif
+ ccstate_p->tohost( ccstate_p->tohostarg, data );
+ msgsend(CI_TTDCC, "%w%w%w%w%w",
+ ADP_TDCC_ToHost | HtoT, debugID, OSinfo1, OSinfo2,
+ RDIError_NoError );
+ break;
+ }
+
+ case ADP_TDCC_FromHost | TtoH:
+ {
+ /* only handles a single word of data, for now */
+
+ int valid;
+ ARMword data;
+
+ ccstate_p->fromhost( ccstate_p->fromhostarg, &data, &valid );
+#ifdef DEBUG
+ angel_DebugPrint( "DEBUG: received CC_FromHost message, returning: %08x %s.\n",
+ data, valid ? "VALID" : "INvalid" );
+#endif
+ msgsend(CI_TTDCC, "%w%w%w%w%w%w%w",
+ ADP_TDCC_FromHost | HtoT, debugID, OSinfo1, OSinfo2,
+ RDIError_NoError, valid ? 1 : 0, data );
+ break;
+ }
+
+ default:
+#ifdef DEBUG
+ angel_DebugPrint( "Unexpected TDCC message %08x received\n", reason );
+#endif
+ break;
+ }
+ DevSW_FreePacket(packet);
+ return;
+}
+
+static void angel_check_DCC_handler( CCState *ccstate_p )
+{
+ int err;
+
+ if ( ccstate_p->tohost != NULL || ccstate_p->fromhost != NULL )
+ {
+ /* doing DCC, so need a handler */
+ if ( ! ccstate_p->registered )
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Registering handler for TTDCC channel.\n" );
+#endif
+ err = Adp_ChannelRegisterRead( CI_TTDCC, HandleDCCMessage,
+ ccstate_p );
+ if ( err == adp_ok )
+ ccstate_p->registered = TRUE;
+#ifdef DEBUG
+ else
+ angel_DebugPrint( "angel_check_DCC_handler: register failed!\n" );
+#endif
+ }
+ }
+ else
+ {
+ /* not doing DCC, so don't need a handler */
+ if ( ccstate_p->registered )
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Unregistering handler for TTDCC channel.\n" );
+#endif
+ err = Adp_ChannelRegisterRead( CI_TTDCC, NULL, NULL );
+ if ( err == adp_ok )
+ ccstate_p->registered = FALSE;
+#ifdef DEBUG
+ else
+ angel_DebugPrint( "angel_check_DCC_handler: unregister failed!\n" );
+#endif
+ }
+ }
+}
+
+
+static int CheckSubMessageReply(int reason, int subreason) {
+ Packet *packet = NULL;
+ int status, debugID, OSinfo1, OSinfo2;
+ int err = RDIError_NoError;
+ reason |= TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ status = err;
+ } else {
+ int sr;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &sr, &status);
+ if (subreason != sr) status = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ return status;
+}
+
+static int SendSubMessageAndCheckReply(int reason, int subreason) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason);
+ return CheckSubMessageReply(reason, subreason);
+}
+
+static int SendSubMessageWordAndCheckReply(int reason, int subreason, ARMword word) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason, word);
+ return CheckSubMessageReply(reason, subreason);
+}
+
+static int SendSubMessageGetWordAndCheckReply(int reason, int subreason, ARMword *resp) {
+ Packet *packet = NULL;
+ int status, debugID, OSinfo1, OSinfo2;
+ int err = RDIError_NoError;
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason);
+ reason |= TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ status = err;
+ } else {
+ int sr;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &sr, &status, resp);
+ if (subreason != sr) status = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ return status;
+}
+
+static int const hostsex = 1;
+
+int angel_RDI_info(unsigned type, ARMword *arg1, ARMword *arg2) {
+ Packet *packet = NULL;
+ int len, status, c, reason, subreason, debugID, OSinfo1, OSinfo2;
+ int err=RDIError_NoError, cpnum=0;
+ struct Dbg_CoProDesc *cpd;
+ int count, i;
+ unsigned char *bp;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_info.\n");
+#endif
+ switch (type) {
+ case RDIInfo_Target:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Target.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Target);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ DevSW_FreePacket(packet);
+
+ if (subreason != ADP_Info_Target)
+ return RDIError_Error;
+ else
+ return status;
+
+ case RDISignal_Stop:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDISignal_Stop.\n");
+ if (interrupt_request)
+ angel_DebugPrint(" STILL WAITING to send previous interrupt request\n");
+#endif
+ interrupt_request = TRUE;
+ return RDIError_NoError;
+
+ case RDIInfo_Points:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Points.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Points, arg1);
+
+ case RDIInfo_Step:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Step.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Step, arg1);
+
+ case RDISet_Cmdline:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDISet_Cmdline.\n");
+#endif
+ if (ardi_commandline != &dummycline)
+ free(ardi_commandline);
+ ardi_commandline = (char *)malloc(strlen((char*)arg1) + 1) ;
+ (void)strcpy(ardi_commandline, (char *)arg1) ;
+ return RDIError_NoError;
+
+ case RDIInfo_SetLog:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_SetLog.\n");
+#endif
+ rdi_log = (int) *arg1;
+ return RDIError_NoError;
+
+ case RDIInfo_Log:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Log.\n");
+#endif
+ *arg1 = rdi_log;
+ return RDIError_NoError;
+
+
+ case RDIInfo_MMU:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_MMU.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_MMU, arg1);
+
+ case RDIInfo_SemiHosting:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_SemiHosting.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_SemiHosting);
+
+ case RDIInfo_CoPro:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_CoPro.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CoPro);
+
+ case RDICycles:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDICycles.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Cycles);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if (subreason != ADP_Info_Cycles)
+ return RDIError_Error;
+ if (status != RDIError_NoError) return status;
+ for (c=0; c<12; c++)
+ arg1[c]=GET32LE(BUFFERDATA(packet->pk_buffer)+24+(c*4));
+ return status;
+
+ case RDIInfo_DescribeCoPro:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_DescribeCoPro.\n");
+#endif
+ cpnum = *(int *)arg1;
+ cpd = (struct Dbg_CoProDesc *)arg2;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (angel_RDI_info(ADP_Info_CoPro, NULL, NULL) != RDIError_NoError)
+ return RDIError_Error;
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_DescribeCoPro);
+ len +=msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b%b%b%b%b", cpnum,
+ cpd->regdesc[cpnum].rmin, cpd->regdesc[cpnum].rmax,
+ cpd->regdesc[cpnum].nbytes, cpd->regdesc[cpnum].access);
+ if (cpd->regdesc[cpnum].access&0x3 == 0x3){
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b",
+ cpd->regdesc[cpnum].accessinst.cprt.read_b0,
+ cpd->regdesc[cpnum].accessinst.cprt.read_b1,
+ cpd->regdesc[cpnum].accessinst.cprt.write_b0,
+ cpd->regdesc[cpnum].accessinst.cprt.write_b1, 0xff);
+ }
+ else {
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b%",
+ cpd->regdesc[cpnum].accessinst.cpdt.rdbits,
+ cpd->regdesc[cpnum].accessinst.cpdt.nbit,0,0, 0xff);
+ }
+ register_debug_message_handler();
+ packet->pk_length = len;
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if (subreason != ADP_Info_DescribeCoPro)
+ return RDIError_Error;
+ else
+ return status;
+
+ case RDIInfo_RequestCoProDesc:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_RequestCoProDesc.\n");
+#endif
+ cpnum = *(int *)arg1;
+ cpd = (struct Dbg_CoProDesc *)arg2;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_RequestCoProDesc);
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b", *(int *)arg1);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Info_RequestCoProDesc) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ } else if ( status != RDIError_NoError ) {
+ DevSW_FreePacket(packet);
+ return status;
+ } else {
+ bp = BUFFERDATA(packet->pk_buffer)+count;
+ for ( i = 0; *bp != 0xFF && i < cpd->entries; ++i ) {
+ cpd->regdesc[i].rmin = *bp++;
+ cpd->regdesc[i].rmax = *bp++;
+ cpd->regdesc[i].nbytes = *bp++;
+ cpd->regdesc[i].access = *bp++;
+ }
+ cpd->entries = i;
+ if ( *bp != 0xFF )
+ status = RDIError_BufferFull;
+ else
+ SetCPWords( cpnum, cpd );
+ DevSW_FreePacket(packet);
+ return status;
+ }
+
+ case RDIInfo_GetLoadSize:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_AngelBufferSize);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Info_AngelBufferSize) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else {
+ word defaultsize, longsize;
+ unpack_message(BUFFERDATA(packet->pk_buffer)+24, "%w%w",
+ &defaultsize, &longsize);
+ *arg1 = longsize - ADP_WriteHeaderSize; /* space for ADP header */
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize: got (%d, %d), returning %d.\n",
+ defaultsize, longsize, *arg1);
+#endif
+ DevSW_FreePacket(packet);
+ return status;
+ }
+
+ case RDIVector_Catch:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_VectorCatch %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_VectorCatch, *arg1);
+
+ case RDISemiHosting_SetState:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetState %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetState, *arg1);
+
+ case RDISemiHosting_GetState:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetState.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetState, arg1);
+
+ case RDISemiHosting_SetVector:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetVector %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetVector, *arg1);
+
+ case RDISemiHosting_GetVector:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetVector.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetVector, arg1);
+
+ case RDISemiHosting_SetARMSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetARMSWI.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetARMSWI, *arg1);
+
+ case RDISemiHosting_GetARMSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetARMSWI.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetARMSWI, arg1);
+
+ case RDISemiHosting_SetThumbSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetThumbSWI.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetThumbSWI, *arg1);
+
+ case RDISemiHosting_GetThumbSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetThumbSWI.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetThumbSWI, arg1);
+
+ case RDIInfo_SetTopMem:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SetTopMem.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SetTopMem, *arg1);
+
+ case RDIPointStatus_Watch:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Watch.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_PointStatus_Watch, *arg1 );
+ reason = ADP_Control |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ if (subreason != ADP_Ctrl_PointStatus_Watch) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+
+ case RDIPointStatus_Break:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Break.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_PointStatus_Break, *arg1 );
+ reason = ADP_Control |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ if (subreason != ADP_Ctrl_PointStatus_Break) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+
+ case RDIInfo_DownLoad:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_Download_Supported.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Control, ADP_Ctrl_Download_Supported);
+
+ case RDIConfig_Count:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEM_ConfigCount.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_ICEman, ADP_ICEM_ConfigCount, arg1);
+
+ case RDIConfig_Nth:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEM_ConfigNth.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_ConfigNth, *arg1 );
+ reason = ADP_ICEman |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ } else {
+ RDI_ConfigDesc *cd = (RDI_ConfigDesc *)arg2;
+ unsigned char n;
+ len = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%b",
+ &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status,
+ &cd->version, &n);
+ if (subreason != ADP_ICEM_ConfigNth) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else {
+ memcpy( cd->name, BUFFERDATA(packet->pk_buffer)+len, n+1 );
+ cd->name[n] = 0;
+ return status;
+ }
+ }
+
+ case RDIInfo_Icebreaker:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_Exists.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_Exists);
+
+ case RDIIcebreaker_GetLocks:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_GetLocks.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_GetLocks, arg1);
+
+ case RDIIcebreaker_SetLocks:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_SetLocks.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_SetLocks, *arg1);
+
+ case RDICommsChannel_ToHost:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_ToHost.\n");
+#endif
+ if ( angel_cc_exists() == RDIError_NoError ) {
+
+ /*
+ * The following three lines of code have to be removed in order to get
+ * the Windows Angel Channel Viewer working with the Thumb comms channel.
+ * At the moment it allows the ARMSD command line to register a CCIN/CCOUT
+ * callback which stops the ACV working!
+ */
+#ifdef __unix
+ ccstate.tohost = (RDICCProc_ToHost *)arg1;
+ ccstate.tohostarg = arg2;
+ angel_check_DCC_handler( &ccstate );
+#endif
+#ifdef _WIN32
+
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Connect_ToHost, (arg1 != NULL) );
+ return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_ToHost);
+ } else {
+ return RDIError_UnimplementedMessage;
+ }
+
+ case RDICommsChannel_FromHost:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_FromHost.\n");
+#endif
+ if ( angel_cc_exists() == RDIError_NoError ) {
+
+ ccstate.fromhost = (RDICCProc_FromHost *)arg1;
+ ccstate.fromhostarg = arg2;
+ angel_check_DCC_handler( &ccstate );
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Connect_FromHost, (arg1 != NULL) );
+ return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_FromHost);
+ } else {
+ return RDIError_UnimplementedMessage;
+ }
+
+ case RDIProfile_Stop:
+ return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_Stop);
+
+ case RDIProfile_ClearCounts:
+ return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_ClearCounts);
+
+ case RDIProfile_Start:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_Start %ld.\n", (long)*arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Profile, ADP_Profile_Start, *arg1);
+
+ case RDIProfile_WriteMap:
+ { RDI_ProfileMap *map = (RDI_ProfileMap *)arg1;
+ int32 maplen = map->len,
+ offset,
+ size;
+ int32 chunk = (Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_ProfileWriteHeaderSize) / sizeof(ARMword);
+ /* Maximum number of words sendable in one message */
+ int oldrev = bytesex_reversing();
+ int host_little = *(uint8 const *)&hostsex;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_WriteMap %ld.\n", maplen);
+#endif
+ status = RDIError_NoError;
+ if (!host_little) {
+ bytesex_reverse(1);
+ for (offset = 0; offset < maplen; offset++)
+ map->map[offset] = bytesex_hostval(map->map[offset]);
+ }
+ for (offset = 0; offset < maplen; offset += size) {
+ unsigned hdrlen;
+ size = maplen - offset;
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_LongBufSize);
+ if (size > chunk) size = chunk;
+ hdrlen = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ ADP_Profile | HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, ADP_Profile_WriteMap,
+ maplen, size, offset);
+
+ /* Copy the data into the packet. */
+ memcpy(BUFFERDATA(packet->pk_buffer)+hdrlen,
+ &map->map[offset], (size_t)size * sizeof(ARMword));
+ packet->pk_length = size * sizeof(ARMword) + hdrlen;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ADP_Profile | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err == RDIError_NoError) {
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Profile_WriteMap) {
+ err = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ }
+ if (err != RDIError_NoError) { status = err; break; }
+ }
+ if (!host_little) {
+ for (offset = 0; offset < maplen; offset++)
+ map->map[offset] = bytesex_hostval(map->map[offset]);
+ bytesex_reverse(oldrev);
+ }
+ return status;
+ }
+
+ case RDIProfile_ReadMap:
+ { int32 maplen = *(int32 *)arg1,
+ offset = 0,
+ size;
+ int32 chunk = (Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ProfileReadHeaderSize) / sizeof(ARMword);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_ReadMap %ld.\n", maplen);
+#endif
+ status = RDIError_NoError;
+ for (offset = 0; offset < maplen; offset += size) {
+ size = maplen - offset;
+ if (size > chunk) size = chunk;
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Profile | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Profile_ReadMap, offset, size);
+ reason = ADP_Profile | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) return err;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ memcpy(&arg2[offset], BUFFERDATA(packet->pk_buffer)+ADP_ProfileReadHeaderSize,
+ size * sizeof(ARMword));
+ DevSW_FreePacket(packet);
+ if (status != RDIError_NoError) break;
+ }
+ { int oldrev = bytesex_reversing();
+ int host_little = *(uint8 const *)&hostsex;
+ if (!host_little) {
+ bytesex_reverse(1);
+ for (offset = 0; offset < maplen; offset++)
+ arg2[offset] = bytesex_hostval(arg2[offset]);
+ }
+ bytesex_reverse(oldrev);
+ }
+ return status;
+ }
+
+ case RDIInfo_CanTargetExecute:
+#ifdef DEBUG
+ printf("DEBUG: RDIInfo_CanTargetExecute.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CanTargetExecute);
+
+ case RDIInfo_AgentEndianess:
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_AgentEndianess);
+
+ default:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Fell through ADP_Info, default case taken.\n");
+ angel_DebugPrint("DEBUG: type = 0x%x.\n", type);
+#endif
+ if (type & RDIInfo_CapabilityRequest) {
+ switch (type & ~RDIInfo_CapabilityRequest) {
+ case RDISemiHosting_SetARMSWI:
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_ChangeableSHSWI);
+ default:
+#ifdef DEBUG
+ angel_DebugPrint(
+ "DEBUG: ADP_Info - Capability Request(%d) - reporting unimplemented \n",
+ type & ~RDIInfo_CapabilityRequest);
+#endif
+ break;
+ }
+ }
+ return RDIError_UnimplementedMessage;
+ }
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_AddConfig------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Add a configuration: use ADP_ICEM_AddConfig. */
+int angel_RDI_AddConfig(unsigned long nbytes) {
+ Packet *packet = NULL;
+ int status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_AddConfig.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_AddConfig, nbytes);
+ reason=ADP_ICEman | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_ICEM_AddConfig )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_LoadConfigData-------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Load configuration data: use ADP_Ctrl_Download_Data. */
+int angel_RDI_LoadConfigData(unsigned long nbytes, char const *data) {
+ Packet *packet = NULL;
+ int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_LoadConfigData (%d bytes)\n", nbytes);
+#endif
+#if 0
+ if (err = angel_RDI_AddConfig(nbytes) != RDIError_NoError)
+ return err;
+#endif
+ packet = DevSW_AllocatePacket(Armsd_LongBufSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Download_Data, nbytes);
+ memcpy(BUFFERDATA(packet->pk_buffer)+len, data, nbytes);
+ len += nbytes;
+ packet->pk_length = len;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: packet len %d.\n", len);
+#endif
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Download_Data )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_SelectConfig---------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Select a configuration: use ADP_ICEM_SelecConfig.*/
+int angel_RDI_SelectConfig(RDI_ConfigAspect aspect, char const *name,
+ RDI_ConfigMatchType matchtype, unsigned versionreq,
+ unsigned *versionp)
+{
+ Packet *packet = NULL;
+ int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_SelectConfig.\n");
+#endif
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b%b%b%w",
+ ADP_ICEman | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_SelectConfig, aspect, strlen(name),
+ matchtype, versionreq);
+ /* copy the name into the buffer */
+ memcpy(BUFFERDATA(packet->pk_buffer)+len, name, strlen(name));
+ len += strlen(name);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_ICEman | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2,
+ &subreason, &status, versionp);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_ICEM_SelectConfig )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_LoadAgent------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Load a new debug agent: use ADP_Ctrl_Download_Agent. */
+int angel_RDI_LoadAgent(ARMword dest, unsigned long size,
+ getbufferproc *getb, void *getbarg)
+{
+ Packet *packet = NULL;
+ int status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+ time_t t;
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: Entered angel_RDI_LoadAgent.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Control | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Download_Agent, dest, size);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Download_Agent )
+ return RDIError_Error;
+ if ( status != RDIError_NoError )
+ return status;
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: starting agent data download.\n");
+#endif
+ { unsigned long pos = 0, segsize;
+ for (; pos < size; pos += segsize) {
+ char *b = getb(getbarg, &segsize);
+ if (b == NULL) return RDIError_NoError;
+ err = angel_RDI_LoadConfigData( segsize, b );
+ if (err != RDIError_NoError) return err;
+ }
+ }
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: finished downloading new agent.\n");
+#endif
+
+ /* renegotiate back down */
+ err = angel_negotiate_defaults();
+ if (err != adp_ok)
+ return err;
+
+ /* Output a message to tell the user what is going on. This is vital
+ * when switching from ADP EICE to ADP over JTAG, as then the user
+ * has to reset the target board !
+ */
+ { char msg[256];
+ int len=angel_RDI_errmess(msg, 256, adp_new_agent_starting);
+ angel_hostif->write(angel_hostif->hostosarg, msg, len);
+ }
+
+ /* get new image started */
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: sending start message for new agent.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Start_Agent, dest);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Start_Agent )
+ return RDIError_Error;
+ if ( status != RDIError_NoError )
+ return status;
+
+ /* wait for image to start up */
+ heartbeat_enabled = FALSE;
+ t=time(NULL);
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+ if ((time(NULL)-t) > 2) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: no booted message from new image yet.\n");
+#endif
+ break;
+ }
+ } while (booted_not_received);
+ booted_not_received=1;
+
+ /* Give device driver a chance to do any necessary resyncing with new agent.
+ * Only used by etherdrv.c at the moment.
+ */
+ (void)Adp_Ioctl( DC_RESYNC, NULL );
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: reopening to new agent.\n");
+#endif
+ err = angel_RDI_open(0, NULL, NULL, NULL);
+ switch ( err )
+ {
+ case RDIError_NoError:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_NoError\n" );
+#endif
+ break;
+ }
+
+ case RDIError_LittleEndian:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_LittleEndian (OK)\n" );
+#endif
+ err = RDIError_NoError;
+ break;
+ }
+
+ case RDIError_BigEndian:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_BigEndian (OK)\n" );
+#endif
+ err = RDIError_NoError;
+ break;
+ }
+
+ default:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned %d - unexpected!\n", err );
+#endif
+ break;
+ }
+ }
+#ifndef NO_HEARTBEAT
+ heartbeat_enabled = TRUE;
+#endif
+ return err;
+}
+
+static int angel_RDI_errmess(char *buf, int blen, int errnum) {
+ char *s=NULL;
+ int n;
+
+ switch (errnum) {
+ case adp_malloc_failure:
+ s=AdpMess_MallocFailed; break;
+ case adp_illegal_args:
+ s=AdpMess_IllegalArgs; break;
+ case adp_device_not_found:
+ s=AdpMess_DeviceNotFound; break;
+ case adp_device_open_failed:
+ s=AdpMess_DeviceOpenFailed; break;
+ case adp_device_already_open:
+ s=AdpMess_DeviceAlreadyOpen; break;
+ case adp_device_not_open:
+ s=AdpMess_DeviceNotOpen; break;
+ case adp_bad_channel_id:
+ s=AdpMess_BadChannelId; break;
+ case adp_callback_already_registered:
+ s=AdpMess_CBAlreadyRegd; break;
+ case adp_write_busy:
+ s=AdpMess_WriteBusy; break;
+ case adp_bad_packet:
+ s=AdpMess_BadPacket; break;
+ case adp_seq_high:
+ s=AdpMess_SeqHigh; break;
+ case adp_seq_low:
+ s=AdpMess_SeqLow; break;
+ case adp_timeout_on_open:
+ s=AdpMess_TimeoutOnOpen; break;
+ case adp_failed:
+ s=AdpMess_Failed; break;
+ case adp_abandon_boot_wait:
+ s=AdpMess_AbandonBootWait; break;
+ case adp_late_startup:
+ s=AdpMess_LateStartup; break;
+ case adp_new_agent_starting:
+ s=AdpMess_NewAgentStarting; break;
+ default: return 0;
+ }
+ n=strlen(s);
+ if (n>blen-1) n=blen-1;
+ memcpy(buf, s, n);
+ buf[n++]=0;
+ return n;
+}
+
+extern const struct RDIProcVec angel_rdi;
+const struct RDIProcVec angel_rdi = {
+ "ADP",
+ angel_RDI_open,
+ angel_RDI_close,
+ angel_RDI_read,
+ angel_RDI_write,
+ angel_RDI_CPUread,
+ angel_RDI_CPUwrite,
+ angel_RDI_CPread,
+ angel_RDI_CPwrite,
+ angel_RDI_setbreak,
+ angel_RDI_clearbreak,
+ angel_RDI_setwatch,
+ angel_RDI_clearwatch,
+ angel_RDI_execute,
+ angel_RDI_step,
+ angel_RDI_info,
+ angel_RDI_pointinq,
+
+ angel_RDI_AddConfig,
+ angel_RDI_LoadConfigData,
+ angel_RDI_SelectConfig,
+
+ 0, /*angel_RDI_drivernames,*/
+ 0, /* cpunames */
+
+ angel_RDI_errmess,
+
+ angel_RDI_LoadAgent
+};
+
+/* EOF ardi.c */
+
+/* Not strictly necessary, but allows linking this code into armsd. */
+
+struct foo {
+ char *name;
+ int (*action)();
+ char *syntax;
+ char **helpmessage;
+ int doafterend;
+ int dobeforestart;
+ int doinmidline;
+} hostappl_CmdTable[1] = {{"", NULL}};
+
+void
+hostappl_Init()
+{
+}
+
+int
+hostappl_Backstop()
+{
+ return -30;
+}
diff --git a/gdb/rdi-share/ardi.h b/gdb/rdi-share/ardi.h
new file mode 100644
index 0000000..66acd1a
--- /dev/null
+++ b/gdb/rdi-share/ardi.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ardi.h
+ * ADP RDI interfaces
+ *
+ * $Revision$
+ * $Date$
+ */
+
+#include "host.h"
+
+typedef unsigned32 ARMword;
+
+#include "dbg_rdi.h"
+#include "dbg_conf.h"
+
+extern char *commandline;
+extern ARMword last_vector_catch;
+
+/* This is the size of buffers that are asked for by standard channels
+ * Non standard channels may wish to copy this!
+ */
+extern int Armsd_BufferSize;
+
+typedef int (*host_ChannelBufferFilledFnPtr)(unsigned int ,unsigned char ** ,void *);
+
+int angel_RDI_open(
+ unsigned type, Dbg_ConfigBlock const *config,
+ Dbg_HostosInterface const *hostif, struct Dbg_MCState *dbg_state);
+int angel_RDI_close(void);
+
+int angel_RDI_read(ARMword source, void *dest, unsigned *nbytes);
+int angel_RDI_write(const void *source, ARMword dest, unsigned *nbytes);
+
+int angel_RDI_CPUread(unsigned mode, unsigned long mask, ARMword *buffer);
+int angel_RDI_CPUwrite(unsigned mode, unsigned long mask,
+ ARMword const *buffer);
+
+int angel_RDI_CPread(unsigned CPnum, unsigned long mask, ARMword *buffer);
+int angel_RDI_CPwrite(unsigned CPnum, unsigned long mask,
+ ARMword const *buffer);
+
+int angel_RDI_setbreak(ARMword address, unsigned type, ARMword bound,
+ PointHandle *handle);
+int angel_RDI_clearbreak(PointHandle handle);
+
+int angel_RDI_setwatch(ARMword address, unsigned type, unsigned datatype,
+ ARMword bound, PointHandle *handle);
+int angel_RDI_clearwatch(PointHandle handle);
+
+int angel_RDI_pointinq(ARMword *address, unsigned type, unsigned datatype,
+ ARMword *bound);
+
+int angel_RDI_execute(PointHandle *handle);
+
+int angel_RDI_step(unsigned ninstr, PointHandle *handle);
+
+int angel_RDI_info(unsigned type, ARMword *arg1, ARMword *arg2);
+
+int angel_RDI_AddConfig(unsigned long nbytes);
+
+int angel_RDI_LoadConfigData(unsigned long nbytes, char const *data);
+
+int angel_RDI_SelectConfig(RDI_ConfigAspect aspect, char const *name,
+ RDI_ConfigMatchType matchtype, unsigned versionreq,
+ unsigned *versionp);
+
+RDI_NameList const *angel_RDI_drivernames(void);
+
+int angel_RDI_LoadAgent(ARMword dest, unsigned long size, getbufferproc *getb,
+ void *getbarg);
+
+extern const struct Dbg_HostosInterface *angel_hostif;
+
+typedef int angel_RDI_TargetStoppedProc(unsigned stopped_reason, void *arg);
+
+extern int angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc *fn,
+ void *arg);
diff --git a/gdb/rdi-share/armdbg.h b/gdb/rdi-share/armdbg.h
new file mode 100644
index 0000000..b5fae11
--- /dev/null
+++ b/gdb/rdi-share/armdbg.h
@@ -0,0 +1,1452 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM symbolic debugger toolbox interface
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+/* Minor points of uncertainty are indicated by a question mark in the
+ LH margin.
+
+ Wherever an interface is required to iterate over things of some class,
+ I prefer something of the form EnumerateXXs(..., XXProc *p, void *arg)
+ which results in a call of p(xx, arg) for each xx, rather than something
+ of the form
+ for (xxh = StartIterationOverXXs(); (xx = Next(xxh)) != 0; ) { ... }
+ EndIterationOverXXs(xxh);
+ Others may disagree.
+ (Each XXProc returns an Error value: if this is not Err_OK, iteration
+ stops immediately and the EnumerateXXs function returns that value).
+
+ ptrace has been retired as of insufficient utility. If such fuctionality is
+ required, it can be constructed using breakpoints.
+
+ The file form of all name fields in debug areas is in-line, with a length
+ byte and no terminator. The debugger toolbox makes an in-store translation,
+ where the strings are out of line (the namep variant in asdfmt.h) and have a
+ terminating zero byte: the pointer is to the first character of the string
+ with the length byte at ...->n.namep[-1].
+ */
+
+#ifndef armdbg__h
+#define armdbg__h
+
+#include <stddef.h>
+
+#include "host.h"
+#include "msg.h"
+
+typedef unsigned32 ARMaddress;
+typedef unsigned32 ARMword;
+typedef unsigned16 ARMhword;
+
+#include "dbg_conf.h"
+#include "dbg_rdi.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef unsigned char Dbg_Byte;
+
+typedef int Dbg_Error;
+
+typedef struct Dbg_MCState Dbg_MCState;
+/* A representation of the state of the target. The structure is not revealed.
+ A pointer to one of these is returned by Dbg_Initialise(), is passed to all
+ toolbox calls which refer to the state of the target, and is discarded
+ by Dbg_Finalise().
+ Nothing in the toolbox itself precludes there being multiple targets, each
+ with its own state.
+ */
+
+/* Most toolbox interfaces return an error status. Only a few of the status
+ values are expected to be interesting to clients and defined here; the
+ rest are private (but a textual form can be produced by ErrorToChars()).
+ */
+
+#define Error_OK 0
+
+/* Partitioning of the error code space: errors below Dbg_Error_Base are RDI
+ errors (as defined in dbg_rdi.h). Codes above Dbg_Error_Limit are
+ available to clients, who may impose some further structure.
+ */
+#define Dbg_Error_Base 0x1000
+#define Dbg_Error_Limit 0x2000
+
+#define DbgError(n) ((Dbg_Error)(Dbg_Error_Base+(n)))
+
+#define Dbg_Err_OK Error_OK
+#define Dbg_Err_Interrupted DbgError(1)
+#define Dbg_Err_Overflow DbgError(2)
+#define Dbg_Err_FileNotFound DbgError(3)
+#define Dbg_Err_ActivationNotPresent DbgError(4)
+#define Dbg_Err_OutOfHeap DbgError(5)
+#define Dbg_Err_TypeNotSimple DbgError(6)
+#define Dbg_Err_BufferFull DbgError(7)
+#define Dbg_Err_AtStackBase DbgError(8)
+#define Dbg_Err_AtStackTop DbgError(9)
+#define Dbg_Err_DbgTableFormat DbgError(10)
+#define Dbg_Err_NotVariable DbgError(11)
+#define Dbg_Err_NoSuchBreakPoint DbgError(12)
+#define Dbg_Err_NoSuchWatchPoint DbgError(13)
+#define Dbg_Err_FileLineNotFound DbgError(14)
+#define Dbg_Err_DbgTableVersion DbgError(15)
+#define Dbg_Err_NoSuchPath DbgError(16)
+#define Dbg_Err_StateChanged DbgError(17)
+#define Dbg_Err_SoftInitialiseError DbgError(18)
+#define Dbg_Err_CoProRegNotWritable DbgError(19)
+#define Dbg_Err_NotInHistory DbgError(20)
+#define Dbg_Err_ContextSyntax DbgError(21)
+#define Dbg_Err_ContextNoLine DbgError(22)
+#define Dbg_Err_ContextTwoLines DbgError(23)
+#define Dbg_Err_VarReadOnly DbgError(24)
+#define Dbg_Err_FileNewerThanImage DbgError(25)
+#define Dbg_Err_NotFound DbgError(26)
+
+ /* functions which evaluate expressions may return this value, to indicate
+ that execution became suspended within a function called in the debugee */
+
+/* Functions returning characters take a BufDesc argument, with fields buffer
+ and bufsize being input arguments describing the buffer to be filled, and
+ filled being set on return to the number of bytes written to the buffer
+ (omitting the terminating 0).
+ */
+
+typedef struct Dbg_BufDesc Dbg_BufDesc;
+
+typedef void Dbg_BufferFullProc(Dbg_BufDesc *bd);
+
+struct Dbg_BufDesc {
+ char *buffer;
+ size_t size,
+ filled;
+ Dbg_BufferFullProc *p;
+ void *arg;
+};
+
+#define Dbg_InitBufDesc(bd, buf, bytes) \
+ ((bd).buffer = (buf), (bd).size = (bytes), (bd).filled = 0,\
+ (bd).p = NULL, (bd).arg = NULL)
+
+#define Dbg_InitBufDesc_P(bd, buf, bytes, fn, a) \
+ ((bd).buffer = (buf), (bd).size = (bytes), (bd).filled = 0,\
+ (bd).p = (fn), (bd).arg = (a))
+
+Dbg_Error Dbg_StringToBuf(Dbg_BufDesc *buf, char const *s);
+Dbg_Error Dbg_BufPrintf(Dbg_BufDesc *buf, char const *form, ...);
+#ifdef NLS
+Dbg_Error Dbg_MsgToBuf(Dbg_BufDesc *buf, msg_t t);
+Dbg_Error Dbg_BufMsgPrintf(Dbg_BufDesc *buf, msg_t form, ...);
+#else
+#define Dbg_MsgToBuf Dbg_StringToBuf
+#define Dbg_BufMsgPrintf Dbg_BufPrintf
+#endif
+Dbg_Error Dbg_CharToBuf(Dbg_BufDesc *buf, int ch);
+
+int Dbg_CIStrCmp(char const *s1, char const *s2);
+/* Case-independent string comparison, interface as for strcmp */
+
+int Dbg_CIStrnCmp(char const *s1, char const *s2, size_t n);
+/* Case-independent string comparison, interface as for strncmp */
+
+void Dbg_ErrorToChars(Dbg_MCState *state, Dbg_Error err, Dbg_BufDesc *buf);
+
+typedef int Dbg_RDIResetCheckProc(int);
+/* Type of a function to be called after each RDI operation performed by the
+ toolbox, with the status from the operation as argument. The value returned
+ is treated as the status. (The intent is to allow the toolbox's client to
+ take special action to handle RDIDbg_Error_Reset).
+ */
+
+typedef struct Dbg_CoProDesc Dbg_CoProDesc;
+
+typedef Dbg_Error Dbg_CoProFoundProc(Dbg_MCState *state, int cpno, Dbg_CoProDesc const *cpd);
+/* Type of a function to be called when the shape of a coprocessor is discovered
+ by enquiry of the target or agent (via RequestCoProDesc)
+ */
+
+typedef struct RDIProcVec RDIProcVec;
+
+Dbg_Error Dbg_RequestReset(Dbg_MCState *);
+
+Dbg_Error Dbg_Initialise(
+ Dbg_ConfigBlock *config, Dbg_HostosInterface const *i,
+ Dbg_RDIResetCheckProc *checkreset, Dbg_CoProFoundProc *coprofound,
+ RDIProcVec const *rdi, Dbg_MCState **statep);
+/* values in config are updated if they call for default values */
+
+void Dbg_Finalise(Dbg_MCState *state, bool targetdead);
+
+typedef struct {
+ char name[16];
+ RDI_MemDescr md;
+ RDI_MemAccessStats a;
+} Dbg_MemStats;
+
+/*--------------------------------------------------------------------------*/
+
+/* Symbol table management.
+ The structure of a Dbg_SymTable is not revealed. It is created by
+ Dbg_ReadSymbols() or by Dbg_LoadFile(), and associated with the argument
+ Dbg_MCState.
+ Many symbol tables may be concurrently active.
+ A Dbg_SymTable is removed either explicitly (by call to Dbg_DeleteSymbols)
+ or implicitly when a symbol table for an overlapping address range is read.
+
+ There is a pre-defined symbol table containing entries for ARM registers,
+ co-processor registers and the like.
+ */
+
+typedef struct Dbg_SymTable Dbg_SymTable;
+
+typedef struct Dbg_ImageFragmentDesc {
+ ARMaddress base, limit;
+} Dbg_ImageFragmentDesc;
+
+typedef enum {
+ Dbg_Lang_None,
+ Dbg_Lang_C,
+ Dbg_Lang_Pascal,
+ Dbg_Lang_Fortran,
+ Dbg_Lang_Asm,
+ Dbg_Lang_Cpp
+} Dbg_Lang;
+
+typedef struct Dbg_ImageDesc {
+ Dbg_Lang lang;
+ int executable;
+ ARMaddress robase, rolimit, rwbase, rwlimit;
+ int nfrags;
+ Dbg_ImageFragmentDesc *fragments;
+ char *name;
+} Dbg_ImageDesc;
+
+Dbg_ImageDesc *Dbg_ImageAreas(Dbg_SymTable *st);
+
+Dbg_SymTable *Dbg_LastImage(Dbg_MCState *state);
+
+Dbg_SymTable *Dbg_NewSymTable(Dbg_MCState *state, const char *name);
+
+Dbg_Error Dbg_ReadSymbols(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
+/* Just read the symbols from the named image. <st> is set to the allocated
+ symbol table.
+? Maybe we could usefully allow other formats than AIF images to describe
+ the symbols (eg) of shared libraries
+ */
+
+typedef struct Dbg_SymInfo {
+ int isize;
+ ARMaddress addr;
+ char *name;
+} Dbg_SymInfo;
+
+Dbg_SymInfo *Dbg_AsmSym(Dbg_SymTable *st, ARMaddress addr);
+int32 Dbg_AsmAddr(Dbg_SymTable *st, int32 line);
+int32 Dbg_AsmLine(Dbg_SymTable *st, ARMaddress addr);
+int32 Dbg_AsmLinesInRange(Dbg_SymTable *st, ARMaddress start, ARMaddress end);
+
+Dbg_Error Dbg_LoadFile(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
+/* load the image into target memory, and read its symbols. <st> is set to
+ the allocated symbol table.
+ A null filename reloads the most recently loaded file (and rereads its
+ symbols).
+ Loading an image leaves breakpoints unchanged. If a client wishes
+ otherwise, it must remove the breakpoints explicitly.
+*/
+
+Dbg_Error Dbg_CallGLoadFile(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
+
+typedef void Dbg_ImageLoadProc(Dbg_MCState *, Dbg_SymTable *);
+Dbg_Error Dbg_OnImageLoad(Dbg_MCState *, Dbg_ImageLoadProc *);
+/* Register function to be called back whenever an image is loaded, or symbols
+ * for an image read. (To allow multiple toolbox clients to coexist).
+ */
+
+Dbg_Error Dbg_LoadAgent(Dbg_MCState *state, const char *filename);
+/* Load a debug agent, and start it.
+ Symbols in the image for the agent are ignored.
+*/
+
+Dbg_Error Dbg_RelocateSymbols(Dbg_SymTable *st, ARMaddress reloc);
+/* add <reloc> to the value of all symbols in <st> describing absolute memory
+ locations. The intent is to allow the symbols in a load-time relocating
+ image (for example) to be useful.
+ */
+
+Dbg_Error Dbg_DeleteSymbols(Dbg_MCState *state, Dbg_SymTable **st);
+
+typedef enum Dbg_LLSymType {
+ llst_code,
+ llst_code16,
+ llst_data,
+ llst_const,
+ llst_unknown,
+ llst_max
+} Dbg_LLSymType;
+/* Since AIF images contain no type information for low-level symbols, this
+ classification is only a guess, and some symbols describing constants will
+ incorrectly be described as code or data.
+ */
+
+typedef Dbg_Error Dbg_SymProc(
+ Dbg_MCState *state,
+ const char *symbol, Dbg_LLSymType symtype, ARMaddress value,
+ void *arg);
+
+Dbg_Error Dbg_EnumerateLowLevelSymbols(
+ Dbg_MCState *state, const char *match, Dbg_SymProc *p,
+ void *arg);
+/* Call p(name, value) for each low level symbol in the tables of <state>
+ whose name matches the regular expression <match> (a NULL <match> matches
+ any name). Symbols are enumerated in no particular order.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* Functions are provided here to allow quick mass access to register values
+ for display. There is no comparable need for quick mass update, so writing
+ should be via Assign().
+ */
+
+typedef struct Dbg_RegSet {
+ ARMword
+ user[15],
+ pc,
+ psr,
+ fiq[7],
+ spsr_fiq,
+ irq[2],
+ spsr_irq,
+ svc[2],
+ spsr_svc,
+ abort[2],
+ spsr_abort,
+ undef[2],
+ spsr_undef;
+} Dbg_RegSet;
+
+/* bits in the modemask argument for ReadRegisters */
+
+#define Dbg_MM_User 1
+#define Dbg_MM_FIQ 2
+#define Dbg_MM_IRQ 4
+#define Dbg_MM_SVC 8
+#define Dbg_MM_Abort 0x10
+#define Dbg_MM_Undef 0x20
+#define Dbg_MM_System 0x40
+
+Dbg_Error Dbg_ReadRegisters(Dbg_MCState *state, Dbg_RegSet *regs, int modemask);
+
+Dbg_Error Dbg_WriteRegister(Dbg_MCState *state, int rno, int modemask, ARMword val);
+
+int Dbg_StringToMode(const char *name);
+
+int Dbg_ModeToModeMask(ARMword mode);
+
+/* Some implementations of the FP instruction set keep FP values loaded into
+ registers in their unconverted format, converting only when necessary.
+ Some RDI implementations deliver these values uninterpreted.
+ (For the rest, register values will always have type F_Extended).
+ */
+
+typedef enum { F_Single, F_Double, F_Extended, F_Packed, /* fpe340 values */
+ F_Internal, /* new fpe : mostly as extended */
+ F_None } Dbg_FPType;
+
+typedef struct { ARMword w[3]; } Dbg_TargetExtendedVal;
+typedef struct { ARMword w[3]; } Dbg_TargetPackedVal;
+typedef struct { ARMword w[2]; } Dbg_TargetDoubleVal;
+typedef struct { ARMword w[1]; } Dbg_TargetFloatVal;
+
+typedef union { Dbg_TargetExtendedVal e; Dbg_TargetPackedVal p;
+ Dbg_TargetDoubleVal d; Dbg_TargetFloatVal f; } Dbg_TargetFPVal;
+
+#define TargetSizeof_Extended 12
+#define TargetSizeof_Packed 12
+#define TargetSizeof_Double 8
+#define TargetSizeof_Float 4
+
+typedef struct Dbg_FPRegVal {
+ Dbg_FPType type;
+ Dbg_TargetFPVal v;
+} Dbg_FPRegVal;
+
+typedef struct Dbg_FPRegSet {
+ Dbg_FPRegVal f[8];
+ ARMword fpsr, fpcr;
+} Dbg_FPRegSet;
+
+Dbg_Error Dbg_ReadFPRegisters(Dbg_MCState *state, Dbg_FPRegSet *regs);
+
+Dbg_Error Dbg_WriteFPRegisters(Dbg_MCState *state, int32 mask, Dbg_FPRegSet *regs);
+
+Dbg_Error Dbg_FPRegToDouble(DbleBin *d, Dbg_FPRegVal const *f);
+/* Converts from a FP register value (in any format) to a double with
+ approximately the same value (or returns Dbg_Err_Overflow)
+ */
+
+void Dbg_DoubleToFPReg(Dbg_FPRegVal *f, DbleBin const *d);
+/* Converts the double <d> to a Dbg_FPRegVal with type F_Extended */
+
+/*--------------------------------------------------------------------------*/
+
+#include "dbg_cp.h"
+
+Dbg_Error Dbg_DescribeCoPro(Dbg_MCState *state, int cpnum, Dbg_CoProDesc *p);
+
+Dbg_Error Dbg_DescribeCoPro_RDI(Dbg_MCState *state, int cpnum, Dbg_CoProDesc *p);
+
+Dbg_Error Dbg_ReadCPRegisters(Dbg_MCState *state, int cpnum, ARMword *regs);
+
+Dbg_Error Dbg_WriteCPRegisters(Dbg_MCState *state, int cpnum, int32 mask, ARMword *regs);
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_ReadWords(
+ Dbg_MCState *state,
+ ARMword *words, ARMaddress addr, unsigned count);
+/* Reads a number of (32-bit) words from target store. The values are in host
+ byte order; if they are also to be interpreted as bytes Dbg_SwapByteOrder()
+ must be called to convert to target byte order.
+ */
+
+Dbg_Error Dbg_WriteWords(
+ Dbg_MCState *state,
+ ARMaddress addr, const ARMword *words, unsigned count);
+/* Writes a number of (32-bit) words to target store. The values are in host
+ byte order (if what is being written is actually a byte string it must be
+ converted by Dbg_SwapByteOrder()).
+ */
+
+Dbg_Error Dbg_ReadHalf(Dbg_MCState *state, ARMhword *val, ARMaddress addr);
+Dbg_Error Dbg_WriteHalf(Dbg_MCState *state, ARMaddress addr, ARMword val);
+
+Dbg_Error Dbg_ReadBytes(Dbg_MCState *state, Dbg_Byte *val, ARMaddress addr, unsigned count);
+Dbg_Error Dbg_WriteBytes(Dbg_MCState *state, ARMaddress addr, const Dbg_Byte *val, unsigned count);
+
+void Dbg_HostWords(Dbg_MCState *state, ARMword *words, unsigned wordcount);
+/* (A noop unless host and target bytesexes differ) */
+
+ARMword Dbg_HostWord(Dbg_MCState *state, ARMword v);
+
+ARMhword Dbg_HostHalf(Dbg_MCState *state, ARMword v);
+
+/*--------------------------------------------------------------------------*/
+
+/* Types describing various aspects of position within code.
+ There are rather a lot of these, in the interests of describing precisely
+ what fields must be present (rather than having a single type with many
+ fields which may or may not be valid according to context).
+ */
+
+typedef struct Dbg_LLPos {
+ Dbg_SymTable *st;
+ char *llsym;
+ ARMaddress offset;
+} Dbg_LLPos;
+
+typedef struct Dbg_File {
+ Dbg_SymTable *st;
+ char *file;
+} Dbg_File;
+
+typedef struct Dbg_Line {
+ unsigned32 line; /* linenumber in the file */
+ unsigned16 statement, /* within the line (1-based) */
+ charpos; /* ditto */
+} Dbg_Line;
+/* As an output value from toolbox functions, both statement and charpos are set
+ if the version of the debugger tables for the section concerned permits.
+ On input, <charpos> is used only if <statement> is 0 (in which case, if
+ <charpos> is non-0, Dbg_Err_DbgTableVersion is returned if the version of
+ the debugger tables concerned is too early.
+ */
+
+typedef struct Dbg_FilePos {
+ Dbg_File f;
+ Dbg_Line line;
+} Dbg_FilePos;
+
+typedef struct Dbg_ProcDesc {
+ Dbg_File f;
+ char *name;
+} Dbg_ProcDesc;
+
+typedef struct Dbg_ProcPos {
+ Dbg_ProcDesc p;
+ Dbg_Line line;
+} Dbg_ProcPos;
+
+/* Support for conversions between position representations */
+
+Dbg_Error Dbg_ProcDescToLine(Dbg_MCState *state, Dbg_ProcDesc *proc, Dbg_Line *line);
+/* If proc->f.file is null (and there is just one function proc->name), it is
+ updated to point to the name of the file containing (the start of)
+ proc->name.
+ */
+
+Dbg_Error Dbg_FilePosToProc(Dbg_MCState *state, const Dbg_FilePos *pos, char **procname);
+
+/* Conversions from position representations to and from code addresses */
+
+Dbg_Error Dbg_AddressToProcPos(
+ Dbg_MCState *state, ARMaddress addr,
+ Dbg_ProcPos *pos);
+Dbg_Error Dbg_AddressToLLPos(
+ Dbg_MCState *state, ARMaddress addr,
+ Dbg_LLPos *pos, Dbg_LLSymType *res_type, int system_names);
+
+Dbg_Error Dbg_ProcPosToAddress(
+ Dbg_MCState *state, const Dbg_ProcPos *pos,
+ ARMaddress *res);
+Dbg_Error Dbg_LLPosToAddress(
+ Dbg_MCState *state, const Dbg_LLPos *pos,
+ ARMaddress *res);
+
+typedef struct {
+ ARMaddress start, end;
+} Dbg_AddressRange;
+
+typedef Dbg_Error Dbg_AddressRangeProc(void *arg, int32 first, int32 last, Dbg_AddressRange const *range);
+
+Dbg_Error Dbg_MapAddressRangesForFileRange(
+ Dbg_MCState *state,
+ Dbg_SymTable *st, const char *f, int32 first, int32 last, Dbg_AddressRangeProc *p, void *arg);
+
+typedef struct Dbg_Environment Dbg_Environment;
+/* A Dbg_Environment describes the context required to make sense of a variable
+ name and access its value. Its format is not revealed. Dbg_Environment
+ values are allocated by Dbg_NewEnvironment() and discarded by
+ Dbg_DeleteEnvironment().
+ */
+
+Dbg_Environment *Dbg_NewEnvironment(Dbg_MCState *state);
+void Dbg_DeleteEnvironment(Dbg_MCState *state, Dbg_Environment *env);
+
+Dbg_Error Dbg_StringToEnv(
+ Dbg_MCState *state, char *str, Dbg_Environment *resenv,
+ int forcontext, Dbg_Environment const *curenv);
+
+Dbg_Error Dbg_ProcPosToEnvironment(
+ Dbg_MCState *state, const Dbg_ProcPos *pos, int activation,
+ const Dbg_Environment *current, Dbg_Environment *res);
+
+/* Conversion from a position representation to an Dbg_Environment (as required
+ to access variable values). Only a Dbg_ProcPos argument here; other
+ representations need to be converted first.
+
+ Returns <res> describing the <activation>th instance of the function
+ described by <pos>, up from the stack base if <activation> is negative,
+ else down from <current>.
+ If this function returns Dbg_Err_ActivationNotPresent, the result
+ Dbg_Environment is still valid for accessing non-auto variables.
+ */
+
+typedef struct Dbg_DeclSpec Dbg_DeclSpec;
+
+Dbg_Error Dbg_EnvToProcItem(
+ Dbg_MCState *state, Dbg_Environment const *env, Dbg_DeclSpec *proc);
+
+Dbg_Error Dbg_ContainingEnvironment(
+ Dbg_MCState *state, const Dbg_Environment *context, Dbg_Environment *res);
+/* Set <res> to describe the containing function, file if <context> is within
+ a top-level function (or error if <context> already describes a file).
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* ASD debug table pointers are not by themselves sufficient description,
+ since there's an implied section context. Hence the DeclSpec and TypeSpec
+ structures.
+ */
+
+
+#ifndef Dbg_TypeSpec_Defined
+
+struct Dbg_DeclSpec { void *a; };
+
+#ifdef CALLABLE_COMPILER
+typedef void *Dbg_TypeSpec;
+
+/* The intention here is to give an alternative definition for Dbg_BasicType
+ which follows.
+ */
+
+#define Dbg_T_Void xDbg_T_Void
+#define Dbg_T_Bool xDbg_T_Bool
+#define Dbg_T_SByte xDbg_T_SByte
+#define Dbg_T_SHalf xDbg_T_Half
+#define Dbg_T_SWord xDbg_T_SWord
+#define Dbg_T_UByte xDbg_T_UByte
+#define Dbg_T_UHalf xDbg_T_UHalf
+#define Dbg_T_UWord xDbg_T_UWord
+#define Dbg_T_Float xDbg_T_Float
+#define Dbg_T_Double xDbg_T_Double
+#define Dbg_T_LDouble xDbg_T_LDouble
+#define Dbg_T_Complex xDbg_T_Complex
+#define Dbg_T_DComplex xDbg_T_DComplex
+#define Dbg_T_String xDbg_T_String
+#define Dbg_T_Function xDbg_T_Function
+
+#define Dbg_BasicType xDbg_BaiscType
+#define Dbg_PrimitiveTypeToTypeSpec xDbg_PrimitiveTypeToTypeSpec
+
+#else
+/* We want a Dbg_TypeSpec to be a an opaque type, but of known size (so the
+ toolbox's clients can allocate the store to hold one); unfortunately, we
+ can do this only by having one definition for the toolbox's clients and
+ one (elsewhere) for the toolbox itself.
+ */
+
+typedef struct Dbg_TypeSpec Dbg_TypeSpec;
+struct Dbg_TypeSpec { void *a; int32 b; };
+#endif /* CALLABLE_COMPILER */
+
+typedef enum {
+ Dbg_T_Void,
+
+ Dbg_T_Bool,
+
+ Dbg_T_SByte,
+ Dbg_T_SHalf,
+ Dbg_T_SWord,
+
+ Dbg_T_UByte,
+ Dbg_T_UHalf,
+ Dbg_T_UWord,
+
+ Dbg_T_Float,
+ Dbg_T_Double,
+ Dbg_T_LDouble,
+
+ Dbg_T_Complex,
+ Dbg_T_DComplex,
+
+ Dbg_T_String,
+
+ Dbg_T_Function
+} Dbg_BasicType;
+
+#endif
+
+void Dbg_PrimitiveTypeToTypeSpec(Dbg_TypeSpec *ts, Dbg_BasicType t);
+
+bool Dbg_TypeIsIntegral(Dbg_TypeSpec const *ts);
+
+bool Dbg_TypeIsPointer(Dbg_TypeSpec const *ts);
+
+bool Dbg_TypeIsFunction(Dbg_TypeSpec const *ts);
+
+bool Dbg_PruneType(Dbg_TypeSpec *tsres, Dbg_TypeSpec const *ts);
+/* Return to tsres a version of ts which has been pruned by the removal of all
+ toplevel typedefs. Result is YES if the result has changed.
+ */
+
+typedef Dbg_Error Dbg_FileProc(Dbg_MCState *state, const char *name, const Dbg_DeclSpec *procdef, void *arg);
+
+Dbg_Error Dbg_EnumerateFiles(Dbg_MCState *state, Dbg_SymTable *st, Dbg_FileProc *p, void *arg);
+/* The top level for a high level enumerate. Lower levels are performed by
+ EnumerateDeclarations (below).
+ */
+
+typedef enum {
+ ds_Invalid,
+ ds_Type,
+ ds_Var,
+ ds_Proc,
+ ds_Enum,
+ ds_Function,
+ ds_Label
+} Dbg_DeclSort;
+
+Dbg_DeclSort Dbg_SortOfDeclSpec(Dbg_DeclSpec const *decl);
+
+char *Dbg_NameOfDeclSpec(Dbg_DeclSpec const *decl);
+
+Dbg_TypeSpec Dbg_TypeSpecOfDeclSpec(Dbg_DeclSpec const *decl);
+
+typedef enum {
+ cs_None,
+ cs_Extern,
+ cs_Static,
+ cs_Auto,
+ cs_Reg,
+ cs_Var,
+ cs_Farg,
+ cs_Fcarg,
+ cs_Local,
+ cs_Filtered,
+ cs_Globalreg
+} Dbg_StgClass;
+
+Dbg_StgClass Dbg_StgClassOfDeclSpec(Dbg_DeclSpec const *decl);
+
+bool Dbg_VarsAtSameAddress(Dbg_DeclSpec const *d1, Dbg_DeclSpec const *d2);
+
+bool Dbg_VarsDecribedForDeclSpec(Dbg_DeclSpec const *decl);
+
+int Dbg_ArgCountOfDeclSpec(Dbg_DeclSpec const *decl);
+
+typedef struct Dbg_DComplex { DbleBin r, i; } Dbg_DComplex;
+
+typedef union Dbg_ConstantVal {
+ int32 l;
+ unsigned32 u;
+ DbleBin d;
+ Dbg_DComplex fc;
+ ARMaddress a;
+ char *s;
+} Dbg_ConstantVal;
+
+typedef struct Dbg_Constant {
+ Dbg_TypeSpec type;
+ Dbg_ConstantVal val;
+} Dbg_Constant;
+
+typedef enum Dbg_ValueSort {
+ vs_register,
+ vs_store,
+ vs_constant,
+ vs_local,
+ vs_filtered,
+ vs_none,
+ vs_error
+} Dbg_ValueSort;
+
+/* vs_local allows the use of symbol table entries to describe entities within
+ the debugger's own address space, accessed in the same way as target
+ variables.
+ vs_filtered describes entities which may be read or written only via an
+ access function (eg r15)
+ */
+
+#define fpr_base 16
+/* There's only one register ValueSort (reflecting asd table StgClass);
+ fp register n is encoded as register n+fpr_base.
+ */
+
+typedef struct Dbg_Value Dbg_Value;
+
+typedef Dbg_Error Dbg_AccessFn(Dbg_MCState *state, int write, Dbg_Value *self, Dbg_Constant *c);
+/* <write> == 0: read a vs_filtered value, updating the value self.
+ <write> == 1: update a vs_filtered value, with the value described by c.
+ <self> allows use of the same Dbg_AccessFn for several different entities
+ (using different val.f.id fields).
+ */
+
+typedef Dbg_Error Dbg_FormatFn(int decode, char *b, ARMword *valp, void *formatarg);
+
+typedef struct { Dbg_AccessFn *f; int id; } Dbg_AccessFnRec;
+
+struct Dbg_Value {
+ Dbg_TypeSpec type;
+ Dbg_ValueSort sort;
+ Dbg_FormatFn *formatp;
+ void *formatarg;
+ int f77csize;
+ union {
+ struct { int no; ARMaddress frame; } r;
+ ARMaddress ptr;
+ Dbg_ConstantVal c;
+ void *localp;
+ Dbg_AccessFnRec f;
+ Dbg_Error err;
+ } val;
+};
+
+Dbg_Error Dbg_AddLLSymbol(Dbg_SymTable *st, char const *name, Dbg_LLSymType type, ARMword val);
+
+Dbg_Error Dbg_AddSymbol(Dbg_SymTable *st, char const *name, Dbg_Value const *val);
+
+typedef struct Dbg_DeclSpecF {
+ Dbg_DeclSpec decl;
+ Dbg_FormatFn *formatp;
+ void *formatarg;
+} Dbg_DeclSpecF;
+
+typedef Dbg_Error Dbg_DeclProc(Dbg_MCState *state, Dbg_Environment const *context,
+ Dbg_DeclSpecF const *var, Dbg_DeclSort sort, int masked,
+ void *arg);
+
+Dbg_Error Dbg_EnumerateDeclarations(Dbg_MCState *state, Dbg_Environment const *context,
+ Dbg_DeclProc *p, void *arg);
+/* call p once for every declaration local to the function described by
+ <context> (or file if <context> describes a place outside a function).
+ p's argument <masked> is true if the variable is not visible, thanks to
+ a declaration in an inner scope.
+ */
+
+Dbg_Error Dbg_ValueOfVar(Dbg_MCState *state, const Dbg_Environment *context,
+ const Dbg_DeclSpec *var, Dbg_Value *val);
+/* Different from Dbg_EvalExpr() in that the thing being evaluated is described
+ by a Dbg_DeclSpec (which must be for a variable), rather than a string
+ needing to be decoded and associated with a symbol-table item. Intended to
+ be called from a Dbg_DeclProc called from Dbg_EnumerateDeclarations.
+ */
+
+Dbg_Error Dbg_EvalExpr(Dbg_MCState *state, Dbg_Environment const *context,
+ char const *expr, int flags, Dbg_Value *val);
+
+Dbg_Error Dbg_EvalExpr_ep(Dbg_MCState *state, Dbg_Environment const *context,
+ char const *expr, char **exprend, int flags, Dbg_Value *val);
+
+/* Both Dbg_ValueOfVar and Dbg_EvalExpr mostly deliver a value still containing
+ an indirection (since it may be wanted as the lhs of an assignment)
+ */
+
+void Dbg_RealLocation(Dbg_MCState *state, Dbg_Value *val);
+/* If val describes a register, this may really be a register, or a place on
+ the stack where the register's value is saved. In the latter case, val
+ is altered to describe the save place. (In all others, it remains
+ unchanged).
+ */
+
+Dbg_Error Dbg_DereferenceValue(Dbg_MCState *state, const Dbg_Value *value, Dbg_Constant *c);
+/* This fails if <value> describes a structure or array, returning
+ Dbg_Err_TypeNotSimple
+ */
+
+typedef struct Dbg_Expr Dbg_Expr;
+/* The result of parsing an expression in an environment: its structure is not
+ revealed. (Clients may wish to parse just once an expression which may be
+ evaluated often). In support of which, the following two functions partition
+ the work of Dbg_EvalExpr().
+ */
+
+#define Dbg_exfl_heap 1 /* allocate Expr on the heap (FreeExpr must then be
+ called to discard it). Otherwise, it goes in a
+ place overwritten by the next call to ParseExpr
+ or EvalExpr
+ */
+#define Dbg_exfl_needassign 2
+#define Dbg_exfl_lowlevel 4
+
+int Dbg_SetInputRadix(Dbg_MCState *state, int radix);
+char *Dbg_SetDefaultIntFormat(Dbg_MCState *state, char *format);
+
+Dbg_Error Dbg_ParseExpr(
+ Dbg_MCState *state, Dbg_Environment const *env, char *string,
+ char **end, Dbg_Expr **res, int flags);
+/* Just parse the argument string, returning a pointer to a parsed expression
+ and a pointer to the first non-white space character in the input string
+ which is not part of the parsed expression. (If macro expansion has taken
+ place, the returned pointer will not be into the argument string at all,
+ rather into the expanded version of it).
+ */
+
+Dbg_Error Dbg_ParseExprCheckEnd(
+ Dbg_MCState *state, Dbg_Environment const *env, char *string,
+ Dbg_Expr **res, int flags);
+/* As Dbg_ParseExpr, but the parsed expression is required completely to fill
+ the argument string (apart possibly for trailing whitespace), and an error
+ is returned if it does not.
+ */
+
+Dbg_Error Dbg_ParsedExprToValue(
+ Dbg_MCState *state, const Dbg_Environment *env, Dbg_Expr *expr, Dbg_Value *v);
+
+Dbg_Error Dbg_ReadDecl(
+ Dbg_MCState *state, Dbg_Environment const *env, char *string,
+ Dbg_TypeSpec *p, char **varp, int flags);
+/* Read a variable declaration, returing a description of the type of the
+ variable to p, and a pointer to its name to varp.
+ */
+
+bool Dbg_IsCastToArrayType(Dbg_MCState *state, Dbg_Expr *expr);
+
+void Dbg_FreeExpr(Dbg_Expr *expr);
+
+Dbg_Error Dbg_CopyType(Dbg_TypeSpec *tdest, Dbg_TypeSpec const *tsource);
+Dbg_Error Dbg_FreeCopiedType(Dbg_TypeSpec *ts);
+
+Dbg_Error Dbg_TypeOfExpr(Dbg_MCState *state, Dbg_Expr *tree, Dbg_TypeSpec *restype);
+
+Dbg_Error Dbg_ExprToVar(const Dbg_Expr *expr, Dbg_DeclSpec *var, Dbg_Environment *env);
+
+Dbg_Error Dbg_Assign(Dbg_MCState *state, const Dbg_Value *lv, const Dbg_Value *rv);
+
+typedef enum Dbg_TypeSort {
+ ts_simple,
+ ts_union,
+ ts_struct,
+ ts_array
+} Dbg_TypeSort;
+
+Dbg_TypeSort Dbg_TypeSortOfValue(Dbg_MCState *state, const Dbg_Value *val, int *fieldcount);
+
+Dbg_Error Dbg_TypeToChars(const Dbg_TypeSpec *var, Dbg_BufDesc *buf);
+
+Dbg_Error Dbg_TypeSize(Dbg_MCState *state, const Dbg_TypeSpec *type, unsigned32 *res);
+
+typedef int Dbg_ValToChars_cb(Dbg_MCState *state, Dbg_Value *subval, const char *fieldname,
+ Dbg_BufDesc *buf, void *arg);
+
+Dbg_Error Dbg_ValToChars(Dbg_MCState *state, Dbg_Value *val, int base,
+ Dbg_ValToChars_cb *cb, void *arg,
+ const char *form, Dbg_BufDesc *buf);
+/*
+ <base> is used for (any size) integer values.
+ If <val> is of an array or structure type, <cb> is called for each element,
+ with <arg> as its last parameter, and <subbuf> describing the space remaining
+ in <buf>. If <cb> returns 0, conversion ceases.
+ */
+
+Dbg_Error Dbg_NthElement(
+ Dbg_MCState *state,
+ const Dbg_Value *val, unsigned32 n, char **fieldname, Dbg_Value *subval);
+
+typedef Dbg_Error Dbg_HistoryProc(void *, int, Dbg_Value *);
+
+Dbg_Error Dbg_RegisterHistoryProc(Dbg_MCState *state, Dbg_HistoryProc *p, void *arg);
+
+typedef enum {
+ ls_cpu,
+ ls_store,
+ ls_copro,
+ ls_local,
+ ls_filtered
+} Dbg_LocSort;
+
+typedef struct {
+ Dbg_LocSort sort;
+ union {
+ struct { ARMaddress addr, size; } store;
+ struct { int modemask; int r; } cpu;
+ struct { int no; int r; } cp;
+ void *localp;
+ Dbg_AccessFnRec f;
+ } loc;
+} Dbg_Loc;
+
+typedef Dbg_Error Dbg_ObjectWriteProc(Dbg_MCState *state, Dbg_Loc const *loc);
+Dbg_Error Dbg_OnObjectWrite(Dbg_MCState *state, Dbg_ObjectWriteProc *p);
+/* Register function to be called back whenever the toolbox has written to any
+ * object accessible by the debuggee (or to local variables belonging to a
+ * toolbox client). The write has already been done.
+ * (To allow multiple toolbox clients to coexist).
+ */
+
+Dbg_Error Dbg_ObjectWritten(Dbg_MCState *state, Dbg_Loc const *loc);
+
+/*--------------------------------------------------------------------------*/
+
+/* Control of target program execution.
+ Currently, only synchronous operation is provided.
+ Execution could possibly be asynchronous where the target is a seperate
+ processor, but is necessarily synchronous if the target is Armulator.
+ Unfortunately, this may require modification to the RDI implementation
+ if multitasking is required but the the host system provides it only
+ cooperatively, or if there is no system-provided way to generate SIGINT.
+ */
+
+Dbg_Error Dbg_SetCommandline(Dbg_MCState *state, const char *args);
+/* Set the argument string to the concatenation of the name of the most
+ recently loaded image and args.
+ */
+
+typedef enum Dbg_ProgramState {
+ ps_notstarted,
+ /* Normal ways of stopping */
+ ps_atbreak, ps_atwatch, ps_stepdone,
+ ps_interrupted,
+ ps_stopped,
+ /* abnormal (but unsurprising) ways of stopping */
+ ps_lostwatch,
+ ps_branchthrough0, ps_undef, ps_caughtswi, ps_prefetch,
+ ps_abort, ps_addrexcept, ps_caughtirq, ps_caughtfiq,
+ ps_error,
+ /* only as a return value from Call() */
+ ps_callfailed, ps_callreturned,
+ /* internal inconsistencies */
+ ps_broken, /* target has "broken" */
+ ps_unknownbreak,
+ ps_unknown
+} Dbg_ProgramState;
+
+int Dbg_IsCallLink(Dbg_MCState *state, ARMaddress pc);
+
+typedef struct {
+ Dbg_FPRegVal fpres;
+ ARMword intres;
+} Dbg_CallResults;
+
+Dbg_CallResults *Dbg_GetCallResults(Dbg_MCState *state);
+
+#define Dbg_S_STATEMENTS 0
+#define Dbg_S_INSTRUCTIONS 1
+#define Dbg_S_STEPINTOPROCS 2
+
+Dbg_Error Dbg_Step(Dbg_MCState *state, int32 stepcount, int stepby, Dbg_ProgramState *status);
+/* <stepby> is a combination of the Dbg_S_... values above */
+
+Dbg_Error Dbg_StepOut(Dbg_MCState *state, Dbg_ProgramState *status);
+
+bool Dbg_CanGo(Dbg_MCState *state);
+
+bool Dbg_IsExecuting(Dbg_MCState *state);
+
+Dbg_Error Dbg_Go(Dbg_MCState *state, Dbg_ProgramState *status);
+
+Dbg_Error Dbg_Stop(Dbg_MCState *state);
+/* Asynchronous Stop request, for call from SIGINT handler. On return to the
+ caller, the call of Dbg_Go, Dbg_Step or Dbg_Call which started execution
+ should return ps_interrupted.
+ */
+
+typedef void Dbg_ExecuteProc(Dbg_MCState *state, Dbg_ProgramState status);
+Dbg_Error Dbg_OnExecute(Dbg_MCState *, Dbg_ExecuteProc *);
+/* Register function to be called back whenever execution stops.
+ * (To allow multiple toolbox clients to coexist).
+ */
+
+Dbg_Error Dbg_SetReturn(Dbg_MCState *state,
+ const Dbg_Environment *context, const Dbg_Value *value);
+/* Prepare continuation by returning <value> from the function activation
+ described by <context>. (Dbg_Go() or Dbg_Step() actually perform the
+ continuation).
+ */
+
+Dbg_Error Dbg_SetExecution(Dbg_MCState *state, Dbg_Environment *context);
+/* Set the pc in a high-level fashion */
+
+Dbg_Error Dbg_ProgramStateToChars(Dbg_MCState *state, Dbg_ProgramState event, Dbg_BufDesc *buf);
+/* This is guaranteed to give a completely accurate description of <event> if
+ this was the value returned by the most recent call of Dbg_Go, Dbg_Step,
+ or Dbg_Call.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_CurrentEnvironment(Dbg_MCState *state, Dbg_Environment *context);
+
+Dbg_Error Dbg_PrevFrame(Dbg_MCState *state, Dbg_Environment *context);
+/* towards the base of the stack */
+
+Dbg_Error Dbg_NextFrame(Dbg_MCState *state, Dbg_Environment *context);
+/* away from the base of the stack */
+
+typedef struct Dbg_AnyPos {
+ enum { pos_source, pos_ll, pos_none } postype;
+ ARMaddress pc;
+ union {
+ Dbg_ProcPos source;
+ Dbg_LLPos ll;
+ ARMaddress none;
+ } pos;
+} Dbg_AnyPos;
+
+Dbg_Error Dbg_EnvironmentToPos(Dbg_MCState *state, const Dbg_Environment *context, Dbg_AnyPos *pos);
+/* <pos> is set to a Dbg_ProcPos if these is one corresponding to <context>
+ else a Dbg_LLPos if there is one.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* Source file management.
+ Pretty vestigial. Handles source path (per loaded image),
+ and translates from line-number (as given in debugger tables) to character
+ position (as required to access files)
+ */
+
+Dbg_Error Dbg_ClearPaths(Dbg_MCState *state, Dbg_SymTable *st);
+Dbg_Error Dbg_AddPath(Dbg_MCState *state, Dbg_SymTable *st, const char *path);
+Dbg_Error Dbg_DeletePath(Dbg_MCState *state, Dbg_SymTable *st, const char *path);
+
+typedef enum {
+ Dbg_PathsCleared,
+ Dbg_PathAdded,
+ Dbg_PathDeleted
+} Dbg_PathAlteration;
+
+typedef void Dbg_PathAlteredProc(
+ Dbg_MCState *state, Dbg_SymTable *st, char const *path,
+ Dbg_PathAlteration sort);
+
+Dbg_Error Dbg_OnPathAlteration(Dbg_MCState *state, Dbg_PathAlteredProc *p);
+/* Register function to be called back whenever one of the source path
+ * modification functions above is called. (To allow multiple toolbox
+ * clients to coexist).
+ */
+
+typedef struct Dbg_FileRec Dbg_FileRec;
+typedef struct {
+ unsigned32 linecount;
+ Dbg_FileRec *handle;
+ char *fullname;
+} Dbg_FileDetails;
+
+Dbg_Error Dbg_GetFileDetails(
+ Dbg_MCState *state, const Dbg_File *fname, Dbg_FileDetails *res);
+Dbg_Error Dbg_FinishedWithFile(Dbg_MCState *state, Dbg_FileRec *handle);
+
+Dbg_Error Dbg_GetFileDetails_fr(
+ Dbg_MCState *state, Dbg_FileRec *handle, Dbg_FileDetails *res);
+/* Refresh details about the file associated with <handle> (in particular,
+ * its linecount).
+ */
+
+Dbg_Error Dbg_FileLineLength(
+ Dbg_MCState *state, Dbg_FileRec *handle, int32 lineno, int32 *len);
+/* Return to <len> the length of line <lineno> of the file associated with
+ * <handle> (without necessarily reading from the file).
+ */
+
+Dbg_Error Dbg_GetFileLine_fr(
+ Dbg_MCState *state, Dbg_FileRec *handle, int32 lineno, Dbg_BufDesc *buf);
+/* Return to <buf> the contents of line <lineno> of the file associated with
+ * <handle> (including its terminating newline).
+ */
+
+Dbg_Error Dbg_StartFileAccess(Dbg_MCState *state, Dbg_FileRec *handle);
+Dbg_Error Dbg_EndFileAccess(Dbg_MCState *state, Dbg_FileRec *handle);
+/* These two calls bracket a sequence of calls to GetFileLine. Between the
+ * calls, the toolbox is permitted to retain state allowing more rapid
+ * access to text on the file associated with <handle>.
+ */
+
+Dbg_Error Dbg_ControlSourceFileAccess(
+ Dbg_MCState *state, uint32 cachesize, bool closefiles);
+/* Control details of how the toolbox manages source files.
+ * If <cachesize> is non-zero, the text from the most recently accessed
+ * source files (of total size not to exceed <cachesize>) is saved in
+ * store on first access to the file; subsequent access to the text of
+ * the file uses this copy.
+ * If <closefiles> is true, no stream is left attached to uncached source
+ * files after Dbg_EndFileAccess has been closed. Otherwise, the toolbox
+ * may retain such streams, in order to improve access.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+/* disassembly */
+
+/*
+ ? More exact control is wanted here, but that requires a more complicated
+ ? disass callback interface.
+ */
+
+typedef const char *Dbg_SWI_Decode(Dbg_MCState *state, ARMword swino);
+
+Dbg_Error Dbg_InstructionAt(Dbg_MCState *state, ARMaddress addr,
+ int isize, ARMhword *inst, Dbg_SymTable *st,
+ Dbg_SWI_Decode *swi_name, Dbg_BufDesc *buf, int *length);
+/* <isize> describes the form of disassembly wanted: 2 for 16-bit, 4 for 32-bit,
+ * 0 for 16- or 32-bit depending whether addr addresses 16- or 32-bit code.
+ * <inst> is a pointer to a pair of halfwords *in target byte order*
+ * Possibly only the first halfword will be consumed: the number of bytes used
+ * is returned via <length>.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+int Dbg_RDIOpen(Dbg_MCState *state, unsigned type);
+int Dbg_RDIInfo(Dbg_MCState *state, unsigned type, ARMword *arg1, ARMword *arg2);
+
+/*--------------------------------------------------------------------------*/
+
+typedef enum {
+ Dbg_Point_Toolbox,
+ Dbg_Point_RDI_Unknown,
+ Dbg_Point_RDI_SW,
+ Dbg_Point_RDI_HW
+} Dbg_PointType;
+
+/* breakpoint management
+ Associated with a breakpoint there may be any of
+ a count
+ an expression
+ a function
+ the breakpoint is activated if
+ the expression evaluates to a non-zero value (or fails to evaluate).
+ && decrementing the count reaches zero (the count is then reset to its
+ initial value).
+ && the function, called with the breakpoint address as argument, returns
+ a non-zero value.
+? (The order here may be open to debate. Note that the first two are in
+ the opposite order in armsd, but I think this order more rational)
+ */
+
+typedef enum Dbg_BreakPosType {
+ bt_procpos,
+ bt_procexit,
+ bt_address
+} Dbg_BreakPosType;
+
+typedef union {
+ Dbg_ProcPos procpos;
+ Dbg_ProcDesc procexit;
+ ARMaddress address;
+} Dbg_BreakPosPos;
+
+typedef struct Dbg_BreakPos {
+ Dbg_BreakPosType sort;
+ Dbg_BreakPosPos loc;
+} Dbg_BreakPos;
+
+typedef int Dbg_BPProc(Dbg_MCState *state, void *BPArg, Dbg_BreakPos *where);
+
+typedef struct Dbg_BreakStatus {
+ int index;
+ int initcount, countnow;
+ Dbg_BreakPos where;
+ char *expr;
+ Dbg_BPProc *p; void *p_arg;
+ int incomplete;
+ Dbg_PointType type;
+ ARMword hwresource;
+} Dbg_BreakStatus;
+
+Dbg_Error Dbg_StringToBreakPos(
+ Dbg_MCState *state, Dbg_Environment *env, char const *str, size_t len,
+ Dbg_BreakPos *bpos, char *b);
+
+Dbg_Error Dbg_SetBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where,
+ int count,
+ const char *expr,
+ Dbg_BPProc *p, void *arg);
+Dbg_Error Dbg_SetBreakPoint16(Dbg_MCState *state, Dbg_BreakPos *where,
+ int count,
+ const char *expr,
+ Dbg_BPProc *p, void *arg);
+Dbg_Error Dbg_SetBreakPointNaturalSize(Dbg_MCState *state, Dbg_BreakPos *where,
+ int count,
+ const char *expr,
+ Dbg_BPProc *p, void *arg);
+/* Setting a breakpoint at the same address as a previous breakpoint
+ completely removes the previous one.
+ */
+
+Dbg_Error Dbg_DeleteBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
+
+Dbg_Error Dbg_SuspendBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
+/* Temporarily remove the break point (until Reinstated) but leave intact
+ its associated expr, the value its count has reached, etc.
+? The debugger toolbox itself wants this, but I'm not sure what use a client
+ could have for it. Ditto Reinstate...
+ */
+
+Dbg_Error Dbg_ReinstateBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
+/* Undo the effect of Dbg_SuspendBreakPoint
+ */
+
+Dbg_Error Dbg_DeleteAllBreakPoints(Dbg_MCState *state);
+
+Dbg_Error Dbg_SuspendAllBreakPoints(Dbg_MCState *state);
+
+Dbg_Error Dbg_ReinstateAllBreakPoints(Dbg_MCState *state);
+
+typedef Dbg_Error Dbg_BPEnumProc(Dbg_MCState *state, Dbg_BreakStatus *status, void *arg);
+
+Dbg_Error Dbg_EnumerateBreakPoints(Dbg_MCState *state, Dbg_BPEnumProc *p, void *arg);
+
+Dbg_Error Dbg_BreakPointStatus(Dbg_MCState *state,
+ const Dbg_BreakPos *where, Dbg_BreakStatus *status);
+
+typedef void Dbg_BreakAlteredProc(Dbg_MCState *state, ARMaddress addr, bool set);
+Dbg_Error Dbg_OnBreak(Dbg_MCState *state, Dbg_BreakAlteredProc *p);
+/* Register function to be called back whenever a breakpoint is set or
+ * cleared. (To allow multiple toolbox clients to coexist).
+ */
+
+bool Dbg_StoppedAtBreakPoint(Dbg_MCState *state, const Dbg_BreakPos *where);
+/* Called after execution which resulted in ps_atbreak, to find out whether
+ the specified breakpoint was hit (could be >1, eg. exit break and another
+ high-level breakpoint at the same position).
+ Returns NO if specified breakpoint not found, or execution didn't stop
+ with ps_atbreak status.
+ */
+
+/*--------------------------------------------------------------------------*/
+
+typedef struct {
+ Dbg_Value val;
+ char *name;
+} Dbg_WatchPos;
+
+typedef int Dbg_WPProc(Dbg_MCState *state, void *WPArg, Dbg_WatchPos *where);
+
+typedef struct Dbg_WPStatus {
+ int index;
+ int initcount, countnow;
+ Dbg_WatchPos what, target;
+ char *expr;
+ Dbg_WPProc *p; void *p_arg;
+ Dbg_PointType type;
+ ARMword hwresource;
+ int skip;
+} Dbg_WPStatus;
+
+Dbg_Error Dbg_SetWatchPoint(
+ Dbg_MCState *state, Dbg_Environment *context, char const *watchee,
+ char const *target,
+ int count,
+ char const *expr,
+ Dbg_WPProc *p, void *arg);
+
+/* Cause a watchpoint event if the value of <watchee> changes to the value of
+ <target> (or changes at all if <target> is NULL). <watchee> should
+ evaluate either to an L-value (when the size of the object being watched is
+ determined by its type) or to an integer constant (when the word with this
+ address is watched).
+ */
+
+Dbg_Error Dbg_DeleteWatchPoint(Dbg_MCState *state, Dbg_Environment *context, char const *watchee);
+
+
+Dbg_Error Dbg_SetWatchPoint_V(
+ Dbg_MCState *state,
+ char const *name, Dbg_Value const *val, char const *tname, Dbg_Value const *tval,
+ int count,
+ char const *expr,
+ Dbg_WPProc *p, void *arg);
+
+Dbg_Error Dbg_DeleteWatchPoint_V(Dbg_MCState *state, Dbg_Value const *val);
+
+
+Dbg_Error Dbg_DeleteAllWatchPoints(Dbg_MCState *state);
+
+typedef Dbg_Error Dbg_WPEnumProc(Dbg_MCState *state, Dbg_WPStatus const *watchee, void *arg);
+
+Dbg_Error Dbg_EnumerateWatchPoints(Dbg_MCState *state, Dbg_WPEnumProc *p, void *arg);
+
+Dbg_Error Dbg_WatchPointStatus(Dbg_MCState *state,
+ Dbg_WatchPos const *where, Dbg_WPStatus *status);
+
+typedef void Dbg_WPRemovedProc(void *arg, Dbg_WPStatus const *wp);
+Dbg_Error Dbg_RegisterWPRemovalProc(Dbg_MCState *state, Dbg_WPRemovedProc *p, void *arg);
+/* When a watchpoint goes out of scope it is removed by the toolbox, and the
+ function registered here gets called back to adjust its view
+ */
+
+typedef void Dbg_WatchAlteredProc(Dbg_MCState *state, Dbg_Value const *where, bool set);
+Dbg_Error Dbg_OnWatch(Dbg_MCState *state, Dbg_WatchAlteredProc *p);
+/* Register function to be called back whenever a watchpoint is set or
+ * cleared. (To allow multiple toolbox clients to coexist).
+ */
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_ProfileLoad(Dbg_MCState *state);
+
+Dbg_Error Dbg_ProfileStart(Dbg_MCState *state, ARMword interval);
+Dbg_Error Dbg_ProfileStop(Dbg_MCState *state);
+
+Dbg_Error Dbg_ProfileClear(Dbg_MCState *state);
+
+Dbg_Error Dbg_WriteProfile(Dbg_MCState *state, char const *filename,
+ char const *toolid, char const *arg);
+
+/*--------------------------------------------------------------------------*/
+
+Dbg_Error Dbg_ConnectChannel_ToHost(Dbg_MCState *state, RDICCProc_ToHost *p, void *arg);
+Dbg_Error Dbg_ConnectChannel_FromHost(Dbg_MCState *state, RDICCProc_FromHost *p, void *arg);
+
+/*--------------------------------------------------------------------------*/
+
+/* Configuration data management */
+
+Dbg_Error Dbg_LoadConfigData(Dbg_MCState *state, char const *filename);
+
+Dbg_Error Dbg_SelectConfig(
+ Dbg_MCState *state,
+ RDI_ConfigAspect aspect, char const *name, RDI_ConfigMatchType matchtype,
+ unsigned versionreq, unsigned *versionp);
+
+Dbg_Error Dbg_ParseConfigVersion(
+ char const *s, RDI_ConfigMatchType *matchp, unsigned *versionp);
+
+typedef Dbg_Error Dbg_ConfigEnumProc(Dbg_MCState *state, RDI_ConfigDesc const *desc, void *arg);
+
+Dbg_Error Dbg_EnumerateConfigs(Dbg_MCState *state, Dbg_ConfigEnumProc *p, void *arg);
+
+/*--------------------------------------------------------------------------*/
+
+/* Angel OS support */
+
+Dbg_Error Dbg_CreateTask(Dbg_MCState **statep, Dbg_MCState *parent, bool inherit);
+/* This is called when a task is to be debugged which has not been debugged
+ before - ie. there is no existing Dbg_MCState for this task. It
+ initialises a new Dbg_MCState and returns a pointer to it.
+ <parent> is any valid previously-created MCCState. If <inherit> is TRUE,
+ the new MCState inherits certain features from it (eg. symbols).
+ Otherwise, only features which are the same across all tasks are inherited,
+ (eg. global breakpoints).
+ */
+
+Dbg_Error Dbg_DeleteTask(Dbg_MCState *state);
+/* This is called when a task dies, and frees up everything which relates to that
+ task which is controlled by armdbg.
+ */
+
+Dbg_Error Dbg_DetachTask(Dbg_MCState *state);
+
+Dbg_Error Dbg_AttachTask(Dbg_MCState *state);
+/* These are called to request a switch of the current task. First
+ Dbg_DetachTask should be called with the state of the old task.
+ Dbg_DetachTask will ensure that any cached state held by armdbg for
+ the old task is immediately written out to the target.
+
+ After Dbg_DetachTask is called and before Dbg_AttachTask is called
+ the OS channel manager should tell the target that any future
+ requests from the debugger will be fore the new task.
+
+ If the new task does not have an armdbg state structure
+ already, then Dbg_CreateTask should be called to create one (see
+ above). Then Dbg_AttachTask is called to tell armdbg to treat the
+ new armdbg state as the current task.
+ */
+
+typedef Dbg_Error Dbg_TaskSwitchProc(void *arg, Dbg_MCState *newstate);
+
+Dbg_Error Dbg_OnTaskSwitch(Dbg_MCState *state, Dbg_TaskSwitchProc *fn, void *arg);
+/* The front end may register a callback which gets called by armdbg whenever
+ Dbg_AttachTask is called. This callback tells the front end the new current
+ Dbg_MCState it should use to call armdbg.
+ [Note that this is only useful if there is one front end shared between all
+ tasks rather than one front end per task]
+ The value of <arg> passed to Dbg_OnTaskSwitch is passed to <fn>
+ when it is called.
+ */
+
+typedef Dbg_Error Dbg_RestartProc(
+ void *arg, Dbg_MCState *curstate, Dbg_MCState **newstate);
+
+Dbg_Error Dbg_OnRestart(Dbg_MCState *state, Dbg_RestartProc *fn, void *arg);
+/* This is used by the OS channels layer to register a callback which
+ will be made by the debugger toolbox early in the process of resuming
+ execution.
+
+ This callback must determine which task will be resumed when the target
+ restarts execution. If this is not already the current task then it must
+ call Dbg_DetachTask and Dbg_AttachTask as decribed above to switch to the
+ task about to be resumed and return the state for the new task in
+ <newstate>.
+
+ This will ensure that armdbg updates the correct task on execution as well
+ as ensuring that stepping over a breakpointed instruction on restarting
+ happens correctly.
+
+ The value of <arg> passed to Dbg_OnRestart is passed to <fn>
+ when it is called.
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* End of armdbg.h */
diff --git a/gdb/rdi-share/buffers.h b/gdb/rdi-share/buffers.h
new file mode 100644
index 0000000..78549de
--- /dev/null
+++ b/gdb/rdi-share/buffers.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Public interface to buffer management
+ */
+
+#ifndef angel_buffers_h
+#define angel_buffers_h
+
+#include "chandefs.h" /* CHAN_HEADER_SIZE */
+
+
+/* the handle to a buffer */
+typedef unsigned char *p_Buffer;
+
+
+/*
+ * Angel Packets are structured as a fixed size header, followed
+ * by the packet data
+ */
+#ifdef TARGET
+# define BUFFERDATA(b) (b) /* channels layer takes care of it */
+#else
+# define BUFFERDATA(b) (&((b)[CHAN_HEADER_SIZE]))
+#endif
+
+
+/*
+ * The buffer management function prototypes are only applicable
+ * when compiling target code
+ */
+#ifdef TARGET
+
+/*
+ * Function: Angel_BufferQuerySizes
+ * Purpose: Request infomation on the default and maximum buffer sizes
+ * that can be allocated
+ *
+ * Params:
+ * In/Out: default_size, max_size: pointers to place the
+ * sizes in on return
+ */
+
+void Angel_BufferQuerySizes(unsigned int *default_size,
+ unsigned int *max_size );
+
+/*
+ * Function: Angel_RxEnginBuffersLeft
+ * Purpose: return the number of free buffers
+ *
+ * Params:
+ * Returns: number of free buffers
+ */
+unsigned int Angel_BuffersLeft( void );
+
+/*
+ * Function: Angel_BufferAlloc
+ * Purpose: allocate a buffer that is at least req_size bytes long
+ *
+ * Params:
+ * Input: req_size the required size of the buffer
+ *
+ * Returns: pointer to the buffer NULL if unable to
+ * fulfil the request
+ */
+p_Buffer Angel_BufferAlloc(unsigned int req_size);
+
+/*
+ * Function: Angel_BufferRelease
+ * Purpose: release a buffer back to the free pool
+ *
+ * Params:
+ * Input: pointer to the buffer to free
+ */
+void Angel_BufferRelease(p_Buffer buffer);
+
+
+/* return values for angel_InitBuffers */
+typedef enum buf_init_error{
+ INIT_BUF_OK,
+ INIT_BUF_FAIL
+} buf_init_error;
+
+/*
+ * Function: Angel_InitBuffers
+ * Purpose: Initalised and malloc the buffer pool
+ *
+ * Params:
+ * Returns: see above
+ */
+
+buf_init_error Angel_InitBuffers(void);
+
+#endif /* def TARGET */
+
+#endif /* ndef angel_buffers_h */
+
+/* EOF buffers.h */
diff --git a/gdb/rdi-share/bytesex.c b/gdb/rdi-share/bytesex.c
new file mode 100644
index 0000000..0c6aaae
--- /dev/null
+++ b/gdb/rdi-share/bytesex.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * bytesex.c - Code to support byte-sex independence
+ * Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England.
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#include "bytesex.h"
+
+static int reversing_bytes = 0;
+
+void bytesex_reverse(yes_or_no)
+int yes_or_no;
+{ reversing_bytes = yes_or_no;
+}
+
+int bytesex_reversing()
+{
+ return reversing_bytes;
+}
+
+int32 bytesex_hostval(v)
+int32 v;
+{ /* Return v with the same endian-ness as the host */
+ /* This mess generates better ARM code than the more obvious mess */
+ /* and may eventually peephole to optimal code... */
+ if (reversing_bytes)
+ { unsigned32 t;
+ /* t = v ^ (v ror 16) */
+ t = v ^ ((v << 16) | (((unsigned32)v) >> 16));
+ t &= ~0xff0000;
+ /* v = v ror 8 */
+ v = (v << 24) | (((unsigned32)v) >> 8);
+ v = v ^ (t >> 8);
+ }
+ return v;
+}
+
+int32 bytesex_hostval_16(v)
+int32 v;
+{
+ if (reversing_bytes) {
+ v = ((v >> 8) & 0xff) | ((v << 8) & 0xff00);
+ }
+ return v;
+}
diff --git a/gdb/rdi-share/bytesex.h b/gdb/rdi-share/bytesex.h
new file mode 100644
index 0000000..4b53ef3
--- /dev/null
+++ b/gdb/rdi-share/bytesex.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ Title: Code to support byte-sex independence
+ Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England.
+*/
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef __bytesex_h
+#define __bytesex_h
+
+#include "host.h"
+
+void bytesex_reverse(int yes_or_no);
+/*
+ * Turn sex-reversal on or off - 0 means off, non-0 means on.
+ */
+
+int bytesex_reversing(void);
+/*
+ * Return non-0 if reversing the byte sex, else 0.
+ */
+
+int32 bytesex_hostval(int32 v);
+/*
+ * Return v or byte-reversed v, according to whether sex-reversval
+ * is on or off.
+ */
+
+int32 bytesex_hostval_16(int32 v);
+/* Return v or byte-reversed v for a 16 bit value */
+
+#endif
diff --git a/gdb/rdi-share/chandefs.h b/gdb/rdi-share/chandefs.h
new file mode 100644
index 0000000..d97f0b5
--- /dev/null
+++ b/gdb/rdi-share/chandefs.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Enumeration with all supported channels
+ */
+
+#ifndef angel_chandefs_h
+#define angel_chandefs_h
+
+enum channelIDs {
+ CI_PRIVATE = 0, /* channels protocol control messages */
+ CI_HADP, /* ADP, host originated */
+ CI_TADP, /* ADP, target originated */
+ CI_HBOOT, /* Boot, host originated */
+ CI_TBOOT, /* Boot, target originated */
+ CI_CLIB, /* Semihosting C library support */
+ CI_HUDBG, /* User debug support, host originated */
+ CI_TUDBG, /* User debug support, target originated */
+ CI_HTDCC, /* Thumb direct comms channel, host orig. */
+ CI_TTDCC, /* Thumb direct comms channel, target orig. */
+ CI_TLOG, /* Target debug/logging */
+ CI_NUM_CHANNELS
+};
+
+typedef unsigned ChannelID;
+
+
+/*
+ * Size in bytes of the channel header.
+ * This is a duplicate of XXX in chanpriv.h, but we don't want everyone
+ * to have access to all of chanpriv.h, so we'll double-check in chanpriv.h.
+ */
+#define CHAN_HEADER_SIZE (4)
+
+#endif /* ndef angel_chandefs_h */
+
+/* EOF chandefs.h */
diff --git a/gdb/rdi-share/channels.h b/gdb/rdi-share/channels.h
new file mode 100644
index 0000000..b43ebc1
--- /dev/null
+++ b/gdb/rdi-share/channels.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: User interface to the channels layer
+ */
+
+#ifndef angel_channels_h
+#define angel_channels_h
+
+/*
+ * This provides the public interface to the channels layer read and write
+ * routines, and buffer management routines.
+ */
+
+/* Nested header files, if required */
+
+#include "devices.h"
+#include "chandefs.h"
+#include "adperr.h"
+
+/* General purpose constants, macros, enums, typedefs */
+
+/* use the default device */
+#define CH_DEFAULT_DEV ((DeviceID)-1)
+
+/* return codes */
+typedef enum ChanError {
+ CE_OKAY, /* no error */
+ CE_ABANDONED, /* abandoned due to device switch */
+ CE_DEV_ERROR, /* unexpected error from device driver */
+ CE_BUSY, /* channel in use */
+ CE_BUFF_ERROR, /* unable to get buffer */
+ CE_PRIVATE /* start of internal error codes */
+} ChanError;
+
+
+/* Publically-accessible globals */
+
+/*
+ * The following two globals are only valid after angel_InitialiseChannels()
+ * has been called.
+ */
+
+/* the default size of a channel buffer, for global use */
+extern unsigned Angel_ChanBuffSize;
+
+/* the size of a long buffer, for global use */
+extern unsigned Angel_ChanLongSize;
+
+#ifdef TARGET
+AdpErrs send_resend_msg(DeviceID devid);
+#endif
+
+/*
+ * Function: angel_InitialiseChannels
+ * Purpose: initialise the channels layer
+ *
+ * Params:
+ * Input: -
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: -
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+void angel_InitialiseChannels( void );
+
+/*
+ * Function: adp_init_seq
+ * Purpose: initialise sequence numbers and free anyt leftover buffers
+ *
+ * Params:
+ * Input: -
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: - adp_ok if things went ok else an error code
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+AdpErrs adp_init_seq(void);
+
+/*
+ * Function: angel_ChannelAllocBuffer
+ * Purpose: allocate a buffer that is at least req_size bytes long
+ *
+ * Params:
+ * Input: req_size the minimum size required
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: pointer to allocated buffer, or
+ * NULL if unable to allocate suitable buffer
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+p_Buffer angel_ChannelAllocBuffer(unsigned req_size);
+
+
+/*
+ * Function: angel_ChannelReleaseBuffer
+ * Purpose: release a buffer back to the free pool
+ *
+ * Params:
+ * Input: buffer the buffer to release
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: -
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+void angel_ChannelReleaseBuffer(p_Buffer buffer);
+
+
+/*
+ * Function: angel_ChannelSend
+ * Purpose: blocking send of a packet via a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for tx
+ * buffer Pointer to data to send
+ * len Length of data to send
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Transmission completed
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+ChanError angel_ChannelSend(DeviceID devid, ChannelID chanid,
+ const p_Buffer buffer, unsigned len);
+
+
+/*
+ * Function: angel_ChannelSendAsync
+ * Purpose: asynchronous send of a packet via a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for tx
+ * buffer Pointer to data to send
+ * len Length of data to send
+ * callback Function to call on completion
+ * callback_data Pointer to pass to callback
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Transmission underway
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * register an asynchronous send on the given channel
+ * (blocks until send can be commenced)
+ */
+
+typedef void (*ChanTx_CB_Fn)(ChannelID chanid, /* which channel */
+ void *callback_data); /* as supplied... */
+
+
+ChanError angel_ChannelSendAsync( DeviceID devid,
+ ChannelID chanid,
+ const p_Buffer buffer,
+ unsigned len,
+ ChanTx_CB_Fn callback,
+ void *callback_data);
+
+
+/*
+ * Function: angel_ChannelRead
+ * Purpose: blocking read of a packet from a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for rx
+ * Output: buffer The buffer, supplied and filled
+ * len How many bytes there are in the buffer
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Reception successful
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Note that in the present version, if an asynchronous read has been
+ * registered, a blocking read will be refused with CE_BUSY.
+ */
+ChanError angel_ChannelRead(DeviceID devid,
+ ChannelID chanid,
+ p_Buffer *buffer,
+ unsigned *len);
+
+
+/*
+ * Function: angel_ChannelReadAsync
+ * Purpose: asynchronous read of a packet via a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to wait on
+ * callback Function to call on completion, or NULL
+ * callback_data Pointer to pass to callback
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Read request registered
+ * CE_BAD_CHAN Channel id invalid
+ * CE_BUSY Someone else is using the channel
+ * (in a single threaded world)
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Register an asynchronous read on the given channel. There can only be one
+ * async. reader per channel, and blocking reads are not permitted whilst
+ * an async. reader is registered.
+ *
+ * Reader can unregister by specifying NULL as the callback function.
+ */
+
+typedef void (*ChanRx_CB_Fn)(DeviceID devID, /* ID of receiving device */
+ ChannelID chanID, /* ID of receiving channel */
+ p_Buffer buff, /* pointer to buffer */
+ unsigned len, /* length of data */
+ void *cb_data /* callback data */
+ );
+
+ChanError angel_ChannelReadAsync(DeviceID devid,
+ ChannelID chanid,
+ ChanRx_CB_Fn callback,
+ void *callback_data);
+
+
+/*
+ * Function: angel_ChannelReadAll
+ * Purpose: register an asynchronous read across all devices
+ *
+ * Params:
+ * Input: chanid Channel to look for (usually HBOOT)
+ * callback Function to call on completion
+ * callback_data Pointer to pass to callback
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Read request registered
+ * CE_BAD_CHAN Channel id invalid
+ * CE_BUSY Someone else is reading all devices
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Register an asynchronous read across all devices. This is a 'fallback',
+ * which will be superseded (temporarily) by a registered reader or blocking
+ * read on a specific device.
+ */
+
+ChanError angel_ChannelReadAll( ChannelID chanid,
+ ChanRx_CB_Fn callback,
+ void *callback_data);
+
+
+
+/*
+ * Function: angel_ChannelSendThenRead
+ * Purpose: blocking write to followed by read from a channel
+ *
+ * Params:
+ * Input: devid Device to use, or CH_DEFAULT_DEV
+ * chanid Channel to use for rx
+ * In/Out: buffer On entry: the packet to be sent
+ * On return: the packet received
+ * len On entry: length of packet to be sent
+ * On return: length of packet rx'd
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Tx and Reception successful
+ * CE_BAD_CHAN Channel id invalid
+ * CE_ABANDONED Tx abandoned due to device switch
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Note that in the present version, if an asynchronous read has been
+ * registered, this will be refused with CE_BUSY.
+ */
+ChanError angel_ChannelSendThenRead(DeviceID devid,
+ ChannelID chanid,
+ p_Buffer *buffer,
+ unsigned *len);
+
+
+/*
+ * Function: angel_ChannelSelectDevice
+ * Purpose: select the device to be used for all channel comms
+ *
+ * Params:
+ * Input: device ID of device to use as the default
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Default device selected
+ * CE_BAD_DEV Invalid device ID
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: Any channel operations in progress are
+ * abandoned.
+ *
+ * select the device for all channels comms
+ */
+
+ChanError angel_ChannelSelectDevice(DeviceID device);
+
+
+/*
+ * Function: angel_ChannelReadActiveDevice
+ * Purpose: reads the device id of the currently active device
+ *
+ * Params:
+ * Input: device address of a DeviceID variable
+ * Output: *device ID of device currently being used
+ * In/Out: -
+ *
+ * Returns: CE_OKAY Default device selected
+ */
+
+ChanError angel_ChannelReadActiveDevice(DeviceID *device);
+
+#endif /* ndef angel_channels_h */
+
+/* EOF channels.h */
diff --git a/gdb/rdi-share/chanpriv.h b/gdb/rdi-share/chanpriv.h
new file mode 100644
index 0000000..155e864
--- /dev/null
+++ b/gdb/rdi-share/chanpriv.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Private header for channels implementations
+ */
+
+#ifndef angel_chanpriv_h
+#define angel_chanpriv_h
+
+/*
+ * This describes the internal structure and flags for a channels packet.
+ */
+
+/* byte positions within channel packet */
+#define CF_CHANNEL_BYTE_POS 0
+#define CF_HOME_SEQ_BYTE_POS 1
+#define CF_OPPO_SEQ_BYTE_POS 2
+#define CF_FLAGS_BYTE_POS 3
+#define CF_DATA_BYTE_POS 4
+
+/* flags for FLAGS field */
+#define CF_RELIABLE (1 << 0) /* use reliable channels protocol */
+#define CF_RESEND (1 << 1) /* this is a renegotiation packet */
+#define CF_HEARTBEAT (1 << 2) /* heartbeat packet - prod target into sync */
+
+/* byte positions within buffer */
+#define CB_LINK_BYTE_POS 0 /* the link pointer */
+#define CB_CHAN_HEADER_BYTE_POS 4 /* the channel frame starts here */
+
+/* macro to get buffer position of packet component */
+#define CB_PACKET(x) (CB_CHAN_HEADER_BYTE_POS + (x))
+
+/* byte offset of packet data within buffer */
+#define CB_CHAN_DATA_BYTE_POS (CB_PACKET(CF_DATA_BYTE_POS))
+
+/* access the link in a buffer, where b is byte pointer to buffer */
+#define CB_LINK(b) ((p_Buffer)(&(b)[0]))
+
+#define invalidChannelID(chan) (((int)(chan)) < 0 || \
+ (chan) >= CI_NUM_CHANNELS)
+
+#endif /* ndef angel_chanpriv_h */
+
+/* EOF chanpriv.h */
diff --git a/gdb/rdi-share/configure.in b/gdb/rdi-share/configure.in
new file mode 100644
index 0000000..cd4a715
--- /dev/null
+++ b/gdb/rdi-share/configure.in
@@ -0,0 +1,44 @@
+srcname="RDI library"
+srctrigger=ardi.c
+
+# per-host:
+
+. ${srcdir}/../configure.host
+
+echo "rdi-share/configure.in: host is $host, target is $target"
+
+if [ ! -f ${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh ]; then
+ echo '***' "GDB remote does not support host ${host}" 1>&2
+ exit 1
+fi
+
+# We really shouldn't depend on there being a space after XM_FILE= ...
+hostfile=`awk '$1 == "XM_FILE=" { print $2 }' <${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh`
+
+# per-target:
+
+. ${srcdir}/../configure.tgt
+
+echo "rdi-share/configure.in: host_cpu is $host_cpu, target_cpu is $target_cpu"
+
+if [ ! -f ${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt ]; then
+ echo '***' "GDB remote does not support target ${target}" 1>&2
+ exit 1
+fi
+
+if [ -z "${removing}" ] ; then
+ cat ${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh ${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt | awk '$1 == "#msg" {
+ print substr($0,6)}'
+fi
+
+# We really shouldn't depend on there being a space after TM_FILE= ...
+targetfile=`awk '$1 == "TM_FILE=" { print $2 }' <${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt`
+
+if [ "${target}" = "${host}" ] ; then
+ nativefile=`awk '$1 == "NAT_FILE=" { print $2 }' <${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh`
+fi
+
+host_makefile_frag=../config/${gdb_host_cpu}/${gdb_host}.mh
+target_makefile_frag=../config/${gdb_target_cpu}/${gdb_target}.mt
+
+# post-target:
diff --git a/gdb/rdi-share/crc.c b/gdb/rdi-share/crc.c
new file mode 100644
index 0000000..cfa6522
--- /dev/null
+++ b/gdb/rdi-share/crc.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * crc.c - provides some "standard" CRC calculation routines.
+ *
+ */
+#include "crc.h" /* describes this code */
+
+/**********************************************************************/
+
+/*
+ * crc32 IEEE-802.3 32bit CRC
+ * ----- --------------------
+ */
+
+/* This table was generated by the "crctable" program */
+static const unsigned int crc32table[256] = {
+ /* 0x00 */ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ /* 0x04 */ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ /* 0x08 */ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ /* 0x0C */ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ /* 0x10 */ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ /* 0x14 */ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ /* 0x18 */ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ /* 0x1C */ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ /* 0x20 */ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ /* 0x24 */ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ /* 0x28 */ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ /* 0x2C */ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ /* 0x30 */ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ /* 0x34 */ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ /* 0x38 */ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ /* 0x3C */ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ /* 0x40 */ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ /* 0x44 */ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ /* 0x48 */ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ /* 0x4C */ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ /* 0x50 */ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ /* 0x54 */ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ /* 0x58 */ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ /* 0x5C */ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ /* 0x60 */ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ /* 0x64 */ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ /* 0x68 */ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ /* 0x6C */ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ /* 0x70 */ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ /* 0x74 */ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ /* 0x78 */ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ /* 0x7C */ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ /* 0x80 */ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ /* 0x84 */ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ /* 0x88 */ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ /* 0x8C */ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ /* 0x90 */ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ /* 0x94 */ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ /* 0x98 */ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ /* 0x9C */ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ /* 0xA0 */ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ /* 0xA4 */ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ /* 0xA8 */ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ /* 0xAC */ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ /* 0xB0 */ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ /* 0xB4 */ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ /* 0xB8 */ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ /* 0xBC */ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ /* 0xC0 */ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ /* 0xC4 */ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ /* 0xC8 */ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ /* 0xCC */ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ /* 0xD0 */ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ /* 0xD4 */ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ /* 0xD8 */ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ /* 0xDC */ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ /* 0xE0 */ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ /* 0xE4 */ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ /* 0xE8 */ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ /* 0xEC */ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ /* 0xF0 */ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ /* 0xF4 */ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ /* 0xF8 */ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ /* 0xFC */ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
+ };
+unsigned int crc32(unsigned char *address, unsigned int size, unsigned int crc)
+{
+#if 0
+ /* FAST, but bigger and only good for word-aligned data */
+ unsigned int *daddr = (unsigned int *)address;
+ unsigned int data = FALSE; /* little-endian by default */
+
+ /*
+ * TODO: We should really get the current processor big- or
+ * little-endian state and set "data" accordingly.
+ */
+
+ /* Perform word loop to save on memory accesses */
+ if (data)
+ /* big-endian */
+ for (; (size > 0); size -= sizeof(unsigned int))
+ {
+ data = *daddr++;
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
+ }
+ else
+ for (; (size > 0); size -= sizeof(unsigned int))
+ {
+ data = *daddr++;
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
+ }
+#else
+ for (; (size > 0); size--)
+ /* byte loop */
+ crc = (((crc >> 8) & 0x00FFFFFF) ^
+ crc32table[(crc ^ *address++) & 0x000000FF]);
+#endif
+
+ return(crc);
+}
+
+/**********************************************************************/
+
+/*
+ * crc16 16bit CRC-CCITT
+ * ----- ---------------
+ * This function provides a table driven 16bit CRC generation for byte data.
+ * This CRC is also known as the HDLC CRC.
+ */
+/*
+ * 960201 KWelton
+ *
+ *TODO: Is this correct? The compiler predefines __arm, *not* __ARM
+ */
+#ifdef __ARM
+/*
+ * To make the code quicker on the ARM, we double the table size and
+ * use integer slots rather than short slots for the table.
+ */
+static const unsigned int crctableA[16] = {
+#else
+static const unsigned short crctableA[16] = {
+#endif
+ 0x0000,
+ 0x1081,
+ 0x2102,
+ 0x3183,
+ 0x4204,
+ 0x5285,
+ 0x6306,
+ 0x7387,
+ 0x8408,
+ 0x9489,
+ 0xA50A,
+ 0xB58B,
+ 0xC60C,
+ 0xD68D,
+ 0xE70E,
+ 0xF78F
+ };
+
+#ifdef __ARM
+/* See comments above */
+static const unsigned int crctableB[16] = {
+#else
+static const unsigned short crctableB[16] = {
+#endif
+ 0x0000,
+ 0x1189,
+ 0x2312,
+ 0x329B,
+ 0x4624,
+ 0x57AD,
+ 0x6536,
+ 0x74BF,
+ 0x8C48,
+ 0x9DC1,
+ 0xAF5A,
+ 0xBED3,
+ 0xCA6C,
+ 0xDBE5,
+ 0xE97E,
+ 0xF8F7
+ };
+
+unsigned short crc16(unsigned char *address, unsigned int size,
+ unsigned short crc)
+{
+ for (; (size > 0); size--)
+ {
+ /* byte loop */
+ unsigned char data = *address++; /* fetch the next data byte */
+
+ data ^= crc; /* EOR data with current CRC value */
+ crc = ((crctableA[(data & 0xF0) >> 4] ^ crctableB[data & 0x0F]) ^
+ (crc >> 8));
+ }
+
+ return(crc);
+}
+
+/**********************************************************************/
+
+#if 0 /* not required at the moment */
+
+/*
+ * elf_hash
+ * --------
+ * This function is derived from the one on page 68 of chapter of the "Unix
+ * SVR4 Programmer's Guide". It is used to generate a hash-code from a
+ * symbol name.
+ */
+unsigned int elf_hash(const unsigned char *name)
+{
+ unsigned int h = 0;
+ unsigned int g;
+
+ /* NULL pointer returns a hash of zero */
+ while (name && (*name))
+ {
+ h = ((h << 4) + *name++);
+
+ if (g = (h & 0xF0000000))
+ h ^= (g >> 24);
+
+ h &= ~g;
+ }
+
+ return(h);
+}
+#endif
+
+/**********************************************************************/
+
+/* EOF crc.c */
diff --git a/gdb/rdi-share/crc.h b/gdb/rdi-share/crc.h
new file mode 100644
index 0000000..77ba23e
--- /dev/null
+++ b/gdb/rdi-share/crc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * crc.h - describes some "standard" CRC calculation routines.
+ */
+#ifndef angel_crc_h
+#define angel_crc_h
+
+/*
+ * manifests
+ */
+
+/*
+ * When using "crc32" or "crc16" these initial CRC values must be given to
+ * the respective function the first time it is called. The function can
+ * then be called with the return value from the last call of the function
+ * to generate a running CRC over multiple data blocks.
+ * When the last data block has been processed using the "crc32" algorithm
+ * the CRC value should be inverted to produce the final CRC value:
+ * e.g. CRC = ~CRC
+ */
+
+#define startCRC32 (0xFFFFFFFF) /* CRC initialised to all 1s */
+#define startCRC16 (0x0000) /* CRC initialised to all 0s */
+
+/*
+ * For the CRC-32 residual to be calculated correctly requires that the CRC
+ * value is in memory little-endian due to the byte read, bit-ordering
+ * nature of the algorithm.
+ */
+#define CRC32residual (0xDEBB20E3) /* good CRC-32 residual */
+
+
+/**********************************************************************/
+
+/*
+ * exported functions
+ */
+
+/*
+ * Function: crc32
+ * Purpose: Provides a table driven implementation of the IEEE-802.3
+ * 32-bit CRC algorithm for byte data.
+ *
+ * Params:
+ * Input: address pointer to the byte data
+ * size number of bytes of data to be processed
+ * crc initial CRC value to be used (can be the output
+ * from a previous call to this function).
+ * Returns:
+ * OK: 32-bit CRC value for the specified data
+ */
+extern unsigned int crc32(unsigned char *address, unsigned int size,
+ unsigned int crc);
+
+/**********************************************************************/
+
+/*
+ *
+ * Function: crc16
+ * Purpose: Generates a table driven 16-bit CRC-CCITT for byte data
+ *
+ * Params:
+ * Input: address pointer to the byte data
+ * size number of bytes of data to be processed
+ * crc initial CRC value to be used (can be the output
+ * from a previous call to this function).
+ *
+ * Returns:
+ * OK: 16-bit CRC value for the specified data
+ */
+extern unsigned short crc16(unsigned char *address, unsigned int size,
+ unsigned short crc);
+
+/**********************************************************************/
+
+#endif /* !defined(angel_crc_h) */
+
+/* EOF crc.h */
diff --git a/gdb/rdi-share/dbg_conf.h b/gdb/rdi-share/dbg_conf.h
new file mode 100644
index 0000000..bf79958
--- /dev/null
+++ b/gdb/rdi-share/dbg_conf.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM symbolic debugger toolbox: dbg_conf.h
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef Dbg_Conf__h
+
+#define Dbg_Conf__h
+
+typedef struct Dbg_ConfigBlock {
+ int bytesex;
+ int fpe; /* Target should initialise FPE */
+ long memorysize;
+ unsigned long cpu_speed;/* Cpu speed (HZ) */
+ int serialport; /*) remote connection parameters */
+ int seriallinespeed; /*) (serial connection) */
+ int parallelport; /*) ditto */
+ int parallellinespeed; /*) (parallel connection) */
+ char *ethernettarget; /* name of remote ethernet target */
+ int processor; /* processor the armulator is to emulate (eg ARM60) */
+ int rditype; /* armulator / remote processor */
+ int heartbeat_on; /* angel heartbeat */
+ int drivertype; /* parallel / serial / etc */
+ char const *configtoload;
+ char const *memconfigtoload;
+ int flags;
+} Dbg_ConfigBlock;
+
+#define Dbg_ConfigFlag_Reset 1
+#define Dbg_ConfigFlag_LLSymsNeedPrefix 2
+
+typedef struct Dbg_HostosInterface Dbg_HostosInterface;
+/* This structure allows access by the (host-independent) C-library support
+ module of armulator or pisd (armos.c) to host-dependent functions for
+ which there is no host-independent interface. Its contents are unknown
+ to the debugger toolbox.
+ The assumption is that, in a windowed system, fputc(stderr) for example
+ may not achieve the desired effect of the character appearing in some
+ window.
+ */
+
+#endif
diff --git a/gdb/rdi-share/dbg_cp.h b/gdb/rdi-share/dbg_cp.h
new file mode 100644
index 0000000..8974f83
--- /dev/null
+++ b/gdb/rdi-share/dbg_cp.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM symbolic debugger toolbox: dbg_cp.h
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef Dbg_CP__h
+
+#define Dbg_CP__h
+
+#define Dbg_Access_Readable 1
+#define Dbg_Access_Writable 2
+#define Dbg_Access_CPDT 4 /* else CPRT */
+
+typedef struct {
+ unsigned short rmin, rmax;
+ /* a single description can be used for a range of registers with
+ the same properties *accessed via CPDT instructions*
+ */
+ unsigned char nbytes; /* size of register */
+ unsigned char access; /* see above (Access_xxx) */
+ union {
+ struct { /* CPDT instructions do not allow the coprocessor much freedom:
+ only bit 22 ('N') and 12-15 ('CRd') are free for the
+ coprocessor to use as it sees fit.
+ */
+ unsigned char nbit;
+ unsigned char rdbits;
+ } cpdt;
+ struct { /* CPRT instructions have much more latitude. The bits fixed
+ by the ARM are 24..31 (condition mask & opcode)
+ 20 (direction)
+ 8..15 (cpnum, arm register)
+ 4 (CPRT not CPDO)
+ leaving 14 bits free to the coprocessor (fortunately
+ falling within two bytes).
+ */
+ unsigned char read_b0, read_b1,
+ write_b0, write_b1;
+ } cprt;
+ } accessinst;
+} Dbg_CoProRegDesc;
+
+struct Dbg_CoProDesc {
+ int entries;
+ Dbg_CoProRegDesc regdesc[1/* really nentries */];
+};
+
+#define Dbg_CoProDesc_Size(n) (sizeof(struct Dbg_CoProDesc) + ((n)-1)*sizeof(Dbg_CoProRegDesc))
+
+#endif
diff --git a/gdb/rdi-share/dbg_hif.h b/gdb/rdi-share/dbg_hif.h
new file mode 100644
index 0000000..3982d11
--- /dev/null
+++ b/gdb/rdi-share/dbg_hif.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM debugger toolbox : dbg_hif.c
+ * Description of the Dbg_HostosInterface structure. This is *NOT*
+ * part of the debugger toolbox, but it is required by 2 back ends
+ * (armul & pisd) and two front ends (armsd & wdbg), so putting it
+ * in the toolbox is the only way of avoiding multiple copies.
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef dbg_hif__h
+#define dbg_hif__h
+
+#if defined __STDC__ || defined ALMOST_STDC
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+typedef void Hif_DbgPrint(void *arg, const char *format, va_list ap);
+typedef void Hif_DbgPause(void *arg);
+
+typedef void Hif_WriteC(void *arg, int c);
+typedef int Hif_ReadC(void *arg);
+typedef int Hif_Write(void *arg, char const *buffer, int len);
+typedef char *Hif_GetS(void *arg, char *buffer, int len);
+
+typedef void Hif_RDIResetProc(void *arg);
+
+struct Dbg_HostosInterface {
+ Hif_DbgPrint *dbgprint;
+ Hif_DbgPause *dbgpause;
+ void *dbgarg;
+
+ Hif_WriteC *writec;
+ Hif_ReadC *readc;
+ Hif_Write *write;
+ Hif_GetS *gets;
+ void *hostosarg;
+
+ Hif_RDIResetProc *reset;
+ void *resetarg;
+};
+
+#endif
diff --git a/gdb/rdi-share/dbg_rdi.h b/gdb/rdi-share/dbg_rdi.h
new file mode 100644
index 0000000..efda7bd
--- /dev/null
+++ b/gdb/rdi-share/dbg_rdi.h
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARM debugger toolbox : dbg_rdi.h
+ */
+
+/*
+ * RCS $Revision$
+ * Checkin $Date$
+ */
+
+#ifndef dbg_rdi__h
+#define dbg_rdi__h
+
+/***************************************************************************\
+* Other RDI values *
+\***************************************************************************/
+
+#define RDISex_Little 0 /* the byte sex of the debuggee */
+#define RDISex_Big 1
+#define RDISex_DontCare 2
+
+#define RDIPoint_EQ 0 /* the different types of break/watchpoints */
+#define RDIPoint_GT 1
+#define RDIPoint_GE 2
+#define RDIPoint_LT 3
+#define RDIPoint_LE 4
+#define RDIPoint_IN 5
+#define RDIPoint_OUT 6
+#define RDIPoint_MASK 7
+
+#define RDIPoint_16Bit 16 /* 16-bit breakpoint */
+#define RDIPoint_Conditional 32
+
+/* ORRed with point type in extended RDP break and watch messages */
+#define RDIPoint_Inquiry 64
+#define RDIPoint_Handle 128 /* messages */
+
+#define RDIWatch_ByteRead 1 /* types of data accesses to watch for*/
+#define RDIWatch_HalfRead 2
+#define RDIWatch_WordRead 4
+#define RDIWatch_ByteWrite 8
+#define RDIWatch_HalfWrite 16
+#define RDIWatch_WordWrite 32
+
+#define RDIReg_R15 (1L << 15) /* mask values for CPU */
+#define RDIReg_PC (1L << 16)
+#define RDIReg_CPSR (1L << 17)
+#define RDIReg_SPSR (1L << 18)
+#define RDINumCPURegs 19
+
+#define RDINumCPRegs 10 /* current maximum */
+
+#define RDIMode_Curr 255
+
+/* RDI_Info subcodes */
+/* rdp in parameters are all preceded by */
+/* in byte = RDP_Info, word = info subcode */
+/* out parameters are all preceded by */
+/* out byte = RDP_Return */
+
+#define RDIInfo_Target 0
+/* rdi: out ARMword *targetflags, out ARMword *processor id */
+/* rdp: in none, out word targetflags, word processorid, byte status */
+/* the following bits are defined in targetflags */
+# define RDITarget_LogSpeed 0x0f
+# define RDITarget_HW 0x10 /* else emulator */
+# define RDITarget_AgentMaxLevel 0xe0
+# define RDITarget_AgentLevelShift 5
+# define RDITarget_DebuggerMinLevel 0x700
+# define RDITarget_DebuggerLevelShift 8
+# define RDITarget_CanReloadAgent 0x800
+# define RDITarget_CanInquireLoadSize 0x1000
+# define RDITarget_UnderstandsRDPInterrupt 0x2000
+# define RDITarget_CanProfile 0x4000
+# define RDITarget_Code16 0x8000
+# define RDITarget_HasCommsChannel 0x10000
+
+#define RDIInfo_Points 1
+/* rdi: out ARMword *pointcapabilities */
+/* rdp: in none, out word pointcapabilities, byte status */
+/* the following bits are defined in pointcapabilities */
+# define RDIPointCapability_Comparison 1
+# define RDIPointCapability_Range 2
+/* 4 to 128 are RDIWatch_xx{Read,Write} left-shifted by two */
+# define RDIPointCapability_Mask 0x100
+# define RDIPointCapability_ThreadBreak 0x200
+# define RDIPointCapability_ThreadWatch 0x400
+# define RDIPointCapability_CondBreak 0x800
+# define RDIPointCapability_Status 0x1000 /* status enquiries available */
+
+#define RDIInfo_Step 2
+/* rdi: out ARMword *stepcapabilities */
+/* rdp: in none, out word stepcapabilities, byte status */
+/* the following bits are defined in stepcapabilities */
+# define RDIStep_Multiple 1
+# define RDIStep_PCChange 2
+# define RDIStep_Single 4
+
+#define RDIInfo_MMU 3
+/* rdi: out ARMword *mmuidentity */
+/* rdp: in none, out word mmuidentity, byte status */
+
+#define RDIInfo_DownLoad 4
+/* Inquires whether configuration download and selection is available. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIInfo_SemiHosting 5
+/* Inquires whether RDISemiHosting_* RDI_Info calls are available. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIInfo_CoPro 6
+/* Inquires whether CoPro RDI_Info calls are available. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIInfo_Icebreaker 7
+/* Inquires whether debuggee controlled by IceBreaker. */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+#define RDIMemory_Access 8
+/* rdi: out RDI_MemAccessStats *p, in ARMword *handle */
+/* rdp: in word handle */
+/* out word nreads, word nwrites, word sreads, word swrites, */
+/* word ns, word s, byte status */
+
+/* Get memory access information for memory block with specified handle */
+
+#define RDIMemory_Map 9
+/* rdi: in RDI_MemDescr md[n], in ARMword *n */
+/* rdp: in word n, n * { */
+/* word handle, word start, word limit, */
+/* byte width, byte access */
+/* word Nread_ns, word Nwrite_ns, */
+/* word Sread_ns, word Swrite_ns} */
+/* out byte status */
+/* Sets memory characteristics. */
+
+#define RDISet_CPUSpeed 10
+/* rdi: in ARMword *speed */
+/* rdp: in word speed, out byte status */
+/* Sets CPU speed (in ns) */
+
+#define RDIRead_Clock 12
+/* rdi: out ARMword *ns, out ARMword *s */
+/* rdp: in none, out word ns, word s, byte status */
+/* Reads simulated time */
+
+#define RDIInfo_Memory_Stats 13
+/* Inquires whether RDI_Info codes 8-10 are available */
+/* rdp: in none, out byte status */
+/* No argument, no return value. status == ok if available */
+
+/* The next two are only to be used if RDIInfo_DownLoad returned no */
+/* error */
+#define RDIConfig_Count 14
+/* rdi: out ARMword *count */
+/* rdp: out byte status, word count (if status == OK) */
+
+/* In addition, the next one is only to be used if RDIConfig_Count */
+/* returned no error */
+typedef struct { unsigned32 version; char name[32]; } RDI_ConfigDesc;
+#define RDIConfig_Nth 15
+/* rdi: in ARMword *n, out RDI_ConfigDesc * */
+/* rdp: in word n */
+/* out word version, byte namelen, bytes * bytelen name, */
+/* byte status */
+
+/* Set a front-end polling function to be used from within driver poll */
+/* loops */
+typedef void RDI_PollProc(void *);
+typedef struct { RDI_PollProc *p; void *arg; } RDI_PollDesc;
+#define RDISet_PollProc 16
+/* rdi: in RDI_PollDesc const *from, RDI_PollDesc *to */
+/* if from non-NULL, sets the polling function from it */
+/* if to non-NULL, returns the previous polling function to it */
+/* No corresponding RDP operation */
+
+/* Called on debugger startup to see if the target is ready to execute */
+#define RDIInfo_CanTargetExecute 20
+/* rdi: in void
+ * out byte status (RDIError_NoError => Yes, Otherwise No)
+ */
+
+/* Called to set the top of target memory in an ICEman2 system
+ * This is then used by ICEman to tell the C Library via the INFOHEAP
+ * SWI where the stack should start.
+ * Note that only ICEman2 supports this call. Other systems eg.
+ * Demon, Angel, will simply return an error, which means that setting
+ * the top of memory in this fashion is not supported.
+ */
+#define RDIInfo_SetTopMem 21
+/* rdi: in word mem_top
+ * out byte status (RDIError_NoError => Done, Other => Not supported
+ */
+
+/* Called before performing a loadagent to determine the endianess of
+ * the debug agent, so that images of the wrong bytesex can be
+ * complained about
+ */
+#define RDIInfo_AgentEndianess 22
+/* rdi: in void
+ * out byte status
+ * status should be RDIError_LittleEndian or RDIError_BigEndian
+ * any other value indicates the target does not support this
+ * request, so the debugger will have to make a best guess, which
+ * probably means only allow little endian loadagenting.
+ */
+
+/* The next two are only to be used if the value returned by */
+/* RDIInfo_Points has RDIPointCapability_Status set. */
+#define RDIPointStatus_Watch 0x80
+#define RDIPointStatus_Break 0x81
+/* rdi: inout ARMword * (in handle, out hwresource), out ARMword *type */
+/* rdp: in word handle, out word hwresource, word type, byte status */
+
+#define RDISignal_Stop 0x100
+/* Requests that the debuggee stop */
+/* No arguments, no return value */
+/* rdp: no reply (when the debuggee stops, there will be a reply to the */
+/* step or execute request which started it) */
+
+#define RDIVector_Catch 0x180
+/* rdi: in ARMword *bitmap */
+/* rdp: int word bitmap, out byte status */
+/* bit i in bitmap set to cause vector i to cause entry to debugger */
+
+/* The next four are only to be used if RDIInfo_Semihosting returned */
+/* no error */
+#define RDISemiHosting_SetState 0x181
+/* rdi: in ARMword *semihostingstate */
+/* rdp: in word semihostingstate, out byte status */
+#define RDISemiHosting_GetState 0x182
+/* rdi: out ARMword *semihostingstate */
+/* rdp: in none, out word semihostingstate, byte status */
+#define RDISemiHosting_SetVector 0x183
+/* rdi: in ARMword *semihostingvector */
+/* rdp: in word semihostingvector, out byte status */
+#define RDISemiHosting_GetVector 0x184
+/* rdi: out ARMword *semihostingvector */
+/* rdp: in none, out word semihostingvector, byte status */
+
+/* The next two are only to be used if RDIInfo_Icebreaker returned */
+/* no error */
+#define RDIIcebreaker_GetLocks 0x185
+/* rdi: out ARMword *lockedstate */
+/* rdp: in none, out word lockedstate, byte status */
+
+#define RDIIcebreaker_SetLocks 0x186
+/* rdi: in ARMword *lockedstate */
+/* rdp: in word lockedstate, out byte status */
+
+/* lockedstate is a bitmap of the icebreaker registers locked against */
+/* use by IceMan (because explicitly written by the user) */
+
+#define RDIInfo_GetLoadSize 0x187
+/* rdi: out ARMword *maxloadsize */
+/* rdp: in none, out word maxloadsize, byte status */
+/* Inquires the maximum length of data transfer the agent is prepared */
+/* to receive */
+/* Only usable if RDIInfo_Target returned RDITarget_CanInquireLoadSize */
+/* rdi: out ARMword *size */
+
+/* Only to be used if the value returned by RDIInfo_Target had */
+/* RDITarget_HasCommsChannel set */
+typedef void RDICCProc_ToHost(void *arg, ARMword data);
+typedef void RDICCProc_FromHost(void *arg, ARMword *data, int *valid);
+
+#define RDICommsChannel_ToHost 0x188
+/* rdi: in RDICCProc_ToHost *, in void *arg */
+/* rdp: in byte connect, out byte status */
+#define RDICommsChannel_FromHost 0x189
+/* rdi: in RDICCProc_FromHost *, in void *arg */
+/* rdp: in byte connect, out byte status */
+
+/* These 4 are only to be used if RDIInfo_Semihosting returns no error */
+#define RDISemiHosting_SetARMSWI 0x190
+/* rdi: in ARMword ARM_SWI_number */
+/* rdp: in ARMword ARM_SWI_number, out byte status */
+
+#define RDISemiHosting_GetARMSWI 0x191
+/* rdi: out ARMword ARM_SWI_number */
+/* rdp: out ARMword ARM_SWI_number, byte status */
+
+#define RDISemiHosting_SetThumbSWI 0x192
+/* rdi: in ARMword Thumb_SWI_number */
+/* rdp: in ARMword Thumb_SWI_number, out byte status */
+
+#define RDISemiHosting_GetThumbSWI 0x193
+/* rdi: out ARMword ARM_Thumb_number */
+/* rdp: out ARMword ARM_Thumb_number, byte status */
+
+
+#define RDICycles 0x200
+/* rdi: out ARMword cycles[12] */
+/* rdp: in none, out 6 words cycles, byte status */
+/* the rdi result represents 6 big-endian doublewords; the rdp results */
+/* return values for the ls halves of these */
+# define RDICycles_Size 48
+
+#define RDIErrorP 0x201
+/* rdi: out ARMaddress *errorp */
+/* rdp: in none, out word errorp, byte status */
+/* Returns the error pointer associated with the last return from step */
+/* or execute with status RDIError_Error. */
+
+#define RDISet_Cmdline 0x300
+/* rdi: in char *commandline (a null-terminated string) */
+/* No corresponding RDP operation (cmdline is sent to the agent in */
+/* response to SWI_GetEnv) */
+
+#define RDISet_RDILevel 0x301
+/* rdi: in ARMword *level */
+/* rdp: in word level, out byte status */
+/* Sets the RDI/RDP protocol level to be used (must lie between the */
+/* limits returned by RDIInfo_Target). */
+
+#define RDISet_Thread 0x302
+/* rdi: in ARMword *threadhandle */
+/* rdp: in word threadhandle, out byte status */
+/* Sets the thread context for subsequent thread-sensitive operations */
+/* (null value sets no thread) */
+
+/* The next two are only to be used if RDI_read or RDI_write returned */
+/* RDIError_LittleEndian or RDIError_BigEndian, to signify that the */
+/* debugger has noticed. */
+#define RDIInfo_AckByteSex 0x303
+/* rdi: in ARMword *sex (RDISex_Little or RDISex_Big) */
+
+/* The next two are only to be used if RDIInfo_CoPro returned no error */
+#define RDIInfo_DescribeCoPro 0x400
+/* rdi: in int *cpno, Dbg_CoProDesc *cpd */
+/* rdp: in byte cpno, */
+/* cpd->entries * { */
+/* byte rmin, byte rmax, byte nbytes, byte access, */
+/* byte cprt_r_b0, cprt_r_b1, cprt_w_b0, cprt_w_b1} */
+/* byte = 255 */
+/* out byte status */
+
+#define RDIInfo_RequestCoProDesc 0x401
+/* rdi: in int *cpno, out Dbg_CoProDesc *cpd */
+/* rpd: in byte cpno */
+/* out nentries * { */
+/* byte rmin, byte rmax, byte nbytes, byte access, */
+/* } */
+/* byte = 255, byte status */
+
+#define RDIInfo_Log 0x800
+/* rdi: out ARMword *logsetting */
+/* No corresponding RDP operation */
+#define RDIInfo_SetLog 0x801
+/* rdi: in ARMword *logsetting */
+/* No corresponding RDP operation */
+
+#define RDIProfile_Stop 0x500
+/* No arguments, no return value */
+/* rdp: in none, out byte status */
+/* Requests that pc sampling stop */
+
+#define RDIProfile_Start 0x501
+/* rdi: in ARMword *interval */
+/* rdp: in word interval, out byte status */
+/* Requests that pc sampling start, with period <interval> usec */
+
+#define RDIProfile_WriteMap 0x502
+/* rdi: in ARMword map[] */
+/* map[0] is the length of the array, subsequent elements are sorted */
+/* and are the base of ranges for pc sampling (so if the sampled pc */
+/* lies between map[i] and map[i+1], count[i] is incremented). */
+/* rdp: a number of messages, each of form: */
+/* in word len, word size, word offset, <size> words map data */
+/* out status */
+/* len, size and offset are all word counts. */
+
+#define RDIProfile_ReadMap 0x503
+/* rdi: in ARMword *len, out ARMword counts[len] */
+/* Requests that the counts array be set to the accumulated pc sample */
+/* counts */
+/* rdp: a number of messages, each of form: */
+/* in word offset, word size */
+/* out <size> words, status */
+/* len, size and offset are all word counts. */
+
+#define RDIProfile_ClearCounts 0x504
+/* No arguments, no return value */
+/* rdp: in none, out byte status */
+/* Requests that pc sample counts be set to zero */
+
+#define RDIInfo_RequestReset 0x900
+/* Request reset of the target environment */
+/* No arguments, no return value */
+/* No RDP equivalent, sends an RDP reset */
+
+#define RDIInfo_CapabilityRequest 0x8000
+/* Request whether the interface supports the named capability. The */
+/* capability is specified by or'ing the RDIInfo number with this, and */
+/* sending that request */
+/* rdi: in none */
+/* rdp: in none, out byte status */
+
+typedef struct {
+ ARMword len;
+ ARMword map[1];
+} RDI_ProfileMap;
+
+typedef unsigned32 PointHandle;
+typedef unsigned32 ThreadHandle;
+#define RDINoPointHandle ((PointHandle)-1L)
+#define RDINoHandle ((ThreadHandle)-1L)
+
+struct Dbg_ConfigBlock;
+struct Dbg_HostosInterface;
+struct Dbg_MCState;
+typedef int rdi_open_proc(unsigned type, struct Dbg_ConfigBlock const *config,
+ struct Dbg_HostosInterface const *i,
+ struct Dbg_MCState *dbg_state);
+typedef int rdi_close_proc(void);
+typedef int rdi_read_proc(ARMword source, void *dest, unsigned *nbytes);
+typedef int rdi_write_proc(const void *source, ARMword dest, unsigned *nbytes);
+typedef int rdi_CPUread_proc(unsigned mode, unsigned32 mask, ARMword *state);
+typedef int rdi_CPUwrite_proc(unsigned mode, unsigned32 mask, ARMword const *state);
+typedef int rdi_CPread_proc(unsigned CPnum, unsigned32 mask, ARMword *state);
+typedef int rdi_CPwrite_proc(unsigned CPnum, unsigned32 mask, ARMword const *state);
+typedef int rdi_setbreak_proc(ARMword address, unsigned type, ARMword bound,
+ PointHandle *handle);
+typedef int rdi_clearbreak_proc(PointHandle handle);
+typedef int rdi_setwatch_proc(ARMword address, unsigned type, unsigned datatype,
+ ARMword bound, PointHandle *handle);
+typedef int rdi_clearwatch_proc(PointHandle handle);
+typedef int rdi_execute_proc(PointHandle *handle);
+typedef int rdi_step_proc(unsigned ninstr, PointHandle *handle);
+typedef int rdi_info_proc(unsigned type, ARMword *arg1, ARMword *arg2);
+typedef int rdi_pointinq_proc(ARMword *address, unsigned type,
+ unsigned datatype, ARMword *bound);
+
+typedef enum {
+ RDI_ConfigCPU,
+ RDI_ConfigSystem
+} RDI_ConfigAspect;
+
+typedef enum {
+ RDI_MatchAny,
+ RDI_MatchExactly,
+ RDI_MatchNoEarlier
+} RDI_ConfigMatchType;
+
+typedef int rdi_addconfig_proc(unsigned32 nbytes);
+typedef int rdi_loadconfigdata_proc(unsigned32 nbytes, char const *data);
+typedef int rdi_selectconfig_proc(RDI_ConfigAspect aspect, char const *name,
+ RDI_ConfigMatchType matchtype, unsigned versionreq,
+ unsigned *versionp);
+
+typedef char *getbufferproc(void *getbarg, unsigned32 *sizep);
+typedef int rdi_loadagentproc(ARMword dest, unsigned32 size, getbufferproc *getb, void *getbarg);
+typedef int rdi_targetisdead(void);
+
+typedef struct {
+ int itemmax;
+ char const * const *names;
+} RDI_NameList;
+
+typedef RDI_NameList const *rdi_namelistproc(void);
+
+typedef int rdi_errmessproc(char *buf, int buflen, int errnum);
+
+struct RDIProcVec {
+ char rditypename[12];
+
+ rdi_open_proc *open;
+ rdi_close_proc *close;
+ rdi_read_proc *read;
+ rdi_write_proc *write;
+ rdi_CPUread_proc *CPUread;
+ rdi_CPUwrite_proc *CPUwrite;
+ rdi_CPread_proc *CPread;
+ rdi_CPwrite_proc *CPwrite;
+ rdi_setbreak_proc *setbreak;
+ rdi_clearbreak_proc *clearbreak;
+ rdi_setwatch_proc *setwatch;
+ rdi_clearwatch_proc *clearwatch;
+ rdi_execute_proc *execute;
+ rdi_step_proc *step;
+ rdi_info_proc *info;
+ /* V2 RDI */
+ rdi_pointinq_proc *pointinquiry;
+
+ /* These three useable only if RDIInfo_DownLoad returns no error */
+ rdi_addconfig_proc *addconfig;
+ rdi_loadconfigdata_proc *loadconfigdata;
+ rdi_selectconfig_proc *selectconfig;
+
+ rdi_namelistproc *drivernames;
+ rdi_namelistproc *cpunames;
+
+ rdi_errmessproc *errmess;
+
+ /* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */
+ rdi_loadagentproc *loadagent;
+ rdi_targetisdead *targetisdead;
+};
+
+#endif
diff --git a/gdb/rdi-share/devclnt.h b/gdb/rdi-share/devclnt.h
new file mode 100644
index 0000000..cb920f6
--- /dev/null
+++ b/gdb/rdi-share/devclnt.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Public client interface to devices
+ */
+
+#ifndef angel_devclnt_h
+#define angel_devclnt_h
+
+/*
+ * This header exports the public interface to Angel-compliant device
+ * drivers.
+ *
+ * They are intended to be used solely by Angel, not by the User
+ * Application. See devappl.h for the User Application interface to
+ * the device drivers.
+ */
+
+#include "devices.h"
+
+/* General purpose constants, macros, enums, typedefs */
+
+/*
+ * possible channels at device level
+ *
+ * XXX
+ *
+ * these are used as array indices, so be specific about their values
+ */
+typedef enum DevChanID {
+ DC_DBUG = 0, /* reliable debug packets
+ * containing SDBG, CLIB,UDBG, etc.) */
+ DC_APPL = 1, /* application packets */
+ DC_NUM_CHANNELS
+} DevChanID;
+
+/* Publically-accessible globals */
+/* none */
+
+/* Public functions */
+
+/*
+ * Function: angel_DeviceWrite
+ * Purpose: The main entry point for asynchronous writes to a device.
+ *
+ * Params:
+ * Input: devID index of the device to write to
+ * buff data to write
+ * length how much data to write
+ * callback callback here when write finished
+ * or error
+ * cb_data data to be passed to callback
+ * chanID device channel to use
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: DE_OKAY write request is underway
+ * DE_NO_DEV no such device
+ * DE_BAD_DEV device does not support angel writes
+ * DE_BAD_CHAN no such device channel
+ * DE_BUSY device busy with another write
+ * DE_INVAL silly length
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Commence asynchronous transmission of a buffer on a device. The
+ * callback will occur when the write completes or if there is an
+ * error.
+ *
+ * This must be called for each packet to be sent.
+ */
+
+DevError angel_DeviceWrite(DeviceID devID, p_Buffer buff,
+ unsigned length, DevWrite_CB_Fn callback,
+ void *cb_data, DevChanID chanID);
+
+
+/*
+ * Function: angel_DeviceRegisterRead
+ * Purpose: The main entry point for asynchronous reads from a device.
+ *
+ * Params:
+ * Input: devID index of the device to read from
+ * callback callback here when read finished
+ * or error
+ * cb_data data to be passed to callback
+ * get_buff callback to be used to acquire buffer
+ * for incoming packets
+ * getb_data data to be passed to get_buff
+ * chanID device channel to use
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: DE_OKAY read request is underway
+ * DE_NO_DEV no such device
+ * DE_BAD_DEV device does not support angel reads
+ * DE_BAD_CHAN no such device channel
+ * DE_BUSY device busy with another read
+ * DE_INVAL silly length
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Register asynchronous packet read from a device. The callback will
+ * occur when the read completes or if there is an error.
+ *
+ * This is persistent: the read remains registered for all incoming
+ * packets on the device channel.
+ */
+
+DevError angel_DeviceRegisterRead(DeviceID devID,
+ DevRead_CB_Fn callback, void *cb_data,
+ DevGetBuff_Fn get_buff, void *getb_data,
+ DevChanID chanID);
+
+
+/*
+ * Function: angel_DeviceControl
+ * Purpose: Call a control function for a device
+ *
+ * Params:
+ * Input: devID index of the device to control to
+ * op operation to perform
+ * arg parameter depending on op
+ *
+ * Returns: DE_OKAY control request is underway
+ * DE_NO_DEV no such device
+ * DE_BAD_OP device does not support operation
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * Have a device perform a control operation. Extra parameters vary
+ * according to the operation requested.
+ */
+
+DevError angel_DeviceControl(DeviceID devID, DeviceControl op, void *arg);
+
+
+/*
+ * Function: angel_ReceiveMode
+ * Purpose: enable or disable reception across all devices
+ *
+ * Params:
+ * Input: mode choose enable or disable
+ *
+ * Pass the mode parameter to the receive_mode control method of each device
+ */
+
+void angel_ReceiveMode(DevRecvMode mode);
+
+
+/*
+ * Function: angel_ResetDevices
+ * Purpose: reset all devices
+ *
+ * Params: none
+ *
+ * Call the reset control method for each device
+ */
+
+void angel_ResetDevices(void);
+
+
+/*
+ * Function: angel_InitialiseDevices
+ * Purpose: initialise the device driver layer
+ *
+ * Params: none
+ *
+ * Set up the device driver layer and call the init method for each device
+ */
+
+void angel_InitialiseDevices(void);
+
+
+/*
+ * Function: angel_IsAngelDevice
+ * Purpose: Find out if a device supports Angel packets
+ *
+ * Params:
+ * Input: devID index of the device to control to
+ *
+ * Returns: TRUE supports Angel packets
+ * FALSE raw device
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ */
+
+bool angel_IsAngelDevice(DeviceID devID);
+
+
+#if !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
+
+/*
+ * Function: angel_ApplDeviceHandler
+ * Purpose: The entry point for User Application Device Driver requests
+ * in a full functiionality version of Angel.
+ * It will never be called directly by the User Application,
+ * but gets called indirectly, via the SWI handler.
+ *
+ * Params:
+ * Input: swi_r0 Argument to SWI indicating that
+ * angel_ApplDeviceHandler was to be called. This
+ * will not be used in this function, but is needed
+ * by the SWI handler.
+ * arg_blk pointer to block of arguments
+ * arg_blk[0] is one of
+ * angel_SWIreason_ApplDevice_{Read,Write,Yield}
+ * which indicates which angel_Device* fn is to
+ * be called. arg_blk[1] - arg_blk[n] are the
+ * arguments to the corresponding
+ * angel_ApplDevice* function.
+ * Output: -
+ * In/Out: -
+ *
+ * Returns: whatever the specified angel_Device* function
+ * returns.
+ *
+ * Reads globals: -
+ * Modifies globals: -
+ *
+ * Other side effects: -
+ *
+ * This has the side effects of angel_Device{Read,Write,Yield}
+ * depending upon which is operation is specified as described above.
+ */
+
+DevError angel_ApplDeviceHandler(
+ unsigned swi_r0, unsigned *arg_blk
+);
+
+#endif /* ndef MINIMAL_ANGEL */
+
+#endif /* ndef angel_devclnt_h */
+
+/* EOF devclnt.h */
diff --git a/gdb/rdi-share/devices.h b/gdb/rdi-share/devices.h
new file mode 100644
index 0000000..eac6ee2
--- /dev/null
+++ b/gdb/rdi-share/devices.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Devices header file
+ */
+
+#ifndef angel_devices_h
+#define angel_devices_h
+
+/*
+ * Provides common types for using devices, and provides access to the
+ * device table.
+ */
+
+#include "angel.h"
+#include "buffers.h"
+
+/* General purpose constants, macros, enums, typedefs */
+
+/* a non-enum holder for device IDs */
+typedef unsigned int DeviceID;
+
+/* device error codes */
+typedef enum DevError {
+ DE_OKAY, /* no error */
+ DE_NO_DEV, /* no such device */
+ DE_BAD_DEV, /* device does not support angel */
+ DE_BAD_CHAN, /* no such device channel */
+ DE_BAD_OP, /* operation not supported by this device */
+ DE_BUSY, /* device already busy */
+ DE_INVAL, /* length invalid */
+ DE_FAILED /* something else went wrong */
+} DevError;
+
+/* return codes from asynchronous calls - primarily for channels' benefit */
+typedef enum DevStatus {
+ DS_DONE, /* operation succeeded */
+ DS_OVERFLOW, /* not enough buffer space */
+ DS_BAD_PACKET, /* packet failed */
+ DS_DEV_ERROR, /* device error */
+ DS_INT_ERROR /* internal error */
+} DevStatus;
+
+/* Callback for async. writes */
+typedef void (*DevWrite_CB_Fn)(
+ void *buff, /* pointer to data -- cast to p_Buffer */
+ void *length, /* how much done -- cast to unsigned */
+ void *status, /* success code -- cast to DevStatus */
+ void *cb_data /* as supplied */
+ );
+
+/* Callback for async. reads */
+typedef void (*DevRead_CB_Fn)(
+ void *buff, /* pointer to data -- cast to p_Buffer */
+ void *length, /* how much read -- cast to unsigned */
+ void *status, /* success code -- cast to DevStatus */
+ void *cb_data /* as supplied */
+ );
+
+/* control operations */
+typedef enum DeviceControl {
+ DC_INIT, /* initialise device */
+ DC_RESET, /* reset device */
+ DC_RECEIVE_MODE, /* control reception */
+ DC_SET_PARAMS, /* set parameters of device */
+#ifndef TARGET
+ DC_GET_USER_PARAMS, /* params set by user at open */
+ DC_GET_DEFAULT_PARAMS, /* device default parameters */
+ DC_RESYNC, /* resynchronise with new agent */
+#endif
+ DC_PRIVATE /* start of private device codes */
+} DeviceControl;
+
+typedef enum DevRecvMode {
+ DR_DISABLE,
+ DR_ENABLE
+} DevRecvMode;
+
+/*
+ * callback to allow a device driver to request a buffer, to be filled
+ * with an incoming packet
+ */
+typedef p_Buffer (*DevGetBuff_Fn)(unsigned req_size, void *cb_data);
+
+
+/* Publically-accessible globals */
+/* none */
+
+#endif /* ndef angel_devices_h */
+
+/* EOF devices.h */
diff --git a/gdb/rdi-share/devsw.c b/gdb/rdi-share/devsw.c
new file mode 100644
index 0000000..590b812
--- /dev/null
+++ b/gdb/rdi-share/devsw.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "adp.h"
+#include "hsys.h"
+#include "rxtx.h"
+#include "drivers.h"
+#include "buffers.h"
+#include "devclnt.h"
+#include "adperr.h"
+#include "devsw.h"
+#include "hostchan.h"
+#include "logging.h"
+
+/*
+ * TODO: this should be adjustable - it could be done by defining
+ * a reason code for DevSW_Ioctl. It could even be a
+ * per-devicechannel parameter.
+ */
+static const unsigned int allocsize = ADP_BUFFER_MIN_SIZE;
+
+#define illegalDevChanID(type) ((type) >= DC_NUM_CHANNELS)
+
+/**********************************************************************/
+
+/*
+ * Function: initialise_read
+ * Purpose: Set up a read request for another packet
+ *
+ * Params:
+ * In/Out: ds State structure to be initialised
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+static int initialise_read(DevSWState *ds)
+{
+ struct data_packet *dp;
+
+ /*
+ * try to claim the structure that will
+ * eventually hold the new packet.
+ */
+ if ((ds->ds_nextreadpacket = DevSW_AllocatePacket(allocsize)) == NULL)
+ return -1;
+
+ /*
+ * Calls into the device driver use the DriverCall structure: use
+ * the buffer we have just allocated, and declare its size. We
+ * are also obliged to clear the driver's context pointer.
+ */
+ dp = &ds->ds_activeread.dc_packet;
+ dp->buf_len = allocsize;
+ dp->data = ds->ds_nextreadpacket->pk_buffer;
+
+ ds->ds_activeread.dc_context = NULL;
+
+ return 0;
+}
+
+/*
+ * Function: initialise_write
+ * Purpose: Set up a write request for another packet
+ *
+ * Params:
+ * Input: packet The packet to be written
+ *
+ * type The type of the packet
+ *
+ * In/Out: dc The structure to be intialised
+ *
+ * Returns: Nothing
+ */
+static void initialise_write(DriverCall *dc, Packet *packet, DevChanID type)
+{
+ struct data_packet *dp = &dc->dc_packet;
+
+ dp->len = packet->pk_length;
+ dp->data = packet->pk_buffer;
+ dp->type = type;
+
+ /*
+ * we are required to clear the state structure for the driver
+ */
+ dc->dc_context = NULL;
+}
+
+/*
+ * Function: enqueue_packet
+ * Purpose: move a newly read packet onto the appropriate queue
+ * of read packets
+ *
+ * Params:
+ * In/Out: ds State structure with new packet
+ *
+ * Returns: Nothing
+ */
+static void enqueue_packet(DevSWState *ds)
+{
+ struct data_packet *dp = &ds->ds_activeread.dc_packet;
+ Packet *packet = ds->ds_nextreadpacket;
+
+ /*
+ * transfer the length
+ */
+ packet->pk_length = dp->len;
+
+ /*
+ * take this packet out of the incoming slot
+ */
+ ds->ds_nextreadpacket = NULL;
+
+ /*
+ * try to put it on the correct input queue
+ */
+ if (illegalDevChanID(dp->type))
+ {
+ /* this shouldn't happen */
+ WARN("Illegal type for Rx packet");
+ DevSW_FreePacket(packet);
+ }
+ else
+ Adp_addToQueue(&ds->ds_readqueue[dp->type], packet);
+}
+
+/*
+ * Function: flush_packet
+ * Purpose: Send a packet to the device driver
+ *
+ * Params:
+ * Input: device The device to be written to
+ *
+ * In/Out: dc Describes the packet to be sent
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: If the whole packet was accepted by the device
+ * driver, then dc->dc_packet.data will be
+ * set to NULL.
+ */
+static void flush_packet(const DeviceDescr *device, DriverCall *dc)
+{
+ if (device->DeviceWrite(dc) > 0)
+ /*
+ * the whole packet was swallowed
+ */
+ dc->dc_packet.data = NULL;
+}
+
+/**********************************************************************/
+
+/*
+ * These are the externally visible functions. They are documented in
+ * devsw.h
+ */
+Packet *DevSW_AllocatePacket(const unsigned int length)
+{
+ Packet *pk;
+
+ if ((pk = malloc(sizeof(*pk))) == NULL)
+ {
+ WARN("malloc failure");
+ return NULL;
+ }
+
+ if ((pk->pk_buffer = malloc(length+CHAN_HEADER_SIZE)) == NULL)
+ {
+ WARN("malloc failure");
+ free(pk);
+ return NULL;
+ }
+
+ return pk;
+}
+
+void DevSW_FreePacket(Packet *pk)
+{
+ free(pk->pk_buffer);
+ free(pk);
+}
+
+AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg,
+ const DevChanID type)
+{
+ DevSWState *ds;
+
+ /*
+ * is this the very first open call for this driver?
+ */
+ if ((ds = (DevSWState *)(device->SwitcherState)) == NULL)
+ {
+ /*
+ * yes, it is: initialise state
+ */
+ if ((ds = malloc(sizeof(*ds))) == NULL)
+ /* give up */
+ return adp_malloc_failure;
+
+ (void)memset(ds, 0, sizeof(*ds));
+ device->SwitcherState = (void *)ds;
+ }
+
+ /*
+ * check that we haven't already been opened for this type
+ */
+ if ((ds->ds_opendevchans & (1 << type)) != 0)
+ return adp_device_already_open;
+
+ /*
+ * if no opens have been done for this device, then do it now
+ */
+ if (ds->ds_opendevchans == 0)
+ if (device->DeviceOpen(name, arg) < 0)
+ return adp_device_open_failed;
+
+ /*
+ * open has finished
+ */
+ ds->ds_opendevchans |= (1 << type);
+ return adp_ok;
+}
+
+AdpErrs DevSW_Match(const DeviceDescr *device, const char *name,
+ const char *arg)
+{
+ return (device->DeviceMatch(name, arg) == -1) ? adp_failed : adp_ok;
+}
+
+AdpErrs DevSW_Close(const DeviceDescr *device, const DevChanID type)
+{
+ DevSWState *ds = (DevSWState *)(device->SwitcherState);
+ Packet *pk;
+
+ if ((ds->ds_opendevchans & (1 << type)) == 0)
+ return adp_device_not_open;
+
+ ds->ds_opendevchans &= ~(1 << type);
+
+ /*
+ * if this is the last close for this channel, then inform the driver
+ */
+ if (ds->ds_opendevchans == 0)
+ device->DeviceClose();
+
+ /*
+ * release all packets of the appropriate type
+ */
+ for (pk = Adp_removeFromQueue(&(ds->ds_readqueue[type]));
+ pk != NULL;
+ pk = Adp_removeFromQueue(&(ds->ds_readqueue[type])))
+ DevSW_FreePacket(pk);
+
+ /* that's all */
+ return adp_ok;
+}
+
+AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
+ Packet **packet, bool block)
+{
+ int read_err;
+ DevSWState *ds = device->SwitcherState;
+
+ /*
+ * To try to get information out of the device driver as
+ * quickly as possible, we try and read more packets, even
+ * if a completed packet is already available.
+ */
+
+ /*
+ * have we got a packet currently pending?
+ */
+ if (ds->ds_nextreadpacket == NULL)
+ /*
+ * no - set things up
+ */
+ if (initialise_read(ds) < 0) {
+ /*
+ * we failed to initialise the next packet, but can
+ * still return a packet that has already arrived.
+ */
+ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
+ return adp_ok;
+ }
+ read_err = device->DeviceRead(&ds->ds_activeread, block);
+ switch (read_err) {
+ case 1:
+ /*
+ * driver has pulled in a complete packet, queue it up
+ */
+#ifdef RET_DEBUG
+ printf("got a complete packet\n");
+#endif
+ enqueue_packet(ds);
+ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
+ return adp_ok;
+ case 0:
+ /*
+ * OK, return the head of the read queue for the given type
+ */
+ /* enqueue_packet(ds); */
+ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
+ return adp_ok;
+ case -1:
+#ifdef RET_DEBUG
+ printf("got a bad packet\n");
+#endif
+ /* bad packet */
+ *packet = NULL;
+ return adp_bad_packet;
+ default:
+ panic("DevSW_Read: bad read status %d", read_err);
+ }
+ return 0; /* get rid of a potential compiler warning */
+}
+
+
+AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device)
+{
+ struct DriverCall *dc;
+ struct data_packet *dp;
+
+ dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
+ dp = &dc->dc_packet;
+
+ /*
+ * try to flush any packet that is still being written
+ */
+ if (dp->data != NULL)
+ {
+ flush_packet(device, dc);
+
+ /* see if it has gone */
+ if (dp->data != NULL)
+ return adp_write_busy;
+ else
+ return adp_ok;
+ }
+ else
+ return adp_ok;
+}
+
+
+AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type)
+{
+ struct DriverCall *dc;
+ struct data_packet *dp;
+
+ dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
+ dp = &dc->dc_packet;
+
+ if (illegalDevChanID(type))
+ return adp_illegal_args;
+
+ /*
+ * try to flush any packet that is still being written
+ */
+ if (DevSW_FlushPendingWrite(device) != adp_ok)
+ return adp_write_busy;
+
+ /*
+ * we can take this packet - set things up, then try to get rid of it
+ */
+ initialise_write(dc, packet, type);
+ flush_packet(device, dc);
+
+ return adp_ok;
+}
+
+AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args)
+{
+ return (device->DeviceIoctl(opcode, args) < 0) ? adp_failed : adp_ok;
+}
+
+bool DevSW_WriteFinished(const DeviceDescr *device)
+{
+ struct DriverCall *dc;
+ struct data_packet *dp;
+
+ dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
+ dp = &dc->dc_packet;
+
+ return (dp == NULL || dp->data == NULL);
+}
+
+/* EOF devsw.c */
diff --git a/gdb/rdi-share/devsw.h b/gdb/rdi-share/devsw.h
new file mode 100644
index 0000000..f561768
--- /dev/null
+++ b/gdb/rdi-share/devsw.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#ifndef angsd_devsw_h
+#define angsd_devsw_h
+
+#include "devclnt.h"
+#include "adperr.h"
+#include "drivers.h"
+
+#ifndef __cplusplus
+typedef struct Packet Packet;
+typedef struct DevSWState DevSWState;
+#endif
+
+/*
+ * the basic structure used for passing packets around
+ */
+struct Packet
+{
+ struct Packet *pk_next; /* XXX first field in struct */
+ unsigned int pk_length;
+ unsigned char *pk_buffer;
+};
+
+/*
+ * control structure, used for maintaining device switcher state
+ */
+struct DevSWState
+{
+ unsigned int ds_opendevchans; /* bitmap of open device channels */
+
+ /*
+ * queue of packets read for the various device channels
+ */
+ Packet *ds_readqueue[DC_NUM_CHANNELS];
+
+ /*
+ * structures for managing active read and write operations
+ */
+ Packet *ds_nextreadpacket;
+ DriverCall ds_activeread;
+ DriverCall ds_activewrite;
+};
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ * Function: DevSW_AllocatePacket
+ * Purpose: Claim some memory to hold a struct Packet, and the buffer for
+ * that packet.
+ *
+ * Params:
+ * Input: length Size of the buffer in struct Packet.
+ *
+ * Returns:
+ * OK: Pointer to the newly malloc()ed Packet.
+ * Error: NULL
+ */
+Packet *DevSW_AllocatePacket(const unsigned int length);
+
+/*
+ * Function: DevSW_FreePacket
+ * Purpose: Free the memory associated with a struct Packet.
+ *
+ * Pre-conditions The structure must have been originally claimed
+ * via DevSW_AllocatePacket.
+ *
+ * Params:
+ * Input: pk The packet to be freed.
+ *
+ * Returns: Nothing
+ */
+void DevSW_FreePacket(Packet *pk);
+
+/*
+ * Function: DevSW_Open
+ * Purpose: Open the specified device driver
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * type The type of packet the caller is interested in. Only
+ * one open is allowed for each type of packet.
+ *
+ * In/Out: device The device driver to open
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_open_failed
+ * adp_device_already_open
+ * adp_malloc_failure
+ */
+AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg,
+ const DevChanID type);
+
+/*
+ * Function: DevSW_Match
+ * Purpose: Minimal veneer for DeviceMatch
+ *
+ * Params:
+ * Input: device The device driver to match.
+ *
+ * name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_failed
+ */
+AdpErrs DevSW_Match(const DeviceDescr *device, const char *name,
+ const char *arg);
+
+/*
+ * Function: DevSW_Close
+ * Purpose: Close the specified device driver. All packets of the type
+ * used by the caller held within the switching layer will
+ * be discarded.
+ *
+ * Pre-conditions: Device must have been previously opened.
+ *
+ * Params:
+ * Input: device The device driver to close
+ *
+ * type The type of packet the caller was interested in.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ */
+AdpErrs DevSW_Close(const DeviceDescr *device, const DevChanID type);
+
+/*
+ * Function: DevSW_Read
+ * Purpose: Read a packet of appropriate type from the device driver
+ *
+ * Params:
+ * Input: device The device driver to read packet from.
+ *
+ * type The type of packet the caller is interested in.
+ *
+ * Output: packet Pointer to new packet (if one is available)
+ * NULL (if no complete packet is available)
+ *
+ * Input: block If TRUE, read may safely block for a short period
+ * of time (say up to 20ms), to avoid high CPU load
+ * whilst waiting for a reply.
+ * If FALSE, read MUST NOT block.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_bad_packet
+ *
+ * Post-conditions: The calling function is responsible for freeing the
+ * resources used by the packet when it is no longer
+ * needed.
+ */
+AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
+ Packet **packet, bool block);
+
+/*
+ * Function: DevSW_Write
+ * Purpose: Try to write a packet to the device driver. The write will
+ * be bounced if another write is still in progress.
+ *
+ * Params:
+ * Input: device The device driver to write a packet to.
+ *
+ * packet The packet to be written.
+ *
+ * type The type to be assigned to the packet.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_illegal_args
+ * adp_write_busy
+ *
+ * Post-conditions: The calling function retains "ownership" of the packet,
+ * i.e. it is responsible for freeing the resources used
+ * by the packet when it is no longer needed.
+ */
+AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type);
+
+/*
+ * Function: DevSW_FlushPendingWrite
+ * Purpose: If a write is in progress, give it a chance to finish.
+ *
+ * Params:
+ * Input: device The device driver to flush.
+ *
+ * Returns:
+ * adp_ok no pending write, or write flushed completely
+ * adp_write_busy pending write not flushed completely
+ */
+AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device);
+
+/*
+ * Function: DevSW_Ioctl
+ * Purpose: Perform miscellaneous control operations. This is a minimal
+ * veneer to DeviceIoctl.
+ *
+ * Params:
+ * Input: device The device driver to control.
+ *
+ * opcode Reason code indicating the operation to perform.
+ *
+ * In/Out: args Pointer to opcode-sensitive arguments/result space.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_failed
+ */
+AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args);
+
+/*
+ * Function: DevSW_WriteFinished
+ * Purpose: Return TRUE if the active device has finished writing
+ * the last packet to be sent, or FALSE if a packet is still
+ * being transmitted.
+ *
+ * Params:
+ * Input: device The device driver to check.
+ *
+ * Returns:
+ * TRUE: write finished or inactive
+ * FALSE: write in progress
+ */
+bool DevSW_WriteFinished(const DeviceDescr *device);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* ndef angsd_devsw_h */
+
+/* EOF devsw.h */
diff --git a/gdb/rdi-share/drivers.c b/gdb/rdi-share/drivers.c
new file mode 100644
index 0000000..ba0eee5
--- /dev/null
+++ b/gdb/rdi-share/drivers.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * drivers.c - declares a NULL terminated list of device driver
+ * descriptors supported by the host.
+ */
+#include <stdio.h>
+
+#include "drivers.h"
+
+extern DeviceDescr angel_SerialDevice;
+extern DeviceDescr angel_SerparDevice;
+extern DeviceDescr angel_EthernetDevice;
+
+DeviceDescr *devices[] =
+{
+ &angel_SerialDevice,
+ &angel_SerparDevice,
+ &angel_EthernetDevice,
+ NULL
+};
+
+/* EOF drivers.c */
diff --git a/gdb/rdi-share/drivers.h b/gdb/rdi-share/drivers.h
new file mode 100644
index 0000000..3655c18
--- /dev/null
+++ b/gdb/rdi-share/drivers.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Definitions for device driver interface.
+ */
+#ifndef angsd_drivers_h
+#define angsd_drivers_h
+
+#include "rxtx.h"
+
+#ifndef __cplusplus
+typedef struct DeviceDescr DeviceDescr;
+typedef struct DriverCall DriverCall;
+#endif
+
+/*
+ * used to pass packets across the driver interface
+ */
+struct DriverCall
+{
+ struct data_packet dc_packet;
+ void *dc_context;
+};
+
+/*
+ * used to describe a device driver
+ */
+struct DeviceDescr
+{
+ char *DeviceName;
+ int (*DeviceOpen)(const char *name, const char *arg);
+ int (*DeviceMatch)(const char *name, const char *arg);
+ void (*DeviceClose)(void);
+ int (*DeviceRead)(DriverCall *dc, bool block);
+ int (*DeviceWrite)(DriverCall *dc);
+ int (*DeviceIoctl)(const int opcode, void *args);
+ void *SwitcherState; /* used by switcher interface */
+};
+
+/*
+ * Function: DeviceOpen
+ *
+ * Purpose: Open a communications device
+ *
+ * Pre-conditions: No previous open is still active
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+extern int DeviceOpen(const char *name, const char *arg);
+
+/*
+ * Function: DeviceMatch
+ *
+ * Purpose: Check whether parameters are OK to be passed to DeviceOpen
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+extern int DeviceMatch(const char *name, const char *arg);
+
+/*
+ * Function: DeviceClose
+ *
+ * Purpose: Close a communications device
+ *
+ * Pre-conditions: Device must have been previously opened
+ *
+ * Params: None
+ *
+ * Returns: Nothing
+ */
+extern void DeviceClose(void);
+
+/*
+ * Function: DeviceRead
+ *
+ * Purpose: Try to read a complete packet from a communications device.
+ * This read must usually be non-blocking, i.e. it should read as
+ * many data from the device as needed to complete the packet,
+ * but it should not wait if the packet is not complete, and no
+ * more data are currently available from the device.
+ * As an optimisation the read can optionally block when 'block'
+ * is TRUE, but only for a short time. It is acceptable for the
+ * 'block' parameter to be ignored in which case all reads
+ * should be non-blocking.
+ *
+ * Pre-conditions: Device has been opened via DeviceOpen()
+ *
+ * Params:
+ * In/Out: dc Describes the packet being read (dc->dc_packet);
+ * dc->dc_context is for the driver to store private
+ * context, and is guaranteed to be NULL the first
+ * time DeviceRead is called for a given packet.
+ *
+ * In: block If TRUE, read may safely block for a short period
+ * of time (say up to 20ms), to avoid high CPU load
+ * whilst waiting for a reply.
+ * If FALSE, read MUST NOT block.
+ *
+ * Returns:
+ * OK: 1 (packet is complete)
+ * 0 (packet is not yet complete)
+ * Error: -1 bad packet
+ *
+ * Post-conditions: should a calamatous error occur panic() will be called
+ */
+extern int DeviceRead(DriverCall *dc, bool block);
+
+/*
+ * Function: DeviceWrite
+ *
+ * Purpose: Try to write a packet to a communications device. This write
+ * must be non-blocking, i.e. it should write as many data to
+ * the device as is immediately possible, but should not wait
+ * for space to send any more after that.
+ *
+ * Pre-conditions: Device has been opened via DeviceOpen()
+ *
+ * Params:
+ * In/Out: dc Describes the packet being written (dc->dc_packet);
+ * dc->dc_context is for the driver to store private
+ * context, and is guaranteed to be NULL the first
+ * time DeviceWrite is called for a given packet.
+ *
+ * Returns:
+ * OK: 1 (all of the packet has been written)
+ * 0 (some of the packet remains to be written)
+ * Error: -1
+ */
+extern int DeviceWrite(DriverCall *dc);
+
+/*
+ * Function: DeviceIoctl
+ *
+ * Purpose: Perform miscellaneous driver operations
+ *
+ * Pre-conditions: Device has been open via DeviceOpen()
+ *
+ * Params:
+ * Input: opcode Reason code indicating the operation to perform
+ * In/Out: args Pointer to opcode-sensitive arguments/result space
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+extern int DeviceIoctl(const int opcode, void *args);
+
+#endif /* !defined(angsd_drivers_h) */
+
+/* EOF drivers.h */
diff --git a/gdb/rdi-share/endian.h b/gdb/rdi-share/endian.h
new file mode 100644
index 0000000..3d32d9a
--- /dev/null
+++ b/gdb/rdi-share/endian.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * endian.h - target endianness independent read/write primitives.
+ */
+
+#ifndef angel_endian_h
+#define angel_endian_h
+
+/*
+ * The endianness of the data being processed needs to be known, but
+ * the host endianness is not required (since the data is constructed
+ * using bytes). At the moment these are provided as macros. This
+ * gives the compiler freedom in optimising individual calls. However,
+ * if space is at a premium then functions should be provided.
+ *
+ * NOTE: These macros assume that the data has been packed in the same format
+ * as the packing on the build host. If this is not the case then
+ * the wrong addresses could be used when dealing with structures.
+ *
+ */
+
+/*
+ * For all the following routines the target endianness is defined by the
+ * following boolean definitions.
+ */
+#define BE (1 == 1) /* TRUE : big-endian */
+#define LE (1 == 0) /* FALSE : little-endian */
+
+/*
+ * The following type definitions are used by the endianness converting
+ * macros.
+ */
+typedef unsigned char U8;
+typedef U8 *P_U8;
+typedef const U8 *CP_U8;
+
+typedef unsigned short U16;
+typedef U16 *P_U16;
+
+typedef unsigned int U32;
+typedef U32 *P_U32;
+
+/*
+ * If the endianness of the host and target are known (fixed) and the same
+ * then the following macro definitions can be used. These just directly copy
+ * the data.
+ *
+ * #define READ(e,a) (a)
+ * #define WRITE(e,a,v) ((a) = (v))
+ * #define PREAD(e,a) (a)
+ * #define PWRITE(e,a,v) (*(a) = (v))
+ */
+
+/*
+ * These macros assume that a byte (char) is 8bits in size, and that the
+ * endianness is not important when reading or writing bytes.
+ */
+#define PUT8(a,v) (*((P_U8)(a)) = (U8)(v))
+#define PUT16LE(a,v) (PUT8(a,((v) & 0xFF)), \
+ PUT8((((P_U8)(a)) + sizeof(char)),((v) >> 8)))
+#define PUT16BE(a,v) (PUT8(a,((v) >> 8)), \
+ PUT8((((P_U8)(a)) + sizeof(char)),((v) & 0xFF)))
+#define PUT32LE(a,v) (PUT16LE(a,v), \
+ PUT16LE((((P_U8)(a)) + sizeof(short)),((v) >> 16)))
+#define PUT32BE(a,v) (PUT16BE(a,((v) >> 16)), \
+ PUT16BE((((P_U8)(a)) + sizeof(short)),v))
+
+#define GET8(a) (*((CP_U8)(a)))
+#define GET16LE(a) (GET8(a) | (((U16)GET8(((CP_U8)(a)) + sizeof(char))) << 8))
+#define GET16BE(a) ((((U16)GET8(a)) << 8) | GET8(((CP_U8)(a)) + sizeof(char)))
+#define GET32LE(a) (GET16LE(a) | \
+ (((U32)GET16LE(((CP_U8)(a)) + sizeof(short))) << 16))
+#define GET32BE(a) ((((U32)GET16BE(a)) << 16) | \
+ GET16BE(((CP_U8)(a)) + sizeof(short)))
+
+/*
+ * These macros simplify the code in respect to reading and writing the
+ * correct size data when dealing with endianness. "e" is TRUE if we are
+ * dealing with big-endian data, FALSE if we are dealing with little-endian.
+ */
+
+/* void WRITE(int endianness, void *address, unsigned value); */
+
+#define WRITE16(e,a,v) ((e) ? PUT16BE(&(a),v) : PUT16LE(&(a),v))
+#define WRITE32(e,a,v) ((e) ? PUT32BE(&(a),v) : PUT32LE(&(a),v))
+#define WRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \
+ PUT8(&(a),v) : ((sizeof(v) == sizeof(short)) ? \
+ WRITE16(e,a,v) : WRITE32(e,a,v)))
+
+/* unsigned READ(int endianness, void *address) */
+#define READ16(e,a) ((e) ? GET16BE(&(a)) : GET16LE(&(a)))
+#define READ32(e,a) ((e) ? GET32BE(&(a)) : GET32LE(&(a)))
+#define READ(e,a) ((sizeof(a) == sizeof(char)) ? \
+ GET8((CP_U8)&(a)) : ((sizeof(a) == sizeof(short)) ? \
+ READ16(e,a) : READ32(e,a)))
+
+/* void PWRITE(int endianness, void *address, unsigned value); */
+#define PWRITE16(e,a,v) ((e) ? PUT16BE(a,v) : PUT16LE(a,v))
+#define PWRITE32(e,a,v) ((e) ? PUT32BE(a,v) : PUT32LE(a,v))
+#define PWRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \
+ PUT8(a,v) : ((sizeof(v) == sizeof(short)) ? \
+ PWRITE16(e,a,v) : PWRITE32(e,a,v)))
+
+/* unsigned PREAD(int endianness, void *address) */
+#define PREAD16(e,a) ((e) ? GET16BE(a) : GET16LE(a))
+#define PREAD32(e,a) ((e) ? GET32BE(a) : GET32LE(a))
+#define PREAD(e,a) ((sizeof(*(a)) == sizeof(char)) ? \
+ GET8((CP_U8)a) : ((sizeof(*(a)) == sizeof(short)) ? \
+ PREAD16(e,a) : PREAD32(e,a)))
+
+#endif /* !defined(angel_endian_h) */
+
+/* EOF endian.h */
diff --git a/gdb/rdi-share/etherdrv.c b/gdb/rdi-share/etherdrv.c
new file mode 100644
index 0000000..976b2f5
--- /dev/null
+++ b/gdb/rdi-share/etherdrv.c
@@ -0,0 +1,725 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * etherdrv.c - Ethernet Driver for Angel.
+ */
+
+#ifdef __hpux
+# define _POSIX_SOURCE 1
+# define _HPUX_SOURCE 1
+# define _XOPEN_SOURCE 1
+#endif
+
+#include <stdio.h>
+#ifdef __hpux
+# define uint hide_HPs_uint
+#endif
+#ifdef __unix
+# include <unistd.h>
+# ifdef __hpux
+# undef uint
+# endif
+#endif
+#include <stdlib.h>
+#include <string.h>
+#ifdef __hpux
+# define uint hide_HPs_uint
+#endif
+#include <fcntl.h>
+#ifdef __hpux
+# undef uint
+#endif
+#include <errno.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "host.h"
+
+#ifdef COMPILING_ON_WINDOWS
+ typedef char * caddr_t;
+# undef IGNORE
+# include <winsock.h>
+# include "angeldll.h"
+#else
+# ifdef __hpux
+# define uint hide_HPs_uint
+# endif
+# include <sys/types.h>
+# include <sys/socket.h>
+# ifdef __hpux
+# undef uint
+# endif
+# include <netdb.h>
+# include <sys/time.h>
+# include <sys/ioctl.h>
+# if !defined(__hpux) && !defined(__linux__) && !defined(_WIN32)
+# include <sys/filio.h>
+# endif
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
+
+#include "hsys.h"
+#include "devices.h"
+#include "endian.h"
+#include "buffers.h"
+#include "hostchan.h"
+#include "params.h"
+#include "logging.h"
+#include "ethernet.h"
+
+
+#ifndef COMPILING_ON_WINDOWS
+/* these two might not work for windows */
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+#endif
+
+#ifndef UNUSED
+# define UNUSED(x) (x = x) /* Silence compiler warnings */
+#endif
+
+/*
+ * forward declarations of static functions
+ */
+static int EthernetOpen(const char *name, const char *arg);
+static int EthernetMatch(const char *name, const char *arg);
+static void EthernetClose(void);
+static int EthernetRead(DriverCall *dc, bool block);
+static int EthernetWrite(DriverCall *dc);
+static int EthernetIoctl(const int opcode, void *args);
+
+/*
+ * the device descriptor for Ethernet
+ */
+DeviceDescr angel_EthernetDevice =
+{
+ "Ethernet",
+ EthernetOpen,
+ EthernetMatch,
+ EthernetClose,
+ EthernetRead,
+ EthernetWrite,
+ EthernetIoctl
+};
+
+/*
+ * descriptor for the socket that we talk down
+ */
+static int sock = -1;
+
+/*
+ * address of the remote target
+ */
+static struct sockaddr_in remote, *ia = &remote;
+
+/*
+ * array of dynamic port numbers on target
+ */
+static unsigned short int ports[2];
+
+/*
+ * Function: set_address
+ * Purpose: Try to get an address into an understandable form
+ *
+ * Params:
+ * Input: addr The address to parse
+ *
+ * Output: ia Structure to hold the parsed address
+ *
+ * Returns:
+ * OK: 0
+ * Error: -1
+ */
+static int set_address(const char *const addr, struct sockaddr_in *const ia)
+{
+ ia->sin_family = AF_INET;
+
+ /*
+ * Try address as a dotted decimal
+ */
+ ia->sin_addr.s_addr = inet_addr(addr);
+
+ /*
+ * If that failed, try it as a hostname
+ */
+ if (ia->sin_addr.s_addr == (u_int)-1)
+ {
+ struct hostent *hp = gethostbyname(addr);
+
+ if (hp == NULL)
+ return -1;
+
+ (void)memcpy((caddr_t)&ia->sin_addr, hp->h_addr, hp->h_length);
+ }
+
+ return 0;
+}
+
+/*
+ * Function: open_socket
+ * Purpose: Open a non-blocking UDP socket, and bind it to a port
+ * assigned by the system.
+ *
+ * Params: None
+ *
+ * Returns:
+ * OK: socket descriptor
+ * Error: -1
+ */
+static int open_socket(void)
+{
+ int sfd;
+#if 0 /* see #if 0 just below -VVV- */
+ int yesplease = 1;
+#endif
+ struct sockaddr_in local;
+
+ /*
+ * open the socket
+ */
+#ifdef COMPILING_ON_WINDOWS
+ if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ return -1;
+#else
+ if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+# ifdef DEBUG
+ perror("socket");
+# endif
+ return -1;
+ }
+#endif
+
+ /*
+ * 960731 KWelton
+ *
+ * I don't believe that this should be necessary - if we
+ * use select(), then non-blocking I/O is redundant.
+ * Unfortunately, select() appears to be broken (under
+ * Solaris, with a limited amount of time available for
+ * debug), so this code stays in for the time being
+ */
+#if 0
+ /*
+ * enable non-blocking I/O
+ */
+ if (ioctlsocket(sfd, FIONBIO, &yesplease) < 0)
+ {
+# ifdef DEBUG
+ perror("ioctl(FIONBIO)");
+# endif
+ closesocket(sfd);
+
+ return -1;
+ }
+#endif /* 0/1 */
+
+ /*
+ * bind local address to a system-assigned port
+ */
+ memset((char *)&local, 0, sizeof(local));
+ local.sin_family = AF_INET;
+ local.sin_port = htons(0);
+ local.sin_addr.s_addr = INADDR_ANY;
+ if (bind(sfd, (struct sockaddr *)&local, sizeof(local)) < 0)
+ {
+#ifdef DEBUG
+ perror("bind");
+#endif
+ closesocket(sfd);
+
+ return -1;
+ }
+
+ /*
+ * all done
+ */
+ return sfd;
+}
+
+/*
+ * Function: fetch_ports
+ * Purpose: Request assigned port numbers from remote target
+ *
+ * Params: None
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: This routine will *always* return something for the
+ * port numbers. If the remote target does not
+ * respond, then it makes something up - this allows
+ * the standard error message (from ardi.c) to be
+ * generated when the target is dead for whatever
+ * reason.
+ */
+static void fetch_ports(void)
+{
+ int i;
+ const char ctrlpacket[] = CTRL_MAGIC;
+ CtrlResponse response;
+
+ /*
+ * we will try 3 times to elicit a response from the target
+ */
+ for (i = 0; i < 3; ++i)
+ {
+ struct timeval tv;
+ fd_set fdset;
+
+ /*
+ * send the magic string to the control
+ * port on the remote target
+ */
+ ia->sin_port = htons(CTRL_PORT);
+ if (sendto(sock, ctrlpacket, sizeof(ctrlpacket), 0,
+ (struct sockaddr *)ia, sizeof(*ia)) < 0)
+ {
+#ifdef DEBUG
+ perror("fetch_ports: sendto");
+#endif
+ return;
+ }
+
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_sec = 0;
+ tv.tv_usec = 250000;
+
+ if (select(sock + 1, &fdset, NULL, NULL, &tv) < 0)
+ {
+#ifdef DEBUG
+ perror("fetch_ports: select");
+#endif
+ return;
+ }
+
+ if (FD_ISSET(sock, &fdset))
+ {
+ /*
+ * there is something there - read it
+ */
+ if (recv(sock, (char *)&response, sizeof(response), 0) < 0)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ unsigned int werrno = WSAGetLastError();
+
+ if (werrno == WSAEWOULDBLOCK || werrno == 0)
+#else
+ if (errno == EWOULDBLOCK)
+#endif
+ {
+ --i;
+ continue;
+ }
+ else
+ {
+#ifdef DEBUG
+ perror("fetch_ports: recv");
+#endif
+ return;
+ }
+ }
+ {
+ /*
+ * XXX
+ *
+ * this is *very* unpleasant - try to match the structure
+ * layout
+ */
+ unsigned short *sptr = (unsigned short *)(response + RESP_DBUG);
+
+ if (strcmp(response, ctrlpacket) == 0)
+ {
+ ports[DBUG_INDEX] = htons(*sptr);
+ sptr++;
+ ports[APPL_INDEX] = htons(*sptr);
+ }
+
+#ifdef DEBUG
+ printf("fetch_ports: got response, DBUG=%d, APPL=%d\n",
+ ports[DBUG_INDEX], ports[APPL_INDEX]);
+#endif
+ return;
+ }
+ }
+ }
+
+ /*
+ * we failed to get a response
+ */
+#ifdef DEBUG
+ printf("fetch_ports: failed to get a real answer\n");
+#endif
+}
+
+/*
+ * Function: read_packet
+ * Purpose: read a packet, and pass it back to higher levels
+ *
+ * Params:
+ * In/Out: packet Holder for the read packet
+ *
+ * Returns: 1 - Packet is complete
+ * 0 - No complete packet read
+ *
+ * Post-conditions: Will call panic() if something goes wrong with the OS
+ */
+static int read_packet(struct data_packet *const packet)
+{
+ struct sockaddr_in from;
+ int nbytes, fromlen = sizeof(from);
+ DevChanID devchan;
+
+ /*
+ * try to get the packet
+ */
+ if ((nbytes = recvfrom(sock, (char *)(packet->data), packet->buf_len, 0,
+ (struct sockaddr *)&from, &fromlen)) < 0)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
+ MessageBox(GetFocus(), "Error receiving packet\n", "Angel", MB_OK | MB_ICONSTOP);
+#else
+ if (errno != EWOULDBLOCK)
+ {
+# ifdef DEBUG
+ perror("recv");
+# endif
+ panic("ethernet recv failure");
+ }
+#endif
+ return 0;
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
+ {
+ progressInfo.nRead += nbytes;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+#endif
+
+ /*
+ * work out where the packet was from
+ */
+ if (from.sin_addr.s_addr != remote.sin_addr.s_addr)
+ {
+ /*
+ * not from our target - ignore it
+ */
+#ifdef DEBUG
+ printf("read_packet: ignoring packet from %s\n",
+ inet_ntoa(from.sin_addr));
+#endif
+
+ return 0;
+ }
+ else if (ntohs(from.sin_port) == ports[DBUG_INDEX])
+ devchan = DC_DBUG;
+ else if (ntohs(from.sin_port) == ports[APPL_INDEX])
+ devchan = DC_APPL;
+ else
+ {
+ /*
+ * unknown port number - ignore it
+ */
+#ifdef DEBUG
+ printf("read_packet: ignore packet from port %hd\n",
+ htons(from.sin_port));
+#endif
+
+ return 0;
+ }
+
+#if defined(DEBUG) && !defined(DO_TRACE)
+ printf("EthernetRead: %d bytes from %s channel\n",
+ nbytes, (devchan == DC_DBUG) ? "DBUG" : "APPL");
+#endif
+
+#ifdef DO_TRACE
+ printf("[%d on %d]\n", nbytes, devchan);
+ {
+ int i = 0;
+ unsigned char *cptr = packet->data;
+
+ while (i < nbytes)
+ {
+ printf("<%02X ", *(cptr++));
+
+ if (!(++i % 16))
+ printf("\n");
+ }
+
+ if (i % 16)
+ printf("\n");
+ }
+#endif
+
+ /*
+ * OK - fill in the details
+ */
+ packet->type = devchan;
+ packet->len = nbytes;
+ return 1;
+}
+
+/**********************************************************************/
+
+/*
+ * Function: Ethernet_Open
+ * Purpose: Open the Ethernet device. See the documentation for
+ * DeviceOpen in drivers.h
+ *
+ * Post-conditions: Will have updated struct sockaddr_in remote (*ia)
+ * with the address of the remote target.
+ */
+static int EthernetOpen(const char *name, const char *arg)
+{
+#ifdef COMPILING_ON_WINDOWS
+ WORD wVersionRequested;
+ WSADATA wsaData;
+#endif
+ /*
+ * name is passed as e=<blah>, so skip 1st two characters
+ */
+ const char *etheraddr = name + 2;
+
+#ifdef DEBUG
+ printf("EthernetOpen: name `%s'\n", name);
+#endif
+
+ /* Check that the name is a valid one */
+ if (EthernetMatch(name, arg) != 0)
+ return -1;
+
+#ifdef COMPILING_ON_WINDOWS
+ wVersionRequested = MAKEWORD(1, 1);
+ if (WSAStartup(wVersionRequested, &wsaData) != 0)
+ /*
+ * Couldn't find a useable winsock.dll.
+ */
+ return -1;
+
+ if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
+ {
+ WSACleanup();
+
+ /*
+ * Couldn't find a winsock.dll with supported version.
+ */
+ return -1;
+ }
+#endif
+
+ memset((char *)ia, 0, sizeof(*ia));
+ if (set_address(etheraddr, ia) < 0)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ /*
+ * SJ - I'm not sure that this is the correct way to handle this
+ * as Fail calls remote_disable and exits, while panic just exits.
+ * However at the time of writing remote_disable does nothing!
+ */
+ /* Panic("EthernetOpen: bad name `%s'\n", etheraddr); */
+#else
+ Fail("EthernetOpen: bad name `%s'\n", etheraddr);
+#endif
+ return -1;
+ }
+
+ if ((sock = open_socket()) < 0)
+ return -1;
+
+ /*
+ * fetch the port numbers assigned by the remote target
+ * to its Debug and Application sockets
+ */
+ fetch_ports();
+
+ return 0;
+}
+
+static int EthernetMatch(const char *name, const char *arg)
+{
+ /* IGNORE arg */
+ if (0)
+ arg = arg;
+
+ if (name == NULL)
+ return -1;
+
+ if (tolower(name[0]) != 'e' || name[1] != '=')
+ return -1;
+
+ return 0;
+}
+
+static void EthernetClose(void)
+{
+ if (sock >= 0)
+ {
+ closesocket(sock);
+ sock = -1;
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ WSACleanup();
+#endif
+}
+
+static int EthernetRead(DriverCall *dc, bool block)
+{
+ fd_set fdset;
+ struct timeval tv;
+ int err;
+
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+
+#ifdef COMPILING_ON_WINDOWS
+ UNUSED(block);
+ tv.tv_sec = tv.tv_usec = 0;
+#else
+ tv.tv_sec = 0;
+ tv.tv_usec = (block ? 10000 : 0);
+#endif
+
+ err = select(sock + 1, &fdset, NULL, NULL, &tv);
+
+ if (err < 0) {
+ if (errno == EINTR) {
+ return 0;
+ }
+ panic("ethernet select failure (errno=%i)",errno);
+ return 0;
+ }
+
+ if (FD_ISSET(sock, &fdset))
+ return read_packet(&dc->dc_packet);
+ else
+ return 0;
+}
+
+static int EthernetWrite(DriverCall *dc)
+{
+ int nbytes;
+ struct data_packet *packet = &dc->dc_packet;
+
+ if (packet->type == DC_DBUG)
+ ia->sin_port = htons(ports[DBUG_INDEX]);
+ else if (packet->type == DC_APPL)
+ ia->sin_port = htons(ports[APPL_INDEX]);
+ else
+ {
+ panic("EthernetWrite: unknown devchan");
+ return 0;
+ }
+
+#if defined(DEBUG) && !defined(DO_TRACE)
+ printf("EthernetWrite: %d bytes to %s channel\n",
+ packet->len, (packet->type == DC_DBUG) ? "DBUG" : "APPL");
+#endif
+
+#ifdef DO_TRACE
+ printf("[%d on %d]\n", packet->len, packet->type);
+ {
+ int i = 0;
+ unsigned char *cptr = packet->data;
+
+ while (i < packet->len)
+ {
+ printf(">%02X ", *(cptr++));
+
+ if (!(++i % 16))
+ printf("\n");
+ }
+
+ if (i % 16)
+ printf("\n");
+ }
+#endif
+
+ if ((nbytes = sendto(sock, (char *)(packet->data), packet->len, 0,
+ (struct sockaddr *)ia, sizeof(*ia))) != packet->len)
+ {
+#ifdef COMPILING_ON_WINDOWS
+ if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
+#else
+ if (nbytes < 0 && errno != EWOULDBLOCK)
+#endif
+ {
+#ifdef DEBUG
+ perror("sendto");
+#endif
+#ifdef COMPILING_ON_WINDOWS
+ panic("ethernet send failure\n");
+#else
+ /* might not work for Windows */
+ panic("ethernet send failure [%s]\n",
+ errno < sys_nerr ? sys_errlist[errno] : "unknown errno");
+#endif
+ }
+#ifdef DEBUG
+ else if (nbytes >= 0)
+ fprintf(stderr, "ethernet send: asked for %d, sent %d\n", packet->len, nbytes);
+#endif
+ return 0;
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
+ {
+ progressInfo.nWritten += nbytes;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+#endif
+
+ return 1;
+}
+
+static int EthernetIoctl(const int opcode, void *args)
+{
+#ifdef DEBUG
+ printf( "EthernetIoctl: op %d arg %x\n", opcode, args );
+#endif
+
+ /*
+ * IGNORE(opcode)
+ */
+ if (0)
+ {
+ int dummy = opcode;
+ UNUSED(dummy);
+ }
+ UNUSED(args);
+
+ switch ( opcode )
+ {
+ case DC_RESYNC:
+ {
+#ifdef DEBUG
+ printf( "EthernetIoctl: resync\n" );
+#endif
+ fetch_ports();
+ return 0;
+ }
+
+ default:
+ {
+ return -1;
+ }
+ }
+}
+
+/* EOF etherdrv.c */
diff --git a/gdb/rdi-share/ethernet.h b/gdb/rdi-share/ethernet.h
new file mode 100644
index 0000000..930aced
--- /dev/null
+++ b/gdb/rdi-share/ethernet.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * ethernet.h: Angel drivers for Ethernet using Fusion UDP/IP stack
+ */
+#ifndef angel_ethernet_h
+#define angel_ethernet_h
+
+/*
+ * the UDP ports that Angel Ethernet uses
+ */
+#define CTRL_PORT 1913
+
+/*
+ * the size of the largest packet accepted on the control socket
+ */
+#define CTRL_MAXPACKET 6
+
+/*
+ * This is the "magic number" sent to the control port to
+ * request that the channel port numbers are returned
+ */
+#define CTRL_MAGIC "Angel"
+
+/*
+ * Array used for responding to a request on the control port
+ */
+typedef unsigned char CtrlResponse[10];
+#define RESP_MAGIC 0
+#define RESP_DBUG 6
+#define RESP_APPL 8
+
+/*
+ * indices for accessing the array of port numbers sent
+ * over the control socket
+ */
+#define DBUG_INDEX 0
+#define APPL_INDEX 1
+
+#ifdef TARGET
+
+# include "devdriv.h"
+
+extern const struct angel_DeviceEntry angel_EthernetDevice;
+
+/*
+ * Function: angel_EthernetPoll
+ * Purpose: Poll Fusion for newly arrived packets
+ *
+ * Pre-conditions: Called in SVC mode with the lock
+ *
+ * Params:
+ * Input: data IGNORE'd
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: Will have passed any packets received along to
+ * higher levels
+ */
+void angel_EthernetPoll(unsigned int data);
+
+void angel_EthernetNOP(unsigned int data);
+
+
+/*
+ * Function: angel_FindEthernetConfigBlock
+ * Purpose: Search the Flash for an ethernet config block and return
+ * it if found.
+ *
+ * Params: None
+ *
+ * Returns: NULL if no config block found, the address if one is found.
+ *
+ */
+extern angel_EthernetConfigBlock *angel_FindEthernetConfigBlock(void);
+
+#else /* def TARGET */
+
+# ifndef COMPILING_ON_WINDOWS
+# define ioctlsocket(x, y, z) ioctl((x), (y), (z))
+# define closesocket(x) close(x)
+# endif
+
+#endif /* def TARGET */
+
+#endif /* ndef angel_ethernet_h */
+
+/* EOF ethernet.h */
diff --git a/gdb/rdi-share/host.h b/gdb/rdi-share/host.h
new file mode 100644
index 0000000..3ae8fc4
--- /dev/null
+++ b/gdb/rdi-share/host.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+
+#ifndef _host_LOADED
+#define _host_LOADED 1
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+# define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+# define SEEK_END 2
+#endif
+
+/* The following for the benefit of compiling on SunOS */
+#ifndef offsetof
+# define offsetof(T, member) ((char *)&(((T *)0)->member) - (char *)0)
+#endif
+
+#ifdef unix /* A temporary sop to older compilers */
+# ifndef __unix /* (good for long-term portability?) */
+# define __unix 1
+# endif
+#endif
+
+#ifdef __unix
+/* Generic unix -- hopefully a split into other variants will not be */
+/* needed. However, beware the 'bsd' test above and safe_toupper etc. */
+/* which cope with backwards (pre-posix/X/open) unix compatility. */
+# define COMPILING_ON_UNIX 1
+#endif
+#if defined(_WIN32)
+# define COMPILING_ON_WIN32 1
+# if !defined(__CYGWIN32__)
+# define COMPILING_ON_WINDOWS 1
+# endif
+#endif
+#if defined(_CONSOLE)
+# define COMPILING_ON_WINDOWS_CONSOLE 1
+# define COMPILING_ON_WINDOWS 1
+#endif
+#ifdef _MSC_VER
+# define COMPILING_ON_MSDOS 1
+# define COMPILING_ON_WINDOWS 1
+# if defined(__cplusplus)
+# define IMPLEMENT_BOOL_AS_INT 1 /* VC++ doesn't have 'bool' (yet) */
+# endif
+#endif
+/* The '(defined(__sparc) && defined(P_tmpdir) */
+/* && !defined(__svr4__))' is to detect gcc on SunOS. */
+/* C++ compilers don't have to define __STDC__ */
+#if (defined(__sparc) && defined(P_tmpdir))
+# if defined(__svr4__)
+# define COMPILING_ON_SOLARIS
+# else
+# define COMPILING_ON_SUNOS
+# endif
+#endif
+#ifdef __hppa
+# define COMPILING_ON_HPUX
+#endif
+
+/*
+ * The following typedefs may need alteration for obscure host machines.
+ */
+#if defined(__alpha) && defined(__osf__) /* =========================== */
+/* Under OSF the alpha has 64-bit pointers and 64-bit longs. */
+typedef int int32;
+typedef unsigned int unsigned32;
+/* IPtr and UPtr are 'ints of same size as pointer'. Do not use in */
+/* new code. Currently only used within 'ncc'. */
+typedef long int IPtr;
+typedef unsigned long int UPtr;
+
+#else /* all hosts except alpha under OSF ============================= */
+
+typedef long int int32;
+typedef unsigned long int unsigned32;
+/* IPtr and UPtr are 'ints of same size as pointer'. Do not use in */
+/* new code. Currently only used within 'ncc'. */
+#define IPtr int32
+#define UPtr unsigned32
+#endif /* ============================================================= */
+
+typedef short int int16;
+typedef unsigned short int unsigned16;
+typedef signed char int8;
+typedef unsigned char unsigned8;
+
+/* The following code defines the 'bool' type to be 'int' under C */
+/* and real 'bool' under C++. It also avoids warnings such as */
+/* C++ keyword 'bool' used as identifier. It can be overridden by */
+/* defining IMPLEMENT_BOOL_AS_ENUM or IMPLEMENT_BOOL_AS_INT. */
+#undef _bool
+
+#ifdef IMPLEMENT_BOOL_AS_ENUM
+ enum _bool { _false, _true };
+# define _bool enum _bool
+#elif defined(IMPLEMENT_BOOL_AS_INT) || !defined(__cplusplus)
+# define _bool int
+# define _false 0
+# define _true 1
+#endif
+
+#ifdef _bool
+# if defined(_MFC_VER) || defined(__CC_NORCROFT) /* When using MS Visual C/C++ v4.2 */
+# define bool _bool /* avoids "'bool' is reserved word" warning */
+# else
+ typedef _bool bool;
+# endif
+# define true _true
+# define false _false
+#endif
+
+#define YES true
+#define NO false
+#undef TRUE /* some OSF headers define as 1 */
+#define TRUE true
+#undef FALSE /* some OSF headers define as 1 */
+#define FALSE false
+
+/* 'uint' conflicts with some Unixen sys/types.h, so we now don't define it */
+typedef unsigned8 uint8;
+typedef unsigned16 uint16;
+typedef unsigned32 uint32;
+
+typedef unsigned Uint;
+typedef unsigned8 Uint8;
+typedef unsigned16 Uint16;
+typedef unsigned32 Uint32;
+
+#ifdef ALPHA_TASO_SHORT_ON_OSF /* was __alpha && __osf. */
+/* The following sets ArgvType for 64-bit pointers so that */
+/* DEC Unix (OSF) cc can be used with the -xtaso_short compiler option */
+/* to force pointers to be 32-bit. Not currently used since most/all */
+/* ARM tools accept 32 or 64 bit pointers transparently. See IPtr. */
+#pragma pointer_size (save)
+#pragma pointer_size (long)
+typedef char *ArgvType;
+#pragma pointer_size (restore)
+#else
+typedef char *ArgvType;
+#endif
+
+/*
+ * Rotate macros
+ */
+#define ROL_32(val, n) \
+((((unsigned32)(val) << (n)) | ((unsigned32)(val) >> (32-(n)))) & 0xFFFFFFFFL)
+#define ROR_32(val, n) \
+((((unsigned32)(val) >> (n)) | ((unsigned32)(val) << (32-(n)))) & 0xFFFFFFFFL)
+
+#ifdef COMPILING_ON_UNIX
+# define FOPEN_WB "w"
+# define FOPEN_RB "r"
+# define FOPEN_RWB "r+"
+# ifndef __STDC__ /* caveat RISCiX... */
+# define remove(file) unlink(file) /* a horrid hack, but probably best? */
+# endif
+#else
+# define FOPEN_WB "wb"
+# define FOPEN_RB "rb"
+# define FOPEN_RWB "rb+"
+#endif
+
+#ifndef FILENAME_MAX
+# define FILENAME_MAX 256
+#endif
+
+#if (!defined(__STDC__) && !defined(__cplusplus) && !defined(_MSC_VER)) || \
+ defined(COMPILING_ON_SUNOS)
+/* Use bcopy rather than memmove, as memmove is not available. */
+/* There does not seem to be a header for bcopy. */
+void bcopy(const char *src, char *dst, int length);
+# define memmove(d,s,l) bcopy(s,d,l)
+
+/* BSD/SUN don't have strtoul(), but then strtol() doesn't barf on */
+/* overflow as required by ANSI... This bodge is horrid. */
+# define strtoul(s, ptr, base) strtol(s, ptr, base)
+
+/* strtod is present in the C-library but is not in stdlib.h */
+extern double strtod(const char *str, char **ptr);
+#endif
+
+/* For systems that do not define EXIT_SUCCESS and EXIT_FAILURE */
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+#ifndef IGNORE
+#define IGNORE(x) (x = x) /* Silence compiler warnings for unused arguments */
+#endif
+
+/* Define endian-ness of host */
+
+#if defined(__acorn) || defined(__mvs) || defined(_WIN32) || \
+ (defined(__alpha) && defined(__osf__))
+# define HOST_ENDIAN_LITTLE
+#elif defined(__sparc) || defined(macintosh)
+# define HOST_ENDIAN_BIG
+#else
+# define HOST_ENDIAN_UNKNOWN
+#endif
+
+#endif
+
+/* end of host.h */
diff --git a/gdb/rdi-share/hostchan.c b/gdb/rdi-share/hostchan.c
new file mode 100644
index 0000000..b62fbe3
--- /dev/null
+++ b/gdb/rdi-share/hostchan.c
@@ -0,0 +1,1060 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * hostchan.c - Semi Synchronous Host side channel interface for Angel.
+ */
+
+#include <stdio.h>
+
+#if defined(__unix) || defined(__CYGWIN32__)
+# include <sys/time.h>
+# ifdef sun
+ int gettimeofday(struct timeval *tp, struct timezone *tzp);
+# endif
+#else
+# include "winsock.h"
+# include "time.h"
+#endif
+#include "hsys.h"
+#include "host.h"
+#include "logging.h"
+#include "chandefs.h"
+#include "chanpriv.h"
+#include "devclnt.h"
+#include "buffers.h"
+#include "drivers.h"
+#include "adperr.h"
+#include "devsw.h"
+#include "hostchan.h"
+
+#ifndef UNUSED
+#define UNUSED(x) (x = x) /* Silence compiler warnings for unused arguments */
+#endif
+
+#define HEARTRATE 5000000
+
+/*
+ * list of available drivers, declared in drivers.c
+ */
+extern DeviceDescr *devices[];
+
+static DeviceDescr *deviceToUse = NULL;
+
+static struct Channel {
+ ChannelCallback callback;
+ void *callback_state;
+} channels[CI_NUM_CHANNELS];
+
+static unsigned char HomeSeq;
+static unsigned char OppoSeq;
+
+/*
+ * Handler for DC_APPL packets
+ */
+static DC_Appl_Handler dc_appl_handler = NULL;
+
+/*
+ * slots for registered asynchronous processing callback procedures
+ */
+#define MAX_ASYNC_CALLBACKS 8
+static unsigned int num_async_callbacks = 0;
+static Adp_Async_Callback async_callbacks[MAX_ASYNC_CALLBACKS];
+
+/*
+ * writeQueueRoot is the queue of write requests pending acknowledgement
+ * writeQueueSend is the queue of pending write requests which will
+ * be a subset of the list writeQueueRoot
+ */
+static Packet *writeQueueRoot = NULL;
+static Packet *writeQueueSend = NULL;
+static Packet *resend_pkt = NULL;
+static int resending = FALSE;
+
+/* heartbeat_enabled is a flag used to indicate whether the heartbeat is
+ * currently turned on, heartbeat_enabled will be false in situations
+ * where even though a heartbeat is being used it is problematical or
+ * dis-advantageous to have it turned on, for instance during the
+ * initial stages of boot up
+ */
+unsigned int heartbeat_enabled = FALSE;
+/* heartbeat_configured is set up by the device driver to indicate whether
+ * the heartbeat is being used during this debug session. In contrast to
+ * heartbeat_enabled it must not be changed during a session. The logic for
+ * deciding whether to send a heartbeat is: Is heartbeat_configured for this
+ * session? if and only if it is then if heartbeat[is currently]_enabled and
+ * we are due to send a pulse then send it
+ */
+unsigned int heartbeat_configured = TRUE;
+
+void Adp_initSeq( void ) {
+ Packet *tmp_pkt = writeQueueSend;
+
+ HomeSeq = 0;
+ OppoSeq = 0;
+ if ( writeQueueSend != NULL) {
+ while (writeQueueSend->pk_next !=NULL) {
+ tmp_pkt = writeQueueSend;
+ writeQueueSend = tmp_pkt->pk_next;
+ DevSW_FreePacket(tmp_pkt);
+ }
+ }
+ tmp_pkt = writeQueueRoot;
+ if ( writeQueueRoot == NULL)
+ return;
+
+ while (writeQueueRoot->pk_next !=NULL) {
+ tmp_pkt = writeQueueRoot;
+ writeQueueRoot = tmp_pkt->pk_next;
+ DevSW_FreePacket(tmp_pkt);
+ }
+ return;
+}
+
+/**********************************************************************/
+
+/*
+ * Function: DummyCallback
+ * Purpose: Default callback routine to handle unexpected input
+ * on a channel
+ *
+ * Params:
+ * Input: packet The received packet
+ *
+ * state Contains nothing of significance
+ *
+ * Returns: Nothing
+ */
+static void DummyCallback(Packet *packet, void *state)
+{
+ ChannelID chan;
+ const char fmt[] = "Unexpected read on channel %u, length %d\n";
+ char fmtbuf[sizeof(fmt) + 24];
+
+ UNUSED(state);
+
+ chan = *(packet->pk_buffer);
+ sprintf(fmtbuf, fmt, chan, packet->pk_length);
+ printf(fmtbuf);
+
+ /*
+ * junk this packet
+ */
+ DevSW_FreePacket(packet);
+}
+
+/*
+ * Function: BlockingCallback
+ * Purpose: Callback routine used to implement a blocking read call
+ *
+ * Params:
+ * Input: packet The received packet.
+ *
+ * Output: state Address of higher level's pointer to the received
+ * packet.
+ *
+ * Returns: Nothing
+ */
+static void BlockingCallback(Packet *packet, void *state)
+{
+ /*
+ * Pass the packet back to the caller which requested a packet
+ * from this channel. This also flags the completion of the I/O
+ * request to the blocking read call.
+ */
+ *((Packet **)state) = packet;
+}
+
+/*
+ * Function: FireCallback
+ * Purpose: Pass received packet along to the callback routine for
+ * the appropriate channel
+ *
+ * Params:
+ * Input: packet The received packet.
+ *
+ * Returns: Nothing
+ *
+ * Post-conditions: The Target-to-Host sequence number for the channel
+ * will have been incremented.
+ */
+static void FireCallback(Packet *packet)
+{
+ ChannelID chan;
+ struct Channel *ch;
+
+ /*
+ * is this a sensible channel number?
+ */
+ chan = *(packet->pk_buffer);
+ if (invalidChannelID(chan))
+ {
+ printf("ERROR: invalid ChannelID received from target\n");
+
+ /*
+ * free the packet's resources, 'cause no-one else will
+ */
+ DevSW_FreePacket(packet);
+ return;
+ }
+
+ /*
+ * looks OK - increment sequence number, and pass packet to callback
+ */
+ ch = channels + chan;
+ (ch->callback)(packet, ch->callback_state);
+}
+
+/**********************************************************************/
+
+/*
+ * These are the externally visible functions. They are documented
+ * in hostchan.h
+ */
+void Adp_addToQueue(Packet **head, Packet *newpkt)
+{
+ /*
+ * this is a bit of a hack
+ */
+ Packet *pk;
+
+ /*
+ * make sure that the hack we are about to use will work as expected
+ */
+ ASSERT(&(((Packet *)0)->pk_next) == 0, "bad struct Packet layout");
+
+#if DEBUG && 0
+ printf("Adp_addToQueue(%p, %p)\n", head, newpkt);
+#endif
+
+ /*
+ * here's the hack - it relies upon the next
+ * pointer being at the start of Packet.
+ */
+ pk = (Packet *)(head);
+
+ /*
+ * skip to the end of the queue
+ */
+ while (pk->pk_next != NULL)
+ pk = pk->pk_next;
+
+ /*
+ * now add the new element
+ */
+ newpkt->pk_next = NULL;
+ pk->pk_next = newpkt;
+}
+
+Packet *Adp_removeFromQueue(Packet **head)
+{
+ struct Packet *pk;
+
+ pk = *head;
+
+ if (pk != NULL)
+ *head = pk->pk_next;
+
+ return pk;
+}
+
+AdpErrs Adp_OpenDevice(const char *name, const char *arg,
+ unsigned int heartbeat_on)
+{
+ int i;
+ AdpErrs retc;
+ ChannelID chan;
+
+#ifdef DEBUG
+ printf("Adp_OpenDevice(%s, %s)\n", name, arg ? arg : "<NULL>");
+#endif
+
+ heartbeat_configured = heartbeat_on;
+ if (deviceToUse != NULL)
+ return adp_device_already_open;
+
+ for (i = 0; (deviceToUse = devices[i]) != NULL; ++i)
+ if (DevSW_Match(deviceToUse, name, arg) == adp_ok)
+ break;
+
+ if (deviceToUse == NULL)
+ return adp_device_not_found;
+
+ /*
+ * we seem to have found a suitable device driver, so try to open it
+ */
+ if ((retc = DevSW_Open(deviceToUse, name, arg, DC_DBUG)) != adp_ok)
+ {
+ /* we don't have a device to use */
+ deviceToUse = NULL;
+ return retc;
+ }
+
+ /*
+ * there is no explicit open on channels any more, so
+ * initialise state for all channels.
+ */
+ for (chan = 0; chan < CI_NUM_CHANNELS; ++chan)
+ {
+ struct Channel *ch = channels + chan;
+
+ ch->callback = DummyCallback;
+ ch->callback_state = NULL;
+ OppoSeq = 0;
+ HomeSeq = 0;
+ }
+
+ return adp_ok;
+}
+
+AdpErrs Adp_CloseDevice(void)
+{
+ AdpErrs retc;
+
+#ifdef DEBUG
+ printf("Adp_CloseDevice\n");
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ heartbeat_enabled = FALSE;
+
+ retc = DevSW_Close(deviceToUse, DC_DBUG);
+
+ /*
+ * we have to clear deviceToUse, even when the lower layers
+ * faulted the close, otherwise the condition will never clear
+ */
+ if (retc != adp_ok)
+ WARN("DevSW_Close faulted the call");
+
+ deviceToUse = NULL;
+ return retc;
+}
+
+AdpErrs Adp_Ioctl(int opcode, void *args)
+{
+#ifdef DEBUG
+ printf("Adp_Ioctl\n");
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ return DevSW_Ioctl(deviceToUse, opcode, args);
+}
+
+AdpErrs Adp_ChannelRegisterRead(const ChannelID chan,
+ const ChannelCallback cbfunc,
+ void *cbstate)
+{
+#ifdef DEBUG
+ printf("Adp_ChannelRegisterRead(%d, %p, %x)\n", chan, cbfunc, cbstate);
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ if (invalidChannelID(chan))
+ return adp_bad_channel_id;
+
+ if (cbfunc == NULL)
+ {
+ channels[chan].callback = DummyCallback;
+ channels[chan].callback_state = NULL;
+ }
+ else
+ {
+ channels[chan].callback = cbfunc;
+ channels[chan].callback_state = cbstate;
+ }
+
+ return adp_ok;
+}
+
+AdpErrs Adp_ChannelRead(const ChannelID chan, Packet **packet)
+{
+ struct Channel *ch;
+
+#ifdef DEBUG
+ printf("Adp_ChannelRead(%d, %x)\n", chan, *packet);
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ if (invalidChannelID(chan))
+ return adp_bad_channel_id;
+
+ /*
+ * if a callback has already been registered for this
+ * channel, then we do not allow this blocking read.
+ */
+ ch = channels + chan;
+ if (ch->callback != DummyCallback)
+ return adp_callback_already_registered;
+
+ /*
+ * OK, use our own callback to wait for a packet to arrive
+ * on this channel
+ */
+ ch->callback = BlockingCallback;
+ ch->callback_state = packet;
+ *packet = NULL;
+
+ /*
+ * keep polling until a packet appears for this channel
+ */
+ while (((volatile Packet *)(*packet)) == NULL)
+ /*
+ * this call will block until a packet is read on any channel
+ */
+ Adp_AsynchronousProcessing(async_block_on_read);
+
+ /*
+ * OK, the packet has arrived: clear the callback
+ */
+ ch->callback = DummyCallback;
+ ch->callback_state = NULL;
+
+ return adp_ok;
+}
+
+static AdpErrs ChannelWrite(
+ const ChannelID chan, Packet *packet, AsyncMode mode)
+{
+ struct Channel *ch;
+ unsigned char *cptr;
+
+#ifdef DEBUG
+ printf( "Adp_ChannelWrite(%d, %x)\n", chan, packet );
+#endif
+
+ if (deviceToUse == NULL)
+ return adp_device_not_open;
+
+ if (invalidChannelID(chan))
+ return adp_bad_channel_id;
+
+ /*
+ * fill in the channels header at the start of this buffer
+ */
+ ch = channels + chan;
+ cptr = packet->pk_buffer;
+ *cptr++ = chan;
+ *cptr = 0;
+ packet->pk_length += CHAN_HEADER_SIZE;
+
+ /*
+ * OK, add this packet to the write queue, and try to flush it out
+ */
+
+ Adp_addToQueue(&writeQueueSend, packet);
+ Adp_AsynchronousProcessing(mode);
+
+ return adp_ok;
+}
+
+AdpErrs Adp_ChannelWrite(const ChannelID chan, Packet *packet) {
+ return ChannelWrite(chan, packet, async_block_on_write);
+}
+
+AdpErrs Adp_ChannelWriteAsync(const ChannelID chan, Packet *packet) {
+ return ChannelWrite(chan, packet, async_block_on_nothing);
+}
+
+static AdpErrs send_resend_msg(DeviceID devid) {
+
+ /*
+ * Send a resend message, usually in response to a bad packet or
+ * a resend request */
+ Packet * packet;
+ packet = DevSW_AllocatePacket(CF_DATA_BYTE_POS);
+ packet->pk_buffer[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;
+ packet->pk_buffer[CF_HOME_SEQ_BYTE_POS] = HomeSeq;
+ packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS] = OppoSeq;
+ packet->pk_buffer[CF_FLAGS_BYTE_POS] = CF_RELIABLE | CF_RESEND;
+ packet->pk_length = CF_DATA_BYTE_POS;
+ return DevSW_Write(deviceToUse, packet, devid);
+}
+
+static AdpErrs check_seq(unsigned char msg_home, unsigned char msg_oppo) {
+ Packet *tmp_pkt;
+
+ UNUSED(msg_oppo);
+ /*
+ * check if we have got an ack for anything and if so remove it from the
+ * queue
+ */
+ if (msg_home == (unsigned char)(OppoSeq+1)) {
+ /*
+ * arrived in sequence can increment our opposing seq number and remove
+ * the relevant packet from our queue
+ * check that the packet we're going to remove really is the right one
+ */
+ tmp_pkt = writeQueueRoot;
+ while ((tmp_pkt->pk_next != NULL) &&
+ (tmp_pkt->pk_next->pk_buffer[CF_HOME_SEQ_BYTE_POS]
+ != OppoSeq)){
+ tmp_pkt = tmp_pkt->pk_next;
+ }
+ OppoSeq++;
+ if (tmp_pkt->pk_next == NULL) {
+#ifdef DEBUG
+ printf("trying to remove a non existant packet\n");
+#endif
+ return adp_bad_packet;
+ }
+ else {
+ Packet *tmp = tmp_pkt->pk_next;
+#ifdef RET_DEBUG
+ printf("removing a packet from the root queue\n");
+#endif
+ tmp_pkt->pk_next = tmp_pkt->pk_next->pk_next;
+ /* remove the appropriate packet */
+ DevSW_FreePacket(tmp);
+ return adp_ok;
+ }
+ }
+ else if (msg_home < (unsigned char) (OppoSeq+1)){
+ /* already received this message */
+#ifdef RET_DEBUG
+ printf("sequence numbers low\n");
+#endif
+ return adp_seq_low;
+ }
+ else { /* we've missed something */
+#ifdef RET_DEBUG
+ printf("sequence numbers high\n");
+#endif
+ return adp_seq_high;
+ }
+}
+
+static unsigned long tv_diff(const struct timeval *time_now,
+ const struct timeval *time_was)
+{
+ return ( ((time_now->tv_sec * 1000000) + time_now->tv_usec)
+ - ((time_was->tv_sec * 1000000) + time_was->tv_usec) );
+}
+
+#if !defined(__unix) && !defined(__CYGWIN32__)
+static void gettimeofday( struct timeval *time_now, void *dummy )
+{
+ time_t t = clock();
+ UNUSED(dummy);
+ time_now->tv_sec = t/CLOCKS_PER_SEC;
+ time_now->tv_usec = (t%CLOCKS_PER_SEC)*(1000000/CLOCKS_PER_SEC);
+}
+#endif
+
+static AdpErrs pacemaker(void)
+{
+ Packet *packet;
+
+ packet = DevSW_AllocatePacket(CF_DATA_BYTE_POS);
+ if (packet == NULL) {
+ printf("ERROR: could not allocate a packet in pacemaker()\n");
+ return adp_malloc_failure;
+ }
+ packet->pk_buffer[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;
+ packet->pk_buffer[CF_HOME_SEQ_BYTE_POS] = HomeSeq;
+ packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS] = OppoSeq;
+ packet->pk_buffer[CF_FLAGS_BYTE_POS] = CF_RELIABLE | CF_HEARTBEAT;
+ packet->pk_length = CF_DATA_BYTE_POS;
+ return DevSW_Write(deviceToUse, packet, DC_DBUG);
+}
+
+#ifdef FAKE_BAD_LINE_RX
+static AdpErrs fake_bad_line_rx( const Packet *const packet, AdpErrs adp_err )
+{
+ static unsigned int bl_num = 0;
+
+ if ( (packet != NULL)
+ && (bl_num++ >= 20 )
+ && ((bl_num % FAKE_BAD_LINE_RX) == 0))
+ {
+ printf("DEBUG: faking a bad packet\n");
+ return adp_bad_packet;
+ }
+ return adp_err;
+}
+#endif /* def FAKE_BAD_LINE_RX */
+
+#ifdef FAKE_BAD_LINE_TX
+static unsigned char tmp_ch;
+
+static void fake_bad_line_tx( void )
+{
+ static unsigned int bl_num = 0;
+
+ /* give the thing a chance to boot then try corrupting stuff */
+ if ( (bl_num++ >= 20) && ((bl_num % FAKE_BAD_LINE_TX) == 0))
+ {
+ printf("DEBUG: faking a bad packet for tx\n");
+ tmp_ch = writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS];
+ writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS] = 77;
+ }
+}
+
+static void unfake_bad_line_tx( void )
+{
+ static unsigned int bl_num = 0;
+
+ /*
+ * must reset the packet so that its not corrupted when we
+ * resend it
+ */
+ if ( (bl_num >= 20) && ((bl_num % FAKE_BAD_LINE_TX) != 0))
+ {
+ writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS] = tmp_ch;
+ }
+}
+#endif /* def FAKE_BAD_LINE_TX */
+
+/*
+ * NOTE: we are assuming that a resolution of microseconds will
+ * be good enough for the purporses of the heartbeat. If this proves
+ * not to be the case then we may need a rethink, possibly using
+ * [get,set]itimer
+ */
+static struct timeval time_now;
+static struct timeval time_lastalive;
+
+static void async_process_dbug_read( const AsyncMode mode,
+ bool *const finished )
+{
+ Packet *packet;
+ unsigned int msg_home, msg_oppo;
+ AdpErrs adp_err;
+
+ adp_err = DevSW_Read(deviceToUse, DC_DBUG, &packet,
+ mode == async_block_on_read );
+
+#ifdef FAKE_BAD_LINE_RX
+ adp_err = fake_bad_line_rx( packet, adp_err );
+#endif
+
+ if (adp_err == adp_bad_packet) {
+ /* We got a bad packet, ask for a resend, send a resend message */
+#ifdef DEBUG
+ printf("received a bad packet\n");
+#endif
+ send_resend_msg(DC_DBUG);
+ }
+ else if (packet != NULL)
+ {
+ /* update the heartbeat clock */
+ gettimeofday(&time_lastalive, NULL);
+
+ /*
+ * we got a live one here - were we waiting for it?
+ */
+ if (mode == async_block_on_read)
+ /* not any more */
+ *finished = TRUE;
+#ifdef RETRANS
+
+ if (packet->pk_length < CF_DATA_BYTE_POS) {
+ /* we've got a packet with no header information! */
+ printf("ERROR: packet with no transport header\n");
+ send_resend_msg(DC_DBUG);
+ }
+ else {
+#ifdef RET_DEBUG
+ unsigned int c;
+#endif
+ /*
+ * TODO: Check to see if its acknowledgeing anything, remove
+ * those packets it is from the queue. If its a retrans add the
+ * packets to the queue
+ */
+ msg_home = packet->pk_buffer[CF_HOME_SEQ_BYTE_POS];
+ msg_oppo = packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS];
+#ifdef RET_DEBUG
+ printf("msg seq numbers are hseq 0x%x oseq 0x%x\n",
+ msg_home, msg_oppo);
+ for (c=0;c<packet->pk_length;c++)
+ printf("%02.2x", packet->pk_buffer[c]);
+ printf("\n");
+#endif
+ /* now was it a resend request? */
+ if ((packet->pk_buffer[CF_FLAGS_BYTE_POS])
+ & CF_RESEND) {
+ /* we've been asked for a resend so we had better resend */
+ /*
+ * I don't think we can use a resend as acknowledgement for
+ * anything so lets not do this for the moment
+ * check_seq(msg_home, msg_oppo);
+ */
+#ifdef RET_DEBUG
+ printf("received a resend request\n");
+#endif
+ if (HomeSeq != msg_oppo) {
+ int found = FALSE;
+ /* need to resend from msg_oppo +1 upwards */
+ DevSW_FreePacket(packet);
+ resending = TRUE;
+ /* find the correct packet to resend from */
+ packet = writeQueueRoot;
+ while (((packet->pk_next) != NULL) && !found) {
+ if ((packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS])
+ != msg_oppo+1) {
+ resend_pkt = packet;
+ found = TRUE;
+ }
+ packet = packet->pk_next;
+ }
+ if (!found) {
+ panic("trying to resend non-existent packets\n");
+ }
+ }
+ else if (OppoSeq != msg_home) {
+ /*
+ * send a resend request telling the target where we think
+ * the world is at
+ */
+ DevSW_FreePacket(packet);
+ send_resend_msg(DC_DBUG);
+ }
+ }
+ else {
+ /* not a resend request, lets check the sequence numbers */
+
+ if ((packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_HBOOT) &&
+ (packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_TBOOT)) {
+ adp_err = check_seq(msg_home, msg_oppo);
+ if (adp_err == adp_seq_low) {
+ /* we have already received this packet so discard */
+ DevSW_FreePacket(packet);
+ }
+ else if (adp_err == adp_seq_high) {
+ /*
+ * we must have missed a packet somewhere, discard this
+ * packet and tell the target where we are
+ */
+ DevSW_FreePacket(packet);
+ send_resend_msg(DC_DBUG);
+ }
+ else
+ /*
+ * now pass the packet to whoever is waiting for it
+ */
+ FireCallback(packet);
+ }
+ else
+ FireCallback(packet);
+ }
+ }
+#else
+ /*
+ * now pass the packet to whoever is waiting for it
+ */
+ FireCallback(packet);
+#endif
+ }
+}
+
+static void async_process_appl_read(void)
+{
+ Packet *packet;
+ AdpErrs adp_err;
+
+ /* see if there is anything for the DC_APPL channel */
+ adp_err = DevSW_Read(deviceToUse, DC_APPL, &packet, FALSE);
+
+ if (adp_err == adp_ok && packet != NULL)
+ {
+ /* got an application packet on a shared device */
+
+#ifdef DEBUG
+ printf("GOT DC_APPL PACKET: len %d\nData: ", packet->pk_length);
+ {
+ unsigned int c;
+ for ( c = 0; c < packet->pk_length; ++c )
+ printf( "%02X ", packet->pk_buffer[c] );
+ }
+ printf("\n");
+#endif
+
+ if (dc_appl_handler != NULL)
+ {
+ dc_appl_handler( deviceToUse, packet );
+ }
+ else
+ {
+ /* for now, just free it!! */
+#ifdef DEBUG
+ printf("no handler - dropping DC_APPL packet\n");
+#endif
+ DevSW_FreePacket( packet );
+ }
+ }
+}
+
+static void async_process_write( const AsyncMode mode,
+ bool *const finished )
+{
+ Packet *packet;
+
+#ifdef DEBUG
+ static unsigned int num_written = 0;
+#endif
+
+ /*
+ * NOTE: here we rely in the fact that any packet in the writeQueueSend
+ * section of the queue will need its sequence number setting up while
+ * and packet in the writeQueueRoot section will have its sequence
+ * numbers set up from when it was first sent so we can easily look
+ * up the packet numbers when(if) we want to resend the packet.
+ */
+
+#ifdef DEBUG
+ if (writeQueueSend!=NULL)
+ printf("written 0x%x\n",num_written += writeQueueSend->pk_length);
+#endif
+ /*
+ * give the switcher a chance to complete any partial writes
+ */
+ if (DevSW_FlushPendingWrite(deviceToUse) == adp_write_busy)
+ {
+ /* no point trying a new write */
+ return;
+ }
+
+ /*
+ * now see whether there is anything to write
+ */
+ packet = NULL;
+ if (resending) {
+ packet = resend_pkt;
+#ifdef RET_DEBUG
+ printf("resending hseq 0x%x oseq 0x%x\n",
+ packet->pk_buffer[CF_HOME_SEQ_BYTE_POS],
+ packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
+#endif
+ }
+ else if (writeQueueSend != NULL) {
+#ifdef RETRANS
+ /* set up the sequence number on the packet */
+ packet = writeQueueSend;
+ HomeSeq++;
+ (writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS])
+ = OppoSeq;
+ (writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS])
+ = HomeSeq;
+ (writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS])
+ = CF_RELIABLE;
+# ifdef RET_DEBUG
+ printf("sending packet with hseq 0x%x oseq 0x%x\n",
+ writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS],
+ writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
+# endif
+#endif /* RETRANS */
+ }
+
+ if (packet != NULL) {
+ AdpErrs dev_err;
+
+#ifdef FAKE_BAD_LINE_TX
+ fake_bad_line_tx();
+#endif
+
+ dev_err = DevSW_Write(deviceToUse, packet, DC_DBUG);
+ if (dev_err == adp_ok) {
+#ifdef RETRANS
+ if (resending) {
+ /* check to see if we've recovered yet */
+ if ((packet->pk_next) == NULL){
+# ifdef RET_DEBUG
+ printf("we have recovered\n");
+# endif
+ resending = FALSE;
+ }
+ else {
+ resend_pkt = resend_pkt->pk_next;
+ }
+ }
+ else {
+ /*
+ * move the packet we just sent from the send queue to the root
+ */
+ Packet *tmp_pkt, *tmp;
+
+# ifdef FAKE_BAD_LINE_TX
+ unfake_bad_line_tx();
+# endif
+
+ tmp_pkt = writeQueueSend;
+ writeQueueSend = writeQueueSend->pk_next;
+ tmp_pkt->pk_next = NULL;
+ if (writeQueueRoot == NULL)
+ writeQueueRoot = tmp_pkt;
+ else {
+ tmp = writeQueueRoot;
+ while (tmp->pk_next != NULL) {
+ tmp = tmp->pk_next;
+ }
+ tmp->pk_next = tmp_pkt;
+ }
+ }
+#else /* not RETRANS */
+ /*
+ * switcher has taken the write, so remove it from the
+ * queue, and free its resources
+ */
+ DevSW_FreePacket(Adp_removeFromQueue(&writeQueueSend));
+#endif /* if RETRANS ... else ... */
+
+ if (mode == async_block_on_write)
+ *finished = DevSW_WriteFinished(deviceToUse);
+
+ } /* endif write ok */
+ }
+ else /* packet == NULL */
+ {
+ if (mode == async_block_on_write)
+ *finished = DevSW_WriteFinished(deviceToUse);
+ }
+}
+
+static void async_process_heartbeat( void )
+{
+ /* check to see whether we need to send a heartbeat */
+ gettimeofday(&time_now, NULL);
+
+ if (tv_diff(&time_now, &time_lastalive) >= HEARTRATE)
+ {
+ /*
+ * if we've not booted then don't do send a heartrate the link
+ * must be reliable enough for us to boot without any clever stuff,
+ * if we can't do this then theres little chance of the link staying
+ * together even with the resends etc
+ */
+ if (heartbeat_enabled) {
+ gettimeofday(&time_lastalive, NULL);
+ pacemaker();
+ }
+ }
+}
+
+static void async_process_callbacks( void )
+{
+ /* call any registered asynchronous callbacks */
+ unsigned int i;
+ for ( i = 0; i < num_async_callbacks; ++i )
+ async_callbacks[i]( deviceToUse, &time_now );
+}
+
+void Adp_AsynchronousProcessing(const AsyncMode mode)
+{
+ bool finished = FALSE;
+#ifdef DEBUG
+ unsigned int wc = 0, dc = 0, ac = 0, hc = 0;
+# define INC_COUNT(x) ((x)++)
+#else
+# define INC_COUNT(x)
+#endif
+
+ if ((time_lastalive.tv_sec == 0) && (time_lastalive.tv_usec == 0)) {
+ /* first time through, needs initing */
+ gettimeofday(&time_lastalive, NULL);
+ }
+
+ /* main loop */
+ do
+ {
+ async_process_write( mode, &finished );
+ INC_COUNT(wc);
+
+ if ( ! finished && mode != async_block_on_write )
+ {
+ async_process_dbug_read( mode, &finished );
+ INC_COUNT(dc);
+ }
+
+ if ( ! finished && mode != async_block_on_write )
+ {
+ async_process_appl_read();
+ INC_COUNT(ac);
+ }
+
+ if ( ! finished )
+ {
+ if (heartbeat_configured)
+ async_process_heartbeat();
+ async_process_callbacks();
+ INC_COUNT(hc);
+ }
+
+ } while (!finished && mode != async_block_on_nothing);
+
+#ifdef DEBUG
+ if ( mode != async_block_on_nothing )
+ printf( "Async: %s - w %d, d %d, a %d, h %d\n",
+ mode == async_block_on_write ? "blk_write" : "blk_read",
+ wc, dc, ac, hc );
+#endif
+}
+
+/*
+ * install a handler for DC_APPL packets (can be NULL), returning old one.
+ */
+DC_Appl_Handler Adp_Install_DC_Appl_Handler(const DC_Appl_Handler handler)
+{
+ DC_Appl_Handler old_handler = dc_appl_handler;
+
+#ifdef DEBUG
+ printf( "Installing DC_APPL handler %x (old %x)\n", handler, old_handler );
+#endif
+
+ dc_appl_handler = handler;
+ return old_handler;
+}
+
+
+/*
+ * add an asynchronous processing callback to the list
+ * TRUE == okay, FALSE == no more async processing slots
+ */
+bool Adp_Install_Async_Callback( const Adp_Async_Callback callback_proc )
+{
+ if ( num_async_callbacks < MAX_ASYNC_CALLBACKS && callback_proc != NULL )
+ {
+ async_callbacks[num_async_callbacks] = callback_proc;
+ ++num_async_callbacks;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+/*
+ * delay for a given period (in microseconds)
+ */
+void Adp_delay(unsigned int period)
+{
+ struct timeval tv;
+
+#ifdef DEBUG
+ printf("delaying for %d microseconds\n", period);
+#endif
+ tv.tv_sec = (period / 1000000);
+ tv.tv_usec = (period % 1000000);
+
+ (void)select(0, NULL, NULL, NULL, &tv);
+}
+
+/* EOF hostchan.c */
diff --git a/gdb/rdi-share/hostchan.h b/gdb/rdi-share/hostchan.h
new file mode 100644
index 0000000..db313dc
--- /dev/null
+++ b/gdb/rdi-share/hostchan.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#ifndef angsd_hostchan_h
+#define angsd_hostchan_h
+
+/* struct timeval */
+#if defined(__unix) || defined(__CYGWIN32__)
+# include <sys/time.h>
+#else
+# include "winsock.h"
+# include "time.h"
+#endif
+
+#include "chandefs.h"
+#include "adperr.h"
+#include "devsw.h"
+
+/*
+ * asynchronous processing modes
+ */
+enum AsyncMode
+{
+ async_block_on_nothing,
+ async_block_on_read,
+ async_block_on_write
+};
+
+#ifndef __cplusplus
+typedef enum AsyncMode AsyncMode;
+#endif
+
+/*
+ * prototype for channels callback function
+ */
+typedef void (*ChannelCallback)(Packet *packet, void *state);
+
+/*
+ * Function: Adp_initSeq
+ * Purpose: initialise the channel protocol and sequence numbers
+ *
+ * Params: none
+ *
+ * Returns: Nothing
+ */
+extern void Adp_initSeq(void);
+
+/*
+ * Function: Adp_addToQueue
+ * Purpose: chain a Packet to the end of a linked list of such structures
+ *
+ * Params:
+ * In/Out: head Head of the linked list
+ *
+ * newpkt Packet to be chained onto the list
+ *
+ * Returns: Nothing
+ */
+extern void Adp_addToQueue(Packet **head, Packet *newpkt);
+
+/*
+ * Function: removeFromQueue
+ * Purpose: remove a Packet from the head of a linked list of such structures
+ *
+ * Params:
+ * In/Out: head Head of the linked list
+ *
+ * Returns: Old head from the linked list
+ *
+ * Post-conditions: Second element in the list will be the new head.
+ */
+
+extern Packet *Adp_removeFromQueue(Packet **head);
+
+/*
+ * Function: Adp_OpenDevice
+ * Purpose: Open a device to use for channels communication. This is a
+ * very thin veneer to the device drivers: what hostchan.c
+ * will do is call DeviceMatch for each device driver until it
+ * finds a driver that will accept name and arg, then call
+ * DeviceOpen for that device.
+ *
+ * Pre-conditions: No previous open is still active
+ *
+ * Params:
+ * Input: name Identifies which device to open. This can either be
+ * a host specific identifier (e.g. "/dev/ttya",
+ * "COM1:"), or a number which is used to refer to
+ * `standard' interfaces, so "1" would be the first host
+ * interface, "2" the second, and so on.
+ *
+ * arg Driver specific arguments. For example, some serial
+ * drivers accept speed and control arguments such as
+ * "9600" or "19200/NO_BREAK". These arguments are
+ * completely free-form: it is the individual drivers
+ * which do the necessary interpretation.
+ *
+ * heartbeat_on Incicates if the heartbeat is configured to be
+ * used or not, true if it is, false otherwise
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_known,
+ * adp_device_open_failed
+ * adp_device_already_open
+ */
+AdpErrs Adp_OpenDevice(const char *name, const char *arg,
+ unsigned int heartbeat_on);
+
+/*
+ * Function: Adp_CloseDevice
+ * Purpose: Close the device used for channels communication.
+ *
+ * Params: None
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ */
+AdpErrs Adp_CloseDevice(void);
+
+/*
+ * Function: Adp_Ioctl
+ * Purpose: Perform miscellaneous control operations on
+ * the device used for channels communication.
+ * This is a minimal veneer to DevSW_Ioctl.
+ *
+ * Params:
+ * Input: opcode Reason code indicating the operation to perform.
+ * In/Out: args Pointer to opcode-sensitive arguments/result space.
+ *
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open, adp_failed
+ */
+AdpErrs Adp_Ioctl(int opcode, void *args);
+
+/*
+ * Function: Adp_ChannelRegisterRead
+ * Purpose: Register a callback function for received packets on a given
+ * channel
+ *
+ * Params:
+ * Input: chan The channel the callback function is for.
+ *
+ * cbfunc The callback function. If NULL, then the current
+ * callback is removed.
+ *
+ * cbstate State pointer to pass into the callback function
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ *
+ * Post-conditions: The callback function is responsible for freeing the
+ * packet that is passed to it, when that packet is
+ * no longer needed.
+ */
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+extern AdpErrs Adp_ChannelRegisterRead(const ChannelID chan,
+ const ChannelCallback cbfunc,
+ void *cbstate);
+
+#ifdef __cplusplus
+ }
+#endif
+/*
+ * Function: Adp_ChannelRead
+ * Purpose: Wait until a packet has been read for a given channel, and
+ * then return it. Callbacks for other channels are still
+ * active while this read is blocking.
+ *
+ * Pre-conditions: No callback has been already been registered for
+ * the channel.
+ *
+ * Params:
+ * Input: chan The channel to read.
+ *
+ * Output: packet The received packet.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ * adp_callback_already_registered
+ *
+ * Post-conditions: The calling function is responsible for freeing the
+ * received packet, when that packet is no longer
+ * needed.
+ */
+AdpErrs Adp_ChannelRead(const ChannelID chan, Packet **packet);
+
+/*
+ * Function: Adp_ChannelWrite
+ * Purpose: Write a packet to the given channel
+ *
+ * Pre-conditions: Channel must have been previously opened.
+ *
+ * Params:
+ * Input: chan The channel to write.
+ *
+ * packet The packet to write.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ *
+ * Post-conditions: The packet being written becomes the "property" of
+ * Adp_ChannelWrite, which is responsible for freeing
+ * the packet when it is no longer needed.
+ */
+AdpErrs Adp_ChannelWrite(const ChannelID chan, Packet *packet);
+
+/*
+ * Function: Adp_ChannelWriteAsync
+ * Purpose: Write a packet to the given channel, but don't wait
+ * for the write to complete before returning.
+ *
+ * Pre-conditions: Channel must have been previously opened.
+ *
+ * Params:
+ * Input: chan The channel to write.
+ *
+ * packet The packet to write.
+ *
+ * Returns:
+ * OK: adp_ok
+ * Error: adp_device_not_open
+ * adp_bad_channel_id
+ *
+ * Post-conditions: The packet being written becomes the "property" of
+ * Adp_ChannelWrite, which is responsible for freeing
+ * the packet when it is no longer needed.
+ */
+AdpErrs Adp_ChannelWriteAsync(const ChannelID chan, Packet *packet);
+
+/*
+ * Function: Adp_AsynchronousProcessing
+ * Purpose: This routine should be called from persistent any idle loop
+ * to give the data I/O routines a chance to poll for packet
+ * activity. Depending upon the requested mode, this routine
+ * may, or may not, block.
+ *
+ * Params:
+ * Input: mode Specifies whether to block until a complete packet
+ * has been read, all pending writes have completed,
+ * or not to block at all.
+ *
+ * Returns: Nothing.
+ */
+void Adp_AsynchronousProcessing(const AsyncMode mode);
+
+/*
+ * prototype for DC_APPL packet handler
+ */
+typedef void (*DC_Appl_Handler)(const DeviceDescr *device, Packet *packet);
+
+/*
+ * install a handler for DC_APPL packets (can be NULL), returning old one.
+ */
+DC_Appl_Handler Adp_Install_DC_Appl_Handler(const DC_Appl_Handler handler);
+
+/*
+ * prototype for asynchronous processing callback
+ */
+typedef void (*Adp_Async_Callback)(const DeviceDescr *device,
+ const struct timeval *const time_now);
+
+/*
+ * add an asynchronous processing callback to the list
+ * TRUE == okay, FALSE == no more async processing slots
+ */
+bool Adp_Install_Async_Callback( const Adp_Async_Callback callback_proc );
+
+/*
+ * delay for a given period (in microseconds)
+ */
+void Adp_delay(unsigned int period);
+
+#endif /* ndef angsd_hostchan_h */
+
+/* EOF hostchan.h */
diff --git a/gdb/rdi-share/hsys.c b/gdb/rdi-share/hsys.c
new file mode 100644
index 0000000..ef42a30
--- /dev/null
+++ b/gdb/rdi-share/hsys.c
@@ -0,0 +1,915 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * Host C Library support functions.
+ *
+ * $Revision$
+ * $Date$
+ */
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <time.h>
+
+#include "adp.h"
+#include "host.h"
+#include "ardi.h"
+#include "buffers.h"
+#include "channels.h" /* Channel interface. */
+#include "endian.h"
+#include "logging.h" /* Angel support functions. */
+#include "msgbuild.h"
+#include "sys.h"
+#include "hsys.h" /* Function and structure declarations. */
+#include "hostchan.h"
+
+#define FILEHANDLE int
+
+/* Note: no statics allowed. All globals must be malloc()ed on the heap.
+ The state struct is used for this purpose. See 'hsys.h'. */
+/* This is the message handler function passed to the channel manager in
+ HostSysInit. It is called whenever a message is received. 'buffptr'
+ points to the message body. Functionality is provided by the debugger
+ toolkit. The routine is very loosely based on the HandleSWI routine from
+ armos.c in the armulator source. */
+/* These routines could be tested by providing a simple interface to armsd,
+ and running them in that. */
+
+
+/* taken staight from armulator source */
+#ifdef __riscos
+ extern int _fisatty(FILE *);
+# define isatty_(f) _fisatty(f)
+# define EMFILE -1
+# define EBADF -1
+ int _kernel_escape_seen(void) { return 0 ;}
+#else
+# if defined(_WINDOWS) || defined(_CONSOLE)
+# define isatty_(f) (f == stdin || f == stdout)
+# else
+# ifdef __ZTC__
+# include <io.h>
+# define isatty_(f) isatty((f)->_file)
+# else
+# ifdef macintosh
+# include <ioctl.h>
+# define isatty_(f) (~ioctl((f)->_file,FIOINTERACTIVE,NULL))
+# else
+# define isatty_(f) isatty(fileno(f))
+# endif
+# endif
+# endif
+#endif
+
+/* Set up the state block, filetable and register the C lib callback fn */
+int HostSysInit(const struct Dbg_HostosInterface *hostif, char **cmdline,
+ hsys_state **stateptr)
+{
+ ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage;
+ int i;
+ *stateptr = (hsys_state *)malloc(sizeof(hsys_state));
+
+ if (*stateptr == NULL) return RDIError_OutOfStore;
+
+ (*stateptr)->hostif=hostif;
+ (*stateptr)->last_errno=0;
+ (*stateptr)->OSptr=(OSblock *)malloc(sizeof(OSblock));
+ if ((*stateptr)->OSptr == NULL) return RDIError_OutOfStore;
+ for (i=0; i<UNIQUETEMPS; i++) (*stateptr)->OSptr->TempNames[i]=NULL;
+ for (i=0; i<HSYS_FOPEN_MAX; i++) {
+ (*stateptr)->OSptr->FileTable[i]=NULL;
+ (*stateptr)->OSptr->FileFlags[i]=0;
+ }
+ (*stateptr)->CommandLine=cmdline;
+
+ return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr,
+ *stateptr);
+}
+
+/* Shut down the Clib support, this will probably never get called though */
+int HostSysExit(hsys_state *stateptr)
+{
+ free(stateptr->OSptr);
+ free(stateptr);
+ return RDIError_NoError;
+}
+
+#ifdef DEBUG
+static void DebugCheckNullTermString(char *prefix, bool nl,
+ unsigned int len, unsigned char *strp)
+{
+ printf("%s: %d: ", prefix, len);
+ if (strp[len]=='\0')
+ printf("\"%s\"", strp);
+ else
+ printf("NOT NULL TERMINATED");
+ if (nl)
+ printf("\n");
+ else
+ {
+ printf(" ");
+ fflush(stdout);
+ }
+}
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+static char *DebugStrError(int last_errno)
+{
+ if (last_errno < sys_nerr)
+ return sys_errlist[last_errno];
+ else
+ return "NO MSG (errno>sys_nerr)";
+}
+
+static void DebugCheckErr(char *prefix, bool nl, int err, int last_errno)
+{
+ printf("\t%s: returned ", prefix);
+ if (err == 0)
+ printf("okay");
+ else
+ printf("%d, errno = %d \"%s\"", err, last_errno,
+ DebugStrError(last_errno));
+ if (nl)
+ printf("\n");
+ else
+ {
+ printf(" ");
+ fflush(stdout);
+ }
+}
+
+static void DebugCheckNonNull(char *prefix, bool nl,
+ void *handle, int last_errno)
+{
+ printf("\t%s: returned ", prefix);
+ if (handle != NULL)
+ printf("okay [%08x]", (unsigned int)handle);
+ else
+ printf("NULL, errno = %d \"%s\"", last_errno,
+ DebugStrError(last_errno));
+ if (nl)
+ printf("\n");
+ else
+ {
+ printf(" ");
+ fflush(stdout);
+ }
+}
+
+#define DebugPrintF(c) printf c;
+
+#else
+
+#define DebugCheckNullTermString(p, n, l, s) ((void)(0))
+#define DebugCheckErr(p, n, e, l) ((void)(0))
+#define DebugCheckNonNull(p, n, h, l) ((void)(0))
+#define DebugPrintF(c) ((void)(0))
+
+#endif /* ifdef DEBUG ... else */
+
+static FILE *hsysGetRealFileHandle(hsys_state *stateptr, int fh, char *flags)
+{
+ FILE *file_p = NULL;
+
+ if (fh < 0 || fh >= HSYS_FOPEN_MAX)
+ {
+ stateptr->last_errno = EBADF;
+ DebugPrintF(("\tfh %d out-of-bounds!\n", fh));
+ return NULL;
+ }
+ else
+ {
+ file_p = stateptr->OSptr->FileTable[fh];
+ if (file_p != NULL) {
+ if (flags != NULL)
+ *flags = stateptr->OSptr->FileFlags[fh];
+ }
+ else {
+ stateptr->last_errno = EBADF;
+ DebugPrintF(("\tFileTable[%d] is NULL\n", fh));
+ }
+
+ return file_p;
+ }
+}
+
+int HandleSysMessage(Packet *packet, hsys_state *stateptr)
+{
+ unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0;
+ long posn, fl;
+ char character;
+ int err;
+
+ /* Note: We must not free the buffer passed in as the callback handler */
+ /* expects to do this. Freeing any other buffers we have malloced */
+ /* ourselves is acceptable */
+
+ unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16;
+ /* buffp points to the parameters*/
+ /* the invidual messages, excluding*/
+ /* standard SYS fields (debugID, */
+ /* osinfo and reasoncode) */
+ unsigned char *buffhead = (unsigned char *)(packet->pk_buffer);
+
+ int DebugID, OSInfo1, OSInfo2, count;
+
+ const char* fmode[] = {"r","rb","r+","r+b",
+ "w","wb","w+","w+b",
+ "a","ab","a+","a+b",
+ "r","r","r","r"} /* last 4 are illegal */ ;
+
+ FILEHANDLE fh; /* fh is used as an index to the real file handle
+ * in OSptr */
+ FILE *fhreal;
+ unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code,
+ &DebugID, &OSInfo1, &OSInfo2);
+ /* Extract reason code from buffer. */
+ reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */
+ /* DebugInfo fields. Will want to do some */
+ /* sort of validation on this later. */
+
+ switch(reason_code)
+ {
+
+ case CL_WriteC: /* Write a character to the terminal. */
+ /* byte data -> word status */
+ {
+#ifdef DEBUG
+ int c = (int)(*buffp);
+ printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.');
+#endif
+ stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp));
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError);
+ }
+
+ case CL_Write0: /* Write a null terminated string to the terminal. */
+ {
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4);
+ stateptr->hostif->write(stateptr->hostif->hostosarg,
+ (char *) buffp+4, len);
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID,
+ OSInfo1, OSInfo2, NoError);
+ }
+
+ case CL_ReadC: /* Read a byte from the terminal */
+ {
+ DebugPrintF(("CL_ReadC: "));
+ DevSW_FreePacket(packet);
+
+ character = stateptr->hostif->readc(stateptr->hostif->hostosarg);
+ DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character,
+ isprint(character) ? character : '.'));
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, character);
+ }
+
+ case CL_System: /* Pass NULL terminated string to the hosts command
+ * interpreter. As it is nULL terminated we dont need
+ * the length
+ */
+ {
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_System", TRUE, len, buffp+4);
+
+ err = system((char *)buffp+4); /* Use the string in the buffer */
+ stateptr->last_errno = errno;
+ DebugCheckErr("system", TRUE, err, stateptr->last_errno);
+
+ err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, err);
+ DevSW_FreePacket(packet);
+ return err;
+ }
+
+ case CL_GetCmdLine: /* Returns the command line used to call the program */
+ {
+ /* Note: we reuse the packet here, this may not always be desirable */
+ /* /* TODO: Use long buffers if possible */
+ DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine)));
+
+ if (buffhead!=NULL) {
+ len = strlen(*(stateptr->CommandLine));
+ if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24;
+ packet->pk_length = len + msgbuild(BUFFERDATA(buffhead),
+ "%w%w%w%w%w%w", CL_GetCmdLine|HtoT,
+ DebugID, OSInfo1, OSInfo2,
+ NoError, len);
+ strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine),
+ len);
+
+ Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
+ return 0;
+ }
+ else return -1;
+ }
+
+ case CL_Clock: /* Return the number of centiseconds since the support */
+ /* code started executing */
+ {
+ time_t retTime = time(NULL);
+ if (retTime == (time_t)-1)
+ stateptr->last_errno = errno;
+ else
+ retTime *=100;
+
+ DebugPrintF(("CL_Clock: %lu\n", retTime));
+ DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
+ stateptr->last_errno);
+
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, retTime);
+ }
+
+ case CL_Time: /* return time, in seconds since the start of 1970 */
+ {
+ time_t retTime = time(NULL);
+ if (retTime == (time_t)-1)
+ stateptr->last_errno = errno;
+
+ DebugPrintF(("CL_Time: %lu\n", retTime));
+ DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
+ stateptr->last_errno);
+
+ DevSW_FreePacket(packet);
+ return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT,
+ DebugID, OSInfo1, OSInfo2, NoError, retTime);
+ }
+
+ case CL_Remove: /* delete named in the null terminated string */
+ {
+ /* Removing an open file will cause problems but once again
+ * its not our problem, likely result is a tangled FileTable */
+ /* As the filename is passed with a null terminator we can use it
+ * straight out of the buffer without copying it.*/
+
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4);
+
+ err=remove((char *)buffp+4);
+ stateptr->last_errno = errno;
+ DevSW_FreePacket(packet);
+ DebugCheckErr("remove", TRUE, err, stateptr->last_errno);
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT,
+ DebugID, OSInfo1, OSInfo2, err?-1:NoError);
+ }
+
+ case CL_Rename: /* rename file */
+ {
+ /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
+ * return(byte status)
+ */
+ unsigned int len2;
+
+ unpack_message(buffp, "%w", &len);
+ DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4);
+ unpack_message(buffp+5+len, "%w", &len2);
+ DebugCheckNullTermString("to", TRUE, len2, buffp+9+len);
+
+ /* Both names are passed with null terminators so we can use them
+ * directly from the buffer. */
+ err = rename((char *)buffp+4, (char *)buffp+9+len);
+ stateptr->last_errno = errno;
+ DebugCheckErr("rename", TRUE, err, stateptr->last_errno);
+ DevSW_FreePacket(packet);
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT,
+ DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1);
+ }
+
+ case CL_Open: /* open the file */
+ {
+ /* Open(word nbytes, bytes name, byte mode)
+ * return(word handle)
+ */
+ unpack_message(buffp, "%w", &len);
+ /* get the open mode */
+ unpack_message((buffp)+4+len+1, "%w", &mode);
+ DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4);
+ DebugPrintF(("mode: %d\n", mode));
+
+ /* do some checking on the file first? */
+ /* check if its a tty */
+ if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) {
+ /* opening tty "r" */
+ fhreal = stdin;
+ stateptr->last_errno = errno;
+ DebugPrintF(("\tstdin "));
+ }
+ else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) {
+ /* opening tty "w" */
+ fhreal = stdout;
+ stateptr->last_errno = errno;
+ DebugPrintF(("\tstdout "));
+ }
+ else
+ {
+ fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]);
+ stateptr->last_errno = errno;
+ DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno);
+ }
+ DevSW_FreePacket(packet);
+
+ c = NONHANDLE;
+ if (fhreal != NULL) {
+ /* update filetable */
+ for (c=3; c < HSYS_FOPEN_MAX; c++) {
+ /* allow for stdin, stdout, stderr (!!! WHY? MJG) */
+ if (stateptr->OSptr->FileTable[c] == NULL) {
+ stateptr->OSptr->FileTable[c]= fhreal;
+ stateptr->OSptr->FileFlags[c]= mode & 1;
+ DebugPrintF(("fh: %d\n", c));
+ break;
+ }
+ else if (c == HSYS_FOPEN_MAX) {
+ /* no filehandles free */
+ DebugPrintF(("no free fh: %d\n", c));
+ stateptr->last_errno = EMFILE;
+ }
+ }
+ }
+ else {
+ /* c = NULL;*/
+ DebugPrintF(("error fh: %d\n", c));
+ }
+ (void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT,
+ DebugID, OSInfo1, OSInfo2, c);
+ return 0;
+ }
+
+ case CL_Close: /* close the file pointed to by the filehandle */
+ {
+ unpack_message(buffp, "%w", &fh);
+ DebugPrintF(("CL_Close: fh %d\n", fh));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ err = -1;
+ else {
+ if (fhreal == stdin || fhreal == stdout || fhreal == stderr) {
+ stateptr->last_errno = errno;
+ DebugPrintF(("\tskipping close of std*\n"));
+ err = 0;
+ }
+ else {
+ err = fclose(fhreal);
+ if (err == 0)
+ stateptr->OSptr->FileTable[fh]=NULL;
+ stateptr->last_errno = errno;
+ DebugCheckErr("fclose", TRUE, err, stateptr->last_errno);
+ }
+ }
+ return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID,
+ OSInfo1, OSInfo2, err);
+ }
+
+ case CL_Write:
+ {
+ /* Write(word handle, word nbtotal, word nbytes, bytes data)
+ * return(word nbytes)
+ * WriteX(word nbytes, bytes data)
+ * return(word nbytes)
+ */
+ unsigned char *rwdata = NULL, *rwhead = NULL;
+ unsigned char *write_source = NULL;
+ char flags;
+ FILE *fhreal;
+ unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
+
+ err = -1; /* err == 0 is fwrite() error indication */
+ unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes);
+ DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
+ fh, nbtotal, nbytes));
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
+ nbtogo = nbtotal;
+
+ /* deal with the file handle */
+ if (fhreal == NULL)
+ err = 0;
+ else {
+ if (flags & READOP)
+ fseek(fhreal,0,SEEK_CUR);
+ stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
+
+ nbtogo -= nbytes;
+
+ if (nbtogo > 0) {
+ write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal);
+ if (rwhead == NULL) {
+ fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
+ __LINE__, __FILE__);
+ return -1;
+ }
+ memcpy(rwdata, buffp+12, nbytes);
+ rwdata += nbytes;
+ }
+ else
+ write_source = buffp+12;
+ }
+
+ do {
+ /* at least once!! */
+
+ if (nbtogo == 0 && err != 0) {
+ /* Do the actual write! */
+ if (fhreal == stdout || fhreal == stderr) {
+ stateptr->hostif->write(stateptr->hostif->hostosarg,
+ (char *)write_source, nbtotal);
+ }
+ else
+ err = fwrite(write_source, 1, nbtotal, fhreal);
+ stateptr->last_errno = errno;
+ DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
+ }
+
+ DevSW_FreePacket(packet);
+ if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT,
+ DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo))
+ {
+ fprintf(stderr, "COULD NOT REPLY at line %d in %s\n",
+ __LINE__, __FILE__);
+ if (rwhead != NULL)
+ free(rwhead);
+ return -1;
+ }
+
+ if (nbtogo == 0 || err == 0) {
+ DebugPrintF(("\twrite complete - returning\n"));
+ if (rwhead != NULL)
+ free(rwhead);
+ return 0;
+ }
+ else {
+ /* await extension */
+ ack_reason = CL_WriteX;
+
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (packet == NULL)
+ {
+ fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
+ __LINE__, __FILE__);
+ if (rwhead != NULL)
+ free(rwhead);
+ return -1;
+ }
+ Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
+ Adp_ChannelRead(CI_CLIB, &packet);
+ Adp_ChannelRegisterRead(CI_CLIB,
+ (ChannelCallback)HandleSysMessage,
+ stateptr);
+
+ buffhead = packet->pk_buffer;
+ unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code,
+ &DebugID, &OSInfo1, &OSInfo2, &nbytes);
+ if (reason_code != (CL_WriteX|TtoH)) {
+ DevSW_FreePacket(packet);
+ free(rwhead);
+ fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n",
+ reason_code, __LINE__, __FILE__);
+ return -1;
+ }
+
+ DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes));
+ memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes);
+ rwdata += nbytes;
+ nbtogo -= nbytes;
+ }
+
+ } while (TRUE); /* will return when done */
+ }
+
+ case CL_WriteX: /*
+ * NOTE: if we've got here something has gone wrong
+ * CL_WriteX's should all be picked up within the
+ * CL_Write loop, probably best to return an error here
+ * do this for the moment just so we do actually return
+ */
+ fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n");
+ return -1;
+
+ case CL_Read:
+ {
+ /* Read(word handle, word nbtotal)
+ * return(word nbytes, word nbmore, bytes data)
+ */
+ /* ReadX()
+ * return(word nbytes, word nbmore, bytes data) */
+ unsigned char *rwdata, *rwhead;
+ int gotlen;
+ unsigned int max_data_in_buffer=Armsd_BufferSize-28;
+ char flags;
+ FILE *fhreal;
+ unsigned int nbleft = 0, reason = CL_Read;
+
+ err = NoError;
+
+ unpack_message(buffp, "%w%w", &fh, &nbtotal);
+ DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal));
+
+ rwdata = rwhead = (unsigned char *)malloc(nbtotal);
+ if (rwdata == NULL) {
+ fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
+ __LINE__, __FILE__);
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+
+ /* perform the actual read */
+ fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
+ if (fhreal == NULL)
+ {
+ /* bad file handle */
+ err = -1;
+ nbytes = 0;
+ gotlen = 0;
+ }
+ else
+ {
+ if (flags & WRITEOP)
+ fseek(fhreal,0,SEEK_CUR);
+ stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
+ if (isatty_(fhreal)) {
+ /* reading from a tty, so do some nasty stuff, reading into rwdata */
+ if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata,
+ nbtotal) != 0)
+ gotlen = strlen((char *)rwdata);
+ else
+ gotlen = 0;
+ stateptr->last_errno = errno;
+ DebugPrintF(("ttyread %d\n", gotlen));
+ }
+ else {
+ /* not a tty, reading from a real file */
+ gotlen = fread(rwdata, 1, nbtotal, fhreal);
+ stateptr->last_errno = errno;
+ DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno);
+ DebugPrintF(("(%d)\n", gotlen));
+ }
+ }
+
+ nbtogo = gotlen;
+
+ do {
+ /* at least once */
+
+ if ((unsigned int) nbtogo <= max_data_in_buffer)
+ nbytes = nbtogo;
+ else
+ nbytes = max_data_in_buffer;
+ nbtogo -= nbytes;
+
+ /* last ReadX needs subtle adjustment to returned nbtogo */
+ if (nbtogo == 0 && err == NoError && reason == CL_ReadX)
+ nbleft = nbtotal - gotlen;
+ else
+ nbleft = nbtogo;
+
+ count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w",
+ reason|HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, err, nbytes, nbleft);
+
+ if (err == NoError) {
+ /* copy data into buffptr */
+ memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes);
+ rwdata += nbytes;
+ count += nbytes;
+ }
+
+ DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n",
+ err, nbytes, nbtogo));
+
+ packet->pk_length = count;
+ Adp_ChannelWrite(CI_CLIB, packet);
+
+ if (nbtogo == 0 || err != NoError) {
+ /* done */
+ free(rwhead);
+ return 0;
+ }
+ else {
+ /* await extension */
+ reason = CL_ReadX;
+
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (packet == NULL) {
+ fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
+ __LINE__, __FILE__);
+ free(rwhead);
+ return -1;
+ }
+ Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
+ Adp_ChannelRead(CI_CLIB, &packet);
+ Adp_ChannelRegisterRead(CI_CLIB,
+ (ChannelCallback)HandleSysMessage,
+ stateptr);
+ buffhead = packet->pk_buffer;
+ unpack_message(BUFFERDATA(buffhead),"%w", &reason_code);
+ if (reason_code != (CL_ReadX|TtoH)) {
+ fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n",
+ reason_code, __LINE__, __FILE__);
+ DevSW_FreePacket(packet);
+ free(rwdata);
+ return -1;
+ }
+ }
+
+ } while (TRUE); /* will return above on error or when done */
+ }
+
+ case CL_ReadX: /* If we're here something has probably gone wrong */
+ fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n");
+ return -1;
+
+ case CL_Seek:
+ {
+ unpack_message(buffp, "%w%w", &fh, &posn);
+ DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ err = -1;
+ else {
+ err = fseek(fhreal, posn, SEEK_SET);
+ stateptr->last_errno = errno;
+ DebugCheckErr("fseek", TRUE, err, stateptr->last_errno);
+ }
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT,
+ DebugID, OSInfo1, OSInfo2, err);
+ }
+
+ case CL_Flen:
+ {
+ unpack_message(buffp, "%w", &fh);
+ DebugPrintF(("CL_Flen: fh %d ", fh));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ fl = -1;
+ else {
+ posn = ftell(fhreal);
+ if (fseek(fhreal, 0L, SEEK_END) < 0) {
+ fl=-1;
+ }
+ else {
+ fl = ftell(fhreal);
+ fseek(fhreal, posn, SEEK_SET);
+ }
+ stateptr->last_errno = errno;
+ }
+ DebugPrintF(("returning len %ld\n", fl));
+ return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1,
+ OSInfo2, fl);
+ }
+
+ case CL_IsTTY:
+ {
+ int ttyOrNot;
+ unpack_message(buffp, "%w", &fh);
+ DebugPrintF(("CL_IsTTY: fh %d ", fh));
+ DevSW_FreePacket(packet);
+
+ fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
+ if (fhreal == NULL)
+ ttyOrNot = FALSE;
+ else {
+ ttyOrNot = isatty_(fhreal);
+ stateptr->last_errno = errno;
+ }
+ DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)"));
+
+ return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT,
+ DebugID, OSInfo1, OSInfo2, ttyOrNot);
+ }
+
+ case CL_TmpNam:
+ {
+ char *name;
+ unsigned int tnamelen, TargetID;
+ unpack_message(buffp, "%w%w", &tnamelen, &TargetID);
+ DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ",
+ tnamelen, TargetID));
+ DevSW_FreePacket(packet);
+
+ TargetID = TargetID & 0xFF;
+ if (stateptr->OSptr->TempNames[TargetID] == NULL) {
+ if ((stateptr->OSptr->TempNames[TargetID] =
+ (char *)malloc(L_tmpnam)) == NULL)
+ {
+ fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
+ __LINE__, __FILE__);
+ return -1;
+ }
+ tmpnam(stateptr->OSptr->TempNames[TargetID]);
+ }
+ name = stateptr->OSptr->TempNames[TargetID];
+ len = strlen(name) + 1;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (packet == NULL)
+ {
+ fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
+ __LINE__, __FILE__);
+ return -1;
+ }
+ buffhead = packet->pk_buffer;
+ if (len > tnamelen) {
+ DebugPrintF(("TMPNAME TOO LONG!\n"));
+ count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w",
+ CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1);
+ }
+ else {
+ DebugPrintF(("returning \"%s\"\n", name));
+ count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT,
+ DebugID, OSInfo1, OSInfo2, 0, len);
+ strcpy((char *)BUFFERDATA(buffhead)+count, name);
+ count +=len+1;
+ }
+ packet->pk_length = count;
+ Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
+ return 0;
+ }
+
+ case CL_Unrecognised:
+ DebugPrintF(("CL_Unrecognised!!\n"));
+ return 0;
+
+ default:
+ fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code);
+ break;
+/* Need some sort of error handling here. */
+/* A call to CL_Unrecognised should suffice */
+ }
+ return -1; /* Stop a potential compiler warning */
+}
+
+#ifdef COMPILING_ON_WINDOWS
+
+#include <windows.h>
+
+extern HWND hwndParent;
+
+void panic(const char *format, ...)
+{
+ char buf[2048];
+ va_list args;
+
+ Adp_CloseDevice();
+
+ va_start(args, format);
+ vsprintf(buf, format, args);
+
+ MessageBox(hwndParent, (LPCTSTR)buf, (LPCTSTR)"Fatal Error:", MB_OK);
+
+ /* SJ - Not the proper way to shutdown the app */
+ exit(EXIT_FAILURE);
+
+/*
+ if (hwndParent != NULL)
+ SendMessage(hwndParent, WM_QUIT, 0, 0);
+*/
+
+ va_end(args);
+}
+
+#else
+
+void panic(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ fprintf(stderr, "Fatal error: ");
+ vfprintf(stderr, format, args);
+ fprintf(stderr,"\n");
+
+ exit(EXIT_FAILURE);
+}
+
+#endif
+
+/* EOF hsys.c */
diff --git a/gdb/rdi-share/hsys.h b/gdb/rdi-share/hsys.h
new file mode 100644
index 0000000..7f63d01
--- /dev/null
+++ b/gdb/rdi-share/hsys.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * Host C library support header file.
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+
+#ifndef angsd_hsys_h
+#define angsd_hsys_h
+
+#define HSYS_FOPEN_MAX 256
+#define NONHANDLE -1
+#define UNIQUETEMPS 256
+
+#include "dbg_hif.h"
+#include "hostchan.h"
+
+typedef struct {
+ FILE *FileTable[HSYS_FOPEN_MAX] ;
+ char FileFlags[HSYS_FOPEN_MAX] ;
+ char *TempNames[UNIQUETEMPS];
+} OSblock;
+
+#define NOOP 0
+#define BINARY 1
+#define READOP 2
+#define WRITEOP 4
+
+typedef struct {
+ const struct Dbg_HostosInterface *hostif; /* Interface to debug toolkit. */
+ int last_errno; /* Number of the last error. */
+ OSblock *OSptr;
+ char **CommandLine ; /* Ptr to cmd line d`string held by ardi.c */
+} hsys_state;
+
+/*
+ * Function: HostSysInit
+ * Purpose: Set up the state block, filetable and register the and C lib
+ * callback fn
+ *
+ * Params:
+ * Input: hostif, the host interface from the debug toolbox
+ * cmdline, the command line used to call the image
+ * state, the status block for the C lib
+ *
+ * Returns:
+ * OK: an RDIError_* valuee
+ */
+extern int HostSysInit(
+ const struct Dbg_HostosInterface *hostif, char **cmdline, hsys_state **state
+);
+
+/*
+ * Function: HostSysExit
+ * Purpose: Close down the host side C library support
+ *
+ * Params:
+ * Input: hstate, the status block for the C lib
+ *
+ * Returns: an RDIError_* valuee
+ */
+extern int HostSysExit(hsys_state *hstate);
+
+/*
+ * Function: HandleSysMessage
+ * Purpose: Handle an incoming C library message as a callback
+ *
+ * Params:
+ * Input: packet is the incoming data packet as described in devsw.h
+ * hstate, the status block for the C lib
+ *
+ * Returns: an RDIError_* valuee
+ */
+extern int HandleSysMessage(Packet *packet, hsys_state* stateptr);
+
+/*
+ * Function: panic
+ * Purpose: Print a fatal error message
+ *
+ * Params:
+ * Input: format printf() style message describing the problem
+ * ... extra arguments for printf().
+ *
+ * Returns: This routine does not return
+ *
+ * Post-conditions: Will have called exit(1);
+ */
+extern void panic(const char *format, ...);
+
+#endif /* ndef angsd_hsys_h */
+
+/* EOF hsys.h */
diff --git a/gdb/rdi-share/logging.c b/gdb/rdi-share/logging.c
new file mode 100644
index 0000000..79b70ef
--- /dev/null
+++ b/gdb/rdi-share/logging.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * logging.c - methods for logging warnings, errors and trace info
+ *
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+
+#ifdef TARGET
+# include "angel.h"
+# include "devconf.h"
+#else
+# include "host.h"
+#endif
+
+#include "logging.h" /* Header file for this source code */
+
+#ifndef UNUSED
+# define UNUSED(x) ((x)=(x))
+#endif
+
+/*
+ * __rt_warning
+ * ------------
+ * This routine is provided as a standard method of generating
+ * run-time system warnings. The actual action taken by this code can
+ * be board or target application specific, e.g. internal logging,
+ * debug message, etc.
+ */
+
+#ifdef DEBUG
+
+# ifdef DEBUG_METHOD
+
+# define STRINGIFY2(x) #x
+# define STRINGIFY(x) STRINGIFY2(x)
+# define DEBUG_METHOD_HEADER STRINGIFY(DEBUG_METHOD##.h)
+
+# include DEBUG_METHOD_HEADER
+
+# define METHOD_EXPAND_2(m, p, c) m##p(c)
+# define METHOD_EXPAND(m, p, c) METHOD_EXPAND_2(m, p, c)
+
+# define CHAROUT(c) METHOD_EXPAND(DEBUG_METHOD, _PutChar, (c))
+# define PRE_DEBUG(l) METHOD_EXPAND(DEBUG_METHOD, _PreWarn, (l))
+# define POST_DEBUG(n) METHOD_EXPAND(DEBUG_METHOD, _PostWarn, (n))
+
+# else
+# error Must define DEBUG_METHOD
+# endif
+
+#endif /* def DEBUG */
+
+/*
+ * the guts of __rt_warning
+ */
+
+#pragma no_check_stack
+#ifdef DEBUG
+
+static const char hextab[] = "0123456789ABCDEF";
+
+/*
+ * If debugging, then we break va_warn into sub-functions which
+ * allow us to get an easy breakpoint on the formatted string
+ */
+static int va_warn0(char *format, va_list args)
+{
+ int len = 0;
+
+ while ((format != NULL) && (*format != '\0'))
+ {
+ if (*format == '%')
+ {
+ char fch = *(++format); /* get format character (skipping '%') */
+ int ival; /* holder for integer arguments */
+ char *string; /* holder for string arguments */
+ int width = 0; /* No field width by default */
+ int padzero = FALSE; /* By default we pad with spaces */
+
+ /*
+ * Check if the format has a width specified. NOTE: We do
+ * not use the "isdigit" function here, since it will
+ * require run-time support. The current ARM Ltd header
+ * defines "isdigit" as a macro, that uses a fixed
+ * character description table.
+ */
+ if ((fch >= '0') && (fch <= '9'))
+ {
+ if (fch == '0')
+ {
+ /* Leading zeroes padding */
+ padzero = TRUE;
+ fch = *(++format);
+ }
+
+ while ((fch >= '0') && (fch <= '9'))
+ {
+ width = ((width * 10) + (fch - '0'));
+ fch = *(++format);
+ }
+ }
+
+ if (fch == 'l')
+ /* skip 'l' in "%lx", etc. */
+ fch = *(++format);
+
+ switch (fch)
+ {
+ case 'c':
+ /* char */
+ ival = va_arg(args, int);
+ CHAROUT((char)ival);
+ len++;
+ break;
+
+ case 'x':
+ case 'X':
+ {
+ /* hexadecimal */
+ unsigned int uval = va_arg(args, unsigned int);
+ int loop;
+
+ UNUSED(uval);
+
+ if ((width == 0) || (width > 8))
+ width = 8;
+
+ for(loop = (width * 4); (loop != 0); loop -= 4)
+ {
+ CHAROUT(hextab[(uval >> (loop - 4)) & 0xF]);
+ len++;
+ }
+ }
+
+ break;
+
+ case 'd':
+ /* decimal */
+ ival = va_arg(args, int);
+
+ if (ival < 0)
+ {
+ ival = -ival;
+ CHAROUT('-');
+ len++;
+ }
+
+ if (ival == 0)
+ {
+ CHAROUT('0');
+ len++;
+ }
+ else
+ {
+ /*
+ * The simplest method of displaying numbers is
+ * to provide a small recursive routine, that
+ * nests until the most-significant digit is
+ * reached, and then falls back out displaying
+ * individual digits. However, we want to avoid
+ * using recursive code within the lo-level
+ * parts of Angel (to minimise the stack
+ * usage). The following number conversion is a
+ * non-recursive solution.
+ */
+ char buffer[16]; /* stack space used to hold number */
+ int count = 0; /* pointer into buffer */
+
+ /*
+ * Place the conversion into the buffer in
+ * reverse order:
+ */
+ while (ival != 0)
+ {
+ buffer[count++] = ('0' + ((unsigned int)ival % 10));
+ ival = ((unsigned int)ival / 10);
+ }
+
+ /*
+ * Check if we are placing the data in a
+ * fixed width field:
+ */
+ if (width != 0)
+ {
+ width -= count;
+
+ for (; (width != 0); width--)
+ {
+ CHAROUT(padzero ? '0': ' ');
+ len++;
+ }
+ }
+
+ /* then display the buffer in reverse order */
+ for (; (count != 0); count--)
+ {
+ CHAROUT(buffer[count - 1]);
+ len++;
+ }
+ }
+
+ break;
+
+ case 's':
+ /* string */
+ string = va_arg(args, char *);
+
+ /* we only need this test once */
+ if (string != NULL)
+ /* whilst we check this for every character */
+ while (*string)
+ {
+ CHAROUT(*string);
+ len++;
+ string++;
+
+ /*
+ * NOTE: We do not use "*string++" as the macro
+ * parameter, since we do not know how many times
+ *the parameter may be expanded within the macro.
+ */
+ }
+
+ break;
+
+ case '\0':
+ /*
+ * string terminated by '%' character, bodge things
+ * to prepare for default "format++" below
+ */
+ format--;
+
+ break;
+
+ default:
+ /* just display the character */
+ CHAROUT(*format);
+ len++;
+
+ break;
+ }
+
+ format++; /* step over format character */
+ }
+ else
+ {
+ CHAROUT(*format);
+ len++;
+ format++;
+ }
+ }
+ return len;
+}
+
+/*
+ * this routine is simply here as a good breakpoint for dumping msg -
+ * can be used by DEBUG_METHOD macros or functions, if required.
+ */
+# ifdef DEBUG_NEED_VA_WARN1
+static void va_warn1(int len, char *msg)
+{
+ UNUSED(len); UNUSED(msg);
+}
+# endif
+
+void va_warn(WarnLevel level, char *format, va_list args)
+{
+ int len;
+
+ if ( PRE_DEBUG( level ) )
+ {
+ len = va_warn0(format, args);
+ POST_DEBUG( len );
+ }
+}
+
+#else /* ndef DEBUG */
+
+void va_warn(WarnLevel level, char *format, va_list args)
+{
+ UNUSED(level); UNUSED(format); UNUSED(args);
+}
+
+#endif /* ... else ndef(DEBUG) ... */
+#pragma check_stack
+
+#pragma no_check_stack
+void __rt_warning(char *format, ...)
+{
+ va_list args;
+
+ /*
+ * For a multi-threaded system we should provide a lock at this point
+ * to ensure that the warning messages are sequenced properly.
+ */
+
+ va_start(args, format);
+ va_warn(WL_WARN, format, args);
+ va_end(args);
+
+ return;
+}
+#pragma check_stack
+
+#ifdef TARGET
+
+#pragma no_check_stack
+void __rt_uninterruptable_loop( void ); /* in suppasm.s */
+
+void __rt_error(char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+
+ /* Display warning message */
+ va_warn(WL_ERROR, format, args);
+
+ __rt_uninterruptable_loop();
+
+ va_end(args);
+ return;
+}
+#pragma check_stack
+
+#endif /* def TARGET */
+
+#ifdef DO_TRACE
+
+static bool trace_on = FALSE; /* must be set true in debugger if req'd */
+
+#pragma no_check_stack
+void __rt_trace(char *format, ...)
+{
+ va_list args;
+
+ /*
+ * For a multi-threaded system we should provide a lock at this point
+ * to ensure that the warning messages are sequenced properly.
+ */
+
+ if (trace_on)
+ {
+ va_start(args, format);
+ va_warn(WL_TRACE, format, args);
+ va_end(args);
+ }
+
+ return;
+}
+#pragma check_stack
+
+#endif /* def DO_TRACE */
+
+
+/* EOF logging.c */
diff --git a/gdb/rdi-share/logging.h b/gdb/rdi-share/logging.h
new file mode 100644
index 0000000..97bf902
--- /dev/null
+++ b/gdb/rdi-share/logging.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * logging.h - methods for logging warnings, errors and trace info
+ */
+
+#ifndef angel_logging_h
+#define angel_logging_h
+
+#include <stdarg.h>
+
+/*
+ * __rt_warning
+ * ------------
+ * Provides a standard method of generating run-time system
+ * warnings. The actual action taken by this code can be board or
+ * target application specific, e.g. internal logging, debug message,
+ * etc.
+ */
+extern void __rt_warning(char *format, ...);
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * __rt_error
+ * ----------
+ * Raise an internal Angel error. The parameters are passed directly
+ * to "__rt_warning" for display, and the code then raises a debugger
+ * event and stops the target processing.
+ */
+extern void __rt_error(char *format, ...);
+
+/*
+ * Some macros for debugging and warning messages
+ */
+
+typedef enum WarnLevel {
+ WL_TRACE,
+ WL_WARN,
+ WL_ERROR
+} WarnLevel;
+
+void va_warn(WarnLevel level, char *format, va_list args);
+
+#ifdef _WINGDI_
+/* stupidity in MSVC <wingdi.h> (in <windows.h> in <winsock.h>) */
+# undef ERROR
+#endif
+
+#ifndef ERROR
+# define ERROR_FORMAT "Error \"%s\" in %s at line %d\n"
+# define ERROR(e) __rt_error(ERROR_FORMAT, (e), __FILE__, __LINE__)
+#endif
+
+#ifndef ASSERT
+# ifdef ASSERTIONS_ENABLED
+# define ASSERT(x, y) ((x) ? (void)(0) : ERROR((y)))
+# else
+# define ASSERT(x, y) ((void)(0))
+# endif
+#endif
+
+#ifndef WARN
+# ifdef ASSERTIONS_ENABLED
+# define WARN_FORMAT "Warning \"%s\" in %s at line %d\n"
+# define WARN(w) __rt_warning(WARN_FORMAT, (w), __FILE__, __LINE__)
+# else
+# define WARN(w) ((void)(0))
+# endif
+#endif
+
+
+#ifdef NO_INFO_MESSAGES
+# define __rt_info (void)
+# ifndef INFO
+# define INFO(w)
+# endif
+#else
+# define __rt_info __rt_warning
+# ifndef INFO
+# ifdef DEBUG
+# define INFO(w) __rt_warning("%s\n", (w))
+# else
+# define INFO(w) ((void)(0))
+# endif
+# endif
+#endif
+
+
+#if defined(DEBUG) && !defined(NO_IDLE_CHITCHAT)
+# ifndef DO_TRACE
+# define DO_TRACE (1)
+# endif
+#endif
+
+#ifdef DO_TRACE
+extern void __rt_trace(char *format, ...);
+#endif
+
+#ifndef TRACE
+# ifdef DO_TRACE
+# define TRACE(w) __rt_trace("%s ", (w))
+# else
+# define TRACE(w) ((void)(0))
+# endif
+#endif
+
+#endif /* ndef angel_logging_h */
+
+/* EOF logging.h */
diff --git a/gdb/rdi-share/msgbuild.c b/gdb/rdi-share/msgbuild.c
new file mode 100644
index 0000000..e2db2cc
--- /dev/null
+++ b/gdb/rdi-share/msgbuild.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * msgbuild.c - utilities for assembling and interpreting ADP messages
+ *
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+
+#ifdef TARGET
+# include "angel.h"
+# include "devconf.h"
+#else
+# include "host.h"
+# include "hostchan.h"
+#endif
+
+#include "channels.h"
+#include "buffers.h"
+#include "endian.h" /* Endianness support macros */
+#include "msgbuild.h" /* Header file for this source code */
+
+#ifndef UNUSED
+# define UNUSED(x) ((x)=(x))
+#endif
+
+#ifndef TARGET
+
+extern unsigned int Armsd_BufferSize;
+
+#endif /* ndef TARGET */
+
+
+unsigned int vmsgbuild(unsigned char *buffer, const char *format, va_list args)
+{
+ unsigned int blen = 0;
+ int ch;
+
+ /* Step through the format string */
+ while ((ch = *format++) != '\0')
+ {
+ if (ch != '%')
+ {
+ if (buffer != NULL)
+ *buffer++ = (unsigned char)ch;
+
+ blen++;
+ }
+ else
+ {
+ switch (ch = *format++)
+ {
+ case 'w':
+ case 'W':
+ /* 32bit pointer */
+ case 'p':
+ case 'P':
+ {
+ /* 32bit word / 32bit pointer */
+ unsigned int na = va_arg(args, unsigned int);
+
+ if (buffer != NULL)
+ {
+ PUT32LE(buffer, na);
+ buffer += sizeof(unsigned int);
+ }
+
+ blen += sizeof(unsigned int);
+
+ break;
+ }
+
+ case 'h':
+ case 'H':
+ {
+ /* 16bit value */
+ unsigned int na = va_arg(args, unsigned int);
+
+ if (buffer != NULL)
+ {
+ PUT16LE(buffer, na);
+ buffer += sizeof(unsigned short);
+ }
+
+ blen += sizeof(unsigned short);
+
+ break;
+ }
+
+ case 'c':
+ case 'C':
+ case 'b':
+ case 'B':
+ /* 8bit character / 8bit byte */
+ ch = va_arg(args, int);
+
+ /*
+ * XXX
+ *
+ * fall through to the normal character processing
+ */
+
+ case '%':
+ default:
+ /* normal '%' character, or a different normal character */
+ if (buffer != NULL)
+ *buffer++ = (unsigned char)ch;
+
+ blen++;
+ break;
+ }
+ }
+ }
+
+ return blen;
+}
+
+/*
+ * msgbuild
+ * --------
+ * Simple routine to aid in construction of Angel messages. See the
+ * "msgbuild.h" header file for a detailed description of the operation
+ * of this routine.
+ */
+unsigned int msgbuild(unsigned char *buffer, const char *format, ...)
+{
+ va_list args;
+ unsigned int blen;
+
+ va_start(args, format);
+ blen = vmsgbuild(buffer, format, args);
+ va_end(args);
+
+ return blen;
+}
+
+#if !defined(JTAG_ADP_SUPPORTED) && !defined(MSG_UTILS_ONLY)
+/*
+ * This routine allocates a buffer, puts the data supplied as
+ * parameters into the buffer and sends the message. It does *NOT*
+ * wait for a reply.
+ */
+extern int msgsend(ChannelID chan, const char *format,...)
+{
+ unsigned int length;
+ p_Buffer buffer;
+ va_list args;
+# ifndef TARGET
+ Packet *packet;
+
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ buffer = packet->pk_buffer;
+# else
+ buffer = angel_ChannelAllocBuffer(Angel_ChanBuffSize);
+# endif
+
+ if (buffer != NULL)
+ {
+ va_start(args, format);
+
+ length = vmsgbuild(BUFFERDATA(buffer), format, args);
+
+# ifdef TARGET
+ angel_ChannelSend(CH_DEFAULT_DEV, chan, buffer, length);
+# else
+ packet->pk_length = length;
+ Adp_ChannelWrite(chan, packet);
+# endif
+
+ va_end(args);
+ return 0;
+ }
+ else
+ return -1;
+}
+
+#endif /* ndef JTAG_ADP_SUPPORTED && ndef MSG_UTILS_ONLY */
+
+/*
+ * unpack_message
+ * --------------
+ */
+extern unsigned int unpack_message(unsigned char *buffer, const char *format, ...)
+{
+ va_list args;
+ unsigned int blen = 0;
+ int ch;
+ char *chp = NULL;
+
+ va_start(args, format);
+
+ /* Step through the format string. */
+ while ((ch = *format++) != '\0')
+ {
+ if (ch != '%')
+ {
+ if (buffer != NULL)
+ ch = (unsigned char)*buffer++;
+
+ blen++;
+ }
+ else
+ {
+ switch (ch = *format++)
+ {
+ case 'w':
+ case 'W':
+ {
+ /* 32bit word. */
+ unsigned int *nap = va_arg(args, unsigned int*);
+
+ if (buffer != NULL)
+ {
+ *nap = PREAD32(LE, buffer);
+ buffer += sizeof(unsigned int);
+ }
+
+ blen += sizeof(unsigned int);
+
+ break;
+ }
+
+ case 'h':
+ case 'H':
+ {
+ /* 16bit value. */
+ unsigned int *nap = va_arg(args, unsigned int*);
+
+ if (buffer != NULL)
+ {
+ *nap = PREAD16(LE,buffer);
+ buffer += sizeof(unsigned short);
+ }
+
+ blen += sizeof(unsigned short);
+
+ break;
+ }
+
+ case 'c':
+ case 'C':
+ case 'b':
+ case 'B':
+ /* 8-bit character, or 8-bit byte */
+ chp = va_arg(args, char*);
+
+ /*
+ * XXX
+ *
+ * fall through to the normal character processing.
+ */
+
+ case '%':
+ default:
+ /* normal '%' character, or a different normal character */
+ if (buffer != NULL)
+ *chp = (unsigned char)*buffer++;
+
+ blen++;
+
+ break;
+ }
+ }
+ }
+
+ va_end(args);
+ return(blen);
+}
+
+
+/* EOF msgbuild.c */
diff --git a/gdb/rdi-share/msgbuild.h b/gdb/rdi-share/msgbuild.h
new file mode 100644
index 0000000..ac2436c
--- /dev/null
+++ b/gdb/rdi-share/msgbuild.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * msgbuild.h - utilities for assembling and interpreting ADP messages
+ */
+
+#ifndef angel_msgbuild_h
+#define angel_msgbuild_h
+#include <stdarg.h>
+#include "channels.h"
+
+/*
+ * msgbuild
+ * --------
+ * We use a "varargs" function to enable a description of how the
+ * final message should look to be provided. We use a function rather
+ * than in-line macros to keep the size of Angel small.
+ *
+ * The "buffer" pointer is the starting point from where the data will
+ * be written. Note: If a NULL pointer is passed then no data will be
+ * written, but the size information will be returned. This allows
+ * code to call this routine with a NULL "buffer" pointer to ascertain
+ * whether the pointer they are passing contains enough space for the
+ * message being constructed.
+ *
+ * The "format" string should contain sequences of the following
+ * tokens:
+ * %w - insert 32bit word value
+ * %p - insert 32bit target pointer value
+ * %h - insert 16bit value
+ * %b - insert 8bit byte value
+ *
+ * The return parameter is the final byte length of the data written.
+ */
+unsigned int msgbuild(unsigned char *buffer, const char *format, ...);
+unsigned int vmsgbuild(unsigned char *buffer, const char *format,
+ va_list args);
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * msgsend
+ * -------
+ * As for msgbuild except that it allocates a buffer, formats the data as
+ * for msgbuild and transmits the packet. Returns 0 if successful non 0 if ot
+ * fails.
+ * Not for use on cooked channels e.g. debug channels only.
+ */
+extern int msgsend(ChannelID chan, const char *format, ...);
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Unpack_message
+ * --------------
+ * This basically does the opposite of msg_build, it takes a message, and
+ * a scanf type format string (but much cut down functionality) and returns
+ * the arguments in the message.
+ */
+extern unsigned int unpack_message(unsigned char *buffer, const char *format, ...);
+
+#endif /* ndef angel_msgbuild_h */
+
+/* EOF msgbuild.h */
diff --git a/gdb/rdi-share/params.c b/gdb/rdi-share/params.c
new file mode 100644
index 0000000..2c78188
--- /dev/null
+++ b/gdb/rdi-share/params.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Parameter negotiation utility functions
+ */
+
+#include "params.h"
+
+#include "endian.h"
+#include "logging.h"
+
+
+/*
+ * Function: Angel_FindParam
+ * Purpose: find the value of a given parameter from a config.
+ *
+ * see params.h for details
+ */
+bool Angel_FindParam( ADP_Parameter type,
+ const ParameterConfig *config,
+ unsigned int *value )
+{
+ unsigned int i;
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ if ( config->param[i].type == type )
+ {
+ *value = config->param[i].value;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+#if !defined(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
+
+ParameterList *Angel_FindParamList( const ParameterOptions *options,
+ ADP_Parameter type )
+{
+ unsigned int i;
+
+ for ( i = 0; i < options->num_param_lists; ++i )
+ if ( options->param_list[i].type == type )
+ return &options->param_list[i];
+
+ return NULL;
+}
+
+
+#if defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_MatchParams
+ * Purpose: find a configuration from the requested options which is
+ * the best match from the supported options.
+ *
+ * see params.h for details
+ */
+const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
+ const ParameterOptions *supported )
+{
+ static Parameter chosen_params[AP_NUM_PARAMS];
+ static ParameterConfig chosen_config = {
+ AP_NUM_PARAMS,
+ chosen_params
+ };
+ unsigned int i;
+
+ ASSERT( requested != NULL, "requested is NULL" );
+ ASSERT( requested != NULL, "requested is NULL" );
+ ASSERT( supported->num_param_lists <= AP_NUM_PARAMS, "supp_num too big" );
+
+ if ( requested->num_param_lists > supported->num_param_lists )
+ {
+ WARN( "req_num exceeds supp_num" );
+ return NULL;
+ }
+
+ for ( i = 0; i < requested->num_param_lists; ++i )
+ {
+ bool match;
+ unsigned int j;
+
+ const ParameterList *req_list = &requested->param_list[i];
+ ADP_Parameter req_type = req_list->type;
+ const ParameterList *sup_list = Angel_FindParamList(
+ supported, req_type );
+
+ if ( sup_list == NULL )
+ {
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning( "option %x not supported\n", req_type );
+#endif
+ return NULL;
+ }
+
+ for ( j = 0, match = FALSE;
+ (j < req_list->num_options) && !match;
+ ++j
+ )
+ {
+ unsigned int k;
+
+ for ( k = 0;
+ (k < sup_list->num_options) && !match;
+ ++k
+ )
+ {
+ if ( req_list->option[j] == sup_list->option[k] )
+ {
+#ifdef DEBUG
+ __rt_info( "chose value %d for option %x\n",
+ req_list->option[j], req_type );
+#endif
+ match = TRUE;
+ chosen_config.param[i].type = req_type;
+ chosen_config.param[i].value = req_list->option[j];
+ }
+ }
+ }
+
+ if ( !match )
+ {
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning( "no match found for option %x\n", req_type );
+#endif
+ return NULL;
+ }
+ }
+
+ chosen_config.num_parameters = i;
+ INFO( "match succeeded" );
+ return &chosen_config;
+}
+#endif /* defined(TARGET) || defined(TEST_PARAMS) */
+
+
+#if !defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_StoreParam
+ * Purpose: store the value of a given parameter to a config.
+ *
+ * see params.h for details
+ */
+bool Angel_StoreParam( ParameterConfig *config,
+ ADP_Parameter type,
+ unsigned int value )
+{
+ unsigned int i;
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ if ( config->param[i].type == type )
+ {
+ config->param[i].value = value;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
+
+
+#if defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_BuildParamConfigMessage
+ * Purpose: write a parameter config to a buffer in ADP format.
+ *
+ * see params.h for details
+ */
+unsigned int Angel_BuildParamConfigMessage( unsigned char *buffer,
+ const ParameterConfig *config )
+{
+ unsigned char *start = buffer;
+ unsigned int i;
+
+ PUT32LE( buffer, config->num_parameters );
+ buffer += sizeof( word );
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ {
+ PUT32LE( buffer, config->param[i].type );
+ buffer += sizeof( word );
+ PUT32LE( buffer, config->param[i].value );
+ buffer += sizeof( word );
+ }
+
+ return (buffer - start);
+}
+#endif /* defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
+
+
+#if !defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_BuildParamOptionsMessage
+ * Purpose: write a parameter Options to a buffer in ADP format.
+ *
+ * see params.h for details
+ */
+unsigned int Angel_BuildParamOptionsMessage( unsigned char *buffer,
+ const ParameterOptions *options )
+{
+ unsigned char *start = buffer;
+ unsigned int i, j;
+
+ PUT32LE( buffer, options->num_param_lists );
+ buffer += sizeof( word );
+
+ for ( i = 0; i < options->num_param_lists; ++i )
+ {
+ PUT32LE( buffer, options->param_list[i].type );
+ buffer += sizeof( word );
+ PUT32LE( buffer, options->param_list[i].num_options );
+ buffer += sizeof( word );
+ for ( j = 0; j < options->param_list[i].num_options; ++j )
+ {
+ PUT32LE( buffer, options->param_list[i].option[j] );
+ buffer += sizeof( word );
+ }
+ }
+
+ return (buffer - start);
+}
+#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
+
+
+#if !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_ReadParamConfigMessage
+ * Purpose: read a parameter config from a buffer where it is in ADP format.
+ *
+ * see params.h for details
+ */
+bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
+ ParameterConfig *config )
+{
+ unsigned int word;
+ unsigned int i;
+
+ word = GET32LE( buffer );
+ buffer += sizeof( word );
+ if ( word > config->num_parameters )
+ {
+ WARN( "not enough space" );
+ return FALSE;
+ }
+ config->num_parameters = word;
+
+ for ( i = 0; i < config->num_parameters; ++i )
+ {
+ config->param[i].type = (ADP_Parameter)GET32LE( buffer );
+ buffer += sizeof( word );
+ config->param[i].value = GET32LE( buffer );
+ buffer += sizeof( word );
+ }
+
+ return TRUE;
+}
+#endif /* !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
+
+
+#if defined(TARGET) || defined(TEST_PARAMS)
+/*
+ * Function: Angel_ReadParamOptionsMessage
+ * Purpose: read a parameter options block from a buffer
+ * where it is in ADP format.
+ *
+ * see params.h for details
+ */
+bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
+ ParameterOptions *options )
+{
+ unsigned int word;
+ unsigned int i, j;
+
+ word = GET32LE( buffer );
+ buffer += sizeof( word );
+ if ( word > options->num_param_lists )
+ {
+ WARN( "not enough space" );
+ return FALSE;
+ }
+ options->num_param_lists = word;
+
+ for ( i = 0; i < options->num_param_lists; ++i )
+ {
+ ParameterList *list = &options->param_list[i];
+
+ list->type = (ADP_Parameter)GET32LE( buffer );
+ buffer += sizeof( word );
+ word = GET32LE( buffer );
+ buffer += sizeof( word );
+ if ( word > list->num_options )
+ {
+ WARN( "not enough list space" );
+ return FALSE;
+ }
+ list->num_options = word;
+
+ for ( j = 0; j < list->num_options; ++j )
+ {
+ list->option[j] = GET32LE( buffer );
+ buffer += sizeof( word );
+ }
+ }
+
+ return TRUE;
+}
+#endif /* defined(TARGET) || defined(TEST_PARAMS) */
+
+#endif /* !define(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0 */
+
+/* EOF params.c */
diff --git a/gdb/rdi-share/params.h b/gdb/rdi-share/params.h
new file mode 100644
index 0000000..5b0757b
--- /dev/null
+++ b/gdb/rdi-share/params.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Parameter negotiation structures and utilities
+ */
+
+#ifndef angel_params_h
+#define angel_params_h
+
+#include "angel.h"
+#include "adp.h"
+
+#ifndef TARGET
+# include "host.h"
+#endif
+
+/* A single parameter, with tag */
+typedef struct Parameter {
+ ADP_Parameter type;
+ unsigned int value;
+} Parameter;
+
+/* A list of parameter values, with tag */
+typedef struct ParameterList {
+ ADP_Parameter type;
+ unsigned int num_options;
+ unsigned int *option; /* points to array of values */
+} ParameterList;
+
+/* A configuration of one or more parameters */
+typedef struct ParameterConfig {
+ unsigned int num_parameters;
+ Parameter *param; /* pointer to array of Parameters */
+} ParameterConfig;
+
+/* A set of parameter options */
+typedef struct ParameterOptions {
+ unsigned int num_param_lists;
+ ParameterList *param_list; /* pointer to array of ParamLists */
+} ParameterOptions;
+
+/*
+ * Function: Angel_MatchParams
+ * Purpose: find a configuration from the requested options which is
+ * the best match from the supported options.
+ *
+ * Params:
+ * Input: requested The offered set of parameters.
+ * supported The supported set of parameters.
+ *
+ * Returns: ptr to config A match has been made, ptr to result
+ * will remain valid until next call to
+ * this function.
+ * NULL Match not possible
+ */
+const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
+ const ParameterOptions *supported );
+
+/*
+ * Function: Angel_FindParam
+ * Purpose: find the value of a given parameter from a config.
+ *
+ * Params:
+ * Input: type parameter type to find
+ * config config to search
+ * Output: value parameter value if found
+ *
+ * Returns: TRUE parameter found
+ * FALSE parameter not found
+ */
+bool Angel_FindParam( ADP_Parameter type,
+ const ParameterConfig *config,
+ unsigned int *value );
+
+/*
+ * Function: Angel_StoreParam
+ * Purpose: store the value of a given parameter in a config.
+ *
+ * Params:
+ * In/Out: config config to store in
+ * Input: type parameter type to store
+ * value parameter value if found
+ *
+ * Returns: TRUE parameter found and new value stored
+ * FALSE parameter not found
+ */
+bool Angel_StoreParam( ParameterConfig *config,
+ ADP_Parameter type,
+ unsigned int value );
+
+/*
+ * Function: Angel_FindParamList
+ * Purpose: find the parameter list of a given parameter from an options.
+ *
+ * Params:
+ * Input: type parameter type to find
+ * options options block to search
+ *
+ * Returns: pointer to list
+ * NULL parameter not found
+ */
+ParameterList *Angel_FindParamList( const ParameterOptions *options,
+ ADP_Parameter type );
+
+/*
+ * Function: Angel_BuildParamConfigMessage
+ * Purpose: write a parameter config to a buffer in ADP format.
+ *
+ * Params:
+ * Input: buffer where to write to
+ * config the parameter config to write
+ *
+ * Returns: number of characters written to buffer
+ */
+unsigned int Angel_BuildParamConfigMessage( unsigned char *buffer,
+ const ParameterConfig *config );
+
+/*
+ * Function: Angel_BuildParamOptionsMessage
+ * Purpose: write a parameter Options to a buffer in ADP format.
+ *
+ * Params:
+ * Input: buffer where to write to
+ * options the options block to write
+ *
+ * Returns: number of characters written to buffer
+ */
+unsigned int Angel_BuildParamOptionsMessage( unsigned char *buffer,
+ const ParameterOptions *options );
+
+/*
+ * Function: Angel_ReadParamConfigMessage
+ * Purpose: read a parameter config from a buffer where it is in ADP format.
+ *
+ * Params:
+ * Input: buffer where to read from
+ * In/Out: config the parameter config to read to, which must
+ * be set up on entry with a valid array, and
+ * the size of the array in num_parameters.
+ *
+ * Returns: TRUE okay
+ * FALSE not enough space in config
+ */
+bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
+ ParameterConfig *config );
+
+/*
+ * Function: Angel_ReadParamOptionsMessage
+ * Purpose: read a parameter options from a buffer
+ * where it is in ADP format.
+ *
+ * Params:
+ * Input: buffer where to read from
+ * In/Out: options the parameter options block to read to,
+ * which must be set up on entry with a valid
+ * array, and the size of the array in
+ * num_parameters. Each param_list must
+ * also be set up in the same way.
+ *
+ * Returns: TRUE okay
+ * FALSE not enough space in options
+ */
+bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
+ ParameterOptions *options );
+
+#endif /* ndef angel_params_h */
+
+/* EOF params.h */
diff --git a/gdb/rdi-share/rx.c b/gdb/rdi-share/rx.c
new file mode 100644
index 0000000..4f434f0
--- /dev/null
+++ b/gdb/rdi-share/rx.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*-*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Character reception engine
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+#include "angel.h" /* Angel system definitions */
+#include "endian.h" /* Endian independant memory access macros */
+#include "crc.h" /* crc generation definitions and headers */
+#include "rxtx.h"
+#include "channels.h"
+#include "buffers.h"
+#ifdef TARGET
+# include "devdriv.h"
+#endif
+#include "logging.h"
+
+static re_status unexp_stx(struct re_state *rxstate);
+static re_status unexp_etx(struct re_state *rxstate);
+
+/* bitfield for the rx_engine state */
+typedef enum rx_state_flag{
+ RST_STX,
+ RST_TYP,
+ RST_LEN,
+ RST_DAT,
+ RST_CRC,
+ RST_ETX,
+ RST_ESC = (0x1 << 0x3)
+} rx_state_flag;
+
+void Angel_RxEngineInit(const struct re_config *rxconfig,
+ struct re_state *rxstate)
+{
+ rxstate->rx_state = RST_STX;
+ rxstate->field_c = 0;
+ rxstate->index = 0;
+ rxstate->crc = 0;
+ rxstate->error = RE_OKAY;
+ rxstate->config = rxconfig;
+}
+
+re_status Angel_RxEngine(unsigned char new_ch, struct data_packet *packet,
+ struct re_state *rxstate)
+{
+ /*
+ * TODO: add the flow control bits in
+ * Note: We test for the data field in a seperate case so we can
+ * completely avoid entering the switch for most chars
+ */
+
+ /* see if we're expecting a escaped char */
+ if ((rxstate->rx_state & RST_ESC) == RST_ESC)
+ {
+ /* unescape the char and unset the flag*/
+ new_ch &= ~serial_ESCAPE;
+#ifdef DO_TRACE
+ __rt_trace("rxe-echar-%2x ", new_ch);
+#endif
+ rxstate->rx_state &= ~RST_ESC;
+ }
+ else if ( (1 << new_ch) & rxstate->config->esc_set )
+ {
+ /* see if the incoming char is a special one */
+ if (new_ch == rxstate->config->esc)
+ {
+#ifdef DO_TRACE
+ __rt_trace("rxe-esc ");
+#endif
+ rxstate->rx_state |= RST_ESC;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ /*
+ * must be a normal packet so do some unexpected etx/stx checking
+ * we haven't been told to escape or received an escape so unless
+ * we are expecting an stx or etx then we can take the unexpected
+ * stx/etx trap
+ */
+ if ((new_ch == (rxstate->config->stx)) && (rxstate->rx_state != RST_STX))
+ return unexp_stx(rxstate);
+ if ((new_ch == (rxstate->config->etx)) && (rxstate->rx_state != RST_ETX))
+ return unexp_etx(rxstate);
+ }
+ }
+
+ if (rxstate->rx_state == RST_DAT)
+ {
+ /*
+ * do this to speed up the common case, no real penalty for
+ * other cases
+ */
+#ifdef DO_TRACE
+ __rt_trace("rxe-dat ");
+#endif
+
+ rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
+ (packet->data)[rxstate->index++] = (unsigned int)new_ch & 0xff;
+
+ if (rxstate->index == packet->len)
+ rxstate->rx_state = RST_CRC;
+
+ return RS_IN_PKT;
+ }
+
+ /*
+ * Now that the common case is out of the way we can test for everything
+ * else without worrying quite so much about the speed, changing the
+ * order to len,crc,stx,etx,typ might gain a tiny bit of speed but lets
+ * leave that for the moment
+ */
+ switch (rxstate->rx_state)
+ {
+ case RST_STX:
+ if (new_ch == rxstate->config->stx)
+ {
+ rxstate->rx_state = RST_TYP;
+ rxstate->error = RE_OKAY;
+ rxstate->crc = startCRC32;
+ rxstate->index = 0;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ rxstate->error = RE_OKAY;
+ return RS_WAIT_PKT;
+ }
+
+ case RST_TYP:
+ packet->type = (DevChanID)new_ch;
+ rxstate->rx_state = RST_LEN;
+ rxstate->error = RE_OKAY;
+ rxstate->field_c = 0; /* set up here for the length that follows */
+#ifdef DO_TRACE
+ __rt_trace("rxe-type-%2x ", packet->type);
+#endif
+ rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
+
+ return RS_IN_PKT;
+
+ case RST_LEN:
+ rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
+
+ if (rxstate->field_c++ == 0)
+ {
+ /* first length byte */
+ packet->len = ((unsigned int)new_ch) << 8;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ /* got the whole legth */
+ packet->len |= new_ch;
+#ifdef DO_TRACE
+ __rt_trace("rxe-len-%4x\n", packet->len);
+#endif
+
+ /* check that the length is ok */
+ if (packet->len == 0)
+ {
+ /* empty pkt */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_CRC;
+ return RS_IN_PKT;
+ }
+ else
+ {
+ if (packet->data == NULL)
+ {
+ /* need to alloc the data buffer */
+ if (!rxstate->config->ba_callback(
+ packet, rxstate->config->ba_data)) {
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_INTERNAL;
+ return RS_BAD_PKT;
+ }
+ }
+
+ if (packet->len > packet->buf_len)
+ {
+ /* pkt bigger than buffer */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_LEN;
+ return RS_BAD_PKT;
+ }
+ else
+ {
+ /* packet ok */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_DAT;
+ return RS_IN_PKT;
+ }
+ }
+ }
+
+ case RST_DAT:
+ /* dummy case (dealt with earlier) */
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("ERROR: hit RST_dat in switch\n");
+#endif
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_INTERNAL;
+ return RS_BAD_PKT;
+
+ case RST_CRC:
+ if (rxstate->field_c == 0)
+ packet->crc = 0;
+
+ packet->crc |= (new_ch & 0xFF) << ((3 - rxstate->field_c) * 8);
+ rxstate->field_c++;
+
+ if (rxstate->field_c == 4)
+ {
+ /* last crc field */
+ rxstate->field_c = 0;
+ rxstate->rx_state = RST_ETX;
+#ifdef DO_TRACE
+ __rt_trace("rxe-rcrc-%8x ", packet->crc);
+#endif
+ }
+
+ return RS_IN_PKT;
+
+ case RST_ETX:
+ if (new_ch == rxstate->config->etx)
+ {
+#if defined(DEBUG) && !defined(NO_PKT_DATA)
+ {
+ int c;
+# ifdef DO_TRACE
+ __rt_trace("\n");
+# endif
+ __rt_info("RXE Data =");
+ for (c=0; c < packet->len; c++)
+ __rt_info("%02x", packet->data[c]);
+ __rt_info("\n");
+ }
+#endif
+
+ /* check crc */
+ if (rxstate->crc == packet->crc)
+ {
+ /* crc ok */
+ rxstate->rx_state = RST_STX;
+ rxstate->field_c = 0;
+ return RS_GOOD_PKT;
+ }
+ else
+ {
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("Bad crc, rx calculates it should be 0x%x\n", rxstate->crc);
+#endif
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_CRC;
+ return RS_BAD_PKT;
+ }
+ }
+ else if (new_ch == rxstate->config->stx)
+ return unexp_stx(rxstate);
+ else
+ {
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_NETX;
+ return RS_BAD_PKT;
+ }
+
+ default:
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("ERROR fell through rxengine\n");
+#endif
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_INTERNAL;
+ return RS_BAD_PKT;
+ }
+}
+
+static re_status unexp_stx(struct re_state *rxstate)
+{
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("Unexpected stx\n");
+#endif
+ rxstate->crc = startCRC32;
+ rxstate->index = 0;
+ rxstate->rx_state = RST_TYP;
+ rxstate->error = RE_U_STX;
+ rxstate->field_c = 0;
+ return RS_BAD_PKT;
+}
+
+static re_status unexp_etx(struct re_state *rxstate)
+{
+#ifdef ASSERTIONS_ENABLED
+ __rt_warning("Unexpected etx, rxstate: index= 0x%2x, field_c=0x%2x, state=0x%2x\n", rxstate->index, rxstate->field_c, rxstate->rx_state);
+#endif
+ rxstate->crc = 0;
+ rxstate->index = 0;
+ rxstate->rx_state = RST_STX;
+ rxstate->error = RE_U_ETX;
+ rxstate->field_c = 0;
+ return RS_BAD_PKT;
+}
+
+/*
+ * This can be used as the buffer allocation callback for the rx engine,
+ * and makes use of angel_DD_GetBuffer() [in devdrv.h].
+ *
+ * Saves duplicating this callback function in every device driver that
+ * uses the rx engine.
+ *
+ * Note that this REQUIRES that the device id is installed as ba_data
+ * in the rx engine config structure for the driver.
+ */
+bool angel_DD_RxEng_BufferAlloc( struct data_packet *packet, void *cb_data )
+{
+#ifdef TARGET
+ DeviceID devid = (DeviceID)cb_data;
+#else
+ IGNORE(cb_data);
+#endif
+
+ if ( packet->type < DC_NUM_CHANNELS )
+ {
+ /* request a buffer down from the channels layer */
+#ifdef TARGET
+ packet->data = angel_DD_GetBuffer( devid, packet->type,
+ packet->len );
+#else
+ packet->data = malloc(packet->len);
+#endif
+ if ( packet->data == NULL )
+ return FALSE;
+ else
+ {
+ packet->buf_len = packet->len;
+ return TRUE;
+ }
+ }
+ else
+ {
+ /* bad type field */
+ return FALSE;
+ }
+}
+
+/* EOF rx.c */
diff --git a/gdb/rdi-share/rxtx.h b/gdb/rdi-share/rxtx.h
new file mode 100644
index 0000000..204e998
--- /dev/null
+++ b/gdb/rdi-share/rxtx.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*-*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * Project: ANGEL
+ *
+ * Title: Definitions required for the rx and tx engines
+ */
+
+#ifndef angel_rxtx_h
+#define angel_rxtx_h
+
+
+/*
+ * we need a definition for bool, which is "system" dependent
+ */
+#ifdef TARGET
+# include "angel.h"
+#else
+# include "host.h"
+#endif
+
+#include "devclnt.h"
+
+/* return status codes for the rx engine */
+typedef enum re_status {
+ RS_WAIT_PKT,
+ RS_IN_PKT,
+ RS_BAD_PKT,
+ RS_GOOD_PKT
+} re_status;
+
+/* return status codes for the tx engine */
+typedef enum te_status {
+ TS_IDLE,
+ TS_IN_PKT,
+ TS_DONE_PKT
+} te_status;
+
+
+/*
+ * required serial definitions, they should all be <32, refer to the
+ * re_config struct comments for more details
+ */
+#define serial_STX (0x1c) /* data packet start */
+#define serial_ETX (0x1d) /* packet end */
+#define serial_ESC (0x1b) /* standard escape character */
+#define serial_XON (0x11) /* software flow control - enable transmission */
+#define serial_XOFF (0x13) /* software flow control - disable transmission */
+
+/*
+ * All other characters are transmitted clean. If any of the above
+ * characters need to be transmitted as part of the serial data stream
+ * then the character will be preceded by the "serial_ESC" character,
+ * and then the required character transmitted (OR-ed with the
+ * "serial_ESCAPE" value, to ensure that the serial stream never has
+ * any of the exceptional characters generated by data transfers).
+ */
+
+#define serial_ESCAPE (0x40) /* OR-ed with escaped characters */
+
+/* bad packet error codes */
+typedef enum re_error {
+ RE_OKAY,
+ RE_U_STX,
+ RE_U_ETX,
+ RE_LEN,
+ RE_CRC,
+ RE_NETX,
+ RE_INTERNAL
+} re_error;
+
+/* a decoded packet */
+struct data_packet {
+ unsigned short buf_len; /* should be set by caller */
+ DevChanID type; /* valid when status is RS_GOOD_PKT */
+ unsigned short len; /* --"-- */
+ unsigned int crc; /* crc for the unescaped pkt */
+ unsigned char *data; /* should be set by caller */
+};
+
+/*
+ * Purpose: typedef for flow control function
+ *
+ * Params:
+ * Input: fc_char the flow control character in question
+ * In/Out: cb_data callback data as set in the fc_data
+ * field of re_config, typically device id
+ *
+ * This callback would tpyically respond to received XON and XOFF
+ * characters by controlling the transmit side of the device.
+ */
+typedef void (*fc_cb_func)(char fc_char, void *cb_data);
+
+
+/*
+ * Purpose: typedef for the function to alloc the data buffer
+ *
+ * Params:
+ * In/Out: packet the data packet: len and type will be set on
+ * entry, and buf_len and data should
+ * be set by this routine if successful.
+ * cb_data callback data as set in the ba_data
+ * field of re_config, typically device id
+ *
+ * Returns: TRUE buffer allocated okay
+ * FALSE couldn't allocate buffer of required size
+ * for given type
+ *
+ * This callback should attempt to acquire a buffer for the data portion
+ * of the packet which is currently being received, based on the len and
+ * type fields supplied in packet.
+ *
+ * angel_DD_RxEng_BufferAlloc() is supplied for use as this callback,
+ * and will be sufficient for most devices.
+ */
+typedef bool (*BufferAlloc_CB_Fn)(struct data_packet *packet, void *cb_data);
+
+
+/*
+ * The static info needed by the engine, may vary per device.
+ *
+ * fc_set and esc_set are bitmaps, e.g. bit 3 == charcode 3 == ASCII ETX.
+ * Thus any of the first 32 charcodes can be set for flow control or to
+ * be escaped.
+ *
+ * Note that esc_set should include all of fc_set, and should have bits
+ * set for stx, etx and esc, as a minimum.
+ *
+ * If character codes > 31 need to be used then fc_set and esc_set
+ * and their handling can be extended to use arrays and bit manipulation
+ * macros, potentially up to the full 256 possible chars.
+ *
+ * Note too that this could/should be shared with the tx engine.
+ */
+
+struct re_config {
+ unsigned char stx; /* the STX char for this device */
+ unsigned char etx; /* the ETX --"-- */
+ unsigned char esc; /* the ESC --"-- */
+ unsigned int fc_set; /* bitmap of flow control chars */
+ unsigned int esc_set; /* bitmap of special chars */
+ fc_cb_func fc_callback; /* flow control callback func */
+ void *fc_data; /* data to pass to fc_callback */
+ BufferAlloc_CB_Fn ba_callback; /* buffer alloc callback */
+ void *ba_data; /* data to pass to ba_calback */
+};
+
+/* the dynamic info needed by the rx engine */
+struct re_state {
+ unsigned char rx_state; /* 3 bits pkt state, 1 prepro state */
+ unsigned short field_c; /* chars left in current field */
+ unsigned short index; /* index into buffer */
+ unsigned int crc; /* crc accumulator */
+ re_error error; /* valid only if status is RS_BAD_PKT */
+ const struct re_config *config; /* pointer to static config */
+};
+
+/* dynamic state info needed by the tx engine */
+struct te_state {
+ unsigned short field_c; /* position in current field */
+ unsigned char tx_state; /* encodes n,e, and f (2+1+2=5 bits) */
+ unsigned char encoded; /* escape-encoded char for transmission */
+ const struct re_config *config; /* pointer to static config */
+ unsigned int crc; /* space for CRC (before escaping) */
+};
+
+/*
+ * Function: Angel_RxEngineInit
+ * Purpose: Initialise state (during device init) for engine.
+ *
+ * Params:
+ * Input: config static config info
+ * In/Out: state internal state
+ */
+
+void Angel_RxEngineInit(const struct re_config *config,
+ struct re_state *state);
+
+/*
+ * Function: Angel_RxEngine
+ * Purpose: Rx Engine for character-based devices
+ *
+ * Params:
+ * Input: new_ch the latest character
+ *
+ * In/Out: packet details of packet
+ * packet.buf_len and packet.data must
+ * be set on entry!
+ * state internal state, intially set by
+ * angel_RxEngineInit()
+ *
+ * Returns: re_status (see above)
+ *
+ */
+
+re_status Angel_RxEngine(unsigned char new_ch, struct data_packet *packet,
+ struct re_state *state);
+
+/*
+ * This can be used as the buffer allocation callback for the rx engine,
+ * and will make use of angel_DD_GetBuffer() [in devdrv.h].
+ *
+ * Saves duplicating this callback function in every device driver that
+ * uses the rx engine.
+ *
+ * Note that this REQUIRES that the device id is installed as ba_data
+ * in the rx engine config structure for the driver.
+ */
+bool angel_DD_RxEng_BufferAlloc( struct data_packet *packet, void *cb_data );
+
+/*
+ * Function: Angel_TxEngineInit
+ * Purpose: Set up tx engine at start of new packet, calculate CRC etc.
+ * (This should perform the actions described under
+ * "Initialisation" above)
+ *
+ * Params:
+ * Input: config static config info
+ * packet the packet to transmit
+ * In/Out: state internal state
+ */
+
+void Angel_TxEngineInit(const struct re_config *config,
+ const struct data_packet *packet,
+ struct te_state *state);
+
+/*
+ * Function: Angel_TxEngine
+ * Purpose: Tx Engine for character-based devices
+ *
+ * Params:
+ * Input: packet details of packet
+ * packet.len, packet.data and
+ * packet.type must
+ * be set on entry!
+ * In/Out: state internal state, intially set by
+ * angel_TxEngineStart()
+ * Output: tx_ch the character to be transmitted
+ * (NOT SET if return code is TS_IDLE)
+ *
+ * Returns: te_status (see above)
+ */
+
+te_status Angel_TxEngine(const struct data_packet *packet,
+ struct te_state *state,
+ unsigned char *tx_ch);
+
+
+
+#endif /* !defined(angel_rxtx_h) */
+
+/* EOF rxtx.h */
diff --git a/gdb/rdi-share/serdrv.c b/gdb/rdi-share/serdrv.c
new file mode 100644
index 0000000..43fd5a0
--- /dev/null
+++ b/gdb/rdi-share/serdrv.c
@@ -0,0 +1,649 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * serdrv.c - Synchronous Serial Driver for Angel.
+ * This is nice and simple just to get something going.
+ */
+
+#ifdef __hpux
+# define _POSIX_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crc.h"
+#include "devices.h"
+#include "buffers.h"
+#include "rxtx.h"
+#include "hostchan.h"
+#include "params.h"
+#include "logging.h"
+
+#ifdef COMPILING_ON_WINDOWS
+# undef ERROR
+# undef IGNORE
+# include <windows.h>
+# include "angeldll.h"
+# include "comb_api.h"
+#else
+# ifdef __hpux
+# define _TERMIOS_INCLUDED
+# include <sys/termio.h>
+# undef _TERMIOS_INCLUDED
+# else
+# include <termios.h>
+# endif
+# include "unixcomm.h"
+#endif
+
+#ifndef UNUSED
+# define UNUSED(x) (x = x) /* Silence compiler warnings */
+#endif
+
+#define MAXREADSIZE 512
+#define MAXWRITESIZE 512
+
+#define SERIAL_FC_SET ((1<<serial_XON)|(1<<serial_XOFF))
+#define SERIAL_CTL_SET ((1<<serial_STX)|(1<<serial_ETX)|(1<<serial_ESC))
+#define SERIAL_ESC_SET (SERIAL_FC_SET|SERIAL_CTL_SET)
+
+static const struct re_config config = {
+ serial_STX, serial_ETX, serial_ESC, /* self-explanatory? */
+ SERIAL_FC_SET, /* set of flow-control characters */
+ SERIAL_ESC_SET, /* set of characters to be escaped */
+ NULL /* serial_flow_control */, NULL , /* what to do with FC chars */
+ angel_DD_RxEng_BufferAlloc, NULL /* how to get a buffer */
+};
+
+static struct re_state rxstate;
+
+typedef struct writestate {
+ unsigned int wbindex;
+ /* static te_status testatus;*/
+ unsigned char writebuf[MAXWRITESIZE];
+ struct te_state txstate;
+} writestate;
+
+static struct writestate wstate;
+
+/*
+ * The set of parameter options supported by the device
+ */
+static unsigned int baud_options[] = {
+#ifdef __hpux
+ 115200, 57600,
+#endif
+ 38400, 19200, 9600
+};
+
+static ParameterList param_list[] = {
+ { AP_BAUD_RATE,
+ sizeof(baud_options)/sizeof(unsigned int),
+ baud_options }
+};
+
+static const ParameterOptions serial_options = {
+ sizeof(param_list)/sizeof(ParameterList), param_list };
+
+/*
+ * The default parameter config for the device
+ */
+static Parameter param_default[] = {
+ { AP_BAUD_RATE, 9600 }
+};
+
+static ParameterConfig serial_defaults = {
+ sizeof(param_default)/sizeof(Parameter), param_default };
+
+/*
+ * The user-modified options for the device
+ */
+static unsigned int user_baud_options[sizeof(baud_options)/sizeof(unsigned)];
+
+static ParameterList param_user_list[] = {
+ { AP_BAUD_RATE,
+ sizeof(user_baud_options)/sizeof(unsigned),
+ user_baud_options }
+};
+
+static ParameterOptions user_options = {
+ sizeof(param_user_list)/sizeof(ParameterList), param_user_list };
+
+static bool user_options_set;
+
+/* forward declarations */
+static int serial_reset( void );
+static int serial_set_params( const ParameterConfig *config );
+static int SerialMatch(const char *name, const char *arg);
+
+static void process_baud_rate( unsigned int target_baud_rate )
+{
+ const ParameterList *full_list;
+ ParameterList *user_list;
+
+ /* create subset of full options */
+ full_list = Angel_FindParamList( &serial_options, AP_BAUD_RATE );
+ user_list = Angel_FindParamList( &user_options, AP_BAUD_RATE );
+
+ if ( full_list != NULL && user_list != NULL )
+ {
+ unsigned int i, j;
+ unsigned int def_baud = 0;
+
+ /* find lower or equal to */
+ for ( i = 0; i < full_list->num_options; ++i )
+ if ( target_baud_rate >= full_list->option[i] )
+ {
+ /* copy remaining */
+ for ( j = 0; j < (full_list->num_options - i); ++j )
+ user_list->option[j] = full_list->option[i+j];
+ user_list->num_options = j;
+
+ /* check this is not the default */
+ Angel_FindParam( AP_BAUD_RATE, &serial_defaults, &def_baud );
+ if ( (j == 1) && (user_list->option[0] == def_baud) )
+ {
+#ifdef DEBUG
+ printf( "user selected default\n" );
+#endif
+ }
+ else
+ {
+ user_options_set = TRUE;
+#ifdef DEBUG
+ printf( "user options are: " );
+ for ( j = 0; j < user_list->num_options; ++j )
+ printf( "%u ", user_list->option[j] );
+ printf( "\n" );
+#endif
+ }
+
+ break; /* out of i loop */
+ }
+
+#ifdef DEBUG
+ if ( i >= full_list->num_options )
+ printf( "couldn't match baud rate %u\n", target_baud_rate );
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf( "failed to find lists\n" );
+#endif
+}
+
+static int SerialOpen(const char *name, const char *arg)
+{
+ const char *port_name = name;
+
+#ifdef DEBUG
+ printf("SerialOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (IsOpenSerial()) return -1;
+#else
+ if (Unix_IsSerialInUse()) return -1;
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (SerialMatch(name, arg) != adp_ok)
+ return adp_failed;
+#else
+ port_name = Unix_MatchValidSerialDevice(port_name);
+# ifdef DEBUG
+ printf("translated port to %s\n", port_name == 0 ? "NULL" : port_name);
+# endif
+ if (port_name == 0) return adp_failed;
+#endif
+
+ user_options_set = FALSE;
+
+ /* interpret and store the arguments */
+ if ( arg != NULL )
+ {
+ unsigned int target_baud_rate;
+ target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
+ if (target_baud_rate > 0)
+ {
+#ifdef DEBUG
+ printf( "user selected baud rate %u\n", target_baud_rate );
+#endif
+ process_baud_rate( target_baud_rate );
+ }
+#ifdef DEBUG
+ else
+ printf( "could not understand baud rate %s\n", arg );
+#endif
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ {
+ int port = IsValidDevice(name);
+ if (OpenSerial(port, FALSE) != COM_OK)
+ return -1;
+ }
+#else
+ if (Unix_OpenSerial(port_name) < 0)
+ return -1;
+#endif
+
+ serial_reset();
+
+#if defined(__unix) || defined(__CYGWIN32__)
+ Unix_ioctlNonBlocking();
+#endif
+
+ Angel_RxEngineInit(&config, &rxstate);
+ /*
+ * DANGER!: passing in NULL as the packet is ok for now as it is just
+ * IGNOREd but this may well change
+ */
+ Angel_TxEngineInit(&config, NULL, &wstate.txstate);
+ return 0;
+}
+
+static int SerialMatch(const char *name, const char *arg)
+{
+ UNUSED(arg);
+#ifdef COMPILING_ON_WINDOWS
+ if (IsValidDevice(name) == COM_DEVICENOTVALID)
+ return -1;
+ else
+ return 0;
+#else
+ return Unix_MatchValidSerialDevice(name) == 0 ? -1 : 0;
+#endif
+}
+
+static void SerialClose(void)
+{
+#ifdef DO_TRACE
+ printf("SerialClose()\n");
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ CloseSerial();
+#else
+ Unix_CloseSerial();
+#endif
+}
+
+static int SerialRead(DriverCall *dc, bool block) {
+ static unsigned char readbuf[MAXREADSIZE];
+ static int rbindex=0;
+
+ int nread;
+ int read_errno;
+ int c=0;
+ re_status restatus;
+ int ret_code = -1; /* assume bad packet or error */
+
+ /* must not overflow buffer and must start after the existing data */
+#ifdef COMPILING_ON_WINDOWS
+ {
+ BOOL dummy = FALSE;
+ nread = BytesInRXBufferSerial();
+
+ if (nread > MAXREADSIZE - rbindex)
+ nread = MAXREADSIZE - rbindex;
+
+ if ((read_errno = ReadSerial(readbuf+rbindex, nread, &dummy)) == COM_READFAIL)
+ {
+ MessageBox(GetFocus(), "Read error\n", "Angel", MB_OK | MB_ICONSTOP);
+ return -1; /* SJ - This really needs to return a value, which is picked up in */
+ /* DevSW_Read as meaning stop debugger but don't kill. */
+ }
+ else if (pfnProgressCallback != NULL && read_errno == COM_OK)
+ {
+ progressInfo.nRead += nread;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+#else
+ nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
+ read_errno = errno;
+#endif
+
+ if ((nread > 0) || (rbindex > 0)) {
+
+#ifdef DO_TRACE
+ printf("[%d@%d] ", nread, rbindex);
+#endif
+
+ if (nread>0)
+ rbindex = rbindex+nread;
+
+ do {
+ restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
+#ifdef DO_TRACE
+ printf("<%02X ",readbuf[c]);
+ if (!(++c % 16))
+ printf("\n");
+#else
+ c++;
+#endif
+ } while (c<rbindex &&
+ ((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));
+
+#ifdef DO_TRACE
+ if (c % 16)
+ printf("\n");
+#endif
+
+ switch(restatus) {
+
+ case RS_GOOD_PKT:
+ ret_code = 1;
+ /* fall through to: */
+
+ case RS_BAD_PKT:
+ /*
+ * We now need to shuffle any left over data down to the
+ * beginning of our private buffer ready to be used
+ *for the next packet
+ */
+#ifdef DO_TRACE
+ printf("SerialRead() processed %d, moving down %d\n", c, rbindex-c);
+#endif
+ if (c != rbindex) memmove((char *) readbuf, (char *) (readbuf+c),
+ rbindex-c);
+ rbindex -= c;
+ break;
+
+ case RS_IN_PKT:
+ case RS_WAIT_PKT:
+ rbindex = 0; /* will have processed all we had */
+ ret_code = 0;
+ break;
+
+ default:
+#ifdef DEBUG
+ printf("Bad re_status in serialRead()\n");
+#endif
+ break;
+ }
+ } else if (nread == 0)
+ ret_code = 0; /* nothing to read */
+ else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
+ ret_code = 0;
+
+#ifdef DEBUG
+ if ((nread<0) && (read_errno!=ERRNO_FOR_BLOCKED_IO))
+ perror("read() error in serialRead()");
+#endif
+
+ return ret_code;
+}
+
+
+static int SerialWrite(DriverCall *dc) {
+ int nwritten = 0;
+ te_status testatus = TS_IN_PKT;
+
+ if (dc->dc_context == NULL) {
+ Angel_TxEngineInit(&config, &(dc->dc_packet), &(wstate.txstate));
+ wstate.wbindex = 0;
+ dc->dc_context = &wstate;
+ }
+
+ while ((testatus == TS_IN_PKT) && (wstate.wbindex < MAXWRITESIZE))
+ {
+ /* send the raw data through the tx engine to escape and encapsulate */
+ testatus = Angel_TxEngine(&(dc->dc_packet), &(wstate.txstate),
+ &(wstate.writebuf)[wstate.wbindex]);
+ if (testatus != TS_IDLE) wstate.wbindex++;
+ }
+
+ if (testatus == TS_IDLE) {
+#ifdef DEBUG
+ printf("SerialWrite: testatus is TS_IDLE during preprocessing\n");
+#endif
+ }
+
+#ifdef DO_TRACE
+ {
+ int i = 0;
+
+ while (i<wstate.wbindex)
+ {
+ printf(">%02X ",wstate.writebuf[i]);
+
+ if (!(++i % 16))
+ printf("\n");
+ }
+ if (i % 16)
+ printf("\n");
+ }
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (WriteSerial(wstate.writebuf, wstate.wbindex) == COM_OK)
+ {
+ nwritten = wstate.wbindex;
+ if (pfnProgressCallback != NULL)
+ {
+ progressInfo.nWritten += nwritten;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+ else
+ {
+ MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
+ return -1; /* SJ - This really needs to return a value, which is picked up in */
+ /* DevSW_Read as meaning stop debugger but don't kill. */
+ }
+#else
+ nwritten = Unix_WriteSerial(wstate.writebuf, wstate.wbindex);
+
+ if (nwritten < 0) {
+ nwritten=0;
+ }
+#endif
+
+#ifdef DEBUG
+ if (nwritten > 0)
+ printf("Wrote %#04x bytes\n", nwritten);
+#endif
+
+ if ((unsigned) nwritten == wstate.wbindex &&
+ (testatus == TS_DONE_PKT || testatus == TS_IDLE)) {
+
+ /* finished sending the packet */
+
+#ifdef DEBUG
+ printf("SerialWrite: calling Angel_TxEngineInit after sending packet (len=%i)\n",wstate.wbindex);
+#endif
+ testatus = TS_IN_PKT;
+ wstate.wbindex = 0;
+ return 1;
+ }
+ else {
+#ifdef DEBUG
+ printf("SerialWrite: Wrote part of packet wbindex=%i, nwritten=%i\n",
+ wstate.wbindex, nwritten);
+#endif
+
+ /*
+ * still some data left to send shuffle whats left down and reset
+ * the ptr
+ */
+ memmove((char *) wstate.writebuf, (char *) (wstate.writebuf+nwritten),
+ wstate.wbindex-nwritten);
+ wstate.wbindex -= nwritten;
+ return 0;
+ }
+ return -1;
+}
+
+
+static int serial_reset( void )
+{
+#ifdef DEBUG
+ printf( "serial_reset\n" );
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ FlushSerial();
+#else
+ Unix_ResetSerial();
+#endif
+
+ return serial_set_params( &serial_defaults );
+}
+
+
+static int find_baud_rate( unsigned int *speed )
+{
+ static struct {
+ unsigned int baud;
+ int termiosValue;
+ } possibleBaudRates[] = {
+#if defined(__hpux)
+ {115200,_B115200}, {57600,_B57600},
+#endif
+#ifdef COMPILING_ON_WINDOWS
+ {38400,CBR_38400}, {19200,CBR_19200}, {9600, CBR_9600}, {0,0}
+#else
+ {38400,B38400}, {19200,B19200}, {9600, B9600}, {0,0}
+#endif
+ };
+ unsigned int i;
+
+ /* look for lower or matching -- will always terminate at 0 end marker */
+ for ( i = 0; possibleBaudRates[i].baud > *speed; ++i )
+ /* do nothing */ ;
+
+ if ( possibleBaudRates[i].baud > 0 )
+ *speed = possibleBaudRates[i].baud;
+
+ return possibleBaudRates[i].termiosValue;
+}
+
+
+static int serial_set_params( const ParameterConfig *config )
+{
+ unsigned int speed;
+ int termios_value;
+
+#ifdef DEBUG
+ printf( "serial_set_params\n" );
+#endif
+
+ if ( ! Angel_FindParam( AP_BAUD_RATE, config, &speed ) )
+ {
+#ifdef DEBUG
+ printf( "speed not found in config\n" );
+#endif
+ return DE_OKAY;
+ }
+
+ termios_value = find_baud_rate( &speed );
+ if ( termios_value == 0 )
+ {
+#ifdef DEBUG
+ printf( "speed not valid: %u\n", speed );
+#endif
+ return DE_OKAY;
+ }
+
+#ifdef DEBUG
+ printf( "setting speed to %u\n", speed );
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ SetBaudRate((WORD)termios_value);
+#else
+ Unix_SetSerialBaudRate(termios_value);
+#endif
+
+ return DE_OKAY;
+}
+
+
+static int serial_get_user_params( ParameterOptions **p_options )
+{
+#ifdef DEBUG
+ printf( "serial_get_user_params\n" );
+#endif
+
+ if ( user_options_set )
+ {
+ *p_options = &user_options;
+ }
+ else
+ {
+ *p_options = NULL;
+ }
+
+ return DE_OKAY;
+}
+
+
+static int serial_get_default_params( ParameterConfig **p_config )
+{
+#ifdef DEBUG
+ printf( "serial_get_default_params\n" );
+#endif
+
+ *p_config = (ParameterConfig *) &serial_defaults;
+ return DE_OKAY;
+}
+
+
+static int SerialIoctl(const int opcode, void *args) {
+
+ int ret_code;
+
+#ifdef DEBUG
+ printf( "SerialIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
+#endif
+
+ switch (opcode)
+ {
+ case DC_RESET:
+ ret_code = serial_reset();
+ break;
+
+ case DC_SET_PARAMS:
+ ret_code = serial_set_params((const ParameterConfig *)args);
+ break;
+
+ case DC_GET_USER_PARAMS:
+ ret_code = serial_get_user_params((ParameterOptions **)args);
+ break;
+
+ case DC_GET_DEFAULT_PARAMS:
+ ret_code = serial_get_default_params((ParameterConfig **)args);
+ break;
+
+ default:
+ ret_code = DE_BAD_OP;
+ break;
+ }
+
+ return ret_code;
+}
+
+DeviceDescr angel_SerialDevice = {
+ "SERIAL",
+ SerialOpen,
+ SerialMatch,
+ SerialClose,
+ SerialRead,
+ SerialWrite,
+ SerialIoctl
+};
diff --git a/gdb/rdi-share/serpardr.c b/gdb/rdi-share/serpardr.c
new file mode 100644
index 0000000..604d048
--- /dev/null
+++ b/gdb/rdi-share/serpardr.c
@@ -0,0 +1,730 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ * serpardv.c - Serial/Parallel Driver for Angel.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crc.h"
+#include "devices.h"
+#include "buffers.h"
+#include "rxtx.h"
+#include "hostchan.h"
+#include "params.h"
+#include "logging.h"
+#include "hsys.h"
+
+#ifdef COMPILING_ON_WINDOWS
+# undef ERROR
+# undef IGNORE
+# include <windows.h>
+# include "angeldll.h"
+# include "comb_api.h"
+#else
+# ifdef __hpux
+# define _TERMIOS_INCLUDED
+# include <sys/termio.h>
+# undef _TERMIOS_INCLUDED
+# else
+# include <termios.h>
+# endif
+# include "unixcomm.h"
+#endif
+
+#ifndef UNUSED
+# define UNUSED(x) (x = x) /* Silence compiler warnings */
+#endif
+
+#define MAXREADSIZE 512
+#define MAXWRITESIZE 512
+
+#define SERPAR_FC_SET ((1 << serial_XON) | (1 << serial_XOFF))
+#define SERPAR_CTL_SET ((1 << serial_STX) | (1 << serial_ETX) | \
+ (1 << serial_ESC))
+#define SERPAR_ESC_SET (SERPAR_FC_SET | SERPAR_CTL_SET)
+
+static const struct re_config config = {
+ serial_STX, serial_ETX, serial_ESC, /* self-explanatory? */
+ SERPAR_FC_SET, /* set of flow-control characters */
+ SERPAR_ESC_SET, /* set of characters to be escaped */
+ NULL, /* serial_flow_control */
+ NULL, /* what to do with FC chars */
+ angel_DD_RxEng_BufferAlloc, NULL /* how to get a buffer */
+};
+
+static struct re_state rxstate;
+
+/*
+ * structure used for manipulating transmit data
+ */
+typedef struct TxState
+{
+ struct te_state state;
+ unsigned int index;
+ unsigned char writebuf[MAXWRITESIZE];
+} TxState;
+
+/*
+ * The set of parameter options supported by the device
+ */
+static unsigned int baud_options[] =
+{
+#ifdef __hpux
+ 115200, 57600,
+#endif
+ 38400, 19200, 9600
+};
+
+static ParameterList param_list[] =
+{
+ {
+ AP_BAUD_RATE,
+ sizeof(baud_options) / sizeof(unsigned int),
+ baud_options
+ }
+};
+
+static const ParameterOptions serpar_options =
+{
+ sizeof(param_list) / sizeof(ParameterList),
+ param_list
+};
+
+/*
+ * The default parameter config for the device
+ */
+static Parameter param_default[] =
+{
+ { AP_BAUD_RATE, 9600 }
+};
+
+static const ParameterConfig serpar_defaults =
+{
+ sizeof(param_default)/sizeof(Parameter),
+ param_default
+};
+
+/*
+ * The user-modified options for the device
+ */
+static unsigned int user_baud_options[sizeof(baud_options) /
+ sizeof(unsigned int)];
+
+static ParameterList param_user_list[] =
+{
+ {
+ AP_BAUD_RATE,
+ sizeof(user_baud_options) / sizeof(unsigned),
+ user_baud_options
+ }
+};
+
+static ParameterOptions user_options =
+{
+ sizeof(param_user_list) / sizeof(ParameterList),
+ param_user_list
+};
+
+static bool user_options_set;
+
+/* forward declarations */
+static int serpar_reset(void);
+static int serpar_set_params(const ParameterConfig *config);
+static int SerparMatch(const char *name, const char *arg);
+
+static void process_baud_rate(unsigned int target_baud_rate)
+{
+ const ParameterList *full_list;
+ ParameterList *user_list;
+
+ /* create subset of full options */
+ full_list = Angel_FindParamList(&serpar_options, AP_BAUD_RATE);
+ user_list = Angel_FindParamList(&user_options, AP_BAUD_RATE);
+
+ if (full_list != NULL && user_list != NULL)
+ {
+ unsigned int i, j;
+ unsigned int def_baud = 0;
+
+ /* find lower or equal to */
+ for (i = 0; i < full_list->num_options; ++i)
+ if (target_baud_rate >= full_list->option[i])
+ {
+ /* copy remaining */
+ for (j = 0; j < (full_list->num_options - i); ++j)
+ user_list->option[j] = full_list->option[i+j];
+ user_list->num_options = j;
+
+ /* check this is not the default */
+ Angel_FindParam(AP_BAUD_RATE, &serpar_defaults, &def_baud);
+ if ((j == 1) && (user_list->option[0] == def_baud))
+ {
+#ifdef DEBUG
+ printf("user selected default\n");
+#endif
+ }
+ else
+ {
+ user_options_set = TRUE;
+#ifdef DEBUG
+ printf("user options are: ");
+ for (j = 0; j < user_list->num_options; ++j)
+ printf("%u ", user_list->option[j]);
+ printf("\n");
+#endif
+ }
+
+ break; /* out of i loop */
+ }
+
+#ifdef DEBUG
+ if (i >= full_list->num_options)
+ printf("couldn't match baud rate %u\n", target_baud_rate);
+#endif
+ }
+#ifdef DEBUG
+ else
+ printf("failed to find lists\n");
+#endif
+}
+
+static int SerparOpen(const char *name, const char *arg)
+{
+ char *sername = NULL;
+ char *parname = NULL;
+
+#ifdef DEBUG
+ printf("SerparOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (IsOpenSerial() || IsOpenParallel()) return -1;
+#else
+ if (Unix_IsSerialInUse() || Unix_IsParallelInUse()) return -1;
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ if (SerparMatch(name, arg) == -1)
+ return -1;
+#else
+ Unix_IsValidParallelDevice(name,&sername,&parname);
+# ifdef DEBUG
+ printf("translated %s to serial %s and parallel %s\n",
+ name==0 ? "NULL" : name,
+ sername==0 ? "NULL" : sername,
+ parname==0 ? "NULL" : parname);
+# endif
+ if (sername==NULL || parname==NULL) return -1;
+#endif
+
+ user_options_set = FALSE;
+
+ /* interpret and store the arguments */
+ if (arg != NULL)
+ {
+ unsigned int target_baud_rate;
+
+ target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
+
+ if (target_baud_rate > 0)
+ {
+#ifdef DEBUG
+ printf("user selected baud rate %u\n", target_baud_rate);
+#endif
+ process_baud_rate(target_baud_rate);
+ }
+#ifdef DEBUG
+ else
+ printf("could not understand baud rate %s\n", arg);
+#endif
+ }
+
+#ifdef COMPILING_ON_WINDOWS
+ {
+ /*
+ * The serial port number is in name[0] followed by
+ * the parallel port number in name[1]
+ */
+
+ int sport = name[0] - '0';
+ int pport = name[1] - '0';
+
+ if (OpenParallel(pport) != COM_OK)
+ return -1;
+
+ if (OpenSerial(sport, FALSE) != COM_OK)
+ {
+ CloseParallel();
+ return -1;
+ }
+ }
+#else
+ Unix_OpenParallel(parname);
+ Unix_OpenSerial(sername);
+#endif
+
+ serpar_reset();
+
+#if defined(__unix) || defined(__CYGWIN32__)
+ Unix_ioctlNonBlocking();
+#endif
+
+ Angel_RxEngineInit(&config, &rxstate);
+
+ return 0;
+}
+
+#ifdef COMPILING_ON_WINDOWS
+static int SerparMatch(const char *name, const char *arg)
+{
+ char sername[2];
+ char parname[2];
+
+ UNUSED(arg);
+
+ sername[0] = name[0];
+ parname[0] = name[1];
+ sername[1] = parname[1] = 0;
+
+ if (IsValidDevice(sername) == COM_DEVICENOTVALID ||
+ IsValidDevice(parname) == COM_DEVICENOTVALID)
+ return -1;
+ else
+ return 0;
+}
+#else
+static int SerparMatch(const char *portstring, const char *arg)
+{
+ char *sername=NULL, *parname=NULL;
+ UNUSED(arg);
+
+ Unix_IsValidParallelDevice(portstring,&sername,&parname);
+
+ /* Match failed if either sername or parname are still NULL */
+ if (sername==NULL || parname==NULL) return -1;
+ return 0;
+}
+#endif
+
+static void SerparClose(void)
+{
+#ifdef COMPILING_ON_WINDOWS
+ CloseParallel();
+ CloseSerial();
+#else
+ Unix_CloseParallel();
+ Unix_CloseSerial();
+#endif
+}
+
+static int SerparRead(DriverCall *dc, bool block)
+{
+ static unsigned char readbuf[MAXREADSIZE];
+ static int rbindex = 0;
+
+ int nread;
+ int read_errno;
+ int c = 0;
+ re_status restatus;
+ int ret_code = -1; /* assume bad packet or error */
+
+ /*
+ * we must not overflow buffer, and must start after
+ * the existing data
+ */
+#ifdef COMPILING_ON_WINDOWS
+ {
+ BOOL dummy = FALSE;
+ nread = BytesInRXBufferSerial();
+
+ if (nread > MAXREADSIZE - rbindex)
+ nread = MAXREADSIZE - rbindex;
+ read_errno = ReadSerial(readbuf+rbindex, nread, &dummy);
+ if (pfnProgressCallback != NULL && read_errno == COM_OK)
+ {
+ progressInfo.nRead += nread;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+#else
+ nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
+ read_errno = errno;
+#endif
+
+ if ((nread > 0) || (rbindex > 0))
+ {
+#ifdef DO_TRACE
+ printf("[%d@%d] ", nread, rbindex);
+#endif
+
+ if (nread > 0)
+ rbindex = rbindex + nread;
+
+ do
+ {
+ restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
+
+#ifdef DO_TRACE
+ printf("<%02X ",readbuf[c]);
+#endif
+ c++;
+ } while (c < rbindex &&
+ ((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));
+
+#ifdef DO_TRACE
+ printf("\n");
+#endif
+
+ switch(restatus)
+ {
+ case RS_GOOD_PKT:
+ ret_code = 1;
+ /* fall through to: */
+
+ case RS_BAD_PKT:
+ /*
+ * We now need to shuffle any left over data down to the
+ * beginning of our private buffer ready to be used
+ *for the next packet
+ */
+#ifdef DO_TRACE
+ printf("SerparRead() processed %d, moving down %d\n",
+ c, rbindex - c);
+#endif
+
+ if (c != rbindex)
+ memmove((char *) readbuf, (char *) (readbuf + c), rbindex - c);
+
+ rbindex -= c;
+
+ break;
+
+ case RS_IN_PKT:
+ case RS_WAIT_PKT:
+ rbindex = 0; /* will have processed all we had */
+ ret_code = 0;
+ break;
+
+ default:
+#ifdef DEBUG
+ printf("Bad re_status in SerparRead()\n");
+#endif
+ break;
+ }
+ }
+ else if (nread == 0)
+ /* nothing to read */
+ ret_code = 0;
+ else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
+ ret_code = 0;
+
+#ifdef DEBUG
+ if ((nread < 0) && (read_errno != ERRNO_FOR_BLOCKED_IO))
+ perror("read() error in SerparRead()");
+#endif
+
+ return ret_code;
+}
+
+/*
+ * Function: send_packet
+ * Purpose: Send a stream of bytes to Angel through the parallel port
+ *
+ * Algorithm: We need to present the data in a form that all boards can
+ * swallow. With the PID board, this is a problem: for reasons
+ * described in the driver (angel/pid/st16c552.c), data are
+ * sent a nybble at a time on D0-D2 and D4; D3 is wired to ACK,
+ * which generates an interrupt when it goes low. This routine
+ * fills in an array of nybbles, with ACK clear in all but the
+ * last one. If, for whatever reason, the write fails, then
+ * ACK is forced high (thereby enabling the next write a chance
+ * to be noticed when the falling edge of ACK generates an
+ * interrupt (hopefully).
+ *
+ * Params:
+ * Input: txstate Contains the packet to be sent
+ *
+ * Returns: Number of *complete* bytes written
+ */
+
+static int SerparWrite(DriverCall *dc)
+{
+ te_status status;
+ int nwritten = 0;
+ static TxState txstate;
+
+ /*
+ * is this a new packet?
+ */
+ if (dc->dc_context == NULL)
+ {
+ /*
+ * yes - initialise TxEngine
+ */
+ Angel_TxEngineInit(&config, &dc->dc_packet, &txstate.state);
+
+ txstate.index = 0;
+ dc->dc_context = &txstate;
+ }
+
+ /*
+ * fill the buffer using the Tx Engine
+ */
+ do
+ {
+ status = Angel_TxEngine(&dc->dc_packet, &txstate.state,
+ &txstate.writebuf[txstate.index]);
+ if (status != TS_IDLE) txstate.index++;
+
+ } while (status == TS_IN_PKT && txstate.index < MAXWRITESIZE);
+
+#ifdef DO_TRACE
+ {
+ unsigned int i = 0;
+
+ while (i < txstate.index)
+ {
+ printf(">%02X ", txstate.writebuf[i]);
+
+ if (!(++i % 16))
+ putc('\n', stdout);
+ }
+
+ if (i % 16)
+ putc('\n', stdout);
+ }
+#endif
+
+ /*
+ * the data are ready, all we need now is to send them out
+ * in a form that Angel can swallow.
+ */
+#ifdef COMPILING_ON_WINDOWS
+ if (WriteParallel(txstate.writebuf, txstate.index) == COM_OK)
+ {
+ nwritten = txstate.index;
+ if (pfnProgressCallback != NULL)
+ {
+ progressInfo.nWritten += nwritten;
+ (*pfnProgressCallback)(&progressInfo);
+ }
+ }
+ else
+ {
+ MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
+ return -1; /* SJ - This really needs to return a value, which is picked up in */
+ /* DevSW_Read as meaning stop debugger but don't kill. */
+ }
+#else
+ nwritten = Unix_WriteParallel(txstate.writebuf, txstate.index);
+#endif
+
+ if (nwritten < 0) nwritten = 0;
+
+#ifdef DO_TRACE
+ printf("SerparWrite: wrote %d out of %d bytes\n",
+ nwritten, txstate.index);
+#endif
+
+ /*
+ * has the whole packet gone?
+ */
+ if (nwritten == (int)txstate.index &&
+ (status == TS_DONE_PKT || status == TS_IDLE))
+ /*
+ * yes it has
+ */
+ return 1;
+ else
+ {
+ /*
+ * if some data are left, shuffle them
+ * to the start of the buffer
+ */
+ if (nwritten != (int)txstate.index && nwritten != 0)
+ {
+ txstate.index -= nwritten;
+ (void)memmove((char *) txstate.writebuf,
+ (char *) (txstate.writebuf + nwritten),
+ txstate.index);
+ }
+ else if (nwritten == (int)txstate.index)
+ txstate.index = 0;
+
+ return 0;
+ }
+}
+
+static int serpar_reset(void)
+{
+#ifdef COMPILING_ON_WINDOWS
+ FlushParallel();
+ FlushSerial();
+#else
+ Unix_ResetParallel();
+ Unix_ResetSerial();
+#endif
+
+ return serpar_set_params(&serpar_defaults);
+}
+
+static int find_baud_rate(unsigned int *speed)
+{
+ static struct
+ {
+ unsigned int baud;
+ int termiosValue;
+ } possibleBaudRates[] =
+ {
+#if defined(__hpux)
+ {115200, _B115200}, {57600, _B57600},
+#endif
+#ifdef COMPILING_ON_WINDOWS
+ {38400, CBR_38400}, {19200, CBR_19200}, {9600, CBR_9600}, {0, 0}
+#else
+ {38400, B38400}, {19200, B19200}, {9600, B9600}, {0, 0}
+#endif
+ };
+ unsigned int i;
+
+ /* look for lower or matching -- will always terminate at 0 end marker */
+ for (i = 0; possibleBaudRates[i].baud > *speed; ++i)
+ /* do nothing */
+ ;
+
+ if (possibleBaudRates[i].baud > 0)
+ *speed = possibleBaudRates[i].baud;
+
+ return possibleBaudRates[i].termiosValue;
+}
+
+static int serpar_set_params(const ParameterConfig *config)
+{
+ unsigned int speed;
+ int termios_value;
+
+#ifdef DEBUG
+ printf("serpar_set_params\n");
+#endif
+
+ if (!Angel_FindParam(AP_BAUD_RATE, config, &speed))
+ {
+#ifdef DEBUG
+ printf("speed not found in config\n");
+#endif
+ return DE_OKAY;
+ }
+
+ termios_value = find_baud_rate(&speed);
+ if (termios_value == 0)
+ {
+#ifdef DEBUG
+ printf("speed not valid: %u\n", speed);
+#endif
+ return DE_OKAY;
+ }
+
+#ifdef DEBUG
+ printf("setting speed to %u\n", speed);
+#endif
+
+#ifdef COMPILING_ON_WINDOWS
+ SetBaudRate((WORD)termios_value);
+#else
+ Unix_SetSerialBaudRate(termios_value);
+#endif
+
+ return DE_OKAY;
+}
+
+
+static int serpar_get_user_params(ParameterOptions **p_options)
+{
+#ifdef DEBUG
+ printf("serpar_get_user_params\n");
+#endif
+
+ if (user_options_set)
+ {
+ *p_options = &user_options;
+ }
+ else
+ {
+ *p_options = NULL;
+ }
+
+ return DE_OKAY;
+}
+
+
+static int serial_get_default_params( const ParameterConfig **p_config )
+{
+#ifdef DEBUG
+ printf( "serial_get_default_params\n" );
+#endif
+
+ *p_config = &serpar_defaults;
+ return DE_OKAY;
+}
+
+
+static int SerparIoctl(const int opcode, void *args)
+{
+ int ret_code;
+
+#ifdef DEBUG
+ printf("SerparIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
+#endif
+
+ switch (opcode)
+ {
+ case DC_RESET:
+ ret_code = serpar_reset();
+ break;
+
+ case DC_SET_PARAMS:
+ ret_code = serpar_set_params((const ParameterConfig *)args);
+ break;
+
+ case DC_GET_USER_PARAMS:
+ ret_code = serpar_get_user_params((ParameterOptions **)args);
+ break;
+
+ case DC_GET_DEFAULT_PARAMS:
+ ret_code =
+ serial_get_default_params((const ParameterConfig **)args);
+ break;
+
+ default:
+ ret_code = DE_BAD_OP;
+ break;
+ }
+
+ return ret_code;
+}
+
+DeviceDescr angel_SerparDevice =
+{
+ "SERPAR",
+ SerparOpen,
+ SerparMatch,
+ SerparClose,
+ SerparRead,
+ SerparWrite,
+ SerparIoctl
+};
+
+/* EOF serpardr.c */
diff --git a/gdb/rdi-share/sys.h b/gdb/rdi-share/sys.h
new file mode 100644
index 0000000..b68ac78
--- /dev/null
+++ b/gdb/rdi-share/sys.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* sys.h
+ ***********************************************************************
+ * Angel C Libary support channel protocol definitions
+ *
+ * $Revision$
+ * $Date$
+ *
+ *
+ *
+ *
+ * MESSAGE FORMAT
+ * --------------
+ * Format of the "data" section of C Lib Support Channel Messages.
+ * You will notice that the format is much the same as the format
+ * of ADP messages - this is so that multi-threaded C Libraries can
+ * be supported.
+ *
+ * unsigned32 reason - Main C Library reason code.
+ * unsigned32 debugID - Info. describing host debug world;
+ * private to host and used in any target
+ * initiated messages.
+ * unsigned32 OSinfo1 \ Target OS information to identify process/thread
+ * unsigned32 OSinfo2 / world, etc. These two fields are target defined.
+ * byte args[n] - Data for message "reason" code.
+ *
+ * The "debugID" is defined by the host-end of the protocol, and is used
+ * by the host to ensure that messages are routed to the correct handler
+ * program/veneer (eg. imagine several threads having opened stdout and
+ * each writing to a different window in a windowed debugger).
+ *
+ * NOTE: The reason that there is no "size" information, is that the
+ * message IDs themselves encode the format of any arguments.
+ *
+ * For further discussion of the format see adp.h
+ *
+ * N.B. All streams are little endian.
+ *
+ * CLIB REASON CODE
+ * ----------------
+ * The message reason codes contain some information that ties them to
+ * the channel and direction that the message will be used with. This
+ * will ensure that even if the message "#define name" is not
+ * completely descriptive, the message reason code is.
+ *
+ * b31 = direction. 0=Host-to-Target; 1=Target-to-Host;
+ * b30-16 = reserved. should be zero
+ * b15-0 = message reason code.
+ *
+ * Note that typically a request will be initiated by the target side, and
+ * that the host will then respond with either an acknowledgement or some
+ * data. In either case the same reason code will be used, but the direction
+ * bit will be reveresed.
+ */
+
+#ifndef __sys_h
+#define __sys_h
+
+#ifndef HtoT
+#define HtoT ((unsigned)0 << 31) /* Host-to-Target message */
+#define TtoH ((unsigned)1 << 31) /* Target-to-Host message */
+#endif
+
+/*
+ * The following are error codes used in the status field returned on
+ * sending a message. 0 represents no error having occurred, non-zero
+ * represents a general error. More codes should be added as required.
+ */
+
+#ifndef ErrCode
+#define NoError 0x0
+#endif
+
+/*************************************************************************/
+/* The following are direct conversions of the DeMon SWI's */
+/* NB: nbytes is the number of bytes INCLUDING THE NULL character where */
+/* applicable. */
+
+/* This message is used as a response to a packet whose message
+ * was not understood. The return parameter, code is the reason
+ * code which was not understood. Although intended for use as a
+ * default case on a received message switch it can also be used
+ * as a proper message*/
+#define CL_Unrecognised 0x00
+ /* Unrecognised()
+ * return(word code)
+ */
+
+/* Write a character to the terminal.
+ */
+#define CL_WriteC 0x01
+ /* WriteC(byte data)
+ * return(word status)
+ */
+
+/* Write a NULL terminated string of characters to the terminal. The length
+ * of the string excluding the NULL terminating character is passed in
+ * 'nbytes'.
+ */
+#define CL_Write0 0x02
+ /* Write0(word nbytes, bytes data)
+ * return(word status)
+ */
+
+/* Read a character from the terminal - probably the keyboard.
+ */
+#define CL_ReadC 0x04
+ /* ReadC(void)
+ * return(word status, byte data)
+ */
+
+/* Perform system call, pass NULL terminated string to host's command
+ * line interpreter(NOT AVAILABLE IN PC/DOS RELEASE). The data byte
+ * returned holds the return code from the system call.
+ */
+#define CL_System 0x05
+ /* CLI(word nbytes, bytes data)
+ * return(word status, word data)
+ */
+
+/* It returns the address of the null terminated command line string used to
+ * invoke the program. status will be set to NoError if the command line
+ * can be returned. Other status values will be treated as error conditions.
+ */
+#define CL_GetCmdLine 0x10
+ /* GetCmdLine(void)
+ * return(word status, word nbytes, bytes argline)
+ */
+
+/* Return the number of centi-seconds since the support code began
+ * execution. Only the difference between successive calls can be
+ * meaningful.
+ */
+#define CL_Clock 0x61
+ /* Clock(void)
+ * return(word status, word clks)
+ */
+
+/* Return the number of seconds since the beginning of 1970.
+ */
+#define CL_Time 0x63
+ /* Time(void)
+ * return(word status, word time)
+ */
+
+/* Delete(remove, un-link, wipe, destroy) the file named by the
+ * NULL-terminated string 'name'.
+ */
+#define CL_Remove 0x64
+ /* Remove(word nbytes, bytes name)
+ * return(word status)
+ */
+
+/* Rename the file specified by the NULL-terminated string 'oname'
+ * to 'nname'.
+ */
+#define CL_Rename 0x65
+ /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
+ * return(word status)
+ */
+
+/* 'name' specifies a NULL-terminated string containing a file name or a
+ * device name. Opens the file/device and returns a non-zero handle on
+ * success that can be quoted to CL_Close, CL_Read, CL_Write, CL_Seek,
+ * CL_Flen or CL_IsTTY. The mode is an integer in the range 0-11:-
+ *
+ * Mode: 0 1 2 3 4 5 6 7 8 9 10 11
+ * ANSI C fopen mode: r rb r+ r+b w wb w+ w+b a ab a+ a+b
+ *
+ * Values 12-15 are illegal. If 'name' is ":tt" the stdin/stdout is
+ * opened depending on whether 'mode' is read or write.
+ */
+#define CL_Open 0x66
+ /* Open(word nbytes, bytes name, word mode)
+ * return(word handle)
+ */
+
+/* 'handle' is a file handle previously returned by CL_Open. CL_Close
+ * closes the file.
+ */
+#define CL_Close 0x68
+ /* Close(word handle)
+ * return(word status)
+ */
+
+/* Writes data of length nbytes to the file/device specified by
+ * handle. nbtotal represents the total number of bytes to be
+ * written, whereas nbytes is the number of bytes in this packet
+ *
+ * If nbtotal is <= DATASIZE - CL_Write message header size in the
+ * packet then nbytes = nbtotal and the number of bytes not written
+ * is returned. If nbtotal is > the packet size then the CL_Write
+ * must be followed by a number of CL_WriteX's to complete the write,
+ * the nbytes returned by CL_Write can be ignored
+ * If the status word returned is non zero, an error has occurred and
+ * the write request has been aborted.
+ *
+ */
+#define CL_Write 0x69
+ /* Write(word handle, word nbtotal, word nbytes, bytes data)
+ * return(word status, word nbytes)
+ */
+
+/* Write Extension is a reads a continuation of data from a CL_Write
+ * which was too big to fit in a single packet.
+ * nbytes is the number of bytes of data in this packet, the
+ * returned value of nbytes can be ignored except if it is the
+ * last packet, in which case it is the number of bytes that were NOT
+ * written
+ */
+#define CL_WriteX 0x6A
+ /* WriteX(word nbytes, bytes data)
+ * return(word status, word nbytes)
+ */
+
+/* Reads 'nbytes' from the file/device specified by 'handle'.
+ *
+ * If nbytes <= DATASIZE then the read will occur in a single packet
+ * and the returned value of nbytes will be the number of bytes actually
+ * read and nbmore will be 0. If nbytes> DATASIZE then multiple packets
+ * will have to be used ie CL_Read followed by 1 or more CL_ReadX
+ * packets. In this case CL_Read will return nbytes read in the current
+ * packet and nbmore representing how many more bytes are expected to be
+ * read
+ * If the status word is non zero then the request has completed with an
+ * error. If the status word is 0xFFFFFFFF (-1) then an EOF condition
+ * has been reached.
+ */
+#define CL_Read 0x6B
+ /* Read(word handle, word nbytes)
+ * return(word status, word nbytes, word nbmore, bytes data)
+ */
+
+/* Read eXtension returns a continuation of the data that was opened for
+ * read in the earlier CL_Read. The return value nbytes is the number of
+ * data bytes in the packet, nbmore is the number of bytes more that are
+ * expected to be read in subsequent packets.
+ */
+#define CL_ReadX 0x6C
+ /* ReadX()
+ * return(word status, word nbytes, word nbmore, bytes data)
+ */
+
+/* Seeks to byte position 'posn' in the file/device specified by 'handle'.
+ */
+#define CL_Seek 0x6D
+ /* Seek(word handle, word posn)
+ * return(word status)
+ */
+
+/* Returns the current length of the file specified by 'handle' in 'len'.
+ * If an error occurs 'len' is set to -1.
+ */
+#define CL_Flen 0x6E
+ /* Flen(word handle)
+ * return(word len)
+ */
+
+/* Returns NoError if 'handle' specifies an interactive device, otherwise
+ * returns GenError
+ */
+#define CL_IsTTY 0x6F
+ /* IsTTY(word handle)
+ * return(word status)
+ */
+
+/* Returns a temporary host file name. The maximum length of a file name
+ * is passed to the host. The TargetID is some identifier from the target
+ * for this particular temporary filename. This value is could be used
+ * directly in the generation of the filename.
+ *
+ * If the host cannot create a suitable name or the generated name is too
+ * long then status is non zero. status will be NoError if the host can create
+ * a name.
+ */
+#define CL_TmpNam 0x70
+ /* TmpNam(word maxlength, word TargetID)
+ * return(word status, word nbytes, bytes fname)
+ */
+
+/* Note there is no message for Exit, EnterOS, InstallHandler or
+ * GenerateError as these will be supported entirely at the host end,
+ * or by the underlying Operating system.
+ */
+
+#define CL_UnknownReason (-1)
+
+extern unsigned int GetRaiseHandler( void );
+extern unsigned int SysLibraryHandler(unsigned int sysCode, unsigned int *args);
+extern void angel_SysLibraryInit(void);
+
+/*
+ * Function: Angel_IsSysHandlerRunning
+ * Purpose: return whether or not SysLibraryHandler is running
+ *
+ * No paramaters
+ *
+ * Returns 1 if SysLibraryHandler is running
+ * 0 otherwise
+ */
+extern int Angel_IsSysHandlerRunning(void);
+
+#ifdef ICEMAN2
+/* This function exists in an ICEman2 system only, and can be called by
+ * debug support code when the debugger tells it how much memory the
+ * target has. This will then be used to deal with the HEAPINFO SWI
+ */
+extern void angel_SetTopMem(unsigned addr);
+#endif
+
+#endif
+
diff --git a/gdb/rdi-share/tx.c b/gdb/rdi-share/tx.c
new file mode 100644
index 0000000..a52286c
--- /dev/null
+++ b/gdb/rdi-share/tx.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*-*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ * Project: ANGEL
+ *
+ * Title: Character based packet transmission engine
+ */
+
+#include <stdarg.h> /* ANSI varargs support */
+#include "angel.h" /* Angel system definitions */
+#include "endian.h" /* Endian independant memory access macros */
+#include "crc.h" /* crc generation definitions and headers */
+#include "rxtx.h"
+#include "channels.h"
+#include "buffers.h"
+#include "logging.h"
+
+/* definitions to describe the engines state */
+#define N_STX 0x0 /* first 2 bits for N_ */
+#define N_BODY 0x1
+#define N_ETX 0x2
+#define N_IDLE 0x3
+#define N_MASK 0x3 /* mask for the Encapsulator state */
+
+#define E_PLAIN (0x0 << 2) /* 3rd bit for E_ */
+#define E_ESC (0x1 << 2) /* 3rd bit for E_ */
+#define E_MASK (0x1 << 2) /* mask for the Escaper state */
+
+#define F_HEAD (0x0 << 3) /* 4th and 5th bits for F_ */
+#define F_DATA (0x1 << 3)
+#define F_CRC (0x1 << 4)
+#define F_MASK (0x3 << 3) /* mask for the Escaper state */
+
+static unsigned char escape(unsigned char ch_in, struct te_state *txstate);
+
+void Angel_TxEngineInit(const struct re_config *txconfig,
+ const struct data_packet *packet,
+ struct te_state *txstate){
+ IGNORE(packet);
+ txstate->tx_state = N_STX | E_PLAIN | F_HEAD;
+ txstate->field_c = 0;
+ txstate->encoded = 0;
+ txstate->config = txconfig;
+ txstate->crc = 0;
+}
+
+te_status Angel_TxEngine(const struct data_packet *packet,
+ struct te_state *txstate,
+ unsigned char *tx_ch){
+ /* TODO: gaurd on long/bad packets */
+ /*
+ * encapsulate the packet, framing has been moved from a seperate
+ * function into the encapsulation routine as it needed too much
+ * inherited state for it to be sensibly located elsewhere
+ */
+ switch ((txstate->tx_state) & N_MASK){
+ case N_STX:
+#ifdef DO_TRACE
+ __rt_trace("txe-stx ");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_BODY;
+ *tx_ch = txstate->config->stx;
+ txstate->field_c = 3; /* set up for the header */
+ txstate->crc = startCRC32; /* set up basic crc */
+ return TS_IN_PKT;
+ case N_BODY:{
+ switch (txstate->tx_state & F_MASK) {
+ case F_HEAD:
+#ifdef DO_TRACE
+ __rt_trace("txe-head ");
+#endif
+ if (txstate->field_c == 3) {
+ /* send type */
+ *tx_ch = escape(packet->type, txstate);
+ return TS_IN_PKT;
+ }
+ else {
+ *tx_ch = escape((packet->len >> (txstate->field_c - 1) * 8) & 0xff,
+ txstate);
+ if (txstate->field_c == 0) {
+ /* move on to the next state */
+ txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_DATA;
+ txstate->field_c = packet->len;
+ }
+ return TS_IN_PKT;
+ }
+ case F_DATA:
+#ifdef DO_TRACE
+ __rt_trace("txe-data ");
+#endif
+ *tx_ch = escape(packet->data[packet->len - txstate->field_c], txstate);
+ if (txstate->field_c == 0) {
+ /* move on to the next state */
+ txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_CRC;
+ txstate->field_c = 4;
+ }
+ return TS_IN_PKT;
+ case F_CRC:
+#ifdef DO_TRACE
+ __rt_trace("txe-crc ");
+#endif
+ *tx_ch = escape((txstate->crc >> ((txstate->field_c - 1) * 8)) & 0xff,
+ txstate);
+
+ if (txstate->field_c == 0) {
+#ifdef DO_TRACE
+ __rt_trace("txe crc = 0x%x\n", txstate->crc);
+#endif
+ /* move on to the next state */
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_ETX;
+ }
+ return TS_IN_PKT;
+ }
+ }
+ case N_ETX:
+#ifdef DO_TRACE
+ __rt_trace("txe-etx\n");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
+ *tx_ch = txstate->config->etx;
+ return TS_DONE_PKT;
+ default:
+#ifdef DEBUG
+ __rt_info("tx default\n");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
+ return TS_IDLE;
+ }
+ /* stop a silly -Wall warning */
+ return (te_status)-1;
+}
+
+/*
+ * crc generation occurs in the escape function because it is the only
+ * place where we know that we're putting a real char into the buffer
+ * rather than an escaped one.
+ * We must be careful here not to update the crc when we're sending it
+ */
+static unsigned char escape(unsigned char ch_in, struct te_state *txstate) {
+ if (((txstate->tx_state) & E_MASK) == E_ESC) {
+ /* char has been escaped so send the real char */
+#ifdef DO_TRACE
+ __rt_trace("txe-echar ");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_PLAIN;
+ txstate->field_c--;
+ if ((txstate->tx_state & F_MASK) != F_CRC)
+ txstate->crc = crc32( &ch_in, 1, txstate->crc);
+ return ch_in | serial_ESCAPE;
+ }
+ if ((ch_in < 32) && ((txstate->config->esc_set & (1 << ch_in)) != 0)) {
+ /* char needs escaping */
+#ifdef DO_TRACE
+ __rt_trace("txe-esc ");
+#endif
+ txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_ESC;
+ return txstate->config->esc;
+ }
+ /* must be a char that can be sent plain */
+ txstate->field_c--;
+ if ((txstate->tx_state & F_MASK) != F_CRC)
+ txstate->crc = crc32(&ch_in, 1, txstate->crc);
+ return ch_in;
+}
+
+/* EOF tx.c */
diff --git a/gdb/rdi-share/unixcomm.c b/gdb/rdi-share/unixcomm.c
new file mode 100644
index 0000000..7cb55e6
--- /dev/null
+++ b/gdb/rdi-share/unixcomm.c
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+
+#ifdef __hpux
+# define _POSIX_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#ifdef __hpux
+# define _TERMIOS_INCLUDED
+# include <sys/termio.h>
+# undef _TERMIOS_INCLUDED
+#else
+# include <termios.h>
+#endif
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef sun
+# include <sys/ioccom.h>
+# ifdef __svr4__
+# include <sys/bpp_io.h>
+# else
+# include <sbusdev/bpp_io.h>
+# endif
+#endif
+
+#ifdef BSD
+# ifdef sun
+# include <sys/ttydev.h>
+# endif
+# ifdef __alpha
+# include <sys/ioctl.h>
+# else
+# include <sys/filio.h>
+# endif
+#endif
+
+#ifdef __hpux
+# define _INCLUDE_HPUX_SOURCE
+# include <sys/ioctl.h>
+# undef _INCLUDE_HPUX_SOURCE
+#endif
+
+#include "host.h"
+#include "unixcomm.h"
+
+#define PP_TIMEOUT 1 /* seconds */
+
+#ifdef sun
+#define SERPORT1 "/dev/ttya"
+#define SERPORT2 "/dev/ttyb"
+#define PARPORT1 "/dev/bpp0"
+#define PARPORT2 "/dev/bpp1"
+#endif
+
+#ifdef __hpux
+#define SERPORT1 "/dev/tty00"
+#define SERPORT2 "/dev/tty01"
+#define PARPORT1 "/dev/ptr_parallel"
+#define PARPORT2 "/dev/ptr_parallel"
+#endif
+
+#ifdef __linux__
+#define SERPORT1 "/dev/cua0"
+#define SERPORT2 "/dev/cua1"
+#define PARPORT1 "/dev/par0"
+#define PARPORT2 "/dev/par1"
+#endif
+
+#ifdef _WIN32
+#define SERPORT1 "com1"
+#define SERPORT2 "com2"
+#define PARPORT1 "lpt1"
+#define PARPORT2 "lpt2"
+#endif
+
+/*
+ * Parallel port output pins, used for signalling to target
+ */
+
+#ifdef sun
+struct bpp_pins bp;
+#endif
+
+static int serpfd = -1;
+static int parpfd = -1;
+
+extern const char *Unix_MatchValidSerialDevice(const char *name)
+{
+ int i=0;
+ char *sername=NULL;
+
+ /* Accept no name as the default serial port */
+ if (name == NULL) {
+ return SERPORT1;
+ }
+
+ /* Look for the simple cases - 1,2,s,S,/dev/... first, and
+ * afterwards look for S=... clauses, which need parsing properly.
+ */
+
+ /* Accept /dev/tty* where * is limited */
+ if (strlen(name) == strlen(SERPORT1) && strncmp(name, "/dev/tty", 8) == 0) return name;
+
+ /* Accept "1" or "2" or "S" - S is equivalent to "1" */
+ if (strcmp(name, "1") == 0 ||
+ strcmp(name, "S") == 0 || strcmp(name, "s") == 0) {
+ return SERPORT1;
+ }
+ if (strcmp(name, "2") == 0) return SERPORT2;
+
+ /* It wasn't one of the simple cases, so now we have to parse it
+ * properly
+ */
+
+ do {
+ switch (name[i]) {
+ case ',':
+ /* Skip over commas */
+ i++;
+ break;
+
+ default:
+ return 0;
+ /* Unexpected character => error - not matched */
+
+ case 0:
+ /* End of string means return whatever we have matched */
+ return sername;
+
+ case 's':
+ case 'S':
+ case 'h':
+ case 'H': {
+ char ch = tolower(name[i]);
+ int j, continue_from, len;
+
+ /* If the next character is a comma or a NULL then this is
+ * a request for the default Serial port
+ */
+ if (name[++i] == 0 || name[i] == ',') {
+ if (ch=='s')
+ sername=SERPORT1;
+ break;
+ }
+
+ /* Next character must be an = */
+ if (name[i] != '=') return 0;
+ /* Search for the end of the port spec. (ends in NULL or ,) */
+ for (j= ++i; name[j] != 0 && name[j] != ','; j++)
+ ; /* Do nothing */
+ /* Notice whether this is the last thing to parse or not
+ * and also calaculate the length of the string
+ */
+ if (name[j] == '0') continue_from = -1;
+ else continue_from = j;
+ len=(j-i);
+
+ /* And now try to match the serial / parallel port */
+ switch (ch) {
+ case 's': {
+ /* Match serial port */
+ if (len==1) {
+ if (name[i]=='1')
+ sername=SERPORT1;
+ else if (name[i]=='2')
+ sername=SERPORT2;
+ } else if (len==strlen(SERPORT1)) {
+ if (strncmp(name+i,SERPORT1,strlen(SERPORT1)) == 0)
+ sername=SERPORT1;
+ else if (strncmp(name+i,SERPORT2,strlen(SERPORT2)) == 0)
+ sername=SERPORT2;
+ }
+
+ break;
+ }
+
+ case 'h':
+ /* We don't actually deal with the H case here, we just
+ * match it and allow it through.
+ */
+ break;
+ }
+
+ if (continue_from == -1) return sername;
+ i = continue_from;
+ break;
+ }
+ }
+ } while (1);
+
+ return 0;
+}
+
+
+extern int Unix_IsSerialInUse(void)
+{
+ if (serpfd >= 0)
+ return -1;
+
+ return 0;
+}
+
+extern int Unix_OpenSerial(const char *name)
+{
+#if defined(BSD)
+ serpfd = open(name, O_RDWR);
+#else
+ serpfd = open(name, O_RDWR | O_NONBLOCK);
+#endif
+
+ if (serpfd < 0) {
+ perror("open");
+ return -1;
+ }
+
+ return 0;
+}
+
+extern void Unix_CloseSerial(void)
+{
+ if (serpfd >= 0)
+ {
+ (void)close(serpfd);
+ serpfd = -1;
+ }
+}
+
+extern int Unix_ReadSerial(unsigned char *buf, int n, bool block)
+{
+ fd_set fdset;
+ struct timeval tv;
+ int err;
+
+ FD_ZERO(&fdset);
+ FD_SET(serpfd, &fdset);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = (block ? 10000 : 0);
+
+ err = select(serpfd + 1, &fdset, NULL, NULL, &tv);
+
+ if (err < 0 && errno != EINTR)
+ {
+#ifdef DEBUG
+ perror("select");
+#endif
+ panic("select failure");
+ return -1;
+ }
+ else if (err > 0 && FD_ISSET(serpfd, &fdset))
+ return read(serpfd, buf, n);
+ else /* err == 0 || FD_CLR(serpfd, &fdset) */
+ {
+ errno = ERRNO_FOR_BLOCKED_IO;
+ return -1;
+ }
+}
+
+extern int Unix_WriteSerial(unsigned char *buf, int n)
+{
+ return write(serpfd, buf, n);
+}
+
+extern void Unix_ResetSerial(void)
+{
+ struct termios terminfo;
+
+ tcgetattr(serpfd, &terminfo);
+#ifdef __CYGWIN32__
+ /* Expedient, but it works. */
+ terminfo.c_iflag = 0;
+ terminfo.c_oflag = 0;
+ terminfo.c_cflag = 48;
+ terminfo.c_lflag = 0;
+ terminfo.c_cc[VMIN] = 0;
+ terminfo.c_cc[VTIME] = 1;
+#else
+ terminfo.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN);
+ terminfo.c_iflag &= ~(IGNCR | INPCK | ISTRIP | ICRNL | BRKINT);
+ terminfo.c_iflag |= (IXON | IXOFF | IGNBRK);
+ terminfo.c_cflag = (terminfo.c_cflag & ~CSIZE) | CS8 | CREAD;
+ terminfo.c_cflag &= ~PARENB;
+ terminfo.c_cc[VMIN] = 1;
+ terminfo.c_cc[VTIME] = 0;
+ terminfo.c_oflag &= ~OPOST;
+#endif
+ tcsetattr(serpfd, TCSAFLUSH, &terminfo);
+}
+
+extern void Unix_SetSerialBaudRate(int baudrate)
+{
+ struct termios terminfo;
+
+ tcgetattr(serpfd, &terminfo);
+ cfsetospeed(&terminfo, baudrate);
+ cfsetispeed(&terminfo, baudrate);
+ tcsetattr(serpfd, TCSAFLUSH, &terminfo);
+}
+
+extern void Unix_ioctlNonBlocking(void)
+{
+#if defined(BSD)
+ int nonblockingIO = 1;
+ (void)ioctl(serpfd, FIONBIO, &nonblockingIO);
+
+ if (parpfd != -1)
+ (void)ioctl(parpfd, FIONBIO, &nonblockingIO);
+#endif
+}
+
+extern void Unix_IsValidParallelDevice(
+ const char *portstring, char **sername, char **parname)
+{
+ int i=0;
+ *sername=NULL;
+ *parname=NULL;
+
+ /* Do not recognise a NULL portstring */
+ if (portstring==NULL) return;
+
+ do {
+ switch (portstring[i]) {
+ case ',':
+ /* Skip over commas */
+ i++;
+ break;
+
+ default:
+ case 0:
+ /* End of string or bad characcter means we have finished */
+ return;
+
+ case 's':
+ case 'S':
+ case 'p':
+ case 'P':
+ case 'h':
+ case 'H': {
+ char ch = tolower(portstring[i]);
+ int j, continue_from, len;
+
+ /* If the next character is a comma or a NULL then this is
+ * a request for the default Serial or Parallel port
+ */
+ if (portstring[++i] == 0 || portstring[i] == ',') {
+ if (ch=='s') *sername=SERPORT1;
+ else if (ch=='p') *parname=PARPORT1;
+ break;
+ }
+
+ /* Next character must be an = */
+ if (portstring[i] != '=') return;
+ /* Search for the end of the port spec. (ends in NULL or ,) */
+ for (j= ++i; portstring[j] != 0 && portstring[j] != ','; j++)
+ ; /* Do nothing */
+ /* Notice whether this is the last thing to parse or not
+ * and also calaculate the length of the string
+ */
+ if (portstring[j] == '0') continue_from = -1;
+ else continue_from = j;
+ len=(j-i);
+
+ /* And now try to match the serial / parallel port */
+ switch (ch) {
+ case 's': {
+ /* Match serial port */
+ if (len==1) {
+ if (portstring[i]=='1') *sername=SERPORT1;
+ else if (portstring[i]=='2') *sername=SERPORT2;
+ } else if (len==strlen(SERPORT1)) {
+ if (strncmp(portstring+i,SERPORT1,strlen(SERPORT1)) == 0)
+ *sername=SERPORT1;
+ else if (strncmp(portstring+i,SERPORT2,strlen(SERPORT2)) == 0)
+ *sername=SERPORT2;
+ }
+ break;
+ }
+
+ case 'p': {
+ /* Match parallel port */
+ if (len==1) {
+ if (portstring[i]=='1') *parname=PARPORT1;
+ else if (portstring[i]=='2') *parname=PARPORT2;
+ } else if (len==strlen(PARPORT1)) {
+ if (strncmp(portstring+i,PARPORT1,strlen(PARPORT1)) == 0)
+ *parname=PARPORT1;
+ else if (strncmp(portstring+i,PARPORT2,strlen(PARPORT2)) == 0)
+ *parname=PARPORT2;
+ }
+ break;
+ }
+
+ case 'h':
+ /* We don't actually deal with the H case here, we just
+ * match it and allow it through.
+ */
+ break;
+ }
+
+ if (continue_from == -1) return;
+ i = continue_from;
+ break;
+ }
+ }
+ } while (1);
+ return; /* Will never get here */
+}
+
+extern int Unix_IsParallelInUse(void)
+{
+ if (parpfd >= 0)
+ return -1;
+
+ return 0;
+}
+
+extern int Unix_OpenParallel(const char *name)
+{
+#if defined(BSD)
+ parpfd = open(name, O_RDWR);
+#else
+ parpfd = open(name, O_RDWR | O_NONBLOCK);
+#endif
+
+ if (parpfd < 0)
+ {
+ char errbuf[256];
+
+ sprintf(errbuf, "open %s", name);
+ perror(errbuf);
+
+ return -1;
+ }
+
+ return 0;
+}
+
+extern void Unix_CloseParallel(void)
+{
+ if (parpfd >= 0)
+ {
+ (void)close(parpfd);
+ parpfd = -1;
+ }
+}
+
+
+extern unsigned int Unix_WriteParallel(unsigned char *buf, int n)
+{
+ int ngone;
+
+ if ((ngone = write(parpfd, buf, n)) < 0)
+ {
+ /*
+ * we ignore errors (except for debug purposes)
+ */
+#ifdef DEBUG
+ char errbuf[256];
+
+ sprintf(errbuf, "send_packet: write");
+ perror(errbuf);
+#endif
+ ngone = 0;
+ }
+
+ /* finished */
+ return (unsigned int)ngone;
+}
+
+
+#ifdef sun
+extern void Unix_ResetParallel(void)
+{
+ struct bpp_transfer_parms tp;
+
+#ifdef DEBUG
+ printf("serpar_reset\n");
+#endif
+
+ /*
+ * we need to set the parallel port up for BUSY handshaking,
+ * and select the timeout
+ */
+ if (ioctl(parpfd, BPPIOC_GETPARMS, &tp) < 0)
+ {
+#ifdef DEBUG
+ perror("ioctl(BPPIOCGETPARMS)");
+#endif
+ panic("serpar_reset: cannot get BPP parameters");
+ }
+
+ tp.write_handshake = BPP_BUSY_HS;
+ tp.write_timeout = PP_TIMEOUT;
+
+ if (ioctl(parpfd, BPPIOC_SETPARMS, &tp) < 0)
+ {
+#ifdef DEBUG
+ perror("ioctl(BPPIOC_SETPARMS)");
+#endif
+ panic("serpar_reset: cannot set BPP parameters");
+ }
+}
+
+#else
+
+/* Parallel not supported on HP */
+
+extern void Unix_ResetParallel(void)
+{
+}
+
+#endif
+
diff --git a/gdb/rdi-share/unixcomm.h b/gdb/rdi-share/unixcomm.h
new file mode 100644
index 0000000..baa6552
--- /dev/null
+++ b/gdb/rdi-share/unixcomm.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+#ifndef angsd_unixcomm_h
+#define angsd_unixcomm_h
+
+#include <errno.h>
+
+#if defined(BSD)
+# define ERRNO_FOR_BLOCKED_IO EWOULDBLOCK
+#else
+# define ERRNO_FOR_BLOCKED_IO EAGAIN
+#endif
+
+/*
+ * Function: Unix_MatchValidSerialDevice
+ * Purpose: check that the serial driver/port name is valid
+ * and return the actual device name if it is.
+ *
+ * Params:
+ * Input: name Name of device going to be used
+ *
+ * Returns:
+ * OK: Pointer to name of the device matched
+ * Error or unrecognised deivce: 0
+ */
+extern const char *Unix_MatchValidSerialDevice(const char *name);
+
+/*
+ * Function: Unix_IsSerialInUse
+ * Purpose: check whether the serial port is in use
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns:
+ * OK: 0 Serial device not in use
+ * Error: -1 Serial device in use
+ */
+extern int Unix_IsSerialInUse(void);
+
+/*
+ * Function: Unix_OpenSerial
+ * Purpose: open the serial port
+ *
+ * Params:
+ * Input: name Name of device to open
+ *
+ * Returns: Unix 'open' returns
+ */
+extern int Unix_OpenSerial(const char *name);
+
+/*
+ * Function: Unix_CloseSerial
+ * Purpose: close the serial port
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_CloseSerial(void);
+
+/*
+ * Function: Unix_ReadSerial
+ * Purpose: reads a specified number of bytes (or less) from the serial port
+ *
+ * Params:
+ * Input: buf Buffer to store read bytes
+ * n Maximum number of bytes to read
+ *
+ * Returns: Unix 'read' returns
+ */
+extern int Unix_ReadSerial(unsigned char *buf, int n, bool block);
+
+/*
+ * Function: Unix_WriteSerial
+ * Purpose: writes a specified number of bytes (or less) to the serial port
+ *
+ * Params:
+ * Input: buf Buffer to write bytes from
+ * n Maximum number of bytes to write
+ *
+ * Returns: Unix 'write' returns
+ */
+extern int Unix_WriteSerial(unsigned char *buf, int n);
+
+/*
+ * Function: Unix_ResetSerial
+ * Purpose: resets the serial port for another operation
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_ResetSerial(void);
+
+/*
+ * Function: Unix_SetSerialBaudRate
+ * Purpose: check that the serial driver/port name is valid
+ *
+ * Params:
+ * Input: baudrate termios value for baud rate
+ *
+ * Returns: Nothing
+ */
+extern void Unix_SetSerialBaudRate(int baudrate);
+
+/*
+ * Function: Unix_ioctlNonBlocking
+ * Purpose: sets the serial port to non-blocking IO
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_ioctlNonBlocking(void);
+
+/*
+ * Function: Unix_IsValidParallelDevice
+ * Purpose: check whether the combined serial and parallel device specification
+ * is ok, and return the ports selected
+ *
+ * Params:
+ * Input: portstring - is a string which specifies which serial
+ * and parallel ports are to be used. Can
+ * include s=<val> and p=<val> separated by a
+ * comma.
+ *
+ * Returns:
+ * Output: *sername - returns the device name of the chosen serial port
+ * *parname - returns the device name of the chosen parallel port
+ * If either of these is NULL on return then the match failed.
+ */
+extern void Unix_IsValidParallelDevice(
+ const char *portstring, char **sername, char **parname
+);
+
+/*
+ * Function: Unix_IsParallelInUse
+ * Purpose: check whether the parallel port is in use
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns:
+ * OK: 0 Parallel device not in use
+ * Error: -1 Parallel device in use
+ */
+extern int Unix_IsParallelInUse(void);
+
+/*
+ * Function: Unix_OpenParallel
+ * Purpose: open the parallel port
+ *
+ * Params:
+ * Input: name Name of device to open
+ *
+ * Returns: Unix 'open' returns
+ */
+extern int Unix_OpenParallel(const char *name);
+
+/*
+ * Function: Unix_CloseParallel
+ * Purpose: close the parallel port
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_CloseParallel(void);
+
+/*
+ * Function: Unix_WriteParallel
+ * Purpose: writes a specified number of bytes (or less) to the parallel port
+ *
+ * Params:
+ * Input: buf Buffer to write bytes from
+ * n Maximum number of bytes to write
+ *
+ * Returns: Unix 'write' returns
+ */
+extern unsigned int Unix_WriteParallel(unsigned char *buf, int n);
+
+/*
+ * Function: Unix_ResetParallel
+ * Purpose: resets the parallel port for another operation
+ *
+ * Params:
+ * Input: Nothing
+ *
+ * Returns: Nothing
+ */
+extern void Unix_ResetParallel(void);
+
+#endif /* ndef angsd_unixcomm_h */
+
+/* EOF unixcomm.h */