gem5  v21.2.1.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ide_disk.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 
45 #include "dev/storage/ide_disk.hh"
46 
47 #include <cerrno>
48 #include <cstring>
49 #include <deque>
50 #include <string>
51 
52 #include "base/chunk_generator.hh"
53 #include "base/compiler.hh"
54 #include "base/cprintf.hh" // csprintf
55 #include "base/trace.hh"
56 #include "debug/IdeDisk.hh"
58 #include "dev/storage/ide_ctrl.hh"
59 #include "sim/cur_tick.hh"
60 #include "sim/sim_object.hh"
61 
62 namespace gem5
63 {
64 
66  : SimObject(p), ctrl(NULL), image(p.image), diskDelay(p.delay),
67  ideDiskStats(this),
68  dmaTransferEvent([this]{ doDmaTransfer(); }, name()),
69  dmaReadCG(NULL),
70  dmaReadWaitEvent([this]{ doDmaRead(); }, name()),
71  dmaWriteCG(NULL),
72  dmaWriteWaitEvent([this]{ doDmaWrite(); }, name()),
73  dmaPrdReadEvent([this]{ dmaPrdReadDone(); }, name()),
74  dmaReadEvent([this]{ dmaReadDone(); }, name()),
75  dmaWriteEvent([this]{ dmaWriteDone(); }, name())
76 {
77  // Reset the device state
78  reset(p.driveID);
79 
80  // fill out the drive ID structure
81  memset(&driveID, 0, sizeof(struct ataparams));
82 
83  // Calculate LBA and C/H/S values
84  uint16_t cylinders;
85  uint8_t heads;
86  uint8_t sectors;
87 
88  uint32_t lba_size = image->size();
89  if (lba_size >= 16383*16*63) {
90  cylinders = 16383;
91  heads = 16;
92  sectors = 63;
93  } else {
94  if (lba_size >= 63)
95  sectors = 63;
96  else if (lba_size == 0)
97  panic("Bad IDE image size: 0\n");
98  else
99  sectors = lba_size;
100 
101  if ((lba_size / sectors) >= 16)
102  heads = 16;
103  else
104  heads = (lba_size / sectors);
105 
106  cylinders = lba_size / (heads * sectors);
107  }
108 
109  // Setup the model name
110  strncpy((char *)driveID.atap_model, "5MI EDD si k",
111  sizeof(driveID.atap_model));
112  // Set the maximum multisector transfer size
113  driveID.atap_multi = MAX_MULTSECT;
114  // IORDY supported, IORDY disabled, LBA enabled, DMA enabled
115  driveID.atap_capabilities1 = 0x7;
116  // UDMA support, EIDE support
117  driveID.atap_extensions = 0x6;
118  // Setup default C/H/S settings
119  driveID.atap_cylinders = cylinders;
120  driveID.atap_sectors = sectors;
121  driveID.atap_heads = heads;
122  // Setup the current multisector transfer size
123  driveID.atap_curmulti = MAX_MULTSECT;
124  driveID.atap_curmulti_valid = 0x1;
125  // Number of sectors on disk
126  driveID.atap_capacity = lba_size;
127  // Multiword DMA mode 2 and below supported
128  driveID.atap_dmamode_supp = 0x4;
129  // Set PIO mode 4 and 3 supported
130  driveID.atap_piomode_supp = 0x3;
131  // Set DMA mode 4 and below supported
132  driveID.atap_udmamode_supp = 0x1f;
133  // Statically set hardware config word
134  driveID.atap_hwreset_res = 0x4001;
135 
136  //arbitrary for now...
137  driveID.atap_ata_major = WDC_VER_ATA7;
138 }
139 
141 {
142  // destroy the data buffer
143  delete [] dataBuffer;
144 }
145 
146 void
148 {
149  // initialize the data buffer and shadow registers
150  dataBuffer = new uint8_t[MAX_DMA_SIZE];
151 
152  memset(dataBuffer, 0, MAX_DMA_SIZE);
153  memset(&cmdReg, 0, sizeof(CommandReg_t));
154  memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
155 
156  curPrdAddr = 0;
157  curSector = 0;
158  cmdBytes = 0;
159  cmdBytesLeft = 0;
160  drqBytesLeft = 0;
161  dmaRead = false;
162  intrPending = false;
163  dmaAborted = false;
164 
165  // set the device state to idle
166  dmaState = Dma_Idle;
167 
168  if (id == DEV0) {
170  devID = DEV0;
171  } else if (id == DEV1) {
173  devID = DEV1;
174  } else {
175  panic("Invalid device ID: %#x\n", id);
176  }
177 
178  // set the device ready bit
180 
181  /* The error register must be set to 0x1 on start-up to
182  indicate that no diagnostic error was detected */
183  cmdReg.error = 0x1;
184 }
185 
187 // Utility functions
189 
190 bool
192 {
193  return ctrl->isDiskSelected(this);
194 }
195 
196 Addr
198 {
199  if (ctrl)
200  return ctrl->pciToDma(pciAddr);
201  else
202  panic("Access to unset controller!\n");
203 }
204 
206 // Device registers read/write
208 
209 void
210 IdeDisk::readCommand(const Addr offset, int size, uint8_t *data)
211 {
212  if (offset == DATA_OFFSET) {
213  if (size == sizeof(uint16_t)) {
214  *(uint16_t *)data = cmdReg.data;
215  } else if (size == sizeof(uint32_t)) {
216  *(uint16_t *)data = cmdReg.data;
218  *((uint16_t *)data + 1) = cmdReg.data;
219  } else {
220  panic("Data read of unsupported size %d.\n", size);
221  }
223  return;
224  }
225  assert(size == sizeof(uint8_t));
226  switch (offset) {
227  case ERROR_OFFSET:
228  *data = cmdReg.error;
229  break;
230  case NSECTOR_OFFSET:
231  *data = cmdReg.sec_count;
232  break;
233  case SECTOR_OFFSET:
234  *data = cmdReg.sec_num;
235  break;
236  case LCYL_OFFSET:
237  *data = cmdReg.cyl_low;
238  break;
239  case HCYL_OFFSET:
240  *data = cmdReg.cyl_high;
241  break;
242  case DRIVE_OFFSET:
243  *data = cmdReg.drive;
244  break;
245  case STATUS_OFFSET:
246  *data = status;
248  break;
249  default:
250  panic("Invalid IDE command register offset: %#x\n", offset);
251  }
252  DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
253 }
254 
255 void
256 IdeDisk::readControl(const Addr offset, int size, uint8_t *data)
257 {
258  assert(size == sizeof(uint8_t));
259  *data = status;
260  if (offset != ALTSTAT_OFFSET)
261  panic("Invalid IDE control register offset: %#x\n", offset);
262  DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
263 }
264 
265 void
266 IdeDisk::writeCommand(const Addr offset, int size, const uint8_t *data)
267 {
268  if (offset == DATA_OFFSET) {
269  if (size == sizeof(uint16_t)) {
270  cmdReg.data = *(const uint16_t *)data;
271  } else if (size == sizeof(uint32_t)) {
272  cmdReg.data = *(const uint16_t *)data;
274  cmdReg.data = *((const uint16_t *)data + 1);
275  } else {
276  panic("Data write of unsupported size %d.\n", size);
277  }
279  return;
280  }
281 
282  assert(size == sizeof(uint8_t));
283  switch (offset) {
284  case FEATURES_OFFSET:
285  break;
286  case NSECTOR_OFFSET:
287  cmdReg.sec_count = *data;
288  break;
289  case SECTOR_OFFSET:
290  cmdReg.sec_num = *data;
291  break;
292  case LCYL_OFFSET:
293  cmdReg.cyl_low = *data;
294  break;
295  case HCYL_OFFSET:
296  cmdReg.cyl_high = *data;
297  break;
298  case DRIVE_OFFSET:
299  cmdReg.drive = *data;
301  break;
302  case COMMAND_OFFSET:
303  cmdReg.command = *data;
305  break;
306  default:
307  panic("Invalid IDE command register offset: %#x\n", offset);
308  }
309  DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
310  (uint32_t)*data);
311 }
312 
313 void
314 IdeDisk::writeControl(const Addr offset, int size, const uint8_t *data)
315 {
316  if (offset != CONTROL_OFFSET)
317  panic("Invalid IDE control register offset: %#x\n", offset);
318 
319  if (*data & CONTROL_RST_BIT) {
320  // force the device into the reset state
323  } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) {
325  }
326 
328 
329  DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
330  (uint32_t)*data);
331 }
332 
334 // Perform DMA transactions
336 
337 void
339 {
340  if (dmaAborted) {
341  DPRINTF(IdeDisk, "DMA Aborted before reading PRD entry\n");
343  return;
344  }
345 
347  panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
348  dmaState, devState);
349 
352  return;
353  } else
355  (uint8_t*)&curPrd.entry);
356 }
357 
358 void
360 {
361  if (dmaAborted) {
362  DPRINTF(IdeDisk, "DMA Aborted while reading PRD entry\n");
364  return;
365  }
366 
368  "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
371  curPrd.getEOT(), curSector);
372 
373  // the prd pointer has already been translated, so just do an increment
374  curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
375 
376  if (dmaRead)
377  doDmaDataRead();
378  else
379  doDmaDataWrite();
380 }
381 
382 void
384 {
386  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
387 
388  DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
389  diskDelay, totalDiskDelay);
390 
391  schedule(dmaReadWaitEvent, curTick() + totalDiskDelay);
392 }
393 
394 IdeDisk::
396  : statistics::Group(parent, "IdeDisk"),
397  ADD_STAT(dmaReadFullPages, statistics::units::Count::get(),
398  "Number of full page size DMA reads (not PRD)."),
399  ADD_STAT(dmaReadBytes, statistics::units::Byte::get(),
400  "Number of bytes transfered via DMA reads (not PRD)."),
401  ADD_STAT(dmaReadTxs, statistics::units::Count::get(),
402  "Number of DMA read transactions (not PRD)."),
403  ADD_STAT(dmaWriteFullPages, statistics::units::Count::get(),
404  "Number of full page size DMA writes."),
405  ADD_STAT(dmaWriteBytes, statistics::units::Byte::get(),
406  "Number of bytes transfered via DMA writes."),
407  ADD_STAT(dmaWriteTxs, statistics::units::Count::get(),
408  "Number of DMA write transactions.")
409 {
410 }
411 
412 void
414 {
415  if (dmaAborted) {
416  DPRINTF(IdeDisk, "DMA Aborted in middle of Dma Read\n");
417  if (dmaReadCG)
418  delete dmaReadCG;
419  dmaReadCG = NULL;
421  return;
422  }
423 
424  if (!dmaReadCG) {
425  // clear out the data buffer
426  memset(dataBuffer, 0, MAX_DMA_SIZE);
429 
430  }
433  return;
434  } else if (!dmaReadCG->done()) {
435  assert(dmaReadCG->complete() < MAX_DMA_SIZE);
440  if (dmaReadCG->size() == chunkBytes)
442  dmaReadCG->next();
443  } else {
444  assert(dmaReadCG->done());
445  delete dmaReadCG;
446  dmaReadCG = NULL;
447  dmaReadDone();
448  }
449 }
450 
451 void
453 {
454  uint32_t bytesWritten = 0;
455 
456  // write the data to the disk image
457  for (bytesWritten = 0; bytesWritten < curPrd.getByteCount();
458  bytesWritten += SectorSize) {
459 
461  writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
462  }
463 
464  // check for the EOT
465  if (curPrd.getEOT()) {
466  assert(cmdBytesLeft == 0);
467  dmaState = Dma_Idle;
469  } else {
470  doDmaTransfer();
471  }
472 }
473 
474 void
476 {
478  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
479  uint32_t bytesRead = 0;
480 
481  DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
482  diskDelay, totalDiskDelay);
483 
484  memset(dataBuffer, 0, MAX_DMA_SIZE);
485  assert(cmdBytesLeft <= MAX_DMA_SIZE);
486  while (bytesRead < curPrd.getByteCount()) {
487  readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
488  bytesRead += SectorSize;
490  }
491  DPRINTF(IdeDisk, "doDmaWrite, bytesRead: %d cmdBytesLeft: %d\n",
492  bytesRead, cmdBytesLeft);
493 
494  schedule(dmaWriteWaitEvent, curTick() + totalDiskDelay);
495 }
496 
497 void
499 {
500  if (dmaAborted) {
501  DPRINTF(IdeDisk, "DMA Aborted while doing DMA Write\n");
502  if (dmaWriteCG)
503  delete dmaWriteCG;
504  dmaWriteCG = NULL;
506  return;
507  }
508  if (!dmaWriteCG) {
509  // clear out the data buffer
512  }
515  DPRINTF(IdeDisk, "doDmaWrite: rescheduling\n");
516  return;
517  } else if (!dmaWriteCG->done()) {
518  assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
521  DPRINTF(IdeDisk, "doDmaWrite: not done curPrd byte count %d, eot %#x\n",
525  if (dmaWriteCG->size() == chunkBytes)
527  dmaWriteCG->next();
528  } else {
529  DPRINTF(IdeDisk, "doDmaWrite: done curPrd byte count %d, eot %#x\n",
531  assert(dmaWriteCG->done());
532  delete dmaWriteCG;
533  dmaWriteCG = NULL;
534  dmaWriteDone();
535  }
536 }
537 
538 void
540 {
541  DPRINTF(IdeDisk, "doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
543  // check for the EOT
544  if (curPrd.getEOT()) {
545  assert(cmdBytesLeft == 0);
546  dmaState = Dma_Idle;
548  } else {
549  doDmaTransfer();
550  }
551 }
552 
554 // Disk utility routines
556 
557 void
558 IdeDisk::readDisk(uint32_t sector, uint8_t *data)
559 {
560  uint32_t bytesRead = image->read(data, sector);
561 
562  if (bytesRead != SectorSize)
563  panic("Can't read from %s. Only %d of %d read. errno=%d\n",
564  name(), bytesRead, SectorSize, errno);
565 }
566 
567 void
568 IdeDisk::writeDisk(uint32_t sector, uint8_t *data)
569 {
570  uint32_t bytesWritten = image->write(data, sector);
571 
572  if (bytesWritten != SectorSize)
573  panic("Can't write to %s. Only %d of %d written. errno=%d\n",
574  name(), bytesWritten, SectorSize, errno);
575 }
576 
578 // Setup and handle commands
580 
581 void
582 IdeDisk::startDma(const uint32_t &prdTableBase)
583 {
584  if (dmaState != Dma_Start)
585  panic("Inconsistent DMA state, should be in Dma_Start!\n");
586 
588  panic("Inconsistent device state for DMA start!\n");
589 
590  // PRD base address is given by bits 31:2
591  curPrdAddr = pciToDma((Addr)(prdTableBase & ~0x3ULL));
592 
594 
595  // schedule dma transfer (doDmaTransfer)
597 }
598 
599 void
601 {
602  if (dmaState == Dma_Idle)
603  panic("Inconsistent DMA state, should be Start or Transfer!");
604 
606  panic("Inconsistent device state, should be Transfer or Prepare!\n");
607 
609 }
610 
611 void
613 {
614  DevAction_t action = ACT_NONE;
615  uint32_t size = 0;
616  dmaRead = false;
617 
618  // Decode commands
619  switch (cmdReg.command) {
620  // Supported non-data commands
622  size = (uint32_t)image->size() - 1;
623  cmdReg.sec_num = (size & 0xff);
624  cmdReg.cyl_low = ((size & 0xff00) >> 8);
625  cmdReg.cyl_high = ((size & 0xff0000) >> 16);
626  cmdReg.head = ((size & 0xf000000) >> 24);
627 
629  action = ACT_CMD_COMPLETE;
630  break;
631 
632  case WDCC_RECAL:
633  case WDCC_IDP:
634  case WDCC_STANDBY_IMMED:
635  case WDCC_FLUSHCACHE:
636  case WDSF_VERIFY:
637  case WDSF_SEEK:
638  case SET_FEATURES:
639  case WDCC_SETMULTI:
640  case WDCC_IDLE:
642  action = ACT_CMD_COMPLETE;
643  break;
644 
645  // Supported PIO data-in commands
646  case WDCC_IDENTIFY:
648  cmdBytes = cmdBytesLeft = sizeof(struct ataparams);
650  action = ACT_DATA_READY;
651  break;
652 
653  case WDCC_READMULTI:
654  case WDCC_READ:
655  if (!(cmdReg.drive & DRIVE_LBA_BIT))
656  panic("Attempt to perform CHS access, only supports LBA\n");
657 
658  if (cmdReg.sec_count == 0)
659  cmdBytes = cmdBytesLeft = (256 * SectorSize);
660  else
662 
663  curSector = getLBABase();
664 
667  action = ACT_DATA_READY;
668  break;
669 
670  // Supported PIO data-out commands
671  case WDCC_WRITEMULTI:
672  case WDCC_WRITE:
673  if (!(cmdReg.drive & DRIVE_LBA_BIT))
674  panic("Attempt to perform CHS access, only supports LBA\n");
675 
676  if (cmdReg.sec_count == 0)
677  cmdBytes = cmdBytesLeft = (256 * SectorSize);
678  else
680  DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d\n", cmdBytesLeft);
681  curSector = getLBABase();
682 
684  action = ACT_DATA_READY;
685  break;
686 
687  // Supported DMA commands
688  case WDCC_WRITEDMA:
689  dmaRead = true; // a write to the disk is a DMA read from memory
690  [[fallthrough]];
691  case WDCC_READDMA:
692  if (!(cmdReg.drive & DRIVE_LBA_BIT))
693  panic("Attempt to perform CHS access, only supports LBA\n");
694 
695  if (cmdReg.sec_count == 0)
696  cmdBytes = cmdBytesLeft = (256 * SectorSize);
697  else
699  DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d in readdma\n", cmdBytesLeft);
700 
701  curSector = getLBABase();
702 
704  action = ACT_DMA_READY;
705  break;
706 
707  default:
708  panic("Unsupported ATA command: %#x\n", cmdReg.command);
709  }
710 
711  if (action != ACT_NONE) {
712  // set the BSY bit
714  // clear the DRQ bit
716  // clear the DF bit
717  status &= ~STATUS_DF_BIT;
718 
719  updateState(action);
720  }
721 }
722 
724 // Handle setting and clearing interrupts
726 
727 void
729 {
730  DPRINTF(IdeDisk, "Posting Interrupt\n");
731  if (intrPending)
732  panic("Attempt to post an interrupt with one pending\n");
733 
734  intrPending = true;
735 
736  // talk to controller to set interrupt
737  if (ctrl) {
738  ctrl->intrPost();
739  }
740 }
741 
742 void
744 {
745  DPRINTF(IdeDisk, "Clearing Interrupt\n");
746  if (!intrPending)
747  panic("Attempt to clear a non-pending interrupt\n");
748 
749  intrPending = false;
750 
751  // talk to controller to clear interrupt
752  if (ctrl)
753  ctrl->intrClear();
754 }
755 
757 // Manage the device internal state machine
759 
760 void
762 {
763  switch (devState) {
764  case Device_Srst:
765  if (action == ACT_SRST_SET) {
766  // set the BSY bit
768  } else if (action == ACT_SRST_CLEAR) {
769  // clear the BSY bit
771 
772  // reset the device state
773  reset(devID);
774  }
775  break;
776 
777  case Device_Idle_S:
778  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
780  } else if (action == ACT_CMD_WRITE) {
781  startCommand();
782  }
783 
784  break;
785 
786  case Device_Idle_SI:
787  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
789  intrClear();
790  } else if (action == ACT_STAT_READ || isIENSet()) {
792  intrClear();
793  } else if (action == ACT_CMD_WRITE) {
794  intrClear();
795  startCommand();
796  }
797 
798  break;
799 
800  case Device_Idle_NS:
801  if (action == ACT_SELECT_WRITE && isDEVSelect()) {
802  if (!isIENSet() && intrPending) {
804  intrPost();
805  }
806  if (isIENSet() || !intrPending) {
808  }
809  }
810  break;
811 
812  case Command_Execution:
813  if (action == ACT_CMD_COMPLETE) {
814  // clear the BSY bit
815  setComplete();
816 
817  if (!isIENSet()) {
819  intrPost();
820  } else {
822  }
823  }
824  break;
825 
826  case Prepare_Data_In:
827  if (action == ACT_CMD_ERROR) {
828  // clear the BSY bit
829  setComplete();
830 
831  if (!isIENSet()) {
833  intrPost();
834  } else {
836  }
837  } else if (action == ACT_DATA_READY) {
838  // clear the BSY bit
840  // set the DRQ bit
842 
843  // copy the data into the data buffer
844  if (cmdReg.command == WDCC_IDENTIFY ||
846  // Reset the drqBytes for this block
847  drqBytesLeft = sizeof(struct ataparams);
848 
849  memcpy((void *)dataBuffer, (void *)&driveID,
850  sizeof(struct ataparams));
851  } else {
852  // Reset the drqBytes for this block
854 
856  }
857 
858  // put the first two bytes into the data register
859  memcpy((void *)&cmdReg.data, (void *)dataBuffer,
860  sizeof(uint16_t));
861 
862  if (!isIENSet()) {
864  intrPost();
865  } else {
867  }
868  }
869  break;
870 
871  case Data_Ready_INTRQ_In:
872  if (action == ACT_STAT_READ) {
874  intrClear();
875  }
876  break;
877 
878  case Transfer_Data_In:
879  if (action == ACT_DATA_READ_BYTE || action == ACT_DATA_READ_SHORT) {
880  if (action == ACT_DATA_READ_BYTE) {
881  panic("DEBUG: READING DATA ONE BYTE AT A TIME!\n");
882  } else {
883  drqBytesLeft -= 2;
884  cmdBytesLeft -= 2;
885 
886  // copy next short into data registers
887  if (drqBytesLeft)
888  memcpy((void *)&cmdReg.data,
889  (void *)&dataBuffer[SectorSize - drqBytesLeft],
890  sizeof(uint16_t));
891  }
892 
893  if (drqBytesLeft == 0) {
894  if (cmdBytesLeft == 0) {
895  // Clear the BSY bit
896  setComplete();
898  } else {
900  // set the BSY_BIT
902  // clear the DRQ_BIT
904 
908  }
909  }
910  }
911  break;
912 
913  case Prepare_Data_Out:
914  if (action == ACT_CMD_ERROR || cmdBytesLeft == 0) {
915  // clear the BSY bit
916  setComplete();
917 
918  if (!isIENSet()) {
920  intrPost();
921  } else {
923  }
924  } else if (action == ACT_DATA_READY && cmdBytesLeft != 0) {
925  // clear the BSY bit
927  // set the DRQ bit
929 
930  // clear the data buffer to get it ready for writes
931  memset(dataBuffer, 0, MAX_DMA_SIZE);
932 
933  // reset the drqBytes for this block
935 
936  if (cmdBytesLeft == cmdBytes || isIENSet()) {
938  } else {
940  intrPost();
941  }
942  }
943  break;
944 
946  if (action == ACT_STAT_READ) {
948  intrClear();
949  }
950  break;
951 
952  case Transfer_Data_Out:
953  if (action == ACT_DATA_WRITE_BYTE ||
954  action == ACT_DATA_WRITE_SHORT) {
955 
956  if (action == ACT_DATA_READ_BYTE) {
957  panic("DEBUG: WRITING DATA ONE BYTE AT A TIME!\n");
958  } else {
959  // copy the latest short into the data buffer
960  memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
961  (void *)&cmdReg.data,
962  sizeof(uint16_t));
963 
964  drqBytesLeft -= 2;
965  cmdBytesLeft -= 2;
966  }
967 
968  if (drqBytesLeft == 0) {
969  // copy the block to the disk
971 
972  // set the BSY bit
974  // set the seek bit
976  // clear the DRQ bit
978 
980 
984  }
985  }
986  break;
987 
988  case Prepare_Data_Dma:
989  if (action == ACT_CMD_ERROR) {
990  // clear the BSY bit
991  setComplete();
992 
993  if (!isIENSet()) {
995  intrPost();
996  } else {
998  }
999  } else if (action == ACT_DMA_READY) {
1000  // clear the BSY bit
1001  status &= ~STATUS_BSY_BIT;
1002  // set the DRQ bit
1004 
1006 
1007  if (dmaState != Dma_Idle)
1008  panic("Inconsistent DMA state, should be Dma_Idle\n");
1009 
1010  dmaState = Dma_Start;
1011  // wait for the write to the DMA start bit
1012  }
1013  break;
1014 
1015  case Transfer_Data_Dma:
1016  if (action == ACT_CMD_ERROR) {
1017  dmaAborted = true;
1019  } else if (action == ACT_DMA_DONE) {
1020  // clear the BSY bit
1021  setComplete();
1022  // set the seek bit
1024  // clear the controller state for DMA transfer
1025  ctrl->setDmaComplete(this);
1026 
1027  if (!isIENSet()) {
1029  intrPost();
1030  } else {
1032  }
1033  }
1034  break;
1035 
1036  case Device_Dma_Abort:
1037  if (action == ACT_CMD_ERROR) {
1038  setComplete();
1040  ctrl->setDmaComplete(this);
1041  dmaAborted = false;
1042  dmaState = Dma_Idle;
1043 
1044  if (!isIENSet()) {
1046  intrPost();
1047  } else {
1049  }
1050  } else {
1051  DPRINTF(IdeDisk, "Disk still busy aborting previous DMA command\n");
1052  }
1053  break;
1054 
1055  default:
1056  panic("Unknown IDE device state: %#x\n", devState);
1057  }
1058 }
1059 
1060 void
1062 {
1063  // Check all outstanding events to see if they are scheduled
1064  // these are all mutually exclusive
1065  Tick reschedule = 0;
1066  Events_t event = None;
1067 
1068  int eventCount = 0;
1069 
1070  if (dmaTransferEvent.scheduled()) {
1072  event = Transfer;
1073  eventCount++;
1074  }
1075  if (dmaReadWaitEvent.scheduled()) {
1077  event = ReadWait;
1078  eventCount++;
1079  }
1080  if (dmaWriteWaitEvent.scheduled()) {
1082  event = WriteWait;
1083  eventCount++;
1084  }
1085  if (dmaPrdReadEvent.scheduled()) {
1087  event = PrdRead;
1088  eventCount++;
1089  }
1090  if (dmaReadEvent.scheduled()) {
1092  event = DmaRead;
1093  eventCount++;
1094  }
1095  if (dmaWriteEvent.scheduled()) {
1097  event = DmaWrite;
1098  eventCount++;
1099  }
1100 
1101  assert(eventCount <= 1);
1102 
1105 
1106  // Serialize device registers
1117 
1118  // Serialize the PRD related information
1123 
1125  // Serialize current transfer related information
1136 }
1137 
1138 void
1140 {
1141  // Reschedule events that were outstanding
1142  // these are all mutually exclusive
1143  Tick reschedule = 0;
1144  Events_t event = None;
1145 
1148 
1149  switch (event) {
1150  case None : break;
1151  case Transfer : schedule(dmaTransferEvent, reschedule); break;
1152  case ReadWait : schedule(dmaReadWaitEvent, reschedule); break;
1154  case PrdRead : schedule(dmaPrdReadEvent, reschedule); break;
1155  case DmaRead : schedule(dmaReadEvent, reschedule); break;
1156  case DmaWrite : schedule(dmaWriteEvent, reschedule); break;
1157  }
1158 
1159  // Unserialize device registers
1170 
1171  // Unserialize the PRD related information
1176 
1178  // Unserialize current transfer related information
1189 }
1190 
1191 } // namespace gem5
CONTROL_OFFSET
#define CONTROL_OFFSET
Definition: ide_disk.hh:113
gem5::IdeDisk::updateState
void updateState(DevAction_t action)
Definition: ide_disk.cc:761
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::PrdTableEntry::getByteCount
uint32_t getByteCount()
Definition: ide_disk.hh:89
gem5::IdeDisk::pciToDma
Addr pciToDma(Addr pciAddr)
Definition: ide_disk.cc:197
gem5::IdeDisk::IdeDisk
IdeDisk(const Params &p)
Definition: ide_disk.cc:65
gem5::Event::when
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:508
gem5::IdeDisk::setComplete
void setComplete()
Definition: ide_disk.hh:358
gem5::IdeDisk::intrPending
bool intrPending
Interrupt pending.
Definition: ide_disk.hh:262
WDSF_SEEK
#define WDSF_SEEK
Definition: ide_wdcreg.h:157
gem5::ACT_DATA_READY
@ ACT_DATA_READY
Definition: ide_disk.hh:164
gem5::CommandReg_t::cyl_low
uint8_t cyl_low
Definition: ide_disk.hh:135
gem5::PrdTableEntry::entry
PrdEntry_t entry
Definition: ide_disk.hh:82
WDCC_IDP
#define WDCC_IDP
Definition: ide_wdcreg.h:87
gem5::IdeDisk::doDmaWrite
void doDmaWrite()
Definition: ide_disk.cc:498
gem5::ACT_DATA_READ_BYTE
@ ACT_DATA_READ_BYTE
Definition: ide_disk.hh:165
gem5::IdeDisk::IdeDiskStats::dmaWriteBytes
statistics::Scalar dmaWriteBytes
Definition: ide_disk.hh:274
gem5::IdeDisk::curSector
uint32_t curSector
Current sector in access.
Definition: ide_disk.hh:240
data
const char data[]
Definition: circlebuf.test.cc:48
WDCC_FLUSHCACHE
#define WDCC_FLUSHCACHE
Definition: ide_wdcreg.h:100
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::CommandReg_t::command
uint8_t command
Definition: ide_disk.hh:142
gem5::Drainable::drainState
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:324
gem5::IdeDisk::curPrd
PrdTableEntry curPrd
PRD entry.
Definition: ide_disk.hh:258
gem5::ACT_DATA_READ_SHORT
@ ACT_DATA_READ_SHORT
Definition: ide_disk.hh:166
gem5::ReadWait
@ ReadWait
Definition: ide_disk.hh:149
gem5::ChunkGenerator::next
bool next()
Advance generator to next chunk.
Definition: chunk_generator.hh:185
gem5::IdeDisk::IdeDiskStats::dmaWriteTxs
statistics::Scalar dmaWriteTxs
Definition: ide_disk.hh:275
gem5::None
@ None
Definition: ide_disk.hh:147
DATA_OFFSET
#define DATA_OFFSET
Definition: ide_disk.hh:101
gem5::IdeDisk::reset
void reset(int id)
Reset the device state.
Definition: ide_disk.cc:147
gem5::ChunkGenerator::complete
Addr complete() const
Number of bytes we have already chunked up.
Definition: chunk_generator.hh:132
LCYL_OFFSET
#define LCYL_OFFSET
Definition: ide_disk.hh:106
gem5::IdeController::intrPost
void intrPost()
Definition: ide_ctrl.cc:138
gem5::Events_t
Events_t
Definition: ide_disk.hh:145
gem5::IdeDisk::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: ide_disk.cc:1139
SectorSize
#define SectorSize
Definition: disk_image.hh:44
gem5::IdeDisk::startCommand
void startCommand()
Definition: ide_disk.cc:612
WDCC_READDMA
#define WDCC_READDMA
Definition: ide_wdcreg.h:93
CONTROL_RST_BIT
#define CONTROL_RST_BIT
Definition: ide_disk.hh:117
WDSF_READ_NATIVE_MAX
#define WDSF_READ_NATIVE_MAX
Definition: ide_wdcreg.h:156
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::IdeDisk::IdeDiskStats::dmaWriteFullPages
statistics::Scalar dmaWriteFullPages
Definition: ide_disk.hh:273
WDCC_READ
#define WDCC_READ
Definition: ide_wdcreg.h:80
gem5::MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:300
gem5::IdeDisk::~IdeDisk
~IdeDisk()
Delete the data buffer.
Definition: ide_disk.cc:140
gem5::PrdEntry_t::byteCount
uint16_t byteCount
Definition: ide_disk.hh:75
cur_tick.hh
gem5::IdeDisk::doDmaTransfer
void doDmaTransfer()
Definition: ide_disk.cc:338
ALTSTAT_OFFSET
#define ALTSTAT_OFFSET
Definition: ide_disk.hh:114
gem5::IdeDisk::dmaWriteCG
ChunkGenerator * dmaWriteCG
Definition: ide_disk.hh:334
disk_image.hh
gem5::IdeDisk::driveID
struct ataparams driveID
Drive identification structure for this disk.
Definition: ide_disk.hh:230
gem5::IdeDisk::isDEVSelect
bool isDEVSelect()
Definition: ide_disk.cc:191
SET_FEATURES
#define SET_FEATURES
Definition: ide_wdcreg.h:102
gem5::IdeDisk::curPrdAddr
uint32_t curPrdAddr
PRD table base address.
Definition: ide_disk.hh:256
WDSF_VERIFY
#define WDSF_VERIFY
Definition: ide_wdcreg.h:158
gem5::Data_Ready_INTRQ_In
@ Data_Ready_INTRQ_In
Definition: ide_disk.hh:190
gem5::CommandReg_t::data
uint16_t data
Definition: ide_disk.hh:131
gem5::IdeDisk::readCommand
void readCommand(const Addr offset, int size, uint8_t *data)
Definition: ide_disk.cc:210
gem5::CommandReg_t::cyl_high
uint8_t cyl_high
Definition: ide_disk.hh:136
gem5::DmaDevice::dmaRead
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
Definition: dma_device.hh:228
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
gem5::PciDevice::intrClear
void intrClear()
Definition: device.hh:365
gem5::IdeDisk::chunkBytes
Addr chunkBytes
Size of chunks to DMA.
Definition: ide_disk.hh:254
gem5::CommandReg_t::sec_count
uint8_t sec_count
Definition: ide_disk.hh:133
gem5::DiskImage::write
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
DRIVE_LBA_BIT
#define DRIVE_LBA_BIT
Definition: ide_disk.hh:124
gem5::ACT_CMD_WRITE
@ ACT_CMD_WRITE
Definition: ide_disk.hh:159
gem5::Device_Idle_NS
@ Device_Idle_NS
Definition: ide_disk.hh:180
gem5::ACT_SRST_CLEAR
@ ACT_SRST_CLEAR
Definition: ide_disk.hh:172
gem5::IdeDisk::startDma
void startDma(const uint32_t &prdTableBase)
Definition: ide_disk.cc:582
gem5::IdeDisk::intrClear
void intrClear()
Definition: ide_disk.cc:743
gem5::DmaRead
@ DmaRead
Definition: ide_disk.hh:152
gem5::IdeDisk::IdeDiskStats::IdeDiskStats
IdeDiskStats(statistics::Group *parent)
Definition: ide_disk.cc:395
DEV0
#define DEV0
Definition: ide_disk.hh:126
COMMAND_OFFSET
#define COMMAND_OFFSET
Definition: ide_disk.hh:111
gem5::IdeDisk::cmdBytesLeft
uint32_t cmdBytesLeft
Number of bytes left in command data transfer.
Definition: ide_disk.hh:236
gem5::PrdTableEntry::getBaseAddr
uint32_t getBaseAddr()
Definition: ide_disk.hh:84
gem5::IdeDisk::doDmaDataWrite
void doDmaDataWrite()
Definition: ide_disk.cc:475
gem5::ChunkGenerator::size
Addr size() const
Return size in bytes of current chunk.
Definition: chunk_generator.hh:125
gem5::ChunkGenerator
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
Definition: chunk_generator.hh:59
NSECTOR_OFFSET
#define NSECTOR_OFFSET
Definition: ide_disk.hh:104
SERIALIZE_ENUM
#define SERIALIZE_ENUM(scalar)
Definition: serialize.hh:591
gem5::IdeDisk::doDmaDataRead
void doDmaDataRead()
Definition: ide_disk.cc:383
gem5::Transfer_Data_Dma
@ Transfer_Data_Dma
Definition: ide_disk.hh:200
gem5::Data_Ready_INTRQ_Out
@ Data_Ready_INTRQ_Out
Definition: ide_disk.hh:195
gem5::PrdEntry_t
Definition: ide_disk.hh:72
gem5::IdeDisk::dmaRead
bool dmaRead
Dma transaction is a read.
Definition: ide_disk.hh:252
gem5::IdeDisk::devState
DevState_t devState
Device state.
Definition: ide_disk.hh:248
gem5::Device_Idle_S
@ Device_Idle_S
Definition: ide_disk.hh:178
gem5::IdeDisk::dmaReadCG
ChunkGenerator * dmaReadCG
Definition: ide_disk.hh:328
gem5::ACT_DATA_WRITE_BYTE
@ ACT_DATA_WRITE_BYTE
Definition: ide_disk.hh:167
gem5::IdeDisk::doDmaRead
void doDmaRead()
Definition: ide_disk.cc:413
WDC_VER_ATA7
#define WDC_VER_ATA7
Definition: ide_atareg.h:183
gem5::ChunkGenerator::done
bool done() const
Are we done? That is, did the last call to next() advance past the end of the region?
Definition: chunk_generator.hh:141
gem5::IdeDisk::nIENBit
bool nIENBit
Interrupt enable bit.
Definition: ide_disk.hh:246
STATUS_BSY_BIT
#define STATUS_BSY_BIT
Definition: ide_disk.hh:119
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::Dma_Start
@ Dma_Start
Definition: ide_disk.hh:207
gem5::ACT_SELECT_WRITE
@ ACT_SELECT_WRITE
Definition: ide_disk.hh:162
STATUS_OFFSET
#define STATUS_OFFSET
Definition: ide_disk.hh:110
gem5::Prepare_Data_Out
@ Prepare_Data_Out
Definition: ide_disk.hh:194
sim_object.hh
gem5::IdeDisk::dmaWriteWaitEvent
EventFunctionWrapper dmaWriteWaitEvent
Definition: ide_disk.hh:335
gem5::Prepare_Data_In
@ Prepare_Data_In
Definition: ide_disk.hh:189
gem5::IdeDisk::dmaReadDone
void dmaReadDone()
Definition: ide_disk.cc:452
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::Prepare_Data_Dma
@ Prepare_Data_Dma
Definition: ide_disk.hh:199
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::IdeDisk::dmaState
DmaState_t dmaState
Dma state.
Definition: ide_disk.hh:250
gem5::Transfer
@ Transfer
Definition: ide_disk.hh:148
gem5::CommandReg_t::error
uint8_t error
Definition: ide_disk.hh:132
gem5::DmaDevice::dmaPending
bool dmaPending() const
Definition: dma_device.hh:241
gem5::CommandReg_t::head
uint8_t head
Definition: ide_disk.hh:140
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::IdeDisk::cmdBytes
uint32_t cmdBytes
Number of bytes in command data transfer.
Definition: ide_disk.hh:234
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::DmaWrite
@ DmaWrite
Definition: ide_disk.hh:153
gem5::IdeDisk::IdeDiskStats::dmaReadTxs
statistics::Scalar dmaReadTxs
Definition: ide_disk.hh:272
gem5::statistics::reset
void reset()
Definition: statistics.cc:310
ide_disk.hh
ataparams
Definition: ide_atareg.h:67
gem5::IdeDisk::dmaReadEvent
EventFunctionWrapper dmaReadEvent
Definition: ide_disk.hh:341
STATUS_SEEK_BIT
#define STATUS_SEEK_BIT
Definition: ide_disk.hh:122
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::EventManager::reschedule
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:1037
gem5::DmaDevice::dmaWrite
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
Definition: dma_device.hh:214
gem5::IdeDisk::devID
int devID
Device ID (device0=0/device1=1)
Definition: ide_disk.hh:260
cprintf.hh
compiler.hh
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:610
gem5::IdeDisk::writeCommand
void writeCommand(const Addr offset, int size, const uint8_t *data)
Definition: ide_disk.cc:266
gem5::SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:146
gem5::ACT_DATA_WRITE_SHORT
@ ACT_DATA_WRITE_SHORT
Definition: ide_disk.hh:168
WDCC_WRITEMULTI
#define WDCC_WRITEMULTI
Definition: ide_wdcreg.h:90
gem5::Device_Srst
@ Device_Srst
Definition: ide_disk.hh:183
gem5::Dma_Transfer
@ Dma_Transfer
Definition: ide_disk.hh:208
gem5::IdeDisk::Params
IdeDiskParams Params
Definition: ide_disk.hh:279
WDCC_WRITEDMA
#define WDCC_WRITEDMA
Definition: ide_wdcreg.h:94
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
DMA_BACKOFF_PERIOD
#define DMA_BACKOFF_PERIOD
Definition: ide_disk.hh:62
gem5::Transfer_Data_Out
@ Transfer_Data_Out
Definition: ide_disk.hh:196
gem5::DevAction_t
DevAction_t
Definition: ide_disk.hh:156
name
const std::string & name()
Definition: trace.cc:49
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
gem5::CommandReg_t::sec_num
uint8_t sec_num
Definition: ide_disk.hh:134
gem5::IdeDisk::getLBABase
uint32_t getLBABase()
Definition: ide_disk.hh:368
gem5::PrdEntry_t::baseAddr
uint32_t baseAddr
Definition: ide_disk.hh:74
STATUS_DF_BIT
#define STATUS_DF_BIT
Definition: ide_disk.hh:123
gem5::ACT_SRST_SET
@ ACT_SRST_SET
Definition: ide_disk.hh:171
gem5::IdeDisk::image
DiskImage * image
The image that contains the data of this disk.
Definition: ide_disk.hh:222
CONTROL_IEN_BIT
#define CONTROL_IEN_BIT
Definition: ide_disk.hh:118
gem5::IdeDisk::isIENSet
bool isIENSet()
Definition: ide_disk.hh:355
gem5::IdeDisk::dmaPrdReadDone
void dmaPrdReadDone()
Definition: ide_disk.cc:359
gem5::IdeDisk::ideDiskStats
gem5::IdeDisk::IdeDiskStats ideDiskStats
DRIVE_OFFSET
#define DRIVE_OFFSET
Definition: ide_disk.hh:109
gem5::IdeDisk::status
uint8_t status
Status register.
Definition: ide_disk.hh:244
FEATURES_OFFSET
#define FEATURES_OFFSET
Definition: ide_disk.hh:103
gem5::IdeDisk::dmaReadWaitEvent
EventFunctionWrapper dmaReadWaitEvent
Definition: ide_disk.hh:329
gem5::Transfer_Data_In
@ Transfer_Data_In
Definition: ide_disk.hh:191
ERROR_OFFSET
#define ERROR_OFFSET
Definition: ide_disk.hh:102
gem5::ACT_STAT_READ
@ ACT_STAT_READ
Definition: ide_disk.hh:163
WDCC_WRITE
#define WDCC_WRITE
Definition: ide_wdcreg.h:81
MAX_MULTSECT
#define MAX_MULTSECT
Definition: ide_disk.hh:66
gem5::IdeDisk::writeDisk
void writeDisk(uint32_t sector, uint8_t *data)
Definition: ide_disk.cc:568
HCYL_OFFSET
#define HCYL_OFFSET
Definition: ide_disk.hh:107
gem5::Dma_Idle
@ Dma_Idle
Definition: ide_disk.hh:206
gem5::Device_Idle_SI
@ Device_Idle_SI
Definition: ide_disk.hh:179
gem5::IdeDisk::readDisk
void readDisk(uint32_t sector, uint8_t *data)
Definition: ide_disk.cc:558
gem5::CommandReg_t::drive
uint8_t drive
Definition: ide_disk.hh:139
WDCC_SETMULTI
#define WDCC_SETMULTI
Definition: ide_wdcreg.h:91
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:618
gem5::IdeController::setDmaComplete
void setDmaComplete(IdeDisk *disk)
Definition: ide_ctrl.cc:145
gem5::IdeController::isDiskSelected
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
Definition: ide_ctrl.cc:132
gem5::CommandReg_t
Definition: ide_disk.hh:129
gem5::ChunkGenerator::addr
Addr addr() const
Return starting address of current chunk.
Definition: chunk_generator.hh:119
gem5::IdeDisk::dmaPrdReadEvent
EventFunctionWrapper dmaPrdReadEvent
Definition: ide_disk.hh:338
gem5::IdeDisk::drqBytesLeft
uint32_t drqBytesLeft
Number of bytes left in DRQ block.
Definition: ide_disk.hh:238
gem5::IdeDisk::dmaWriteDone
void dmaWriteDone()
Definition: ide_disk.cc:539
gem5::IdeDisk::IdeDiskStats::dmaReadFullPages
statistics::Scalar dmaReadFullPages
Definition: ide_disk.hh:270
STATUS_DRDY_BIT
#define STATUS_DRDY_BIT
Definition: ide_disk.hh:120
ide_ctrl.hh
gem5::IdeDisk::readControl
void readControl(const Addr offset, int size, uint8_t *data)
Definition: ide_disk.cc:256
ATAPI_IDENTIFY_DEVICE
#define ATAPI_IDENTIFY_DEVICE
Definition: ide_wdcreg.h:171
gem5::statistics::Group
Statistics container.
Definition: group.hh:93
gem5::DiskImage::size
virtual std::streampos size() const =0
gem5::IdeDisk::intrPost
void intrPost()
Definition: ide_disk.cc:728
chunk_generator.hh
WDCC_STANDBY_IMMED
#define WDCC_STANDBY_IMMED
Definition: ide_wdcreg.h:108
WDCC_RECAL
#define WDCC_RECAL
Definition: ide_wdcreg.h:78
gem5::ACT_DMA_READY
@ ACT_DMA_READY
Definition: ide_disk.hh:169
gem5::DiskImage::read
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
gem5::ACT_CMD_COMPLETE
@ ACT_CMD_COMPLETE
Definition: ide_disk.hh:160
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::IdeDisk::IdeDiskStats::dmaReadBytes
statistics::Scalar dmaReadBytes
Definition: ide_disk.hh:271
gem5::IdeDisk::ctrl
IdeController * ctrl
The IDE controller for this disk.
Definition: ide_disk.hh:220
gem5::IdeDisk
IDE Disk device model.
Definition: ide_disk.hh:216
UNSERIALIZE_ENUM
#define UNSERIALIZE_ENUM(scalar)
Definition: serialize.hh:598
gem5::IdeDisk::abortDma
void abortDma()
Definition: ide_disk.cc:600
trace.hh
gem5::Command_Execution
@ Command_Execution
Definition: ide_disk.hh:186
WDCC_IDENTIFY
#define WDCC_IDENTIFY
Definition: ide_wdcreg.h:101
gem5::DrainState::Running
@ Running
Running normally.
SECTOR_OFFSET
#define SECTOR_OFFSET
Definition: ide_disk.hh:105
gem5::Device_Dma_Abort
@ Device_Dma_Abort
Definition: ide_disk.hh:201
gem5::PciDevice::pciToDma
Addr pciToDma(Addr pci_addr) const
Definition: device.hh:359
gem5::PrdTableEntry::getEOT
uint16_t getEOT()
Definition: ide_disk.hh:95
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: tlb.cc:60
gem5::ACT_DMA_DONE
@ ACT_DMA_DONE
Definition: ide_disk.hh:170
gem5::IdeDisk::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: ide_disk.cc:1061
gem5::IdeDisk::dmaTransferEvent
EventFunctionWrapper dmaTransferEvent
Definition: ide_disk.hh:323
WDCC_READMULTI
#define WDCC_READMULTI
Definition: ide_wdcreg.h:89
DEV1
#define DEV1
Definition: ide_disk.hh:127
gem5::ACT_NONE
@ ACT_NONE
Definition: ide_disk.hh:158
gem5::ACT_CMD_ERROR
@ ACT_CMD_ERROR
Definition: ide_disk.hh:161
gem5::IdeDisk::dataBuffer
uint8_t * dataBuffer
Data buffer for transfers.
Definition: ide_disk.hh:232
STATUS_DRQ_BIT
#define STATUS_DRQ_BIT
Definition: ide_disk.hh:121
gem5::IdeDisk::dmaAborted
bool dmaAborted
DMA Aborted.
Definition: ide_disk.hh:264
gem5::IdeDisk::cmdReg
CommandReg_t cmdReg
Command block registers.
Definition: ide_disk.hh:242
gem5::IdeDisk::diskDelay
int diskDelay
The disk delay in microseconds.
Definition: ide_disk.hh:226
MAX_DMA_SIZE
#define MAX_DMA_SIZE
Definition: ide_disk.hh:64
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
gem5::IdeDisk::writeControl
void writeControl(const Addr offset, int size, const uint8_t *data)
Definition: ide_disk.cc:314
gem5::PrdRead
@ PrdRead
Definition: ide_disk.hh:151
gem5::IdeDisk::dmaWriteEvent
EventFunctionWrapper dmaWriteEvent
Definition: ide_disk.hh:344
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
gem5::PrdEntry_t::endOfTable
uint16_t endOfTable
Definition: ide_disk.hh:76
WDCC_IDLE
#define WDCC_IDLE
Definition: ide_wdcreg.h:104
gem5::WriteWait
@ WriteWait
Definition: ide_disk.hh:150

Generated on Wed May 4 2022 12:13:58 for gem5 by doxygen 1.8.17