system.cc revision 2520
1#include "base/loader/object_file.hh"
2#include "base/loader/symtab.hh"
3#include "cpu/exec_context.hh"
4#include "sim/builder.hh"
5#include "arch/isa_traits.hh"
6#include "sim/byteswap.hh"
7#include "sim/system.hh"
8#include "base/trace.hh"
9#include "mem/mem_object.hh"
10#if FULL_SYSTEM
11#include "base/remote_gdb.hh"
12#include "kern/kernel_stats.hh"
13#include "arch/vtophys.hh"
14#endif
15
16using namespace std;
17using namespace TheISA;
18
19vector<System *> System::systemList;
20
21int System::numSystemsRunning = 0;
22
23System::System(Params *p)
24    : SimObject(p->name), physmem(p->physmem), numcpus(0),
25#if FULL_SYSTEM
26      memctrl(p->memctrl), init_param(p->init_param),
27#else
28      page_ptr(0),
29#endif
30      _params(p)
31{
32    // add self to global system list
33    systemList.push_back(this);
34
35#if FULL_SYSTEM
36    kernelSymtab = new SymbolTable;
37    debugSymbolTable = new SymbolTable;
38
39
40    /**
41     * Get a functional port to memory
42     */
43    Port *mem_port;
44    mem_port = physmem->getPort("functional");
45    functionalPort.setPeer(mem_port);
46    mem_port->setPeer(&functionalPort);
47
48
49    /**
50     * Load the kernel code into memory
51     */
52    // Load kernel code
53    kernel = createObjectFile(params()->kernel_path);
54    if (kernel == NULL)
55        fatal("Could not load kernel file %s", params()->kernel_path);
56
57    // Load program sections into memory
58    kernel->loadSections(&functionalPort, LoadAddrMask);
59
60    // setup entry points
61    kernelStart = kernel->textBase();
62    kernelEnd = kernel->bssBase() + kernel->bssSize();
63    kernelEntry = kernel->entryPoint();
64
65    // load symbols
66    if (!kernel->loadGlobalSymbols(kernelSymtab))
67        panic("could not load kernel symbols\n");
68
69    if (!kernel->loadLocalSymbols(kernelSymtab))
70        panic("could not load kernel local symbols\n");
71
72    if (!kernel->loadGlobalSymbols(debugSymbolTable))
73        panic("could not load kernel symbols\n");
74
75    if (!kernel->loadLocalSymbols(debugSymbolTable))
76        panic("could not load kernel local symbols\n");
77
78    DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
79    DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
80    DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
81    DPRINTF(Loader, "Kernel loaded...\n");
82
83    kernelBinning = new Kernel::Binning(this);
84#endif // FULL_SYSTEM
85
86    // increment the number of running systms
87    numSystemsRunning++;
88}
89
90System::~System()
91{
92#if FULL_SYSTEM
93    delete kernelSymtab;
94    delete kernel;
95
96    delete kernelBinning;
97#else
98    panic("System::fixFuncEventAddr needs to be rewritten "
99          "to work with syscall emulation");
100#endif // FULL_SYSTEM}
101}
102
103#if FULL_SYSTEM
104
105
106int rgdb_wait = -1;
107
108#endif // FULL_SYSTEM
109
110int
111System::registerExecContext(ExecContext *xc, int id)
112{
113    if (id == -1) {
114        for (id = 0; id < execContexts.size(); id++) {
115            if (!execContexts[id])
116                break;
117        }
118    }
119
120    if (execContexts.size() <= id)
121        execContexts.resize(id + 1);
122
123    if (execContexts[id])
124        panic("Cannot have two CPUs with the same id (%d)\n", id);
125
126    execContexts[id] = xc;
127    numcpus++;
128
129#if FULL_SYSTEM
130    RemoteGDB *rgdb = new RemoteGDB(this, xc);
131    GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
132    gdbl->listen();
133    /**
134     * Uncommenting this line waits for a remote debugger to connect
135     * to the simulator before continuing.
136     */
137    if (rgdb_wait != -1 && rgdb_wait == id)
138        gdbl->accept();
139
140    if (remoteGDB.size() <= id) {
141        remoteGDB.resize(id + 1);
142    }
143
144    remoteGDB[id] = rgdb;
145#endif // FULL_SYSTEM
146
147    return id;
148}
149
150void
151System::startup()
152{
153    int i;
154    for (i = 0; i < execContexts.size(); i++)
155        execContexts[i]->activate(0);
156}
157
158void
159System::replaceExecContext(ExecContext *xc, int id)
160{
161    if (id >= execContexts.size()) {
162        panic("replaceExecContext: bad id, %d >= %d\n",
163              id, execContexts.size());
164    }
165
166    execContexts[id] = xc;
167#if FULL_SYSTEM
168    remoteGDB[id]->replaceExecContext(xc);
169#endif // FULL_SYSTEM
170}
171
172#if !FULL_SYSTEM
173Addr
174System::new_page()
175{
176    Addr return_addr = page_ptr << LogVMPageSize;
177    ++page_ptr;
178    return return_addr;
179}
180#endif
181
182void
183System::regStats()
184{
185#if FULL_SYSTEM
186    kernelBinning->regStats(name() + ".kern");
187#endif // FULL_SYSTEM
188}
189
190void
191System::serialize(ostream &os)
192{
193#if FULL_SYSTEM
194    kernelBinning->serialize(os);
195
196    kernelSymtab->serialize("kernel_symtab", os);
197#endif // FULL_SYSTEM
198}
199
200
201void
202System::unserialize(Checkpoint *cp, const string &section)
203{
204#if FULL_SYSTEM
205    kernelBinning->unserialize(cp, section);
206
207    kernelSymtab->unserialize("kernel_symtab", cp, section);
208#endif // FULL_SYSTEM
209}
210
211void
212System::printSystems()
213{
214    vector<System *>::iterator i = systemList.begin();
215    vector<System *>::iterator end = systemList.end();
216    for (; i != end; ++i) {
217        System *sys = *i;
218        cerr << "System " << sys->name() << ": " << hex << sys << endl;
219    }
220}
221
222extern "C"
223void
224printSystems()
225{
226    System::printSystems();
227}
228
229#if FULL_SYSTEM
230
231// In full system mode, only derived classes (e.g. AlphaLinuxSystem)
232// can be created directly.
233
234DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
235
236#else
237
238BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
239
240    SimObjectParam<MemObject *> physmem;
241
242END_DECLARE_SIM_OBJECT_PARAMS(System)
243
244BEGIN_INIT_SIM_OBJECT_PARAMS(System)
245
246    INIT_PARAM(physmem, "physical memory")
247
248END_INIT_SIM_OBJECT_PARAMS(System)
249
250CREATE_SIM_OBJECT(System)
251{
252    System::Params *p = new System::Params;
253    p->name = getInstanceName();
254    p->physmem = physmem;
255    return new System(p);
256}
257
258REGISTER_SIM_OBJECT("System", System)
259
260#endif
261