backdoor.cc revision 545
110915Sandreas.sandberg@arm.com/*
211313Sandreas.sandberg@arm.com * Copyright (c) 2003 The Regents of The University of Michigan
311313Sandreas.sandberg@arm.com * All rights reserved.
410915Sandreas.sandberg@arm.com *
510915Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
610915Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
710915Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
810915Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/* @file
30 * System Console Definition
31 */
32
33#include <cstddef>
34#include <cstdio>
35#include <string>
36
37#include "base/inifile.hh"
38#include "base/str.hh"	// for to_number()
39#include "base/trace.hh"
40#include "cpu/base_cpu.hh"
41#include "cpu/exec_context.hh"
42#include "dev/alpha_console.hh"
43#include "dev/console.hh"
44#include "dev/simple_disk.hh"
45#include "dev/tlaser_clock.hh"
46#include "mem/bus/bus.hh"
47#include "mem/bus/pio_interface.hh"
48#include "mem/bus/pio_interface_impl.hh"
49#include "mem/functional_mem/memory_control.hh"
50#include "sim/builder.hh"
51#include "sim/system.hh"
52
53using namespace std;
54
55AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
56                           System *system, BaseCPU *cpu, TlaserClock *clock,
57                           int num_cpus, MemoryController *mmu, Addr a,
58                           HierParams *hier, Bus *bus)
59    : PioDevice(name), disk(d), console(cons), addr(a)
60{
61    mmu->add_child(this, Range<Addr>(addr, addr + size));
62
63    if (bus) {
64        pioInterface = newPioInterface(name, hier, bus, this,
65                                       &AlphaConsole::cacheAccess);
66        pioInterface->setAddrRange(addr, addr + size);
67    }
68
69    consoleData = new uint8_t[size];
70    memset(consoleData, 0, size);
71
72    alphaAccess->last_offset = size - 1;
73    alphaAccess->kernStart = system->getKernelStart();
74    alphaAccess->kernEnd = system->getKernelEnd();
75    alphaAccess->entryPoint = system->getKernelEntry();
76
77    alphaAccess->version = ALPHA_ACCESS_VERSION;
78    alphaAccess->numCPUs = num_cpus;
79    alphaAccess->mem_size = system->physmem->size();
80    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
81    alphaAccess->intrClockFrequency = clock->frequency();
82
83    alphaAccess->diskUnit = 1;
84}
85
86Fault
87AlphaConsole::read(MemReqPtr &req, uint8_t *data)
88{
89    memset(data, 0, req->size);
90    uint64_t val;
91
92    Addr daddr = req->paddr - addr;
93
94    switch (daddr) {
95      case offsetof(AlphaAccess, inputChar):
96        val = console->console_in();
97        break;
98
99      default:
100        val = *(uint64_t *)(consoleData + daddr);
101        break;
102    }
103
104    DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, val);
105
106    switch (req->size) {
107      case sizeof(uint32_t):
108        *(uint32_t *)data = (uint32_t)val;
109        break;
110
111      case sizeof(uint64_t):
112        *(uint64_t *)data = val;
113        break;
114
115      default:
116        return Machine_Check_Fault;
117    }
118
119
120    return No_Fault;
121}
122
123Fault
124AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
125{
126    uint64_t val;
127
128    switch (req->size) {
129      case sizeof(uint32_t):
130        val = *(uint32_t *)data;
131        break;
132
133      case sizeof(uint64_t):
134        val = *(uint64_t *)data;
135        break;
136      default:
137        return Machine_Check_Fault;
138    }
139
140    Addr daddr = req->paddr - addr;
141    ExecContext *other_xc;
142
143    switch (daddr) {
144      case offsetof(AlphaAccess, diskUnit):
145        alphaAccess->diskUnit = val;
146        break;
147
148      case offsetof(AlphaAccess, diskCount):
149        alphaAccess->diskCount = val;
150        break;
151
152      case offsetof(AlphaAccess, diskPAddr):
153        alphaAccess->diskPAddr = val;
154        break;
155
156      case offsetof(AlphaAccess, diskBlock):
157        alphaAccess->diskBlock = val;
158        break;
159
160      case offsetof(AlphaAccess, diskOperation):
161        if (val == 0x13)
162            disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
163                       alphaAccess->diskCount);
164        else
165            panic("Invalid disk operation!");
166
167        break;
168
169      case offsetof(AlphaAccess, outputChar):
170        console->out((char)(val & 0xff), false);
171        break;
172
173      case offsetof(AlphaAccess, bootStrapImpure):
174        alphaAccess->bootStrapImpure = val;
175        break;
176
177      case offsetof(AlphaAccess, bootStrapCPU):
178        warn("%d: Trying to launch another CPU!", curTick);
179        assert(val > 0 && "Must not access primary cpu");
180
181        other_xc = req->xc->system->execContexts[val];
182        other_xc->regs.intRegFile[16] = val;
183        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
184        other_xc->regs.intRegFile[0] = val;
185        other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
186        other_xc->activate(); //Start the cpu
187        break;
188
189      default:
190        return Machine_Check_Fault;
191    }
192
193    return No_Fault;
194}
195
196Tick
197AlphaConsole::cacheAccess(MemReqPtr &req)
198{
199    return curTick + 1000;
200}
201
202void
203AlphaAccess::serialize(ostream &os)
204{
205    SERIALIZE_SCALAR(last_offset);
206    SERIALIZE_SCALAR(version);
207    SERIALIZE_SCALAR(numCPUs);
208    SERIALIZE_SCALAR(mem_size);
209    SERIALIZE_SCALAR(cpuClock);
210    SERIALIZE_SCALAR(intrClockFrequency);
211    SERIALIZE_SCALAR(kernStart);
212    SERIALIZE_SCALAR(kernEnd);
213    SERIALIZE_SCALAR(entryPoint);
214    SERIALIZE_SCALAR(diskUnit);
215    SERIALIZE_SCALAR(diskCount);
216    SERIALIZE_SCALAR(diskPAddr);
217    SERIALIZE_SCALAR(diskBlock);
218    SERIALIZE_SCALAR(diskOperation);
219    SERIALIZE_SCALAR(outputChar);
220    SERIALIZE_SCALAR(inputChar);
221    SERIALIZE_SCALAR(bootStrapImpure);
222    SERIALIZE_SCALAR(bootStrapCPU);
223}
224
225void
226AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
227{
228    UNSERIALIZE_SCALAR(last_offset);
229    UNSERIALIZE_SCALAR(version);
230    UNSERIALIZE_SCALAR(numCPUs);
231    UNSERIALIZE_SCALAR(mem_size);
232    UNSERIALIZE_SCALAR(cpuClock);
233    UNSERIALIZE_SCALAR(intrClockFrequency);
234    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