2 * Copyright (c) 2003 The Regents of The University of Michigan
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.
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.
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"
41 vector
<System
*> System::systemList
;
43 int System::numSystemsRunning
= 0;
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
)
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"),
67 kernelSymtab
= new SymbolTable
;
68 consoleSymtab
= new SymbolTable
;
70 ObjectFile
*kernel
= createObjectFile(kernel_path
);
72 fatal("Could not load kernel file %s", kernel_path
);
74 ObjectFile
*console
= createObjectFile(console_path
);
76 fatal("Could not load console file %s", console_path
);
78 if (!kernel
->loadGlobalSymbols(kernelSymtab
))
79 panic("could not load kernel symbols\n");
81 if (!console
->loadGlobalSymbols(consoleSymtab
))
82 panic("could not load console symbols\n");
85 ObjectFile
*pal
= createObjectFile(palcode
);
87 fatal("Could not load PALcode file %s", palcode
);
88 pal
->loadSections(physmem
, true);
90 // copy of initial reg file contents
91 initRegs
= new RegFile
;
92 memset(initRegs
, 0, sizeof(RegFile
));
95 console
->loadSections(physmem
, true);
98 kernel
->loadSections(physmem
, true);
99 kernelStart
= kernel
->textBase();
100 kernelEnd
= kernel
->bssBase() + kernel
->bssSize();
101 kernelEntry
= kernel
->entryPoint();
103 DPRINTF(Loader
, "Kernel start = %#x\n"
105 "Kernel entry = %#x\n",
106 kernelStart
, kernelEnd
, kernelEntry
);
108 // Setup kernel boot parameters
109 initRegs
->pc
= 0x4001;
110 initRegs
->npc
= initRegs
->pc
+ sizeof(MachInst
);
112 DPRINTF(Loader
, "Kernel loaded...\n");
117 for(int i
= 0; i
< 12/*MAX_CPUS*/; i
++)
118 xc_array
[i
] = (ExecContext
*) 0;
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));
127 if (enable_async_printf
)
128 *(uint32_t *)enable_async_printf
= 0;
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));
136 strcpy(osflags
, boot_osflags
.c_str());
139 if (kernelSymtab
->findAddress("panic", addr
))
140 kernel_panic_event
.schedule(addr
);
142 panic("could not find kernel symbol \'panic\'");
144 if (consoleSymtab
->findAddress("panic", addr
))
145 console_panic_event
.schedule(addr
);
147 if (kernelSymtab
->findAddress("badaddr", addr
))
148 badaddr_event
.schedule(addr
);
150 panic("could not find kernel symbol \'badaddr\'");
152 if (kernelSymtab
->findAddress("tl_v48_capture_power_state", addr
))
153 skip_power_state
.schedule(addr
);
155 if (kernelSymtab
->findAddress("pmap_scavenge_boot", addr
))
156 skip_scavenge_boot
.schedule(addr
);
159 if (kernelSymtab
->findAddress("printf", addr
))
160 printf_event
.schedule(addr
);
162 if (kernelSymtab
->findAddress("m5printf", addr
))
163 debug_printf_event
.schedule(addr
);
165 if (kernelSymtab
->findAddress("m5printfr", addr
))
166 debug_printfr_event
.schedule(addr
);
168 if (kernelSymtab
->findAddress("m5_dump_mbuf", addr
))
169 dump_mbuf_event
.schedule(addr
);
174 // add self to global system list
175 systemList
.push_back(this);
184 delete consoleSymtab
;
190 System::initBootContext(ExecContext
*xc
)
192 xc
->regs
= *initRegs
;
194 remoteGDB
= new RemoteGDB(this, xc
);
195 gdbListen
= new GDBListener(remoteGDB
, 7000);
200 TheISA::init(physmem
, &xc
->regs
);
205 System::registerExecContext(ExecContext
*xc
)
207 if (num_cpus
== 12/*MAX_CPUS*/)
208 panic("Too many CPU's\n");
209 xc_array
[xc
->cpu_id
] = xc
;
215 System::printSystems()
217 vector
<System
*>::iterator i
= systemList
.begin();
218 vector
<System
*>::iterator end
= systemList
.end();
219 for (; i
!= end
; ++i
) {
221 cerr
<< "System " << sys
->name() << ": " << hex
<< sys
<< endl
;
230 System::printSystems();
234 BEGIN_DECLARE_SIM_OBJECT_PARAMS(System
)
236 SimObjectParam
<MemoryController
*> mem_ctl
;
237 SimObjectParam
<PhysicalMemory
*> physmem
;
239 Param
<string
> kernel_code
;
240 Param
<string
> console_code
;
241 Param
<string
> pal_code
;
242 Param
<string
> boot_osflags
;
244 END_DECLARE_SIM_OBJECT_PARAMS(System
)
246 BEGIN_INIT_SIM_OBJECT_PARAMS(System
)
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",
256 END_INIT_SIM_OBJECT_PARAMS(System
)
259 CREATE_SIM_OBJECT(System
)
261 System
*sys
= new System(getInstanceName(), mem_ctl
, physmem
,
262 kernel_code
, console_code
, pal_code
,
268 REGISTER_SIM_OBJECT("System", System
)