system.cc revision 2632:1bb2f91485ea
110447Snilay@cs.wisc.edu#include "arch/isa_traits.hh"
210447Snilay@cs.wisc.edu#include "base/loader/object_file.hh"
310447Snilay@cs.wisc.edu#include "base/loader/symtab.hh"
410447Snilay@cs.wisc.edu#include "base/trace.hh"
510447Snilay@cs.wisc.edu#include "cpu/exec_context.hh"
610447Snilay@cs.wisc.edu#include "mem/mem_object.hh"
710447Snilay@cs.wisc.edu#include "mem/physical.hh"
810447Snilay@cs.wisc.edu#include "sim/builder.hh"
910447Snilay@cs.wisc.edu#include "sim/byteswap.hh"
1010447Snilay@cs.wisc.edu#include "sim/system.hh"
1110447Snilay@cs.wisc.edu#if FULL_SYSTEM
1210447Snilay@cs.wisc.edu#include "arch/vtophys.hh"
1310447Snilay@cs.wisc.edu#include "base/remote_gdb.hh"
1410447Snilay@cs.wisc.edu#include "kern/kernel_stats.hh"
1510447Snilay@cs.wisc.edu#endif
1610447Snilay@cs.wisc.edu
1710447Snilay@cs.wisc.eduusing namespace std;
1810447Snilay@cs.wisc.eduusing namespace TheISA;
1910447Snilay@cs.wisc.edu
2010447Snilay@cs.wisc.eduvector<System *> System::systemList;
2110447Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.eduint System::numSystemsRunning = 0;
2310447Snilay@cs.wisc.edu
2410447Snilay@cs.wisc.eduSystem::System(Params *p)
2510447Snilay@cs.wisc.edu    : SimObject(p->name), physmem(p->physmem), numcpus(0),
2610447Snilay@cs.wisc.edu#if FULL_SYSTEM
2710447Snilay@cs.wisc.edu      init_param(p->init_param),
2810447Snilay@cs.wisc.edu#else
2910447Snilay@cs.wisc.edu      page_ptr(0),
3010447Snilay@cs.wisc.edu#endif
3110447Snilay@cs.wisc.edu      _params(p)
3210447Snilay@cs.wisc.edu{
3310447Snilay@cs.wisc.edu    // add self to global system list
3410447Snilay@cs.wisc.edu    systemList.push_back(this);
3510447Snilay@cs.wisc.edu
3610447Snilay@cs.wisc.edu#if FULL_SYSTEM
3710447Snilay@cs.wisc.edu    kernelSymtab = new SymbolTable;
3810447Snilay@cs.wisc.edu    debugSymbolTable = new SymbolTable;
3910447Snilay@cs.wisc.edu
4010447Snilay@cs.wisc.edu
4110447Snilay@cs.wisc.edu    /**
4210447Snilay@cs.wisc.edu     * Get a functional port to memory
4310447Snilay@cs.wisc.edu     */
4410447Snilay@cs.wisc.edu    Port *mem_port;
4510447Snilay@cs.wisc.edu    mem_port = physmem->getPort("functional");
4610447Snilay@cs.wisc.edu    functionalPort.setPeer(mem_port);
4710447Snilay@cs.wisc.edu    mem_port->setPeer(&functionalPort);
4810447Snilay@cs.wisc.edu
4910447Snilay@cs.wisc.edu    mem_port = physmem->getPort("functional");
5010447Snilay@cs.wisc.edu    virtPort.setPeer(mem_port);
5110447Snilay@cs.wisc.edu    mem_port->setPeer(&virtPort);
5210447Snilay@cs.wisc.edu
5310447Snilay@cs.wisc.edu
5410447Snilay@cs.wisc.edu    /**
5510447Snilay@cs.wisc.edu     * Load the kernel code into memory
5610447Snilay@cs.wisc.edu     */
5710447Snilay@cs.wisc.edu    // Load kernel code
5810447Snilay@cs.wisc.edu    kernel = createObjectFile(params()->kernel_path);
5910447Snilay@cs.wisc.edu    if (kernel == NULL)
6010447Snilay@cs.wisc.edu        fatal("Could not load kernel file %s", params()->kernel_path);
6110447Snilay@cs.wisc.edu
6210447Snilay@cs.wisc.edu    // Load program sections into memory
63    kernel->loadSections(&functionalPort, LoadAddrMask);
64
65    // setup entry points
66    kernelStart = kernel->textBase();
67    kernelEnd = kernel->bssBase() + kernel->bssSize();
68    kernelEntry = kernel->entryPoint();
69
70    // load symbols
71    if (!kernel->loadGlobalSymbols(kernelSymtab))
72        panic("could not load kernel symbols\n");
73
74    if (!kernel->loadLocalSymbols(kernelSymtab))
75        panic("could not load kernel local symbols\n");
76
77    if (!kernel->loadGlobalSymbols(debugSymbolTable))
78        panic("could not load kernel symbols\n");
79
80    if (!kernel->loadLocalSymbols(debugSymbolTable))
81        panic("could not load kernel local symbols\n");
82
83    DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
84    DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
85    DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
86    DPRINTF(Loader, "Kernel loaded...\n");
87
88    kernelBinning = new Kernel::Binning(this);
89#endif // FULL_SYSTEM
90
91    // increment the number of running systms
92    numSystemsRunning++;
93}
94
95System::~System()
96{
97#if FULL_SYSTEM
98    delete kernelSymtab;
99    delete kernel;
100
101    delete kernelBinning;
102#else
103    panic("System::fixFuncEventAddr needs to be rewritten "
104          "to work with syscall emulation");
105#endif // FULL_SYSTEM}
106}
107
108#if FULL_SYSTEM
109
110
111int rgdb_wait = -1;
112
113#endif // FULL_SYSTEM
114
115int
116System::registerExecContext(ExecContext *xc, int id)
117{
118    if (id == -1) {
119        for (id = 0; id < execContexts.size(); id++) {
120            if (!execContexts[id])
121                break;
122        }
123    }
124
125    if (execContexts.size() <= id)
126        execContexts.resize(id + 1);
127
128    if (execContexts[id])
129        panic("Cannot have two CPUs with the same id (%d)\n", id);
130
131    execContexts[id] = xc;
132    numcpus++;
133
134#if FULL_SYSTEM
135    RemoteGDB *rgdb = new RemoteGDB(this, xc);
136    GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
137    gdbl->listen();
138    /**
139     * Uncommenting this line waits for a remote debugger to connect
140     * to the simulator before continuing.
141     */
142    if (rgdb_wait != -1 && rgdb_wait == id)
143        gdbl->accept();
144
145    if (remoteGDB.size() <= id) {
146        remoteGDB.resize(id + 1);
147    }
148
149    remoteGDB[id] = rgdb;
150#endif // FULL_SYSTEM
151
152    return id;
153}
154
155void
156System::startup()
157{
158    int i;
159    for (i = 0; i < execContexts.size(); i++)
160        execContexts[i]->activate(0);
161}
162
163void
164System::replaceExecContext(ExecContext *xc, int id)
165{
166    if (id >= execContexts.size()) {
167        panic("replaceExecContext: bad id, %d >= %d\n",
168              id, execContexts.size());
169    }
170
171    execContexts[id] = xc;
172#if FULL_SYSTEM
173    remoteGDB[id]->replaceExecContext(xc);
174#endif // FULL_SYSTEM
175}
176
177#if !FULL_SYSTEM
178Addr
179System::new_page()
180{
181    Addr return_addr = page_ptr << LogVMPageSize;
182    ++page_ptr;
183    return return_addr;
184}
185#endif
186
187void
188System::regStats()
189{
190#if FULL_SYSTEM
191    kernelBinning->regStats(name() + ".kern");
192#endif // FULL_SYSTEM
193}
194
195void
196System::serialize(ostream &os)
197{
198#if FULL_SYSTEM
199    kernelBinning->serialize(os);
200
201    kernelSymtab->serialize("kernel_symtab", os);
202#endif // FULL_SYSTEM
203}
204
205
206void
207System::unserialize(Checkpoint *cp, const string &section)
208{
209#if FULL_SYSTEM
210    kernelBinning->unserialize(cp, section);
211
212    kernelSymtab->unserialize("kernel_symtab", cp, section);
213#endif // FULL_SYSTEM
214}
215
216void
217System::printSystems()
218{
219    vector<System *>::iterator i = systemList.begin();
220    vector<System *>::iterator end = systemList.end();
221    for (; i != end; ++i) {
222        System *sys = *i;
223        cerr << "System " << sys->name() << ": " << hex << sys << endl;
224    }
225}
226
227extern "C"
228void
229printSystems()
230{
231    System::printSystems();
232}
233
234#if FULL_SYSTEM
235
236// In full system mode, only derived classes (e.g. AlphaLinuxSystem)
237// can be created directly.
238
239DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
240
241#else
242
243BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
244
245    SimObjectParam<PhysicalMemory *> physmem;
246
247END_DECLARE_SIM_OBJECT_PARAMS(System)
248
249BEGIN_INIT_SIM_OBJECT_PARAMS(System)
250
251    INIT_PARAM(physmem, "physical memory")
252
253END_INIT_SIM_OBJECT_PARAMS(System)
254
255CREATE_SIM_OBJECT(System)
256{
257    System::Params *p = new System::Params;
258    p->name = getInstanceName();
259    p->physmem = physmem;
260    return new System(p);
261}
262
263REGISTER_SIM_OBJECT("System", System)
264
265#endif
266