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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [sh-stub.c] - Blame information for rev 178

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

Line No. Rev Author Line
1 24 jeremybenn
/* sh-stub.c -- debugging stub for the Renesas-SH.
2
 
3
 NOTE!! This code has to be compiled with optimization, otherwise the
4
 function inlining which generates the exception handlers won't work.
5
 
6
*/
7
 
8
/*   This is originally based on an m68k software stub written by Glenn
9
     Engel at HP, but has changed quite a bit.
10
 
11
     Modifications for the SH by Ben Lee and Steve Chamberlain
12
 
13
*/
14
 
15
/****************************************************************************
16
 
17
                THIS SOFTWARE IS NOT COPYRIGHTED
18
 
19
   HP offers the following for use in the public domain.  HP makes no
20
   warranty with regard to the software or it's performance and the
21
   user accepts the software "AS IS" with all faults.
22
 
23
   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
24
   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26
 
27
****************************************************************************/
28
 
29
 
30
/* Remote communication protocol.
31
 
32
   A debug packet whose contents are <data>
33
   is encapsulated for transmission in the form:
34
 
35
        $ <data> # CSUM1 CSUM2
36
 
37
        <data> must be ASCII alphanumeric and cannot include characters
38
        '$' or '#'.  If <data> starts with two characters followed by
39
        ':', then the existing stubs interpret this as a sequence number.
40
 
41
        CSUM1 and CSUM2 are ascii hex representation of an 8-bit
42
        checksum of <data>, the most significant nibble is sent first.
43
        the hex digits 0-9,a-f are used.
44
 
45
   Receiver responds with:
46
 
47
        +       - if CSUM is correct and ready for next packet
48
        -       - if CSUM is incorrect
49
 
50
   <data> is as follows:
51
   All values are encoded in ascii hex digits.
52
 
53
        Request         Packet
54
 
55
        read registers  g
56
        reply           XX....X         Each byte of register data
57
                                        is described by two hex digits.
58
                                        Registers are in the internal order
59
                                        for GDB, and the bytes in a register
60
                                        are in the same order the machine uses.
61
                        or ENN          for an error.
62
 
63
        write regs      GXX..XX         Each byte of register data
64
                                        is described by two hex digits.
65
        reply           OK              for success
66
                        ENN             for an error
67
 
68
        write reg       Pn...=r...      Write register n... with value r...,
69
                                        which contains two hex digits for each
70
                                        byte in the register (target byte
71
                                        order).
72
        reply           OK              for success
73
                        ENN             for an error
74
        (not supported by all stubs).
75
 
76
        read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.
77
        reply           XX..XX          XX..XX is mem contents
78
                                        Can be fewer bytes than requested
79
                                        if able to read only part of the data.
80
                        or ENN          NN is errno
81
 
82
        write mem       MAA..AA,LLLL:XX..XX
83
                                        AA..AA is address,
84
                                        LLLL is number of bytes,
85
                                        XX..XX is data
86
        reply           OK              for success
87
                        ENN             for an error (this includes the case
88
                                        where only part of the data was
89
                                        written).
90
 
91
        cont            cAA..AA         AA..AA is address to resume
92
                                        If AA..AA is omitted,
93
                                        resume at same address.
94
 
95
        step            sAA..AA         AA..AA is address to resume
96
                                        If AA..AA is omitted,
97
                                        resume at same address.
98
 
99
        last signal     ?               Reply the current reason for stopping.
100
                                        This is the same reply as is generated
101
                                        for step or cont : SAA where AA is the
102
                                        signal number.
103
 
104
        There is no immediate reply to step or cont.
105
        The reply comes when the machine stops.
106
        It is           SAA             AA is the "signal number"
107
 
108
        or...           TAAn...:r...;n:r...;n...:r...;
109
                                        AA = signal number
110
                                        n... = register number
111
                                        r... = register contents
112
        or...           WAA             The process exited, and AA is
113
                                        the exit status.  This is only
114
                                        applicable for certains sorts of
115
                                        targets.
116
        kill request    k
117
 
118
        toggle debug    d               toggle debug flag (see 386 & 68k stubs)
119
        reset           r               reset -- see sparc stub.
120
        reserved        <other>         On other requests, the stub should
121
                                        ignore the request and send an empty
122
                                        response ($#<checksum>).  This way
123
                                        we can extend the protocol and GDB
124
                                        can tell whether the stub it is
125
                                        talking to uses the old or the new.
126
        search          tAA:PP,MM       Search backwards starting at address
127
                                        AA for a match with pattern PP and
128
                                        mask MM.  PP and MM are 4 bytes.
129
                                        Not supported by all stubs.
130
 
131
        general query   qXXXX           Request info about XXXX.
132
        general set     QXXXX=yyyy      Set value of XXXX to yyyy.
133
        query sect offs qOffsets        Get section offsets.  Reply is
134
                                        Text=xxx;Data=yyy;Bss=zzz
135
        console output  Otext           Send text to stdout.  Only comes from
136
                                        remote target.
137
 
138
        Responses can be run-length encoded to save space.  A '*' means that
139
        the next character is an ASCII encoding giving a repeat count which
140
        stands for that many repititions of the character preceding the '*'.
141
        The encoding is n+29, yielding a printable character where n >=3
142
        (which is where rle starts to win).  Don't use an n > 126.
143
 
144
        So
145
        "0* " means the same as "0000".  */
146
 
147
#include <string.h>
148
#include <setjmp.h>
149
 
150
/* Renesas SH architecture instruction encoding masks */
151
 
152
#define COND_BR_MASK   0xff00
153
#define UCOND_DBR_MASK 0xe000
154
#define UCOND_RBR_MASK 0xf0df
155
#define TRAPA_MASK     0xff00
156
 
157
#define COND_DISP      0x00ff
158
#define UCOND_DISP     0x0fff
159
#define UCOND_REG      0x0f00
160
 
161
/* Renesas SH instruction opcodes */
162
 
163
#define BF_INSTR       0x8b00
164
#define BT_INSTR       0x8900
165
#define BRA_INSTR      0xa000
166
#define BSR_INSTR      0xb000
167
#define JMP_INSTR      0x402b
168
#define JSR_INSTR      0x400b
169
#define RTS_INSTR      0x000b
170
#define RTE_INSTR      0x002b
171
#define TRAPA_INSTR    0xc300
172
#define SSTEP_INSTR    0xc3ff
173
 
174
/* Renesas SH processor register masks */
175
 
176
#define T_BIT_MASK     0x0001
177
 
178
/*
179
 * BUFMAX defines the maximum number of characters in inbound/outbound
180
 * buffers. At least NUMREGBYTES*2 are needed for register packets.
181
 */
182
#define BUFMAX 1024
183
 
184
/*
185
 * Number of bytes for registers
186
 */
187
#define NUMREGBYTES 112         /* 92 */
188
 
189
/*
190
 * typedef
191
 */
192
typedef void (*Function) ();
193
 
194
/*
195
 * Forward declarations
196
 */
197
 
198
static int hex (char);
199
static char *mem2hex (char *, char *, int);
200
static char *hex2mem (char *, char *, int);
201
static int hexToInt (char **, int *);
202
static unsigned char *getpacket (void);
203
static void putpacket (char *);
204
static void handle_buserror (void);
205
static int computeSignal (int exceptionVector);
206
static void handle_exception (int exceptionVector);
207
void init_serial();
208
 
209
void putDebugChar (char);
210
char getDebugChar (void);
211
 
212
/* These are in the file but in asm statements so the compiler can't see them */
213
void catch_exception_4 (void);
214
void catch_exception_6 (void);
215
void catch_exception_9 (void);
216
void catch_exception_10 (void);
217
void catch_exception_11 (void);
218
void catch_exception_32 (void);
219
void catch_exception_33 (void);
220
void catch_exception_255 (void);
221
 
222
 
223
 
224
#define catch_exception_random catch_exception_255 /* Treat all odd ones like 255 */
225
 
226
void breakpoint (void);
227
 
228
 
229
#define init_stack_size 8*1024  /* if you change this you should also modify BINIT */
230
#define stub_stack_size 8*1024
231
 
232
int init_stack[init_stack_size] __attribute__ ((section ("stack"))) = {0};
233
int stub_stack[stub_stack_size] __attribute__ ((section ("stack"))) = {0};
234
 
235
 
236
void INIT ();
237
void BINIT ();
238
 
239
#define CPU_BUS_ERROR_VEC  9
240
#define DMA_BUS_ERROR_VEC 10
241
#define NMI_VEC           11
242
#define INVALID_INSN_VEC   4
243
#define INVALID_SLOT_VEC   6
244
#define TRAP_VEC          32
245
#define IO_VEC            33
246
#define USER_VEC         255
247
 
248
 
249
 
250
char in_nmi;   /* Set when handling an NMI, so we don't reenter */
251
int dofault;  /* Non zero, bus errors will raise exception */
252
 
253
int *stub_sp;
254
 
255
/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
256
int remote_debug;
257
 
258
/* jump buffer used for setjmp/longjmp */
259
jmp_buf remcomEnv;
260
 
261
enum regnames
262
  {
263
    R0, R1, R2, R3, R4, R5, R6, R7,
264
    R8, R9, R10, R11, R12, R13, R14,
265
    R15, PC, PR, GBR, VBR, MACH, MACL, SR,
266
    TICKS, STALLS, CYCLES, INSTS, PLR
267
  };
268
 
269
typedef struct
270
  {
271
    short *memAddr;
272
    short oldInstr;
273
  }
274
stepData;
275
 
276
int registers[NUMREGBYTES / 4];
277
stepData instrBuffer;
278
char stepped;
279
static const char hexchars[] = "0123456789abcdef";
280
static char remcomInBuffer[BUFMAX];
281
static char remcomOutBuffer[BUFMAX];
282
 
283
char highhex(int  x)
284
{
285
  return hexchars[(x >> 4) & 0xf];
286
}
287
 
288
char lowhex(int  x)
289
{
290
  return hexchars[x & 0xf];
291
}
292
 
293
/*
294
 * Assembly macros
295
 */
296
 
297
#define BREAKPOINT()   asm("trapa       #0x20"::);
298
 
299
 
300
/*
301
 * Routines to handle hex data
302
 */
303
 
304
static int
305
hex (char ch)
306
{
307
  if ((ch >= 'a') && (ch <= 'f'))
308
    return (ch - 'a' + 10);
309
  if ((ch >= '0') && (ch <= '9'))
310
    return (ch - '0');
311
  if ((ch >= 'A') && (ch <= 'F'))
312
    return (ch - 'A' + 10);
313
  return (-1);
314
}
315
 
316
/* convert the memory, pointed to by mem into hex, placing result in buf */
317
/* return a pointer to the last char put in buf (null) */
318
static char *
319
mem2hex (char *mem, char *buf, int count)
320
{
321
  int i;
322
  int ch;
323
  for (i = 0; i < count; i++)
324
    {
325
      ch = *mem++;
326
      *buf++ = highhex (ch);
327
      *buf++ = lowhex (ch);
328
    }
329
  *buf = 0;
330
  return (buf);
331
}
332
 
333
/* convert the hex array pointed to by buf into binary, to be placed in mem */
334
/* return a pointer to the character after the last byte written */
335
 
336
static char *
337
hex2mem (char *buf, char *mem, int count)
338
{
339
  int i;
340
  unsigned char ch;
341
  for (i = 0; i < count; i++)
342
    {
343
      ch = hex (*buf++) << 4;
344
      ch = ch + hex (*buf++);
345
      *mem++ = ch;
346
    }
347
  return (mem);
348
}
349
 
350
/**********************************************/
351
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
352
/* RETURN NUMBER OF CHARS PROCESSED           */
353
/**********************************************/
354
static int
355
hexToInt (char **ptr, int *intValue)
356
{
357
  int numChars = 0;
358
  int hexValue;
359
 
360
  *intValue = 0;
361
 
362
  while (**ptr)
363
    {
364
      hexValue = hex (**ptr);
365
      if (hexValue >= 0)
366
        {
367
          *intValue = (*intValue << 4) | hexValue;
368
          numChars++;
369
        }
370
      else
371
        break;
372
 
373
      (*ptr)++;
374
    }
375
 
376
  return (numChars);
377
}
378
 
379
/*
380
 * Routines to get and put packets
381
 */
382
 
383
/* scan for the sequence $<data>#<checksum>     */
384
 
385
char *
386
getpacket (void)
387
{
388
  unsigned char *buffer = &remcomInBuffer[0];
389
  unsigned char checksum;
390
  unsigned char xmitcsum;
391
  int count;
392
  char ch;
393
 
394
  while (1)
395
    {
396
      /* wait around for the start character, ignore all other characters */
397
      while ((ch = getDebugChar ()) != '$')
398
        ;
399
 
400
retry:
401
      checksum = 0;
402
      xmitcsum = -1;
403
      count = 0;
404
 
405
      /* now, read until a # or end of buffer is found */
406
      while (count < BUFMAX - 1)
407
        {
408
          ch = getDebugChar ();
409
          if (ch == '$')
410
            goto retry;
411
          if (ch == '#')
412
            break;
413
          checksum = checksum + ch;
414
          buffer[count] = ch;
415
          count = count + 1;
416
        }
417
      buffer[count] = 0;
418
 
419
      if (ch == '#')
420
        {
421
          ch = getDebugChar ();
422
          xmitcsum = hex (ch) << 4;
423
          ch = getDebugChar ();
424
          xmitcsum += hex (ch);
425
 
426
          if (checksum != xmitcsum)
427
            {
428
              putDebugChar ('-');       /* failed checksum */
429
            }
430
          else
431
            {
432
              putDebugChar ('+');       /* successful transfer */
433
 
434
              /* if a sequence char is present, reply the sequence ID */
435
              if (buffer[2] == ':')
436
                {
437
                  putDebugChar (buffer[0]);
438
                  putDebugChar (buffer[1]);
439
 
440
                  return &buffer[3];
441
                }
442
 
443
              return &buffer[0];
444
            }
445
        }
446
    }
447
}
448
 
449
 
450
/* send the packet in buffer. */
451
 
452
static void
453
putpacket (char *buffer)
454
{
455
  int checksum;
456
  int count;
457
 
458
  /*  $<packet info>#<checksum>. */
459
  do
460
    {
461
      char *src = buffer;
462
      putDebugChar ('$');
463
      checksum = 0;
464
 
465
      while (*src)
466
        {
467
          int runlen;
468
 
469
          /* Do run length encoding */
470
          for (runlen = 0; runlen < 100; runlen ++)
471
            {
472
              if (src[0] != src[runlen])
473
                {
474
                  if (runlen > 3)
475
                    {
476
                      int encode;
477
                      /* Got a useful amount */
478
                      putDebugChar (*src);
479
                      checksum += *src;
480
                      putDebugChar ('*');
481
                      checksum += '*';
482
                      checksum += (encode = runlen + ' ' - 4);
483
                      putDebugChar (encode);
484
                      src += runlen;
485
                    }
486
                  else
487
                    {
488
                      putDebugChar (*src);
489
                      checksum += *src;
490
                      src++;
491
                    }
492
                  break;
493
                }
494
            }
495
        }
496
 
497
 
498
      putDebugChar ('#');
499
      putDebugChar (highhex(checksum));
500
      putDebugChar (lowhex(checksum));
501
    }
502
  while  (getDebugChar() != '+');
503
}
504
 
505
 
506
/* a bus error has occurred, perform a longjmp
507
   to return execution and allow handling of the error */
508
 
509
void
510
handle_buserror (void)
511
{
512
  longjmp (remcomEnv, 1);
513
}
514
 
515
/*
516
 * this function takes the SH-1 exception number and attempts to
517
 * translate this number into a unix compatible signal value
518
 */
519
static int
520
computeSignal (int exceptionVector)
521
{
522
  int sigval;
523
  switch (exceptionVector)
524
    {
525
    case INVALID_INSN_VEC:
526
      sigval = 4;
527
      break;
528
    case INVALID_SLOT_VEC:
529
      sigval = 4;
530
      break;
531
    case CPU_BUS_ERROR_VEC:
532
      sigval = 10;
533
      break;
534
    case DMA_BUS_ERROR_VEC:
535
      sigval = 10;
536
      break;
537
    case NMI_VEC:
538
      sigval = 2;
539
      break;
540
 
541
    case TRAP_VEC:
542
    case USER_VEC:
543
      sigval = 5;
544
      break;
545
 
546
    default:
547
      sigval = 7;               /* "software generated"*/
548
      break;
549
    }
550
  return (sigval);
551
}
552
 
553
void
554
doSStep (void)
555
{
556
  short *instrMem;
557
  int displacement;
558
  int reg;
559
  unsigned short opcode;
560
 
561
  instrMem = (short *) registers[PC];
562
 
563
  opcode = *instrMem;
564
  stepped = 1;
565
 
566
  if ((opcode & COND_BR_MASK) == BT_INSTR)
567
    {
568
      if (registers[SR] & T_BIT_MASK)
569
        {
570
          displacement = (opcode & COND_DISP) << 1;
571
          if (displacement & 0x80)
572
            displacement |= 0xffffff00;
573
          /*
574
                   * Remember PC points to second instr.
575
                   * after PC of branch ... so add 4
576
                   */
577
          instrMem = (short *) (registers[PC] + displacement + 4);
578
        }
579
      else
580
        instrMem += 1;
581
    }
582
  else if ((opcode & COND_BR_MASK) == BF_INSTR)
583
    {
584
      if (registers[SR] & T_BIT_MASK)
585
        instrMem += 1;
586
      else
587
        {
588
          displacement = (opcode & COND_DISP) << 1;
589
          if (displacement & 0x80)
590
            displacement |= 0xffffff00;
591
          /*
592
                   * Remember PC points to second instr.
593
                   * after PC of branch ... so add 4
594
                   */
595
          instrMem = (short *) (registers[PC] + displacement + 4);
596
        }
597
    }
598
  else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
599
    {
600
      displacement = (opcode & UCOND_DISP) << 1;
601
      if (displacement & 0x0800)
602
        displacement |= 0xfffff000;
603
 
604
      /*
605
           * Remember PC points to second instr.
606
           * after PC of branch ... so add 4
607
           */
608
      instrMem = (short *) (registers[PC] + displacement + 4);
609
    }
610
  else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
611
    {
612
      reg = (char) ((opcode & UCOND_REG) >> 8);
613
 
614
      instrMem = (short *) registers[reg];
615
    }
616
  else if (opcode == RTS_INSTR)
617
    instrMem = (short *) registers[PR];
618
  else if (opcode == RTE_INSTR)
619
    instrMem = (short *) registers[15];
620
  else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
621
    instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
622
  else
623
    instrMem += 1;
624
 
625
  instrBuffer.memAddr = instrMem;
626
  instrBuffer.oldInstr = *instrMem;
627
  *instrMem = SSTEP_INSTR;
628
}
629
 
630
 
631
/* Undo the effect of a previous doSStep.  If we single stepped,
632
   restore the old instruction. */
633
 
634
void
635
undoSStep (void)
636
{
637
  if (stepped)
638
    {  short *instrMem;
639
      instrMem = instrBuffer.memAddr;
640
      *instrMem = instrBuffer.oldInstr;
641
    }
642
  stepped = 0;
643
}
644
 
645
/*
646
This function does all exception handling.  It only does two things -
647
it figures out why it was called and tells gdb, and then it reacts
648
to gdb's requests.
649
 
650
When in the monitor mode we talk a human on the serial line rather than gdb.
651
 
652
*/
653
 
654
 
655
void
656
gdb_handle_exception (int exceptionVector)
657
{
658
  int sigval, stepping;
659
  int addr, length;
660
  char *ptr;
661
 
662
  /* reply to host that an exception has occurred */
663
  sigval = computeSignal (exceptionVector);
664
  remcomOutBuffer[0] = 'S';
665
  remcomOutBuffer[1] = highhex(sigval);
666
  remcomOutBuffer[2] = lowhex (sigval);
667
  remcomOutBuffer[3] = 0;
668
 
669
  putpacket (remcomOutBuffer);
670
 
671
  /*
672
   * exception 255 indicates a software trap
673
   * inserted in place of code ... so back up
674
   * PC by one instruction, since this instruction
675
   * will later be replaced by its original one!
676
   */
677
  if (exceptionVector == 0xff
678
      || exceptionVector == 0x20)
679
    registers[PC] -= 2;
680
 
681
  /*
682
   * Do the thangs needed to undo
683
   * any stepping we may have done!
684
   */
685
  undoSStep ();
686
 
687
  stepping = 0;
688
 
689
  while (1)
690
    {
691
      remcomOutBuffer[0] = 0;
692
      ptr = getpacket ();
693
 
694
      switch (*ptr++)
695
        {
696
        case '?':
697
          remcomOutBuffer[0] = 'S';
698
          remcomOutBuffer[1] = highhex (sigval);
699
          remcomOutBuffer[2] = lowhex (sigval);
700
          remcomOutBuffer[3] = 0;
701
          break;
702
        case 'd':
703
          remote_debug = !(remote_debug);       /* toggle debug flag */
704
          break;
705
        case 'g':               /* return the value of the CPU registers */
706
          mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
707
          break;
708
        case 'G':               /* set the value of the CPU registers - return OK */
709
          hex2mem (ptr, (char *) registers, NUMREGBYTES);
710
          strcpy (remcomOutBuffer, "OK");
711
          break;
712
 
713
          /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
714
        case 'm':
715
          if (setjmp (remcomEnv) == 0)
716
            {
717
              dofault = 0;
718
              /* TRY, TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
719
              if (hexToInt (&ptr, &addr))
720
                if (*(ptr++) == ',')
721
                  if (hexToInt (&ptr, &length))
722
                    {
723
                      ptr = 0;
724
                      mem2hex ((char *) addr, remcomOutBuffer, length);
725
                    }
726
              if (ptr)
727
                strcpy (remcomOutBuffer, "E01");
728
            }
729
          else
730
            strcpy (remcomOutBuffer, "E03");
731
 
732
          /* restore handler for bus error */
733
          dofault = 1;
734
          break;
735
 
736
          /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
737
        case 'M':
738
          if (setjmp (remcomEnv) == 0)
739
            {
740
              dofault = 0;
741
 
742
              /* TRY, TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
743
              if (hexToInt (&ptr, &addr))
744
                if (*(ptr++) == ',')
745
                  if (hexToInt (&ptr, &length))
746
                    if (*(ptr++) == ':')
747
                      {
748
                        hex2mem (ptr, (char *) addr, length);
749
                        ptr = 0;
750
                        strcpy (remcomOutBuffer, "OK");
751
                      }
752
              if (ptr)
753
                strcpy (remcomOutBuffer, "E02");
754
            }
755
          else
756
            strcpy (remcomOutBuffer, "E03");
757
 
758
          /* restore handler for bus error */
759
          dofault = 1;
760
          break;
761
 
762
          /* cAA..AA    Continue at address AA..AA(optional) */
763
          /* sAA..AA   Step one instruction from AA..AA(optional) */
764
        case 's':
765
          stepping = 1;
766
        case 'c':
767
          {
768
            /* tRY, to read optional parameter, pc unchanged if no parm */
769
            if (hexToInt (&ptr, &addr))
770
              registers[PC] = addr;
771
 
772
            if (stepping)
773
              doSStep ();
774
          }
775
          return;
776
          break;
777
 
778
          /* kill the program */
779
        case 'k':               /* do nothing */
780
          break;
781
        }                       /* switch */
782
 
783
      /* reply to the request */
784
      putpacket (remcomOutBuffer);
785
    }
786
}
787
 
788
 
789
#define GDBCOOKIE 0x5ac 
790
static int ingdbmode;
791
/* We've had an exception - choose to go into the monitor or
792
   the gdb stub */
793
void handle_exception(int exceptionVector)
794
{
795
#ifdef MONITOR
796
    if (ingdbmode != GDBCOOKIE)
797
      monitor_handle_exception (exceptionVector);
798
    else
799
#endif
800
      gdb_handle_exception (exceptionVector);
801
 
802
}
803
 
804
void
805
gdb_mode (void)
806
{
807
  ingdbmode = GDBCOOKIE;
808
  breakpoint();
809
}
810
/* This function will generate a breakpoint exception.  It is used at the
811
   beginning of a program to sync up with a debugger and can be used
812
   otherwise as a quick means to stop program execution and "break" into
813
   the debugger. */
814
 
815
void
816
breakpoint (void)
817
{
818
      BREAKPOINT ();
819
}
820
 
821
/**** Processor-specific routines start here ****/
822
/**** Processor-specific routines start here ****/
823
/**** Processor-specific routines start here ****/
824
 
825
/* Note:
826
 
827
   The Renesas SH family uses two exception architectures:
828
 
829
   SH1 & SH2:
830
 
831
       These processors utilize an exception vector table.
832
       Exceptions are vectored to the address stored at VBR + (exception_num * 4)
833
 
834
  SH3, SH3E, & SH4:
835
 
836
       These processors have fixed entry points relative to the VBR for
837
       various exception classes.
838
*/
839
 
840
#if defined(__sh1__) || defined(__sh2__)
841
 
842
/* SH1/SH2 exception vector table format */
843
 
844
typedef struct
845
  {
846
    void (*func_cold) ();
847
    int *stack_cold;
848
    void (*func_warm) ();
849
    int *stack_warm;
850
    void (*(handler[256 - 4])) ();
851
  }
852
vec_type;
853
 
854
/* vectable is the SH1/SH2 vector table. It must be at address 0
855
   or wherever your vbr points. */
856
 
857
const vec_type vectable =
858
{
859
  &BINIT,                       /* 0: Power-on reset PC */
860
  init_stack + init_stack_size, /* 1: Power-on reset SP */
861
  &BINIT,                       /* 2: Manual reset PC */
862
  init_stack + init_stack_size, /* 3: Manual reset SP */
863
{
864
  &catch_exception_4,           /* 4: General invalid instruction */
865
  &catch_exception_random,      /* 5: Reserved for system */
866
  &catch_exception_6,           /* 6: Invalid slot instruction */
867
  &catch_exception_random,      /* 7: Reserved for system */
868
  &catch_exception_random,      /* 8: Reserved for system */
869
  &catch_exception_9,           /* 9: CPU bus error */
870
  &catch_exception_10,          /* 10: DMA bus error */
871
  &catch_exception_11,          /* 11: NMI */
872
  &catch_exception_random,      /* 12: User break */
873
  &catch_exception_random,      /* 13: Reserved for system */
874
  &catch_exception_random,      /* 14: Reserved for system */
875
  &catch_exception_random,      /* 15: Reserved for system */
876
  &catch_exception_random,      /* 16: Reserved for system */
877
  &catch_exception_random,      /* 17: Reserved for system */
878
  &catch_exception_random,      /* 18: Reserved for system */
879
  &catch_exception_random,      /* 19: Reserved for system */
880
  &catch_exception_random,      /* 20: Reserved for system */
881
  &catch_exception_random,      /* 21: Reserved for system */
882
  &catch_exception_random,      /* 22: Reserved for system */
883
  &catch_exception_random,      /* 23: Reserved for system */
884
  &catch_exception_random,      /* 24: Reserved for system */
885
  &catch_exception_random,      /* 25: Reserved for system */
886
  &catch_exception_random,      /* 26: Reserved for system */
887
  &catch_exception_random,      /* 27: Reserved for system */
888
  &catch_exception_random,      /* 28: Reserved for system */
889
  &catch_exception_random,      /* 29: Reserved for system */
890
  &catch_exception_random,      /* 30: Reserved for system */
891
  &catch_exception_random,      /* 31: Reserved for system */
892
  &catch_exception_32,          /* 32: Trap instr (user vectors) */
893
  &catch_exception_33,          /* 33: Trap instr (user vectors) */
894
  &catch_exception_random,      /* 34: Trap instr (user vectors) */
895
  &catch_exception_random,      /* 35: Trap instr (user vectors) */
896
  &catch_exception_random,      /* 36: Trap instr (user vectors) */
897
  &catch_exception_random,      /* 37: Trap instr (user vectors) */
898
  &catch_exception_random,      /* 38: Trap instr (user vectors) */
899
  &catch_exception_random,      /* 39: Trap instr (user vectors) */
900
  &catch_exception_random,      /* 40: Trap instr (user vectors) */
901
  &catch_exception_random,      /* 41: Trap instr (user vectors) */
902
  &catch_exception_random,      /* 42: Trap instr (user vectors) */
903
  &catch_exception_random,      /* 43: Trap instr (user vectors) */
904
  &catch_exception_random,      /* 44: Trap instr (user vectors) */
905
  &catch_exception_random,      /* 45: Trap instr (user vectors) */
906
  &catch_exception_random,      /* 46: Trap instr (user vectors) */
907
  &catch_exception_random,      /* 47: Trap instr (user vectors) */
908
  &catch_exception_random,      /* 48: Trap instr (user vectors) */
909
  &catch_exception_random,      /* 49: Trap instr (user vectors) */
910
  &catch_exception_random,      /* 50: Trap instr (user vectors) */
911
  &catch_exception_random,      /* 51: Trap instr (user vectors) */
912
  &catch_exception_random,      /* 52: Trap instr (user vectors) */
913
  &catch_exception_random,      /* 53: Trap instr (user vectors) */
914
  &catch_exception_random,      /* 54: Trap instr (user vectors) */
915
  &catch_exception_random,      /* 55: Trap instr (user vectors) */
916
  &catch_exception_random,      /* 56: Trap instr (user vectors) */
917
  &catch_exception_random,      /* 57: Trap instr (user vectors) */
918
  &catch_exception_random,      /* 58: Trap instr (user vectors) */
919
  &catch_exception_random,      /* 59: Trap instr (user vectors) */
920
  &catch_exception_random,      /* 60: Trap instr (user vectors) */
921
  &catch_exception_random,      /* 61: Trap instr (user vectors) */
922
  &catch_exception_random,      /* 62: Trap instr (user vectors) */
923
  &catch_exception_random,      /* 63: Trap instr (user vectors) */
924
  &catch_exception_random,      /* 64: IRQ0 */
925
  &catch_exception_random,      /* 65: IRQ1 */
926
  &catch_exception_random,      /* 66: IRQ2 */
927
  &catch_exception_random,      /* 67: IRQ3 */
928
  &catch_exception_random,      /* 68: IRQ4 */
929
  &catch_exception_random,      /* 69: IRQ5 */
930
  &catch_exception_random,      /* 70: IRQ6 */
931
  &catch_exception_random,      /* 71: IRQ7 */
932
  &catch_exception_random,
933
  &catch_exception_random,
934
  &catch_exception_random,
935
  &catch_exception_random,
936
  &catch_exception_random,
937
  &catch_exception_random,
938
  &catch_exception_random,
939
  &catch_exception_random,
940
  &catch_exception_random,
941
     &catch_exception_random,
942
     &catch_exception_random,
943
     &catch_exception_random,
944
     &catch_exception_random,
945
     &catch_exception_random,
946
     &catch_exception_random,
947
     &catch_exception_random,
948
     &catch_exception_random,
949
     &catch_exception_random,
950
     &catch_exception_random,
951
     &catch_exception_random,
952
     &catch_exception_random,
953
     &catch_exception_random,
954
     &catch_exception_random,
955
     &catch_exception_random,
956
     &catch_exception_random,
957
     &catch_exception_random,
958
     &catch_exception_random,
959
     &catch_exception_random,
960
     &catch_exception_random,
961
     &catch_exception_random,
962
     &catch_exception_random,
963
     &catch_exception_random,
964
     &catch_exception_random,
965
     &catch_exception_random,
966
     &catch_exception_random,
967
     &catch_exception_random,
968
     &catch_exception_random,
969
     &catch_exception_random,
970
     &catch_exception_random,
971
     &catch_exception_random,
972
     &catch_exception_random,
973
     &catch_exception_random,
974
     &catch_exception_random,
975
     &catch_exception_random,
976
     &catch_exception_random,
977
     &catch_exception_random,
978
     &catch_exception_random,
979
     &catch_exception_random,
980
     &catch_exception_random,
981
     &catch_exception_random,
982
     &catch_exception_random,
983
     &catch_exception_random,
984
     &catch_exception_random,
985
     &catch_exception_random,
986
     &catch_exception_random,
987
     &catch_exception_random,
988
     &catch_exception_random,
989
     &catch_exception_random,
990
     &catch_exception_random,
991
     &catch_exception_random,
992
     &catch_exception_random,
993
     &catch_exception_random,
994
     &catch_exception_random,
995
     &catch_exception_random,
996
     &catch_exception_random,
997
     &catch_exception_random,
998
     &catch_exception_random,
999
     &catch_exception_random,
1000
     &catch_exception_random,
1001
     &catch_exception_random,
1002
     &catch_exception_random,
1003
     &catch_exception_random,
1004
     &catch_exception_random,
1005
     &catch_exception_random,
1006
     &catch_exception_random,
1007
     &catch_exception_random,
1008
     &catch_exception_random,
1009
     &catch_exception_random,
1010
     &catch_exception_random,
1011
     &catch_exception_random,
1012
     &catch_exception_random,
1013
     &catch_exception_random,
1014
     &catch_exception_random,
1015
     &catch_exception_random,
1016
     &catch_exception_random,
1017
     &catch_exception_random,
1018
     &catch_exception_random,
1019
     &catch_exception_random,
1020
     &catch_exception_random,
1021
     &catch_exception_random,
1022
     &catch_exception_random,
1023
     &catch_exception_random,
1024
     &catch_exception_random,
1025
     &catch_exception_random,
1026
     &catch_exception_random,
1027
     &catch_exception_random,
1028
     &catch_exception_random,
1029
     &catch_exception_random,
1030
     &catch_exception_random,
1031
     &catch_exception_random,
1032
     &catch_exception_random,
1033
     &catch_exception_random,
1034
     &catch_exception_random,
1035
     &catch_exception_random,
1036
     &catch_exception_random,
1037
     &catch_exception_random,
1038
     &catch_exception_random,
1039
     &catch_exception_random,
1040
     &catch_exception_random,
1041
     &catch_exception_random,
1042
     &catch_exception_random,
1043
     &catch_exception_random,
1044
     &catch_exception_random,
1045
     &catch_exception_random,
1046
     &catch_exception_random,
1047
     &catch_exception_random,
1048
     &catch_exception_random,
1049
     &catch_exception_random,
1050
     &catch_exception_random,
1051
     &catch_exception_random,
1052
     &catch_exception_random,
1053
     &catch_exception_random,
1054
     &catch_exception_random,
1055
     &catch_exception_random,
1056
     &catch_exception_random,
1057
     &catch_exception_random,
1058
     &catch_exception_random,
1059
     &catch_exception_random,
1060
     &catch_exception_random,
1061
     &catch_exception_random,
1062
     &catch_exception_random,
1063
     &catch_exception_random,
1064
     &catch_exception_random,
1065
     &catch_exception_random,
1066
     &catch_exception_random,
1067
     &catch_exception_random,
1068
     &catch_exception_random,
1069
     &catch_exception_random,
1070
     &catch_exception_random,
1071
     &catch_exception_random,
1072
     &catch_exception_random,
1073
     &catch_exception_random,
1074
     &catch_exception_random,
1075
     &catch_exception_random,
1076
     &catch_exception_random,
1077
     &catch_exception_random,
1078
     &catch_exception_random,
1079
     &catch_exception_random,
1080
     &catch_exception_random,
1081
     &catch_exception_random,
1082
     &catch_exception_random,
1083
     &catch_exception_random,
1084
     &catch_exception_random,
1085
     &catch_exception_random,
1086
     &catch_exception_random,
1087
     &catch_exception_random,
1088
     &catch_exception_random,
1089
     &catch_exception_random,
1090
     &catch_exception_random,
1091
     &catch_exception_random,
1092
     &catch_exception_random,
1093
     &catch_exception_random,
1094
     &catch_exception_random,
1095
     &catch_exception_random,
1096
     &catch_exception_random,
1097
     &catch_exception_random,
1098
     &catch_exception_random,
1099
     &catch_exception_random,
1100
     &catch_exception_random,
1101
     &catch_exception_random,
1102
     &catch_exception_random,
1103
     &catch_exception_random,
1104
     &catch_exception_random,
1105
     &catch_exception_random,
1106
     &catch_exception_random,
1107
     &catch_exception_random,
1108
     &catch_exception_random,
1109
     &catch_exception_random,
1110
     &catch_exception_random,
1111
     &catch_exception_random,
1112
     &catch_exception_random,
1113
     &catch_exception_random,
1114
     &catch_exception_random,
1115
     &catch_exception_255}};
1116
 
1117
#define BCR  (*(volatile short *)(0x05FFFFA0)) /* Bus control register */
1118
#define BAS  (0x800)                            /* Byte access select */
1119
#define WCR1 (*(volatile short *)(0x05ffffA2)) /* Wait state control register */
1120
 
1121
asm ("_BINIT: mov.l  L1,r15");
1122
asm ("bra _INIT");
1123
asm ("nop");
1124
asm ("L1: .long _init_stack + 8*1024*4");
1125
void
1126
INIT (void)
1127
{
1128
  /* First turn on the ram */
1129
  WCR1  = 0;    /* Never sample wait */
1130
  BCR = BAS;    /* use lowbyte/high byte */
1131
 
1132
  init_serial();
1133
 
1134
#ifdef MONITOR
1135
  reset_hook ();
1136
#endif
1137
 
1138
 
1139
  in_nmi = 0;
1140
  dofault = 1;
1141
  stepped = 0;
1142
 
1143
  stub_sp = stub_stack + stub_stack_size;
1144
  breakpoint ();
1145
 
1146
  while (1)
1147
    ;
1148
}
1149
 
1150
 
1151
static void sr()
1152
{
1153
 
1154
 
1155
  /* Calling Reset does the same as pressing the button */
1156
  asm (".global _Reset
1157
        .global _WarmReset
1158
_Reset:
1159
_WarmReset:
1160
         mov.l L_sp,r15
1161
         bra   _INIT
1162
         nop
1163
         .align 2
1164
L_sp:    .long _init_stack + 8000");
1165
 
1166
  asm("saveRegisters:
1167
        mov.l   @(L_reg, pc), r0
1168
        mov.l   @r15+, r1                               ! pop R0
1169
        mov.l   r2, @(0x08, r0)                         ! save R2
1170
        mov.l   r1, @r0                                 ! save R0
1171
        mov.l   @r15+, r1                               ! pop R1
1172
        mov.l   r3, @(0x0c, r0)                         ! save R3
1173
        mov.l   r1, @(0x04, r0)                         ! save R1
1174
        mov.l   r4, @(0x10, r0)                         ! save R4
1175
        mov.l   r5, @(0x14, r0)                         ! save R5
1176
        mov.l   r6, @(0x18, r0)                         ! save R6
1177
        mov.l   r7, @(0x1c, r0)                         ! save R7
1178
        mov.l   r8, @(0x20, r0)                         ! save R8
1179
        mov.l   r9, @(0x24, r0)                         ! save R9
1180
        mov.l   r10, @(0x28, r0)                        ! save R10
1181
        mov.l   r11, @(0x2c, r0)                        ! save R11
1182
        mov.l   r12, @(0x30, r0)                        ! save R12
1183
        mov.l   r13, @(0x34, r0)                        ! save R13
1184
        mov.l   r14, @(0x38, r0)                        ! save R14
1185
        mov.l   @r15+, r4                               ! save arg to handleException
1186
        add     #8, r15                                 ! hide PC/SR values on stack
1187
        mov.l   r15, @(0x3c, r0)                        ! save R15
1188
        add     #-8, r15                                ! save still needs old SP value
1189
        add     #92, r0                                 ! readjust register pointer
1190
        mov     r15, r2
1191
        add     #4, r2
1192
        mov.l   @r2, r2                                 ! R2 has SR
1193
        mov.l   @r15, r1                                ! R1 has PC
1194
        mov.l   r2, @-r0                                ! save SR
1195
        sts.l   macl, @-r0                              ! save MACL
1196
        sts.l   mach, @-r0                              ! save MACH
1197
        stc.l   vbr, @-r0                               ! save VBR
1198
        stc.l   gbr, @-r0                               ! save GBR
1199
        sts.l   pr, @-r0                                ! save PR
1200
        mov.l   @(L_stubstack, pc), r2
1201
        mov.l   @(L_hdl_except, pc), r3
1202
        mov.l   @r2, r15
1203
        jsr     @r3
1204
        mov.l   r1, @-r0                                ! save PC
1205
        mov.l   @(L_stubstack, pc), r0
1206
        mov.l   @(L_reg, pc), r1
1207
        bra     restoreRegisters
1208
        mov.l   r15, @r0                                ! save __stub_stack
1209
 
1210
        .align 2
1211
L_reg:
1212
        .long   _registers
1213
L_stubstack:
1214
        .long   _stub_sp
1215
L_hdl_except:
1216
        .long   _handle_exception");
1217
 
1218
}
1219
 
1220
static void rr()
1221
{
1222
asm("
1223
        .align 2
1224
        .global _resume
1225
_resume:
1226
        mov     r4,r1
1227
restoreRegisters:
1228
        add     #8, r1                                          ! skip to R2
1229
        mov.l   @r1+, r2                                        ! restore R2
1230
        mov.l   @r1+, r3                                        ! restore R3
1231
        mov.l   @r1+, r4                                        ! restore R4
1232
        mov.l   @r1+, r5                                        ! restore R5
1233
        mov.l   @r1+, r6                                        ! restore R6
1234
        mov.l   @r1+, r7                                        ! restore R7
1235
        mov.l   @r1+, r8                                        ! restore R8
1236
        mov.l   @r1+, r9                                        ! restore R9
1237
        mov.l   @r1+, r10                                       ! restore R10
1238
        mov.l   @r1+, r11                                       ! restore R11
1239
        mov.l   @r1+, r12                                       ! restore R12
1240
        mov.l   @r1+, r13                                       ! restore R13
1241
        mov.l   @r1+, r14                                       ! restore R14
1242
        mov.l   @r1+, r15                                       ! restore programs stack
1243
        mov.l   @r1+, r0
1244
        add     #-8, r15                                        ! uncover PC/SR on stack
1245
        mov.l   r0, @r15                                        ! restore PC onto stack
1246
        lds.l   @r1+, pr                                        ! restore PR
1247
        ldc.l   @r1+, gbr                                       ! restore GBR
1248
        ldc.l   @r1+, vbr                                       ! restore VBR
1249
        lds.l   @r1+, mach                                      ! restore MACH
1250
        lds.l   @r1+, macl                                      ! restore MACL
1251
        mov.l   @r1, r0
1252
        add     #-88, r1                                        ! readjust reg pointer to R1
1253
        mov.l   r0, @(4, r15)                                   ! restore SR onto stack+4
1254
        mov.l   r2, @-r15
1255
        mov.l   L_in_nmi, r0
1256
        mov             #0, r2
1257
        mov.b   r2, @r0
1258
        mov.l   @r15+, r2
1259
        mov.l   @r1+, r0                                        ! restore R0
1260
        rte
1261
        mov.l   @r1, r1                                         ! restore R1
1262
 
1263
");
1264
}
1265
 
1266
 
1267
static __inline__ void code_for_catch_exception(int n)
1268
{
1269
  asm("         .globl  _catch_exception_%O0" : : "i" (n)                               );
1270
  asm(" _catch_exception_%O0:" :: "i" (n)                                               );
1271
 
1272
  asm("         add     #-4, r15                                ! reserve spot on stack ");
1273
  asm("         mov.l   r1, @-r15                               ! push R1               ");
1274
 
1275
  if (n == NMI_VEC)
1276
    {
1277
      /* Special case for NMI - make sure that they don't nest */
1278
      asm("     mov.l   r0, @-r15                                       ! push R0");
1279
      asm("     mov.l   L_in_nmi, r0");
1280
      asm("     tas.b   @r0                                             ! Fend off against addtnl NMIs");
1281
      asm("     bt              noNMI");
1282
      asm("     mov.l   @r15+, r0");
1283
      asm("     mov.l   @r15+, r1");
1284
      asm("     add             #4, r15");
1285
      asm("     rte");
1286
      asm("     nop");
1287
      asm(".align 2");
1288
      asm("L_in_nmi: .long      _in_nmi");
1289
      asm("noNMI:");
1290
    }
1291
  else
1292
    {
1293
 
1294
      if (n == CPU_BUS_ERROR_VEC)
1295
        {
1296
          /* Exception 9 (bus errors) are disasbleable - so that you
1297
             can probe memory and get zero instead of a fault.
1298
             Because the vector table may be in ROM we don't revector
1299
             the interrupt like all the other stubs, we check in here
1300
             */
1301
          asm("mov.l    L_dofault,r1");
1302
          asm("mov.l    @r1,r1");
1303
          asm("tst      r1,r1");
1304
          asm("bf       faultaway");
1305
          asm("bsr      _handle_buserror");
1306
          asm(".align   2");
1307
          asm("L_dofault: .long _dofault");
1308
          asm("faultaway:");
1309
        }
1310
      asm("             mov     #15<<4, r1                                                      ");
1311
      asm("             ldc     r1, sr                                  ! disable interrupts    ");
1312
      asm("             mov.l   r0, @-r15                               ! push R0               ");
1313
    }
1314
 
1315
  /* Prepare for saving context, we've already pushed r0 and r1, stick exception number
1316
     into the frame */
1317
  asm("         mov     r15, r0                                                         ");
1318
  asm("         add     #8, r0                                                          ");
1319
  asm("         mov     %0,r1" :: "i" (n)                                               );
1320
  asm("         extu.b  r1,r1                                                           ");
1321
  asm("         bra     saveRegisters                           ! save register values  ");
1322
  asm("         mov.l   r1, @r0                                 ! save exception #      ");
1323
}
1324
 
1325
 
1326
static  void
1327
exceptions (void)
1328
{
1329
  code_for_catch_exception (CPU_BUS_ERROR_VEC);
1330
  code_for_catch_exception (DMA_BUS_ERROR_VEC);
1331
  code_for_catch_exception (INVALID_INSN_VEC);
1332
  code_for_catch_exception (INVALID_SLOT_VEC);
1333
  code_for_catch_exception (NMI_VEC);
1334
  code_for_catch_exception (TRAP_VEC);
1335
  code_for_catch_exception (USER_VEC);
1336
  code_for_catch_exception (IO_VEC);
1337
}
1338
 
1339
 
1340
 
1341
 
1342
 
1343
 
1344
/* Support for Serial I/O using on chip uart */
1345
 
1346
#define SMR0 (*(volatile char *)(0x05FFFEC0)) /* Channel 0  serial mode register */
1347
#define BRR0 (*(volatile char *)(0x05FFFEC1)) /* Channel 0  bit rate register */
1348
#define SCR0 (*(volatile char *)(0x05FFFEC2)) /* Channel 0  serial control register */
1349
#define TDR0 (*(volatile char *)(0x05FFFEC3)) /* Channel 0  transmit data register */
1350
#define SSR0 (*(volatile char *)(0x05FFFEC4)) /* Channel 0  serial status register */
1351
#define RDR0 (*(volatile char *)(0x05FFFEC5)) /* Channel 0  receive data register */
1352
 
1353
#define SMR1 (*(volatile char *)(0x05FFFEC8)) /* Channel 1  serial mode register */
1354
#define BRR1 (*(volatile char *)(0x05FFFEC9)) /* Channel 1  bit rate register */
1355
#define SCR1 (*(volatile char *)(0x05FFFECA)) /* Channel 1  serial control register */
1356
#define TDR1 (*(volatile char *)(0x05FFFECB)) /* Channel 1  transmit data register */
1357
#define SSR1 (*(volatile char *)(0x05FFFECC)) /* Channel 1  serial status register */
1358
#define RDR1 (*(volatile char *)(0x05FFFECD)) /* Channel 1  receive data register */
1359
 
1360
/*
1361
 * Serial mode register bits
1362
 */
1363
 
1364
#define SYNC_MODE               0x80
1365
#define SEVEN_BIT_DATA          0x40
1366
#define PARITY_ON               0x20
1367
#define ODD_PARITY              0x10
1368
#define STOP_BITS_2             0x08
1369
#define ENABLE_MULTIP           0x04
1370
#define PHI_64                  0x03
1371
#define PHI_16                  0x02
1372
#define PHI_4                   0x01
1373
 
1374
/*
1375
 * Serial control register bits
1376
 */
1377
#define SCI_TIE                         0x80    /* Transmit interrupt enable */
1378
#define SCI_RIE                         0x40    /* Receive interrupt enable */
1379
#define SCI_TE                          0x20    /* Transmit enable */
1380
#define SCI_RE                          0x10    /* Receive enable */
1381
#define SCI_MPIE                        0x08    /* Multiprocessor interrupt enable */
1382
#define SCI_TEIE                        0x04    /* Transmit end interrupt enable */
1383
#define SCI_CKE1                        0x02    /* Clock enable 1 */
1384
#define SCI_CKE0                        0x01    /* Clock enable 0 */
1385
 
1386
/*
1387
 * Serial status register bits
1388
 */
1389
#define SCI_TDRE                        0x80    /* Transmit data register empty */
1390
#define SCI_RDRF                        0x40    /* Receive data register full */
1391
#define SCI_ORER                        0x20    /* Overrun error */
1392
#define SCI_FER                         0x10    /* Framing error */
1393
#define SCI_PER                         0x08    /* Parity error */
1394
#define SCI_TEND                        0x04    /* Transmit end */
1395
#define SCI_MPB                         0x02    /* Multiprocessor bit */
1396
#define SCI_MPBT                        0x01    /* Multiprocessor bit transfer */
1397
 
1398
 
1399
/*
1400
 * Port B IO Register (PBIOR)
1401
 */
1402
#define PBIOR           (*(volatile char *)(0x05FFFFC6))
1403
#define PB15IOR         0x8000
1404
#define PB14IOR         0x4000
1405
#define PB13IOR         0x2000
1406
#define PB12IOR         0x1000
1407
#define PB11IOR         0x0800
1408
#define PB10IOR         0x0400
1409
#define PB9IOR          0x0200
1410
#define PB8IOR          0x0100
1411
#define PB7IOR          0x0080
1412
#define PB6IOR          0x0040
1413
#define PB5IOR          0x0020
1414
#define PB4IOR          0x0010
1415
#define PB3IOR          0x0008
1416
#define PB2IOR          0x0004
1417
#define PB1IOR          0x0002
1418
#define PB0IOR          0x0001
1419
 
1420
/*
1421
 * Port B Control Register (PBCR1)
1422
 */
1423
#define PBCR1           (*(volatile short *)(0x05FFFFCC))
1424
#define PB15MD1         0x8000
1425
#define PB15MD0         0x4000
1426
#define PB14MD1         0x2000
1427
#define PB14MD0         0x1000
1428
#define PB13MD1         0x0800
1429
#define PB13MD0         0x0400
1430
#define PB12MD1         0x0200
1431
#define PB12MD0         0x0100
1432
#define PB11MD1         0x0080
1433
#define PB11MD0         0x0040
1434
#define PB10MD1         0x0020
1435
#define PB10MD0         0x0010
1436
#define PB9MD1          0x0008
1437
#define PB9MD0          0x0004
1438
#define PB8MD1          0x0002
1439
#define PB8MD0          0x0001
1440
 
1441
#define PB15MD          PB15MD1|PB14MD0
1442
#define PB14MD          PB14MD1|PB14MD0
1443
#define PB13MD          PB13MD1|PB13MD0
1444
#define PB12MD          PB12MD1|PB12MD0
1445
#define PB11MD          PB11MD1|PB11MD0
1446
#define PB10MD          PB10MD1|PB10MD0
1447
#define PB9MD           PB9MD1|PB9MD0
1448
#define PB8MD           PB8MD1|PB8MD0
1449
 
1450
#define PB_TXD1         PB11MD1
1451
#define PB_RXD1         PB10MD1
1452
#define PB_TXD0         PB9MD1
1453
#define PB_RXD0         PB8MD1
1454
 
1455
/*
1456
 * Port B Control Register (PBCR2)
1457
 */
1458
#define PBCR2   0x05FFFFCE
1459
#define PB7MD1  0x8000
1460
#define PB7MD0  0x4000
1461
#define PB6MD1  0x2000
1462
#define PB6MD0  0x1000
1463
#define PB5MD1  0x0800
1464
#define PB5MD0  0x0400
1465
#define PB4MD1  0x0200
1466
#define PB4MD0  0x0100
1467
#define PB3MD1  0x0080
1468
#define PB3MD0  0x0040
1469
#define PB2MD1  0x0020
1470
#define PB2MD0  0x0010
1471
#define PB1MD1  0x0008
1472
#define PB1MD0  0x0004
1473
#define PB0MD1  0x0002
1474
#define PB0MD0  0x0001
1475
 
1476
#define PB7MD   PB7MD1|PB7MD0
1477
#define PB6MD   PB6MD1|PB6MD0
1478
#define PB5MD   PB5MD1|PB5MD0
1479
#define PB4MD   PB4MD1|PB4MD0
1480
#define PB3MD   PB3MD1|PB3MD0
1481
#define PB2MD   PB2MD1|PB2MD0
1482
#define PB1MD   PB1MD1|PB1MD0
1483
#define PB0MD   PB0MD1|PB0MD0
1484
 
1485
 
1486
#ifdef MHZ
1487
#define BPS                     32 * 9600 * MHZ / ( BAUD * 10)
1488
#else
1489
#define BPS                     32      /* 9600 for 10 Mhz */
1490
#endif
1491
 
1492
void handleError (char theSSR);
1493
 
1494
void
1495
nop (void)
1496
{
1497
 
1498
}
1499
void
1500
init_serial (void)
1501
{
1502
  int i;
1503
 
1504
  /* Clear TE and RE in Channel 1's SCR   */
1505
  SCR1 &= ~(SCI_TE | SCI_RE);
1506
 
1507
  /* Set communication to be async, 8-bit data, no parity, 1 stop bit and use internal clock */
1508
 
1509
  SMR1 = 0;
1510
  BRR1 = BPS;
1511
 
1512
  SCR1 &= ~(SCI_CKE1 | SCI_CKE0);
1513
 
1514
  /* let the hardware settle */
1515
 
1516
  for (i = 0; i < 1000; i++)
1517
    nop ();
1518
 
1519
  /* Turn on in and out */
1520
  SCR1 |= SCI_RE | SCI_TE;
1521
 
1522
  /* Set the PFC to make RXD1 (pin PB8) an input pin and TXD1 (pin PB9) an output pin */
1523
  PBCR1 &= ~(PB_TXD1 | PB_RXD1);
1524
  PBCR1 |= PB_TXD1 | PB_RXD1;
1525
}
1526
 
1527
 
1528
int
1529
getDebugCharReady (void)
1530
{
1531
  char mySSR;
1532
  mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
1533
  if ( mySSR )
1534
    handleError ( mySSR );
1535
  return SSR1 & SCI_RDRF ;
1536
}
1537
 
1538
char
1539
getDebugChar (void)
1540
{
1541
  char ch;
1542
  char mySSR;
1543
 
1544
  while ( ! getDebugCharReady())
1545
    ;
1546
 
1547
  ch = RDR1;
1548
  SSR1 &= ~SCI_RDRF;
1549
 
1550
  mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
1551
 
1552
  if (mySSR)
1553
    handleError (mySSR);
1554
 
1555
  return ch;
1556
}
1557
 
1558
int
1559
putDebugCharReady (void)
1560
{
1561
  return (SSR1 & SCI_TDRE);
1562
}
1563
 
1564
void
1565
putDebugChar (char ch)
1566
{
1567
  while (!putDebugCharReady())
1568
    ;
1569
 
1570
  /*
1571
   * Write data into TDR and clear TDRE
1572
   */
1573
  TDR1 = ch;
1574
  SSR1 &= ~SCI_TDRE;
1575
}
1576
 
1577
void
1578
handleError (char theSSR)
1579
{
1580
  SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
1581
}
1582
 
1583
#endif

powered by: WebSVN 2.1.0

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