Implement Ali's review feedback.
Try to decrease indentation, and remove some redundant FullSystem checks.
This commit is contained in:
@@ -187,16 +187,17 @@ ItbPageFault::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
ItbFault::invoke(tc);
|
||||
return;
|
||||
}
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(pc, entry);
|
||||
if (!success) {
|
||||
panic("Tried to execute unmapped address %#x.\n", pc);
|
||||
} else {
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(pc, entry);
|
||||
if (!success) {
|
||||
panic("Tried to execute unmapped address %#x.\n", pc);
|
||||
} else {
|
||||
VAddr vaddr(pc);
|
||||
tc->getITBPtr()->insert(vaddr.page(), entry);
|
||||
}
|
||||
VAddr vaddr(pc);
|
||||
tc->getITBPtr()->insert(vaddr.page(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,19 +206,20 @@ NDtbMissFault::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
DtbFault::invoke(tc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(vaddr, entry);
|
||||
if (!success) {
|
||||
if (p->fixupStackFault(vaddr))
|
||||
success = p->pTable->lookup(vaddr, entry);
|
||||
}
|
||||
if (!success) {
|
||||
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
|
||||
} else {
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(vaddr, entry);
|
||||
if (!success) {
|
||||
if (p->fixupStackFault(vaddr))
|
||||
success = p->pTable->lookup(vaddr, entry);
|
||||
}
|
||||
if (!success) {
|
||||
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
|
||||
} else {
|
||||
tc->getDTBPtr()->insert(vaddr.page(), entry);
|
||||
}
|
||||
tc->getDTBPtr()->insert(vaddr.page(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,51 +156,50 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
||||
bool
|
||||
RemoteGDB::acc(Addr va, size_t len)
|
||||
{
|
||||
if (FullSystem) {
|
||||
Addr last_va;
|
||||
if (!FullSystem)
|
||||
panic("acc function needs to be rewritten for SE mode\n");
|
||||
|
||||
va = TruncPage(va);
|
||||
last_va = RoundPage(va + len);
|
||||
Addr last_va;
|
||||
|
||||
do {
|
||||
if (IsK0Seg(va)) {
|
||||
if (va < (K0SegBase + pmem->size())) {
|
||||
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
|
||||
"%#x < K0SEG + size\n", va);
|
||||
return true;
|
||||
} else {
|
||||
DPRINTF(GDBAcc, "acc: Mapping invalid %#x "
|
||||
"> K0SEG + size\n", va);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
va = TruncPage(va);
|
||||
last_va = RoundPage(va + len);
|
||||
|
||||
/**
|
||||
* This code says that all accesses to palcode (instruction
|
||||
* and data) are valid since there isn't a va->pa mapping
|
||||
* because palcode is accessed physically. At some point this
|
||||
* should probably be cleaned up but there is no easy way to
|
||||
* do it.
|
||||
*/
|
||||
|
||||
if (PcPAL(va) || va < 0x10000)
|
||||
do {
|
||||
if (IsK0Seg(va)) {
|
||||
if (va < (K0SegBase + pmem->size())) {
|
||||
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
|
||||
"%#x < K0SEG + size\n", va);
|
||||
return true;
|
||||
|
||||
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
||||
PageTableEntry pte =
|
||||
kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
|
||||
if (!pte.valid()) {
|
||||
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
||||
} else {
|
||||
DPRINTF(GDBAcc, "acc: Mapping invalid %#x "
|
||||
"> K0SEG + size\n", va);
|
||||
return false;
|
||||
}
|
||||
va += PageBytes;
|
||||
} while (va < last_va);
|
||||
}
|
||||
|
||||
DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
|
||||
return true;
|
||||
} else {
|
||||
panic("acc function needs to be rewritten for SE mode\n");
|
||||
}
|
||||
/**
|
||||
* This code says that all accesses to palcode (instruction
|
||||
* and data) are valid since there isn't a va->pa mapping
|
||||
* because palcode is accessed physically. At some point this
|
||||
* should probably be cleaned up but there is no easy way to
|
||||
* do it.
|
||||
*/
|
||||
|
||||
if (PcPAL(va) || va < 0x10000)
|
||||
return true;
|
||||
|
||||
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
||||
PageTableEntry pte =
|
||||
kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
|
||||
if (!pte.valid()) {
|
||||
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
||||
return false;
|
||||
}
|
||||
va += PageBytes;
|
||||
} while (va < last_va);
|
||||
|
||||
DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -39,24 +39,24 @@ namespace AlphaISA {
|
||||
uint64_t
|
||||
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||
{
|
||||
if (FullSystem) {
|
||||
const int NumArgumentRegs = 6;
|
||||
if (number < NumArgumentRegs) {
|
||||
if (fp)
|
||||
return tc->readFloatRegBits(16 + number);
|
||||
else
|
||||
return tc->readIntReg(16 + number);
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg = vp->read<uint64_t>(sp +
|
||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||
return arg;
|
||||
}
|
||||
} else {
|
||||
if (!FullSystem) {
|
||||
panic("getArgument() is Full system only\n");
|
||||
M5_DUMMY_RETURN;
|
||||
}
|
||||
|
||||
const int NumArgumentRegs = 6;
|
||||
if (number < NumArgumentRegs) {
|
||||
if (fp)
|
||||
return tc->readFloatRegBits(16 + number);
|
||||
else
|
||||
return tc->readIntReg(16 + number);
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg = vp->read<uint64_t>(sp +
|
||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -178,19 +178,20 @@ UndefinedInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
ArmFault::invoke(tc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the mnemonic isn't defined this has to be an unknown instruction.
|
||||
assert(unknown || mnemonic != NULL);
|
||||
if (disabled) {
|
||||
panic("Attempted to execute disabled instruction "
|
||||
"'%s' (inst 0x%08x)", mnemonic, machInst);
|
||||
} else if (unknown) {
|
||||
panic("Attempted to execute unknown instruction (inst 0x%08x)",
|
||||
machInst);
|
||||
} else {
|
||||
// If the mnemonic isn't defined this has to be an unknown instruction.
|
||||
assert(unknown || mnemonic != NULL);
|
||||
if (disabled) {
|
||||
panic("Attempted to execute disabled instruction "
|
||||
"'%s' (inst 0x%08x)", mnemonic, machInst);
|
||||
} else if (unknown) {
|
||||
panic("Attempted to execute unknown instruction (inst 0x%08x)",
|
||||
machInst);
|
||||
} else {
|
||||
panic("Attempted to execute unimplemented instruction "
|
||||
"'%s' (inst 0x%08x)", mnemonic, machInst);
|
||||
}
|
||||
panic("Attempted to execute unimplemented instruction "
|
||||
"'%s' (inst 0x%08x)", mnemonic, machInst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,19 +200,20 @@ SupervisorCall::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
ArmFault::invoke(tc, inst);
|
||||
} else {
|
||||
// As of now, there isn't a 32 bit thumb version of this instruction.
|
||||
assert(!machInst.bigThumb);
|
||||
uint32_t callNum;
|
||||
callNum = tc->readIntReg(INTREG_R7);
|
||||
tc->syscall(callNum);
|
||||
|
||||
// Advance the PC since that won't happen automatically.
|
||||
PCState pc = tc->pcState();
|
||||
assert(inst);
|
||||
inst->advancePC(pc);
|
||||
tc->pcState(pc);
|
||||
return;
|
||||
}
|
||||
|
||||
// As of now, there isn't a 32 bit thumb version of this instruction.
|
||||
assert(!machInst.bigThumb);
|
||||
uint32_t callNum;
|
||||
callNum = tc->readIntReg(INTREG_R7);
|
||||
tc->syscall(callNum);
|
||||
|
||||
// Advance the PC since that won't happen automatically.
|
||||
PCState pc = tc->pcState();
|
||||
assert(inst);
|
||||
inst->advancePC(pc);
|
||||
tc->pcState(pc);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -252,13 +254,14 @@ template void AbortFault<DataAbort>::invoke(ThreadContext *tc,
|
||||
void
|
||||
ArmSev::invoke(ThreadContext *tc, StaticInstPtr inst) {
|
||||
DPRINTF(Faults, "Invoking ArmSev Fault\n");
|
||||
if (FullSystem) {
|
||||
// Set sev_mailbox to 1, clear the pending interrupt from remote
|
||||
// SEV execution and let pipeline continue as pcState is still
|
||||
// valid.
|
||||
tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
|
||||
tc->getCpuPtr()->clearInterrupt(INT_SEV, 0);
|
||||
}
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
// Set sev_mailbox to 1, clear the pending interrupt from remote
|
||||
// SEV execution and let pipeline continue as pcState is still
|
||||
// valid.
|
||||
tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
|
||||
tc->getCpuPtr()->clearInterrupt(INT_SEV, 0);
|
||||
}
|
||||
|
||||
// return via SUBS pc, lr, xxx; rfe, movs, ldm
|
||||
|
||||
@@ -418,14 +418,12 @@ TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
if (!FullSystem) {
|
||||
Addr paddr;
|
||||
Process *p = tc->getProcessPtr();
|
||||
Addr paddr;
|
||||
Process *p = tc->getProcessPtr();
|
||||
|
||||
if (!p->pTable->translate(vaddr, paddr))
|
||||
return Fault(new GenericPageTableFault(vaddr));
|
||||
req->setPaddr(paddr);
|
||||
}
|
||||
if (!p->pTable->translate(vaddr, paddr))
|
||||
return Fault(new GenericPageTableFault(vaddr));
|
||||
req->setPaddr(paddr);
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
@@ -570,11 +568,9 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
if (FullSystem) {
|
||||
if (!bootUncacheability &&
|
||||
((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr))
|
||||
req->setFlags(Request::UNCACHEABLE);
|
||||
}
|
||||
if (!bootUncacheability &&
|
||||
((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr))
|
||||
req->setFlags(Request::UNCACHEABLE);
|
||||
|
||||
switch ( (dacr >> (te->domain * 2)) & 0x3) {
|
||||
case 0:
|
||||
|
||||
@@ -63,49 +63,49 @@ initCPU(ThreadContext *tc, int cpuId)
|
||||
uint64_t
|
||||
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||
{
|
||||
if (FullSystem) {
|
||||
if (size == (uint16_t)(-1))
|
||||
size = ArmISA::MachineBytes;
|
||||
if (fp)
|
||||
panic("getArgument(): Floating point arguments not implemented\n");
|
||||
|
||||
if (number < NumArgumentRegs) {
|
||||
// If the argument is 64 bits, it must be in an even regiser
|
||||
// number. Increment the number here if it isn't even.
|
||||
if (size == sizeof(uint64_t)) {
|
||||
if ((number % 2) != 0)
|
||||
number++;
|
||||
// Read the two halves of the data. Number is inc here to
|
||||
// get the second half of the 64 bit reg.
|
||||
uint64_t tmp;
|
||||
tmp = tc->readIntReg(number++);
|
||||
tmp |= tc->readIntReg(number) << 32;
|
||||
return tmp;
|
||||
} else {
|
||||
return tc->readIntReg(number);
|
||||
}
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg;
|
||||
if (size == sizeof(uint64_t)) {
|
||||
// If the argument is even it must be aligned
|
||||
if ((number % 2) != 0)
|
||||
number++;
|
||||
arg = vp->read<uint64_t>(sp +
|
||||
(number-NumArgumentRegs) * sizeof(uint32_t));
|
||||
// since two 32 bit args == 1 64 bit arg, increment number
|
||||
number++;
|
||||
} else {
|
||||
arg = vp->read<uint32_t>(sp +
|
||||
(number-NumArgumentRegs) * sizeof(uint32_t));
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
} else {
|
||||
if (!FullSystem) {
|
||||
panic("getArgument() only implemented for full system mode.\n");
|
||||
M5_DUMMY_RETURN
|
||||
}
|
||||
|
||||
if (size == (uint16_t)(-1))
|
||||
size = ArmISA::MachineBytes;
|
||||
if (fp)
|
||||
panic("getArgument(): Floating point arguments not implemented\n");
|
||||
|
||||
if (number < NumArgumentRegs) {
|
||||
// If the argument is 64 bits, it must be in an even regiser
|
||||
// number. Increment the number here if it isn't even.
|
||||
if (size == sizeof(uint64_t)) {
|
||||
if ((number % 2) != 0)
|
||||
number++;
|
||||
// Read the two halves of the data. Number is inc here to
|
||||
// get the second half of the 64 bit reg.
|
||||
uint64_t tmp;
|
||||
tmp = tc->readIntReg(number++);
|
||||
tmp |= tc->readIntReg(number) << 32;
|
||||
return tmp;
|
||||
} else {
|
||||
return tc->readIntReg(number);
|
||||
}
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg;
|
||||
if (size == sizeof(uint64_t)) {
|
||||
// If the argument is even it must be aligned
|
||||
if ((number % 2) != 0)
|
||||
number++;
|
||||
arg = vp->read<uint64_t>(sp +
|
||||
(number-NumArgumentRegs) * sizeof(uint32_t));
|
||||
// since two 32 bit args == 1 64 bit arg, increment number
|
||||
number++;
|
||||
} else {
|
||||
arg = vp->read<uint32_t>(sp +
|
||||
(number-NumArgumentRegs) * sizeof(uint32_t));
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -295,33 +295,31 @@ TLB::regStats()
|
||||
Fault
|
||||
TLB::translateInst(RequestPtr req, ThreadContext *tc)
|
||||
{
|
||||
if (!FullSystem) {
|
||||
Process * p = tc->getProcessPtr();
|
||||
|
||||
Fault fault = p->pTable->translate(req);
|
||||
if (fault != NoFault)
|
||||
return fault;
|
||||
|
||||
return NoFault;
|
||||
} else {
|
||||
if (FullSystem)
|
||||
panic("translateInst not implemented in MIPS.\n");
|
||||
}
|
||||
|
||||
Process * p = tc->getProcessPtr();
|
||||
|
||||
Fault fault = p->pTable->translate(req);
|
||||
if (fault != NoFault)
|
||||
return fault;
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault
|
||||
TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||
{
|
||||
if (!FullSystem) {
|
||||
Process * p = tc->getProcessPtr();
|
||||
|
||||
Fault fault = p->pTable->translate(req);
|
||||
if (fault != NoFault)
|
||||
return fault;
|
||||
|
||||
return NoFault;
|
||||
} else {
|
||||
if (FullSystem)
|
||||
panic("translateData not implemented in MIPS.\n");
|
||||
}
|
||||
|
||||
Process * p = tc->getProcessPtr();
|
||||
|
||||
Fault fault = p->pTable->translate(req);
|
||||
if (fault != NoFault)
|
||||
return fault;
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault
|
||||
|
||||
@@ -309,14 +309,13 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||
Fault
|
||||
TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
|
||||
{
|
||||
if (FullSystem) {
|
||||
if (FullSystem)
|
||||
fatal("translate atomic not yet implemented in full system mode.\n");
|
||||
} else {
|
||||
if (mode == Execute)
|
||||
return translateInst(req, tc);
|
||||
else
|
||||
return translateData(req, tc, mode == Write);
|
||||
}
|
||||
|
||||
if (mode == Execute)
|
||||
return translateInst(req, tc);
|
||||
else
|
||||
return translateData(req, tc, mode == Write);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||
* Copyright (c) 2007 MIPS Technologies, Inc.
|
||||
* Copyright (c) 2012 Google
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -26,9 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
* Nathan Binkert
|
||||
* Jaidev Patwardhan
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "arch/power/vtophys.hh"
|
||||
@@ -38,12 +35,12 @@ using namespace std;
|
||||
Addr
|
||||
PowerISA::vtophys(Addr vaddr)
|
||||
{
|
||||
fatal("VTOPHYS: Unimplemented on POWER\n");
|
||||
fatal("vtophys: Unimplemented on POWER\n");
|
||||
}
|
||||
|
||||
Addr
|
||||
PowerISA::vtophys(ThreadContext *tc, Addr addr)
|
||||
{
|
||||
fatal("VTOPHYS: Unimplemented on POWER\n");
|
||||
fatal("vtophys: Unimplemented on POWER\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -624,17 +624,18 @@ FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
SparcFaultBase::invoke(tc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(vaddr, entry);
|
||||
if (!success) {
|
||||
panic("Tried to execute unmapped address %#x.\n", vaddr);
|
||||
} else {
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(vaddr, entry);
|
||||
if (!success) {
|
||||
panic("Tried to execute unmapped address %#x.\n", vaddr);
|
||||
} else {
|
||||
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
||||
tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/,
|
||||
p->M5_pid /*context id*/, false, entry.pte);
|
||||
}
|
||||
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
||||
tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/,
|
||||
p->M5_pid /*context id*/, false, entry.pte);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,21 +644,22 @@ FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
SparcFaultBase::invoke(tc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(vaddr, entry);
|
||||
if (!success) {
|
||||
if (p->fixupStackFault(vaddr))
|
||||
success = p->pTable->lookup(vaddr, entry);
|
||||
}
|
||||
if (!success) {
|
||||
panic("Tried to access unmapped address %#x.\n", vaddr);
|
||||
} else {
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(vaddr, entry);
|
||||
if (!success) {
|
||||
if (p->fixupStackFault(vaddr))
|
||||
success = p->pTable->lookup(vaddr, entry);
|
||||
}
|
||||
if (!success) {
|
||||
panic("Tried to access unmapped address %#x.\n", vaddr);
|
||||
} else {
|
||||
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
||||
tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/,
|
||||
p->M5_pid /*context id*/, false, entry.pte);
|
||||
}
|
||||
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
|
||||
tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/,
|
||||
p->M5_pid /*context id*/, false, entry.pte);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,18 +668,19 @@ SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
SparcFaultBase::invoke(tc, inst);
|
||||
} else {
|
||||
doNormalFault(tc, trapType(), false);
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
|
||||
//XXX This will only work in faults from a SparcLiveProcess
|
||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||
assert(lp);
|
||||
|
||||
// Then adjust the PC and NPC
|
||||
tc->pcState(lp->readSpillStart());
|
||||
return;
|
||||
}
|
||||
|
||||
doNormalFault(tc, trapType(), false);
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
|
||||
//XXX This will only work in faults from a SparcLiveProcess
|
||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||
assert(lp);
|
||||
|
||||
// Then adjust the PC and NPC
|
||||
tc->pcState(lp->readSpillStart());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -685,18 +688,19 @@ FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
SparcFaultBase::invoke(tc, inst);
|
||||
} else {
|
||||
doNormalFault(tc, trapType(), false);
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
|
||||
//XXX This will only work in faults from a SparcLiveProcess
|
||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||
assert(lp);
|
||||
|
||||
// Then adjust the PC and NPC
|
||||
tc->pcState(lp->readFillStart());
|
||||
return;
|
||||
}
|
||||
|
||||
doNormalFault(tc, trapType(), false);
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
|
||||
//XXX This will only work in faults from a SparcLiveProcess
|
||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||
assert(lp);
|
||||
|
||||
// Then adjust the PC and NPC
|
||||
tc->pcState(lp->readFillStart());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -704,24 +708,25 @@ TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
SparcFaultBase::invoke(tc, inst);
|
||||
} else {
|
||||
// In SE, this mechanism is how the process requests a service from
|
||||
// the operating system. We'll get the process object from the thread
|
||||
// context and let it service the request.
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
|
||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||
assert(lp);
|
||||
|
||||
lp->handleTrap(_n, tc);
|
||||
|
||||
// We need to explicitly advance the pc, since that's not done for us
|
||||
// on a faulting instruction
|
||||
PCState pc = tc->pcState();
|
||||
pc.advance();
|
||||
tc->pcState(pc);
|
||||
return;
|
||||
}
|
||||
|
||||
// In SE, this mechanism is how the process requests a service from
|
||||
// the operating system. We'll get the process object from the thread
|
||||
// context and let it service the request.
|
||||
|
||||
Process *p = tc->getProcessPtr();
|
||||
|
||||
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
|
||||
assert(lp);
|
||||
|
||||
lp->handleTrap(_n, tc);
|
||||
|
||||
// We need to explicitly advance the pc, since that's not done for us
|
||||
// on a faulting instruction
|
||||
PCState pc = tc->pcState();
|
||||
pc.advance();
|
||||
tc->pcState(pc);
|
||||
}
|
||||
|
||||
} // namespace SparcISA
|
||||
|
||||
@@ -46,21 +46,21 @@ namespace SparcISA {
|
||||
uint64_t
|
||||
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||
{
|
||||
if (FullSystem) {
|
||||
const int NumArgumentRegs = 6;
|
||||
if (number < NumArgumentRegs) {
|
||||
return tc->readIntReg(8 + number);
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg = vp->read<uint64_t>(sp + 92 +
|
||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||
return arg;
|
||||
}
|
||||
} else {
|
||||
if (!FullSystem) {
|
||||
panic("getArgument() only implemented for full system\n");
|
||||
M5_DUMMY_RETURN
|
||||
}
|
||||
|
||||
const int NumArgumentRegs = 6;
|
||||
if (number < NumArgumentRegs) {
|
||||
return tc->readIntReg(8 + number);
|
||||
} else {
|
||||
Addr sp = tc->readIntReg(StackPointerReg);
|
||||
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||
uint64_t arg = vp->read<uint64_t>(sp + 92 +
|
||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -52,43 +52,44 @@ namespace X86ISA
|
||||
{
|
||||
void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
PCState pcState = tc->pcState();
|
||||
Addr pc = pcState.pc();
|
||||
DPRINTF(Faults, "RIP %#x: vector %d: %s\n",
|
||||
pc, vector, describe());
|
||||
using namespace X86ISAInst::RomLabels;
|
||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||
MicroPC entry;
|
||||
if (m5reg.mode == LongMode) {
|
||||
if (isSoft()) {
|
||||
entry = extern_label_longModeSoftInterrupt;
|
||||
} else {
|
||||
entry = extern_label_longModeInterrupt;
|
||||
}
|
||||
} else {
|
||||
entry = extern_label_legacyModeInterrupt;
|
||||
}
|
||||
tc->setIntReg(INTREG_MICRO(1), vector);
|
||||
tc->setIntReg(INTREG_MICRO(7), pc);
|
||||
if (errorCode != (uint64_t)(-1)) {
|
||||
if (m5reg.mode == LongMode) {
|
||||
entry = extern_label_longModeInterruptWithError;
|
||||
} else {
|
||||
panic("Legacy mode interrupts with error codes "
|
||||
"aren't implementde.\n");
|
||||
}
|
||||
// Software interrupts shouldn't have error codes. If one
|
||||
// does, there would need to be microcode to set it up.
|
||||
assert(!isSoft());
|
||||
tc->setIntReg(INTREG_MICRO(15), errorCode);
|
||||
}
|
||||
pcState.upc(romMicroPC(entry));
|
||||
pcState.nupc(romMicroPC(entry) + 1);
|
||||
tc->pcState(pcState);
|
||||
} else {
|
||||
if (!FullSystem) {
|
||||
FaultBase::invoke(tc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
PCState pcState = tc->pcState();
|
||||
Addr pc = pcState.pc();
|
||||
DPRINTF(Faults, "RIP %#x: vector %d: %s\n",
|
||||
pc, vector, describe());
|
||||
using namespace X86ISAInst::RomLabels;
|
||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||
MicroPC entry;
|
||||
if (m5reg.mode == LongMode) {
|
||||
if (isSoft()) {
|
||||
entry = extern_label_longModeSoftInterrupt;
|
||||
} else {
|
||||
entry = extern_label_longModeInterrupt;
|
||||
}
|
||||
} else {
|
||||
entry = extern_label_legacyModeInterrupt;
|
||||
}
|
||||
tc->setIntReg(INTREG_MICRO(1), vector);
|
||||
tc->setIntReg(INTREG_MICRO(7), pc);
|
||||
if (errorCode != (uint64_t)(-1)) {
|
||||
if (m5reg.mode == LongMode) {
|
||||
entry = extern_label_longModeInterruptWithError;
|
||||
} else {
|
||||
panic("Legacy mode interrupts with error codes "
|
||||
"aren't implementde.\n");
|
||||
}
|
||||
// Software interrupts shouldn't have error codes. If one
|
||||
// does, there would need to be microcode to set it up.
|
||||
assert(!isSoft());
|
||||
tc->setIntReg(INTREG_MICRO(15), errorCode);
|
||||
}
|
||||
pcState.upc(romMicroPC(entry));
|
||||
pcState.nupc(romMicroPC(entry) + 1);
|
||||
tc->pcState(pcState);
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -106,12 +107,13 @@ namespace X86ISA
|
||||
void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||
{
|
||||
X86FaultBase::invoke(tc);
|
||||
if (FullSystem) {
|
||||
// This is the same as a fault, but it happens -after- the
|
||||
// instruction.
|
||||
PCState pc = tc->pcState();
|
||||
pc.uEnd();
|
||||
}
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
// This is the same as a fault, but it happens -after- the
|
||||
// instruction.
|
||||
PCState pc = tc->pcState();
|
||||
pc.uEnd();
|
||||
}
|
||||
|
||||
void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
|
||||
|
||||
@@ -314,12 +314,11 @@ InOrderDynInst::simPalCheck(int palFunc)
|
||||
void
|
||||
InOrderDynInst::syscall(int64_t callnum)
|
||||
{
|
||||
if (FullSystem) {
|
||||
if (FullSystem)
|
||||
panic("Syscall emulation isn't available in FS mode.\n");
|
||||
} else {
|
||||
syscallNum = callnum;
|
||||
cpu->syscallContext(NoFault, this->threadNumber, this);
|
||||
}
|
||||
|
||||
syscallNum = callnum;
|
||||
cpu->syscallContext(NoFault, this->threadNumber, this);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -193,18 +193,17 @@ template <class Impl>
|
||||
void
|
||||
BaseO3DynInst<Impl>::syscall(int64_t callnum)
|
||||
{
|
||||
if (FullSystem) {
|
||||
if (FullSystem)
|
||||
panic("Syscall emulation isn't available in FS mode.\n");
|
||||
} else {
|
||||
// HACK: check CPU's nextPC before and after syscall. If it
|
||||
// changes, update this instruction's nextPC because the syscall
|
||||
// must have changed the nextPC.
|
||||
TheISA::PCState curPC = this->cpu->pcState(this->threadNumber);
|
||||
this->cpu->syscall(callnum, this->threadNumber);
|
||||
TheISA::PCState newPC = this->cpu->pcState(this->threadNumber);
|
||||
if (!(curPC == newPC)) {
|
||||
this->pcState(newPC);
|
||||
}
|
||||
|
||||
// HACK: check CPU's nextPC before and after syscall. If it
|
||||
// changes, update this instruction's nextPC because the syscall
|
||||
// must have changed the nextPC.
|
||||
TheISA::PCState curPC = this->cpu->pcState(this->threadNumber);
|
||||
this->cpu->syscall(callnum, this->threadNumber);
|
||||
TheISA::PCState newPC = this->cpu->pcState(this->threadNumber);
|
||||
if (!(curPC == newPC)) {
|
||||
this->pcState(newPC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,22 +75,23 @@ struct O3ThreadState : public ThreadState {
|
||||
: ThreadState(_cpu, _thread_num, _process),
|
||||
cpu(_cpu), inSyscall(0), trapPending(0)
|
||||
{
|
||||
if (FullSystem) {
|
||||
if (cpu->params()->profile) {
|
||||
profile = new FunctionProfile(
|
||||
cpu->params()->system->kernelSymtab);
|
||||
Callback *cb =
|
||||
new MakeCallback<O3ThreadState,
|
||||
&O3ThreadState::dumpFuncProfile>(this);
|
||||
registerExitCallback(cb);
|
||||
}
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
// let's fill with a dummy node for now so we don't get a segfault
|
||||
// on the first cycle when there's no node available.
|
||||
static ProfileNode dummyNode;
|
||||
profileNode = &dummyNode;
|
||||
profilePC = 3;
|
||||
if (cpu->params()->profile) {
|
||||
profile = new FunctionProfile(
|
||||
cpu->params()->system->kernelSymtab);
|
||||
Callback *cb =
|
||||
new MakeCallback<O3ThreadState,
|
||||
&O3ThreadState::dumpFuncProfile>(this);
|
||||
registerExitCallback(cb);
|
||||
}
|
||||
|
||||
// let's fill with a dummy node for now so we don't get a segfault
|
||||
// on the first cycle when there's no node available.
|
||||
static ProfileNode dummyNode;
|
||||
profileNode = &dummyNode;
|
||||
profilePC = 3;
|
||||
}
|
||||
|
||||
/** Pointer to the ThreadContext of this thread. */
|
||||
|
||||
@@ -396,8 +396,8 @@ class BaseSimpleCPU : public BaseCPU
|
||||
{
|
||||
if (FullSystem)
|
||||
panic("Syscall emulation isn't available in FS mode.\n");
|
||||
else
|
||||
thread->syscall(callnum);
|
||||
|
||||
thread->syscall(callnum);
|
||||
}
|
||||
|
||||
bool misspeculating() { return thread->misspeculating(); }
|
||||
|
||||
@@ -68,14 +68,15 @@ ThreadState::serialize(std::ostream &os)
|
||||
// thread_num and cpu_id are deterministic from the config
|
||||
SERIALIZE_SCALAR(funcExeInst);
|
||||
|
||||
if (FullSystem) {
|
||||
Tick quiesceEndTick = 0;
|
||||
if (quiesceEvent->scheduled())
|
||||
quiesceEndTick = quiesceEvent->when();
|
||||
SERIALIZE_SCALAR(quiesceEndTick);
|
||||
if (kernelStats)
|
||||
kernelStats->serialize(os);
|
||||
}
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
Tick quiesceEndTick = 0;
|
||||
if (quiesceEvent->scheduled())
|
||||
quiesceEndTick = quiesceEvent->when();
|
||||
SERIALIZE_SCALAR(quiesceEndTick);
|
||||
if (kernelStats)
|
||||
kernelStats->serialize(os);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -86,14 +87,15 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
// thread_num and cpu_id are deterministic from the config
|
||||
UNSERIALIZE_SCALAR(funcExeInst);
|
||||
|
||||
if (FullSystem) {
|
||||
Tick quiesceEndTick;
|
||||
UNSERIALIZE_SCALAR(quiesceEndTick);
|
||||
if (quiesceEndTick)
|
||||
baseCpu->schedule(quiesceEvent, quiesceEndTick);
|
||||
if (kernelStats)
|
||||
kernelStats->unserialize(cp, section);
|
||||
}
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
Tick quiesceEndTick;
|
||||
UNSERIALIZE_SCALAR(quiesceEndTick);
|
||||
if (quiesceEndTick)
|
||||
baseCpu->schedule(quiesceEvent, quiesceEndTick);
|
||||
if (kernelStats)
|
||||
kernelStats->unserialize(cp, section);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -63,8 +63,7 @@ using namespace AlphaISA;
|
||||
|
||||
AlphaBackdoor::AlphaBackdoor(const Params *p)
|
||||
: BasicPioDevice(p), disk(p->disk), terminal(p->terminal),
|
||||
system(p->system),
|
||||
cpu(p->cpu)
|
||||
system(p->system), cpu(p->cpu)
|
||||
{
|
||||
|
||||
pioSize = sizeof(struct AlphaAccess);
|
||||
@@ -96,7 +95,8 @@ AlphaBackdoor::startup()
|
||||
alphaAccess->mem_size = system->physmem->size();
|
||||
alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz
|
||||
Tsunami *tsunami = dynamic_cast<Tsunami *>(params()->platform);
|
||||
assert(tsunami);
|
||||
if (!tsunami)
|
||||
fatal("Platform is not Tsunami.\n");
|
||||
alphaAccess->intrClockFrequency = tsunami->io->frequency();
|
||||
}
|
||||
|
||||
|
||||
@@ -85,119 +85,114 @@ panicFsOnlyPseudoInst(const char *name)
|
||||
void
|
||||
arm(ThreadContext *tc)
|
||||
{
|
||||
if (FullSystem) {
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->arm();
|
||||
} else {
|
||||
if (!FullSystem)
|
||||
panicFsOnlyPseudoInst("arm");
|
||||
}
|
||||
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->arm();
|
||||
}
|
||||
|
||||
void
|
||||
quiesce(ThreadContext *tc)
|
||||
{
|
||||
if (FullSystem) {
|
||||
if (!tc->getCpuPtr()->params()->do_quiesce)
|
||||
return;
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
} else {
|
||||
if (!FullSystem)
|
||||
panicFsOnlyPseudoInst("quiesce");
|
||||
}
|
||||
|
||||
if (!tc->getCpuPtr()->params()->do_quiesce)
|
||||
return;
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
}
|
||||
|
||||
void
|
||||
quiesceSkip(ThreadContext *tc)
|
||||
{
|
||||
if (FullSystem) {
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
if (!cpu->params()->do_quiesce)
|
||||
return;
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick() + 1;
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
|
||||
cpu->name(), resume);
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
} else {
|
||||
if (!FullSystem)
|
||||
panicFsOnlyPseudoInst("quiesceSkip");
|
||||
}
|
||||
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
if (!cpu->params()->do_quiesce)
|
||||
return;
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick() + 1;
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
|
||||
cpu->name(), resume);
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
}
|
||||
|
||||
void
|
||||
quiesceNs(ThreadContext *tc, uint64_t ns)
|
||||
{
|
||||
if (FullSystem) {
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
if (!cpu->params()->do_quiesce || ns == 0)
|
||||
return;
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick() + SimClock::Int::ns * ns;
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
|
||||
cpu->name(), ns, resume);
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
} else {
|
||||
if (!FullSystem)
|
||||
panicFsOnlyPseudoInst("quiesceNs");
|
||||
}
|
||||
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
if (!cpu->params()->do_quiesce || ns == 0)
|
||||
return;
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick() + SimClock::Int::ns * ns;
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
|
||||
cpu->name(), ns, resume);
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
}
|
||||
|
||||
void
|
||||
quiesceCycles(ThreadContext *tc, uint64_t cycles)
|
||||
{
|
||||
if (FullSystem) {
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
if (!cpu->params()->do_quiesce || cycles == 0)
|
||||
return;
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick() + cpu->ticks(cycles);
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
|
||||
cpu->name(), cycles, resume);
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
} else {
|
||||
if (!FullSystem)
|
||||
panicFsOnlyPseudoInst("quiesceCycles");
|
||||
}
|
||||
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
if (!cpu->params()->do_quiesce || cycles == 0)
|
||||
return;
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick() + cpu->ticks(cycles);
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
|
||||
cpu->name(), cycles, resume);
|
||||
|
||||
tc->suspend();
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->quiesce();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
quiesceTime(ThreadContext *tc)
|
||||
{
|
||||
if (FullSystem) {
|
||||
return (tc->readLastActivate() - tc->readLastSuspend()) /
|
||||
SimClock::Int::ns;
|
||||
} else {
|
||||
if (!FullSystem) {
|
||||
panicFsOnlyPseudoInst("quiesceTime");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (tc->readLastActivate() - tc->readLastSuspend()) /
|
||||
SimClock::Int::ns;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
@@ -225,81 +220,79 @@ m5exit(ThreadContext *tc, Tick delay)
|
||||
void
|
||||
loadsymbol(ThreadContext *tc)
|
||||
{
|
||||
if (FullSystem) {
|
||||
const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
|
||||
if (filename.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
ifstream file(filename.c_str());
|
||||
|
||||
if (!file)
|
||||
fatal("file error: Can't open symbol table file %s\n", filename);
|
||||
|
||||
while (!file.eof()) {
|
||||
getline(file, buffer);
|
||||
|
||||
if (buffer.empty())
|
||||
continue;
|
||||
|
||||
string::size_type idx = buffer.find(' ');
|
||||
if (idx == string::npos)
|
||||
continue;
|
||||
|
||||
string address = "0x" + buffer.substr(0, idx);
|
||||
eat_white(address);
|
||||
if (address.empty())
|
||||
continue;
|
||||
|
||||
// Skip over letter and space
|
||||
string symbol = buffer.substr(idx + 3);
|
||||
eat_white(symbol);
|
||||
if (symbol.empty())
|
||||
continue;
|
||||
|
||||
Addr addr;
|
||||
if (!to_number(address, addr))
|
||||
continue;
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
|
||||
continue;
|
||||
|
||||
|
||||
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
|
||||
}
|
||||
file.close();
|
||||
} else {
|
||||
if (!FullSystem)
|
||||
panicFsOnlyPseudoInst("loadsymbol");
|
||||
|
||||
const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
|
||||
if (filename.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
ifstream file(filename.c_str());
|
||||
|
||||
if (!file)
|
||||
fatal("file error: Can't open symbol table file %s\n", filename);
|
||||
|
||||
while (!file.eof()) {
|
||||
getline(file, buffer);
|
||||
|
||||
if (buffer.empty())
|
||||
continue;
|
||||
|
||||
string::size_type idx = buffer.find(' ');
|
||||
if (idx == string::npos)
|
||||
continue;
|
||||
|
||||
string address = "0x" + buffer.substr(0, idx);
|
||||
eat_white(address);
|
||||
if (address.empty())
|
||||
continue;
|
||||
|
||||
// Skip over letter and space
|
||||
string symbol = buffer.substr(idx + 3);
|
||||
eat_white(symbol);
|
||||
if (symbol.empty())
|
||||
continue;
|
||||
|
||||
Addr addr;
|
||||
if (!to_number(address, addr))
|
||||
continue;
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
|
||||
continue;
|
||||
|
||||
|
||||
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void
|
||||
addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
|
||||
{
|
||||
if (FullSystem) {
|
||||
char symb[100];
|
||||
CopyStringOut(tc, symb, symbolAddr, 100);
|
||||
std::string symbol(symb);
|
||||
|
||||
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
|
||||
|
||||
tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
|
||||
debugSymbolTable->insert(addr,symbol);
|
||||
} else {
|
||||
if (!FullSystem)
|
||||
panicFsOnlyPseudoInst("addSymbol");
|
||||
}
|
||||
|
||||
char symb[100];
|
||||
CopyStringOut(tc, symb, symbolAddr, 100);
|
||||
std::string symbol(symb);
|
||||
|
||||
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
|
||||
|
||||
tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
|
||||
debugSymbolTable->insert(addr,symbol);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
initParam(ThreadContext *tc)
|
||||
{
|
||||
if (FullSystem) {
|
||||
return tc->getCpuPtr()->system->init_param;
|
||||
} else {
|
||||
if (!FullSystem) {
|
||||
panicFsOnlyPseudoInst("initParam");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tc->getCpuPtr()->system->init_param;
|
||||
}
|
||||
|
||||
|
||||
@@ -357,41 +350,41 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
|
||||
uint64_t
|
||||
readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
|
||||
{
|
||||
if (FullSystem) {
|
||||
const string &file = tc->getSystemPtr()->params()->readfile;
|
||||
if (file.empty()) {
|
||||
return ULL(0);
|
||||
}
|
||||
|
||||
uint64_t result = 0;
|
||||
|
||||
int fd = ::open(file.c_str(), O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
panic("could not open file %s\n", file);
|
||||
|
||||
if (::lseek(fd, offset, SEEK_SET) < 0)
|
||||
panic("could not seek: %s", strerror(errno));
|
||||
|
||||
char *buf = new char[len];
|
||||
char *p = buf;
|
||||
while (len > 0) {
|
||||
int bytes = ::read(fd, p, len);
|
||||
if (bytes <= 0)
|
||||
break;
|
||||
|
||||
p += bytes;
|
||||
result += bytes;
|
||||
len -= bytes;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
CopyIn(tc, vaddr, buf, result);
|
||||
delete [] buf;
|
||||
return result;
|
||||
} else {
|
||||
if (!FullSystem) {
|
||||
panicFsOnlyPseudoInst("readfile");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const string &file = tc->getSystemPtr()->params()->readfile;
|
||||
if (file.empty()) {
|
||||
return ULL(0);
|
||||
}
|
||||
|
||||
uint64_t result = 0;
|
||||
|
||||
int fd = ::open(file.c_str(), O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
panic("could not open file %s\n", file);
|
||||
|
||||
if (::lseek(fd, offset, SEEK_SET) < 0)
|
||||
panic("could not seek: %s", strerror(errno));
|
||||
|
||||
char *buf = new char[len];
|
||||
char *p = buf;
|
||||
while (len > 0) {
|
||||
int bytes = ::read(fd, p, len);
|
||||
if (bytes <= 0)
|
||||
break;
|
||||
|
||||
p += bytes;
|
||||
result += bytes;
|
||||
len -= bytes;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
CopyIn(tc, vaddr, buf, result);
|
||||
delete [] buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -218,8 +218,8 @@ System::numRunningContexts()
|
||||
void
|
||||
System::initState()
|
||||
{
|
||||
int i;
|
||||
if (FullSystem) {
|
||||
int i;
|
||||
for (i = 0; i < threadContexts.size(); i++)
|
||||
TheISA::startupCPU(threadContexts[i], i);
|
||||
// Moved from the constructor to here since it relies on the
|
||||
@@ -271,11 +271,11 @@ System::initState()
|
||||
|
||||
activeCpus.clear();
|
||||
|
||||
if (FullSystem) {
|
||||
int i;
|
||||
for (i = 0; i < threadContexts.size(); i++)
|
||||
TheISA::startupCPU(threadContexts[i], i);
|
||||
}
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
for (i = 0; i < threadContexts.size(); i++)
|
||||
TheISA::startupCPU(threadContexts[i], i);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user