diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index c11b3632ef..7dc02a611e 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -547,3 +547,53 @@ copyIprs(ThreadContext *src, ThreadContext *dest) } } // namespace AlphaISA + +#if FULL_SYSTEM + +using namespace AlphaISA; + +Fault +SimpleThread::hwrei() +{ + if (!(readPC() & 0x3)) + return new UnimplementedOpcodeFault; + + setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); + + if (!misspeculating()) { + if (kernelStats) + kernelStats->hwrei(); + } + + // FIXME: XXX check for interrupts? XXX + return NoFault; +} + +/** + * Check for special simulator handling of specific PAL calls. + * If return value is false, actual PAL call will be suppressed. + */ +bool +SimpleThread::simPalCheck(int palFunc) +{ + if (kernelStats) + kernelStats->callpal(palFunc, tc); + + switch (palFunc) { + case PAL::halt: + halt(); + if (--System::numSystemsRunning == 0) + exitSimLoop("all cpus halted"); + break; + + case PAL::bpt: + case PAL::bugchk: + if (system->breakpoint()) + return false; + break; + } + + return true; +} + +#endif // FULL_SYSTEM diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 06676ae871..270940df2e 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -698,28 +698,7 @@ decode OPCODE default Unknown::unknown() { else { // check to see if simulator wants to do something special // on this PAL call (including maybe suppress it) - - bool dopal = true; - - ThreadContext * tc = xc->tcBase(); - AlphaISA::Kernel::Statistics * kernelStats = tc->getKernelStats(); - System * system = tc->getSystemPtr(); - if (kernelStats) - kernelStats->callpal(palFunc, tc); - - switch (palFunc) { - case PAL::halt: - tc->halt(); - if (--System::numSystemsRunning == 0) - exitSimLoop("all cpus halted"); - break; - - case PAL::bpt: - case PAL::bugchk: - if (system->breakpoint()) - dopal = false; - break; - } + bool dopal = xc->simPalCheck(palFunc); if (dopal) { xc->setMiscReg(IPR_EXC_ADDR, NPC); @@ -807,16 +786,7 @@ decode OPCODE default Unknown::unknown() { format BasicOperate { 0x1e: decode PALMODE { 0: OpcdecFault::hw_rei(); - 1: hw_rei({{ - NPC = ExcAddr; - ThreadContext * tc = xc->tcBase(); - if (!tc->misspeculating()) { - AlphaISA::Kernel::Statistics * kernelStats = - tc->getKernelStats(); - if (kernelStats) - kernelStats->hwrei(); - } - }}, IsSerializing, IsSerializeBefore); + 1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); } // M5 special opcodes use the reserved 0x01 opcode space diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 0f7f74359a..5231712c8e 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -69,8 +69,6 @@ output exec {{ #include #if FULL_SYSTEM -#include "arch/alpha/kernel_stats.hh" -#include "arch/alpha/osfpal.hh" #include "sim/pseudo_inst.hh" #endif #include "arch/alpha/ipr.hh" @@ -189,7 +187,6 @@ def operands {{ 'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1), 'FPCR': ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1), 'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1), - 'ExcAddr': ('ControlReg', 'uq', 'IPR_EXC_ADDR', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py index 7589321809..70e7963fa0 100644 --- a/src/arch/x86/bios/IntelMP.py +++ b/src/arch/x86/bios/IntelMP.py @@ -86,15 +86,6 @@ class X86IntelMPConfigTable(SimObject): ext_entries = VectorParam.X86IntelMPExtConfigEntry([], 'extended configuration table entries') - def add_entry(self, entry): - if isinstance(entry, X86IntelMPBaseConfigEntry): - self.base_entries.append(entry) - elif isinstance(entry, X86IntelMPExtConfigEntry): - self.base_entries.append(entry) - else: - panic("Don't know what type of Intel MP entry %s is." \ - % entry.__class__.__name__) - class X86IntelMPBaseConfigEntry(SimObject): type = 'X86IntelMPBaseConfigEntry' cxx_class = 'X86ISA::IntelMP::BaseConfigEntry' diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 0f01f17c57..5b3c4582c9 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -336,7 +336,9 @@ class CheckerCPU : public BaseCPU void translateDataReadReq(Request *req); #if FULL_SYSTEM + Fault hwrei() { return thread->hwrei(); } void ev5_trap(Fault fault) { fault->invoke(tc); } + bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } #else // Assume that the normal CPU's call to syscall was successful. // The checker's state would have already been updated by the syscall. diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index 836cf43528..2b9fe4bcf1 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -143,7 +143,17 @@ class ExecContext { * given flags. */ void writeHint(Addr addr, int size, unsigned flags); -#if !FULL_SYSTEM +#if FULL_SYSTEM + /** Somewhat Alpha-specific function that handles returning from + * an error or interrupt. */ + Fault hwrei(); + + /** + * Check for special simulator handling of specific PAL calls. If + * return value is false, actual PAL call will be suppressed. + */ + bool simPalCheck(int palFunc); +#else /** Executes a syscall specified by the callnum. */ void syscall(int64_t callnum); #endif diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index c110bbd50b..41b7e8b14f 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -53,6 +53,10 @@ #include "cpu/checker/cpu.hh" #endif +#if THE_ISA == ALPHA_ISA +#include "arch/alpha/osfpal.hh" +#endif + class BaseCPUParams; using namespace TheISA; @@ -901,6 +905,47 @@ FullO3CPU::post_interrupt(int int_num, int index) } } +template +Fault +FullO3CPU::hwrei(unsigned tid) +{ +#if THE_ISA == ALPHA_ISA + // Need to clear the lock flag upon returning from an interrupt. + this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid); + + this->thread[tid]->kernelStats->hwrei(); + + // FIXME: XXX check for interrupts? XXX +#endif + return NoFault; +} + +template +bool +FullO3CPU::simPalCheck(int palFunc, unsigned tid) +{ +#if THE_ISA == ALPHA_ISA + if (this->thread[tid]->kernelStats) + this->thread[tid]->kernelStats->callpal(palFunc, + this->threadContexts[tid]); + + switch (palFunc) { + case PAL::halt: + halt(); + if (--System::numSystemsRunning == 0) + exitSimLoop("all cpus halted"); + break; + + case PAL::bpt: + case PAL::bugchk: + if (this->system->breakpoint()) + return false; + break; + } +#endif + return true; +} + template Fault FullO3CPU::getInterrupts() diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 07ba8d7018..406d965bec 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -414,6 +414,11 @@ class FullO3CPU : public BaseO3CPU /** Posts an interrupt. */ void post_interrupt(int int_num, int index); + /** HW return from error interrupt. */ + Fault hwrei(unsigned tid); + + bool simPalCheck(int palFunc, unsigned tid); + /** Returns the Fault for any valid interrupt. */ Fault getInterrupts(); diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 28dd60f5fa..292547b6b8 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -168,8 +168,11 @@ class BaseO3DynInst : public BaseDynInst } #if FULL_SYSTEM + /** Calls hardware return from error interrupt. */ + Fault hwrei(); /** Traps to handle specified fault. */ void trap(Fault fault); + bool simPalCheck(int palFunc); #else /** Calls a syscall. */ void syscall(int64_t callnum); diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh index 3b713ea8f5..6398a3afee 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -124,12 +124,44 @@ BaseO3DynInst::completeAcc(PacketPtr pkt) } #if FULL_SYSTEM +template +Fault +BaseO3DynInst::hwrei() +{ +#if THE_ISA == ALPHA_ISA + // Can only do a hwrei when in pal mode. + if (!(this->readPC() & 0x3)) + return new AlphaISA::UnimplementedOpcodeFault; + + // Set the next PC based on the value of the EXC_ADDR IPR. + this->setNextPC(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, + this->threadNumber)); + + // Tell CPU to clear any state it needs to if a hwrei is taken. + this->cpu->hwrei(this->threadNumber); +#else + +#endif + // FIXME: XXX check for interrupts? XXX + return NoFault; +} + template void BaseO3DynInst::trap(Fault fault) { this->cpu->trap(fault, this->threadNumber); } + +template +bool +BaseO3DynInst::simPalCheck(int palFunc) +{ +#if THE_ISA != ALPHA_ISA + panic("simPalCheck called, but PAL only exists in Alpha!\n"); +#endif + return this->cpu->simPalCheck(palFunc, this->threadNumber); +} #else template void diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index ee5e9e6683..845cbbd95f 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -507,6 +507,8 @@ class OzoneCPU : public BaseCPU void dumpInsts() { frontEnd->dumpInsts(); } #if FULL_SYSTEM + Fault hwrei(); + bool simPalCheck(int palFunc); void processInterrupts(); #else void syscall(uint64_t &callnum); diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index 94af07525e..c8e0dfe3d7 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -668,6 +668,21 @@ OzoneCPU::setSyscallReturn(SyscallReturn return_value, int tid) } } #else +template +Fault +OzoneCPU::hwrei() +{ + // Need to move this to ISA code + // May also need to make this per thread + + lockFlag = false; + lockAddrList.clear(); + thread.kernelStats->hwrei(); + + // FIXME: XXX check for interrupts? XXX + return NoFault; +} + template void OzoneCPU::processInterrupts() @@ -685,6 +700,31 @@ OzoneCPU::processInterrupts() interrupt->invoke(thread.getTC()); } } + +template +bool +OzoneCPU::simPalCheck(int palFunc) +{ + // Need to move this to ISA code + // May also need to make this per thread + thread.kernelStats->callpal(palFunc, tc); + + switch (palFunc) { + case PAL::halt: + haltContext(thread.readTid()); + if (--System::numSystemsRunning == 0) + exitSimLoop("all cpus halted"); + break; + + case PAL::bpt: + case PAL::bugchk: + if (system->breakpoint()) + return false; + break; + } + + return true; +} #endif template diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index 12a19e70df..e138cbe13a 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -240,7 +240,9 @@ class OzoneDynInst : public BaseDynInst void setMiscReg(int misc_reg, const MiscReg &val); #if FULL_SYSTEM + Fault hwrei(); void trap(Fault fault); + bool simPalCheck(int palFunc); #else void syscall(uint64_t &callnum); #endif diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 3960076876..8519917f5a 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -248,12 +248,34 @@ OzoneDynInst::setMiscReg(int misc_reg, const MiscReg &val) #if FULL_SYSTEM +template +Fault +OzoneDynInst::hwrei() +{ + if (!(this->readPC() & 0x3)) + return new AlphaISA::UnimplementedOpcodeFault; + + this->setNextPC(this->thread->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR)); + + this->cpu->hwrei(); + + // FIXME: XXX check for interrupts? XXX + return NoFault; +} + template void OzoneDynInst::trap(Fault fault) { fault->invoke(this->thread->getTC()); } + +template +bool +OzoneDynInst::simPalCheck(int palFunc) +{ + return this->cpu->simPalCheck(palFunc); +} #else template void diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 03c20a6f27..b7fcf1708d 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -413,7 +413,9 @@ class BaseSimpleCPU : public BaseCPU //Fault CacheOp(uint8_t Op, Addr EA); #if FULL_SYSTEM + Fault hwrei() { return thread->hwrei(); } void ev5_trap(Fault fault) { fault->invoke(tc); } + bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } #else void syscall(int64_t callnum) { thread->syscall(callnum); } #endif diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index d26e984a3e..189cbeec5e 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -185,6 +185,10 @@ class SimpleThread : public ThreadState void dumpFuncProfile(); + Fault hwrei(); + + bool simPalCheck(int palFunc); + #endif /*******************************************