#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "srec.h"
#include "arch-utils.h"
static serial_t parallel;
static int parallel_in_use;
static void sh3_open (char *args, int from_tty);
static void
sh3_supply_register (char *regname, int regnamelen, char *val, int vallen)
{
int numregs;
int regno;
numregs = 1;
regno = -1;
if (regnamelen == 2)
{
switch (regname[0])
{
case 'S':
if (regname[1] == 'R')
regno = SR_REGNUM;
break;
case 'P':
if (regname[1] == 'C')
regno = PC_REGNUM;
else if (regname[1] == 'R')
regno = PR_REGNUM;
break;
}
}
else if (regnamelen == 3)
{
switch (regname[0])
{
case 'G':
case 'V':
if (regname[1] == 'B' && regname[2] == 'R')
{
if (regname[0] == 'G')
regno = VBR_REGNUM;
else
regno = GBR_REGNUM;
}
break;
case 'S':
if (regname[1] == 'S' && regname[2] == 'R')
regno = gdbarch_tdep (current_gdbarch)->SSR_REGNUM;
else if (regname[1] == 'P' && regname[2] == 'C')
regno = gdbarch_tdep (current_gdbarch)->SPC_REGNUM;
break;
}
}
else if (regnamelen == 4)
{
switch (regname[0])
{
case 'M':
if (regname[1] == 'A' && regname[2] == 'C')
{
if (regname[3] == 'H')
regno = MACH_REGNUM;
else if (regname[3] == 'L')
regno = MACL_REGNUM;
}
break;
case 'R':
if (regname[1] == '0' && regname[2] == '-' && regname[3] == '7')
{
regno = R0_REGNUM;
numregs = 8;
}
}
}
else if (regnamelen == 5)
{
if (regname[1] == '8' && regname[2] == '-' && regname[3] == '1'
&& regname[4] == '5')
{
regno = R0_REGNUM + 8;
numregs = 8;
}
}
else if (regnamelen == 17)
{
}
if (regno >= 0)
while (numregs-- > 0)
val = monitor_supply_register (regno++, val);
}
static void
sh3_load (serial_t desc, char *file, int hashmark)
{
if (parallel_in_use)
{
monitor_printf ("pl;s\r");
load_srec (parallel, file, 0, 80, SREC_ALL, hashmark, NULL);
monitor_expect_prompt (NULL, 0);
}
else
{
monitor_printf ("il;s:x\r");
monitor_expect ("\005", NULL, 0);
SERIAL_WRITE (desc, "\006", 1);
monitor_expect ("LO x\r", NULL, 0);
load_srec (desc, file, 0, 80, SREC_ALL, hashmark, NULL);
monitor_expect ("\005", NULL, 0);
SERIAL_WRITE (desc, "\006", 1);
monitor_expect_prompt (NULL, 0);
}
}
static char *sh3_regnames[] =
{
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
"R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
"PC", "PR", "GBR", "VBR", "MACH", "MACL", "SR",
NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"SSR", "SPC",
"R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
"R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
"R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
"R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
};
static char *sh3e_regnames[] =
{
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
"R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
"PC", "PR", "GBR", "VBR", "MACH", "MACL", "SR",
"FPUL", "FPSCR",
"FR0", "FR1", "FR2", "FR3", "FR4", "FR5", "FR6", "FR7",
"FR8", "FR9", "FR10", "FR11", "FR12", "FR13", "FR14", "FR15",
"SSR", "SPC",
"R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
"R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
"R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
"R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
};
static struct target_ops sh3_ops, sh3e_ops;
static char *sh3_inits[] =
{"\003", NULL};
static struct monitor_ops sh3_cmds;
static void
init_sh3_cmds (void)
{
sh3_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_GETMEM_READ_SINGLE;
sh3_cmds.init = sh3_inits;
sh3_cmds.cont = "g\r";
sh3_cmds.step = "s\r";
sh3_cmds.stop = "\003";
sh3_cmds.set_break = "b %x\r";
sh3_cmds.clr_break = "b -%x\r";
sh3_cmds.clr_all_break = "b -\r";
sh3_cmds.fill = "f %x @%x %x\r";
sh3_cmds.setmem.cmdb = "m %x %x\r";
sh3_cmds.setmem.cmdw = "m %x %x;w\r";
sh3_cmds.setmem.cmdl = "m %x %x;l\r";
sh3_cmds.setmem.cmdll = NULL;
sh3_cmds.setmem.resp_delim = NULL;
sh3_cmds.setmem.term = NULL;
sh3_cmds.setmem.term_cmd = NULL;
sh3_cmds.getmem.cmdb = "m %x\r";
sh3_cmds.getmem.cmdw = "m %x;w\r";
sh3_cmds.getmem.cmdl = "m %x;l\r";
sh3_cmds.getmem.cmdll = NULL;
sh3_cmds.getmem.resp_delim = "^ [0-9A-F]+ ";
sh3_cmds.getmem.term = "? ";
sh3_cmds.getmem.term_cmd = ".\r";
sh3_cmds.setreg.cmd = ".%s %x\r";
sh3_cmds.setreg.resp_delim = NULL;
sh3_cmds.setreg.term = NULL;
sh3_cmds.setreg.term_cmd = NULL;
sh3_cmds.getreg.cmd = ".%s\r";
sh3_cmds.getreg.resp_delim = "=";
sh3_cmds.getreg.term = "? ";
sh3_cmds.getreg.term_cmd = ".\r";
sh3_cmds.dump_registers = "r\r";
sh3_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\( +[0-9a-fA-F]+\\b\\)*\\)";
sh3_cmds.supply_register = sh3_supply_register;
sh3_cmds.load_routine = sh3_load;
sh3_cmds.load = NULL;
sh3_cmds.loadresp = NULL;
sh3_cmds.prompt = "\n:";
sh3_cmds.line_term = "\r";
sh3_cmds.cmd_end = ".\r";
sh3_cmds.target = &sh3_ops;
sh3_cmds.stopbits = SERIAL_1_STOPBITS;
sh3_cmds.regnames = sh3_regnames;
sh3_cmds.magic = MONITOR_OPS_MAGIC;
}
static struct monitor_ops sh3e_cmds;
static void
sh3_open (char *args, int from_tty)
{
char *serial_port_name = args;
char *parallel_port_name = 0;
if (args)
{
char *cursor = serial_port_name = strsave (args);
while (*cursor && *cursor != ' ')
cursor++;
if (*cursor)
*cursor++ = 0;
while (*cursor == ' ')
cursor++;
if (*cursor)
parallel_port_name = cursor;
}
monitor_open (serial_port_name, &sh3_cmds, from_tty);
if (parallel_port_name)
{
parallel = SERIAL_OPEN (parallel_port_name);
if (!parallel)
perror_with_name ("Unable to open parallel port.");
parallel_in_use = 1;
}
set_architecture_from_arch_mach (bfd_arch_sh, bfd_mach_sh3);
}
static void
sh3e_open (char *args, int from_tty)
{
char *serial_port_name = args;
char *parallel_port_name = 0;
if (args)
{
char *cursor = serial_port_name = strsave (args);
while (*cursor && *cursor != ' ')
cursor++;
if (*cursor)
*cursor++ = 0;
while (*cursor == ' ')
cursor++;
if (*cursor)
parallel_port_name = cursor;
}
memcpy (&sh3e_cmds, &sh3_cmds, sizeof (struct monitor_ops));
sh3e_cmds.target = &sh3e_ops;
sh3e_cmds.regnames = sh3e_regnames;
monitor_open (serial_port_name, &sh3e_cmds, from_tty);
if (parallel_port_name)
{
parallel = SERIAL_OPEN (parallel_port_name);
if (!parallel)
perror_with_name ("Unable to open parallel port.");
parallel_in_use = 1;
}
set_architecture_from_arch_mach (bfd_arch_sh, bfd_mach_sh3);
}
static void
sh3_close (int quitting)
{
monitor_close (quitting);
if (parallel_in_use)
{
SERIAL_CLOSE (parallel);
parallel_in_use = 0;
}
}
void
_initialize_sh3_rom (void)
{
init_sh3_cmds ();
init_monitor_ops (&sh3_ops);
sh3_ops.to_shortname = "sh3";
sh3_ops.to_longname = "Hitachi SH-3 rom monitor";
sh3_ops.to_doc =
#ifdef _WINDOWS
"Debug on a Hitachi eval board running the SH-3 rom monitor.\n"
"Specify the serial device it is connected to (e.g. com2).\n"
"If you want to use the parallel port to download to it, specify that\n"
"as the second argument. (e.g. lpt1)";
#else
"Debug on a Hitachi eval board running the SH-3 rom monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
#endif
sh3_ops.to_open = sh3_open;
sh3_ops.to_close = sh3_close;
add_target (&sh3_ops);
init_monitor_ops (&sh3e_ops);
sh3e_ops.to_shortname = "sh3e";
sh3e_ops.to_longname = "Hitachi SH-3E rom monitor";
sh3e_ops.to_doc =
#ifdef _WINDOWS
"Debug on a Hitachi eval board running the SH-3E rom monitor.\n"
"Specify the serial device it is connected to (e.g. com2).\n"
"If you want to use the parallel port to download to it, specify that\n"
"as the second argument. (e.g. lpt1)";
#else
"Debug on a Hitachi eval board running the SH-3E rom monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
#endif
sh3e_ops.to_open = sh3e_open;
sh3e_ops.to_close = sh3_close;
add_target (&sh3e_ops);
}