# Node ID 9a09f71f7234472cdf13e59fd39b14b4158b0738 # Parent 21f657b1dc1ba741018b83e05480f7ac13f3047c diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -231,6 +231,8 @@ { Addr paddr = req->getPaddr(); + AddrRange m5opRange(0xFFFF0000, 0xFFFFFFFF); + // Check for an access to the local APIC if (FullSystem) { LocalApicBase localApicBase = @@ -238,8 +240,6 @@ AddrRange apicRange(localApicBase.base * PageBytes, (localApicBase.base + 1) * PageBytes - 1); - AddrRange m5opRange(0xFFFF0000, 0xFFFFFFFF); - if (apicRange.contains(paddr)) { // The Intel developer's manuals say the below restrictions apply, // but the linux kernel, because of a compiler optimization, breaks @@ -262,6 +262,13 @@ (paddr >> 8) & 0xFF, paddr & 0xFF)); } + } else { + if (m5opRange.contains(paddr)) { + req->setFlags(Request::MMAPPED_IPR | Request::GENERIC_IPR); + req->setPaddr(GenericISA::iprAddressPseudoInst( + (paddr >> 8) & 0xFF, + paddr & 0xFF)); + } } return NoFault; diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -52,9 +52,7 @@ uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) { - if (!FullSystem) { - panic("getArgument() only implemented for full system mode.\n"); - } else if (fp) { + if (fp) { panic("getArgument(): Floating point arguments not implemented\n"); } else if (size != 8) { panic("getArgument(): Can only handle 64-bit arguments.\n"); diff --git a/src/cpu/kvm/base.hh b/src/cpu/kvm/base.hh --- a/src/cpu/kvm/base.hh +++ b/src/cpu/kvm/base.hh @@ -666,6 +666,7 @@ * contain other data such as the MMIO ring buffer. */ struct kvm_run *_kvmRun; + private: /** * Coalesced MMIO ring buffer. NULL if coalesced MMIO is not * supported. diff --git a/src/cpu/kvm/base.cc b/src/cpu/kvm/base.cc --- a/src/cpu/kvm/base.cc +++ b/src/cpu/kvm/base.cc @@ -85,8 +85,14 @@ panic("KVM: Failed to determine host page size (%i)\n", errno); - thread = new SimpleThread(this, 0, params->system, - params->itb, params->dtb, params->isa[0]); + if (FullSystem) + thread = new SimpleThread(this, 0, params->system, params->itb, params->dtb, + params->isa[0]); + else + thread = new SimpleThread(this, /* thread_num */ 0, params->system, + params->workload[0], params->itb, + params->dtb, params->isa[0]); + thread->setStatus(ThreadContext::Halted); tc = thread->getTC(); threadContexts.push_back(tc); @@ -1011,6 +1017,7 @@ const Cycles ipr_delay(write ? TheISA::handleIprWrite(tc, &pkt) : TheISA::handleIprRead(tc, &pkt)); + threadContextDirty = true; return clockPeriod() * ipr_delay; } else { // Temporarily lock and migrate to the event queue of the diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -88,6 +88,8 @@ void switchcpu(ThreadContext *tc); void workbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid); void workend(ThreadContext *tc, uint64_t workid, uint64_t threadid); +void m5syscall(ThreadContext *tc); +void m5pagefault(ThreadContext *tc); } // namespace PseudoInst diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -64,6 +64,7 @@ #include "debug/WorkItems.hh" #include "params/BaseCPU.hh" #include "sim/full_system.hh" +#include "sim/process.hh" #include "sim/pseudo_inst.hh" #include "sim/serialize.hh" #include "sim/sim_events.hh" @@ -191,8 +192,17 @@ break; case 0x55: // annotate_func - case 0x56: // reserved2_func - case 0x57: // reserved3_func + warn("Unimplemented m5 op (0x%x)\n", func); + break; + + case 0x56: // syscall_func + m5syscall(tc); + break; + + case 0x57: // pagefault_func + m5pagefault(tc); + break; + case 0x58: // reserved4_func case 0x59: // reserved5_func warn("Unimplemented m5 op (0x%x)\n", func); @@ -706,4 +716,34 @@ } } +// +// This function is executed when the simulation is executing the syscall +// handler in System Emulation mode. +// +void +m5syscall(ThreadContext *tc) +{ + DPRINTF(PseudoInst, "PseudoInst::m5syscall()\n"); + + tc->syscall( tc->readIntReg(INTREG_RAX) ); + MiscReg rflags = tc->readMiscReg(MISCREG_RFLAGS); + rflags &= ~(1<<16); + tc->setMiscReg(MISCREG_RFLAGS, rflags); +} + +// +// This function is executed when the simulation is executing the pagefault +// handler in System Emulation mode. +// +void +m5pagefault(ThreadContext *tc) +{ + DPRINTF(PseudoInst, "PseudoInst::m5pagefault()\n"); + + Process *p = tc->getProcessPtr(); + if ( !p->fixupStackFault(tc->readMiscReg(MISCREG_CR2)) ) { + panic("Page fault at %#x ", tc->readMiscReg(MISCREG_CR2)); + } +} + } // namespace PseudoInst diff --git a/src/sim/system.cc b/src/sim/system.cc --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -319,6 +319,16 @@ { Addr return_addr = pagePtr << LogVMPageSize; pagePtr += npages; + + Addr next_return_addr = pagePtr << LogVMPageSize; + + AddrRange m5opRange(0xffff0000, 0xffffffff); + if (m5opRange.contains(next_return_addr)) { + warn("Reached m5ops MMIO region\n"); + return_addr = 0xffffffff; + pagePtr = 0xffffffff >> LogVMPageSize; + } + if ((pagePtr << LogVMPageSize) > physmem.totalSize()) fatal("Out of memory, please increase size of physical memory."); return return_addr; diff --git a/util/m5/m5ops.h b/util/m5/m5ops.h --- a/util/m5/m5ops.h +++ b/util/m5/m5ops.h @@ -54,8 +54,8 @@ #define addsymbol_func 0x53 #define panic_func 0x54 -#define reserved2_func 0x56 // Reserved for user -#define reserved3_func 0x57 // Reserved for user +#define syscall_func 0x56 // Reserved for user +#define pagefault_func 0x57 // Reserved for user #define reserved4_func 0x58 // Reserved for user #define reserved5_func 0x59 // Reserved for user