backdoor.cc revision 8232
12SN/A/* 21762SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Nathan Binkert 292665SN/A * Ali Saidi 302665SN/A * Steve Reinhardt 312665SN/A * Erik Hallnor 322SN/A */ 332SN/A 341722SN/A/** @file 355480Snate@binkert.org * Alpha Console Backdoor Definition 362SN/A */ 372SN/A 38146SN/A#include <cstddef> 392SN/A#include <string> 402SN/A 412158SN/A#include "arch/alpha/system.hh" 42146SN/A#include "base/inifile.hh" 431805SN/A#include "base/str.hh" 44146SN/A#include "base/trace.hh" 451717SN/A#include "cpu/base.hh" 462680SN/A#include "cpu/thread_context.hh" 478232Snate@binkert.org#include "debug/AlphaBackdoor.hh" 485480Snate@binkert.org#include "dev/alpha/backdoor.hh" 492521SN/A#include "dev/platform.hh" 5056SN/A#include "dev/simple_disk.hh" 515478SN/A#include "dev/terminal.hh" 523348SN/A#include "mem/packet.hh" 533348SN/A#include "mem/packet_access.hh" 542521SN/A#include "mem/physical.hh" 555480Snate@binkert.org#include "params/AlphaBackdoor.hh" 561805SN/A#include "sim/sim_object.hh" 572SN/A 582SN/Ausing namespace std; 592107SN/Ausing namespace AlphaISA; 602SN/A 615480Snate@binkert.orgAlphaBackdoor::AlphaBackdoor(const Params *p) 625478SN/A : BasicPioDevice(p), disk(p->disk), terminal(p->terminal), 634762SN/A system(p->system), cpu(p->cpu) 642SN/A{ 65545SN/A 662521SN/A pioSize = sizeof(struct AlphaAccess); 672521SN/A 682521SN/A alphaAccess = new Access(); 692521SN/A alphaAccess->last_offset = pioSize - 1; 702SN/A 712SN/A alphaAccess->version = ALPHA_ACCESS_VERSION; 722SN/A alphaAccess->diskUnit = 1; 73926SN/A 74926SN/A alphaAccess->diskCount = 0; 75926SN/A alphaAccess->diskPAddr = 0; 76926SN/A alphaAccess->diskBlock = 0; 77926SN/A alphaAccess->diskOperation = 0; 78926SN/A alphaAccess->outputChar = 0; 79926SN/A alphaAccess->inputChar = 0; 804395SN/A std::memset(alphaAccess->cpuStack, 0, sizeof(alphaAccess->cpuStack)); 811805SN/A 822SN/A} 832SN/A 841634SN/Avoid 855480Snate@binkert.orgAlphaBackdoor::startup() 861634SN/A{ 872549SN/A system->setAlphaAccess(pioAddr); 885714Shsul@eecs.umich.edu alphaAccess->numCPUs = system->numContexts(); 891634SN/A alphaAccess->kernStart = system->getKernelStart(); 901634SN/A alphaAccess->kernEnd = system->getKernelEnd(); 911634SN/A alphaAccess->entryPoint = system->getKernelEntry(); 921634SN/A alphaAccess->mem_size = system->physmem->size(); 931634SN/A alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz 942521SN/A alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); 951634SN/A} 961634SN/A 972512SN/ATick 985480Snate@binkert.orgAlphaBackdoor::read(PacketPtr pkt) 992SN/A{ 1002SN/A 1012512SN/A /** XXX Do we want to push the addr munging to a bus brige or something? So 1022512SN/A * the device has it's physical address and then the bridge adds on whatever 1032512SN/A * machine dependent address swizzle is required? 1042512SN/A */ 105540SN/A 1062641SN/A assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 1072522SN/A 1082641SN/A Addr daddr = pkt->getAddr() - pioAddr; 1092512SN/A 1102630SN/A pkt->allocate(); 1114986SN/A pkt->makeAtomicResponse(); 1122521SN/A 1132641SN/A switch (pkt->getSize()) 114873SN/A { 115873SN/A case sizeof(uint32_t): 116873SN/A switch (daddr) 117873SN/A { 118873SN/A case offsetof(AlphaAccess, last_offset): 1192630SN/A pkt->set(alphaAccess->last_offset); 120873SN/A break; 121873SN/A case offsetof(AlphaAccess, version): 1222630SN/A pkt->set(alphaAccess->version); 123873SN/A break; 124873SN/A case offsetof(AlphaAccess, numCPUs): 1252630SN/A pkt->set(alphaAccess->numCPUs); 126873SN/A break; 127873SN/A case offsetof(AlphaAccess, intrClockFrequency): 1282630SN/A pkt->set(alphaAccess->intrClockFrequency); 129873SN/A break; 130873SN/A default: 1312512SN/A /* Old console code read in everyting as a 32bit int 1322512SN/A * we now break that for better error checking. 1332512SN/A */ 1344870SN/A pkt->setBadAddress(); 135873SN/A } 1365480Snate@binkert.org DPRINTF(AlphaBackdoor, "read: offset=%#x val=%#x\n", daddr, 1372630SN/A pkt->get<uint32_t>()); 138873SN/A break; 139873SN/A case sizeof(uint64_t): 140873SN/A switch (daddr) 141873SN/A { 142873SN/A case offsetof(AlphaAccess, inputChar): 1435478SN/A pkt->set(terminal->console_in()); 144873SN/A break; 145873SN/A case offsetof(AlphaAccess, cpuClock): 1462630SN/A pkt->set(alphaAccess->cpuClock); 147873SN/A break; 148873SN/A case offsetof(AlphaAccess, mem_size): 1492630SN/A pkt->set(alphaAccess->mem_size); 150873SN/A break; 151873SN/A case offsetof(AlphaAccess, kernStart): 1522630SN/A pkt->set(alphaAccess->kernStart); 153873SN/A break; 154873SN/A case offsetof(AlphaAccess, kernEnd): 1552630SN/A pkt->set(alphaAccess->kernEnd); 156873SN/A break; 157873SN/A case offsetof(AlphaAccess, entryPoint): 1582630SN/A pkt->set(alphaAccess->entryPoint); 159873SN/A break; 160873SN/A case offsetof(AlphaAccess, diskUnit): 1612630SN/A pkt->set(alphaAccess->diskUnit); 162873SN/A break; 163873SN/A case offsetof(AlphaAccess, diskCount): 1642630SN/A pkt->set(alphaAccess->diskCount); 165873SN/A break; 166873SN/A case offsetof(AlphaAccess, diskPAddr): 1672630SN/A pkt->set(alphaAccess->diskPAddr); 168873SN/A break; 169873SN/A case offsetof(AlphaAccess, diskBlock): 1702630SN/A pkt->set(alphaAccess->diskBlock); 171873SN/A break; 172873SN/A case offsetof(AlphaAccess, diskOperation): 1732630SN/A pkt->set(alphaAccess->diskOperation); 174873SN/A break; 175873SN/A case offsetof(AlphaAccess, outputChar): 1762630SN/A pkt->set(alphaAccess->outputChar); 177873SN/A break; 178873SN/A default: 1792114SN/A int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 1802114SN/A sizeof(alphaAccess->cpuStack[0]); 1812114SN/A 1822114SN/A if (cpunum >= 0 && cpunum < 64) 1832630SN/A pkt->set(alphaAccess->cpuStack[cpunum]); 1842114SN/A else 1852114SN/A panic("Unknown 64bit access, %#x\n", daddr); 186873SN/A } 1875480Snate@binkert.org DPRINTF(AlphaBackdoor, "read: offset=%#x val=%#x\n", daddr, 1882630SN/A pkt->get<uint64_t>()); 189873SN/A break; 190873SN/A default: 1914870SN/A pkt->setBadAddress(); 1922SN/A } 1932512SN/A return pioDelay; 1942SN/A} 1952SN/A 1962512SN/ATick 1975480Snate@binkert.orgAlphaBackdoor::write(PacketPtr pkt) 1982SN/A{ 1992641SN/A assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 2002641SN/A Addr daddr = pkt->getAddr() - pioAddr; 201430SN/A 2022630SN/A uint64_t val = pkt->get<uint64_t>(); 2032641SN/A assert(pkt->getSize() == sizeof(uint64_t)); 2042SN/A 205430SN/A switch (daddr) { 206430SN/A case offsetof(AlphaAccess, diskUnit): 2072SN/A alphaAccess->diskUnit = val; 208430SN/A break; 2092SN/A 210430SN/A case offsetof(AlphaAccess, diskCount): 2112SN/A alphaAccess->diskCount = val; 212430SN/A break; 2132SN/A 214430SN/A case offsetof(AlphaAccess, diskPAddr): 2152SN/A alphaAccess->diskPAddr = val; 216430SN/A break; 2172SN/A 218430SN/A case offsetof(AlphaAccess, diskBlock): 2192SN/A alphaAccess->diskBlock = val; 220430SN/A break; 2212SN/A 222430SN/A case offsetof(AlphaAccess, diskOperation): 2232SN/A if (val == 0x13) 2242SN/A disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 2252SN/A alphaAccess->diskCount); 2262SN/A else 2272SN/A panic("Invalid disk operation!"); 2282SN/A 229430SN/A break; 2302SN/A 231430SN/A case offsetof(AlphaAccess, outputChar): 2325478SN/A terminal->out((char)(val & 0xff)); 233430SN/A break; 2342SN/A 235430SN/A default: 2362114SN/A int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 2372114SN/A sizeof(alphaAccess->cpuStack[0]); 2387823Ssteve.reinhardt@amd.com inform("Launching CPU %d @ %d", cpunum, curTick()); 2392114SN/A assert(val > 0 && "Must not access primary cpu"); 2402114SN/A if (cpunum >= 0 && cpunum < 64) 2412114SN/A alphaAccess->cpuStack[cpunum] = val; 2422114SN/A else 2432114SN/A panic("Unknown 64bit access, %#x\n", daddr); 2442SN/A } 2452SN/A 2464870SN/A pkt->makeAtomicResponse(); 2472SN/A 2482512SN/A return pioDelay; 249545SN/A} 250545SN/A 2512SN/Avoid 2525480Snate@binkert.orgAlphaBackdoor::Access::serialize(ostream &os) 2532SN/A{ 254222SN/A SERIALIZE_SCALAR(last_offset); 255222SN/A SERIALIZE_SCALAR(version); 256222SN/A SERIALIZE_SCALAR(numCPUs); 257222SN/A SERIALIZE_SCALAR(mem_size); 258222SN/A SERIALIZE_SCALAR(cpuClock); 259222SN/A SERIALIZE_SCALAR(intrClockFrequency); 260222SN/A SERIALIZE_SCALAR(kernStart); 261222SN/A SERIALIZE_SCALAR(kernEnd); 262222SN/A SERIALIZE_SCALAR(entryPoint); 263222SN/A SERIALIZE_SCALAR(diskUnit); 264222SN/A SERIALIZE_SCALAR(diskCount); 265222SN/A SERIALIZE_SCALAR(diskPAddr); 266222SN/A SERIALIZE_SCALAR(diskBlock); 267222SN/A SERIALIZE_SCALAR(diskOperation); 268222SN/A SERIALIZE_SCALAR(outputChar); 269430SN/A SERIALIZE_SCALAR(inputChar); 2702114SN/A SERIALIZE_ARRAY(cpuStack,64); 2712SN/A} 2722SN/A 2732SN/Avoid 2745480Snate@binkert.orgAlphaBackdoor::Access::unserialize(Checkpoint *cp, const std::string §ion) 2752SN/A{ 276222SN/A UNSERIALIZE_SCALAR(last_offset); 277222SN/A UNSERIALIZE_SCALAR(version); 278222SN/A UNSERIALIZE_SCALAR(numCPUs); 279222SN/A UNSERIALIZE_SCALAR(mem_size); 280222SN/A UNSERIALIZE_SCALAR(cpuClock); 281222SN/A UNSERIALIZE_SCALAR(intrClockFrequency); 282222SN/A UNSERIALIZE_SCALAR(kernStart); 283222SN/A UNSERIALIZE_SCALAR(kernEnd); 284222SN/A UNSERIALIZE_SCALAR(entryPoint); 285222SN/A UNSERIALIZE_SCALAR(diskUnit); 286222SN/A UNSERIALIZE_SCALAR(diskCount); 287222SN/A UNSERIALIZE_SCALAR(diskPAddr); 288222SN/A UNSERIALIZE_SCALAR(diskBlock); 289222SN/A UNSERIALIZE_SCALAR(diskOperation); 290222SN/A UNSERIALIZE_SCALAR(outputChar); 291430SN/A UNSERIALIZE_SCALAR(inputChar); 2922114SN/A UNSERIALIZE_ARRAY(cpuStack, 64); 293217SN/A} 2942SN/A 295217SN/Avoid 2965480Snate@binkert.orgAlphaBackdoor::serialize(ostream &os) 297217SN/A{ 298217SN/A alphaAccess->serialize(os); 299217SN/A} 300217SN/A 301217SN/Avoid 3025480Snate@binkert.orgAlphaBackdoor::unserialize(Checkpoint *cp, const std::string §ion) 303217SN/A{ 304237SN/A alphaAccess->unserialize(cp, section); 3052SN/A} 3062SN/A 3075480Snate@binkert.orgAlphaBackdoor * 3085480Snate@binkert.orgAlphaBackdoorParams::create() 3092SN/A{ 3105480Snate@binkert.org return new AlphaBackdoor(this); 3112SN/A} 312