aboutsummaryrefslogtreecommitdiff
path: root/gdb/rdi-share/ardi.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/rdi-share/ardi.c')
-rw-r--r--gdb/rdi-share/ardi.c2672
1 files changed, 2672 insertions, 0 deletions
diff --git a/gdb/rdi-share/ardi.c b/gdb/rdi-share/ardi.c
new file mode 100644
index 0000000..f61f724
--- /dev/null
+++ b/gdb/rdi-share/ardi.c
@@ -0,0 +1,2672 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/*
+ * ARDI.c
+ * Angel Remote Debug Interface
+ *
+ *
+ * $Revision$
+ * $Date$
+ *
+ * This file is based on /plg/pisd/rdi.c, but instead of using RDP it uses
+ * ADP messages.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define uint HIDE_HPs_uint
+#include <signal.h>
+#undef uint
+
+
+#include "endian.h"
+#include "ardi.h"
+#include "buffers.h"
+#include "channels.h"
+#include "hostchan.h"
+#include "host.h"
+#include "bytesex.h"
+#include "dbg_cp.h"
+#include "adp.h"
+#include "hsys.h"
+#include "logging.h"
+#include "msgbuild.h"
+#include "rxtx.h"
+#include "devsw.h"
+#include "params.h"
+
+#ifdef COMPILING_ON_WINDOWS
+# define IGNORE(x) (x = x) /* must go after #includes to work on Windows */
+#endif
+#define NOT(x) (!(x))
+
+#define ADP_INITIAL_TIMEOUT_PERIOD 5
+
+static volatile int executing;
+static int rdi_log = 0 ; /* debugging ? */
+
+/* we need a starting point for our first buffers, this is a safe one */
+int Armsd_BufferSize = ADP_BUFFER_MIN_SIZE;
+int Armsd_LongBufSize = ADP_BUFFER_MIN_SIZE;
+
+#ifdef WIN32
+ extern int interrupted;
+ extern int swiprocessing;
+#endif
+
+static char dummycline = 0;
+char *ardi_commandline = &dummycline ; /* exported in ardi.h */
+
+extern unsigned int heartbeat_enabled;
+
+static unsigned char *cpwords[16];
+
+typedef struct stoppedProcListElement {
+ struct stoppedProcListElement *next;
+ angel_RDI_TargetStoppedProc *fn;
+ void *arg;
+} stoppedProcListElement;
+
+static stoppedProcListElement *stopped_proc_list=NULL;
+
+const struct Dbg_HostosInterface *angel_hostif;
+static hsys_state *hstate;
+
+static void angel_DebugPrint(const char *format, ...)
+{ va_list ap;
+ va_start(ap, format);
+ angel_hostif->dbgprint(angel_hostif->dbgarg, format, ap);
+ va_end(ap);
+}
+
+#ifdef RDI_VERBOSE
+#define TracePrint(s) \
+ if (rdi_log & 2) angel_DebugPrint("\n"); \
+ if (rdi_log & 1) angel_DebugPrint s
+#else
+#define TracePrint(s)
+#endif
+
+typedef struct receive_dbgmsg_state {
+ volatile int received;
+ Packet *packet;
+} receive_dbgmsg_state;
+
+static receive_dbgmsg_state dbgmsg_state;
+
+static void receive_debug_packet(Packet *packet, void *stateptr)
+{
+ receive_dbgmsg_state *state = stateptr;
+
+ state->packet = packet;
+ state->received = 1;
+}
+
+static int register_debug_message_handler(void)
+{
+ int err;
+ dbgmsg_state.received = 0;
+
+ err = Adp_ChannelRegisterRead(CI_HADP, receive_debug_packet, &dbgmsg_state);
+#ifdef DEBUG
+ if (err!=adp_ok) angel_DebugPrint("register_debug_message_handler failed %i\n", err);
+#endif
+ return err;
+}
+
+
+static int wait_for_debug_message(int *rcode, int *debugID,
+ int *OSinfo1, int *OSinfo2,
+ int *status, Packet **packet)
+{
+ unsigned int reason;
+
+#ifdef DEBUG
+ angel_DebugPrint("wait_for_debug_message waiting for %X\n", *rcode);
+#endif
+
+ for ( ; dbgmsg_state.received == 0 ; )
+ Adp_AsynchronousProcessing(async_block_on_read);
+
+#ifdef DEBUG
+ angel_DebugPrint("wait_for_debug_message got packet\n");
+#endif
+
+ *packet = dbgmsg_state.packet;
+
+ Adp_ChannelRegisterRead(CI_HADP, NULL, NULL);
+
+ /*
+ * TODO:
+ * If ADP_Unrecognised return error.
+ * If ADP_Acknowledge - handle appropriately.
+ * If expected message read arguments and return RDIError_NoError.
+ * Note: if RDIError occurs then the data values returned are junk
+ */
+
+ unpack_message(BUFFERDATA((*packet)->pk_buffer), "%w%w%w%w%w", &reason, debugID,
+ OSinfo1, OSinfo2, status);
+ if (reason&0xffffff == ADP_HADPUnrecognised)
+ return RDIError_UnimplementedMessage;
+ if (reason != (unsigned ) *rcode) {
+ if((reason&0xffffff) == ADP_HADPUnrecognised)
+ return RDIError_UnimplementedMessage;
+ else {
+ angel_DebugPrint("ARDI ERROR: Expected reasoncode %x got reasoncode %x.\n",
+ *rcode, reason);
+ return RDIError_Error;
+ }
+ }
+ else
+ return RDIError_NoError;
+ return RDIError_Error; /* stop a pesky ANSI compiler warning */
+}
+
+
+/*
+ * Handler and registration for logging messages from target
+ */
+static void TargetLogCallback( Packet *packet, void *state )
+{
+ p_Buffer reply = BUFFERDATA(packet->pk_buffer);
+ unsigned int len = packet->pk_length;
+ IGNORE(state);
+ angel_hostif->write(angel_hostif->hostosarg,
+ (char *)reply, len - CHAN_HEADER_SIZE);
+ DevSW_FreePacket(packet);
+
+ packet = DevSW_AllocatePacket(4); /* better not ask for 0 */
+ /* the reply is the ACK - any contents are ignored */
+ if (packet != NULL)
+ Adp_ChannelWrite( CI_TLOG, packet );
+}
+
+static void TargetLogInit( void )
+{
+ AdpErrs err = Adp_ChannelRegisterRead( CI_TLOG, TargetLogCallback, NULL );
+
+#ifdef DEBUG
+ if (err != adp_ok)
+ angel_DebugPrint("CI_TLOG RegisterRead failed %d\n", err);
+#else
+ IGNORE(err);
+#endif
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_open-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+typedef struct NegotiateState {
+ bool negotiate_resp;
+ bool negotiate_ack;
+ bool link_check_resp;
+ ParameterConfig *accepted_config;
+} NegotiateState;
+
+static void receive_negotiate(Packet *packet, void *stateptr)
+{
+ unsigned reason, debugID, OSinfo1, OSinfo2, status;
+ NegotiateState *n_state = (NegotiateState *)stateptr;
+ p_Buffer reply = BUFFERDATA(packet->pk_buffer);
+
+ unpack_message( reply, "%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2 );
+ reply += ADP_DEFAULT_HEADER_SIZE;
+
+#ifdef DEBUG
+ angel_DebugPrint( "receive_negotiate: reason %x\n", reason );
+#endif
+
+ switch ( reason )
+ {
+ case ADP_ParamNegotiate | TtoH:
+ {
+ n_state->negotiate_resp = TRUE;
+
+ status = GET32LE( reply );
+ reply += sizeof(word);
+#ifdef DEBUG
+ angel_DebugPrint( "ParamNegotiate status %u\n", status );
+#endif
+ if ( status == RDIError_NoError )
+ {
+ if ( Angel_ReadParamConfigMessage(
+ reply, n_state->accepted_config ) )
+ n_state->negotiate_ack = TRUE;
+ }
+ break;
+ }
+
+ case ADP_LinkCheck | TtoH:
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "PONG!\n" );
+#endif
+ n_state->link_check_resp = TRUE;
+ break;
+ }
+
+ default:
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Unexpected!\n" );
+#endif
+ break;
+ }
+ }
+ DevSW_FreePacket( packet );
+}
+
+# include <sys/types.h>
+#ifdef __unix
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+/*
+ * convert a config into a single-valued options list
+ */
+static ParameterOptions *config_to_options( const ParameterConfig *config )
+{
+ unsigned int num_params;
+ size_t size;
+ ParameterOptions *base_p;
+
+ num_params = config->num_parameters;
+ size =
+ sizeof(ParameterOptions)
+ + num_params*(sizeof(ParameterList) + sizeof(unsigned int));
+ base_p = malloc( size );
+
+ if ( base_p != NULL )
+ {
+ unsigned int u;
+ ParameterList *list_p =
+ (ParameterList *)((char *)base_p + sizeof(ParameterOptions));
+ unsigned int *option_p =
+ (unsigned int *)(list_p + num_params);
+
+ base_p->num_param_lists = num_params;
+ base_p->param_list = list_p;
+
+ for ( u = 0; u < num_params; ++u )
+ {
+ option_p[u] = config->param[u].value;
+ list_p[u].type = config->param[u].type;
+ list_p[u].num_options = 1;
+ list_p[u].option = &option_p[u];
+ }
+ }
+
+ return base_p;
+}
+
+static AdpErrs negotiate_params( const ParameterOptions *user_options )
+{
+ Packet *packet;
+ unsigned int count;
+ static Parameter params[AP_NUM_PARAMS];
+ static ParameterConfig accepted_config = { AP_NUM_PARAMS, params };
+
+ time_t t;
+
+ static volatile NegotiateState n_state = {
+ FALSE, FALSE, FALSE, &accepted_config };
+
+#ifdef DEBUG
+ angel_DebugPrint( "negotiate_params\n" );
+#endif
+
+ Adp_ChannelRegisterRead( CI_HBOOT, receive_negotiate, (void *)&n_state );
+
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
+ count = msgbuild( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
+ ADP_ParamNegotiate | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown );
+ count += Angel_BuildParamOptionsMessage(
+ BUFFERDATA(packet->pk_buffer) + count, user_options );
+ packet->pk_length = count;
+ Adp_ChannelWriteAsync( CI_HBOOT, packet );
+
+#ifdef DEBUG
+ angel_DebugPrint( "sent negotiate packet\n" );
+#endif
+
+ t=time(NULL);
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+
+ if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD) {
+ return adp_timeout_on_open;
+ }
+ } while ( ! n_state.negotiate_resp );
+
+ if ( n_state.negotiate_ack )
+ {
+ /* select accepted config */
+ Adp_Ioctl( DC_SET_PARAMS, (void *)n_state.accepted_config );
+
+ /*
+ * 960430 KWelton
+ *
+ * There is a race in the renegotiation protocol: the
+ * target has to have had time to load new config before
+ * we send the link check packet - insert a deliberate
+ * pause (100ms) to give the target some time
+ */
+ Adp_delay(100000);
+
+ /* do link check */
+ msgsend( CI_HBOOT, "%w%w%w%w", ADP_LinkCheck | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown );
+#ifdef DEBUG
+ angel_DebugPrint("sent link check\n");
+#endif
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_read);
+ } while ( ! n_state.link_check_resp );
+ Adp_initSeq();
+ }
+ return adp_ok;
+}
+
+static int late_booted = FALSE;
+static bool ardi_handler_installed = FALSE;
+
+#ifdef __unix
+static struct sigaction old_action;
+#else
+static void (*old_handler)();
+#endif
+
+static bool boot_interrupted = FALSE;
+
+static void ardi_sigint_handler(int sig) {
+#ifdef DEBUG
+ if (sig != SIGINT)
+ angel_DebugPrint("Expecting SIGINT got %d.\n", sig);
+#else
+ IGNORE(sig);
+#endif
+ boot_interrupted = TRUE;
+#ifndef __unix
+ signal(SIGINT, ardi_sigint_handler);
+#endif
+}
+
+static void install_ardi_handler( void ) {
+ if (!ardi_handler_installed) {
+ /* install a new Ctrl-C handler so we can abandon waiting */
+#ifdef __unix
+ struct sigaction new_action;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_handler = ardi_sigint_handler;
+ new_action.sa_flags = 0;
+ sigaction(SIGINT, &new_action, &old_action);
+#else
+ old_handler = signal(SIGINT, ardi_sigint_handler);
+#endif
+ ardi_handler_installed = TRUE;
+ }
+}
+
+static int angel_RDI_errmess(char *buf, int blen, int errnum);
+
+static void receive_reset_acknowledge(Packet *packet, void *stateptr) {
+ unsigned reason, debugID, OSinfo1, OSinfo2, status;
+ IGNORE(stateptr);
+
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ if (reason==(ADP_Reset | TtoH) && status==AB_NORMAL_ACK) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Successfully received normal reset acknowledgement\n");
+ late_booted = FALSE;
+#endif
+ } else if (reason==(ADP_Reset | TtoH) && status==AB_LATE_ACK) {
+ char late_msg[AdpMessLen_LateStartup];
+ int late_len;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Successfully received LATE reset acknowledgement\n");
+#endif
+ late_booted = TRUE;
+ install_ardi_handler();
+ late_len = angel_RDI_errmess(late_msg,
+ AdpMessLen_LateStartup, adp_late_startup);
+ angel_hostif->write(angel_hostif->hostosarg, late_msg, late_len);
+ } else {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Bad reset ack: reason=%8X, status=%8X\n", reason, status);
+#endif
+ }
+ DevSW_FreePacket(packet);
+}
+
+static int booted_not_received;
+static unsigned int angel_version;
+static unsigned int adp_version;
+static unsigned int arch_info;
+static unsigned int cpu_info;
+static unsigned int hw_status;
+
+static void receive_booted(Packet *packet, void *stateptr) {
+ unsigned reason, debugID, OSinfo1, OSinfo2, banner_length, bufsiz, longsiz;
+ unsigned i, count;
+
+ IGNORE(stateptr);
+
+ count = unpack_message(BUFFERDATA(packet->pk_buffer),
+ "%w%w%w%w%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &bufsiz, &longsiz,
+ &angel_version, &adp_version,
+ &arch_info, &cpu_info, &hw_status, &banner_length);
+ if (reason==(ADP_Booted | TtoH)) {
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("DEBUG: Successfully received Booted\n");
+ angel_DebugPrint(" cpu_info=%8X, hw_status=%8X, bufsiz=%d, longsiz=%d\n",
+ cpu_info, hw_status, bufsiz, longsiz);
+#endif
+ /* Get the banner from the booted message */
+ for (i=0; i<banner_length; i++)
+ angel_hostif->writec(angel_hostif->hostosarg,
+ (BUFFERDATA(packet->pk_buffer)+count)[i]);
+
+ booted_not_received=0;
+#ifndef NO_HEARTBEAT
+ heartbeat_enabled = TRUE;
+#endif
+ Armsd_BufferSize = bufsiz + CHAN_HEADER_SIZE;
+ Armsd_LongBufSize = longsiz + CHAN_HEADER_SIZE;
+ } else {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Bad Booted msg: reason=%8X\n", reason);
+#endif
+ }
+ DevSW_FreePacket(packet);
+}
+
+
+/* forward declaration */
+static int angel_negotiate_defaults( void );
+
+/* Open communications. */
+int angel_RDI_open(
+ unsigned type, Dbg_ConfigBlock const *config,
+ Dbg_HostosInterface const *hostif, struct Dbg_MCState *dbg_state)
+{
+ Packet *packet;
+ int status, reasoncode, debugID, OSinfo1, OSinfo2, err;
+ ParameterOptions *user_options = NULL;
+
+ time_t t;
+
+ IGNORE( dbg_state );
+
+ if ((type & 1) == 0) {
+ /* cold start */
+ if (hostif != NULL) {
+ angel_hostif = hostif;
+ err = HostSysInit(hostif, &ardi_commandline, &hstate);
+ if (err != RDIError_NoError) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: HostSysInit error %i\n",err);
+#endif
+ return err;
+ }
+ }
+ TargetLogInit();
+ }
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Buffer allocated in angel_RDI_open(type=%i).\n",type);
+#endif
+
+ if ((type & 1) == 0) {
+ /* cold start */
+ unsigned endian;
+ Adp_Ioctl( DC_GET_USER_PARAMS, (void *)&user_options );
+ if ( user_options != NULL ) {
+ err = negotiate_params( user_options );
+ if (err != adp_ok) return err;
+ }
+ else {
+ ParameterConfig *default_config = NULL;
+ Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
+ if ( default_config != NULL ) {
+ ParameterOptions *default_options = config_to_options(default_config);
+ err = negotiate_params( default_options );
+ if (err != adp_ok) return err;
+ }
+ }
+
+ /* Register handlers before sending any messages */
+ booted_not_received=1;
+ Adp_ChannelRegisterRead(CI_HBOOT, receive_reset_acknowledge, NULL);
+ Adp_ChannelRegisterRead(CI_TBOOT, receive_booted, NULL);
+ endian = 0;
+ if (config!=NULL) {
+ if (config->bytesex & RDISex_Little) endian |= ADP_BootHostFeature_LittleEnd;
+ if (config->bytesex & RDISex_Big) endian |= ADP_BootHostFeature_BigEnd;
+ }
+ msgsend(CI_HBOOT,"%w%w%w%w%w", ADP_Reset | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, endian);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted Reset message in angel_RDI_open.\n");
+#endif
+
+ /* We will now either get an acknowledgement for the Reset message
+ * or if the target was started after the host, we will get a
+ * rebooted message first.
+ */
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: waiting for a booted message\n");
+#endif
+
+ {
+ boot_interrupted = FALSE;
+
+ if (late_booted)
+ install_ardi_handler();
+
+ t=time(NULL);
+
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+ if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD && !late_booted) {
+ return adp_timeout_on_open;
+ }
+ } while (booted_not_received && !boot_interrupted);
+
+ if (ardi_handler_installed)
+ {
+ /* uninstall our Ctrl-C handler */
+#ifdef __unix
+ sigaction(SIGINT, &old_action, NULL);
+#else
+ signal(SIGINT, old_handler);
+#endif
+ }
+
+ if (boot_interrupted) {
+ angel_negotiate_defaults();
+ return adp_abandon_boot_wait;
+ }
+ }
+
+ booted_not_received=1;
+ Adp_ChannelRegisterRead(CI_HBOOT, NULL, NULL);
+
+ /* Leave the booted handler installed */
+ msgsend(CI_TBOOT, "%w%w%w%w%w", ADP_Booted | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, 0);
+ Adp_initSeq();
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted ADP_Booted acknowledgement.\n");
+ angel_DebugPrint("DEBUG: Boot sequence completed, leaving angel_RDI_open.\n");
+#endif
+
+ return (hw_status & ADP_CPU_BigEndian )? RDIError_BigEndian :
+ RDIError_LittleEndian;
+ }
+ else {
+ /* warm start */
+ register_debug_message_handler();
+
+ msgsend(CI_HADP, "%w%w%w%w",
+ ADP_InitialiseApplication | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Transmitted Initialise Application\n");
+#endif
+ reasoncode=ADP_InitialiseApplication | TtoH;
+ err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) return err;
+ return status;
+ }
+ return -1;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_close----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+static int angel_negotiate_defaults( void ) {
+ int err = adp_ok;
+ ParameterConfig *default_config = NULL;
+ Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
+ if ( default_config != NULL ) {
+ ParameterOptions *default_options = config_to_options(default_config);
+ err = negotiate_params( default_options );
+ free( default_options );
+ }
+ return err;
+}
+
+int angel_RDI_close(void) {
+/*Angel host exit */
+ int err;
+ int status,debugID, OSinfo1,OSinfo2;
+ int reason;
+ Packet *packet = NULL;;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_Close.\n");
+#endif
+
+ register_debug_message_handler();
+
+ heartbeat_enabled = FALSE;
+
+ err = msgsend(CI_HADP,"%w%w%w%w",ADP_End | HtoT,0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+ if (err != RDIError_NoError) return err;
+ reason = ADP_End | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError) return err;
+ if (status == RDIError_NoError) {
+ err = angel_negotiate_defaults();
+ if (err != adp_ok) return err;
+ Adp_Ioctl( DC_RESET, NULL ); /* just to be safe */
+ return HostSysExit(hstate);
+ }
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_read-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Read memory contents from target to host: use ADP_Read */
+int angel_RDI_read(ARMword source, void *dest, unsigned *nbytes)
+{
+ Packet *packet=NULL;
+ int len; /* Integer to hold message length. */
+ unsigned int nbtogo = *nbytes, nbinpacket, nbdone=0;
+ int rnbytes = 0, status, reason, debugID, OSinfo1, OSinfo2, err;
+ unsigned int maxlen = Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ReadHeaderSize;
+
+ /* Print debug trace information, this is just copied straight from rdi.c
+ and I can see no reason why it should have to be changed. */
+ TracePrint(("angel_RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
+ (unsigned long)source, dest, *nbytes));
+ if (*nbytes == 0) return RDIError_NoError; /* Read nothing - easy! */
+ /* check the buffer size */
+ while (nbtogo >0) {
+ register_debug_message_handler();
+
+ nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
+ len = msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Read | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, source+nbdone,
+ nbinpacket);
+ reason=ADP_Read | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ TracePrint(("angel_RDI_read: nbinpacket =%d status=%08x err = %d\n",
+ nbinpacket,status,err));
+ if (err != RDIError_NoError) return err; /* Was there an error? */
+ if (status == RDIError_NoError){
+ rnbytes += PREAD(LE,(unsigned int *)(BUFFERDATA(packet->pk_buffer)+20));
+ TracePrint(("angel_RDI_read: rnbytes = %d\n",rnbytes));
+ memcpy(((unsigned char *)dest)+nbdone, BUFFERDATA(packet->pk_buffer)+24,
+ nbinpacket);
+ }
+ nbdone += nbinpacket;
+ nbtogo -= nbinpacket;
+ }
+ *nbytes -= rnbytes;
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_write----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Transfer memory block from host to target. Use ADP_Write>. */
+int angel_RDI_write(const void *source, ARMword dest, unsigned *nbytes)
+{
+ Packet *packet;/* Message buffers. */
+ unsigned int len, nbtogo = *nbytes, nboffset = 0, nbinpacket;
+ int status, reason, debugID, OSinfo1, OSinfo2, err;
+ unsigned int maxlen = Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_WriteHeaderSize;
+
+ TracePrint(("angel_RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
+ source, (unsigned long)dest, *nbytes));
+
+ if (*nbytes == 0) return RDIError_NoError;
+
+ *nbytes = 0;
+ while (nbtogo > 0) {
+ packet = (Packet *) DevSW_AllocatePacket(Armsd_LongBufSize);
+ nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ ADP_Write | HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, dest+nboffset, nbinpacket);
+ /* Copy the data into the packet. */
+
+ memcpy(BUFFERDATA(packet->pk_buffer)+len,
+ ((const unsigned char *) source)+nboffset, nbinpacket);
+ nboffset += nbinpacket;
+ packet->pk_length = nbinpacket+len;
+
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("angel_RDI_write packet size=%i, bytes done=%i\n",
+ nbinpacket, nboffset);
+#endif
+
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_Write | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ nbtogo -= nbinpacket;
+ if (err != RDIError_NoError) return err;
+ if (status == RDIError_NoError)
+ *nbytes += nbinpacket;
+
+ DevSW_FreePacket(packet);
+ }
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPUread--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Reads the values of registers in the CPU, uses ADP_CPUwrite. */
+int angel_RDI_CPUread(unsigned mode, unsigned long mask, ARMword *buffer)
+{
+ unsigned int i, j;
+ Packet *packet = NULL;
+ int err, status, reason, debugID, OSinfo1, OSinfo2;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_CPUread.\n");
+#endif
+ for (i=0, j=0 ; i < RDINumCPURegs ; i++)
+ if (mask & (1L << i)) j++; /* Count the number of registers. */
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%c%w", ADP_CPUread | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
+ reason = ADP_CPUread | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ if(status == RDIError_NoError) {
+ for (i=0; i<j; i++)
+ buffer[i] = GET32LE(BUFFERDATA(packet->pk_buffer)+20+(i*4));
+ TracePrint(("angel_RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask));
+ DevSW_FreePacket(packet);
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ unsigned k;
+ for (k = 0, j = 0 ; j <= 20 ; j++)
+ if (mask & (1L << j)) {
+ angel_DebugPrint("%c%.8lx",k%4==0?'\n':' ',
+ (unsigned long)buffer[k]);
+ k++ ;
+ }
+ angel_DebugPrint("\n") ;
+ }
+#endif
+
+ }
+ return status;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPUwrite-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Write CPU registers: use ADP_CPUwrite. */
+int angel_RDI_CPUwrite(unsigned mode, unsigned long mask,
+ ARMword const *buffer){
+
+ unsigned i, j, c;
+ Packet *packet;
+ int status, reason, debugID, OSinfo1, OSinfo2, err, len;
+
+ TracePrint(("angel_RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (j = 0, i = 0 ; i <= 20 ; i++)
+ if (mask & (1L << i)) {
+ angel_DebugPrint("%c%.8lx",j%4==0?'\n':' ',
+ (unsigned long)buffer[j]);
+ j++ ;
+ }
+ angel_DebugPrint("\n") ;
+ }
+#endif
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
+ for (i=0, j=0; i < RDINumCPURegs ; i++)
+ if (mask & (1L << i)) j++; /* count the number of registers */
+
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%b%w",
+ ADP_CPUwrite | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
+ for(c=0; c<j; c++)
+ PUT32LE(BUFFERDATA(packet->pk_buffer)+len+(c*4), buffer[c]);
+ packet->pk_length = len+(j*4);
+ register_debug_message_handler();
+
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ADP_CPUwrite | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError)
+ return err; /* Was there an error? */
+ else
+ return status;
+ }
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPread---------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Read coprocessor's internal state. See dbg_cp.h for help.
+ * Use ADP_CPRead.
+ * It would appear that the correct behaviour at this point is to leave
+ * the unpacking to a the caller and to simply copy the stream of data
+ * words into the buffer
+ */
+
+int angel_RDI_CPread(unsigned CPnum, unsigned long mask, ARMword *buffer){
+ Packet *packet = NULL;
+ int i, j, status, reasoncode, OSinfo1, OSinfo2, err, debugID;
+ unsigned char *rmap = cpwords[CPnum];
+ int n;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_CPread.\n");
+#endif
+ if (rmap == NULL) return RDIError_UnknownCoPro;
+
+ register_debug_message_handler();
+ n = rmap[-1];
+ msgsend(CI_HADP, "%w%w%w%w%b%w", ADP_CPread | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
+ reasoncode=ADP_CPread | TtoH;
+ err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ for (j=i=0; i < n ; i++) /* count the number of registers */
+ if (mask & (1L << i)) {
+ j++;
+ }
+ for (i=0; i<j; i++)
+ buffer[i] = PREAD32(LE, BUFFERDATA(packet->pk_buffer) + 20 + (i*4));
+ DevSW_FreePacket(packet);
+ TracePrint(("angel_RDI_CPread: CPnum=%.8x mask=%.8lx\n", CPnum, mask));
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (i = 0, j = 0; j < n ; j++) {
+ if (mask & (1L << j)) {
+ int nw = rmap[j];
+ angel_DebugPrint("%2d ", j);
+ while (--nw > 0)
+ angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
+ angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
+ }
+ }
+ }
+#endif
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_CPwrite--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Write coprocessor's internal state. See dbg_cp.h for help. Use
+ * ADP_CPwrite.
+ */
+
+int angel_RDI_CPwrite(unsigned CPnum, unsigned long mask,
+ ARMword const *buffer)
+{
+ Packet *packet = NULL;
+ int i, j, len, status, reason, OSinfo1, OSinfo2, err, debugID;
+ unsigned char *rmap = cpwords[CPnum];
+ int n;
+
+ if (rmap == NULL) return RDIError_UnknownCoPro;
+ n = rmap[-1];
+
+ TracePrint(("angel_RDI_CPwrite: CPnum=%d mask=%.8lx\n", CPnum, mask));
+
+#ifdef RDI_VERBOSE
+ if (rdi_log & 1) {
+ for (i = 0, j = 0; j < n ; j++)
+ if (mask & (1L << j)) {
+ int nw = rmap[j];
+ angel_DebugPrint("%2d ", j);
+ while (--nw > 0)
+ angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
+ angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
+ }
+ }
+#endif
+
+ for (j=i=0; i < n ; i++) /* Count the number of registers. */
+ if (mask & (1L << i)) j++;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%c%w",
+ ADP_CPwrite | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
+ for(i=0; i<j; i++)
+ len+=msgbuild(BUFFERDATA(packet->pk_buffer) + len, "%w", buffer[i]);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason=ADP_CPwrite | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+ if (err != RDIError_NoError)
+ return err;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_pointinq-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Do test calls to ADP_SetBreak/ADP_SetWatch to see if resources exist to
+ carry out request. */
+int angel_RDI_pointinq(ARMword *address, unsigned type, unsigned datatype,
+ ARMword *bound)
+{
+ Packet *packet = NULL;
+ int len, status, reason, OSinfo1, OSinfo2, err=RDIError_NoError;
+ /* stop a compiler warning */
+ int debugID, pointhandle;
+ TracePrint(
+ ("angel_RDI_pointinq: address=%.8lx type=%d datatype=%d bound=%.8lx ",
+ (unsigned long)*address, type, datatype, (unsigned long)*bound));
+ /* for a buffer. */
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b",
+ ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch) | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, address, type);
+ if (datatype == 0)
+ len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%w", bound);
+ else
+ len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%b%w", datatype, bound);
+
+ register_debug_message_handler();
+ packet->pk_length = len;
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch | TtoH);
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ &pointhandle, &address, &bound);
+ DevSW_FreePacket(packet);
+ return err;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_setbreak-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Set a breakpoint: Use ADP_SetBreak */
+int angel_RDI_setbreak(ARMword address, unsigned type, ARMword bound,
+ PointHandle *handle)
+{
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+ int tmpval, tmpaddr, tmpbnd;
+ Packet *packet;
+ TracePrint(("angel_RDI_setbreak address=%.8lx type=%d bound=%.8lx \n",
+ (unsigned long)address, type, (unsigned long)bound));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b%w",
+ ADP_SetBreak| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, address, type, bound);
+ reason = ADP_SetBreak |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ /* Work around varargs problem... -sts */
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ &tmpval, &tmpaddr, &tmpbnd);
+ *handle = tmpval;
+ address = tmpaddr;
+ bound = tmpbnd;
+ DevSW_FreePacket(packet);
+ if (status != RDIError_NoError) return status;
+ TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
+ return RDIError_NoError;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_clearbreak-----------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Clear a breakpoint: Use ADP_ClearBreak. */
+int angel_RDI_clearbreak(PointHandle handle)
+{
+ Packet *packet = NULL;
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+
+ TracePrint(("angel_RDI_clearbreak: handle=%.8lx\n", (unsigned long)handle));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w",
+ ADP_ClearBreak| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, handle);
+ reason = ADP_ClearBreak|TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ angel_DebugPrint("***RECEIVE DEBUG MESSAGE RETURNED ERR = %d.\n", err);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Clear Break completed OK.\n");
+#endif
+ return RDIError_NoError;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_setwatch-------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Set a watchpoint: use ADP_SetWatch. */
+int angel_RDI_setwatch(ARMword address, unsigned type, unsigned datatype,
+ ARMword bound, PointHandle *handle)
+{
+ Packet *packet = NULL;
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+
+ TracePrint(("angel_RDI_setwatch: address=%.8lx type=%d bound=%.8lx ",
+ (unsigned long)address, type, (unsigned long)bound));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b%b%w",
+ ADP_SetWatch| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, address, type, datatype, bound);
+
+ reason = ADP_SetWatch | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2, &status,
+ handle, &address, &bound);
+ DevSW_FreePacket(packet);
+ TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
+ return RDIError_NoError;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_clearwatch-----------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Clear a watchpoint: use ADP_ClearWatch. */
+int angel_RDI_clearwatch(PointHandle handle) {
+
+ int status, reason, OSinfo1, OSinfo2, err, debugID;
+ Packet *packet = NULL;
+
+ TracePrint(("angel_RDI_clearwatch: handle=%.8lx\n", (unsigned long)handle));
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w",
+ ADP_ClearWatch| HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, handle);
+ reason = ADP_ClearWatch|TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err; /* Was there an error? */
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &status);
+ DevSW_FreePacket(packet);
+ return RDIError_NoError;
+}
+
+typedef struct {
+ unsigned stopped_reason;
+ int stopped_status;
+ int data;
+} adp_stopped_struct;
+
+
+int angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc *fn,
+ void *arg)
+{
+ stoppedProcListElement **lptr = &stopped_proc_list;
+
+ /* Find the address of the NULL ptr at the end of the list */
+ for (; *lptr!=NULL ; lptr = &((*lptr)->next))
+ ; /* Do nothing */
+
+ *lptr = (stoppedProcListElement *) malloc(sizeof(stoppedProcListElement));
+ if (*lptr == NULL) return RDIError_OutOfStore;
+ (*lptr)->fn = fn;
+ (*lptr)->arg = arg;
+
+ return RDIError_NoError;
+}
+
+static int CallStoppedProcs(unsigned reason)
+{
+ stoppedProcListElement *p = stopped_proc_list;
+ int err=RDIError_NoError;
+
+ for (; p!=NULL ; p=p->next) {
+ int local_err = p->fn(reason, p->arg);
+ if (local_err != RDIError_NoError) err=local_err;
+ }
+
+ return err;
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_execute--------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+static int HandleStoppedMessage(Packet *packet, void *stateptr) {
+ unsigned int err, reason, debugID, OSinfo1, OSinfo2, count;
+ adp_stopped_struct *stopped_info;
+ stopped_info = (adp_stopped_struct *) stateptr;
+ IGNORE(stateptr);
+ count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ &reason, &debugID,
+ &OSinfo1, &OSinfo2,
+ &stopped_info->stopped_reason, &stopped_info->data);
+ DevSW_FreePacket(packet);
+
+ if (reason != (ADP_Stopped | TtoH)) {
+#ifdef DEBUG
+ angel_DebugPrint("Expecting stopped message, got %x", reason);
+#endif
+ return RDIError_Error;
+ }
+ else {
+ executing = FALSE;
+#ifdef DEBUG
+ angel_DebugPrint("Received stopped message.\n");
+#endif
+ }
+
+ err = msgsend(CI_TADP, "%w%w%w%w%w", (ADP_Stopped | HtoT), 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, RDIError_NoError);
+#ifdef DEBUG
+ angel_DebugPrint("Transmiting stopped acknowledge.\n");
+#endif
+ if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Stopped reason : %x\n", stopped_info->stopped_reason);
+#endif
+ switch (stopped_info->stopped_reason) {
+ case ADP_Stopped_BranchThroughZero:
+ stopped_info->stopped_status = RDIError_BranchThrough0;
+ break;
+ case ADP_Stopped_UndefinedInstr:
+ stopped_info->stopped_status = RDIError_UndefinedInstruction;
+ break;
+ case ADP_Stopped_SoftwareInterrupt:
+ stopped_info->stopped_status = RDIError_SoftwareInterrupt;
+ break;
+ case ADP_Stopped_PrefetchAbort:
+ stopped_info->stopped_status = RDIError_PrefetchAbort;
+ break;
+ case ADP_Stopped_DataAbort:
+ stopped_info->stopped_status = RDIError_DataAbort;
+ break;
+ case ADP_Stopped_AddressException:
+ stopped_info->stopped_status = RDIError_AddressException;
+ break;
+ case ADP_Stopped_IRQ:
+ stopped_info->stopped_status = RDIError_IRQ;
+ break;
+ case ADP_Stopped_BreakPoint:
+ stopped_info->stopped_status = RDIError_BreakpointReached;
+ break;
+ case ADP_Stopped_WatchPoint:
+ stopped_info->stopped_status = RDIError_WatchpointAccessed;
+ break;
+ case ADP_Stopped_StepComplete:
+ stopped_info->stopped_status = RDIError_ProgramFinishedInStep;
+ break;
+ case ADP_Stopped_RunTimeErrorUnknown:
+ case ADP_Stopped_StackOverflow:
+ case ADP_Stopped_DivisionByZero:
+ stopped_info->stopped_status = RDIError_Error;
+ break;
+ case ADP_Stopped_FIQ:
+ stopped_info->stopped_status = RDIError_FIQ;
+ break;
+ case ADP_Stopped_UserInterruption:
+ case ADP_Stopped_OSSpecific:
+ stopped_info->stopped_status = RDIError_UserInterrupt;
+ break;
+ case ADP_Stopped_ApplicationExit:
+ stopped_info->stopped_status = RDIError_NoError;
+ break;
+ default:
+ stopped_info->stopped_status = RDIError_NoError;
+ break;
+ }
+ return RDIError_NoError;
+}
+
+static volatile bool interrupt_request = FALSE;
+
+static void interrupt_target( void )
+{
+ Packet *packet = NULL;
+ int err;
+ int reason, debugID, OSinfo1, OSinfo2, status;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: interrupt_target.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w", ADP_InterruptRequest | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown);
+
+ reason = ADP_InterruptRequest |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ DevSW_FreePacket(packet);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: got interrupt ack ok err = %d, status=%i\n",
+ err, status);
+#endif
+
+ return;
+}
+
+#ifdef TEST_DC_APPL
+ extern void test_dc_appl_handler( const DeviceDescr *device,
+ Packet *packet );
+#endif
+
+/* Core functionality for execute and step */
+static int angel_RDI_ExecuteOrStep(PointHandle *handle, word type,
+ unsigned ninstr)
+{
+ int err;
+ adp_stopped_struct stopped_info;
+ void* stateptr = (void *)&stopped_info;
+ ChannelCallback HandleStoppedMessageFPtr=(ChannelCallback) HandleStoppedMessage;
+ int status, reasoncode, debugID, OSinfo1, OSinfo2;
+ Packet *packet = NULL;
+
+ TracePrint(("angel_RDI_ExecuteOrStep\n"));
+
+ err = Adp_ChannelRegisterRead(CI_TADP,
+ HandleStoppedMessageFPtr, stateptr);
+ if (err != RDIError_NoError) {
+#ifdef DEBUG
+ angel_DebugPrint("TADP Register failed.\n");
+#endif
+ return err;
+ }
+ /* Set executing TRUE here, as it must be set up before the target has
+ * had any chance at all to execute, or it may send its stopped message
+ * before we get round to setting executing = TRUE !!!
+ */
+ executing = TRUE;
+
+ register_debug_message_handler();
+
+#ifdef TEST_DC_APPL
+ Adp_Install_DC_Appl_Handler( test_dc_appl_handler );
+#endif
+
+#ifdef DEBUG
+ angel_DebugPrint("Transmiting %s message.\n",
+ type == ADP_Execute ? "execute": "step");
+#endif
+
+ register_debug_message_handler();
+ /* Extra ninstr parameter for execute message will simply be ignored */
+ err = msgsend(CI_HADP,"%w%w%w%w%w", type | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ninstr);
+#if DEBUG
+ if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
+#endif
+
+ reasoncode = type | TtoH;
+ err = wait_for_debug_message( &reasoncode, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet );
+ if (err != RDIError_NoError)
+ return err;
+ else if (status != RDIError_NoError)
+ return status;
+
+#ifdef DEBUG
+ angel_DebugPrint("Waiting for program to finish...\n");
+#endif
+
+ while( executing )
+ {
+ if (interrupt_request)
+ {
+ interrupt_target();
+ interrupt_request = FALSE;
+ }
+ Adp_AsynchronousProcessing( async_block_on_nothing );
+ }
+
+#ifdef TEST_DC_APPL
+ Adp_Install_DC_Appl_Handler( NULL );
+#endif
+
+ (void)Adp_ChannelRegisterRead(CI_TADP, NULL, NULL);
+
+ *handle = (PointHandle)stopped_info.data;
+
+ CallStoppedProcs(stopped_info.stopped_reason);
+
+ return stopped_info.stopped_status;
+}
+
+/* Request that the target starts executing from the stored CPU state: use
+ ADP_Execute. */
+int angel_RDI_execute(PointHandle *handle)
+{
+ return angel_RDI_ExecuteOrStep(handle, ADP_Execute, 0);
+}
+
+#ifdef __WATCOMC__
+typedef void handlertype(int);
+
+static int interrupted=0;
+
+static void myhandler(int sig) {
+ IGNORE(sig);
+ interrupted=1;
+ signal(SIGINT, myhandler);
+}
+#endif
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_step-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Step 'ninstr' through the code: use ADP_Step. */
+int angel_RDI_step(unsigned ninstr, PointHandle *handle)
+{
+ int err = angel_RDI_ExecuteOrStep(handle, ADP_Step, ninstr);
+ if (err == RDIError_ProgramFinishedInStep)
+ return RDIError_NoError;
+ else
+ return err;
+}
+
+
+static void SetCPWords(int cpnum, struct Dbg_CoProDesc const *cpd) {
+ int i, rmax = 0;
+ for (i = 0; i < cpd->entries; i++)
+ if (cpd->regdesc[i].rmax > rmax)
+ rmax = cpd->regdesc[i].rmax;
+
+ { unsigned char *rmap = (unsigned char *)malloc(rmax + 2);
+ *rmap++ = rmax + 1;
+ for (i = 0; i < cpd->entries; i++) {
+ int r;
+ for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++)
+ rmap[r] = (cpd->regdesc[i].nbytes+3) / 4;
+ }
+/* if (cpwords[cpnum] != NULL) free(cpwords[cpnum]); */
+ cpwords[cpnum] = rmap;
+ }
+}
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_info-----------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Use ADP_Info, ADP_Ctrl and ADP_Profile calls to implement these,
+ see adp.h for more details. */
+
+static int angel_cc_exists( void )
+{
+ Packet *packet = NULL;
+ int err;
+ int reason, debugID, OSinfo1, OSinfo2, subreason, status;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Exists.\n");
+#endif
+
+ if ( angel_RDI_info( RDIInfo_Icebreaker, NULL, NULL ) == RDIError_NoError ) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Exists );
+ reason = ADP_ICEbreakerHADP |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_ICEB_CC_Exists) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+ }
+ else
+ return RDIError_UnimplementedMessage;
+}
+
+typedef struct {
+ RDICCProc_ToHost *tohost; void *tohostarg;
+ RDICCProc_FromHost *fromhost; void *fromhostarg;
+ bool registered;
+} CCState;
+static CCState ccstate = { NULL, NULL, NULL, NULL, FALSE };
+
+static void HandleDCCMessage( Packet *packet, void *stateptr )
+{
+ unsigned int reason, debugID, OSinfo1, OSinfo2;
+ int count;
+ CCState *ccstate_p = (CCState *)stateptr;
+
+ count = unpack_message( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2 );
+ switch ( reason )
+ {
+ case ADP_TDCC_ToHost | TtoH:
+ {
+ /* only handles a single word of data, for now */
+
+ unsigned int nbytes, data;
+
+ unpack_message( BUFFERDATA(packet->pk_buffer)+count, "%w%w",
+ &nbytes, &data );
+#ifdef DEBUG
+ angel_DebugPrint( "DEBUG: received CC_ToHost message: nbytes %d data %08x.\n",
+ nbytes, data );
+#endif
+ ccstate_p->tohost( ccstate_p->tohostarg, data );
+ msgsend(CI_TTDCC, "%w%w%w%w%w",
+ ADP_TDCC_ToHost | HtoT, debugID, OSinfo1, OSinfo2,
+ RDIError_NoError );
+ break;
+ }
+
+ case ADP_TDCC_FromHost | TtoH:
+ {
+ /* only handles a single word of data, for now */
+
+ int valid;
+ ARMword data;
+
+ ccstate_p->fromhost( ccstate_p->fromhostarg, &data, &valid );
+#ifdef DEBUG
+ angel_DebugPrint( "DEBUG: received CC_FromHost message, returning: %08x %s.\n",
+ data, valid ? "VALID" : "INvalid" );
+#endif
+ msgsend(CI_TTDCC, "%w%w%w%w%w%w%w",
+ ADP_TDCC_FromHost | HtoT, debugID, OSinfo1, OSinfo2,
+ RDIError_NoError, valid ? 1 : 0, data );
+ break;
+ }
+
+ default:
+#ifdef DEBUG
+ angel_DebugPrint( "Unexpected TDCC message %08x received\n", reason );
+#endif
+ break;
+ }
+ DevSW_FreePacket(packet);
+ return;
+}
+
+static void angel_check_DCC_handler( CCState *ccstate_p )
+{
+ int err;
+
+ if ( ccstate_p->tohost != NULL || ccstate_p->fromhost != NULL )
+ {
+ /* doing DCC, so need a handler */
+ if ( ! ccstate_p->registered )
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Registering handler for TTDCC channel.\n" );
+#endif
+ err = Adp_ChannelRegisterRead( CI_TTDCC, HandleDCCMessage,
+ ccstate_p );
+ if ( err == adp_ok )
+ ccstate_p->registered = TRUE;
+#ifdef DEBUG
+ else
+ angel_DebugPrint( "angel_check_DCC_handler: register failed!\n" );
+#endif
+ }
+ }
+ else
+ {
+ /* not doing DCC, so don't need a handler */
+ if ( ccstate_p->registered )
+ {
+#ifdef DEBUG
+ angel_DebugPrint( "Unregistering handler for TTDCC channel.\n" );
+#endif
+ err = Adp_ChannelRegisterRead( CI_TTDCC, NULL, NULL );
+ if ( err == adp_ok )
+ ccstate_p->registered = FALSE;
+#ifdef DEBUG
+ else
+ angel_DebugPrint( "angel_check_DCC_handler: unregister failed!\n" );
+#endif
+ }
+ }
+}
+
+
+static int CheckSubMessageReply(int reason, int subreason) {
+ Packet *packet = NULL;
+ int status, debugID, OSinfo1, OSinfo2;
+ int err = RDIError_NoError;
+ reason |= TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ status = err;
+ } else {
+ int sr;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &sr, &status);
+ if (subreason != sr) status = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ return status;
+}
+
+static int SendSubMessageAndCheckReply(int reason, int subreason) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason);
+ return CheckSubMessageReply(reason, subreason);
+}
+
+static int SendSubMessageWordAndCheckReply(int reason, int subreason, ARMword word) {
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason, word);
+ return CheckSubMessageReply(reason, subreason);
+}
+
+static int SendSubMessageGetWordAndCheckReply(int reason, int subreason, ARMword *resp) {
+ Packet *packet = NULL;
+ int status, debugID, OSinfo1, OSinfo2;
+ int err = RDIError_NoError;
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ subreason);
+ reason |= TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ status = err;
+ } else {
+ int sr;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &sr, &status, resp);
+ if (subreason != sr) status = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ return status;
+}
+
+static int const hostsex = 1;
+
+int angel_RDI_info(unsigned type, ARMword *arg1, ARMword *arg2) {
+ Packet *packet = NULL;
+ int len, status, c, reason, subreason, debugID, OSinfo1, OSinfo2;
+ int err=RDIError_NoError, cpnum=0;
+ struct Dbg_CoProDesc *cpd;
+ int count, i;
+ unsigned char *bp;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_info.\n");
+#endif
+ switch (type) {
+ case RDIInfo_Target:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Target.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Target);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ DevSW_FreePacket(packet);
+
+ if (subreason != ADP_Info_Target)
+ return RDIError_Error;
+ else
+ return status;
+
+ case RDISignal_Stop:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDISignal_Stop.\n");
+ if (interrupt_request)
+ angel_DebugPrint(" STILL WAITING to send previous interrupt request\n");
+#endif
+ interrupt_request = TRUE;
+ return RDIError_NoError;
+
+ case RDIInfo_Points:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Points.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Points, arg1);
+
+ case RDIInfo_Step:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Step.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Step, arg1);
+
+ case RDISet_Cmdline:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDISet_Cmdline.\n");
+#endif
+ if (ardi_commandline != &dummycline)
+ free(ardi_commandline);
+ ardi_commandline = (char *)malloc(strlen((char*)arg1) + 1) ;
+ (void)strcpy(ardi_commandline, (char *)arg1) ;
+ return RDIError_NoError;
+
+ case RDIInfo_SetLog:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_SetLog.\n");
+#endif
+ rdi_log = (int) *arg1;
+ return RDIError_NoError;
+
+ case RDIInfo_Log:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_Log.\n");
+#endif
+ *arg1 = rdi_log;
+ return RDIError_NoError;
+
+
+ case RDIInfo_MMU:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_MMU.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_MMU, arg1);
+
+ case RDIInfo_SemiHosting:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_SemiHosting.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_SemiHosting);
+
+ case RDIInfo_CoPro:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_CoPro.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CoPro);
+
+ case RDICycles:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDICycles.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Cycles);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if (subreason != ADP_Info_Cycles)
+ return RDIError_Error;
+ if (status != RDIError_NoError) return status;
+ for (c=0; c<12; c++)
+ arg1[c]=GET32LE(BUFFERDATA(packet->pk_buffer)+24+(c*4));
+ return status;
+
+ case RDIInfo_DescribeCoPro:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_DescribeCoPro.\n");
+#endif
+ cpnum = *(int *)arg1;
+ cpd = (struct Dbg_CoProDesc *)arg2;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ if (angel_RDI_info(ADP_Info_CoPro, NULL, NULL) != RDIError_NoError)
+ return RDIError_Error;
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_DescribeCoPro);
+ len +=msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b%b%b%b%b", cpnum,
+ cpd->regdesc[cpnum].rmin, cpd->regdesc[cpnum].rmax,
+ cpd->regdesc[cpnum].nbytes, cpd->regdesc[cpnum].access);
+ if (cpd->regdesc[cpnum].access&0x3 == 0x3){
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b",
+ cpd->regdesc[cpnum].accessinst.cprt.read_b0,
+ cpd->regdesc[cpnum].accessinst.cprt.read_b1,
+ cpd->regdesc[cpnum].accessinst.cprt.write_b0,
+ cpd->regdesc[cpnum].accessinst.cprt.write_b1, 0xff);
+ }
+ else {
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b%",
+ cpd->regdesc[cpnum].accessinst.cpdt.rdbits,
+ cpd->regdesc[cpnum].accessinst.cpdt.nbit,0,0, 0xff);
+ }
+ register_debug_message_handler();
+ packet->pk_length = len;
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if (subreason != ADP_Info_DescribeCoPro)
+ return RDIError_Error;
+ else
+ return status;
+
+ case RDIInfo_RequestCoProDesc:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: RDIInfo_RequestCoProDesc.\n");
+#endif
+ cpnum = *(int *)arg1;
+ cpd = (struct Dbg_CoProDesc *)arg2;
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_RequestCoProDesc);
+ len += msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b", *(int *)arg1);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Info_RequestCoProDesc) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ } else if ( status != RDIError_NoError ) {
+ DevSW_FreePacket(packet);
+ return status;
+ } else {
+ bp = BUFFERDATA(packet->pk_buffer)+count;
+ for ( i = 0; *bp != 0xFF && i < cpd->entries; ++i ) {
+ cpd->regdesc[i].rmin = *bp++;
+ cpd->regdesc[i].rmax = *bp++;
+ cpd->regdesc[i].nbytes = *bp++;
+ cpd->regdesc[i].access = *bp++;
+ }
+ cpd->entries = i;
+ if ( *bp != 0xFF )
+ status = RDIError_BufferFull;
+ else
+ SetCPWords( cpnum, cpd );
+ DevSW_FreePacket(packet);
+ return status;
+ }
+
+ case RDIInfo_GetLoadSize:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Info_AngelBufferSize);
+ reason = ADP_Info |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Info_AngelBufferSize) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else {
+ word defaultsize, longsize;
+ unpack_message(BUFFERDATA(packet->pk_buffer)+24, "%w%w",
+ &defaultsize, &longsize);
+ *arg1 = longsize - ADP_WriteHeaderSize; /* space for ADP header */
+#ifdef MONITOR_DOWNLOAD_PACKETS
+ angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize: got (%d, %d), returning %d.\n",
+ defaultsize, longsize, *arg1);
+#endif
+ DevSW_FreePacket(packet);
+ return status;
+ }
+
+ case RDIVector_Catch:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_VectorCatch %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_VectorCatch, *arg1);
+
+ case RDISemiHosting_SetState:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetState %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetState, *arg1);
+
+ case RDISemiHosting_GetState:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetState.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetState, arg1);
+
+ case RDISemiHosting_SetVector:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetVector %lx.\n", *arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetVector, *arg1);
+
+ case RDISemiHosting_GetVector:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetVector.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetVector, arg1);
+
+ case RDISemiHosting_SetARMSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetARMSWI.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetARMSWI, *arg1);
+
+ case RDISemiHosting_GetARMSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetARMSWI.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetARMSWI, arg1);
+
+ case RDISemiHosting_SetThumbSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetThumbSWI.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetThumbSWI, *arg1);
+
+ case RDISemiHosting_GetThumbSWI:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetThumbSWI.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetThumbSWI, arg1);
+
+ case RDIInfo_SetTopMem:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_SetTopMem.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SetTopMem, *arg1);
+
+ case RDIPointStatus_Watch:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Watch.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_PointStatus_Watch, *arg1 );
+ reason = ADP_Control |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ if (subreason != ADP_Ctrl_PointStatus_Watch) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+
+ case RDIPointStatus_Break:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Break.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_PointStatus_Break, *arg1 );
+ reason = ADP_Control |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status,
+ arg1, arg2);
+ if (subreason != ADP_Ctrl_PointStatus_Break) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else
+ return status;
+
+ case RDIInfo_DownLoad:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Ctrl_Download_Supported.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Control, ADP_Ctrl_Download_Supported);
+
+ case RDIConfig_Count:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEM_ConfigCount.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_ICEman, ADP_ICEM_ConfigCount, arg1);
+
+ case RDIConfig_Nth:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEM_ConfigNth.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_ConfigNth, *arg1 );
+ reason = ADP_ICEman |TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ } else {
+ RDI_ConfigDesc *cd = (RDI_ConfigDesc *)arg2;
+ unsigned char n;
+ len = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%b",
+ &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status,
+ &cd->version, &n);
+ if (subreason != ADP_ICEM_ConfigNth) {
+ DevSW_FreePacket(packet);
+ return RDIError_Error;
+ }
+ else {
+ memcpy( cd->name, BUFFERDATA(packet->pk_buffer)+len, n+1 );
+ cd->name[n] = 0;
+ return status;
+ }
+ }
+
+ case RDIInfo_Icebreaker:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_Exists.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_Exists);
+
+ case RDIIcebreaker_GetLocks:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_GetLocks.\n");
+#endif
+ return SendSubMessageGetWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_GetLocks, arg1);
+
+ case RDIIcebreaker_SetLocks:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_SetLocks.\n");
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_SetLocks, *arg1);
+
+ case RDICommsChannel_ToHost:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_ToHost.\n");
+#endif
+ if ( angel_cc_exists() == RDIError_NoError ) {
+
+ /*
+ * The following three lines of code have to be removed in order to get
+ * the Windows Angel Channel Viewer working with the Thumb comms channel.
+ * At the moment it allows the ARMSD command line to register a CCIN/CCOUT
+ * callback which stops the ACV working!
+ */
+#ifdef __unix
+ ccstate.tohost = (RDICCProc_ToHost *)arg1;
+ ccstate.tohostarg = arg2;
+ angel_check_DCC_handler( &ccstate );
+#endif
+#ifdef _WIN32
+
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Connect_ToHost, (arg1 != NULL) );
+ return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_ToHost);
+ } else {
+ return RDIError_UnimplementedMessage;
+ }
+
+ case RDICommsChannel_FromHost:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_FromHost.\n");
+#endif
+ if ( angel_cc_exists() == RDIError_NoError ) {
+
+ ccstate.fromhost = (RDICCProc_FromHost *)arg1;
+ ccstate.fromhostarg = arg2;
+ angel_check_DCC_handler( &ccstate );
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEB_CC_Connect_FromHost, (arg1 != NULL) );
+ return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_FromHost);
+ } else {
+ return RDIError_UnimplementedMessage;
+ }
+
+ case RDIProfile_Stop:
+ return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_Stop);
+
+ case RDIProfile_ClearCounts:
+ return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_ClearCounts);
+
+ case RDIProfile_Start:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_Start %ld.\n", (long)*arg1);
+#endif
+ return SendSubMessageWordAndCheckReply(ADP_Profile, ADP_Profile_Start, *arg1);
+
+ case RDIProfile_WriteMap:
+ { RDI_ProfileMap *map = (RDI_ProfileMap *)arg1;
+ int32 maplen = map->len,
+ offset,
+ size;
+ int32 chunk = (Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_ProfileWriteHeaderSize) / sizeof(ARMword);
+ /* Maximum number of words sendable in one message */
+ int oldrev = bytesex_reversing();
+ int host_little = *(uint8 const *)&hostsex;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_WriteMap %ld.\n", maplen);
+#endif
+ status = RDIError_NoError;
+ if (!host_little) {
+ bytesex_reverse(1);
+ for (offset = 0; offset < maplen; offset++)
+ map->map[offset] = bytesex_hostval(map->map[offset]);
+ }
+ for (offset = 0; offset < maplen; offset += size) {
+ unsigned hdrlen;
+ size = maplen - offset;
+ packet = (Packet *)DevSW_AllocatePacket(Armsd_LongBufSize);
+ if (size > chunk) size = chunk;
+ hdrlen = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
+ ADP_Profile | HtoT, 0, ADP_HandleUnknown,
+ ADP_HandleUnknown, ADP_Profile_WriteMap,
+ maplen, size, offset);
+
+ /* Copy the data into the packet. */
+ memcpy(BUFFERDATA(packet->pk_buffer)+hdrlen,
+ &map->map[offset], (size_t)size * sizeof(ARMword));
+ packet->pk_length = size * sizeof(ARMword) + hdrlen;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason = ADP_Profile | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err == RDIError_NoError) {
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ if (subreason != ADP_Profile_WriteMap) {
+ err = RDIError_Error;
+ }
+ DevSW_FreePacket(packet);
+ }
+ if (err != RDIError_NoError) { status = err; break; }
+ }
+ if (!host_little) {
+ for (offset = 0; offset < maplen; offset++)
+ map->map[offset] = bytesex_hostval(map->map[offset]);
+ bytesex_reverse(oldrev);
+ }
+ return status;
+ }
+
+ case RDIProfile_ReadMap:
+ { int32 maplen = *(int32 *)arg1,
+ offset = 0,
+ size;
+ int32 chunk = (Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ProfileReadHeaderSize) / sizeof(ARMword);
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: ADP_Profile_ReadMap %ld.\n", maplen);
+#endif
+ status = RDIError_NoError;
+ for (offset = 0; offset < maplen; offset += size) {
+ size = maplen - offset;
+ if (size > chunk) size = chunk;
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Profile | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Profile_ReadMap, offset, size);
+ reason = ADP_Profile | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) return err;
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ memcpy(&arg2[offset], BUFFERDATA(packet->pk_buffer)+ADP_ProfileReadHeaderSize,
+ size * sizeof(ARMword));
+ DevSW_FreePacket(packet);
+ if (status != RDIError_NoError) break;
+ }
+ { int oldrev = bytesex_reversing();
+ int host_little = *(uint8 const *)&hostsex;
+ if (!host_little) {
+ bytesex_reverse(1);
+ for (offset = 0; offset < maplen; offset++)
+ arg2[offset] = bytesex_hostval(arg2[offset]);
+ }
+ bytesex_reverse(oldrev);
+ }
+ return status;
+ }
+
+ case RDIInfo_CanTargetExecute:
+#ifdef DEBUG
+ printf("DEBUG: RDIInfo_CanTargetExecute.\n");
+#endif
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CanTargetExecute);
+
+ case RDIInfo_AgentEndianess:
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_AgentEndianess);
+
+ default:
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Fell through ADP_Info, default case taken.\n");
+ angel_DebugPrint("DEBUG: type = 0x%x.\n", type);
+#endif
+ if (type & RDIInfo_CapabilityRequest) {
+ switch (type & ~RDIInfo_CapabilityRequest) {
+ case RDISemiHosting_SetARMSWI:
+ return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_ChangeableSHSWI);
+ default:
+#ifdef DEBUG
+ angel_DebugPrint(
+ "DEBUG: ADP_Info - Capability Request(%d) - reporting unimplemented \n",
+ type & ~RDIInfo_CapabilityRequest);
+#endif
+ break;
+ }
+ }
+ return RDIError_UnimplementedMessage;
+ }
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_AddConfig------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Add a configuration: use ADP_ICEM_AddConfig. */
+int angel_RDI_AddConfig(unsigned long nbytes) {
+ Packet *packet = NULL;
+ int status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_AddConfig.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_AddConfig, nbytes);
+ reason=ADP_ICEman | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_ICEM_AddConfig )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_LoadConfigData-------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Load configuration data: use ADP_Ctrl_Download_Data. */
+int angel_RDI_LoadConfigData(unsigned long nbytes, char const *data) {
+ Packet *packet = NULL;
+ int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_LoadConfigData (%d bytes)\n", nbytes);
+#endif
+#if 0
+ if (err = angel_RDI_AddConfig(nbytes) != RDIError_NoError)
+ return err;
+#endif
+ packet = DevSW_AllocatePacket(Armsd_LongBufSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
+ ADP_Control | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Download_Data, nbytes);
+ memcpy(BUFFERDATA(packet->pk_buffer)+len, data, nbytes);
+ len += nbytes;
+ packet->pk_length = len;
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: packet len %d.\n", len);
+#endif
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Download_Data )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_SelectConfig---------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Select a configuration: use ADP_ICEM_SelecConfig.*/
+int angel_RDI_SelectConfig(RDI_ConfigAspect aspect, char const *name,
+ RDI_ConfigMatchType matchtype, unsigned versionreq,
+ unsigned *versionp)
+{
+ Packet *packet = NULL;
+ int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: Entered angel_RDI_SelectConfig.\n");
+#endif
+ packet = DevSW_AllocatePacket(Armsd_BufferSize);
+ len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b%b%b%w",
+ ADP_ICEman | HtoT, 0,
+ ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_ICEM_SelectConfig, aspect, strlen(name),
+ matchtype, versionreq);
+ /* copy the name into the buffer */
+ memcpy(BUFFERDATA(packet->pk_buffer)+len, name, strlen(name));
+ len += strlen(name);
+ packet->pk_length = len;
+ register_debug_message_handler();
+ Adp_ChannelWrite(CI_HADP, packet);
+ reason=ADP_ICEman | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return err;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w",
+ &reason, &debugID, &OSinfo1, &OSinfo2,
+ &subreason, &status, versionp);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_ICEM_SelectConfig )
+ return RDIError_Error;
+ else
+ return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*----angel_RDI_LoadAgent------------------------------------------------*/
+/*----------------------------------------------------------------------*/
+
+/* Load a new debug agent: use ADP_Ctrl_Download_Agent. */
+int angel_RDI_LoadAgent(ARMword dest, unsigned long size,
+ getbufferproc *getb, void *getbarg)
+{
+ Packet *packet = NULL;
+ int status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
+ time_t t;
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: Entered angel_RDI_LoadAgent.\n");
+#endif
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Control | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Download_Agent, dest, size);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
+ &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Download_Agent )
+ return RDIError_Error;
+ if ( status != RDIError_NoError )
+ return status;
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: starting agent data download.\n");
+#endif
+ { unsigned long pos = 0, segsize;
+ for (; pos < size; pos += segsize) {
+ char *b = getb(getbarg, &segsize);
+ if (b == NULL) return RDIError_NoError;
+ err = angel_RDI_LoadConfigData( segsize, b );
+ if (err != RDIError_NoError) return err;
+ }
+ }
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: finished downloading new agent.\n");
+#endif
+
+ /* renegotiate back down */
+ err = angel_negotiate_defaults();
+ if (err != adp_ok)
+ return err;
+
+ /* Output a message to tell the user what is going on. This is vital
+ * when switching from ADP EICE to ADP over JTAG, as then the user
+ * has to reset the target board !
+ */
+ { char msg[256];
+ int len=angel_RDI_errmess(msg, 256, adp_new_agent_starting);
+ angel_hostif->write(angel_hostif->hostosarg, msg, len);
+ }
+
+ /* get new image started */
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: sending start message for new agent.\n");
+#endif
+
+ register_debug_message_handler();
+ msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT,
+ 0, ADP_HandleUnknown, ADP_HandleUnknown,
+ ADP_Ctrl_Start_Agent, dest);
+ reason=ADP_Control | TtoH;
+ err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
+ &status, &packet);
+ if (err != RDIError_NoError) {
+ DevSW_FreePacket(packet);
+ return -1;
+ }
+ unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
+ &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
+ DevSW_FreePacket(packet);
+ if ( subreason != ADP_Ctrl_Start_Agent )
+ return RDIError_Error;
+ if ( status != RDIError_NoError )
+ return status;
+
+ /* wait for image to start up */
+ heartbeat_enabled = FALSE;
+ t=time(NULL);
+ do {
+ Adp_AsynchronousProcessing(async_block_on_nothing);
+ if ((time(NULL)-t) > 2) {
+#ifdef DEBUG
+ angel_DebugPrint("DEBUG: no booted message from new image yet.\n");
+#endif
+ break;
+ }
+ } while (booted_not_received);
+ booted_not_received=1;
+
+ /* Give device driver a chance to do any necessary resyncing with new agent.
+ * Only used by etherdrv.c at the moment.
+ */
+ (void)Adp_Ioctl( DC_RESYNC, NULL );
+
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint("DEBUG: reopening to new agent.\n");
+#endif
+ err = angel_RDI_open(0, NULL, NULL, NULL);
+ switch ( err )
+ {
+ case RDIError_NoError:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_NoError\n" );
+#endif
+ break;
+ }
+
+ case RDIError_LittleEndian:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_LittleEndian (OK)\n" );
+#endif
+ err = RDIError_NoError;
+ break;
+ }
+
+ case RDIError_BigEndian:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned RDIError_BigEndian (OK)\n" );
+#endif
+ err = RDIError_NoError;
+ break;
+ }
+
+ default:
+ {
+#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
+ angel_DebugPrint( "LoadAgent: Open returned %d - unexpected!\n", err );
+#endif
+ break;
+ }
+ }
+#ifndef NO_HEARTBEAT
+ heartbeat_enabled = TRUE;
+#endif
+ return err;
+}
+
+static int angel_RDI_errmess(char *buf, int blen, int errnum) {
+ char *s=NULL;
+ int n;
+
+ switch (errnum) {
+ case adp_malloc_failure:
+ s=AdpMess_MallocFailed; break;
+ case adp_illegal_args:
+ s=AdpMess_IllegalArgs; break;
+ case adp_device_not_found:
+ s=AdpMess_DeviceNotFound; break;
+ case adp_device_open_failed:
+ s=AdpMess_DeviceOpenFailed; break;
+ case adp_device_already_open:
+ s=AdpMess_DeviceAlreadyOpen; break;
+ case adp_device_not_open:
+ s=AdpMess_DeviceNotOpen; break;
+ case adp_bad_channel_id:
+ s=AdpMess_BadChannelId; break;
+ case adp_callback_already_registered:
+ s=AdpMess_CBAlreadyRegd; break;
+ case adp_write_busy:
+ s=AdpMess_WriteBusy; break;
+ case adp_bad_packet:
+ s=AdpMess_BadPacket; break;
+ case adp_seq_high:
+ s=AdpMess_SeqHigh; break;
+ case adp_seq_low:
+ s=AdpMess_SeqLow; break;
+ case adp_timeout_on_open:
+ s=AdpMess_TimeoutOnOpen; break;
+ case adp_failed:
+ s=AdpMess_Failed; break;
+ case adp_abandon_boot_wait:
+ s=AdpMess_AbandonBootWait; break;
+ case adp_late_startup:
+ s=AdpMess_LateStartup; break;
+ case adp_new_agent_starting:
+ s=AdpMess_NewAgentStarting; break;
+ default: return 0;
+ }
+ n=strlen(s);
+ if (n>blen-1) n=blen-1;
+ memcpy(buf, s, n);
+ buf[n++]=0;
+ return n;
+}
+
+extern const struct RDIProcVec angel_rdi;
+const struct RDIProcVec angel_rdi = {
+ "ADP",
+ angel_RDI_open,
+ angel_RDI_close,
+ angel_RDI_read,
+ angel_RDI_write,
+ angel_RDI_CPUread,
+ angel_RDI_CPUwrite,
+ angel_RDI_CPread,
+ angel_RDI_CPwrite,
+ angel_RDI_setbreak,
+ angel_RDI_clearbreak,
+ angel_RDI_setwatch,
+ angel_RDI_clearwatch,
+ angel_RDI_execute,
+ angel_RDI_step,
+ angel_RDI_info,
+ angel_RDI_pointinq,
+
+ angel_RDI_AddConfig,
+ angel_RDI_LoadConfigData,
+ angel_RDI_SelectConfig,
+
+ 0, /*angel_RDI_drivernames,*/
+ 0, /* cpunames */
+
+ angel_RDI_errmess,
+
+ angel_RDI_LoadAgent
+};
+
+/* EOF ardi.c */
+
+/* Not strictly necessary, but allows linking this code into armsd. */
+
+struct foo {
+ char *name;
+ int (*action)();
+ char *syntax;
+ char **helpmessage;
+ int doafterend;
+ int dobeforestart;
+ int doinmidline;
+} hostappl_CmdTable[1] = {{"", NULL}};
+
+void
+hostappl_Init()
+{
+}
+
+int
+hostappl_Backstop()
+{
+ return -30;
+}