backdoor.cc revision 430
12SN/A/*
21762SN/A * Copyright (c) 2003 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292SN/A/* @file
302SN/A * System Console Definition
312SN/A */
322SN/A
332SN/A#include <cstddef>
348229Snate@binkert.org#include <cstdio>
358229Snate@binkert.org#include <string>
362SN/A
378229Snate@binkert.org#include "base/inifile.hh"
384167Sbinkertn@umich.edu#include "base/str.hh"	// for to_number()
392SN/A#include "base/trace.hh"
40252SN/A#include "cpu/base_cpu.hh"
411872SN/A#include "cpu/exec_context.hh"
42252SN/A#include "dev/alpha_console.hh"
432SN/A#include "dev/console.hh"
442SN/A#include "dev/simple_disk.hh"
452SN/A#include "dev/tlaser_clock.hh"
462SN/A#include "mem/functional_mem/memory_control.hh"
472SN/A#include "sim/builder.hh"
482SN/A#include "sim/system.hh"
492SN/A
502SN/Ausing namespace std;
512SN/A
522SN/AAlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
532SN/A                           SimpleDisk *d, int size, System *system,
542SN/A                           BaseCPU *cpu, TlaserClock *clock, int num_cpus,
552SN/A                           Addr addr, Addr mask, MemoryController *mmu)
562SN/A    : MmapDevice(name, addr, mask, mmu), disk(d), console(cons)
572SN/A{
582SN/A    consoleData = new uint8_t[size];
592SN/A    memset(consoleData, 0, size);
60251SN/A
61251SN/A    alphaAccess->last_offset = size - 1;
62252SN/A    alphaAccess->kernStart = system->getKernelStart();
63252SN/A    alphaAccess->kernEnd = system->getKernelEnd();
64252SN/A    alphaAccess->entryPoint = system->getKernelEntry();
652SN/A
662SN/A    alphaAccess->version = ALPHA_ACCESS_VERSION;
672SN/A    alphaAccess->numCPUs = num_cpus;
682SN/A    alphaAccess->mem_size = system->physmem->getSize();
692SN/A    alphaAccess->cpuClock = cpu->getFreq() / 1000000;
702SN/A    alphaAccess->intrClockFrequency = clock->frequency();
712SN/A
722SN/A    alphaAccess->diskUnit = 1;
732SN/A}
742SN/A
752SN/AFault
762SN/AAlphaConsole::read(MemReqPtr req, uint8_t *data)
772SN/A{
782SN/A    memset(data, 0, req->size);
792SN/A    uint64_t val;
802SN/A
812SN/A    Addr daddr = req->paddr & addr_mask;
822SN/A    switch (daddr) {
832SN/A      case offsetof(AlphaAccess, inputChar):
842SN/A        val = console->in();
852SN/A        break;
862SN/A
872SN/A      default:
882SN/A        val = *(uint64_t *)(consoleData + daddr);
892SN/A        break;
902SN/A    }
912SN/A
922SN/A    DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, val);
932SN/A
942SN/A    switch (req->size) {
952SN/A      case sizeof(uint32_t):
962SN/A        *(uint32_t *)data = (uint32_t)val;
972SN/A        break;
982SN/A
992SN/A      case sizeof(uint64_t):
1002SN/A        *(uint64_t *)data = val;
1012SN/A        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