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 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 "dev/alpha/console.hh"
48 #include "dev/platform.hh"
49 #include "dev/simconsole.hh"
50 #include "dev/simple_disk.hh"
51 #include "mem/packet.hh"
52 #include "mem/packet_access.hh"
53 #include "mem/physical.hh"
54 #include "params/AlphaConsole.hh"
55 #include "sim/sim_object.hh"
58 using namespace AlphaISA
;
60 AlphaConsole::AlphaConsole(const Params
*p
)
61 : BasicPioDevice(p
), disk(p
->disk
), console(p
->sim_console
),
62 system(p
->system
), cpu(p
->cpu
)
65 pioSize
= sizeof(struct AlphaAccess
);
67 alphaAccess
= new Access();
68 alphaAccess
->last_offset
= pioSize
- 1;
70 alphaAccess
->version
= ALPHA_ACCESS_VERSION
;
71 alphaAccess
->diskUnit
= 1;
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
));
84 AlphaConsole::startup()
86 system
->setAlphaAccess(pioAddr
);
87 alphaAccess
->numCPUs
= system
->getNumCPUs();
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();
97 AlphaConsole::read(PacketPtr pkt
)
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?
105 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
107 Addr daddr
= pkt
->getAddr() - pioAddr
;
110 pkt
->makeAtomicResponse();
112 switch (pkt
->getSize())
114 case sizeof(uint32_t):
117 case offsetof(AlphaAccess
, last_offset
):
118 pkt
->set(alphaAccess
->last_offset
);
120 case offsetof(AlphaAccess
, version
):
121 pkt
->set(alphaAccess
->version
);
123 case offsetof(AlphaAccess
, numCPUs
):
124 pkt
->set(alphaAccess
->numCPUs
);
126 case offsetof(AlphaAccess
, intrClockFrequency
):
127 pkt
->set(alphaAccess
->intrClockFrequency
);
130 /* Old console code read in everyting as a 32bit int
131 * we now break that for better error checking.
133 pkt
->setBadAddress();
135 DPRINTF(AlphaConsole
, "read: offset=%#x val=%#x\n", daddr
,
136 pkt
->get
<uint32_t>());
138 case sizeof(uint64_t):
141 case offsetof(AlphaAccess
, inputChar
):
142 pkt
->set(console
->console_in());
144 case offsetof(AlphaAccess
, cpuClock
):
145 pkt
->set(alphaAccess
->cpuClock
);
147 case offsetof(AlphaAccess
, mem_size
):
148 pkt
->set(alphaAccess
->mem_size
);
150 case offsetof(AlphaAccess
, kernStart
):
151 pkt
->set(alphaAccess
->kernStart
);
153 case offsetof(AlphaAccess
, kernEnd
):
154 pkt
->set(alphaAccess
->kernEnd
);
156 case offsetof(AlphaAccess
, entryPoint
):
157 pkt
->set(alphaAccess
->entryPoint
);
159 case offsetof(AlphaAccess
, diskUnit
):
160 pkt
->set(alphaAccess
->diskUnit
);
162 case offsetof(AlphaAccess
, diskCount
):
163 pkt
->set(alphaAccess
->diskCount
);
165 case offsetof(AlphaAccess
, diskPAddr
):
166 pkt
->set(alphaAccess
->diskPAddr
);
168 case offsetof(AlphaAccess
, diskBlock
):
169 pkt
->set(alphaAccess
->diskBlock
);
171 case offsetof(AlphaAccess
, diskOperation
):
172 pkt
->set(alphaAccess
->diskOperation
);
174 case offsetof(AlphaAccess
, outputChar
):
175 pkt
->set(alphaAccess
->outputChar
);
178 int cpunum
= (daddr
- offsetof(AlphaAccess
, cpuStack
)) /
179 sizeof(alphaAccess
->cpuStack
[0]);
181 if (cpunum
>= 0 && cpunum
< 64)
182 pkt
->set(alphaAccess
->cpuStack
[cpunum
]);
184 panic("Unknown 64bit access, %#x\n", daddr
);
186 DPRINTF(AlphaConsole
, "read: offset=%#x val=%#x\n", daddr
,
187 pkt
->get
<uint64_t>());
190 pkt
->setBadAddress();
196 AlphaConsole::write(PacketPtr pkt
)
198 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
199 Addr daddr
= pkt
->getAddr() - pioAddr
;
201 uint64_t val
= pkt
->get
<uint64_t>();
202 assert(pkt
->getSize() == sizeof(uint64_t));
205 case offsetof(AlphaAccess
, diskUnit
):
206 alphaAccess
->diskUnit
= val
;
209 case offsetof(AlphaAccess
, diskCount
):
210 alphaAccess
->diskCount
= val
;
213 case offsetof(AlphaAccess
, diskPAddr
):
214 alphaAccess
->diskPAddr
= val
;
217 case offsetof(AlphaAccess
, diskBlock
):
218 alphaAccess
->diskBlock
= val
;
221 case offsetof(AlphaAccess
, diskOperation
):
223 disk
->read(alphaAccess
->diskPAddr
, alphaAccess
->diskBlock
,
224 alphaAccess
->diskCount
);
226 panic("Invalid disk operation!");
230 case offsetof(AlphaAccess
, outputChar
):
231 console
->out((char)(val
& 0xff));
235 int cpunum
= (daddr
- offsetof(AlphaAccess
, cpuStack
)) /
236 sizeof(alphaAccess
->cpuStack
[0]);
237 warn("%d: Trying to launch CPU number %d!", curTick
, cpunum
);
238 assert(val
> 0 && "Must not access primary cpu");
239 if (cpunum
>= 0 && cpunum
< 64)
240 alphaAccess
->cpuStack
[cpunum
] = val
;
242 panic("Unknown 64bit access, %#x\n", daddr
);
245 pkt
->makeAtomicResponse();
251 AlphaConsole::Access::serialize(ostream
&os
)
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);
273 AlphaConsole::Access::unserialize(Checkpoint
*cp
, const std::string
§ion
)
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);
295 AlphaConsole::serialize(ostream
&os
)
297 alphaAccess
->serialize(os
);
301 AlphaConsole::unserialize(Checkpoint
*cp
, const std::string
§ion
)
303 alphaAccess
->unserialize(cp
, section
);
307 AlphaConsoleParams::create()
309 return new AlphaConsole(this);