backdoor.cc revision 2641
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 == Packet::Unknown); 99 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 100 101 pkt->time += pioDelay; 102 Addr daddr = pkt->getAddr() - pioAddr; 103 104 pkt->allocate(); 105 106 switch (pkt->getSize()) 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 = Packet::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 = Packet::BadAddress; 185 } 186 if (pkt->result == Packet::Unknown) 187 pkt->result = Packet::Success; 188 return pioDelay; 189} 190 191Tick 192AlphaConsole::write(Packet *pkt) 193{ 194 pkt->time += pioDelay; 195 196 assert(pkt->result == Packet::Unknown); 197 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 198 Addr daddr = pkt->getAddr() - pioAddr; 199 200 uint64_t val = pkt->get<uint64_t>(); 201 assert(pkt->getSize() == sizeof(uint64_t)); 202 203 switch (daddr) { 204 case offsetof(AlphaAccess, diskUnit): 205 alphaAccess->diskUnit = val; 206 break; 207 208 case offsetof(AlphaAccess, diskCount): 209 alphaAccess->diskCount = val; 210 break; 211 212 case offsetof(AlphaAccess, diskPAddr): 213 alphaAccess->diskPAddr = val; 214 break; 215 216 case offsetof(AlphaAccess, diskBlock): 217 alphaAccess->diskBlock = val; 218 break; 219 220 case offsetof(AlphaAccess, diskOperation): 221 if (val == 0x13) 222 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 223 alphaAccess->diskCount); 224 else 225 panic("Invalid disk operation!"); 226 227 break; 228 229 case offsetof(AlphaAccess, outputChar): 230 console->out((char)(val & 0xff)); 231 break; 232 233 default: 234 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 235 sizeof(alphaAccess->cpuStack[0]); 236 warn("%d: Trying to launch CPU number %d!", curTick, cpunum); 237 assert(val > 0 && "Must not access primary cpu"); 238 if (cpunum >= 0 && cpunum < 64) 239 alphaAccess->cpuStack[cpunum] = val; 240 else 241 panic("Unknown 64bit access, %#x\n", daddr); 242 } 243 244 pkt->result = Packet::Success; 245 246 return pioDelay; 247} 248 249void 250AlphaConsole::Access::serialize(ostream &os) 251{ 252 SERIALIZE_SCALAR(last_offset); 253 SERIALIZE_SCALAR(version); 254 SERIALIZE_SCALAR(numCPUs); 255 SERIALIZE_SCALAR(mem_size); 256 SERIALIZE_SCALAR(cpuClock); 257 SERIALIZE_SCALAR(intrClockFrequency); 258 SERIALIZE_SCALAR(kernStart); 259 SERIALIZE_SCALAR(kernEnd); 260 SERIALIZE_SCALAR(entryPoint); 261 SERIALIZE_SCALAR(diskUnit); 262 SERIALIZE_SCALAR(diskCount); 263 SERIALIZE_SCALAR(diskPAddr); 264 SERIALIZE_SCALAR(diskBlock); 265 SERIALIZE_SCALAR(diskOperation); 266 SERIALIZE_SCALAR(outputChar); 267 SERIALIZE_SCALAR(inputChar); 268 SERIALIZE_ARRAY(cpuStack,64); 269} 270 271void 272AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) 273{ 274 UNSERIALIZE_SCALAR(last_offset); 275 UNSERIALIZE_SCALAR(version); 276 UNSERIALIZE_SCALAR(numCPUs); 277 UNSERIALIZE_SCALAR(mem_size); 278 UNSERIALIZE_SCALAR(cpuClock); 279 UNSERIALIZE_SCALAR(intrClockFrequency); 280 UNSERIALIZE_SCALAR(kernStart); 281 UNSERIALIZE_SCALAR(kernEnd); 282 UNSERIALIZE_SCALAR(entryPoint); 283 UNSERIALIZE_SCALAR(diskUnit); 284 UNSERIALIZE_SCALAR(diskCount); 285 UNSERIALIZE_SCALAR(diskPAddr); 286 UNSERIALIZE_SCALAR(diskBlock); 287 UNSERIALIZE_SCALAR(diskOperation); 288 UNSERIALIZE_SCALAR(outputChar); 289 UNSERIALIZE_SCALAR(inputChar); 290 UNSERIALIZE_ARRAY(cpuStack, 64); 291} 292 293void 294AlphaConsole::serialize(ostream &os) 295{ 296 alphaAccess->serialize(os); 297} 298 299void 300AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) 301{ 302 alphaAccess->unserialize(cp, section); 303} 304 305BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 306 307 SimObjectParam<SimConsole *> sim_console; 308 SimObjectParam<SimpleDisk *> disk; 309 Param<Addr> pio_addr; 310 SimObjectParam<AlphaSystem *> system; 311 SimObjectParam<BaseCPU *> cpu; 312 SimObjectParam<Platform *> platform; 313 Param<Tick> pio_latency; 314 315END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 316 317BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 318 319 INIT_PARAM(sim_console, "The Simulator Console"), 320 INIT_PARAM(disk, "Simple Disk"), 321 INIT_PARAM(pio_addr, "Device Address"), 322 INIT_PARAM(system, "system object"), 323 INIT_PARAM(cpu, "Processor"), 324 INIT_PARAM(platform, "platform"), 325 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) 326 327END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 328 329CREATE_SIM_OBJECT(AlphaConsole) 330{ 331 AlphaConsole::Params *p = new AlphaConsole::Params; 332 p->name = getInstanceName(); 333 p->platform = platform; 334 p->pio_addr = pio_addr; 335 p->pio_delay = pio_latency; 336 p->cons = sim_console; 337 p->disk = disk; 338 p->alpha_sys = system; 339 p->system = system; 340 p->cpu = cpu; 341 return new AlphaConsole(p); 342} 343 344REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) 345