1/*
2 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3 *
4 * This software may be freely used, copied, modified, and distributed
5 * provided that the above copyright notice is preserved in all copies of the
6 * software.
7 */
8
9/*
10 * ARDI.c
11 * Angel Remote Debug Interface
12 *
13 *
14 * $Revision: 1.3 $
15 *     $Date: 2004/12/27 14:00:53 $
16 *
17 * This file is based on /plg/pisd/rdi.c, but instead of using RDP it uses
18 * ADP messages.
19 */
20
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#define uint HIDE_HPs_uint
26#include <signal.h>
27#undef uint
28
29
30#include "angel_endian.h"
31#include "ardi.h"
32#include "buffers.h"
33#include "channels.h"
34#include "hostchan.h"
35#include "host.h"
36#include "angel_bytesex.h"
37#include "dbg_cp.h"
38#include "adp.h"
39#include "hsys.h"
40#include "logging.h"
41#include "msgbuild.h"
42#include "rxtx.h"
43#include "devsw.h"
44#include "params.h"
45
46#ifdef COMPILING_ON_WINDOWS
47#  define IGNORE(x) (x = x)   /* must go after #includes to work on Windows */
48#endif
49#define NOT(x) (!(x))
50
51#define ADP_INITIAL_TIMEOUT_PERIOD 5
52
53static volatile int executing;
54static int rdi_log = 0 ; /* debugging  ? */
55
56/* we need a starting point for our first buffers, this is a safe one */
57int Armsd_BufferSize = ADP_BUFFER_MIN_SIZE;
58int Armsd_LongBufSize = ADP_BUFFER_MIN_SIZE;
59
60#ifdef WIN32
61  extern int interrupted;
62  extern int swiprocessing;
63#endif
64
65static char dummycline = 0;
66char *ardi_commandline = &dummycline ; /* exported in ardi.h */
67
68extern unsigned int heartbeat_enabled;
69
70static unsigned char *cpwords[16];
71
72typedef struct stoppedProcListElement {
73  struct stoppedProcListElement *next;
74  angel_RDI_TargetStoppedProc *fn;
75  void *arg;
76} stoppedProcListElement;
77
78static stoppedProcListElement *stopped_proc_list=NULL;
79
80const struct Dbg_HostosInterface *angel_hostif;
81static hsys_state *hstate;
82
83static void angel_DebugPrint(const char *format, ...)
84{ va_list ap;
85  va_start(ap, format);
86  angel_hostif->dbgprint(angel_hostif->dbgarg, format, ap);
87  va_end(ap);
88}
89
90#ifdef RDI_VERBOSE
91#define TracePrint(s) \
92  if (rdi_log & 2) angel_DebugPrint("\n"); \
93  if (rdi_log & 1) angel_DebugPrint s
94#else
95#define TracePrint(s)
96#endif
97
98typedef struct receive_dbgmsg_state {
99  volatile int received;
100  Packet *packet;
101} receive_dbgmsg_state;
102
103static receive_dbgmsg_state dbgmsg_state;
104
105static void receive_debug_packet(Packet *packet, void *stateptr)
106{
107  receive_dbgmsg_state *state = stateptr;
108
109  state->packet = packet;
110  state->received = 1;
111}
112
113static int register_debug_message_handler(void)
114{
115  int err;
116  dbgmsg_state.received = 0;
117
118  err = Adp_ChannelRegisterRead(CI_HADP, receive_debug_packet, &dbgmsg_state);
119#ifdef DEBUG
120  if (err!=adp_ok) angel_DebugPrint("register_debug_message_handler failed %i\n", err);
121#endif
122  return err;
123}
124
125
126static int wait_for_debug_message(int *rcode, int *debugID,
127                                  int *OSinfo1, int *OSinfo2,
128                                  int *status, Packet **packet)
129{
130  unsigned int reason;
131
132#ifdef DEBUG
133  angel_DebugPrint("wait_for_debug_message waiting for %X\n", *rcode);
134#endif
135
136  for ( ; dbgmsg_state.received == 0 ; )
137    Adp_AsynchronousProcessing(async_block_on_read);
138
139#ifdef DEBUG
140  angel_DebugPrint("wait_for_debug_message got packet\n");
141#endif
142
143  *packet = dbgmsg_state.packet;
144
145  Adp_ChannelRegisterRead(CI_HADP, NULL, NULL);
146
147  /*
148   * TODO:
149   * If ADP_Unrecognised return error.
150   * If ADP_Acknowledge - handle appropriately.
151   * If expected message read arguments and return RDIError_NoError.
152   * Note: if RDIError occurs then the data values returned are junk
153   */
154
155  unpack_message(BUFFERDATA((*packet)->pk_buffer), "%w%w%w%w%w", &reason, debugID,
156                 OSinfo1, OSinfo2, status);
157  if ((reason&0xffffff) == ADP_HADPUnrecognised)
158    return RDIError_UnimplementedMessage;
159  if (reason != (unsigned ) *rcode) {
160    if((reason&0xffffff) == ADP_HADPUnrecognised)
161      return RDIError_UnimplementedMessage;
162    else {
163      angel_DebugPrint("ARDI ERROR: Expected reasoncode %x got reasoncode %x.\n",
164             *rcode, reason);
165      return RDIError_Error;
166    }
167  }
168  else
169    return RDIError_NoError;
170  return RDIError_Error;    /* stop a pesky ANSI compiler warning */
171}
172
173
174/*
175 * Handler and registration for logging messages from target
176 */
177static void TargetLogCallback( Packet *packet, void *state )
178{
179    p_Buffer     reply = BUFFERDATA(packet->pk_buffer);
180    unsigned int len   = packet->pk_length;
181    IGNORE(state);
182    angel_hostif->write(angel_hostif->hostosarg,
183                        (char *)reply, len - CHAN_HEADER_SIZE);
184    DevSW_FreePacket(packet);
185
186    packet = DevSW_AllocatePacket(4); /* better not ask for 0 */
187    /* the reply is the ACK - any contents are ignored */
188    if (packet != NULL)
189       Adp_ChannelWrite( CI_TLOG, packet );
190}
191
192static void TargetLogInit( void )
193{
194    AdpErrs err = Adp_ChannelRegisterRead( CI_TLOG, TargetLogCallback, NULL );
195
196#ifdef DEBUG
197    if (err != adp_ok)
198       angel_DebugPrint("CI_TLOG RegisterRead failed %d\n", err);
199#else
200    IGNORE(err);
201#endif
202}
203
204/*----------------------------------------------------------------------*/
205/*----angel_RDI_open-----------------------------------------------------*/
206/*----------------------------------------------------------------------*/
207
208typedef struct NegotiateState {
209      bool             negotiate_resp;
210      bool             negotiate_ack;
211      bool             link_check_resp;
212      ParameterConfig *accepted_config;
213} NegotiateState;
214
215static void receive_negotiate(Packet *packet, void *stateptr)
216{
217    unsigned reason, debugID, OSinfo1, OSinfo2, status;
218    NegotiateState *n_state = (NegotiateState *)stateptr;
219    p_Buffer reply = BUFFERDATA(packet->pk_buffer);
220
221    unpack_message( reply, "%w%w%w%w",
222                    &reason, &debugID, &OSinfo1, &OSinfo2 );
223    reply += ADP_DEFAULT_HEADER_SIZE;
224
225#ifdef DEBUG
226    angel_DebugPrint( "receive_negotiate: reason %x\n", reason );
227#endif
228
229    switch ( reason )
230    {
231        case ADP_ParamNegotiate | TtoH:
232        {
233            n_state->negotiate_resp = TRUE;
234
235            status = GET32LE( reply );
236            reply += sizeof(word);
237#ifdef DEBUG
238            angel_DebugPrint( "ParamNegotiate status %u\n", status );
239#endif
240            if ( status == RDIError_NoError )
241            {
242                if ( Angel_ReadParamConfigMessage(
243                         reply, n_state->accepted_config ) )
244                   n_state->negotiate_ack = TRUE;
245            }
246            break;
247        }
248
249        case ADP_LinkCheck | TtoH:
250        {
251#ifdef DEBUG
252            angel_DebugPrint( "PONG!\n" );
253#endif
254            n_state->link_check_resp = TRUE;
255            break;
256        }
257
258        default:
259        {
260#ifdef DEBUG
261            angel_DebugPrint( "Unexpected!\n" );
262#endif
263            break;
264        }
265    }
266    DevSW_FreePacket( packet );
267}
268
269# include <sys/types.h>
270#ifdef __unix
271# include <sys/time.h>
272#else
273# include <time.h>
274#endif
275
276/*
277 * convert a config into a single-valued options list
278 */
279static ParameterOptions *config_to_options( const ParameterConfig *config )
280{
281    unsigned int        num_params;
282    size_t              size;
283    ParameterOptions   *base_p;
284
285    num_params  = config->num_parameters;
286    size        =
287        sizeof(ParameterOptions)
288        + num_params*(sizeof(ParameterList) + sizeof(unsigned int));
289    base_p      = malloc( size );
290
291    if ( base_p != NULL )
292    {
293        unsigned int    u;
294        ParameterList  *list_p          =
295            (ParameterList *)((char *)base_p + sizeof(ParameterOptions));
296        unsigned int   *option_p        =
297            (unsigned int *)(list_p + num_params);
298
299        base_p->num_param_lists = num_params;
300        base_p->param_list = list_p;
301
302        for ( u = 0; u < num_params; ++u )
303        {
304            option_p[u]                 = config->param[u].value;
305            list_p[u].type              = config->param[u].type;
306            list_p[u].num_options       = 1;
307            list_p[u].option            = &option_p[u];
308        }
309    }
310
311    return base_p;
312}
313
314static AdpErrs negotiate_params( const ParameterOptions *user_options )
315{
316    Packet                    *packet;
317    unsigned int               count;
318    static Parameter           params[AP_NUM_PARAMS];
319    static ParameterConfig     accepted_config = { AP_NUM_PARAMS, params };
320
321    time_t t;
322
323    static volatile NegotiateState    n_state;
324    n_state.negotiate_resp = FALSE;
325    n_state.negotiate_ack = FALSE;
326    n_state.link_check_resp = FALSE;
327    n_state.accepted_config = &accepted_config;
328
329#ifdef DEBUG
330    angel_DebugPrint( "negotiate_params\n" );
331#endif
332
333    Adp_ChannelRegisterRead( CI_HBOOT, receive_negotiate, (void *)&n_state );
334
335    packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
336    count = msgbuild( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
337                      ADP_ParamNegotiate | HtoT, 0,
338                      ADP_HandleUnknown, ADP_HandleUnknown );
339    count += Angel_BuildParamOptionsMessage(
340        BUFFERDATA(packet->pk_buffer) + count, user_options );
341    packet->pk_length = count;
342    Adp_ChannelWriteAsync( CI_HBOOT, packet );
343
344#ifdef DEBUG
345    angel_DebugPrint( "sent negotiate packet\n" );
346#endif
347
348    t=time(NULL);
349
350    do {
351      Adp_AsynchronousProcessing(async_block_on_nothing);
352
353      if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD) {
354        return adp_timeout_on_open;
355      }
356    } while ( ! n_state.negotiate_resp );
357
358    if ( n_state.negotiate_ack )
359    {
360        /* select accepted config */
361        Adp_Ioctl( DC_SET_PARAMS, (void *)n_state.accepted_config );
362
363        /*
364         * 960430 KWelton
365         *
366         * There is a race in the renegotiation protocol: the
367         * target has to have had time to load new config before
368         * we send the link check packet - insert a deliberate
369         * pause (100ms) to give the target some time
370         */
371        Adp_delay(100000);
372
373        /* do link check */
374        msgsend( CI_HBOOT, "%w%w%w%w", ADP_LinkCheck | HtoT, 0,
375                 ADP_HandleUnknown, ADP_HandleUnknown );
376#ifdef DEBUG
377        angel_DebugPrint("sent link check\n");
378#endif
379
380        do {
381            Adp_AsynchronousProcessing(async_block_on_read);
382        } while ( ! n_state.link_check_resp );
383        Adp_initSeq();
384    }
385    return adp_ok;
386}
387
388static int late_booted = FALSE;
389static bool ardi_handler_installed = FALSE;
390
391#ifdef __unix
392static struct sigaction old_action;
393#else
394static void (*old_handler)();
395#endif
396
397static bool boot_interrupted = FALSE;
398static volatile bool interrupt_request = FALSE;
399static volatile bool stop_request = FALSE;
400
401static void ardi_sigint_handler(int sig) {
402#ifdef DEBUG
403    if (sig != SIGINT)
404       angel_DebugPrint("Expecting SIGINT got %d.\n", sig);
405#else
406    IGNORE(sig);
407#endif
408    boot_interrupted = TRUE;
409    interrupt_request = TRUE;
410#ifndef __unix
411    signal(SIGINT, ardi_sigint_handler);
412#endif
413}
414
415static void install_ardi_handler( void ) {
416  if (!ardi_handler_installed) {
417    /* install a new Ctrl-C handler so we can abandon waiting */
418#ifdef __unix
419    struct sigaction new_action;
420    sigemptyset(&new_action.sa_mask);
421    new_action.sa_handler = ardi_sigint_handler;
422    new_action.sa_flags = 0;
423    sigaction(SIGINT, &new_action, &old_action);
424#else
425    old_handler = signal(SIGINT, ardi_sigint_handler);
426#endif
427    ardi_handler_installed = TRUE;
428  }
429}
430
431static int angel_RDI_errmess(char *buf, int blen, int errnum);
432
433static void receive_reset_acknowledge(Packet *packet, void *stateptr) {
434  unsigned reason, debugID, OSinfo1, OSinfo2, status;
435  IGNORE(stateptr);
436
437  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
438                 &OSinfo1, &OSinfo2, &status);
439  if (reason==(ADP_Reset | TtoH) && status==AB_NORMAL_ACK) {
440#ifdef DEBUG
441    angel_DebugPrint("DEBUG: Successfully received normal reset acknowledgement\n");
442    late_booted = FALSE;
443#endif
444  } else if (reason==(ADP_Reset | TtoH) && status==AB_LATE_ACK) {
445    char late_msg[AdpMessLen_LateStartup];
446    int  late_len;
447#ifdef DEBUG
448    angel_DebugPrint("DEBUG: Successfully received LATE reset acknowledgement\n");
449#endif
450    late_booted = TRUE;
451    install_ardi_handler();
452    late_len = angel_RDI_errmess(late_msg,
453                                 AdpMessLen_LateStartup, adp_late_startup);
454    angel_hostif->write(angel_hostif->hostosarg, late_msg, late_len);
455  } else {
456#ifdef DEBUG
457    angel_DebugPrint("DEBUG: Bad reset ack: reason=%8X, status=%8X\n", reason, status);
458#endif
459  }
460  DevSW_FreePacket(packet);
461}
462
463static int booted_not_received;
464static unsigned int angel_version;
465static unsigned int adp_version;
466static unsigned int arch_info;
467static unsigned int cpu_info;
468static unsigned int hw_status;
469
470static void receive_booted(Packet *packet, void *stateptr) {
471  unsigned reason, debugID, OSinfo1, OSinfo2, banner_length, bufsiz, longsiz;
472  unsigned i, count;
473
474  IGNORE(stateptr);
475
476  count = unpack_message(BUFFERDATA(packet->pk_buffer),
477                         "%w%w%w%w%w%w%w%w%w%w%w%w",
478                 &reason, &debugID, &OSinfo1, &OSinfo2, &bufsiz, &longsiz,
479                 &angel_version, &adp_version,
480                 &arch_info, &cpu_info, &hw_status, &banner_length);
481  if (reason==(ADP_Booted | TtoH)) {
482#ifdef MONITOR_DOWNLOAD_PACKETS
483    angel_DebugPrint("DEBUG: Successfully received Booted\n");
484    angel_DebugPrint("       cpu_info=%8X, hw_status=%8X, bufsiz=%d, longsiz=%d\n",
485           cpu_info, hw_status, bufsiz, longsiz);
486#endif
487    /* Get the banner from the booted message */
488    for (i=0; i<banner_length; i++)
489      angel_hostif->writec(angel_hostif->hostosarg,
490                          (BUFFERDATA(packet->pk_buffer)+count)[i]);
491
492    booted_not_received=0;
493#ifndef NO_HEARTBEAT
494    heartbeat_enabled = TRUE;
495#endif
496    Armsd_BufferSize = bufsiz + CHAN_HEADER_SIZE;
497    Armsd_LongBufSize = longsiz + CHAN_HEADER_SIZE;
498  } else {
499#ifdef DEBUG
500    angel_DebugPrint("DEBUG: Bad Booted msg: reason=%8X\n", reason);
501#endif
502  }
503  DevSW_FreePacket(packet);
504}
505
506
507/* forward declaration */
508static int angel_negotiate_defaults( void );
509
510/* Open communications. */
511int angel_RDI_open(
512    unsigned type, Dbg_ConfigBlock const *config,
513    Dbg_HostosInterface const *hostif, struct Dbg_MCState *dbg_state)
514{
515  Packet *packet;
516  int status, reasoncode, debugID, OSinfo1, OSinfo2, err;
517  ParameterOptions *user_options = NULL;
518
519  time_t t;
520
521  IGNORE( dbg_state );
522
523  if ((type & 1) == 0) {
524    /* cold start */
525    if (hostif != NULL) {
526      angel_hostif = hostif;
527      err = HostSysInit(hostif, &ardi_commandline, &hstate);
528      if (err != RDIError_NoError) {
529#ifdef DEBUG
530        angel_DebugPrint("DEBUG: HostSysInit error %i\n",err);
531#endif
532        return err;
533      }
534    }
535    TargetLogInit();
536  }
537
538#ifdef DEBUG
539  angel_DebugPrint("DEBUG: Buffer allocated in angel_RDI_open(type=%i).\n",type);
540#endif
541
542  if ((type & 1) == 0) {
543    /* cold start */
544    unsigned endian;
545    Adp_Ioctl( DC_GET_USER_PARAMS, (void *)&user_options );
546    if ( user_options != NULL ) {
547      err = negotiate_params( user_options );
548      if (err != adp_ok) return err;
549    }
550    else {
551      ParameterConfig *default_config = NULL;
552      Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
553      if ( default_config != NULL ) {
554        ParameterOptions *default_options = config_to_options(default_config);
555        err = negotiate_params( default_options );
556        if (err != adp_ok) return err;
557      }
558    }
559
560    /* Register handlers before sending any messages */
561    booted_not_received=1;
562    Adp_ChannelRegisterRead(CI_HBOOT, receive_reset_acknowledge, NULL);
563    Adp_ChannelRegisterRead(CI_TBOOT, receive_booted, NULL);
564    endian = 0;
565    if (config!=NULL) {
566      if (config->bytesex & RDISex_Little) endian |= ADP_BootHostFeature_LittleEnd;
567      if (config->bytesex & RDISex_Big) endian |= ADP_BootHostFeature_BigEnd;
568    }
569    msgsend(CI_HBOOT,"%w%w%w%w%w", ADP_Reset | HtoT, 0,
570            ADP_HandleUnknown, ADP_HandleUnknown, endian);
571#ifdef DEBUG
572    angel_DebugPrint("DEBUG: Transmitted Reset message in angel_RDI_open.\n");
573#endif
574
575    /* We will now either get an acknowledgement for the Reset message
576     * or if the target was started after the host, we will get a
577     * rebooted message first.
578     */
579
580#ifdef DEBUG
581    angel_DebugPrint("DEBUG: waiting for a booted message\n");
582#endif
583
584    {
585      boot_interrupted = FALSE;
586
587      if (late_booted)
588        install_ardi_handler();
589
590      t=time(NULL);
591
592      do {
593        Adp_AsynchronousProcessing(async_block_on_nothing);
594        if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD && !late_booted) {
595          return adp_timeout_on_open;
596        }
597      } while (booted_not_received && !boot_interrupted);
598
599      if (ardi_handler_installed)
600      {
601        /* uninstall our Ctrl-C handler */
602#ifdef __unix
603        sigaction(SIGINT, &old_action, NULL);
604#else
605        signal(SIGINT, old_handler);
606#endif
607      }
608
609      if (boot_interrupted) {
610        angel_negotiate_defaults();
611        return adp_abandon_boot_wait;
612      }
613    }
614
615    booted_not_received=1;
616    Adp_ChannelRegisterRead(CI_HBOOT, NULL, NULL);
617
618    /* Leave the booted handler installed */
619    msgsend(CI_TBOOT, "%w%w%w%w%w", ADP_Booted | HtoT, 0,
620            ADP_HandleUnknown, ADP_HandleUnknown, 0);
621    Adp_initSeq();
622#ifdef DEBUG
623    angel_DebugPrint("DEBUG: Transmitted ADP_Booted acknowledgement.\n");
624    angel_DebugPrint("DEBUG: Boot sequence completed, leaving angel_RDI_open.\n");
625#endif
626
627    return (hw_status & ADP_CPU_BigEndian )? RDIError_BigEndian :
628      RDIError_LittleEndian;
629  }
630  else {
631    /* warm start */
632    register_debug_message_handler();
633
634    msgsend(CI_HADP, "%w%w%w%w",
635            ADP_InitialiseApplication | HtoT, 0,
636            ADP_HandleUnknown, ADP_HandleUnknown);
637#ifdef DEBUG
638    angel_DebugPrint("DEBUG: Transmitted Initialise Application\n");
639#endif
640    reasoncode=ADP_InitialiseApplication | TtoH;
641    err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
642                                &status, &packet);
643    if (err != RDIError_NoError) return err;
644    return status;
645  }
646  return -1;
647}
648
649
650/*----------------------------------------------------------------------*/
651/*----angel_RDI_close----------------------------------------------------*/
652/*----------------------------------------------------------------------*/
653
654static int angel_negotiate_defaults( void ) {
655    int err = adp_ok;
656    ParameterConfig *default_config = NULL;
657    Adp_Ioctl( DC_GET_DEFAULT_PARAMS, (void *)&default_config );
658    if ( default_config != NULL ) {
659        ParameterOptions *default_options = config_to_options(default_config);
660        err = negotiate_params( default_options );
661        free( default_options );
662    }
663    return err;
664}
665
666int angel_RDI_close(void) {
667/*Angel host exit */
668  int err;
669  int status,debugID, OSinfo1,OSinfo2;
670  int reason;
671  Packet *packet = NULL;;
672#ifdef DEBUG
673  angel_DebugPrint("DEBUG: Entered angel_RDI_Close.\n");
674#endif
675
676  register_debug_message_handler();
677
678  heartbeat_enabled = FALSE;
679
680  err = msgsend(CI_HADP,"%w%w%w%w",ADP_End | HtoT,0,
681          ADP_HandleUnknown, ADP_HandleUnknown);
682  if (err != RDIError_NoError) return err;
683  reason = ADP_End | TtoH;
684  err =  wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
685                                  &status, &packet);
686  DevSW_FreePacket(packet);
687  if (err != RDIError_NoError) return err;
688  if (status == RDIError_NoError) {
689    err = angel_negotiate_defaults();
690    if (err != adp_ok) return err;
691    Adp_Ioctl( DC_RESET, NULL ); /* just to be safe */
692    return HostSysExit(hstate);
693  }
694  else
695      return status;
696}
697
698
699/*----------------------------------------------------------------------*/
700/*----angel_RDI_read-----------------------------------------------------*/
701/*----------------------------------------------------------------------*/
702
703/* Read memory contents from target to host: use ADP_Read */
704int angel_RDI_read(ARMword source, void *dest, unsigned *nbytes)
705{
706  Packet *packet=NULL;
707  int len;                               /* Integer to hold message length. */
708  unsigned int nbtogo = *nbytes, nbinpacket, nbdone=0;
709  int rnbytes = 0, status, reason, debugID, OSinfo1, OSinfo2, err;
710  unsigned int maxlen = Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ReadHeaderSize;
711
712  /* Print debug trace information, this is just copied straight from rdi.c
713     and I can see no reason why it should have to be changed. */
714  TracePrint(("angel_RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
715                (unsigned long)source, dest, *nbytes));
716  if (*nbytes == 0) return RDIError_NoError;       /* Read nothing - easy! */
717  /* check the buffer size */
718  while (nbtogo >0) {
719    register_debug_message_handler();
720
721    nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
722    len = msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Read | HtoT, 0,
723                  ADP_HandleUnknown, ADP_HandleUnknown, source+nbdone,
724                  nbinpacket);
725    reason=ADP_Read | TtoH;
726    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
727                                &status, &packet);
728    TracePrint(("angel_RDI_read: nbinpacket =%d status=%08x err = %d\n",
729                nbinpacket,status,err));
730    if (err != RDIError_NoError) return err;       /* Was there an error? */
731    if (status == RDIError_NoError){
732      rnbytes += PREAD(LE,(unsigned int *)(BUFFERDATA(packet->pk_buffer)+20));
733      TracePrint(("angel_RDI_read: rnbytes = %d\n",rnbytes));
734      memcpy(((unsigned char *)dest)+nbdone, BUFFERDATA(packet->pk_buffer)+24,
735             nbinpacket);
736    }
737    nbdone += nbinpacket;
738    nbtogo -= nbinpacket;
739  }
740  *nbytes -= rnbytes;
741  return status;
742}
743
744
745/*----------------------------------------------------------------------*/
746/*----angel_RDI_write----------------------------------------------------*/
747/*----------------------------------------------------------------------*/
748
749/* Transfer memory block from host to target.  Use ADP_Write>. */
750int angel_RDI_write(const void *source, ARMword dest, unsigned *nbytes)
751{
752  Packet *packet;/* Message buffers. */
753  unsigned int len, nbtogo = *nbytes, nboffset = 0, nbinpacket;
754  int status, reason, debugID, OSinfo1, OSinfo2, err;
755  unsigned int maxlen = Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_WriteHeaderSize;
756
757  TracePrint(("angel_RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
758                 source, (unsigned long)dest, *nbytes));
759
760  if (*nbytes == 0) return RDIError_NoError;
761
762  *nbytes = 0;
763  while (nbtogo > 0) {
764    packet = (Packet *) DevSW_AllocatePacket(Armsd_LongBufSize);
765    nbinpacket = (nbtogo <= maxlen) ? nbtogo : maxlen;
766    len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
767                   ADP_Write | HtoT, 0, ADP_HandleUnknown,
768                   ADP_HandleUnknown, dest+nboffset, nbinpacket);
769    /* Copy the data into the packet. */
770
771    memcpy(BUFFERDATA(packet->pk_buffer)+len,
772           ((const unsigned char *) source)+nboffset, nbinpacket);
773    nboffset += nbinpacket;
774    packet->pk_length = nbinpacket+len;
775
776#ifdef MONITOR_DOWNLOAD_PACKETS
777    angel_DebugPrint("angel_RDI_write packet size=%i, bytes done=%i\n",
778            nbinpacket, nboffset);
779#endif
780
781    register_debug_message_handler();
782    Adp_ChannelWrite(CI_HADP, packet);
783    reason=ADP_Write | TtoH;
784    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
785                                &status, &packet);
786    nbtogo -= nbinpacket;
787    if (err != RDIError_NoError) return err;
788    if (status == RDIError_NoError)
789      *nbytes += nbinpacket;
790
791    DevSW_FreePacket(packet);
792  }
793  return status;
794}
795
796
797/*----------------------------------------------------------------------*/
798/*----angel_RDI_CPUread--------------------------------------------------*/
799/*----------------------------------------------------------------------*/
800
801/* Reads the values of registers in the CPU, uses ADP_CPUwrite. */
802int angel_RDI_CPUread(unsigned mode, unsigned long mask, ARMword *buffer)
803{
804  unsigned int i, j;
805  Packet *packet = NULL;
806  int err, status, reason, debugID, OSinfo1, OSinfo2;
807#ifdef DEBUG
808  angel_DebugPrint("DEBUG: Entered angel_RDI_CPUread.\n");
809#endif
810  for (i=0, j=0 ; i < RDINumCPURegs ; i++)
811    if (mask & (1L << i)) j++;            /* Count the number of registers. */
812
813  register_debug_message_handler();
814  msgsend(CI_HADP, "%w%w%w%w%c%w", ADP_CPUread | HtoT, 0,
815          ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
816  reason = ADP_CPUread | TtoH;
817  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
818                              &status, &packet);
819  if (err != RDIError_NoError) {
820    DevSW_FreePacket(packet);
821    return err;
822  }
823  if(status == RDIError_NoError) {
824    for (i=0; i<j; i++)
825      buffer[i] = GET32LE(BUFFERDATA(packet->pk_buffer)+20+(i*4));
826    TracePrint(("angel_RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask));
827    DevSW_FreePacket(packet);
828#ifdef RDI_VERBOSE
829    if (rdi_log & 1) {
830      unsigned k;
831      for (k = 0, j = 0 ; j <= 20 ; j++)
832        if (mask & (1L << j)) {
833          angel_DebugPrint("%c%.8lx",k%4==0?'\n':' ',
834                           (unsigned long)buffer[k]);
835          k++ ;
836        }
837      angel_DebugPrint("\n") ;
838    }
839#endif
840
841  }
842  return status;
843}
844
845/*----------------------------------------------------------------------*/
846/*----angel_RDI_CPUwrite-------------------------------------------------*/
847/*----------------------------------------------------------------------*/
848
849/* Write CPU registers: use ADP_CPUwrite. */
850int angel_RDI_CPUwrite(unsigned mode, unsigned long mask,
851                      ARMword const *buffer){
852
853  unsigned i, j, c;
854  Packet *packet;
855  int status, reason, debugID, OSinfo1, OSinfo2, err, len;
856
857  TracePrint(("angel_RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
858#ifdef RDI_VERBOSE
859 if (rdi_log & 1) {
860    for (j = 0, i = 0 ; i <= 20 ; i++)
861       if (mask & (1L << i)) {
862          angel_DebugPrint("%c%.8lx",j%4==0?'\n':' ',
863                           (unsigned long)buffer[j]);
864          j++ ;
865          }
866    angel_DebugPrint("\n") ;
867    }
868#endif
869 packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize);
870 for (i=0, j=0; i < RDINumCPURegs ; i++)
871   if (mask & (1L << i)) j++; /* count the number of registers */
872
873 len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%b%w",
874                ADP_CPUwrite | HtoT, 0,
875                ADP_HandleUnknown, ADP_HandleUnknown, mode, mask);
876 for(c=0; c<j; c++)
877   PUT32LE(BUFFERDATA(packet->pk_buffer)+len+(c*4), buffer[c]);
878 packet->pk_length = len+(j*4);
879 register_debug_message_handler();
880
881 Adp_ChannelWrite(CI_HADP, packet);
882 reason = ADP_CPUwrite | TtoH;
883 err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
884                             &status, &packet);
885 unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", &reason, &debugID,
886                &OSinfo1, &OSinfo2, &status);
887 DevSW_FreePacket(packet);
888 if (err != RDIError_NoError)
889   return err;      /* Was there an error? */
890 else
891   return status;
892 }
893
894
895/*----------------------------------------------------------------------*/
896/*----angel_RDI_CPread---------------------------------------------------*/
897/*----------------------------------------------------------------------*/
898
899/* Read coprocessor's internal state.  See dbg_cp.h for help.
900 * Use ADP_CPRead.
901 * It would appear that the correct behaviour at this point is to leave
902 * the unpacking to a the caller and to simply copy the stream of data
903 * words into the buffer
904 */
905
906int angel_RDI_CPread(unsigned CPnum, unsigned long mask, ARMword *buffer){
907  Packet *packet = NULL;
908  int i, j, status, reasoncode, OSinfo1, OSinfo2, err, debugID;
909  unsigned char *rmap = cpwords[CPnum];
910  int n;
911#ifdef DEBUG
912  angel_DebugPrint("DEBUG: Entered angel_RDI_CPread.\n");
913#endif
914  if (rmap == NULL) return RDIError_UnknownCoPro;
915
916  register_debug_message_handler();
917  n = rmap[-1];
918  msgsend(CI_HADP, "%w%w%w%w%b%w", ADP_CPread | HtoT, 0,
919          ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
920  reasoncode=ADP_CPread | TtoH;
921  err = wait_for_debug_message(&reasoncode, &debugID, &OSinfo1, &OSinfo2,
922                              &status, &packet);
923  if (err != RDIError_NoError) {
924    DevSW_FreePacket(packet);
925    return err;          /* Was there an error? */
926  }
927  for (j=i=0; i < n ; i++) /* count the number of registers */
928    if (mask & (1L << i)) {
929      j++;
930    }
931  for (i=0; i<j; i++)
932    buffer[i] = PREAD32(LE, BUFFERDATA(packet->pk_buffer) + 20 + (i*4));
933  DevSW_FreePacket(packet);
934  TracePrint(("angel_RDI_CPread: CPnum=%.8x mask=%.8lx\n", CPnum, mask));
935#ifdef RDI_VERBOSE
936  if (rdi_log & 1) {
937    for (i = 0, j = 0; j < n ; j++) {
938      if (mask & (1L << j)) {
939        int nw = rmap[j];
940        angel_DebugPrint("%2d ", j);
941        while (--nw > 0)
942          angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
943        angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
944      }
945    }
946  }
947#endif
948  return status;
949}
950
951
952/*----------------------------------------------------------------------*/
953/*----angel_RDI_CPwrite--------------------------------------------------*/
954/*----------------------------------------------------------------------*/
955
956/* Write coprocessor's internal state.  See dbg_cp.h for help. Use
957 * ADP_CPwrite.
958 */
959
960int angel_RDI_CPwrite(unsigned CPnum, unsigned long mask,
961                      ARMword const *buffer)
962{
963  Packet *packet = NULL;
964  int i, j, len, status, reason, OSinfo1, OSinfo2, err, debugID;
965  unsigned char *rmap = cpwords[CPnum];
966  int n;
967
968  if (rmap == NULL) return RDIError_UnknownCoPro;
969  n = rmap[-1];
970
971  TracePrint(("angel_RDI_CPwrite: CPnum=%d mask=%.8lx\n", CPnum, mask));
972
973#ifdef RDI_VERBOSE
974 if (rdi_log & 1) {
975    for (i = 0, j = 0; j < n ; j++)
976       if (mask & (1L << j)) {
977          int nw = rmap[j];
978          angel_DebugPrint("%2d ", j);
979          while (--nw > 0)
980             angel_DebugPrint("%.8lx ", (unsigned long)buffer[i++]);
981          angel_DebugPrint("%.8lx\n", (unsigned long)buffer[i++]);
982       }
983 }
984#endif
985
986  for (j=i=0; i < n ; i++) /* Count the number of registers. */
987    if (mask & (1L << i)) j++;
988  packet = DevSW_AllocatePacket(Armsd_BufferSize);
989  len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%c%w",
990                 ADP_CPwrite | HtoT, 0,
991                 ADP_HandleUnknown, ADP_HandleUnknown, CPnum, mask);
992  for(i=0;  i<j; i++)
993    len+=msgbuild(BUFFERDATA(packet->pk_buffer) + len, "%w", buffer[i]);
994  packet->pk_length = len;
995  register_debug_message_handler();
996  Adp_ChannelWrite(CI_HADP, packet);    /* Transmit message. */
997  reason=ADP_CPwrite | TtoH;
998  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
999                              &status, &packet);
1000  DevSW_FreePacket(packet);
1001  if (err != RDIError_NoError)
1002    return err;
1003  else
1004    return status;
1005}
1006
1007
1008/*----------------------------------------------------------------------*/
1009/*----angel_RDI_pointinq-------------------------------------------------*/
1010/*----------------------------------------------------------------------*/
1011
1012/* Do test calls to ADP_SetBreak/ADP_SetWatch to see if resources exist to
1013   carry out request. */
1014int angel_RDI_pointinq(ARMword *address, unsigned type, unsigned datatype,
1015                       ARMword *bound)
1016{
1017  Packet *packet = NULL;
1018  int len, status, reason, OSinfo1, OSinfo2, err=RDIError_NoError;
1019       /* stop a compiler warning */
1020  int debugID, pointhandle;
1021  TracePrint(
1022      ("angel_RDI_pointinq: address=%.8lx type=%d datatype=%d bound=%.8lx ",
1023      (unsigned long)*address, type, datatype, (unsigned long)*bound));
1024       /* for a buffer.  */
1025  packet = DevSW_AllocatePacket(Armsd_BufferSize);
1026  len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b",
1027                 ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch) | HtoT, 0,
1028                 ADP_HandleUnknown, ADP_HandleUnknown, address, type);
1029  if (datatype == 0)
1030    len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%w", bound);
1031  else
1032    len += msgbuild(BUFFERDATA(packet->pk_buffer) + 21, "%b%w", datatype, bound);
1033
1034  register_debug_message_handler();
1035  packet->pk_length = len;
1036  Adp_ChannelWrite(CI_HADP, packet);
1037  reason = ((datatype == 0) ? ADP_SetBreak : ADP_SetWatch | TtoH);
1038  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1039                              &status, &packet);
1040  if (err != RDIError_NoError) {
1041    DevSW_FreePacket(packet);
1042    return err;        /* Was there an error? */
1043  }
1044  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
1045                 &reason, &debugID, &OSinfo1, &OSinfo2, &status,
1046                 &pointhandle, &address, &bound);
1047  DevSW_FreePacket(packet);
1048  return err;
1049}
1050
1051
1052/*----------------------------------------------------------------------*/
1053/*----angel_RDI_setbreak-------------------------------------------------*/
1054/*----------------------------------------------------------------------*/
1055
1056/* Set a breakpoint: Use ADP_SetBreak */
1057int angel_RDI_setbreak(ARMword address, unsigned type, ARMword bound,
1058                      PointHandle *handle)
1059{
1060  int status, reason, OSinfo1, OSinfo2, err, debugID;
1061  int tmpval, tmpaddr, tmpbnd;
1062  Packet *packet;
1063  TracePrint(("angel_RDI_setbreak address=%.8lx type=%d bound=%.8lx \n",
1064              (unsigned long)address, type, (unsigned long)bound));
1065
1066  register_debug_message_handler();
1067  msgsend(CI_HADP, "%w%w%w%w%w%b%w",
1068          ADP_SetBreak| HtoT, 0,  ADP_HandleUnknown,
1069          ADP_HandleUnknown, address, type, bound);
1070  reason = ADP_SetBreak |TtoH;
1071  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1072                              &status, &packet);
1073  if (err != RDIError_NoError) {
1074    DevSW_FreePacket(packet);
1075    return err;         /* Was there an error? */
1076  }
1077  /* Work around varargs problem... -sts */
1078  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
1079                 &reason, &debugID, &OSinfo1, &OSinfo2, &status,
1080                 &tmpval, &tmpaddr, &tmpbnd);
1081  *handle = tmpval;
1082  address = tmpaddr;
1083  bound = tmpbnd;
1084  DevSW_FreePacket(packet);
1085  if (status != RDIError_NoError) return status;
1086  TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
1087  return RDIError_NoError;
1088}
1089
1090
1091/*----------------------------------------------------------------------*/
1092/*----angel_RDI_clearbreak-----------------------------------------------*/
1093/*----------------------------------------------------------------------*/
1094
1095/* Clear a breakpoint: Use ADP_ClearBreak. */
1096int angel_RDI_clearbreak(PointHandle handle)
1097{
1098  Packet *packet = NULL;
1099  int status, reason, OSinfo1, OSinfo2, err, debugID;
1100
1101  TracePrint(("angel_RDI_clearbreak: handle=%.8lx\n", (unsigned long)handle));
1102
1103  register_debug_message_handler();
1104  msgsend(CI_HADP, "%w%w%w%w%w",
1105          ADP_ClearBreak| HtoT, 0,  ADP_HandleUnknown,
1106          ADP_HandleUnknown, handle);
1107  reason = ADP_ClearBreak|TtoH;
1108  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1109                              &status, &packet);
1110  if (err != RDIError_NoError) {
1111    DevSW_FreePacket(packet);
1112    angel_DebugPrint("***RECEIVE DEBUG MESSAGE RETURNED ERR = %d.\n", err);
1113    return err;          /* Was there an error? */
1114  }
1115  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w",  &reason,
1116                 &debugID, &OSinfo1, &OSinfo2, &status);
1117  DevSW_FreePacket(packet);
1118#ifdef DEBUG
1119  angel_DebugPrint("DEBUG: Clear Break completed OK.\n");
1120#endif
1121  return RDIError_NoError;
1122}
1123
1124
1125/*----------------------------------------------------------------------*/
1126/*----angel_RDI_setwatch-------------------------------------------------*/
1127/*----------------------------------------------------------------------*/
1128
1129/* Set a watchpoint: use ADP_SetWatch. */
1130int angel_RDI_setwatch(ARMword address, unsigned type, unsigned datatype,
1131                       ARMword bound, PointHandle *handle)
1132{
1133  Packet *packet = NULL;
1134  int status, reason, OSinfo1, OSinfo2, err, debugID;
1135
1136  TracePrint(("angel_RDI_setwatch: address=%.8lx type=%d bound=%.8lx ",
1137              (unsigned long)address, type, (unsigned long)bound));
1138
1139  register_debug_message_handler();
1140  msgsend(CI_HADP, "%w%w%w%w%w%b%b%w",
1141          ADP_SetWatch| HtoT, 0,  ADP_HandleUnknown,
1142          ADP_HandleUnknown, address, type, datatype, bound);
1143
1144  reason = ADP_SetWatch | TtoH;
1145  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1146                              &status, &packet);
1147  if (err != RDIError_NoError) {
1148    DevSW_FreePacket(packet);
1149    return err;        /* Was there an error? */
1150  }
1151  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
1152                 &reason, &debugID, &OSinfo1, &OSinfo2, &status,
1153                 handle, &address, &bound);
1154  DevSW_FreePacket(packet);
1155  TracePrint(("returns handle %.8lx\n", (unsigned long)*handle));
1156  return RDIError_NoError;
1157}
1158
1159/*----------------------------------------------------------------------*/
1160/*----angel_RDI_clearwatch-----------------------------------------------*/
1161/*----------------------------------------------------------------------*/
1162
1163/* Clear a watchpoint: use ADP_ClearWatch. */
1164int angel_RDI_clearwatch(PointHandle handle) {
1165
1166  int status, reason, OSinfo1, OSinfo2, err, debugID;
1167  Packet *packet = NULL;
1168
1169  TracePrint(("angel_RDI_clearwatch: handle=%.8lx\n", (unsigned long)handle));
1170
1171  register_debug_message_handler();
1172  msgsend(CI_HADP, "%w%w%w%w%w",
1173          ADP_ClearWatch| HtoT, 0,  ADP_HandleUnknown,
1174          ADP_HandleUnknown, handle);
1175  reason = ADP_ClearWatch|TtoH;
1176  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1177                              &status, &packet);
1178  if (err != RDIError_NoError) {
1179    DevSW_FreePacket(packet);
1180    return err;        /* Was there an error? */
1181  }
1182  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w",  &reason, &debugID,
1183                 &OSinfo1, &OSinfo2, &status);
1184  DevSW_FreePacket(packet);
1185  return RDIError_NoError;
1186}
1187
1188typedef struct {
1189  unsigned stopped_reason;
1190  int stopped_status;
1191  int data;
1192} adp_stopped_struct;
1193
1194
1195int angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc *fn,
1196                               void *arg)
1197{
1198  stoppedProcListElement **lptr = &stopped_proc_list;
1199
1200  /* Find the address of the NULL ptr at the end of the list */
1201  for (; *lptr!=NULL ; lptr = &((*lptr)->next))
1202    ; /* Do nothing */
1203
1204  *lptr = (stoppedProcListElement *) malloc(sizeof(stoppedProcListElement));
1205  if (*lptr == NULL) return RDIError_OutOfStore;
1206  (*lptr)->fn = fn;
1207  (*lptr)->arg = arg;
1208
1209  return RDIError_NoError;
1210}
1211
1212static int CallStoppedProcs(unsigned reason)
1213{
1214  stoppedProcListElement *p = stopped_proc_list;
1215  int err=RDIError_NoError;
1216
1217  for (; p!=NULL ; p=p->next) {
1218    int local_err = p->fn(reason, p->arg);
1219    if (local_err != RDIError_NoError) err=local_err;
1220  }
1221
1222  return err;
1223}
1224
1225/*----------------------------------------------------------------------*/
1226/*----angel_RDI_execute--------------------------------------------------*/
1227/*----------------------------------------------------------------------*/
1228
1229static int HandleStoppedMessage(Packet *packet, void *stateptr) {
1230  unsigned int err,  reason, debugID, OSinfo1, OSinfo2, count;
1231  adp_stopped_struct *stopped_info;
1232  stopped_info = (adp_stopped_struct *) stateptr;
1233  IGNORE(stateptr);
1234  count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
1235                         &reason, &debugID,
1236                         &OSinfo1, &OSinfo2,
1237                         &stopped_info->stopped_reason, &stopped_info->data);
1238  DevSW_FreePacket(packet);
1239
1240  if (reason != (ADP_Stopped | TtoH)) {
1241#ifdef DEBUG
1242    angel_DebugPrint("Expecting stopped message, got %x", reason);
1243#endif
1244    return RDIError_Error;
1245  }
1246  else {
1247    executing = FALSE;
1248#ifdef DEBUG
1249    angel_DebugPrint("Received stopped message.\n");
1250#endif
1251  }
1252
1253  err = msgsend(CI_TADP,  "%w%w%w%w%w", (ADP_Stopped | HtoT), 0,
1254                ADP_HandleUnknown, ADP_HandleUnknown, RDIError_NoError);
1255#ifdef DEBUG
1256  angel_DebugPrint("Transmiting stopped acknowledge.\n");
1257#endif
1258  if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
1259#ifdef DEBUG
1260  angel_DebugPrint("DEBUG: Stopped reason : %x\n", stopped_info->stopped_reason);
1261#endif
1262  switch (stopped_info->stopped_reason) {
1263  case ADP_Stopped_BranchThroughZero:
1264    stopped_info->stopped_status = RDIError_BranchThrough0;
1265    break;
1266  case ADP_Stopped_UndefinedInstr:
1267    stopped_info->stopped_status = RDIError_UndefinedInstruction;
1268    break;
1269  case ADP_Stopped_SoftwareInterrupt:
1270    stopped_info->stopped_status = RDIError_SoftwareInterrupt;
1271    break;
1272  case ADP_Stopped_PrefetchAbort:
1273    stopped_info->stopped_status = RDIError_PrefetchAbort;
1274    break;
1275  case ADP_Stopped_DataAbort:
1276    stopped_info->stopped_status = RDIError_DataAbort;
1277    break;
1278  case ADP_Stopped_AddressException:
1279    stopped_info->stopped_status = RDIError_AddressException;
1280    break;
1281  case ADP_Stopped_IRQ:
1282    stopped_info->stopped_status = RDIError_IRQ;
1283    break;
1284  case ADP_Stopped_BreakPoint:
1285    stopped_info->stopped_status = RDIError_BreakpointReached;
1286    break;
1287  case ADP_Stopped_WatchPoint:
1288    stopped_info->stopped_status = RDIError_WatchpointAccessed;
1289    break;
1290  case ADP_Stopped_StepComplete:
1291    stopped_info->stopped_status = RDIError_ProgramFinishedInStep;
1292    break;
1293  case ADP_Stopped_RunTimeErrorUnknown:
1294  case ADP_Stopped_StackOverflow:
1295  case ADP_Stopped_DivisionByZero:
1296    stopped_info->stopped_status = RDIError_Error;
1297    break;
1298  case ADP_Stopped_FIQ:
1299    stopped_info->stopped_status = RDIError_FIQ;
1300    break;
1301  case ADP_Stopped_UserInterruption:
1302  case ADP_Stopped_OSSpecific:
1303    stopped_info->stopped_status = RDIError_UserInterrupt;
1304    break;
1305  case ADP_Stopped_ApplicationExit:
1306    stopped_info->stopped_status = RDIError_NoError;
1307    break;
1308  default:
1309    stopped_info->stopped_status = RDIError_Error;
1310    break;
1311  }
1312  return RDIError_NoError;
1313}
1314
1315
1316static void interrupt_target( void )
1317{
1318    Packet *packet = NULL;
1319    int err;
1320    int reason, debugID, OSinfo1, OSinfo2, status;
1321
1322#ifdef DEBUG
1323    angel_DebugPrint("DEBUG: interrupt_target.\n");
1324#endif
1325
1326    register_debug_message_handler();
1327    msgsend(CI_HADP, "%w%w%w%w", ADP_InterruptRequest | HtoT, 0,
1328                   ADP_HandleUnknown, ADP_HandleUnknown);
1329
1330    reason = ADP_InterruptRequest |TtoH;
1331    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1332                              &status, &packet);
1333    DevSW_FreePacket(packet);
1334#ifdef DEBUG
1335    angel_DebugPrint("DEBUG: got interrupt ack ok err = %d, status=%i\n",
1336                     err, status);
1337#endif
1338
1339    return;
1340}
1341
1342#ifdef TEST_DC_APPL
1343  extern void test_dc_appl_handler( const DeviceDescr *device,
1344                                    Packet *packet );
1345#endif
1346
1347void angel_RDI_stop_request(void)
1348{
1349  stop_request = 1;
1350}
1351
1352/* Core functionality for execute and step */
1353static int angel_RDI_ExecuteOrStep(PointHandle *handle, word type,
1354                                   unsigned ninstr)
1355{
1356  extern int (*deprecated_ui_loop_hook) (int);
1357  int err;
1358  adp_stopped_struct stopped_info;
1359  void* stateptr = (void *)&stopped_info;
1360  ChannelCallback HandleStoppedMessageFPtr=(ChannelCallback) HandleStoppedMessage;
1361  int status, reasoncode, debugID, OSinfo1, OSinfo2;
1362  Packet *packet = NULL;
1363
1364  TracePrint(("angel_RDI_ExecuteOrStep\n"));
1365
1366  err = Adp_ChannelRegisterRead(CI_TADP,
1367                                HandleStoppedMessageFPtr, stateptr);
1368  if (err != RDIError_NoError) {
1369#ifdef DEBUG
1370    angel_DebugPrint("TADP Register failed.\n");
1371#endif
1372    return err;
1373  }
1374  /* Set executing TRUE here, as it must be set up before the target has
1375   * had any chance at all to execute, or it may send its stopped message
1376   * before we get round to setting executing = TRUE !!!
1377   */
1378  executing = TRUE;
1379
1380  register_debug_message_handler();
1381
1382#ifdef TEST_DC_APPL
1383  Adp_Install_DC_Appl_Handler( test_dc_appl_handler );
1384#endif
1385
1386#ifdef DEBUG
1387  angel_DebugPrint("Transmiting %s message.\n",
1388                   type == ADP_Execute ? "execute": "step");
1389#endif
1390
1391  register_debug_message_handler();
1392  /* Extra ninstr parameter for execute message will simply be ignored */
1393  err = msgsend(CI_HADP,"%w%w%w%w%w", type | HtoT, 0,
1394                ADP_HandleUnknown, ADP_HandleUnknown, ninstr);
1395#if DEBUG
1396  if (err != RDIError_NoError) angel_DebugPrint("Transmit failed.\n");
1397#endif
1398
1399  reasoncode = type | TtoH;
1400  err = wait_for_debug_message( &reasoncode, &debugID, &OSinfo1, &OSinfo2,
1401                                &status, &packet );
1402  if (err != RDIError_NoError)
1403     return err;
1404  else if (status != RDIError_NoError)
1405     return status;
1406
1407#ifdef DEBUG
1408  angel_DebugPrint("Waiting for program to finish...\n");
1409#endif
1410
1411  interrupt_request = FALSE;
1412  stop_request = FALSE;
1413
1414  signal(SIGINT, ardi_sigint_handler);
1415  while( executing )
1416  {
1417    if (deprecated_ui_loop_hook)
1418      deprecated_ui_loop_hook(0);
1419
1420    if (interrupt_request || stop_request)
1421      {
1422        interrupt_target();
1423        interrupt_request = FALSE;
1424        stop_request = FALSE;
1425      }
1426    Adp_AsynchronousProcessing( async_block_on_nothing );
1427  }
1428  signal(SIGINT, SIG_IGN);
1429
1430
1431#ifdef TEST_DC_APPL
1432  Adp_Install_DC_Appl_Handler( NULL );
1433#endif
1434
1435  (void)Adp_ChannelRegisterRead(CI_TADP, NULL, NULL);
1436
1437  *handle = (PointHandle)stopped_info.data;
1438
1439  CallStoppedProcs(stopped_info.stopped_reason);
1440
1441  return stopped_info.stopped_status;
1442}
1443
1444/* Request that the target starts executing from the stored CPU state: use
1445   ADP_Execute. */
1446int angel_RDI_execute(PointHandle *handle)
1447{
1448    return angel_RDI_ExecuteOrStep(handle, ADP_Execute, 0);
1449}
1450
1451#ifdef __WATCOMC__
1452typedef void handlertype(int);
1453
1454static int interrupted=0;
1455
1456static void myhandler(int sig) {
1457  IGNORE(sig);
1458  interrupted=1;
1459  signal(SIGINT, myhandler);
1460}
1461#endif
1462
1463/*----------------------------------------------------------------------*/
1464/*----angel_RDI_step-----------------------------------------------------*/
1465/*----------------------------------------------------------------------*/
1466
1467/* Step 'ninstr' through the code: use ADP_Step. */
1468int angel_RDI_step(unsigned ninstr, PointHandle *handle)
1469{
1470    int err = angel_RDI_ExecuteOrStep(handle, ADP_Step, ninstr);
1471    if (err == RDIError_ProgramFinishedInStep)
1472       return RDIError_NoError;
1473    else
1474       return err;
1475}
1476
1477
1478static void SetCPWords(int cpnum, struct Dbg_CoProDesc const *cpd) {
1479  int i, rmax = 0;
1480  for (i = 0; i < cpd->entries; i++)
1481    if (cpd->regdesc[i].rmax > rmax)
1482      rmax = cpd->regdesc[i].rmax;
1483
1484  { unsigned char *rmap = (unsigned char *)malloc(rmax + 2);
1485    *rmap++ = rmax + 1;
1486    for (i = 0; i < cpd->entries; i++) {
1487      int r;
1488      for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++)
1489        rmap[r] = (cpd->regdesc[i].nbytes+3) / 4;
1490      }
1491/*    if (cpwords[cpnum] != NULL) free(cpwords[cpnum]); */
1492    cpwords[cpnum] = rmap;
1493  }
1494}
1495
1496/*----------------------------------------------------------------------*/
1497/*----angel_RDI_info-----------------------------------------------------*/
1498/*----------------------------------------------------------------------*/
1499
1500/* Use ADP_Info, ADP_Ctrl and ADP_Profile calls to implement these,
1501   see adp.h for more details. */
1502
1503static int angel_cc_exists( void )
1504{
1505  Packet *packet = NULL;
1506  int err;
1507  int reason, debugID, OSinfo1, OSinfo2, subreason, status;
1508
1509#ifdef DEBUG
1510  angel_DebugPrint("DEBUG: ADP_ICEB_CC_Exists.\n");
1511#endif
1512
1513  if ( angel_RDI_info( RDIInfo_Icebreaker, NULL, NULL ) == RDIError_NoError ) {
1514    register_debug_message_handler();
1515    msgsend(CI_HADP, "%w%w%w%w%w", ADP_ICEbreakerHADP | HtoT, 0,
1516            ADP_HandleUnknown, ADP_HandleUnknown,
1517            ADP_ICEB_CC_Exists );
1518    reason = ADP_ICEbreakerHADP |TtoH;
1519    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1520                                &status, &packet);
1521    if (err != RDIError_NoError) {
1522      DevSW_FreePacket(packet);
1523      return err;
1524    }
1525    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
1526                   &debugID, &OSinfo1, &OSinfo2,  &subreason, &status);
1527    if (subreason !=  ADP_ICEB_CC_Exists) {
1528      DevSW_FreePacket(packet);
1529      return RDIError_Error;
1530    }
1531    else
1532      return status;
1533  }
1534  else
1535    return RDIError_UnimplementedMessage;
1536}
1537
1538typedef struct {
1539  RDICCProc_ToHost *tohost; void *tohostarg;
1540  RDICCProc_FromHost *fromhost; void *fromhostarg;
1541  bool registered;
1542} CCState;
1543static CCState ccstate = { NULL, NULL, NULL, NULL, FALSE };
1544
1545static void HandleDCCMessage( Packet *packet, void *stateptr )
1546{
1547  unsigned int reason, debugID, OSinfo1, OSinfo2;
1548  int count;
1549  CCState *ccstate_p = (CCState *)stateptr;
1550
1551  count = unpack_message( BUFFERDATA(packet->pk_buffer), "%w%w%w%w",
1552                          &reason, &debugID, &OSinfo1, &OSinfo2 );
1553  switch ( reason )
1554  {
1555      case ADP_TDCC_ToHost | TtoH:
1556      {
1557           /* only handles a single word of data, for now */
1558
1559          unsigned int nbytes, data;
1560
1561          unpack_message( BUFFERDATA(packet->pk_buffer)+count, "%w%w",
1562                          &nbytes, &data );
1563#ifdef DEBUG
1564          angel_DebugPrint( "DEBUG: received CC_ToHost message: nbytes %d data %08x.\n",
1565                  nbytes, data );
1566#endif
1567          ccstate_p->tohost( ccstate_p->tohostarg, data );
1568          msgsend(CI_TTDCC, "%w%w%w%w%w",
1569                  ADP_TDCC_ToHost | HtoT, debugID, OSinfo1, OSinfo2,
1570                  RDIError_NoError );
1571          break;
1572      }
1573
1574      case ADP_TDCC_FromHost | TtoH:
1575      {
1576           /* only handles a single word of data, for now */
1577
1578          int valid;
1579          ARMword data;
1580
1581          ccstate_p->fromhost( ccstate_p->fromhostarg, &data, &valid );
1582#ifdef DEBUG
1583          angel_DebugPrint( "DEBUG: received CC_FromHost message, returning: %08x %s.\n",
1584                  data, valid ? "VALID" : "INvalid" );
1585#endif
1586          msgsend(CI_TTDCC, "%w%w%w%w%w%w%w",
1587                  ADP_TDCC_FromHost | HtoT, debugID, OSinfo1, OSinfo2,
1588                  RDIError_NoError, valid ? 1 : 0, data );
1589          break;
1590      }
1591
1592      default:
1593#ifdef DEBUG
1594      angel_DebugPrint( "Unexpected TDCC message %08x received\n", reason );
1595#endif
1596      break;
1597  }
1598  DevSW_FreePacket(packet);
1599  return;
1600}
1601
1602static void angel_check_DCC_handler( CCState *ccstate_p )
1603{
1604    int err;
1605
1606    if ( ccstate_p->tohost != NULL || ccstate_p->fromhost != NULL )
1607    {
1608        /* doing DCC, so need a handler */
1609        if ( ! ccstate_p->registered )
1610        {
1611#ifdef DEBUG
1612            angel_DebugPrint( "Registering handler for TTDCC channel.\n" );
1613#endif
1614            err = Adp_ChannelRegisterRead( CI_TTDCC, HandleDCCMessage,
1615                                           ccstate_p );
1616            if ( err == adp_ok )
1617               ccstate_p->registered = TRUE;
1618#ifdef DEBUG
1619            else
1620               angel_DebugPrint( "angel_check_DCC_handler: register failed!\n" );
1621#endif
1622        }
1623    }
1624    else
1625    {
1626        /* not doing DCC, so don't need a handler */
1627        if ( ccstate_p->registered )
1628        {
1629#ifdef DEBUG
1630            angel_DebugPrint( "Unregistering handler for TTDCC channel.\n" );
1631#endif
1632            err = Adp_ChannelRegisterRead( CI_TTDCC, NULL, NULL );
1633            if ( err == adp_ok )
1634               ccstate_p->registered = FALSE;
1635#ifdef DEBUG
1636            else
1637               angel_DebugPrint( "angel_check_DCC_handler: unregister failed!\n" );
1638#endif
1639        }
1640    }
1641}
1642
1643
1644static int CheckSubMessageReply(int reason, int subreason) {
1645  Packet *packet = NULL;
1646  int status, debugID, OSinfo1, OSinfo2;
1647  int err = RDIError_NoError;
1648  reason |= TtoH;
1649  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1650                               &status, &packet);
1651  if (err != RDIError_NoError) {
1652    status = err;
1653  } else {
1654    int sr;
1655    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
1656                   &OSinfo1, &OSinfo2, &sr, &status);
1657    if (subreason != sr) status = RDIError_Error;
1658  }
1659  DevSW_FreePacket(packet);
1660  return status;
1661}
1662
1663static int SendSubMessageAndCheckReply(int reason, int subreason) {
1664  register_debug_message_handler();
1665  msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
1666          ADP_HandleUnknown, ADP_HandleUnknown,
1667          subreason);
1668  return CheckSubMessageReply(reason, subreason);
1669}
1670
1671static int SendSubMessageWordAndCheckReply(int reason, int subreason, ARMword word) {
1672  register_debug_message_handler();
1673  msgsend(CI_HADP, "%w%w%w%w%w%w", reason | HtoT, 0,
1674          ADP_HandleUnknown, ADP_HandleUnknown,
1675          subreason, word);
1676  return CheckSubMessageReply(reason, subreason);
1677}
1678
1679static int SendSubMessageGetWordAndCheckReply(int reason, int subreason, ARMword *resp) {
1680  Packet *packet = NULL;
1681  int status, debugID, OSinfo1, OSinfo2;
1682  int err = RDIError_NoError;
1683
1684  register_debug_message_handler();
1685  msgsend(CI_HADP, "%w%w%w%w%w", reason | HtoT, 0,
1686          ADP_HandleUnknown, ADP_HandleUnknown,
1687          subreason);
1688  reason |= TtoH;
1689  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1690                               &status, &packet);
1691  if (err != RDIError_NoError) {
1692    status = err;
1693  } else {
1694    int sr;
1695    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w", &reason, &debugID,
1696                   &OSinfo1, &OSinfo2,  &sr, &status, resp);
1697    if (subreason != sr) status = RDIError_Error;
1698  }
1699  DevSW_FreePacket(packet);
1700  return status;
1701}
1702
1703static int const hostsex = 1;
1704
1705int angel_RDI_info(unsigned type, ARMword *arg1, ARMword *arg2) {
1706  Packet *packet = NULL;
1707  int len, status, c, reason, subreason, debugID, OSinfo1, OSinfo2;
1708  int err=RDIError_NoError, cpnum=0;
1709  struct Dbg_CoProDesc *cpd;
1710  int count, i;
1711  unsigned char *bp;
1712
1713#ifdef DEBUG
1714  angel_DebugPrint("DEBUG: Entered angel_RDI_info.\n");
1715#endif
1716  switch (type) {
1717  case RDIInfo_Target:
1718#ifdef DEBUG
1719    angel_DebugPrint("DEBUG: RDIInfo_Target.\n");
1720#endif
1721
1722    register_debug_message_handler();
1723    msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
1724                 ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Target);
1725    reason = ADP_Info |TtoH;
1726    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1727                              &status, &packet);
1728    if (err != RDIError_NoError) {
1729      DevSW_FreePacket(packet);
1730      return err;
1731    }
1732    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
1733                   &debugID, &OSinfo1, &OSinfo2,  &subreason, &status,
1734                   arg1, arg2);
1735    DevSW_FreePacket(packet);
1736
1737    if (subreason !=  ADP_Info_Target)
1738      return RDIError_Error;
1739    else
1740      return status;
1741
1742  case RDISignal_Stop:
1743#ifdef DEBUG
1744    angel_DebugPrint("DEBUG: RDISignal_Stop.\n");
1745    if (interrupt_request)
1746       angel_DebugPrint("       STILL WAITING to send previous interrupt request\n");
1747#endif
1748    interrupt_request = TRUE;
1749    return RDIError_NoError;
1750
1751  case RDIInfo_Points:
1752#ifdef DEBUG
1753    angel_DebugPrint("DEBUG: RDIInfo_Points.\n");
1754#endif
1755    return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Points, arg1);
1756
1757  case RDIInfo_Step:
1758#ifdef DEBUG
1759    angel_DebugPrint("DEBUG: RDIInfo_Step.\n");
1760#endif
1761    return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_Step, arg1);
1762
1763  case RDISet_Cmdline:
1764#ifdef DEBUG
1765    angel_DebugPrint("DEBUG: RDISet_Cmdline.\n");
1766#endif
1767    if (ardi_commandline != &dummycline)
1768      free(ardi_commandline);
1769    ardi_commandline = (char *)malloc(strlen((char*)arg1) + 1) ;
1770    (void)strcpy(ardi_commandline, (char *)arg1) ;
1771    return RDIError_NoError;
1772
1773  case RDIInfo_SetLog:
1774#ifdef DEBUG
1775    angel_DebugPrint("DEBUG: RDIInfo_SetLog.\n");
1776#endif
1777    rdi_log = (int) *arg1;
1778    return RDIError_NoError;
1779
1780  case RDIInfo_Log:
1781#ifdef DEBUG
1782    angel_DebugPrint("DEBUG: RDIInfo_Log.\n");
1783#endif
1784    *arg1 = rdi_log;
1785    return RDIError_NoError;
1786
1787
1788  case RDIInfo_MMU:
1789#ifdef DEBUG
1790    angel_DebugPrint("DEBUG: RDIInfo_MMU.\n");
1791#endif
1792    return SendSubMessageGetWordAndCheckReply(ADP_Info, ADP_Info_MMU, arg1);
1793
1794  case RDIInfo_SemiHosting:
1795#ifdef DEBUG
1796    angel_DebugPrint("DEBUG: RDIInfo_SemiHosting.\n");
1797#endif
1798    return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_SemiHosting);
1799
1800  case RDIInfo_CoPro:
1801#ifdef DEBUG
1802    angel_DebugPrint("DEBUG: RDIInfo_CoPro.\n");
1803#endif
1804    return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CoPro);
1805
1806  case RDICycles:
1807#ifdef DEBUG
1808    angel_DebugPrint("DEBUG: RDICycles.\n");
1809#endif
1810    register_debug_message_handler();
1811    msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
1812            ADP_HandleUnknown, ADP_HandleUnknown, ADP_Info_Cycles);
1813    reason = ADP_Info |TtoH;
1814    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1815                              &status, &packet);
1816    if (err != RDIError_NoError) {
1817      DevSW_FreePacket(packet);
1818      return err;
1819    }
1820    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
1821                 &OSinfo1, &OSinfo2,  &subreason, &status);
1822    DevSW_FreePacket(packet);
1823    if (subreason !=  ADP_Info_Cycles)
1824      return RDIError_Error;
1825    if (status != RDIError_NoError) return status;
1826    for (c=0; c<12; c++)
1827      arg1[c]=GET32LE(BUFFERDATA(packet->pk_buffer)+24+(c*4));
1828    return status;
1829
1830  case RDIInfo_DescribeCoPro:
1831#ifdef DEBUG
1832    angel_DebugPrint("DEBUG: RDIInfo_DescribeCoPro.\n");
1833#endif
1834    cpnum = *(int *)arg1;
1835    cpd = (struct Dbg_CoProDesc *)arg2;
1836    packet = DevSW_AllocatePacket(Armsd_BufferSize);
1837    if (angel_RDI_info(ADP_Info_CoPro, NULL, NULL) != RDIError_NoError)
1838      return RDIError_Error;
1839    len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
1840                   ADP_HandleUnknown, ADP_HandleUnknown,
1841                   ADP_Info_DescribeCoPro);
1842    len +=msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b%b%b%b%b", cpnum,
1843                   cpd->regdesc[cpnum].rmin, cpd->regdesc[cpnum].rmax,
1844                   cpd->regdesc[cpnum].nbytes, cpd->regdesc[cpnum].access);
1845    if ((cpd->regdesc[cpnum].access&0x3) == 0x3){
1846      len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b",
1847                      cpd->regdesc[cpnum].accessinst.cprt.read_b0,
1848                      cpd->regdesc[cpnum].accessinst.cprt.read_b1,
1849                      cpd->regdesc[cpnum].accessinst.cprt.write_b0,
1850                      cpd->regdesc[cpnum].accessinst.cprt.write_b1, 0xff);
1851    }
1852    else {
1853      len += msgbuild(BUFFERDATA(packet->pk_buffer)+25, "%b%b%b%b%b%",
1854                      cpd->regdesc[cpnum].accessinst.cpdt.rdbits,
1855                      cpd->regdesc[cpnum].accessinst.cpdt.nbit,0,0, 0xff);
1856    }
1857    register_debug_message_handler();
1858    packet->pk_length = len;
1859    Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
1860    reason = ADP_Info |TtoH;
1861    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1862                                &status, &packet);
1863    if (err != RDIError_NoError) {
1864      DevSW_FreePacket(packet);
1865      return err;
1866    }
1867    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
1868                   &OSinfo1, &OSinfo2, &subreason, &status);
1869    DevSW_FreePacket(packet);
1870    if (subreason != ADP_Info_DescribeCoPro)
1871      return RDIError_Error;
1872    else
1873      return status;
1874
1875  case RDIInfo_RequestCoProDesc:
1876#ifdef DEBUG
1877    angel_DebugPrint("DEBUG: RDIInfo_RequestCoProDesc.\n");
1878#endif
1879    cpnum = *(int *)arg1;
1880    cpd = (struct Dbg_CoProDesc *)arg2;
1881    packet = DevSW_AllocatePacket(Armsd_BufferSize);
1882    len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w", ADP_Info | HtoT, 0,
1883                   ADP_HandleUnknown, ADP_HandleUnknown,
1884                   ADP_Info_RequestCoProDesc);
1885    len += msgbuild(BUFFERDATA(packet->pk_buffer)+20, "%b", *(int *)arg1);
1886    packet->pk_length = len;
1887    register_debug_message_handler();
1888    Adp_ChannelWrite(CI_HADP, packet); /* Transmit message. */
1889    reason = ADP_Info |TtoH;
1890    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1891                              &status, &packet);
1892    if (err != RDIError_NoError) {
1893      DevSW_FreePacket(packet);
1894      return err;
1895    }
1896    count = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
1897                           &debugID, &OSinfo1, &OSinfo2,  &subreason, &status);
1898    if (subreason !=  ADP_Info_RequestCoProDesc) {
1899      DevSW_FreePacket(packet);
1900      return RDIError_Error;
1901    } else if ( status != RDIError_NoError ) {
1902      DevSW_FreePacket(packet);
1903      return status;
1904    } else {
1905      bp = BUFFERDATA(packet->pk_buffer)+count;
1906      for ( i = 0; *bp != 0xFF && i < cpd->entries; ++i ) {
1907        cpd->regdesc[i].rmin = *bp++;
1908        cpd->regdesc[i].rmax = *bp++;
1909        cpd->regdesc[i].nbytes = *bp++;
1910        cpd->regdesc[i].access = *bp++;
1911      }
1912      cpd->entries = i;
1913      if ( *bp != 0xFF )
1914        status = RDIError_BufferFull;
1915      else
1916        SetCPWords( cpnum, cpd );
1917      DevSW_FreePacket(packet);
1918      return status;
1919    }
1920
1921  case RDIInfo_GetLoadSize:
1922#ifdef DEBUG
1923    angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize.\n");
1924#endif
1925    register_debug_message_handler();
1926    msgsend(CI_HADP, "%w%w%w%w%w", ADP_Info | HtoT, 0,
1927            ADP_HandleUnknown, ADP_HandleUnknown,
1928            ADP_Info_AngelBufferSize);
1929    reason = ADP_Info |TtoH;
1930    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
1931                              &status, &packet);
1932    if (err != RDIError_NoError) {
1933      DevSW_FreePacket(packet);
1934      return err;
1935    }
1936    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
1937                   &debugID, &OSinfo1, &OSinfo2,  &subreason, &status);
1938    if (subreason !=  ADP_Info_AngelBufferSize) {
1939      DevSW_FreePacket(packet);
1940      return RDIError_Error;
1941    }
1942    else {
1943      word defaultsize, longsize;
1944      unpack_message(BUFFERDATA(packet->pk_buffer)+24, "%w%w",
1945                     &defaultsize, &longsize);
1946      *arg1 = longsize - ADP_WriteHeaderSize;   /* space for ADP header */
1947#ifdef MONITOR_DOWNLOAD_PACKETS
1948      angel_DebugPrint("DEBUG: ADP_Info_AngelBufferSize: got (%d, %d), returning %d.\n",
1949             defaultsize, longsize, *arg1);
1950#endif
1951      DevSW_FreePacket(packet);
1952      return status;
1953    }
1954
1955  case RDIVector_Catch:
1956#ifdef DEBUG
1957    angel_DebugPrint("DEBUG: ADP_Ctrl_VectorCatch %lx.\n", *arg1);
1958#endif
1959    return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_VectorCatch, *arg1);
1960
1961  case RDISemiHosting_SetState:
1962#ifdef DEBUG
1963    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetState %lx.\n", *arg1);
1964#endif
1965    return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetState, *arg1);
1966
1967  case RDISemiHosting_GetState:
1968#ifdef DEBUG
1969    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetState.\n");
1970#endif
1971    return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetState, arg1);
1972
1973  case RDISemiHosting_SetVector:
1974#ifdef DEBUG
1975    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetVector %lx.\n", *arg1);
1976#endif
1977    return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetVector, *arg1);
1978
1979  case RDISemiHosting_GetVector:
1980#ifdef DEBUG
1981    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetVector.\n");
1982#endif
1983    return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetVector, arg1);
1984
1985  case RDISemiHosting_SetARMSWI:
1986#ifdef DEBUG
1987    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetARMSWI.\n");
1988#endif
1989    return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetARMSWI, *arg1);
1990
1991  case RDISemiHosting_GetARMSWI:
1992#ifdef DEBUG
1993    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetARMSWI.\n");
1994#endif
1995    return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetARMSWI, arg1);
1996
1997  case RDISemiHosting_SetThumbSWI:
1998#ifdef DEBUG
1999    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_SetThumbSWI.\n");
2000#endif
2001    return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_SetThumbSWI, *arg1);
2002
2003  case RDISemiHosting_GetThumbSWI:
2004#ifdef DEBUG
2005    angel_DebugPrint("DEBUG: ADP_Ctrl_SemiHosting_GetThumbSWI.\n");
2006#endif
2007    return SendSubMessageGetWordAndCheckReply(ADP_Control, ADP_Ctrl_SemiHosting_GetThumbSWI, arg1);
2008
2009  case RDIInfo_SetTopMem:
2010#ifdef DEBUG
2011    angel_DebugPrint("DEBUG: ADP_Ctrl_SetTopMem.\n");
2012#endif
2013    return SendSubMessageWordAndCheckReply(ADP_Control, ADP_Ctrl_SetTopMem, *arg1);
2014
2015  case RDIPointStatus_Watch:
2016#ifdef DEBUG
2017    angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Watch.\n");
2018#endif
2019    register_debug_message_handler();
2020    msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
2021            ADP_HandleUnknown, ADP_HandleUnknown,
2022            ADP_Ctrl_PointStatus_Watch, *arg1 );
2023    reason = ADP_Control |TtoH;
2024    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2025                              &status, &packet);
2026    if (err != RDIError_NoError) {
2027      DevSW_FreePacket(packet);
2028      return err;
2029    }
2030    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
2031                   &debugID, &OSinfo1, &OSinfo2,  &subreason, &status,
2032                   arg1, arg2);
2033    if (subreason !=  ADP_Ctrl_PointStatus_Watch) {
2034      DevSW_FreePacket(packet);
2035      return RDIError_Error;
2036    }
2037    else
2038      return status;
2039
2040  case RDIPointStatus_Break:
2041#ifdef DEBUG
2042    angel_DebugPrint("DEBUG: ADP_Ctrl_PointStatus_Break.\n");
2043#endif
2044    register_debug_message_handler();
2045    msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT, 0,
2046            ADP_HandleUnknown, ADP_HandleUnknown,
2047            ADP_Ctrl_PointStatus_Break, *arg1 );
2048    reason = ADP_Control |TtoH;
2049    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2050                              &status, &packet);
2051    if (err != RDIError_NoError) {
2052      DevSW_FreePacket(packet);
2053      return err;
2054    }
2055    unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w", &reason,
2056                   &debugID, &OSinfo1, &OSinfo2,  &subreason, &status,
2057                   arg1, arg2);
2058    if (subreason !=  ADP_Ctrl_PointStatus_Break) {
2059      DevSW_FreePacket(packet);
2060      return RDIError_Error;
2061    }
2062    else
2063      return status;
2064
2065  case RDIInfo_DownLoad:
2066#ifdef DEBUG
2067    angel_DebugPrint("DEBUG: ADP_Ctrl_Download_Supported.\n");
2068#endif
2069    return SendSubMessageAndCheckReply(ADP_Control, ADP_Ctrl_Download_Supported);
2070
2071  case RDIConfig_Count:
2072#ifdef DEBUG
2073    angel_DebugPrint("DEBUG: ADP_ICEM_ConfigCount.\n");
2074#endif
2075    return SendSubMessageGetWordAndCheckReply(ADP_ICEman, ADP_ICEM_ConfigCount, arg1);
2076
2077  case RDIConfig_Nth:
2078#ifdef DEBUG
2079    angel_DebugPrint("DEBUG: ADP_ICEM_ConfigNth.\n");
2080#endif
2081    register_debug_message_handler();
2082    msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT, 0,
2083            ADP_HandleUnknown, ADP_HandleUnknown,
2084            ADP_ICEM_ConfigNth, *arg1 );
2085    reason = ADP_ICEman |TtoH;
2086    err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2087                              &status, &packet);
2088    if (err != RDIError_NoError) {
2089      DevSW_FreePacket(packet);
2090      return err;
2091    } else {
2092      RDI_ConfigDesc *cd = (RDI_ConfigDesc *)arg2;
2093      unsigned char n;
2094      len = unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%b",
2095                           &reason, &debugID,
2096                           &OSinfo1, &OSinfo2,  &subreason, &status,
2097                           &cd->version, &n);
2098      if (subreason !=  ADP_ICEM_ConfigNth) {
2099        DevSW_FreePacket(packet);
2100        return RDIError_Error;
2101      }
2102      else {
2103        memcpy( cd->name, BUFFERDATA(packet->pk_buffer)+len, n+1 );
2104        cd->name[n] = 0;
2105        return status;
2106      }
2107    }
2108
2109  case RDIInfo_Icebreaker:
2110#ifdef DEBUG
2111    angel_DebugPrint("DEBUG: ADP_ICEB_Exists.\n");
2112#endif
2113    return SendSubMessageAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_Exists);
2114
2115  case RDIIcebreaker_GetLocks:
2116#ifdef DEBUG
2117    angel_DebugPrint("DEBUG: ADP_ICEB_GetLocks.\n");
2118#endif
2119    return SendSubMessageGetWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_GetLocks, arg1);
2120
2121  case RDIIcebreaker_SetLocks:
2122#ifdef DEBUG
2123    angel_DebugPrint("DEBUG: ADP_ICEB_SetLocks.\n");
2124#endif
2125    return SendSubMessageWordAndCheckReply(ADP_ICEbreakerHADP, ADP_ICEB_SetLocks, *arg1);
2126
2127  case RDICommsChannel_ToHost:
2128#ifdef DEBUG
2129    angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_ToHost.\n");
2130#endif
2131    if ( angel_cc_exists() == RDIError_NoError ) {
2132
2133    /*
2134     * The following three lines of code have to be removed in order to get
2135     * the Windows Angel Channel Viewer working with the Thumb comms channel.
2136     * At the moment it allows the ARMSD command line to register a CCIN/CCOUT
2137     * callback which stops the ACV working!
2138     */
2139#ifdef __unix
2140      ccstate.tohost = (RDICCProc_ToHost *)arg1;
2141      ccstate.tohostarg = arg2;
2142      angel_check_DCC_handler( &ccstate );
2143#endif
2144#ifdef _WIN32
2145
2146#endif
2147
2148      register_debug_message_handler();
2149      msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
2150              ADP_HandleUnknown, ADP_HandleUnknown,
2151              ADP_ICEB_CC_Connect_ToHost, (arg1 != NULL) );
2152      return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_ToHost);
2153    } else {
2154      return RDIError_UnimplementedMessage;
2155    }
2156
2157  case RDICommsChannel_FromHost:
2158#ifdef DEBUG
2159    angel_DebugPrint("DEBUG: ADP_ICEB_CC_Connect_FromHost.\n");
2160#endif
2161    if ( angel_cc_exists() == RDIError_NoError ) {
2162
2163      ccstate.fromhost = (RDICCProc_FromHost *)arg1;
2164      ccstate.fromhostarg = arg2;
2165      angel_check_DCC_handler( &ccstate );
2166
2167      register_debug_message_handler();
2168      msgsend(CI_HADP, "%w%w%w%w%w%b", ADP_ICEbreakerHADP | HtoT, 0,
2169              ADP_HandleUnknown, ADP_HandleUnknown,
2170              ADP_ICEB_CC_Connect_FromHost, (arg1 != NULL) );
2171      return CheckSubMessageReply(ADP_ICEbreakerHADP, ADP_ICEB_CC_Connect_FromHost);
2172    } else {
2173      return RDIError_UnimplementedMessage;
2174    }
2175
2176  case RDIProfile_Stop:
2177    return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_Stop);
2178
2179  case RDIProfile_ClearCounts:
2180    return SendSubMessageAndCheckReply(ADP_Profile, ADP_Profile_ClearCounts);
2181
2182  case RDIProfile_Start:
2183#ifdef DEBUG
2184    angel_DebugPrint("DEBUG: ADP_Profile_Start %ld.\n", (long)*arg1);
2185#endif
2186    return SendSubMessageWordAndCheckReply(ADP_Profile, ADP_Profile_Start, *arg1);
2187
2188  case RDIProfile_WriteMap:
2189    { RDI_ProfileMap *map = (RDI_ProfileMap *)arg1;
2190      int32 maplen = map->len,
2191            offset,
2192            size;
2193      int32 chunk = (Armsd_LongBufSize-CHAN_HEADER_SIZE-ADP_ProfileWriteHeaderSize) / sizeof(ARMword);
2194                     /* Maximum number of words sendable in one message */
2195      int oldrev = bytesex_reversing();
2196      int host_little = *(uint8 const *)&hostsex;
2197#ifdef DEBUG
2198      angel_DebugPrint("DEBUG: ADP_Profile_WriteMap %ld.\n", maplen);
2199#endif
2200      status = RDIError_NoError;
2201      if (!host_little) {
2202        bytesex_reverse(1);
2203        for (offset = 0; offset < maplen; offset++)
2204          map->map[offset] = bytesex_hostval(map->map[offset]);
2205      }
2206      for (offset = 0; offset < maplen; offset += size) {
2207        unsigned hdrlen;
2208        size = maplen - offset;
2209        packet = (Packet *)DevSW_AllocatePacket(Armsd_LongBufSize);
2210        if (size > chunk) size = chunk;
2211        hdrlen = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w%w",
2212                          ADP_Profile | HtoT, 0, ADP_HandleUnknown,
2213                          ADP_HandleUnknown, ADP_Profile_WriteMap,
2214                          maplen, size, offset);
2215
2216        /* Copy the data into the packet. */
2217        memcpy(BUFFERDATA(packet->pk_buffer)+hdrlen,
2218               &map->map[offset], (size_t)size * sizeof(ARMword));
2219        packet->pk_length = size * sizeof(ARMword) + hdrlen;
2220        register_debug_message_handler();
2221        Adp_ChannelWrite(CI_HADP, packet);
2222        reason = ADP_Profile | TtoH;
2223        err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2224                                     &status, &packet);
2225        if (err == RDIError_NoError) {
2226          unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
2227                         &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
2228          if (subreason !=  ADP_Profile_WriteMap) {
2229            err = RDIError_Error;
2230          }
2231          DevSW_FreePacket(packet);
2232        }
2233        if (err != RDIError_NoError) { status = err; break; }
2234      }
2235      if (!host_little) {
2236        for (offset = 0; offset < maplen; offset++)
2237          map->map[offset] = bytesex_hostval(map->map[offset]);
2238        bytesex_reverse(oldrev);
2239      }
2240      return status;
2241    }
2242
2243  case RDIProfile_ReadMap:
2244    { int32 maplen = *(int32 *)arg1,
2245            offset = 0,
2246            size;
2247      int32 chunk = (Armsd_BufferSize-CHAN_HEADER_SIZE-ADP_ProfileReadHeaderSize) / sizeof(ARMword);
2248#ifdef DEBUG
2249      angel_DebugPrint("DEBUG: ADP_Profile_ReadMap %ld.\n", maplen);
2250#endif
2251      status = RDIError_NoError;
2252      for (offset = 0; offset < maplen; offset += size) {
2253        size = maplen - offset;
2254        if (size > chunk) size = chunk;
2255        register_debug_message_handler();
2256        msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Profile | HtoT, 0,
2257                ADP_HandleUnknown, ADP_HandleUnknown,
2258                ADP_Profile_ReadMap, offset, size);
2259        reason = ADP_Profile | TtoH;
2260        err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2261                                     &status, &packet);
2262        if (err != RDIError_NoError) return err;
2263        unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
2264                       &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
2265        memcpy(&arg2[offset], BUFFERDATA(packet->pk_buffer)+ADP_ProfileReadHeaderSize,
2266               size * sizeof(ARMword));
2267        DevSW_FreePacket(packet);
2268        if (status != RDIError_NoError) break;
2269      }
2270      { int oldrev = bytesex_reversing();
2271        int host_little = *(uint8 const *)&hostsex;
2272        if (!host_little) {
2273          bytesex_reverse(1);
2274          for (offset = 0; offset < maplen; offset++)
2275            arg2[offset] = bytesex_hostval(arg2[offset]);
2276        }
2277        bytesex_reverse(oldrev);
2278      }
2279      return status;
2280    }
2281
2282  case RDIInfo_CanTargetExecute:
2283#ifdef DEBUG
2284    printf("DEBUG: RDIInfo_CanTargetExecute.\n");
2285#endif
2286    return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_CanTargetExecute);
2287
2288  case RDIInfo_AgentEndianess:
2289    return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_AgentEndianess);
2290
2291  default:
2292#ifdef DEBUG
2293    angel_DebugPrint("DEBUG: Fell through ADP_Info, default case taken.\n");
2294    angel_DebugPrint("DEBUG: type = 0x%x.\n", type);
2295#endif
2296    if (type & RDIInfo_CapabilityRequest) {
2297      switch (type & ~RDIInfo_CapabilityRequest) {
2298        case RDISemiHosting_SetARMSWI:
2299          return SendSubMessageAndCheckReply(ADP_Info, ADP_Info_ChangeableSHSWI);
2300        default:
2301#ifdef DEBUG
2302          angel_DebugPrint(
2303          "DEBUG: ADP_Info - Capability Request(%d) - reporting unimplemented \n",
2304                 type & ~RDIInfo_CapabilityRequest);
2305#endif
2306          break;
2307      }
2308    }
2309    return RDIError_UnimplementedMessage;
2310  }
2311}
2312
2313
2314/*----------------------------------------------------------------------*/
2315/*----angel_RDI_AddConfig------------------------------------------------*/
2316/*----------------------------------------------------------------------*/
2317
2318/* Add a configuration: use ADP_ICEM_AddConfig. */
2319int angel_RDI_AddConfig(unsigned long nbytes) {
2320  Packet *packet = NULL;
2321  int status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
2322
2323#ifdef DEBUG
2324  angel_DebugPrint("DEBUG: Entered angel_RDI_AddConfig.\n");
2325#endif
2326  register_debug_message_handler();
2327  msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_ICEman | HtoT,
2328          0, ADP_HandleUnknown, ADP_HandleUnknown,
2329          ADP_ICEM_AddConfig, nbytes);
2330  reason=ADP_ICEman | TtoH;
2331  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2332                              &status, &packet);
2333  if (err != RDIError_NoError) {
2334    DevSW_FreePacket(packet);
2335    return -1;
2336  }
2337  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
2338                 &OSinfo1, &OSinfo2, &subreason, &status);
2339  DevSW_FreePacket(packet);
2340  if ( subreason != ADP_ICEM_AddConfig )
2341    return RDIError_Error;
2342  else
2343    return status;
2344}
2345
2346
2347/*----------------------------------------------------------------------*/
2348/*----angel_RDI_LoadConfigData-------------------------------------------*/
2349/*----------------------------------------------------------------------*/
2350
2351/* Load configuration data: use ADP_Ctrl_Download_Data. */
2352int angel_RDI_LoadConfigData(unsigned long nbytes, char const *data) {
2353  Packet *packet = NULL;
2354  int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
2355
2356#ifdef DEBUG
2357  angel_DebugPrint("DEBUG: Entered angel_RDI_LoadConfigData (%d bytes)\n", nbytes);
2358#endif
2359#if 0
2360  if (err = angel_RDI_AddConfig(nbytes) != RDIError_NoError)
2361    return err;
2362#endif
2363  packet = DevSW_AllocatePacket(Armsd_LongBufSize);
2364  len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w",
2365                 ADP_Control | HtoT, 0,
2366                 ADP_HandleUnknown, ADP_HandleUnknown,
2367                 ADP_Ctrl_Download_Data, nbytes);
2368  memcpy(BUFFERDATA(packet->pk_buffer)+len, data, nbytes);
2369  len += nbytes;
2370  packet->pk_length = len;
2371#ifdef DEBUG
2372  angel_DebugPrint("DEBUG: packet len %d.\n", len);
2373#endif
2374  register_debug_message_handler();
2375  Adp_ChannelWrite(CI_HADP, packet);
2376  reason=ADP_Control | TtoH;
2377  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2378                              &status, &packet);
2379  if (err != RDIError_NoError) {
2380    DevSW_FreePacket(packet);
2381    return -1;
2382  }
2383  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
2384                 &OSinfo1, &OSinfo2, &subreason, &status);
2385  DevSW_FreePacket(packet);
2386  if ( subreason != ADP_Ctrl_Download_Data )
2387    return RDIError_Error;
2388  else
2389    return status;
2390}
2391
2392
2393/*----------------------------------------------------------------------*/
2394/*----angel_RDI_SelectConfig---------------------------------------------*/
2395/*----------------------------------------------------------------------*/
2396
2397/* Select a configuration: use ADP_ICEM_SelecConfig.*/
2398int angel_RDI_SelectConfig(RDI_ConfigAspect aspect, char const *name,
2399                           RDI_ConfigMatchType matchtype, unsigned versionreq,
2400                            unsigned *versionp)
2401{
2402  Packet *packet = NULL;
2403  int len, status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
2404
2405#ifdef DEBUG
2406  angel_DebugPrint("DEBUG: Entered angel_RDI_SelectConfig.\n");
2407#endif
2408  packet = DevSW_AllocatePacket(Armsd_BufferSize);
2409  len = msgbuild(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%b%b%b%w",
2410                 ADP_ICEman | HtoT, 0,
2411                 ADP_HandleUnknown, ADP_HandleUnknown,
2412                 ADP_ICEM_SelectConfig, aspect, strlen(name),
2413                 matchtype, versionreq);
2414  /* copy the name into the buffer */
2415  memcpy(BUFFERDATA(packet->pk_buffer)+len, name, strlen(name));
2416  len += strlen(name);
2417  packet->pk_length = len;
2418  register_debug_message_handler();
2419  Adp_ChannelWrite(CI_HADP, packet);
2420  reason=ADP_ICEman | TtoH;
2421  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2422                              &status, &packet);
2423  if (err != RDIError_NoError) {
2424    DevSW_FreePacket(packet);
2425    return err;
2426  }
2427  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w%w",
2428                 &reason, &debugID, &OSinfo1, &OSinfo2,
2429                 &subreason, &status, versionp);
2430  DevSW_FreePacket(packet);
2431  if ( subreason != ADP_ICEM_SelectConfig )
2432    return RDIError_Error;
2433  else
2434    return status;
2435}
2436
2437
2438/*----------------------------------------------------------------------*/
2439/*----angel_RDI_LoadAgent------------------------------------------------*/
2440/*----------------------------------------------------------------------*/
2441
2442/* Load a new debug agent: use ADP_Ctrl_Download_Agent. */
2443int angel_RDI_LoadAgent(ARMword dest, unsigned long size,
2444                       getbufferproc *getb, void *getbarg)
2445{
2446  Packet *packet = NULL;
2447  int  status, reason, subreason, debugID, OSinfo1, OSinfo2, err;
2448  time_t t;
2449
2450#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2451  angel_DebugPrint("DEBUG: Entered angel_RDI_LoadAgent.\n");
2452#endif
2453  register_debug_message_handler();
2454  msgsend(CI_HADP, "%w%w%w%w%w%w%w", ADP_Control | HtoT,
2455          0, ADP_HandleUnknown, ADP_HandleUnknown,
2456          ADP_Ctrl_Download_Agent, dest, size);
2457  reason=ADP_Control | TtoH;
2458  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2459                              &status, &packet);
2460  if (err != RDIError_NoError) {
2461    DevSW_FreePacket(packet);
2462    return -1;
2463  }
2464  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason, &debugID,
2465                 &OSinfo1, &OSinfo2, &subreason, &status);
2466    DevSW_FreePacket(packet);
2467  if ( subreason != ADP_Ctrl_Download_Agent )
2468    return RDIError_Error;
2469  if ( status != RDIError_NoError )
2470    return status;
2471
2472#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2473  angel_DebugPrint("DEBUG: starting agent data download.\n");
2474#endif
2475  { unsigned long pos = 0, segsize;
2476    for (; pos < size; pos += segsize) {
2477      char *b = getb(getbarg, &segsize);
2478      if (b == NULL) return RDIError_NoError;
2479      err = angel_RDI_LoadConfigData( segsize, b );
2480      if (err != RDIError_NoError) return err;
2481    }
2482  }
2483#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2484  angel_DebugPrint("DEBUG: finished downloading new agent.\n");
2485#endif
2486
2487  /* renegotiate back down */
2488  err = angel_negotiate_defaults();
2489  if (err != adp_ok)
2490     return err;
2491
2492  /* Output a message to tell the user what is going on.  This is vital
2493   * when switching from ADP EICE to ADP over JTAG, as then the user
2494   * has to reset the target board !
2495   */
2496  { char msg[256];
2497    int len=angel_RDI_errmess(msg, 256, adp_new_agent_starting);
2498    angel_hostif->write(angel_hostif->hostosarg, msg, len);
2499  }
2500
2501  /* get new image started */
2502#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2503  angel_DebugPrint("DEBUG: sending start message for new agent.\n");
2504#endif
2505
2506  register_debug_message_handler();
2507  msgsend(CI_HADP, "%w%w%w%w%w%w", ADP_Control | HtoT,
2508          0, ADP_HandleUnknown, ADP_HandleUnknown,
2509          ADP_Ctrl_Start_Agent, dest);
2510  reason=ADP_Control | TtoH;
2511  err = wait_for_debug_message(&reason, &debugID, &OSinfo1, &OSinfo2,
2512                              &status, &packet);
2513  if (err != RDIError_NoError) {
2514    DevSW_FreePacket(packet);
2515    return -1;
2516  }
2517  unpack_message(BUFFERDATA(packet->pk_buffer), "%w%w%w%w%w%w", &reason,
2518                 &debugID, &OSinfo1, &OSinfo2, &subreason, &status);
2519    DevSW_FreePacket(packet);
2520  if ( subreason != ADP_Ctrl_Start_Agent )
2521    return RDIError_Error;
2522  if ( status != RDIError_NoError )
2523    return status;
2524
2525  /* wait for image to start up */
2526  heartbeat_enabled = FALSE;
2527  t=time(NULL);
2528  do {
2529    Adp_AsynchronousProcessing(async_block_on_nothing);
2530    if ((time(NULL)-t) > 2) {
2531#ifdef DEBUG
2532      angel_DebugPrint("DEBUG: no booted message from new image yet.\n");
2533#endif
2534      break;
2535    }
2536  } while (booted_not_received);
2537  booted_not_received=1;
2538
2539  /* Give device driver a chance to do any necessary resyncing with new agent.
2540   * Only used by etherdrv.c at the moment.
2541   */
2542  (void)Adp_Ioctl( DC_RESYNC, NULL );
2543
2544#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2545  angel_DebugPrint("DEBUG: reopening to new agent.\n");
2546#endif
2547  err = angel_RDI_open(0, NULL, NULL, NULL);
2548  switch ( err )
2549  {
2550      case RDIError_NoError:
2551      {
2552#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2553          angel_DebugPrint( "LoadAgent: Open returned RDIError_NoError\n" );
2554#endif
2555          break;
2556      }
2557
2558      case RDIError_LittleEndian:
2559      {
2560#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2561          angel_DebugPrint( "LoadAgent: Open returned RDIError_LittleEndian (OK)\n" );
2562#endif
2563          err = RDIError_NoError;
2564          break;
2565      }
2566
2567      case RDIError_BigEndian:
2568      {
2569#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2570          angel_DebugPrint( "LoadAgent: Open returned RDIError_BigEndian (OK)\n" );
2571#endif
2572          err = RDIError_NoError;
2573          break;
2574      }
2575
2576      default:
2577      {
2578#if defined(DEBUG) || defined(DEBUG_LOADAGENT)
2579          angel_DebugPrint( "LoadAgent: Open returned %d - unexpected!\n", err );
2580#endif
2581          break;
2582      }
2583  }
2584#ifndef NO_HEARTBEAT
2585  heartbeat_enabled = TRUE;
2586#endif
2587  return err;
2588}
2589
2590static int angel_RDI_errmess(char *buf, int blen, int errnum) {
2591  char *s=NULL;
2592  int n;
2593
2594  switch (errnum) {
2595    case adp_malloc_failure:
2596      s=AdpMess_MallocFailed; break;
2597    case adp_illegal_args:
2598      s=AdpMess_IllegalArgs; break;
2599    case adp_device_not_found:
2600      s=AdpMess_DeviceNotFound; break;
2601    case adp_device_open_failed:
2602      s=AdpMess_DeviceOpenFailed; break;
2603    case adp_device_already_open:
2604      s=AdpMess_DeviceAlreadyOpen; break;
2605    case adp_device_not_open:
2606      s=AdpMess_DeviceNotOpen; break;
2607    case adp_bad_channel_id:
2608      s=AdpMess_BadChannelId; break;
2609    case adp_callback_already_registered:
2610      s=AdpMess_CBAlreadyRegd; break;
2611    case adp_write_busy:
2612      s=AdpMess_WriteBusy; break;
2613    case adp_bad_packet:
2614      s=AdpMess_BadPacket; break;
2615    case adp_seq_high:
2616      s=AdpMess_SeqHigh; break;
2617    case adp_seq_low:
2618      s=AdpMess_SeqLow; break;
2619    case adp_timeout_on_open:
2620      s=AdpMess_TimeoutOnOpen; break;
2621    case adp_failed:
2622      s=AdpMess_Failed; break;
2623    case adp_abandon_boot_wait:
2624      s=AdpMess_AbandonBootWait; break;
2625    case adp_late_startup:
2626      s=AdpMess_LateStartup; break;
2627    case adp_new_agent_starting:
2628      s=AdpMess_NewAgentStarting; break;
2629    default: return 0;
2630  }
2631  n=strlen(s);
2632  if (n>blen-1) n=blen-1;
2633  memcpy(buf, s, n);
2634  buf[n++]=0;
2635  return n;
2636}
2637
2638extern const struct RDIProcVec angel_rdi;
2639const struct RDIProcVec angel_rdi = {
2640    "ADP",
2641    angel_RDI_open,
2642    angel_RDI_close,
2643    angel_RDI_read,
2644    angel_RDI_write,
2645    angel_RDI_CPUread,
2646    angel_RDI_CPUwrite,
2647    angel_RDI_CPread,
2648    angel_RDI_CPwrite,
2649    angel_RDI_setbreak,
2650    angel_RDI_clearbreak,
2651    angel_RDI_setwatch,
2652    angel_RDI_clearwatch,
2653    angel_RDI_execute,
2654    angel_RDI_step,
2655    angel_RDI_info,
2656    angel_RDI_pointinq,
2657
2658    angel_RDI_AddConfig,
2659    angel_RDI_LoadConfigData,
2660    angel_RDI_SelectConfig,
2661
2662    0, /*angel_RDI_drivernames,*/
2663    0,   /* cpunames */
2664
2665    angel_RDI_errmess,
2666
2667    angel_RDI_LoadAgent
2668};
2669
2670/* EOF ardi.c */
2671
2672/* Not strictly necessary, but allows linking this code into armsd. */
2673
2674struct foo {
2675    char *name;
2676    int (*action)();
2677    char *syntax;
2678    char **helpmessage;
2679    int doafterend;
2680    int dobeforestart;
2681    int doinmidline;
2682} hostappl_CmdTable[1] = {{"", NULL}};
2683
2684void
2685hostappl_Init()
2686{
2687}
2688
2689int
2690hostappl_Backstop()
2691{
2692  return -30;
2693}
2694