gdb/stubs/sh-stub.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* sh-stub.c -- debugging stub for the Renesas-SH.

  2. NOTE!! This code has to be compiled with optimization, otherwise the
  3. function inlining which generates the exception handlers won't work.

  4. */

  5. /*   This is originally based on an m68k software stub written by Glenn
  6.      Engel at HP, but has changed quite a bit.

  7.      Modifications for the SH by Ben Lee and Steve Chamberlain

  8. */

  9. /****************************************************************************

  10.                 THIS SOFTWARE IS NOT COPYRIGHTED

  11.    HP offers the following for use in the public domain.  HP makes no
  12.    warranty with regard to the software or it's performance and the
  13.    user accepts the software "AS IS" with all faults.

  14.    HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
  15.    TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  16.    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

  17. ****************************************************************************/


  18. /* Remote communication protocol.

  19.    A debug packet whose contents are <data>
  20.    is encapsulated for transmission in the form:

  21.         $ <data> # CSUM1 CSUM2

  22.         <data> must be ASCII alphanumeric and cannot include characters
  23.         '$' or '#'.  If <data> starts with two characters followed by
  24.         ':', then the existing stubs interpret this as a sequence number.

  25.         CSUM1 and CSUM2 are ascii hex representation of an 8-bit
  26.         checksum of <data>, the most significant nibble is sent first.
  27.         the hex digits 0-9,a-f are used.

  28.    Receiver responds with:

  29.         +        - if CSUM is correct and ready for next packet
  30.         -        - if CSUM is incorrect

  31.    <data> is as follows:
  32.    All values are encoded in ascii hex digits.

  33.         Request                Packet

  34.         read registers  g
  35.         reply                XX....X                Each byte of register data
  36.                                         is described by two hex digits.
  37.                                         Registers are in the internal order
  38.                                         for GDB, and the bytes in a register
  39.                                         are in the same order the machine uses.
  40.                         or ENN                for an error.

  41.         write regs        GXX..XX                Each byte of register data
  42.                                         is described by two hex digits.
  43.         reply                OK                for success
  44.                         ENN                for an error

  45.         write reg        Pn...=r...        Write register n... with value r...,
  46.                                         which contains two hex digits for each
  47.                                         byte in the register (target byte
  48.                                         order).
  49.         reply                OK                for success
  50.                         ENN                for an error
  51.         (not supported by all stubs).

  52.         read mem        mAA..AA,LLLL        AA..AA is address, LLLL is length.
  53.         reply                XX..XX                XX..XX is mem contents
  54.                                         Can be fewer bytes than requested
  55.                                         if able to read only part of the data.
  56.                         or ENN                NN is errno

  57.         write mem        MAA..AA,LLLL:XX..XX
  58.                                         AA..AA is address,
  59.                                         LLLL is number of bytes,
  60.                                         XX..XX is data
  61.         reply                OK                for success
  62.                         ENN                for an error (this includes the case
  63.                                         where only part of the data was
  64.                                         written).

  65.         cont                cAA..AA                AA..AA is address to resume
  66.                                         If AA..AA is omitted,
  67.                                         resume at same address.

  68.         step                sAA..AA                AA..AA is address to resume
  69.                                         If AA..AA is omitted,
  70.                                         resume at same address.

  71.         last signal     ?               Reply the current reason for stopping.
  72.                                         This is the same reply as is generated
  73.                                         for step or cont : SAA where AA is the
  74.                                         signal number.

  75.         There is no immediate reply to step or cont.
  76.         The reply comes when the machine stops.
  77.         It is                SAA                AA is the "signal number"

  78.         or...                TAAn...:r...;n:r...;n...:r...;
  79.                                         AA = signal number
  80.                                         n... = register number
  81.                                         r... = register contents
  82.         or...                WAA                The process exited, and AA is
  83.                                         the exit status.  This is only
  84.                                         applicable for certains sorts of
  85.                                         targets.
  86.         kill request        k

  87.         toggle debug        d                toggle debug flag (see 386 & 68k stubs)
  88.         reset                r                reset -- see sparc stub.
  89.         reserved        <other>                On other requests, the stub should
  90.                                         ignore the request and send an empty
  91.                                         response ($#<checksum>).  This way
  92.                                         we can extend the protocol and GDB
  93.                                         can tell whether the stub it is
  94.                                         talking to uses the old or the new.
  95.         search                tAA:PP,MM        Search backwards starting at address
  96.                                         AA for a match with pattern PP and
  97.                                         mask MM.  PP and MM are 4 bytes.
  98.                                         Not supported by all stubs.

  99.         general query        qXXXX                Request info about XXXX.
  100.         general set        QXXXX=yyyy        Set value of XXXX to yyyy.
  101.         query sect offs        qOffsets        Get section offsets.  Reply is
  102.                                         Text=xxx;Data=yyy;Bss=zzz
  103.         console output        Otext                Send text to stdout.  Only comes from
  104.                                         remote target.

  105.         Responses can be run-length encoded to save space.  A '*' means that
  106.         the next character is an ASCII encoding giving a repeat count which
  107.         stands for that many repititions of the character preceding the '*'.
  108.         The encoding is n+29, yielding a printable character where n >=3
  109.         (which is where rle starts to win).  Don't use an n > 126.

  110.         So
  111.         "0* " means the same as "0000".  */

  112. #include <string.h>
  113. #include <setjmp.h>

  114. /* Renesas SH architecture instruction encoding masks */

  115. #define COND_BR_MASK   0xff00
  116. #define UCOND_DBR_MASK 0xe000
  117. #define UCOND_RBR_MASK 0xf0df
  118. #define TRAPA_MASK     0xff00

  119. #define COND_DISP      0x00ff
  120. #define UCOND_DISP     0x0fff
  121. #define UCOND_REG      0x0f00

  122. /* Renesas SH instruction opcodes */

  123. #define BF_INSTR       0x8b00
  124. #define BT_INSTR       0x8900
  125. #define BRA_INSTR      0xa000
  126. #define BSR_INSTR      0xb000
  127. #define JMP_INSTR      0x402b
  128. #define JSR_INSTR      0x400b
  129. #define RTS_INSTR      0x000b
  130. #define RTE_INSTR      0x002b
  131. #define TRAPA_INSTR    0xc300
  132. #define SSTEP_INSTR    0xc3ff

  133. /* Renesas SH processor register masks */

  134. #define T_BIT_MASK     0x0001

  135. /*
  136. * BUFMAX defines the maximum number of characters in inbound/outbound
  137. * buffers. At least NUMREGBYTES*2 are needed for register packets.
  138. */
  139. #define BUFMAX 1024

  140. /*
  141. * Number of bytes for registers
  142. */
  143. #define NUMREGBYTES 112                /* 92 */

  144. /*
  145. * typedef
  146. */
  147. typedef void (*Function) ();

  148. /*
  149. * Forward declarations
  150. */

  151. static int hex (char);
  152. static char *mem2hex (char *, char *, int);
  153. static char *hex2mem (char *, char *, int);
  154. static int hexToInt (char **, int *);
  155. static unsigned char *getpacket (void);
  156. static void putpacket (char *);
  157. static void handle_buserror (void);
  158. static int computeSignal (int exceptionVector);
  159. static void handle_exception (int exceptionVector);
  160. void init_serial();

  161. void putDebugChar (char);
  162. char getDebugChar (void);

  163. /* These are in the file but in asm statements so the compiler can't see them */
  164. void catch_exception_4 (void);
  165. void catch_exception_6 (void);
  166. void catch_exception_9 (void);
  167. void catch_exception_10 (void);
  168. void catch_exception_11 (void);
  169. void catch_exception_32 (void);
  170. void catch_exception_33 (void);
  171. void catch_exception_255 (void);



  172. #define catch_exception_random catch_exception_255 /* Treat all odd ones like 255 */

  173. void breakpoint (void);


  174. #define init_stack_size 8*1024  /* if you change this you should also modify BINIT */
  175. #define stub_stack_size 8*1024

  176. int init_stack[init_stack_size] __attribute__ ((section ("stack"))) = {0};
  177. int stub_stack[stub_stack_size] __attribute__ ((section ("stack"))) = {0};


  178. void INIT ();
  179. void BINIT ();

  180. #define CPU_BUS_ERROR_VEC  9
  181. #define DMA_BUS_ERROR_VEC 10
  182. #define NMI_VEC           11
  183. #define INVALID_INSN_VEC   4
  184. #define INVALID_SLOT_VEC   6
  185. #define TRAP_VEC          32
  186. #define IO_VEC            33
  187. #define USER_VEC         255



  188. char in_nmi;   /* Set when handling an NMI, so we don't reenter */
  189. int dofault/* Non zero, bus errors will raise exception */

  190. int *stub_sp;

  191. /* debug > 0 prints ill-formed commands in valid packets & checksum errors */
  192. int remote_debug;

  193. /* jump buffer used for setjmp/longjmp */
  194. jmp_buf remcomEnv;

  195. enum regnames
  196.   {
  197.     R0, R1, R2, R3, R4, R5, R6, R7,
  198.     R8, R9, R10, R11, R12, R13, R14,
  199.     R15, PC, PR, GBR, VBR, MACH, MACL, SR,
  200.     TICKS, STALLS, CYCLES, INSTS, PLR
  201.   };

  202. typedef struct
  203.   {
  204.     short *memAddr;
  205.     short oldInstr;
  206.   }
  207. stepData;

  208. int registers[NUMREGBYTES / 4];
  209. stepData instrBuffer;
  210. char stepped;
  211. static const char hexchars[] = "0123456789abcdef";
  212. static char remcomInBuffer[BUFMAX];
  213. static char remcomOutBuffer[BUFMAX];

  214. char highhex(int  x)
  215. {
  216.   return hexchars[(x >> 4) & 0xf];
  217. }

  218. char lowhex(int  x)
  219. {
  220.   return hexchars[x & 0xf];
  221. }

  222. /*
  223. * Assembly macros
  224. */

  225. #define BREAKPOINT()   asm("trapa        #0x20"::);


  226. /*
  227. * Routines to handle hex data
  228. */

  229. static int
  230. hex (char ch)
  231. {
  232.   if ((ch >= 'a') && (ch <= 'f'))
  233.     return (ch - 'a' + 10);
  234.   if ((ch >= '0') && (ch <= '9'))
  235.     return (ch - '0');
  236.   if ((ch >= 'A') && (ch <= 'F'))
  237.     return (ch - 'A' + 10);
  238.   return (-1);
  239. }

  240. /* convert the memory, pointed to by mem into hex, placing result in buf */
  241. /* return a pointer to the last char put in buf (null) */
  242. static char *
  243. mem2hex (char *mem, char *buf, int count)
  244. {
  245.   int i;
  246.   int ch;
  247.   for (i = 0; i < count; i++)
  248.     {
  249.       ch = *mem++;
  250.       *buf++ = highhex (ch);
  251.       *buf++ = lowhex (ch);
  252.     }
  253.   *buf = 0;
  254.   return (buf);
  255. }

  256. /* convert the hex array pointed to by buf into binary, to be placed in mem */
  257. /* return a pointer to the character after the last byte written */

  258. static char *
  259. hex2mem (char *buf, char *mem, int count)
  260. {
  261.   int i;
  262.   unsigned char ch;
  263.   for (i = 0; i < count; i++)
  264.     {
  265.       ch = hex (*buf++) << 4;
  266.       ch = ch + hex (*buf++);
  267.       *mem++ = ch;
  268.     }
  269.   return (mem);
  270. }

  271. /**********************************************/
  272. /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
  273. /* RETURN NUMBER OF CHARS PROCESSED           */
  274. /**********************************************/
  275. static int
  276. hexToInt (char **ptr, int *intValue)
  277. {
  278.   int numChars = 0;
  279.   int hexValue;

  280.   *intValue = 0;

  281.   while (**ptr)
  282.     {
  283.       hexValue = hex (**ptr);
  284.       if (hexValue >= 0)
  285.         {
  286.           *intValue = (*intValue << 4) | hexValue;
  287.           numChars++;
  288.         }
  289.       else
  290.         break;

  291.       (*ptr)++;
  292.     }

  293.   return (numChars);
  294. }

  295. /*
  296. * Routines to get and put packets
  297. */

  298. /* scan for the sequence $<data>#<checksum>     */

  299. char *
  300. getpacket (void)
  301. {
  302.   unsigned char *buffer = &remcomInBuffer[0];
  303.   unsigned char checksum;
  304.   unsigned char xmitcsum;
  305.   int count;
  306.   char ch;

  307.   while (1)
  308.     {
  309.       /* wait around for the start character, ignore all other characters */
  310.       while ((ch = getDebugChar ()) != '$')
  311.         ;

  312. retry:
  313.       checksum = 0;
  314.       xmitcsum = -1;
  315.       count = 0;

  316.       /* now, read until a # or end of buffer is found */
  317.       while (count < BUFMAX - 1)
  318.         {
  319.           ch = getDebugChar ();
  320.           if (ch == '$')
  321.             goto retry;
  322.           if (ch == '#')
  323.             break;
  324.           checksum = checksum + ch;
  325.           buffer[count] = ch;
  326.           count = count + 1;
  327.         }
  328.       buffer[count] = 0;

  329.       if (ch == '#')
  330.         {
  331.            ch = getDebugChar ();
  332.            xmitcsum = hex (ch) << 4;
  333.            ch = getDebugChar ();
  334.            xmitcsum += hex (ch);

  335.           if (checksum != xmitcsum)
  336.             {
  337.               putDebugChar ('-');        /* failed checksum */
  338.             }
  339.           else
  340.             {
  341.               putDebugChar ('+');        /* successful transfer */

  342.               /* if a sequence char is present, reply the sequence ID */
  343.               if (buffer[2] == ':')
  344.                 {
  345.                   putDebugChar (buffer[0]);
  346.                   putDebugChar (buffer[1]);

  347.                    return &buffer[3];
  348.                 }

  349.               return &buffer[0];
  350.             }
  351.         }
  352.     }
  353. }


  354. /* send the packet in buffer. */

  355. static void
  356. putpacket (char *buffer)
  357. {
  358.   int checksum;
  359.   int count;

  360.   /*  $<packet info>#<checksum>. */
  361.   do
  362.     {
  363.       char *src = buffer;
  364.       putDebugChar ('$');
  365.       checksum = 0;

  366.       while (*src)
  367.         {
  368.           int runlen;

  369.           /* Do run length encoding */
  370.           for (runlen = 0; runlen < 100; runlen ++)
  371.             {
  372.               if (src[0] != src[runlen])
  373.                 {
  374.                   if (runlen > 3)
  375.                     {
  376.                       int encode;
  377.                       /* Got a useful amount */
  378.                       putDebugChar (*src);
  379.                       checksum += *src;
  380.                       putDebugChar ('*');
  381.                       checksum += '*';
  382.                       checksum += (encode = runlen + ' ' - 4);
  383.                       putDebugChar (encode);
  384.                       src += runlen;
  385.                     }
  386.                   else
  387.                     {
  388.                       putDebugChar (*src);
  389.                       checksum += *src;
  390.                       src++;
  391.                     }
  392.                   break;
  393.                 }
  394.             }
  395.         }


  396.       putDebugChar ('#');
  397.       putDebugChar (highhex(checksum));
  398.       putDebugChar (lowhex(checksum));
  399.     }
  400.   while  (getDebugChar() != '+');
  401. }


  402. /* a bus error has occurred, perform a longjmp
  403.    to return execution and allow handling of the error */

  404. void
  405. handle_buserror (void)
  406. {
  407.   longjmp (remcomEnv, 1);
  408. }

  409. /*
  410. * this function takes the SH-1 exception number and attempts to
  411. * translate this number into a unix compatible signal value
  412. */
  413. static int
  414. computeSignal (int exceptionVector)
  415. {
  416.   int sigval;
  417.   switch (exceptionVector)
  418.     {
  419.     case INVALID_INSN_VEC:
  420.       sigval = 4;
  421.       break;
  422.     case INVALID_SLOT_VEC:
  423.       sigval = 4;
  424.       break;
  425.     case CPU_BUS_ERROR_VEC:
  426.       sigval = 10;
  427.       break;
  428.     case DMA_BUS_ERROR_VEC:
  429.       sigval = 10;
  430.       break;
  431.     case NMI_VEC:
  432.       sigval = 2;
  433.       break;

  434.     case TRAP_VEC:
  435.     case USER_VEC:
  436.       sigval = 5;
  437.       break;

  438.     default:
  439.       sigval = 7;                /* "software generated"*/
  440.       break;
  441.     }
  442.   return (sigval);
  443. }

  444. void
  445. doSStep (void)
  446. {
  447.   short *instrMem;
  448.   int displacement;
  449.   int reg;
  450.   unsigned short opcode;

  451.   instrMem = (short *) registers[PC];

  452.   opcode = *instrMem;
  453.   stepped = 1;

  454.   if ((opcode & COND_BR_MASK) == BT_INSTR)
  455.     {
  456.       if (registers[SR] & T_BIT_MASK)
  457.         {
  458.           displacement = (opcode & COND_DISP) << 1;
  459.           if (displacement & 0x80)
  460.             displacement |= 0xffffff00;
  461.           /*
  462.                    * Remember PC points to second instr.
  463.                    * after PC of branch ... so add 4
  464.                    */
  465.           instrMem = (short *) (registers[PC] + displacement + 4);
  466.         }
  467.       else
  468.         instrMem += 1;
  469.     }
  470.   else if ((opcode & COND_BR_MASK) == BF_INSTR)
  471.     {
  472.       if (registers[SR] & T_BIT_MASK)
  473.         instrMem += 1;
  474.       else
  475.         {
  476.           displacement = (opcode & COND_DISP) << 1;
  477.           if (displacement & 0x80)
  478.             displacement |= 0xffffff00;
  479.           /*
  480.                    * Remember PC points to second instr.
  481.                    * after PC of branch ... so add 4
  482.                    */
  483.           instrMem = (short *) (registers[PC] + displacement + 4);
  484.         }
  485.     }
  486.   else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
  487.     {
  488.       displacement = (opcode & UCOND_DISP) << 1;
  489.       if (displacement & 0x0800)
  490.         displacement |= 0xfffff000;

  491.       /*
  492.            * Remember PC points to second instr.
  493.            * after PC of branch ... so add 4
  494.            */
  495.       instrMem = (short *) (registers[PC] + displacement + 4);
  496.     }
  497.   else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
  498.     {
  499.       reg = (char) ((opcode & UCOND_REG) >> 8);

  500.       instrMem = (short *) registers[reg];
  501.     }
  502.   else if (opcode == RTS_INSTR)
  503.     instrMem = (short *) registers[PR];
  504.   else if (opcode == RTE_INSTR)
  505.     instrMem = (short *) registers[15];
  506.   else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
  507.     instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
  508.   else
  509.     instrMem += 1;

  510.   instrBuffer.memAddr = instrMem;
  511.   instrBuffer.oldInstr = *instrMem;
  512.   *instrMem = SSTEP_INSTR;
  513. }


  514. /* Undo the effect of a previous doSStep.  If we single stepped,
  515.    restore the old instruction. */

  516. void
  517. undoSStep (void)
  518. {
  519.   if (stepped)
  520.     {  short *instrMem;
  521.       instrMem = instrBuffer.memAddr;
  522.       *instrMem = instrBuffer.oldInstr;
  523.     }
  524.   stepped = 0;
  525. }

  526. /*
  527. This function does all exception handling.  It only does two things -
  528. it figures out why it was called and tells gdb, and then it reacts
  529. to gdb's requests.

  530. When in the monitor mode we talk a human on the serial line rather than gdb.

  531. */


  532. void
  533. gdb_handle_exception (int exceptionVector)
  534. {
  535.   int sigval, stepping;
  536.   int addr, length;
  537.   char *ptr;

  538.   /* reply to host that an exception has occurred */
  539.   sigval = computeSignal (exceptionVector);
  540.   remcomOutBuffer[0] = 'S';
  541.   remcomOutBuffer[1] = highhex(sigval);
  542.   remcomOutBuffer[2] = lowhex (sigval);
  543.   remcomOutBuffer[3] = 0;

  544.   putpacket (remcomOutBuffer);

  545.   /*
  546.    * exception 255 indicates a software trap
  547.    * inserted in place of code ... so back up
  548.    * PC by one instruction, since this instruction
  549.    * will later be replaced by its original one!
  550.    */
  551.   if (exceptionVector == 0xff
  552.       || exceptionVector == 0x20)
  553.     registers[PC] -= 2;

  554.   /*
  555.    * Do the thangs needed to undo
  556.    * any stepping we may have done!
  557.    */
  558.   undoSStep ();

  559.   stepping = 0;

  560.   while (1)
  561.     {
  562.       remcomOutBuffer[0] = 0;
  563.       ptr = getpacket ();

  564.       switch (*ptr++)
  565.         {
  566.         case '?':
  567.           remcomOutBuffer[0] = 'S';
  568.           remcomOutBuffer[1] = highhex (sigval);
  569.           remcomOutBuffer[2] = lowhex (sigval);
  570.           remcomOutBuffer[3] = 0;
  571.           break;
  572.         case 'd':
  573.           remote_debug = !(remote_debug);        /* toggle debug flag */
  574.           break;
  575.         case 'g':                /* return the value of the CPU registers */
  576.           mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
  577.           break;
  578.         case 'G':                /* set the value of the CPU registers - return OK */
  579.           hex2mem (ptr, (char *) registers, NUMREGBYTES);
  580.           strcpy (remcomOutBuffer, "OK");
  581.           break;

  582.           /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
  583.         case 'm':
  584.           if (setjmp (remcomEnv) == 0)
  585.             {
  586.               dofault = 0;
  587.               /* TRY, TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
  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.               if (ptr)
  596.                 strcpy (remcomOutBuffer, "E01");
  597.             }
  598.           else
  599.             strcpy (remcomOutBuffer, "E03");

  600.           /* restore handler for bus error */
  601.           dofault = 1;
  602.           break;

  603.           /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
  604.         case 'M':
  605.           if (setjmp (remcomEnv) == 0)
  606.             {
  607.               dofault = 0;

  608.               /* TRY, TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
  609.               if (hexToInt (&ptr, &addr))
  610.                 if (*(ptr++) == ',')
  611.                   if (hexToInt (&ptr, &length))
  612.                     if (*(ptr++) == ':')
  613.                       {
  614.                         hex2mem (ptr, (char *) addr, length);
  615.                         ptr = 0;
  616.                         strcpy (remcomOutBuffer, "OK");
  617.                       }
  618.               if (ptr)
  619.                 strcpy (remcomOutBuffer, "E02");
  620.             }
  621.           else
  622.             strcpy (remcomOutBuffer, "E03");

  623.           /* restore handler for bus error */
  624.           dofault = 1;
  625.           break;

  626.           /* cAA..AA    Continue at address AA..AA(optional) */
  627.           /* sAA..AA   Step one instruction from AA..AA(optional) */
  628.         case 's':
  629.           stepping = 1;
  630.         case 'c':
  631.           {
  632.             /* tRY, to read optional parameter, pc unchanged if no parm */
  633.             if (hexToInt (&ptr, &addr))
  634.               registers[PC] = addr;

  635.             if (stepping)
  636.               doSStep ();
  637.           }
  638.           return;
  639.           break;

  640.           /* kill the program */
  641.         case 'k':                /* do nothing */
  642.           break;
  643.         }                        /* switch */

  644.       /* reply to the request */
  645.       putpacket (remcomOutBuffer);
  646.     }
  647. }


  648. #define GDBCOOKIE 0x5ac
  649. static int ingdbmode;
  650. /* We've had an exception - choose to go into the monitor or
  651.    the gdb stub */
  652. void handle_exception(int exceptionVector)
  653. {
  654. #ifdef MONITOR
  655.     if (ingdbmode != GDBCOOKIE)
  656.       monitor_handle_exception (exceptionVector);
  657.     else
  658. #endif
  659.       gdb_handle_exception (exceptionVector);

  660. }

  661. void
  662. gdb_mode (void)
  663. {
  664.   ingdbmode = GDBCOOKIE;
  665.   breakpoint();
  666. }
  667. /* This function will generate a breakpoint exception.  It is used at the
  668.    beginning of a program to sync up with a debugger and can be used
  669.    otherwise as a quick means to stop program execution and "break" into
  670.    the debugger. */

  671. void
  672. breakpoint (void)
  673. {
  674.       BREAKPOINT ();
  675. }

  676. /**** Processor-specific routines start here ****/
  677. /**** Processor-specific routines start here ****/
  678. /**** Processor-specific routines start here ****/

  679. /* Note:

  680.    The Renesas SH family uses two exception architectures:

  681.    SH1 & SH2:

  682.        These processors utilize an exception vector table.
  683.        Exceptions are vectored to the address stored at VBR + (exception_num * 4)

  684.   SH3, SH3E, & SH4:

  685.        These processors have fixed entry points relative to the VBR for
  686.        various exception classes.
  687. */

  688. #if defined(__sh1__) || defined(__sh2__)

  689. /* SH1/SH2 exception vector table format */

  690. typedef struct
  691.   {
  692.     void (*func_cold) ();
  693.     int *stack_cold;
  694.     void (*func_warm) ();
  695.     int *stack_warm;
  696.     void (*(handler[256 - 4])) ();
  697.   }
  698. vec_type;

  699. /* vectable is the SH1/SH2 vector table. It must be at address 0
  700.    or wherever your vbr points. */

  701. const vec_type vectable =
  702. {
  703.   &BINIT,                        /* 0: Power-on reset PC */
  704.   init_stack + init_stack_size, /* 1: Power-on reset SP */
  705.   &BINIT,                        /* 2: Manual reset PC */
  706.   init_stack + init_stack_size, /* 3: Manual reset SP */
  707. {
  708.   &catch_exception_4,                /* 4: General invalid instruction */
  709.   &catch_exception_random,        /* 5: Reserved for system */
  710.   &catch_exception_6,                /* 6: Invalid slot instruction */
  711.   &catch_exception_random,        /* 7: Reserved for system */
  712.   &catch_exception_random,        /* 8: Reserved for system */
  713.   &catch_exception_9,                /* 9: CPU bus error */
  714.   &catch_exception_10,                /* 10: DMA bus error */
  715.   &catch_exception_11,                /* 11: NMI */
  716.   &catch_exception_random,        /* 12: User break */
  717.   &catch_exception_random,        /* 13: Reserved for system */
  718.   &catch_exception_random,        /* 14: Reserved for system */
  719.   &catch_exception_random,        /* 15: Reserved for system */
  720.   &catch_exception_random,        /* 16: Reserved for system */
  721.   &catch_exception_random,        /* 17: Reserved for system */
  722.   &catch_exception_random,        /* 18: Reserved for system */
  723.   &catch_exception_random,        /* 19: Reserved for system */
  724.   &catch_exception_random,        /* 20: Reserved for system */
  725.   &catch_exception_random,        /* 21: Reserved for system */
  726.   &catch_exception_random,        /* 22: Reserved for system */
  727.   &catch_exception_random,        /* 23: Reserved for system */
  728.   &catch_exception_random,        /* 24: Reserved for system */
  729.   &catch_exception_random,        /* 25: Reserved for system */
  730.   &catch_exception_random,        /* 26: Reserved for system */
  731.   &catch_exception_random,        /* 27: Reserved for system */
  732.   &catch_exception_random,        /* 28: Reserved for system */
  733.   &catch_exception_random,        /* 29: Reserved for system */
  734.   &catch_exception_random,        /* 30: Reserved for system */
  735.   &catch_exception_random,        /* 31: Reserved for system */
  736.   &catch_exception_32,                /* 32: Trap instr (user vectors) */
  737.   &catch_exception_33,                /* 33: Trap instr (user vectors) */
  738.   &catch_exception_random,        /* 34: Trap instr (user vectors) */
  739.   &catch_exception_random,        /* 35: Trap instr (user vectors) */
  740.   &catch_exception_random,        /* 36: Trap instr (user vectors) */
  741.   &catch_exception_random,        /* 37: Trap instr (user vectors) */
  742.   &catch_exception_random,        /* 38: Trap instr (user vectors) */
  743.   &catch_exception_random,        /* 39: Trap instr (user vectors) */
  744.   &catch_exception_random,        /* 40: Trap instr (user vectors) */
  745.   &catch_exception_random,        /* 41: Trap instr (user vectors) */
  746.   &catch_exception_random,        /* 42: Trap instr (user vectors) */
  747.   &catch_exception_random,        /* 43: Trap instr (user vectors) */
  748.   &catch_exception_random,        /* 44: Trap instr (user vectors) */
  749.   &catch_exception_random,        /* 45: Trap instr (user vectors) */
  750.   &catch_exception_random,        /* 46: Trap instr (user vectors) */
  751.   &catch_exception_random,        /* 47: Trap instr (user vectors) */
  752.   &catch_exception_random,        /* 48: Trap instr (user vectors) */
  753.   &catch_exception_random,        /* 49: Trap instr (user vectors) */
  754.   &catch_exception_random,        /* 50: Trap instr (user vectors) */
  755.   &catch_exception_random,        /* 51: Trap instr (user vectors) */
  756.   &catch_exception_random,        /* 52: Trap instr (user vectors) */
  757.   &catch_exception_random,        /* 53: Trap instr (user vectors) */
  758.   &catch_exception_random,        /* 54: Trap instr (user vectors) */
  759.   &catch_exception_random,        /* 55: Trap instr (user vectors) */
  760.   &catch_exception_random,        /* 56: Trap instr (user vectors) */
  761.   &catch_exception_random,        /* 57: Trap instr (user vectors) */
  762.   &catch_exception_random,        /* 58: Trap instr (user vectors) */
  763.   &catch_exception_random,        /* 59: Trap instr (user vectors) */
  764.   &catch_exception_random,        /* 60: Trap instr (user vectors) */
  765.   &catch_exception_random,        /* 61: Trap instr (user vectors) */
  766.   &catch_exception_random,        /* 62: Trap instr (user vectors) */
  767.   &catch_exception_random,        /* 63: Trap instr (user vectors) */
  768.   &catch_exception_random,        /* 64: IRQ0 */
  769.   &catch_exception_random,        /* 65: IRQ1 */
  770.   &catch_exception_random,        /* 66: IRQ2 */
  771.   &catch_exception_random,        /* 67: IRQ3 */
  772.   &catch_exception_random,        /* 68: IRQ4 */
  773.   &catch_exception_random,        /* 69: IRQ5 */
  774.   &catch_exception_random,        /* 70: IRQ6 */
  775.   &catch_exception_random,        /* 71: IRQ7 */
  776.   &catch_exception_random,
  777.   &catch_exception_random,
  778.   &catch_exception_random,
  779.   &catch_exception_random,
  780.   &catch_exception_random,
  781.   &catch_exception_random,
  782.   &catch_exception_random,
  783.   &catch_exception_random,
  784.   &catch_exception_random,
  785.      &catch_exception_random,
  786.      &catch_exception_random,
  787.      &catch_exception_random,
  788.      &catch_exception_random,
  789.      &catch_exception_random,
  790.      &catch_exception_random,
  791.      &catch_exception_random,
  792.      &catch_exception_random,
  793.      &catch_exception_random,
  794.      &catch_exception_random,
  795.      &catch_exception_random,
  796.      &catch_exception_random,
  797.      &catch_exception_random,
  798.      &catch_exception_random,
  799.      &catch_exception_random,
  800.      &catch_exception_random,
  801.      &catch_exception_random,
  802.      &catch_exception_random,
  803.      &catch_exception_random,
  804.      &catch_exception_random,
  805.      &catch_exception_random,
  806.      &catch_exception_random,
  807.      &catch_exception_random,
  808.      &catch_exception_random,
  809.      &catch_exception_random,
  810.      &catch_exception_random,
  811.      &catch_exception_random,
  812.      &catch_exception_random,
  813.      &catch_exception_random,
  814.      &catch_exception_random,
  815.      &catch_exception_random,
  816.      &catch_exception_random,
  817.      &catch_exception_random,
  818.      &catch_exception_random,
  819.      &catch_exception_random,
  820.      &catch_exception_random,
  821.      &catch_exception_random,
  822.      &catch_exception_random,
  823.      &catch_exception_random,
  824.      &catch_exception_random,
  825.      &catch_exception_random,
  826.      &catch_exception_random,
  827.      &catch_exception_random,
  828.      &catch_exception_random,
  829.      &catch_exception_random,
  830.      &catch_exception_random,
  831.      &catch_exception_random,
  832.      &catch_exception_random,
  833.      &catch_exception_random,
  834.      &catch_exception_random,
  835.      &catch_exception_random,
  836.      &catch_exception_random,
  837.      &catch_exception_random,
  838.      &catch_exception_random,
  839.      &catch_exception_random,
  840.      &catch_exception_random,
  841.      &catch_exception_random,
  842.      &catch_exception_random,
  843.      &catch_exception_random,
  844.      &catch_exception_random,
  845.      &catch_exception_random,
  846.      &catch_exception_random,
  847.      &catch_exception_random,
  848.      &catch_exception_random,
  849.      &catch_exception_random,
  850.      &catch_exception_random,
  851.      &catch_exception_random,
  852.      &catch_exception_random,
  853.      &catch_exception_random,
  854.      &catch_exception_random,
  855.      &catch_exception_random,
  856.      &catch_exception_random,
  857.      &catch_exception_random,
  858.      &catch_exception_random,
  859.      &catch_exception_random,
  860.      &catch_exception_random,
  861.      &catch_exception_random,
  862.      &catch_exception_random,
  863.      &catch_exception_random,
  864.      &catch_exception_random,
  865.      &catch_exception_random,
  866.      &catch_exception_random,
  867.      &catch_exception_random,
  868.      &catch_exception_random,
  869.      &catch_exception_random,
  870.      &catch_exception_random,
  871.      &catch_exception_random,
  872.      &catch_exception_random,
  873.      &catch_exception_random,
  874.      &catch_exception_random,
  875.      &catch_exception_random,
  876.      &catch_exception_random,
  877.      &catch_exception_random,
  878.      &catch_exception_random,
  879.      &catch_exception_random,
  880.      &catch_exception_random,
  881.      &catch_exception_random,
  882.      &catch_exception_random,
  883.      &catch_exception_random,
  884.      &catch_exception_random,
  885.      &catch_exception_random,
  886.      &catch_exception_random,
  887.      &catch_exception_random,
  888.      &catch_exception_random,
  889.      &catch_exception_random,
  890.      &catch_exception_random,
  891.      &catch_exception_random,
  892.      &catch_exception_random,
  893.      &catch_exception_random,
  894.      &catch_exception_random,
  895.      &catch_exception_random,
  896.      &catch_exception_random,
  897.      &catch_exception_random,
  898.      &catch_exception_random,
  899.      &catch_exception_random,
  900.      &catch_exception_random,
  901.      &catch_exception_random,
  902.      &catch_exception_random,
  903.      &catch_exception_random,
  904.      &catch_exception_random,
  905.      &catch_exception_random,
  906.      &catch_exception_random,
  907.      &catch_exception_random,
  908.      &catch_exception_random,
  909.      &catch_exception_random,
  910.      &catch_exception_random,
  911.      &catch_exception_random,
  912.      &catch_exception_random,
  913.      &catch_exception_random,
  914.      &catch_exception_random,
  915.      &catch_exception_random,
  916.      &catch_exception_random,
  917.      &catch_exception_random,
  918.      &catch_exception_random,
  919.      &catch_exception_random,
  920.      &catch_exception_random,
  921.      &catch_exception_random,
  922.      &catch_exception_random,
  923.      &catch_exception_random,
  924.      &catch_exception_random,
  925.      &catch_exception_random,
  926.      &catch_exception_random,
  927.      &catch_exception_random,
  928.      &catch_exception_random,
  929.      &catch_exception_random,
  930.      &catch_exception_random,
  931.      &catch_exception_random,
  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_255}};

  960. #define BCR  (*(volatile short *)(0x05FFFFA0)) /* Bus control register */
  961. #define BAS  (0x800)                                /* Byte access select */
  962. #define WCR1 (*(volatile short *)(0x05ffffA2)) /* Wait state control register */

  963. asm ("_BINIT: mov.l  L1,r15");
  964. asm ("bra _INIT");
  965. asm ("nop");
  966. asm ("L1: .long _init_stack + 8*1024*4");
  967. void
  968. INIT (void)
  969. {
  970.   /* First turn on the ram */
  971.   WCR1  = 0;    /* Never sample wait */
  972.   BCR = BAS;    /* use lowbyte/high byte */

  973.   init_serial();

  974. #ifdef MONITOR
  975.   reset_hook ();
  976. #endif


  977.   in_nmi = 0;
  978.   dofault = 1;
  979.   stepped = 0;

  980.   stub_sp = stub_stack + stub_stack_size;
  981.   breakpoint ();

  982.   while (1)
  983.     ;
  984. }


  985. static void sr()
  986. {


  987.   /* Calling Reset does the same as pressing the button */
  988.   asm (".global _Reset
  989.         .global _WarmReset
  990. _Reset:
  991. _WarmReset:
  992.          mov.l L_sp,r15
  993.          bra   _INIT
  994.          nop
  995.          .align 2
  996. L_sp:    .long _init_stack + 8000");

  997.   asm("saveRegisters:
  998.         mov.l        @(L_reg, pc), r0
  999.         mov.l        @r15+, r1                                ! pop R0
  1000.         mov.l        r2, @(0x08, r0)                                ! save R2
  1001.         mov.l        r1, @r0                                        ! save R0
  1002.         mov.l        @r15+, r1                                ! pop R1
  1003.         mov.l        r3, @(0x0c, r0)                                ! save R3
  1004.         mov.l        r1, @(0x04, r0)                                ! save R1
  1005.         mov.l        r4, @(0x10, r0)                                ! save R4
  1006.         mov.l        r5, @(0x14, r0)                                ! save R5
  1007.         mov.l        r6, @(0x18, r0)                                ! save R6
  1008.         mov.l        r7, @(0x1c, r0)                                ! save R7
  1009.         mov.l        r8, @(0x20, r0)                                ! save R8
  1010.         mov.l        r9, @(0x24, r0)                                ! save R9
  1011.         mov.l        r10, @(0x28, r0)                        ! save R10
  1012.         mov.l        r11, @(0x2c, r0)                        ! save R11
  1013.         mov.l        r12, @(0x30, r0)                        ! save R12
  1014.         mov.l        r13, @(0x34, r0)                        ! save R13
  1015.         mov.l        r14, @(0x38, r0)                        ! save R14
  1016.         mov.l        @r15+, r4                                ! save arg to handleException
  1017.         add        #8, r15                                        ! hide PC/SR values on stack
  1018.         mov.l        r15, @(0x3c, r0)                        ! save R15
  1019.         add        #-8, r15                                ! save still needs old SP value
  1020.         add        #92, r0                                        ! readjust register pointer
  1021.         mov        r15, r2
  1022.         add        #4, r2
  1023.         mov.l        @r2, r2                                        ! R2 has SR
  1024.         mov.l        @r15, r1                                ! R1 has PC
  1025.         mov.l        r2, @-r0                                ! save SR
  1026.         sts.l        macl, @-r0                                ! save MACL
  1027.         sts.l        mach, @-r0                                ! save MACH
  1028.         stc.l        vbr, @-r0                                ! save VBR
  1029.         stc.l        gbr, @-r0                                ! save GBR
  1030.         sts.l        pr, @-r0                                ! save PR
  1031.         mov.l        @(L_stubstack, pc), r2
  1032.         mov.l        @(L_hdl_except, pc), r3
  1033.         mov.l        @r2, r15
  1034.         jsr        @r3
  1035.         mov.l        r1, @-r0                                ! save PC
  1036.         mov.l        @(L_stubstack, pc), r0
  1037.         mov.l        @(L_reg, pc), r1
  1038.         bra        restoreRegisters
  1039.         mov.l        r15, @r0                                ! save __stub_stack

  1040.         .align 2
  1041. L_reg:
  1042.         .long        _registers
  1043. L_stubstack:
  1044.         .long        _stub_sp
  1045. L_hdl_except:
  1046.         .long        _handle_exception");

  1047. }

  1048. static void rr()
  1049. {
  1050. asm("
  1051.         .align 2
  1052.         .global _resume
  1053. _resume:
  1054.         mov        r4,r1
  1055. restoreRegisters:
  1056.         add        #8, r1                                                ! skip to R2
  1057.         mov.l        @r1+, r2                                        ! restore R2
  1058.         mov.l        @r1+, r3                                        ! restore R3
  1059.         mov.l        @r1+, r4                                        ! restore R4
  1060.         mov.l        @r1+, r5                                        ! restore R5
  1061.         mov.l        @r1+, r6                                        ! restore R6
  1062.         mov.l        @r1+, r7                                        ! restore R7
  1063.         mov.l        @r1+, r8                                        ! restore R8
  1064.         mov.l        @r1+, r9                                        ! restore R9
  1065.         mov.l        @r1+, r10                                        ! restore R10
  1066.         mov.l        @r1+, r11                                        ! restore R11
  1067.         mov.l        @r1+, r12                                        ! restore R12
  1068.         mov.l        @r1+, r13                                        ! restore R13
  1069.         mov.l        @r1+, r14                                        ! restore R14
  1070.         mov.l        @r1+, r15                                        ! restore programs stack
  1071.         mov.l        @r1+, r0
  1072.         add        #-8, r15                                        ! uncover PC/SR on stack
  1073.         mov.l        r0, @r15                                        ! restore PC onto stack
  1074.         lds.l        @r1+, pr                                        ! restore PR
  1075.         ldc.l        @r1+, gbr                                        ! restore GBR
  1076.         ldc.l        @r1+, vbr                                        ! restore VBR
  1077.         lds.l        @r1+, mach                                        ! restore MACH
  1078.         lds.l        @r1+, macl                                        ! restore MACL
  1079.         mov.l        @r1, r0
  1080.         add        #-88, r1                                        ! readjust reg pointer to R1
  1081.         mov.l        r0, @(4, r15)                                        ! restore SR onto stack+4
  1082.         mov.l        r2, @-r15
  1083.         mov.l        L_in_nmi, r0
  1084.         mov                #0, r2
  1085.         mov.b        r2, @r0
  1086.         mov.l        @r15+, r2
  1087.         mov.l        @r1+, r0                                        ! restore R0
  1088.         rte
  1089.         mov.l        @r1, r1                                                ! restore R1

  1090. ");
  1091. }


  1092. static __inline__ void code_for_catch_exception(int n)
  1093. {
  1094.   asm("                .globl        _catch_exception_%O0" : : "i" (n)                                 );
  1095.   asm("        _catch_exception_%O0:" :: "i" (n)                                                      );

  1096.   asm("                add        #-4, r15                                 ! reserve spot on stack ");
  1097.   asm("                mov.l        r1, @-r15                                ! push R1                ");

  1098.   if (n == NMI_VEC)
  1099.     {
  1100.       /* Special case for NMI - make sure that they don't nest */
  1101.       asm("        mov.l        r0, @-r15                                        ! push R0");
  1102.       asm("        mov.l        L_in_nmi, r0");
  1103.       asm("        tas.b        @r0                                                ! Fend off against addtnl NMIs");
  1104.       asm("        bt                noNMI");
  1105.       asm("        mov.l        @r15+, r0");
  1106.       asm("        mov.l        @r15+, r1");
  1107.       asm("        add                #4, r15");
  1108.       asm("        rte");
  1109.       asm("        nop");
  1110.       asm(".align 2");
  1111.       asm("L_in_nmi: .long        _in_nmi");
  1112.       asm("noNMI:");
  1113.     }
  1114.   else
  1115.     {

  1116.       if (n == CPU_BUS_ERROR_VEC)
  1117.         {
  1118.           /* Exception 9 (bus errors) are disasbleable - so that you
  1119.              can probe memory and get zero instead of a fault.
  1120.              Because the vector table may be in ROM we don't revector
  1121.              the interrupt like all the other stubs, we check in here
  1122.              */
  1123.           asm("mov.l        L_dofault,r1");
  1124.           asm("mov.l        @r1,r1");
  1125.           asm("tst        r1,r1");
  1126.           asm("bf        faultaway");
  1127.           asm("bsr        _handle_buserror");
  1128.           asm(".align        2");
  1129.           asm("L_dofault: .long _dofault");
  1130.           asm("faultaway:");
  1131.         }
  1132.       asm("                mov        #15<<4, r1                                                        ");
  1133.       asm("                ldc        r1, sr                                        ! disable interrupts        ");
  1134.       asm("                mov.l        r0, @-r15                                ! push R0                ");
  1135.     }

  1136.   /* Prepare for saving context, we've already pushed r0 and r1, stick exception number
  1137.      into the frame */
  1138.   asm("                mov        r15, r0                                                                ");
  1139.   asm("                add        #8, r0                                                                ");
  1140.   asm("                mov        %0,r1" :: "i" (n)                                                );
  1141.   asm("                extu.b  r1,r1                                                                ");
  1142.   asm("                bra        saveRegisters                                ! save register values        ");
  1143.   asm("                mov.l        r1, @r0                                        ! save exception #         ");
  1144. }


  1145. static  void
  1146. exceptions (void)
  1147. {
  1148.   code_for_catch_exception (CPU_BUS_ERROR_VEC);
  1149.   code_for_catch_exception (DMA_BUS_ERROR_VEC);
  1150.   code_for_catch_exception (INVALID_INSN_VEC);
  1151.   code_for_catch_exception (INVALID_SLOT_VEC);
  1152.   code_for_catch_exception (NMI_VEC);
  1153.   code_for_catch_exception (TRAP_VEC);
  1154.   code_for_catch_exception (USER_VEC);
  1155.   code_for_catch_exception (IO_VEC);
  1156. }






  1157. /* Support for Serial I/O using on chip uart */

  1158. #define SMR0 (*(volatile char *)(0x05FFFEC0)) /* Channel 0  serial mode register */
  1159. #define BRR0 (*(volatile char *)(0x05FFFEC1)) /* Channel 0  bit rate register */
  1160. #define SCR0 (*(volatile char *)(0x05FFFEC2)) /* Channel 0  serial control register */
  1161. #define TDR0 (*(volatile char *)(0x05FFFEC3)) /* Channel 0  transmit data register */
  1162. #define SSR0 (*(volatile char *)(0x05FFFEC4)) /* Channel 0  serial status register */
  1163. #define RDR0 (*(volatile char *)(0x05FFFEC5)) /* Channel 0  receive data register */

  1164. #define SMR1 (*(volatile char *)(0x05FFFEC8)) /* Channel 1  serial mode register */
  1165. #define BRR1 (*(volatile char *)(0x05FFFEC9)) /* Channel 1  bit rate register */
  1166. #define SCR1 (*(volatile char *)(0x05FFFECA)) /* Channel 1  serial control register */
  1167. #define TDR1 (*(volatile char *)(0x05FFFECB)) /* Channel 1  transmit data register */
  1168. #define SSR1 (*(volatile char *)(0x05FFFECC)) /* Channel 1  serial status register */
  1169. #define RDR1 (*(volatile char *)(0x05FFFECD)) /* Channel 1  receive data register */

  1170. /*
  1171. * Serial mode register bits
  1172. */

  1173. #define SYNC_MODE                 0x80
  1174. #define SEVEN_BIT_DATA                 0x40
  1175. #define PARITY_ON                0x20
  1176. #define ODD_PARITY                0x10
  1177. #define STOP_BITS_2                0x08
  1178. #define ENABLE_MULTIP                0x04
  1179. #define PHI_64                        0x03
  1180. #define PHI_16                        0x02
  1181. #define PHI_4                        0x01

  1182. /*
  1183. * Serial control register bits
  1184. */
  1185. #define SCI_TIE                                0x80        /* Transmit interrupt enable */
  1186. #define SCI_RIE                                0x40        /* Receive interrupt enable */
  1187. #define SCI_TE                                0x20        /* Transmit enable */
  1188. #define SCI_RE                                0x10        /* Receive enable */
  1189. #define SCI_MPIE                        0x08        /* Multiprocessor interrupt enable */
  1190. #define SCI_TEIE                        0x04        /* Transmit end interrupt enable */
  1191. #define SCI_CKE1                        0x02        /* Clock enable 1 */
  1192. #define SCI_CKE0                        0x01        /* Clock enable 0 */

  1193. /*
  1194. * Serial status register bits
  1195. */
  1196. #define SCI_TDRE                        0x80        /* Transmit data register empty */
  1197. #define SCI_RDRF                        0x40        /* Receive data register full */
  1198. #define SCI_ORER                        0x20        /* Overrun error */
  1199. #define SCI_FER                                0x10        /* Framing error */
  1200. #define SCI_PER                                0x08        /* Parity error */
  1201. #define SCI_TEND                        0x04        /* Transmit end */
  1202. #define SCI_MPB                                0x02        /* Multiprocessor bit */
  1203. #define SCI_MPBT                        0x01        /* Multiprocessor bit transfer */


  1204. /*
  1205. * Port B IO Register (PBIOR)
  1206. */
  1207. #define        PBIOR                 (*(volatile char *)(0x05FFFFC6))
  1208. #define        PB15IOR         0x8000
  1209. #define        PB14IOR         0x4000
  1210. #define        PB13IOR         0x2000
  1211. #define        PB12IOR         0x1000
  1212. #define        PB11IOR         0x0800
  1213. #define        PB10IOR         0x0400
  1214. #define        PB9IOR                 0x0200
  1215. #define        PB8IOR                 0x0100
  1216. #define        PB7IOR                 0x0080
  1217. #define        PB6IOR                 0x0040
  1218. #define        PB5IOR                 0x0020
  1219. #define        PB4IOR                 0x0010
  1220. #define        PB3IOR                 0x0008
  1221. #define        PB2IOR                 0x0004
  1222. #define        PB1IOR                 0x0002
  1223. #define        PB0IOR                 0x0001

  1224. /*
  1225. * Port B Control Register (PBCR1)
  1226. */
  1227. #define        PBCR1                 (*(volatile short *)(0x05FFFFCC))
  1228. #define        PB15MD1         0x8000
  1229. #define        PB15MD0         0x4000
  1230. #define        PB14MD1         0x2000
  1231. #define        PB14MD0         0x1000
  1232. #define        PB13MD1         0x0800
  1233. #define        PB13MD0         0x0400
  1234. #define        PB12MD1         0x0200
  1235. #define        PB12MD0         0x0100
  1236. #define        PB11MD1         0x0080
  1237. #define        PB11MD0         0x0040
  1238. #define        PB10MD1         0x0020
  1239. #define        PB10MD0         0x0010
  1240. #define        PB9MD1                 0x0008
  1241. #define        PB9MD0                 0x0004
  1242. #define        PB8MD1                 0x0002
  1243. #define        PB8MD0                 0x0001

  1244. #define        PB15MD                 PB15MD1|PB14MD0
  1245. #define        PB14MD                 PB14MD1|PB14MD0
  1246. #define        PB13MD                 PB13MD1|PB13MD0
  1247. #define        PB12MD                 PB12MD1|PB12MD0
  1248. #define        PB11MD                 PB11MD1|PB11MD0
  1249. #define        PB10MD                 PB10MD1|PB10MD0
  1250. #define        PB9MD                 PB9MD1|PB9MD0
  1251. #define        PB8MD                 PB8MD1|PB8MD0

  1252. #define PB_TXD1         PB11MD1
  1253. #define PB_RXD1         PB10MD1
  1254. #define PB_TXD0         PB9MD1
  1255. #define PB_RXD0         PB8MD1

  1256. /*
  1257. * Port B Control Register (PBCR2)
  1258. */
  1259. #define        PBCR2         0x05FFFFCE
  1260. #define        PB7MD1         0x8000
  1261. #define        PB7MD0         0x4000
  1262. #define        PB6MD1         0x2000
  1263. #define        PB6MD0         0x1000
  1264. #define        PB5MD1         0x0800
  1265. #define        PB5MD0         0x0400
  1266. #define        PB4MD1         0x0200
  1267. #define        PB4MD0         0x0100
  1268. #define        PB3MD1         0x0080
  1269. #define        PB3MD0         0x0040
  1270. #define        PB2MD1         0x0020
  1271. #define        PB2MD0         0x0010
  1272. #define        PB1MD1         0x0008
  1273. #define        PB1MD0         0x0004
  1274. #define        PB0MD1         0x0002
  1275. #define        PB0MD0         0x0001

  1276. #define        PB7MD         PB7MD1|PB7MD0
  1277. #define        PB6MD         PB6MD1|PB6MD0
  1278. #define        PB5MD         PB5MD1|PB5MD0
  1279. #define        PB4MD         PB4MD1|PB4MD0
  1280. #define        PB3MD         PB3MD1|PB3MD0
  1281. #define        PB2MD         PB2MD1|PB2MD0
  1282. #define        PB1MD         PB1MD1|PB1MD0
  1283. #define        PB0MD         PB0MD1|PB0MD0


  1284. #ifdef MHZ
  1285. #define BPS                        32 * 9600 * MHZ / ( BAUD * 10)
  1286. #else
  1287. #define BPS                        32        /* 9600 for 10 Mhz */
  1288. #endif

  1289. void handleError (char theSSR);

  1290. void
  1291. nop (void)
  1292. {

  1293. }
  1294. void
  1295. init_serial (void)
  1296. {
  1297.   int i;

  1298.   /* Clear TE and RE in Channel 1's SCR   */
  1299.   SCR1 &= ~(SCI_TE | SCI_RE);

  1300.   /* Set communication to be async, 8-bit data, no parity, 1 stop bit and use internal clock */

  1301.   SMR1 = 0;
  1302.   BRR1 = BPS;

  1303.   SCR1 &= ~(SCI_CKE1 | SCI_CKE0);

  1304.   /* let the hardware settle */

  1305.   for (i = 0; i < 1000; i++)
  1306.     nop ();

  1307.   /* Turn on in and out */
  1308.   SCR1 |= SCI_RE | SCI_TE;

  1309.   /* Set the PFC to make RXD1 (pin PB8) an input pin and TXD1 (pin PB9) an output pin */
  1310.   PBCR1 &= ~(PB_TXD1 | PB_RXD1);
  1311.   PBCR1 |= PB_TXD1 | PB_RXD1;
  1312. }


  1313. int
  1314. getDebugCharReady (void)
  1315. {
  1316.   char mySSR;
  1317.   mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
  1318.   if ( mySSR )
  1319.     handleError ( mySSR );
  1320.   return SSR1 & SCI_RDRF ;
  1321. }

  1322. char
  1323. getDebugChar (void)
  1324. {
  1325.   char ch;
  1326.   char mySSR;

  1327.   while ( ! getDebugCharReady())
  1328.     ;

  1329.   ch = RDR1;
  1330.   SSR1 &= ~SCI_RDRF;

  1331.   mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);

  1332.   if (mySSR)
  1333.     handleError (mySSR);

  1334.   return ch;
  1335. }

  1336. int
  1337. putDebugCharReady (void)
  1338. {
  1339.   return (SSR1 & SCI_TDRE);
  1340. }

  1341. void
  1342. putDebugChar (char ch)
  1343. {
  1344.   while (!putDebugCharReady())
  1345.     ;

  1346.   /*
  1347.    * Write data into TDR and clear TDRE
  1348.    */
  1349.   TDR1 = ch;
  1350.   SSR1 &= ~SCI_TDRE;
  1351. }

  1352. void
  1353. handleError (char theSSR)
  1354. {
  1355.   SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
  1356. }

  1357. #endif