backdoor.cc revision 2107
12391SN/A/* 22391SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 32391SN/A * All rights reserved. 42391SN/A * 52391SN/A * Redistribution and use in source and binary forms, with or without 62391SN/A * modification, are permitted provided that the following conditions are 72391SN/A * met: redistributions of source code must retain the above copyright 82391SN/A * notice, this list of conditions and the following disclaimer; 92391SN/A * redistributions in binary form must reproduce the above copyright 102391SN/A * notice, this list of conditions and the following disclaimer in the 112391SN/A * documentation and/or other materials provided with the distribution; 122391SN/A * neither the name of the copyright holders nor the names of its 132391SN/A * contributors may be used to endorse or promote products derived from 142391SN/A * this software without specific prior written permission. 152391SN/A * 162391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272391SN/A */ 282391SN/A 292391SN/A/** @file 302391SN/A * Alpha Console Definition 312391SN/A */ 322391SN/A 332391SN/A#include <cstddef> 342391SN/A#include <cstdio> 352391SN/A#include <string> 362462SN/A 372414SN/A#include "base/inifile.hh" 382415SN/A#include "base/str.hh" 392415SN/A#include "base/trace.hh" 402416SN/A#include "cpu/base.hh" 412416SN/A#include "cpu/exec_context.hh" 422462SN/A#include "dev/alpha_console.hh" 432391SN/A#include "dev/simconsole.hh" 442391SN/A#include "dev/simple_disk.hh" 452391SN/A#include "dev/tsunami_io.hh" 462462SN/A#include "mem/bus/bus.hh" 472391SN/A#include "mem/bus/pio_interface.hh" 482413SN/A#include "mem/bus/pio_interface_impl.hh" 492413SN/A#include "mem/functional/memory_control.hh" 502413SN/A#include "mem/functional/physical.hh" 512413SN/A#include "sim/builder.hh" 522413SN/A#include "sim/sim_object.hh" 532413SN/A#include "sim/system.hh" 542640Sstever@eecs.umich.edu 552413SN/Ausing namespace std; 562413SN/Ausing namespace AlphaISA; 572413SN/A 582630SN/AAlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, 592413SN/A System *s, BaseCPU *c, Platform *p, 602630SN/A MemoryController *mmu, Addr a, 612413SN/A HierParams *hier, Bus *pio_bus) 622630SN/A : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a) 632413SN/A{ 642413SN/A mmu->add_child(this, RangeSize(addr, size)); 652413SN/A 662521SN/A if (pio_bus) { 672521SN/A pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, 682413SN/A &AlphaConsole::cacheAccess); 692413SN/A pioInterface->addAddrRange(RangeSize(addr, size)); 702413SN/A } 712413SN/A 722416SN/A alphaAccess = new Access; 732416SN/A alphaAccess->last_offset = size - 1; 742413SN/A 752415SN/A alphaAccess->version = ALPHA_ACCESS_VERSION; 762415SN/A alphaAccess->diskUnit = 1; 772630SN/A 782415SN/A alphaAccess->diskCount = 0; 792415SN/A alphaAccess->diskPAddr = 0; 802630SN/A alphaAccess->diskBlock = 0; 812415SN/A alphaAccess->diskOperation = 0; 822415SN/A alphaAccess->outputChar = 0; 832415SN/A alphaAccess->inputChar = 0; 842413SN/A alphaAccess->bootStrapImpure = 0; 852391SN/A alphaAccess->bootStrapCPU = 0; 862391SN/A alphaAccess->align2 = 0; 872391SN/A 882391SN/A system->setAlphaAccess(addr); 892391SN/A} 902391SN/A 912391SN/Avoid 922391SN/AAlphaConsole::startup() 932391SN/A{ 942499SN/A alphaAccess->numCPUs = system->getNumCPUs(); 952391SN/A alphaAccess->kernStart = system->getKernelStart(); 962565SN/A alphaAccess->kernEnd = system->getKernelEnd(); 972391SN/A alphaAccess->entryPoint = system->getKernelEntry(); 982391SN/A alphaAccess->mem_size = system->physmem->size(); 992391SN/A alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz 1002391SN/A alphaAccess->intrClockFrequency = platform->intrFrequency(); 1012391SN/A} 1022391SN/A 1032565SN/AFault * 1042391SN/AAlphaConsole::read(MemReqPtr &req, uint8_t *data) 1052391SN/A{ 1062391SN/A memset(data, 0, req->size); 1072415SN/A 1082521SN/A Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); 1092521SN/A 1102541SN/A switch (req->size) 1112391SN/A { 1122391SN/A case sizeof(uint32_t): 1132414SN/A DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 1142413SN/A *(uint32_t*)data); 1152630SN/A switch (daddr) 1162630SN/A { 1172630SN/A case offsetof(AlphaAccess, last_offset): 1182413SN/A *(uint32_t*)data = alphaAccess->last_offset; 1192413SN/A break; 1202391SN/A case offsetof(AlphaAccess, version): 1212391SN/A *(uint32_t*)data = alphaAccess->version; 1222391SN/A break; 1232391SN/A case offsetof(AlphaAccess, numCPUs): 1242497SN/A *(uint32_t*)data = alphaAccess->numCPUs; 1252391SN/A break; 1262391SN/A case offsetof(AlphaAccess, bootStrapCPU): 1272391SN/A *(uint32_t*)data = alphaAccess->bootStrapCPU; 128 break; 129 case offsetof(AlphaAccess, intrClockFrequency): 130 *(uint32_t*)data = alphaAccess->intrClockFrequency; 131 break; 132 default: 133 // Old console code read in everyting as a 32bit int 134 *(uint32_t*)data = *(uint32_t*)(consoleData + daddr); 135 136 } 137 break; 138 case sizeof(uint64_t): 139 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 140 *(uint64_t*)data); 141 switch (daddr) 142 { 143 case offsetof(AlphaAccess, inputChar): 144 *(uint64_t*)data = console->console_in(); 145 break; 146 case offsetof(AlphaAccess, cpuClock): 147 *(uint64_t*)data = alphaAccess->cpuClock; 148 break; 149 case offsetof(AlphaAccess, mem_size): 150 *(uint64_t*)data = alphaAccess->mem_size; 151 break; 152 case offsetof(AlphaAccess, kernStart): 153 *(uint64_t*)data = alphaAccess->kernStart; 154 break; 155 case offsetof(AlphaAccess, kernEnd): 156 *(uint64_t*)data = alphaAccess->kernEnd; 157 break; 158 case offsetof(AlphaAccess, entryPoint): 159 *(uint64_t*)data = alphaAccess->entryPoint; 160 break; 161 case offsetof(AlphaAccess, diskUnit): 162 *(uint64_t*)data = alphaAccess->diskUnit; 163 break; 164 case offsetof(AlphaAccess, diskCount): 165 *(uint64_t*)data = alphaAccess->diskCount; 166 break; 167 case offsetof(AlphaAccess, diskPAddr): 168 *(uint64_t*)data = alphaAccess->diskPAddr; 169 break; 170 case offsetof(AlphaAccess, diskBlock): 171 *(uint64_t*)data = alphaAccess->diskBlock; 172 break; 173 case offsetof(AlphaAccess, diskOperation): 174 *(uint64_t*)data = alphaAccess->diskOperation; 175 break; 176 case offsetof(AlphaAccess, outputChar): 177 *(uint64_t*)data = alphaAccess->outputChar; 178 break; 179 case offsetof(AlphaAccess, bootStrapImpure): 180 *(uint64_t*)data = alphaAccess->bootStrapImpure; 181 break; 182 default: 183 panic("Unknown 64bit access, %#x\n", daddr); 184 } 185 break; 186 default: 187 return MachineCheckFault; 188 } 189 190 return NoFault; 191} 192 193Fault * 194AlphaConsole::write(MemReqPtr &req, const uint8_t *data) 195{ 196 uint64_t val; 197 198 switch (req->size) { 199 case sizeof(uint32_t): 200 val = *(uint32_t *)data; 201 break; 202 203 case sizeof(uint64_t): 204 val = *(uint64_t *)data; 205 break; 206 default: 207 return MachineCheckFault; 208 } 209 210 Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); 211 ExecContext *other_xc; 212 213 switch (daddr) { 214 case offsetof(AlphaAccess, diskUnit): 215 alphaAccess->diskUnit = val; 216 break; 217 218 case offsetof(AlphaAccess, diskCount): 219 alphaAccess->diskCount = val; 220 break; 221 222 case offsetof(AlphaAccess, diskPAddr): 223 alphaAccess->diskPAddr = val; 224 break; 225 226 case offsetof(AlphaAccess, diskBlock): 227 alphaAccess->diskBlock = val; 228 break; 229 230 case offsetof(AlphaAccess, diskOperation): 231 if (val == 0x13) 232 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 233 alphaAccess->diskCount); 234 else 235 panic("Invalid disk operation!"); 236 237 break; 238 239 case offsetof(AlphaAccess, outputChar): 240 console->out((char)(val & 0xff)); 241 break; 242 243 case offsetof(AlphaAccess, bootStrapImpure): 244 alphaAccess->bootStrapImpure = val; 245 break; 246 247 case offsetof(AlphaAccess, bootStrapCPU): 248 warn("%d: Trying to launch another CPU!", curTick); 249 assert(val > 0 && "Must not access primary cpu"); 250 251 other_xc = req->xc->system->execContexts[val]; 252 other_xc->regs.intRegFile[16] = val; 253 other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val; 254 other_xc->regs.intRegFile[0] = val; 255 other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure; 256 other_xc->activate(); //Start the cpu 257 break; 258 259 default: 260 return MachineCheckFault; 261 } 262 263 return NoFault; 264} 265 266Tick 267AlphaConsole::cacheAccess(MemReqPtr &req) 268{ 269 return curTick + 1000; 270} 271 272void 273AlphaConsole::Access::serialize(ostream &os) 274{ 275 SERIALIZE_SCALAR(last_offset); 276 SERIALIZE_SCALAR(version); 277 SERIALIZE_SCALAR(numCPUs); 278 SERIALIZE_SCALAR(mem_size); 279 SERIALIZE_SCALAR(cpuClock); 280 SERIALIZE_SCALAR(intrClockFrequency); 281 SERIALIZE_SCALAR(kernStart); 282 SERIALIZE_SCALAR(kernEnd); 283 SERIALIZE_SCALAR(entryPoint); 284 SERIALIZE_SCALAR(diskUnit); 285 SERIALIZE_SCALAR(diskCount); 286 SERIALIZE_SCALAR(diskPAddr); 287 SERIALIZE_SCALAR(diskBlock); 288 SERIALIZE_SCALAR(diskOperation); 289 SERIALIZE_SCALAR(outputChar); 290 SERIALIZE_SCALAR(inputChar); 291 SERIALIZE_SCALAR(bootStrapImpure); 292 SERIALIZE_SCALAR(bootStrapCPU); 293} 294 295void 296AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) 297{ 298 UNSERIALIZE_SCALAR(last_offset); 299 UNSERIALIZE_SCALAR(version); 300 UNSERIALIZE_SCALAR(numCPUs); 301 UNSERIALIZE_SCALAR(mem_size); 302 UNSERIALIZE_SCALAR(cpuClock); 303 UNSERIALIZE_SCALAR(intrClockFrequency); 304 UNSERIALIZE_SCALAR(kernStart); 305 UNSERIALIZE_SCALAR(kernEnd); 306 UNSERIALIZE_SCALAR(entryPoint); 307 UNSERIALIZE_SCALAR(diskUnit); 308 UNSERIALIZE_SCALAR(diskCount); 309 UNSERIALIZE_SCALAR(diskPAddr); 310 UNSERIALIZE_SCALAR(diskBlock); 311 UNSERIALIZE_SCALAR(diskOperation); 312 UNSERIALIZE_SCALAR(outputChar); 313 UNSERIALIZE_SCALAR(inputChar); 314 UNSERIALIZE_SCALAR(bootStrapImpure); 315 UNSERIALIZE_SCALAR(bootStrapCPU); 316} 317 318void 319AlphaConsole::serialize(ostream &os) 320{ 321 alphaAccess->serialize(os); 322} 323 324void 325AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) 326{ 327 alphaAccess->unserialize(cp, section); 328} 329 330BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 331 332 SimObjectParam<SimConsole *> sim_console; 333 SimObjectParam<SimpleDisk *> disk; 334 SimObjectParam<MemoryController *> mmu; 335 Param<Addr> addr; 336 SimObjectParam<System *> system; 337 SimObjectParam<BaseCPU *> cpu; 338 SimObjectParam<Platform *> platform; 339 SimObjectParam<Bus*> pio_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(mmu, "Memory Controller"), 350 INIT_PARAM(addr, "Device Address"), 351 INIT_PARAM(system, "system object"), 352 INIT_PARAM(cpu, "Processor"), 353 INIT_PARAM(platform, "platform"), 354 INIT_PARAM(pio_bus, "The IO Bus to attach to"), 355 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), 356 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) 357 358END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 359 360CREATE_SIM_OBJECT(AlphaConsole) 361{ 362 return new AlphaConsole(getInstanceName(), sim_console, disk, 363 system, cpu, platform, mmu, addr, hier, pio_bus); 364} 365 366REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) 367