summaryrefslogtreecommitdiff
path: root/kern/linux
diff options
context:
space:
mode:
Diffstat (limited to 'kern/linux')
-rw-r--r--kern/linux/linux_system.cc266
-rw-r--r--kern/linux/linux_system.hh103
2 files changed, 87 insertions, 282 deletions
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
index dd188ffe0..10641de87 100644
--- a/kern/linux/linux_system.cc
+++ b/kern/linux/linux_system.cc
@@ -35,11 +35,6 @@
* up boot time.
*/
-#include "base/loader/aout_object.hh"
-#include "base/loader/elf_object.hh"
-#include "base/loader/object_file.hh"
-#include "base/loader/symtab.hh"
-#include "base/remote_gdb.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "cpu/base_cpu.hh"
@@ -58,88 +53,15 @@ extern SymbolTable *debugSymbolTable;
using namespace std;
-LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
- MemoryController *_memCtrl, PhysicalMemory *_physmem,
- const string &kernel_path, const string &console_path,
- const string &palcode, const string &boot_osflags,
- const bool _bin, const vector<string> &_binned_fns)
- : System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns),
- bin(_bin), binned_fns(_binned_fns)
+LinuxSystem::LinuxSystem(Params *p)
+ : System(p)
{
- kernelSymtab = new SymbolTable;
- consoleSymtab = new SymbolTable;
-
- /**
- * Load the kernel, pal, and console code into memory
- */
- // Load kernel code
- ObjectFile *kernel = createObjectFile(kernel_path);
- if (kernel == NULL)
- fatal("Could not load kernel file %s", kernel_path);
-
- // Load Console Code
- ObjectFile *console = createObjectFile(console_path);
- if (console == NULL)
- fatal("Could not load console file %s", console_path);
-
- // Load pal file
- ObjectFile *pal = createObjectFile(palcode);
- if (pal == NULL)
- fatal("Could not load PALcode file %s", palcode);
- pal->loadSections(physmem, true);
-
- // Load console file
- console->loadSections(physmem, true);
-
- // Load kernel file
- kernel->loadSections(physmem, true);
- kernelStart = kernel->textBase();
- kernelEnd = kernel->bssBase() + kernel->bssSize();
- kernelEntry = kernel->entryPoint();
-
- // load symbols
- if (!kernel->loadGlobalSymbols(kernelSymtab))
- panic("could not load kernel symbols\n");
- debugSymbolTable = kernelSymtab;
-
- if (!kernel->loadLocalSymbols(kernelSymtab))
- panic("could not load kernel local symbols\n");
-
- if (!console->loadGlobalSymbols(consoleSymtab))
- panic("could not load console symbols\n");
-
- DPRINTF(Loader, "Kernel start = %#x\n"
- "Kernel end = %#x\n"
- "Kernel entry = %#x\n",
- kernelStart, kernelEnd, kernelEntry);
-
- DPRINTF(Loader, "Kernel loaded...\n");
-
-
-#ifdef DEBUG
- kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
- consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
-#endif
-
- skipIdeDelay50msEvent = new SkipFuncEvent(&pcEventQueue,
- "ide_delay_50ms");
-
- skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue,
- "calibrate_delay");
-
- skipCacheProbeEvent = new SkipFuncEvent(&pcEventQueue,
- "determine_cpu_caches");
-
- debugPrintkEvent = new DebugPrintkEvent(&pcEventQueue, "dprintk");
-
- printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo");
-
Addr addr = 0;
/**
- * find the address of the est_cycle_freq variable and insert it so we don't
- * through the lengthly process of trying to calculated it by using the PIT,
- * RTC, etc.
+ * find the address of the est_cycle_freq variable and insert it
+ * so we don't through the lengthly process of trying to
+ * calculated it by using the PIT, RTC, etc.
*/
if (kernelSymtab->findAddress("est_cycle_freq", addr)) {
Addr paddr = vtophys(physmem, addr);
@@ -152,19 +74,6 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
/**
- * Copy the osflags (kernel arguments) into the consoles memory. Presently
- * Linux does use the console service routine to get these command line
- * arguments, but we might as well make them available just in case.
- */
- if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
- Addr paddr = vtophys(physmem, addr);
- char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
-
- if (osflags)
- strcpy(osflags, boot_osflags.c_str());
- }
-
- /**
* Since we aren't using a bootloader, we have to copy the kernel arguments
* directly into the kernels memory.
*/
@@ -172,32 +81,11 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
Addr paddr = vtophys(physmem, PARAM_ADDR);
char *commandline = (char*)physmem->dma_addr(paddr, sizeof(uint64_t));
if (commandline)
- strcpy(commandline, boot_osflags.c_str());
+ strcpy(commandline, params->boot_osflags.c_str());
}
/**
- * Set the hardware reset parameter block system type and revision
- * information to Tsunami.
- */
- if (consoleSymtab->findAddress("xxm_rpb", addr)) {
- Addr paddr = vtophys(physmem, addr);
- char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
-
- if (hwprb) {
- // Tsunami
- *(uint64_t*)(hwprb + 0x50) = htoa(ULL(34));
-
- // Plain DP264
- *(uint64_t*)(hwprb + 0x58) = htoa(ULL(1) << 10);
- }
- else
- panic("could not translate hwprb addr to set system type/variation\n");
-
- } else
- panic("could not find hwprb to set system type/variation\n");
-
- /**
* EV5 only supports 127 ASNs so we are going to tell the kernel that the
* paritiuclar EV6 we have only supports 127 asns.
* @todo At some point we should change ev5.hh and the palcode to support
@@ -210,59 +98,63 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
if (dp264_mv) {
*(uint32_t*)(dp264_mv+0x18) = htoa((uint32_t)127);
} else
- panic("could not translate dp264_mv addr to set the MAX_ASN to 127\n");
+ panic("could not translate dp264_mv addr\n");
} else
- panic("could not find dp264_mv to set the MAX_ASN to 127\n");
-
-
+ panic("could not find dp264_mv\n");
#ifdef DEBUG
+ kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
if (kernelSymtab->findAddress("panic", addr))
kernelPanicEvent->schedule(addr);
else
panic("could not find kernel symbol \'panic\'");
-
- if (consoleSymtab->findAddress("panic", addr))
- consolePanicEvent->schedule(addr);
#endif
/**
- * Any time ide_delay_50ms, calibarte_delay or determine_cpu_caches is called
- * just skip the function. Currently determine_cpu_caches only is used put
- * information in proc, however if that changes in the future we will have to
- * fill in the cache size variables appropriately.
+ * Any time ide_delay_50ms, calibarte_delay or
+ * determine_cpu_caches is called just skip the
+ * function. Currently determine_cpu_caches only is used put
+ * information in proc, however if that changes in the future we
+ * will have to fill in the cache size variables appropriately.
*/
+ skipIdeDelay50msEvent = new SkipFuncEvent(&pcEventQueue, "ide_delay_50ms");
if (kernelSymtab->findAddress("ide_delay_50ms", addr))
skipIdeDelay50msEvent->schedule(addr+sizeof(MachInst));
+ skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue,
+ "calibrate_delay");
if (kernelSymtab->findAddress("calibrate_delay", addr))
skipDelayLoopEvent->schedule(addr+sizeof(MachInst));
+ skipCacheProbeEvent = new SkipFuncEvent(&pcEventQueue,
+ "determine_cpu_caches");
if (kernelSymtab->findAddress("determine_cpu_caches", addr))
skipCacheProbeEvent->schedule(addr+sizeof(MachInst));
+ debugPrintkEvent = new DebugPrintkEvent(&pcEventQueue, "dprintk");
if (kernelSymtab->findAddress("dprintk", addr))
- debugPrintkEvent->schedule(addr+sizeof(MachInst)*2);
+ debugPrintkEvent->schedule(addr+8);
+
+ idleStartEvent = new IdleStartEvent(&pcEventQueue, "cpu_idle", this);
+ if (kernelSymtab->findAddress("cpu_idle", addr))
+ idleStartEvent->schedule(addr);
- if (kernelSymtab->findAddress("alpha_switch_to", addr) &&
- DTRACE(Thread))
- printThreadEvent->schedule(addr+sizeof(MachInst)*6);
+ printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo");
+ if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread))
+ printThreadEvent->schedule(addr + sizeof(MachInst) * 6);
}
LinuxSystem::~LinuxSystem()
{
- delete kernel;
- delete console;
-
- delete kernelSymtab;
- delete consoleSymtab;
-
+#ifdef DEBUG
delete kernelPanicEvent;
- delete consolePanicEvent;
+#endif
delete skipIdeDelay50msEvent;
delete skipDelayLoopEvent;
delete skipCacheProbeEvent;
+ delete debugPrintkEvent;
+ delete idleStartEvent;
}
@@ -283,92 +175,64 @@ LinuxSystem::setDelayLoop(ExecContext *xc)
}
}
-int
-LinuxSystem::registerExecContext(ExecContext *xc)
-{
- int xcIndex = System::registerExecContext(xc);
-
- if (xcIndex == 0) {
- // activate with zero delay so that we start ticking right
- // away on cycle 0
- xc->activate(0);
- }
-
- RemoteGDB *rgdb = new RemoteGDB(this, xc);
- GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
- gdbl->listen();
- /**
- * Uncommenting this line waits for a remote debugger to connect
- * to the simulator before continuing.
- */
- //gdbl->accept();
-
- if (remoteGDB.size() <= xcIndex) {
- remoteGDB.resize(xcIndex+1);
- }
-
- remoteGDB[xcIndex] = rgdb;
-
- return xcIndex;
-}
-
-
-void
-LinuxSystem::replaceExecContext(ExecContext *xc, int xcIndex)
-{
- System::replaceExecContext(xcIndex, xc);
- remoteGDB[xcIndex]->replaceExecContext(xc);
-}
-
-bool
-LinuxSystem::breakpoint()
-{
- return remoteGDB[0]->trap(ALPHA_KENTRY_IF);
-}
-
BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
- Param<bool> bin;
SimObjectParam<MemoryController *> mem_ctl;
SimObjectParam<PhysicalMemory *> physmem;
- Param<uint64_t> init_param;
Param<string> kernel_code;
Param<string> console_code;
Param<string> pal_code;
- Param<string> boot_osflags;
- VectorParam<string> binned_fns;
+ Param<string> boot_osflags;
Param<string> readfile;
+ Param<unsigned int> init_param;
+
+ Param<uint64_t> system_type;
+ Param<uint64_t> system_rev;
+
+ Param<bool> bin;
+ VectorParam<string> binned_fns;
END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
-
- INIT_PARAM_DFLT(bin, "is this system to be binned", false),
INIT_PARAM(mem_ctl, "memory controller"),
INIT_PARAM(physmem, "phsyical memory"),
- INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
- INIT_PARAM(kernel_code, "file that contains the code"),
+ INIT_PARAM(kernel_code, "file that contains the kernel code"),
INIT_PARAM(console_code, "file that contains the console code"),
INIT_PARAM(pal_code, "file that contains palcode"),
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
- "a"),
- INIT_PARAM(binned_fns, "functions to be broken down and binned"),
- INIT_PARAM_DFLT(readfile, "file to read startup script from", "")
-
+ "a"),
+ INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
+ INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
+ 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")
END_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
CREATE_SIM_OBJECT(LinuxSystem)
{
- LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl,
- physmem, kernel_code, console_code,
- pal_code, boot_osflags, bin, binned_fns);
-
- sys->readfile = readfile;
- return sys;
+ System::Params *p = new System::Params;
+ p->name = getInstanceName();
+ p->memctrl = mem_ctl;
+ p->physmem = physmem;
+ p->kernel_path = kernel_code;
+ p->console_path = console_code;
+ p->palcode = pal_code;
+ p->boot_osflags = boot_osflags;
+ p->init_param = init_param;
+ p->readfile = readfile;
+ p->system_type = system_type;
+ p->system_rev = system_rev;
+ p->bin = bin;
+ p->binned_fns = binned_fns;
+
+ return new LinuxSystem(p);
}
REGISTER_SIM_OBJECT("LinuxSystem", LinuxSystem)
+
diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh
index fbfcb788f..707204607 100644
--- a/kern/linux/linux_system.hh
+++ b/kern/linux/linux_system.hh
@@ -26,32 +26,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __LINUX_SYSTEM_HH__
-#define __LINUX_SYSTEM_HH__
+#ifndef __KERN_LINUX_LINUX_SYSTEM_HH__
+#define __KERN_LINUX_LINUX_SYSTEM_HH__
-#include <vector>
-
-#include "sim/system.hh"
#include "sim/host.hh"
+#include "sim/system.hh"
#include "targetarch/isa_traits.hh"
-#include <map>
-
/**
* MAGIC address where the kernel arguments should go. Defined as
* PARAM in linux kernel alpha-asm.
*/
-const Addr PARAM_ADDR = ULL(0xfffffc000030a000);
+const Addr PARAM_ADDR = ULL(0xfffffc000030a000);
class ExecContext;
-class ElfObject;
-class SymbolTable;
+
+class BreakPCEvent;
class DebugPrintkEvent;
class BreakPCEvent;
class LinuxSkipDelayLoopEvent;
class SkipFuncEvent;
-class FnEvent;
-class AlphaArguments;
+class IdleStartEvent;
class PrintThreadInfo;
/**
@@ -62,96 +57,42 @@ class PrintThreadInfo;
class LinuxSystem : public System
{
private:
- /** Object pointer for the kernel code */
- ElfObject *kernel;
-
- /** Object pointer for the console code */
- ElfObject *console;
-
- /** kernel Symbol table */
- SymbolTable *kernelSymtab;
-
- /** console symbol table */
- SymbolTable *consoleSymtab;
-
+#ifdef DEBUG
/** Event to halt the simulator if the kernel calls panic() */
BreakPCEvent *kernelPanicEvent;
+#endif
- /** Event to halt the simulator if the console calls panic() */
- BreakPCEvent *consolePanicEvent;
-
- /** Event to skip determine_cpu_caches() because we don't support the
- * IPRs that the code can access to figure out cache sizes
+ /**
+ * Event to skip determine_cpu_caches() because we don't support
+ * the IPRs that the code can access to figure out cache sizes
*/
SkipFuncEvent *skipCacheProbeEvent;
/** PC based event to skip the ide_delay_50ms() call */
SkipFuncEvent *skipIdeDelay50msEvent;
- /** PC based event to skip the dprink() call and emulate its functionality */
+ /**
+ * PC based event to skip the dprink() call and emulate its
+ * functionality
+ */
DebugPrintkEvent *debugPrintkEvent;
- /** Skip calculate_delay_loop() rather than waiting for this to be
+ /**
+ * Skip calculate_delay_loop() rather than waiting for this to be
* calculated
*/
LinuxSkipDelayLoopEvent *skipDelayLoopEvent;
PrintThreadInfo *printThreadEvent;
- /** Begining of kernel code */
- Addr kernelStart;
-
- /** End of kernel code */
- Addr kernelEnd;
-
- /** Entry point in the kernel to start at */
- Addr kernelEntry;
-
- bool bin;
- std::vector<string> binned_fns;
+ /** Grab the PCBB of the idle process when it starts */
+ IdleStartEvent *idleStartEvent;
public:
- std::vector<RemoteGDB *> remoteGDB;
- std::vector<GDBListener *> gdbListen;
-
- LinuxSystem(const std::string _name,
- const uint64_t _init_param,
- MemoryController *_memCtrl,
- PhysicalMemory *_physmem,
- const std::string &kernel_path,
- const std::string &console_path,
- const std::string &palcode,
- const std::string &boot_osflags,
- const bool _bin,
- const std::vector<std::string> &_binned_fns);
-
+ LinuxSystem(Params *p);
~LinuxSystem();
void setDelayLoop(ExecContext *xc);
-
- int registerExecContext(ExecContext *xc);
- void replaceExecContext(ExecContext *xc, int xcIndex);
-
- /**
- * Returns the addess the kernel starts at.
- * @return address the kernel starts at
- */
- Addr getKernelStart() const { return kernelStart; }
-
- /**
- * Returns the addess the kernel ends at.
- * @return address the kernel ends at
- */
- Addr getKernelEnd() const { return kernelEnd; }
-
- /**
- * Returns the addess the entry point to the kernel code.
- * @return entry point of the kernel code
- */
- Addr getKernelEntry() const { return kernelEntry; }
-
-
- bool breakpoint();
};
-#endif // __LINUX_SYSTEM_HH__
+#endif // __KERN_LINUX_LINUX_SYSTEM_HH__