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 "kernel_loader.hh"
30 #include "exec_context.hh"
31 #include "object_file.hh"
32 #include "memory_control.hh"
33 #include "physical_memory.hh"
35 #include "remote_gdb.hh"
42 vector
<System
*> System::systemList
;
44 int System::numSystemsRunning
= 0;
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
)
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"),
68 kernelSymtab
= new SymbolTable
;
69 consoleSymtab
= new SymbolTable
;
71 EcoffObject
kernel(kernel_path
);
72 EcoffObject
console(console_path
);
74 if (!kernel
.loadGlobals(kernelSymtab
))
75 panic("could not load kernel symbols\n");
77 if (!console
.loadGlobals(consoleSymtab
))
78 panic("could not load console symbols\n");
81 loadPal(palcode
, physmem
, PAL_BASE
);
83 // copy of initial reg file contents
84 initRegs
= new RegFile
;
85 memset(initRegs
, 0, sizeof(RegFile
));
88 loadKernel(console_path
, physmem
);
91 loadKernel(kernel_path
, physmem
, initRegs
,
92 &kernelStart
, &kernelEnd
, &kernelEntry
);
94 DPRINTF(Loader
, "Kernel loaded...\n");
99 for(int i
= 0; i
< 12/*MAX_CPUS*/; i
++)
100 xc_array
[i
] = (ExecContext
*) 0;
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));
109 if (enable_async_printf
)
110 *(uint32_t *)enable_async_printf
= 0;
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));
118 strcpy(osflags
, boot_osflags
.c_str());
121 if (kernelSymtab
->findAddress("panic", addr
))
122 kernel_panic_event
.schedule(addr
);
124 panic("could not find kernel symbol \'panic\'");
126 if (consoleSymtab
->findAddress("panic", addr
))
127 console_panic_event
.schedule(addr
);
129 if (kernelSymtab
->findAddress("badaddr", addr
))
130 badaddr_event
.schedule(addr
);
132 panic("could not find kernel symbol \'badaddr\'");
134 if (kernelSymtab
->findAddress("tl_v48_capture_power_state", addr
))
135 skip_power_state
.schedule(addr
);
137 if (kernelSymtab
->findAddress("pmap_scavenge_boot", addr
))
138 skip_scavenge_boot
.schedule(addr
);
141 if (kernelSymtab
->findAddress("printf", addr
))
142 printf_event
.schedule(addr
);
144 if (kernelSymtab
->findAddress("m5printf", addr
))
145 debug_printf_event
.schedule(addr
);
147 if (kernelSymtab
->findAddress("m5printfr", addr
))
148 debug_printfr_event
.schedule(addr
);
150 if (kernelSymtab
->findAddress("m5_dump_mbuf", addr
))
151 dump_mbuf_event
.schedule(addr
);
156 // add self to global system list
157 systemList
.push_back(this);
166 delete consoleSymtab
;
172 System::initBootContext(ExecContext
*xc
)
174 xc
->regs
= *initRegs
;
176 remoteGDB
= new RemoteGDB(this, xc
);
177 gdbListen
= new GDBListener(remoteGDB
, 7000);
182 TheISA::init(physmem
, &xc
->regs
);
187 System::registerExecContext(ExecContext
*xc
)
189 if (num_cpus
== 12/*MAX_CPUS*/)
190 panic("Too many CPU's\n");
191 xc_array
[xc
->cpu_id
] = xc
;
197 System::printSystems()
199 vector
<System
*>::iterator i
= systemList
.begin();
200 vector
<System
*>::iterator end
= systemList
.end();
201 for (; i
!= end
; ++i
) {
203 cerr
<< "System " << sys
->name() << ": " << hex
<< sys
<< endl
;
212 System::printSystems();
216 BEGIN_DECLARE_SIM_OBJECT_PARAMS(System
)
218 SimObjectParam
<MemoryController
*> mem_ctl
;
219 SimObjectParam
<PhysicalMemory
*> physmem
;
221 Param
<string
> kernel_code
;
222 Param
<string
> console_code
;
223 Param
<string
> pal_code
;
224 Param
<string
> boot_osflags
;
226 END_DECLARE_SIM_OBJECT_PARAMS(System
)
228 BEGIN_INIT_SIM_OBJECT_PARAMS(System
)
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",
238 END_INIT_SIM_OBJECT_PARAMS(System
)
241 CREATE_SIM_OBJECT(System
)
243 System
*sys
= new System(getInstanceName(), mem_ctl
, physmem
,
244 kernel_code
, console_code
, pal_code
,
250 REGISTER_SIM_OBJECT("System", System
)