20000317 sourceware import
This commit is contained in:
698
libgloss/hp74x/pa_stub.c
Normal file
698
libgloss/hp74x/pa_stub.c
Normal file
@ -0,0 +1,698 @@
|
||||
/* -*-C-*-
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: pa_stub.c
|
||||
* RCS: $Header$
|
||||
* Description: main routines for PA RISC monitor stub
|
||||
* Author: Robert Quist
|
||||
* Created: Mon Nov 1 10:00:36 1993
|
||||
* Modified: Fri Nov 12 15:14:23 1993 (Robert Quist) quist@hpfcrdq
|
||||
* Language: C
|
||||
* Package: N/A
|
||||
* Status: Experimental (Do Not Distribute)
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Description: low level support for gdb debugger. $
|
||||
*
|
||||
* Considerations: only works on target hardware $
|
||||
*
|
||||
* NOTES: See Below $
|
||||
*
|
||||
* To enable debugger support, two things need to happen.
|
||||
*
|
||||
* One, a call to set_debug_traps() is necessary in order to allow
|
||||
* any breakpoints or error conditions to be properly intercepted and
|
||||
* reported to gdb.
|
||||
*
|
||||
* Two, a breakpoint needs to be generated to begin communication.
|
||||
* This is most easily accomplished by a call to breakpoint().
|
||||
* breakpoint() simulates a breakpoint
|
||||
|
||||
|
||||
*************
|
||||
*
|
||||
* The following gdb commands are supported:
|
||||
*
|
||||
* command function Return value
|
||||
*
|
||||
* g return the value of the CPU registers hex data or ENN
|
||||
* G set the value of the CPU registers OK or ENN
|
||||
*
|
||||
* mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
|
||||
* MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
|
||||
*
|
||||
* c Resume at current address SNN ( signal NN)
|
||||
* cAA..AA Continue at address AA..AA SNN
|
||||
*
|
||||
* s Step one instruction SNN
|
||||
* sAA..AA Step one instruction from AA..AA SNN
|
||||
*
|
||||
* k kill
|
||||
*
|
||||
* ? What was the last sigval ? SNN (signal NN)
|
||||
*
|
||||
* bBB..BB Set baud rate to BB..BB OK or BNN, then sets
|
||||
* baud rate
|
||||
*
|
||||
|
||||
************
|
||||
* All commands and responses are sent with a packet which includes a
|
||||
* checksum. A packet consists of :
|
||||
*
|
||||
* $<packet info>#<checksum>.
|
||||
*
|
||||
* where
|
||||
* <packet info> :: <characters representing the command or response>
|
||||
* <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
|
||||
*
|
||||
* When a packet is received, it is first acknowledged with either '+' or '-'.
|
||||
* '+' indicates a successful transfer. '-' indicates a failed transfer.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Host: Reply:
|
||||
* $m0,10#2a +$00010203040506070809101112131415#42
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <signal.h>
|
||||
#include "hppa-defs.h"
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* external low-level support
|
||||
*/
|
||||
#define OPT_PDC_CACHE 5
|
||||
#define OPT_PDC_ADD_VALID 12
|
||||
#define PGZ_MEM_PDC 0x0388 /* location of PDC_ENTRY in memory */
|
||||
#define CALL_PDC (*(int (*)())((int *)(*((int *)PGZ_MEM_PDC))))
|
||||
|
||||
extern putDebugChar(); /* write a single character */
|
||||
extern getDebugChar(); /* read and return a single char */
|
||||
extern FICE(); /* flush i cache entry */
|
||||
extern INLINE_BREAK(); /* break for user call */
|
||||
|
||||
#define RADDR_ALIGN(s,r) (s = ((unsigned int *) ((((int) r ) + 7 ) & 0xFFFFFFF8)))
|
||||
|
||||
/************************************************************************/
|
||||
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
|
||||
/* at least NUMREGBYTES*2 are needed for register packets */
|
||||
|
||||
#define BUFMAX 2048
|
||||
|
||||
#define NUMGPRS 32
|
||||
#define NUMSRS 8
|
||||
#define NUMCRS 32
|
||||
#define NUMSPCLS 3
|
||||
#define NUMFPRS 32
|
||||
|
||||
#define NUMGPRBYTES 4
|
||||
#define NUMSRBYTES 4
|
||||
#define NUMCRBYTES 4
|
||||
#define NUMSPCLBYTES 4
|
||||
#define NUMFPRBYTES 8
|
||||
|
||||
/* Number of bytes of registers. */
|
||||
#define NUMREGBYTES \
|
||||
( (NUMGPRS * NUMGPRBYTES) \
|
||||
+ (NUMSRS * NUMSRBYTES) \
|
||||
+ (NUMCRS * NUMCRBYTES) \
|
||||
+ (NUMSPCLS * NUMSPCLBYTES) \
|
||||
+ (NUMFPRS * NUMFPRBYTES) \
|
||||
)
|
||||
|
||||
|
||||
enum regnames {GR0, GR1, GR2, GR3, GR4, GR5, GR6, GR7,
|
||||
GR8, GR9, GR10, GR11, GR12, GR13, GR14, GR15,
|
||||
GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
|
||||
GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
|
||||
|
||||
SR0, SR1, SR2, SR3, SR4, SR5, SR6, SR7,
|
||||
|
||||
CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7,
|
||||
CR8, CR9, CR10, CR11, CR12, CR13, CR14, CR15,
|
||||
CR16, CR17H,CR18H,CR19, CR20, CR21, CR22, CR23,
|
||||
CR24, CR25, CR26, CR27, CR28, CR29, CR30, CR31,
|
||||
|
||||
CR17T,CR18T,CPUD0 };
|
||||
|
||||
enum fregnames {FPR0, FPR1, FPR2, FPR3, FPR4, FPR5, FPR6, FPR7,
|
||||
FPR8, FPR9, FPR10, FPR11, FPR12, FPR13, FPR14, FPR15,
|
||||
FPR16, FPR17, FPR18, FPR19, FPR20, FPR21, FPR22, FPR23,
|
||||
FPR24, FPR25, FPR26, FPR27, FPR28, FPR29, FPR30, FPR31 };
|
||||
|
||||
#define PC CR18H
|
||||
#define NPC CR18T
|
||||
#define SP GR30
|
||||
|
||||
struct registers {
|
||||
int intregs[NUMGPRS + NUMSRS + NUMCRS + NUMSPCLS];
|
||||
int fpregs [NUMFPRS * 2];
|
||||
};
|
||||
/* Global Variables */
|
||||
|
||||
static int initialized = 0; /* !0 means we've been initialized */
|
||||
static unsigned char hexchars[]="0123456789abcdef";
|
||||
static unsigned char remcomInBuffer[BUFMAX];
|
||||
static unsigned char remcomOutBuffer[BUFMAX];
|
||||
static unsigned int i_cache_params[6];
|
||||
|
||||
/* This table contains the mapping between PA hardware exception
|
||||
types, and signals, which are primarily what GDB understands. It also
|
||||
indicates which hardware traps we need to commandeer when initializing
|
||||
the stub.
|
||||
|
||||
The only two currently used are Recovery counter (single stepping)
|
||||
and Break trap ( break points ).
|
||||
*/
|
||||
|
||||
static struct hard_trap_info
|
||||
{
|
||||
unsigned char tt; /* Trap number for PA-RISC */
|
||||
unsigned char signo; /* Signal that we map this trap into */
|
||||
} hard_trap_info[] = {
|
||||
/* 1 High priority machine check */
|
||||
/* 2 Power failure interrupt*/
|
||||
/* 3 Recovery counter -- init */
|
||||
/* 4 External interrupt */
|
||||
/* 5 Low priority machine check */
|
||||
{6, SIGSEGV}, /* Instruction TLB miss/page fault */
|
||||
{7, SIGSEGV}, /* Memory protection */
|
||||
{8, SIGILL}, /* Illegal instruction */
|
||||
{9, SIGTRAP}, /* Break instruction -- init */
|
||||
{10,SIGILL}, /* Privileged instruction */
|
||||
{11,SIGILL}, /* Privileged register */
|
||||
{12,SIGUSR1}, /* Overflow */
|
||||
{13,SIGUSR2}, /* Conditional */
|
||||
{14,SIGEMT}, /* Assist Exception */
|
||||
{15,SIGSEGV}, /* Data TLB miss/page fault */
|
||||
{16,SIGSEGV}, /* Non-access Instruction TLB miss */
|
||||
{17,SIGSEGV}, /* Non-access Data TLB miss/page fault */
|
||||
{18,SIGSEGV}, /* Data memory protection/ unaligned data reference */
|
||||
{19,SIGTRAP}, /* Data memory break */
|
||||
{20,SIGSEGV}, /* TLB dirty bit */
|
||||
{21,SIGSEGV}, /* Page reference */
|
||||
{22,SIGEMT}, /* Assist emulation */
|
||||
{23,SIGILL}, /* Higher-privilege */
|
||||
{24,SIGILL}, /* Lower-privilege */
|
||||
{25,SIGTRAP}, /* Taken branch */
|
||||
{0, 0} /* Must be last */
|
||||
};
|
||||
|
||||
/* Functions */
|
||||
/*========================================================================== */
|
||||
|
||||
/* Convert ch from a hex digit to an int */
|
||||
|
||||
static int
|
||||
hex(ch)
|
||||
unsigned 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;
|
||||
}
|
||||
|
||||
/* scan for the sequence $<data>#<checksum> */
|
||||
|
||||
static void
|
||||
getpacket(buffer)
|
||||
char *buffer;
|
||||
{
|
||||
unsigned char checksum;
|
||||
unsigned char xmitcsum;
|
||||
int i;
|
||||
int count;
|
||||
unsigned char ch;
|
||||
|
||||
do
|
||||
{
|
||||
/* wait around for the start character, ignore all other characters */
|
||||
strobe();
|
||||
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;
|
||||
}
|
||||
|
||||
if (count >= BUFMAX)
|
||||
continue;
|
||||
|
||||
buffer[count] = 0;
|
||||
|
||||
if (ch == '#')
|
||||
{
|
||||
xmitcsum = hex(getDebugChar()) << 4;
|
||||
xmitcsum |= hex(getDebugChar());
|
||||
|
||||
#if TESTING
|
||||
/* Humans shouldn't have to figure out checksums to type to it. */
|
||||
putDebugChar ('+');
|
||||
return;
|
||||
#endif
|
||||
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. */
|
||||
|
||||
static void
|
||||
putpacket(buffer)
|
||||
unsigned char *buffer;
|
||||
{
|
||||
unsigned char checksum;
|
||||
int count;
|
||||
unsigned char ch;
|
||||
|
||||
/* $<packet info>#<checksum>. */
|
||||
|
||||
do
|
||||
{
|
||||
putDebugChar('$');
|
||||
checksum = 0;
|
||||
count = 0;
|
||||
|
||||
while (ch = buffer[count])
|
||||
{
|
||||
if (! putDebugChar(ch))
|
||||
return;
|
||||
checksum += ch;
|
||||
count += 1;
|
||||
}
|
||||
|
||||
putDebugChar('#');
|
||||
putDebugChar(hexchars[checksum >> 4]);
|
||||
putDebugChar(hexchars[checksum & 0xf]);
|
||||
} while (getDebugChar() != '+');
|
||||
}
|
||||
|
||||
/* Convert the memory pointed to by mem into hex, placing result in buf.
|
||||
* Return a pointer to the last char put in buf (null), in case of mem fault,
|
||||
* return 0.
|
||||
* If MAY_FAULT is non-zero, then we will handle memory faults by returning
|
||||
* a 0, else treat a fault like any other fault in the stub.
|
||||
*/
|
||||
|
||||
static unsigned char *
|
||||
mem2hex(mem, buf, count, may_fault)
|
||||
unsigned char *mem;
|
||||
unsigned char *buf;
|
||||
int count;
|
||||
int may_fault;
|
||||
{
|
||||
unsigned char ch;
|
||||
int check_addr,
|
||||
new_addr;
|
||||
|
||||
check_addr = 0;
|
||||
|
||||
while (count-- > 0)
|
||||
{
|
||||
if (may_fault)
|
||||
{ new_addr = ((int) (mem+3)) & 0xFFFFFFF8;
|
||||
if (new_addr != check_addr)
|
||||
{ check_addr = new_addr;
|
||||
if (pdc_call(OPT_PDC_ADD_VALID,0,check_addr)) return 0;
|
||||
}
|
||||
}
|
||||
ch = *mem++;
|
||||
*buf++ = hexchars[ch >> 4];
|
||||
*buf++ = hexchars[ch & 0xf];
|
||||
}
|
||||
|
||||
*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 unsigned char *
|
||||
hex2mem(buf, mem, count, may_fault)
|
||||
unsigned char *buf;
|
||||
unsigned char *mem;
|
||||
int count;
|
||||
int may_fault;
|
||||
{
|
||||
int i;
|
||||
unsigned int ch;
|
||||
int check_addr,
|
||||
new_addr;
|
||||
|
||||
check_addr = 0;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
ch = hex(*buf++) << 4;
|
||||
ch |= hex(*buf++);
|
||||
if (may_fault)
|
||||
{ new_addr = ((int)(mem+3)) & 0xFFFFFFF8;
|
||||
if (new_addr != check_addr)
|
||||
{ check_addr = new_addr;
|
||||
if (pdc_call(OPT_PDC_ADD_VALID,0,check_addr)) return 0;
|
||||
}
|
||||
}
|
||||
*mem++ = ch;
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
/* Set up exception handlers for traceing and breakpoints */
|
||||
|
||||
void
|
||||
set_debug_traps()
|
||||
{
|
||||
unsigned int R_addr[33];
|
||||
unsigned int *Raddr_ptr;
|
||||
|
||||
setup_vectors();
|
||||
|
||||
/* get cache params for use by flush_i_cache */
|
||||
RADDR_ALIGN(Raddr_ptr,R_addr);
|
||||
|
||||
if (pdc_call(OPT_PDC_CACHE,0,Raddr_ptr,0))
|
||||
i_cache_params[0] = -1;
|
||||
else
|
||||
i_cache_params[0] = R_addr[0];
|
||||
|
||||
i_cache_params[1] = Raddr_ptr[1];
|
||||
i_cache_params[2] = Raddr_ptr[2];
|
||||
i_cache_params[3] = Raddr_ptr[3];
|
||||
i_cache_params[4] = Raddr_ptr[4];
|
||||
i_cache_params[5] = Raddr_ptr[5];
|
||||
|
||||
/* In case GDB is started before us, ack any packets (presumably
|
||||
"$?#xx") sitting there. */
|
||||
|
||||
putDebugChar ('+');
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
|
||||
/* Convert the PA-RISC hardware trap number to a unix signal number. */
|
||||
|
||||
static int
|
||||
computeSignal(tt)
|
||||
int tt;
|
||||
{
|
||||
struct hard_trap_info *ht;
|
||||
|
||||
for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
|
||||
if (ht->tt == tt)
|
||||
return ht->signo;
|
||||
|
||||
return SIGHUP; /* default for things we don't know about */
|
||||
}
|
||||
|
||||
/*
|
||||
* While we find nice hex chars, build an int.
|
||||
* Return number of chars processed.
|
||||
*/
|
||||
|
||||
static int
|
||||
hexToInt(ptr, intValue)
|
||||
unsigned char **ptr;
|
||||
int *intValue;
|
||||
{
|
||||
int numChars = 0;
|
||||
int hexValue;
|
||||
|
||||
*intValue = 0;
|
||||
|
||||
while (**ptr)
|
||||
{
|
||||
hexValue = hex(**ptr);
|
||||
if (hexValue < 0)
|
||||
break;
|
||||
|
||||
*intValue = (*intValue << 4) | hexValue;
|
||||
numChars ++;
|
||||
|
||||
(*ptr)++;
|
||||
}
|
||||
|
||||
return (numChars);
|
||||
}
|
||||
|
||||
void
|
||||
flush_i_cache()
|
||||
|
||||
{
|
||||
unsigned int addr,count,loop;
|
||||
|
||||
if (i_cache_params[0] <= 0) return;
|
||||
|
||||
addr = i_cache_params[2];
|
||||
for (count = 0; count < i_cache_params[4]; count++)
|
||||
{ for ( loop = 0; loop < i_cache_params[5]; loop++) FICE(addr);
|
||||
addr = addr + i_cache_params[3];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function does all command procesing for interfacing to gdb.
|
||||
return of 0 will execute DEBUG_GO (continue)
|
||||
return of 1 will execute DEBUG_SS (single step)
|
||||
*/
|
||||
|
||||
int
|
||||
handle_exception (registers,tt)
|
||||
unsigned long *registers;
|
||||
int tt; /* Trap type */
|
||||
{
|
||||
int sigval;
|
||||
int addr;
|
||||
int length;
|
||||
unsigned char *ptr;
|
||||
|
||||
/* reply to host that an exception has occurred */
|
||||
sigval = computeSignal(tt);
|
||||
ptr = remcomOutBuffer;
|
||||
|
||||
*ptr++ = 'T';
|
||||
*ptr++ = hexchars[sigval >> 4];
|
||||
*ptr++ = hexchars[sigval & 0xf];
|
||||
|
||||
/* could be lots of stuff here like PC and SP registers */
|
||||
|
||||
*ptr++ = 0;
|
||||
|
||||
putpacket(remcomOutBuffer);
|
||||
|
||||
while (1)
|
||||
{
|
||||
remcomOutBuffer[0] = 0;
|
||||
|
||||
getpacket(remcomInBuffer);
|
||||
switch (remcomInBuffer[0])
|
||||
{
|
||||
case '?':
|
||||
remcomOutBuffer[0] = 'S';
|
||||
remcomOutBuffer[1] = hexchars[sigval >> 4];
|
||||
remcomOutBuffer[2] = hexchars[sigval & 0xf];
|
||||
remcomOutBuffer[3] = 0;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
/* toggle debug flag */
|
||||
led_putnum (16);
|
||||
break;
|
||||
|
||||
case 'g': /* return the value of the CPU registers */
|
||||
{
|
||||
ptr = remcomOutBuffer;
|
||||
/* GR0..GR31 SR0..SR7 CR0..CR31 specials */
|
||||
ptr = mem2hex((char *)registers, ptr, NUMREGBYTES, 0);
|
||||
/* need to add floating point registers */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G': /* set the value of the CPU registers - return OK */
|
||||
{
|
||||
ptr = &remcomInBuffer[1];
|
||||
/* GR0..GR31 SR0..SR7 CR0..CR31 specials */
|
||||
hex2mem(ptr, (char *)registers, NUMREGBYTES, 0);
|
||||
strcpy(remcomOutBuffer,"OK 1");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
|
||||
/* Try to read %x,%x. */
|
||||
|
||||
ptr = &remcomInBuffer[1];
|
||||
|
||||
if (hexToInt(&ptr, &addr)
|
||||
&& *ptr++ == ','
|
||||
&& hexToInt(&ptr, &length))
|
||||
{
|
||||
if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
|
||||
break;
|
||||
|
||||
strcpy (remcomOutBuffer, "E03");
|
||||
}
|
||||
else
|
||||
strcpy(remcomOutBuffer,"E01");
|
||||
break;
|
||||
|
||||
case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
|
||||
/* Try to read '%x,%x:'. */
|
||||
|
||||
ptr = &remcomInBuffer[1];
|
||||
|
||||
if (hexToInt(&ptr, &addr)
|
||||
&& *ptr++ == ','
|
||||
&& hexToInt(&ptr, &length)
|
||||
&& *ptr++ == ':')
|
||||
{
|
||||
if (hex2mem(ptr, (char *)addr, length, 1))
|
||||
strcpy(remcomOutBuffer, "OK");
|
||||
else
|
||||
strcpy(remcomOutBuffer, "E03");
|
||||
}
|
||||
else
|
||||
strcpy(remcomOutBuffer, "E02");
|
||||
break;
|
||||
|
||||
case 'c': /* cAA..AA Continue at address AA..AA(optional) */
|
||||
/* try to read optional parameter, pc unchanged if no parm */
|
||||
|
||||
ptr = &remcomInBuffer[1];
|
||||
if (hexToInt(&ptr, &addr))
|
||||
{
|
||||
registers[PC] = addr;
|
||||
registers[NPC] = addr + 4;
|
||||
}
|
||||
|
||||
/* Need to flush the instruction cache here, as we may have deposited a
|
||||
breakpoint, and the icache probably has no way of knowing that a data ref to
|
||||
some location may have changed something that is in the instruction cache.
|
||||
*/
|
||||
|
||||
flush_i_cache();
|
||||
return 0; /* execute GO */
|
||||
|
||||
/* kill the program */
|
||||
case 'k' : /* do nothing */
|
||||
break;
|
||||
|
||||
case 's' : /* single step */
|
||||
/* try to read optional parameter, pc unchanged if no parm */
|
||||
|
||||
ptr = &remcomInBuffer[1];
|
||||
if (hexToInt(&ptr, &addr))
|
||||
{
|
||||
registers[PC] = addr;
|
||||
registers[NPC] = addr + 4;
|
||||
}
|
||||
/* Need to flush the instruction cache here, as we may have deposited a
|
||||
breakpoint, and the icache probably has no way of knowing that a data ref to
|
||||
some location may have changed something that is in the instruction cache.
|
||||
*/
|
||||
flush_i_cache();
|
||||
return 1; /* execute Single Step */
|
||||
break;
|
||||
|
||||
#if TESTING1
|
||||
case 't': /* Test feature */
|
||||
break;
|
||||
#endif
|
||||
case 'r': /* Reset */
|
||||
break;
|
||||
|
||||
#if TESTING2
|
||||
Disabled until we can unscrew this properly
|
||||
|
||||
case 'b': /* bBB... Set baud rate to BB... */
|
||||
{
|
||||
int baudrate;
|
||||
extern void set_timer_3();
|
||||
|
||||
ptr = &remcomInBuffer[1];
|
||||
if (!hexToInt(&ptr, &baudrate))
|
||||
{
|
||||
strcpy(remcomOutBuffer,"B01");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Convert baud rate to uart clock divider */
|
||||
switch (baudrate)
|
||||
{
|
||||
case 38400:
|
||||
baudrate = 16;
|
||||
break;
|
||||
case 19200:
|
||||
baudrate = 33;
|
||||
break;
|
||||
case 9600:
|
||||
baudrate = 65;
|
||||
break;
|
||||
default:
|
||||
strcpy(remcomOutBuffer,"B02");
|
||||
goto x1;
|
||||
}
|
||||
|
||||
putpacket("OK 2"); /* Ack before changing speed */
|
||||
set_timer_3(baudrate); /* Set it */
|
||||
}
|
||||
x1: break;
|
||||
#endif
|
||||
} /* switch */
|
||||
|
||||
/* reply to the request */
|
||||
putpacket(remcomOutBuffer);
|
||||
}
|
||||
print ("\r\nEscaped handle_exception\r\n");
|
||||
}
|
Reference in New Issue
Block a user