backdoor.cc (7446:f056e1b65c13) backdoor.cc (7823:dac01f14f20f)
1/*
2 * Copyright (c) 2001-2005 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 * Authors: Nathan Binkert
29 * Ali Saidi
30 * Steve Reinhardt
31 * Erik Hallnor
32 */
33
34/** @file
35 * Alpha Console Backdoor Definition
36 */
37
38#include <cstddef>
39#include <string>
40
41#include "arch/alpha/system.hh"
42#include "base/inifile.hh"
43#include "base/str.hh"
44#include "base/trace.hh"
45#include "cpu/base.hh"
46#include "cpu/thread_context.hh"
47#include "dev/alpha/backdoor.hh"
48#include "dev/platform.hh"
49#include "dev/simple_disk.hh"
50#include "dev/terminal.hh"
51#include "mem/packet.hh"
52#include "mem/packet_access.hh"
53#include "mem/physical.hh"
54#include "params/AlphaBackdoor.hh"
55#include "sim/sim_object.hh"
56
57using namespace std;
58using namespace AlphaISA;
59
60AlphaBackdoor::AlphaBackdoor(const Params *p)
61 : BasicPioDevice(p), disk(p->disk), terminal(p->terminal),
62 system(p->system), cpu(p->cpu)
63{
64
65 pioSize = sizeof(struct AlphaAccess);
66
67 alphaAccess = new Access();
68 alphaAccess->last_offset = pioSize - 1;
69
70 alphaAccess->version = ALPHA_ACCESS_VERSION;
71 alphaAccess->diskUnit = 1;
72
73 alphaAccess->diskCount = 0;
74 alphaAccess->diskPAddr = 0;
75 alphaAccess->diskBlock = 0;
76 alphaAccess->diskOperation = 0;
77 alphaAccess->outputChar = 0;
78 alphaAccess->inputChar = 0;
79 std::memset(alphaAccess->cpuStack, 0, sizeof(alphaAccess->cpuStack));
80
81}
82
83void
84AlphaBackdoor::startup()
85{
86 system->setAlphaAccess(pioAddr);
87 alphaAccess->numCPUs = system->numContexts();
88 alphaAccess->kernStart = system->getKernelStart();
89 alphaAccess->kernEnd = system->getKernelEnd();
90 alphaAccess->entryPoint = system->getKernelEntry();
91 alphaAccess->mem_size = system->physmem->size();
92 alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz
93 alphaAccess->intrClockFrequency = params()->platform->intrFrequency();
94}
95
96Tick
97AlphaBackdoor::read(PacketPtr pkt)
98{
99
100 /** XXX Do we want to push the addr munging to a bus brige or something? So
101 * the device has it's physical address and then the bridge adds on whatever
102 * machine dependent address swizzle is required?
103 */
104
105 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
106
107 Addr daddr = pkt->getAddr() - pioAddr;
108
109 pkt->allocate();
110 pkt->makeAtomicResponse();
111
112 switch (pkt->getSize())
113 {
114 case sizeof(uint32_t):
115 switch (daddr)
116 {
117 case offsetof(AlphaAccess, last_offset):
118 pkt->set(alphaAccess->last_offset);
119 break;
120 case offsetof(AlphaAccess, version):
121 pkt->set(alphaAccess->version);
122 break;
123 case offsetof(AlphaAccess, numCPUs):
124 pkt->set(alphaAccess->numCPUs);
125 break;
126 case offsetof(AlphaAccess, intrClockFrequency):
127 pkt->set(alphaAccess->intrClockFrequency);
128 break;
129 default:
130 /* Old console code read in everyting as a 32bit int
131 * we now break that for better error checking.
132 */
133 pkt->setBadAddress();
134 }
135 DPRINTF(AlphaBackdoor, "read: offset=%#x val=%#x\n", daddr,
136 pkt->get<uint32_t>());
137 break;
138 case sizeof(uint64_t):
139 switch (daddr)
140 {
141 case offsetof(AlphaAccess, inputChar):
142 pkt->set(terminal->console_in());
143 break;
144 case offsetof(AlphaAccess, cpuClock):
145 pkt->set(alphaAccess->cpuClock);
146 break;
147 case offsetof(AlphaAccess, mem_size):
148 pkt->set(alphaAccess->mem_size);
149 break;
150 case offsetof(AlphaAccess, kernStart):
151 pkt->set(alphaAccess->kernStart);
152 break;
153 case offsetof(AlphaAccess, kernEnd):
154 pkt->set(alphaAccess->kernEnd);
155 break;
156 case offsetof(AlphaAccess, entryPoint):
157 pkt->set(alphaAccess->entryPoint);
158 break;
159 case offsetof(AlphaAccess, diskUnit):
160 pkt->set(alphaAccess->diskUnit);
161 break;
162 case offsetof(AlphaAccess, diskCount):
163 pkt->set(alphaAccess->diskCount);
164 break;
165 case offsetof(AlphaAccess, diskPAddr):
166 pkt->set(alphaAccess->diskPAddr);
167 break;
168 case offsetof(AlphaAccess, diskBlock):
169 pkt->set(alphaAccess->diskBlock);
170 break;
171 case offsetof(AlphaAccess, diskOperation):
172 pkt->set(alphaAccess->diskOperation);
173 break;
174 case offsetof(AlphaAccess, outputChar):
175 pkt->set(alphaAccess->outputChar);
176 break;
177 default:
178 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
179 sizeof(alphaAccess->cpuStack[0]);
180
181 if (cpunum >= 0 && cpunum < 64)
182 pkt->set(alphaAccess->cpuStack[cpunum]);
183 else
184 panic("Unknown 64bit access, %#x\n", daddr);
185 }
186 DPRINTF(AlphaBackdoor, "read: offset=%#x val=%#x\n", daddr,
187 pkt->get<uint64_t>());
188 break;
189 default:
190 pkt->setBadAddress();
191 }
192 return pioDelay;
193}
194
195Tick
196AlphaBackdoor::write(PacketPtr pkt)
197{
198 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
199 Addr daddr = pkt->getAddr() - pioAddr;
200
201 uint64_t val = pkt->get<uint64_t>();
202 assert(pkt->getSize() == sizeof(uint64_t));
203
204 switch (daddr) {
205 case offsetof(AlphaAccess, diskUnit):
206 alphaAccess->diskUnit = val;
207 break;
208
209 case offsetof(AlphaAccess, diskCount):
210 alphaAccess->diskCount = val;
211 break;
212
213 case offsetof(AlphaAccess, diskPAddr):
214 alphaAccess->diskPAddr = val;
215 break;
216
217 case offsetof(AlphaAccess, diskBlock):
218 alphaAccess->diskBlock = val;
219 break;
220
221 case offsetof(AlphaAccess, diskOperation):
222 if (val == 0x13)
223 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
224 alphaAccess->diskCount);
225 else
226 panic("Invalid disk operation!");
227
228 break;
229
230 case offsetof(AlphaAccess, outputChar):
231 terminal->out((char)(val & 0xff));
232 break;
233
234 default:
235 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
236 sizeof(alphaAccess->cpuStack[0]);
1/*
2 * Copyright (c) 2001-2005 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 * Authors: Nathan Binkert
29 * Ali Saidi
30 * Steve Reinhardt
31 * Erik Hallnor
32 */
33
34/** @file
35 * Alpha Console Backdoor Definition
36 */
37
38#include <cstddef>
39#include <string>
40
41#include "arch/alpha/system.hh"
42#include "base/inifile.hh"
43#include "base/str.hh"
44#include "base/trace.hh"
45#include "cpu/base.hh"
46#include "cpu/thread_context.hh"
47#include "dev/alpha/backdoor.hh"
48#include "dev/platform.hh"
49#include "dev/simple_disk.hh"
50#include "dev/terminal.hh"
51#include "mem/packet.hh"
52#include "mem/packet_access.hh"
53#include "mem/physical.hh"
54#include "params/AlphaBackdoor.hh"
55#include "sim/sim_object.hh"
56
57using namespace std;
58using namespace AlphaISA;
59
60AlphaBackdoor::AlphaBackdoor(const Params *p)
61 : BasicPioDevice(p), disk(p->disk), terminal(p->terminal),
62 system(p->system), cpu(p->cpu)
63{
64
65 pioSize = sizeof(struct AlphaAccess);
66
67 alphaAccess = new Access();
68 alphaAccess->last_offset = pioSize - 1;
69
70 alphaAccess->version = ALPHA_ACCESS_VERSION;
71 alphaAccess->diskUnit = 1;
72
73 alphaAccess->diskCount = 0;
74 alphaAccess->diskPAddr = 0;
75 alphaAccess->diskBlock = 0;
76 alphaAccess->diskOperation = 0;
77 alphaAccess->outputChar = 0;
78 alphaAccess->inputChar = 0;
79 std::memset(alphaAccess->cpuStack, 0, sizeof(alphaAccess->cpuStack));
80
81}
82
83void
84AlphaBackdoor::startup()
85{
86 system->setAlphaAccess(pioAddr);
87 alphaAccess->numCPUs = system->numContexts();
88 alphaAccess->kernStart = system->getKernelStart();
89 alphaAccess->kernEnd = system->getKernelEnd();
90 alphaAccess->entryPoint = system->getKernelEntry();
91 alphaAccess->mem_size = system->physmem->size();
92 alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz
93 alphaAccess->intrClockFrequency = params()->platform->intrFrequency();
94}
95
96Tick
97AlphaBackdoor::read(PacketPtr pkt)
98{
99
100 /** XXX Do we want to push the addr munging to a bus brige or something? So
101 * the device has it's physical address and then the bridge adds on whatever
102 * machine dependent address swizzle is required?
103 */
104
105 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
106
107 Addr daddr = pkt->getAddr() - pioAddr;
108
109 pkt->allocate();
110 pkt->makeAtomicResponse();
111
112 switch (pkt->getSize())
113 {
114 case sizeof(uint32_t):
115 switch (daddr)
116 {
117 case offsetof(AlphaAccess, last_offset):
118 pkt->set(alphaAccess->last_offset);
119 break;
120 case offsetof(AlphaAccess, version):
121 pkt->set(alphaAccess->version);
122 break;
123 case offsetof(AlphaAccess, numCPUs):
124 pkt->set(alphaAccess->numCPUs);
125 break;
126 case offsetof(AlphaAccess, intrClockFrequency):
127 pkt->set(alphaAccess->intrClockFrequency);
128 break;
129 default:
130 /* Old console code read in everyting as a 32bit int
131 * we now break that for better error checking.
132 */
133 pkt->setBadAddress();
134 }
135 DPRINTF(AlphaBackdoor, "read: offset=%#x val=%#x\n", daddr,
136 pkt->get<uint32_t>());
137 break;
138 case sizeof(uint64_t):
139 switch (daddr)
140 {
141 case offsetof(AlphaAccess, inputChar):
142 pkt->set(terminal->console_in());
143 break;
144 case offsetof(AlphaAccess, cpuClock):
145 pkt->set(alphaAccess->cpuClock);
146 break;
147 case offsetof(AlphaAccess, mem_size):
148 pkt->set(alphaAccess->mem_size);
149 break;
150 case offsetof(AlphaAccess, kernStart):
151 pkt->set(alphaAccess->kernStart);
152 break;
153 case offsetof(AlphaAccess, kernEnd):
154 pkt->set(alphaAccess->kernEnd);
155 break;
156 case offsetof(AlphaAccess, entryPoint):
157 pkt->set(alphaAccess->entryPoint);
158 break;
159 case offsetof(AlphaAccess, diskUnit):
160 pkt->set(alphaAccess->diskUnit);
161 break;
162 case offsetof(AlphaAccess, diskCount):
163 pkt->set(alphaAccess->diskCount);
164 break;
165 case offsetof(AlphaAccess, diskPAddr):
166 pkt->set(alphaAccess->diskPAddr);
167 break;
168 case offsetof(AlphaAccess, diskBlock):
169 pkt->set(alphaAccess->diskBlock);
170 break;
171 case offsetof(AlphaAccess, diskOperation):
172 pkt->set(alphaAccess->diskOperation);
173 break;
174 case offsetof(AlphaAccess, outputChar):
175 pkt->set(alphaAccess->outputChar);
176 break;
177 default:
178 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
179 sizeof(alphaAccess->cpuStack[0]);
180
181 if (cpunum >= 0 && cpunum < 64)
182 pkt->set(alphaAccess->cpuStack[cpunum]);
183 else
184 panic("Unknown 64bit access, %#x\n", daddr);
185 }
186 DPRINTF(AlphaBackdoor, "read: offset=%#x val=%#x\n", daddr,
187 pkt->get<uint64_t>());
188 break;
189 default:
190 pkt->setBadAddress();
191 }
192 return pioDelay;
193}
194
195Tick
196AlphaBackdoor::write(PacketPtr pkt)
197{
198 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
199 Addr daddr = pkt->getAddr() - pioAddr;
200
201 uint64_t val = pkt->get<uint64_t>();
202 assert(pkt->getSize() == sizeof(uint64_t));
203
204 switch (daddr) {
205 case offsetof(AlphaAccess, diskUnit):
206 alphaAccess->diskUnit = val;
207 break;
208
209 case offsetof(AlphaAccess, diskCount):
210 alphaAccess->diskCount = val;
211 break;
212
213 case offsetof(AlphaAccess, diskPAddr):
214 alphaAccess->diskPAddr = val;
215 break;
216
217 case offsetof(AlphaAccess, diskBlock):
218 alphaAccess->diskBlock = val;
219 break;
220
221 case offsetof(AlphaAccess, diskOperation):
222 if (val == 0x13)
223 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
224 alphaAccess->diskCount);
225 else
226 panic("Invalid disk operation!");
227
228 break;
229
230 case offsetof(AlphaAccess, outputChar):
231 terminal->out((char)(val & 0xff));
232 break;
233
234 default:
235 int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
236 sizeof(alphaAccess->cpuStack[0]);
237 inform("Launching CPU %d @ %d", cpunum, curTick);
237 inform("Launching CPU %d @ %d", cpunum, curTick());
238 assert(val > 0 && "Must not access primary cpu");
239 if (cpunum >= 0 && cpunum < 64)
240 alphaAccess->cpuStack[cpunum] = val;
241 else
242 panic("Unknown 64bit access, %#x\n", daddr);
243 }
244
245 pkt->makeAtomicResponse();
246
247 return pioDelay;
248}
249
250void
251AlphaBackdoor::Access::serialize(ostream &os)
252{
253 SERIALIZE_SCALAR(last_offset);
254 SERIALIZE_SCALAR(version);
255 SERIALIZE_SCALAR(numCPUs);
256 SERIALIZE_SCALAR(mem_size);
257 SERIALIZE_SCALAR(cpuClock);
258 SERIALIZE_SCALAR(intrClockFrequency);
259 SERIALIZE_SCALAR(kernStart);
260 SERIALIZE_SCALAR(kernEnd);
261 SERIALIZE_SCALAR(entryPoint);
262 SERIALIZE_SCALAR(diskUnit);
263 SERIALIZE_SCALAR(diskCount);
264 SERIALIZE_SCALAR(diskPAddr);
265 SERIALIZE_SCALAR(diskBlock);
266 SERIALIZE_SCALAR(diskOperation);
267 SERIALIZE_SCALAR(outputChar);
268 SERIALIZE_SCALAR(inputChar);
269 SERIALIZE_ARRAY(cpuStack,64);
270}
271
272void
273AlphaBackdoor::Access::unserialize(Checkpoint *cp, const std::string &section)
274{
275 UNSERIALIZE_SCALAR(last_offset);
276 UNSERIALIZE_SCALAR(version);
277 UNSERIALIZE_SCALAR(numCPUs);
278 UNSERIALIZE_SCALAR(mem_size);
279 UNSERIALIZE_SCALAR(cpuClock);
280 UNSERIALIZE_SCALAR(intrClockFrequency);
281 UNSERIALIZE_SCALAR(kernStart);
282 UNSERIALIZE_SCALAR(kernEnd);
283 UNSERIALIZE_SCALAR(entryPoint);
284 UNSERIALIZE_SCALAR(diskUnit);
285 UNSERIALIZE_SCALAR(diskCount);
286 UNSERIALIZE_SCALAR(diskPAddr);
287 UNSERIALIZE_SCALAR(diskBlock);
288 UNSERIALIZE_SCALAR(diskOperation);
289 UNSERIALIZE_SCALAR(outputChar);
290 UNSERIALIZE_SCALAR(inputChar);
291 UNSERIALIZE_ARRAY(cpuStack, 64);
292}
293
294void
295AlphaBackdoor::serialize(ostream &os)
296{
297 alphaAccess->serialize(os);
298}
299
300void
301AlphaBackdoor::unserialize(Checkpoint *cp, const std::string &section)
302{
303 alphaAccess->unserialize(cp, section);
304}
305
306AlphaBackdoor *
307AlphaBackdoorParams::create()
308{
309 return new AlphaBackdoor(this);
310}
238 assert(val > 0 && "Must not access primary cpu");
239 if (cpunum >= 0 && cpunum < 64)
240 alphaAccess->cpuStack[cpunum] = val;
241 else
242 panic("Unknown 64bit access, %#x\n", daddr);
243 }
244
245 pkt->makeAtomicResponse();
246
247 return pioDelay;
248}
249
250void
251AlphaBackdoor::Access::serialize(ostream &os)
252{
253 SERIALIZE_SCALAR(last_offset);
254 SERIALIZE_SCALAR(version);
255 SERIALIZE_SCALAR(numCPUs);
256 SERIALIZE_SCALAR(mem_size);
257 SERIALIZE_SCALAR(cpuClock);
258 SERIALIZE_SCALAR(intrClockFrequency);
259 SERIALIZE_SCALAR(kernStart);
260 SERIALIZE_SCALAR(kernEnd);
261 SERIALIZE_SCALAR(entryPoint);
262 SERIALIZE_SCALAR(diskUnit);
263 SERIALIZE_SCALAR(diskCount);
264 SERIALIZE_SCALAR(diskPAddr);
265 SERIALIZE_SCALAR(diskBlock);
266 SERIALIZE_SCALAR(diskOperation);
267 SERIALIZE_SCALAR(outputChar);
268 SERIALIZE_SCALAR(inputChar);
269 SERIALIZE_ARRAY(cpuStack,64);
270}
271
272void
273AlphaBackdoor::Access::unserialize(Checkpoint *cp, const std::string &section)
274{
275 UNSERIALIZE_SCALAR(last_offset);
276 UNSERIALIZE_SCALAR(version);
277 UNSERIALIZE_SCALAR(numCPUs);
278 UNSERIALIZE_SCALAR(mem_size);
279 UNSERIALIZE_SCALAR(cpuClock);
280 UNSERIALIZE_SCALAR(intrClockFrequency);
281 UNSERIALIZE_SCALAR(kernStart);
282 UNSERIALIZE_SCALAR(kernEnd);
283 UNSERIALIZE_SCALAR(entryPoint);
284 UNSERIALIZE_SCALAR(diskUnit);
285 UNSERIALIZE_SCALAR(diskCount);
286 UNSERIALIZE_SCALAR(diskPAddr);
287 UNSERIALIZE_SCALAR(diskBlock);
288 UNSERIALIZE_SCALAR(diskOperation);
289 UNSERIALIZE_SCALAR(outputChar);
290 UNSERIALIZE_SCALAR(inputChar);
291 UNSERIALIZE_ARRAY(cpuStack, 64);
292}
293
294void
295AlphaBackdoor::serialize(ostream &os)
296{
297 alphaAccess->serialize(os);
298}
299
300void
301AlphaBackdoor::unserialize(Checkpoint *cp, const std::string &section)
302{
303 alphaAccess->unserialize(cp, section);
304}
305
306AlphaBackdoor *
307AlphaBackdoorParams::create()
308{
309 return new AlphaBackdoor(this);
310}