2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
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.
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.
28 * Authors: Nathan Binkert
35 * Alpha Console Backdoor Definition
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 "debug/AlphaBackdoor.hh"
48 #include "dev/alpha/backdoor.hh"
49 #include "dev/platform.hh"
50 #include "dev/simple_disk.hh"
51 #include "dev/terminal.hh"
52 #include "mem/packet.hh"
53 #include "mem/packet_access.hh"
54 #include "mem/physical.hh"
55 #include "params/AlphaBackdoor.hh"
56 #include "sim/sim_object.hh"
59 using namespace AlphaISA
;
61 AlphaBackdoor::AlphaBackdoor(const Params
*p
)
62 : BasicPioDevice(p
), disk(p
->disk
), terminal(p
->terminal
),
63 system(p
->system
), cpu(p
->cpu
)
66 pioSize
= sizeof(struct AlphaAccess
);
68 alphaAccess
= new Access();
69 alphaAccess
->last_offset
= pioSize
- 1;
71 alphaAccess
->version
= ALPHA_ACCESS_VERSION
;
72 alphaAccess
->diskUnit
= 1;
74 alphaAccess
->diskCount
= 0;
75 alphaAccess
->diskPAddr
= 0;
76 alphaAccess
->diskBlock
= 0;
77 alphaAccess
->diskOperation
= 0;
78 alphaAccess
->outputChar
= 0;
79 alphaAccess
->inputChar
= 0;
80 std::memset(alphaAccess
->cpuStack
, 0, sizeof(alphaAccess
->cpuStack
));
85 AlphaBackdoor::startup()
87 system
->setAlphaAccess(pioAddr
);
88 alphaAccess
->numCPUs
= system
->numContexts();
89 alphaAccess
->kernStart
= system
->getKernelStart();
90 alphaAccess
->kernEnd
= system
->getKernelEnd();
91 alphaAccess
->entryPoint
= system
->getKernelEntry();
92 alphaAccess
->mem_size
= system
->physmem
->size();
93 alphaAccess
->cpuClock
= cpu
->frequency() / 1000000; // In MHz
94 alphaAccess
->intrClockFrequency
= params()->platform
->intrFrequency();
98 AlphaBackdoor::read(PacketPtr pkt
)
101 /** XXX Do we want to push the addr munging to a bus brige or something? So
102 * the device has it's physical address and then the bridge adds on whatever
103 * machine dependent address swizzle is required?
106 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
108 Addr daddr
= pkt
->getAddr() - pioAddr
;
111 pkt
->makeAtomicResponse();
113 switch (pkt
->getSize())
115 case sizeof(uint32_t):
118 case offsetof(AlphaAccess
, last_offset
):
119 pkt
->set(alphaAccess
->last_offset
);
121 case offsetof(AlphaAccess
, version
):
122 pkt
->set(alphaAccess
->version
);
124 case offsetof(AlphaAccess
, numCPUs
):
125 pkt
->set(alphaAccess
->numCPUs
);
127 case offsetof(AlphaAccess
, intrClockFrequency
):
128 pkt
->set(alphaAccess
->intrClockFrequency
);
131 /* Old console code read in everyting as a 32bit int
132 * we now break that for better error checking.
134 pkt
->setBadAddress();
136 DPRINTF(AlphaBackdoor
, "read: offset=%#x val=%#x\n", daddr
,
137 pkt
->get
<uint32_t>());
139 case sizeof(uint64_t):
142 case offsetof(AlphaAccess
, inputChar
):
143 pkt
->set(terminal
->console_in());
145 case offsetof(AlphaAccess
, cpuClock
):
146 pkt
->set(alphaAccess
->cpuClock
);
148 case offsetof(AlphaAccess
, mem_size
):
149 pkt
->set(alphaAccess
->mem_size
);
151 case offsetof(AlphaAccess
, kernStart
):
152 pkt
->set(alphaAccess
->kernStart
);
154 case offsetof(AlphaAccess
, kernEnd
):
155 pkt
->set(alphaAccess
->kernEnd
);
157 case offsetof(AlphaAccess
, entryPoint
):
158 pkt
->set(alphaAccess
->entryPoint
);
160 case offsetof(AlphaAccess
, diskUnit
):
161 pkt
->set(alphaAccess
->diskUnit
);
163 case offsetof(AlphaAccess
, diskCount
):
164 pkt
->set(alphaAccess
->diskCount
);
166 case offsetof(AlphaAccess
, diskPAddr
):
167 pkt
->set(alphaAccess
->diskPAddr
);
169 case offsetof(AlphaAccess
, diskBlock
):
170 pkt
->set(alphaAccess
->diskBlock
);
172 case offsetof(AlphaAccess
, diskOperation
):
173 pkt
->set(alphaAccess
->diskOperation
);
175 case offsetof(AlphaAccess
, outputChar
):
176 pkt
->set(alphaAccess
->outputChar
);
179 int cpunum
= (daddr
- offsetof(AlphaAccess
, cpuStack
)) /
180 sizeof(alphaAccess
->cpuStack
[0]);
182 if (cpunum
>= 0 && cpunum
< 64)
183 pkt
->set(alphaAccess
->cpuStack
[cpunum
]);
185 panic("Unknown 64bit access, %#x\n", daddr
);
187 DPRINTF(AlphaBackdoor
, "read: offset=%#x val=%#x\n", daddr
,
188 pkt
->get
<uint64_t>());
191 pkt
->setBadAddress();
197 AlphaBackdoor::write(PacketPtr pkt
)
199 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
200 Addr daddr
= pkt
->getAddr() - pioAddr
;
202 uint64_t val
= pkt
->get
<uint64_t>();
203 assert(pkt
->getSize() == sizeof(uint64_t));
206 case offsetof(AlphaAccess
, diskUnit
):
207 alphaAccess
->diskUnit
= val
;
210 case offsetof(AlphaAccess
, diskCount
):
211 alphaAccess
->diskCount
= val
;
214 case offsetof(AlphaAccess
, diskPAddr
):
215 alphaAccess
->diskPAddr
= val
;
218 case offsetof(AlphaAccess
, diskBlock
):
219 alphaAccess
->diskBlock
= val
;
222 case offsetof(AlphaAccess
, diskOperation
):
224 disk
->read(alphaAccess
->diskPAddr
, alphaAccess
->diskBlock
,
225 alphaAccess
->diskCount
);
227 panic("Invalid disk operation!");
231 case offsetof(AlphaAccess
, outputChar
):
232 terminal
->out((char)(val
& 0xff));
236 int cpunum
= (daddr
- offsetof(AlphaAccess
, cpuStack
)) /
237 sizeof(alphaAccess
->cpuStack
[0]);
238 inform("Launching CPU %d @ %d", cpunum
, curTick());
239 assert(val
> 0 && "Must not access primary cpu");
240 if (cpunum
>= 0 && cpunum
< 64)
241 alphaAccess
->cpuStack
[cpunum
] = val
;
243 panic("Unknown 64bit access, %#x\n", daddr
);
246 pkt
->makeAtomicResponse();
252 AlphaBackdoor::Access::serialize(ostream
&os
)
254 SERIALIZE_SCALAR(last_offset
);
255 SERIALIZE_SCALAR(version
);
256 SERIALIZE_SCALAR(numCPUs
);
257 SERIALIZE_SCALAR(mem_size
);
258 SERIALIZE_SCALAR(cpuClock
);
259 SERIALIZE_SCALAR(intrClockFrequency
);
260 SERIALIZE_SCALAR(kernStart
);
261 SERIALIZE_SCALAR(kernEnd
);
262 SERIALIZE_SCALAR(entryPoint
);
263 SERIALIZE_SCALAR(diskUnit
);
264 SERIALIZE_SCALAR(diskCount
);
265 SERIALIZE_SCALAR(diskPAddr
);
266 SERIALIZE_SCALAR(diskBlock
);
267 SERIALIZE_SCALAR(diskOperation
);
268 SERIALIZE_SCALAR(outputChar
);
269 SERIALIZE_SCALAR(inputChar
);
270 SERIALIZE_ARRAY(cpuStack
,64);
274 AlphaBackdoor::Access::unserialize(Checkpoint
*cp
, const std::string
§ion
)
276 UNSERIALIZE_SCALAR(last_offset
);
277 UNSERIALIZE_SCALAR(version
);
278 UNSERIALIZE_SCALAR(numCPUs
);
279 UNSERIALIZE_SCALAR(mem_size
);
280 UNSERIALIZE_SCALAR(cpuClock
);
281 UNSERIALIZE_SCALAR(intrClockFrequency
);
282 UNSERIALIZE_SCALAR(kernStart
);
283 UNSERIALIZE_SCALAR(kernEnd
);
284 UNSERIALIZE_SCALAR(entryPoint
);
285 UNSERIALIZE_SCALAR(diskUnit
);
286 UNSERIALIZE_SCALAR(diskCount
);
287 UNSERIALIZE_SCALAR(diskPAddr
);
288 UNSERIALIZE_SCALAR(diskBlock
);
289 UNSERIALIZE_SCALAR(diskOperation
);
290 UNSERIALIZE_SCALAR(outputChar
);
291 UNSERIALIZE_SCALAR(inputChar
);
292 UNSERIALIZE_ARRAY(cpuStack
, 64);
296 AlphaBackdoor::serialize(ostream
&os
)
298 alphaAccess
->serialize(os
);
302 AlphaBackdoor::unserialize(Checkpoint
*cp
, const std::string
§ion
)
304 alphaAccess
->unserialize(cp
, section
);
308 AlphaBackdoorParams::create()
310 return new AlphaBackdoor(this);