system.cc revision 56
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 "cpu/exec_context.hh"
30#include "base/loader/object_file.hh"
31#include "mem/functional_mem/memory_control.hh"
32#include "mem/functional_mem/physical_memory.hh"
33#include "base/loader/symtab.hh"
34#include "base/remote_gdb.hh"
35#include "targetarch/vtophys.hh"
36#include "sim/system.hh"
37#include "base/trace.hh"
38
39using namespace std;
40
41vector<System *> System::systemList;
42
43int System::numSystemsRunning = 0;
44
45System::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
181System::~System()
182{
183    delete kernelSymtab;
184    delete consoleSymtab;
185    delete initRegs;
186}
187
188
189void
190System::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
204void
205System::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
214void
215System::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
226extern "C"
227void
228printSystems()
229{
230    System::printSystems();
231}
232
233
234BEGIN_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
244END_DECLARE_SIM_OBJECT_PARAMS(System)
245
246BEGIN_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
256END_INIT_SIM_OBJECT_PARAMS(System)
257
258
259CREATE_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
268REGISTER_SIM_OBJECT("System", System)
269