backdoor.cc revision 545
112839Sgabeblack@google.com/*
212839Sgabeblack@google.com * Copyright (c) 2003 The Regents of The University of Michigan
312839Sgabeblack@google.com * All rights reserved.
412839Sgabeblack@google.com *
512839Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612839Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712839Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812839Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912839Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012839Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112839Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212839Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312839Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412839Sgabeblack@google.com * this software without specific prior written permission.
1512839Sgabeblack@google.com *
1612839Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712839Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812839Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912839Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012839Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112839Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212839Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312839Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412839Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512839Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612839Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712839Sgabeblack@google.com */
2812839Sgabeblack@google.com
2912839Sgabeblack@google.com/* @file
3012839Sgabeblack@google.com * System Console Definition
3112993Sgabeblack@google.com */
3212993Sgabeblack@google.com
3312993Sgabeblack@google.com#include <cstddef>
3413129Sgabeblack@google.com#include <cstdio>
3512993Sgabeblack@google.com#include <string>
3612839Sgabeblack@google.com
3712839Sgabeblack@google.com#include "base/inifile.hh"
3812993Sgabeblack@google.com#include "base/str.hh"	// for to_number()
3912993Sgabeblack@google.com#include "base/trace.hh"
4012993Sgabeblack@google.com#include "cpu/base_cpu.hh"
4112993Sgabeblack@google.com#include "cpu/exec_context.hh"
4212993Sgabeblack@google.com#include "dev/alpha_console.hh"
4312993Sgabeblack@google.com#include "dev/console.hh"
4412993Sgabeblack@google.com#include "dev/simple_disk.hh"
4512993Sgabeblack@google.com#include "dev/tlaser_clock.hh"
4612993Sgabeblack@google.com#include "mem/bus/bus.hh"
4712993Sgabeblack@google.com#include "mem/bus/pio_interface.hh"
4812993Sgabeblack@google.com#include "mem/bus/pio_interface_impl.hh"
4912993Sgabeblack@google.com#include "mem/functional_mem/memory_control.hh"
5012993Sgabeblack@google.com#include "sim/builder.hh"
5112993Sgabeblack@google.com#include "sim/system.hh"
5212993Sgabeblack@google.com
5312993Sgabeblack@google.comusing namespace std;
5412993Sgabeblack@google.com
5512993Sgabeblack@google.comAlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
5612993Sgabeblack@google.com                           System *system, BaseCPU *cpu, TlaserClock *clock,
5712993Sgabeblack@google.com                           int num_cpus, MemoryController *mmu, Addr a,
5812993Sgabeblack@google.com                           HierParams *hier, Bus *bus)
5912993Sgabeblack@google.com    : PioDevice(name), disk(d), console(cons), addr(a)
6012993Sgabeblack@google.com{
6112993Sgabeblack@google.com    mmu->add_child(this, Range<Addr>(addr, addr + size));
6212993Sgabeblack@google.com
6312993Sgabeblack@google.com    if (bus) {
6412993Sgabeblack@google.com        pioInterface = newPioInterface(name, hier, bus, this,
6513131Sgabeblack@google.com                                       &AlphaConsole::cacheAccess);
6612993Sgabeblack@google.com        pioInterface->setAddrRange(addr, addr + size);
6713131Sgabeblack@google.com    }
6812993Sgabeblack@google.com
6913194Sgabeblack@google.com    consoleData = new uint8_t[size];
7013194Sgabeblack@google.com    memset(consoleData, 0, size);
7112993Sgabeblack@google.com
7212993Sgabeblack@google.com    alphaAccess->last_offset = size - 1;
7313207Sgabeblack@google.com    alphaAccess->kernStart = system->getKernelStart();
7412993Sgabeblack@google.com    alphaAccess->kernEnd = system->getKernelEnd();
7512993Sgabeblack@google.com    alphaAccess->entryPoint = system->getKernelEntry();
7613207Sgabeblack@google.com
7712993Sgabeblack@google.com    alphaAccess->version = ALPHA_ACCESS_VERSION;
7812993Sgabeblack@google.com    alphaAccess->numCPUs = num_cpus;
7913207Sgabeblack@google.com    alphaAccess->mem_size = system->physmem->size();
8012993Sgabeblack@google.com    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
8112993Sgabeblack@google.com    alphaAccess->intrClockFrequency = clock->frequency();
8213207Sgabeblack@google.com
8312993Sgabeblack@google.com    alphaAccess->diskUnit = 1;
8412993Sgabeblack@google.com}
8513207Sgabeblack@google.com
8612993Sgabeblack@google.comFault
8712993Sgabeblack@google.comAlphaConsole::read(MemReqPtr &req, uint8_t *data)
8813180Sgabeblack@google.com{
8913180Sgabeblack@google.com    memset(data, 0, req->size);
9013180Sgabeblack@google.com    uint64_t val;
9113180Sgabeblack@google.com
9213180Sgabeblack@google.com    Addr daddr = req->paddr - addr;
9313180Sgabeblack@google.com
9413180Sgabeblack@google.com    switch (daddr) {
9513180Sgabeblack@google.com      case offsetof(AlphaAccess, inputChar):
9613180Sgabeblack@google.com        val = console->console_in();
9713180Sgabeblack@google.com        break;
9812993Sgabeblack@google.com
9912993Sgabeblack@google.com      default:
10012993Sgabeblack@google.com        val = *(uint64_t *)(consoleData + daddr);
10112993Sgabeblack@google.com        break;
10212993Sgabeblack@google.com    }
10312993Sgabeblack@google.com
10412993Sgabeblack@google.com    DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, val);
10512839Sgabeblack@google.com
10612839Sgabeblack@google.com    switch (req->size) {
10712839Sgabeblack@google.com      case sizeof(uint32_t):
10812993Sgabeblack@google.com        *(uint32_t *)data = (uint32_t)val;
10912993Sgabeblack@google.com        break;
11012993Sgabeblack@google.com
11112839Sgabeblack@google.com      case sizeof(uint64_t):
11212839Sgabeblack@google.com        *(uint64_t *)data = val;
11312839Sgabeblack@google.com        break;
11412839Sgabeblack@google.com
11512839Sgabeblack@google.com      default:
11612993Sgabeblack@google.com        return Machine_Check_Fault;
11712839Sgabeblack@google.com    }
11812839Sgabeblack@google.com
11912839Sgabeblack@google.com
12012839Sgabeblack@google.com    return No_Fault;
12112839Sgabeblack@google.com}
12212993Sgabeblack@google.com
12312839Sgabeblack@google.comFault
12412839Sgabeblack@google.comAlphaConsole::write(MemReqPtr &req, const uint8_t *data)
12512839Sgabeblack@google.com{
12612993Sgabeblack@google.com    uint64_t val;
12712839Sgabeblack@google.com
12812993Sgabeblack@google.com    switch (req->size) {
12912839Sgabeblack@google.com      case sizeof(uint32_t):
13012839Sgabeblack@google.com        val = *(uint32_t *)data;
13112839Sgabeblack@google.com        break;
13212839Sgabeblack@google.com
13312993Sgabeblack@google.com      case sizeof(uint64_t):
13412839Sgabeblack@google.com        val = *(uint64_t *)data;
13512993Sgabeblack@google.com        break;
13612839Sgabeblack@google.com      default:
13712839Sgabeblack@google.com        return Machine_Check_Fault;
13812839Sgabeblack@google.com    }
13912993Sgabeblack@google.com
14012839Sgabeblack@google.com    Addr daddr = req->paddr - addr;
14112993Sgabeblack@google.com    ExecContext *other_xc;
14212839Sgabeblack@google.com
14312839Sgabeblack@google.com    switch (daddr) {
14412839Sgabeblack@google.com      case offsetof(AlphaAccess, diskUnit):
14512993Sgabeblack@google.com        alphaAccess->diskUnit = val;
14612839Sgabeblack@google.com        break;
14712993Sgabeblack@google.com
14812839Sgabeblack@google.com      case offsetof(AlphaAccess, diskCount):
14912839Sgabeblack@google.com        alphaAccess->diskCount = val;
15012839Sgabeblack@google.com        break;
15112993Sgabeblack@google.com
15212839Sgabeblack@google.com      case offsetof(AlphaAccess, diskPAddr):
15312993Sgabeblack@google.com        alphaAccess->diskPAddr = val;
15412839Sgabeblack@google.com        break;
15512839Sgabeblack@google.com
15612839Sgabeblack@google.com      case offsetof(AlphaAccess, diskBlock):
15712993Sgabeblack@google.com        alphaAccess->diskBlock = val;
15812839Sgabeblack@google.com        break;
15912993Sgabeblack@google.com
16012839Sgabeblack@google.com      case offsetof(AlphaAccess, diskOperation):
16112839Sgabeblack@google.com        if (val == 0x13)
16212839Sgabeblack@google.com            disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
16312839Sgabeblack@google.com                       alphaAccess->diskCount);
16412839Sgabeblack@google.com        else
16512839Sgabeblack@google.com            panic("Invalid disk operation!");
16612839Sgabeblack@google.com
16712839Sgabeblack@google.com        break;
16812839Sgabeblack@google.com
16912839Sgabeblack@google.com      case offsetof(AlphaAccess, outputChar):
17012839Sgabeblack@google.com        console->out((char)(val & 0xff), false);
17112839Sgabeblack@google.com        break;
17212839Sgabeblack@google.com
17312839Sgabeblack@google.com      case offsetof(AlphaAccess, bootStrapImpure):
17412839Sgabeblack@google.com        alphaAccess->bootStrapImpure = val;
17512839Sgabeblack@google.com        break;
17612839Sgabeblack@google.com
17712839Sgabeblack@google.com      case offsetof(AlphaAccess, bootStrapCPU):
17812839Sgabeblack@google.com        warn("%d: Trying to launch another CPU!", curTick);
17912839Sgabeblack@google.com        assert(val > 0 && "Must not access primary cpu");
18012839Sgabeblack@google.com
18112839Sgabeblack@google.com        other_xc = req->xc->system->execContexts[val];
18212839Sgabeblack@google.com        other_xc->regs.intRegFile[16] = val;
18312839Sgabeblack@google.com        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
18412839Sgabeblack@google.com        other_xc->regs.intRegFile[0] = val;
18512839Sgabeblack@google.com        other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
18612839Sgabeblack@google.com        other_xc->activate(); //Start the cpu
18712839Sgabeblack@google.com        break;
18812839Sgabeblack@google.com
18912839Sgabeblack@google.com      default:
19012839Sgabeblack@google.com        return Machine_Check_Fault;
19112839Sgabeblack@google.com    }
19212839Sgabeblack@google.com
19312839Sgabeblack@google.com    return No_Fault;
19412839Sgabeblack@google.com}
19512839Sgabeblack@google.com
19612839Sgabeblack@google.comTick
19712839Sgabeblack@google.comAlphaConsole::cacheAccess(MemReqPtr &req)
19812839Sgabeblack@google.com{
19912839Sgabeblack@google.com    return curTick + 1000;
20012839Sgabeblack@google.com}
20112839Sgabeblack@google.com
20212839Sgabeblack@google.comvoid
20312839Sgabeblack@google.comAlphaAccess::serialize(ostream &os)
20412839Sgabeblack@google.com{
20512839Sgabeblack@google.com    SERIALIZE_SCALAR(last_offset);
20612839Sgabeblack@google.com    SERIALIZE_SCALAR(version);
20712839Sgabeblack@google.com    SERIALIZE_SCALAR(numCPUs);
20812839Sgabeblack@google.com    SERIALIZE_SCALAR(mem_size);
20912839Sgabeblack@google.com    SERIALIZE_SCALAR(cpuClock);
21012839Sgabeblack@google.com    SERIALIZE_SCALAR(intrClockFrequency);
21112839Sgabeblack@google.com    SERIALIZE_SCALAR(kernStart);
21212839Sgabeblack@google.com    SERIALIZE_SCALAR(kernEnd);
21312839Sgabeblack@google.com    SERIALIZE_SCALAR(entryPoint);
21412839Sgabeblack@google.com    SERIALIZE_SCALAR(diskUnit);
21512839Sgabeblack@google.com    SERIALIZE_SCALAR(diskCount);
21612839Sgabeblack@google.com    SERIALIZE_SCALAR(diskPAddr);
21712839Sgabeblack@google.com    SERIALIZE_SCALAR(diskBlock);
21812839Sgabeblack@google.com    SERIALIZE_SCALAR(diskOperation);
21912839Sgabeblack@google.com    SERIALIZE_SCALAR(outputChar);
22012839Sgabeblack@google.com    SERIALIZE_SCALAR(inputChar);
22112839Sgabeblack@google.com    SERIALIZE_SCALAR(bootStrapImpure);
22212839Sgabeblack@google.com    SERIALIZE_SCALAR(bootStrapCPU);
22312839Sgabeblack@google.com}
22412839Sgabeblack@google.com
22512839Sgabeblack@google.comvoid
22612839Sgabeblack@google.comAlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
22712839Sgabeblack@google.com{
22812839Sgabeblack@google.com    UNSERIALIZE_SCALAR(last_offset);
22912839Sgabeblack@google.com    UNSERIALIZE_SCALAR(version);
23012839Sgabeblack@google.com    UNSERIALIZE_SCALAR(numCPUs);
23112839Sgabeblack@google.com    UNSERIALIZE_SCALAR(mem_size);
23212839Sgabeblack@google.com    UNSERIALIZE_SCALAR(cpuClock);
23312839Sgabeblack@google.com    UNSERIALIZE_SCALAR(intrClockFrequency);
23412839Sgabeblack@google.com    UNSERIALIZE_SCALAR(kernStart);
235    UNSERIALIZE_SCALAR(kernEnd);
236    UNSERIALIZE_SCALAR(entryPoint);
237    UNSERIALIZE_SCALAR(diskUnit);
238    UNSERIALIZE_SCALAR(diskCount);
239    UNSERIALIZE_SCALAR(diskPAddr);
240    UNSERIALIZE_SCALAR(diskBlock);
241    UNSERIALIZE_SCALAR(diskOperation);
242    UNSERIALIZE_SCALAR(outputChar);
243    UNSERIALIZE_SCALAR(inputChar);
244    UNSERIALIZE_SCALAR(bootStrapImpure);
245    UNSERIALIZE_SCALAR(bootStrapCPU);
246}
247
248void
249AlphaConsole::serialize(ostream &os)
250{
251    alphaAccess->serialize(os);
252}
253
254void
255AlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
256{
257    alphaAccess->unserialize(cp, section);
258}
259
260BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
261
262    SimObjectParam<SimConsole *> sim_console;
263    SimObjectParam<SimpleDisk *> disk;
264    Param<int> num_cpus;
265    SimObjectParam<MemoryController *> mmu;
266    Param<Addr> addr;
267    SimObjectParam<System *> system;
268    SimObjectParam<BaseCPU *> cpu;
269    SimObjectParam<TlaserClock *> clock;
270    SimObjectParam<Bus*> io_bus;
271    SimObjectParam<HierParams *> hier;
272
273END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
274
275BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
276
277    INIT_PARAM(sim_console, "The Simulator Console"),
278    INIT_PARAM(disk, "Simple Disk"),
279    INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
280    INIT_PARAM(mmu, "Memory Controller"),
281    INIT_PARAM(addr, "Device Address"),
282    INIT_PARAM(system, "system object"),
283    INIT_PARAM(cpu, "Processor"),
284    INIT_PARAM(clock, "Turbolaser Clock"),
285    INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
286    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
287
288END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
289
290CREATE_SIM_OBJECT(AlphaConsole)
291{
292    return new AlphaConsole(getInstanceName(), sim_console, disk,
293                            system, cpu, clock, num_cpus, mmu,
294                            addr, hier, io_bus);
295}
296
297REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
298