Merge zizzer:/bk/m5 into isabel.reinhardt.house:/z/stever/bk/m5
[gem5.git] / sim / system.cc
1 /*
2 * Copyright (c) 2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "exec_context.hh"
30 #include "object_file.hh"
31 #include "memory_control.hh"
32 #include "physical_memory.hh"
33 #include "symtab.hh"
34 #include "remote_gdb.hh"
35 #include "vtophys.hh"
36 #include "system.hh"
37 #include "trace.hh"
38
39 using namespace std;
40
41 vector<System *> System::systemList;
42
43 int System::numSystemsRunning = 0;
44
45 System::System(const std::string _name,
46 MemoryController *_memCtrl,
47 PhysicalMemory *_physmem,
48 const std::string &kernel_path,
49 const std::string &console_path,
50 const std::string &palcode,
51 const std::string &boot_osflags)
52 : SimObject(_name),
53 kernel_panic_event(&pcEventQueue, "kernel panic"),
54 console_panic_event(&pcEventQueue, "console panic"),
55 badaddr_event(&pcEventQueue, "badaddr"),
56 skip_power_state(&pcEventQueue, "tl_v48_capture_power_state"),
57 skip_scavenge_boot(&pcEventQueue, "pmap_scavenge_boot"),
58 printf_event(&pcEventQueue, "printf"),
59 debug_printf_event(&pcEventQueue, "debug_printf", false),
60 debug_printfr_event(&pcEventQueue, "debug_printfr", true),
61 dump_mbuf_event(&pcEventQueue, "dump_mbuf"),
62 memCtrl(_memCtrl),
63 physmem(_physmem),
64 remoteGDB(NULL),
65 gdbListen(NULL)
66 {
67 kernelSymtab = new SymbolTable;
68 consoleSymtab = new SymbolTable;
69
70 ObjectFile *kernel = createObjectFile(kernel_path);
71 if (kernel == NULL)
72 fatal("Could not load kernel file %s", kernel_path);
73
74 ObjectFile *console = createObjectFile(console_path);
75 if (console == NULL)
76 fatal("Could not load console file %s", console_path);
77
78 if (!kernel->loadGlobalSymbols(kernelSymtab))
79 panic("could not load kernel symbols\n");
80
81 if (!console->loadGlobalSymbols(consoleSymtab))
82 panic("could not load console symbols\n");
83
84 // Load pal file
85 ObjectFile *pal = createObjectFile(palcode);
86 if (pal == NULL)
87 fatal("Could not load PALcode file %s", palcode);
88 pal->loadSections(physmem, true);
89
90 // copy of initial reg file contents
91 initRegs = new RegFile;
92 memset(initRegs, 0, sizeof(RegFile));
93
94 // Load console file
95 console->loadSections(physmem, true);
96
97 // Load kernel file
98 kernel->loadSections(physmem, true);
99 kernelStart = kernel->textBase();
100 kernelEnd = kernel->bssBase() + kernel->bssSize();
101 kernelEntry = kernel->entryPoint();
102
103 DPRINTF(Loader, "Kernel start = %#x\n"
104 "Kernel end = %#x\n"
105 "Kernel entry = %#x\n",
106 kernelStart, kernelEnd, kernelEntry);
107
108 // Setup kernel boot parameters
109 initRegs->pc = 0x4001;
110 initRegs->npc = initRegs->pc + sizeof(MachInst);
111
112 DPRINTF(Loader, "Kernel loaded...\n");
113
114 #ifdef FULL_SYSTEM
115 Addr addr = 0;
116
117 for(int i = 0; i < 12/*MAX_CPUS*/; i++)
118 xc_array[i] = (ExecContext *) 0;
119
120 num_cpus = 0;
121
122 if (kernelSymtab->findAddress("enable_async_printf", addr)) {
123 Addr paddr = vtophys(physmem, addr);
124 uint8_t *enable_async_printf =
125 physmem->dma_addr(paddr, sizeof(uint32_t));
126
127 if (enable_async_printf)
128 *(uint32_t *)enable_async_printf = 0;
129 }
130
131 if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
132 Addr paddr = vtophys(physmem, addr);
133 char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
134
135 if (osflags)
136 strcpy(osflags, boot_osflags.c_str());
137 }
138
139 if (kernelSymtab->findAddress("panic", addr))
140 kernel_panic_event.schedule(addr);
141 else
142 panic("could not find kernel symbol \'panic\'");
143
144 if (consoleSymtab->findAddress("panic", addr))
145 console_panic_event.schedule(addr);
146
147 if (kernelSymtab->findAddress("badaddr", addr))
148 badaddr_event.schedule(addr);
149 else
150 panic("could not find kernel symbol \'badaddr\'");
151
152 if (kernelSymtab->findAddress("tl_v48_capture_power_state", addr))
153 skip_power_state.schedule(addr);
154
155 if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
156 skip_scavenge_boot.schedule(addr);
157
158 #if TRACING_ON
159 if (kernelSymtab->findAddress("printf", addr))
160 printf_event.schedule(addr);
161
162 if (kernelSymtab->findAddress("m5printf", addr))
163 debug_printf_event.schedule(addr);
164
165 if (kernelSymtab->findAddress("m5printfr", addr))
166 debug_printfr_event.schedule(addr);
167
168 if (kernelSymtab->findAddress("m5_dump_mbuf", addr))
169 dump_mbuf_event.schedule(addr);
170 #endif
171
172 #endif
173
174 // add self to global system list
175 systemList.push_back(this);
176
177 numSystemsRunning++;
178 }
179
180
181 System::~System()
182 {
183 delete kernelSymtab;
184 delete consoleSymtab;
185 delete initRegs;
186 }
187
188
189 void
190 System::initBootContext(ExecContext *xc)
191 {
192 xc->regs = *initRegs;
193
194 remoteGDB = new RemoteGDB(this, xc);
195 gdbListen = new GDBListener(remoteGDB, 7000);
196 gdbListen->listen();
197
198 // Reset the system
199 //
200 TheISA::init(physmem, &xc->regs);
201 }
202
203
204 void
205 System::registerExecContext(ExecContext *xc)
206 {
207 if (num_cpus == 12/*MAX_CPUS*/)
208 panic("Too many CPU's\n");
209 xc_array[xc->cpu_id] = xc;
210 num_cpus++;
211 }
212
213
214 void
215 System::printSystems()
216 {
217 vector<System *>::iterator i = systemList.begin();
218 vector<System *>::iterator end = systemList.end();
219 for (; i != end; ++i) {
220 System *sys = *i;
221 cerr << "System " << sys->name() << ": " << hex << sys << endl;
222 }
223 }
224
225
226 extern "C"
227 void
228 printSystems()
229 {
230 System::printSystems();
231 }
232
233
234 BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
235
236 SimObjectParam<MemoryController *> mem_ctl;
237 SimObjectParam<PhysicalMemory *> physmem;
238
239 Param<string> kernel_code;
240 Param<string> console_code;
241 Param<string> pal_code;
242 Param<string> boot_osflags;
243
244 END_DECLARE_SIM_OBJECT_PARAMS(System)
245
246 BEGIN_INIT_SIM_OBJECT_PARAMS(System)
247
248 INIT_PARAM(mem_ctl, "memory controller"),
249 INIT_PARAM(physmem, "phsyical memory"),
250 INIT_PARAM(kernel_code, "file that contains the kernel code"),
251 INIT_PARAM(console_code, "file that contains the console code"),
252 INIT_PARAM(pal_code, "file that contains palcode"),
253 INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
254 "a")
255
256 END_INIT_SIM_OBJECT_PARAMS(System)
257
258
259 CREATE_SIM_OBJECT(System)
260 {
261 System *sys = new System(getInstanceName(), mem_ctl, physmem,
262 kernel_code, console_code, pal_code,
263 boot_osflags);
264
265 return sys;
266 }
267
268 REGISTER_SIM_OBJECT("System", System)