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/alpha/tsunami.hh"
50 #include "dev/alpha/tsunami_cchip.hh"
51 #include "dev/alpha/tsunami_io.hh"
52 #include "dev/platform.hh"
53 #include "dev/simple_disk.hh"
54 #include "dev/terminal.hh"
55 #include "mem/packet.hh"
56 #include "mem/packet_access.hh"
57 #include "mem/physical.hh"
58 #include "params/AlphaBackdoor.hh"
59 #include "sim/sim_object.hh"
62 using namespace AlphaISA
;
64 AlphaBackdoor::AlphaBackdoor(const Params
*p
)
65 : BasicPioDevice(p
), disk(p
->disk
), terminal(p
->terminal
),
66 system(p
->system
), cpu(p
->cpu
)
69 pioSize
= sizeof(struct AlphaAccess
);
71 alphaAccess
= new Access();
72 alphaAccess
->last_offset
= pioSize
- 1;
74 alphaAccess
->version
= ALPHA_ACCESS_VERSION
;
75 alphaAccess
->diskUnit
= 1;
77 alphaAccess
->diskCount
= 0;
78 alphaAccess
->diskPAddr
= 0;
79 alphaAccess
->diskBlock
= 0;
80 alphaAccess
->diskOperation
= 0;
81 alphaAccess
->outputChar
= 0;
82 alphaAccess
->inputChar
= 0;
83 std::memset(alphaAccess
->cpuStack
, 0, sizeof(alphaAccess
->cpuStack
));
88 AlphaBackdoor::startup()
90 system
->setAlphaAccess(pioAddr
);
91 alphaAccess
->numCPUs
= system
->numContexts();
92 alphaAccess
->kernStart
= system
->getKernelStart();
93 alphaAccess
->kernEnd
= system
->getKernelEnd();
94 alphaAccess
->entryPoint
= system
->getKernelEntry();
95 alphaAccess
->mem_size
= system
->physmem
->size();
96 alphaAccess
->cpuClock
= cpu
->frequency() / 1000000; // In MHz
97 Tsunami
*tsunami
= dynamic_cast<Tsunami
*>(params()->platform
);
99 fatal("Platform is not Tsunami.\n");
100 alphaAccess
->intrClockFrequency
= tsunami
->io
->frequency();
104 AlphaBackdoor::read(PacketPtr pkt
)
107 /** XXX Do we want to push the addr munging to a bus brige or something? So
108 * the device has it's physical address and then the bridge adds on whatever
109 * machine dependent address swizzle is required?
112 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
114 Addr daddr
= pkt
->getAddr() - pioAddr
;
117 pkt
->makeAtomicResponse();
119 switch (pkt
->getSize())
121 case sizeof(uint32_t):
124 case offsetof(AlphaAccess
, last_offset
):
125 pkt
->set(alphaAccess
->last_offset
);
127 case offsetof(AlphaAccess
, version
):
128 pkt
->set(alphaAccess
->version
);
130 case offsetof(AlphaAccess
, numCPUs
):
131 pkt
->set(alphaAccess
->numCPUs
);
133 case offsetof(AlphaAccess
, intrClockFrequency
):
134 pkt
->set(alphaAccess
->intrClockFrequency
);
137 /* Old console code read in everyting as a 32bit int
138 * we now break that for better error checking.
140 pkt
->setBadAddress();
142 DPRINTF(AlphaBackdoor
, "read: offset=%#x val=%#x\n", daddr
,
143 pkt
->get
<uint32_t>());
145 case sizeof(uint64_t):
148 case offsetof(AlphaAccess
, inputChar
):
149 pkt
->set(terminal
->console_in());
151 case offsetof(AlphaAccess
, cpuClock
):
152 pkt
->set(alphaAccess
->cpuClock
);
154 case offsetof(AlphaAccess
, mem_size
):
155 pkt
->set(alphaAccess
->mem_size
);
157 case offsetof(AlphaAccess
, kernStart
):
158 pkt
->set(alphaAccess
->kernStart
);
160 case offsetof(AlphaAccess
, kernEnd
):
161 pkt
->set(alphaAccess
->kernEnd
);
163 case offsetof(AlphaAccess
, entryPoint
):
164 pkt
->set(alphaAccess
->entryPoint
);
166 case offsetof(AlphaAccess
, diskUnit
):
167 pkt
->set(alphaAccess
->diskUnit
);
169 case offsetof(AlphaAccess
, diskCount
):
170 pkt
->set(alphaAccess
->diskCount
);
172 case offsetof(AlphaAccess
, diskPAddr
):
173 pkt
->set(alphaAccess
->diskPAddr
);
175 case offsetof(AlphaAccess
, diskBlock
):
176 pkt
->set(alphaAccess
->diskBlock
);
178 case offsetof(AlphaAccess
, diskOperation
):
179 pkt
->set(alphaAccess
->diskOperation
);
181 case offsetof(AlphaAccess
, outputChar
):
182 pkt
->set(alphaAccess
->outputChar
);
185 int cpunum
= (daddr
- offsetof(AlphaAccess
, cpuStack
)) /
186 sizeof(alphaAccess
->cpuStack
[0]);
188 if (cpunum
>= 0 && cpunum
< 64)
189 pkt
->set(alphaAccess
->cpuStack
[cpunum
]);
191 panic("Unknown 64bit access, %#x\n", daddr
);
193 DPRINTF(AlphaBackdoor
, "read: offset=%#x val=%#x\n", daddr
,
194 pkt
->get
<uint64_t>());
197 pkt
->setBadAddress();
203 AlphaBackdoor::write(PacketPtr pkt
)
205 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
206 Addr daddr
= pkt
->getAddr() - pioAddr
;
208 uint64_t val
= pkt
->get
<uint64_t>();
209 assert(pkt
->getSize() == sizeof(uint64_t));
212 case offsetof(AlphaAccess
, diskUnit
):
213 alphaAccess
->diskUnit
= val
;
216 case offsetof(AlphaAccess
, diskCount
):
217 alphaAccess
->diskCount
= val
;
220 case offsetof(AlphaAccess
, diskPAddr
):
221 alphaAccess
->diskPAddr
= val
;
224 case offsetof(AlphaAccess
, diskBlock
):
225 alphaAccess
->diskBlock
= val
;
228 case offsetof(AlphaAccess
, diskOperation
):
230 disk
->read(alphaAccess
->diskPAddr
, alphaAccess
->diskBlock
,
231 alphaAccess
->diskCount
);
233 panic("Invalid disk operation!");
237 case offsetof(AlphaAccess
, outputChar
):
238 terminal
->out((char)(val
& 0xff));
242 int cpunum
= (daddr
- offsetof(AlphaAccess
, cpuStack
)) /
243 sizeof(alphaAccess
->cpuStack
[0]);
244 inform("Launching CPU %d @ %d", cpunum
, curTick());
245 assert(val
> 0 && "Must not access primary cpu");
246 if (cpunum
>= 0 && cpunum
< 64)
247 alphaAccess
->cpuStack
[cpunum
] = val
;
249 panic("Unknown 64bit access, %#x\n", daddr
);
252 pkt
->makeAtomicResponse();
258 AlphaBackdoor::Access::serialize(ostream
&os
)
260 SERIALIZE_SCALAR(last_offset
);
261 SERIALIZE_SCALAR(version
);
262 SERIALIZE_SCALAR(numCPUs
);
263 SERIALIZE_SCALAR(mem_size
);
264 SERIALIZE_SCALAR(cpuClock
);
265 SERIALIZE_SCALAR(intrClockFrequency
);
266 SERIALIZE_SCALAR(kernStart
);
267 SERIALIZE_SCALAR(kernEnd
);
268 SERIALIZE_SCALAR(entryPoint
);
269 SERIALIZE_SCALAR(diskUnit
);
270 SERIALIZE_SCALAR(diskCount
);
271 SERIALIZE_SCALAR(diskPAddr
);
272 SERIALIZE_SCALAR(diskBlock
);
273 SERIALIZE_SCALAR(diskOperation
);
274 SERIALIZE_SCALAR(outputChar
);
275 SERIALIZE_SCALAR(inputChar
);
276 SERIALIZE_ARRAY(cpuStack
,64);
280 AlphaBackdoor::Access::unserialize(Checkpoint
*cp
, const std::string
§ion
)
282 UNSERIALIZE_SCALAR(last_offset
);
283 UNSERIALIZE_SCALAR(version
);
284 UNSERIALIZE_SCALAR(numCPUs
);
285 UNSERIALIZE_SCALAR(mem_size
);
286 UNSERIALIZE_SCALAR(cpuClock
);
287 UNSERIALIZE_SCALAR(intrClockFrequency
);
288 UNSERIALIZE_SCALAR(kernStart
);
289 UNSERIALIZE_SCALAR(kernEnd
);
290 UNSERIALIZE_SCALAR(entryPoint
);
291 UNSERIALIZE_SCALAR(diskUnit
);
292 UNSERIALIZE_SCALAR(diskCount
);
293 UNSERIALIZE_SCALAR(diskPAddr
);
294 UNSERIALIZE_SCALAR(diskBlock
);
295 UNSERIALIZE_SCALAR(diskOperation
);
296 UNSERIALIZE_SCALAR(outputChar
);
297 UNSERIALIZE_SCALAR(inputChar
);
298 UNSERIALIZE_ARRAY(cpuStack
, 64);
302 AlphaBackdoor::serialize(ostream
&os
)
304 alphaAccess
->serialize(os
);
308 AlphaBackdoor::unserialize(Checkpoint
*cp
, const std::string
§ion
)
310 alphaAccess
->unserialize(cp
, section
);
314 AlphaBackdoorParams::create()
316 return new AlphaBackdoor(this);