backdoor.cc revision 2630
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 <string> 35 36#include "arch/alpha/system.hh" 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/platform.hh" 44#include "dev/simconsole.hh" 45#include "dev/simple_disk.hh" 46#include "mem/physical.hh" 47#include "sim/builder.hh" 48#include "sim/sim_object.hh" 49 50using namespace std; 51using namespace AlphaISA; 52 53AlphaConsole::AlphaConsole(Params *p) 54 : BasicPioDevice(p), disk(p->disk), 55 console(params()->cons), system(params()->alpha_sys), cpu(params()->cpu) 56{ 57 58 pioSize = sizeof(struct AlphaAccess); 59 60 alphaAccess = new Access(); 61 alphaAccess->last_offset = pioSize - 1; 62 63 alphaAccess->version = ALPHA_ACCESS_VERSION; 64 alphaAccess->diskUnit = 1; 65 66 alphaAccess->diskCount = 0; 67 alphaAccess->diskPAddr = 0; 68 alphaAccess->diskBlock = 0; 69 alphaAccess->diskOperation = 0; 70 alphaAccess->outputChar = 0; 71 alphaAccess->inputChar = 0; 72 bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); 73 74} 75 76void 77AlphaConsole::startup() 78{ 79 system->setAlphaAccess(pioAddr); 80 alphaAccess->numCPUs = system->getNumCPUs(); 81 alphaAccess->kernStart = system->getKernelStart(); 82 alphaAccess->kernEnd = system->getKernelEnd(); 83 alphaAccess->entryPoint = system->getKernelEntry(); 84 alphaAccess->mem_size = system->physmem->size(); 85 alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz 86 alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); 87} 88 89Tick 90AlphaConsole::read(Packet *pkt) 91{ 92 93 /** XXX Do we want to push the addr munging to a bus brige or something? So 94 * the device has it's physical address and then the bridge adds on whatever 95 * machine dependent address swizzle is required? 96 */ 97 98 assert(pkt->result == Unknown); 99 assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); 100 101 pkt->time += pioDelay; 102 Addr daddr = pkt->addr - pioAddr; 103 104 pkt->allocate(); 105 106 switch (pkt->size) 107 { 108 case sizeof(uint32_t): 109 switch (daddr) 110 { 111 case offsetof(AlphaAccess, last_offset): 112 pkt->set(alphaAccess->last_offset); 113 break; 114 case offsetof(AlphaAccess, version): 115 pkt->set(alphaAccess->version); 116 break; 117 case offsetof(AlphaAccess, numCPUs): 118 pkt->set(alphaAccess->numCPUs); 119 break; 120 case offsetof(AlphaAccess, intrClockFrequency): 121 pkt->set(alphaAccess->intrClockFrequency); 122 break; 123 default: 124 /* Old console code read in everyting as a 32bit int 125 * we now break that for better error checking. 126 */ 127 pkt->result = BadAddress; 128 } 129 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 130 pkt->get<uint32_t>()); 131 break; 132 case sizeof(uint64_t): 133 switch (daddr) 134 { 135 case offsetof(AlphaAccess, inputChar): 136 pkt->set(console->console_in()); 137 break; 138 case offsetof(AlphaAccess, cpuClock): 139 pkt->set(alphaAccess->cpuClock); 140 break; 141 case offsetof(AlphaAccess, mem_size): 142 pkt->set(alphaAccess->mem_size); 143 break; 144 case offsetof(AlphaAccess, kernStart): 145 pkt->set(alphaAccess->kernStart); 146 break; 147 case offsetof(AlphaAccess, kernEnd): 148 pkt->set(alphaAccess->kernEnd); 149 break; 150 case offsetof(AlphaAccess, entryPoint): 151 pkt->set(alphaAccess->entryPoint); 152 break; 153 case offsetof(AlphaAccess, diskUnit): 154 pkt->set(alphaAccess->diskUnit); 155 break; 156 case offsetof(AlphaAccess, diskCount): 157 pkt->set(alphaAccess->diskCount); 158 break; 159 case offsetof(AlphaAccess, diskPAddr): 160 pkt->set(alphaAccess->diskPAddr); 161 break; 162 case offsetof(AlphaAccess, diskBlock): 163 pkt->set(alphaAccess->diskBlock); 164 break; 165 case offsetof(AlphaAccess, diskOperation): 166 pkt->set(alphaAccess->diskOperation); 167 break; 168 case offsetof(AlphaAccess, outputChar): 169 pkt->set(alphaAccess->outputChar); 170 break; 171 default: 172 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 173 sizeof(alphaAccess->cpuStack[0]); 174 175 if (cpunum >= 0 && cpunum < 64) 176 pkt->set(alphaAccess->cpuStack[cpunum]); 177 else 178 panic("Unknown 64bit access, %#x\n", daddr); 179 } 180 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 181 pkt->get<uint64_t>()); 182 break; 183 default: 184 pkt->result = BadAddress; 185 } 186 if (pkt->result == Unknown) pkt->result = Success; 187 return pioDelay; 188} 189 190Tick 191AlphaConsole::write(Packet *pkt) 192{ 193 pkt->time += pioDelay; 194 195 assert(pkt->result == Unknown); 196 assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); 197 Addr daddr = pkt->addr - pioAddr; 198 199 uint64_t val = pkt->get<uint64_t>(); 200 assert(pkt->size == sizeof(uint64_t)); 201 202 switch (daddr) { 203 case offsetof(AlphaAccess, diskUnit): 204 alphaAccess->diskUnit = val; 205 break; 206 207 case offsetof(AlphaAccess, diskCount): 208 alphaAccess->diskCount = val; 209 break; 210 211 case offsetof(AlphaAccess, diskPAddr): 212 alphaAccess->diskPAddr = val; 213 break; 214 215 case offsetof(AlphaAccess, diskBlock): 216 alphaAccess->diskBlock = val; 217 break; 218 219 case offsetof(AlphaAccess, diskOperation): 220 if (val == 0x13) 221 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 222 alphaAccess->diskCount); 223 else 224 panic("Invalid disk operation!"); 225 226 break; 227 228 case offsetof(AlphaAccess, outputChar): 229 console->out((char)(val & 0xff)); 230 break; 231 232 default: 233 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 234 sizeof(alphaAccess->cpuStack[0]); 235 warn("%d: Trying to launch CPU number %d!", curTick, cpunum); 236 assert(val > 0 && "Must not access primary cpu"); 237 if (cpunum >= 0 && cpunum < 64) 238 alphaAccess->cpuStack[cpunum] = val; 239 else 240 panic("Unknown 64bit access, %#x\n", daddr); 241 } 242 243 pkt->result = Success; 244 245 return pioDelay; 246} 247 248void 249AlphaConsole::Access::serialize(ostream &os) 250{ 251 SERIALIZE_SCALAR(last_offset); 252 SERIALIZE_SCALAR(version); 253 SERIALIZE_SCALAR(numCPUs); 254 SERIALIZE_SCALAR(mem_size); 255 SERIALIZE_SCALAR(cpuClock); 256 SERIALIZE_SCALAR(intrClockFrequency); 257 SERIALIZE_SCALAR(kernStart); 258 SERIALIZE_SCALAR(kernEnd); 259 SERIALIZE_SCALAR(entryPoint); 260 SERIALIZE_SCALAR(diskUnit); 261 SERIALIZE_SCALAR(diskCount); 262 SERIALIZE_SCALAR(diskPAddr); 263 SERIALIZE_SCALAR(diskBlock); 264 SERIALIZE_SCALAR(diskOperation); 265 SERIALIZE_SCALAR(outputChar); 266 SERIALIZE_SCALAR(inputChar); 267 SERIALIZE_ARRAY(cpuStack,64); 268} 269 270void 271AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) 272{ 273 UNSERIALIZE_SCALAR(last_offset); 274 UNSERIALIZE_SCALAR(version); 275 UNSERIALIZE_SCALAR(numCPUs); 276 UNSERIALIZE_SCALAR(mem_size); 277 UNSERIALIZE_SCALAR(cpuClock); 278 UNSERIALIZE_SCALAR(intrClockFrequency); 279 UNSERIALIZE_SCALAR(kernStart); 280 UNSERIALIZE_SCALAR(kernEnd); 281 UNSERIALIZE_SCALAR(entryPoint); 282 UNSERIALIZE_SCALAR(diskUnit); 283 UNSERIALIZE_SCALAR(diskCount); 284 UNSERIALIZE_SCALAR(diskPAddr); 285 UNSERIALIZE_SCALAR(diskBlock); 286 UNSERIALIZE_SCALAR(diskOperation); 287 UNSERIALIZE_SCALAR(outputChar); 288 UNSERIALIZE_SCALAR(inputChar); 289 UNSERIALIZE_ARRAY(cpuStack, 64); 290} 291 292void 293AlphaConsole::serialize(ostream &os) 294{ 295 alphaAccess->serialize(os); 296} 297 298void 299AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) 300{ 301 alphaAccess->unserialize(cp, section); 302} 303 304BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 305 306 SimObjectParam<SimConsole *> sim_console; 307 SimObjectParam<SimpleDisk *> disk; 308 Param<Addr> pio_addr; 309 SimObjectParam<AlphaSystem *> system; 310 SimObjectParam<BaseCPU *> cpu; 311 SimObjectParam<Platform *> platform; 312 Param<Tick> pio_latency; 313 314END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 315 316BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 317 318 INIT_PARAM(sim_console, "The Simulator Console"), 319 INIT_PARAM(disk, "Simple Disk"), 320 INIT_PARAM(pio_addr, "Device Address"), 321 INIT_PARAM(system, "system object"), 322 INIT_PARAM(cpu, "Processor"), 323 INIT_PARAM(platform, "platform"), 324 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) 325 326END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 327 328CREATE_SIM_OBJECT(AlphaConsole) 329{ 330 AlphaConsole::Params *p = new AlphaConsole::Params; 331 p->name = getInstanceName(); 332 p->platform = platform; 333 p->pio_addr = pio_addr; 334 p->pio_delay = pio_latency; 335 p->cons = sim_console; 336 p->disk = disk; 337 p->alpha_sys = system; 338 p->system = system; 339 p->cpu = cpu; 340 return new AlphaConsole(p); 341} 342 343REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) 344