Applied patches from Tony.Thompson@arm.com to implement the Angel remote
debugging interface and resurrected associated RDI files.
This commit is contained in:
parent
d7ab10784a
commit
3a9c3d120f
54 changed files with 19554 additions and 10 deletions
|
@ -1,3 +1,15 @@
|
|||
Thu Jan 8 11:03:59 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* remote-rdp.c: Applied patches submitted by Tony.Thompson@arm.com
|
||||
to implement the Angel remote debugging interface.
|
||||
|
||||
* Makefile.in: Add build rules for remote-rdi.c and
|
||||
rdi-share/libangsd.a
|
||||
|
||||
* configure.tgt: Updated from source on branch.
|
||||
* config/arm/tm-arm.h: Updated from source on branch.
|
||||
* arm-tdep.c: Updated from source on branch.
|
||||
|
||||
Mon Jan 5 20:21:59 1998 Mark Alexander <marka@cygnus.com>
|
||||
|
||||
* monitor.h (MO_PRINT_PROGRAM_OUTPUT): Define.
|
||||
|
|
|
@ -163,6 +163,10 @@ WIN32LIBS = @WIN32LIBS@
|
|||
ENABLE_GDBTK= @ENABLE_GDBTK@
|
||||
ENABLE_IDE= @ENABLE_IDE@
|
||||
|
||||
LIBGUI = ../libgui/src/libgui.a
|
||||
|
||||
GUI_CFLAGS_X = -I$(srcdir)/../libgui/src
|
||||
|
||||
IDE_CFLAGS_X = -I$(srcdir)/../libide/src \
|
||||
`if [ x"$(ENABLE_IDE)" != x ] ; then \
|
||||
echo -DIDE -I$(srcdir)/../ilu/runtime/mainloop;\
|
||||
|
@ -179,7 +183,7 @@ IDE_DEPS = ../ilu/runtime/mainloop/libilu-Tk.a \
|
|||
../ilu/runtime/c/libilu-c.a ../ilu/runtime/kernel/libilu.a
|
||||
|
||||
IDE=$(IDE_X)
|
||||
IDE_CFLAGS=$(IDE_CFLAGS_X)
|
||||
IDE_CFLAGS=$(GUI_CFLAGS_X) $(IDE_CFLAGS_X)
|
||||
#end-sanitize-gdbtk
|
||||
|
||||
ENABLE_CFLAGS= @ENABLE_CFLAGS@
|
||||
|
@ -1359,6 +1363,19 @@ remote-adapt.o: remote-adapt.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
|||
remote-array.o: remote-array.c $(wait_h) $(defs_h) $(gdbcore_h) target.h \
|
||||
gdb_string.h $(command_h) serial.h monitor.h $(remote_utils_h)
|
||||
|
||||
remote-rdi.o: remote-rdi.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
||||
$(inferior_h) gdb_string.h
|
||||
|
||||
rdi-share/libangsd.a: force
|
||||
@dir=rdi-share; \
|
||||
if [ -f ./$${dir}/Makefile ] ; then \
|
||||
r=`pwd`; export r; \
|
||||
srcroot=`cd $(srcdir); pwd`; export srcroot; \
|
||||
(cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) all); \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
|
||||
remote-rdp.o: remote-rdp.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
||||
$(inferior_h) gdb_string.h
|
||||
|
||||
|
|
|
@ -48,7 +48,17 @@ alpha-*-linux*) gdb_target=alpha-linux ;;
|
|||
|
||||
arc-*-*) gdb_target=arc ;;
|
||||
|
||||
arm-*-* | thumb-*-*) gdb_target=arm ;;
|
||||
arm-*-* | thumb-*-*) gdb_target=arm
|
||||
|
||||
# rdi doesn't work for wingdb yet
|
||||
case $gdb_host in
|
||||
windows) ;;
|
||||
*)
|
||||
configdirs="$configdirs rdi-share"
|
||||
CONFIG_OBS="$CONFIG_OBS remote-rdi.o rdi-share/libangsd.a"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
c1-*-*) gdb_target=convex ;;
|
||||
c2-*-*) gdb_target=convex ;;
|
||||
|
|
165
gdb/rdi-share/Makefile.in
Normal file
165
gdb/rdi-share/Makefile.in
Normal file
|
@ -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".
|
6
gdb/rdi-share/README.CYGNUS
Normal file
6
gdb/rdi-share/README.CYGNUS
Normal file
|
@ -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.
|
2528
gdb/rdi-share/adp.h
Normal file
2528
gdb/rdi-share/adp.h
Normal file
File diff suppressed because it is too large
Load diff
74
gdb/rdi-share/adperr.h
Normal file
74
gdb/rdi-share/adperr.h
Normal file
|
@ -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 */
|
177
gdb/rdi-share/angel.h
Normal file
177
gdb/rdi-share/angel.h
Normal file
|
@ -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 */
|
2672
gdb/rdi-share/ardi.c
Normal file
2672
gdb/rdi-share/ardi.c
Normal file
File diff suppressed because it is too large
Load diff
85
gdb/rdi-share/ardi.h
Normal file
85
gdb/rdi-share/ardi.h
Normal file
|
@ -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);
|
1452
gdb/rdi-share/armdbg.h
Normal file
1452
gdb/rdi-share/armdbg.h
Normal file
File diff suppressed because it is too large
Load diff
111
gdb/rdi-share/buffers.h
Normal file
111
gdb/rdi-share/buffers.h
Normal file
|
@ -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 */
|
57
gdb/rdi-share/bytesex.c
Normal file
57
gdb/rdi-share/bytesex.c
Normal file
|
@ -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;
|
||||
}
|
42
gdb/rdi-share/bytesex.h
Normal file
42
gdb/rdi-share/bytesex.h
Normal file
|
@ -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
|
50
gdb/rdi-share/chandefs.h
Normal file
50
gdb/rdi-share/chandefs.h
Normal file
|
@ -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 */
|
384
gdb/rdi-share/channels.h
Normal file
384
gdb/rdi-share/channels.h
Normal file
|
@ -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 */
|
57
gdb/rdi-share/chanpriv.h
Normal file
57
gdb/rdi-share/chanpriv.h
Normal file
|
@ -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 */
|
44
gdb/rdi-share/configure.in
Normal file
44
gdb/rdi-share/configure.in
Normal file
|
@ -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:
|
257
gdb/rdi-share/crc.c
Normal file
257
gdb/rdi-share/crc.c
Normal file
|
@ -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 */
|
90
gdb/rdi-share/crc.h
Normal file
90
gdb/rdi-share/crc.h
Normal file
|
@ -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 */
|
54
gdb/rdi-share/dbg_conf.h
Normal file
54
gdb/rdi-share/dbg_conf.h
Normal file
|
@ -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
|
62
gdb/rdi-share/dbg_cp.h
Normal file
62
gdb/rdi-share/dbg_cp.h
Normal file
|
@ -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
|
56
gdb/rdi-share/dbg_hif.h
Normal file
56
gdb/rdi-share/dbg_hif.h
Normal file
|
@ -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
|
511
gdb/rdi-share/dbg_rdi.h
Normal file
511
gdb/rdi-share/dbg_rdi.h
Normal file
|
@ -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
|
260
gdb/rdi-share/devclnt.h
Normal file
260
gdb/rdi-share/devclnt.h
Normal file
|
@ -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 */
|
104
gdb/rdi-share/devices.h
Normal file
104
gdb/rdi-share/devices.h
Normal file
|
@ -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 */
|
400
gdb/rdi-share/devsw.c
Normal file
400
gdb/rdi-share/devsw.c
Normal file
|
@ -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 */
|
268
gdb/rdi-share/devsw.h
Normal file
268
gdb/rdi-share/devsw.h
Normal file
|
@ -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 */
|
34
gdb/rdi-share/drivers.c
Normal file
34
gdb/rdi-share/drivers.c
Normal file
|
@ -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 */
|
193
gdb/rdi-share/drivers.h
Normal file
193
gdb/rdi-share/drivers.h
Normal file
|
@ -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 */
|
125
gdb/rdi-share/endian.h
Normal file
125
gdb/rdi-share/endian.h
Normal file
|
@ -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 */
|
725
gdb/rdi-share/etherdrv.c
Normal file
725
gdb/rdi-share/etherdrv.c
Normal file
|
@ -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 */
|
99
gdb/rdi-share/ethernet.h
Normal file
99
gdb/rdi-share/ethernet.h
Normal file
|
@ -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 */
|
222
gdb/rdi-share/host.h
Normal file
222
gdb/rdi-share/host.h
Normal file
|
@ -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 */
|
1060
gdb/rdi-share/hostchan.c
Normal file
1060
gdb/rdi-share/hostchan.c
Normal file
File diff suppressed because it is too large
Load diff
300
gdb/rdi-share/hostchan.h
Normal file
300
gdb/rdi-share/hostchan.h
Normal file
|
@ -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 */
|
915
gdb/rdi-share/hsys.c
Normal file
915
gdb/rdi-share/hsys.c
Normal file
|
@ -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 */
|
101
gdb/rdi-share/hsys.h
Normal file
101
gdb/rdi-share/hsys.h
Normal file
|
@ -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 */
|
369
gdb/rdi-share/logging.c
Normal file
369
gdb/rdi-share/logging.c
Normal file
|
@ -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 */
|
121
gdb/rdi-share/logging.h
Normal file
121
gdb/rdi-share/logging.h
Normal file
|
@ -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 */
|
282
gdb/rdi-share/msgbuild.c
Normal file
282
gdb/rdi-share/msgbuild.c
Normal file
|
@ -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 */
|
75
gdb/rdi-share/msgbuild.h
Normal file
75
gdb/rdi-share/msgbuild.h
Normal file
|
@ -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 */
|
325
gdb/rdi-share/params.c
Normal file
325
gdb/rdi-share/params.c
Normal file
|
@ -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 */
|
181
gdb/rdi-share/params.h
Normal file
181
gdb/rdi-share/params.h
Normal file
|
@ -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 */
|
361
gdb/rdi-share/rx.c
Normal file
361
gdb/rdi-share/rx.c
Normal file
|
@ -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 */
|
263
gdb/rdi-share/rxtx.h
Normal file
263
gdb/rdi-share/rxtx.h
Normal file
|
@ -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 */
|
649
gdb/rdi-share/serdrv.c
Normal file
649
gdb/rdi-share/serdrv.c
Normal file
|
@ -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
|
||||
};
|
730
gdb/rdi-share/serpardr.c
Normal file
730
gdb/rdi-share/serpardr.c
Normal file
|
@ -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 */
|
319
gdb/rdi-share/sys.h
Normal file
319
gdb/rdi-share/sys.h
Normal file
|
@ -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
|
||||
|
176
gdb/rdi-share/tx.c
Normal file
176
gdb/rdi-share/tx.c
Normal file
|
@ -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 */
|
535
gdb/rdi-share/unixcomm.c
Normal file
535
gdb/rdi-share/unixcomm.c
Normal file
|
@ -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
|
||||
|
212
gdb/rdi-share/unixcomm.h
Normal file
212
gdb/rdi-share/unixcomm.h
Normal file
|
@ -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 */
|
966
gdb/remote-rdi.c
Normal file
966
gdb/remote-rdi.c
Normal file
|
@ -0,0 +1,966 @@
|
|||
/* GDB interface to ARM RDI library.
|
||||
Copyright 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdb_string.h"
|
||||
#include <fcntl.h>
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
#include "target.h"
|
||||
#include "wait.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "objfiles.h"
|
||||
#include "gdb-stabs.h"
|
||||
#include "gdbthread.h"
|
||||
#include "gdbcore.h"
|
||||
|
||||
#ifdef USG
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "rdi-share/ardi.h"
|
||||
#include "rdi-share/adp.h"
|
||||
#include "rdi-share/hsys.h"
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
static void arm_rdi_files_info PARAMS ((struct target_ops *ignore));
|
||||
|
||||
static int arm_rdi_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
|
||||
int len, int should_write,
|
||||
struct target_ops *target));
|
||||
|
||||
static void arm_rdi_prepare_to_store PARAMS ((void));
|
||||
|
||||
static void arm_rdi_fetch_registers PARAMS ((int regno));
|
||||
|
||||
static void arm_rdi_resume PARAMS ((int pid, int step,
|
||||
enum target_signal siggnal));
|
||||
|
||||
static int arm_rdi_start_remote PARAMS ((char *dummy));
|
||||
|
||||
static void arm_rdi_open PARAMS ((char *name, int from_tty));
|
||||
|
||||
static void arm_rdi_create_inferior PARAMS ((char *exec_file, char *args,
|
||||
char **env));
|
||||
|
||||
static void arm_rdi_close PARAMS ((int quitting));
|
||||
|
||||
static void arm_rdi_store_registers PARAMS ((int regno));
|
||||
|
||||
static void arm_rdi_mourn PARAMS ((void));
|
||||
|
||||
static void arm_rdi_send PARAMS ((char *buf));
|
||||
|
||||
static int arm_rdi_wait PARAMS ((int pid, struct target_waitstatus *status));
|
||||
|
||||
static void arm_rdi_kill PARAMS ((void));
|
||||
|
||||
static void arm_rdi_detach PARAMS ((char *args, int from_tty));
|
||||
|
||||
static void arm_rdi_interrupt PARAMS ((int signo));
|
||||
|
||||
static void arm_rdi_interrupt_twice PARAMS ((int signo));
|
||||
|
||||
static void interrupt_query PARAMS ((void));
|
||||
|
||||
static int arm_rdi_insert_breakpoint PARAMS ((CORE_ADDR, char *));
|
||||
|
||||
static int arm_rdi_remove_breakpoint PARAMS ((CORE_ADDR, char *));
|
||||
|
||||
static char *rdi_error_message PARAMS ((int err));
|
||||
|
||||
static enum target_signal rdi_error_signal PARAMS ((int err));
|
||||
|
||||
extern struct target_ops arm_rdi_ops; /* Forward decl */
|
||||
|
||||
static struct Dbg_ConfigBlock gdb_config;
|
||||
|
||||
static struct Dbg_HostosInterface gdb_hostif;
|
||||
|
||||
static int max_load_size;
|
||||
|
||||
static int execute_status;
|
||||
|
||||
/* A little list of breakpoints that have been set. */
|
||||
|
||||
static struct local_bp_list_entry {
|
||||
CORE_ADDR addr;
|
||||
PointHandle point;
|
||||
struct local_bp_list_entry *next;
|
||||
} *local_bp_list;
|
||||
|
||||
|
||||
/* Stub for catch_errors. */
|
||||
|
||||
static int
|
||||
arm_rdi_start_remote (dummy)
|
||||
char *dummy;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Helper callbacks for the "host interface" structure. RDI functions call
|
||||
these to forward output from the target system and so forth. */
|
||||
|
||||
void
|
||||
voiddummy()
|
||||
{
|
||||
printf("void dummy\n");
|
||||
}
|
||||
|
||||
static void
|
||||
myprint (arg, format, ap)
|
||||
PTR arg;
|
||||
const char *format;
|
||||
va_list ap;
|
||||
{
|
||||
vfprintf (stdout, format, ap);
|
||||
}
|
||||
|
||||
static void
|
||||
mywritec (arg, c)
|
||||
PTR arg;
|
||||
int c;
|
||||
{
|
||||
fputc (c, (FILE *) arg);
|
||||
}
|
||||
|
||||
static int
|
||||
mywrite (arg, buffer, len)
|
||||
PTR arg;
|
||||
char const *buffer;
|
||||
int len;
|
||||
{
|
||||
return fwrite (buffer, 1, len, stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
mypause (arg)
|
||||
PTR arg;
|
||||
{
|
||||
}
|
||||
|
||||
/* These last two are tricky as we have to handle the special case of
|
||||
being interrupted more carefully */
|
||||
|
||||
static int
|
||||
myreadc (arg)
|
||||
PTR arg;
|
||||
{
|
||||
return fgetc (stdin);
|
||||
}
|
||||
|
||||
static char *
|
||||
mygets (arg, buffer, len)
|
||||
PTR arg;
|
||||
char *buffer;
|
||||
int len;
|
||||
{
|
||||
return fgets(buffer, len, stdin);
|
||||
}
|
||||
|
||||
/* Open a connection to a remote debugger. NAME is the filename used
|
||||
for communication. */
|
||||
|
||||
static void
|
||||
arm_rdi_open (name, from_tty)
|
||||
char *name;
|
||||
int from_tty;
|
||||
{
|
||||
int rslt, i;
|
||||
unsigned long arg1, arg2;
|
||||
|
||||
if (name == NULL)
|
||||
error ("To open an RDI connection, you need to specify what serial\n\
|
||||
device is attached to the remote system (e.g. /dev/ttya).");
|
||||
|
||||
/* Make the basic low-level connection. */
|
||||
|
||||
rslt = Adp_OpenDevice (NULL, NULL, 1);
|
||||
|
||||
if (rslt != adp_ok)
|
||||
error ("Could not open port");
|
||||
|
||||
gdb_config.bytesex = 2 | (target_byte_order == BIG_ENDIAN ? 1 : 0);
|
||||
gdb_config.fpe = 1;
|
||||
gdb_config.rditype = 2;
|
||||
gdb_config.heartbeat_on = 1;
|
||||
gdb_config.flags = 2;
|
||||
|
||||
gdb_hostif.dbgprint = myprint;
|
||||
gdb_hostif.dbgpause = mypause;
|
||||
gdb_hostif.dbgarg = stdout;
|
||||
gdb_hostif.writec = mywritec;
|
||||
gdb_hostif.readc = myreadc;
|
||||
gdb_hostif.write = mywrite;
|
||||
gdb_hostif.gets = mygets;
|
||||
gdb_hostif.hostosarg = stdout;
|
||||
gdb_hostif.reset = voiddummy;
|
||||
|
||||
rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
|
||||
if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
|
||||
; /* do nothing, this is the expected return */
|
||||
else if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
|
||||
rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
rslt = angel_RDI_info (RDIInfo_DownLoad, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
max_load_size = arg1;
|
||||
|
||||
push_target (&arm_rdi_ops);
|
||||
|
||||
target_fetch_registers (-1);
|
||||
|
||||
rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
|
||||
arg1 = 0x13b;
|
||||
rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
|
||||
arg1 = (unsigned long) "";
|
||||
rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
|
||||
/* Clear out any existing records of breakpoints. */
|
||||
{
|
||||
struct local_bp_list_entry *entry, *preventry = NULL;
|
||||
|
||||
for (entry = local_bp_list; entry != NULL; entry = entry->next)
|
||||
{
|
||||
if (preventry)
|
||||
free (preventry);
|
||||
}
|
||||
}
|
||||
|
||||
printf_filtered ("Connected to ARM RDI target.\n");
|
||||
}
|
||||
|
||||
/* Start an inferior process and set inferior_pid to its pid.
|
||||
EXEC_FILE is the file to run.
|
||||
ARGS is a string containing the arguments to the program.
|
||||
ENV is the environment vector to pass. Errors reported with error().
|
||||
On VxWorks and various standalone systems, we ignore exec_file. */
|
||||
/* This is called not only when we first attach, but also when the
|
||||
user types "run" after having attached. */
|
||||
|
||||
static void
|
||||
arm_rdi_create_inferior (exec_file, args, env)
|
||||
char *exec_file;
|
||||
char *args;
|
||||
char **env;
|
||||
{
|
||||
int len, rslt;
|
||||
unsigned long arg1, arg2;
|
||||
char *arg_buf;
|
||||
CORE_ADDR entry_point;
|
||||
|
||||
if (exec_file == 0 || exec_bfd == 0)
|
||||
error ("No exec file specified.");
|
||||
|
||||
entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
|
||||
|
||||
arm_rdi_kill ();
|
||||
remove_breakpoints ();
|
||||
init_wait_for_inferior ();
|
||||
|
||||
len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
|
||||
arg_buf = (char *) alloca (len);
|
||||
arg_buf[0] = '\0';
|
||||
strcat (arg_buf, exec_file);
|
||||
strcat (arg_buf, " ");
|
||||
strcat (arg_buf, args);
|
||||
|
||||
inferior_pid = 42;
|
||||
insert_breakpoints (); /* Needed to get correct instruction in cache */
|
||||
|
||||
if ( env != NULL)
|
||||
{
|
||||
while (*env)
|
||||
{
|
||||
if (strncmp(*env, "MEMSIZE=", sizeof("MEMSIZE=")-1)==0)
|
||||
{
|
||||
unsigned long top_of_memory;
|
||||
char *end_of_num;
|
||||
|
||||
/* Set up memory limit */
|
||||
top_of_memory = strtoul(*env + sizeof("MEMSIZE=")-1,
|
||||
&end_of_num, 0);
|
||||
printf_filtered ("Setting top-of-memory to 0x%x\n",
|
||||
top_of_memory);
|
||||
|
||||
rslt=angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
}
|
||||
env++;
|
||||
}
|
||||
}
|
||||
|
||||
arg1 = (unsigned long) arg_buf;
|
||||
rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *)arg_buf, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
|
||||
proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
|
||||
}
|
||||
|
||||
/* This takes a program previously attached to and detaches it. After
|
||||
this is done, GDB can be used to debug some other program. We
|
||||
better not have left any breakpoints in the target program or it'll
|
||||
die when it hits one. */
|
||||
|
||||
static void
|
||||
arm_rdi_detach (args, from_tty)
|
||||
char *args;
|
||||
int from_tty;
|
||||
{
|
||||
/* (anything to do?) */
|
||||
}
|
||||
|
||||
/* Clean up connection to a remote debugger. */
|
||||
|
||||
static void
|
||||
arm_rdi_close (quitting)
|
||||
int quitting;
|
||||
{
|
||||
int rslt;
|
||||
|
||||
rslt = angel_RDI_close ();
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell the remote machine to resume. */
|
||||
|
||||
static void
|
||||
arm_rdi_resume (pid, step, siggnal)
|
||||
int pid, step;
|
||||
enum target_signal siggnal;
|
||||
{
|
||||
int rslt;
|
||||
PointHandle point;
|
||||
|
||||
if (0 /* turn on when hardware supports single-stepping */)
|
||||
{
|
||||
rslt = angel_RDI_step (1, &point);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char handle[4];
|
||||
CORE_ADDR pc;
|
||||
|
||||
if (step)
|
||||
{
|
||||
pc = read_register (PC_REGNUM);
|
||||
pc = arm_get_next_pc (pc);
|
||||
arm_rdi_insert_breakpoint (pc, handle);
|
||||
}
|
||||
execute_status = rslt = angel_RDI_execute (&point);
|
||||
if (rslt == RDIError_BreakpointReached)
|
||||
;
|
||||
else if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
if (step)
|
||||
{
|
||||
arm_rdi_remove_breakpoint (pc, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send ^C to target to halt it. Target will respond, and send us a
|
||||
packet. */
|
||||
|
||||
static void
|
||||
arm_rdi_interrupt (signo)
|
||||
int signo;
|
||||
{
|
||||
}
|
||||
|
||||
static void (*ofunc)();
|
||||
|
||||
/* The user typed ^C twice. */
|
||||
static void
|
||||
arm_rdi_interrupt_twice (signo)
|
||||
int signo;
|
||||
{
|
||||
}
|
||||
|
||||
/* Ask the user what to do when an interrupt is received. */
|
||||
|
||||
static void
|
||||
interrupt_query ()
|
||||
{
|
||||
}
|
||||
|
||||
/* Wait until the remote machine stops, then return, storing status in
|
||||
STATUS just as `wait' would. Returns "pid" (though it's not clear
|
||||
what, if anything, that means in the case of this target). */
|
||||
|
||||
static int
|
||||
arm_rdi_wait (pid, status)
|
||||
int pid;
|
||||
struct target_waitstatus *status;
|
||||
{
|
||||
status->kind = execute_status == RDIError_NoError ?
|
||||
TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED;
|
||||
|
||||
/* convert stopped code from target into right signal */
|
||||
status->value.sig = rdi_error_signal ( execute_status );
|
||||
|
||||
return inferior_pid;
|
||||
}
|
||||
|
||||
/* Read the remote registers into the block REGS. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
arm_rdi_fetch_registers (regno)
|
||||
int regno;
|
||||
{
|
||||
int rslt, rdi_regmask;
|
||||
unsigned long rawreg, rawregs[32];
|
||||
char cookedreg[4];
|
||||
|
||||
if (regno == -1)
|
||||
{
|
||||
rslt = angel_RDI_CPUread (255, 0x27fff, rawregs);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
|
||||
for (regno = 0; regno < 15; regno++)
|
||||
{
|
||||
store_unsigned_integer (cookedreg, 4, rawregs[regno]);
|
||||
supply_register (regno, (char *) cookedreg);
|
||||
}
|
||||
store_unsigned_integer (cookedreg, 4, rawregs[15]);
|
||||
supply_register (PS_REGNUM, (char *) cookedreg);
|
||||
arm_rdi_fetch_registers (PC_REGNUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (regno == PC_REGNUM)
|
||||
rdi_regmask = RDIReg_PC;
|
||||
else if (regno == PS_REGNUM)
|
||||
rdi_regmask = RDIReg_CPSR;
|
||||
else if (regno < 0 || regno > 15)
|
||||
{
|
||||
rawreg = 0;
|
||||
supply_register (regno, (char *) &rawreg);
|
||||
return;
|
||||
}
|
||||
else
|
||||
rdi_regmask = 1 << regno;
|
||||
|
||||
rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
store_unsigned_integer (cookedreg, 4, rawreg);
|
||||
supply_register (regno, (char *) cookedreg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
arm_rdi_prepare_to_store ()
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
/* Store register REGNO, or all registers if REGNO == -1, from the contents
|
||||
of REGISTERS. FIXME: ignores errors. */
|
||||
|
||||
static void
|
||||
arm_rdi_store_registers (regno)
|
||||
int regno;
|
||||
{
|
||||
int rslt, rdi_regmask;
|
||||
|
||||
/* These need to be able to take 'floating point register' contents */
|
||||
unsigned long rawreg[3], rawerreg[3];
|
||||
|
||||
if (regno == -1)
|
||||
{
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
arm_rdi_store_registers (regno);
|
||||
}
|
||||
else
|
||||
{
|
||||
read_register_gen (regno, (char *) rawreg);
|
||||
/* RDI manipulates data in host byte order, so convert now. */
|
||||
store_unsigned_integer (rawerreg, 4, rawreg[0]);
|
||||
|
||||
if (regno == PC_REGNUM)
|
||||
rdi_regmask = RDIReg_PC;
|
||||
else if (regno == PS_REGNUM)
|
||||
rdi_regmask = RDIReg_CPSR;
|
||||
else if (regno < 0 || regno > 15)
|
||||
return;
|
||||
else
|
||||
rdi_regmask = 1 << regno;
|
||||
|
||||
rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read or write LEN bytes from inferior memory at MEMADDR,
|
||||
transferring to or from debugger address MYADDR. Write to inferior
|
||||
if SHOULD_WRITE is nonzero. Returns length of data written or
|
||||
read; 0 for error. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
arm_rdi_xfer_memory(memaddr, myaddr, len, should_write, target)
|
||||
CORE_ADDR memaddr;
|
||||
char *myaddr;
|
||||
int len;
|
||||
int should_write;
|
||||
struct target_ops *target; /* ignored */
|
||||
{
|
||||
int rslt, i;
|
||||
|
||||
if (should_write)
|
||||
{
|
||||
rslt = angel_RDI_write (myaddr, memaddr, &len);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rslt = angel_RDI_read (memaddr, myaddr, &len);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Display random info collected from the target. */
|
||||
|
||||
static void
|
||||
arm_rdi_files_info (ignore)
|
||||
struct target_ops *ignore;
|
||||
{
|
||||
char *file = "nothing";
|
||||
int rslt;
|
||||
unsigned long arg1, arg2;
|
||||
|
||||
rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
if (arg1 & (1 << 15))
|
||||
printf_filtered ("Target supports Thumb code.\n");
|
||||
if (arg1 & (1 << 14))
|
||||
printf_filtered ("Target can do profiling.\n");
|
||||
if (arg1 & (1 << 4))
|
||||
printf_filtered ("Target is real hardware.\n");
|
||||
|
||||
rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
|
||||
|
||||
rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
else
|
||||
printf_filtered ("Target includes an EmbeddedICE.\n");
|
||||
}
|
||||
|
||||
static void
|
||||
arm_rdi_kill ()
|
||||
{
|
||||
int rslt;
|
||||
|
||||
rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
arm_rdi_mourn_inferior ()
|
||||
{
|
||||
unpush_target (&arm_rdi_ops);
|
||||
generic_mourn_inferior ();
|
||||
}
|
||||
|
||||
/* While the RDI library keeps track of its own breakpoints, we need
|
||||
to remember "handles" so that we can delete them later. Since
|
||||
breakpoints get used for stepping, be careful not to leak memory
|
||||
here. */
|
||||
|
||||
static int
|
||||
arm_rdi_insert_breakpoint (addr, contents_cache)
|
||||
CORE_ADDR addr;
|
||||
char *contents_cache;
|
||||
{
|
||||
int rslt;
|
||||
PointHandle point;
|
||||
struct local_bp_list_entry *entry;
|
||||
int type = RDIPoint_EQ;
|
||||
|
||||
if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
|
||||
type |= RDIPoint_16Bit;
|
||||
rslt = angel_RDI_setbreak (addr, type, 0, &point);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
entry =
|
||||
(struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
|
||||
entry->addr = addr;
|
||||
entry->point = point;
|
||||
entry->next = local_bp_list;
|
||||
local_bp_list = entry;
|
||||
return rslt;
|
||||
}
|
||||
|
||||
static int
|
||||
arm_rdi_remove_breakpoint (addr, contents_cache)
|
||||
CORE_ADDR addr;
|
||||
char *contents_cache;
|
||||
{
|
||||
int rslt;
|
||||
PointHandle point;
|
||||
struct local_bp_list_entry *entry, *preventry;
|
||||
|
||||
for (entry = local_bp_list; entry != NULL; entry = entry->next)
|
||||
{
|
||||
if (entry->addr == addr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
preventry = entry;
|
||||
}
|
||||
if (entry)
|
||||
{
|
||||
rslt = angel_RDI_clearbreak (entry->point);
|
||||
if (rslt)
|
||||
{
|
||||
printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
|
||||
}
|
||||
/* Delete the breakpoint entry locally. */
|
||||
if (entry == local_bp_list)
|
||||
{
|
||||
local_bp_list = entry->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
preventry->next = entry->next;
|
||||
}
|
||||
free (entry);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
rdi_error_message (err)
|
||||
int err;
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case RDIError_NoError:
|
||||
return "no error";
|
||||
case RDIError_Reset:
|
||||
return "debuggee reset";
|
||||
case RDIError_UndefinedInstruction:
|
||||
return "undefined instruction";
|
||||
case RDIError_SoftwareInterrupt:
|
||||
return "SWI trapped";
|
||||
case RDIError_PrefetchAbort:
|
||||
return "prefetch abort, execution ran into unmapped memory?";
|
||||
case RDIError_DataAbort:
|
||||
return "data abort, no memory at specified address?";
|
||||
case RDIError_AddressException:
|
||||
return "address exception, access >26bit in 26bit mode";
|
||||
case RDIError_IRQ:
|
||||
return "IRQ, interrupt trapped";
|
||||
case RDIError_FIQ:
|
||||
return "FIQ, fast interrupt trapped";
|
||||
case RDIError_Error:
|
||||
return "a miscellaneous type of error";
|
||||
case RDIError_BranchThrough0:
|
||||
return "branch through location 0";
|
||||
case RDIError_NotInitialised:
|
||||
return "internal error, RDI_open not called first";
|
||||
case RDIError_UnableToInitialise:
|
||||
return "internal error, target world is broken";
|
||||
case RDIError_WrongByteSex:
|
||||
return "See Operator: WrongByteSex";
|
||||
case RDIError_UnableToTerminate:
|
||||
return "See Operator: Unable to Terminate";
|
||||
case RDIError_BadInstruction:
|
||||
return "bad instruction, illegal to execute this instruction";
|
||||
case RDIError_IllegalInstruction:
|
||||
return "illegal instruction, the effect of executing it is undefined";
|
||||
case RDIError_BadCPUStateSetting:
|
||||
return "internal error, tried to set SPSR of user mode";
|
||||
case RDIError_UnknownCoPro:
|
||||
return "unknown co-processor";
|
||||
case RDIError_UnknownCoProState:
|
||||
return "cannot execute co-processor request";
|
||||
case RDIError_BadCoProState:
|
||||
return "recognizably broken co-processor request";
|
||||
case RDIError_BadPointType:
|
||||
return "internal error, bad point yype";
|
||||
case RDIError_UnimplementedType:
|
||||
return "internal error, unimplemented type";
|
||||
case RDIError_BadPointSize:
|
||||
return "internal error, bad point size";
|
||||
case RDIError_UnimplementedSize:
|
||||
return "internal error, unimplemented size";
|
||||
case RDIError_NoMorePoints:
|
||||
return "last break/watch point was used";
|
||||
case RDIError_BreakpointReached:
|
||||
return "breakpoint reached";
|
||||
case RDIError_WatchpointAccessed:
|
||||
return "watchpoint accessed";
|
||||
case RDIError_NoSuchPoint:
|
||||
return "attempted to clear non-existent break/watch point";
|
||||
case RDIError_ProgramFinishedInStep:
|
||||
return "end of the program reached while stepping";
|
||||
case RDIError_UserInterrupt:
|
||||
return "you pressed Escape";
|
||||
case RDIError_CantSetPoint:
|
||||
return "no more break/watch points available";
|
||||
case RDIError_IncompatibleRDILevels:
|
||||
return "incompatible RDI levels";
|
||||
case RDIError_LittleEndian:
|
||||
return "debuggee is little endian";
|
||||
case RDIError_BigEndian:
|
||||
return "debuggee is big endian";
|
||||
case RDIError_SoftInitialiseError:
|
||||
return "recoverable error in RDI initialization";
|
||||
case RDIError_InsufficientPrivilege:
|
||||
return "internal error, supervisor state not accessible to monitor";
|
||||
case RDIError_UnimplementedMessage:
|
||||
return "internal error, unimplemented message";
|
||||
case RDIError_UndefinedMessage:
|
||||
return "internal error, undefined message";
|
||||
default:
|
||||
return "undefined error message, should reset target";
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the ARM error messages to signals that GDB knows about. */
|
||||
|
||||
static enum target_signal
|
||||
rdi_error_signal (err)
|
||||
int err;
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case RDIError_NoError:
|
||||
return 0;
|
||||
case RDIError_Reset:
|
||||
return TARGET_SIGNAL_TERM; /* ??? */
|
||||
case RDIError_UndefinedInstruction:
|
||||
return TARGET_SIGNAL_ILL;
|
||||
case RDIError_SoftwareInterrupt:
|
||||
case RDIError_PrefetchAbort:
|
||||
case RDIError_DataAbort:
|
||||
return TARGET_SIGNAL_TRAP;
|
||||
case RDIError_AddressException:
|
||||
return TARGET_SIGNAL_SEGV;
|
||||
case RDIError_IRQ:
|
||||
case RDIError_FIQ:
|
||||
return TARGET_SIGNAL_TRAP;
|
||||
case RDIError_Error:
|
||||
return TARGET_SIGNAL_TERM;
|
||||
case RDIError_BranchThrough0:
|
||||
return TARGET_SIGNAL_TRAP;
|
||||
case RDIError_NotInitialised:
|
||||
case RDIError_UnableToInitialise:
|
||||
case RDIError_WrongByteSex:
|
||||
case RDIError_UnableToTerminate:
|
||||
return TARGET_SIGNAL_UNKNOWN;
|
||||
case RDIError_BadInstruction:
|
||||
case RDIError_IllegalInstruction:
|
||||
return TARGET_SIGNAL_ILL;
|
||||
case RDIError_BadCPUStateSetting:
|
||||
case RDIError_UnknownCoPro:
|
||||
case RDIError_UnknownCoProState:
|
||||
case RDIError_BadCoProState:
|
||||
case RDIError_BadPointType:
|
||||
case RDIError_UnimplementedType:
|
||||
case RDIError_BadPointSize:
|
||||
case RDIError_UnimplementedSize:
|
||||
case RDIError_NoMorePoints:
|
||||
return TARGET_SIGNAL_UNKNOWN;
|
||||
case RDIError_BreakpointReached:
|
||||
case RDIError_WatchpointAccessed:
|
||||
return TARGET_SIGNAL_TRAP;
|
||||
case RDIError_NoSuchPoint:
|
||||
case RDIError_ProgramFinishedInStep:
|
||||
return TARGET_SIGNAL_UNKNOWN;
|
||||
case RDIError_UserInterrupt:
|
||||
return TARGET_SIGNAL_INT;
|
||||
case RDIError_IncompatibleRDILevels:
|
||||
case RDIError_LittleEndian:
|
||||
case RDIError_BigEndian:
|
||||
case RDIError_SoftInitialiseError:
|
||||
case RDIError_InsufficientPrivilege:
|
||||
case RDIError_UnimplementedMessage:
|
||||
case RDIError_UndefinedMessage:
|
||||
default:
|
||||
return TARGET_SIGNAL_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Define the target operations structure. */
|
||||
|
||||
struct target_ops arm_rdi_ops = {
|
||||
"rdi", /* to_shortname */
|
||||
"ARM RDI", /* to_longname */
|
||||
"Use a remote ARM-based computer, via the RDI library.\n\
|
||||
Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
|
||||
arm_rdi_open, /* to_open */
|
||||
arm_rdi_close, /* to_close */
|
||||
NULL, /* to_attach */
|
||||
arm_rdi_detach, /* to_detach */
|
||||
arm_rdi_resume, /* to_resume */
|
||||
arm_rdi_wait, /* to_wait */
|
||||
arm_rdi_fetch_registers, /* to_fetch_registers */
|
||||
arm_rdi_store_registers, /* to_store_registers */
|
||||
arm_rdi_prepare_to_store, /* to_prepare_to_store */
|
||||
arm_rdi_xfer_memory, /* to_xfer_memory */
|
||||
arm_rdi_files_info, /* to_files_info */
|
||||
arm_rdi_insert_breakpoint, /* to_insert_breakpoint */
|
||||
arm_rdi_remove_breakpoint, /* to_remove_breakpoint */
|
||||
NULL, /* to_terminal_init */
|
||||
NULL, /* to_terminal_inferior */
|
||||
NULL, /* to_terminal_ours_for_output */
|
||||
NULL, /* to_terminal_ours */
|
||||
NULL, /* to_terminal_info */
|
||||
arm_rdi_kill, /* to_kill */
|
||||
generic_load, /* to_load */
|
||||
NULL, /* to_lookup_symbol */
|
||||
arm_rdi_create_inferior, /* to_create_inferior */
|
||||
arm_rdi_mourn_inferior, /* to_mourn_inferior */
|
||||
0, /* to_can_run */
|
||||
0, /* to_notice_signals */
|
||||
0, /* to_thread_alive */
|
||||
0, /* to_stop */
|
||||
process_stratum, /* to_stratum */
|
||||
NULL, /* to_next */
|
||||
1, /* to_has_all_memory */
|
||||
1, /* to_has_memory */
|
||||
1, /* to_has_stack */
|
||||
1, /* to_has_registers */
|
||||
1, /* to_has_execution */
|
||||
NULL, /* sections */
|
||||
NULL, /* sections_end */
|
||||
OPS_MAGIC /* to_magic */
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_remote_rdi ()
|
||||
{
|
||||
add_target (&arm_rdi_ops);
|
||||
}
|
||||
|
||||
/* A little dummy to make linking with the library succeed. */
|
||||
|
||||
Fail() {}
|
217
gdb/remote-rdp.c
217
gdb/remote-rdp.c
|
@ -54,6 +54,7 @@
|
|||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "gdbcore.h"
|
||||
|
||||
|
||||
extern struct target_ops remote_rdp_ops;
|
||||
|
@ -138,6 +139,16 @@ ds;
|
|||
#define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9)
|
||||
#define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10)
|
||||
#define RDP_INFO_ABOUT_BREAK_COND (1<<11)
|
||||
#define RDP_INFO_VECTOR_CATCH (0x180)
|
||||
#define RDP_INFO_ICEBREAKER (7)
|
||||
#define RDP_INFO_SET_CMDLINE (0x300)
|
||||
|
||||
#define RDP_SELECT_CONFIG (0x16)
|
||||
#define RDI_ConfigCPU 0
|
||||
#define RDI_ConfigSystem 1
|
||||
#define RDI_MatchAny 0
|
||||
#define RDI_MatchExactly 1
|
||||
#define RDI_MatchNoEarlier 2
|
||||
|
||||
#define RDP_RESET 0x7f
|
||||
|
||||
|
@ -157,6 +168,8 @@ ds;
|
|||
|
||||
static int timeout = 2;
|
||||
|
||||
static char * commandline = NULL;
|
||||
|
||||
static int
|
||||
remote_rdp_xfer_inferior_memory PARAMS ((CORE_ADDR memaddr,
|
||||
char *myaddr,
|
||||
|
@ -263,9 +276,39 @@ rdp_init (cold, tty)
|
|||
|
||||
if (tty)
|
||||
printf_unfiltered ("Trying to connect at %d baud.\n", baudtry);
|
||||
|
||||
/*
|
||||
** It seems necessary to reset an EmbeddedICE to get it going.
|
||||
** This has the side benefit of displaying the startup banner.
|
||||
*/
|
||||
if (cold)
|
||||
{
|
||||
put_byte (RDP_RESET);
|
||||
while ((restype = SERIAL_READCHAR (io, 1)) > 0)
|
||||
{
|
||||
switch (restype)
|
||||
{
|
||||
case SERIAL_TIMEOUT:
|
||||
break;
|
||||
case RDP_RESET:
|
||||
/* Sent at start of reset process: ignore */
|
||||
break;
|
||||
default:
|
||||
printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (restype == 0)
|
||||
{
|
||||
/* Got end-of-banner mark */
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
put_byte (RDP_OPEN);
|
||||
|
||||
put_byte (type | RDP_OPEN_TYPE_RETURN_SEX);
|
||||
put_byte (type | RDP_OPEN_TYPE_RETURN_SEX );
|
||||
put_word (0);
|
||||
|
||||
while (!sync && (restype = SERIAL_READCHAR (io, 1)) > 0)
|
||||
|
@ -300,6 +343,10 @@ rdp_init (cold, tty)
|
|||
case RDP_RES_VALUE:
|
||||
{
|
||||
int resval = SERIAL_READCHAR (io, 1);
|
||||
|
||||
if (remote_debug)
|
||||
printf_unfiltered ("[%02x]\n", resval);
|
||||
|
||||
switch (resval)
|
||||
{
|
||||
case SERIAL_TIMEOUT:
|
||||
|
@ -384,9 +431,27 @@ send_rdp (char *template, va_alist)
|
|||
}
|
||||
break;
|
||||
case 'Z':
|
||||
/* Check the result code, error if not zero */
|
||||
if (get_byte ())
|
||||
error ("Command garbled");
|
||||
/* Check the result code */
|
||||
switch (get_byte ())
|
||||
{
|
||||
case 0:
|
||||
/* Success */
|
||||
break;
|
||||
case 253:
|
||||
/* Target can't do it; never mind */
|
||||
printf_unfiltered ("RDP: Insufficient privilege\n");
|
||||
return;
|
||||
case 254:
|
||||
/* Target can't do it; never mind */
|
||||
printf_unfiltered ("RDP: Unimplemented message\n");
|
||||
return;
|
||||
case 255:
|
||||
error ("Command garbled");
|
||||
break;
|
||||
default:
|
||||
error ("Corrupt reply from target");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
/* Read a word from the target */
|
||||
|
@ -652,6 +717,50 @@ rdp_execute_start ()
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
rdp_set_command_line (command, args)
|
||||
char * command;
|
||||
char * args;
|
||||
{
|
||||
/*
|
||||
** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems
|
||||
** don't implement that, and get all confused at the unexpected text.
|
||||
** Instead, just keep a copy, and send it when the target does a SWI_GetEnv
|
||||
*/
|
||||
|
||||
if (commandline != NULL)
|
||||
free (commandline);
|
||||
|
||||
commandline = malloc (strlen (command) + strlen (args) + 2);
|
||||
if (commandline != NULL)
|
||||
{
|
||||
strcpy (commandline, command);
|
||||
strcat (commandline, " ");
|
||||
strcat (commandline, args);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rdp_catch_vectors ()
|
||||
{
|
||||
/*
|
||||
** We want the target monitor to intercept the abort vectors
|
||||
** i.e. stop the program if any of these are used.
|
||||
*/
|
||||
send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH,
|
||||
/*
|
||||
** Specify a bitmask including
|
||||
** the reset vector
|
||||
** the undefined instruction vector
|
||||
** the prefetch abort vector
|
||||
** the data abort vector
|
||||
** the address exception vector
|
||||
*/
|
||||
(1<<0)|(1<<1)|(1<<3)|(1<<4)|(1<<5)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define a_byte 1
|
||||
#define a_word 2
|
||||
|
@ -786,6 +895,22 @@ exec_swi (swi, args)
|
|||
args->n = callback->isatty (callback, args->n);
|
||||
return 1;
|
||||
|
||||
case SWI_GetEnv:
|
||||
if (commandline != NULL)
|
||||
{
|
||||
int len = strlen (commandline);
|
||||
if (len > 255)
|
||||
{
|
||||
len = 255;
|
||||
commandline [255]='\0';
|
||||
}
|
||||
remote_rdp_xfer_inferior_memory (args[0].n,
|
||||
commandline, len+1, 1, 0);
|
||||
}
|
||||
else
|
||||
remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -986,6 +1111,8 @@ remote_rdp_open (args, from_tty)
|
|||
char *args;
|
||||
int from_tty;
|
||||
{
|
||||
int not_icebreaker;
|
||||
|
||||
if (!args)
|
||||
error_no_arg ("serial port device name");
|
||||
|
||||
|
@ -1010,7 +1137,33 @@ remote_rdp_open (args, from_tty)
|
|||
|
||||
rdp_info ();
|
||||
|
||||
push_target (&remote_rdp_ops);
|
||||
/* Need to set up the vector interception state */
|
||||
rdp_catch_vectors();
|
||||
|
||||
/*
|
||||
** If it's an EmbeddedICE, we need to set the processor config.
|
||||
** Assume we can always have ARM7TDI...
|
||||
*/
|
||||
send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, & not_icebreaker);
|
||||
if (!not_icebreaker)
|
||||
{
|
||||
const char * CPU = "ARM7TDI";
|
||||
int ICEversion;
|
||||
int len = strlen (CPU);
|
||||
|
||||
send_rdp ("bbbbw-p-SWZ",
|
||||
RDP_SELECT_CONFIG,
|
||||
RDI_ConfigCPU, /* Aspect: set the CPU */
|
||||
len, /* The number of bytes in the name */
|
||||
RDI_MatchAny, /* We'll take whatever we get */
|
||||
0, /* We'll take whatever version's there */
|
||||
CPU,len,
|
||||
& ICEversion);
|
||||
}
|
||||
|
||||
/* command line initialised on 'run'*/
|
||||
|
||||
push_target (& remote_rdp_ops);
|
||||
|
||||
callback->init (callback);
|
||||
flush_cached_frames ();
|
||||
|
@ -1192,6 +1345,54 @@ remote_rdp_files_info (target)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
remote_rdp_create_inferior (exec_file, allargs, env)
|
||||
char * exec_file;
|
||||
char * allargs;
|
||||
char ** env;
|
||||
{
|
||||
CORE_ADDR entry_point;
|
||||
|
||||
if (exec_file == 0 || exec_bfd == 0)
|
||||
error ("No exec file specified.");
|
||||
|
||||
entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
|
||||
|
||||
remote_rdp_kill ();
|
||||
remove_breakpoints ();
|
||||
init_wait_for_inferior ();
|
||||
|
||||
/* This gives us a chance to set up the command line */
|
||||
rdp_set_command_line (exec_file, allargs);
|
||||
|
||||
inferior_pid = 42;
|
||||
insert_breakpoints (); /* Needed to get correct instruction in cache */
|
||||
|
||||
/*
|
||||
** RDP targets don't provide any facility to set the top of memory,
|
||||
** so we don't bother to look for MEMSIZE in the environment.
|
||||
*/
|
||||
|
||||
/* Let's go! */
|
||||
proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
|
||||
}
|
||||
|
||||
/* Accept any stray run/attach commands */
|
||||
static int
|
||||
remote_rdp_can_run()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Attach doesn't need to do anything */
|
||||
static void
|
||||
remote_rdp_attach(args, from_tty)
|
||||
char * args;
|
||||
int from_tty;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Define the target subroutine names */
|
||||
|
||||
struct target_ops remote_rdp_ops =
|
||||
|
@ -1203,7 +1404,7 @@ struct target_ops remote_rdp_ops =
|
|||
"Use a remote ARM system which uses the ARM Remote Debugging Protocol",
|
||||
remote_rdp_open, /* to_open */
|
||||
remote_rdp_close, /* to_close */
|
||||
NULL, /* to_attach */
|
||||
remote_rdp_attach, /* to_attach */
|
||||
NULL, /* to_detach */
|
||||
remote_rdp_resume, /* to_resume */
|
||||
remote_rdp_wait, /* to_wait */
|
||||
|
@ -1222,9 +1423,9 @@ struct target_ops remote_rdp_ops =
|
|||
remote_rdp_kill, /* to_kill */
|
||||
generic_load, /* to_load */
|
||||
NULL, /* to_lookup_symbol */
|
||||
NULL, /* to_create_inferior */
|
||||
remote_rdp_create_inferior, /* to_create_inferior */
|
||||
generic_mourn_inferior, /* to_mourn_inferior */
|
||||
0, /* to_can_run */
|
||||
remote_rdp_can_run, /* to_can_run */
|
||||
0, /* to_notice_signals */
|
||||
0, /* to_thread_alive */
|
||||
0, /* to_stop */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue