+++ /dev/null
-/* sh-stub.c -- debugging stub for the Hitachi-SH.
-
- NOTE!! This code has to be compiled with optimization, otherwise the
- function inlining which generates the exception handlers won't work.
-
-*/
-
-/* This is originally based on an m68k software stub written by Glenn
- Engel at HP, but has changed quite a bit.
-
- Modifications for the SH by Ben Lee and Steve Chamberlain
-
-*/
-
-/****************************************************************************
-
- THIS SOFTWARE IS NOT COPYRIGHTED
-
- HP offers the following for use in the public domain. HP makes no
- warranty with regard to the software or it's performance and the
- user accepts the software "AS IS" with all faults.
-
- HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
- TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-
-/* Remote communication protocol.
-
- A debug packet whose contents are <data>
- is encapsulated for transmission in the form:
-
- $ <data> # CSUM1 CSUM2
-
- <data> must be ASCII alphanumeric and cannot include characters
- '$' or '#'. If <data> starts with two characters followed by
- ':', then the existing stubs interpret this as a sequence number.
-
- CSUM1 and CSUM2 are ascii hex representation of an 8-bit
- checksum of <data>, the most significant nibble is sent first.
- the hex digits 0-9,a-f are used.
-
- Receiver responds with:
-
- + - if CSUM is correct and ready for next packet
- - - if CSUM is incorrect
-
- <data> is as follows:
- All values are encoded in ascii hex digits.
-
- Request Packet
-
- read registers g
- reply XX....X Each byte of register data
- is described by two hex digits.
- Registers are in the internal order
- for GDB, and the bytes in a register
- are in the same order the machine uses.
- or ENN for an error.
-
- write regs GXX..XX Each byte of register data
- is described by two hex digits.
- reply OK for success
- ENN for an error
-
- write reg Pn...=r... Write register n... with value r...,
- which contains two hex digits for each
- byte in the register (target byte
- order).
- reply OK for success
- ENN for an error
- (not supported by all stubs).
-
- read mem mAA..AA,LLLL AA..AA is address, LLLL is length.
- reply XX..XX XX..XX is mem contents
- Can be fewer bytes than requested
- if able to read only part of the data.
- or ENN NN is errno
-
- write mem MAA..AA,LLLL:XX..XX
- AA..AA is address,
- LLLL is number of bytes,
- XX..XX is data
- reply OK for success
- ENN for an error (this includes the case
- where only part of the data was
- written).
-
- cont cAA..AA AA..AA is address to resume
- If AA..AA is omitted,
- resume at same address.
-
- step sAA..AA AA..AA is address to resume
- If AA..AA is omitted,
- resume at same address.
-
- last signal ? Reply the current reason for stopping.
- This is the same reply as is generated
- for step or cont : SAA where AA is the
- signal number.
-
- There is no immediate reply to step or cont.
- The reply comes when the machine stops.
- It is SAA AA is the "signal number"
-
- or... TAAn...:r...;n:r...;n...:r...;
- AA = signal number
- n... = register number
- r... = register contents
- or... WAA The process exited, and AA is
- the exit status. This is only
- applicable for certains sorts of
- targets.
- kill request k
-
- toggle debug d toggle debug flag (see 386 & 68k stubs)
- reset r reset -- see sparc stub.
- reserved <other> On other requests, the stub should
- ignore the request and send an empty
- response ($#<checksum>). This way
- we can extend the protocol and GDB
- can tell whether the stub it is
- talking to uses the old or the new.
- search tAA:PP,MM Search backwards starting at address
- AA for a match with pattern PP and
- mask MM. PP and MM are 4 bytes.
- Not supported by all stubs.
-
- general query qXXXX Request info about XXXX.
- general set QXXXX=yyyy Set value of XXXX to yyyy.
- query sect offs qOffsets Get section offsets. Reply is
- Text=xxx;Data=yyy;Bss=zzz
- console output Otext Send text to stdout. Only comes from
- remote target.
-
- Responses can be run-length encoded to save space. A '*' means that
- the next character is an ASCII encoding giving a repeat count which
- stands for that many repititions of the character preceding the '*'.
- The encoding is n+29, yielding a printable character where n >=3
- (which is where rle starts to win). Don't use an n > 126.
-
- So
- "0* " means the same as "0000". */
-
-#include <string.h>
-#include <setjmp.h>
-
-
-
-#define COND_BR_MASK 0xff00
-#define UCOND_DBR_MASK 0xe000
-#define UCOND_RBR_MASK 0xf0df
-#define TRAPA_MASK 0xff00
-
-#define COND_DISP 0x00ff
-#define UCOND_DISP 0x0fff
-#define UCOND_REG 0x0f00
-
-#define BF_INSTR 0x8b00
-#define BT_INSTR 0x8900
-#define BRA_INSTR 0xa000
-#define BSR_INSTR 0xb000
-#define JMP_INSTR 0x402b
-#define JSR_INSTR 0x400b
-#define RTS_INSTR 0x000b
-#define RTE_INSTR 0x002b
-#define TRAPA_INSTR 0xc300
-
-#define SSTEP_INSTR 0xc3ff
-
-#define T_BIT_MASK 0x0001
-/*
- * BUFMAX defines the maximum number of characters in inbound/outbound
- * buffers at least NUMREGBYTES*2 are needed for register packets
- */
-#define BUFMAX 1024
-
-/*
- * Number of bytes for registers
- */
-#define NUMREGBYTES 112 /* 92 */
-
-/*
- * typedef
- */
-typedef void (*Function) ();
-
-/*
- * Forward declarations
- */
-
-static int hex (char);
-static char *mem2hex (char *, char *, int);
-static char *hex2mem (char *, char *, int);
-static int hexToInt (char **, int *);
-static void getpacket (char *);
-static void putpacket (char *);
-static void handle_buserror (void);
-static int computeSignal (int exceptionVector);
-static void handle_exception (int exceptionVector);
-void init_serial();
-
-
-int putDebugChar (char);
-char getDebugChar (void);
-
-/* These are in the file but in asm statements so the compiler can't see them */
-void catch_exception_4 (void);
-void catch_exception_6 (void);
-void catch_exception_9 (void);
-void catch_exception_10 (void);
-void catch_exception_11 (void);
-void catch_exception_32 (void);
-void catch_exception_33 (void);
-void catch_exception_255 (void);
-
-
-
-#define catch_exception_random catch_exception_255 /* Treat all odd ones like 255 */
-
-void breakpoint (void);
-
-
-#define init_stack_size 8*1024 /* if you change this you should also modify BINIT */
-#define stub_stack_size 8*1024
-
-int init_stack[init_stack_size] __attribute__ ((section ("stack"))) = {0};
-int stub_stack[stub_stack_size] __attribute__ ((section ("stack"))) = {0};
-
-typedef struct
- {
- void (*func_cold) ();
- int *stack_cold;
- void (*func_warm) ();
- int *stack_warm;
- void (*(handler[256 - 4])) ();
- }
-vec_type;
-
-
-void INIT ();
-void BINIT ();
-
-/* When you link take care that this is at address 0 -
- or wherever your vbr points */
-
-#define CPU_BUS_ERROR_VEC 9
-#define DMA_BUS_ERROR_VEC 10
-#define NMI_VEC 11
-#define INVALID_INSN_VEC 4
-#define INVALID_SLOT_VEC 6
-#define TRAP_VEC 32
-#define IO_VEC 33
-#define USER_VEC 255
-
-
-#define BCR (*(volatile short *)(0x05FFFFA0)) /* Bus control register */
-#define BAS (0x800) /* Byte access select */
-#define WCR1 (*(volatile short *)(0x05ffffA2)) /* Wait state control register */
-
-const vec_type vectable =
-{
- &BINIT, /* 0: Power-on reset PC */
- init_stack + init_stack_size, /* 1: Power-on reset SP */
- &BINIT, /* 2: Manual reset PC */
- init_stack + init_stack_size, /* 3: Manual reset SP */
-{
- &catch_exception_4, /* 4: General invalid instruction */
- &catch_exception_random, /* 5: Reserved for system */
- &catch_exception_6, /* 6: Invalid slot instruction */
- &catch_exception_random, /* 7: Reserved for system */
- &catch_exception_random, /* 8: Reserved for system */
- &catch_exception_9, /* 9: CPU bus error */
- &catch_exception_10, /* 10: DMA bus error */
- &catch_exception_11, /* 11: NMI */
- &catch_exception_random, /* 12: User break */
- &catch_exception_random, /* 13: Reserved for system */
- &catch_exception_random, /* 14: Reserved for system */
- &catch_exception_random, /* 15: Reserved for system */
- &catch_exception_random, /* 16: Reserved for system */
- &catch_exception_random, /* 17: Reserved for system */
- &catch_exception_random, /* 18: Reserved for system */
- &catch_exception_random, /* 19: Reserved for system */
- &catch_exception_random, /* 20: Reserved for system */
- &catch_exception_random, /* 21: Reserved for system */
- &catch_exception_random, /* 22: Reserved for system */
- &catch_exception_random, /* 23: Reserved for system */
- &catch_exception_random, /* 24: Reserved for system */
- &catch_exception_random, /* 25: Reserved for system */
- &catch_exception_random, /* 26: Reserved for system */
- &catch_exception_random, /* 27: Reserved for system */
- &catch_exception_random, /* 28: Reserved for system */
- &catch_exception_random, /* 29: Reserved for system */
- &catch_exception_random, /* 30: Reserved for system */
- &catch_exception_random, /* 31: Reserved for system */
- &catch_exception_32, /* 32: Trap instr (user vectors) */
- &catch_exception_33, /* 33: Trap instr (user vectors) */
- &catch_exception_random, /* 34: Trap instr (user vectors) */
- &catch_exception_random, /* 35: Trap instr (user vectors) */
- &catch_exception_random, /* 36: Trap instr (user vectors) */
- &catch_exception_random, /* 37: Trap instr (user vectors) */
- &catch_exception_random, /* 38: Trap instr (user vectors) */
- &catch_exception_random, /* 39: Trap instr (user vectors) */
- &catch_exception_random, /* 40: Trap instr (user vectors) */
- &catch_exception_random, /* 41: Trap instr (user vectors) */
- &catch_exception_random, /* 42: Trap instr (user vectors) */
- &catch_exception_random, /* 43: Trap instr (user vectors) */
- &catch_exception_random, /* 44: Trap instr (user vectors) */
- &catch_exception_random, /* 45: Trap instr (user vectors) */
- &catch_exception_random, /* 46: Trap instr (user vectors) */
- &catch_exception_random, /* 47: Trap instr (user vectors) */
- &catch_exception_random, /* 48: Trap instr (user vectors) */
- &catch_exception_random, /* 49: Trap instr (user vectors) */
- &catch_exception_random, /* 50: Trap instr (user vectors) */
- &catch_exception_random, /* 51: Trap instr (user vectors) */
- &catch_exception_random, /* 52: Trap instr (user vectors) */
- &catch_exception_random, /* 53: Trap instr (user vectors) */
- &catch_exception_random, /* 54: Trap instr (user vectors) */
- &catch_exception_random, /* 55: Trap instr (user vectors) */
- &catch_exception_random, /* 56: Trap instr (user vectors) */
- &catch_exception_random, /* 57: Trap instr (user vectors) */
- &catch_exception_random, /* 58: Trap instr (user vectors) */
- &catch_exception_random, /* 59: Trap instr (user vectors) */
- &catch_exception_random, /* 60: Trap instr (user vectors) */
- &catch_exception_random, /* 61: Trap instr (user vectors) */
- &catch_exception_random, /* 62: Trap instr (user vectors) */
- &catch_exception_random, /* 63: Trap instr (user vectors) */
- &catch_exception_random, /* 64: IRQ0 */
- &catch_exception_random, /* 65: IRQ1 */
- &catch_exception_random, /* 66: IRQ2 */
- &catch_exception_random, /* 67: IRQ3 */
- &catch_exception_random, /* 68: IRQ4 */
- &catch_exception_random, /* 69: IRQ5 */
- &catch_exception_random, /* 70: IRQ6 */
- &catch_exception_random, /* 71: IRQ7 */
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_random,
- &catch_exception_255}};
-
-
-char in_nmi; /* Set when handling an NMI, so we don't reenter */
-int dofault; /* Non zero, bus errors will raise exception */
-
-int *stub_sp;
-
-/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
-int remote_debug;
-
-/* jump buffer used for setjmp/longjmp */
-jmp_buf remcomEnv;
-
-enum regnames
- {
- R0, R1, R2, R3, R4, R5, R6, R7,
- R8, R9, R10, R11, R12, R13, R14,
- R15, PC, PR, GBR, VBR, MACH, MACL, SR,
- TICKS, STALLS, CYCLES, INSTS, PLR
- };
-
-typedef struct
- {
- short *memAddr;
- short oldInstr;
- }
-stepData;
-
-int registers[NUMREGBYTES / 4];
-stepData instrBuffer;
-char stepped;
-static const char hexchars[] = "0123456789abcdef";
-char remcomInBuffer[BUFMAX];
-char remcomOutBuffer[BUFMAX];
-
-char highhex(int x)
-{
- return hexchars[(x >> 4) & 0xf];
-}
-
-char lowhex(int x)
-{
- return hexchars[x & 0xf];
-}
-
-/*
- * Assembly macros
- */
-
-#define BREAKPOINT() asm("trapa #0x20"::);
-
-
-/*
- * Routines to handle hex data
- */
-
-static int
-hex (char ch)
-{
- if ((ch >= 'a') && (ch <= 'f'))
- return (ch - 'a' + 10);
- if ((ch >= '0') && (ch <= '9'))
- return (ch - '0');
- if ((ch >= 'A') && (ch <= 'F'))
- return (ch - 'A' + 10);
- return (-1);
-}
-
-/* convert the memory, pointed to by mem into hex, placing result in buf */
-/* return a pointer to the last char put in buf (null) */
-static char *
-mem2hex (char *mem, char *buf, int count)
-{
- int i;
- int ch;
- for (i = 0; i < count; i++)
- {
- ch = *mem++;
- *buf++ = highhex (ch);
- *buf++ = lowhex (ch);
- }
- *buf = 0;
- return (buf);
-}
-
-/* convert the hex array pointed to by buf into binary, to be placed in mem */
-/* return a pointer to the character after the last byte written */
-
-static char *
-hex2mem (char *buf, char *mem, int count)
-{
- int i;
- unsigned char ch;
- for (i = 0; i < count; i++)
- {
- ch = hex (*buf++) << 4;
- ch = ch + hex (*buf++);
- *mem++ = ch;
- }
- return (mem);
-}
-
-/**********************************************/
-/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-/* RETURN NUMBER OF CHARS PROCESSED */
-/**********************************************/
-static int
-hexToInt (char **ptr, int *intValue)
-{
- int numChars = 0;
- int hexValue;
-
- *intValue = 0;
-
- while (**ptr)
- {
- hexValue = hex (**ptr);
- if (hexValue >= 0)
- {
- *intValue = (*intValue << 4) | hexValue;
- numChars++;
- }
- else
- break;
-
- (*ptr)++;
- }
-
- return (numChars);
-}
-
-/*
- * Routines to get and put packets
- */
-
-/* scan for the sequence $<data>#<checksum> */
-
-static
-void
-getpacket (char *buffer)
-{
- unsigned char checksum;
- unsigned char xmitcsum;
- int i;
- int count;
- char ch;
- do
- {
- /* wait around for the start character, ignore all other characters */
- while ((ch = getDebugChar ()) != '$');
- checksum = 0;
- xmitcsum = -1;
-
- count = 0;
-
- /* now, read until a # or end of buffer is found */
- while (count < BUFMAX)
- {
- ch = getDebugChar ();
- if (ch == '#')
- break;
- checksum = checksum + ch;
- buffer[count] = ch;
- count = count + 1;
- }
- buffer[count] = 0;
-
- if (ch == '#')
- {
- xmitcsum = hex (getDebugChar ()) << 4;
- xmitcsum += hex (getDebugChar ());
- if (checksum != xmitcsum)
- putDebugChar ('-'); /* failed checksum */
- else
- {
- putDebugChar ('+'); /* successful transfer */
- /* if a sequence char is present, reply the sequence ID */
- if (buffer[2] == ':')
- {
- putDebugChar (buffer[0]);
- putDebugChar (buffer[1]);
- /* remove sequence chars from buffer */
- count = strlen (buffer);
- for (i = 3; i <= count; i++)
- buffer[i - 3] = buffer[i];
- }
- }
- }
- }
- while (checksum != xmitcsum);
-
-}
-
-
-/* send the packet in buffer. The host get's one chance to read it.
- This routine does not wait for a positive acknowledge. */
-
-static void
-putpacket (register char *buffer)
-{
- register int checksum;
- register int count;
-
- /* $<packet info>#<checksum>. */
- do
- {
- char *src = buffer;
- putDebugChar ('$');
- checksum = 0;
-
- while (*src)
- {
- int runlen;
-
- /* Do run length encoding */
- for (runlen = 0; runlen < 100; runlen ++)
- {
- if (src[0] != src[runlen])
- {
- if (runlen > 3)
- {
- int encode;
- /* Got a useful amount */
- putDebugChar (*src);
- checksum += *src;
- putDebugChar ('*');
- checksum += '*';
- checksum += (encode = runlen + ' ' - 4);
- putDebugChar (encode);
- src += runlen;
- }
- else
- {
- putDebugChar (*src);
- checksum += *src;
- src++;
- }
- break;
- }
- }
- }
-
-
- putDebugChar ('#');
- putDebugChar (highhex(checksum));
- putDebugChar (lowhex(checksum));
- }
- while (getDebugChar() != '+');
-
-}
-
-
-/* a bus error has occurred, perform a longjmp
- to return execution and allow handling of the error */
-
-void
-handle_buserror (void)
-{
- longjmp (remcomEnv, 1);
-}
-
-/*
- * this function takes the SH-1 exception number and attempts to
- * translate this number into a unix compatible signal value
- */
-static int
-computeSignal (int exceptionVector)
-{
- int sigval;
- switch (exceptionVector)
- {
- case INVALID_INSN_VEC:
- sigval = 4;
- break;
- case INVALID_SLOT_VEC:
- sigval = 4;
- break;
- case CPU_BUS_ERROR_VEC:
- sigval = 10;
- break;
- case DMA_BUS_ERROR_VEC:
- sigval = 10;
- break;
- case NMI_VEC:
- sigval = 2;
- break;
-
- case TRAP_VEC:
- case USER_VEC:
- sigval = 5;
- break;
-
- default:
- sigval = 7; /* "software generated"*/
- break;
- }
- return (sigval);
-}
-
-void
-doSStep (void)
-{
- short *instrMem;
- int displacement;
- int reg;
- unsigned short opcode;
-
- instrMem = (short *) registers[PC];
-
- opcode = *instrMem;
- stepped = 1;
-
- if ((opcode & COND_BR_MASK) == BT_INSTR)
- {
- if (registers[SR] & T_BIT_MASK)
- {
- displacement = (opcode & COND_DISP) << 1;
- if (displacement & 0x80)
- displacement |= 0xffffff00;
- /*
- * Remember PC points to second instr.
- * after PC of branch ... so add 4
- */
- instrMem = (short *) (registers[PC] + displacement + 4);
- }
- else
- instrMem += 1;
- }
- else if ((opcode & COND_BR_MASK) == BF_INSTR)
- {
- if (registers[SR] & T_BIT_MASK)
- instrMem += 1;
- else
- {
- displacement = (opcode & COND_DISP) << 1;
- if (displacement & 0x80)
- displacement |= 0xffffff00;
- /*
- * Remember PC points to second instr.
- * after PC of branch ... so add 4
- */
- instrMem = (short *) (registers[PC] + displacement + 4);
- }
- }
- else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
- {
- displacement = (opcode & UCOND_DISP) << 1;
- if (displacement & 0x0800)
- displacement |= 0xfffff000;
-
- /*
- * Remember PC points to second instr.
- * after PC of branch ... so add 4
- */
- instrMem = (short *) (registers[PC] + displacement + 4);
- }
- else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
- {
- reg = (char) ((opcode & UCOND_REG) >> 8);
-
- instrMem = (short *) registers[reg];
- }
- else if (opcode == RTS_INSTR)
- instrMem = (short *) registers[PR];
- else if (opcode == RTE_INSTR)
- instrMem = (short *) registers[15];
- else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
- instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
- else
- instrMem += 1;
-
- instrBuffer.memAddr = instrMem;
- instrBuffer.oldInstr = *instrMem;
- *instrMem = SSTEP_INSTR;
-}
-
-void
-undoSStep (void)
-{
- /*
- If we single stepped,
- restore the old instruction!
-*/
- if (stepped)
- { short *instrMem;
- instrMem = instrBuffer.memAddr;
- *instrMem = instrBuffer.oldInstr;
- }
- stepped = 0;
-}
-
-/*
-This function does all exception handling. It only does two things -
-it figures out why it was called and tells gdb, and then it reacts
-to gdb's requests.
-
-When in the monitor mode we talk a human on the serial line rather than gdb.
-
-*/
-
-
-void
-gdb_handle_exception (int exceptionVector)
-{
- int sigval;
- int addr, length;
- char *ptr;
-
- /* reply to host that an exception has occurred */
- sigval = computeSignal (exceptionVector);
- remcomOutBuffer[0] = 'S';
- remcomOutBuffer[1] = highhex(sigval);
- remcomOutBuffer[2] = lowhex (sigval);
- remcomOutBuffer[3] = 0;
-
- putpacket (remcomOutBuffer);
-
- /*
- * exception 255 indicates a software trap
- * inserted in place of code ... so back up
- * PC by one instruction, since this instruction
- * will later be replaced by its original one!
- */
- if (exceptionVector == 0xff
- || exceptionVector == 0x20)
- registers[PC] -= 2;
-
- /*
- * Do the thangs needed to undo
- * any stepping we may have done!
- */
- undoSStep ();
-
- while (1)
- {
- remcomOutBuffer[0] = 0;
- getpacket (remcomInBuffer);
-
- switch (remcomInBuffer[0])
- {
- case '?':
- remcomOutBuffer[0] = 'S';
- remcomOutBuffer[1] = highhex (sigval);
- remcomOutBuffer[2] = lowhex (sigval);
- remcomOutBuffer[3] = 0;
- break;
- case 'd':
- remote_debug = !(remote_debug); /* toggle debug flag */
- break;
- case 'g': /* return the value of the CPU registers */
- mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
- break;
- case 'G': /* set the value of the CPU registers - return OK */
- hex2mem (&remcomInBuffer[1], (char *) registers, NUMREGBYTES);
- strcpy (remcomOutBuffer, "OK");
- break;
-
- /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
- case 'm':
- if (setjmp (remcomEnv) == 0)
- {
- dofault = 0;
- /* TRY, TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
- ptr = &remcomInBuffer[1];
- if (hexToInt (&ptr, &addr))
- if (*(ptr++) == ',')
- if (hexToInt (&ptr, &length))
- {
- ptr = 0;
- mem2hex ((char *) addr, remcomOutBuffer, length);
- }
- if (ptr)
- strcpy (remcomOutBuffer, "E01");
- }
- else
- strcpy (remcomOutBuffer, "E03");
-
- /* restore handler for bus error */
- dofault = 1;
- break;
-
- /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
- case 'M':
- if (setjmp (remcomEnv) == 0)
- {
- dofault = 0;
-
- /* TRY, TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
- ptr = &remcomInBuffer[1];
- if (hexToInt (&ptr, &addr))
- if (*(ptr++) == ',')
- if (hexToInt (&ptr, &length))
- if (*(ptr++) == ':')
- {
- hex2mem (ptr, (char *) addr, length);
- ptr = 0;
- strcpy (remcomOutBuffer, "OK");
- }
- if (ptr)
- strcpy (remcomOutBuffer, "E02");
- }
- else
- strcpy (remcomOutBuffer, "E03");
-
- /* restore handler for bus error */
- dofault = 1;
- break;
-
- /* cAA..AA Continue at address AA..AA(optional) */
- /* sAA..AA Step one instruction from AA..AA(optional) */
- case 'c':
- case 's':
- {
- /* tRY, to read optional parameter, pc unchanged if no parm */
- ptr = &remcomInBuffer[1];
- if (hexToInt (&ptr, &addr))
- registers[PC] = addr;
-
- if (remcomInBuffer[0] == 's')
- doSStep ();
- }
- return;
- break;
-
- /* kill the program */
- case 'k': /* do nothing */
- break;
- } /* switch */
-
- /* reply to the request */
- putpacket (remcomOutBuffer);
- }
-}
-
-
-#define GDBCOOKIE 0x5ac
-static int ingdbmode;
-/* We've had an exception - choose to go into the monitor or
- the gdb stub */
-void handle_exception(int exceptionVector)
-{
-#ifdef MONITOR
- if (ingdbmode != GDBCOOKIE)
- monitor_handle_exception (exceptionVector);
- else
-#endif
- gdb_handle_exception (exceptionVector);
-
-}
-
-void
-gdb_mode()
-{
- ingdbmode = GDBCOOKIE;
- breakpoint();
-}
-/* This function will generate a breakpoint exception. It is used at the
- beginning of a program to sync up with a debugger and can be used
- otherwise as a quick means to stop program execution and "break" into
- the debugger. */
-
-void
-breakpoint (void)
-{
- BREAKPOINT ();
-}
-
-asm ("_BINIT: mov.l L1,r15");
-asm ("bra _INIT");
-asm ("nop");
-asm ("L1: .long _init_stack + 8*1024*4");
-void
-INIT (void)
-{
- /* First turn on the ram */
- WCR1 = 0; /* Never sample wait */
- BCR = BAS; /* use lowbyte/high byte */
-
- init_serial();
-
-#ifdef MONITOR
- reset_hook ();
-#endif
-
-
- in_nmi = 0;
- dofault = 1;
- stepped = 0;
-
- stub_sp = stub_stack + stub_stack_size;
- breakpoint ();
-
- while (1)
- ;
-}
-
-
-static void sr()
-{
-
-
- /* Calling Reset does the same as pressing the button */
- asm (".global _Reset
- .global _WarmReset
-_Reset:
-_WarmReset:
- mov.l L_sp,r15
- bra _INIT
- nop
- .align 2
-L_sp: .long _init_stack + 8000");
-
- asm("saveRegisters:
- mov.l @(L_reg, pc), r0
- mov.l @r15+, r1 ! pop R0
- mov.l r2, @(0x08, r0) ! save R2
- mov.l r1, @r0 ! save R0
- mov.l @r15+, r1 ! pop R1
- mov.l r3, @(0x0c, r0) ! save R3
- mov.l r1, @(0x04, r0) ! save R1
- mov.l r4, @(0x10, r0) ! save R4
- mov.l r5, @(0x14, r0) ! save R5
- mov.l r6, @(0x18, r0) ! save R6
- mov.l r7, @(0x1c, r0) ! save R7
- mov.l r8, @(0x20, r0) ! save R8
- mov.l r9, @(0x24, r0) ! save R9
- mov.l r10, @(0x28, r0) ! save R10
- mov.l r11, @(0x2c, r0) ! save R11
- mov.l r12, @(0x30, r0) ! save R12
- mov.l r13, @(0x34, r0) ! save R13
- mov.l r14, @(0x38, r0) ! save R14
- mov.l @r15+, r4 ! save arg to handleException
- add #8, r15 ! hide PC/SR values on stack
- mov.l r15, @(0x3c, r0) ! save R15
- add #-8, r15 ! save still needs old SP value
- add #92, r0 ! readjust register pointer
- mov r15, r2
- add #4, r2
- mov.l @r2, r2 ! R2 has SR
- mov.l @r15, r1 ! R1 has PC
- mov.l r2, @-r0 ! save SR
- sts.l macl, @-r0 ! save MACL
- sts.l mach, @-r0 ! save MACH
- stc.l vbr, @-r0 ! save VBR
- stc.l gbr, @-r0 ! save GBR
- sts.l pr, @-r0 ! save PR
- mov.l @(L_stubstack, pc), r2
- mov.l @(L_hdl_except, pc), r3
- mov.l @r2, r15
- jsr @r3
- mov.l r1, @-r0 ! save PC
- mov.l @(L_stubstack, pc), r0
- mov.l @(L_reg, pc), r1
- bra restoreRegisters
- mov.l r15, @r0 ! save __stub_stack
-
- .align 2
-L_reg:
- .long _registers
-L_stubstack:
- .long _stub_sp
-L_hdl_except:
- .long _handle_exception");
-
-}
-
-static void rr()
-{
-asm("
- .align 2
- .global _resume
-_resume:
- mov r4,r1
-restoreRegisters:
- add #8, r1 ! skip to R2
- mov.l @r1+, r2 ! restore R2
- mov.l @r1+, r3 ! restore R3
- mov.l @r1+, r4 ! restore R4
- mov.l @r1+, r5 ! restore R5
- mov.l @r1+, r6 ! restore R6
- mov.l @r1+, r7 ! restore R7
- mov.l @r1+, r8 ! restore R8
- mov.l @r1+, r9 ! restore R9
- mov.l @r1+, r10 ! restore R10
- mov.l @r1+, r11 ! restore R11
- mov.l @r1+, r12 ! restore R12
- mov.l @r1+, r13 ! restore R13
- mov.l @r1+, r14 ! restore R14
- mov.l @r1+, r15 ! restore programs stack
- mov.l @r1+, r0
- add #-8, r15 ! uncover PC/SR on stack
- mov.l r0, @r15 ! restore PC onto stack
- lds.l @r1+, pr ! restore PR
- ldc.l @r1+, gbr ! restore GBR
- ldc.l @r1+, vbr ! restore VBR
- lds.l @r1+, mach ! restore MACH
- lds.l @r1+, macl ! restore MACL
- mov.l @r1, r0
- add #-88, r1 ! readjust reg pointer to R1
- mov.l r0, @(4, r15) ! restore SR onto stack+4
- mov.l r2, @-r15
- mov.l L_in_nmi, r0
- mov #0, r2
- mov.b r2, @r0
- mov.l @r15+, r2
- mov.l @r1+, r0 ! restore R0
- rte
- mov.l @r1, r1 ! restore R1
-
-");
-}
-
-
-static __inline__ void code_for_catch_exception(int n)
-{
- asm(" .globl _catch_exception_%O0" : : "i" (n) );
- asm(" _catch_exception_%O0:" :: "i" (n) );
-
- asm(" add #-4, r15 ! reserve spot on stack ");
- asm(" mov.l r1, @-r15 ! push R1 ");
-
- if (n == NMI_VEC)
- {
- /* Special case for NMI - make sure that they don't nest */
- asm(" mov.l r0, @-r15 ! push R0");
- asm(" mov.l L_in_nmi, r0");
- asm(" tas.b @r0 ! Fend off against addtnl NMIs");
- asm(" bt noNMI");
- asm(" mov.l @r15+, r0");
- asm(" mov.l @r15+, r1");
- asm(" add #4, r15");
- asm(" rte");
- asm(" nop");
- asm(".align 2");
- asm("L_in_nmi: .long _in_nmi");
- asm("noNMI:");
- }
- else
- {
-
- if (n == CPU_BUS_ERROR_VEC)
- {
- /* Exception 9 (bus errors) are disasbleable - so that you
- can probe memory and get zero instead of a fault.
- Because the vector table may be in ROM we don't revector
- the interrupt like all the other stubs, we check in here
- */
- asm("mov.l L_dofault,r1");
- asm("mov.l @r1,r1");
- asm("tst r1,r1");
- asm("bf faultaway");
- asm("bsr _handle_buserror");
- asm(".align 2");
- asm("L_dofault: .long _dofault");
- asm("faultaway:");
- }
- asm(" mov #15<<4, r1 ");
- asm(" ldc r1, sr ! disable interrupts ");
- asm(" mov.l r0, @-r15 ! push R0 ");
- }
-
- /* Prepare for saving context, we've already pushed r0 and r1, stick exception number
- into the frame */
- asm(" mov r15, r0 ");
- asm(" add #8, r0 ");
- asm(" mov %0,r1" :: "i" (n) );
- asm(" extu.b r1,r1 ");
- asm(" bra saveRegisters ! save register values ");
- asm(" mov.l r1, @r0 ! save exception # ");
-}
-
-
-static void
-exceptions()
-{
- code_for_catch_exception (CPU_BUS_ERROR_VEC);
- code_for_catch_exception (DMA_BUS_ERROR_VEC);
- code_for_catch_exception (INVALID_INSN_VEC);
- code_for_catch_exception (INVALID_SLOT_VEC);
- code_for_catch_exception (NMI_VEC);
- code_for_catch_exception (TRAP_VEC);
- code_for_catch_exception (USER_VEC);
- code_for_catch_exception (IO_VEC);
-}
-
-
-
-
-
-
-/* Support for Serial I/O using on chip uart */
-
-#define SMR0 (*(volatile char *)(0x05FFFEC0)) /* Channel 0 serial mode register */
-#define BRR0 (*(volatile char *)(0x05FFFEC1)) /* Channel 0 bit rate register */
-#define SCR0 (*(volatile char *)(0x05FFFEC2)) /* Channel 0 serial control register */
-#define TDR0 (*(volatile char *)(0x05FFFEC3)) /* Channel 0 transmit data register */
-#define SSR0 (*(volatile char *)(0x05FFFEC4)) /* Channel 0 serial status register */
-#define RDR0 (*(volatile char *)(0x05FFFEC5)) /* Channel 0 receive data register */
-
-#define SMR1 (*(volatile char *)(0x05FFFEC8)) /* Channel 1 serial mode register */
-#define BRR1 (*(volatile char *)(0x05FFFEC9)) /* Channel 1 bit rate register */
-#define SCR1 (*(volatile char *)(0x05FFFECA)) /* Channel 1 serial control register */
-#define TDR1 (*(volatile char *)(0x05FFFECB)) /* Channel 1 transmit data register */
-#define SSR1 (*(volatile char *)(0x05FFFECC)) /* Channel 1 serial status register */
-#define RDR1 (*(volatile char *)(0x05FFFECD)) /* Channel 1 receive data register */
-
-/*
- * Serial mode register bits
- */
-
-#define SYNC_MODE 0x80
-#define SEVEN_BIT_DATA 0x40
-#define PARITY_ON 0x20
-#define ODD_PARITY 0x10
-#define STOP_BITS_2 0x08
-#define ENABLE_MULTIP 0x04
-#define PHI_64 0x03
-#define PHI_16 0x02
-#define PHI_4 0x01
-
-/*
- * Serial control register bits
- */
-#define SCI_TIE 0x80 /* Transmit interrupt enable */
-#define SCI_RIE 0x40 /* Receive interrupt enable */
-#define SCI_TE 0x20 /* Transmit enable */
-#define SCI_RE 0x10 /* Receive enable */
-#define SCI_MPIE 0x08 /* Multiprocessor interrupt enable */
-#define SCI_TEIE 0x04 /* Transmit end interrupt enable */
-#define SCI_CKE1 0x02 /* Clock enable 1 */
-#define SCI_CKE0 0x01 /* Clock enable 0 */
-
-/*
- * Serial status register bits
- */
-#define SCI_TDRE 0x80 /* Transmit data register empty */
-#define SCI_RDRF 0x40 /* Receive data register full */
-#define SCI_ORER 0x20 /* Overrun error */
-#define SCI_FER 0x10 /* Framing error */
-#define SCI_PER 0x08 /* Parity error */
-#define SCI_TEND 0x04 /* Transmit end */
-#define SCI_MPB 0x02 /* Multiprocessor bit */
-#define SCI_MPBT 0x01 /* Multiprocessor bit transfer */
-
-
-/*
- * Port B IO Register (PBIOR)
- */
-#define PBIOR (*(volatile char *)(0x05FFFFC6))
-#define PB15IOR 0x8000
-#define PB14IOR 0x4000
-#define PB13IOR 0x2000
-#define PB12IOR 0x1000
-#define PB11IOR 0x0800
-#define PB10IOR 0x0400
-#define PB9IOR 0x0200
-#define PB8IOR 0x0100
-#define PB7IOR 0x0080
-#define PB6IOR 0x0040
-#define PB5IOR 0x0020
-#define PB4IOR 0x0010
-#define PB3IOR 0x0008
-#define PB2IOR 0x0004
-#define PB1IOR 0x0002
-#define PB0IOR 0x0001
-
-/*
- * Port B Control Register (PBCR1)
- */
-#define PBCR1 (*(volatile short *)(0x05FFFFCC))
-#define PB15MD1 0x8000
-#define PB15MD0 0x4000
-#define PB14MD1 0x2000
-#define PB14MD0 0x1000
-#define PB13MD1 0x0800
-#define PB13MD0 0x0400
-#define PB12MD1 0x0200
-#define PB12MD0 0x0100
-#define PB11MD1 0x0080
-#define PB11MD0 0x0040
-#define PB10MD1 0x0020
-#define PB10MD0 0x0010
-#define PB9MD1 0x0008
-#define PB9MD0 0x0004
-#define PB8MD1 0x0002
-#define PB8MD0 0x0001
-
-#define PB15MD PB15MD1|PB14MD0
-#define PB14MD PB14MD1|PB14MD0
-#define PB13MD PB13MD1|PB13MD0
-#define PB12MD PB12MD1|PB12MD0
-#define PB11MD PB11MD1|PB11MD0
-#define PB10MD PB10MD1|PB10MD0
-#define PB9MD PB9MD1|PB9MD0
-#define PB8MD PB8MD1|PB8MD0
-
-#define PB_TXD1 PB11MD1
-#define PB_RXD1 PB10MD1
-#define PB_TXD0 PB9MD1
-#define PB_RXD0 PB8MD1
-
-/*
- * Port B Control Register (PBCR2)
- */
-#define PBCR2 0x05FFFFCE
-#define PB7MD1 0x8000
-#define PB7MD0 0x4000
-#define PB6MD1 0x2000
-#define PB6MD0 0x1000
-#define PB5MD1 0x0800
-#define PB5MD0 0x0400
-#define PB4MD1 0x0200
-#define PB4MD0 0x0100
-#define PB3MD1 0x0080
-#define PB3MD0 0x0040
-#define PB2MD1 0x0020
-#define PB2MD0 0x0010
-#define PB1MD1 0x0008
-#define PB1MD0 0x0004
-#define PB0MD1 0x0002
-#define PB0MD0 0x0001
-
-#define PB7MD PB7MD1|PB7MD0
-#define PB6MD PB6MD1|PB6MD0
-#define PB5MD PB5MD1|PB5MD0
-#define PB4MD PB4MD1|PB4MD0
-#define PB3MD PB3MD1|PB3MD0
-#define PB2MD PB2MD1|PB2MD0
-#define PB1MD PB1MD1|PB1MD0
-#define PB0MD PB0MD1|PB0MD0
-
-
-#ifdef MHZ
-#define BPS 32 * 9600 * MHZ / ( BAUD * 10)
-#else
-#define BPS 32 /* 9600 for 10 Mhz */
-#endif
-
-char getDebugChar (void);
-int putDebugChar (char);
-void handleError (char theSSR);
-
-void
-nop ()
-{
-
-}
-void
-init_serial()
-{
- int i;
-
- /* Clear TE and RE in Channel 1's SCR */
- SCR1 &= ~(SCI_TE | SCI_RE);
-
- /* Set communication to be async, 8-bit data, no parity, 1 stop bit and use internal clock */
-
- SMR1 = 0;
- BRR1 = BPS;
-
- SCR1 &= ~(SCI_CKE1 | SCI_CKE0);
-
- /* let the hardware settle */
-
- for (i = 0; i < 1000; i++)
- nop ();
-
- /* Turn on in and out */
- SCR1 |= SCI_RE | SCI_TE;
-
- /* Set the PFC to make RXD1 (pin PB8) an input pin and TXD1 (pin PB9) an output pin */
- PBCR1 &= ~(PB_TXD1 | PB_RXD1);
- PBCR1 |= PB_TXD1 | PB_RXD1;
-}
-
-
-int
-getDebugCharReady (void)
-{
- char mySSR;
- mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
- if ( mySSR )
- handleError ( mySSR );
- return SSR1 & SCI_RDRF ;
-}
-
-char
-getDebugChar (void)
-{
- char ch;
- char mySSR;
-
- while ( ! getDebugCharReady())
- ;
-
- ch = RDR1;
- SSR1 &= ~SCI_RDRF;
-
- mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
-
- if (mySSR)
- handleError (mySSR);
-
- return ch;
-}
-
-int
-putDebugCharReady()
-{
- return (SSR1 & SCI_TDRE);
-}
-
-int
-putDebugChar (char ch)
-{
- while (!putDebugCharReady())
- ;
-
- /*
- * Write data into TDR and clear TDRE
- */
- TDR1 = ch;
- SSR1 &= ~SCI_TDRE;
- return 1;
-}
-
-void
-handleError (char theSSR)
-{
- SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
-}
-