diff options
Diffstat (limited to 'kern/linux')
-rw-r--r-- | kern/linux/linux_system.cc | 26 | ||||
-rw-r--r-- | kern/linux/linux_system.hh | 4 |
2 files changed, 30 insertions, 0 deletions
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index db67c5619..798577ba5 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -33,11 +33,13 @@ #include "base/remote_gdb.hh" #include "base/trace.hh" #include "cpu/exec_context.hh" +#include "cpu/base_cpu.hh" #include "kern/linux/linux_events.hh" #include "kern/linux/linux_system.hh" #include "mem/functional_mem/memory_control.hh" #include "mem/functional_mem/physical_memory.hh" #include "sim/builder.hh" +#include "dev/platform.hh" #include "targetarch/isa_traits.hh" #include "targetarch/vtophys.hh" @@ -220,6 +222,10 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, skipScavengeBootEvent = new LinuxSkipFuncEvent(&pcEventQueue, "pmap_scavenge_boot"); printfEvent = new LinuxPrintfEvent(&pcEventQueue, "printf"); + + skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue, + "calibrate_delay"); + /* debugPrintfEvent = new DebugPrintfEvent(&pcEventQueue, "debug_printf", false); debugPrintfrEvent = new DebugPrintfEvent(&pcEventQueue, @@ -301,6 +307,9 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, if (kernelSymtab->findAddress("pmap_scavenge_boot", addr)) skipScavengeBootEvent->schedule(addr); + if (kernelSymtab->findAddress("calibrate_delay", addr)) + skipDelayLoopEvent->schedule(addr+8); + #if TRACING_ON if (kernelSymtab->findAddress("printk", addr)) printfEvent->schedule(addr); @@ -581,6 +590,23 @@ LinuxSystem::~LinuxSystem() #endif //FS_MEASURE } +void +LinuxSystem::setDelayLoop(ExecContext *xc) +{ + Addr addr = 0; + if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { + Addr paddr = vtophys(physmem, addr); + + uint8_t *loops_per_jiffy = + physmem->dma_addr(paddr, sizeof(uint32_t)); + + Tick cpuFreq = xc->cpu->getFreq(); + Tick intrFreq = platform->interrupt_frequency; + *(uint32_t *)loops_per_jiffy = + (uint32_t)((cpuFreq / intrFreq) * 0.9988); + } +} + int LinuxSystem::registerExecContext(ExecContext *xc) { diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh index cfb20f6dc..6aa29249a 100644 --- a/kern/linux/linux_system.hh +++ b/kern/linux/linux_system.hh @@ -45,6 +45,7 @@ class SymbolTable; class BreakPCEvent; class LinuxBadAddrEvent; class LinuxSkipFuncEvent; +class LinuxSkipDelayLoopEvent; class LinuxPrintfEvent; class LinuxDebugPrintfEvent; class LinuxDumpMbufEvent; @@ -105,6 +106,7 @@ class LinuxSystem : public System LinuxBadAddrEvent *badaddrEvent; LinuxSkipFuncEvent *skipPowerStateEvent; LinuxSkipFuncEvent *skipScavengeBootEvent; + LinuxSkipDelayLoopEvent *skipDelayLoopEvent; LinuxPrintfEvent *printfEvent; LinuxDebugPrintfEvent *debugPrintfEvent; LinuxDebugPrintfEvent *debugPrintfrEvent; @@ -174,6 +176,8 @@ class LinuxSystem : public System const bool _bin); ~LinuxSystem(); + void setDelayLoop(ExecContext *xc); + int registerExecContext(ExecContext *xc); void replaceExecContext(ExecContext *xc, int xcIndex); |