backdoor.cc revision 1634
1695SN/A/*
21762SN/A * Copyright (c) 2001-2004 The Regents of The University of Michigan
3695SN/A * All rights reserved.
4695SN/A *
5695SN/A * Redistribution and use in source and binary forms, with or without
6695SN/A * modification, are permitted provided that the following conditions are
7695SN/A * met: redistributions of source code must retain the above copyright
8695SN/A * notice, this list of conditions and the following disclaimer;
9695SN/A * redistributions in binary form must reproduce the above copyright
10695SN/A * notice, this list of conditions and the following disclaimer in the
11695SN/A * documentation and/or other materials provided with the distribution;
12695SN/A * neither the name of the copyright holders nor the names of its
13695SN/A * contributors may be used to endorse or promote products derived from
14695SN/A * this software without specific prior written permission.
15695SN/A *
16695SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17695SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18695SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19695SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20695SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21695SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22695SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23695SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24695SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25695SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26695SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
29695SN/A/* @file
30695SN/A * System Console Definition
31873SN/A */
32873SN/A
33873SN/A#include <cstddef>
34873SN/A#include <cstdio>
353918Ssaidi@eecs.umich.edu#include <string>
368230Snate@binkert.org
373918Ssaidi@eecs.umich.edu#include "base/inifile.hh"
383918Ssaidi@eecs.umich.edu#include "base/str.hh"	// for to_number()
396129Snate@binkert.org#include "base/trace.hh"
406129Snate@binkert.org#include "cpu/base_cpu.hh"
418230Snate@binkert.org#include "cpu/exec_context.hh"
426129Snate@binkert.org#include "dev/alpha_console.hh"
436129Snate@binkert.org#include "dev/simconsole.hh"
448229Snate@binkert.org#include "dev/simple_disk.hh"
45695SN/A#include "dev/tlaser_clock.hh"
462621SN/A#include "mem/bus/bus.hh"
47695SN/A#include "mem/bus/pio_interface.hh"
48695SN/A#include "mem/bus/pio_interface_impl.hh"
498229Snate@binkert.org#include "mem/functional_mem/memory_control.hh"
508229Snate@binkert.org#include "sim/builder.hh"
516129Snate@binkert.org#include "sim/system.hh"
52695SN/A#include "dev/tsunami_io.hh"
536129Snate@binkert.org#include "sim/sim_object.hh"
54695SN/A#include "targetarch/byte_swap.hh"
55695SN/A
56695SN/Ausing namespace std;
57695SN/A
58695SN/AAlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
59695SN/A                           System *s, BaseCPU *c, Platform *p,
60695SN/A                           int num_cpus, MemoryController *mmu, Addr a,
61695SN/A                           HierParams *hier, Bus *bus)
62695SN/A    : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a)
63695SN/A{
64695SN/A    mmu->add_child(this, RangeSize(addr, size));
65695SN/A
66695SN/A    if (bus) {
67695SN/A        pioInterface = newPioInterface(name, hier, bus, this,
68695SN/A                                       &AlphaConsole::cacheAccess);
69695SN/A        pioInterface->addAddrRange(RangeSize(addr, size));
70695SN/A    }
71695SN/A
72695SN/A    alphaAccess = new AlphaAccess;
73695SN/A    alphaAccess->last_offset = size - 1;
74695SN/A
75695SN/A    alphaAccess->version = ALPHA_ACCESS_VERSION;
76695SN/A    alphaAccess->numCPUs = num_cpus;
77695SN/A    alphaAccess->diskUnit = 1;
78695SN/A
79729SN/A    alphaAccess->diskCount = 0;
80695SN/A    alphaAccess->diskPAddr = 0;
816129Snate@binkert.org    alphaAccess->diskBlock = 0;
826129Snate@binkert.org    alphaAccess->diskOperation = 0;
83695SN/A    alphaAccess->outputChar = 0;
846126Snate@binkert.org    alphaAccess->inputChar = 0;
85695SN/A    alphaAccess->bootStrapImpure = 0;
86695SN/A    alphaAccess->bootStrapCPU = 0;
87695SN/A    alphaAccess->align2 = 0;
88695SN/A}
896126Snate@binkert.org
90695SN/Avoid
91695SN/AAlphaConsole::init()
92695SN/A{
93695SN/A    alphaAccess->kernStart = system->getKernelStart();
94695SN/A    alphaAccess->kernEnd = system->getKernelEnd();
956126Snate@binkert.org    alphaAccess->entryPoint = system->getKernelEntry();
96695SN/A    alphaAccess->mem_size = system->physmem->size();
97695SN/A    alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz
98695SN/A    alphaAccess->intrClockFrequency = platform->intrFrequency();
99695SN/A}
100695SN/A
101695SN/AFault
102695SN/AAlphaConsole::read(MemReqPtr &req, uint8_t *data)
103695SN/A{
104695SN/A    memset(data, 0, req->size);
105695SN/A
106695SN/A    Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
107695SN/A
108695SN/A    switch (req->size)
109695SN/A    {
110695SN/A        case sizeof(uint32_t):
111695SN/A            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint32_t*)data);
112695SN/A            switch (daddr)
113695SN/A            {
114695SN/A                case offsetof(AlphaAccess, last_offset):
115695SN/A                    *(uint32_t*)data = alphaAccess->last_offset;
116695SN/A                    break;
1175581Ssaidi@eecs.umich.edu                case offsetof(AlphaAccess, version):
1185581Ssaidi@eecs.umich.edu                    *(uint32_t*)data = alphaAccess->version;
119695SN/A                    break;
120695SN/A                case offsetof(AlphaAccess, numCPUs):
121695SN/A                    *(uint32_t*)data = alphaAccess->numCPUs;
122695SN/A                    break;
123695SN/A                case offsetof(AlphaAccess, bootStrapCPU):
124695SN/A                    *(uint32_t*)data = alphaAccess->bootStrapCPU;
125695SN/A                    break;
126695SN/A                case offsetof(AlphaAccess, intrClockFrequency):
127695SN/A                    *(uint32_t*)data = alphaAccess->intrClockFrequency;
128695SN/A                    break;
1295581Ssaidi@eecs.umich.edu                default:
1305581Ssaidi@eecs.umich.edu                    // Old console code read in everyting as a 32bit int
131695SN/A                    *(uint32_t*)data = *(uint32_t*)(consoleData + daddr);
132695SN/A
133695SN/A            }
134695SN/A            break;
135695SN/A        case sizeof(uint64_t):
1365581Ssaidi@eecs.umich.edu            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint64_t*)data);
137695SN/A            switch (daddr)
138695SN/A            {
139695SN/A                case offsetof(AlphaAccess, inputChar):
1408296Snate@binkert.org                    *(uint64_t*)data = console->console_in();
141695SN/A                    break;
142695SN/A                case offsetof(AlphaAccess, cpuClock):
1438296Snate@binkert.org                    *(uint64_t*)data = alphaAccess->cpuClock;
1448296Snate@binkert.org                    break;
1458296Snate@binkert.org                case offsetof(AlphaAccess, mem_size):
1468296Snate@binkert.org                    *(uint64_t*)data = alphaAccess->mem_size;
1478296Snate@binkert.org                    break;
148695SN/A                case offsetof(AlphaAccess, kernStart):
149695SN/A                    *(uint64_t*)data = alphaAccess->kernStart;
150695SN/A                    break;
151695SN/A                case offsetof(AlphaAccess, kernEnd):
152695SN/A                    *(uint64_t*)data = alphaAccess->kernEnd;
1535886Snate@binkert.org                    break;
154695SN/A                case offsetof(AlphaAccess, entryPoint):
1557462Snate@binkert.org                    *(uint64_t*)data = alphaAccess->entryPoint;
156695SN/A                    break;
157695SN/A                case offsetof(AlphaAccess, diskUnit):
1585886Snate@binkert.org                    *(uint64_t*)data = alphaAccess->diskUnit;
159695SN/A                    break;
160695SN/A                case offsetof(AlphaAccess, diskCount):
161695SN/A                    *(uint64_t*)data = alphaAccess->diskCount;
162695SN/A                    break;
163695SN/A                case offsetof(AlphaAccess, diskPAddr):
164695SN/A                    *(uint64_t*)data = alphaAccess->diskPAddr;
1656126Snate@binkert.org                    break;
166695SN/A                case offsetof(AlphaAccess, diskBlock):
167695SN/A                    *(uint64_t*)data = alphaAccess->diskBlock;
168695SN/A                    break;
1698946Sandreas.hansson@arm.com                case offsetof(AlphaAccess, diskOperation):
170695SN/A                    *(uint64_t*)data = alphaAccess->diskOperation;
171695SN/A                    break;
172695SN/A                case offsetof(AlphaAccess, outputChar):
173695SN/A                    *(uint64_t*)data = alphaAccess->outputChar;
174695SN/A                    break;
175695SN/A                case offsetof(AlphaAccess, bootStrapImpure):
176695SN/A                    *(uint64_t*)data = alphaAccess->bootStrapImpure;
177695SN/A                    break;
178695SN/A                default:
1798982Snate@binkert.org                    panic("Unknown 64bit access, %#x\n", daddr);
180695SN/A            }
181695SN/A            break;
182695SN/A        default:
183695SN/A            return Machine_Check_Fault;
184695SN/A    }
185695SN/A
186695SN/A    return No_Fault;
187695SN/A}
188695SN/A
189695SN/AFault
1906130Snate@binkert.orgAlphaConsole::write(MemReqPtr &req, const uint8_t *data)
191695SN/A{
192695SN/A    uint64_t val;
193695SN/A
194695SN/A    switch (req->size) {
195695SN/A      case sizeof(uint32_t):
1966211Snate@binkert.org        val = *(uint32_t *)data;
1979743Snilay@cs.wisc.edu        break;
198695SN/A
199695SN/A      case sizeof(uint64_t):
200695SN/A        val = *(uint64_t *)data;
2016211Snate@binkert.org        break;
2026211Snate@binkert.org      default:
2036211Snate@binkert.org        return Machine_Check_Fault;
2046211Snate@binkert.org    }
2056211Snate@binkert.org
2066211Snate@binkert.org    Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
2076211Snate@binkert.org    ExecContext *other_xc;
2086211Snate@binkert.org
2096211Snate@binkert.org    switch (daddr) {
2106211Snate@binkert.org      case offsetof(AlphaAccess, diskUnit):
2119743Snilay@cs.wisc.edu        alphaAccess->diskUnit = val;
212695SN/A        break;
21310011Snilay@cs.wisc.edu
2148946Sandreas.hansson@arm.com      case offsetof(AlphaAccess, diskCount):
215695SN/A        alphaAccess->diskCount = val;
216695SN/A        break;
217695SN/A
218695SN/A      case offsetof(AlphaAccess, diskPAddr):
2198946Sandreas.hansson@arm.com        alphaAccess->diskPAddr = val;
220695SN/A        break;
221695SN/A
2228946Sandreas.hansson@arm.com      case offsetof(AlphaAccess, diskBlock):
223695SN/A        alphaAccess->diskBlock = val;
224695SN/A        break;
2259743Snilay@cs.wisc.edu
2269743Snilay@cs.wisc.edu      case offsetof(AlphaAccess, diskOperation):
2279743Snilay@cs.wisc.edu        if (val == 0x13)
2289743Snilay@cs.wisc.edu            disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
2299743Snilay@cs.wisc.edu                       alphaAccess->diskCount);
2309743Snilay@cs.wisc.edu        else
231695SN/A            panic("Invalid disk operation!");
2329743Snilay@cs.wisc.edu
2339743Snilay@cs.wisc.edu        break;
2349743Snilay@cs.wisc.edu
2359743Snilay@cs.wisc.edu      case offsetof(AlphaAccess, outputChar):
2369743Snilay@cs.wisc.edu        console->out((char)(val & 0xff));
237695SN/A        break;
238695SN/A
239695SN/A      case offsetof(AlphaAccess, bootStrapImpure):
240695SN/A        alphaAccess->bootStrapImpure = val;
241695SN/A        break;
242695SN/A
2438243Sbradley.danofsky@amd.com      case offsetof(AlphaAccess, bootStrapCPU):
244695SN/A        warn("%d: Trying to launch another CPU!", curTick);
245695SN/A        assert(val > 0 && "Must not access primary cpu");
246695SN/A
2476130Snate@binkert.org        other_xc = req->xc->system->execContexts[val];
248695SN/A        other_xc->regs.intRegFile[16] = val;
249695SN/A        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
250695SN/A        other_xc->regs.intRegFile[0] = val;
251695SN/A        other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
2529839Sandreas.hansson@arm.com        other_xc->activate(); //Start the cpu
253695SN/A        break;
254695SN/A
255695SN/A      default:
256695SN/A        return Machine_Check_Fault;
257695SN/A    }
258695SN/A
259695SN/A    return No_Fault;
2605599Snate@binkert.org}
261695SN/A
262695SN/ATick
2636130Snate@binkert.orgAlphaConsole::cacheAccess(MemReqPtr &req)
2645599Snate@binkert.org{
265695SN/A    return curTick + 1000;
266695SN/A}
267695SN/A
268695SN/Avoid
2698243Sbradley.danofsky@amd.comAlphaAccess::serialize(ostream &os)
270695SN/A{
271695SN/A    SERIALIZE_SCALAR(last_offset);
272695SN/A    SERIALIZE_SCALAR(version);
273695SN/A    SERIALIZE_SCALAR(numCPUs);
274695SN/A    SERIALIZE_SCALAR(mem_size);
275695SN/A    SERIALIZE_SCALAR(cpuClock);
276695SN/A    SERIALIZE_SCALAR(intrClockFrequency);
2776211Snate@binkert.org    SERIALIZE_SCALAR(kernStart);
2786211Snate@binkert.org    SERIALIZE_SCALAR(kernEnd);
279695SN/A    SERIALIZE_SCALAR(entryPoint);
280695SN/A    SERIALIZE_SCALAR(diskUnit);
281695SN/A    SERIALIZE_SCALAR(diskCount);
282695SN/A    SERIALIZE_SCALAR(diskPAddr);
2839828Ssascha.bischoff@arm.com    SERIALIZE_SCALAR(diskBlock);
2849828Ssascha.bischoff@arm.com    SERIALIZE_SCALAR(diskOperation);
2859828Ssascha.bischoff@arm.com    SERIALIZE_SCALAR(outputChar);
2869828Ssascha.bischoff@arm.com    SERIALIZE_SCALAR(inputChar);
2879828Ssascha.bischoff@arm.com    SERIALIZE_SCALAR(bootStrapImpure);
288695SN/A    SERIALIZE_SCALAR(bootStrapCPU);
289695SN/A}
2906126Snate@binkert.org
2916126Snate@binkert.orgvoid
292695SN/AAlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
2939743Snilay@cs.wisc.edu{
2949743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(last_offset);
2959743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(version);
2969743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(numCPUs);
2979743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(mem_size);
298695SN/A    UNSERIALIZE_SCALAR(cpuClock);
2999743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(intrClockFrequency);
3009743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(kernStart);
3019743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(kernEnd);
302695SN/A    UNSERIALIZE_SCALAR(entryPoint);
3039743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(diskUnit);
3049743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(diskCount);
3059743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(diskPAddr);
3069743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(diskBlock);
3079743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(diskOperation);
3089743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(outputChar);
3099743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(inputChar);
3109743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(bootStrapImpure);
3119743Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(bootStrapCPU);
3129743Snilay@cs.wisc.edu}
3139743Snilay@cs.wisc.edu
3149743Snilay@cs.wisc.eduvoid
3159743Snilay@cs.wisc.eduAlphaConsole::serialize(ostream &os)
3169743Snilay@cs.wisc.edu{
3176126Snate@binkert.org    alphaAccess->serialize(os);
318695SN/A}
3196130Snate@binkert.org
3206126Snate@binkert.orgvoid
3216126Snate@binkert.orgAlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
3226126Snate@binkert.org{
3236126Snate@binkert.org    alphaAccess->unserialize(cp, section);
3246126Snate@binkert.org}
3256126Snate@binkert.org
326695SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
327695SN/A
328695SN/A    SimObjectParam<SimConsole *> sim_console;
329695SN/A    SimObjectParam<SimpleDisk *> disk;
330695SN/A    Param<int> num_cpus;
331695SN/A    SimObjectParam<MemoryController *> mmu;
3328243Sbradley.danofsky@amd.com    Param<Addr> addr;
333695SN/A    SimObjectParam<System *> system;
3346130Snate@binkert.org    SimObjectParam<BaseCPU *> cpu;
335695SN/A    SimObjectParam<Platform *> platform;
336695SN/A    SimObjectParam<Bus*> io_bus;
337695SN/A    Param<Tick> pio_latency;
3386004Snate@binkert.org    SimObjectParam<HierParams *> hier;
3396004Snate@binkert.org
3406128Snate@binkert.orgEND_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
3416128Snate@binkert.org
3427505Snate@binkert.orgBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
343695SN/A
344695SN/A    INIT_PARAM(sim_console, "The Simulator Console"),
345695SN/A    INIT_PARAM(disk, "Simple Disk"),
3466128Snate@binkert.org    INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
3476004Snate@binkert.org    INIT_PARAM(mmu, "Memory Controller"),
3486004Snate@binkert.org    INIT_PARAM(addr, "Device Address"),
3497505Snate@binkert.org    INIT_PARAM(system, "system object"),
3506004Snate@binkert.org    INIT_PARAM(cpu, "Processor"),
3516004Snate@binkert.org    INIT_PARAM(platform, "platform"),
3526128Snate@binkert.org    INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
3536004Snate@binkert.org    INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
3546004Snate@binkert.org    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
3557505Snate@binkert.org
3566004Snate@binkert.orgEND_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
3576004Snate@binkert.org
3586004Snate@binkert.orgCREATE_SIM_OBJECT(AlphaConsole)
3596004Snate@binkert.org{
3606004Snate@binkert.org    return new AlphaConsole(getInstanceName(), sim_console, disk,
3616004Snate@binkert.org                            system, cpu, platform, num_cpus, mmu,
3626004Snate@binkert.org                            addr, hier, io_bus);
3636004Snate@binkert.org}
3646004Snate@binkert.org
3657505Snate@binkert.orgREGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
3666004Snate@binkert.org