backdoor.cc revision 1805
1/* 2 * Copyright (c) 2001-2005 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/** @file 30 * Alpha Console Definition 31 */ 32 33#include <cstddef> 34#include <cstdio> 35#include <string> 36 37#include "base/inifile.hh" 38#include "base/str.hh" 39#include "base/trace.hh" 40#include "cpu/base.hh" 41#include "cpu/exec_context.hh" 42#include "dev/alpha_console.hh" 43#include "dev/simconsole.hh" 44#include "dev/simple_disk.hh" 45#include "dev/tsunami_io.hh" 46#include "mem/bus/bus.hh" 47#include "mem/bus/pio_interface.hh" 48#include "mem/bus/pio_interface_impl.hh" 49#include "mem/functional/memory_control.hh" 50#include "mem/functional/physical.hh" 51#include "sim/builder.hh" 52#include "sim/sim_object.hh" 53#include "sim/system.hh" 54 55using namespace std; 56 57AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, 58 System *s, BaseCPU *c, Platform *p, 59 int num_cpus, MemoryController *mmu, Addr a, 60 HierParams *hier, Bus *bus) 61 : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a) 62{ 63 mmu->add_child(this, RangeSize(addr, size)); 64 65 if (bus) { 66 pioInterface = newPioInterface(name, hier, bus, this, 67 &AlphaConsole::cacheAccess); 68 pioInterface->addAddrRange(RangeSize(addr, size)); 69 } 70 71 alphaAccess = new Access; 72 alphaAccess->last_offset = size - 1; 73 74 alphaAccess->version = ALPHA_ACCESS_VERSION; 75 alphaAccess->numCPUs = num_cpus; 76 alphaAccess->diskUnit = 1; 77 78 alphaAccess->diskCount = 0; 79 alphaAccess->diskPAddr = 0; 80 alphaAccess->diskBlock = 0; 81 alphaAccess->diskOperation = 0; 82 alphaAccess->outputChar = 0; 83 alphaAccess->inputChar = 0; 84 alphaAccess->bootStrapImpure = 0; 85 alphaAccess->bootStrapCPU = 0; 86 alphaAccess->align2 = 0; 87 88 system->setAlphaAccess(addr); 89} 90 91void 92AlphaConsole::init() 93{ 94 alphaAccess->kernStart = system->getKernelStart(); 95 alphaAccess->kernEnd = system->getKernelEnd(); 96 alphaAccess->entryPoint = system->getKernelEntry(); 97 alphaAccess->mem_size = system->physmem->size(); 98 alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz 99 alphaAccess->intrClockFrequency = platform->intrFrequency(); 100} 101 102Fault 103AlphaConsole::read(MemReqPtr &req, uint8_t *data) 104{ 105 memset(data, 0, req->size); 106 107 Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); 108 109 switch (req->size) 110 { 111 case sizeof(uint32_t): 112 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 113 *(uint32_t*)data); 114 switch (daddr) 115 { 116 case offsetof(AlphaAccess, last_offset): 117 *(uint32_t*)data = alphaAccess->last_offset; 118 break; 119 case offsetof(AlphaAccess, version): 120 *(uint32_t*)data = alphaAccess->version; 121 break; 122 case offsetof(AlphaAccess, numCPUs): 123 *(uint32_t*)data = alphaAccess->numCPUs; 124 break; 125 case offsetof(AlphaAccess, bootStrapCPU): 126 *(uint32_t*)data = alphaAccess->bootStrapCPU; 127 break; 128 case offsetof(AlphaAccess, intrClockFrequency): 129 *(uint32_t*)data = alphaAccess->intrClockFrequency; 130 break; 131 default: 132 // Old console code read in everyting as a 32bit int 133 *(uint32_t*)data = *(uint32_t*)(consoleData + daddr); 134 135 } 136 break; 137 case sizeof(uint64_t): 138 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 139 *(uint64_t*)data); 140 switch (daddr) 141 { 142 case offsetof(AlphaAccess, inputChar): 143 *(uint64_t*)data = console->console_in(); 144 break; 145 case offsetof(AlphaAccess, cpuClock): 146 *(uint64_t*)data = alphaAccess->cpuClock; 147 break; 148 case offsetof(AlphaAccess, mem_size): 149 *(uint64_t*)data = alphaAccess->mem_size; 150 break; 151 case offsetof(AlphaAccess, kernStart): 152 *(uint64_t*)data = alphaAccess->kernStart; 153 break; 154 case offsetof(AlphaAccess, kernEnd): 155 *(uint64_t*)data = alphaAccess->kernEnd; 156 break; 157 case offsetof(AlphaAccess, entryPoint): 158 *(uint64_t*)data = alphaAccess->entryPoint; 159 break; 160 case offsetof(AlphaAccess, diskUnit): 161 *(uint64_t*)data = alphaAccess->diskUnit; 162 break; 163 case offsetof(AlphaAccess, diskCount): 164 *(uint64_t*)data = alphaAccess->diskCount; 165 break; 166 case offsetof(AlphaAccess, diskPAddr): 167 *(uint64_t*)data = alphaAccess->diskPAddr; 168 break; 169 case offsetof(AlphaAccess, diskBlock): 170 *(uint64_t*)data = alphaAccess->diskBlock; 171 break; 172 case offsetof(AlphaAccess, diskOperation): 173 *(uint64_t*)data = alphaAccess->diskOperation; 174 break; 175 case offsetof(AlphaAccess, outputChar): 176 *(uint64_t*)data = alphaAccess->outputChar; 177 break; 178 case offsetof(AlphaAccess, bootStrapImpure): 179 *(uint64_t*)data = alphaAccess->bootStrapImpure; 180 break; 181 default: 182 panic("Unknown 64bit access, %#x\n", daddr); 183 } 184 break; 185 default: 186 return Machine_Check_Fault; 187 } 188 189 return No_Fault; 190} 191 192Fault 193AlphaConsole::write(MemReqPtr &req, const uint8_t *data) 194{ 195 uint64_t val; 196 197 switch (req->size) { 198 case sizeof(uint32_t): 199 val = *(uint32_t *)data; 200 break; 201 202 case sizeof(uint64_t): 203 val = *(uint64_t *)data; 204 break; 205 default: 206 return Machine_Check_Fault; 207 } 208 209 Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); 210 ExecContext *other_xc; 211 212 switch (daddr) { 213 case offsetof(AlphaAccess, diskUnit): 214 alphaAccess->diskUnit = val; 215 break; 216 217 case offsetof(AlphaAccess, diskCount): 218 alphaAccess->diskCount = val; 219 break; 220 221 case offsetof(AlphaAccess, diskPAddr): 222 alphaAccess->diskPAddr = val; 223 break; 224 225 case offsetof(AlphaAccess, diskBlock): 226 alphaAccess->diskBlock = val; 227 break; 228 229 case offsetof(AlphaAccess, diskOperation): 230 if (val == 0x13) 231 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 232 alphaAccess->diskCount); 233 else 234 panic("Invalid disk operation!"); 235 236 break; 237 238 case offsetof(AlphaAccess, outputChar): 239 console->out((char)(val & 0xff)); 240 break; 241 242 case offsetof(AlphaAccess, bootStrapImpure): 243 alphaAccess->bootStrapImpure = val; 244 break; 245 246 case offsetof(AlphaAccess, bootStrapCPU): 247 warn("%d: Trying to launch another CPU!", curTick); 248 assert(val > 0 && "Must not access primary cpu"); 249 250 other_xc = req->xc->system->execContexts[val]; 251 other_xc->regs.intRegFile[16] = val; 252 other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val; 253 other_xc->regs.intRegFile[0] = val; 254 other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure; 255 other_xc->activate(); //Start the cpu 256 break; 257 258 default: 259 return Machine_Check_Fault; 260 } 261 262 return No_Fault; 263} 264 265Tick 266AlphaConsole::cacheAccess(MemReqPtr &req) 267{ 268 return curTick + 1000; 269} 270 271void 272AlphaConsole::Access::serialize(ostream &os) 273{ 274 SERIALIZE_SCALAR(last_offset); 275 SERIALIZE_SCALAR(version); 276 SERIALIZE_SCALAR(numCPUs); 277 SERIALIZE_SCALAR(mem_size); 278 SERIALIZE_SCALAR(cpuClock); 279 SERIALIZE_SCALAR(intrClockFrequency); 280 SERIALIZE_SCALAR(kernStart); 281 SERIALIZE_SCALAR(kernEnd); 282 SERIALIZE_SCALAR(entryPoint); 283 SERIALIZE_SCALAR(diskUnit); 284 SERIALIZE_SCALAR(diskCount); 285 SERIALIZE_SCALAR(diskPAddr); 286 SERIALIZE_SCALAR(diskBlock); 287 SERIALIZE_SCALAR(diskOperation); 288 SERIALIZE_SCALAR(outputChar); 289 SERIALIZE_SCALAR(inputChar); 290 SERIALIZE_SCALAR(bootStrapImpure); 291 SERIALIZE_SCALAR(bootStrapCPU); 292} 293 294void 295AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) 296{ 297 UNSERIALIZE_SCALAR(last_offset); 298 UNSERIALIZE_SCALAR(version); 299 UNSERIALIZE_SCALAR(numCPUs); 300 UNSERIALIZE_SCALAR(mem_size); 301 UNSERIALIZE_SCALAR(cpuClock); 302 UNSERIALIZE_SCALAR(intrClockFrequency); 303 UNSERIALIZE_SCALAR(kernStart); 304 UNSERIALIZE_SCALAR(kernEnd); 305 UNSERIALIZE_SCALAR(entryPoint); 306 UNSERIALIZE_SCALAR(diskUnit); 307 UNSERIALIZE_SCALAR(diskCount); 308 UNSERIALIZE_SCALAR(diskPAddr); 309 UNSERIALIZE_SCALAR(diskBlock); 310 UNSERIALIZE_SCALAR(diskOperation); 311 UNSERIALIZE_SCALAR(outputChar); 312 UNSERIALIZE_SCALAR(inputChar); 313 UNSERIALIZE_SCALAR(bootStrapImpure); 314 UNSERIALIZE_SCALAR(bootStrapCPU); 315} 316 317void 318AlphaConsole::serialize(ostream &os) 319{ 320 alphaAccess->serialize(os); 321} 322 323void 324AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) 325{ 326 alphaAccess->unserialize(cp, section); 327} 328 329BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 330 331 SimObjectParam<SimConsole *> sim_console; 332 SimObjectParam<SimpleDisk *> disk; 333 Param<int> num_cpus; 334 SimObjectParam<MemoryController *> mmu; 335 Param<Addr> addr; 336 SimObjectParam<System *> system; 337 SimObjectParam<BaseCPU *> cpu; 338 SimObjectParam<Platform *> platform; 339 SimObjectParam<Bus*> io_bus; 340 Param<Tick> pio_latency; 341 SimObjectParam<HierParams *> hier; 342 343END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 344 345BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 346 347 INIT_PARAM(sim_console, "The Simulator Console"), 348 INIT_PARAM(disk, "Simple Disk"), 349 INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1), 350 INIT_PARAM(mmu, "Memory Controller"), 351 INIT_PARAM(addr, "Device Address"), 352 INIT_PARAM(system, "system object"), 353 INIT_PARAM(cpu, "Processor"), 354 INIT_PARAM(platform, "platform"), 355 INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), 356 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), 357 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) 358 359END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 360 361CREATE_SIM_OBJECT(AlphaConsole) 362{ 363 return new AlphaConsole(getInstanceName(), sim_console, disk, 364 system, cpu, platform, num_cpus, mmu, 365 addr, hier, io_bus); 366} 367 368REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) 369