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

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