backdoor.cc revision 2114
112855Sgabeblack@google.com/* 212855Sgabeblack@google.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 312855Sgabeblack@google.com * All rights reserved. 412855Sgabeblack@google.com * 512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412855Sgabeblack@google.com * this software without specific prior written permission. 1512855Sgabeblack@google.com * 1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712855Sgabeblack@google.com */ 2812855Sgabeblack@google.com 2912855Sgabeblack@google.com/** @file 3012855Sgabeblack@google.com * Alpha Console Definition 3112855Sgabeblack@google.com */ 3212855Sgabeblack@google.com 3312855Sgabeblack@google.com#include <cstddef> 3412855Sgabeblack@google.com#include <cstdio> 3512855Sgabeblack@google.com#include <string> 3612855Sgabeblack@google.com 3712855Sgabeblack@google.com#include "base/inifile.hh" 3812855Sgabeblack@google.com#include "base/str.hh" 3912855Sgabeblack@google.com#include "base/trace.hh" 4012855Sgabeblack@google.com#include "cpu/base.hh" 4112855Sgabeblack@google.com#include "cpu/exec_context.hh" 4212855Sgabeblack@google.com#include "dev/alpha_console.hh" 4312855Sgabeblack@google.com#include "dev/simconsole.hh" 4412855Sgabeblack@google.com#include "dev/simple_disk.hh" 4512855Sgabeblack@google.com#include "dev/tsunami_io.hh" 4612855Sgabeblack@google.com#include "mem/bus/bus.hh" 4712855Sgabeblack@google.com#include "mem/bus/pio_interface.hh" 4812855Sgabeblack@google.com#include "mem/bus/pio_interface_impl.hh" 4912855Sgabeblack@google.com#include "mem/functional/memory_control.hh" 5012855Sgabeblack@google.com#include "mem/functional/physical.hh" 5112855Sgabeblack@google.com#include "sim/builder.hh" 5212855Sgabeblack@google.com#include "sim/sim_object.hh" 5312855Sgabeblack@google.com#include "sim/system.hh" 5412855Sgabeblack@google.com 5512855Sgabeblack@google.comusing namespace std; 5612855Sgabeblack@google.com 5712855Sgabeblack@google.comAlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, 5812855Sgabeblack@google.com System *s, BaseCPU *c, Platform *p, 5912855Sgabeblack@google.com MemoryController *mmu, Addr a, 6012855Sgabeblack@google.com HierParams *hier, Bus *pio_bus) 6112855Sgabeblack@google.com : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a) 6212855Sgabeblack@google.com{ 6312855Sgabeblack@google.com mmu->add_child(this, RangeSize(addr, size)); 6412855Sgabeblack@google.com 6512855Sgabeblack@google.com if (pio_bus) { 6612855Sgabeblack@google.com pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, 6712855Sgabeblack@google.com &AlphaConsole::cacheAccess); 6812855Sgabeblack@google.com pioInterface->addAddrRange(RangeSize(addr, size)); 6912855Sgabeblack@google.com } 7012855Sgabeblack@google.com 7112855Sgabeblack@google.com alphaAccess = new Access; 7212855Sgabeblack@google.com alphaAccess->last_offset = size - 1; 7312855Sgabeblack@google.com 7412855Sgabeblack@google.com alphaAccess->version = ALPHA_ACCESS_VERSION; 7512855Sgabeblack@google.com alphaAccess->diskUnit = 1; 7612855Sgabeblack@google.com 7712855Sgabeblack@google.com alphaAccess->diskCount = 0; 7812855Sgabeblack@google.com alphaAccess->diskPAddr = 0; 7912855Sgabeblack@google.com alphaAccess->diskBlock = 0; 8012855Sgabeblack@google.com alphaAccess->diskOperation = 0; 8112855Sgabeblack@google.com alphaAccess->outputChar = 0; 8212855Sgabeblack@google.com alphaAccess->inputChar = 0; 8312855Sgabeblack@google.com bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); 8412855Sgabeblack@google.com 8512855Sgabeblack@google.com system->setAlphaAccess(addr); 8612855Sgabeblack@google.com} 8712855Sgabeblack@google.com 8812855Sgabeblack@google.comvoid 8912855Sgabeblack@google.comAlphaConsole::startup() 9012855Sgabeblack@google.com{ 9112855Sgabeblack@google.com alphaAccess->numCPUs = system->getNumCPUs(); 9212855Sgabeblack@google.com alphaAccess->kernStart = system->getKernelStart(); 9312855Sgabeblack@google.com alphaAccess->kernEnd = system->getKernelEnd(); 9412855Sgabeblack@google.com alphaAccess->entryPoint = system->getKernelEntry(); 9512855Sgabeblack@google.com alphaAccess->mem_size = system->physmem->size(); 9612855Sgabeblack@google.com alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz 9712855Sgabeblack@google.com alphaAccess->intrClockFrequency = platform->intrFrequency(); 9812855Sgabeblack@google.com} 9912855Sgabeblack@google.com 10012855Sgabeblack@google.comFault 10112855Sgabeblack@google.comAlphaConsole::read(MemReqPtr &req, uint8_t *data) 10212855Sgabeblack@google.com{ 10312855Sgabeblack@google.com memset(data, 0, req->size); 10412855Sgabeblack@google.com 10512855Sgabeblack@google.com Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); 10612855Sgabeblack@google.com 10712855Sgabeblack@google.com switch (req->size) 10812855Sgabeblack@google.com { 10912855Sgabeblack@google.com case sizeof(uint32_t): 110 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 111 *(uint32_t*)data); 112 switch (daddr) 113 { 114 case offsetof(AlphaAccess, last_offset): 115 *(uint32_t*)data = alphaAccess->last_offset; 116 break; 117 case offsetof(AlphaAccess, version): 118 *(uint32_t*)data = alphaAccess->version; 119 break; 120 case offsetof(AlphaAccess, numCPUs): 121 *(uint32_t*)data = alphaAccess->numCPUs; 122 break; 123 case offsetof(AlphaAccess, intrClockFrequency): 124 *(uint32_t*)data = alphaAccess->intrClockFrequency; 125 break; 126 default: 127 // Old console code read in everyting as a 32bit int 128 *(uint32_t*)data = *(uint32_t*)(consoleData + daddr); 129 130 } 131 break; 132 case sizeof(uint64_t): 133 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 134 *(uint64_t*)data); 135 switch (daddr) 136 { 137 case offsetof(AlphaAccess, inputChar): 138 *(uint64_t*)data = console->console_in(); 139 break; 140 case offsetof(AlphaAccess, cpuClock): 141 *(uint64_t*)data = alphaAccess->cpuClock; 142 break; 143 case offsetof(AlphaAccess, mem_size): 144 *(uint64_t*)data = alphaAccess->mem_size; 145 break; 146 case offsetof(AlphaAccess, kernStart): 147 *(uint64_t*)data = alphaAccess->kernStart; 148 break; 149 case offsetof(AlphaAccess, kernEnd): 150 *(uint64_t*)data = alphaAccess->kernEnd; 151 break; 152 case offsetof(AlphaAccess, entryPoint): 153 *(uint64_t*)data = alphaAccess->entryPoint; 154 break; 155 case offsetof(AlphaAccess, diskUnit): 156 *(uint64_t*)data = alphaAccess->diskUnit; 157 break; 158 case offsetof(AlphaAccess, diskCount): 159 *(uint64_t*)data = alphaAccess->diskCount; 160 break; 161 case offsetof(AlphaAccess, diskPAddr): 162 *(uint64_t*)data = alphaAccess->diskPAddr; 163 break; 164 case offsetof(AlphaAccess, diskBlock): 165 *(uint64_t*)data = alphaAccess->diskBlock; 166 break; 167 case offsetof(AlphaAccess, diskOperation): 168 *(uint64_t*)data = alphaAccess->diskOperation; 169 break; 170 case offsetof(AlphaAccess, outputChar): 171 *(uint64_t*)data = alphaAccess->outputChar; 172 break; 173 default: 174 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 175 sizeof(alphaAccess->cpuStack[0]); 176 177 if (cpunum >= 0 && cpunum < 64) 178 *(uint64_t*)data = alphaAccess->cpuStack[cpunum]; 179 else 180 panic("Unknown 64bit access, %#x\n", daddr); 181 } 182 break; 183 default: 184 return Machine_Check_Fault; 185 } 186 187 return No_Fault; 188} 189 190Fault 191AlphaConsole::write(MemReqPtr &req, const uint8_t *data) 192{ 193 uint64_t val; 194 195 switch (req->size) { 196 case sizeof(uint32_t): 197 val = *(uint32_t *)data; 198 break; 199 200 case sizeof(uint64_t): 201 val = *(uint64_t *)data; 202 break; 203 default: 204 return Machine_Check_Fault; 205 } 206 207 Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); 208 ExecContext *other_xc; 209 210 switch (daddr) { 211 case offsetof(AlphaAccess, diskUnit): 212 alphaAccess->diskUnit = val; 213 break; 214 215 case offsetof(AlphaAccess, diskCount): 216 alphaAccess->diskCount = val; 217 break; 218 219 case offsetof(AlphaAccess, diskPAddr): 220 alphaAccess->diskPAddr = val; 221 break; 222 223 case offsetof(AlphaAccess, diskBlock): 224 alphaAccess->diskBlock = val; 225 break; 226 227 case offsetof(AlphaAccess, diskOperation): 228 if (val == 0x13) 229 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 230 alphaAccess->diskCount); 231 else 232 panic("Invalid disk operation!"); 233 234 break; 235 236 case offsetof(AlphaAccess, outputChar): 237 console->out((char)(val & 0xff)); 238 break; 239 240 other_xc->activate(); //Start the cpu 241 break; 242 243 default: 244 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 245 sizeof(alphaAccess->cpuStack[0]); 246 warn("%d: Trying to launch CPU number %d!", curTick, cpunum); 247 assert(val > 0 && "Must not access primary cpu"); 248 if (cpunum >= 0 && cpunum < 64) 249 alphaAccess->cpuStack[cpunum] = val; 250 else 251 panic("Unknown 64bit access, %#x\n", daddr); 252 } 253 254 return No_Fault; 255} 256 257Tick 258AlphaConsole::cacheAccess(MemReqPtr &req) 259{ 260 return curTick + 1000; 261} 262 263void 264AlphaConsole::Access::serialize(ostream &os) 265{ 266 SERIALIZE_SCALAR(last_offset); 267 SERIALIZE_SCALAR(version); 268 SERIALIZE_SCALAR(numCPUs); 269 SERIALIZE_SCALAR(mem_size); 270 SERIALIZE_SCALAR(cpuClock); 271 SERIALIZE_SCALAR(intrClockFrequency); 272 SERIALIZE_SCALAR(kernStart); 273 SERIALIZE_SCALAR(kernEnd); 274 SERIALIZE_SCALAR(entryPoint); 275 SERIALIZE_SCALAR(diskUnit); 276 SERIALIZE_SCALAR(diskCount); 277 SERIALIZE_SCALAR(diskPAddr); 278 SERIALIZE_SCALAR(diskBlock); 279 SERIALIZE_SCALAR(diskOperation); 280 SERIALIZE_SCALAR(outputChar); 281 SERIALIZE_SCALAR(inputChar); 282 SERIALIZE_ARRAY(cpuStack,64); 283} 284 285void 286AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) 287{ 288 UNSERIALIZE_SCALAR(last_offset); 289 UNSERIALIZE_SCALAR(version); 290 UNSERIALIZE_SCALAR(numCPUs); 291 UNSERIALIZE_SCALAR(mem_size); 292 UNSERIALIZE_SCALAR(cpuClock); 293 UNSERIALIZE_SCALAR(intrClockFrequency); 294 UNSERIALIZE_SCALAR(kernStart); 295 UNSERIALIZE_SCALAR(kernEnd); 296 UNSERIALIZE_SCALAR(entryPoint); 297 UNSERIALIZE_SCALAR(diskUnit); 298 UNSERIALIZE_SCALAR(diskCount); 299 UNSERIALIZE_SCALAR(diskPAddr); 300 UNSERIALIZE_SCALAR(diskBlock); 301 UNSERIALIZE_SCALAR(diskOperation); 302 UNSERIALIZE_SCALAR(outputChar); 303 UNSERIALIZE_SCALAR(inputChar); 304 UNSERIALIZE_ARRAY(cpuStack, 64); 305} 306 307void 308AlphaConsole::serialize(ostream &os) 309{ 310 alphaAccess->serialize(os); 311} 312 313void 314AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) 315{ 316 alphaAccess->unserialize(cp, section); 317} 318 319BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 320 321 SimObjectParam<SimConsole *> sim_console; 322 SimObjectParam<SimpleDisk *> disk; 323 SimObjectParam<MemoryController *> mmu; 324 Param<Addr> addr; 325 SimObjectParam<System *> system; 326 SimObjectParam<BaseCPU *> cpu; 327 SimObjectParam<Platform *> platform; 328 SimObjectParam<Bus*> pio_bus; 329 Param<Tick> pio_latency; 330 SimObjectParam<HierParams *> hier; 331 332END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 333 334BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 335 336 INIT_PARAM(sim_console, "The Simulator Console"), 337 INIT_PARAM(disk, "Simple Disk"), 338 INIT_PARAM(mmu, "Memory Controller"), 339 INIT_PARAM(addr, "Device Address"), 340 INIT_PARAM(system, "system object"), 341 INIT_PARAM(cpu, "Processor"), 342 INIT_PARAM(platform, "platform"), 343 INIT_PARAM(pio_bus, "The IO Bus to attach to"), 344 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), 345 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) 346 347END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 348 349CREATE_SIM_OBJECT(AlphaConsole) 350{ 351 return new AlphaConsole(getInstanceName(), sim_console, disk, 352 system, cpu, platform, mmu, addr, hier, pio_bus); 353} 354 355REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) 356