Import changeset
[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 "kernel_loader.hh"
30 #include "exec_context.hh"
31 #include "object_file.hh"
32 #include "memory_control.hh"
33 #include "physical_memory.hh"
34 #include "symtab.hh"
35 #include "remote_gdb.hh"
36 #include "vtophys.hh"
37 #include "system.hh"
38 #include "trace.hh"
39
40 using namespace std;
41
42 vector<System *> System::systemList;
43
44 int System::numSystemsRunning = 0;
45
46 System::System(const std::string _name,
47 MemoryController *_memCtrl,
48 PhysicalMemory *_physmem,
49 const std::string &kernel_path,
50 const std::string &console_path,
51 const std::string &palcode,
52 const std::string &boot_osflags)
53 : SimObject(_name),
54 kernel_panic_event(&pcEventQueue, "kernel panic"),
55 console_panic_event(&pcEventQueue, "console panic"),
56 badaddr_event(&pcEventQueue, "badaddr"),
57 skip_power_state(&pcEventQueue, "tl_v48_capture_power_state"),
58 skip_scavenge_boot(&pcEventQueue, "pmap_scavenge_boot"),
59 printf_event(&pcEventQueue, "printf"),
60 debug_printf_event(&pcEventQueue, "debug_printf", false),
61 debug_printfr_event(&pcEventQueue, "debug_printfr", true),
62 dump_mbuf_event(&pcEventQueue, "dump_mbuf"),
63 memCtrl(_memCtrl),
64 physmem(_physmem),
65 remoteGDB(NULL),
66 gdbListen(NULL)
67 {
68 kernelSymtab = new SymbolTable;
69 consoleSymtab = new SymbolTable;
70
71 EcoffObject kernel(kernel_path);
72 EcoffObject console(console_path);
73
74 if (!kernel.loadGlobals(kernelSymtab))
75 panic("could not load kernel symbols\n");
76
77 if (!console.loadGlobals(consoleSymtab))
78 panic("could not load console symbols\n");
79
80 // Load pal file
81 loadPal(palcode, physmem, PAL_BASE);
82
83 // copy of initial reg file contents
84 initRegs = new RegFile;
85 memset(initRegs, 0, sizeof(RegFile));
86
87 // Load console file
88 loadKernel(console_path, physmem);
89
90 // Load kernel file
91 loadKernel(kernel_path, physmem, initRegs,
92 &kernelStart, &kernelEnd, &kernelEntry);
93
94 DPRINTF(Loader, "Kernel loaded...\n");
95
96 #ifdef FULL_SYSTEM
97 Addr addr = 0;
98
99 for(int i = 0; i < 12/*MAX_CPUS*/; i++)
100 xc_array[i] = (ExecContext *) 0;
101
102 num_cpus = 0;
103
104 if (kernelSymtab->findAddress("enable_async_printf", addr)) {
105 Addr paddr = vtophys(physmem, addr);
106 uint8_t *enable_async_printf =
107 physmem->dma_addr(paddr, sizeof(uint32_t));
108
109 if (enable_async_printf)
110 *(uint32_t *)enable_async_printf = 0;
111 }
112
113 if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
114 Addr paddr = vtophys(physmem, addr);
115 char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
116
117 if (osflags)
118 strcpy(osflags, boot_osflags.c_str());
119 }
120
121 if (kernelSymtab->findAddress("panic", addr))
122 kernel_panic_event.schedule(addr);
123 else
124 panic("could not find kernel symbol \'panic\'");
125
126 if (consoleSymtab->findAddress("panic", addr))
127 console_panic_event.schedule(addr);
128
129 if (kernelSymtab->findAddress("badaddr", addr))
130 badaddr_event.schedule(addr);
131 else
132 panic("could not find kernel symbol \'badaddr\'");
133
134 if (kernelSymtab->findAddress("tl_v48_capture_power_state", addr))
135 skip_power_state.schedule(addr);
136
137 if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
138 skip_scavenge_boot.schedule(addr);
139
140 #if TRACING_ON
141 if (kernelSymtab->findAddress("printf", addr))
142 printf_event.schedule(addr);
143
144 if (kernelSymtab->findAddress("m5printf", addr))
145 debug_printf_event.schedule(addr);
146
147 if (kernelSymtab->findAddress("m5printfr", addr))
148 debug_printfr_event.schedule(addr);
149
150 if (kernelSymtab->findAddress("m5_dump_mbuf", addr))
151 dump_mbuf_event.schedule(addr);
152 #endif
153
154 #endif
155
156 // add self to global system list
157 systemList.push_back(this);
158
159 numSystemsRunning++;
160 }
161
162
163 System::~System()
164 {
165 delete kernelSymtab;
166 delete consoleSymtab;
167 delete initRegs;
168 }
169
170
171 void
172 System::initBootContext(ExecContext *xc)
173 {
174 xc->regs = *initRegs;
175
176 remoteGDB = new RemoteGDB(this, xc);
177 gdbListen = new GDBListener(remoteGDB, 7000);
178 gdbListen->listen();
179
180 // Reset the system
181 //
182 TheISA::init(physmem, &xc->regs);
183 }
184
185
186 void
187 System::registerExecContext(ExecContext *xc)
188 {
189 if (num_cpus == 12/*MAX_CPUS*/)
190 panic("Too many CPU's\n");
191 xc_array[xc->cpu_id] = xc;
192 num_cpus++;
193 }
194
195
196 void
197 System::printSystems()
198 {
199 vector<System *>::iterator i = systemList.begin();
200 vector<System *>::iterator end = systemList.end();
201 for (; i != end; ++i) {
202 System *sys = *i;
203 cerr << "System " << sys->name() << ": " << hex << sys << endl;
204 }
205 }
206
207
208 extern "C"
209 void
210 printSystems()
211 {
212 System::printSystems();
213 }
214
215
216 BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
217
218 SimObjectParam<MemoryController *> mem_ctl;
219 SimObjectParam<PhysicalMemory *> physmem;
220
221 Param<string> kernel_code;
222 Param<string> console_code;
223 Param<string> pal_code;
224 Param<string> boot_osflags;
225
226 END_DECLARE_SIM_OBJECT_PARAMS(System)
227
228 BEGIN_INIT_SIM_OBJECT_PARAMS(System)
229
230 INIT_PARAM(mem_ctl, "memory controller"),
231 INIT_PARAM(physmem, "phsyical memory"),
232 INIT_PARAM(kernel_code, "file that contains the kernel code"),
233 INIT_PARAM(console_code, "file that contains the console code"),
234 INIT_PARAM(pal_code, "file that contains palcode"),
235 INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
236 "a")
237
238 END_INIT_SIM_OBJECT_PARAMS(System)
239
240
241 CREATE_SIM_OBJECT(System)
242 {
243 System *sys = new System(getInstanceName(), mem_ctl, physmem,
244 kernel_code, console_code, pal_code,
245 boot_osflags);
246
247 return sys;
248 }
249
250 REGISTER_SIM_OBJECT("System", System)