Make sinic work with mpy
[gem5.git] / dev / alpha_console.cc
1 /*
2 * Copyright (c) 2001-2004 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
29 /* @file
30 * System Console Definition
31 */
32
33 #include <cstddef>
34 #include <cstdio>
35 #include <string>
36
37 #include "base/inifile.hh"
38 #include "base/str.hh" // for to_number()
39 #include "base/trace.hh"
40 #include "cpu/base_cpu.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/tlaser_clock.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_mem/memory_control.hh"
50 #include "sim/builder.hh"
51 #include "sim/system.hh"
52 #include "dev/tsunami_io.hh"
53 #include "sim/sim_object.hh"
54 #include "targetarch/byte_swap.hh"
55
56 using namespace std;
57
58 AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
59 System *s, BaseCPU *c, Platform *p,
60 int num_cpus, MemoryController *mmu, Addr a,
61 HierParams *hier, Bus *bus)
62 : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a)
63 {
64 mmu->add_child(this, RangeSize(addr, size));
65
66 if (bus) {
67 pioInterface = newPioInterface(name, hier, bus, this,
68 &AlphaConsole::cacheAccess);
69 pioInterface->addAddrRange(RangeSize(addr, size));
70 }
71
72 alphaAccess = new AlphaAccess;
73 alphaAccess->last_offset = size - 1;
74
75 alphaAccess->version = ALPHA_ACCESS_VERSION;
76 alphaAccess->numCPUs = num_cpus;
77 alphaAccess->diskUnit = 1;
78
79 alphaAccess->diskCount = 0;
80 alphaAccess->diskPAddr = 0;
81 alphaAccess->diskBlock = 0;
82 alphaAccess->diskOperation = 0;
83 alphaAccess->outputChar = 0;
84 alphaAccess->inputChar = 0;
85 alphaAccess->bootStrapImpure = 0;
86 alphaAccess->bootStrapCPU = 0;
87 alphaAccess->align2 = 0;
88 }
89
90 void
91 AlphaConsole::init()
92 {
93 alphaAccess->kernStart = system->getKernelStart();
94 alphaAccess->kernEnd = system->getKernelEnd();
95 alphaAccess->entryPoint = system->getKernelEntry();
96 alphaAccess->mem_size = system->physmem->size();
97 alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz
98 alphaAccess->intrClockFrequency = platform->intrFrequency();
99 }
100
101 Fault
102 AlphaConsole::read(MemReqPtr &req, uint8_t *data)
103 {
104 memset(data, 0, req->size);
105
106 Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
107
108 switch (req->size)
109 {
110 case sizeof(uint32_t):
111 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint32_t*)data);
112 switch (daddr)
113 {
114 case offsetof(AlphaAccess, last_offset):
115 *(uint32_t*)data = alphaAccess->last_offset;
116 break;
117 case offsetof(AlphaAccess, version):
118 *(uint32_t*)data = alphaAccess->version;
119 break;
120 case offsetof(AlphaAccess, numCPUs):
121 *(uint32_t*)data = alphaAccess->numCPUs;
122 break;
123 case offsetof(AlphaAccess, bootStrapCPU):
124 *(uint32_t*)data = alphaAccess->bootStrapCPU;
125 break;
126 case offsetof(AlphaAccess, intrClockFrequency):
127 *(uint32_t*)data = alphaAccess->intrClockFrequency;
128 break;
129 default:
130 // Old console code read in everyting as a 32bit int
131 *(uint32_t*)data = *(uint32_t*)(consoleData + daddr);
132
133 }
134 break;
135 case sizeof(uint64_t):
136 DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint64_t*)data);
137 switch (daddr)
138 {
139 case offsetof(AlphaAccess, inputChar):
140 *(uint64_t*)data = console->console_in();
141 break;
142 case offsetof(AlphaAccess, cpuClock):
143 *(uint64_t*)data = alphaAccess->cpuClock;
144 break;
145 case offsetof(AlphaAccess, mem_size):
146 *(uint64_t*)data = alphaAccess->mem_size;
147 break;
148 case offsetof(AlphaAccess, kernStart):
149 *(uint64_t*)data = alphaAccess->kernStart;
150 break;
151 case offsetof(AlphaAccess, kernEnd):
152 *(uint64_t*)data = alphaAccess->kernEnd;
153 break;
154 case offsetof(AlphaAccess, entryPoint):
155 *(uint64_t*)data = alphaAccess->entryPoint;
156 break;
157 case offsetof(AlphaAccess, diskUnit):
158 *(uint64_t*)data = alphaAccess->diskUnit;
159 break;
160 case offsetof(AlphaAccess, diskCount):
161 *(uint64_t*)data = alphaAccess->diskCount;
162 break;
163 case offsetof(AlphaAccess, diskPAddr):
164 *(uint64_t*)data = alphaAccess->diskPAddr;
165 break;
166 case offsetof(AlphaAccess, diskBlock):
167 *(uint64_t*)data = alphaAccess->diskBlock;
168 break;
169 case offsetof(AlphaAccess, diskOperation):
170 *(uint64_t*)data = alphaAccess->diskOperation;
171 break;
172 case offsetof(AlphaAccess, outputChar):
173 *(uint64_t*)data = alphaAccess->outputChar;
174 break;
175 case offsetof(AlphaAccess, bootStrapImpure):
176 *(uint64_t*)data = alphaAccess->bootStrapImpure;
177 break;
178 default:
179 panic("Unknown 64bit access, %#x\n", daddr);
180 }
181 break;
182 default:
183 return Machine_Check_Fault;
184 }
185
186 return No_Fault;
187 }
188
189 Fault
190 AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
191 {
192 uint64_t val;
193
194 switch (req->size) {
195 case sizeof(uint32_t):
196 val = *(uint32_t *)data;
197 break;
198
199 case sizeof(uint64_t):
200 val = *(uint64_t *)data;
201 break;
202 default:
203 return Machine_Check_Fault;
204 }
205
206 Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
207 ExecContext *other_xc;
208
209 switch (daddr) {
210 case offsetof(AlphaAccess, diskUnit):
211 alphaAccess->diskUnit = val;
212 break;
213
214 case offsetof(AlphaAccess, diskCount):
215 alphaAccess->diskCount = val;
216 break;
217
218 case offsetof(AlphaAccess, diskPAddr):
219 alphaAccess->diskPAddr = val;
220 break;
221
222 case offsetof(AlphaAccess, diskBlock):
223 alphaAccess->diskBlock = val;
224 break;
225
226 case offsetof(AlphaAccess, diskOperation):
227 if (val == 0x13)
228 disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock,
229 alphaAccess->diskCount);
230 else
231 panic("Invalid disk operation!");
232
233 break;
234
235 case offsetof(AlphaAccess, outputChar):
236 console->out((char)(val & 0xff));
237 break;
238
239 case offsetof(AlphaAccess, bootStrapImpure):
240 alphaAccess->bootStrapImpure = val;
241 break;
242
243 case offsetof(AlphaAccess, bootStrapCPU):
244 warn("%d: Trying to launch another CPU!", curTick);
245 assert(val > 0 && "Must not access primary cpu");
246
247 other_xc = req->xc->system->execContexts[val];
248 other_xc->regs.intRegFile[16] = val;
249 other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
250 other_xc->regs.intRegFile[0] = val;
251 other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
252 other_xc->activate(); //Start the cpu
253 break;
254
255 default:
256 return Machine_Check_Fault;
257 }
258
259 return No_Fault;
260 }
261
262 Tick
263 AlphaConsole::cacheAccess(MemReqPtr &req)
264 {
265 return curTick + 1000;
266 }
267
268 void
269 AlphaAccess::serialize(ostream &os)
270 {
271 SERIALIZE_SCALAR(last_offset);
272 SERIALIZE_SCALAR(version);
273 SERIALIZE_SCALAR(numCPUs);
274 SERIALIZE_SCALAR(mem_size);
275 SERIALIZE_SCALAR(cpuClock);
276 SERIALIZE_SCALAR(intrClockFrequency);
277 SERIALIZE_SCALAR(kernStart);
278 SERIALIZE_SCALAR(kernEnd);
279 SERIALIZE_SCALAR(entryPoint);
280 SERIALIZE_SCALAR(diskUnit);
281 SERIALIZE_SCALAR(diskCount);
282 SERIALIZE_SCALAR(diskPAddr);
283 SERIALIZE_SCALAR(diskBlock);
284 SERIALIZE_SCALAR(diskOperation);
285 SERIALIZE_SCALAR(outputChar);
286 SERIALIZE_SCALAR(inputChar);
287 SERIALIZE_SCALAR(bootStrapImpure);
288 SERIALIZE_SCALAR(bootStrapCPU);
289 }
290
291 void
292 AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
293 {
294 UNSERIALIZE_SCALAR(last_offset);
295 UNSERIALIZE_SCALAR(version);
296 UNSERIALIZE_SCALAR(numCPUs);
297 UNSERIALIZE_SCALAR(mem_size);
298 UNSERIALIZE_SCALAR(cpuClock);
299 UNSERIALIZE_SCALAR(intrClockFrequency);
300 UNSERIALIZE_SCALAR(kernStart);
301 UNSERIALIZE_SCALAR(kernEnd);
302 UNSERIALIZE_SCALAR(entryPoint);
303 UNSERIALIZE_SCALAR(diskUnit);
304 UNSERIALIZE_SCALAR(diskCount);
305 UNSERIALIZE_SCALAR(diskPAddr);
306 UNSERIALIZE_SCALAR(diskBlock);
307 UNSERIALIZE_SCALAR(diskOperation);
308 UNSERIALIZE_SCALAR(outputChar);
309 UNSERIALIZE_SCALAR(inputChar);
310 UNSERIALIZE_SCALAR(bootStrapImpure);
311 UNSERIALIZE_SCALAR(bootStrapCPU);
312 }
313
314 void
315 AlphaConsole::serialize(ostream &os)
316 {
317 alphaAccess->serialize(os);
318 }
319
320 void
321 AlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
322 {
323 alphaAccess->unserialize(cp, section);
324 }
325
326 BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
327
328 SimObjectParam<SimConsole *> sim_console;
329 SimObjectParam<SimpleDisk *> disk;
330 Param<int> num_cpus;
331 SimObjectParam<MemoryController *> mmu;
332 Param<Addr> addr;
333 SimObjectParam<System *> system;
334 SimObjectParam<BaseCPU *> cpu;
335 SimObjectParam<Platform *> platform;
336 SimObjectParam<Bus*> io_bus;
337 Param<Tick> pio_latency;
338 SimObjectParam<HierParams *> hier;
339
340 END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
341
342 BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
343
344 INIT_PARAM(sim_console, "The Simulator Console"),
345 INIT_PARAM(disk, "Simple Disk"),
346 INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
347 INIT_PARAM(mmu, "Memory Controller"),
348 INIT_PARAM(addr, "Device Address"),
349 INIT_PARAM(system, "system object"),
350 INIT_PARAM(cpu, "Processor"),
351 INIT_PARAM(platform, "platform"),
352 INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
353 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
354 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
355
356 END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
357
358 CREATE_SIM_OBJECT(AlphaConsole)
359 {
360 return new AlphaConsole(getInstanceName(), sim_console, disk,
361 system, cpu, platform, num_cpus, mmu,
362 addr, hier, io_bus);
363 }
364
365 REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)