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: 163 $
15  *     $Date: 2004-10-15 22:38:47 +0200 (Fri, 15 Oct 2004) $
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 
53 static volatile int executing;
54 static int rdi_log = 0 ; /* debugging  ? */
55 
56 /* we need a starting point for our first buffers, this is a safe one */
57 int Armsd_BufferSize = ADP_BUFFER_MIN_SIZE;
58 int Armsd_LongBufSize = ADP_BUFFER_MIN_SIZE;
59 
60 #ifdef WIN32
61   extern int interrupted;
62   extern int swiprocessing;
63 #endif
64 
65 static char dummycline = 0;
66 char *ardi_commandline = &dummycline ; /* exported in ardi.h */
67 
68 extern unsigned int heartbeat_enabled;
69 
70 static unsigned char *cpwords[16];
71 
72 typedef struct stoppedProcListElement {
73   struct stoppedProcListElement *next;
74   angel_RDI_TargetStoppedProc *fn;
75   void *arg;
76 } stoppedProcListElement;
77 
78 static stoppedProcListElement *stopped_proc_list=NULL;
79 
80 const struct Dbg_HostosInterface *angel_hostif;
81 static hsys_state *hstate;
82 
angel_DebugPrint(const char * format,...)83 static 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 
98 typedef struct receive_dbgmsg_state {
99   volatile int received;
100   Packet *packet;
101 } receive_dbgmsg_state;
102 
103 static receive_dbgmsg_state dbgmsg_state;
104 
receive_debug_packet(Packet * packet,void * stateptr)105 static 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 
register_debug_message_handler(void)113 static 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 
wait_for_debug_message(int * rcode,int * debugID,int * OSinfo1,int * OSinfo2,int * status,Packet ** packet)126 static 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  */
TargetLogCallback(Packet * packet,void * state)177 static 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 
TargetLogInit(void)192 static 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 
208 typedef struct NegotiateState {
209       bool             negotiate_resp;
210       bool             negotiate_ack;
211       bool             link_check_resp;
212       ParameterConfig *accepted_config;
213 } NegotiateState;
214 
receive_negotiate(Packet * packet,void * stateptr)215 static 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  */
config_to_options(const ParameterConfig * config)279 static 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 
negotiate_params(const ParameterOptions * user_options)314 static 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 
388 static int late_booted = FALSE;
389 static bool ardi_handler_installed = FALSE;
390 
391 #ifdef __unix
392 static struct sigaction old_action;
393 #else
394 static void (*old_handler)();
395 #endif
396 
397 static bool boot_interrupted = FALSE;
398 static volatile bool interrupt_request = FALSE;
399 static volatile bool stop_request = FALSE;
400 
ardi_sigint_handler(int sig)401 static 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 
install_ardi_handler(void)415 static 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 
431 static int angel_RDI_errmess(char *buf, int blen, int errnum);
432 
receive_reset_acknowledge(Packet * packet,void * stateptr)433 static 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 
463 static int booted_not_received;
464 static unsigned int angel_version;
465 static unsigned int adp_version;
466 static unsigned int arch_info;
467 static unsigned int cpu_info;
468 static unsigned int hw_status;
469 
receive_booted(Packet * packet,void * stateptr)470 static 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 */
508 static int angel_negotiate_defaults( void );
509 
510 /* Open communications. */
angel_RDI_open(unsigned type,Dbg_ConfigBlock const * config,Dbg_HostosInterface const * hostif,struct Dbg_MCState * dbg_state)511 int 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 
angel_negotiate_defaults(void)654 static 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 
angel_RDI_close(void)666 int 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 */
angel_RDI_read(ARMword source,void * dest,unsigned * nbytes)704 int 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>. */
angel_RDI_write(const void * source,ARMword dest,unsigned * nbytes)750 int 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. */
angel_RDI_CPUread(unsigned mode,unsigned long mask,ARMword * buffer)802 int 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. */
angel_RDI_CPUwrite(unsigned mode,unsigned long mask,ARMword const * buffer)850 int 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 
angel_RDI_CPread(unsigned CPnum,unsigned long mask,ARMword * buffer)906 int 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 
angel_RDI_CPwrite(unsigned CPnum,unsigned long mask,ARMword const * buffer)960 int 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. */
angel_RDI_pointinq(ARMword * address,unsigned type,unsigned datatype,ARMword * bound)1014 int 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 */
angel_RDI_setbreak(ARMword address,unsigned type,ARMword bound,PointHandle * handle)1057 int 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. */
angel_RDI_clearbreak(PointHandle handle)1096 int 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. */
angel_RDI_setwatch(ARMword address,unsigned type,unsigned datatype,ARMword bound,PointHandle * handle)1130 int 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. */
angel_RDI_clearwatch(PointHandle handle)1164 int 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 
1188 typedef struct {
1189   unsigned stopped_reason;
1190   int stopped_status;
1191   int data;
1192 } adp_stopped_struct;
1193 
1194 
angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc * fn,void * arg)1195 int 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 
CallStoppedProcs(unsigned reason)1212 static 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 
HandleStoppedMessage(Packet * packet,void * stateptr)1229 static 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 
interrupt_target(void)1316 static 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 
angel_RDI_stop_request(void)1347 void angel_RDI_stop_request(void)
1348 {
1349   stop_request = 1;
1350 }
1351 
1352 /* Core functionality for execute and step */
angel_RDI_ExecuteOrStep(PointHandle * handle,word type,unsigned ninstr)1353 static 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. */
angel_RDI_execute(PointHandle * handle)1446 int angel_RDI_execute(PointHandle *handle)
1447 {
1448     return angel_RDI_ExecuteOrStep(handle, ADP_Execute, 0);
1449 }
1450 
1451 #ifdef __WATCOMC__
1452 typedef void handlertype(int);
1453 
1454 static int interrupted=0;
1455 
myhandler(int sig)1456 static 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. */
angel_RDI_step(unsigned ninstr,PointHandle * handle)1468 int 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 
SetCPWords(int cpnum,struct Dbg_CoProDesc const * cpd)1478 static 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 
angel_cc_exists(void)1503 static 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 
1538 typedef struct {
1539   RDICCProc_ToHost *tohost; void *tohostarg;
1540   RDICCProc_FromHost *fromhost; void *fromhostarg;
1541   bool registered;
1542 } CCState;
1543 static CCState ccstate = { NULL, NULL, NULL, NULL, FALSE };
1544 
HandleDCCMessage(Packet * packet,void * stateptr)1545 static 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 
angel_check_DCC_handler(CCState * ccstate_p)1602 static 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 
CheckSubMessageReply(int reason,int subreason)1644 static 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 
SendSubMessageAndCheckReply(int reason,int subreason)1663 static 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 
SendSubMessageWordAndCheckReply(int reason,int subreason,ARMword word)1671 static 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 
SendSubMessageGetWordAndCheckReply(int reason,int subreason,ARMword * resp)1679 static 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 
1703 static int const hostsex = 1;
1704 
angel_RDI_info(unsigned type,ARMword * arg1,ARMword * arg2)1705 int 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. */
angel_RDI_AddConfig(unsigned long nbytes)2319 int 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. */
angel_RDI_LoadConfigData(unsigned long nbytes,char const * data)2352 int 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.*/
angel_RDI_SelectConfig(RDI_ConfigAspect aspect,char const * name,RDI_ConfigMatchType matchtype,unsigned versionreq,unsigned * versionp)2398 int 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. */
angel_RDI_LoadAgent(ARMword dest,unsigned long size,getbufferproc * getb,void * getbarg)2443 int 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 
angel_RDI_errmess(char * buf,int blen,int errnum)2590 static 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 
2638 extern const struct RDIProcVec angel_rdi;
2639 const 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 
2674 struct 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 
2684 void
hostappl_Init()2685 hostappl_Init()
2686 {
2687 }
2688 
2689 int
hostappl_Backstop()2690 hostappl_Backstop()
2691 {
2692   return -30;
2693 }
2694