gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tsunami_cchip.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2005 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  * Ron Dreslinski
30  */
31 
37 
38 #include <deque>
39 #include <string>
40 #include <vector>
41 
42 #include "arch/alpha/ev5.hh"
43 #include "base/trace.hh"
44 #include "config/the_isa.hh"
45 #include "cpu/intr_control.hh"
46 #include "cpu/thread_context.hh"
47 #include "debug/IPI.hh"
48 #include "debug/Tsunami.hh"
49 #include "dev/alpha/tsunami.hh"
50 #include "dev/alpha/tsunamireg.h"
51 #include "mem/packet.hh"
52 #include "mem/packet_access.hh"
53 #include "mem/port.hh"
54 #include "params/TsunamiCChip.hh"
55 #include "sim/system.hh"
56 
57 //Should this be AlphaISA?
58 using namespace TheISA;
59 
61  : BasicPioDevice(p, 0x10000000), tsunami(p->tsunami)
62 {
63  drir = 0;
64  ipint = 0;
65  itint = 0;
66 
67  for (int x = 0; x < Tsunami::Max_CPUs; x++)
68  {
69  dim[x] = 0;
70  dir[x] = 0;
71  }
72 
73  //Put back pointer in tsunami
74  tsunami->cchip = this;
75 }
76 
77 Tick
79 {
80  DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
81 
82  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
83 
84  Addr regnum = (pkt->getAddr() - pioAddr) >> 6;
85  Addr daddr = (pkt->getAddr() - pioAddr);
86 
87  switch (pkt->getSize()) {
88 
89  case sizeof(uint64_t):
90  pkt->set<uint64_t>(0);
91 
92  if (daddr & TSDEV_CC_BDIMS)
93  {
94  pkt->set(dim[(daddr >> 4) & 0x3F]);
95  break;
96  }
97 
98  if (daddr & TSDEV_CC_BDIRS)
99  {
100  pkt->set(dir[(daddr >> 4) & 0x3F]);
101  break;
102  }
103 
104  switch(regnum) {
105  case TSDEV_CC_CSR:
106  pkt->set(0x0);
107  break;
108  case TSDEV_CC_MTR:
109  panic("TSDEV_CC_MTR not implemeted\n");
110  break;
111  case TSDEV_CC_MISC:
112  pkt->set(((ipint << 8) & 0xF) | ((itint << 4) & 0xF) |
113  (pkt->req->contextId() & 0x3));
114  // currently, FS cannot handle MT so contextId and
115  // cpuId are effectively the same, don't know if it will
116  // matter if FS becomes MT enabled. I suspect no because
117  // we are currently able to boot up to 64 procs anyway
118  // which would render the CPUID of this register useless
119  // anyway
120  break;
121  case TSDEV_CC_AAR0:
122  case TSDEV_CC_AAR1:
123  case TSDEV_CC_AAR2:
124  case TSDEV_CC_AAR3:
125  pkt->set(0);
126  break;
127  case TSDEV_CC_DIM0:
128  pkt->set(dim[0]);
129  break;
130  case TSDEV_CC_DIM1:
131  pkt->set(dim[1]);
132  break;
133  case TSDEV_CC_DIM2:
134  pkt->set(dim[2]);
135  break;
136  case TSDEV_CC_DIM3:
137  pkt->set(dim[3]);
138  break;
139  case TSDEV_CC_DIR0:
140  pkt->set(dir[0]);
141  break;
142  case TSDEV_CC_DIR1:
143  pkt->set(dir[1]);
144  break;
145  case TSDEV_CC_DIR2:
146  pkt->set(dir[2]);
147  break;
148  case TSDEV_CC_DIR3:
149  pkt->set(dir[3]);
150  break;
151  case TSDEV_CC_DRIR:
152  pkt->set(drir);
153  break;
154  case TSDEV_CC_PRBEN:
155  panic("TSDEV_CC_PRBEN not implemented\n");
156  break;
157  case TSDEV_CC_IIC0:
158  case TSDEV_CC_IIC1:
159  case TSDEV_CC_IIC2:
160  case TSDEV_CC_IIC3:
161  panic("TSDEV_CC_IICx not implemented\n");
162  break;
163  case TSDEV_CC_MPR0:
164  case TSDEV_CC_MPR1:
165  case TSDEV_CC_MPR2:
166  case TSDEV_CC_MPR3:
167  panic("TSDEV_CC_MPRx not implemented\n");
168  break;
169  case TSDEV_CC_IPIR:
170  pkt->set(ipint);
171  break;
172  case TSDEV_CC_ITIR:
173  pkt->set(itint);
174  break;
175  default:
176  panic("default in cchip read reached, accessing 0x%x\n");
177  } // uint64_t
178 
179  break;
180  case sizeof(uint32_t):
181  case sizeof(uint16_t):
182  case sizeof(uint8_t):
183  default:
184  panic("invalid access size(?) for tsunami register!\n");
185  }
186  DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n",
187  regnum, pkt->getSize(), pkt->get<uint64_t>());
188 
189  pkt->makeAtomicResponse();
190  return pioDelay;
191 }
192 
193 Tick
195 {
196  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
197  Addr daddr = pkt->getAddr() - pioAddr;
198  Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ;
199 
200 
201  assert(pkt->getSize() == sizeof(uint64_t));
202 
203  DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get<uint64_t>());
204 
205  bool supportedWrite = false;
206 
207 
208  if (daddr & TSDEV_CC_BDIMS)
209  {
210  int number = (daddr >> 4) & 0x3F;
211 
212  uint64_t bitvector;
213  uint64_t olddim;
214  uint64_t olddir;
215 
216  olddim = dim[number];
217  olddir = dir[number];
218  dim[number] = pkt->get<uint64_t>();
219  dir[number] = dim[number] & drir;
220  for (int x = 0; x < Tsunami::Max_CPUs; x++)
221  {
222  bitvector = ULL(1) << x;
223  // Figure out which bits have changed
224  if ((dim[number] & bitvector) != (olddim & bitvector))
225  {
226  // The bit is now set and it wasn't before (set)
227  if ((dim[number] & bitvector) && (dir[number] & bitvector))
228  {
230  DPRINTF(Tsunami, "dim write resulting in posting dir"
231  " interrupt to cpu %d\n", number);
232  }
233  else if ((olddir & bitvector) &&
234  !(dir[number] & bitvector))
235  {
236  // The bit was set and now its now clear and
237  // we were interrupting on that bit before
239  DPRINTF(Tsunami, "dim write resulting in clear"
240  " dir interrupt to cpu %d\n", number);
241 
242  }
243 
244 
245  }
246  }
247  } else {
248  switch(regnum) {
249  case TSDEV_CC_CSR:
250  panic("TSDEV_CC_CSR write\n");
251  case TSDEV_CC_MTR:
252  panic("TSDEV_CC_MTR write not implemented\n");
253  case TSDEV_CC_MISC:
254  uint64_t ipreq;
255  ipreq = (pkt->get<uint64_t>() >> 12) & 0xF;
256  //If it is bit 12-15, this is an IPI post
257  if (ipreq) {
258  reqIPI(ipreq);
259  supportedWrite = true;
260  }
261 
262  //If it is bit 8-11, this is an IPI clear
263  uint64_t ipintr;
264  ipintr = (pkt->get<uint64_t>() >> 8) & 0xF;
265  if (ipintr) {
266  clearIPI(ipintr);
267  supportedWrite = true;
268  }
269 
270  //If it is the 4-7th bit, clear the RTC interrupt
271  uint64_t itintr;
272  itintr = (pkt->get<uint64_t>() >> 4) & 0xF;
273  if (itintr) {
274  clearITI(itintr);
275  supportedWrite = true;
276  }
277 
278  // ignore NXMs
279  if (pkt->get<uint64_t>() & 0x10000000)
280  supportedWrite = true;
281 
282  if (!supportedWrite)
283  panic("TSDEV_CC_MISC write not implemented\n");
284 
285  break;
286  case TSDEV_CC_AAR0:
287  case TSDEV_CC_AAR1:
288  case TSDEV_CC_AAR2:
289  case TSDEV_CC_AAR3:
290  panic("TSDEV_CC_AARx write not implemeted\n");
291  case TSDEV_CC_DIM0:
292  case TSDEV_CC_DIM1:
293  case TSDEV_CC_DIM2:
294  case TSDEV_CC_DIM3:
295  int number;
296  if (regnum == TSDEV_CC_DIM0)
297  number = 0;
298  else if (regnum == TSDEV_CC_DIM1)
299  number = 1;
300  else if (regnum == TSDEV_CC_DIM2)
301  number = 2;
302  else
303  number = 3;
304 
305  uint64_t bitvector;
306  uint64_t olddim;
307  uint64_t olddir;
308 
309  olddim = dim[number];
310  olddir = dir[number];
311  dim[number] = pkt->get<uint64_t>();
312  dir[number] = dim[number] & drir;
313  for (int x = 0; x < 64; x++)
314  {
315  bitvector = ULL(1) << x;
316  // Figure out which bits have changed
317  if ((dim[number] & bitvector) != (olddim & bitvector))
318  {
319  // The bit is now set and it wasn't before (set)
320  if ((dim[number] & bitvector) && (dir[number] & bitvector))
321  {
323  DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n");
324  }
325  else if ((olddir & bitvector) &&
326  !(dir[number] & bitvector))
327  {
328  // The bit was set and now its now clear and
329  // we were interrupting on that bit before
331  DPRINTF(Tsunami, "dim write resulting in clear"
332  " dir interrupt to cpu %d\n",
333  x);
334 
335  }
336 
337 
338  }
339  }
340  break;
341  case TSDEV_CC_DIR0:
342  case TSDEV_CC_DIR1:
343  case TSDEV_CC_DIR2:
344  case TSDEV_CC_DIR3:
345  panic("TSDEV_CC_DIR write not implemented\n");
346  case TSDEV_CC_DRIR:
347  panic("TSDEV_CC_DRIR write not implemented\n");
348  case TSDEV_CC_PRBEN:
349  panic("TSDEV_CC_PRBEN write not implemented\n");
350  case TSDEV_CC_IIC0:
351  case TSDEV_CC_IIC1:
352  case TSDEV_CC_IIC2:
353  case TSDEV_CC_IIC3:
354  panic("TSDEV_CC_IICx write not implemented\n");
355  case TSDEV_CC_MPR0:
356  case TSDEV_CC_MPR1:
357  case TSDEV_CC_MPR2:
358  case TSDEV_CC_MPR3:
359  panic("TSDEV_CC_MPRx write not implemented\n");
360  case TSDEV_CC_IPIR:
361  clearIPI(pkt->get<uint64_t>());
362  break;
363  case TSDEV_CC_ITIR:
364  clearITI(pkt->get<uint64_t>());
365  break;
366  case TSDEV_CC_IPIQ:
367  reqIPI(pkt->get<uint64_t>());
368  break;
369  default:
370  panic("default in cchip read reached, accessing 0x%x\n");
371  } // swtich(regnum)
372  } // not BIG_TSUNAMI write
373  pkt->makeAtomicResponse();
374  return pioDelay;
375 }
376 
377 void
378 TsunamiCChip::clearIPI(uint64_t ipintr)
379 {
380  int numcpus = sys->threadContexts.size();
381  assert(numcpus <= Tsunami::Max_CPUs);
382 
383  if (ipintr) {
384  for (int cpunum=0; cpunum < numcpus; cpunum++) {
385  // Check each cpu bit
386  uint64_t cpumask = ULL(1) << cpunum;
387  if (ipintr & cpumask) {
388  // Check if there is a pending ipi
389  if (ipint & cpumask) {
390  ipint &= ~cpumask;
392  DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum);
393  }
394  else
395  warn("clear IPI for CPU=%d, but NO IPI\n", cpunum);
396  }
397  }
398  }
399  else
400  panic("Big IPI Clear, but not processors indicated\n");
401 }
402 
403 void
404 TsunamiCChip::clearITI(uint64_t itintr)
405 {
406  int numcpus = sys->threadContexts.size();
407  assert(numcpus <= Tsunami::Max_CPUs);
408 
409  if (itintr) {
410  for (int i=0; i < numcpus; i++) {
411  uint64_t cpumask = ULL(1) << i;
412  if (itintr & cpumask & itint) {
414  itint &= ~cpumask;
415  DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i);
416  }
417  }
418  }
419  else
420  panic("Big ITI Clear, but not processors indicated\n");
421 }
422 
423 void
424 TsunamiCChip::reqIPI(uint64_t ipreq)
425 {
426  int numcpus = sys->threadContexts.size();
427  assert(numcpus <= Tsunami::Max_CPUs);
428 
429  if (ipreq) {
430  for (int cpunum=0; cpunum < numcpus; cpunum++) {
431  // Check each cpu bit
432  uint64_t cpumask = ULL(1) << cpunum;
433  if (ipreq & cpumask) {
434  // Check if there is already an ipi (bits 8:11)
435  if (!(ipint & cpumask)) {
436  ipint |= cpumask;
438  DPRINTF(IPI, "send IPI cpu=%d\n", cpunum);
439  }
440  else
441  warn("post IPI for CPU=%d, but IPI already\n", cpunum);
442  }
443  }
444  }
445  else
446  panic("Big IPI Request, but not processors indicated\n");
447 }
448 
449 
450 void
452 {
453  int size = sys->threadContexts.size();
454  assert(size <= Tsunami::Max_CPUs);
455 
456  for (int i = 0; i < size; i++) {
457  uint64_t cpumask = ULL(1) << i;
458  if (!(cpumask & itint)) {
459  itint |= cpumask;
461  DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d\n", i);
462  }
463  }
464 
465 }
466 
467 void
469 {
470  uint64_t bitvector = ULL(1) << interrupt;
471  uint64_t size = sys->threadContexts.size();
472  assert(size <= Tsunami::Max_CPUs);
473  drir |= bitvector;
474 
475  for (int i=0; i < size; i++) {
476  dir[i] = dim[i] & drir;
477  if (dim[i] & bitvector) {
479  DPRINTF(Tsunami, "posting dir interrupt to cpu %d,"
480  "interrupt %d\n",i, interrupt);
481  }
482  }
483 }
484 
485 void
487 {
488  uint64_t bitvector = ULL(1) << interrupt;
489  uint64_t size = sys->threadContexts.size();
490  assert(size <= Tsunami::Max_CPUs);
491 
492  if (drir & bitvector)
493  {
494  drir &= ~bitvector;
495  for (int i=0; i < size; i++) {
496  if (dir[i] & bitvector) {
498  DPRINTF(Tsunami, "clearing dir interrupt to cpu %d,"
499  "interrupt %d\n",i, interrupt);
500 
501  }
502  dir[i] = dim[i] & drir;
503  }
504  }
505  else
506  DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt);
507 }
508 
509 
510 void
512 {
518 }
519 
520 void
522 {
528 }
529 
530 TsunamiCChip *
531 TsunamiCChipParams::create()
532 {
533  return new TsunamiCChip(this);
534 }
IntrControl * intrctrl
Pointer to the interrupt controller.
Definition: platform.hh:56
#define DPRINTF(x,...)
Definition: trace.hh:212
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
Emulation of the Tsunami CChip CSRs.
#define TSDEV_CC_MPR2
Definition: tsunamireg.h:59
#define TSDEV_CC_MISC
Definition: tsunamireg.h:43
Bitfield< 7 > i
Definition: miscregs.hh:1378
Tsunami * tsunami
pointer to the tsunami object.
ContextID contextId() const
Accessor function for context ID.
Definition: request.hh:694
#define panic(...)
Definition: misc.hh:153
void postDRIR(uint32_t interrupt)
post an interrupt to the CPU.
void postRTC()
post an RTC interrupt to the CPU
void post(int cpu_id, int int_num, int index)
Definition: intr_control.cc:50
void reqIPI(uint64_t ipreq)
request an interrupt be posted to the CPU.
uint64_t drir
This register contains bits for each PCI interrupt that can occur.
TsunamiCChip(const Params *p)
Initialize the Tsunami CChip by setting all of the device register to 0.
Top level class for Tsunami Chipset emulation.
Definition: tsunami.hh:56
#define TSDEV_CC_MPR3
Definition: tsunamireg.h:60
uint64_t ipint
Indicator of which CPUs have an IPI interrupt.
#define TSDEV_CC_DRIR
Definition: tsunamireg.h:53
#define TSDEV_CC_IIC3
Definition: tsunamireg.h:67
static const int Max_CPUs
Max number of CPUs in a Tsunami.
Definition: tsunami.hh:60
uint64_t dim[Tsunami::Max_CPUs]
The dims are device interrupt mask registers.
Port Object Declaration.
TsunamiCChipParams Params
void clearIPI(uint64_t ipintr)
post an ipi interrupt to the CPU.
TsunamiCChip * cchip
Pointer to the Tsunami CChip.
Definition: tsunami.hh:72
#define TSDEV_CC_DIM0
Definition: tsunamireg.h:49
#define TSDEV_CC_MPR0
Definition: tsunamireg.h:57
#define TSDEV_CC_CSR
Definition: tsunamireg.h:41
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
#define TSDEV_CC_MTR
Definition: tsunamireg.h:42
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
#define TSDEV_CC_AAR0
Definition: tsunamireg.h:45
#define TSDEV_CC_ITIR
Definition: tsunamireg.h:74
#define warn(...)
Definition: misc.hh:219
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
Addr pioSize
Size that the device's address range.
Definition: io_device.hh:142
void makeAtomicResponse()
Definition: packet.hh:857
uint64_t Tick
Tick count type.
Definition: types.hh:63
void serialize(CheckpointOut &cp) const override
Serialize an object.
#define TSDEV_CC_DIR1
Definition: tsunamireg.h:52
Declaration of top level class for the Tsunami chipset.
#define TSDEV_CC_IPIQ
Definition: tsunamireg.h:72
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
void clearITI(uint64_t itintr)
clear a timer interrupt previously posted to the CPU.
#define TSDEV_CC_MPR1
Definition: tsunamireg.h:58
#define TSDEV_CC_IPIR
Definition: tsunamireg.h:73
void unserialize(CheckpointIn &cp) override
Unserialize an object.
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
#define TSDEV_CC_BDIRS
Definition: tsunamireg.h:71
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
#define TSDEV_CC_DIM3
Definition: tsunamireg.h:63
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
cbk_int func interrupt
Definition: gpu_nomali.cc:94
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:161
int size()
Definition: pagetable.hh:146
Tsunami CChip CSR Emulation.
#define TSDEV_CC_IIC2
Definition: tsunamireg.h:66
#define TSDEV_CC_IIC1
Definition: tsunamireg.h:56
Declaration of the Packet class.
std::ostream CheckpointOut
Definition: serialize.hh:67
List of Tsunami CSRs.
Tick pioDelay
Delay that the device experinces on an access.
Definition: io_device.hh:145
uint64_t dir[Tsunami::Max_CPUs]
The dirs are device interrupt registers.
#define TSDEV_CC_AAR1
Definition: tsunamireg.h:46
void clearDRIR(uint32_t interrupt)
clear an interrupt previously posted to the CPU.
#define TSDEV_CC_DIR2
Definition: tsunamireg.h:64
unsigned getSize() const
Definition: packet.hh:649
#define TSDEV_CC_AAR3
Definition: tsunamireg.h:48
void clear(int cpu_id, int int_num, int index)
Definition: intr_control.cc:59
uint64_t itint
Indicator of which CPUs have an RTC interrupt.
Bitfield< 0 > p
Addr pioAddr
Address that the device listens to.
Definition: io_device.hh:139
Bitfield< 1 > x
Definition: types.hh:105
#define TSDEV_CC_BDIMS
Definition: tsunamireg.h:70
#define TSDEV_CC_DIR0
Definition: tsunamireg.h:51
#define TSDEV_CC_DIM1
Definition: tsunamireg.h:50
#define TSDEV_CC_IIC0
Definition: tsunamireg.h:55
#define TSDEV_CC_DIM2
Definition: tsunamireg.h:62
#define TSDEV_CC_AAR2
Definition: tsunamireg.h:47
#define TSDEV_CC_DIR3
Definition: tsunamireg.h:65
Addr getAddr() const
Definition: packet.hh:639
#define TSDEV_CC_PRBEN
Definition: tsunamireg.h:54

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