diff options
-rw-r--r-- | src/arch/alpha/linux/system.cc | 7 | ||||
-rw-r--r-- | src/arch/alpha/linux/system.hh | 6 | ||||
-rw-r--r-- | src/arch/alpha/system.cc | 70 | ||||
-rw-r--r-- | src/arch/alpha/system.hh | 10 | ||||
-rw-r--r-- | src/arch/arm/linux/system.cc | 69 | ||||
-rw-r--r-- | src/arch/arm/system.cc | 34 | ||||
-rw-r--r-- | src/arch/sparc/system.cc | 54 | ||||
-rw-r--r-- | src/sim/system.cc | 71 |
8 files changed, 187 insertions, 134 deletions
diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index e42553b63..db3c16d7e 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -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); diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index 5436a27b2..345c17bb7 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -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); diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index 8d6629169..51e1d7e07 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -63,6 +63,27 @@ AlphaSystem::AlphaSystem(Params *p) pal = createObjectFile(params()->pal); if (pal == NULL) fatal("Could not load PALcode file %s", params()->pal); + + // load symbols + if (!console->loadGlobalSymbols(consoleSymtab)) + panic("could not load console symbols\n"); + + if (!pal->loadGlobalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!pal->loadLocalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!console->loadGlobalSymbols(debugSymbolTable)) + panic("could not load console symbols\n"); + + if (!pal->loadGlobalSymbols(debugSymbolTable)) + panic("could not load pal symbols\n"); + + if (!pal->loadLocalSymbols(debugSymbolTable)) + panic("could not load pal symbols\n"); + + } AlphaSystem::~AlphaSystem() @@ -78,6 +99,8 @@ AlphaSystem::~AlphaSystem() void AlphaSystem::initState() { + Addr addr = 0; + // Moved from the constructor to here since it relies on the // address map being resolved in the interconnect @@ -88,30 +111,6 @@ AlphaSystem::initState() pal->loadSections(physProxy, loadAddrMask); console->loadSections(physProxy, loadAddrMask); - // load symbols - if (!console->loadGlobalSymbols(consoleSymtab)) - panic("could not load console symbols\n"); - - if (!pal->loadGlobalSymbols(palSymtab)) - panic("could not load pal symbols\n"); - - if (!pal->loadLocalSymbols(palSymtab)) - panic("could not load pal symbols\n"); - - if (!console->loadGlobalSymbols(debugSymbolTable)) - panic("could not load console symbols\n"); - - if (!pal->loadGlobalSymbols(debugSymbolTable)) - panic("could not load pal symbols\n"); - - if (!pal->loadLocalSymbols(debugSymbolTable)) - panic("could not load pal symbols\n"); - - Addr addr = 0; -#ifndef NDEBUG - consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic"); -#endif - /** * Copy the osflags (kernel arguments) into the consoles * memory. (Presently Linux does not use the console service @@ -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 } /** diff --git a/src/arch/alpha/system.hh b/src/arch/alpha/system.hh index 0e809cb94..d832dfe77 100644 --- a/src/arch/alpha/system.hh +++ b/src/arch/alpha/system.hh @@ -62,6 +62,10 @@ class AlphaSystem : public System virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + /** 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 * diff --git a/src/arch/arm/linux/system.cc b/src/arch/arm/linux/system.cc index 4e18a265d..64bda4b4d 100644 --- a/src/arch/arm/linux/system.cc +++ b/src/arch/arm/linux/system.cc @@ -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); diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc index 8b85715cb..7fbabafcb 100644 --- a/src/arch/arm/system.cc +++ b/src/arch/arm/system.cc @@ -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() diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc index ab5f7432e..9ce0a90de 100644 --- a/src/arch/sparc/system.cc +++ b/src/arch/sparc/system.cc @@ -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. diff --git a/src/sim/system.cc b/src/sim/system.cc index 36d4447ff..4601d2d52 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -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) |