gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  * Authors: Ali Saidi
29  */
30 
38 #include "dev/sparc/iob.hh"
39 
40 #include <cstring>
41 
42 #include "arch/sparc/faults.hh"
43 #include "arch/sparc/isa_traits.hh"
44 #include "base/bitfield.hh"
45 #include "base/trace.hh"
46 #include "cpu/intr_control.hh"
47 #include "cpu/thread_context.hh"
48 #include "debug/Iob.hh"
49 #include "dev/platform.hh"
50 #include "mem/packet_access.hh"
51 #include "mem/port.hh"
52 #include "sim/faults.hh"
53 #include "sim/system.hh"
54 
55 Iob::Iob(const Params *p)
56  : PioDevice(p), ic(p->platform->intrctrl)
57 {
58  iobManAddr = ULL(0x9800000000);
59  iobManSize = ULL(0x0100000000);
60  iobJBusAddr = ULL(0x9F00000000);
61  iobJBusSize = ULL(0x0100000000);
62  assert (params()->system->threadContexts.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 
75 Tick
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 
90 void
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->set(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->set(data);
108  return;
109  }
110 
111  if (accessAddr == JIntVecAddr) {
112  pkt->set(jIntVec);
113  return;
114  }
115 
116  panic("Read to unknown IOB offset 0x%x\n", accessAddr);
117 }
118 
119 void
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->set(jBusData0[index]);
133  return;
134  }
135 
136  if (accessAddr >= JIntData1Addr && accessAddr < JIntDataA0Addr) {
137  index = (accessAddr - JIntData1Addr) >> 3;
138  pkt->set(jBusData1[index]);
139  return;
140  }
141 
142  if (accessAddr == JIntDataA0Addr) {
143  pkt->set(jBusData0[cpuid]);
144  return;
145  }
146 
147  if (accessAddr == JIntDataA1Addr) {
148  pkt->set(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->set(data);
157  return;
158  }
159  if (accessAddr == JIntABusyAddr) {
160  data = jIntBusy[cpuid].busy ? 1 << 5 : 0 |
162  pkt->set(data);
163  return;
164  };
165 
166  panic("Read to unknown JBus offset 0x%x\n", accessAddr);
167 }
168 
169 Tick
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 
184 void
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->get<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,
198  intMan[index].cpu, intMan[index].vector);
199  return;
200  }
201 
202  if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
203  index = (accessAddr - IntCtlAddr) >> 3;
204  data = pkt->get<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->get<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->get<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 
235 void
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->get<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->get<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 
262 void
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  ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector);
273 }
274 
275 
276 void
277 Iob::generateIpi(Type type, int cpu_id, int vector)
278 {
280  if (cpu_id >= sys->numContexts())
281  return;
282 
283  switch (type) {
284  case 0: // interrupt
285  DPRINTF(Iob, "Generating interrupt because of I/O write to cpu: %d vec %d\n",
286  cpu_id, vector);
287  ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
288  break;
289  case 1: // reset
290  warn("Sending reset to CPU: %d\n", cpu_id);
291  if (vector != por->trapType())
292  panic("Don't know how to set non-POR reset to cpu\n");
293  por->invoke(sys->threadContexts[cpu_id]);
294  sys->threadContexts[cpu_id]->activate();
295  break;
296  case 2: // idle -- this means stop executing and don't wake on interrupts
297  DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
298  sys->threadContexts[cpu_id]->halt();
299  break;
300  case 3: // resume
301  DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
302  sys->threadContexts[cpu_id]->activate();
303  break;
304  default:
305  panic("Invalid type to generate ipi\n");
306  }
307 }
308 
309 bool
310 Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
311 {
312  // If we are already dealing with an interrupt for that cpu we can't deal
313  // with another one right now... come back later
314  if (jIntBusy[cpu_id].busy)
315  return false;
316 
317  DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n",
318  source, cpu_id, jIntVec);
319 
320  jIntBusy[cpu_id].busy = true;
321  jIntBusy[cpu_id].source = source;
322  jBusData0[cpu_id] = d0;
323  jBusData1[cpu_id] = d1;
324 
325  ic->post(cpu_id, SparcISA::IT_INT_VEC, jIntVec);
326  return true;
327 }
328 
331 {
332  AddrRangeList ranges;
333  ranges.push_back(RangeSize(iobManAddr, iobManSize));
334  ranges.push_back(RangeSize(iobJBusAddr, iobJBusSize));
335  return ranges;
336 }
337 
338 
339 void
341 {
342 
346  for (int x = 0; x < NumDeviceIds; x++) {
347  ScopedCheckpointSection sec(cp, csprintf("Int%d", x));
348  paramOut(cp, "cpu", intMan[x].cpu);
349  paramOut(cp, "vector", intMan[x].vector);
350  paramOut(cp, "mask", intCtl[x].mask);
351  paramOut(cp, "pend", intCtl[x].pend);
352  };
353  for (int x = 0; x < MaxNiagaraProcs; x++) {
354  ScopedCheckpointSection sec(cp, csprintf("jIntBusy%d", x));
355  paramOut(cp, "busy", jIntBusy[x].busy);
356  paramOut(cp, "source", jIntBusy[x].source);
357  };
358 }
359 
360 void
362 {
366  for (int x = 0; x < NumDeviceIds; x++) {
367  ScopedCheckpointSection sec(cp, csprintf("Int%d", x));
368  paramIn(cp, "cpu", intMan[x].cpu);
369  paramIn(cp, "vector", intMan[x].vector);
370  paramIn(cp, "mask", intCtl[x].mask);
371  paramIn(cp, "pend", intCtl[x].pend);
372  };
373  for (int x = 0; x < MaxNiagaraProcs; x++) {
374  ScopedCheckpointSection sec(cp, csprintf("jIntBusy%d", x));
375  paramIn(cp, "busy", jIntBusy[x].busy);
376  paramIn(cp, "source", jIntBusy[x].source);
377  };
378 }
379 
380 Iob *
381 IobParams::create()
382 {
383  return new Iob(this);
384 }
Addr iobManAddr
Definition: iob.hh:77
#define DPRINTF(x,...)
Definition: trace.hh:212
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:398
This device implements the niagara I/O Bridge chip.
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
Addr iobManSize
Definition: iob.hh:78
Bitfield< 30, 0 > index
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Definition: iob.cc:330
void receiveDeviceInterrupt(DeviceId devid)
Definition: iob.cc:263
ContextID contextId() const
Accessor function for context ID.
Definition: request.hh:694
#define panic(...)
Definition: misc.hh:153
bool mask
Definition: iob.hh:97
bool busy
Definition: iob.hh:102
void post(int cpu_id, int int_num, int index)
Definition: intr_control.cc:50
const Addr JIntVecAddr
Definition: iob.hh:50
PioDeviceParams Params
Definition: io_device.hh:116
Port Object Declaration.
Bitfield< 28, 21 > cpuid
Definition: dt_constants.hh:94
Type
Definition: iob.hh:106
IntMan intMan[NumDeviceIds]
Definition: iob.hh:113
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
const char data[]
Definition: circlebuf.cc:43
const Addr JIntDataA1Addr
Definition: iob.hh:59
#define warn(...)
Definition: misc.hh:219
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
void generateIpi(Type type, int cpu_id, int vector)
Definition: iob.cc:277
system
Definition: isa.cc:226
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: iob.cc:170
void writeJBus(PacketPtr pkt)
Definition: iob.cc:236
const Addr IntCtlSize
Definition: iob.hh:49
Iob(const Params *p)
Definition: iob.cc:55
uint64_t jIntVec
Definition: iob.hh:115
void makeAtomicResponse()
Definition: packet.hh:857
uint64_t Tick
Tick count type.
Definition: types.hh:63
void writeIob(PacketPtr pkt)
Definition: iob.cc:185
Definition: iob.hh:73
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:40
Tick pioDelay
Definition: iob.hh:81
std::vector< ThreadContext * > threadContexts
Definition: system.hh:199
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:158
const RequestPtr req
A pointer to the original request.
Definition: packet.hh:304
int vector
Definition: iob.hh:93
DeviceId
Definition: iob.hh:83
const Addr JIntBusySize
Definition: iob.hh:61
bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
Definition: iob.cc:310
uint64_t jBusData0[MaxNiagaraProcs]
Definition: iob.hh:116
This device is the base class which all devices senstive to an address range inherit from...
Definition: io_device.hh:84
const Addr JIntBusyAddr
Definition: iob.hh:60
const Addr JIntABusyAddr
Definition: iob.hh:62
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
#define ULL(N)
uint64_t constant
Definition: types.hh:50
System * sys
Definition: io_device.hh:87
bool pend
Definition: iob.hh:98
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
Bitfield< 15, 8 > vector
Definition: intmessage.hh:45
int numContexts()
Definition: system.hh:208
void readIob(PacketPtr pkt)
Definition: iob.cc:91
Addr iobJBusAddr
Definition: iob.hh:79
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: iob.cc:340
void readJBus(PacketPtr pkt)
Definition: iob.cc:120
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:161
const Addr IntVecDisAddr
Definition: iob.hh:51
type
Definition: misc.hh:728
Generic interface for platforms.
const Addr IntVecDisSize
Definition: iob.hh:52
std::ostream CheckpointOut
Definition: serialize.hh:67
const Params * params() const
Definition: iob.hh:130
const Addr IntCtlAddr
Definition: iob.hh:48
IntBusy jIntBusy[MaxNiagaraProcs]
Definition: iob.hh:118
const Addr JIntData0Addr
Definition: iob.hh:56
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:71
IntrControl * ic
Definition: iob.hh:76
Bitfield< 3, 0 > mask
Definition: types.hh:64
int cpu
Definition: iob.hh:92
const int MaxNiagaraProcs
Definition: iob.hh:44
Addr iobJBusSize
Definition: iob.hh:80
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
Definition: bitfield.hh:67
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: iob.cc:76
const Addr JIntDataA0Addr
Definition: iob.hh:58
uint64_t jBusData1[MaxNiagaraProcs]
Definition: iob.hh:117
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
Definition: faults.cc:493
Scoped checkpoint section helper class.
Definition: serialize.hh:240
Bitfield< 0 > p
Bitfield< 1 > x
Definition: types.hh:105
IntCtl intCtl[NumDeviceIds]
Definition: iob.hh:114
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: iob.cc:361
int source
Definition: iob.hh:103
int ContextID
Globally unique thread context ID.
Definition: types.hh:175
const Addr JIntData1Addr
Definition: iob.hh:57
bool ic(TxDesc *d)
TrapType trapType()
Definition: faults.hh:83
const Addr IntManAddr
Definition: iob.hh:46
Addr getAddr() const
Definition: packet.hh:639
const Addr IntManSize
Definition: iob.hh:47

Generated on Fri Jun 9 2017 13:03:47 for gem5 by doxygen 1.8.6