gem5 v24.0.0.0
Loading...
Searching...
No Matches
iob.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2006 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
36#include "dev/sparc/iob.hh"
37
38#include <cstring>
39
40#include "arch/sparc/faults.hh"
42#include "base/bitfield.hh"
43#include "base/trace.hh"
44#include "cpu/base.hh"
45#include "cpu/thread_context.hh"
46#include "debug/Iob.hh"
47#include "dev/platform.hh"
48#include "mem/packet_access.hh"
49#include "mem/port.hh"
50#include "sim/faults.hh"
51#include "sim/system.hh"
52
53namespace gem5
54{
55
57{
58 iobManAddr = 0x9800000000ULL;
59 iobManSize = 0x0100000000ULL;
60 iobJBusAddr = 0x9F00000000ULL;
61 iobJBusSize = 0x0100000000ULL;
62 assert(params().system->threads.size() <= MaxNiagaraProcs);
63
64 pioDelay = p.pio_latency;
65
66 for (int x = 0; x < NumDeviceIds; ++x) {
67 intMan[x].cpu = 0;
68 intMan[x].vector = 0;
69 intCtl[x].mask = true;
70 intCtl[x].pend = false;
71 }
72
73}
74
75Tick
77{
78
79 if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
80 readIob(pkt);
81 else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
82 readJBus(pkt);
83 else
84 panic("Invalid address reached Iob\n");
85
86 pkt->makeAtomicResponse();
87 return pioDelay;
88}
89
90void
92{
93 Addr accessAddr = pkt->getAddr() - iobManAddr;
94
95 assert(IntManAddr == 0);
96 if (accessAddr < IntManAddr + IntManSize) {
97 int index = (accessAddr - IntManAddr) >> 3;
98 uint64_t data = intMan[index].cpu << 8 | intMan[index].vector << 0;
99 pkt->setBE(data);
100 return;
101 }
102
103 if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
104 int index = (accessAddr - IntCtlAddr) >> 3;
105 uint64_t data = (intCtl[index].mask ? (1 << 2) : 0) |
106 (intCtl[index].pend ? (1 << 0) : 0);
107 pkt->setBE(data);
108 return;
109 }
110
111 if (accessAddr == JIntVecAddr) {
112 pkt->setBE(jIntVec);
113 return;
114 }
115
116 panic("Read to unknown IOB offset 0x%x\n", accessAddr);
117}
118
119void
121{
122 Addr accessAddr = pkt->getAddr() - iobJBusAddr;
123 ContextID cpuid = pkt->req->contextId();
124 int index;
125 uint64_t data;
126
127
128
129
130 if (accessAddr >= JIntData0Addr && accessAddr < JIntData1Addr) {
131 index = (accessAddr - JIntData0Addr) >> 3;
132 pkt->setBE(jBusData0[index]);
133 return;
134 }
135
136 if (accessAddr >= JIntData1Addr && accessAddr < JIntDataA0Addr) {
137 index = (accessAddr - JIntData1Addr) >> 3;
138 pkt->setBE(jBusData1[index]);
139 return;
140 }
141
142 if (accessAddr == JIntDataA0Addr) {
143 pkt->setBE(jBusData0[cpuid]);
144 return;
145 }
146
147 if (accessAddr == JIntDataA1Addr) {
148 pkt->setBE(jBusData1[cpuid]);
149 return;
150 }
151
152 if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
153 index = (accessAddr - JIntBusyAddr) >> 3;
154 data = jIntBusy[index].busy ? 1 << 5 : 0 |
156 pkt->setBE(data);
157 return;
158 }
159 if (accessAddr == JIntABusyAddr) {
160 data = jIntBusy[cpuid].busy ? 1 << 5 : 0 |
162 pkt->setBE(data);
163 return;
164 };
165
166 panic("Read to unknown JBus offset 0x%x\n", accessAddr);
167}
168
169Tick
171{
172 if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
173 writeIob(pkt);
174 else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
175 writeJBus(pkt);
176 else
177 panic("Invalid address reached Iob\n");
178
179
180 pkt->makeAtomicResponse();
181 return pioDelay;
182}
183
184void
186{
187 Addr accessAddr = pkt->getAddr() - iobManAddr;
188 int index;
189 uint64_t data;
190
191 assert(IntManAddr == 0);
192 if (accessAddr < IntManAddr + IntManSize) {
193 index = (accessAddr - IntManAddr) >> 3;
194 data = pkt->getBE<uint64_t>();
195 intMan[index].cpu = bits(data,12,8);
196 intMan[index].vector = bits(data,5,0);
197 DPRINTF(Iob, "Wrote IntMan %d cpu %d, vec %d\n", index,
199 return;
200 }
201
202 if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
203 index = (accessAddr - IntCtlAddr) >> 3;
204 data = pkt->getBE<uint64_t>();
205 intCtl[index].mask = bits(data,2,2);
206 if (bits(data,1,1))
207 intCtl[index].pend = false;
208 DPRINTF(Iob, "Wrote IntCtl %d pend %d cleared %d\n", index,
209 intCtl[index].pend, bits(data,2,2));
210 return;
211 }
212
213 if (accessAddr == JIntVecAddr) {
214 jIntVec = bits(pkt->getBE<uint64_t>(), 5,0);
215 DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec);
216 return;
217 }
218
219 if (accessAddr >= IntVecDisAddr && accessAddr < IntVecDisAddr + IntVecDisSize) {
220 Type type;
221 int cpu_id;
222 int vector;
223 index = (accessAddr - IntManAddr) >> 3;
224 data = pkt->getBE<uint64_t>();
225 type = (Type)bits(data,17,16);
226 cpu_id = bits(data, 12,8);
227 vector = bits(data,5,0);
228 generateIpi(type,cpu_id, vector);
229 return;
230 }
231
232 panic("Write to unknown IOB offset 0x%x\n", accessAddr);
233}
234
235void
237{
238 Addr accessAddr = pkt->getAddr() - iobJBusAddr;
239 ContextID cpuid = pkt->req->contextId();
240 int index;
241 uint64_t data;
242
243 if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
244 index = (accessAddr - JIntBusyAddr) >> 3;
245 data = pkt->getBE<uint64_t>();
246 jIntBusy[index].busy = bits(data,5,5);
247 DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", index,
248 jIntBusy[index].busy);
249 return;
250 }
251 if (accessAddr == JIntABusyAddr) {
252 data = pkt->getBE<uint64_t>();
253 jIntBusy[cpuid].busy = bits(data,5,5);
254 DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid,
255 jIntBusy[cpuid].busy);
256 return;
257 };
258
259 panic("Write to unknown JBus offset 0x%x\n", accessAddr);
260}
261
262void
264{
265 assert(devid < NumDeviceIds);
266 if (intCtl[devid].mask)
267 return;
268 intCtl[devid].mask = true;
269 intCtl[devid].pend = true;
270 DPRINTF(Iob, "Receiving Device interrupt: %d for cpu %d vec %d\n",
271 devid, intMan[devid].cpu, intMan[devid].vector);
272 auto tc = sys->threads[intMan[devid].cpu];
273 tc->getCpuPtr()->postInterrupt(tc->threadId(), SparcISA::IT_INT_VEC,
274 intMan[devid].vector);
275}
276
277
278void
280{
283 if (cpu_id >= sys->threads.size())
284 return;
285
286 auto tc = sys->threads[cpu_id];
287 switch (type) {
288 case 0: // interrupt
289 DPRINTF(Iob,
290 "Generating interrupt because of I/O write to cpu: "
291 "%d vec %d\n",
292 cpu_id, vector);
293 tc->getCpuPtr()->postInterrupt(
294 tc->threadId(), SparcISA::IT_INT_VEC, vector);
295 break;
296 case 1: // reset
297 warn("Sending reset to CPU: %d\n", cpu_id);
298 if (vector != por->trapType())
299 panic("Don't know how to set non-POR reset to cpu\n");
300 por->invoke(tc);
301 tc->activate();
302 break;
303 case 2: // idle -- this means stop executing and don't wake on interrupts
304 DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
305 tc->halt();
306 break;
307 case 3: // resume
308 DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
309 tc->activate();
310 break;
311 default:
312 panic("Invalid type to generate ipi\n");
313 }
314}
315
316bool
317Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
318{
319 // If we are already dealing with an interrupt for that cpu we can't deal
320 // with another one right now... come back later
321 if (jIntBusy[cpu_id].busy)
322 return false;
323
324 DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n",
325 source, cpu_id, jIntVec);
326
327 jIntBusy[cpu_id].busy = true;
328 jIntBusy[cpu_id].source = source;
329 jBusData0[cpu_id] = d0;
330 jBusData1[cpu_id] = d1;
331
332 auto tc = sys->threads[cpu_id];
333 tc->getCpuPtr()->postInterrupt(
334 tc->threadId(), SparcISA::IT_INT_VEC, jIntVec);
335 return true;
336}
337
340{
341 AddrRangeList ranges;
342 ranges.push_back(RangeSize(iobManAddr, iobManSize));
343 ranges.push_back(RangeSize(iobJBusAddr, iobJBusSize));
344 return ranges;
345}
346
347
348void
350{
351
355 for (int x = 0; x < NumDeviceIds; x++) {
356 ScopedCheckpointSection sec(cp, csprintf("Int%d", x));
357 paramOut(cp, "cpu", intMan[x].cpu);
358 paramOut(cp, "vector", intMan[x].vector);
359 paramOut(cp, "mask", intCtl[x].mask);
360 paramOut(cp, "pend", intCtl[x].pend);
361 };
362 for (int x = 0; x < MaxNiagaraProcs; x++) {
363 ScopedCheckpointSection sec(cp, csprintf("jIntBusy%d", x));
364 paramOut(cp, "busy", jIntBusy[x].busy);
365 paramOut(cp, "source", jIntBusy[x].source);
366 };
367}
368
369void
371{
375 for (int x = 0; x < NumDeviceIds; x++) {
376 ScopedCheckpointSection sec(cp, csprintf("Int%d", x));
377 paramIn(cp, "cpu", intMan[x].cpu);
378 paramIn(cp, "vector", intMan[x].vector);
379 paramIn(cp, "mask", intCtl[x].mask);
380 paramIn(cp, "pend", intCtl[x].pend);
381 };
382 for (int x = 0; x < MaxNiagaraProcs; x++) {
383 ScopedCheckpointSection sec(cp, csprintf("jIntBusy%d", x));
384 paramIn(cp, "busy", jIntBusy[x].busy);
385 paramIn(cp, "source", jIntBusy[x].source);
386 };
387}
388
389} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
const char data[]
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition iob.cc:370
IntCtl intCtl[NumDeviceIds]
Definition iob.hh:117
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Definition iob.cc:339
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition iob.cc:76
Addr iobJBusAddr
Definition iob.hh:77
bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
Definition iob.cc:317
void readJBus(PacketPtr pkt)
Definition iob.cc:120
uint64_t jBusData1[MaxNiagaraProcs]
Definition iob.hh:120
Iob(const Params &p)
Definition iob.cc:56
void writeIob(PacketPtr pkt)
Definition iob.cc:185
IntMan intMan[NumDeviceIds]
Definition iob.hh:116
Addr iobJBusSize
Definition iob.hh:78
Addr iobManAddr
Definition iob.hh:75
void readIob(PacketPtr pkt)
Definition iob.cc:91
Tick pioDelay
Definition iob.hh:79
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition iob.cc:349
IntBusy jIntBusy[MaxNiagaraProcs]
Definition iob.hh:121
Addr iobManSize
Definition iob.hh:76
DeviceId
Definition iob.hh:82
@ NumDeviceIds
Definition iob.hh:87
uint64_t jBusData0[MaxNiagaraProcs]
Definition iob.hh:119
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition iob.cc:170
void generateIpi(Type type, int cpu_id, int vector)
Definition iob.cc:279
uint64_t jIntVec
Definition iob.hh:118
void receiveDeviceInterrupt(DeviceId devid)
Definition iob.cc:263
void writeJBus(PacketPtr pkt)
Definition iob.cc:236
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void setBE(T v)
Set the value in the data pointer to v as big endian.
T getBE() const
Get the data in the packet byte swapped from big endian to host endian.
RequestPtr req
A pointer to the original request.
Definition packet.hh:377
void makeAtomicResponse()
Definition packet.hh:1074
This device is the base class which all devices senstive to an address range inherit from.
Definition io_device.hh:103
PioDeviceParams Params
Definition io_device.hh:134
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:497
int size() const
Definition system.hh:210
Threads threads
Definition system.hh:310
AddrRange RangeSize(Addr start, Addr size)
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define UNSERIALIZE_ARRAY(member, size)
Definition serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition serialize.hh:610
const Params & params() const
This device implements the niagara I/O Bridge chip.
#define warn(...)
Definition logging.hh:256
Port Object Declaration.
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 30, 0 > index
Bitfield< 0 > p
Bitfield< 28, 21 > cpuid
Bitfield< 20, 16 > d1
Definition types.hh:66
Bitfield< 15, 6 > d0
Definition types.hh:65
Bitfield< 3 > x
Definition pagetable.hh:73
Bitfield< 15 > system
Definition misc.hh:1032
Bitfield< 15, 8 > vector
Definition intmessage.hh:48
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
const Addr IntVecDisSize
Definition iob.hh:51
const Addr JIntDataA1Addr
Definition iob.hh:58
const Addr IntManSize
Definition iob.hh:46
const Addr JIntBusyAddr
Definition iob.hh:59
const Addr JIntData1Addr
Definition iob.hh:56
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition types.cc:40
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition types.cc:72
const Addr IntCtlSize
Definition iob.hh:48
const Addr IntCtlAddr
Definition iob.hh:47
uint64_t Tick
Tick count type.
Definition types.hh:58
const Addr JIntVecAddr
Definition iob.hh:49
const Addr JIntABusyAddr
Definition iob.hh:61
int ContextID
Globally unique thread context ID.
Definition types.hh:239
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
const Addr JIntData0Addr
Definition iob.hh:55
const int MaxNiagaraProcs
Definition iob.hh:43
const Addr IntVecDisAddr
Definition iob.hh:50
const Addr JIntBusySize
Definition iob.hh:60
const Addr IntManAddr
Definition iob.hh:45
const Addr JIntDataA0Addr
Definition iob.hh:57
Generic interface for platforms.
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568

Generated on Tue Jun 18 2024 16:24:03 for gem5 by doxygen 1.11.0