mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-23 02:51:56 +00:00
o Fixes to repeated watchpoints
o Add mips ISA instructions needed to handle interrupts
This commit is contained in:
parent
f131deb19f
commit
56e7c84918
@ -1,3 +1,28 @@
|
||||
Tue Jun 3 04:52:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-watch.c (schedule_watchpoint): Use sim_unschedule_watchpoint
|
||||
to remove the old watchpoint, not delete_watchpoint.
|
||||
(watch_option_handler): Action the correct watchpoint, not just
|
||||
cycles.
|
||||
|
||||
Wed May 28 14:47:41 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-n-core.h (sim_core_write_aligned_N): For 8byte reads, output
|
||||
both low and high word.
|
||||
(sim_core_write_aligned_N): Ditto.
|
||||
|
||||
* sim-trace.c (set_trace_options): Delete code explicitly setting
|
||||
core->trace.
|
||||
|
||||
* sim-options.c (sim_print_help): Call the list commands if not a
|
||||
standalone simulator.
|
||||
(sim_print_help): Advise that some options may not be applicable.
|
||||
|
||||
* sim-trace.c (set_trace_options): Assume core present.
|
||||
|
||||
* sim-events.c (sim_events_schedule_after_signal): Overflow signal
|
||||
buffer when full not almost full.
|
||||
|
||||
Tue May 27 14:32:00 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-events.c (sim_events_process): Don't blat the event queue
|
||||
|
@ -1,3 +1,35 @@
|
||||
start-sanitize-r5900
|
||||
Tue Jun 3 05:00:33 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* interp.c (SignalException): Clear the simDELAYSLOT flag when an
|
||||
exception has been taken.
|
||||
|
||||
* interp.c: Implement the ERET and mt/f sr instructions.
|
||||
|
||||
Mon Jun 2 23:28:19 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* gencode.c (build_instruction): For paddu, extract unsigned
|
||||
sub-fields.
|
||||
|
||||
* gencode.c (build_instruction): Saturate padds instead of padd
|
||||
instructions.
|
||||
|
||||
end-sanitize-r5900
|
||||
Sat May 31 00:44:16 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* interp.c (SignalException): Don't bother restarting an
|
||||
interrupt.
|
||||
|
||||
Fri May 30 23:41:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* interp.c (SignalException): Really take an interrupt.
|
||||
(interrupt_event): Only deliver interrupts when enabled.
|
||||
|
||||
Tue May 27 20:08:06 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* interp.c (sim_info): Only print info when verbose.
|
||||
(sim_info) Use sim_io_printf for output.
|
||||
|
||||
Tue May 27 14:22:23 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* interp.c (CoProcPresent): Add UNUSED attribute - not used by all
|
||||
@ -192,8 +224,8 @@ Wed Feb 26 18:32:21 1997 Gavin Koch <gavin@cygnus.com>
|
||||
Change values to avoid overloading DOUBLEWORD which is tested
|
||||
for all insns.
|
||||
* gencode.c: reinstate "offending code".
|
||||
end-sanitize-r5900
|
||||
|
||||
end-sanitize-r5900
|
||||
Mon Feb 24 22:47:14 1997 Dawn Perchik <dawn@cygnus.com>
|
||||
|
||||
* interp.c: Fix printing of addresses for non-64-bit targets.
|
||||
|
@ -385,6 +385,8 @@ static ut_reg DSPC = 0; /* delay-slot PC */
|
||||
#define ksu_user (0x2)
|
||||
#define ksu_unknown (0x3)
|
||||
|
||||
#define status_IE (1 << 0) /* Interrupt enable */
|
||||
#define status_EXL (1 << 1) /* Exception level */
|
||||
#define status_RE (1 << 25) /* Reverse Endian in user mode */
|
||||
#define status_FR (1 << 26) /* enables MIPS III additional FP registers */
|
||||
#define status_SR (1 << 20) /* soft reset or NMI */
|
||||
@ -746,10 +748,18 @@ static const OPTION mips_options[] =
|
||||
};
|
||||
|
||||
|
||||
int interrupt_pending;
|
||||
|
||||
static void
|
||||
interrupt_event (SIM_DESC sd, void *data)
|
||||
{
|
||||
SignalException (Interrupt);
|
||||
if (SR & status_IE)
|
||||
{
|
||||
interrupt_pending = 0;
|
||||
SignalException (Interrupt);
|
||||
}
|
||||
else if (!interrupt_pending)
|
||||
sim_events_schedule (sd, 1, interrupt_event, data);
|
||||
}
|
||||
|
||||
|
||||
@ -1240,43 +1250,49 @@ sim_info (sd,verbose)
|
||||
SIM_DESC sd;
|
||||
int verbose;
|
||||
{
|
||||
/* Accessed from the GDB "info files" command: */
|
||||
|
||||
callback->printf_filtered(callback,"MIPS %d-bit simulator\n",(PROCESSOR_64BIT ? 64 : 32));
|
||||
|
||||
callback->printf_filtered(callback,"%s endian memory model\n",
|
||||
(CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
|
||||
? "Big" : "Little"));
|
||||
|
||||
callback->printf_filtered(callback,"0x%08X bytes of memory at 0x%s\n",
|
||||
STATE_MEM_SIZE (sd),
|
||||
pr_addr (STATE_MEM_BASE (sd)));
|
||||
|
||||
#if !defined(FASTSIM)
|
||||
if (instruction_fetch_overflow != 0)
|
||||
callback->printf_filtered(callback,"Instruction fetches = 0x%08X%08X\n",instruction_fetch_overflow,instruction_fetches);
|
||||
else
|
||||
callback->printf_filtered(callback,"Instruction fetches = %d\n",instruction_fetches);
|
||||
callback->printf_filtered(callback,"Pipeline ticks = %ld\n",
|
||||
(long) sim_events_time (sd));
|
||||
/* It would be a useful feature, if when performing multi-cycle
|
||||
simulations (rather than single-stepping) we keep the start and
|
||||
end times of the execution, so that we can give a performance
|
||||
figure for the simulator. */
|
||||
#endif /* !FASTSIM */
|
||||
|
||||
/* print information pertaining to MIPS ISA and architecture being simulated */
|
||||
/* things that may be interesting */
|
||||
/* instructions executed - if available */
|
||||
/* cycles executed - if available */
|
||||
/* pipeline stalls - if available */
|
||||
/* virtual time taken */
|
||||
/* profiling size */
|
||||
/* profiling frequency */
|
||||
/* profile minpc */
|
||||
/* profile maxpc */
|
||||
|
||||
|
||||
return;
|
||||
/* Accessed from the GDB "info files" command: */
|
||||
if (STATE_VERBOSE_P (sd) || verbose)
|
||||
{
|
||||
|
||||
sim_io_printf (sd, "MIPS %d-bit %s endian simulator\n",
|
||||
(PROCESSOR_64BIT ? 64 : 32),
|
||||
(CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little"));
|
||||
|
||||
sim_io_printf (sd, "0x%08X bytes of memory at 0x%s\n",
|
||||
STATE_MEM_SIZE (sd),
|
||||
pr_addr (STATE_MEM_BASE (sd)));
|
||||
|
||||
#if !defined(FASTSIM)
|
||||
#if 0
|
||||
/* at present this simulator executes one instruction per
|
||||
simulator cycle. Consequently this data never changes */
|
||||
if (instruction_fetch_overflow != 0)
|
||||
sim_io_printf (sd, "Instruction fetches = 0x%08X%08X\n",
|
||||
instruction_fetch_overflow, instruction_fetches);
|
||||
else
|
||||
sim_io_printf (sd, "Instruction fetches = %d\n", instruction_fetches);
|
||||
#endif
|
||||
/* It would be a useful feature, if when performing multi-cycle
|
||||
simulations (rather than single-stepping) we keep the start and
|
||||
end times of the execution, so that we can give a performance
|
||||
figure for the simulator. */
|
||||
#endif /* !FASTSIM */
|
||||
sim_io_printf (sd, "Number of execution cycles = %ld\n",
|
||||
(long) sim_events_time (sd));
|
||||
|
||||
/* print information pertaining to MIPS ISA and architecture being simulated */
|
||||
/* things that may be interesting */
|
||||
/* instructions executed - if available */
|
||||
/* cycles executed - if available */
|
||||
/* pipeline stalls - if available */
|
||||
/* virtual time taken */
|
||||
/* profiling size */
|
||||
/* profiling frequency */
|
||||
/* profile minpc */
|
||||
/* profile maxpc */
|
||||
}
|
||||
}
|
||||
|
||||
SIM_RC
|
||||
@ -2731,6 +2747,7 @@ SyncOperation(stype)
|
||||
static void
|
||||
SignalException (int exception,...)
|
||||
{
|
||||
int vector;
|
||||
SIM_DESC sd = &simulator;
|
||||
/* Ensure that any active atomic read/modify/write operation will fail: */
|
||||
LLBIT = 0;
|
||||
@ -2805,22 +2822,40 @@ SignalException (int exception,...)
|
||||
}
|
||||
}
|
||||
|
||||
/* See figure 5-17 for an outline of the code below */
|
||||
if (! (SR & status_EXL))
|
||||
{
|
||||
CAUSE = (exception << 2);
|
||||
if (state & simDELAYSLOT)
|
||||
{
|
||||
state &= ~simDELAYSLOT;
|
||||
CAUSE |= cause_BD;
|
||||
EPC = (IPC - 4); /* reference the branch instruction */
|
||||
}
|
||||
else
|
||||
EPC = IPC;
|
||||
/* FIXME: TLB et.al. */
|
||||
vector = 0x180;
|
||||
}
|
||||
else
|
||||
{
|
||||
CAUSE = 0;
|
||||
vector = 0x180;
|
||||
}
|
||||
SR |= status_EXL;
|
||||
/* Store exception code into current exception id variable (used
|
||||
by exit code): */
|
||||
CAUSE = (exception << 2);
|
||||
if (state & simDELAYSLOT) {
|
||||
CAUSE |= cause_BD;
|
||||
EPC = (IPC - 4); /* reference the branch instruction */
|
||||
} else
|
||||
EPC = IPC;
|
||||
/* The following is so that the simulator will continue from the
|
||||
exception address on breakpoint operations. */
|
||||
PC = EPC;
|
||||
if (SR & status_BEV)
|
||||
PC = (signed)0xBFC00200 + 0x180;
|
||||
else
|
||||
PC = (signed)0x80000000 + 0x180;
|
||||
|
||||
switch ((CAUSE >> 2) & 0x1F)
|
||||
{
|
||||
case Interrupt:
|
||||
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
|
||||
sim_stopped, SIGINT);
|
||||
/* Interrupts arrive during event processing, no need to
|
||||
restart */
|
||||
return;
|
||||
|
||||
case TLBModification:
|
||||
case TLBLoad:
|
||||
@ -2829,11 +2864,15 @@ SignalException (int exception,...)
|
||||
case AddressStore:
|
||||
case InstructionFetch:
|
||||
case DataReference:
|
||||
/* The following is so that the simulator will continue from the
|
||||
exception address on breakpoint operations. */
|
||||
PC = EPC;
|
||||
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
|
||||
sim_stopped, SIGBUS);
|
||||
|
||||
case ReservedInstruction:
|
||||
case CoProcessorUnusable:
|
||||
PC = EPC;
|
||||
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
|
||||
sim_stopped, SIGILL);
|
||||
|
||||
@ -2846,10 +2885,12 @@ SignalException (int exception,...)
|
||||
case Watch:
|
||||
case SystemCall:
|
||||
case BreakPoint:
|
||||
PC = EPC;
|
||||
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
|
||||
sim_stopped, SIGTRAP);
|
||||
|
||||
default : /* Unknown internal exception */
|
||||
PC = EPC;
|
||||
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
|
||||
sim_stopped, SIGQUIT);
|
||||
|
||||
@ -4026,85 +4067,105 @@ decode_coproc(instruction)
|
||||
{
|
||||
int coprocnum = ((instruction >> 26) & 3);
|
||||
|
||||
switch (coprocnum) {
|
||||
switch (coprocnum)
|
||||
{
|
||||
case 0: /* standard CPU control and cache registers */
|
||||
{
|
||||
/* NOTEs:
|
||||
Standard CP0 registers
|
||||
0 = Index R4000 VR4100 VR4300
|
||||
1 = Random R4000 VR4100 VR4300
|
||||
2 = EntryLo0 R4000 VR4100 VR4300
|
||||
3 = EntryLo1 R4000 VR4100 VR4300
|
||||
4 = Context R4000 VR4100 VR4300
|
||||
5 = PageMask R4000 VR4100 VR4300
|
||||
6 = Wired R4000 VR4100 VR4300
|
||||
8 = BadVAddr R4000 VR4100 VR4300
|
||||
9 = Count R4000 VR4100 VR4300
|
||||
10 = EntryHi R4000 VR4100 VR4300
|
||||
11 = Compare R4000 VR4100 VR4300
|
||||
12 = SR R4000 VR4100 VR4300
|
||||
13 = Cause R4000 VR4100 VR4300
|
||||
14 = EPC R4000 VR4100 VR4300
|
||||
15 = PRId R4000 VR4100 VR4300
|
||||
16 = Config R4000 VR4100 VR4300
|
||||
17 = LLAddr R4000 VR4100 VR4300
|
||||
18 = WatchLo R4000 VR4100 VR4300
|
||||
19 = WatchHi R4000 VR4100 VR4300
|
||||
20 = XContext R4000 VR4100 VR4300
|
||||
26 = PErr or ECC R4000 VR4100 VR4300
|
||||
27 = CacheErr R4000 VR4100
|
||||
28 = TagLo R4000 VR4100 VR4300
|
||||
29 = TagHi R4000 VR4100 VR4300
|
||||
30 = ErrorEPC R4000 VR4100 VR4300
|
||||
*/
|
||||
int code = ((instruction >> 21) & 0x1F);
|
||||
/* R4000 Users Manual (second edition) lists the following CP0
|
||||
instructions:
|
||||
DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
|
||||
DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
|
||||
MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
|
||||
MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
|
||||
TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
|
||||
TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
|
||||
TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
|
||||
TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
|
||||
CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
|
||||
ERET Exception return (VR4100 = 01000010000000000000000000011000)
|
||||
*/
|
||||
if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0)) {
|
||||
int rt = ((instruction >> 16) & 0x1F);
|
||||
#if 0
|
||||
int rd = ((instruction >> 11) & 0x1F);
|
||||
#endif
|
||||
if (code == 0x00) { /* MF : move from */
|
||||
#if 0 /* message should be controlled by configuration option */
|
||||
callback->printf_filtered(callback,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
|
||||
#endif
|
||||
GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
|
||||
} else { /* MT : move to */
|
||||
/* CPR[0,rd] = GPR[rt]; */
|
||||
#if 0 /* should be controlled by configuration option */
|
||||
callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
|
||||
#endif
|
||||
}
|
||||
} else
|
||||
sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
|
||||
DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
|
||||
DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
|
||||
MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
|
||||
MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
|
||||
TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
|
||||
TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
|
||||
TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
|
||||
TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
|
||||
CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
|
||||
ERET Exception return (VR4100 = 01000010000000000000000000011000)
|
||||
*/
|
||||
if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
|
||||
{
|
||||
int rt = ((instruction >> 16) & 0x1F);
|
||||
int rd = ((instruction >> 11) & 0x1F);
|
||||
|
||||
switch (rd) /* NOTEs: Standard CP0 registers */
|
||||
{
|
||||
/* 0 = Index R4000 VR4100 VR4300 */
|
||||
/* 1 = Random R4000 VR4100 VR4300 */
|
||||
/* 2 = EntryLo0 R4000 VR4100 VR4300 */
|
||||
/* 3 = EntryLo1 R4000 VR4100 VR4300 */
|
||||
/* 4 = Context R4000 VR4100 VR4300 */
|
||||
/* 5 = PageMask R4000 VR4100 VR4300 */
|
||||
/* 6 = Wired R4000 VR4100 VR4300 */
|
||||
/* 8 = BadVAddr R4000 VR4100 VR4300 */
|
||||
/* 9 = Count R4000 VR4100 VR4300 */
|
||||
/* 10 = EntryHi R4000 VR4100 VR4300 */
|
||||
/* 11 = Compare R4000 VR4100 VR4300 */
|
||||
/* 12 = SR R4000 VR4100 VR4300 */
|
||||
case 12:
|
||||
if (code == 0x00)
|
||||
GPR[rt] = SR;
|
||||
else
|
||||
SR = GPR[rt];
|
||||
break;
|
||||
/* 13 = Cause R4000 VR4100 VR4300 */
|
||||
/* 14 = EPC R4000 VR4100 VR4300 */
|
||||
/* 15 = PRId R4000 VR4100 VR4300 */
|
||||
/* 16 = Config R4000 VR4100 VR4300 */
|
||||
/* 17 = LLAddr R4000 VR4100 VR4300 */
|
||||
/* 18 = WatchLo R4000 VR4100 VR4300 */
|
||||
/* 19 = WatchHi R4000 VR4100 VR4300 */
|
||||
/* 20 = XContext R4000 VR4100 VR4300 */
|
||||
/* 26 = PErr or ECC R4000 VR4100 VR4300 */
|
||||
/* 27 = CacheErr R4000 VR4100 */
|
||||
/* 28 = TagLo R4000 VR4100 VR4300 */
|
||||
/* 29 = TagHi R4000 VR4100 VR4300 */
|
||||
/* 30 = ErrorEPC R4000 VR4100 VR4300 */
|
||||
GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
|
||||
/* CPR[0,rd] = GPR[rt]; */
|
||||
default:
|
||||
if (code == 0x00)
|
||||
callback->printf_filtered(callback,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
|
||||
else
|
||||
callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
|
||||
}
|
||||
}
|
||||
else if (code == 0x10 && (instruction & 0x3f) == 0x18)
|
||||
{
|
||||
/* ERET */
|
||||
if (SR & status_ERL)
|
||||
{
|
||||
/* Oops, not yet available */
|
||||
callback->printf_filtered(callback,"Warning: ERET when SR[ERL] set not handled yet");
|
||||
PC = EPC;
|
||||
SR &= ~status_ERL;
|
||||
}
|
||||
else
|
||||
{
|
||||
PC = EPC;
|
||||
SR &= ~status_EXL;
|
||||
}
|
||||
}
|
||||
else
|
||||
sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
|
||||
/* TODO: When executing an ERET or RFE instruction we should
|
||||
clear LLBIT, to ensure that any out-standing atomic
|
||||
read/modify/write sequence fails. */
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case 2: /* undefined co-processor */
|
||||
sim_warning("COP2 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
|
||||
break;
|
||||
|
||||
|
||||
case 1: /* should not occur (FPU co-processor) */
|
||||
case 3: /* should not occur (FPU co-processor) */
|
||||
SignalException(ReservedInstruction,instruction);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user