Merge zizzer.eecs.umich.edu:/bk/newmem/
into zeep.eecs.umich.edu:/home/gblack/m5/newmemmemops --HG-- extra : convert_revision : 966246877ac1f1e6c2675d413b0b405cccfecbeb
This commit is contained in:
@@ -129,6 +129,7 @@ base_sources = Split('''
|
||||
|
||||
mem/cache/cache_builder.cc
|
||||
|
||||
python/swig/debug_wrap.cc
|
||||
python/swig/main_wrap.cc
|
||||
|
||||
sim/builder.cc
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace AlphaISA
|
||||
{
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
newInfoSet = false;
|
||||
}
|
||||
|
||||
void post(int int_num, int index)
|
||||
@@ -137,18 +138,10 @@ namespace AlphaISA
|
||||
}
|
||||
|
||||
if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) {
|
||||
tc->setMiscReg(IPR_ISR, summary);
|
||||
tc->setMiscReg(IPR_INTID, ipl);
|
||||
|
||||
/* The following needs to be added back in somehow */
|
||||
// Checker needs to know these two registers were updated.
|
||||
/*#if USE_CHECKER
|
||||
if (this->checker) {
|
||||
this->checker->threadBase()->setMiscReg(IPR_ISR, summary);
|
||||
this->checker->threadBase()->setMiscReg(IPR_INTID, ipl);
|
||||
}
|
||||
#endif*/
|
||||
|
||||
// assert(!newInfoSet);
|
||||
newIpl = ipl;
|
||||
newSummary = newSummary;
|
||||
newInfoSet = true;
|
||||
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
|
||||
tc->readMiscReg(IPR_IPLR), ipl, summary);
|
||||
|
||||
@@ -158,7 +151,18 @@ namespace AlphaISA
|
||||
}
|
||||
}
|
||||
|
||||
void updateIntrInfo(ThreadContext *tc)
|
||||
{
|
||||
assert(newInfoSet);
|
||||
tc->setMiscReg(IPR_ISR, newSummary);
|
||||
tc->setMiscReg(IPR_INTID, newIpl);
|
||||
newInfoSet = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool newInfoSet;
|
||||
int newIpl;
|
||||
int newSummary;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,6 @@ namespace AlphaISA
|
||||
MiscRegFile::setRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
switch(misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
fpcr = val;
|
||||
@@ -150,12 +149,13 @@ namespace AlphaISA
|
||||
intr_flag = val;
|
||||
return;
|
||||
default:
|
||||
return setIpr(misc_reg, val, tc);
|
||||
}
|
||||
#if FULL_SYSTEM
|
||||
setIpr(misc_reg, val, tc);
|
||||
#else
|
||||
//panic("No registers with side effects in SE mode!");
|
||||
return;
|
||||
panic("No registers with side effects in SE mode!");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace AlphaISA
|
||||
Fault
|
||||
ITB::translate(RequestPtr &req, ThreadContext *tc) const
|
||||
{
|
||||
if (PcPAL(req->getVaddr())) {
|
||||
if (PcPAL(req->getPC())) {
|
||||
// strip off PAL PC marker (lsb is 1)
|
||||
req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
|
||||
hits++;
|
||||
|
||||
@@ -79,6 +79,11 @@ namespace SparcISA
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void updateIntrInfo(ThreadContext * tc)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -156,8 +156,11 @@ class AlphaO3CPU : public FullO3CPU<Impl>
|
||||
|
||||
bool simPalCheck(int palFunc, unsigned tid);
|
||||
|
||||
/** Processes any interrupts. */
|
||||
void processInterrupts();
|
||||
/** Returns the Fault for any valid interrupt. */
|
||||
Fault getInterrupts();
|
||||
|
||||
/** Processes any an interrupt fault. */
|
||||
void processInterrupts(Fault interrupt);
|
||||
|
||||
/** Halts the CPU. */
|
||||
void halt() { panic("Halt not implemented!\n"); }
|
||||
|
||||
@@ -266,9 +266,17 @@ AlphaO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
Fault
|
||||
AlphaO3CPU<Impl>::getInterrupts()
|
||||
{
|
||||
// Check if there are any outstanding interrupts
|
||||
return this->interrupts.getInterrupt(this->threadContexts[0]);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
AlphaO3CPU<Impl>::processInterrupts()
|
||||
AlphaO3CPU<Impl>::processInterrupts(Fault interrupt)
|
||||
{
|
||||
// Check for interrupts here. For now can copy the code that
|
||||
// exists within isa_fullsys_traits.hh. Also assume that thread 0
|
||||
@@ -276,14 +284,12 @@ AlphaO3CPU<Impl>::processInterrupts()
|
||||
// @todo: Possibly consolidate the interrupt checking code.
|
||||
// @todo: Allow other threads to handle interrupts.
|
||||
|
||||
// Check if there are any outstanding interrupts
|
||||
//Handle the interrupts
|
||||
Fault interrupt = this->interrupts.getInterrupt(this->tcBase(0));
|
||||
assert(interrupt != NoFault);
|
||||
this->interrupts.updateIntrInfo(this->threadContexts[0]);
|
||||
|
||||
if (interrupt != NoFault) {
|
||||
this->checkInterrupts = false;
|
||||
this->trap(interrupt, 0);
|
||||
}
|
||||
DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
|
||||
this->checkInterrupts = false;
|
||||
this->trap(interrupt, 0);
|
||||
}
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
@@ -392,6 +392,9 @@ class DefaultCommit
|
||||
*/
|
||||
Tick trapLatency;
|
||||
|
||||
/** The interrupt fault. */
|
||||
Fault interrupt;
|
||||
|
||||
/** The commit PC of each thread. Refers to the instruction that
|
||||
* is currently being processed/committed.
|
||||
*/
|
||||
|
||||
@@ -122,6 +122,9 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
|
||||
tcSquash[i] = false;
|
||||
PC[i] = nextPC[i] = nextNPC[i] = 0;
|
||||
}
|
||||
#if FULL_SYSTEM
|
||||
interrupt = NoFault;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
@@ -635,51 +638,59 @@ DefaultCommit<Impl>::commit()
|
||||
//////////////////////////////////////
|
||||
|
||||
#if FULL_SYSTEM
|
||||
// Process interrupts if interrupts are enabled, not in PAL mode,
|
||||
// and no other traps or external squashes are currently pending.
|
||||
// @todo: Allow other threads to handle interrupts.
|
||||
if (cpu->checkInterrupts &&
|
||||
cpu->check_interrupts(cpu->tcBase(0)) &&
|
||||
!trapSquash[0] &&
|
||||
!tcSquash[0]) {
|
||||
// Tell fetch that there is an interrupt pending. This will
|
||||
// make fetch wait until it sees a non PAL-mode PC, at which
|
||||
// point it stops fetching instructions.
|
||||
toIEW->commitInfo[0].interruptPending = true;
|
||||
|
||||
if (interrupt != NoFault) {
|
||||
// Wait until the ROB is empty and all stores have drained in
|
||||
// order to enter the interrupt.
|
||||
if (rob->isEmpty() && !iewStage->hasStoresToWB()) {
|
||||
// Not sure which thread should be the one to interrupt. For now
|
||||
// always do thread 0.
|
||||
// Squash or record that I need to squash this cycle if
|
||||
// an interrupt needed to be handled.
|
||||
DPRINTF(Commit, "Interrupt detected.\n");
|
||||
|
||||
assert(!thread[0]->inSyscall);
|
||||
thread[0]->inSyscall = true;
|
||||
|
||||
// CPU will handle implementation of the interrupt.
|
||||
cpu->processInterrupts();
|
||||
// CPU will handle interrupt.
|
||||
cpu->processInterrupts(interrupt);
|
||||
|
||||
// Now squash or record that I need to squash this cycle.
|
||||
commitStatus[0] = TrapPending;
|
||||
|
||||
// Exit state update mode to avoid accidental updating.
|
||||
thread[0]->inSyscall = false;
|
||||
|
||||
commitStatus[0] = TrapPending;
|
||||
|
||||
// Generate trap squash event.
|
||||
generateTrapEvent(0);
|
||||
|
||||
// Clear the interrupt now that it's been handled
|
||||
toIEW->commitInfo[0].clearInterrupt = true;
|
||||
|
||||
DPRINTF(Commit, "Interrupt detected.\n");
|
||||
interrupt = NoFault;
|
||||
} else {
|
||||
DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
|
||||
}
|
||||
} else if (cpu->checkInterrupts &&
|
||||
cpu->check_interrupts(cpu->tcBase(0)) &&
|
||||
commitStatus[0] != TrapPending &&
|
||||
!trapSquash[0] &&
|
||||
!tcSquash[0]) {
|
||||
// Process interrupts if interrupts are enabled, not in PAL
|
||||
// mode, and no other traps or external squashes are currently
|
||||
// pending.
|
||||
// @todo: Allow other threads to handle interrupts.
|
||||
|
||||
// Get any interrupt that happened
|
||||
interrupt = cpu->getInterrupts();
|
||||
|
||||
if (interrupt != NoFault) {
|
||||
// Tell fetch that there is an interrupt pending. This
|
||||
// will make fetch wait until it sees a non PAL-mode PC,
|
||||
// at which point it stops fetching instructions.
|
||||
toIEW->commitInfo[0].interruptPending = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
////////////////////////////////////
|
||||
// Check for any possible squashes, handle them first
|
||||
////////////////////////////////////
|
||||
|
||||
std::list<unsigned>::iterator threads = (*activeThreads).begin();
|
||||
|
||||
while (threads != (*activeThreads).end()) {
|
||||
|
||||
@@ -819,6 +819,12 @@ unsigned int
|
||||
FullO3CPU<Impl>::drain(Event *drain_event)
|
||||
{
|
||||
DPRINTF(O3CPU, "Switching out\n");
|
||||
|
||||
// If the CPU isn't doing anything, then return immediately.
|
||||
if (_status == Idle || _status == SwitchedOut) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
drainCount = 0;
|
||||
fetch.drain();
|
||||
decode.drain();
|
||||
|
||||
@@ -561,27 +561,36 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
||||
Fault fault = NoFault;
|
||||
|
||||
//AlphaDep
|
||||
if (cacheBlocked || isSwitchedOut() ||
|
||||
(interruptPending && (fetch_PC & 0x3))) {
|
||||
if (cacheBlocked) {
|
||||
DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n",
|
||||
tid);
|
||||
return false;
|
||||
} else if (isSwitchedOut()) {
|
||||
DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, switched out\n",
|
||||
tid);
|
||||
return false;
|
||||
} else if (interruptPending && !(fetch_PC & 0x3)) {
|
||||
// Hold off fetch from getting new instructions when:
|
||||
// Cache is blocked, or
|
||||
// while an interrupt is pending and we're not in PAL mode, or
|
||||
// fetch is switched out.
|
||||
DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n",
|
||||
tid);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Align the fetch PC so it's at the start of a cache block.
|
||||
fetch_PC = icacheBlockAlignPC(fetch_PC);
|
||||
Addr block_PC = icacheBlockAlignPC(fetch_PC);
|
||||
|
||||
// If we've already got the block, no need to try to fetch it again.
|
||||
if (cacheDataValid[tid] && fetch_PC == cacheDataPC[tid]) {
|
||||
if (cacheDataValid[tid] && block_PC == cacheDataPC[tid]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Setup the memReq to do a read of the first instruction's address.
|
||||
// Set the appropriate read size and flags as well.
|
||||
// Build request here.
|
||||
RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, 0,
|
||||
RequestPtr mem_req = new Request(tid, block_PC, cacheBlkSize, 0,
|
||||
fetch_PC, cpu->readCpuId(), tid);
|
||||
|
||||
memReq[tid] = mem_req;
|
||||
@@ -611,7 +620,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
||||
Packet::ReadReq, Packet::Broadcast);
|
||||
data_pkt->dataDynamicArray(new uint8_t[cacheBlkSize]);
|
||||
|
||||
cacheDataPC[tid] = fetch_PC;
|
||||
cacheDataPC[tid] = block_PC;
|
||||
cacheDataValid[tid] = false;
|
||||
|
||||
DPRINTF(Fetch, "Fetch: Doing instruction read.\n");
|
||||
@@ -976,7 +985,9 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(unsigned tid)
|
||||
}
|
||||
}
|
||||
|
||||
if (checkStall(tid) && fetchStatus[tid] != IcacheWaitResponse) {
|
||||
if (checkStall(tid) &&
|
||||
fetchStatus[tid] != IcacheWaitResponse &&
|
||||
fetchStatus[tid] != IcacheWaitRetry) {
|
||||
DPRINTF(Fetch, "[tid:%i]: Setting to blocked\n",tid);
|
||||
|
||||
fetchStatus[tid] = Blocked;
|
||||
@@ -1052,12 +1063,16 @@ DefaultFetch<Impl>::fetch(bool &status_change)
|
||||
} else {
|
||||
if (fetchStatus[tid] == Idle) {
|
||||
++fetchIdleCycles;
|
||||
DPRINTF(Fetch, "[tid:%i]: Fetch is idle!\n", tid);
|
||||
} else if (fetchStatus[tid] == Blocked) {
|
||||
++fetchBlockedCycles;
|
||||
DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid);
|
||||
} else if (fetchStatus[tid] == Squashing) {
|
||||
++fetchSquashCycles;
|
||||
DPRINTF(Fetch, "[tid:%i]: Fetch is squashing!\n", tid);
|
||||
} else if (fetchStatus[tid] == IcacheWaitResponse) {
|
||||
++icacheStallCycles;
|
||||
DPRINTF(Fetch, "[tid:%i]: Fetch is waiting cache response!\n", tid);
|
||||
}
|
||||
|
||||
// Status is Idle, Squashing, Blocked, or IcacheWaitResponse, so
|
||||
|
||||
@@ -46,7 +46,7 @@ template <class Impl>
|
||||
void
|
||||
LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
warn("O3CPU doesn't update things on a recvFunctional.");
|
||||
DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.");
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -67,7 +67,7 @@ Param<Tick> profile;
|
||||
|
||||
Param<bool> do_quiesce;
|
||||
Param<bool> do_checkpoint_insts;
|
||||
Param<bool> do_statistics_insts
|
||||
Param<bool> do_statistics_insts;
|
||||
#else
|
||||
SimObjectVectorParam<Process *> workload;
|
||||
//SimObjectParam<PageTable *> page_table;
|
||||
|
||||
@@ -700,52 +700,12 @@ OzoneCPU<Impl>::processInterrupts()
|
||||
|
||||
// Check if there are any outstanding interrupts
|
||||
//Handle the interrupts
|
||||
int ipl = 0;
|
||||
int summary = 0;
|
||||
Fault interrupt = this->interrupts.getInterrupt(thread.getTC());
|
||||
|
||||
checkInterrupts = false;
|
||||
|
||||
if (thread.readMiscReg(IPR_ASTRR))
|
||||
panic("asynchronous traps not implemented\n");
|
||||
|
||||
if (thread.readMiscReg(IPR_SIRR)) {
|
||||
for (int i = INTLEVEL_SOFTWARE_MIN;
|
||||
i < INTLEVEL_SOFTWARE_MAX; i++) {
|
||||
if (thread.readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
|
||||
// See table 4-19 of the 21164 hardware reference
|
||||
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t interrupts = intr_status();
|
||||
|
||||
if (interrupts) {
|
||||
for (int i = INTLEVEL_EXTERNAL_MIN;
|
||||
i < INTLEVEL_EXTERNAL_MAX; i++) {
|
||||
if (interrupts & (ULL(1) << i)) {
|
||||
// See table 4-19 of the 21164 hardware reference
|
||||
ipl = i;
|
||||
summary |= (ULL(1) << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ipl && ipl > thread.readMiscReg(IPR_IPLR)) {
|
||||
thread.setMiscReg(IPR_ISR, summary);
|
||||
thread.setMiscReg(IPR_INTID, ipl);
|
||||
#if USE_CHECKER
|
||||
// @todo: Make this more transparent
|
||||
if (checker) {
|
||||
checker->threadBase()->setMiscReg(IPR_ISR, summary);
|
||||
checker->threadBase()->setMiscReg(IPR_INTID, ipl);
|
||||
}
|
||||
#endif
|
||||
Fault fault = new InterruptFault;
|
||||
fault->invoke(thread.getTC());
|
||||
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
|
||||
thread.readMiscReg(IPR_IPLR), ipl, summary);
|
||||
if (interrupt != NoFault) {
|
||||
this->interrupts.updateIntrInfo(thread.getTC());
|
||||
this->checkInterrupts = false;
|
||||
interrupt->invoke(thread.getTC());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -476,8 +476,8 @@ FrontEnd<Impl>::fetchCacheLine()
|
||||
|
||||
// Setup the memReq to do a read of the first isntruction's address.
|
||||
// Set the appropriate read size and flags as well.
|
||||
memReq = new Request(0, fetch_PC, cacheBlkSize, flags,
|
||||
fetch_PC, cpu->readCpuId(), 0);
|
||||
memReq = new Request(0, fetch_PC, cacheBlkSize, 0,
|
||||
PC, cpu->readCpuId(), 0);
|
||||
|
||||
// Translate the instruction request.
|
||||
fault = cpu->translateInstReq(memReq, thread);
|
||||
|
||||
@@ -213,6 +213,9 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_status != Running) {
|
||||
_status = Idle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -315,6 +315,7 @@ BaseSimpleCPU::checkForInterrupts()
|
||||
Fault interrupt = interrupts.getInterrupt(tc);
|
||||
|
||||
if (interrupt != NoFault) {
|
||||
interrupts.updateIntrInfo(tc);
|
||||
checkInterrupts = false;
|
||||
interrupt->invoke(tc);
|
||||
}
|
||||
|
||||
@@ -242,8 +242,11 @@ Bus::recvRetry(int id)
|
||||
}
|
||||
}
|
||||
//If we weren't able to drain before, we might be able to now.
|
||||
if (drainEvent && retryList.size() == 0 && curTick >= tickNextIdle)
|
||||
if (drainEvent && retryList.size() == 0 && curTick >= tickNextIdle) {
|
||||
drainEvent->process();
|
||||
// Clear the drain event once we're done with it.
|
||||
drainEvent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Port *
|
||||
@@ -367,6 +370,10 @@ Bus::recvAtomic(PacketPtr pkt)
|
||||
DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n",
|
||||
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
||||
assert(pkt->getDest() == Packet::Broadcast);
|
||||
|
||||
// Assume one bus cycle in order to get through. This may have
|
||||
// some clock skew issues yet again...
|
||||
pkt->finishTime = curTick + clock;
|
||||
Tick snoopTime = atomicSnoop(pkt);
|
||||
if (snoopTime)
|
||||
return snoopTime; //Snoop satisfies it
|
||||
|
||||
2
src/mem/cache/miss/miss_queue.cc
vendored
2
src/mem/cache/miss/miss_queue.cc
vendored
@@ -612,6 +612,8 @@ MissQueue::handleResponse(PacketPtr &pkt, Tick time)
|
||||
if (mshr->hasTargets()) {
|
||||
// Didn't satisfy all the targets, need to resend
|
||||
Packet::Command cmd = mshr->getTarget()->cmd;
|
||||
mshr->pkt->setDest(Packet::Broadcast);
|
||||
mshr->pkt->result = Packet::Unknown;
|
||||
mq.markPending(mshr, cmd);
|
||||
mshr->order = order++;
|
||||
cache->setMasterRequest(Request_MSHR, time);
|
||||
|
||||
@@ -98,11 +98,17 @@ pyzip_files.append('m5/defines.py')
|
||||
pyzip_files.append('m5/info.py')
|
||||
pyzip_files.append(join(env['ROOT'], 'util/pbs/jobfile.py'))
|
||||
|
||||
env.Command(['swig/debug_wrap.cc', 'm5/internal/debug.py'],
|
||||
'swig/debug.i',
|
||||
'$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
|
||||
'-o ${TARGETS[0]} $SOURCES')
|
||||
|
||||
env.Command(['swig/main_wrap.cc', 'm5/internal/main.py'],
|
||||
'swig/main.i',
|
||||
'$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
|
||||
'-o ${TARGETS[0]} $SOURCES')
|
||||
|
||||
pyzip_dep_files.append('m5/internal/debug.py')
|
||||
pyzip_dep_files.append('m5/internal/main.py')
|
||||
|
||||
# Action function to build the zip archive. Uses the PyZipFile module
|
||||
|
||||
@@ -275,7 +275,8 @@ def main():
|
||||
objects.Statistics.text_file = options.stats_file
|
||||
|
||||
# set debugging options
|
||||
objects.Debug.break_cycles = options.debug_break
|
||||
for when in options.debug_break:
|
||||
internal.debug.schedBreakCycle(int(when))
|
||||
|
||||
# set tracing options
|
||||
objects.Trace.flags = options.trace_flags
|
||||
|
||||
@@ -5,7 +5,6 @@ from Serialize import Statreset
|
||||
from Statistics import Statistics
|
||||
from Trace import Trace
|
||||
from ExeTrace import ExecutionTrace
|
||||
from Debug import Debug
|
||||
|
||||
class Root(SimObject):
|
||||
type = 'Root'
|
||||
@@ -22,4 +21,3 @@ class Root(SimObject):
|
||||
trace = Trace()
|
||||
exetrace = ExecutionTrace()
|
||||
serialize = Serialize()
|
||||
debug = Debug()
|
||||
|
||||
19
src/python/swig/debug.i
Normal file
19
src/python/swig/debug.i
Normal file
@@ -0,0 +1,19 @@
|
||||
%module debug
|
||||
|
||||
%{
|
||||
// include these files when compiling debug_wrap.cc
|
||||
#include "sim/host.hh"
|
||||
%}
|
||||
|
||||
%include "stdint.i"
|
||||
%include "sim/host.hh"
|
||||
|
||||
%inline %{
|
||||
extern void schedBreakCycle(Tick when);
|
||||
%}
|
||||
|
||||
%wrapper %{
|
||||
// fix up module name to reflect the fact that it's inside the m5 package
|
||||
#undef SWIG_name
|
||||
#define SWIG_name "m5.internal._debug"
|
||||
%}
|
||||
@@ -93,46 +93,18 @@ DebugBreakEvent::description()
|
||||
return "debug break";
|
||||
}
|
||||
|
||||
//
|
||||
// Parameter context for global debug options
|
||||
//
|
||||
class DebugContext : public ParamContext
|
||||
{
|
||||
public:
|
||||
DebugContext(const string &_iniSection)
|
||||
: ParamContext(_iniSection) {}
|
||||
void checkParams();
|
||||
};
|
||||
|
||||
DebugContext debugParams("debug");
|
||||
|
||||
VectorParam<Tick> break_cycles(&debugParams, "break_cycles",
|
||||
"cycle(s) to create breakpoint events");
|
||||
|
||||
void
|
||||
DebugContext::checkParams()
|
||||
{
|
||||
if (break_cycles.isValid()) {
|
||||
vector<Tick> &cycles = break_cycles;
|
||||
|
||||
vector<Tick>::iterator i = cycles.begin();
|
||||
vector<Tick>::iterator end = cycles.end();
|
||||
|
||||
for (; i < end; ++i)
|
||||
new DebugBreakEvent(&mainEventQueue, *i);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// handy function to schedule DebugBreakEvent on main event queue
|
||||
// (callable from debugger)
|
||||
//
|
||||
void sched_break_cycle(Tick when)
|
||||
void
|
||||
schedBreakCycle(Tick when)
|
||||
{
|
||||
new DebugBreakEvent(&mainEventQueue, when);
|
||||
}
|
||||
|
||||
void eventq_dump()
|
||||
void
|
||||
eventqDump()
|
||||
{
|
||||
mainEventQueue.dump();
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ abortHandler(int sigtype)
|
||||
|
||||
extern "C" {
|
||||
void init_main();
|
||||
void init_debug();
|
||||
}
|
||||
|
||||
int
|
||||
@@ -157,8 +158,9 @@ main(int argc, char **argv)
|
||||
Py_Initialize();
|
||||
PySys_SetArgv(argc, argv);
|
||||
|
||||
// initialize SWIG 'm5.internal.main' module
|
||||
// initialize SWIG modules
|
||||
init_main();
|
||||
init_debug();
|
||||
|
||||
PyRun_SimpleString("import m5.main");
|
||||
PyRun_SimpleString("m5.main.main()");
|
||||
|
||||
Reference in New Issue
Block a user