Implement Ali's review feedback.

Try to decrease indentation, and remove some redundant FullSystem checks.
This commit is contained in:
Gabe Black
2012-01-29 02:04:34 -08:00
parent 22a076a6d5
commit dc0e629ea1
20 changed files with 530 additions and 535 deletions

View File

@@ -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);
}
}

View File

@@ -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;
}
/*

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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. */

View File

@@ -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(); }

View File

@@ -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 &section)
// 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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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