backdoor.cc revision 4870
12SN/A/* 21762SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 35502Snate@binkert.org * All rights reserved. 49983Sstever@gmail.com * 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. 272SN/A * 282SN/A * Authors: Nathan Binkert 292665Ssaidi@eecs.umich.edu * Ali Saidi 302665Ssaidi@eecs.umich.edu * Steve Reinhardt 312665Ssaidi@eecs.umich.edu * Erik Hallnor 322665Ssaidi@eecs.umich.edu */ 332SN/A 342SN/A/** @file 355501Snate@binkert.org * Alpha Console Definition 362SN/A */ 372SN/A 382SN/A#include <cstddef> 392SN/A#include <string> 405502Snate@binkert.org 415501Snate@binkert.org#include "arch/alpha/system.hh" 425501Snate@binkert.org#include "base/inifile.hh" 431717SN/A#include "base/str.hh" 4410906Sandreas.sandberg@arm.com#include "base/trace.hh" 455501Snate@binkert.org#include "cpu/base.hh" 469356Snilay@cs.wisc.edu#include "cpu/thread_context.hh" 472SN/A#include "dev/alpha/console.hh" 482SN/A#include "dev/platform.hh" 492SN/A#include "dev/simconsole.hh" 509983Sstever@gmail.com#include "dev/simple_disk.hh" 519983Sstever@gmail.com#include "mem/packet.hh" 522SN/A#include "mem/packet_access.hh" 539983Sstever@gmail.com#include "mem/physical.hh" 542SN/A#include "sim/builder.hh" 559983Sstever@gmail.com#include "sim/sim_object.hh" 562SN/A 572SN/Ausing namespace std; 589983Sstever@gmail.comusing namespace AlphaISA; 599983Sstever@gmail.com 609983Sstever@gmail.comAlphaConsole::AlphaConsole(Params *p) 619983Sstever@gmail.com : BasicPioDevice(p), disk(p->disk), 629983Sstever@gmail.com console(params()->cons), system(params()->alpha_sys), cpu(params()->cpu) 639983Sstever@gmail.com{ 649983Sstever@gmail.com 659983Sstever@gmail.com pioSize = sizeof(struct AlphaAccess); 669983Sstever@gmail.com 679983Sstever@gmail.com alphaAccess = new Access(); 689983Sstever@gmail.com alphaAccess->last_offset = pioSize - 1; 699983Sstever@gmail.com 709983Sstever@gmail.com alphaAccess->version = ALPHA_ACCESS_VERSION; 719983Sstever@gmail.com alphaAccess->diskUnit = 1; 729983Sstever@gmail.com 739983Sstever@gmail.com alphaAccess->diskCount = 0; 742SN/A alphaAccess->diskPAddr = 0; 754017Sstever@eecs.umich.edu alphaAccess->diskBlock = 0; 764016Sstever@eecs.umich.edu alphaAccess->diskOperation = 0; 774017Sstever@eecs.umich.edu alphaAccess->outputChar = 0; 784016Sstever@eecs.umich.edu alphaAccess->inputChar = 0; 795768Snate@binkert.org std::memset(alphaAccess->cpuStack, 0, sizeof(alphaAccess->cpuStack)); 805768Snate@binkert.org 815774Snate@binkert.org} 827059Snate@binkert.org 835768Snate@binkert.orgvoid 845768Snate@binkert.orgAlphaConsole::startup() 855768Snate@binkert.org{ 865768Snate@binkert.org system->setAlphaAccess(pioAddr); 875768Snate@binkert.org alphaAccess->numCPUs = system->getNumCPUs(); 885768Snate@binkert.org alphaAccess->kernStart = system->getKernelStart(); 895768Snate@binkert.org alphaAccess->kernEnd = system->getKernelEnd(); 905768Snate@binkert.org alphaAccess->entryPoint = system->getKernelEntry(); 915768Snate@binkert.org alphaAccess->mem_size = system->physmem->size(); 925768Snate@binkert.org alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz 935768Snate@binkert.org alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); 945768Snate@binkert.org} 955768Snate@binkert.org 965602Snate@binkert.orgTick 975602Snate@binkert.orgAlphaConsole::read(PacketPtr pkt) 985502Snate@binkert.org{ 995503Snate@binkert.org 1005502Snate@binkert.org /** XXX Do we want to push the addr munging to a bus brige or something? So 1015502Snate@binkert.org * the device has it's physical address and then the bridge adds on whatever 1025502Snate@binkert.org * machine dependent address swizzle is required? 1035502Snate@binkert.org */ 1045502Snate@binkert.org 1055503Snate@binkert.org assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 1065502Snate@binkert.org 1075502Snate@binkert.org Addr daddr = pkt->getAddr() - pioAddr; 1085502Snate@binkert.org 1095502Snate@binkert.org pkt->allocate(); 1105503Snate@binkert.org 1115503Snate@binkert.org switch (pkt->getSize()) 1125503Snate@binkert.org { 1135502Snate@binkert.org case sizeof(uint32_t): 1145503Snate@binkert.org switch (daddr) 1155502Snate@binkert.org { 1165502Snate@binkert.org case offsetof(AlphaAccess, last_offset): 1172SN/A pkt->set(alphaAccess->last_offset); 1182SN/A break; 1192SN/A case offsetof(AlphaAccess, version): 1205502Snate@binkert.org pkt->set(alphaAccess->version); 1215502Snate@binkert.org break; 1225602Snate@binkert.org case offsetof(AlphaAccess, numCPUs): 1235502Snate@binkert.org pkt->set(alphaAccess->numCPUs); 1245502Snate@binkert.org break; 1252SN/A case offsetof(AlphaAccess, intrClockFrequency): 1265502Snate@binkert.org pkt->set(alphaAccess->intrClockFrequency); 1275502Snate@binkert.org break; 1285503Snate@binkert.org default: 1295503Snate@binkert.org /* Old console code read in everyting as a 32bit int 1305503Snate@binkert.org * we now break that for better error checking. 1315503Snate@binkert.org */ 1325503Snate@binkert.org pkt->setBadAddress(); 1335502Snate@binkert.org } 1342SN/A DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 1355503Snate@binkert.org pkt->get<uint32_t>()); 1365503Snate@binkert.org break; 1375602Snate@binkert.org case sizeof(uint64_t): 1385502Snate@binkert.org switch (daddr) 1392SN/A { 1405602Snate@binkert.org case offsetof(AlphaAccess, inputChar): 1415602Snate@binkert.org pkt->set(console->console_in()); 1425502Snate@binkert.org break; 1435503Snate@binkert.org case offsetof(AlphaAccess, cpuClock): 1445503Snate@binkert.org pkt->set(alphaAccess->cpuClock); 1455502Snate@binkert.org break; 1465503Snate@binkert.org case offsetof(AlphaAccess, mem_size): 1475503Snate@binkert.org pkt->set(alphaAccess->mem_size); 1485503Snate@binkert.org break; 1495503Snate@binkert.org case offsetof(AlphaAccess, kernStart): 1505503Snate@binkert.org pkt->set(alphaAccess->kernStart); 1515503Snate@binkert.org break; 1525503Snate@binkert.org case offsetof(AlphaAccess, kernEnd): 1535503Snate@binkert.org pkt->set(alphaAccess->kernEnd); 1545503Snate@binkert.org break; 1555503Snate@binkert.org case offsetof(AlphaAccess, entryPoint): 1565503Snate@binkert.org pkt->set(alphaAccess->entryPoint); 1575503Snate@binkert.org break; 1585503Snate@binkert.org case offsetof(AlphaAccess, diskUnit): 1595503Snate@binkert.org pkt->set(alphaAccess->diskUnit); 1605502Snate@binkert.org break; 1615502Snate@binkert.org case offsetof(AlphaAccess, diskCount): 1625503Snate@binkert.org pkt->set(alphaAccess->diskCount); 1635503Snate@binkert.org break; 1642SN/A case offsetof(AlphaAccess, diskPAddr): 1655502Snate@binkert.org pkt->set(alphaAccess->diskPAddr); 1665503Snate@binkert.org break; 1675503Snate@binkert.org case offsetof(AlphaAccess, diskBlock): 1685503Snate@binkert.org pkt->set(alphaAccess->diskBlock); 1692SN/A break; 1702SN/A case offsetof(AlphaAccess, diskOperation): 1712SN/A pkt->set(alphaAccess->diskOperation); 1722SN/A break; 1732SN/A case offsetof(AlphaAccess, outputChar): 1742SN/A pkt->set(alphaAccess->outputChar); 1755502Snate@binkert.org break; 1762SN/A default: 1779983Sstever@gmail.com int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 1789983Sstever@gmail.com sizeof(alphaAccess->cpuStack[0]); 1795502Snate@binkert.org 1805502Snate@binkert.org if (cpunum >= 0 && cpunum < 64) 1815502Snate@binkert.org pkt->set(alphaAccess->cpuStack[cpunum]); 1825602Snate@binkert.org else 1832SN/A panic("Unknown 64bit access, %#x\n", daddr); 1842SN/A } 1852SN/A DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, 1865502Snate@binkert.org pkt->get<uint64_t>()); 1872SN/A break; 1885502Snate@binkert.org default: 1895502Snate@binkert.org pkt->setBadAddress(); 1902SN/A } 1915502Snate@binkert.org pkt->makeAtomicResponse(); 1922SN/A return pioDelay; 1932SN/A} 1945502Snate@binkert.org 1955502Snate@binkert.orgTick 1965502Snate@binkert.orgAlphaConsole::write(PacketPtr pkt) 1975503Snate@binkert.org{ 1985503Snate@binkert.org assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 1995502Snate@binkert.org Addr daddr = pkt->getAddr() - pioAddr; 2005602Snate@binkert.org 2012SN/A uint64_t val = pkt->get<uint64_t>(); 2022SN/A assert(pkt->getSize() == sizeof(uint64_t)); 2032667Sstever@eecs.umich.edu 2042SN/A switch (daddr) { 2052SN/A case offsetof(AlphaAccess, diskUnit): 20610153Sandreas@sandberg.pp.se alphaAccess->diskUnit = val; 2075503Snate@binkert.org break; 2085503Snate@binkert.org 2095769Snate@binkert.org case offsetof(AlphaAccess, diskCount): 2105502Snate@binkert.org alphaAccess->diskCount = val; 2115503Snate@binkert.org break; 2125503Snate@binkert.org 2135503Snate@binkert.org case offsetof(AlphaAccess, diskPAddr): 2145503Snate@binkert.org alphaAccess->diskPAddr = val; 2155503Snate@binkert.org break; 2165503Snate@binkert.org 2175503Snate@binkert.org case offsetof(AlphaAccess, diskBlock): 2185502Snate@binkert.org alphaAccess->diskBlock = val; 2195502Snate@binkert.org break; 2205503Snate@binkert.org 2215502Snate@binkert.org case offsetof(AlphaAccess, diskOperation): 2222SN/A if (val == 0x13) 2232SN/A disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 2242667Sstever@eecs.umich.edu alphaAccess->diskCount); 2259356Snilay@cs.wisc.edu else 2269356Snilay@cs.wisc.edu panic("Invalid disk operation!"); 2279356Snilay@cs.wisc.edu 2282SN/A break; 2292667Sstever@eecs.umich.edu 2309328SAli.Saidi@ARM.com case offsetof(AlphaAccess, outputChar): 2319328SAli.Saidi@ARM.com console->out((char)(val & 0xff)); 2322667Sstever@eecs.umich.edu break; 2332667Sstever@eecs.umich.edu 2342667Sstever@eecs.umich.edu default: 2355769Snate@binkert.org int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / 2362667Sstever@eecs.umich.edu sizeof(alphaAccess->cpuStack[0]); 2372SN/A warn("%d: Trying to launch CPU number %d!", curTick, cpunum); 2385769Snate@binkert.org assert(val > 0 && "Must not access primary cpu"); 2392SN/A if (cpunum >= 0 && cpunum < 64) 2402667Sstever@eecs.umich.edu alphaAccess->cpuStack[cpunum] = val; 2412667Sstever@eecs.umich.edu else 2422SN/A panic("Unknown 64bit access, %#x\n", daddr); 2432SN/A } 244224SN/A 24510905Sandreas.sandberg@arm.com pkt->makeAtomicResponse(); 246224SN/A 247224SN/A return pioDelay; 248224SN/A} 2495769Snate@binkert.org 2505769Snate@binkert.orgvoid 251224SN/AAlphaConsole::Access::serialize(ostream &os) 252224SN/A{ 253224SN/A SERIALIZE_SCALAR(last_offset); 25410905Sandreas.sandberg@arm.com SERIALIZE_SCALAR(version); 255224SN/A SERIALIZE_SCALAR(numCPUs); 25610906Sandreas.sandberg@arm.com SERIALIZE_SCALAR(mem_size); 257224SN/A SERIALIZE_SCALAR(cpuClock); 258224SN/A SERIALIZE_SCALAR(intrClockFrequency); 259224SN/A SERIALIZE_SCALAR(kernStart); 260224SN/A SERIALIZE_SCALAR(kernEnd); 26110906Sandreas.sandberg@arm.com SERIALIZE_SCALAR(entryPoint); 2625769Snate@binkert.org SERIALIZE_SCALAR(diskUnit); 2637452SLisa.Hsu@amd.com SERIALIZE_SCALAR(diskCount); 2647452SLisa.Hsu@amd.com SERIALIZE_SCALAR(diskPAddr); 2657452SLisa.Hsu@amd.com SERIALIZE_SCALAR(diskBlock); 2667452SLisa.Hsu@amd.com SERIALIZE_SCALAR(diskOperation); 2677452SLisa.Hsu@amd.com SERIALIZE_SCALAR(outputChar); 2687452SLisa.Hsu@amd.com SERIALIZE_SCALAR(inputChar); 2697452SLisa.Hsu@amd.com SERIALIZE_ARRAY(cpuStack,64); 2707451SLisa.Hsu@amd.com} 2715769Snate@binkert.org 2727451SLisa.Hsu@amd.comvoid 2735769Snate@binkert.orgAlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) 2747452SLisa.Hsu@amd.com{ 2757452SLisa.Hsu@amd.com UNSERIALIZE_SCALAR(last_offset); 2767452SLisa.Hsu@amd.com UNSERIALIZE_SCALAR(version); 27710906Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(numCPUs); 27810906Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(mem_size); 27910906Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(cpuClock); 28010906Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(intrClockFrequency); 28110906Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(kernStart); 282224SN/A UNSERIALIZE_SCALAR(kernEnd); 283224SN/A UNSERIALIZE_SCALAR(entryPoint); 284224SN/A UNSERIALIZE_SCALAR(diskUnit); 2852SN/A UNSERIALIZE_SCALAR(diskCount); 28610905Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(diskPAddr); 2872SN/A UNSERIALIZE_SCALAR(diskBlock); 288265SN/A UNSERIALIZE_SCALAR(diskOperation); 289237SN/A UNSERIALIZE_SCALAR(outputChar); 290237SN/A UNSERIALIZE_SCALAR(inputChar); 2915502Snate@binkert.org UNSERIALIZE_ARRAY(cpuStack, 64); 2925502Snate@binkert.org} 2935503Snate@binkert.org 2945502Snate@binkert.orgvoid 2955503Snate@binkert.orgAlphaConsole::serialize(ostream &os) 2965769Snate@binkert.org{ 2975502Snate@binkert.org alphaAccess->serialize(os); 29810905Sandreas.sandberg@arm.com} 2995502Snate@binkert.org 3005502Snate@binkert.orgvoid 3015502Snate@binkert.orgAlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) 3025503Snate@binkert.org{ 3035502Snate@binkert.org alphaAccess->unserialize(cp, section); 3045502Snate@binkert.org} 3052SN/A 306237SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 307265SN/A 308265SN/A SimObjectParam<SimConsole *> sim_console; 30910905Sandreas.sandberg@arm.com SimObjectParam<SimpleDisk *> disk; 31010905Sandreas.sandberg@arm.com Param<Addr> pio_addr; 3112SN/A SimObjectParam<AlphaSystem *> system; 3122SN/A SimObjectParam<BaseCPU *> cpu; 313237SN/A SimObjectParam<Platform *> platform; 31410905Sandreas.sandberg@arm.com Param<Tick> pio_latency; 315237SN/A 316265SN/AEND_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 317265SN/A 318265SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 319270SN/A 320265SN/A INIT_PARAM(sim_console, "The Simulator Console"), 321265SN/A INIT_PARAM(disk, "Simple Disk"), 32210905Sandreas.sandberg@arm.com INIT_PARAM(pio_addr, "Device Address"), 323265SN/A INIT_PARAM(system, "system object"), 324265SN/A INIT_PARAM(cpu, "Processor"), 32510906Sandreas.sandberg@arm.com INIT_PARAM(platform, "platform"), 32610906Sandreas.sandberg@arm.com INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) 32710906Sandreas.sandberg@arm.com 32810906Sandreas.sandberg@arm.comEND_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 32910906Sandreas.sandberg@arm.com 33010906Sandreas.sandberg@arm.comCREATE_SIM_OBJECT(AlphaConsole) 331237SN/A{ 332237SN/A AlphaConsole::Params *p = new AlphaConsole::Params; 333237SN/A p->name = getInstanceName(); 3342SN/A p->platform = platform; 33510906Sandreas.sandberg@arm.com p->pio_addr = pio_addr; 33610906Sandreas.sandberg@arm.com p->pio_delay = pio_latency; 33710906Sandreas.sandberg@arm.com p->cons = sim_console; 33810906Sandreas.sandberg@arm.com p->disk = disk; 33910906Sandreas.sandberg@arm.com p->alpha_sys = system; 34010906Sandreas.sandberg@arm.com p->system = system; 34110906Sandreas.sandberg@arm.com p->cpu = cpu; 34210906Sandreas.sandberg@arm.com return new AlphaConsole(p); 34310906Sandreas.sandberg@arm.com} 3445501Snate@binkert.org 3452SN/AREGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) 3462SN/A