Line 43... |
Line 43... |
#define debug if (remote_debug) printf_unfiltered
|
#define debug if (remote_debug) printf_unfiltered
|
|
|
/* The following prototype is necessary or the compiler will not
|
/* The following prototype is necessary or the compiler will not
|
correctly promote the data argument to ULONGEST */
|
correctly promote the data argument to ULONGEST */
|
static void or1k_write_reg (unsigned int, ULONGEST);
|
static void or1k_write_reg (unsigned int, ULONGEST);
|
|
static int insn_has_delay_slot (unsigned int);
|
|
|
/* JTAG or1k target ops. */
|
/* JTAG or1k target ops. */
|
extern void jtag_init PARAMS ((char * args));
|
extern void jtag_init PARAMS ((char * args));
|
extern ULONGEST jtag_read_reg PARAMS ((unsigned int regno));
|
extern ULONGEST jtag_read_reg PARAMS ((unsigned int regno));
|
extern void jtag_write_reg PARAMS ((unsigned int regno, ULONGEST data));
|
extern void jtag_write_reg PARAMS ((unsigned int regno, ULONGEST data));
|
Line 519... |
Line 520... |
|
|
/* Enable exceptions */
|
/* Enable exceptions */
|
or1k_write_spr_reg (SR_SPRNUM, or1k_read_spr_reg(SR_SPRNUM) | 0x2);
|
or1k_write_spr_reg (SR_SPRNUM, or1k_read_spr_reg(SR_SPRNUM) | 0x2);
|
|
|
/* Stop when breakpoint occurs. */
|
/* Stop when breakpoint occurs. */
|
or1k_write_spr_reg (DSR_SPRNUM, 0x2000);
|
or1k_write_spr_reg (DSR_SPRNUM, dsr = 0x2000);
|
|
|
do_cleanups (old_cleanups);
|
do_cleanups (old_cleanups);
|
|
|
/* This should cause an error if not connected. */
|
/* This should cause an error if not connected. */
|
or1k_fetch_registers (-1);
|
or1k_fetch_registers (-1);
|
Line 729... |
Line 730... |
static void
|
static void
|
or1k_resume (pid, step, siggnal)
|
or1k_resume (pid, step, siggnal)
|
int pid, step;
|
int pid, step;
|
enum target_signal siggnal;
|
enum target_signal siggnal;
|
{
|
{
|
debug ("pc = %08x\n", read_pc());
|
unsigned int pc;
|
|
unsigned int ppc;
|
|
unsigned int npc;
|
|
unsigned int val;
|
|
|
|
pc = read_pc();
|
|
npc = or1k_read_spr_reg (PC_SPRNUM);
|
|
ppc = or1k_read_spr_reg (PPC_SPRNUM);
|
|
debug ("pc = %08x BP = %x npc = %08x ppc = %08x\n", pc, breakpoint_here_p (pc), npc, ppc);
|
debug ("resume %i, %i, %i\n",step, siggnal, or1k_status);
|
debug ("resume %i, %i, %i\n",step, siggnal, or1k_status);
|
if (or1k_status != TARGET_STOPPED)
|
if (or1k_status != TARGET_STOPPED)
|
if (or1k_status == TARGET_RUNNING)
|
if (or1k_status == TARGET_RUNNING)
|
error ("Program is already running.");
|
error ("Program is already running.");
|
else
|
else
|
Line 750... |
Line 759... |
{
|
{
|
/* HW STEP. Set DMR1_ST. */
|
/* HW STEP. Set DMR1_ST. */
|
dmr1 |= DMR1_ST;
|
dmr1 |= DMR1_ST;
|
or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
|
or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
|
dmr1 &= ~DMR1_ST;
|
dmr1 &= ~DMR1_ST;
|
|
|
|
if (breakpoint_here_p (pc) && ((ppc + 4) != npc))
|
|
{
|
|
/* Trapped on delay slot instruction. */
|
|
/* Set PC to branch insn preceding delay slot. */
|
|
or1k_write_spr_reg (PC_SPRNUM, ppc - 4);
|
|
|
|
or1k_unstall ();
|
|
|
|
or1k_set_chain (SC_REGISTER);
|
|
val = or1k_read_reg (JTAG_RISCOP);
|
|
do {
|
|
val = or1k_read_reg (JTAG_RISCOP);
|
|
} while ((val & 1) == 0);
|
|
}
|
|
else if (breakpoint_here_p (npc) && insn_has_delay_slot (or1k_fetch_instruction (ppc)))
|
|
{
|
|
/* Steping to the trap insn in delay slot - we need to execute branch insn again */
|
|
debug ("resume: steping to the trap insn in delay slot\n");
|
|
or1k_write_spr_reg (PC_SPRNUM, ppc);
|
|
|
|
or1k_unstall ();
|
|
|
|
or1k_set_chain (SC_REGISTER);
|
|
val = or1k_read_reg (JTAG_RISCOP);
|
|
do {
|
|
val = or1k_read_reg (JTAG_RISCOP);
|
|
} while ((val & 1) == 0);
|
|
}
|
|
else if (breakpoint_here_p (pc))
|
|
or1k_write_spr_reg (PC_SPRNUM, pc);
|
}
|
}
|
else
|
else
|
{
|
{
|
dmr1 &= ~DMR1_ST;
|
dmr1 &= ~DMR1_ST;
|
or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
|
or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
|
Line 772... |
Line 812... |
int pid;
|
int pid;
|
struct target_waitstatus *status;
|
struct target_waitstatus *status;
|
{
|
{
|
unsigned long val;
|
unsigned long val;
|
unsigned long pc;
|
unsigned long pc;
|
|
unsigned long npc;
|
|
unsigned long ppc;
|
char buf[MAX_REGISTER_RAW_SIZE];
|
char buf[MAX_REGISTER_RAW_SIZE];
|
interrupt_count = 0;
|
interrupt_count = 0;
|
|
|
debug ("pc = %08x\n", read_pc());
|
|
debug ("wait %i %i\n", pid, or1k_status);
|
debug ("wait %i %i\n", pid, or1k_status);
|
/* If we have not sent a single step or continue command, then the
|
/* If we have not sent a single step or continue command, then the
|
board is waiting for us to do something. Return a status
|
board is waiting for us to do something. Return a status
|
indicating that it is stopped. */
|
indicating that it is stopped. */
|
if (or1k_status != TARGET_RUNNING)
|
if (or1k_status != TARGET_RUNNING)
|
Line 814... |
Line 855... |
drr = or1k_read_spr_reg (DRR_SPRNUM);
|
drr = or1k_read_spr_reg (DRR_SPRNUM);
|
|
|
/* Restore old INT signal handler */
|
/* Restore old INT signal handler */
|
signal (SIGINT, ofunc);
|
signal (SIGINT, ofunc);
|
|
|
/* If we encounter breakpoint, drr is not set, so we set it manually. */
|
/* Single step does not set trap exception, so we set it manually to simplify our code */
|
if (!drr)
|
dmr1 = or1k_read_spr_reg (DMR1_SPRNUM);
|
drr |= DRR_BE;
|
if (dmr1 & DMR1_ST)
|
|
drr |= DRR_TE;
|
|
|
status->kind = TARGET_WAITKIND_STOPPED;
|
status->kind = TARGET_WAITKIND_STOPPED;
|
|
|
debug ("epcr0 = %08x\n", or1k_read_spr_reg (EPCR0_SPRNUM));
|
debug ("epcr0 = %08x\n", or1k_read_spr_reg (EPCR0_SPRNUM));
|
debug ("drr = %08x\n", drr);
|
debug ("drr = %08x\n", drr);
|
|
|
registers_changed ();
|
registers_changed ();
|
pc = read_pc ();
|
pc = read_pc ();
|
debug ("pc = %08x\n", pc);
|
npc = or1k_read_spr_reg (PC_SPRNUM);
|
|
ppc = or1k_read_spr_reg (PPC_SPRNUM);
|
|
debug ("npc = %08x ppc = %08x\n", npc, ppc);
|
|
|
if (drr & DRR_RSTE)
|
if (drr & DRR_TE)
|
|
{
|
|
/* If single step is not set, we should correct the pc. */
|
|
if (!(dmr1 & DMR1_ST))
|
|
/* PC has already stepped over the l.trap instruction. */
|
|
pc = ppc;
|
|
status->value.sig = TARGET_SIGNAL_TRAP;
|
|
drr &= ~DRR_TE;
|
|
}
|
|
else if (drr & DRR_RSTE)
|
|
{
|
status->value.sig = TARGET_SIGNAL_REALTIME_33;
|
status->value.sig = TARGET_SIGNAL_REALTIME_33;
|
|
drr &= ~DRR_RSTE;
|
|
}
|
else if (drr & DRR_BUSEE)
|
else if (drr & DRR_BUSEE)
|
|
{
|
status->value.sig = TARGET_SIGNAL_BUS;
|
status->value.sig = TARGET_SIGNAL_BUS;
|
else if (drr & DRR_DPFE)
|
drr &= ~DRR_BUSEE;
|
status->value.sig = TARGET_SIGNAL_REALTIME_34;
|
}
|
else if (drr & DRR_IPFE)
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_35;
|
|
else if (drr & DRR_LPINTE)
|
|
status->value.sig = TARGET_SIGNAL_INT;
|
|
else if (drr & DRR_AE)
|
else if (drr & DRR_AE)
|
|
{
|
status->value.sig = TARGET_SIGNAL_REALTIME_36;
|
status->value.sig = TARGET_SIGNAL_REALTIME_36;
|
|
drr &= ~DRR_AE;
|
|
}
|
else if (drr & DRR_IIE)
|
else if (drr & DRR_IIE)
|
|
{
|
status->value.sig = TARGET_SIGNAL_ILL;
|
status->value.sig = TARGET_SIGNAL_ILL;
|
else if (drr & DRR_HPINTE)
|
drr &= ~DRR_IIE;
|
status->value.sig = TARGET_SIGNAL_INT;
|
}
|
else if (drr & DRR_DME)
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_37;
|
|
else if (drr & DRR_IME)
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_38;
|
|
else if (drr & DRR_RE)
|
else if (drr & DRR_RE)
|
|
{
|
status->value.sig = TARGET_SIGNAL_REALTIME_39;
|
status->value.sig = TARGET_SIGNAL_REALTIME_39;
|
|
drr &= ~DRR_RE;
|
|
}
|
|
else if (drr & DRR_IME)
|
|
{
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_38;
|
|
drr &= ~DRR_IME;
|
|
}
|
|
else if (drr & DRR_DME)
|
|
{
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_37;
|
|
drr &= ~DRR_DME;
|
|
}
|
|
else if (drr & DRR_DPFE)
|
|
{
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_34;
|
|
drr &= ~DRR_DPFE;
|
|
}
|
|
else if (drr & DRR_IPFE)
|
|
{
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_35;
|
|
drr &= ~DRR_DPFE;
|
|
}
|
else if (drr & DRR_SCE)
|
else if (drr & DRR_SCE)
|
|
{
|
status->value.sig = TARGET_SIGNAL_REALTIME_40;
|
status->value.sig = TARGET_SIGNAL_REALTIME_40;
|
else if (drr & DRR_BE)
|
drr &= ~DRR_SCE;
|
status->value.sig = TARGET_SIGNAL_TRAP;
|
}
|
else if (drr & DRR_TE)
|
else if (drr & DRR_HPINTE)
|
|
{
|
|
status->value.sig = TARGET_SIGNAL_INT;
|
|
drr &= ~DRR_HPINTE;
|
|
}
|
|
else if (drr & DRR_LPINTE)
|
|
{
|
|
status->value.sig = TARGET_SIGNAL_INT;
|
|
drr &= ~DRR_LPINTE;
|
|
}
|
|
else
|
{
|
{
|
/* PC has already stepped over the l.trap instruction. */
|
|
pc -= 8;
|
|
status->value.sig = TARGET_SIGNAL_TRAP;
|
|
} else {
|
|
status->value.sig = TARGET_SIGNAL_UNKNOWN;
|
status->value.sig = TARGET_SIGNAL_UNKNOWN;
|
warning ("Invalid exception occured.");
|
warning ("Invalid exception occured.");
|
}
|
}
|
|
|
|
/* Update drr register */
|
|
or1k_write_spr_reg (DRR_SPRNUM, drr);
|
|
|
/* Write into PC flushes the pipeline! */
|
/* Write into PC flushes the pipeline! */
|
/* We got the number the register holds, but gdb expects to see a
|
/* We got the number the register holds, but gdb expects to see a
|
value in the target byte ordering. */
|
value in the target byte ordering. */
|
write_pc (pc);
|
/* write_pc (pc);
|
|
*/
|
|
store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), pc);
|
|
supply_register (PC_REGNUM, buf);
|
|
|
/*or1k_write_spr_reg (PC_SPRNUM, pc);
|
/*or1k_write_spr_reg (PC_SPRNUM, pc);
|
store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), pc);
|
store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), pc);
|
supply_register (PC_REGNUM, buf);*/
|
supply_register (PC_REGNUM, buf);*/
|
|
|
/* Log remote stop. */
|
/* Log remote stop. */
|
Line 1660... |
Line 1750... |
if ((dmr2 >> (i + 11)) & 1)
|
if ((dmr2 >> (i + 11)) & 1)
|
printf_filtered (", increments counter");
|
printf_filtered (", increments counter");
|
printf_filtered ("\n");
|
printf_filtered ("\n");
|
}
|
}
|
}
|
}
|
|
static int
|
|
insn_has_delay_slot (insn)
|
|
unsigned int insn;
|
|
{
|
|
if (((insn >> 26) <= 4) || ((insn >> 26) == 17) || ((insn >> 26) == 18))
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
void
|
void
|
_initialize_remote_or1k ()
|
_initialize_remote_or1k ()
|
{
|
{
|
/* Initialize the fields in or1k_ops that are common to all targets. */
|
/* Initialize the fields in or1k_ops that are common to all targets. */
|