summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript10
-rw-r--r--arch/alpha/alpha_memory.cc9
-rw-r--r--arch/alpha/ev5.cc7
-rw-r--r--cpu/pc_event.cc4
-rw-r--r--cpu/pc_event.hh4
-rw-r--r--cpu/simple_cpu/simple_cpu.hh1
-rw-r--r--kern/kernel_stats.cc28
-rw-r--r--kern/kernel_stats.hh7
-rw-r--r--kern/linux/linux_system.cc35
-rw-r--r--kern/linux/linux_system.hh16
-rw-r--r--kern/system_events.cc14
-rw-r--r--kern/system_events.hh20
-rw-r--r--sim/system.cc9
-rw-r--r--sim/system.hh4
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;