gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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  bmiRegs.reset();
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 
106  // Assign the disks to channels
107  for (int i = 0; i < params()->disks.size(); i++) {
108  if (!params()->disks[i])
109  continue;
110  switch (i) {
111  case 0:
112  primary.master = params()->disks[0];
113  break;
114  case 1:
115  primary.slave = params()->disks[1];
116  break;
117  case 2:
118  secondary.master = params()->disks[2];
119  break;
120  case 3:
121  secondary.slave = params()->disks[3];
122  break;
123  default:
124  panic("IDE controllers support a maximum "
125  "of 4 devices attached!\n");
126  }
127  params()->disks[i]->setController(this, sys->getPageBytes());
128  }
129 
130  primary.select(false);
131  secondary.select(false);
132 
133  if ((BARAddrs[0] & ~BAR_IO_MASK) && (!legacyIO[0] || ioShift)) {
134  primary.cmdAddr = BARAddrs[0]; primary.cmdSize = BARSize[0];
135  primary.ctrlAddr = BARAddrs[1]; primary.ctrlSize = BARSize[1];
136  }
137  if ((BARAddrs[2] & ~BAR_IO_MASK) && (!legacyIO[2] || ioShift)) {
138  secondary.cmdAddr = BARAddrs[2]; secondary.cmdSize = BARSize[2];
139  secondary.ctrlAddr = BARAddrs[3]; secondary.ctrlSize = BARSize[3];
140  }
141 
144 }
145 
146 bool
148 {
149  return (primary.selected == diskPtr || secondary.selected == diskPtr);
150 }
151 
152 void
154 {
155  primary.bmiRegs.status.intStatus = 1;
157 }
158 
159 void
161 {
162  Channel *channel;
163  if (disk == primary.master || disk == primary.slave) {
164  channel = &primary;
165  } else if (disk == secondary.master || disk == secondary.slave) {
166  channel = &secondary;
167  } else {
168  panic("Unable to find disk based on pointer %#x\n", disk);
169  }
170 
171  channel->bmiRegs.command.startStop = 0;
172  channel->bmiRegs.status.active = 0;
173  channel->bmiRegs.status.intStatus = 1;
174 }
175 
176 Tick
178 {
179  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
180  if (offset < PCI_DEVICE_SPECIFIC) {
181  return PciDevice::readConfig(pkt);
182  }
183 
184  switch (pkt->getSize()) {
185  case sizeof(uint8_t):
186  switch (offset) {
187  case DeviceTiming:
188  pkt->setLE<uint8_t>(deviceTiming);
189  break;
190  case UDMAControl:
191  pkt->setLE<uint8_t>(udmaControl);
192  break;
193  case PrimaryTiming + 1:
194  pkt->setLE<uint8_t>(bits(htole(primaryTiming), 15, 8));
195  break;
196  case SecondaryTiming + 1:
197  pkt->setLE<uint8_t>(bits(htole(secondaryTiming), 15, 8));
198  break;
199  case IDEConfig:
200  pkt->setLE<uint8_t>(bits(htole(ideConfig), 7, 0));
201  break;
202  case IDEConfig + 1:
203  pkt->setLE<uint8_t>(bits(htole(ideConfig), 15, 8));
204  break;
205  default:
206  panic("Invalid PCI configuration read for size 1 at offset: %#x!\n",
207  offset);
208  }
209  DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n", offset,
210  (uint32_t)pkt->getLE<uint8_t>());
211  break;
212  case sizeof(uint16_t):
213  switch (offset) {
214  case UDMAControl:
215  pkt->setLE<uint16_t>(udmaControl);
216  break;
217  case PrimaryTiming:
218  pkt->setLE<uint16_t>(primaryTiming);
219  break;
220  case SecondaryTiming:
221  pkt->setLE<uint16_t>(secondaryTiming);
222  break;
223  case UDMATiming:
224  pkt->setLE<uint16_t>(udmaTiming);
225  break;
226  case IDEConfig:
227  pkt->setLE<uint16_t>(ideConfig);
228  break;
229  default:
230  panic("Invalid PCI configuration read for size 2 offset: %#x!\n",
231  offset);
232  }
233  DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset,
234  (uint32_t)pkt->getLE<uint16_t>());
235  break;
236  case sizeof(uint32_t):
237  switch (offset) {
238  case PrimaryTiming:
239  pkt->setLE<uint32_t>(primaryTiming);
240  break;
241  case IDEConfig:
242  pkt->setLE<uint32_t>(ideConfig);
243  break;
244  default:
245  panic("No 32bit reads implemented for this device.");
246  }
247  DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset,
248  (uint32_t)pkt->getLE<uint32_t>());
249  break;
250  default:
251  panic("invalid access size(?) for PCI configspace!\n");
252  }
253  pkt->makeAtomicResponse();
254  return configDelay;
255 }
256 
257 
258 Tick
260 {
261  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
262  if (offset < PCI_DEVICE_SPECIFIC) {
264  } else {
265  switch (pkt->getSize()) {
266  case sizeof(uint8_t):
267  switch (offset) {
268  case DeviceTiming:
269  deviceTiming = pkt->getLE<uint8_t>();
270  break;
271  case UDMAControl:
272  udmaControl = pkt->getLE<uint8_t>();
273  break;
274  case IDEConfig:
275  replaceBits(ideConfig, 7, 0, pkt->getLE<uint8_t>());
276  break;
277  case IDEConfig + 1:
278  replaceBits(ideConfig, 15, 8, pkt->getLE<uint8_t>());
279  break;
280  default:
281  panic("Invalid PCI configuration write "
282  "for size 1 offset: %#x!\n", offset);
283  }
284  DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n",
285  offset, (uint32_t)pkt->getLE<uint8_t>());
286  break;
287  case sizeof(uint16_t):
288  switch (offset) {
289  case UDMAControl:
290  udmaControl = pkt->getLE<uint16_t>();
291  break;
292  case PrimaryTiming:
293  primaryTiming = pkt->getLE<uint16_t>();
294  break;
295  case SecondaryTiming:
296  secondaryTiming = pkt->getLE<uint16_t>();
297  break;
298  case UDMATiming:
299  udmaTiming = pkt->getLE<uint16_t>();
300  break;
301  case IDEConfig:
302  ideConfig = pkt->getLE<uint16_t>();
303  break;
304  default:
305  panic("Invalid PCI configuration write "
306  "for size 2 offset: %#x!\n",
307  offset);
308  }
309  DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n",
310  offset, (uint32_t)pkt->getLE<uint16_t>());
311  break;
312  case sizeof(uint32_t):
313  switch (offset) {
314  case PrimaryTiming:
315  primaryTiming = pkt->getLE<uint32_t>();
316  break;
317  case IDEConfig:
318  ideConfig = pkt->getLE<uint32_t>();
319  break;
320  default:
321  panic("Write of unimplemented PCI config. register: %x\n", offset);
322  }
323  break;
324  default:
325  panic("invalid access size(?) for PCI configspace!\n");
326  }
327  pkt->makeAtomicResponse();
328  }
329 
330  /* Trap command register writes and enable IO/BM as appropriate as well as
331  * BARs. */
332  switch(offset) {
333  case PCI0_BASE_ADDR0:
334  if (BARAddrs[0] != 0)
335  primary.cmdAddr = BARAddrs[0];
336  break;
337 
338  case PCI0_BASE_ADDR1:
339  if (BARAddrs[1] != 0)
340  primary.ctrlAddr = BARAddrs[1];
341  break;
342 
343  case PCI0_BASE_ADDR2:
344  if (BARAddrs[2] != 0)
345  secondary.cmdAddr = BARAddrs[2];
346  break;
347 
348  case PCI0_BASE_ADDR3:
349  if (BARAddrs[3] != 0)
350  secondary.ctrlAddr = BARAddrs[3];
351  break;
352 
353  case PCI0_BASE_ADDR4:
354  if (BARAddrs[4] != 0)
355  bmiAddr = BARAddrs[4];
356  break;
357 
358  case PCI_COMMAND:
359  DPRINTF(IdeCtrl, "Writing to PCI Command val: %#x\n", config.command);
362  break;
363  }
364  return configDelay;
365 }
366 
367 void
368 IdeController::Channel::accessCommand(Addr offset,
369  int size, uint8_t *data, bool read)
370 {
371  const Addr SelectOffset = 6;
372  const uint8_t SelectDevBit = 0x10;
373 
374  if (!read && offset == SelectOffset)
375  select(*data & SelectDevBit);
376 
377  if (selected == NULL) {
378  assert(size == sizeof(uint8_t));
379  *data = 0;
380  } else if (read) {
381  selected->readCommand(offset, size, data);
382  } else {
383  selected->writeCommand(offset, size, data);
384  }
385 }
386 
387 void
388 IdeController::Channel::accessControl(Addr offset,
389  int size, uint8_t *data, bool read)
390 {
391  if (selected == NULL) {
392  assert(size == sizeof(uint8_t));
393  *data = 0;
394  } else if (read) {
395  selected->readControl(offset, size, data);
396  } else {
397  selected->writeControl(offset, size, data);
398  }
399 }
400 
401 void
402 IdeController::Channel::accessBMI(Addr offset,
403  int size, uint8_t *data, bool read)
404 {
405  assert(offset + size <= sizeof(BMIRegs));
406  if (read) {
407  memcpy(data, (uint8_t *)&bmiRegs + offset, size);
408  } else {
409  switch (offset) {
410  case BMICommand:
411  {
412  if (size != sizeof(uint8_t))
413  panic("Invalid BMIC write size: %x\n", size);
414 
415  BMICommandReg oldVal = bmiRegs.command;
416  BMICommandReg newVal = *data;
417 
418  // if a DMA transfer is in progress, R/W control cannot change
419  if (oldVal.startStop && oldVal.rw != newVal.rw)
420  oldVal.rw = newVal.rw;
421 
422  if (oldVal.startStop != newVal.startStop) {
423  if (selected == NULL)
424  panic("DMA start for disk which does not exist\n");
425 
426  if (oldVal.startStop) {
427  DPRINTF(IdeCtrl, "Stopping DMA transfer\n");
428  bmiRegs.status.active = 0;
429 
430  selected->abortDma();
431  } else {
432  DPRINTF(IdeCtrl, "Starting DMA transfer\n");
433  bmiRegs.status.active = 1;
434 
435  selected->startDma(letoh(bmiRegs.bmidtp));
436  }
437  }
438 
439  bmiRegs.command = newVal;
440  }
441  break;
442  case BMIStatus:
443  {
444  if (size != sizeof(uint8_t))
445  panic("Invalid BMIS write size: %x\n", size);
446 
447  BMIStatusReg oldVal = bmiRegs.status;
448  BMIStatusReg newVal = *data;
449 
450  // the BMIDEA bit is read only
451  newVal.active = oldVal.active;
452 
453  // to reset (set 0) IDEINTS and IDEDMAE, write 1 to each
454  if ((oldVal.intStatus == 1) && (newVal.intStatus == 1)) {
455  newVal.intStatus = 0; // clear the interrupt?
456  } else {
457  // Assigning two bitunion fields to each other does not
458  // work as intended, so we need to use this temporary variable
459  // to get around the bug.
460  uint8_t tmp = oldVal.intStatus;
461  newVal.intStatus = tmp;
462  }
463  if ((oldVal.dmaError == 1) && (newVal.dmaError == 1)) {
464  newVal.dmaError = 0;
465  } else {
466  uint8_t tmp = oldVal.dmaError;
467  newVal.dmaError = tmp;
468  }
469 
470  bmiRegs.status = newVal;
471  }
472  break;
473  case BMIDescTablePtr:
474  if (size != sizeof(uint32_t))
475  panic("Invalid BMIDTP write size: %x\n", size);
476  bmiRegs.bmidtp = htole(*(uint32_t *)data & ~0x3);
477  break;
478  default:
479  if (size != sizeof(uint8_t) && size != sizeof(uint16_t) &&
480  size != sizeof(uint32_t))
481  panic("IDE controller write of invalid write size: %x\n", size);
482  memcpy((uint8_t *)&bmiRegs + offset, data, size);
483  }
484  }
485 }
486 
487 void
489 {
490  if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4)
491  panic("Bad IDE read size: %d\n", pkt->getSize());
492 
493  if (!ioEnabled) {
494  pkt->makeAtomicResponse();
495  DPRINTF(IdeCtrl, "io not enabled\n");
496  return;
497  }
498 
499  Addr addr = pkt->getAddr();
500  int size = pkt->getSize();
501  uint8_t *dataPtr = pkt->getPtr<uint8_t>();
502 
503  if (addr >= primary.cmdAddr &&
504  addr < (primary.cmdAddr + primary.cmdSize)) {
505  addr -= primary.cmdAddr;
506  // linux may have shifted the address by ioShift,
507  // here we shift it back, similarly for ctrlOffset.
508  addr >>= ioShift;
509  primary.accessCommand(addr, size, dataPtr, read);
510  } else if (addr >= primary.ctrlAddr &&
511  addr < (primary.ctrlAddr + primary.ctrlSize)) {
512  addr -= primary.ctrlAddr;
513  addr += ctrlOffset;
514  primary.accessControl(addr, size, dataPtr, read);
515  } else if (addr >= secondary.cmdAddr &&
516  addr < (secondary.cmdAddr + secondary.cmdSize)) {
517  addr -= secondary.cmdAddr;
518  secondary.accessCommand(addr, size, dataPtr, read);
519  } else if (addr >= secondary.ctrlAddr &&
520  addr < (secondary.ctrlAddr + secondary.ctrlSize)) {
521  addr -= secondary.ctrlAddr;
522  secondary.accessControl(addr, size, dataPtr, read);
523  } else if (addr >= bmiAddr && addr < (bmiAddr + bmiSize)) {
524  if (!read && !bmEnabled)
525  return;
526  addr -= bmiAddr;
527  if (addr < sizeof(Channel::BMIRegs)) {
528  primary.accessBMI(addr, size, dataPtr, read);
529  } else {
530  addr -= sizeof(Channel::BMIRegs);
531  secondary.accessBMI(addr, size, dataPtr, read);
532  }
533  } else {
534  panic("IDE controller access to invalid address: %#x\n", addr);
535  }
536 
537 #ifndef NDEBUG
538  uint32_t data;
539  if (pkt->getSize() == 1)
540  data = pkt->getLE<uint8_t>();
541  else if (pkt->getSize() == 2)
542  data = pkt->getLE<uint16_t>();
543  else
544  data = pkt->getLE<uint32_t>();
545  DPRINTF(IdeCtrl, "%s from offset: %#x size: %#x data: %#x\n",
546  read ? "Read" : "Write", pkt->getAddr(), pkt->getSize(), data);
547 #endif
548 
549  pkt->makeAtomicResponse();
550 }
551 
552 Tick
554 {
555  dispatchAccess(pkt, true);
556  return pioDelay;
557 }
558 
559 Tick
561 {
562  dispatchAccess(pkt, false);
563  return pioDelay;
564 }
565 
566 void
568 {
569  // Serialize the PciDevice base class
571 
572  // Serialize channels
573  primary.serialize("primary", cp);
574  secondary.serialize("secondary", cp);
575 
576  // Serialize config registers
583 
584  // Serialize internal state
589 }
590 
591 void
592 IdeController::Channel::serialize(const std::string &base,
593  CheckpointOut &cp) const
594 {
595  paramOut(cp, base + ".cmdAddr", cmdAddr);
596  paramOut(cp, base + ".cmdSize", cmdSize);
597  paramOut(cp, base + ".ctrlAddr", ctrlAddr);
598  paramOut(cp, base + ".ctrlSize", ctrlSize);
599  uint8_t command = bmiRegs.command;
600  paramOut(cp, base + ".bmiRegs.command", command);
601  paramOut(cp, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
602  uint8_t status = bmiRegs.status;
603  paramOut(cp, base + ".bmiRegs.status", status);
604  paramOut(cp, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
605  paramOut(cp, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
606  paramOut(cp, base + ".selectBit", selectBit);
607 }
608 
609 void
611 {
612  // Unserialize the PciDevice base class
614 
615  // Unserialize channels
616  primary.unserialize("primary", cp);
617  secondary.unserialize("secondary", cp);
618 
619  // Unserialize config registers
626 
627  // Unserialize internal state
632 }
633 
634 void
636 {
637  paramIn(cp, base + ".cmdAddr", cmdAddr);
638  paramIn(cp, base + ".cmdSize", cmdSize);
639  paramIn(cp, base + ".ctrlAddr", ctrlAddr);
640  paramIn(cp, base + ".ctrlSize", ctrlSize);
641  uint8_t command;
642  paramIn(cp, base +".bmiRegs.command", command);
643  bmiRegs.command = command;
644  paramIn(cp, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
645  uint8_t status;
646  paramIn(cp, base + ".bmiRegs.status", status);
647  bmiRegs.status = status;
648  paramIn(cp, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
649  paramIn(cp, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
650  paramIn(cp, base + ".selectBit", selectBit);
651  select(selectBit);
652 }
653 
655 IdeControllerParams::create()
656 {
657  return new IdeController(this);
658 }
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:229
Tick readConfig(PacketPtr pkt) override
Read from the PCI config space data that is stored locally.
Definition: ide_ctrl.cc:177
#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:511
const std::string & name()
Definition: trace.cc:54
Bitfield< 7 > i
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: ide_ctrl.cc:610
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:147
#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:132
uint16_t secondaryTiming
Definition: ide_ctrl.hh:128
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:553
Simple PCI IDE controller with bus mastering capability and UDMA modeled after controller in the Inte...
Bitfield< 23, 0 > offset
Definition: types.hh:154
T letoh(T value)
Definition: byteswap.hh:145
Definition: cprintf.cc:42
bool ioEnabled
Definition: ide_ctrl.hh:135
uint8_t udmaControl
Definition: ide_ctrl.hh:130
T * getPtr()
get a pointer to the data ptr.
Definition: packet.hh:1090
uint16_t primaryTiming
Registers used in device specific PCI configuration.
Definition: ide_ctrl.hh:128
IdeController(Params *p)
Definition: ide_ctrl.cc:95
void dispatchAccess(PacketPtr pkt, bool read)
Definition: ide_ctrl.cc:488
void setLE(T v)
Set the value in the data pointer to v as little endian.
ConfRegOffset
Definition: ide_ctrl.cc:69
Bitfield< 5, 0 > status
unsigned getSize() const
Definition: packet.hh:736
uint32_t ctrlOffset
Definition: ide_ctrl.hh:138
Channel primary
Definition: ide_ctrl.hh:119
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:645
#define PCI_CMD_BME
Definition: pcireg.h:104
T htole(T value)
Definition: byteswap.hh:144
uint8_t deviceTiming
Definition: ide_ctrl.hh:129
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:949
DmaDeviceParams Params
Definition: dma_device.hh:175
uint64_t Tick
Tick count type.
Definition: types.hh:63
uint16_t udmaTiming
Definition: ide_ctrl.hh:131
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:157
BMIRegOffset
Definition: ide_ctrl.cc:62
Bitfield< 51, 12 > base
Definition: pagetable.hh:142
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
Addr getAddr() const
Definition: packet.hh:726
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:138
const Params * params() const
Definition: ide_ctrl.hh:144
#define PCI_DEVICE_SPECIFIC
Definition: pcireg.h:151
Tick pioDelay
Definition: device.hh:194
#define PCI0_BASE_ADDR1
Definition: pcireg.h:110
Tick configDelay
Definition: device.hh:195
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
System * sys
Definition: io_device.hh:105
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
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:643
Addr bmiAddr
Bus master interface (BMI) registers.
Definition: ide_ctrl.hh:125
IDE Disk device model.
Definition: ide_disk.hh:207
Declaration of the Packet class.
std::ostream CheckpointOut
Definition: serialize.hh:68
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:122
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:71
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void unserialize(ThreadContext &tc, CheckpointIn &cp)
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: ide_ctrl.cc:567
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
void intrPost()
Definition: device.hh:202
bool bmEnabled
Definition: ide_ctrl.hh:136
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:560
const char data[]
void setDmaComplete(IdeDisk *disk)
Definition: ide_ctrl.cc:160
void intrPost()
Definition: ide_ctrl.cc:153
#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:259
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:446
uint32_t BARSize[6]
The size of the BARs.
Definition: device.hh:110
Addr getPageBytes() const
Get the page bytes for the ISA.
Definition: system.hh:305
#define PCI_COMMAND
Definition: pcireg.h:92

Generated on Fri Feb 28 2020 16:27:01 for gem5 by doxygen 1.8.13