backdoor.cc revision 926
1/*
2 * Copyright (c) 2001-2004 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/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#include "dev/tsunami_io.hh"
53#include "sim/sim_object.hh"
54#include "targetarch/byte_swap.hh"
55
56using namespace std;
57
58AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
59                           System *system, BaseCPU *cpu, Platform *platform,
60                           int num_cpus, MemoryController *mmu, Addr a,
61                           HierParams *hier, Bus *bus)
62    : PioDevice(name), disk(d), console(cons), addr(a)
63{
64    mmu->add_child(this, Range<Addr>(addr, addr + size));
65
66    if (bus) {
67        pioInterface = newPioInterface(name, hier, bus, this,
68                                       &AlphaConsole::cacheAccess);
69        pioInterface->addAddrRange(addr, addr + size);
70    }
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 = platform->intrFrequency();
82    alphaAccess->diskUnit = 1;
83
84    alphaAccess->diskCount = 0;
85    alphaAccess->diskPAddr = 0;
86    alphaAccess->diskBlock = 0;
87    alphaAccess->diskOperation = 0;
88    alphaAccess->outputChar = 0;
89    alphaAccess->inputChar = 0;
90    alphaAccess->bootStrapImpure = 0;
91    alphaAccess->bootStrapCPU = 0;
92    alphaAccess->align2 = 0;
93}
94
95Fault
96AlphaConsole::read(MemReqPtr &req, uint8_t *data)
97{
98    memset(data, 0, req->size);
99
100    Addr daddr = req->paddr - (addr & PA_IMPL_MASK);
101
102    switch (req->size)
103    {
104        case sizeof(uint32_t):
105            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint32_t*)data);
106            switch (daddr)
107            {
108                case offsetof(AlphaAccess, last_offset):
109                    *(uint32_t*)data = alphaAccess->last_offset;
110                    break;
111                case offsetof(AlphaAccess, version):
112                    *(uint32_t*)data = alphaAccess->version;
113                    break;
114                case offsetof(AlphaAccess, numCPUs):
115                    *(uint32_t*)data = alphaAccess->numCPUs;
116                    break;
117                case offsetof(AlphaAccess, bootStrapCPU):
118                    *(uint32_t*)data = alphaAccess->bootStrapCPU;
119                    break;
120                case offsetof(AlphaAccess, intrClockFrequency):
121                    *(uint32_t*)data = alphaAccess->intrClockFrequency;
122                    break;
123                default:
124                    panic("Unknown 32bit access, %#x\n", daddr);
125            }
126            break;
127        case sizeof(uint64_t):
128            DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint64_t*)data);
129            switch (daddr)
130            {
131                case offsetof(AlphaAccess, inputChar):
132                    *(uint64_t*)data = console->console_in();
133                    break;
134                case offsetof(AlphaAccess, cpuClock):
135                    *(uint64_t*)data = alphaAccess->cpuClock;
136                    break;
137                case offsetof(AlphaAccess, mem_size):
138                    *(uint64_t*)data = alphaAccess->mem_size;
139                    break;
140                case offsetof(AlphaAccess, kernStart):
141                    *(uint64_t*)data = alphaAccess->kernStart;
142                    break;
143                case offsetof(AlphaAccess, kernEnd):
144                    *(uint64_t*)data = alphaAccess->kernEnd;
145                    break;
146                case offsetof(AlphaAccess, entryPoint):
147                    *(uint64_t*)data = alphaAccess->entryPoint;
148                    break;
149                case offsetof(AlphaAccess, diskUnit):
150                    *(uint64_t*)data = alphaAccess->diskUnit;
151                    break;
152                case offsetof(AlphaAccess, diskCount):
153                    *(uint64_t*)data = alphaAccess->diskCount;
154                    break;
155                case offsetof(AlphaAccess, diskPAddr):
156                    *(uint64_t*)data = alphaAccess->diskPAddr;
157                    break;
158                case offsetof(AlphaAccess, diskBlock):
159                    *(uint64_t*)data = alphaAccess->diskBlock;
160                    break;
161                case offsetof(AlphaAccess, diskOperation):
162                    *(uint64_t*)data = alphaAccess->diskOperation;
163                    break;
164                case offsetof(AlphaAccess, outputChar):
165                    *(uint64_t*)data = alphaAccess->outputChar;
166                    break;
167                case offsetof(AlphaAccess, bootStrapImpure):
168                    *(uint64_t*)data = alphaAccess->bootStrapImpure;
169                    break;
170                default:
171                    panic("Unknown 64bit access, %#x\n", daddr);
172            }
173            break;
174        default:
175            return Machine_Check_Fault;
176    }
177
178    return No_Fault;
179}
180
181Fault
182AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
183{
184    uint64_t val;
185
186    switch (req->size) {
187      case sizeof(uint32_t):
188        val = *(uint32_t *)data;
189        break;
190
191      case sizeof(uint64_t):
192        val = *(uint64_t *)data;
193        break;
194      default:
195        return Machine_Check_Fault;
196    }
197
198    Addr daddr = req->paddr - (addr & PA_IMPL_MASK);
199    ExecContext *other_xc;
200
201    switch (daddr) {
202      case offsetof(AlphaAccess, diskUnit):
203        alphaAccess->diskUnit = val;
204        break;
205
206      case offsetof(AlphaAccess, diskCount):
207        alphaAccess->diskCount = val;
208        break;
209
210      case offsetof(AlphaAccess, diskPAddr):
211        alphaAccess->diskPAddr = val;
212        break;
213
214      case offsetof(AlphaAccess, diskBlock):
215        alphaAccess->diskBlock = val;
216        break;
217
218      case offsetof(AlphaAccess, diskOperation):
219        if (val == 0x13)
220            disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
221                       alphaAccess->diskCount);
222        else
223            panic("Invalid disk operation!");
224
225        break;
226
227      case offsetof(AlphaAccess, outputChar):
228        console->out((char)(val & 0xff), false);
229        break;
230
231      case offsetof(AlphaAccess, bootStrapImpure):
232        alphaAccess->bootStrapImpure = val;
233        break;
234
235      case offsetof(AlphaAccess, bootStrapCPU):
236        warn("%d: Trying to launch another CPU!", curTick);
237        assert(val > 0 && "Must not access primary cpu");
238
239        other_xc = req->xc->system->execContexts[val];
240        other_xc->regs.intRegFile[16] = val;
241        other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
242        other_xc->regs.intRegFile[0] = val;
243        other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
244        other_xc->activate(); //Start the cpu
245        break;
246
247      default:
248        return Machine_Check_Fault;
249    }
250
251    return No_Fault;
252}
253
254Tick
255AlphaConsole::cacheAccess(MemReqPtr &req)
256{
257    return curTick + 1000;
258}
259
260void
261AlphaAccess::serialize(ostream &os)
262{
263    SERIALIZE_SCALAR(last_offset);
264    SERIALIZE_SCALAR(version);
265    SERIALIZE_SCALAR(numCPUs);
266    SERIALIZE_SCALAR(mem_size);
267    SERIALIZE_SCALAR(cpuClock);
268    SERIALIZE_SCALAR(intrClockFrequency);
269    SERIALIZE_SCALAR(kernStart);
270    SERIALIZE_SCALAR(kernEnd);
271    SERIALIZE_SCALAR(entryPoint);
272    SERIALIZE_SCALAR(diskUnit);
273    SERIALIZE_SCALAR(diskCount);
274    SERIALIZE_SCALAR(diskPAddr);
275    SERIALIZE_SCALAR(diskBlock);
276    SERIALIZE_SCALAR(diskOperation);
277    SERIALIZE_SCALAR(outputChar);
278    SERIALIZE_SCALAR(inputChar);
279    SERIALIZE_SCALAR(bootStrapImpure);
280    SERIALIZE_SCALAR(bootStrapCPU);
281}
282
283void
284AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
285{
286    UNSERIALIZE_SCALAR(last_offset);
287    UNSERIALIZE_SCALAR(version);
288    UNSERIALIZE_SCALAR(numCPUs);
289    UNSERIALIZE_SCALAR(mem_size);
290    UNSERIALIZE_SCALAR(cpuClock);
291    UNSERIALIZE_SCALAR(intrClockFrequency);
292    UNSERIALIZE_SCALAR(kernStart);
293    UNSERIALIZE_SCALAR(kernEnd);
294    UNSERIALIZE_SCALAR(entryPoint);
295    UNSERIALIZE_SCALAR(diskUnit);
296    UNSERIALIZE_SCALAR(diskCount);
297    UNSERIALIZE_SCALAR(diskPAddr);
298    UNSERIALIZE_SCALAR(diskBlock);
299    UNSERIALIZE_SCALAR(diskOperation);
300    UNSERIALIZE_SCALAR(outputChar);
301    UNSERIALIZE_SCALAR(inputChar);
302    UNSERIALIZE_SCALAR(bootStrapImpure);
303    UNSERIALIZE_SCALAR(bootStrapCPU);
304}
305
306void
307AlphaConsole::serialize(ostream &os)
308{
309    alphaAccess->serialize(os);
310}
311
312void
313AlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
314{
315    alphaAccess->unserialize(cp, section);
316}
317
318BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
319
320    SimObjectParam<SimConsole *> sim_console;
321    SimObjectParam<SimpleDisk *> disk;
322    Param<int> num_cpus;
323    SimObjectParam<MemoryController *> mmu;
324    Param<Addr> addr;
325    SimObjectParam<System *> system;
326    SimObjectParam<BaseCPU *> cpu;
327    SimObjectParam<Platform *> platform;
328    SimObjectParam<Bus*> io_bus;
329    SimObjectParam<HierParams *> hier;
330
331END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
332
333BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
334
335    INIT_PARAM(sim_console, "The Simulator Console"),
336    INIT_PARAM(disk, "Simple Disk"),
337    INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
338    INIT_PARAM(mmu, "Memory Controller"),
339    INIT_PARAM(addr, "Device Address"),
340    INIT_PARAM(system, "system object"),
341    INIT_PARAM(cpu, "Processor"),
342    INIT_PARAM(platform, "platform"),
343    INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
344    INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
345
346END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
347
348CREATE_SIM_OBJECT(AlphaConsole)
349{
350    return new AlphaConsole(getInstanceName(), sim_console, disk,
351                            system, cpu, platform, num_cpus, mmu,
352                            addr, hier, io_bus);
353}
354
355REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
356