diff options
-rw-r--r-- | SConscript | 10 | ||||
-rw-r--r-- | arch/alpha/alpha_memory.cc | 9 | ||||
-rw-r--r-- | arch/alpha/ev5.cc | 7 | ||||
-rw-r--r-- | cpu/pc_event.cc | 4 | ||||
-rw-r--r-- | cpu/pc_event.hh | 4 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.hh | 1 | ||||
-rw-r--r-- | kern/kernel_stats.cc | 28 | ||||
-rw-r--r-- | kern/kernel_stats.hh | 7 | ||||
-rw-r--r-- | kern/linux/linux_system.cc | 35 | ||||
-rw-r--r-- | kern/linux/linux_system.hh | 16 | ||||
-rw-r--r-- | kern/system_events.cc | 14 | ||||
-rw-r--r-- | kern/system_events.hh | 20 | ||||
-rw-r--r-- | sim/system.cc | 9 | ||||
-rw-r--r-- | sim/system.hh | 4 |
14 files changed, 135 insertions, 33 deletions
diff --git a/SConscript b/SConscript index 6949d9548..4ef66dec3 100644 --- a/SConscript +++ b/SConscript @@ -383,13 +383,15 @@ extra_libraries = [] if env['USE_MYSQL']: sources += mysql_sources env.Append(CPPDEFINES = 'USE_MYSQL') + env.Append(CPPDEFINES = 'STATS_BINNING') env.Append(CPPPATH=['/usr/local/include/mysql', '/usr/include/mysql']) env.Append(LIBS=['z']) - if sys.platform.lower().startswith('linux'): - extra_libraries.append('/usr/lib/mysql/libmysqlclient.a') + if os.path.isdir('/usr/lib64'): + env.Append(LIBPATH=['/usr/lib64/mysql']) else: - env.Append(LIBS=['mysql']) - env.Append(LIBPATH=['/usr/local/lib/mysql/']) + env.Append(LIBPATH=['/usr/lib/mysql/']) + env.Append(LIBS=['mysqlclient']) + ################################################### # diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 9f5ab185e..4a350dbfc 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -492,10 +492,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); - /* @todo this should actually be in there but for whatever reason - * Its not working at present. + /** + * Check for alignment faults */ if (req->vaddr & (req->size - 1)) { + fault(req, write ? MM_STAT_WR_MASK : 0); return Alignment_Fault; } @@ -510,8 +511,8 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const } else { // verify that this is a good virtual address if (!validVirtualAddress(req->vaddr)) { - fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | - MM_STAT_ACV_MASK)); + fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | + MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } return DTB_Fault_Fault; diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index b0f2251dc..8b95e8b3d 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -164,7 +164,7 @@ AlphaISA::zeroRegisters(XC *xc) void ExecContext::ev5_trap(Fault fault) { - DPRINTF(Fault, "Fault %s\n", FaultName(fault)); + DPRINTF(Fault, "Fault %s at PC: %#x\n", FaultName(fault), regs.pc); cpu->recordEvent(csprintf("Fault %s", FaultName(fault))); assert(!misspeculating()); @@ -447,7 +447,10 @@ ExecContext::setIpr(int idx, uint64_t val) break; case AlphaISA::IPR_DTB_CM: - kernelStats->mode((val & 0x18) != 0); + if (val & 0x18) + kernelStats->mode(Kernel::user); + else + kernelStats->mode(Kernel::kernel); case AlphaISA::IPR_ICM: // only write two mode bits - processor mode diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc index a86c017d4..8f046a7a4 100644 --- a/cpu/pc_event.cc +++ b/cpu/pc_event.cc @@ -77,7 +77,7 @@ PCEventQueue::schedule(PCEvent *event) bool PCEventQueue::doService(ExecContext *xc) { - Addr pc = xc->regs.pc; + Addr pc = xc->regs.pc & ~0x3; int serviced = 0; range_t range = equal_range(pc); for (iterator i = range.first; i != range.second; ++i) { @@ -85,7 +85,7 @@ PCEventQueue::doService(ExecContext *xc) // another event. This for example, prevents two invocations // of the SkipFuncEvent. Maybe we should have separate PC // event queues for each processor? - if (pc != xc->regs.pc) + if (pc != (xc->regs.pc & ~0x3)) continue; DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n", diff --git a/cpu/pc_event.hh b/cpu/pc_event.hh index 131016fc6..9983d679b 100644 --- a/cpu/pc_event.hh +++ b/cpu/pc_event.hh @@ -143,7 +143,7 @@ PCEvent::schedule(Addr pc) { if (evpc != badpc) panic("cannot switch PC"); - evpc = pc; + evpc = pc & ~0x3; return schedule(); } @@ -158,7 +158,7 @@ PCEvent::schedule(PCEventQueue *q, Addr pc) panic("cannot switch addresses"); queue = q; - evpc = pc; + evpc = pc & ~0x3; return schedule(); } diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index 6ab231e7e..451c801ee 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -40,7 +40,6 @@ // forward declarations #ifdef FULL_SYSTEM class Processor; -class Kernel; class AlphaITB; class AlphaDTB; class PhysicalMemory; diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index c8c04e6d1..c08ee08f7 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -45,12 +45,13 @@ using namespace Stats; namespace Kernel { -const char *modestr[] = { "kernel", "user", "idle" }; +const char *modestr[] = { "kernel", "user", "idle", "interrupt" }; Statistics::Statistics(ExecContext *context) : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0), iplLast(0), iplLastTick(0) { + bin_int = xc->system->params->bin_int; } void @@ -153,20 +154,20 @@ Statistics::regStats(const string &_name) } _mode - .init(3) + .init(cpu_mode_num) .name(name() + ".mode_switch") .desc("number of protection mode switches") ; - for (int i = 0; i < 3; ++i) + for (int i = 0; i < cpu_mode_num; ++i) _mode.subname(i, modestr[i]); _modeGood - .init(3) + .init(cpu_mode_num) .name(name() + ".mode_good") ; - for (int i = 0; i < 3; ++i) + for (int i = 0; i < cpu_mode_num; ++i) _modeGood.subname(i, modestr[i]); _modeFraction @@ -175,18 +176,18 @@ Statistics::regStats(const string &_name) .flags(total) ; - for (int i = 0; i < 3; ++i) + for (int i = 0; i < cpu_mode_num; ++i) _modeFraction.subname(i, modestr[i]); _modeFraction = _modeGood / _mode; _modeTicks - .init(3) + .init(cpu_mode_num) .name(name() + ".mode_ticks") .desc("number of ticks spent at the given mode") .flags(pdf) ; - for (int i = 0; i < 3; ++i) + for (int i = 0; i < cpu_mode_num; ++i) _modeTicks.subname(i, modestr[i]); _swap_context @@ -198,7 +199,7 @@ Statistics::regStats(const string &_name) void Statistics::setIdleProcess(Addr idlepcbb) { - assert(themode == kernel); + assert(themode == kernel || themode == interrupt); idleProcess = idlepcbb; themode = idle; changeMode(themode); @@ -241,14 +242,17 @@ Statistics::swpipl(int ipl) } void -Statistics::mode(bool usermode) +Statistics::mode(cpu_mode newmode) { Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23]; - cpu_mode newmode = usermode ? user : kernel; - if (newmode == kernel && pcbb == idleProcess) + if ((newmode == kernel || newmode == interrupt) && + pcbb == idleProcess) newmode = idle; + if (bin_int == false && newmode == interrupt) + newmode = kernel; + changeMode(newmode); } diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 8339c578c..af93eb95c 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -45,7 +45,7 @@ enum Fault; namespace Kernel { -enum cpu_mode { kernel, user, idle, cpu_mode_num }; +enum cpu_mode { kernel, user, idle, interrupt, cpu_mode_num }; extern const char *modestr[]; class Binning @@ -98,7 +98,7 @@ class Binning std::vector<std::string> binned_fns; private: - Stats::MainBin *modeBin[3]; + Stats::MainBin *modeBin[cpu_mode_num]; public: const bool bin; @@ -133,6 +133,7 @@ class Statistics : public Serializable Addr idleProcess; cpu_mode themode; Tick lastModeTick; + bool bin_int; void changeMode(cpu_mode newmode); @@ -177,7 +178,7 @@ class Statistics : public Serializable void hwrei() { _hwrei++; } void fault(Fault fault) { _faults[fault]++; } void swpipl(int ipl); - void mode(bool usermode); + void mode(cpu_mode newmode); void context(Addr oldpcbb, Addr newpcbb); void callpal(int code); diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index 10641de87..fd5d48195 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -143,6 +143,31 @@ LinuxSystem::LinuxSystem(Params *p) printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo"); if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread)) printThreadEvent->schedule(addr + sizeof(MachInst) * 6); + + intStartEvent = new InterruptStartEvent(&pcEventQueue, "intStartEvent"); + if (palSymtab->findAddress("sys_int_21", addr)) + intStartEvent->schedule(addr + sizeof(MachInst) * 2); + else + panic("could not find symbol: sys_int_21\n"); + + intEndEvent = new InterruptEndEvent(&pcEventQueue, "intEndEvent"); + if (palSymtab->findAddress("rti_to_kern", addr)) + intEndEvent->schedule(addr) ; + else + panic("could not find symbol: rti_to_kern\n"); + + intEndEvent2 = new InterruptEndEvent(&pcEventQueue, "intEndEvent2"); + if (palSymtab->findAddress("rti_to_user", addr)) + intEndEvent2->schedule(addr); + else + panic("could not find symbol: rti_to_user\n"); + + + intEndEvent3 = new InterruptEndEvent(&pcEventQueue, "intEndEvent3"); + if (kernelSymtab->findAddress("do_softirq", addr)) + intEndEvent3->schedule(addr + sizeof(MachInst) * 2); + else + panic("could not find symbol: do_softirq\n"); } LinuxSystem::~LinuxSystem() @@ -155,6 +180,10 @@ LinuxSystem::~LinuxSystem() delete skipCacheProbeEvent; delete debugPrintkEvent; delete idleStartEvent; + delete printThreadEvent; + delete intStartEvent; + delete intEndEvent; + delete intEndEvent2; } @@ -193,6 +222,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) Param<bool> bin; VectorParam<string> binned_fns; + Param<bool> bin_int; END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) @@ -210,7 +240,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), INIT_PARAM_DFLT(bin, "is this system to be binned", false), - INIT_PARAM(binned_fns, "functions to be broken down and binned") + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", false) END_INIT_SIM_OBJECT_PARAMS(LinuxSystem) @@ -230,7 +261,7 @@ CREATE_SIM_OBJECT(LinuxSystem) p->system_rev = system_rev; p->bin = bin; p->binned_fns = binned_fns; - + p->bin_int = bin_int; return new LinuxSystem(p); } diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh index 707204607..5e3cba9b3 100644 --- a/kern/linux/linux_system.hh +++ b/kern/linux/linux_system.hh @@ -83,8 +83,24 @@ class LinuxSystem : public System */ LinuxSkipDelayLoopEvent *skipDelayLoopEvent; + /** + * Event to print information about thread switches if the trace flag + * Thread is set + */ PrintThreadInfo *printThreadEvent; + /** + * Event to bin Interrupts seperately from kernel code + */ + InterruptStartEvent *intStartEvent; + + /** + * Event to bin Interrupts seperately from kernel code + */ + InterruptEndEvent *intEndEvent; + InterruptEndEvent *intEndEvent2; + InterruptEndEvent *intEndEvent3; + /** Grab the PCBB of the idle process when it starts */ IdleStartEvent *idleStartEvent; diff --git a/kern/system_events.cc b/kern/system_events.cc index 91daf53ca..b6526d193 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -71,3 +71,17 @@ IdleStartEvent::process(ExecContext *xc) { xc->kernelStats->setIdleProcess(xc->regs.ipr[AlphaISA::IPR_PALtemp23]); } + +void +InterruptStartEvent::process(ExecContext *xc) +{ + xc->kernelStats->mode(Kernel::interrupt); +} + +void +InterruptEndEvent::process(ExecContext *xc) +{ + // We go back to kernel, if we are user, inside the rti + // pal code we will get switched to user because of the ICM write + xc->kernelStats->mode(Kernel::kernel); +} diff --git a/kern/system_events.hh b/kern/system_events.hh index 95027572f..8a8549d03 100644 --- a/kern/system_events.hh +++ b/kern/system_events.hh @@ -64,4 +64,24 @@ class IdleStartEvent : public PCEvent {} virtual void process(ExecContext *xc); }; + +class InterruptStartEvent : public PCEvent +{ + public: + InterruptStartEvent(PCEventQueue *q, const std::string &desc) + : PCEvent(q, desc) + {} + virtual void process(ExecContext *xc); +}; + +class InterruptEndEvent : public PCEvent +{ + public: + InterruptEndEvent(PCEventQueue *q, const std::string &desc) + : PCEvent(q, desc) + {} + virtual void process(ExecContext *xc); +}; + + #endif // __SYSTEM_EVENTS_HH__ diff --git a/sim/system.cc b/sim/system.cc index de988f8d7..f8312e33b 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -55,6 +55,7 @@ System::System(Params *p) kernelSymtab = new SymbolTable; consoleSymtab = new SymbolTable; + palSymtab = new SymbolTable; debugSymbolTable = new SymbolTable; /** @@ -96,7 +97,13 @@ System::System(Params *p) if (!console->loadGlobalSymbols(consoleSymtab)) panic("could not load console symbols\n"); - if (!kernel->loadGlobalSymbols(debugSymbolTable)) + if (!pal->loadGlobalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!pal->loadLocalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!kernel->loadGlobalSymbols(debugSymbolTable)) panic("could not load kernel symbols\n"); if (!kernel->loadLocalSymbols(debugSymbolTable)) diff --git a/sim/system.hh b/sim/system.hh index 05b97ad62..5294f417e 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -64,6 +64,9 @@ class System : public SimObject /** console symbol table */ SymbolTable *consoleSymtab; + /** pal symbol table */ + SymbolTable *palSymtab; + /** Object pointer for the kernel code */ ObjectFile *kernel; @@ -103,6 +106,7 @@ class System : public SimObject uint64_t init_param; bool bin; std::vector<std::string> binned_fns; + bool bin_int; std::string kernel_path; std::string console_path; |