System: Move code in initState() back into constructor whenever possible.

The change to port proxies recently moved code out of the constructor into
initState(). This is needed for code that loads data into memory, however
for code that setups symbol tables, kernel based events, etc this is the wrong
thing to do as that code is only called when a checkpoint isn't being restored
from.
This commit is contained in:
Ali Saidi 2012-03-09 09:59:26 -05:00
parent ec1ef24895
commit 3ce2d0fad0
8 changed files with 190 additions and 137 deletions

View file

@ -113,6 +113,12 @@ LinuxAlphaSystem::initState()
else
panic("could not find dp264_mv\n");
}
void
LinuxAlphaSystem::setupFuncEvents()
{
AlphaSystem::setupFuncEvents();
#ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
if (!kernelPanicEvent)
@ -148,6 +154,7 @@ LinuxAlphaSystem::initState()
// re-enable, but we should find a better way to turn it on than
// using DTRACE(Thread), since looking at a trace flag at tick 0
// leads to non-intuitive behavior with --trace-start.
Addr addr = 0;
if (false && kernelSymtab->findAddress("alpha_switch_to", addr)) {
printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
addr + sizeof(MachInst) * 6);

View file

@ -123,6 +123,12 @@ class LinuxAlphaSystem : public AlphaSystem
/** Grab the PCBB of the idle process when it starts */
IdleStartEvent *idleStartEvent;
protected:
/** Setup all the function events. Must be done after init() for Alpha since
* fixFuncEvent() requires a function port
*/
virtual void setupFuncEvents();
public:
typedef LinuxAlphaSystemParams Params;
LinuxAlphaSystem(Params *p);

View file

@ -63,30 +63,6 @@ AlphaSystem::AlphaSystem(Params *p)
pal = createObjectFile(params()->pal);
if (pal == NULL)
fatal("Could not load PALcode file %s", params()->pal);
}
AlphaSystem::~AlphaSystem()
{
delete consoleSymtab;
delete console;
delete pal;
#ifdef DEBUG
delete consolePanicEvent;
#endif
}
void
AlphaSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
System::initState();
// Load program sections into memory
pal->loadSections(physProxy, loadAddrMask);
console->loadSections(physProxy, loadAddrMask);
// load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
@ -107,10 +83,33 @@ AlphaSystem::initState()
if (!pal->loadLocalSymbols(debugSymbolTable))
panic("could not load pal symbols\n");
Addr addr = 0;
#ifndef NDEBUG
consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
}
AlphaSystem::~AlphaSystem()
{
delete consoleSymtab;
delete console;
delete pal;
#ifdef DEBUG
delete consolePanicEvent;
#endif
}
void
AlphaSystem::initState()
{
Addr addr = 0;
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
System::initState();
// Load program sections into memory
pal->loadSections(physProxy, loadAddrMask);
console->loadSections(physProxy, loadAddrMask);
/**
* Copy the osflags (kernel arguments) into the consoles
@ -135,6 +134,29 @@ AlphaSystem::initState()
virtProxy.write(addr+0x58, data);
} else
panic("could not find hwrpb\n");
// Setup all the function events now that we have a system and a symbol
// table
setupFuncEvents();
}
void
AlphaSystem::loadState(Checkpoint *cp)
{
System::loadState(cp);
// Setup all the function events now that we have a system and a symbol
// table
setupFuncEvents();
}
void
AlphaSystem::setupFuncEvents()
{
#ifndef NDEBUG
consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
#endif
}
/**

View file

@ -62,6 +62,10 @@ class AlphaSystem : public System
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
/** Override loadState to provide a path to call setupFuncEvents()
*/
virtual void loadState(Checkpoint *cp);
/**
* Set the m5AlphaAccess pointer in the console
*/
@ -89,6 +93,12 @@ class AlphaSystem : public System
const Params *params() const { return (const Params *)_params; }
/** Setup all the function events. Must be done after init() for Alpha since
* fixFuncEvent() requires a function port
*/
virtual void setupFuncEvents();
/** Add a function-based event to PALcode. */
template <class T>
T *

View file

@ -58,6 +58,40 @@ using namespace Linux;
LinuxArmSystem::LinuxArmSystem(Params *p)
: ArmSystem(p)
{
#ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
if (!kernelPanicEvent)
panic("could not find kernel symbol \'panic\'");
#endif
// With ARM udelay() is #defined to __udelay
Addr addr = 0;
if (kernelSymtab->findAddress("__udelay", addr)) {
uDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__udelay",
fixFuncEventAddr(addr), 1000, 0);
} else {
panic("couldn't find kernel symbol \'udelay\'");
}
// constant arguments to udelay() have some precomputation done ahead of
// time. Constant comes from code.
if (kernelSymtab->findAddress("__const_udelay", addr)) {
constUDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__const_udelay",
fixFuncEventAddr(addr), 1000, 107374);
} else {
panic("couldn't find kernel symbol \'udelay\'");
}
secDataPtrAddr = 0;
secDataAddr = 0;
penReleaseAddr = 0;
kernelSymtab->findAddress("__secondary_data", secDataPtrAddr);
kernelSymtab->findAddress("secondary_data", secDataAddr);
kernelSymtab->findAddress("pen_release", penReleaseAddr);
secDataPtrAddr &= ~ULL(0x7F);
secDataAddr &= ~ULL(0x7F);
penReleaseAddr &= ~ULL(0x7F);
}
bool
@ -116,41 +150,6 @@ LinuxArmSystem::initState()
physProxy.writeBlob(params()->atags_addr, boot_data, size << 2);
#ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
if (!kernelPanicEvent)
panic("could not find kernel symbol \'panic\'");
#endif
// With ARM udelay() is #defined to __udelay
Addr addr = 0;
if (kernelSymtab->findAddress("__udelay", addr)) {
uDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__udelay",
fixFuncEventAddr(addr), 1000, 0);
} else {
panic("couldn't find kernel symbol \'udelay\'");
}
// constant arguments to udelay() have some precomputation done ahead of
// time. Constant comes from code.
if (kernelSymtab->findAddress("__const_udelay", addr)) {
constUDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__const_udelay",
fixFuncEventAddr(addr), 1000, 107374);
} else {
panic("couldn't find kernel symbol \'udelay\'");
}
secDataPtrAddr = 0;
secDataAddr = 0;
penReleaseAddr = 0;
kernelSymtab->findAddress("__secondary_data", secDataPtrAddr);
kernelSymtab->findAddress("secondary_data", secDataAddr);
kernelSymtab->findAddress("pen_release", penReleaseAddr);
secDataPtrAddr &= ~ULL(0x7F);
secDataAddr &= ~ULL(0x7F);
penReleaseAddr &= ~ULL(0x7F);
for (int i = 0; i < threadContexts.size(); i++) {
threadContexts[i]->setIntReg(0, 0);
threadContexts[i]->setIntReg(1, params()->machine_type);

View file

@ -55,6 +55,19 @@ using namespace Linux;
ArmSystem::ArmSystem(Params *p)
: System(p), bootldr(NULL)
{
if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
fatal("If boot_loader is specifed, memory to load it must be also.\n");
if (p->boot_loader != "") {
bootldr = createObjectFile(p->boot_loader);
if (!bootldr)
fatal("Could not read bootloader: %s\n", p->boot_loader);
bootldr->loadGlobalSymbols(debugSymbolTable);
}
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
}
void
@ -68,17 +81,8 @@ ArmSystem::initState()
const Params* p = params();
if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
fatal("If boot_loader is specifed, memory to load it must be also.\n");
if (p->boot_loader != "") {
bootldr = createObjectFile(p->boot_loader);
if (!bootldr)
fatal("Could not read bootloader: %s\n", p->boot_loader);
if (bootldr) {
bootldr->loadSections(physProxy);
bootldr->loadGlobalSymbols(debugSymbolTable);
uint8_t jump_to_bl[] =
{
@ -87,32 +91,30 @@ ArmSystem::initState()
physProxy.writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
inform("Using bootloader at address %#x\n", bootldr->entryPoint());
}
if (bootldr) {
// Put the address of the boot loader into r7 so we know
// where to branch to after the reset fault
// All other values needed by the boot loader to know what to do
if (!p->gic_cpu_addr || !p->flags_addr)
fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
for (int i = 0; i < threadContexts.size(); i++) {
threadContexts[i]->setIntReg(3, kernelEntry & loadAddrMask);
threadContexts[i]->setIntReg(4, params()->gic_cpu_addr);
threadContexts[i]->setIntReg(5, params()->flags_addr);
threadContexts[i]->setIntReg(7, bootldr->entryPoint());
}
if (!p->gic_cpu_addr || !p->flags_addr)
fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
} else {
// Set the initial PC to be at start of the kernel code
threadContexts[0]->pcState(kernelEntry & loadAddrMask);
}
for (int i = 0; i < threadContexts.size(); i++) {
if (p->midr_regval) {
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
p->midr_regval);
}
}
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
}
ArmSystem::~ArmSystem()

View file

@ -48,13 +48,6 @@ SparcSystem::SparcSystem(Params *p)
nvramSymtab = new SymbolTable;
hypervisorDescSymtab = new SymbolTable;
partitionDescSymtab = new SymbolTable;
}
void
SparcSystem::initState()
{
// Call the initialisation of the super class
System::initState();
/**
* Load the boot code, and hypervisor into memory.
@ -91,26 +84,6 @@ SparcSystem::initState()
fatal("Could not load partition description image %s",
params()->partition_desc_bin);
// Load reset binary into memory
reset->setTextBase(params()->reset_addr);
reset->loadSections(physProxy);
// Load the openboot binary
openboot->setTextBase(params()->openboot_addr);
openboot->loadSections(physProxy);
// Load the hypervisor binary
hypervisor->setTextBase(params()->hypervisor_addr);
hypervisor->loadSections(physProxy);
// Load the nvram image
nvram->setTextBase(params()->nvram_addr);
nvram->loadSections(physProxy);
// Load the hypervisor description image
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
hypervisor_desc->loadSections(physProxy);
// Load the partition description image
partition_desc->setTextBase(params()->partition_desc_addr);
partition_desc->loadSections(physProxy);
// load symbols
if (!reset->loadGlobalSymbols(resetSymtab))
panic("could not load reset symbols\n");
@ -154,6 +127,33 @@ SparcSystem::initState()
if (!partition_desc->loadLocalSymbols(debugSymbolTable))
panic("could not load partition description symbols\n");
}
void
SparcSystem::initState()
{
// Call the initialisation of the super class
System::initState();
// Load reset binary into memory
reset->setTextBase(params()->reset_addr);
reset->loadSections(physProxy);
// Load the openboot binary
openboot->setTextBase(params()->openboot_addr);
openboot->loadSections(physProxy);
// Load the hypervisor binary
hypervisor->setTextBase(params()->hypervisor_addr);
hypervisor->loadSections(physProxy);
// Load the nvram image
nvram->setTextBase(params()->nvram_addr);
nvram->loadSections(physProxy);
// Load the hypervisor description image
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
hypervisor_desc->loadSections(physProxy);
// Load the partition description image
partition_desc->setTextBase(params()->partition_desc_addr);
partition_desc->loadSections(physProxy);
// @todo any fixup code over writing data in binaries on setting break
// events on functions should happen here.

View file

@ -117,6 +117,44 @@ System::System(Params *p)
tmp_id = getMasterId("interrupt");
assert(tmp_id == Request::intMasterId);
if (FullSystem) {
if (params()->kernel == "") {
inform("No kernel set for full system simulation. "
"Assuming you know what you're doing if not SPARC ISA\n");
} else {
// Get the kernel code
kernel = createObjectFile(params()->kernel);
inform("kernel located at: %s", params()->kernel);
if (kernel == NULL)
fatal("Could not load kernel file %s", params()->kernel);
// setup entry points
kernelStart = kernel->textBase();
kernelEnd = kernel->bssBase() + kernel->bssSize();
kernelEntry = kernel->entryPoint();
// load symbols
if (!kernel->loadGlobalSymbols(kernelSymtab))
fatal("could not load kernel symbols\n");
if (!kernel->loadLocalSymbols(kernelSymtab))
fatal("could not load kernel local symbols\n");
if (!kernel->loadGlobalSymbols(debugSymbolTable))
fatal("could not load kernel symbols\n");
if (!kernel->loadLocalSymbols(debugSymbolTable))
fatal("could not load kernel local symbols\n");
// Loading only needs to happen once and after memory system is
// connected so it will happen in initState()
}
}
// increment the number of running systms
numSystemsRunning++;
}
System::~System()
@ -232,38 +270,10 @@ System::initState()
/**
* Load the kernel code into memory
*/
if (params()->kernel == "") {
inform("No kernel set for full system simulation. "
"Assuming you know what you're doing...\n");
} else {
// Load kernel code
kernel = createObjectFile(params()->kernel);
inform("kernel located at: %s", params()->kernel);
if (kernel == NULL)
fatal("Could not load kernel file %s", params()->kernel);
if (params()->kernel != "") {
// Load program sections into memory
kernel->loadSections(physProxy, loadAddrMask);
// setup entry points
kernelStart = kernel->textBase();
kernelEnd = kernel->bssBase() + kernel->bssSize();
kernelEntry = kernel->entryPoint();
// load symbols
if (!kernel->loadGlobalSymbols(kernelSymtab))
fatal("could not load kernel symbols\n");
if (!kernel->loadLocalSymbols(kernelSymtab))
fatal("could not load kernel local symbols\n");
if (!kernel->loadGlobalSymbols(debugSymbolTable))
fatal("could not load kernel symbols\n");
if (!kernel->loadLocalSymbols(debugSymbolTable))
fatal("could not load kernel local symbols\n");
DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
@ -271,9 +281,6 @@ System::initState()
}
}
// increment the number of running systms
numSystemsRunning++;
activeCpus.clear();
if (!FullSystem)