system.cc revision 2158
1#include "base/loader/object_file.hh"
2#include "base/loader/symtab.hh"
3#include "base/remote_gdb.hh"
4#include "cpu/exec_context.hh"
5#include "kern/kernel_stats.hh"
6#include "mem/functional/memory_control.hh"
7#include "mem/functional/physical.hh"
8#include "targetarch/vtophys.hh"
9#include "sim/builder.hh"
10#include "arch/isa_traits.hh"
11#include "sim/byteswap.hh"
12#include "sim/system.hh"
13#include "base/trace.hh"
14
15using namespace std;
16using namespace TheISA;
17
18vector<System *> System::systemList;
19
20int System::numSystemsRunning = 0;
21
22System::System(Params *p)
23    : SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
24      init_param(p->init_param), numcpus(0), _params(p)
25{
26    // add self to global system list
27    systemList.push_back(this);
28
29    kernelSymtab = new SymbolTable;
30    debugSymbolTable = new SymbolTable;
31
32    /**
33     * Load the kernel code into memory
34     */
35    // Load kernel code
36    kernel = createObjectFile(params()->kernel_path);
37    if (kernel == NULL)
38        fatal("Could not load kernel file %s", params()->kernel_path);
39
40    // Load program sections into memory
41    kernel->loadSections(physmem, true);
42
43    // setup entry points
44    kernelStart = kernel->textBase();
45    kernelEnd = kernel->bssBase() + kernel->bssSize();
46    kernelEntry = kernel->entryPoint();
47
48    // load symbols
49    if (!kernel->loadGlobalSymbols(kernelSymtab))
50        panic("could not load kernel symbols\n");
51
52    if (!kernel->loadLocalSymbols(kernelSymtab))
53        panic("could not load kernel local symbols\n");
54
55    if (!kernel->loadGlobalSymbols(debugSymbolTable))
56        panic("could not load kernel symbols\n");
57
58    if (!kernel->loadLocalSymbols(debugSymbolTable))
59        panic("could not load kernel local symbols\n");
60
61    DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
62    DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
63    DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
64    DPRINTF(Loader, "Kernel loaded...\n");
65
66    // increment the number of running systms
67    numSystemsRunning++;
68
69    kernelBinning = new Kernel::Binning(this);
70}
71
72System::~System()
73{
74    delete kernelSymtab;
75    delete kernel;
76
77    delete kernelBinning;
78}
79
80
81
82
83int rgdb_wait = -1;
84
85int
86System::registerExecContext(ExecContext *xc, int id)
87{
88    if (id == -1) {
89        for (id = 0; id < execContexts.size(); id++) {
90            if (!execContexts[id])
91                break;
92        }
93    }
94
95    if (execContexts.size() <= id)
96        execContexts.resize(id + 1);
97
98    if (execContexts[id])
99        panic("Cannot have two CPUs with the same id (%d)\n", id);
100
101    execContexts[id] = xc;
102    numcpus++;
103
104    RemoteGDB *rgdb = new RemoteGDB(this, xc);
105    GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
106    gdbl->listen();
107    /**
108     * Uncommenting this line waits for a remote debugger to connect
109     * to the simulator before continuing.
110     */
111    if (rgdb_wait != -1 && rgdb_wait == id)
112        gdbl->accept();
113
114    if (remoteGDB.size() <= id) {
115        remoteGDB.resize(id + 1);
116    }
117
118    remoteGDB[id] = rgdb;
119
120    return id;
121}
122
123void
124System::startup()
125{
126    int i;
127    for (i = 0; i < execContexts.size(); i++)
128        execContexts[i]->activate(0);
129}
130
131void
132System::replaceExecContext(ExecContext *xc, int id)
133{
134    if (id >= execContexts.size()) {
135        panic("replaceExecContext: bad id, %d >= %d\n",
136              id, execContexts.size());
137    }
138
139    execContexts[id] = xc;
140    remoteGDB[id]->replaceExecContext(xc);
141}
142
143void
144System::regStats()
145{
146    kernelBinning->regStats(name() + ".kern");
147}
148
149void
150System::serialize(ostream &os)
151{
152    kernelBinning->serialize(os);
153
154    kernelSymtab->serialize("kernel_symtab", os);
155}
156
157
158void
159System::unserialize(Checkpoint *cp, const string &section)
160{
161    kernelBinning->unserialize(cp, section);
162
163    kernelSymtab->unserialize("kernel_symtab", cp, section);
164}
165
166void
167System::printSystems()
168{
169    vector<System *>::iterator i = systemList.begin();
170    vector<System *>::iterator end = systemList.end();
171    for (; i != end; ++i) {
172        System *sys = *i;
173        cerr << "System " << sys->name() << ": " << hex << sys << endl;
174    }
175}
176
177extern "C"
178void
179printSystems()
180{
181    System::printSystems();
182}
183
184DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
185
186