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