OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [common/] [v2_0/] [src/] [generic-stub.c] - Blame information for rev 810

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#include "board.h"
2
 
3
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
4
 
5
/* Eventually, this should default to ON */
6
#if USE_GDBSTUB_PROTOTYPES
7
#include "stub-tservice.h"
8
#include "generic-stub.h"
9
#else
10
// Function declarations (prevents compiler warnings)
11
int stubhex (unsigned char ch);
12
static void unlock_thread_scheduler (void);
13
static uint32 crc32 (target_addr_t mem, int len, uint32 crc);
14
#endif
15
 
16
#include "thread-pkts.h"
17
  /* Defines function macros if thread support is not selected in board.h */
18
 
19
#ifdef __ECOS__
20
char GDB_stubs_version[] CYGBLD_ATTRIB_WEAK =
21
    "eCos GDB stubs - built " __DATE__ " / " __TIME__;
22
#endif
23
 
24
/****************************************************************************
25
 
26
                THIS SOFTWARE IS NOT COPYRIGHTED
27
 
28
   HP offers the following for use in the public domain.  HP makes no
29
   warranty with regard to the software or it's performance and the
30
   user accepts the software "AS IS" with all faults.
31
 
32
   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
33
   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
34
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
35
 
36
****************************************************************************/
37
 
38
/****************************************************************************
39
 *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
40
 *
41
 *  Module name: remcom.c $
42
 *  Revision: 1.34 $
43
 *  Date: 91/03/09 12:29:49 $
44
 *  Contributor:     Lake Stevens Instrument Division$
45
 *
46
 *  Description:     low level support for gdb debugger. $
47
 *
48
 *  Considerations:  only works on target hardware $
49
 *
50
 *  Written by:      Glenn Engel $
51
 *  ModuleState:     Experimental $
52
 *
53
 *  NOTES:           See Below $
54
 *
55
 *  Modified for SPARC by Stu Grossman, Red Hat.
56
 *  Modified for generic CygMON stub support by Bob Manson, Red Hat.
57
 *
58
 *  To enable debugger support, two things need to happen.  One, a
59
 *  call to set_debug_traps () is necessary in order to allow any breakpoints
60
 *  or error conditions to be properly intercepted and reported to gdb.
61
 *  Two, a breakpoint needs to be generated to begin communication.  This
62
 *  is most easily accomplished by a call to breakpoint ().  Breakpoint ()
63
 *  simulates a breakpoint by executing a trap #1.
64
 *
65
 *************
66
 *
67
 *    The following gdb commands are supported:
68
 *
69
 * command          function                               Return value
70
 *
71
 *    g             return the value of the CPU registers  hex data or ENN
72
 *    G             set the value of the CPU registers     OK or ENN
73
 *
74
 *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
75
 *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
76
 *
77
 *    c             Resume at current address              SNN   ( signal NN)
78
 *    cAA..AA       Continue at address AA..AA             SNN
79
 *
80
 *    s             Step one instruction                   SNN
81
 *    sAA..AA       Step one instruction from AA..AA       SNN
82
 *
83
 *    k             kill
84
 *
85
 *    ?             What was the last sigval ?             SNN   (signal NN)
86
 *
87
 *    bBB..BB       Set baud rate to BB..BB                OK or BNN, then sets
88
 *                                                         baud rate
89
 *
90
 * All commands and responses are sent with a packet which includes a
91
 * checksum.  A packet consists of
92
 *
93
 * $<packet info>#<checksum>.
94
 *
95
 * where
96
 * <packet info> :: <characters representing the command or response>
97
 * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
98
 *
99
 * When a packet is received, it is first acknowledged with either '+' or '-'.
100
 * '+' indicates a successful transfer.  '-' indicates a failed transfer.
101
 *
102
 * Example:
103
 *
104
 * Host:                  Reply:
105
 * $m0,10#2a               +$00010203040506070809101112131415#42
106
 *
107
 ****************************************************************************/
108
 
109
#ifdef __ECOS__
110
 
111
// We cannot share memcpy and memset with the rest of the system since
112
// the user may want to step through it.
113
static inline void*
114
_memcpy(void* dest, void* src, int size)
115
{
116
    unsigned char* __d = (unsigned char*) dest;
117
    unsigned char* __s = (unsigned char*) src;
118
 
119
    while(size--)
120
        *__d++ = *__s++;
121
 
122
    return dest;
123
}
124
 
125
static inline void*
126
_memset(void* s, int c, int size)
127
{
128
    unsigned char* __s = (unsigned char*) s;
129
    unsigned char __c = (unsigned char) c;
130
 
131
    while(size--)
132
        *__s++ = __c;
133
 
134
    return s;
135
}
136
 
137
#else
138
#include <string.h>
139
#include <signal.h>
140
#define _memcpy memcpy
141
#define _memset memset
142
#endif // __ECOS__
143
 
144
/************************************************************************/
145
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
146
/* at least NUMREGBYTES*2 are needed for register packets */
147
#ifdef __ECOS__
148
#ifdef NUMREGBYTES
149
#define BUFMAX (32 + (NUMREGBYTES*2))
150
#else
151
#define BUFMAX 2048
152
#endif
153
#else
154
#define BUFMAX 2048
155
#endif
156
 
157
static int initialized = 0;     /* !0 means we've been initialized */
158
 
159
static int process_exception (int sigval);
160
static void do_nothing (void); /* and do it gracefully */
161
static int syscall_do_nothing (int);
162
 
163
void __free_program_args (void);
164
 
165
volatile __PFI __process_exception_vec = process_exception;
166
volatile __PFV __process_exit_vec = do_nothing;
167
volatile __PFI __process_syscall_vec = syscall_do_nothing;
168
volatile __PFI __process_signal_vec = NULL;
169
volatile __PFV __init_vec = NULL;
170
volatile __PFV __cleanup_vec = NULL;
171
 
172
static char *__add_program_arg (int argnum, uint32 arglen);
173
 
174
static const char hexchars[] = "0123456789abcdef";
175
 
176
static void process_query (char *pkt);
177
static void process_set   (char *pkt);
178
 
179
char
180
__tohex (int c)
181
{
182
  return hexchars [c & 15];
183
}
184
 
185
#define __tohex(c) hexchars[(c) & 15]
186
 
187
#ifndef NUMREGS_GDB
188
#define NUMREGS_GDB NUMREGS
189
#endif
190
 
191
/* One pushback character. */
192
int ungot_char = -1;
193
 
194
static int
195
readDebugChar (void)
196
{
197
  if (ungot_char > 0)
198
    {
199
      int result = ungot_char;
200
      ungot_char = -1;
201
      return result;
202
    }
203
  else
204
    return getDebugChar ();
205
}
206
 
207
/* Convert ch from a hex digit to an int. */
208
 
209
int
210
stubhex (ch)
211
     unsigned char ch;
212
{
213
  if (ch >= 'a' && ch <= 'f')
214
    return ch-'a'+10;
215
  if (ch >= '0' && ch <= '9')
216
    return ch-'0';
217
  if (ch >= 'A' && ch <= 'F')
218
    return ch-'A'+10;
219
  return -1;
220
}
221
 
222
void
223
__getpacket (buffer)
224
     char *buffer;
225
{
226
    struct gdb_packet packet;
227
    int res;
228
 
229
    packet.state = 0;
230
    packet.contents = buffer;
231
    packet.err = 0;
232
    while ((res = __add_char_to_packet (readDebugChar () & 0xff, &packet)) != 1) {
233
        if (res == -2) {
234
            putDebugChar ('-'); // Tell host packet was not processed
235
            // Reset for the next packet
236
            packet.state = 0;
237
            packet.err = 0;
238
        }
239
    }
240
}
241
 
242
int
243
__add_char_to_packet (ch, packet)
244
     unsigned int ch;
245
     struct gdb_packet *packet;
246
{
247
  if (packet->state == 0)
248
    {
249
      if (ch == '$')
250
        {
251
          packet->state = 1;
252
          packet->length = 0;
253
          packet->checksum = 0;
254
          packet->xmitcsum = -1;
255
        }
256
      return 0;
257
    }
258
 
259
  if (packet->state == 1)
260
    {
261
      if (packet->length == BUFMAX)
262
        {
263
          packet->state = 0;
264
          packet->err = 1;
265
        }
266
      else if (ch == '#')
267
        {
268
          packet->contents[packet->length] = 0;
269
          packet->state = 2;
270
        }
271
      else
272
        {
273
          packet->checksum += ch;
274
          packet->contents[packet->length++] = ch;
275
        }
276
      return 0;
277
    }
278
 
279
  if (packet->state == 2)
280
    {
281
      packet->xmitcsum = stubhex (ch) << 4;
282
      packet->state = 3;
283
      return 0;
284
    }
285
 
286
  if (packet->state == 3)
287
    {
288
      packet->xmitcsum |= stubhex (ch);
289
      if (packet->err) {
290
          // Packet was too long - just tell the consumer
291
          return -2;
292
      }
293
      if ((packet->checksum & 255) != packet->xmitcsum)
294
        {
295
          putDebugChar ('-');   /* failed checksum */
296
          packet->state = 0;
297
          return -1;
298
        }
299
      else
300
        {
301
          putDebugChar ('+'); /* successful transfer */
302
          /* if a sequence char is present, reply the sequence ID */
303
          if (packet->contents[2] == ':')
304
            {
305
              uint32 count = packet->length;
306
              uint32 i;
307
              putDebugChar (packet->contents[0]);
308
              putDebugChar (packet->contents[1]);
309
              /* remove sequence chars from buffer */
310
              for (i=3; i <= count; i++)
311
                packet->contents[i-3] = packet->contents[i];
312
            }
313
          return 1;
314
        }
315
    }
316
  /* We should never get here. */
317
  packet->state = 0;
318
  return -1;
319
}
320
 
321
/* send the packet in buffer.  */
322
 
323
void
324
__putpacket (buffer)
325
     char *buffer;
326
{
327
  unsigned char checksum;
328
  uint32 count;
329
  unsigned char ch;
330
 
331
  /*  $<packet info>#<checksum>. */
332
  do
333
    {
334
      putDebugChar ('$');
335
      checksum = 0;
336
      count = 0;
337
 
338
      while ((ch = buffer[count]))
339
        {
340
          putDebugChar (ch);
341
          checksum += ch;
342
          count += 1;
343
        }
344
 
345
      putDebugChar ('#');
346
      putDebugChar (hexchars[(checksum >> 4) & 0xf]);
347
      putDebugChar (hexchars[checksum & 0xf]);
348
 
349
    }
350
  while ((readDebugChar () & 0x7f) != '+');
351
}
352
 
353
char __remcomInBuffer[BUFMAX];
354
char __remcomOutBuffer[BUFMAX];
355
 
356
/* Indicate to caller of mem2hex or hex2mem that there has been an
357
   error.  */
358
volatile int __mem_fault = 0;
359
 
360
 
361
#ifndef TARGET_HAS_OWN_MEM_FUNCS
362
/*
363
 * _target_readmem_hook / _target_writemem_hook:
364
 * Allow target to get involved in reading/writing memory.
365
 *
366
 * If these hooks are defined by the target, they will be
367
 * called for each user program memory access.  Otherwise, the stub
368
 * will simply dereference a pointer to access user program memory.
369
 */
370
 
371
unsigned char (*_target_readmem_hook)  (unsigned char* addr);
372
void          (*_target_writemem_hook) (unsigned char* addr,
373
                                        unsigned char value);
374
 
375
static unsigned char
376
get_target_byte (volatile unsigned char *address)
377
{
378
  if (_target_readmem_hook)     /* target needs to control memory access */
379
    return _target_readmem_hook ((unsigned char *) address);
380
  else
381
    return *address;
382
}
383
 
384
static void
385
put_target_byte (volatile unsigned char *address, unsigned char value)
386
{
387
  if (_target_writemem_hook)    /* target needs to control memory access */
388
    _target_writemem_hook ((unsigned char *) address, value);
389
  else
390
    *address = value;
391
}
392
 
393
/* These are the "arguments" to __do_read_mem and __do_write_mem,
394
   which are passed as globals to avoid squeezing them thru
395
   __set_mem_fault_trap.  */
396
 
397
static volatile target_register_t memCount;
398
static volatile unsigned char    *memSrc,  *memDst;
399
 
400
/*
401
 * __do_read_mem:
402
 * Copy from target memory to trusted memory.
403
 */
404
 
405
static void
406
__do_read_mem (void)
407
{
408
  __mem_fault = 0;
409
  while (memCount)
410
    {
411
      unsigned char ch = get_target_byte (memSrc++);
412
 
413
      if (__mem_fault)
414
        return;
415
      *memDst++ = ch;
416
      memCount--;
417
    }
418
}
419
 
420
/*
421
 * __do_write_mem:
422
 * Copy from trusted memory to target memory.
423
 */
424
 
425
static void
426
__do_write_mem (void)
427
{
428
  __mem_fault = 0;
429
  while (memCount)
430
    {
431
      unsigned char ch = *memSrc++;
432
 
433
      put_target_byte (memDst++, ch);
434
      if (__mem_fault)
435
        return;
436
      memCount--;
437
    }
438
}
439
 
440
/*
441
 * __read_mem_safe:
442
 * Get contents of target memory, abort on error.
443
 */
444
 
445
int
446
__read_mem_safe (void *dst, target_register_t src, int count)
447
{
448
  memCount = count;
449
  memSrc   = (unsigned char *) src;
450
  memDst   = (unsigned char *) dst;
451
  __set_mem_fault_trap (__do_read_mem);
452
  return count - memCount;      /* return number of bytes successfully read */
453
}
454
 
455
/*
456
 * __write_mem_safe:
457
 * Set contents of target memory, abort on error.
458
 */
459
 
460
int
461
__write_mem_safe (unsigned char *src, target_register_t dst, int count)
462
{
463
  memCount = count;
464
  memSrc   = (unsigned char *) src;
465
  memDst   = (unsigned char *) dst;
466
  __set_mem_fault_trap (__do_write_mem);
467
  return count - memCount;      /* return number of bytes successfully read */
468
}
469
 
470
#endif /* TARGET_HAS_OWN_MEM_FUNCS */
471
 
472
/* These are the "arguments" to __mem2hex_helper and __hex2mem_helper,
473
   which are passed as globals to avoid squeezing them thru
474
   __set_mem_fault_trap.  */
475
 
476
static int   hexMemCount;
477
static char *hexMemSrc, *hexMemDst;
478
static int   may_fault_mode;
479
#ifdef TARGET_HAS_HARVARD_MEMORY
480
static int   progMem;
481
#endif
482
 
483
/* Hamburger helper? */
484
static void
485
__mem2hex_helper (void)
486
{
487
    union {
488
        unsigned long  long_val;
489
        unsigned char  bytes[sizeof(long)];
490
    } val;
491
    int len, i;
492
    unsigned char ch;
493
    __mem_fault = 0;
494
    while (hexMemCount > 0) {
495
        if (may_fault_mode) {
496
            if ((hexMemCount >= sizeof(long)) &&
497
                (((target_register_t)hexMemSrc & (sizeof(long)-1)) == 0)) {
498
                // Should be safe to access via a long
499
                len = sizeof(long);
500
            } else if ((hexMemCount >= sizeof(short)) &&
501
                       (((target_register_t)hexMemSrc & (sizeof(short)-1)) == 0)) {
502
                // Should be safe to access via a short
503
                len = sizeof(short);
504
            } else {
505
                len = 1;
506
            }
507
#ifdef TARGET_HAS_HARVARD_MEMORY
508
            if (progMem)
509
                __read_progmem_safe(&val.bytes[0], hexMemSrc, len);
510
            else
511
#endif
512
            __read_mem_safe(&val.bytes[0], hexMemSrc, len);
513
        } else {
514
            len = 1;
515
            val.bytes[0] = *hexMemSrc;
516
        }
517
        if (__mem_fault)
518
            return;
519
 
520
        for (i = 0;  i < len;  i++) {
521
            ch = val.bytes[i];
522
            *(hexMemDst++) = hexchars[(ch >> 4) & 0xf];
523
            if (__mem_fault)
524
                return;
525
            *(hexMemDst++) = hexchars[ch & 0xf];
526
            if (__mem_fault)
527
                return;
528
        }
529
        hexMemCount -= len;
530
        hexMemSrc += len;
531
    }
532
}
533
 
534
/* Convert the memory pointed to by MEM into HEX, placing result in BUF.
535
 * Return a pointer to the last char put in buf (NUL). In case of a memory
536
 * fault, return 0.
537
 * If MAY_FAULT is non-zero, then we will handle memory faults by returning
538
 * a 0 (and assume that MEM is a pointer into the user program), else we
539
 * treat a fault like any other fault in the stub (and assume that MEM is
540
 * a pointer into the stub's memory).
541
 */
542
 
543
char *
544
__mem2hex (mem, buf, count, may_fault)
545
     char *mem;
546
     char *buf;
547
     int count;
548
     int may_fault;
549
{
550
  hexMemDst      = (unsigned char *) buf;
551
  hexMemSrc      = (unsigned char *) mem;
552
  hexMemCount    = count;
553
  may_fault_mode = may_fault;
554
#ifdef TARGET_HAS_HARVARD_MEMORY
555
  progMem = 0;
556
#endif
557
 
558
  if (may_fault)
559
    {
560
      if (__set_mem_fault_trap (__mem2hex_helper))
561
        return 0;
562
    }
563
  else
564
    __mem2hex_helper ();
565
 
566
  *hexMemDst = 0;
567
 
568
  return (char *) hexMemDst;
569
}
570
 
571
/* Convert the target memory identified by MEM into HEX, placing result in BUF.
572
 * Return a pointer to the last char put in buf (NUL). In case of a memory
573
 * fault, return 0.
574
 */
575
 
576
static char *
577
__mem2hex_safe (target_addr_t mem, char *buf, int count)
578
{
579
  hexMemDst      = (unsigned char *) buf;
580
  hexMemSrc      = (unsigned char *) TARGET_ADDR_TO_PTR(mem);
581
  hexMemCount    = count;
582
  may_fault_mode = 1;
583
#ifdef TARGET_HAS_HARVARD_MEMORY
584
  progMem = TARGET_ADDR_IS_PROGMEM(mem);
585
#endif
586
 
587
  if (__set_mem_fault_trap (__mem2hex_helper))
588
    return 0;
589
 
590
  *hexMemDst = 0;
591
 
592
  return (char *) hexMemDst;
593
}
594
 
595
 
596
 
597
static void
598
__hex2mem_helper (void)
599
{
600
    union {
601
        unsigned long  long_val;
602
        unsigned char  bytes[sizeof(long)];
603
    } val;
604
    int len, i;
605
    unsigned char ch = '\0';
606
 
607
    __mem_fault = 0;
608
    while (hexMemCount > 0 && *hexMemSrc) {
609
        if (may_fault_mode) {
610
            if ((hexMemCount >= sizeof(long)) &&
611
                (((target_register_t)hexMemDst & (sizeof(long)-1)) == 0)) {
612
                len = sizeof(long);
613
            } else if ((hexMemCount >= sizeof(short)) &&
614
                       (((target_register_t)hexMemDst & (sizeof(short)-1)) == 0)) {
615
                len = sizeof(short);
616
            } else {
617
                len = 1;
618
            }
619
        } else {
620
            len = 1;
621
        }
622
 
623
        for (i = 0;  i < len;  i++) {
624
            // Check for short data?
625
            ch = stubhex (*(hexMemSrc++)) << 4;
626
            if (__mem_fault)
627
                return;
628
            ch |= stubhex (*(hexMemSrc++));
629
            if (__mem_fault)
630
                return;
631
            val.bytes[i] = ch;
632
        }
633
 
634
        if (may_fault_mode) {
635
#ifdef TARGET_HAS_HARVARD_MEMORY
636
            if (progMem)
637
                __write_progmem_safe (&val.bytes[0], hexMemDst, len);
638
            else
639
#endif
640
            __write_mem_safe (&val.bytes[0], hexMemDst, len);
641
        } else
642
            *hexMemDst = ch;
643
 
644
        if (__mem_fault)
645
            return;
646
        hexMemCount -= len;
647
        hexMemDst += len;
648
    }
649
}
650
 
651
/* Convert COUNT bytes of the hex array pointed to by BUF into binary
652
   to be placed in MEM.  Return a pointer to the character AFTER the
653
   last byte written.
654
 
655
   If MAY_FAULT is set, we will return a non-zero value if a memory
656
   fault occurs (and we assume that MEM is a pointer into the user
657
   program). Otherwise, we will take a trap just like any other memory
658
   fault (and assume that MEM points into the stub's memory). */
659
 
660
char *
661
__hex2mem (buf, mem, count, may_fault)
662
     char *buf;
663
     char *mem;
664
     int count;
665
     int may_fault;
666
{
667
  hexMemSrc      = (unsigned char *) buf;
668
  hexMemDst      = (unsigned char *) mem;
669
  hexMemCount    = count;
670
  may_fault_mode = may_fault;
671
#ifdef TARGET_HAS_HARVARD_MEMORY
672
  progMem = 0;
673
#endif
674
 
675
  if (may_fault)
676
    {
677
      if (__set_mem_fault_trap (__hex2mem_helper))
678
        return 0;
679
    }
680
  else
681
    __hex2mem_helper ();
682
 
683
  return (char *) hexMemDst;
684
}
685
 
686
/* Convert COUNT bytes of the hex array pointed to by BUF into binary
687
   to be placed in target MEM.  Return a pointer to the character AFTER
688
   the last byte written.
689
*/
690
char *
691
__hex2mem_safe (char *buf, target_addr_t mem, int count)
692
{
693
  hexMemSrc      = (unsigned char *) buf;
694
  hexMemDst      = (unsigned char *) TARGET_ADDR_TO_PTR(mem);
695
  hexMemCount    = count;
696
  may_fault_mode = 1;
697
#ifdef TARGET_HAS_HARVARD_MEMORY
698
  progMem = TARGET_ADDR_IS_PROGMEM(mem);
699
#endif
700
 
701
  if (__set_mem_fault_trap (__hex2mem_helper))
702
    return 0;
703
 
704
  return (char *) hexMemDst;
705
}
706
 
707
 
708
void
709
set_debug_traps (void)
710
{
711
  __install_traps ();
712
  initialized = 1;    /* FIXME: Change this to dbg_stub_initialized */
713
}
714
 
715
/*
716
 * While we find nice hex chars, build an int.
717
 * Return number of chars processed.
718
 */
719
 
720
unsigned int
721
__hexToInt (char **ptr, target_register_t *intValue)
722
{
723
  int numChars = 0;
724
  int hexValue;
725
 
726
  *intValue = 0;
727
 
728
  while (**ptr)
729
    {
730
      hexValue = stubhex (**ptr);
731
      if (hexValue < 0)
732
        break;
733
 
734
      *intValue = (*intValue << 4) | hexValue;
735
      numChars ++;
736
 
737
      (*ptr)++;
738
    }
739
 
740
  return (numChars);
741
}
742
 
743
/*
744
 * While we find nice hex chars, build a target memory address.
745
 * Return number of chars processed.
746
 */
747
 
748
unsigned int
749
__hexToAddr (char **ptr, target_addr_t *val)
750
{
751
  int numChars = 0;
752
  int hexValue;
753
 
754
  *val = 0;
755
 
756
  while (**ptr)
757
    {
758
      hexValue = stubhex (**ptr);
759
      if (hexValue < 0)
760
        break;
761
 
762
      *val = (*val << 4) | hexValue;
763
      numChars ++;
764
 
765
      (*ptr)++;
766
    }
767
 
768
  return (numChars);
769
}
770
 
771
 
772
/*
773
 * Complement of __hexToInt: take an int of size "numBits",
774
 * convert it to a hex string.  Return length of (unterminated) output.
775
 */
776
 
777
unsigned int
778
__intToHex (char *ptr, target_register_t intValue, int numBits)
779
{
780
  int numChars = 0;
781
 
782
  if (intValue == 0)
783
    {
784
      *(ptr++) = '0';
785
      *(ptr++) = '0';
786
      return 2;
787
    }
788
 
789
  numBits = (numBits + 7) / 8;
790
  while (numBits)
791
    {
792
      int v = (intValue >> ((numBits - 1) * 8));
793
      if (v || (numBits == 1))
794
        {
795
          v = v & 255;
796
          *(ptr++) = __tohex ((v / 16) & 15);
797
          *(ptr++) = __tohex (v & 15);
798
          numChars += 2;
799
        }
800
      numBits--;
801
    }
802
 
803
  return (numChars);
804
}
805
 
806
#if DEBUG_THREADS 
807
/*
808
 * Kernel Thread Control
809
 *
810
 * If the current thread is set to other than zero (or minus one),
811
 * then ask the kernel to lock it's scheduler so that only that thread
812
 * can run.
813
 */
814
 
815
static unsigned char did_lock_scheduler = 0;
816
static unsigned char did_disable_interrupts = 0;
817
 
818
/* Pointer to "kernel call" for scheduler control */
819
static int (*schedlock_fn) (int, int, long) = stub_lock_scheduler;
820
 
821
/* Pointer to target stub call for disabling interrupts.
822
   Target stub will initialize this if it can.  */
823
int (*__disable_interrupts_hook) (int); /* don't initialize here! */
824
#endif
825
 
826
static void
827
lock_thread_scheduler (int kind)        /* "step" or "continue" */
828
{
829
#if DEBUG_THREADS 
830
  int ret = 0;
831
 
832
  /* GDB will signal its desire to run a single thread
833
     by setting _gdb_cont_thread to non-zero / non-negative.  */
834
  if (_gdb_cont_thread <= 0)
835
    return;
836
 
837
  if (schedlock_fn)                     /* kernel call */
838
    ret = (*schedlock_fn) (1, kind, _gdb_cont_thread);
839
 
840
  if (ret == 1)
841
    {
842
      did_lock_scheduler = 1;
843
      return;
844
    }
845
 
846
  if (schedlock_fn == 0 ||              /* no kernel scheduler call */
847
      ret == -1)                        /* kernel asks stub to handle it */
848
    if (__disable_interrupts_hook)      /* target stub has capability */
849
      if ((*__disable_interrupts_hook) (1))
850
        {
851
          did_disable_interrupts = 1;
852
          return;
853
        }
854
#endif /* DEBUG_THREADS */
855
}
856
 
857
static void
858
unlock_thread_scheduler ()
859
{
860
#if DEBUG_THREADS
861
  if (did_lock_scheduler)
862
    if (schedlock_fn)                   /* kernel call */
863
      {
864
        (*schedlock_fn) (0, 0, _gdb_cont_thread);
865
        /* I could check the return value, but
866
           what would I do if it failed???  */
867
        did_lock_scheduler = 0;
868
      }
869
  if (did_disable_interrupts)
870
    if (__disable_interrupts_hook)      /* target stub call */
871
      {
872
        (*__disable_interrupts_hook) (0);
873
        /* Again, I could check the return value, but
874
           what would I do if it failed???  */
875
        did_disable_interrupts = 0;
876
      }
877
#endif /* DEBUG_THREADS */
878
}
879
 
880
#ifdef CYGPKG_CYGMON
881
int processing_breakpoint_function = 0;
882
#endif
883
 
884
void
885
__handle_exception (void)
886
{
887
  int sigval = 0;
888
 
889
#ifdef TARGET_HAS_NEXT_STEP
890
  if (! __next_step_done ())
891
    {
892
      __clear_breakpoints ();
893
      __install_breakpoints ();
894
      __single_step ();
895
      return;
896
    }
897
#endif
898
 
899
#ifdef __ECOS__
900
  // We need to unpack the registers before they are accessed.
901
  if (__cleanup_vec != NULL)
902
    __cleanup_vec ();
903
 
904
#if defined(CYGSEM_REDBOOT_BSP_SYSCALLS)
905
  // Temporary support for gnupro bsp SWIs
906
  if (__is_bsp_syscall())
907
  {
908
      sigval = hal_syscall_handler();
909
      if (0 == sigval)
910
      {
911
          if (__init_vec != NULL)
912
              __init_vec ();
913
          return;
914
      }
915
  }
916
#endif
917
 
918
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
919
  // Special case for GDB BREAKs. This flag is set by cyg_stub_cleanup.
920
  if (cyg_hal_gdb_break) {
921
      cyg_hal_gdb_break = 0;
922
      sigval = SIGINT;
923
  }
924
#endif
925
 
926
  // Only compute sigval if it wasn't already computed (in
927
  // hal_syscall_handler or as a result of a GDB async break)
928
  if (0 == sigval)
929
      sigval = __computeSignal (__get_trap_number ());
930
 
931
#else  // __ECOS__
932
  /* reply to host that an exception has occurred */
933
  sigval = __computeSignal (__get_trap_number ());
934
#endif // __ECOS__
935
 
936
  if (__is_breakpoint_function ())
937
  {
938
#ifdef CYGPKG_CYGMON
939
    processing_breakpoint_function = 1;
940
#endif
941
    __skipinst ();
942
  } else {
943
#ifdef CYGPKG_CYGMON
944
    processing_breakpoint_function = 0;
945
#endif
946
  }
947
 
948
#ifndef __ECOS__
949
  if (__cleanup_vec != NULL)
950
    __cleanup_vec ();
951
#endif // !__ECOS__
952
 
953
  __clear_breakpoints ();
954
 
955
  /* Undo effect of previous single step.  */
956
  unlock_thread_scheduler ();
957
  __clear_single_step ();
958
 
959
#ifdef __ECOS__
960
      /* Need to flush the data and instruction cache here, as we may have
961
         removed a breakpoint in __single_step - and we may be sharing
962
         some code with the application! */
963
 
964
        __data_cache (CACHE_FLUSH) ;
965
        __instruction_cache (CACHE_FLUSH) ;
966
#endif
967
 
968
#ifdef SIGSYSCALL
969
  if (sigval == SIGSYSCALL)
970
    {
971
      int val;
972
      /* Do the skipinst FIRST. */
973
#ifndef SYSCALL_PC_AFTER_INST
974
      __skipinst ();
975
#endif
976
      val =  __process_syscall_vec (__get_syscall_num ());
977
      if (val < 0)
978
        sigval = -val;
979
      else
980
        sigval = 0;
981
    }
982
 
983
#endif
984
 
985
  /* Indirect function call to stub, cygmon monitor or other */
986
  if (sigval != 0)
987
    {
988
      while (__process_exception_vec (sigval))
989
        {
990
          /* Empty! */
991
        }
992
    }
993
 
994
  __install_breakpoints ();
995
 
996
  if (__init_vec != NULL)
997
    __init_vec ();
998
}
999
 
1000
/*
1001
 * _get_trace_register_hook:
1002
 * This function pointer will be non-zero if the trace component
1003
 * wants to intercept requests for register values.
1004
 *
1005
 * FIXME: evidently I need a new hook for large registers...
1006
 */
1007
 
1008
int   (*_get_trace_register_hook) (regnames_t, target_register_t *);
1009
 
1010
void
1011
stub_format_registers(char *packet, char *ptr)
1012
{
1013
    int regnum;
1014
    int sr = 0, er = NUMREGS_GDB;
1015
 
1016
    if (packet[0] == 'p')
1017
      {
1018
         target_register_t regno;
1019
         char *p = &packet[1];
1020
         if (__hexToInt (&p, &regno))
1021
           {
1022
             sr = regno;
1023
             er = regno + 1;
1024
           }
1025
         else
1026
           {
1027
             strcpy (ptr, "INVALID");
1028
             return;
1029
           }
1030
      }
1031
 
1032
    for (regnum = sr; regnum < er; regnum++)
1033
      {
1034
        /* We need to compensate for the value offset within the
1035
           register. */
1036
        char dummyDat[32];
1037
        target_register_t addr;
1038
        char *vptr;
1039
        int  reg_valid = 1;
1040
 
1041
#ifdef TARGET_HAS_LARGE_REGISTERS
1042
        if (sizeof (target_register_t) < REGSIZE (regnum)) {
1043
            get_register_as_bytes (regnum, dummyDat);
1044
            vptr = dummyDat;
1045
        } else
1046
#endif
1047
        {
1048
            if (_get_trace_register_hook)
1049
                reg_valid = _get_trace_register_hook (regnum, &addr);
1050
            else
1051
            {
1052
                addr = get_register (regnum);
1053
#ifdef CYGHWR_REGISTER_VALIDITY_CHECKING
1054
                reg_valid = get_register_valid (regnum);
1055
#endif
1056
            }
1057
            vptr = ((char *) &addr);
1058
            if (sizeof (addr) > REGSIZE(regnum)) {
1059
                /* May need to cope with endian-ness */
1060
 
1061
#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN)
1062
                vptr += sizeof (addr) - REGSIZE (regnum);
1063
#endif
1064
            } else if (sizeof (addr) < REGSIZE (regnum)) {
1065
                int off = REGSIZE (regnum) - sizeof (addr);
1066
                int x;
1067
                char extend_val = 0;
1068
 
1069
#ifdef CYGARC_SIGN_EXTEND_REGISTERS
1070
                {
1071
                    unsigned long bits_in_addr = (sizeof(addr) << 3);  // ie Size in bytes * 8
1072
                    target_register_t sign_bit_mask = (1 << (bits_in_addr - 1));
1073
                    if ((addr & sign_bit_mask) == sign_bit_mask)
1074
                        extend_val = ~0;
1075
                }
1076
#endif
1077
 
1078
#if defined(__LITTLE_ENDIAN__) || defined(_LITTLE_ENDIAN)
1079
                for (x = 0; x < off; x++)
1080
                    dummyDat[x + sizeof(addr)] = extend_val;
1081
                _memcpy (dummyDat, &addr, sizeof (addr));
1082
#else
1083
                for (x = 0; x < off; x++)
1084
                    dummyDat[x] = extend_val;
1085
                _memcpy (dummyDat + off, &addr, sizeof (addr));
1086
#endif
1087
                vptr = dummyDat;
1088
            }
1089
        }
1090
        if (reg_valid) {      /* we have a valid reg value */
1091
            ptr = __mem2hex (vptr, ptr, REGSIZE (regnum), 0);
1092
        } else {
1093
            /* Trace component returned a failure code.
1094
               This means that the register value is not available.
1095
               We'll fill it with 'x's, and GDB will understand.  */
1096
            _memset (ptr, 'x', 2 * REGSIZE (regnum));
1097
            ptr += 2 * REGSIZE (regnum);
1098
        }
1099
    }
1100
}
1101
 
1102
void
1103
stub_update_registers(char *in_ptr, char *out_ptr)
1104
{
1105
    char *ptr = &in_ptr[1];
1106
    int x;
1107
    int sr = 0, er = NUMREGS_GDB;
1108
 
1109
    if (*in_ptr == 'P') {
1110
        target_register_t regno;
1111
 
1112
        if (__hexToInt (&ptr, &regno) && (*ptr++ == '=')) {
1113
 
1114
            sr = regno;
1115
            er = regno + 1;
1116
        } else {
1117
            strcpy (out_ptr, "P01");
1118
            return;
1119
        }
1120
    }
1121
 
1122
    for (x = sr; x < er; x++) {
1123
        target_register_t value = 0;
1124
        char *vptr;
1125
 
1126
#ifdef TARGET_HAS_LARGE_REGISTERS
1127
        if (sizeof (target_register_t) < REGSIZE (x)) {
1128
            char dummyDat [32];
1129
 
1130
            __hex2mem (ptr, dummyDat, REGSIZE (x), 0);
1131
            put_register_as_bytes (x, dummyDat);
1132
        } else
1133
#endif
1134
        {
1135
            vptr = ((char *) &value);
1136
#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN)
1137
            vptr += sizeof (value) - REGSIZE (x);
1138
#endif
1139
            __hex2mem (ptr, vptr, REGSIZE (x), 0);
1140
            put_register (x, value);
1141
        }
1142
        ptr += REGSIZE (x) * 2;
1143
    }
1144
 
1145
    strcpy (out_ptr, "OK");
1146
}
1147
 
1148
int
1149
__process_packet (char *packet)
1150
{
1151
  int  is_binary = 0;
1152
#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE)
1153
  int is_Z = 0;
1154
#endif
1155
 
1156
  __remcomOutBuffer[0] = 0;
1157
  switch (packet[0])
1158
    {
1159
    case '?':
1160
      {
1161
        int sigval = __computeSignal (__get_trap_number ());
1162
        __remcomOutBuffer[0] = 'S';
1163
        __remcomOutBuffer[1] = hexchars[(sigval >> 4) & 0xf];
1164
        __remcomOutBuffer[2] = hexchars[sigval & 0xf];
1165
        __remcomOutBuffer[3] = 0;
1166
        break;
1167
      }
1168
 
1169
#ifdef __ECOS__
1170
#if !defined(CYG_HAL_STARTUP_RAM)    // Only for ROM based stubs
1171
#if 0 // Disable to avoid conflict with stub-breakpoint z/Z-packets
1172
    case 'z':
1173
        /* report IO buffer sizes so download can achieve optimal
1174
           download speed */
1175
    {
1176
        int i;
1177
        i = __intToHex (__remcomOutBuffer, BUFMAX, 32);
1178
        __remcomOutBuffer[i] = 0;
1179
        break;
1180
    }
1181
#endif
1182
    case 'd':
1183
      /* toggle debug flag */
1184
      strcpy(__remcomOutBuffer, GDB_stubs_version);
1185
      break;
1186
#endif
1187
#endif // __ECOS__
1188
 
1189
    case 'q':
1190
      /* general query packet */
1191
      process_query (&packet[1]);
1192
      break;
1193
 
1194
    case 'Q':
1195
      /* general set packet */
1196
      process_set (&packet[1]);
1197
      break;
1198
 
1199
    case 'p':           /* return the value of  a single CPU register */
1200
    case 'g':           /* return the value of the CPU registers */
1201
      {
1202
        stub_format_registers(&packet[0], __remcomOutBuffer);
1203
        break;
1204
      }
1205
 
1206
    case 'A': /* set program arguments */
1207
      {
1208
#ifdef CYGSEM_ECOS_SUPPORTS_PROGRAM_ARGS
1209
        if (packet[1] == '\0')
1210
          {
1211
            __free_program_args ();
1212
            strcpy (__remcomOutBuffer, "OK");
1213
          }
1214
        else
1215
          {
1216
            target_register_t arglen, argnum;
1217
            char *ptr = &packet[1];
1218
 
1219
            while (1)
1220
              {
1221
                if (__hexToInt (&ptr, &arglen)
1222
                    && (*ptr++ == ',')
1223
                    && __hexToInt (&ptr, &argnum)
1224
                    && (*ptr++ == ','))
1225
                  {
1226
                    if (arglen > 0)
1227
                      {
1228
                        char *s = __add_program_arg (argnum, arglen);
1229
                        if (s != NULL)
1230
                          {
1231
                            __hex2mem (ptr, s, arglen, 0);
1232
                          }
1233
                        ptr += arglen * 2;
1234
                      }
1235
 
1236
                    if (*ptr == ',')
1237
                      ptr++;
1238
                    else
1239
                      break;
1240
                  }
1241
                else
1242
                  break;
1243
              }
1244
            if (*ptr == '\0')
1245
              strcpy (__remcomOutBuffer, "OK");
1246
            else
1247
              strcpy (__remcomOutBuffer, "E01");
1248
          }
1249
#else
1250
        strcpy (__remcomOutBuffer, "E01");
1251
#endif
1252
      }
1253
      break;
1254
 
1255
    case 'P':
1256
    case 'G':      /* set the value of the CPU registers - return OK */
1257
      {
1258
        char *in_ptr = &packet[0];
1259
        char *out_ptr = __remcomOutBuffer;
1260
        stub_update_registers(in_ptr, out_ptr);
1261
        break;
1262
      }
1263
 
1264
    case 'm':     /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
1265
      /* Try to read %x,%x.  */
1266
      {
1267
        target_register_t length;
1268
        char *ptr = &packet[1];
1269
        target_addr_t addr;
1270
 
1271
        if (__hexToAddr (&ptr, &addr)
1272
            && *ptr++ == ','
1273
            && __hexToInt (&ptr, &length))
1274
          {
1275
            if (__mem2hex_safe (addr, __remcomOutBuffer, length))
1276
              break;
1277
 
1278
            strcpy (__remcomOutBuffer, "E03");
1279
          }
1280
        else
1281
          strcpy (__remcomOutBuffer, "E01");
1282
        break;
1283
      }
1284
 
1285
    case 'X':
1286
      /* XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA */
1287
      is_binary = 1;
1288
      /* fall through */
1289
    case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
1290
      /* Try to read '%x,%x:'.  */
1291
      {
1292
        target_register_t length;
1293
        char *ptr = &packet[1], buf[128];
1294
        int  i;
1295
        target_addr_t addr;
1296
 
1297
        if (__hexToAddr (&ptr, &addr)
1298
            && *ptr++ == ','
1299
            && __hexToInt (&ptr, &length)
1300
            && *ptr++ == ':')
1301
          {
1302
            /* GDB sometimes sends an impossible length */
1303
            if (length < 0 || length >= BUFMAX)
1304
              strcpy (__remcomOutBuffer, "E01");
1305
 
1306
            else if (is_binary)
1307
              {
1308
                while (length > 0)
1309
                  {
1310
                    for (i = 0; i < sizeof(buf) && i < length; i++)
1311
                      if ((buf[i] = *ptr++) == 0x7d)
1312
                        buf[i] = 0x20 | (*ptr++ & 0xff);
1313
 
1314
#ifdef TARGET_HAS_HARVARD_MEMORY
1315
                    if (TARGET_ADDR_IS_PROGMEM(addr)) {
1316
                      if (__write_progmem_safe (buf, (void *)TARGET_ADDR_TO_PTR(addr), i) != i)
1317
                        break;
1318
                    } else
1319
#endif
1320
                      if (__write_mem_safe (buf, (void *)TARGET_ADDR_TO_PTR(addr), i) != i)
1321
                        break;
1322
 
1323
 
1324
                    length -= i;
1325
                    addr += i;
1326
                  }
1327
                if (length <= 0)
1328
                  strcpy (__remcomOutBuffer, "OK");
1329
                else
1330
                  strcpy (__remcomOutBuffer, "E03");
1331
              }
1332
            else
1333
              {
1334
                if (__hex2mem_safe (ptr, addr, length) != NULL)
1335
                  strcpy (__remcomOutBuffer, "OK");
1336
                else
1337
                  strcpy (__remcomOutBuffer, "E03");
1338
              }
1339
          }
1340
        else
1341
          strcpy (__remcomOutBuffer, "E02");
1342
        break;
1343
      }
1344
 
1345
    case 'S':
1346
    case 's':    /* sAA..AA    Step from address AA..AA (optional) */
1347
    case 'C':
1348
    case 'c':    /* cAA..AA    Continue at address AA..AA (optional) */
1349
      /* try to read optional parameter, pc unchanged if no parm */
1350
 
1351
      {
1352
        char *ptr = &packet[1];
1353
        target_addr_t addr;
1354
        target_register_t sigval = 0;
1355
 
1356
        if (packet[0] == 'C' || packet[0] == 'S')
1357
          {
1358
            __hexToInt (&ptr, &sigval);
1359
            if (*ptr == ';')
1360
              ptr++;
1361
          }
1362
 
1363
        if (__hexToAddr (&ptr, &addr))
1364
          set_pc ((target_register_t)TARGET_ADDR_TO_PTR(addr));
1365
 
1366
      /* Need to flush the instruction cache here, as we may have
1367
         deposited a breakpoint, and the icache probably has no way of
1368
         knowing that a data ref to some location may have changed
1369
         something that is in the instruction cache.  */
1370
 
1371
#ifdef __ECOS__
1372
        __data_cache (CACHE_FLUSH) ;
1373
#endif
1374
        __instruction_cache (CACHE_FLUSH) ;
1375
 
1376
        /* If we have a function to handle signals, call it. */
1377
        if (sigval != 0 && __process_signal_vec != NULL)
1378
          {
1379
            /* If 0 is returned, we either ignored the signal or invoked a user
1380
               handler. Otherwise, the user program should die. */
1381
            if (! __process_signal_vec (sigval))
1382
              sigval = 0;
1383
          }
1384
 
1385
        if (sigval != 0)
1386
          {
1387
            sigval = SIGKILL; /* Always nuke the program */
1388
            __kill_program (sigval);
1389
            return 0;
1390
          }
1391
 
1392
#ifdef __ECOS__
1393
        // CASE 102327 - watchpoints fight with output, so do not step
1394
        // through $O packet output routines.
1395
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
1396
        if ( cyg_hal_gdb_break_is_set() ) {
1397
            packet[0] = 'c'; // Force it to be a "continue" instead of step.
1398
            cyg_hal_gdb_running_step = 1; // And tell the hal_stub...
1399
        }
1400
#endif
1401
#endif
1402
 
1403
        /* Set machine state to force a single step.  */
1404
        if (packet[0] == 's' || packet[0] == 'S')
1405
          {
1406
            lock_thread_scheduler (0);  /* 0 == single-step */
1407
#ifdef __ECOS__
1408
            // PR 19845 workaround:
1409
            // Make sure the single-step magic affects the correct registers.
1410
            _registers = &registers[0];
1411
#endif
1412
            __single_step ();
1413
          }
1414
        else
1415
          {
1416
            lock_thread_scheduler (1);  /* 1 == continue */
1417
          }
1418
 
1419
#ifdef __ECOS__
1420
      /* Need to flush the data and instruction cache here, as we may have
1421
         deposited a breakpoint in __single_step. */
1422
 
1423
        __data_cache (CACHE_FLUSH) ;
1424
        __instruction_cache (CACHE_FLUSH) ;
1425
        hal_flush_output();
1426
#endif
1427
 
1428
        return -1;
1429
      }
1430
 
1431
    case 'D' :     /* detach */
1432
      __putpacket (__remcomOutBuffer);
1433
      /* fall through */
1434
    case 'k' :      /* kill the program */
1435
#ifdef __ECOS__
1436
      hal_flush_output();
1437
#endif
1438
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
1439
      {   // Reset the timer to default and cancel any callback
1440
          extern void sys_profile_reset(void);
1441
          sys_profile_reset();
1442
      }
1443
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
1444
      __process_exit_vec ();
1445
      return -1;
1446
 
1447
    case 'r':           /* Reset */
1448
      /* With the next 'k' packet, reset the board */
1449
      __process_exit_vec = &__reset;
1450
      break;
1451
 
1452
    case 'H':
1453
      STUB_PKT_CHANGETHREAD (packet+1, __remcomOutBuffer, 300) ;
1454
      break ;
1455
    case 'T' :
1456
      STUB_PKT_THREAD_ALIVE (packet+1, __remcomOutBuffer, 300) ;
1457
      break ;
1458
    case 'B':
1459
      /* breakpoint */
1460
      {
1461
        target_register_t addr;
1462
        char mode;
1463
        char *ptr = &packet[1];
1464
        if (__hexToInt (&ptr, &addr) && *(ptr++) == ',')
1465
          {
1466
            mode = *(ptr++);
1467
            if (mode == 'C')
1468
              __remove_breakpoint (addr,0);
1469
            else
1470
              __set_breakpoint (addr,0);
1471
            strcpy (__remcomOutBuffer, "OK");
1472
          }
1473
        else
1474
          {
1475
            strcpy (__remcomOutBuffer, "E01");
1476
          }
1477
        break;
1478
      }
1479
 
1480
      case 'b':   /* bBB...  Set baud rate to BB... */
1481
      {
1482
        target_register_t baudrate;
1483
 
1484
        char *ptr = &packet[1];
1485
        if (!__hexToInt (&ptr, &baudrate))
1486
          {
1487
            strcpy (__remcomOutBuffer, "B01");
1488
            break;
1489
          }
1490
 
1491
        __putpacket ("OK");     /* Ack before changing speed */
1492
        __set_baud_rate (baudrate);
1493
        break;
1494
      }
1495
 
1496
#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)
1497
    case 'Z':
1498
      is_Z = 1;
1499
    case 'z':
1500
      {
1501
        char *ptr = &packet[1];
1502
        target_register_t ztype, addr, length;
1503
        int err;
1504
        target_addr_t taddr;
1505
 
1506
        if (__hexToInt (&ptr, &ztype) && *(ptr++) == ',')
1507
          {
1508
            if (__hexToAddr (&ptr, &taddr))
1509
              {
1510
                if (*(ptr++) == ',')
1511
                  {
1512
                      /* When there is a comma, there must be a length */
1513
                      if  (!__hexToInt (&ptr, &length))
1514
                        {
1515
                          strcpy (__remcomOutBuffer, "E02");
1516
                          break;
1517
                        }
1518
                  }
1519
                else
1520
                  length = 0;
1521
 
1522
                addr = (target_register_t)TARGET_ADDR_TO_PTR(taddr);
1523
 
1524
                switch (ztype)
1525
                  {
1526
                    case ZTYPE_SW_BREAKPOINT:
1527
                      /* sw breakpoint */
1528
                      if (is_Z)
1529
                        err = __set_breakpoint(addr,length);
1530
                      else
1531
                        err = __remove_breakpoint(addr,length);
1532
                      if (!err)
1533
                        strcpy (__remcomOutBuffer, "OK");
1534
                      else
1535
                        strcpy (__remcomOutBuffer, "E02");
1536
                      break;
1537
                    case ZTYPE_HW_BREAKPOINT:
1538
#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
1539
                      if (is_Z)
1540
                        err = __set_hw_breakpoint(addr, length);
1541
                      else
1542
                        err = __remove_hw_breakpoint(addr, length);
1543
                      if (!err)
1544
                        strcpy (__remcomOutBuffer, "OK");
1545
                      else
1546
#endif
1547
                        strcpy (__remcomOutBuffer, "E02");
1548
                      break;
1549
                    case ZTYPE_HW_WATCHPOINT_WRITE:
1550
                    case ZTYPE_HW_WATCHPOINT_READ:
1551
                    case ZTYPE_HW_WATCHPOINT_ACCESS:
1552
#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
1553
                      if (is_Z)
1554
                        err = __set_hw_watchpoint(addr, length, ztype);
1555
                      else
1556
                        err = __remove_hw_watchpoint(addr, length, ztype);
1557
                      if (!err)
1558
                        strcpy (__remcomOutBuffer, "OK");
1559
                      else
1560
#endif
1561
                        strcpy (__remcomOutBuffer, "E02");
1562
                      break;
1563
                  }
1564
              }
1565
          }
1566
        break;
1567
      }
1568
#endif // Z packet support
1569
#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
1570
    case 'F':
1571
    {
1572
        extern void cyg_hal_gdbfileio_process_F_packet( char *, char *);
1573
        cyg_hal_gdbfileio_process_F_packet( packet, __remcomOutBuffer );
1574
        return -1;
1575
    }
1576
#endif
1577
    default:
1578
      __process_target_packet (packet, __remcomOutBuffer, 300);
1579
      break;
1580
    }
1581
 
1582
  /* reply to the request */
1583
  __putpacket (__remcomOutBuffer);
1584
  return 0;
1585
}
1586
 
1587
static void
1588
send_t_packet (int sigval)
1589
{
1590
  __build_t_packet (sigval, __remcomOutBuffer);
1591
  __putpacket (__remcomOutBuffer);
1592
}
1593
 
1594
/*
1595
 * This function does all command procesing for interfacing to gdb.
1596
 */
1597
 
1598
static int
1599
process_exception (int sigval)
1600
{
1601
  int status;
1602
 
1603
  /* Nasty. */
1604
  if (ungot_char < 0)
1605
    send_t_packet (sigval);
1606
 
1607
  do {
1608
    __getpacket (__remcomInBuffer);
1609
    status = __process_packet (__remcomInBuffer);
1610
  } while (status == 0);
1611
 
1612
  if (status < 0)
1613
    return 0;
1614
  else
1615
    return 1;
1616
}
1617
 
1618
void
1619
__send_exit_status (int status)
1620
{
1621
  __remcomOutBuffer[0] = 'W';
1622
  __remcomOutBuffer[1] = hexchars[(status >> 4) & 0xf];
1623
  __remcomOutBuffer[2] = hexchars[status & 0xf];
1624
  __remcomOutBuffer[3] = 0;
1625
  __putpacket (__remcomOutBuffer);
1626
}
1627
 
1628
/* Read up to MAXLEN bytes from the remote GDB client, and store in DEST
1629
   (which is a pointer in the user program). BLOCK indicates what mode
1630
   is being used; if it is set, we will wait for MAXLEN bytes to be
1631
   entered. Otherwise, the function will return immediately with whatever
1632
   bytes are waiting to be read.
1633
 
1634
   The value returned is the number of bytes read. A -1 indicates that an
1635
   error of some sort occurred. */
1636
 
1637
int
1638
__get_gdb_input (target_register_t dest, int maxlen, int block)
1639
{
1640
  char buf[4];
1641
  int len, i;
1642
  char d;
1643
 
1644
  buf[0] = 'I';
1645
  buf[1] = '0';
1646
  buf[2] = block ? '0' : '1';
1647
  buf[3] = 0;
1648
  __putpacket (buf);
1649
  __getpacket (__remcomInBuffer);
1650
  if (__remcomInBuffer[0] != 'I')
1651
    return -1;
1652
  len = stubhex (__remcomInBuffer[1]) * 16 + stubhex (__remcomInBuffer[2]);
1653
  for (i = 0; i < len; i++)
1654
    {
1655
      d = stubhex (__remcomInBuffer[3 + i * 2]) * 16;
1656
      d |=  stubhex (__remcomInBuffer[3 + i * 2 + 1]);
1657
      __write_mem_safe (&d, (void *)(dest + i), 1);
1658
    }
1659
  /* Write the trailing \0. */
1660
  d = '\0';
1661
  __write_mem_safe (&d, (void *)(dest + i), 1);
1662
  return len;
1663
}
1664
 
1665
void
1666
__output_hex_value (target_register_t i)
1667
{
1668
  char buf[32], *ptr=buf+31;
1669
  unsigned int x;
1670
 
1671
  *ptr = 0;
1672
  for (x = 0; x < (sizeof (i) * 2); x++)
1673
    {
1674
      *(--ptr) = hexchars[i & 15];
1675
      i = i >> 4;
1676
    }
1677
  while (*ptr)
1678
    {
1679
      putDebugChar (*(ptr++));
1680
    }
1681
}
1682
 
1683
/* Write the C-style string pointed to by STR to the GDB comm port. */
1684
void
1685
__putDebugStr (char *str)
1686
{
1687
  while (*str)
1688
    {
1689
      putDebugChar (*str);
1690
      str++;
1691
    }
1692
}
1693
 
1694
/* Send STRING_LEN bytes of STR to GDB, using 'O' packets.
1695
   STR is assumed to be in the program being debugged. */
1696
 
1697
int
1698
__output_gdb_string (target_register_t str, int string_len)
1699
{
1700
  /* We will arbitrarily limit output packets to less than 400 bytes. */
1701
  static char buf[400];
1702
  int x;
1703
  int len;
1704
 
1705
  if (string_len == 0)
1706
    {
1707
      /* We can't do strlen on a user pointer. */
1708
      return -1;
1709
    }
1710
 
1711
  len = string_len;
1712
  while (len > 0)
1713
    {
1714
      int packetlen = ((len < 175) ? len : 175);
1715
      buf[0] = 'O';
1716
      for (x = 0; x < packetlen; x++)
1717
        {
1718
          char c;
1719
 
1720
          __read_mem_safe (&c, (void *)(str + x), 1);
1721
          buf[x*2+1] = hexchars[(c >> 4) & 0xf];
1722
          buf[x*2+2] = hexchars[c % 16];
1723
        }
1724
      str += x;
1725
      len -= x;
1726
      buf[x*2+1] = 0;
1727
      __putpacket (buf);
1728
    }
1729
  return string_len;
1730
}
1731
 
1732
static void
1733
do_nothing (void)
1734
{
1735
  /* mmmm */
1736
}
1737
 
1738
static int
1739
syscall_do_nothing (int junk)
1740
{
1741
  return 0;
1742
}
1743
 
1744
/* Start the stub running. */
1745
void
1746
__switch_to_stub (void)
1747
{
1748
  __process_exception_vec = process_exception;
1749
#ifdef CYGPKG_CYGMON
1750
  // Cygmon will have consumed the '$' character for this packet.
1751
  // Let's put one in the unget buffer.
1752
  // Actually, Cygmon does an unget, but since it uses different
1753
  // unget handling, we need to do this here.
1754
  ungetDebugChar('$');
1755
#endif
1756
}
1757
 
1758
#if ! defined(BOARD_SPECIFIC_STUB_INIT)
1759
void
1760
initialize_stub (void)
1761
{
1762
  set_debug_traps ();
1763
  /* FIXME: This function should be renamed to specifically init the
1764
     hardware required by debug operations. If initHardware is implemented at
1765
     all, it should be called before main ().
1766
     */
1767
  initHardware () ;
1768
  /* This acks any stale packets , NOT an effective solution */
1769
  putDebugChar ('+');
1770
}
1771
#endif
1772
 
1773
void
1774
ungetDebugChar (int c)
1775
{
1776
  ungot_char = c;
1777
}
1778
 
1779
void
1780
__kill_program (int sigval)
1781
{
1782
  __remcomOutBuffer[0] = 'X';
1783
  __remcomOutBuffer[1] = hexchars[(sigval >> 4) & 15];
1784
  __remcomOutBuffer[2] = hexchars[sigval & 15];
1785
  __remcomOutBuffer[3] = 0;
1786
  __putpacket (__remcomOutBuffer);
1787
}
1788
 
1789
#define MAX_ARG_COUNT 20
1790
#define MAX_ARGDATA 128
1791
 
1792
static char *program_argv [MAX_ARG_COUNT];
1793
static int program_argc;
1794
static int last_program_arg;
1795
static char program_argstr [MAX_ARGDATA], *argptr;
1796
static int args_initted = 0;
1797
 
1798
void
1799
__free_program_args (void)
1800
{
1801
  last_program_arg = -1;
1802
  program_argc = 0;
1803
  program_argv [0] = NULL;
1804
  argptr = program_argstr;
1805
  args_initted = 1;
1806
}
1807
 
1808
static char *
1809
__add_program_arg (int argc, uint32 len)
1810
{
1811
  char *res;
1812
 
1813
  if (! args_initted)
1814
    {
1815
      __free_program_args ();
1816
    }
1817
 
1818
  if ((argc >= (MAX_ARG_COUNT - 1))
1819
      || ((argptr - program_argstr + len) > MAX_ARGDATA))
1820
    {
1821
      return NULL;
1822
    }
1823
 
1824
  if (argc != last_program_arg)
1825
    {
1826
      if (argc >= program_argc)
1827
        {
1828
          program_argc = argc + 1;
1829
          program_argv [program_argc] = NULL;
1830
        }
1831
      program_argv [argc] = argptr;
1832
      last_program_arg = argc;
1833
    }
1834
 
1835
  res = argptr;
1836
  argptr += len;
1837
 
1838
  return res;
1839
}
1840
 
1841
void
1842
__set_program_args (int argc, char **argv)
1843
{
1844
  int x;
1845
 
1846
  __free_program_args ();
1847
  if (argc)
1848
    {
1849
      for (x = 0; x < argc; x++)
1850
        {
1851
          uint32 len = strlen (argv[x])+1;
1852
          char *s = __add_program_arg (x, len);
1853
 
1854
          if (s == NULL)
1855
            return;
1856
 
1857
          _memcpy (s, argv[x], len);
1858
        }
1859
    }
1860
}
1861
 
1862
char **
1863
__get_program_args (target_register_t argcPtr)
1864
{
1865
  if (!args_initted)
1866
    {
1867
      __free_program_args ();
1868
    }
1869
  __write_mem_safe ((char *) &program_argc, (void *)argcPtr, sizeof (program_argc));
1870
  return program_argv;
1871
}
1872
 
1873
/* Table used by the crc32 function to calcuate the checksum. */
1874
static uint32 crc32_table[256];
1875
static int tableInit = 0;
1876
 
1877
/*
1878
   Calculate a CRC-32 using LEN bytes of PTR. CRC is the initial CRC
1879
   value.
1880
   PTR is assumed to be a pointer in the user program. */
1881
 
1882
static uint32
1883
crc32 (target_addr_t mem, int len, uint32 crc)
1884
{
1885
  unsigned char *ptr = (unsigned char *)TARGET_ADDR_TO_PTR(mem);
1886
#ifdef TARGET_HAS_HARVARD_MEMORY
1887
  int  is_progmem = TARGET_ADDR_IS_PROGMEM(mem);
1888
#endif
1889
 
1890
  if (! tableInit)
1891
    {
1892
      /* Initialize the CRC table and the decoding table. */
1893
      uint32 i, j;
1894
      uint32 c;
1895
 
1896
      tableInit = 1;
1897
      for (i = 0; i < 256; i++)
1898
        {
1899
          for (c = i << 24, j = 8; j > 0; --j)
1900
            c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
1901
          crc32_table[i] = c;
1902
        }
1903
    }
1904
 
1905
  __mem_fault = 0;
1906
  while (len--)
1907
    {
1908
      unsigned char ch;
1909
 
1910
#ifdef TARGET_HAS_HARVARD_MEMORY
1911
      if (is_progmem)
1912
          __read_progmem_safe (&ch, (void *)ptr, 1);
1913
      else
1914
#endif
1915
      __read_mem_safe (&ch, (void *)ptr, 1);
1916
      if (__mem_fault)
1917
        {
1918
          break;
1919
        }
1920
      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ ch) & 255];
1921
      ptr++;
1922
    }
1923
  return crc;
1924
}
1925
 
1926
/* Handle the 'q' request */
1927
 
1928
static void
1929
process_query (char *pkt)
1930
{
1931
  __remcomOutBuffer[0] = '\0';
1932
#ifdef __ECOS__
1933
  if ('C' == pkt[0] &&
1934
      'R' == pkt[1] &&
1935
      'C' == pkt[2] &&
1936
      ':' == pkt[3])
1937
#else  // __ECOS__
1938
  if (strncmp (pkt, "CRC:", 4) == 0)
1939
#endif // __ECOS__
1940
    {
1941
      target_addr_t startmem;
1942
      target_register_t length;
1943
      uint32 our_crc;
1944
 
1945
      pkt += 4;
1946
      if (__hexToAddr (&pkt, &startmem)
1947
          && *(pkt++) == ','
1948
          && __hexToInt (&pkt, &length))
1949
        {
1950
          our_crc = crc32 (startmem, length, 0xffffffff);
1951
          if (__mem_fault)
1952
            {
1953
              strcpy (__remcomOutBuffer, "E01");
1954
            }
1955
          else
1956
            {
1957
              int numb = __intToHex (__remcomOutBuffer + 1, our_crc, 32);
1958
              __remcomOutBuffer[0] = 'C';
1959
              __remcomOutBuffer[numb + 1] = 0;
1960
            }
1961
        }
1962
      return;
1963
    }
1964
#ifdef CYG_HAL_STUB_PROCESS_QUERY
1965
  else if (CYG_HAL_STUB_PROCESS_QUERY (pkt, __remcomOutBuffer, sizeof(__remcomOutBuffer)))
1966
    return;
1967
#endif
1968
  else
1969
    {
1970
      char ch ;
1971
      char * subpkt ;
1972
      ch = *pkt ;
1973
      subpkt = pkt + 1 ;
1974
      switch (ch)
1975
        {
1976
        case 'L' : /* threadlistquery */
1977
          STUB_PKT_GETTHREADLIST (subpkt, __remcomOutBuffer, 300);
1978
          break ;
1979
        case 'P' : /* Thread or process information request */
1980
          STUB_PKT_GETTHREADINFO (subpkt, __remcomOutBuffer, 300);
1981
          break ;
1982
        case 'C' : /* current thread query */
1983
          STUB_PKT_CURRTHREAD(subpkt, __remcomOutBuffer, sizeof(__remcomOutBuffer));
1984
          break;
1985
        default:
1986
          __process_target_query (pkt, __remcomOutBuffer, 300);
1987
          break ;
1988
        }
1989
    }
1990
}
1991
 
1992
/* Handle the 'Q' request */
1993
 
1994
static void
1995
process_set (char *pkt)
1996
{
1997
  char ch ;
1998
 
1999
#ifdef CYG_HAL_STUB_PROCESS_SET
2000
  if (CYG_HAL_STUB_PROCESS_SET (pkt, __remcomOutBuffer, sizeof(__remcomOutBuffer)))
2001
    return;
2002
#endif
2003
 
2004
  ch = *pkt ;
2005
  switch (ch)
2006
    {
2007
    case 'p' : /* Set current process or thread */
2008
      /* reserve the packet id even if support is not present */
2009
      /* Dont strip the 'p' off the header, there are several variations of
2010
         this packet */
2011
      STUB_PKT_CHANGETHREAD (pkt, __remcomOutBuffer, 300) ;
2012
      break ;
2013
    default:
2014
      __process_target_set (pkt, __remcomOutBuffer, 300);
2015
      break ;
2016
    }
2017
}
2018
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.