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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [m68k/] [efi68k/] [startup/] [m68k-stub.c] - Blame information for rev 773

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

Line No. Rev Author Line
1 30 unneback
/*  m68k-stub.c
2
 *
3
 *  $Id: m68k-stub.c,v 1.2 2001-09-27 12:00:03 chris Exp $
4
 */
5
 
6
#include <efi68k.h>
7
#include <rtems.h>
8
 
9
m68k_isr_entry set_vector(
10
  rtems_isr_entry     handler,
11
  rtems_vector_number vector,
12
  int                 type
13
);
14
 
15
 
16
void (*exceptionHook)() = 0;
17
 
18
void outbyte(char c);
19
char putDebugChar( char c)
20
{
21
  outbyte(c);
22
  return c;
23
}
24
 
25
char inbyte(void);
26
char getDebugChar(void)
27
{
28
  return inbyte();
29
}
30
 
31
void flush_i_cache(void)
32
{
33
  return;
34
}
35
 
36
void *memset(void *p, int c, int n)
37
{
38
  register int i;
39
  void *s=p;
40
 
41
  for (i=0;i<n;i++) *((char *)p)++=(char)c;
42
  return s;
43
}
44
 
45
char *db_strcpy(char *s, const char *t)
46
{
47
  char *save=s;
48
  while((*s++ = *t++) != '\0');
49
  return save;
50
}
51
 
52
int db_strlen(const char *s)
53
{
54
  int n;
55
 
56
  for (n=0; *s!='\0'; s++) n++;
57
  return n;
58
}
59
 
60
/************************************************************************
61
 *
62
 * external low-level support routines
63
 */
64
typedef void (*ExceptionHook)(int);   /* pointer to function with int parm */
65
typedef void (*Function)();           /* pointer to a function */
66
 
67
/* extern Function exceptionHandler(); */ /* assign an exception handler */
68
extern ExceptionHook exceptionHook;  /* hook variable for errors/exceptions */
69
/* extern void exceptionHandler(int vect, void (*function)()); */
70
 
71
/************************/
72
/* FORWARD DECLARATIONS */
73
/************************/
74
static void initializeRemcomErrorFrame();
75
 
76
/************************************************************************/
77
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
78
/* at least NUMREGBYTES*2 are needed for register packets */
79
#define BUFMAX 400
80
 
81
static char initialized;  /* boolean flag. != 0 means we've been initialized */
82
 
83
int     remote_debug;
84
/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
85
 
86
static const char hexchars[]="0123456789abcdef";
87
 
88
/* there are 180 bytes of registers on a 68020 w/68881      */
89
/* many of the fpa registers are 12 byte (96 bit) registers */
90
#define NUMREGBYTES 180
91
enum regnames {D0,D1,D2,D3,D4,D5,D6,D7,
92
               A0,A1,A2,A3,A4,A5,A6,A7,
93
               PS,PC,
94
               FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
95
               FPCONTROL,FPSTATUS,FPIADDR
96
              };
97
 
98
 
99
 
100
typedef struct FrameStruct
101
{
102
    struct FrameStruct  *previous;
103
    int       exceptionPC;      /* pc value when this frame created */
104
    int       exceptionVector;  /* cpu vector causing exception     */
105
    short     frameSize;        /* size of cpu frame in words       */
106
    short     sr;               /* for 68000, this not always sr    */
107
    int       pc;
108
    short     format;
109
    int       fsaveHeader;
110
    int       morejunk[0];        /* exception frame, fp save... */
111
} Frame;
112
 
113
#define FRAMESIZE 10
114
int   gdbFrameStack[FRAMESIZE];
115
static Frame *lastFrame;
116
 
117
/*
118
 * these should not be static cuz they can be used outside this module
119
 */
120
int registers[NUMREGBYTES/4];
121
int superStack;
122
 
123
#define STACKSIZE 600
124
int remcomStack[STACKSIZE/sizeof(int)];
125
static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
126
 
127
static ExceptionHook oldExceptionHook;
128
 
129
#define SAVE_FP_REGS()
130
#define RESTORE_FP_REGS()
131
 
132
void return_to_super();
133
void return_to_user();
134
 
135
asm("
136
.text
137
.align 2
138
.globl return_to_super
139
return_to_super:
140
        oriw    #0x0700,%sr
141
        movel   registers+60,%sp /* get new stack pointer */
142
        movel   lastFrame,%a0   /* get last frame info  */
143
        bra     return_to_any
144
 
145
.globl return_to_user
146
return_to_user:
147
        oriw    #0x0700,%sr
148
        movel   registers+60,%a0 /* get usp */
149
        movel   %a0,%usp           /* set usp */
150
        movel   superStack,%sp  /* get original stack pointer */
151
 
152
return_to_any:
153
        movel   lastFrame,%a0   /* get last frame info  */
154
        movel   %a0@+,lastFrame /* link in previous frame     */
155
        addql   #8,%a0           /* skip over pc, vector#*/
156
        movew   %a0@+,%d0         /* get # of words in cpu frame */
157
        addw    %d0,%a0           /* point to end of data        */
158
        addw    %d0,%a0           /* point to end of data        */
159
        movel   %a0,%a1
160
#
161
# copy the stack frame
162
        subql   #1,%d0
163
copyUserLoop:
164
        movew   %a1@-,%sp@-
165
        dbf     %d0,copyUserLoop
166
");
167
        RESTORE_FP_REGS()
168
   asm("   moveml  registers,%d0-%d7/%a0-%a6");
169
   asm("   rte");  /* pop and go! */
170
 
171
#define DISABLE_INTERRUPTS()   asm("         oriw   #0x0700,%sr");
172
#define BREAKPOINT() asm("   trap #1");
173
 
174
/* this function is called immediately when a level 7 interrupt occurs */
175
/* if the previous interrupt level was 7 then we're already servicing  */
176
/* this interrupt and an rte is in order to return to the debugger.    */
177
/* For the 68000, the offset for sr is 6 due to the jsr return address */
178
asm("
179
.text
180
.align 2
181
.globl _debug_level7
182
_debug_level7:
183
        movew   %d0,%sp@-");
184
asm("   movew   %sp@(6),%d0");
185
 
186
asm("   andiw   #0x700,%d0
187
        cmpiw   #0x700,%d0
188
        beq     already7
189
        movew   %sp@+,%d0
190
        bra     _catchException
191
already7:
192
        movew   %sp@+,%d0");
193
asm("   lea     %sp@(4),%sp");     /* pull off 68000 return address */
194
 
195
asm("   rte");
196
 
197
extern void _catchException ();
198
 
199
/* This function is called when an exception occurs.  It translates the
200
 * return address found on the stack into an exception vector # which
201
 * is then handled by either handle_exception or a system handler.
202
 * _catchException provides a front end for both.
203
 *
204
 * stack on entry:                       stack on exit:
205
 *   Program counter MSWord              exception # MSWord
206
 *   Program counter LSWord              exception # MSWord
207
 *   Status Register
208
 *   Return Address  MSWord
209
 *   Return Address  LSWord
210
 */
211
 
212
asm("
213
.text
214
.align 2
215
.globl _catchException
216
_catchException:
217
");
218
DISABLE_INTERRUPTS();
219
asm("
220
        moveml %d0-%d7/%a0-%a6,registers  /* save registers               */
221
        movel   lastFrame,%a0   /* last frame pointer */
222
 
223
        move.b #64,(0x00600001)
224
        move.b (0x00600007),%d0
225
        andib #-64,%d0
226
        move.b %d0,(0x00600007)
227
 
228
");
229
SAVE_FP_REGS();
230
asm("
231
        lea     registers,%a5   /* get address of registers     */
232
        movel   %sp@+,%d2         /* pop return address           */
233
        addq.l  #6,%d2
234
        sub.l   #0x200000,%d2
235
        divs    #6,%d2
236
/*      addl    #1530,%d2  */      /* convert return addr to    */
237
/*      divs    #6,%d2     */   /*  exception number            */
238
        extl    %d2
239
 
240
        moveql  #3,%d3           /* assume a three word frame     */
241
 
242
        cmpiw   #3,%d2           /* bus error or address error ? */
243
        bgt     normal          /* if >3 then normal error      */
244
        movel   %sp@+,%a0@-       /* copy error info to frame buff*/
245
        movel   %sp@+,%a0@-       /* these are never used         */
246
        moveql  #7,%d3           /* this is a 7 word frame       */
247
 
248
normal:
249
        movew   %sp@+,%d1         /* pop status register          */
250
        movel   %sp@+,%a4         /* pop program counter          */
251
        movew   %d1,%a5@(66)      /* save sr                    */
252
        movel   %a4,%a5@(68)      /* save pc in _regisers[]             */
253
        movel   %a4,%a0@-         /* copy pc to frame buffer      */
254
        movew   %d1,%a0@-         /* copy sr to frame buffer      */
255
 
256
        movel   %sp,superStack  /* save supervisor sp          */
257
 
258
        andiw   #0x2000,%d1      /* were we in supervisor mode ? */
259
        beq     userMode
260
        movel   %a7,%a5@(60)      /* save a7                  */
261
        bra     saveDone
262
userMode:
263
        movel   %usp,%a1        /* save user stack pointer      */
264
        movel   %a1,%a5@(60)      /* save user stack pointer    */
265
saveDone:
266
 
267
        movew   %d3,%a0@-         /* push frame size in words     */
268
        movel   %d2,%a0@-         /* push vector number           */
269
        movel   %a4,%a0@-         /* push exception pc            */
270
 
271
#
272
# save old frame link and set the new value
273
        movel   lastFrame,%a1   /* last frame pointer */
274
        movel   %a1,%a0@-               /* save pointer to prev frame   */
275
        movel   %a0,lastFrame
276
 
277
        movel   %d2,%sp@-               /* push exception num           */
278
        movel   exceptionHook,%a0  /* get address of handler */
279
        jbsr    %a0@             /* and call it */
280
        clrl    %sp@             /* replace exception num parm with frame ptr*/
281
        jbsr     _returnFromException   /* jbsr, but never returns */
282
");
283
 
284
 
285
/*
286
 * remcomHandler is a front end for handle_exception.  It moves the
287
 * stack pointer into an area reserved for debugger use in case the
288
 * breakpoint happened in supervisor mode.
289
 */
290
asm("remcomHandler:");
291
asm("           addl    #4,%sp");        /* pop off return address     */
292
asm("           movel   %sp@+,%d0");      /* get the exception number   */
293
asm("           movel   stackPtr,%sp"); /* move to remcom stack area  */
294
asm("           movel   %d0,%sp@-");    /* push exception onto stack  */
295
asm("           andiw   #0xf8ff,%sr");
296
asm("           jbsr    handle_exception");    /* this never returns */
297
asm("           rts");                  /* return */
298
 
299
void _returnFromException( Frame *frame )
300
{
301
    /* if no passed in frame, use the last one */
302
    if (! frame)
303
    {
304
        frame = lastFrame;
305
        frame->frameSize = 4;
306
        frame->format = 0;
307
        frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/
308
    }
309
 
310
 
311
    /* a 68000 cannot use the internal info pushed onto a bus error
312
     * or address error frame when doing an RTE so don't put this info
313
     * onto the stack or the stack will creep every time this happens.
314
     */
315
    frame->frameSize=3;
316
 
317
 
318
    /* throw away any frames in the list after this frame */
319
    lastFrame = frame;
320
 
321
    frame->sr = registers[(int) PS];
322
    frame->pc = registers[(int) PC];
323
 
324
    if (registers[(int) PS] & 0x2000)
325
    {
326
        /* return to supervisor mode... */
327
        return_to_super();
328
    }
329
    else
330
    { /* return to user mode */
331
        return_to_user();
332
    }
333
}
334
 
335
int hex(ch)
336
char ch;
337
{
338
  if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
339
  if ((ch >= '0') && (ch <= '9')) return (ch-'0');
340
  if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
341
  return (-1);
342
}
343
 
344
 
345
/* scan for the sequence $<data>#<checksum>     */
346
void getpacket(buffer)
347
char * buffer;
348
{
349
  unsigned char checksum;
350
  unsigned char xmitcsum;
351
  int  i;
352
  int  count;
353
  char ch;
354
 
355
  do {
356
    /* wait around for the start character, ignore all other characters */
357
    while ((ch = getDebugChar()) != '$');
358
    checksum = 0;
359
    xmitcsum = -1;
360
 
361
    count = 0;
362
 
363
    /* now, read until a # or end of buffer is found */
364
    while (count < BUFMAX) {
365
      ch = getDebugChar();
366
      if (ch == '#') break;
367
      checksum = checksum + ch;
368
      buffer[count] = ch;
369
      count = count + 1;
370
      }
371
    buffer[count] = 0;
372
 
373
    if (ch == '#') {
374
      xmitcsum = hex(getDebugChar()) << 4;
375
      xmitcsum += hex(getDebugChar());
376
 
377
      if (checksum != xmitcsum) putDebugChar('-');  /* failed checksum */
378
      else {
379
         putDebugChar('+');  /* successful transfer */
380
         /* if a sequence char is present, reply the sequence ID */
381
         if (buffer[2] == ':') {
382
            putDebugChar( buffer[0] );
383
            putDebugChar( buffer[1] );
384
            /* remove sequence chars from buffer */
385
            count = db_strlen(buffer);
386
            for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
387
         }
388
      }
389
    }
390
  } while (checksum != xmitcsum);
391
 
392
}
393
 
394
/* send the packet in buffer.  The host get's one chance to read it.
395
   This routine does not wait for a positive acknowledge.  */
396
 
397
 
398
void putpacket(buffer)
399
char * buffer;
400
{
401
  unsigned char checksum;
402
  int  count;
403
  char ch;
404
 
405
  /*  $<packet info>#<checksum>. */
406
  do {
407
  putDebugChar('$');
408
  checksum = 0;
409
  count    = 0;
410
 
411
  while ((ch=buffer[count])) {
412
    if (! putDebugChar(ch)) return;
413
    checksum += ch;
414
    count += 1;
415
  }
416
 
417
  putDebugChar('#');
418
  putDebugChar(hexchars[checksum >> 4]);
419
  putDebugChar(hexchars[checksum % 16]);
420
 
421
  } while (1 == 0);  /* (getDebugChar() != '+'); */
422
 
423
}
424
 
425
char  remcomInBuffer[BUFMAX];
426
char  remcomOutBuffer[BUFMAX];
427
static short error;
428
 
429
 
430
void debug_error(format, parm)
431
char * format;
432
char * parm;
433
{
434
  return;
435
}
436
 
437
/* convert the memory pointed to by mem into hex, placing result in buf */
438
/* return a pointer to the last char put in buf (null) */
439
char* mem2hex(mem, buf, count)
440
char* mem;
441
char* buf;
442
int   count;
443
{
444
      int i;
445
      unsigned char ch;
446
      for (i=0;i<count;i++) {
447
          ch = *mem++;
448
          *buf++ = hexchars[ch >> 4];
449
          *buf++ = hexchars[ch % 16];
450
      }
451
      *buf = 0;
452
      return(buf);
453
}
454
 
455
/* convert the hex array pointed to by buf into binary to be placed in mem */
456
/* return a pointer to the character AFTER the last byte written */
457
char* hex2mem(buf, mem, count)
458
char* buf;
459
char* mem;
460
int   count;
461
{
462
      int i;
463
      unsigned char ch;
464
      for (i=0;i<count;i++) {
465
          ch = hex(*buf++) << 4;
466
          ch = ch + hex(*buf++);
467
          *mem++ = ch;
468
      }
469
      return(mem);
470
}
471
 
472
/* this function takes the 68000 exception number and attempts to
473
   translate this number into a unix compatible signal value */
474
int computeSignal( exceptionVector )
475
int exceptionVector;
476
{
477
  int sigval;
478
  switch (exceptionVector) {
479
    case 2 : sigval = 10; break; /* bus error           */
480
    case 3 : sigval = 10; break; /* address error       */
481
    case 4 : sigval = 4;  break; /* illegal instruction */
482
    case 5 : sigval = 8;  break; /* zero divide         */
483
    case 6 : sigval = 8; break; /* chk instruction     */
484
    case 7 : sigval = 8; break; /* trapv instruction   */
485
    case 8 : sigval = 11; break; /* privilege violation */
486
    case 9 : sigval = 5;  break; /* trace trap          */
487
    case 10: sigval = 4;  break; /* line 1010 emulator  */
488
    case 11: sigval = 4;  break; /* line 1111 emulator  */
489
 
490
      /* Coprocessor protocol violation.  Using a standard MMU or FPU
491
         this cannot be triggered by software.  Call it a SIGBUS.  */
492
    case 13: sigval = 10;  break;
493
 
494
    case 31: sigval = 2;  break; /* interrupt           */
495
    case 33: sigval = 5;  break; /* breakpoint          */
496
 
497
      /* This is a trap #8 instruction.  Apparently it is someone's software
498
         convention for some sort of SIGFPE condition.  Whose?  How many
499
         people are being screwed by having this code the way it is?
500
         Is there a clean solution?  */
501
    case 40: sigval = 8;  break; /* floating point err  */
502
 
503
    case 48: sigval = 8;  break; /* floating point err  */
504
    case 49: sigval = 8;  break; /* floating point err  */
505
    case 50: sigval = 8;  break; /* zero divide         */
506
    case 51: sigval = 8;  break; /* underflow           */
507
    case 52: sigval = 8;  break; /* operand error       */
508
    case 53: sigval = 8;  break; /* overflow            */
509
    case 54: sigval = 8;  break; /* NAN                 */
510
    default:
511
      sigval = 7;         /* "software generated"*/
512
  }
513
  return (sigval);
514
}
515
 
516
/**********************************************/
517
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
518
/* RETURN NUMBER OF CHARS PROCESSED           */
519
/**********************************************/
520
int hexToInt(char **ptr, int *intValue)
521
{
522
    int numChars = 0;
523
    int hexValue;
524
 
525
    *intValue = 0;
526
 
527
    while (**ptr)
528
    {
529
        hexValue = hex(**ptr);
530
        if (hexValue >=0)
531
        {
532
            *intValue = (*intValue <<4) | hexValue;
533
            numChars ++;
534
        }
535
        else
536
            break;
537
 
538
        (*ptr)++;
539
    }
540
 
541
    return (numChars);
542
}
543
 
544
/*
545
 * This function does all command procesing for interfacing to gdb.
546
 */
547
void handle_exception(int exceptionVector)
548
{
549
  int    sigval;
550
  int    addr, length;
551
  char * ptr;
552
  int    newPC;
553
  Frame  *frame;
554
 
555
  /* reply to host that an exception has occurred */
556
  sigval = computeSignal( exceptionVector );
557
  remcomOutBuffer[0] = 'S';
558
  remcomOutBuffer[1] =  hexchars[sigval >> 4];
559
  remcomOutBuffer[2] =  hexchars[sigval % 16];
560
  remcomOutBuffer[3] = 0;
561
 
562
  putpacket(remcomOutBuffer);
563
 
564
  while (1==1) {
565
    error = 0;
566
    remcomOutBuffer[0] = 0;
567
    getpacket(remcomInBuffer);
568
    switch (remcomInBuffer[0]) {
569
      case '?' :   remcomOutBuffer[0] = 'S';
570
                   remcomOutBuffer[1] =  hexchars[sigval >> 4];
571
                   remcomOutBuffer[2] =  hexchars[sigval % 16];
572
                   remcomOutBuffer[3] = 0;
573
                 break;
574
      case 'd' : remote_debug = !(remote_debug);  /* toggle debug flag */
575
                 break;
576
      case 'g' : /* return the value of the CPU registers */
577
                mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES);
578
                break;
579
      case 'G' : /* set the value of the CPU registers - return OK */
580
                hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES);
581
                db_strcpy(remcomOutBuffer,"OK");
582
                break;
583
 
584
      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
585
      case 'm' :
586
        /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
587
        ptr = &remcomInBuffer[1];
588
        if (hexToInt(&ptr,&addr))
589
          if (*(ptr++) == ',')
590
            if (hexToInt(&ptr,&length))
591
              {
592
                ptr = 0;
593
                mem2hex((char*) addr, remcomOutBuffer, length);
594
              }
595
 
596
        if (ptr)
597
          {
598
            db_strcpy(remcomOutBuffer,"E01");
599
            debug_error("malformed read memory command: %s",remcomInBuffer);
600
          }
601
        break;
602
 
603
      /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
604
      case 'M' :
605
        /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
606
        ptr = &remcomInBuffer[1];
607
        if (hexToInt(&ptr,&addr))
608
          if (*(ptr++) == ',')
609
            if (hexToInt(&ptr,&length))
610
              if (*(ptr++) == ':')
611
                {
612
                  hex2mem(ptr, (char*) addr, length);
613
                  ptr = 0;
614
                  db_strcpy(remcomOutBuffer,"OK");
615
                }
616
        if (ptr)
617
          {
618
            db_strcpy(remcomOutBuffer,"E02");
619
            debug_error("malformed write memory command: %s",remcomInBuffer);
620
          }
621
        break;
622
 
623
     /* cAA..AA    Continue at address AA..AA(optional) */
624
     /* sAA..AA   Step one instruction from AA..AA(optional) */
625
     case 'c' :
626
     case 's' :
627
          /* try to read optional parameter, pc unchanged if no parm */
628
         ptr = &remcomInBuffer[1];
629
         if (hexToInt(&ptr,&addr))
630
             registers[ PC ] = addr;
631
 
632
          newPC = registers[ PC];
633
 
634
          /* clear the trace bit */
635
          registers[ PS ] &= 0x7fff;
636
 
637
          /* set the trace bit if we're stepping */
638
          if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000;
639
 
640
          /*
641
           * look for newPC in the linked list of exception frames.
642
           * if it is found, use the old frame it.  otherwise,
643
           * fake up a dummy frame in returnFromException().
644
           */
645
          frame = lastFrame;
646
          while (frame)
647
          {
648
              if (frame->exceptionPC == newPC) break;  /* bingo! a match */
649
              /*
650
               * for a breakpoint instruction, the saved pc may
651
               * be off by two due to re-executing the instruction
652
               * replaced by the trap instruction.  Check for this.
653
               */
654
              if ((frame->exceptionVector == 33) &&
655
                  (frame->exceptionPC == (newPC+2))) break;
656
              if (frame == frame->previous)
657
              {
658
                  frame = 0; /* no match found */
659
                  break;
660
              }
661
              frame = frame->previous;
662
          }
663
 
664
          /*
665
           * If we found a match for the PC AND we are not returning
666
           * as a result of a breakpoint (33),
667
           * trace exception (9), nmi (31), jmp to
668
           * the old exception handler as if this code never ran.
669
           */
670
          if (frame)
671
          {
672
              if ((frame->exceptionVector != 9)  &&
673
                  (frame->exceptionVector != 31) &&
674
                  (frame->exceptionVector != 33))
675
              {
676
                  /*
677
                   * invoke the previous handler.
678
                   */
679
                  if (oldExceptionHook)
680
                      (*oldExceptionHook) (frame->exceptionVector);
681
                  newPC = registers[ PC ];    /* pc may have changed  */
682
                  if (newPC != frame->exceptionPC)
683
                  {
684
                      /* re-use the last frame, we're skipping it (longjump?)*/
685
                      frame = (Frame *) 0;
686
                      _returnFromException( frame );  /* this is a jump */
687
                  }
688
              }
689
          }
690
 
691
          /* if we couldn't find a frame, create one */
692
          if (frame == 0)
693
          {
694
              frame = lastFrame -1 ;
695
 
696
              /* by using a bunch of print commands with breakpoints,
697
                 it's possible for the frame stack to creep down.  If it creeps
698
                 too far, give up and reset it to the top.  Normal use should
699
                 not see this happen.
700
              */
701
              if ((unsigned int) (frame-2) < (unsigned int) &gdbFrameStack)
702
              {
703
                 initializeRemcomErrorFrame();
704
                 frame = lastFrame;
705
              }
706
              frame->previous = lastFrame;
707
              lastFrame = frame;
708
              frame = 0;  /* null so _return... will properly initialize it */
709
          }
710
 
711
          _returnFromException( frame ); /* this is a jump */
712
 
713
          break;
714
 
715
      /* kill the program */
716
      case 'k' :  /* do nothing */
717
                break;
718
      } /* switch */
719
 
720
    /* reply to the request */
721
    putpacket(remcomOutBuffer);
722
    }
723
}
724
 
725
 
726
void
727
initializeRemcomErrorFrame()
728
{
729
    lastFrame = ((Frame *) &gdbFrameStack[FRAMESIZE-1]) - 1;
730
    lastFrame->previous = lastFrame;
731
}
732
 
733
/* this function is used to set up exception handlers for tracing and
734
   breakpoints */
735
void set_debug_traps()
736
{
737
  extern void _debug_level7();
738
  extern void remcomHandler();
739
  int exception;
740
 
741
  initializeRemcomErrorFrame();
742
  stackPtr  = &remcomStack[STACKSIZE/sizeof(int) - 1];
743
 
744
  for (exception = 2; exception <= 23; exception++)
745
      set_vector(_catchException,exception,0);
746
 
747
  /* level 7 interrupt              */
748
  set_vector(_debug_level7,31,0);
749
 
750
  /* breakpoint exception (trap #1) */
751
  set_vector(_catchException,33,0);
752
 
753
  /* This is a trap #8 instruction.  Apparently it is someone's software
754
     convention for some sort of SIGFPE condition.  Whose?  How many
755
     people are being screwed by having this code the way it is?
756
     Is there a clean solution?  */
757
  set_vector(_catchException,40,0);
758
 
759
  /* 48 to 54 are floating point coprocessor errors */
760
  for (exception = 48; exception <= 54; exception++)
761
      set_vector(_catchException,exception,0);
762
 
763
  if (oldExceptionHook != remcomHandler)
764
  {
765
      oldExceptionHook = exceptionHook;
766
      exceptionHook    = remcomHandler;
767
  }
768
 
769
  initialized = 1;
770
 
771
}
772
 
773
/* This function will generate a breakpoint exception.  It is used at the
774
   beginning of a program to sync up with a debugger and can be used
775
   otherwise as a quick means to stop program execution and "break" into
776
   the debugger. */
777
 
778
void breakpoint()
779
{
780
  if (initialized) BREAKPOINT();
781
}
782
 

powered by: WebSVN 2.1.0

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