gem5  v20.1.0.0
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/cprintf.hh" // csprintf
54 #include "base/trace.hh"
55 #include "debug/IdeDisk.hh"
57 #include "dev/storage/ide_ctrl.hh"
58 #include "sim/core.hh"
59 #include "sim/sim_object.hh"
60 
62  : SimObject(p), ctrl(NULL), image(p->image), diskDelay(p->delay),
63  dmaTransferEvent([this]{ doDmaTransfer(); }, name()),
64  dmaReadCG(NULL),
65  dmaReadWaitEvent([this]{ doDmaRead(); }, name()),
66  dmaWriteCG(NULL),
67  dmaWriteWaitEvent([this]{ doDmaWrite(); }, name()),
68  dmaPrdReadEvent([this]{ dmaPrdReadDone(); }, name()),
69  dmaReadEvent([this]{ dmaReadDone(); }, name()),
70  dmaWriteEvent([this]{ dmaWriteDone(); }, name())
71 {
72  // Reset the device state
73  reset(p->driveID);
74 
75  // fill out the drive ID structure
76  memset(&driveID, 0, sizeof(struct ataparams));
77 
78  // Calculate LBA and C/H/S values
79  uint16_t cylinders;
80  uint8_t heads;
81  uint8_t sectors;
82 
83  uint32_t lba_size = image->size();
84  if (lba_size >= 16383*16*63) {
85  cylinders = 16383;
86  heads = 16;
87  sectors = 63;
88  } else {
89  if (lba_size >= 63)
90  sectors = 63;
91  else if (lba_size == 0)
92  panic("Bad IDE image size: 0\n");
93  else
94  sectors = lba_size;
95 
96  if ((lba_size / sectors) >= 16)
97  heads = 16;
98  else
99  heads = (lba_size / sectors);
100 
101  cylinders = lba_size / (heads * sectors);
102  }
103 
104  // Setup the model name
105  strncpy((char *)driveID.atap_model, "5MI EDD si k",
106  sizeof(driveID.atap_model));
107  // Set the maximum multisector transfer size
108  driveID.atap_multi = MAX_MULTSECT;
109  // IORDY supported, IORDY disabled, LBA enabled, DMA enabled
110  driveID.atap_capabilities1 = 0x7;
111  // UDMA support, EIDE support
112  driveID.atap_extensions = 0x6;
113  // Setup default C/H/S settings
114  driveID.atap_cylinders = cylinders;
115  driveID.atap_sectors = sectors;
116  driveID.atap_heads = heads;
117  // Setup the current multisector transfer size
118  driveID.atap_curmulti = MAX_MULTSECT;
119  driveID.atap_curmulti_valid = 0x1;
120  // Number of sectors on disk
121  driveID.atap_capacity = lba_size;
122  // Multiword DMA mode 2 and below supported
123  driveID.atap_dmamode_supp = 0x4;
124  // Set PIO mode 4 and 3 supported
125  driveID.atap_piomode_supp = 0x3;
126  // Set DMA mode 4 and below supported
127  driveID.atap_udmamode_supp = 0x1f;
128  // Statically set hardware config word
129  driveID.atap_hwreset_res = 0x4001;
130 
131  //arbitrary for now...
132  driveID.atap_ata_major = WDC_VER_ATA7;
133 }
134 
136 {
137  // destroy the data buffer
138  delete [] dataBuffer;
139 }
140 
141 void
143 {
144  // initialize the data buffer and shadow registers
145  dataBuffer = new uint8_t[MAX_DMA_SIZE];
146 
147  memset(dataBuffer, 0, MAX_DMA_SIZE);
148  memset(&cmdReg, 0, sizeof(CommandReg_t));
149  memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
150 
151  curPrdAddr = 0;
152  curSector = 0;
153  cmdBytes = 0;
154  cmdBytesLeft = 0;
155  drqBytesLeft = 0;
156  dmaRead = false;
157  intrPending = false;
158  dmaAborted = false;
159 
160  // set the device state to idle
161  dmaState = Dma_Idle;
162 
163  if (id == DEV0) {
165  devID = DEV0;
166  } else if (id == DEV1) {
168  devID = DEV1;
169  } else {
170  panic("Invalid device ID: %#x\n", id);
171  }
172 
173  // set the device ready bit
175 
176  /* The error register must be set to 0x1 on start-up to
177  indicate that no diagnostic error was detected */
178  cmdReg.error = 0x1;
179 }
180 
182 // Utility functions
184 
185 bool
187 {
188  return ctrl->isDiskSelected(this);
189 }
190 
191 Addr
193 {
194  if (ctrl)
195  return ctrl->pciToDma(pciAddr);
196  else
197  panic("Access to unset controller!\n");
198 }
199 
201 // Device registers read/write
203 
204 void
205 IdeDisk::readCommand(const Addr offset, int size, uint8_t *data)
206 {
207  if (offset == DATA_OFFSET) {
208  if (size == sizeof(uint16_t)) {
209  *(uint16_t *)data = cmdReg.data;
210  } else if (size == sizeof(uint32_t)) {
211  *(uint16_t *)data = cmdReg.data;
213  *((uint16_t *)data + 1) = cmdReg.data;
214  } else {
215  panic("Data read of unsupported size %d.\n", size);
216  }
218  return;
219  }
220  assert(size == sizeof(uint8_t));
221  switch (offset) {
222  case ERROR_OFFSET:
223  *data = cmdReg.error;
224  break;
225  case NSECTOR_OFFSET:
226  *data = cmdReg.sec_count;
227  break;
228  case SECTOR_OFFSET:
229  *data = cmdReg.sec_num;
230  break;
231  case LCYL_OFFSET:
232  *data = cmdReg.cyl_low;
233  break;
234  case HCYL_OFFSET:
235  *data = cmdReg.cyl_high;
236  break;
237  case DRIVE_OFFSET:
238  *data = cmdReg.drive;
239  break;
240  case STATUS_OFFSET:
241  *data = status;
243  break;
244  default:
245  panic("Invalid IDE command register offset: %#x\n", offset);
246  }
247  DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
248 }
249 
250 void
251 IdeDisk::readControl(const Addr offset, int size, uint8_t *data)
252 {
253  assert(size == sizeof(uint8_t));
254  *data = status;
255  if (offset != ALTSTAT_OFFSET)
256  panic("Invalid IDE control register offset: %#x\n", offset);
257  DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
258 }
259 
260 void
261 IdeDisk::writeCommand(const Addr offset, int size, const uint8_t *data)
262 {
263  if (offset == DATA_OFFSET) {
264  if (size == sizeof(uint16_t)) {
265  cmdReg.data = *(const uint16_t *)data;
266  } else if (size == sizeof(uint32_t)) {
267  cmdReg.data = *(const uint16_t *)data;
269  cmdReg.data = *((const uint16_t *)data + 1);
270  } else {
271  panic("Data write of unsupported size %d.\n", size);
272  }
274  return;
275  }
276 
277  assert(size == sizeof(uint8_t));
278  switch (offset) {
279  case FEATURES_OFFSET:
280  break;
281  case NSECTOR_OFFSET:
282  cmdReg.sec_count = *data;
283  break;
284  case SECTOR_OFFSET:
285  cmdReg.sec_num = *data;
286  break;
287  case LCYL_OFFSET:
288  cmdReg.cyl_low = *data;
289  break;
290  case HCYL_OFFSET:
291  cmdReg.cyl_high = *data;
292  break;
293  case DRIVE_OFFSET:
294  cmdReg.drive = *data;
296  break;
297  case COMMAND_OFFSET:
298  cmdReg.command = *data;
300  break;
301  default:
302  panic("Invalid IDE command register offset: %#x\n", offset);
303  }
304  DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
305  (uint32_t)*data);
306 }
307 
308 void
309 IdeDisk::writeControl(const Addr offset, int size, const uint8_t *data)
310 {
311  if (offset != CONTROL_OFFSET)
312  panic("Invalid IDE control register offset: %#x\n", offset);
313 
314  if (*data & CONTROL_RST_BIT) {
315  // force the device into the reset state
318  } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) {
320  }
321 
323 
324  DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
325  (uint32_t)*data);
326 }
327 
329 // Perform DMA transactions
331 
332 void
334 {
335  if (dmaAborted) {
336  DPRINTF(IdeDisk, "DMA Aborted before reading PRD entry\n");
338  return;
339  }
340 
342  panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
343  dmaState, devState);
344 
347  return;
348  } else
350  (uint8_t*)&curPrd.entry);
351 }
352 
353 void
355 {
356  if (dmaAborted) {
357  DPRINTF(IdeDisk, "DMA Aborted while reading PRD entry\n");
359  return;
360  }
361 
363  "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
366  curPrd.getEOT(), curSector);
367 
368  // the prd pointer has already been translated, so just do an increment
369  curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
370 
371  if (dmaRead)
372  doDmaDataRead();
373  else
374  doDmaDataWrite();
375 }
376 
377 void
379 {
381  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
382 
383  DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
384  diskDelay, totalDiskDelay);
385 
386  schedule(dmaReadWaitEvent, curTick() + totalDiskDelay);
387 }
388 
389 void
391 {
393 
394  using namespace Stats;
396  .name(name() + ".dma_read_full_pages")
397  .desc("Number of full page size DMA reads (not PRD).")
398  ;
400  .name(name() + ".dma_read_bytes")
401  .desc("Number of bytes transfered via DMA reads (not PRD).")
402  ;
403  dmaReadTxs
404  .name(name() + ".dma_read_txs")
405  .desc("Number of DMA read transactions (not PRD).")
406  ;
407 
409  .name(name() + ".dma_write_full_pages")
410  .desc("Number of full page size DMA writes.")
411  ;
413  .name(name() + ".dma_write_bytes")
414  .desc("Number of bytes transfered via DMA writes.")
415  ;
417  .name(name() + ".dma_write_txs")
418  .desc("Number of DMA write transactions.")
419  ;
420 }
421 
422 void
424 {
425  if (dmaAborted) {
426  DPRINTF(IdeDisk, "DMA Aborted in middle of Dma Read\n");
427  if (dmaReadCG)
428  delete dmaReadCG;
429  dmaReadCG = NULL;
431  return;
432  }
433 
434  if (!dmaReadCG) {
435  // clear out the data buffer
436  memset(dataBuffer, 0, MAX_DMA_SIZE);
439 
440  }
443  return;
444  } else if (!dmaReadCG->done()) {
445  assert(dmaReadCG->complete() < MAX_DMA_SIZE);
449  dmaReadTxs++;
450  if (dmaReadCG->size() == pageBytes)
452  dmaReadCG->next();
453  } else {
454  assert(dmaReadCG->done());
455  delete dmaReadCG;
456  dmaReadCG = NULL;
457  dmaReadDone();
458  }
459 }
460 
461 void
463 {
464  uint32_t bytesWritten = 0;
465 
466  // write the data to the disk image
467  for (bytesWritten = 0; bytesWritten < curPrd.getByteCount();
468  bytesWritten += SectorSize) {
469 
471  writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
472  }
473 
474  // check for the EOT
475  if (curPrd.getEOT()) {
476  assert(cmdBytesLeft == 0);
477  dmaState = Dma_Idle;
479  } else {
480  doDmaTransfer();
481  }
482 }
483 
484 void
486 {
488  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
489  uint32_t bytesRead = 0;
490 
491  DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
492  diskDelay, totalDiskDelay);
493 
494  memset(dataBuffer, 0, MAX_DMA_SIZE);
495  assert(cmdBytesLeft <= MAX_DMA_SIZE);
496  while (bytesRead < curPrd.getByteCount()) {
497  readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
498  bytesRead += SectorSize;
500  }
501  DPRINTF(IdeDisk, "doDmaWrite, bytesRead: %d cmdBytesLeft: %d\n",
502  bytesRead, cmdBytesLeft);
503 
504  schedule(dmaWriteWaitEvent, curTick() + totalDiskDelay);
505 }
506 
507 void
509 {
510  if (dmaAborted) {
511  DPRINTF(IdeDisk, "DMA Aborted while doing DMA Write\n");
512  if (dmaWriteCG)
513  delete dmaWriteCG;
514  dmaWriteCG = NULL;
516  return;
517  }
518  if (!dmaWriteCG) {
519  // clear out the data buffer
522  }
525  DPRINTF(IdeDisk, "doDmaWrite: rescheduling\n");
526  return;
527  } else if (!dmaWriteCG->done()) {
528  assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
531  DPRINTF(IdeDisk, "doDmaWrite: not done curPrd byte count %d, eot %#x\n",
534  dmaWriteTxs++;
535  if (dmaWriteCG->size() == pageBytes)
537  dmaWriteCG->next();
538  } else {
539  DPRINTF(IdeDisk, "doDmaWrite: done curPrd byte count %d, eot %#x\n",
541  assert(dmaWriteCG->done());
542  delete dmaWriteCG;
543  dmaWriteCG = NULL;
544  dmaWriteDone();
545  }
546 }
547 
548 void
550 {
551  DPRINTF(IdeDisk, "doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
553  // check for the EOT
554  if (curPrd.getEOT()) {
555  assert(cmdBytesLeft == 0);
556  dmaState = Dma_Idle;
558  } else {
559  doDmaTransfer();
560  }
561 }
562 
564 // Disk utility routines
566 
567 void
568 IdeDisk::readDisk(uint32_t sector, uint8_t *data)
569 {
570  uint32_t bytesRead = image->read(data, sector);
571 
572  if (bytesRead != SectorSize)
573  panic("Can't read from %s. Only %d of %d read. errno=%d\n",
574  name(), bytesRead, SectorSize, errno);
575 }
576 
577 void
578 IdeDisk::writeDisk(uint32_t sector, uint8_t *data)
579 {
580  uint32_t bytesWritten = image->write(data, sector);
581 
582  if (bytesWritten != SectorSize)
583  panic("Can't write to %s. Only %d of %d written. errno=%d\n",
584  name(), bytesWritten, SectorSize, errno);
585 }
586 
588 // Setup and handle commands
590 
591 void
592 IdeDisk::startDma(const uint32_t &prdTableBase)
593 {
594  if (dmaState != Dma_Start)
595  panic("Inconsistent DMA state, should be in Dma_Start!\n");
596 
598  panic("Inconsistent device state for DMA start!\n");
599 
600  // PRD base address is given by bits 31:2
601  curPrdAddr = pciToDma((Addr)(prdTableBase & ~ULL(0x3)));
602 
604 
605  // schedule dma transfer (doDmaTransfer)
607 }
608 
609 void
611 {
612  if (dmaState == Dma_Idle)
613  panic("Inconsistent DMA state, should be Start or Transfer!");
614 
616  panic("Inconsistent device state, should be Transfer or Prepare!\n");
617 
619 }
620 
621 void
623 {
624  DevAction_t action = ACT_NONE;
625  uint32_t size = 0;
626  dmaRead = false;
627 
628  // Decode commands
629  switch (cmdReg.command) {
630  // Supported non-data commands
632  size = (uint32_t)image->size() - 1;
633  cmdReg.sec_num = (size & 0xff);
634  cmdReg.cyl_low = ((size & 0xff00) >> 8);
635  cmdReg.cyl_high = ((size & 0xff0000) >> 16);
636  cmdReg.head = ((size & 0xf000000) >> 24);
637 
639  action = ACT_CMD_COMPLETE;
640  break;
641 
642  case WDCC_RECAL:
643  case WDCC_IDP:
644  case WDCC_STANDBY_IMMED:
645  case WDCC_FLUSHCACHE:
646  case WDSF_VERIFY:
647  case WDSF_SEEK:
648  case SET_FEATURES:
649  case WDCC_SETMULTI:
650  case WDCC_IDLE:
652  action = ACT_CMD_COMPLETE;
653  break;
654 
655  // Supported PIO data-in commands
656  case WDCC_IDENTIFY:
658  cmdBytes = cmdBytesLeft = sizeof(struct ataparams);
660  action = ACT_DATA_READY;
661  break;
662 
663  case WDCC_READMULTI:
664  case WDCC_READ:
665  if (!(cmdReg.drive & DRIVE_LBA_BIT))
666  panic("Attempt to perform CHS access, only supports LBA\n");
667 
668  if (cmdReg.sec_count == 0)
669  cmdBytes = cmdBytesLeft = (256 * SectorSize);
670  else
672 
673  curSector = getLBABase();
674 
677  action = ACT_DATA_READY;
678  break;
679 
680  // Supported PIO data-out commands
681  case WDCC_WRITEMULTI:
682  case WDCC_WRITE:
683  if (!(cmdReg.drive & DRIVE_LBA_BIT))
684  panic("Attempt to perform CHS access, only supports LBA\n");
685 
686  if (cmdReg.sec_count == 0)
687  cmdBytes = cmdBytesLeft = (256 * SectorSize);
688  else
690  DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d\n", cmdBytesLeft);
691  curSector = getLBABase();
692 
694  action = ACT_DATA_READY;
695  break;
696 
697  // Supported DMA commands
698  case WDCC_WRITEDMA:
699  dmaRead = true; // a write to the disk is a DMA read from memory
701  case WDCC_READDMA:
702  if (!(cmdReg.drive & DRIVE_LBA_BIT))
703  panic("Attempt to perform CHS access, only supports LBA\n");
704 
705  if (cmdReg.sec_count == 0)
706  cmdBytes = cmdBytesLeft = (256 * SectorSize);
707  else
709  DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d in readdma\n", cmdBytesLeft);
710 
711  curSector = getLBABase();
712 
714  action = ACT_DMA_READY;
715  break;
716 
717  default:
718  panic("Unsupported ATA command: %#x\n", cmdReg.command);
719  }
720 
721  if (action != ACT_NONE) {
722  // set the BSY bit
724  // clear the DRQ bit
726  // clear the DF bit
727  status &= ~STATUS_DF_BIT;
728 
729  updateState(action);
730  }
731 }
732 
734 // Handle setting and clearing interrupts
736 
737 void
739 {
740  DPRINTF(IdeDisk, "Posting Interrupt\n");
741  if (intrPending)
742  panic("Attempt to post an interrupt with one pending\n");
743 
744  intrPending = true;
745 
746  // talk to controller to set interrupt
747  if (ctrl) {
748  ctrl->intrPost();
749  }
750 }
751 
752 void
754 {
755  DPRINTF(IdeDisk, "Clearing Interrupt\n");
756  if (!intrPending)
757  panic("Attempt to clear a non-pending interrupt\n");
758 
759  intrPending = false;
760 
761  // talk to controller to clear interrupt
762  if (ctrl)
763  ctrl->intrClear();
764 }
765 
767 // Manage the device internal state machine
769 
770 void
772 {
773  switch (devState) {
774  case Device_Srst:
775  if (action == ACT_SRST_SET) {
776  // set the BSY bit
778  } else if (action == ACT_SRST_CLEAR) {
779  // clear the BSY bit
781 
782  // reset the device state
783  reset(devID);
784  }
785  break;
786 
787  case Device_Idle_S:
788  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
790  } else if (action == ACT_CMD_WRITE) {
791  startCommand();
792  }
793 
794  break;
795 
796  case Device_Idle_SI:
797  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
799  intrClear();
800  } else if (action == ACT_STAT_READ || isIENSet()) {
802  intrClear();
803  } else if (action == ACT_CMD_WRITE) {
804  intrClear();
805  startCommand();
806  }
807 
808  break;
809 
810  case Device_Idle_NS:
811  if (action == ACT_SELECT_WRITE && isDEVSelect()) {
812  if (!isIENSet() && intrPending) {
814  intrPost();
815  }
816  if (isIENSet() || !intrPending) {
818  }
819  }
820  break;
821 
822  case Command_Execution:
823  if (action == ACT_CMD_COMPLETE) {
824  // clear the BSY bit
825  setComplete();
826 
827  if (!isIENSet()) {
829  intrPost();
830  } else {
832  }
833  }
834  break;
835 
836  case Prepare_Data_In:
837  if (action == ACT_CMD_ERROR) {
838  // clear the BSY bit
839  setComplete();
840 
841  if (!isIENSet()) {
843  intrPost();
844  } else {
846  }
847  } else if (action == ACT_DATA_READY) {
848  // clear the BSY bit
850  // set the DRQ bit
852 
853  // copy the data into the data buffer
854  if (cmdReg.command == WDCC_IDENTIFY ||
856  // Reset the drqBytes for this block
857  drqBytesLeft = sizeof(struct ataparams);
858 
859  memcpy((void *)dataBuffer, (void *)&driveID,
860  sizeof(struct ataparams));
861  } else {
862  // Reset the drqBytes for this block
864 
866  }
867 
868  // put the first two bytes into the data register
869  memcpy((void *)&cmdReg.data, (void *)dataBuffer,
870  sizeof(uint16_t));
871 
872  if (!isIENSet()) {
874  intrPost();
875  } else {
877  }
878  }
879  break;
880 
881  case Data_Ready_INTRQ_In:
882  if (action == ACT_STAT_READ) {
884  intrClear();
885  }
886  break;
887 
888  case Transfer_Data_In:
889  if (action == ACT_DATA_READ_BYTE || action == ACT_DATA_READ_SHORT) {
890  if (action == ACT_DATA_READ_BYTE) {
891  panic("DEBUG: READING DATA ONE BYTE AT A TIME!\n");
892  } else {
893  drqBytesLeft -= 2;
894  cmdBytesLeft -= 2;
895 
896  // copy next short into data registers
897  if (drqBytesLeft)
898  memcpy((void *)&cmdReg.data,
899  (void *)&dataBuffer[SectorSize - drqBytesLeft],
900  sizeof(uint16_t));
901  }
902 
903  if (drqBytesLeft == 0) {
904  if (cmdBytesLeft == 0) {
905  // Clear the BSY bit
906  setComplete();
908  } else {
910  // set the BSY_BIT
912  // clear the DRQ_BIT
914 
918  }
919  }
920  }
921  break;
922 
923  case Prepare_Data_Out:
924  if (action == ACT_CMD_ERROR || cmdBytesLeft == 0) {
925  // clear the BSY bit
926  setComplete();
927 
928  if (!isIENSet()) {
930  intrPost();
931  } else {
933  }
934  } else if (action == ACT_DATA_READY && cmdBytesLeft != 0) {
935  // clear the BSY bit
937  // set the DRQ bit
939 
940  // clear the data buffer to get it ready for writes
941  memset(dataBuffer, 0, MAX_DMA_SIZE);
942 
943  // reset the drqBytes for this block
945 
946  if (cmdBytesLeft == cmdBytes || isIENSet()) {
948  } else {
950  intrPost();
951  }
952  }
953  break;
954 
956  if (action == ACT_STAT_READ) {
958  intrClear();
959  }
960  break;
961 
962  case Transfer_Data_Out:
963  if (action == ACT_DATA_WRITE_BYTE ||
964  action == ACT_DATA_WRITE_SHORT) {
965 
966  if (action == ACT_DATA_READ_BYTE) {
967  panic("DEBUG: WRITING DATA ONE BYTE AT A TIME!\n");
968  } else {
969  // copy the latest short into the data buffer
970  memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
971  (void *)&cmdReg.data,
972  sizeof(uint16_t));
973 
974  drqBytesLeft -= 2;
975  cmdBytesLeft -= 2;
976  }
977 
978  if (drqBytesLeft == 0) {
979  // copy the block to the disk
981 
982  // set the BSY bit
984  // set the seek bit
986  // clear the DRQ bit
988 
990 
994  }
995  }
996  break;
997 
998  case Prepare_Data_Dma:
999  if (action == ACT_CMD_ERROR) {
1000  // clear the BSY bit
1001  setComplete();
1002 
1003  if (!isIENSet()) {
1005  intrPost();
1006  } else {
1008  }
1009  } else if (action == ACT_DMA_READY) {
1010  // clear the BSY bit
1011  status &= ~STATUS_BSY_BIT;
1012  // set the DRQ bit
1014 
1016 
1017  if (dmaState != Dma_Idle)
1018  panic("Inconsistent DMA state, should be Dma_Idle\n");
1019 
1020  dmaState = Dma_Start;
1021  // wait for the write to the DMA start bit
1022  }
1023  break;
1024 
1025  case Transfer_Data_Dma:
1026  if (action == ACT_CMD_ERROR) {
1027  dmaAborted = true;
1029  } else if (action == ACT_DMA_DONE) {
1030  // clear the BSY bit
1031  setComplete();
1032  // set the seek bit
1034  // clear the controller state for DMA transfer
1035  ctrl->setDmaComplete(this);
1036 
1037  if (!isIENSet()) {
1039  intrPost();
1040  } else {
1042  }
1043  }
1044  break;
1045 
1046  case Device_Dma_Abort:
1047  if (action == ACT_CMD_ERROR) {
1048  setComplete();
1050  ctrl->setDmaComplete(this);
1051  dmaAborted = false;
1052  dmaState = Dma_Idle;
1053 
1054  if (!isIENSet()) {
1056  intrPost();
1057  } else {
1059  }
1060  } else {
1061  DPRINTF(IdeDisk, "Disk still busy aborting previous DMA command\n");
1062  }
1063  break;
1064 
1065  default:
1066  panic("Unknown IDE device state: %#x\n", devState);
1067  }
1068 }
1069 
1070 void
1072 {
1073  // Check all outstanding events to see if they are scheduled
1074  // these are all mutually exclusive
1075  Tick reschedule = 0;
1076  Events_t event = None;
1077 
1078  int eventCount = 0;
1079 
1080  if (dmaTransferEvent.scheduled()) {
1082  event = Transfer;
1083  eventCount++;
1084  }
1085  if (dmaReadWaitEvent.scheduled()) {
1087  event = ReadWait;
1088  eventCount++;
1089  }
1090  if (dmaWriteWaitEvent.scheduled()) {
1092  event = WriteWait;
1093  eventCount++;
1094  }
1095  if (dmaPrdReadEvent.scheduled()) {
1097  event = PrdRead;
1098  eventCount++;
1099  }
1100  if (dmaReadEvent.scheduled()) {
1102  event = DmaRead;
1103  eventCount++;
1104  }
1105  if (dmaWriteEvent.scheduled()) {
1107  event = DmaWrite;
1108  eventCount++;
1109  }
1110 
1111  assert(eventCount <= 1);
1112 
1115 
1116  // Serialize device registers
1127 
1128  // Serialize the PRD related information
1133 
1135  // Serialize current transfer related information
1146 }
1147 
1148 void
1150 {
1151  // Reschedule events that were outstanding
1152  // these are all mutually exclusive
1153  Tick reschedule = 0;
1154  Events_t event = None;
1155 
1158 
1159  switch (event) {
1160  case None : break;
1161  case Transfer : schedule(dmaTransferEvent, reschedule); break;
1162  case ReadWait : schedule(dmaReadWaitEvent, reschedule); break;
1164  case PrdRead : schedule(dmaPrdReadEvent, reschedule); break;
1165  case DmaRead : schedule(dmaReadEvent, reschedule); break;
1166  case DmaWrite : schedule(dmaWriteEvent, reschedule); break;
1167  }
1168 
1169  // Unserialize device registers
1180 
1181  // Unserialize the PRD related information
1186 
1188  // Unserialize current transfer related information
1199 }
1200 
1201 IdeDisk *
1202 IdeDiskParams::create()
1203 {
1204  return new IdeDisk(this);
1205 }
CONTROL_OFFSET
#define CONTROL_OFFSET
Definition: ide_disk.hh:108
IdeDisk::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: ide_disk.cc:1071
IdeDisk::dmaReadBytes
Stats::Scalar dmaReadBytes
Definition: ide_disk.hh:256
Prepare_Data_In
@ Prepare_Data_In
Definition: ide_disk.hh:179
Stats::Group::regStats
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:64
DiskImage::write
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
ACT_DMA_READY
@ ACT_DMA_READY
Definition: ide_disk.hh:160
WDSF_SEEK
#define WDSF_SEEK
Definition: ide_wdcreg.h:157
IdeDisk::getLBABase
uint32_t getLBABase()
Definition: ide_disk.hh:357
WDCC_IDP
#define WDCC_IDP
Definition: ide_wdcreg.h:87
IdeDisk::curPrdAddr
uint32_t curPrdAddr
PRD table base address.
Definition: ide_disk.hh:245
ChunkGenerator::complete
unsigned complete() const
Number of bytes we have already chunked up.
Definition: chunk_generator.hh:128
DmaWrite
@ DmaWrite
Definition: ide_disk.hh:145
DrainState::Running
@ Running
Running normally.
CommandReg::head
uint8_t head
Definition: ide_disk.hh:133
data
const char data[]
Definition: circlebuf.test.cc:42
WDCC_FLUSHCACHE
#define WDCC_FLUSHCACHE
Definition: ide_wdcreg.h:100
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
IdeDisk::status
uint8_t status
Status register.
Definition: ide_disk.hh:233
PrdTableEntry::getBaseAddr
uint32_t getBaseAddr()
Definition: ide_disk.hh:79
Events_t
enum Events Events_t
CommandReg::error
uint8_t error
Definition: ide_disk.hh:126
PrdEntry::endOfTable
uint16_t endOfTable
Definition: ide_disk.hh:72
IdeDisk::dmaPrdReadEvent
EventFunctionWrapper dmaPrdReadEvent
Definition: ide_disk.hh:327
DATA_OFFSET
#define DATA_OFFSET
Definition: ide_disk.hh:96
IdeDisk::~IdeDisk
~IdeDisk()
Delete the data buffer.
Definition: ide_disk.cc:135
EventManager::reschedule
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:1023
LCYL_OFFSET
#define LCYL_OFFSET
Definition: ide_disk.hh:101
Transfer
@ Transfer
Definition: ide_disk.hh:140
ACT_SRST_SET
@ ACT_SRST_SET
Definition: ide_disk.hh:162
SectorSize
#define SectorSize
Definition: disk_image.hh:44
WDCC_READDMA
#define WDCC_READDMA
Definition: ide_wdcreg.h:93
CONTROL_RST_BIT
#define CONTROL_RST_BIT
Definition: ide_disk.hh:112
WDSF_READ_NATIVE_MAX
#define WDSF_READ_NATIVE_MAX
Definition: ide_wdcreg.h:156
IdeDisk::doDmaDataRead
void doDmaDataRead()
Definition: ide_disk.cc:378
WDCC_READ
#define WDCC_READ
Definition: ide_wdcreg.h:80
IdeDisk::dmaWriteDone
void dmaWriteDone()
Definition: ide_disk.cc:549
ACT_CMD_COMPLETE
@ ACT_CMD_COMPLETE
Definition: ide_disk.hh:151
ALTSTAT_OFFSET
#define ALTSTAT_OFFSET
Definition: ide_disk.hh:109
disk_image.hh
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
IdeDisk::updateState
void updateState(DevAction_t action)
Definition: ide_disk.cc:771
Transfer_Data_In
@ Transfer_Data_In
Definition: ide_disk.hh:181
SET_FEATURES
#define SET_FEATURES
Definition: ide_wdcreg.h:102
PrdEntry
Definition: ide_disk.hh:69
Device_Idle_S
@ Device_Idle_S
Definition: ide_disk.hh:168
ACT_DATA_READ_BYTE
@ ACT_DATA_READ_BYTE
Definition: ide_disk.hh:156
WDSF_VERIFY
#define WDSF_VERIFY
Definition: ide_wdcreg.h:158
IdeDisk::curPrd
PrdTableEntry curPrd
PRD entry.
Definition: ide_disk.hh:247
IdeDisk::dmaReadWaitEvent
EventFunctionWrapper dmaReadWaitEvent
Definition: ide_disk.hh:318
ACT_DATA_READY
@ ACT_DATA_READY
Definition: ide_disk.hh:155
Device_Srst
@ Device_Srst
Definition: ide_disk.hh:173
CommandReg::cyl_high
uint8_t cyl_high
Definition: ide_disk.hh:130
IdeDisk::diskDelay
int diskDelay
The disk delay in microseconds.
Definition: ide_disk.hh:215
IdeDisk::dmaReadDone
void dmaReadDone()
Definition: ide_disk.cc:462
PciDevice::intrClear
void intrClear()
Definition: device.hh:199
ACT_STAT_READ
@ ACT_STAT_READ
Definition: ide_disk.hh:154
IdeDisk::doDmaTransfer
void doDmaTransfer()
Definition: ide_disk.cc:333
DRIVE_LBA_BIT
#define DRIVE_LBA_BIT
Definition: ide_disk.hh:119
IdeDisk::startDma
void startDma(const uint32_t &prdTableBase)
Definition: ide_disk.cc:592
Transfer_Data_Out
@ Transfer_Data_Out
Definition: ide_disk.hh:186
ACT_DATA_WRITE_BYTE
@ ACT_DATA_WRITE_BYTE
Definition: ide_disk.hh:158
IdeDisk::abortDma
void abortDma()
Definition: ide_disk.cc:610
Stats::reset
void reset()
Definition: statistics.cc:569
Event::when
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:503
DiskImage::size
virtual std::streampos size() const =0
CommandReg::command
uint8_t command
Definition: ide_disk.hh:135
IdeDisk::pageBytes
Addr pageBytes
Size of OS pages.
Definition: ide_disk.hh:243
ACT_CMD_ERROR
@ ACT_CMD_ERROR
Definition: ide_disk.hh:152
Device_Dma_Abort
@ Device_Dma_Abort
Definition: ide_disk.hh:191
DEV0
#define DEV0
Definition: ide_disk.hh:121
COMMAND_OFFSET
#define COMMAND_OFFSET
Definition: ide_disk.hh:106
Prepare_Data_Out
@ Prepare_Data_Out
Definition: ide_disk.hh:184
IdeDisk::dmaReadCG
ChunkGenerator * dmaReadCG
Definition: ide_disk.hh:317
IdeDisk::devState
DevState_t devState
Device state.
Definition: ide_disk.hh:237
NSECTOR_OFFSET
#define NSECTOR_OFFSET
Definition: ide_disk.hh:99
IdeDisk::writeDisk
void writeDisk(uint32_t sector, uint8_t *data)
Definition: ide_disk.cc:578
CommandReg::drive
uint8_t drive
Definition: ide_disk.hh:132
IdeDisk::dmaPrdReadDone
void dmaPrdReadDone()
Definition: ide_disk.cc:354
SERIALIZE_ENUM
#define SERIALIZE_ENUM(scalar)
Definition: serialize.hh:813
ChunkGenerator::size
unsigned size() const
Return size in bytes of current chunk.
Definition: chunk_generator.hh:121
Device_Idle_SI
@ Device_Idle_SI
Definition: ide_disk.hh:169
PrdTableEntry::getEOT
uint16_t getEOT()
Definition: ide_disk.hh:90
IdeDisk::cmdBytes
uint32_t cmdBytes
Number of bytes in command data transfer.
Definition: ide_disk.hh:223
IdeDisk::cmdReg
CommandReg_t cmdReg
Command block registers.
Definition: ide_disk.hh:231
ChunkGenerator::addr
Addr addr() const
Return starting address of current chunk.
Definition: chunk_generator.hh:115
IdeDisk::dmaState
DmaState_t dmaState
Dma state.
Definition: ide_disk.hh:239
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:188
IdeController::isDiskSelected
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
Definition: ide_ctrl.cc:143
IdeDisk::readControl
void readControl(const Addr offset, int size, uint8_t *data)
Definition: ide_disk.cc:251
cp
Definition: cprintf.cc:40
IdeDisk::dmaWriteEvent
EventFunctionWrapper dmaWriteEvent
Definition: ide_disk.hh:333
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
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:175
WDC_VER_ATA7
#define WDC_VER_ATA7
Definition: ide_atareg.h:182
IdeDisk::regStats
void regStats() override
Register Statistics.
Definition: ide_disk.cc:390
None
@ None
Definition: ide_disk.hh:139
STATUS_BSY_BIT
#define STATUS_BSY_BIT
Definition: ide_disk.hh:114
IdeDisk::isIENSet
bool isIENSet()
Definition: ide_disk.hh:344
IdeDisk::doDmaDataWrite
void doDmaDataWrite()
Definition: ide_disk.cc:485
IdeDisk::intrClear
void intrClear()
Definition: ide_disk.cc:753
STATUS_OFFSET
#define STATUS_OFFSET
Definition: ide_disk.hh:105
IdeDisk::pciToDma
Addr pciToDma(Addr pciAddr)
Definition: ide_disk.cc:192
IdeDisk::writeControl
void writeControl(const Addr offset, int size, const uint8_t *data)
Definition: ide_disk.cc:309
sim_object.hh
IdeDisk::dmaReadFullPages
Stats::Scalar dmaReadFullPages
Definition: ide_disk.hh:255
IdeController::setDmaComplete
void setDmaComplete(IdeDisk *disk)
Definition: ide_ctrl.cc:156
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:297
Data_Ready_INTRQ_Out
@ Data_Ready_INTRQ_Out
Definition: ide_disk.hh:185
IdeDisk::startCommand
void startCommand()
Definition: ide_disk.cc:622
IdeDisk::curSector
uint32_t curSector
Current sector in access.
Definition: ide_disk.hh:229
CommandReg::sec_count
uint8_t sec_count
Definition: ide_disk.hh:127
IdeDisk::dmaWriteTxs
Stats::Scalar dmaWriteTxs
Definition: ide_disk.hh:260
PrdTableEntry::entry
PrdEntry_t entry
Definition: ide_disk.hh:77
ide_disk.hh
ataparams
Definition: ide_atareg.h:67
ACT_NONE
@ ACT_NONE
Definition: ide_disk.hh:149
PrdEntry_t
struct PrdEntry PrdEntry_t
WriteWait
@ WriteWait
Definition: ide_disk.hh:142
STATUS_SEEK_BIT
#define STATUS_SEEK_BIT
Definition: ide_disk.hh:117
M5_FALLTHROUGH
#define M5_FALLTHROUGH
Definition: compiler.hh:84
ACT_CMD_WRITE
@ ACT_CMD_WRITE
Definition: ide_disk.hh:150
cprintf.hh
IdeDisk::reset
void reset(int id)
Reset the device state.
Definition: ide_disk.cc:142
ChunkGenerator::next
bool next()
Advance generator to next chunk.
Definition: chunk_generator.hh:155
CommandReg
Definition: ide_disk.hh:124
ACT_DATA_READ_SHORT
@ ACT_DATA_READ_SHORT
Definition: ide_disk.hh:157
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:832
PrdEntry::baseAddr
uint32_t baseAddr
Definition: ide_disk.hh:70
IdeDisk::dmaAborted
bool dmaAborted
DMA Aborted.
Definition: ide_disk.hh:253
IdeDisk::dmaReadEvent
EventFunctionWrapper dmaReadEvent
Definition: ide_disk.hh:330
WDCC_WRITEMULTI
#define WDCC_WRITEMULTI
Definition: ide_wdcreg.h:90
WDCC_WRITEDMA
#define WDCC_WRITEDMA
Definition: ide_wdcreg.h:94
IdeDisk::dmaWriteFullPages
Stats::Scalar dmaWriteFullPages
Definition: ide_disk.hh:258
core.hh
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
IdeDisk::setComplete
void setComplete()
Definition: ide_disk.hh:347
IdeDisk::doDmaRead
void doDmaRead()
Definition: ide_disk.cc:423
DMA_BACKOFF_PERIOD
#define DMA_BACKOFF_PERIOD
Definition: ide_disk.hh:59
Stats::DataWrap::name
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:274
Transfer_Data_Dma
@ Transfer_Data_Dma
Definition: ide_disk.hh:190
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:137
name
const std::string & name()
Definition: trace.cc:50
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
IdeDisk
IDE Disk device model.
Definition: ide_disk.hh:205
STATUS_DF_BIT
#define STATUS_DF_BIT
Definition: ide_disk.hh:118
IdeDisk::intrPending
bool intrPending
Interrupt pending.
Definition: ide_disk.hh:251
CONTROL_IEN_BIT
#define CONTROL_IEN_BIT
Definition: ide_disk.hh:113
IdeDisk::driveID
struct ataparams driveID
Drive identification structure for this disk.
Definition: ide_disk.hh:219
PrdTableEntry::getByteCount
uint32_t getByteCount()
Definition: ide_disk.hh:84
Device_Idle_NS
@ Device_Idle_NS
Definition: ide_disk.hh:170
DRIVE_OFFSET
#define DRIVE_OFFSET
Definition: ide_disk.hh:104
Drainable::drainState
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:320
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
FEATURES_OFFSET
#define FEATURES_OFFSET
Definition: ide_disk.hh:98
DmaRead
@ DmaRead
Definition: ide_disk.hh:144
ERROR_OFFSET
#define ERROR_OFFSET
Definition: ide_disk.hh:97
WDCC_WRITE
#define WDCC_WRITE
Definition: ide_wdcreg.h:81
IdeDisk::ctrl
IdeController * ctrl
The IDE controller for this disk.
Definition: ide_disk.hh:209
MAX_MULTSECT
#define MAX_MULTSECT
Definition: ide_disk.hh:63
CommandReg::data
uint16_t data
Definition: ide_disk.hh:125
HCYL_OFFSET
#define HCYL_OFFSET
Definition: ide_disk.hh:102
Command_Execution
@ Command_Execution
Definition: ide_disk.hh:176
IdeDisk::devID
int devID
Device ID (device0=0/device1=1)
Definition: ide_disk.hh:249
CommandReg::cyl_low
uint8_t cyl_low
Definition: ide_disk.hh:129
IdeDisk::image
DiskImage * image
The image that contains the data of this disk.
Definition: ide_disk.hh:211
WDCC_SETMULTI
#define WDCC_SETMULTI
Definition: ide_wdcreg.h:91
ACT_SRST_CLEAR
@ ACT_SRST_CLEAR
Definition: ide_disk.hh:163
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:840
Dma_Start
@ Dma_Start
Definition: ide_disk.hh:196
ReadWait
@ ReadWait
Definition: ide_disk.hh:141
PrdRead
@ PrdRead
Definition: ide_disk.hh:143
IdeDisk::readCommand
void readCommand(const Addr offset, int size, uint8_t *data)
Definition: ide_disk.cc:205
DevAction_t
enum DevAction DevAction_t
STATUS_DRDY_BIT
#define STATUS_DRDY_BIT
Definition: ide_disk.hh:115
ide_ctrl.hh
PrdEntry::byteCount
uint16_t byteCount
Definition: ide_disk.hh:71
ATAPI_IDENTIFY_DEVICE
#define ATAPI_IDENTIFY_DEVICE
Definition: ide_wdcreg.h:171
IdeDisk::Params
IdeDiskParams Params
Definition: ide_disk.hh:263
chunk_generator.hh
CommandReg::sec_num
uint8_t sec_num
Definition: ide_disk.hh:128
WDCC_STANDBY_IMMED
#define WDCC_STANDBY_IMMED
Definition: ide_wdcreg.h:108
WDCC_RECAL
#define WDCC_RECAL
Definition: ide_wdcreg.h:78
IdeDisk::dmaRead
bool dmaRead
Dma transaction is a read.
Definition: ide_disk.hh:241
IdeDisk::isDEVSelect
bool isDEVSelect()
Definition: ide_disk.cc:186
DiskImage::read
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
Data_Ready_INTRQ_In
@ Data_Ready_INTRQ_In
Definition: ide_disk.hh:180
ACT_DMA_DONE
@ ACT_DMA_DONE
Definition: ide_disk.hh:161
IdeDisk::IdeDisk
IdeDisk(const Params *p)
Definition: ide_disk.cc:61
IdeController::intrPost
void intrPost()
Definition: ide_ctrl.cc:149
IdeDisk::intrPost
void intrPost()
Definition: ide_disk.cc:738
Stats
Definition: statistics.cc:61
IdeDisk::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: ide_disk.cc:1149
UNSERIALIZE_ENUM
#define UNSERIALIZE_ENUM(scalar)
Definition: serialize.hh:820
ChunkGenerator
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
Definition: chunk_generator.hh:55
trace.hh
WDCC_IDENTIFY
#define WDCC_IDENTIFY
Definition: ide_wdcreg.h:101
Dma_Transfer
@ Dma_Transfer
Definition: ide_disk.hh:197
Dma_Idle
@ Dma_Idle
Definition: ide_disk.hh:195
Prepare_Data_Dma
@ Prepare_Data_Dma
Definition: ide_disk.hh:189
SECTOR_OFFSET
#define SECTOR_OFFSET
Definition: ide_disk.hh:100
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
IdeDisk::nIENBit
bool nIENBit
Interrupt enable bit.
Definition: ide_disk.hh:235
ACT_DATA_WRITE_SHORT
@ ACT_DATA_WRITE_SHORT
Definition: ide_disk.hh:159
CheckpointIn
Definition: serialize.hh:67
IdeDisk::cmdBytesLeft
uint32_t cmdBytesLeft
Number of bytes left in command data transfer.
Definition: ide_disk.hh:225
ACT_SELECT_WRITE
@ ACT_SELECT_WRITE
Definition: ide_disk.hh:153
Stats::DataWrap::desc
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:307
IdeDisk::dmaReadTxs
Stats::Scalar dmaReadTxs
Definition: ide_disk.hh:257
DmaDevice::dmaPending
bool dmaPending() const
Definition: dma_device.hh:201
IdeDisk::dataBuffer
uint8_t * dataBuffer
Data buffer for transfers.
Definition: ide_disk.hh:221
WDCC_READMULTI
#define WDCC_READMULTI
Definition: ide_wdcreg.h:89
DEV1
#define DEV1
Definition: ide_disk.hh:122
IdeDisk::writeCommand
void writeCommand(const Addr offset, int size, const uint8_t *data)
Definition: ide_disk.cc:261
STATUS_DRQ_BIT
#define STATUS_DRQ_BIT
Definition: ide_disk.hh:116
IdeDisk::drqBytesLeft
uint32_t drqBytesLeft
Number of bytes left in DRQ block.
Definition: ide_disk.hh:227
ULL
#define ULL(N)
uint64_t constant
Definition: types.hh:50
MAX_DMA_SIZE
#define MAX_DMA_SIZE
Definition: ide_disk.hh:61
IdeDisk::dmaWriteBytes
Stats::Scalar dmaWriteBytes
Definition: ide_disk.hh:259
IdeDisk::doDmaWrite
void doDmaWrite()
Definition: ide_disk.cc:508
PciDevice::pciToDma
Addr pciToDma(Addr pci_addr) const
Definition: device.hh:194
IdeDisk::dmaTransferEvent
EventFunctionWrapper dmaTransferEvent
Definition: ide_disk.hh:312
IdeDisk::dmaWriteCG
ChunkGenerator * dmaWriteCG
Definition: ide_disk.hh:323
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
IdeDisk::dmaWriteWaitEvent
EventFunctionWrapper dmaWriteWaitEvent
Definition: ide_disk.hh:324
WDCC_IDLE
#define WDCC_IDLE
Definition: ide_wdcreg.h:104
IdeDisk::readDisk
void readDisk(uint32_t sector, uint8_t *data)
Definition: ide_disk.cc:568
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

Generated on Wed Sep 30 2020 14:02:11 for gem5 by doxygen 1.8.17