diff options
-rw-r--r-- | src/arch/alpha/ev5.cc | 50 | ||||
-rw-r--r-- | src/arch/alpha/isa/decoder.isa | 34 | ||||
-rw-r--r-- | src/arch/alpha/isa/main.isa | 3 | ||||
-rw-r--r-- | src/arch/x86/bios/IntelMP.py | 9 | ||||
-rw-r--r-- | src/cpu/checker/cpu.hh | 2 | ||||
-rw-r--r-- | src/cpu/exec_context.hh | 12 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 45 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 5 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 3 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst_impl.hh | 32 | ||||
-rw-r--r-- | src/cpu/ozone/cpu.hh | 2 | ||||
-rw-r--r-- | src/cpu/ozone/cpu_impl.hh | 40 | ||||
-rw-r--r-- | src/cpu/ozone/dyn_inst.hh | 2 | ||||
-rw-r--r-- | src/cpu/ozone/dyn_inst_impl.hh | 22 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 2 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 4 |
16 files changed, 222 insertions, 45 deletions
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index c11b3632e..7dc02a611 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 06676ae87..270940df2 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 0f7f74359..5231712c8 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -69,8 +69,6 @@ output exec {{ #include <math.h> #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 758932180..70e7963fa 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 0f01f17c5..5b3c4582c 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 836cf4352..2b9fe4bcf 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 c110bbd50..41b7e8b14 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; @@ -903,6 +907,47 @@ FullO3CPU<Impl>::post_interrupt(int int_num, int index) template <class Impl> Fault +FullO3CPU<Impl>::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 <class Impl> +bool +FullO3CPU<Impl>::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 <class Impl> +Fault FullO3CPU<Impl>::getInterrupts() { // Check if there are any outstanding interrupts diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 07ba8d701..406d965be 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 28dd60f5f..292547b6b 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -168,8 +168,11 @@ class BaseO3DynInst : public BaseDynInst<Impl> } #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 3b713ea8f..6398a3afe 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -125,11 +125,43 @@ BaseO3DynInst<Impl>::completeAcc(PacketPtr pkt) #if FULL_SYSTEM template <class Impl> +Fault +BaseO3DynInst<Impl>::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 <class Impl> void BaseO3DynInst<Impl>::trap(Fault fault) { this->cpu->trap(fault, this->threadNumber); } + +template <class Impl> +bool +BaseO3DynInst<Impl>::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 <class Impl> void diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index ee5e9e668..845cbbd95 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 94af07525..c8e0dfe3d 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -669,6 +669,21 @@ OzoneCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid) } #else template <class Impl> +Fault +OzoneCPU<Impl>::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 <class Impl> void OzoneCPU<Impl>::processInterrupts() { @@ -685,6 +700,31 @@ OzoneCPU<Impl>::processInterrupts() interrupt->invoke(thread.getTC()); } } + +template <class Impl> +bool +OzoneCPU<Impl>::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 <class Impl> diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index 12a19e70d..e138cbe13 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -240,7 +240,9 @@ class OzoneDynInst : public BaseDynInst<Impl> 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 396007687..8519917f5 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -249,11 +249,33 @@ OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val) #if FULL_SYSTEM template <class Impl> +Fault +OzoneDynInst<Impl>::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 <class Impl> void OzoneDynInst<Impl>::trap(Fault fault) { fault->invoke(this->thread->getTC()); } + +template <class Impl> +bool +OzoneDynInst<Impl>::simPalCheck(int palFunc) +{ + return this->cpu->simPalCheck(palFunc); +} #else template <class Impl> void diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 03c20a6f2..b7fcf1708 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 d26e984a3..189cbeec5 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 /******************************************* |