gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ide_ctrl.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2004-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Andrew Schultz
41  * Ali Saidi
42  * Miguel Serrano
43  */
44 
45 #include "dev/storage/ide_ctrl.hh"
46 
47 #include <string>
48 
49 #include "cpu/intr_control.hh"
50 #include "debug/IdeCtrl.hh"
51 #include "dev/storage/ide_disk.hh"
52 #include "mem/packet.hh"
53 #include "mem/packet_access.hh"
54 #include "params/IdeController.hh"
55 #include "sim/byteswap.hh"
56 
57 // clang complains about std::set being overloaded with Packet::set if
58 // we open up the entire namespace std
59 using std::string;
60 
61 // Bus master IDE registers
63  BMICommand = 0x0,
64  BMIStatus = 0x2,
66 };
67 
68 // PCI config space registers
70  PrimaryTiming = 0x40,
72  DeviceTiming = 0x44,
73  UDMAControl = 0x48,
74  UDMATiming = 0x4A,
75  IDEConfig = 0x54
76 };
77 
78 static const uint16_t timeRegWithDecodeEn = 0x8000;
79 
80 IdeController::Channel::Channel(
81  string newName, Addr _cmdSize, Addr _ctrlSize) :
82  _name(newName),
83  cmdAddr(0), cmdSize(_cmdSize), ctrlAddr(0), ctrlSize(_ctrlSize),
84  master(NULL), slave(NULL), selected(NULL)
85 {
86  memset(&bmiRegs, 0, sizeof(bmiRegs));
87  bmiRegs.status.dmaCap0 = 1;
88  bmiRegs.status.dmaCap1 = 1;
89 }
90 
91 IdeController::Channel::~Channel()
92 {
93 }
94 
96  : PciDevice(p), primary(name() + ".primary", BARSize[0], BARSize[1]),
97  secondary(name() + ".secondary", BARSize[2], BARSize[3]),
98  bmiAddr(0), bmiSize(BARSize[4]),
99  primaryTiming(htole(timeRegWithDecodeEn)),
100  secondaryTiming(htole(timeRegWithDecodeEn)),
101  deviceTiming(0), udmaControl(0), udmaTiming(0), ideConfig(0),
102  ioEnabled(false), bmEnabled(false),
103  ioShift(p->io_shift), ctrlOffset(p->ctrl_offset)
104 {
105  if (params()->disks.size() > 3)
106  panic("IDE controllers support a maximum of 4 devices attached!\n");
107 
108  // Assign the disks to channels
109  int numDisks = params()->disks.size();
110  if (numDisks > 0)
111  primary.master = params()->disks[0];
112  if (numDisks > 1)
113  primary.slave = params()->disks[1];
114  if (numDisks > 2)
115  secondary.master = params()->disks[2];
116  if (numDisks > 3)
117  secondary.slave = params()->disks[3];
118 
119  for (int i = 0; i < params()->disks.size(); i++) {
120  params()->disks[i]->setController(this);
121  }
122  primary.select(false);
123  secondary.select(false);
124 
125  if ((BARAddrs[0] & ~BAR_IO_MASK) && (!legacyIO[0] || ioShift)) {
126  primary.cmdAddr = BARAddrs[0]; primary.cmdSize = BARSize[0];
127  primary.ctrlAddr = BARAddrs[1]; primary.ctrlSize = BARSize[1];
128  }
129  if ((BARAddrs[2] & ~BAR_IO_MASK) && (!legacyIO[2] || ioShift)) {
130  secondary.cmdAddr = BARAddrs[2]; secondary.cmdSize = BARSize[2];
131  secondary.ctrlAddr = BARAddrs[3]; secondary.ctrlSize = BARSize[3];
132  }
133 
136 }
137 
138 bool
140 {
141  return (primary.selected == diskPtr || secondary.selected == diskPtr);
142 }
143 
144 void
146 {
147  primary.bmiRegs.status.intStatus = 1;
149 }
150 
151 void
153 {
154  Channel *channel;
155  if (disk == primary.master || disk == primary.slave) {
156  channel = &primary;
157  } else if (disk == secondary.master || disk == secondary.slave) {
158  channel = &secondary;
159  } else {
160  panic("Unable to find disk based on pointer %#x\n", disk);
161  }
162 
163  channel->bmiRegs.command.startStop = 0;
164  channel->bmiRegs.status.active = 0;
165  channel->bmiRegs.status.intStatus = 1;
166 }
167 
168 Tick
170 {
171  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
172  if (offset < PCI_DEVICE_SPECIFIC) {
173  return PciDevice::readConfig(pkt);
174  }
175 
176  switch (pkt->getSize()) {
177  case sizeof(uint8_t):
178  switch (offset) {
179  case DeviceTiming:
180  pkt->set<uint8_t>(deviceTiming);
181  break;
182  case UDMAControl:
183  pkt->set<uint8_t>(udmaControl);
184  break;
185  case PrimaryTiming + 1:
186  pkt->set<uint8_t>(bits(htole(primaryTiming), 15, 8));
187  break;
188  case SecondaryTiming + 1:
189  pkt->set<uint8_t>(bits(htole(secondaryTiming), 15, 8));
190  break;
191  case IDEConfig:
192  pkt->set<uint8_t>(bits(htole(ideConfig), 7, 0));
193  break;
194  case IDEConfig + 1:
195  pkt->set<uint8_t>(bits(htole(ideConfig), 15, 8));
196  break;
197  default:
198  panic("Invalid PCI configuration read for size 1 at offset: %#x!\n",
199  offset);
200  }
201  DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n", offset,
202  (uint32_t)pkt->get<uint8_t>());
203  break;
204  case sizeof(uint16_t):
205  switch (offset) {
206  case UDMAControl:
207  pkt->set<uint16_t>(udmaControl);
208  break;
209  case PrimaryTiming:
210  pkt->set<uint16_t>(primaryTiming);
211  break;
212  case SecondaryTiming:
213  pkt->set<uint16_t>(secondaryTiming);
214  break;
215  case UDMATiming:
216  pkt->set<uint16_t>(udmaTiming);
217  break;
218  case IDEConfig:
219  pkt->set<uint16_t>(ideConfig);
220  break;
221  default:
222  panic("Invalid PCI configuration read for size 2 offset: %#x!\n",
223  offset);
224  }
225  DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset,
226  (uint32_t)pkt->get<uint16_t>());
227  break;
228  case sizeof(uint32_t):
229  switch (offset) {
230  case PrimaryTiming:
231  pkt->set<uint32_t>(primaryTiming);
232  break;
233  case IDEConfig:
234  pkt->set<uint32_t>(ideConfig);
235  break;
236  default:
237  panic("No 32bit reads implemented for this device.");
238  }
239  DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset,
240  (uint32_t)pkt->get<uint32_t>());
241  break;
242  default:
243  panic("invalid access size(?) for PCI configspace!\n");
244  }
245  pkt->makeAtomicResponse();
246  return configDelay;
247 }
248 
249 
250 Tick
252 {
253  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
254  if (offset < PCI_DEVICE_SPECIFIC) {
256  } else {
257  switch (pkt->getSize()) {
258  case sizeof(uint8_t):
259  switch (offset) {
260  case DeviceTiming:
261  deviceTiming = pkt->get<uint8_t>();
262  break;
263  case UDMAControl:
264  udmaControl = pkt->get<uint8_t>();
265  break;
266  case IDEConfig:
267  replaceBits(ideConfig, 7, 0, pkt->get<uint8_t>());
268  break;
269  case IDEConfig + 1:
270  replaceBits(ideConfig, 15, 8, pkt->get<uint8_t>());
271  break;
272  default:
273  panic("Invalid PCI configuration write "
274  "for size 1 offset: %#x!\n", offset);
275  }
276  DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n",
277  offset, (uint32_t)pkt->get<uint8_t>());
278  break;
279  case sizeof(uint16_t):
280  switch (offset) {
281  case UDMAControl:
282  udmaControl = pkt->get<uint16_t>();
283  break;
284  case PrimaryTiming:
285  primaryTiming = pkt->get<uint16_t>();
286  break;
287  case SecondaryTiming:
288  secondaryTiming = pkt->get<uint16_t>();
289  break;
290  case UDMATiming:
291  udmaTiming = pkt->get<uint16_t>();
292  break;
293  case IDEConfig:
294  ideConfig = pkt->get<uint16_t>();
295  break;
296  default:
297  panic("Invalid PCI configuration write "
298  "for size 2 offset: %#x!\n",
299  offset);
300  }
301  DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n",
302  offset, (uint32_t)pkt->get<uint16_t>());
303  break;
304  case sizeof(uint32_t):
305  switch (offset) {
306  case PrimaryTiming:
307  primaryTiming = pkt->get<uint32_t>();
308  break;
309  case IDEConfig:
310  ideConfig = pkt->get<uint32_t>();
311  break;
312  default:
313  panic("Write of unimplemented PCI config. register: %x\n", offset);
314  }
315  break;
316  default:
317  panic("invalid access size(?) for PCI configspace!\n");
318  }
319  pkt->makeAtomicResponse();
320  }
321 
322  /* Trap command register writes and enable IO/BM as appropriate as well as
323  * BARs. */
324  switch(offset) {
325  case PCI0_BASE_ADDR0:
326  if (BARAddrs[0] != 0)
327  primary.cmdAddr = BARAddrs[0];
328  break;
329 
330  case PCI0_BASE_ADDR1:
331  if (BARAddrs[1] != 0)
332  primary.ctrlAddr = BARAddrs[1];
333  break;
334 
335  case PCI0_BASE_ADDR2:
336  if (BARAddrs[2] != 0)
337  secondary.cmdAddr = BARAddrs[2];
338  break;
339 
340  case PCI0_BASE_ADDR3:
341  if (BARAddrs[3] != 0)
342  secondary.ctrlAddr = BARAddrs[3];
343  break;
344 
345  case PCI0_BASE_ADDR4:
346  if (BARAddrs[4] != 0)
347  bmiAddr = BARAddrs[4];
348  break;
349 
350  case PCI_COMMAND:
351  DPRINTF(IdeCtrl, "Writing to PCI Command val: %#x\n", config.command);
354  break;
355  }
356  return configDelay;
357 }
358 
359 void
360 IdeController::Channel::accessCommand(Addr offset,
361  int size, uint8_t *data, bool read)
362 {
363  const Addr SelectOffset = 6;
364  const uint8_t SelectDevBit = 0x10;
365 
366  if (!read && offset == SelectOffset)
367  select(*data & SelectDevBit);
368 
369  if (selected == NULL) {
370  assert(size == sizeof(uint8_t));
371  *data = 0;
372  } else if (read) {
373  selected->readCommand(offset, size, data);
374  } else {
375  selected->writeCommand(offset, size, data);
376  }
377 }
378 
379 void
380 IdeController::Channel::accessControl(Addr offset,
381  int size, uint8_t *data, bool read)
382 {
383  if (selected == NULL) {
384  assert(size == sizeof(uint8_t));
385  *data = 0;
386  } else if (read) {
387  selected->readControl(offset, size, data);
388  } else {
389  selected->writeControl(offset, size, data);
390  }
391 }
392 
393 void
394 IdeController::Channel::accessBMI(Addr offset,
395  int size, uint8_t *data, bool read)
396 {
397  assert(offset + size <= sizeof(BMIRegs));
398  if (read) {
399  memcpy(data, (uint8_t *)&bmiRegs + offset, size);
400  } else {
401  switch (offset) {
402  case BMICommand:
403  {
404  if (size != sizeof(uint8_t))
405  panic("Invalid BMIC write size: %x\n", size);
406 
407  BMICommandReg oldVal = bmiRegs.command;
408  BMICommandReg newVal = *data;
409 
410  // if a DMA transfer is in progress, R/W control cannot change
411  if (oldVal.startStop && oldVal.rw != newVal.rw)
412  oldVal.rw = newVal.rw;
413 
414  if (oldVal.startStop != newVal.startStop) {
415  if (selected == NULL)
416  panic("DMA start for disk which does not exist\n");
417 
418  if (oldVal.startStop) {
419  DPRINTF(IdeCtrl, "Stopping DMA transfer\n");
420  bmiRegs.status.active = 0;
421 
422  selected->abortDma();
423  } else {
424  DPRINTF(IdeCtrl, "Starting DMA transfer\n");
425  bmiRegs.status.active = 1;
426 
427  selected->startDma(letoh(bmiRegs.bmidtp));
428  }
429  }
430 
431  bmiRegs.command = newVal;
432  }
433  break;
434  case BMIStatus:
435  {
436  if (size != sizeof(uint8_t))
437  panic("Invalid BMIS write size: %x\n", size);
438 
439  BMIStatusReg oldVal = bmiRegs.status;
440  BMIStatusReg newVal = *data;
441 
442  // the BMIDEA bit is read only
443  newVal.active = oldVal.active;
444 
445  // to reset (set 0) IDEINTS and IDEDMAE, write 1 to each
446  if ((oldVal.intStatus == 1) && (newVal.intStatus == 1)) {
447  newVal.intStatus = 0; // clear the interrupt?
448  } else {
449  // Assigning two bitunion fields to each other does not
450  // work as intended, so we need to use this temporary variable
451  // to get around the bug.
452  uint8_t tmp = oldVal.intStatus;
453  newVal.intStatus = tmp;
454  }
455  if ((oldVal.dmaError == 1) && (newVal.dmaError == 1)) {
456  newVal.dmaError = 0;
457  } else {
458  uint8_t tmp = oldVal.dmaError;
459  newVal.dmaError = tmp;
460  }
461 
462  bmiRegs.status = newVal;
463  }
464  break;
465  case BMIDescTablePtr:
466  if (size != sizeof(uint32_t))
467  panic("Invalid BMIDTP write size: %x\n", size);
468  bmiRegs.bmidtp = htole(*(uint32_t *)data & ~0x3);
469  break;
470  default:
471  if (size != sizeof(uint8_t) && size != sizeof(uint16_t) &&
472  size != sizeof(uint32_t))
473  panic("IDE controller write of invalid write size: %x\n", size);
474  memcpy((uint8_t *)&bmiRegs + offset, data, size);
475  }
476  }
477 }
478 
479 void
481 {
482  if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4)
483  panic("Bad IDE read size: %d\n", pkt->getSize());
484 
485  if (!ioEnabled) {
486  pkt->makeAtomicResponse();
487  DPRINTF(IdeCtrl, "io not enabled\n");
488  return;
489  }
490 
491  Addr addr = pkt->getAddr();
492  int size = pkt->getSize();
493  uint8_t *dataPtr = pkt->getPtr<uint8_t>();
494 
495  if (addr >= primary.cmdAddr &&
496  addr < (primary.cmdAddr + primary.cmdSize)) {
497  addr -= primary.cmdAddr;
498  // linux may have shifted the address by ioShift,
499  // here we shift it back, similarly for ctrlOffset.
500  addr >>= ioShift;
501  primary.accessCommand(addr, size, dataPtr, read);
502  } else if (addr >= primary.ctrlAddr &&
503  addr < (primary.ctrlAddr + primary.ctrlSize)) {
504  addr -= primary.ctrlAddr;
505  addr += ctrlOffset;
506  primary.accessControl(addr, size, dataPtr, read);
507  } else if (addr >= secondary.cmdAddr &&
508  addr < (secondary.cmdAddr + secondary.cmdSize)) {
509  addr -= secondary.cmdAddr;
510  secondary.accessCommand(addr, size, dataPtr, read);
511  } else if (addr >= secondary.ctrlAddr &&
512  addr < (secondary.ctrlAddr + secondary.ctrlSize)) {
513  addr -= secondary.ctrlAddr;
514  secondary.accessControl(addr, size, dataPtr, read);
515  } else if (addr >= bmiAddr && addr < (bmiAddr + bmiSize)) {
516  if (!read && !bmEnabled)
517  return;
518  addr -= bmiAddr;
519  if (addr < sizeof(Channel::BMIRegs)) {
520  primary.accessBMI(addr, size, dataPtr, read);
521  } else {
522  addr -= sizeof(Channel::BMIRegs);
523  secondary.accessBMI(addr, size, dataPtr, read);
524  }
525  } else {
526  panic("IDE controller access to invalid address: %#x\n", addr);
527  }
528 
529 #ifndef NDEBUG
530  uint32_t data;
531  if (pkt->getSize() == 1)
532  data = pkt->get<uint8_t>();
533  else if (pkt->getSize() == 2)
534  data = pkt->get<uint16_t>();
535  else
536  data = pkt->get<uint32_t>();
537  DPRINTF(IdeCtrl, "%s from offset: %#x size: %#x data: %#x\n",
538  read ? "Read" : "Write", pkt->getAddr(), pkt->getSize(), data);
539 #endif
540 
541  pkt->makeAtomicResponse();
542 }
543 
544 Tick
546 {
547  dispatchAccess(pkt, true);
548  return pioDelay;
549 }
550 
551 Tick
553 {
554  dispatchAccess(pkt, false);
555  return pioDelay;
556 }
557 
558 void
560 {
561  // Serialize the PciDevice base class
563 
564  // Serialize channels
565  primary.serialize("primary", cp);
566  secondary.serialize("secondary", cp);
567 
568  // Serialize config registers
575 
576  // Serialize internal state
581 }
582 
583 void
584 IdeController::Channel::serialize(const std::string &base,
585  CheckpointOut &cp) const
586 {
587  paramOut(cp, base + ".cmdAddr", cmdAddr);
588  paramOut(cp, base + ".cmdSize", cmdSize);
589  paramOut(cp, base + ".ctrlAddr", ctrlAddr);
590  paramOut(cp, base + ".ctrlSize", ctrlSize);
591  uint8_t command = bmiRegs.command;
592  paramOut(cp, base + ".bmiRegs.command", command);
593  paramOut(cp, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
594  uint8_t status = bmiRegs.status;
595  paramOut(cp, base + ".bmiRegs.status", status);
596  paramOut(cp, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
597  paramOut(cp, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
598  paramOut(cp, base + ".selectBit", selectBit);
599 }
600 
601 void
603 {
604  // Unserialize the PciDevice base class
606 
607  // Unserialize channels
608  primary.unserialize("primary", cp);
609  secondary.unserialize("secondary", cp);
610 
611  // Unserialize config registers
618 
619  // Unserialize internal state
624 }
625 
626 void
628 {
629  paramIn(cp, base + ".cmdAddr", cmdAddr);
630  paramIn(cp, base + ".cmdSize", cmdSize);
631  paramIn(cp, base + ".ctrlAddr", ctrlAddr);
632  paramIn(cp, base + ".ctrlSize", ctrlSize);
633  uint8_t command;
634  paramIn(cp, base +".bmiRegs.command", command);
635  bmiRegs.command = command;
636  paramIn(cp, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
637  uint8_t status;
638  paramIn(cp, base + ".bmiRegs.status", status);
639  bmiRegs.status = status;
640  paramIn(cp, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
641  paramIn(cp, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
642  paramIn(cp, base + ".selectBit", selectBit);
643  select(selectBit);
644 }
645 
647 IdeControllerParams::create()
648 {
649  return new IdeController(this);
650 }
#define DPRINTF(x,...)
Definition: trace.hh:212
Tick readConfig(PacketPtr pkt) override
Read from the PCI config space data that is stored locally.
Definition: ide_ctrl.cc:169
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
#define BAR_IO_MASK
Definition: device.hh:61
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: device.cc:490
const std::string & name()
Definition: trace.cc:49
Bitfield< 7 > i
Definition: miscregs.hh:1378
#define panic(...)
Definition: misc.hh:153
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: ide_ctrl.cc:602
PCI device, base implementation is only config space.
Definition: device.hh:70
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
Definition: ide_ctrl.cc:139
#define PCI_CONFIG_SIZE
Definition: pcireg.h:152
Device model for an IDE disk.
#define PCI0_BASE_ADDR3
Definition: pcireg.h:112
ip6_addr_t addr
Definition: inet.hh:335
uint16_t ideConfig
Definition: ide_ctrl.hh:128
uint16_t secondaryTiming
Definition: ide_ctrl.hh:124
Device model for an Intel PIIX4 IDE controller.
Definition: ide_ctrl.hh:51
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: ide_ctrl.cc:545
const Params * params() const
Definition: ide_ctrl.hh:140
Simple PCI IDE controller with bus mastering capability and UDMA modeled after controller in the Inte...
Bitfield< 23, 0 > offset
Definition: types.hh:149
T letoh(T value)
Definition: byteswap.hh:152
bool ioEnabled
Definition: ide_ctrl.hh:131
uint8_t udmaControl
Definition: ide_ctrl.hh:126
T * getPtr()
get a pointer to the data ptr.
Definition: packet.hh:959
uint16_t primaryTiming
Registers used in device specific PCI configuration.
Definition: ide_ctrl.hh:124
IdeController(Params *p)
Definition: ide_ctrl.cc:95
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
void dispatchAccess(PacketPtr pkt, bool read)
Definition: ide_ctrl.cc:480
const char data[]
Definition: circlebuf.cc:43
ConfRegOffset
Definition: ide_ctrl.cc:69
Bitfield< 5, 0 > status
Definition: miscregs.hh:1604
uint32_t ctrlOffset
Definition: ide_ctrl.hh:134
Channel primary
Definition: ide_ctrl.hh:115
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
#define PCI_CMD_BME
Definition: pcireg.h:104
T htole(T value)
Definition: byteswap.hh:151
uint8_t deviceTiming
Definition: ide_ctrl.hh:125
bool legacyIO[6]
Whether the BARs are really hardwired legacy IO locations.
Definition: device.hh:116
#define PCI0_BASE_ADDR2
Definition: pcireg.h:111
void makeAtomicResponse()
Definition: packet.hh:857
DmaDeviceParams Params
Definition: dma_device.hh:160
uint64_t Tick
Tick count type.
Definition: types.hh:63
uint16_t udmaTiming
Definition: ide_ctrl.hh:127
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Definition: device.cc:288
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:40
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:145
BMIRegOffset
Definition: ide_ctrl.cc:62
Bitfield< 51, 12 > base
Definition: pagetable.hh:85
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition: device.cc:220
uint32_t ioShift
Definition: ide_ctrl.hh:134
#define PCI_DEVICE_SPECIFIC
Definition: pcireg.h:151
Tick pioDelay
Definition: device.hh:185
#define PCI0_BASE_ADDR1
Definition: pcireg.h:110
Tick configDelay
Definition: device.hh:186
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
Addr BARAddrs[6]
The current address mapping of the BARs.
Definition: device.hh:113
uint16_t command
Definition: pcireg.h:62
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
Addr bmiAddr
Bus master interface (BMI) registers.
Definition: ide_ctrl.hh:121
int size()
Definition: pagetable.hh:146
IDE Disk device model.
Definition: ide_disk.hh:207
Declaration of the Packet class.
std::ostream CheckpointOut
Definition: serialize.hh:67
static const uint16_t timeRegWithDecodeEn
Definition: ide_ctrl.cc:78
#define PCI0_BASE_ADDR0
Definition: pcireg.h:109
#define PCI_CMD_IOSE
Definition: pcireg.h:106
Channel secondary
Definition: ide_ctrl.hh:118
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:71
void serialize(CheckpointOut &cp) const override
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: ide_ctrl.cc:559
unsigned getSize() const
Definition: packet.hh:649
void unserialize(CheckpointIn &cp) override
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
void intrPost()
Definition: device.hh:193
bool bmEnabled
Definition: ide_ctrl.hh:132
PCIConfig config
The current config space.
Definition: device.hh:76
Bitfield< 0 > p
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: ide_ctrl.cc:552
void setDmaComplete(IdeDisk *disk)
Definition: ide_ctrl.cc:152
void intrPost()
Definition: ide_ctrl.cc:145
#define PCI0_BASE_ADDR4
Definition: pcireg.h:113
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
Definition: ide_ctrl.cc:251
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:425
uint32_t BARSize[6]
The size of the BARs.
Definition: device.hh:110
Addr getAddr() const
Definition: packet.hh:639
#define PCI_COMMAND
Definition: pcireg.h:92

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