backdoor.cc revision 430
1/*
2 * Copyright (c) 2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * 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/functional_mem/memory_control.hh"
47#include "sim/builder.hh"
48#include "sim/system.hh"
49
50using namespace std;
51
52AlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
53                           SimpleDisk *d, int size, System *system,
54                           BaseCPU *cpu, TlaserClock *clock, int num_cpus,
55                           Addr addr, Addr mask, MemoryController *mmu)
56    : MmapDevice(name, addr, mask, mmu), disk(d), console(cons)
57{
58    consoleData = new uint8_t[size];
59    memset(consoleData, 0, size);
60
61    alphaAccess->last_offset = size - 1;
62    alphaAccess->kernStart = system->getKernelStart();
63    alphaAccess->kernEnd = system->getKernelEnd();
64    alphaAccess->entryPoint = system->getKernelEntry();
65
66    alphaAccess->version = ALPHA_ACCESS_VERSION;
67    alphaAccess->numCPUs = num_cpus;
68    alphaAccess->mem_size = system->physmem->getSize();
69    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
70    alphaAccess->intrClockFrequency = clock->frequency();
71
72    alphaAccess->diskUnit = 1;
73}
74
75Fault
76AlphaConsole::read(MemReqPtr req, uint8_t *data)
77{
78    memset(data, 0, req->size);
79    uint64_t val;
80
81    Addr daddr = req->paddr & addr_mask;
82    switch (daddr) {
83      case offsetof(AlphaAccess, inputChar):
84        val = console->in();
85        break;
86
87      default:
88        val = *(uint64_t *)(consoleData + daddr);
89        break;
90    }
91
92    DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, val);
93
94    switch (req->size) {
95      case sizeof(uint32_t):
96        *(uint32_t *)data = (uint32_t)val;
97        break;
98
99      case sizeof(uint64_t):
100        *(uint64_t *)data = val;
101        break;
102
103      default:
104        return Machine_Check_Fault;
105    }
106
107
108    return No_Fault;
109}
110
111Fault
112AlphaConsole::write(MemReqPtr req, const uint8_t *data)
113{
114    uint64_t val;
115
116    switch (req->size) {
117      case sizeof(uint32_t):
118        val = *(uint32_t *)data;
119        break;
120
121      case sizeof(uint64_t):
122        val = *(uint64_t *)data;
123        break;
124      default:
125        return Machine_Check_Fault;
126    }
127
128    Addr daddr = req->paddr & addr_mask;
129    ExecContext *other_xc;
130
131    switch (daddr) {
132      case offsetof(AlphaAccess, diskUnit):
133        alphaAccess->diskUnit = val;
134        break;
135
136      case offsetof(AlphaAccess, diskCount):
137        alphaAccess->diskCount = val;
138        break;
139
140      case offsetof(AlphaAccess, diskPAddr):
141        alphaAccess->diskPAddr = val;
142        break;
143
144      case offsetof(AlphaAccess, diskBlock):
145        alphaAccess->diskBlock = val;
146        break;
147
148      case offsetof(AlphaAccess, diskOperation):
149        if (val == 0x13)
150            disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
151                       alphaAccess->diskCount);
152        else
153            panic("Invalid disk operation!");
154
155        break;
156
157      case offsetof(AlphaAccess, outputChar):
158        console->out((char)(val & 0xff), false);
159        break;
160
161      case offsetof(AlphaAccess, bootStrapImpure):
162        alphaAccess->bootStrapImpure = val;
163        break;
164
165      case offsetof(AlphaAccess, bootStrapCPU):
166        warn("%d: Trying to launch another CPU!", curTick);
167        assert(val > 0 && "Must not access primary cpu");
168
169        other_xc = req->xc->system->execContexts[val];
170        other_xc->regs.intRegFile[16] = val;
171        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
172        other_xc->regs.intRegFile[0] = val;
173        other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
174        other_xc->activate(); //Start the cpu
175        break;
176
177      default:
178        return Machine_Check_Fault;
179    }
180
181    return No_Fault;
182}
183
184void
185AlphaAccess::serialize(ostream &os)
186{
187    SERIALIZE_SCALAR(last_offset);
188    SERIALIZE_SCALAR(version);
189    SERIALIZE_SCALAR(numCPUs);
190    SERIALIZE_SCALAR(mem_size);
191    SERIALIZE_SCALAR(cpuClock);
192    SERIALIZE_SCALAR(intrClockFrequency);
193    SERIALIZE_SCALAR(kernStart);
194    SERIALIZE_SCALAR(kernEnd);
195    SERIALIZE_SCALAR(entryPoint);
196    SERIALIZE_SCALAR(diskUnit);
197    SERIALIZE_SCALAR(diskCount);
198    SERIALIZE_SCALAR(diskPAddr);
199    SERIALIZE_SCALAR(diskBlock);
200    SERIALIZE_SCALAR(diskOperation);
201    SERIALIZE_SCALAR(outputChar);
202    SERIALIZE_SCALAR(inputChar);
203    SERIALIZE_SCALAR(bootStrapImpure);
204    SERIALIZE_SCALAR(bootStrapCPU);
205}
206
207void
208AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
209{
210    UNSERIALIZE_SCALAR(last_offset);
211    UNSERIALIZE_SCALAR(version);
212    UNSERIALIZE_SCALAR(numCPUs);
213    UNSERIALIZE_SCALAR(mem_size);
214    UNSERIALIZE_SCALAR(cpuClock);
215    UNSERIALIZE_SCALAR(intrClockFrequency);
216    UNSERIALIZE_SCALAR(kernStart);
217    UNSERIALIZE_SCALAR(kernEnd);
218    UNSERIALIZE_SCALAR(entryPoint);
219    UNSERIALIZE_SCALAR(diskUnit);
220    UNSERIALIZE_SCALAR(diskCount);
221    UNSERIALIZE_SCALAR(diskPAddr);
222    UNSERIALIZE_SCALAR(diskBlock);
223    UNSERIALIZE_SCALAR(diskOperation);
224    UNSERIALIZE_SCALAR(outputChar);
225    UNSERIALIZE_SCALAR(inputChar);
226    UNSERIALIZE_SCALAR(bootStrapImpure);
227    UNSERIALIZE_SCALAR(bootStrapCPU);
228}
229
230void
231AlphaConsole::serialize(ostream &os)
232{
233    alphaAccess->serialize(os);
234}
235
236void
237AlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
238{
239    alphaAccess->unserialize(cp, section);
240}
241
242BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
243
244    SimObjectParam<SimConsole *> sim_console;
245    SimObjectParam<SimpleDisk *> disk;
246    Param<int> size;
247    Param<int> num_cpus;
248    SimObjectParam<MemoryController *> mmu;
249    Param<Addr> addr;
250    Param<Addr> mask;
251    SimObjectParam<System *> system;
252    SimObjectParam<BaseCPU *> cpu;
253    SimObjectParam<TlaserClock *> clock;
254
255END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
256
257BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
258
259    INIT_PARAM(sim_console, "The Simulator Console"),
260    INIT_PARAM(disk, "Simple Disk"),
261    INIT_PARAM_DFLT(size, "AlphaConsole size", sizeof(AlphaAccess)),
262    INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
263    INIT_PARAM(mmu, "Memory Controller"),
264    INIT_PARAM(addr, "Device Address"),
265    INIT_PARAM(mask, "Address Mask"),
266    INIT_PARAM(system, "system object"),
267    INIT_PARAM(cpu, "Processor"),
268    INIT_PARAM(clock, "Turbolaser Clock")
269
270END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
271
272CREATE_SIM_OBJECT(AlphaConsole)
273{
274    return  new AlphaConsole(getInstanceName(), sim_console,
275                             disk, size, system,
276                             cpu, clock, num_cpus,
277                             addr, mask, mmu);
278}
279
280REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
281