added system option to bin interrupt code seperately.

arch/alpha/ev5.cc:
    set the mode explictly rather than having a bool user/notuser
cpu/simple_cpu/simple_cpu.hh:
    there is no class Kernel
kern/kernel_stats.cc:
    use cpu_mode_num
kern/kernel_stats.hh:
    add interrupt mode and use cpu_mode_num rather than constant
kern/linux/linux_system.cc:
kern/linux/linux_system.hh:
kern/system_events.cc:
kern/system_events.hh:
    add events to change the mode to/from interrupt
sim/system.cc:
sim/system.hh:
    add a pal symbol table

--HG--
extra : convert_revision : 9d30e826b72122062a5ea12d094f94760e75c66a
This commit is contained in:
Ali Saidi 2004-09-03 14:12:59 -04:00
parent 8efb592e0b
commit af620e1187
10 changed files with 97 additions and 20 deletions

View file

@ -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

View file

@ -40,7 +40,6 @@
// forward declarations
#ifdef FULL_SYSTEM
class Processor;
class Kernel;
class AlphaITB;
class AlphaDTB;
class PhysicalMemory;

View file

@ -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);
}

View file

@ -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);

View file

@ -143,6 +143,16 @@ 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 (kernelSymtab->findAddress("do_entInt", addr))
intStartEvent->schedule(addr + sizeof(MachInst) * 2);
intEndEvent = new InterruptEndEvent(&pcEventQueue, "intStartEvent");
if (palSymtab->findAddress("Call_Pal_Rti", addr))
intEndEvent->schedule(addr + sizeof(MachInst));
else
panic("could not find symbol\n");
}
LinuxSystem::~LinuxSystem()
@ -155,6 +165,8 @@ LinuxSystem::~LinuxSystem()
delete skipCacheProbeEvent;
delete debugPrintkEvent;
delete idleStartEvent;
delete printThreadEvent;
delete intStartEvent;
}
@ -193,6 +205,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 +223,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 +244,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);
}

View file

@ -83,8 +83,22 @@ 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;
/** Grab the PCBB of the idle process when it starts */
IdleStartEvent *idleStartEvent;

View file

@ -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);
}

View file

@ -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__

View file

@ -55,6 +55,7 @@ System::System(Params *p)
kernelSymtab = new SymbolTable;
consoleSymtab = new SymbolTable;
palSymtab = new SymbolTable;
debugSymbolTable = new SymbolTable;
/**
@ -96,6 +97,9 @@ System::System(Params *p)
if (!console->loadGlobalSymbols(consoleSymtab))
panic("could not load console symbols\n");
if (!pal->loadGlobalSymbols(palSymtab))
panic("could not load pal symbols\n");
if (!kernel->loadGlobalSymbols(debugSymbolTable))
panic("could not load kernel symbols\n");

View file

@ -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;