OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [libgloss/] [m68k/] [mvme-stub.c] - Blame information for rev 410

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

Line No. Rev Author Line
1 148 jeremybenn
unsigned long sp_ptr;
2
unsigned long pc_ptr;
3
int cnt;
4
#define UNWIND asm ("movel %/sp, %0" : "=g" (sp_ptr));\
5
    printf ("\n\t\t== Starting at 0x%x ==\n", sp_ptr);\
6
    for (cnt=4; cnt <=32; cnt+=4) {\
7
      printf ("+%d(0x%x): 0x%x\t\t-%d(0x%x): 0x%x\n",\
8
              cnt, (sp_ptr + cnt), *(unsigned long *)(sp_ptr + cnt),\
9
              cnt, (sp_ptr - cnt), *(unsigned long *)(sp_ptr - cnt)\
10
              ); }; fflush (stdout);
11
 
12
/****************************************************************************
13
 
14
                THIS SOFTWARE IS NOT COPYRIGHTED
15
 
16
   HP offers the following for use in the public domain.  HP makes no
17
   warranty with regard to the software or it's performance and the
18
   user accepts the software "AS IS" with all faults.
19
 
20
   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
21
   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23
 
24
****************************************************************************/
25
 
26
/****************************************************************************
27
 *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
28
 *
29
 *  Module name: remcom.c $
30
 *  Revision: 1.34 $
31
 *  Date: 91/03/09 12:29:49 $
32
 *  Contributor:     Lake Stevens Instrument Division$
33
 *
34
 *  Description:     low level support for gdb debugger. $
35
 *
36
 *  Considerations:  only works on target hardware $
37
 *
38
 *  Written by:      Glenn Engel $
39
 *  ModuleState:     Experimental $
40
 *
41
 *  NOTES:           See Below $
42
 *
43
 *  To enable debugger support, two things need to happen.  One, a
44
 *  call to set_debug_traps() is necessary in order to allow any breakpoints
45
 *  or error conditions to be properly intercepted and reported to gdb.
46
 *  Two, a breakpoint needs to be generated to begin communication.  This
47
 *  is most easily accomplished by a call to breakpoint().  Breakpoint()
48
 *  simulates a breakpoint by executing a trap #1.
49
 *
50
 *  Some explanation is probably necessary to explain how exceptions are
51
 *  handled.  When an exception is encountered the 68000 pushes the current
52
 *  program counter and status register onto the supervisor stack and then
53
 *  transfers execution to a location specified in it's vector table.
54
 *  The handlers for the exception vectors are hardwired to jmp to an address
55
 *  given by the relation:  (exception - 256) * 6.  These are decending
56
 *  addresses starting from -6, -12, -18, ...  By allowing 6 bytes for
57
 *  each entry, a jsr, jmp, bsr, ... can be used to enter the exception
58
 *  handler.  Using a jsr to handle an exception has an added benefit of
59
 *  allowing a single handler to service several exceptions and use the
60
 *  return address as the key differentiation.  The vector number can be
61
 *  computed from the return address by [ exception = (addr + 1530) / 6 ].
62
 *  The sole purpose of the routine _catchException is to compute the
63
 *  exception number and push it on the stack in place of the return address.
64
 *  The external function exceptionHandler() is
65
 *  used to attach a specific handler to a specific 68k exception.
66
 *  For 68020 machines, the ability to have a return address around just
67
 *  so the vector can be determined is not necessary because the '020 pushes an
68
 *  extra word onto the stack containing the vector offset
69
 *
70
 *  Because gdb will sometimes write to the stack area to execute function
71
 *  calls, this program cannot rely on using the supervisor stack so it
72
 *  uses it's own stack area reserved in the int array remcomStack.
73
 *
74
 *************
75
 *
76
 *    The following gdb commands are supported:
77
 *
78
 * command          function                               Return value
79
 *
80
 *    g             return the value of the CPU registers  hex data or ENN
81
 *    G             set the value of the CPU registers     OK or ENN
82
 *
83
 *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
84
 *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
85
 *
86
 *    c             Resume at current address              SNN   ( signal NN)
87
 *    cAA..AA       Continue at address AA..AA             SNN
88
 *
89
 *    s             Step one instruction                   SNN
90
 *    sAA..AA       Step one instruction from AA..AA       SNN
91
 *
92
 *    k             kill
93
 *
94
 *    ?             What was the last sigval ?             SNN   (signal NN)
95
 *
96
 * All commands and responses are sent with a packet which includes a
97
 * checksum.  A packet consists of
98
 *
99
 * $<packet info>#<checksum>.
100
 *
101
 * where
102
 * <packet info> :: <characters representing the command or response>
103
 * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
104
 *
105
 * When a packet is received, it is first acknowledged with either '+' or '-'.
106
 * '+' indicates a successful transfer.  '-' indicates a failed transfer.
107
 *
108
 * Example:
109
 *
110
 * Host:                  Reply:
111
 * $m0,10#2a               +$00010203040506070809101112131415#42
112
 *
113
 ****************************************************************************/
114
 
115
#include <stdio.h>
116
#include <string.h>
117
#include <setjmp.h>
118
#include <_ansi.h>
119
 
120
/************************************************************************
121
 *
122
 * external low-level support routines
123
 */
124
typedef void (*ExceptionHook)(int);   /* pointer to function with int parm */
125
typedef void (*Function)();           /* pointer to a function */
126
 
127
extern int  putDebugChar();   /* write a single character      */
128
extern char getDebugChar();   /* read and return a single char */
129
 
130
ExceptionHook exceptionHook;  /* hook variable for errors/exceptions */
131
 
132
/************************/
133
/* FORWARD DECLARATIONS */
134
/************************/
135
/** static void initializeRemcomErrorFrame PARAMS ((void)); **/
136
static void _DEFUN_VOID (initializeRemcomErrorFrame);
137
 
138
/************************************************************************/
139
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
140
/* at least NUMREGBYTES*2 are needed for register packets */
141
#define BUFMAX 400
142
 
143
static char initialized;  /* boolean flag. != 0 means we've been initialized */
144
 
145
int     remote_debug = 0; /*** Robs Thu Sep 24 22:18:51 PDT 1992 ***/
146
/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
147
 
148
static const char hexchars[]="0123456789abcdef";
149
 
150
/* there are 180 bytes of registers on a 68020 w/68881      */
151
/* many of the fpa registers are 12 byte (96 bit) registers */
152
#define NUMREGBYTES 180
153
enum regnames {D0,D1,D2,D3,D4,D5,D6,D7,
154
               A0,A1,A2,A3,A4,A5,A6,A7,
155
               PS,PC,
156
               FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
157
               FPCONTROL,FPSTATUS,FPIADDR
158
              };
159
 
160
typedef struct FrameStruct
161
{
162
    struct FrameStruct  *previous;
163
    int       exceptionPC;      /* pc value when this frame created */
164
    int       exceptionVector;  /* cpu vector causing exception     */
165
    short     frameSize;        /* size of cpu frame in words       */
166
    short     sr;               /* for 68000, this not always sr    */
167
    int       pc;
168
    short     format;
169
    int       fsaveHeader;
170
    int       morejunk[0];        /* exception frame, fp save... */
171
} Frame;
172
 
173
#define FRAMESIZE 500
174
int   gdbFrameStack[FRAMESIZE];
175
Frame *lastFrame;
176
 
177
/*
178
 * these should not be static cuz they can be used outside this module
179
 */
180
int registers[NUMREGBYTES/4];
181
int superStack;
182
 
183
#define STACKSIZE 10000
184
int remcomStack[STACKSIZE/sizeof(int)];
185
int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
186
 
187
/*
188
 * In many cases, the system will want to continue exception processing
189
 * when a continue command is given.
190
 * oldExceptionHook is a function to invoke in this case.
191
 */
192
 
193
static ExceptionHook oldExceptionHook;
194
 
195
/* the size of the exception stack on the 68020 varies with the type of
196
 * exception.  The following table is the number of WORDS used
197
 * for each exception format.
198
 */
199
const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
200
 
201
/************* jump buffer used for setjmp/longjmp **************************/
202
jmp_buf remcomEnv;
203
 
204
#define BREAKPOINT() asm("   trap #1");
205
 
206
extern void _DEFUN_VOID (return_to_super);
207
extern void _DEFUN_VOID (return_to_user);
208
extern void _DEFUN_VOID (_catchException);
209
 
210
void _returnFromException( Frame *frame )
211
{
212
    /* if no passed in frame, use the last one */
213
    if (! frame)
214
    {
215
        frame = lastFrame;
216
        frame->frameSize = 4;
217
        frame->format = 0;
218
        frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/
219
    }
220
 
221
#ifndef mc68020
222
    /* a 68000 cannot use the internal info pushed onto a bus error
223
     * or address error frame when doing an RTE so don't put this info
224
     * onto the stack or the stack will creep every time this happens.
225
     */
226
    frame->frameSize=3;
227
#endif
228
 
229
    /* throw away any frames in the list after this frame */
230
    lastFrame = frame;
231
 
232
    frame->sr = registers[(int) PS];
233
    frame->pc = registers[(int) PC];
234
 
235
    if (registers[(int) PS] & 0x2000)
236
    {
237
        /* return to supervisor mode... */
238
        return_to_super();
239
    }
240
    else
241
    { /* return to user mode */
242
        return_to_user();
243
    }
244
}
245
 
246
int hex(ch)
247
char ch;
248
{
249
  if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
250
  if ((ch >= '0') && (ch <= '9')) return (ch-'0');
251
  if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
252
  return (-1);
253
}
254
 
255
 
256
/* scan for the sequence $<data>#<checksum>     */
257
void getpacket(buffer)
258
char * buffer;
259
{
260
  unsigned char checksum;
261
  unsigned char xmitcsum;
262
  int  i;
263
  int  count;
264
  char ch;
265
 
266
  if (remote_debug) {
267
    printf("\nGETPACKET: sr=0x%x, pc=0x%x, sp=0x%x\n",
268
           registers[ PS ],
269
           registers[ PC ],
270
           registers[ A7 ]
271
           ); fflush (stdout);
272
    UNWIND
273
  }
274
 
275
  do {
276
    /* wait around for the start character, ignore all other characters */
277
    while ((ch = getDebugChar()) != '$');
278
     checksum = 0;
279
    xmitcsum = -1;
280
 
281
    count = 0;
282
 
283
    /* now, read until a # or end of buffer is found */
284
    while (count < BUFMAX) {
285
      ch = getDebugChar();
286
      if (ch == '#') break;
287
      checksum = checksum + ch;
288
      buffer[count] = ch;
289
      count = count + 1;
290
      }
291
    buffer[count] = 0;
292
 
293
    if (ch == '#') {
294
      xmitcsum = hex(getDebugChar()) << 4;
295
      xmitcsum += hex(getDebugChar());
296
      if ((remote_debug ) && (checksum != xmitcsum)) {
297
        fprintf(stderr,"bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
298
                                                     checksum,xmitcsum,buffer);
299
      }
300
 
301
      if (checksum != xmitcsum) putDebugChar('-');  /* failed checksum */
302
      else {
303
         putDebugChar('+');  /* successful transfer */
304
         /* if a sequence char is present, reply the sequence ID */
305
         if (buffer[2] == ':') {
306
            putDebugChar( buffer[0] );
307
            putDebugChar( buffer[1] );
308
            /* remove sequence chars from buffer */
309
            count = strlen(buffer);
310
            for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
311
         }
312
      }
313
    }
314
  } while (checksum != xmitcsum);
315
 
316
}
317
 
318
/* send the packet in buffer.  The host get's one chance to read it.
319
   This routine does not wait for a positive acknowledge.  */
320
 
321
void putpacket(buffer)
322
char * buffer;
323
{
324
  unsigned char checksum;
325
  int  count;
326
  char ch;
327
 
328
  /*  $<packet info>#<checksum>. */
329
  /***  do {***/
330
  putDebugChar('$');
331
  checksum = 0;
332
  count    = 0;
333
 
334
  while (ch=buffer[count]) {
335
    if (! putDebugChar(ch)) return;
336
    checksum += ch;
337
    count += 1;
338
  }
339
 
340
  putDebugChar('#');
341
  putDebugChar(hexchars[checksum >> 4]);
342
  putDebugChar(hexchars[checksum % 16]);
343
 
344
  if (remote_debug) {
345
    printf("\nPUTPACKET: sr=0x%x, pc=0x%x, sp=0x%x\n",
346
           registers[ PS ],
347
           registers[ PC ],
348
           registers[ A7 ]
349
           ); fflush (stdout);
350
    UNWIND
351
  }
352
 
353
/*** } while (getDebugChar() != '+'); ***/
354
/** } while (1 == 0);  (getDebugChar() != '+'); **/
355
 
356
}
357
 
358
char  remcomInBuffer[BUFMAX];
359
char  remcomOutBuffer[BUFMAX];
360
static short error;
361
 
362
 
363
void debug_error(format, parm)
364
char * format;
365
char * parm;
366
{
367
  if (remote_debug) fprintf(stderr,format,parm);
368
}
369
 
370
/* convert the memory pointed to by mem into hex, placing result in buf */
371
/* return a pointer to the last char put in buf (null) */
372
char* mem2hex(mem, buf, count)
373
char* mem;
374
char* buf;
375
int   count;
376
{
377
      int i;
378
      unsigned char ch;
379
      for (i=0;i<count;i++) {
380
          ch = *mem++;
381
          *buf++ = hexchars[ch >> 4];
382
          *buf++ = hexchars[ch % 16];
383
      }
384
      *buf = 0;
385
      return(buf);
386
}
387
 
388
/* convert the hex array pointed to by buf into binary to be placed in mem */
389
/* return a pointer to the character AFTER the last byte written */
390
char* hex2mem(buf, mem, count)
391
char* buf;
392
char* mem;
393
int   count;
394
{
395
      int i;
396
      unsigned char ch;
397
      for (i=0;i<count;i++) {
398
          ch = hex(*buf++) << 4;
399
          ch = ch + hex(*buf++);
400
          *mem++ = ch;
401
      }
402
      return(mem);
403
}
404
 
405
/* a bus error has occurred, perform a longjmp
406
   to return execution and allow handling of the error */
407
 
408
void handle_buserror()
409
{
410
  longjmp(remcomEnv,1);
411
}
412
 
413
/* this function takes the 68000 exception number and attempts to
414
   translate this number into a unix compatible signal value */
415
int computeSignal( exceptionVector )
416
int exceptionVector;
417
{
418
  int sigval;
419
  switch (exceptionVector) {
420
    case 2 : sigval = 10; break; /* bus error           */
421
    case 3 : sigval = 10; break; /* address error       */
422
    case 4 : sigval = 4;  break; /* illegal instruction */
423
    case 5 : sigval = 8;  break; /* zero divide         */
424
    case 6 : sigval = 16; break; /* chk instruction     */
425
    case 7 : sigval = 16; break; /* trapv instruction   */
426
    case 8 : sigval = 11; break; /* privilege violation */
427
    case 9 : sigval = 5;  break; /* trace trap          */
428
    case 10: sigval = 4;  break; /* line 1010 emulator  */
429
    case 11: sigval = 4;  break; /* line 1111 emulator  */
430
    case 13: sigval = 8;  break; /* floating point err  */
431
    case 31: sigval = 2;  break; /* interrupt           */
432
    case 33: sigval = 5;  break; /* breakpoint          */
433
    case 40: sigval = 8;  break; /* floating point err  */
434
    case 48: sigval = 8;  break; /* floating point err  */
435
    case 49: sigval = 8;  break; /* floating point err  */
436
    case 50: sigval = 8;  break; /* zero divide         */
437
    case 51: sigval = 8;  break; /* underflow           */
438
    case 52: sigval = 8;  break; /* operand error       */
439
    case 53: sigval = 8;  break; /* overflow            */
440
    case 54: sigval = 8;  break; /* NAN                 */
441
    default:
442
      sigval = 7;         /* "software generated"*/
443
  }
444
  return (sigval);
445
}
446
 
447
/**********************************************/
448
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
449
/* RETURN NUMBER OF CHARS PROCESSED           */
450
/**********************************************/
451
int hexToInt(char **ptr, int *intValue)
452
{
453
    int numChars = 0;
454
    int hexValue;
455
 
456
    *intValue = 0;
457
 
458
    while (**ptr)
459
    {
460
        hexValue = hex(**ptr);
461
        if (hexValue >=0)
462
        {
463
            *intValue = (*intValue <<4) | hexValue;
464
            numChars ++;
465
        }
466
        else
467
            break;
468
 
469
        (*ptr)++;
470
    }
471
 
472
    return (numChars);
473
}
474
 
475
/*
476
 * This function does all command procesing for interfacing to gdb.
477
 */
478
void handle_exception(int exceptionVector)
479
{
480
  int    sigval;
481
  int    addr, length;
482
  char * ptr;
483
  int    newPC;
484
  Frame  *frame;
485
 
486
  if (remote_debug)    printf("\nHANDLE_EXCEPTION: vector=%d, sr=0x%x, pc=0x%x, sp=0x%x\n",
487
                            exceptionVector,
488
                            registers[ PS ],
489
                            registers[ PC ],
490
                            registers[ A7 ]
491
                              ); fflush (stdout);
492
 
493
  /* reply to host that an exception has occurred */
494
  sigval = computeSignal( exceptionVector );
495
  remcomOutBuffer[0] = 'S';
496
  remcomOutBuffer[1] =  hexchars[sigval >> 4];
497
  remcomOutBuffer[2] =  hexchars[sigval % 16];
498
  remcomOutBuffer[3] = 0;
499
 
500
  putpacket(remcomOutBuffer);
501
 
502
  while (1==1) {
503
    error = 0;
504
    remcomOutBuffer[0] = 0;
505
    getpacket(remcomInBuffer);
506
    switch (remcomInBuffer[0]) {
507
      case '?' :   remcomOutBuffer[0] = 'S';
508
                   remcomOutBuffer[1] =  hexchars[sigval >> 4];
509
                   remcomOutBuffer[2] =  hexchars[sigval % 16];
510
                   remcomOutBuffer[3] = 0;
511
                 break;
512
      case 'd' : remote_debug = !(remote_debug);  /* toggle debug flag */
513
                 break;
514
      case 'g' : /* return the value of the CPU registers */
515
                mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES);
516
                break;
517
      case 'G' : /* set the value of the CPU registers - return OK */
518
                hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES);
519
                strcpy(remcomOutBuffer,"OK");
520
                break;
521
 
522
      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
523
      case 'm' :
524
                if (setjmp(remcomEnv) == 0)
525
                {
526
                    exceptionHandler(2,handle_buserror);
527
 
528
                    /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
529
                    ptr = &remcomInBuffer[1];
530
                    if (hexToInt(&ptr,&addr))
531
                        if (*(ptr++) == ',')
532
                            if (hexToInt(&ptr,&length))
533
                            {
534
                                ptr = 0;
535
                                mem2hex((char*) addr, remcomOutBuffer, length);
536
                            }
537
 
538
                    if (ptr)
539
                    {
540
                      strcpy(remcomOutBuffer,"E01");
541
                      debug_error("malformed read memory command: %s",remcomInBuffer);
542
                  }
543
                }
544
                else {
545
                  exceptionHandler(2,_catchException);
546
                  strcpy(remcomOutBuffer,"E03");
547
                  debug_error("bus error");
548
                  }
549
 
550
                /* restore handler for bus error */
551
                exceptionHandler(2,_catchException);
552
                break;
553
 
554
      /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
555
      case 'M' :
556
                if (setjmp(remcomEnv) == 0) {
557
                    exceptionHandler(2,handle_buserror);
558
 
559
                    /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
560
                    ptr = &remcomInBuffer[1];
561
                    if (hexToInt(&ptr,&addr))
562
                        if (*(ptr++) == ',')
563
                            if (hexToInt(&ptr,&length))
564
                                if (*(ptr++) == ':')
565
                                {
566
                                    hex2mem(ptr, (char*) addr, length);
567
                                    ptr = 0;
568
                                    strcpy(remcomOutBuffer,"OK");
569
                                }
570
                    if (ptr)
571
                    {
572
                      strcpy(remcomOutBuffer,"E02");
573
                      debug_error("malformed write memory command: %s",remcomInBuffer);
574
                      }
575
                }
576
                else {
577
                  exceptionHandler(2,_catchException);
578
                  strcpy(remcomOutBuffer,"E03");
579
                  debug_error("bus error");
580
                  }
581
 
582
                /* restore handler for bus error */
583
                exceptionHandler(2,_catchException);
584
                break;
585
 
586
     /* cAA..AA    Continue at address AA..AA(optional) */
587
     /* sAA..AA   Step one instruction from AA..AA(optional) */
588
     case 'c' :
589
     case 's' :
590
          /* try to read optional parameter, pc unchanged if no parm */
591
         ptr = &remcomInBuffer[1];
592
         if (hexToInt(&ptr,&addr))
593
             registers[ PC ] = addr;
594
 
595
          newPC = registers[ PC];
596
 
597
          /* clear the trace bit */
598
          registers[ PS ] &= 0x7fff;
599
 
600
          /* set the trace bit if we're stepping */
601
          if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000;
602
 
603
          /*
604
           * look for newPC in the linked list of exception frames.
605
           * if it is found, use the old frame it.  otherwise,
606
           * fake up a dummy frame in returnFromException().
607
           */
608
          if (remote_debug) printf("new pc = 0x%x\n",newPC);
609
          frame = lastFrame;
610
          while (frame)
611
          {
612
              if (remote_debug)
613
                  printf("frame at 0x%x has pc=0x%x, except#=%d\n",
614
                         frame,frame->exceptionPC,
615
                         frame->exceptionVector);
616
              if (frame->exceptionPC == newPC) break;  /* bingo! a match */
617
              /*
618
               * for a breakpoint instruction, the saved pc may
619
               * be off by two due to re-executing the instruction
620
               * replaced by the trap instruction.  Check for this.
621
               */
622
              if ((frame->exceptionVector == 33) &&
623
                  (frame->exceptionPC == (newPC+2))) break;
624
              if (frame == frame->previous)
625
              {
626
                  frame = 0; /* no match found */
627
                  break;
628
              }
629
              frame = frame->previous;
630
          }
631
 
632
          /*
633
           * If we found a match for the PC AND we are not returning
634
           * as a result of a breakpoint (33),
635
           * trace exception (9), nmi (31), jmp to
636
           * the old exception handler as if this code never ran.
637
           */
638
          if (frame)
639
          {
640
              if ((frame->exceptionVector != 9)  &&
641
                  (frame->exceptionVector != 31) &&
642
                  (frame->exceptionVector != 33))
643
              {
644
                  /*
645
                   * invoke the previous handler.
646
                   */
647
                  if (oldExceptionHook)
648
                      (*oldExceptionHook) (frame->exceptionVector);
649
                  newPC = registers[ PC ];    /* pc may have changed  */
650
                  if (newPC != frame->exceptionPC)
651
                  {
652
                      if (remote_debug)
653
                          printf("frame at 0x%x has pc=0x%x, except#=%d\n",
654
                                 frame,frame->exceptionPC,
655
                                 frame->exceptionVector);
656
                      /* re-use the last frame, we're skipping it (longjump?)*/
657
                      frame = (Frame *) 0;
658
                      _returnFromException( frame );  /* this is a jump */
659
                  }
660
              }
661
          }
662
 
663
          /* if we couldn't find a frame, create one */
664
          if (frame == 0)
665
          {
666
              frame = lastFrame -1 ;
667
 
668
              /* by using a bunch of print commands with breakpoints,
669
                 it's possible for the frame stack to creep down.  If it creeps
670
                 too far, give up and reset it to the top.  Normal use should
671
                 not see this happen.
672
              */
673
              if ((unsigned int) (frame-2) < (unsigned int) &gdbFrameStack)
674
              {
675
                 initializeRemcomErrorFrame();
676
                 frame = lastFrame;
677
              }
678
              frame->previous = lastFrame;
679
              lastFrame = frame;
680
              frame = 0;  /* null so _return... will properly initialize it */
681
          }
682
 
683
          _returnFromException( frame ); /* this is a jump */
684
 
685
          break;
686
 
687
      /* kill the program */
688
      case 'k' :  /* do nothing */
689
                break;
690
      } /* switch */
691
 
692
    /* reply to the request */
693
    putpacket(remcomOutBuffer);
694
    }
695
}
696
 
697
 
698
void initializeRemcomErrorFrame()
699
{
700
    lastFrame = ((Frame *) &gdbFrameStack[FRAMESIZE-1]) - 1;
701
    lastFrame->previous = lastFrame;
702
}
703
 
704
/* this function is used to set up exception handlers for tracing and
705
   breakpoints */
706
void set_debug_traps()
707
{
708
extern void _debug_level7();
709
extern void remcomHandler();
710
int exception;
711
 
712
  initializeRemcomErrorFrame();
713
  stackPtr  = &remcomStack[STACKSIZE/sizeof(int) - 1];
714
 
715
  setup_vectors();
716
 
717
  if (oldExceptionHook != remcomHandler)
718
  {
719
      oldExceptionHook = exceptionHook;
720
      exceptionHook    = remcomHandler;
721
  }
722
 
723
  initialized = 1;
724
 
725
}
726
/* This function will generate a breakpoint exception.  It is used at the
727
   beginning of a program to sync up with a debugger and can be used
728
   otherwise as a quick means to stop program execution and "break" into
729
   the debugger. */
730
 
731
void breakpoint()
732
{
733
  if (initialized) BREAKPOINT();
734
}

powered by: WebSVN 2.1.0

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