Line 162... |
Line 162... |
unsigned int dmr1 = 0;
|
unsigned int dmr1 = 0;
|
unsigned int dmr2 = 0;
|
unsigned int dmr2 = 0;
|
unsigned int dsr = 0;
|
unsigned int dsr = 0;
|
unsigned int drr = 0;
|
unsigned int drr = 0;
|
|
|
|
static void (*old_sigint) (); /* Old signal-handler for sigint */
|
|
static int interrupt_requested = 0; /* Interrupted flag */
|
|
static void or1k_request_int ()
|
|
{
|
|
/* restore original signalhandler */
|
|
signal (SIGINT, old_sigint);
|
|
interrupt_requested = 1;
|
|
}
|
|
|
/* Current matchpoints. */
|
/* Current matchpoints. */
|
unsigned int dvr[MAX_MATCHPOINTS];
|
unsigned int dvr[MAX_MATCHPOINTS];
|
struct dcr_struct dcr[MAX_MATCHPOINTS];
|
struct dcr_struct dcr[MAX_MATCHPOINTS];
|
|
|
int matchpoint_user_count[MAX_MATCHPOINTS] = {0};
|
int matchpoint_user_count[MAX_MATCHPOINTS] = {0};
|
Line 297... |
Line 306... |
{
|
{
|
or1k_set_chain (SC_RISC_DEBUG);
|
or1k_set_chain (SC_RISC_DEBUG);
|
return or1k_read_reg (regno + REG_SPACE);
|
return or1k_read_reg (regno + REG_SPACE);
|
}
|
}
|
|
|
|
/* CZ 15/09/01 -- This is hacked in right now. This should
|
|
probably NOT be called directly, but at the moment I don't
|
|
have the time to figure out how to do it right. The problem
|
|
is the following, in order to write the PC, I may need to
|
|
step the processor...(long story, but trust me, I need to
|
|
do this)...I need to do this sometimes even when I have
|
|
not started or even loaded a program, thus I can not
|
|
use the default routines gdb provides for this purpose.
|
|
|
|
I do not wish to embed targets directly into or1k-tdep,
|
|
but I need a simple function there that will cause the
|
|
processor to continue 1 instruction and not pay attention
|
|
to gdb's state machine. I know this could conceivably break
|
|
things if we stop connecting via jtag and start doing
|
|
something else, so anyone who wants to figure out how to do
|
|
this right is welcome. Drop me an email if you want to
|
|
correct it. I'll try to help you understand the issue. */
|
|
|
|
/* The processor should already be in single step mode or
|
|
this will continue indefinitely! */
|
|
void or1k_do_1_processor_step()
|
|
{
|
|
unsigned long drr = 0;
|
|
unsigned long val;
|
|
|
|
/* Run the processor */
|
|
or1k_set_chain (SC_REGISTER);
|
|
val = or1k_read_reg (JTAG_RISCOP);
|
|
or1k_write_reg (JTAG_RISCOP, val & ~1);
|
|
|
|
/* Wait for the DEBUG_REASON_REGISTER to be non zero */
|
|
while(!(drr = or1k_read_spr_reg (DRR_SPRNUM)))
|
|
usleep (10);
|
|
|
|
/* OK..we're done */
|
|
}
|
|
|
|
static int saved_stall_state = 0;
|
|
void or1k_save_stall_state()
|
|
{
|
|
or1k_set_chain (SC_REGISTER);
|
|
saved_stall_state = or1k_read_reg (JTAG_RISCOP) & 0x01;
|
|
}
|
|
void or1k_restore_stall_state()
|
|
{
|
|
int val;
|
|
|
|
or1k_set_chain (SC_REGISTER);
|
|
val = or1k_read_reg (JTAG_RISCOP);
|
|
val |= saved_stall_state;
|
|
or1k_write_reg (JTAG_RISCOP, val);
|
|
saved_stall_state = 0;
|
|
}
|
|
|
/* Stalls the CPU. */
|
/* Stalls the CPU. */
|
|
|
static void
|
static void
|
or1k_stall ()
|
or1k_stall ()
|
{
|
{
|
Line 320... |
Line 383... |
static void
|
static void
|
or1k_unstall ()
|
or1k_unstall ()
|
{
|
{
|
unsigned int val;
|
unsigned int val;
|
|
|
|
|
or1k_set_chain (SC_REGISTER);
|
or1k_set_chain (SC_REGISTER);
|
val = or1k_read_reg (JTAG_RISCOP);
|
val = or1k_read_reg (JTAG_RISCOP);
|
or1k_write_reg (JTAG_RISCOP, val & ~1);
|
or1k_write_reg (JTAG_RISCOP, val & ~1);
|
}
|
}
|
|
|
Line 643... |
Line 707... |
or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
|
or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
|
}
|
}
|
|
|
or1k_commit_debug_registers ();
|
or1k_commit_debug_registers ();
|
/* Run the target. */
|
/* Run the target. */
|
|
#ifdef NEW_PC_HANDLING
|
|
|
|
/* In the new style PC handling mode, we should always
|
|
keep stepping the target until we get out of the
|
|
breakpoint exception vector assuming that "step"
|
|
has been specified. Otherwise, this isn't
|
|
particularly useful, as we'll keep hitting the
|
|
same breakpoint that put us here in the first
|
|
place. By stepping out of this vector we guarantee
|
|
to step over the instruction that caused the
|
|
breakpoint, so when they are reinserted we are
|
|
already past that location. */
|
|
if(step)
|
|
{
|
|
while((or1k_read_spr_reg(PC_SPRNUM) & 0xFFFFFF00) == 0xD00)
|
|
or1k_do_1_processor_step();
|
|
}
|
|
#endif
|
|
|
|
/* We can now continue normally, independent of step */
|
or1k_unstall ();
|
or1k_unstall ();
|
or1k_status = TARGET_RUNNING;
|
or1k_status = TARGET_RUNNING;
|
}
|
}
|
|
|
/* Wait until the remote stops, and return a wait status. */
|
/* Wait until the remote stops, and return a wait status. */
|
Line 672... |
Line 756... |
|
|
if (err)
|
if (err)
|
or1k_error ("Remote failure: %s", or1k_err_name (err));
|
or1k_error ("Remote failure: %s", or1k_err_name (err));
|
|
|
/* Wait for or1k DRR register to be nonzero. */
|
/* Wait for or1k DRR register to be nonzero. */
|
|
interrupt_requested = 0;
|
|
old_sigint = signal (SIGINT, or1k_request_int);
|
do
|
do
|
{
|
{
|
|
if(interrupt_requested)
|
|
{
|
|
or1k_stall();
|
|
status->kind = TARGET_WAITKIND_STOPPED;
|
|
status->value.sig = TARGET_SIGNAL_INT;
|
|
or1k_status = TARGET_STOPPED;
|
|
or1k_read_trace();
|
|
return 0;
|
|
}
|
drr = or1k_read_spr_reg (DRR_SPRNUM);
|
drr = or1k_read_spr_reg (DRR_SPRNUM);
|
usleep (10);
|
usleep (10);
|
}
|
}
|
while (drr == 0);
|
while (drr == 0);
|
|
|
|
signal (SIGINT, old_sigint);
|
status->kind = TARGET_WAITKIND_STOPPED;
|
status->kind = TARGET_WAITKIND_STOPPED;
|
or1k_flush_pipeline ();
|
or1k_flush_pipeline ();
|
|
|
if (drr & DRR_RSTE)
|
if (drr & DRR_RSTE)
|
status->value.sig = TARGET_SIGNAL_REALTIME_33;
|
status->value.sig = TARGET_SIGNAL_REALTIME_33;
|
Line 708... |
Line 804... |
status->value.sig = TARGET_SIGNAL_REALTIME_39;
|
status->value.sig = TARGET_SIGNAL_REALTIME_39;
|
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)
|
else if (drr & DRR_BE)
|
status->value.sig = TARGET_SIGNAL_TRAP;
|
status->value.sig = TARGET_SIGNAL_TRAP;
|
|
else if (drr & DRR_TE)
|
|
status->value.sig = TARGET_SIGNAL_REALTIME_41;
|
|
else if (drr & DRR_SS) /* CZ 16/09/01 */
|
|
status->value.sig = TARGET_SIGNAL_TRAP;
|
else
|
else
|
{
|
{
|
status->value.sig = TARGET_SIGNAL_UNKNOWN;
|
status->value.sig = TARGET_SIGNAL_UNKNOWN;
|
warning ("Invalid exception occured.");
|
warning ("Invalid exception occured.");
|
}
|
}
|
Line 737... |
Line 837... |
breakpoint = 1;
|
breakpoint = 1;
|
break;
|
break;
|
}
|
}
|
hit_watchpoint = !breakpoint;
|
hit_watchpoint = !breakpoint;
|
|
|
|
|
|
#ifndef NEW_PC_HANDLING
|
/* Cause the trap/breakpoint exception to be ignored. This is
|
/* Cause the trap/breakpoint exception to be ignored. This is
|
the behavior of the simulator when the PC value is changed
|
the behavior of the simulator when the PC value is changed
|
by a write command. All pending exceptions are cleared and
|
by a write command. All pending exceptions are cleared and
|
the simulator continues at the PC value specified. We need
|
the simulator continues at the PC value specified. We need
|
to do this if the instruction at the current PC has the
|
to do this if the instruction at the current PC has the
|
Line 748... |
Line 850... |
|
|
if(b_insn == or1k_read_reg((pc >> 2) + MEM_SPACE))
|
if(b_insn == or1k_read_reg((pc >> 2) + MEM_SPACE))
|
{
|
{
|
or1k_write_spr_reg(PC_SPRNUM,value);
|
or1k_write_spr_reg(PC_SPRNUM,value);
|
}
|
}
|
|
#endif
|
|
|
|
#ifdef NEW_PC_HANDLING
|
|
|
|
/* If we're a software breakpoint and we're currently located
|
|
in the breakpoint vector, then we need to reset the pc
|
|
back 4 bytes. This will ensure that the instruction gets
|
|
executed. If we don't do this, gdb will skip this instruction,
|
|
even if we set DECR_PC_AFTER_BREAK, which seems to have no
|
|
effect other than to calculate the correct breakpoint
|
|
address. */
|
|
|
|
if((b_insn == or1k_read_spr_reg(((pc-4) >> 2) + MEM_SPACE)) &&
|
|
or1k_read_spr_reg(PC_SPRNUM) == 0xD00)
|
|
or1k_write_spr_reg(EPC_SPRNUM(CURRENT_CID),pc-4);
|
|
|
|
#endif
|
|
|
}
|
}
|
else
|
else
|
hit_watchpoint = 0;
|
hit_watchpoint = 0;
|
|
|
/* If the stop PC is in the _exit function, assume
|
/* If the stop PC is in the _exit function, assume
|
Line 1059... |
Line 1179... |
instruction, that caused break or watchpoint. */
|
instruction, that caused break or watchpoint. */
|
|
|
void
|
void
|
or1k_flush_pipeline ()
|
or1k_flush_pipeline ()
|
{
|
{
|
or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
|
/* CZ 15/09/01 -- Damjan has made it perfectly clear
|
or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
|
that the DIR will not be implemented on any chip
|
or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
|
as the entire concept is poorly conceived. This
|
|
section has therefore been removed. */
|
|
/* or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
|
|
or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
|
|
or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR); */
|
}
|
}
|
|
|
/* Print info on this target. */
|
/* Print info on this target. */
|
|
|
static void
|
static void
|