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