system.cc revision 75
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    if (kernelSymtab->findAddress("enable_async_printf", addr)) {
118        Addr paddr = vtophys(physmem, addr);
119        uint8_t *enable_async_printf =
120            physmem->dma_addr(paddr, sizeof(uint32_t));
121
122        if (enable_async_printf)
123            *(uint32_t *)enable_async_printf = 0;
124    }
125
126    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
127        Addr paddr = vtophys(physmem, addr);
128        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
129
130        if (osflags)
131            strcpy(osflags, boot_osflags.c_str());
132    }
133
134    if (kernelSymtab->findAddress("panic", addr))
135        kernel_panic_event.schedule(addr);
136    else
137        panic("could not find kernel symbol \'panic\'");
138
139    if (consoleSymtab->findAddress("panic", addr))
140        console_panic_event.schedule(addr);
141
142    if (kernelSymtab->findAddress("badaddr", addr))
143        badaddr_event.schedule(addr);
144    else
145        panic("could not find kernel symbol \'badaddr\'");
146
147    if (kernelSymtab->findAddress("tl_v48_capture_power_state", addr))
148        skip_power_state.schedule(addr);
149
150    if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
151        skip_scavenge_boot.schedule(addr);
152
153#if TRACING_ON
154    if (kernelSymtab->findAddress("printf", addr))
155        printf_event.schedule(addr);
156
157    if (kernelSymtab->findAddress("m5printf", addr))
158        debug_printf_event.schedule(addr);
159
160    if (kernelSymtab->findAddress("m5printfr", addr))
161        debug_printfr_event.schedule(addr);
162
163    if (kernelSymtab->findAddress("m5_dump_mbuf", addr))
164        dump_mbuf_event.schedule(addr);
165#endif
166
167#endif
168
169    // add self to global system list
170    systemList.push_back(this);
171
172    numSystemsRunning++;
173}
174
175
176System::~System()
177{
178    delete kernelSymtab;
179    delete consoleSymtab;
180    delete initRegs;
181}
182
183
184void
185System::initBootContext(ExecContext *xc)
186{
187    xc->regs = *initRegs;
188
189    remoteGDB = new RemoteGDB(this, xc);
190    gdbListen = new GDBListener(remoteGDB, 7000);
191    gdbListen->listen();
192
193    // Reset the system
194    //
195    TheISA::init(physmem, &xc->regs);
196}
197
198
199void
200System::registerExecContext(ExecContext *xc)
201{
202    if (xc->cpu_id >= 12/*MAX_CPUS*/)
203        panic("Too many CPU's\n");
204
205    if (xc->cpu_id >= xcvec.size())
206        xcvec.resize(xc->cpu_id + 1);
207
208    xcvec[xc->cpu_id] = xc;
209}
210
211
212void
213System::printSystems()
214{
215    vector<System *>::iterator i = systemList.begin();
216    vector<System *>::iterator end = systemList.end();
217    for (; i != end; ++i) {
218        System *sys = *i;
219        cerr << "System " << sys->name() << ": " << hex << sys << endl;
220    }
221}
222
223
224extern "C"
225void
226printSystems()
227{
228    System::printSystems();
229}
230
231
232BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
233
234    SimObjectParam<MemoryController *> mem_ctl;
235    SimObjectParam<PhysicalMemory *> physmem;
236
237    Param<string> kernel_code;
238    Param<string> console_code;
239    Param<string> pal_code;
240    Param<string> boot_osflags;
241
242END_DECLARE_SIM_OBJECT_PARAMS(System)
243
244BEGIN_INIT_SIM_OBJECT_PARAMS(System)
245
246    INIT_PARAM(mem_ctl, "memory controller"),
247    INIT_PARAM(physmem, "phsyical memory"),
248    INIT_PARAM(kernel_code, "file that contains the kernel code"),
249    INIT_PARAM(console_code, "file that contains the console code"),
250    INIT_PARAM(pal_code, "file that contains palcode"),
251    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
252                    "a")
253
254END_INIT_SIM_OBJECT_PARAMS(System)
255
256
257CREATE_SIM_OBJECT(System)
258{
259    System *sys = new System(getInstanceName(), mem_ctl, physmem,
260                             kernel_code, console_code, pal_code,
261                             boot_osflags);
262
263    return sys;
264}
265
266REGISTER_SIM_OBJECT("System", System)
267