system.cc revision 2
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 40using namespace std; 41 42vector<System *> System::systemList; 43 44int System::numSystemsRunning = 0; 45 46System::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 163System::~System() 164{ 165 delete kernelSymtab; 166 delete consoleSymtab; 167 delete initRegs; 168} 169 170 171void 172System::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 186void 187System::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 196void 197System::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 208extern "C" 209void 210printSystems() 211{ 212 System::printSystems(); 213} 214 215 216BEGIN_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 226END_DECLARE_SIM_OBJECT_PARAMS(System) 227 228BEGIN_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 238END_INIT_SIM_OBJECT_PARAMS(System) 239 240 241CREATE_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 250REGISTER_SIM_OBJECT("System", System) 251