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.
30 * Alpha Console Definition
37 #include "base/inifile.hh"
38 #include "base/str.hh"
39 #include "base/trace.hh"
40 #include "cpu/base.hh"
41 #include "cpu/exec_context.hh"
42 #include "dev/alpha_console.hh"
43 #include "dev/simconsole.hh"
44 #include "dev/simple_disk.hh"
45 #include "dev/tsunami_io.hh"
46 #include "mem/bus/bus.hh"
47 #include "mem/bus/pio_interface.hh"
48 #include "mem/bus/pio_interface_impl.hh"
49 #include "mem/functional/memory_control.hh"
50 #include "mem/functional/physical.hh"
51 #include "sim/builder.hh"
52 #include "sim/sim_object.hh"
53 #include "sim/system.hh"
56 using namespace AlphaISA
;
58 AlphaConsole::AlphaConsole(const string
&name
, SimConsole
*cons
, SimpleDisk
*d
,
59 System
*s
, BaseCPU
*c
, Platform
*p
,
60 MemoryController
*mmu
, Addr a
,
61 HierParams
*hier
, Bus
*pio_bus
)
62 : PioDevice(name
, p
), disk(d
), console(cons
), system(s
), cpu(c
), addr(a
)
64 mmu
->add_child(this, RangeSize(addr
, size
));
67 pioInterface
= newPioInterface(name
+ ".pio", hier
, pio_bus
, this,
68 &AlphaConsole::cacheAccess
);
69 pioInterface
->addAddrRange(RangeSize(addr
, size
));
72 alphaAccess
= new Access
;
73 alphaAccess
->last_offset
= size
- 1;
75 alphaAccess
->version
= ALPHA_ACCESS_VERSION
;
76 alphaAccess
->diskUnit
= 1;
78 alphaAccess
->diskCount
= 0;
79 alphaAccess
->diskPAddr
= 0;
80 alphaAccess
->diskBlock
= 0;
81 alphaAccess
->diskOperation
= 0;
82 alphaAccess
->outputChar
= 0;
83 alphaAccess
->inputChar
= 0;
84 alphaAccess
->bootStrapImpure
= 0;
85 alphaAccess
->bootStrapCPU
= 0;
86 alphaAccess
->align2
= 0;
88 system
->setAlphaAccess(addr
);
92 AlphaConsole::startup()
94 alphaAccess
->numCPUs
= system
->getNumCPUs();
95 alphaAccess
->kernStart
= system
->getKernelStart();
96 alphaAccess
->kernEnd
= system
->getKernelEnd();
97 alphaAccess
->entryPoint
= system
->getKernelEntry();
98 alphaAccess
->mem_size
= system
->physmem
->size();
99 alphaAccess
->cpuClock
= cpu
->frequency() / 1000000; // In MHz
100 alphaAccess
->intrClockFrequency
= platform
->intrFrequency();
104 AlphaConsole::read(MemReqPtr
&req
, uint8_t *data
)
106 memset(data
, 0, req
->size
);
108 Addr daddr
= req
->paddr
- (addr
& EV5::PAddrImplMask
);
112 case sizeof(uint32_t):
113 DPRINTF(AlphaConsole
, "read: offset=%#x val=%#x\n", daddr
,
117 case offsetof(AlphaAccess
, last_offset
):
118 *(uint32_t*)data
= alphaAccess
->last_offset
;
120 case offsetof(AlphaAccess
, version
):
121 *(uint32_t*)data
= alphaAccess
->version
;
123 case offsetof(AlphaAccess
, numCPUs
):
124 *(uint32_t*)data
= alphaAccess
->numCPUs
;
126 case offsetof(AlphaAccess
, bootStrapCPU
):
127 *(uint32_t*)data
= alphaAccess
->bootStrapCPU
;
129 case offsetof(AlphaAccess
, intrClockFrequency
):
130 *(uint32_t*)data
= alphaAccess
->intrClockFrequency
;
133 // Old console code read in everyting as a 32bit int
134 *(uint32_t*)data
= *(uint32_t*)(consoleData
+ daddr
);
138 case sizeof(uint64_t):
139 DPRINTF(AlphaConsole
, "read: offset=%#x val=%#x\n", daddr
,
143 case offsetof(AlphaAccess
, inputChar
):
144 *(uint64_t*)data
= console
->console_in();
146 case offsetof(AlphaAccess
, cpuClock
):
147 *(uint64_t*)data
= alphaAccess
->cpuClock
;
149 case offsetof(AlphaAccess
, mem_size
):
150 *(uint64_t*)data
= alphaAccess
->mem_size
;
152 case offsetof(AlphaAccess
, kernStart
):
153 *(uint64_t*)data
= alphaAccess
->kernStart
;
155 case offsetof(AlphaAccess
, kernEnd
):
156 *(uint64_t*)data
= alphaAccess
->kernEnd
;
158 case offsetof(AlphaAccess
, entryPoint
):
159 *(uint64_t*)data
= alphaAccess
->entryPoint
;
161 case offsetof(AlphaAccess
, diskUnit
):
162 *(uint64_t*)data
= alphaAccess
->diskUnit
;
164 case offsetof(AlphaAccess
, diskCount
):
165 *(uint64_t*)data
= alphaAccess
->diskCount
;
167 case offsetof(AlphaAccess
, diskPAddr
):
168 *(uint64_t*)data
= alphaAccess
->diskPAddr
;
170 case offsetof(AlphaAccess
, diskBlock
):
171 *(uint64_t*)data
= alphaAccess
->diskBlock
;
173 case offsetof(AlphaAccess
, diskOperation
):
174 *(uint64_t*)data
= alphaAccess
->diskOperation
;
176 case offsetof(AlphaAccess
, outputChar
):
177 *(uint64_t*)data
= alphaAccess
->outputChar
;
179 case offsetof(AlphaAccess
, bootStrapImpure
):
180 *(uint64_t*)data
= alphaAccess
->bootStrapImpure
;
183 panic("Unknown 64bit access, %#x\n", daddr
);
187 return MachineCheckFault
;
194 AlphaConsole::write(MemReqPtr
&req
, const uint8_t *data
)
199 case sizeof(uint32_t):
200 val
= *(uint32_t *)data
;
203 case sizeof(uint64_t):
204 val
= *(uint64_t *)data
;
207 return MachineCheckFault
;
210 Addr daddr
= req
->paddr
- (addr
& EV5::PAddrImplMask
);
211 ExecContext
*other_xc
;
214 case offsetof(AlphaAccess
, diskUnit
):
215 alphaAccess
->diskUnit
= val
;
218 case offsetof(AlphaAccess
, diskCount
):
219 alphaAccess
->diskCount
= val
;
222 case offsetof(AlphaAccess
, diskPAddr
):
223 alphaAccess
->diskPAddr
= val
;
226 case offsetof(AlphaAccess
, diskBlock
):
227 alphaAccess
->diskBlock
= val
;
230 case offsetof(AlphaAccess
, diskOperation
):
232 disk
->read(alphaAccess
->diskPAddr
, alphaAccess
->diskBlock
,
233 alphaAccess
->diskCount
);
235 panic("Invalid disk operation!");
239 case offsetof(AlphaAccess
, outputChar
):
240 console
->out((char)(val
& 0xff));
243 case offsetof(AlphaAccess
, bootStrapImpure
):
244 alphaAccess
->bootStrapImpure
= val
;
247 case offsetof(AlphaAccess
, bootStrapCPU
):
248 warn("%d: Trying to launch another CPU!", curTick
);
249 assert(val
> 0 && "Must not access primary cpu");
251 other_xc
= req
->xc
->system
->execContexts
[val
];
252 other_xc
->regs
.intRegFile
[16] = val
;
253 other_xc
->regs
.ipr
[TheISA::IPR_PALtemp16
] = val
;
254 other_xc
->regs
.intRegFile
[0] = val
;
255 other_xc
->regs
.intRegFile
[30] = alphaAccess
->bootStrapImpure
;
256 other_xc
->activate(); //Start the cpu
260 return MachineCheckFault
;
267 AlphaConsole::cacheAccess(MemReqPtr
&req
)
269 return curTick
+ 1000;
273 AlphaConsole::Access::serialize(ostream
&os
)
275 SERIALIZE_SCALAR(last_offset
);
276 SERIALIZE_SCALAR(version
);
277 SERIALIZE_SCALAR(numCPUs
);
278 SERIALIZE_SCALAR(mem_size
);
279 SERIALIZE_SCALAR(cpuClock
);
280 SERIALIZE_SCALAR(intrClockFrequency
);
281 SERIALIZE_SCALAR(kernStart
);
282 SERIALIZE_SCALAR(kernEnd
);
283 SERIALIZE_SCALAR(entryPoint
);
284 SERIALIZE_SCALAR(diskUnit
);
285 SERIALIZE_SCALAR(diskCount
);
286 SERIALIZE_SCALAR(diskPAddr
);
287 SERIALIZE_SCALAR(diskBlock
);
288 SERIALIZE_SCALAR(diskOperation
);
289 SERIALIZE_SCALAR(outputChar
);
290 SERIALIZE_SCALAR(inputChar
);
291 SERIALIZE_SCALAR(bootStrapImpure
);
292 SERIALIZE_SCALAR(bootStrapCPU
);
296 AlphaConsole::Access::unserialize(Checkpoint
*cp
, const std::string
§ion
)
298 UNSERIALIZE_SCALAR(last_offset
);
299 UNSERIALIZE_SCALAR(version
);
300 UNSERIALIZE_SCALAR(numCPUs
);
301 UNSERIALIZE_SCALAR(mem_size
);
302 UNSERIALIZE_SCALAR(cpuClock
);
303 UNSERIALIZE_SCALAR(intrClockFrequency
);
304 UNSERIALIZE_SCALAR(kernStart
);
305 UNSERIALIZE_SCALAR(kernEnd
);
306 UNSERIALIZE_SCALAR(entryPoint
);
307 UNSERIALIZE_SCALAR(diskUnit
);
308 UNSERIALIZE_SCALAR(diskCount
);
309 UNSERIALIZE_SCALAR(diskPAddr
);
310 UNSERIALIZE_SCALAR(diskBlock
);
311 UNSERIALIZE_SCALAR(diskOperation
);
312 UNSERIALIZE_SCALAR(outputChar
);
313 UNSERIALIZE_SCALAR(inputChar
);
314 UNSERIALIZE_SCALAR(bootStrapImpure
);
315 UNSERIALIZE_SCALAR(bootStrapCPU
);
319 AlphaConsole::serialize(ostream
&os
)
321 alphaAccess
->serialize(os
);
325 AlphaConsole::unserialize(Checkpoint
*cp
, const std::string
§ion
)
327 alphaAccess
->unserialize(cp
, section
);
330 BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole
)
332 SimObjectParam
<SimConsole
*> sim_console
;
333 SimObjectParam
<SimpleDisk
*> disk
;
334 SimObjectParam
<MemoryController
*> mmu
;
336 SimObjectParam
<System
*> system
;
337 SimObjectParam
<BaseCPU
*> cpu
;
338 SimObjectParam
<Platform
*> platform
;
339 SimObjectParam
<Bus
*> pio_bus
;
340 Param
<Tick
> pio_latency
;
341 SimObjectParam
<HierParams
*> hier
;
343 END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole
)
345 BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole
)
347 INIT_PARAM(sim_console
, "The Simulator Console"),
348 INIT_PARAM(disk
, "Simple Disk"),
349 INIT_PARAM(mmu
, "Memory Controller"),
350 INIT_PARAM(addr
, "Device Address"),
351 INIT_PARAM(system
, "system object"),
352 INIT_PARAM(cpu
, "Processor"),
353 INIT_PARAM(platform
, "platform"),
354 INIT_PARAM(pio_bus
, "The IO Bus to attach to"),
355 INIT_PARAM_DFLT(pio_latency
, "Programmed IO latency", 1000),
356 INIT_PARAM_DFLT(hier
, "Hierarchy global variables", &defaultHierParams
)
358 END_INIT_SIM_OBJECT_PARAMS(AlphaConsole
)
360 CREATE_SIM_OBJECT(AlphaConsole
)
362 return new AlphaConsole(getInstanceName(), sim_console
, disk
,
363 system
, cpu
, platform
, mmu
, addr
, hier
, pio_bus
);
366 REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole
)