gem5  v21.0.0.0
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/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  ideDiskStats(this),
64  dmaTransferEvent([this]{ doDmaTransfer(); }, name()),
65  dmaReadCG(NULL),
66  dmaReadWaitEvent([this]{ doDmaRead(); }, name()),
67  dmaWriteCG(NULL),
68  dmaWriteWaitEvent([this]{ doDmaWrite(); }, name()),
69  dmaPrdReadEvent([this]{ dmaPrdReadDone(); }, name()),
70  dmaReadEvent([this]{ dmaReadDone(); }, name()),
71  dmaWriteEvent([this]{ dmaWriteDone(); }, name())
72 {
73  // Reset the device state
74  reset(p.driveID);
75 
76  // fill out the drive ID structure
77  memset(&driveID, 0, sizeof(struct ataparams));
78 
79  // Calculate LBA and C/H/S values
80  uint16_t cylinders;
81  uint8_t heads;
82  uint8_t sectors;
83 
84  uint32_t lba_size = image->size();
85  if (lba_size >= 16383*16*63) {
86  cylinders = 16383;
87  heads = 16;
88  sectors = 63;
89  } else {
90  if (lba_size >= 63)
91  sectors = 63;
92  else if (lba_size == 0)
93  panic("Bad IDE image size: 0\n");
94  else
95  sectors = lba_size;
96 
97  if ((lba_size / sectors) >= 16)
98  heads = 16;
99  else
100  heads = (lba_size / sectors);
101 
102  cylinders = lba_size / (heads * sectors);
103  }
104 
105  // Setup the model name
106  strncpy((char *)driveID.atap_model, "5MI EDD si k",
107  sizeof(driveID.atap_model));
108  // Set the maximum multisector transfer size
109  driveID.atap_multi = MAX_MULTSECT;
110  // IORDY supported, IORDY disabled, LBA enabled, DMA enabled
111  driveID.atap_capabilities1 = 0x7;
112  // UDMA support, EIDE support
113  driveID.atap_extensions = 0x6;
114  // Setup default C/H/S settings
115  driveID.atap_cylinders = cylinders;
116  driveID.atap_sectors = sectors;
117  driveID.atap_heads = heads;
118  // Setup the current multisector transfer size
119  driveID.atap_curmulti = MAX_MULTSECT;
120  driveID.atap_curmulti_valid = 0x1;
121  // Number of sectors on disk
122  driveID.atap_capacity = lba_size;
123  // Multiword DMA mode 2 and below supported
124  driveID.atap_dmamode_supp = 0x4;
125  // Set PIO mode 4 and 3 supported
126  driveID.atap_piomode_supp = 0x3;
127  // Set DMA mode 4 and below supported
128  driveID.atap_udmamode_supp = 0x1f;
129  // Statically set hardware config word
130  driveID.atap_hwreset_res = 0x4001;
131 
132  //arbitrary for now...
133  driveID.atap_ata_major = WDC_VER_ATA7;
134 }
135 
137 {
138  // destroy the data buffer
139  delete [] dataBuffer;
140 }
141 
142 void
144 {
145  // initialize the data buffer and shadow registers
146  dataBuffer = new uint8_t[MAX_DMA_SIZE];
147 
148  memset(dataBuffer, 0, MAX_DMA_SIZE);
149  memset(&cmdReg, 0, sizeof(CommandReg_t));
150  memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
151 
152  curPrdAddr = 0;
153  curSector = 0;
154  cmdBytes = 0;
155  cmdBytesLeft = 0;
156  drqBytesLeft = 0;
157  dmaRead = false;
158  intrPending = false;
159  dmaAborted = false;
160 
161  // set the device state to idle
162  dmaState = Dma_Idle;
163 
164  if (id == DEV0) {
166  devID = DEV0;
167  } else if (id == DEV1) {
169  devID = DEV1;
170  } else {
171  panic("Invalid device ID: %#x\n", id);
172  }
173 
174  // set the device ready bit
176 
177  /* The error register must be set to 0x1 on start-up to
178  indicate that no diagnostic error was detected */
179  cmdReg.error = 0x1;
180 }
181 
183 // Utility functions
185 
186 bool
188 {
189  return ctrl->isDiskSelected(this);
190 }
191 
192 Addr
194 {
195  if (ctrl)
196  return ctrl->pciToDma(pciAddr);
197  else
198  panic("Access to unset controller!\n");
199 }
200 
202 // Device registers read/write
204 
205 void
206 IdeDisk::readCommand(const Addr offset, int size, uint8_t *data)
207 {
208  if (offset == DATA_OFFSET) {
209  if (size == sizeof(uint16_t)) {
210  *(uint16_t *)data = cmdReg.data;
211  } else if (size == sizeof(uint32_t)) {
212  *(uint16_t *)data = cmdReg.data;
214  *((uint16_t *)data + 1) = cmdReg.data;
215  } else {
216  panic("Data read of unsupported size %d.\n", size);
217  }
219  return;
220  }
221  assert(size == sizeof(uint8_t));
222  switch (offset) {
223  case ERROR_OFFSET:
224  *data = cmdReg.error;
225  break;
226  case NSECTOR_OFFSET:
227  *data = cmdReg.sec_count;
228  break;
229  case SECTOR_OFFSET:
230  *data = cmdReg.sec_num;
231  break;
232  case LCYL_OFFSET:
233  *data = cmdReg.cyl_low;
234  break;
235  case HCYL_OFFSET:
236  *data = cmdReg.cyl_high;
237  break;
238  case DRIVE_OFFSET:
239  *data = cmdReg.drive;
240  break;
241  case STATUS_OFFSET:
242  *data = status;
244  break;
245  default:
246  panic("Invalid IDE command register offset: %#x\n", offset);
247  }
248  DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
249 }
250 
251 void
252 IdeDisk::readControl(const Addr offset, int size, uint8_t *data)
253 {
254  assert(size == sizeof(uint8_t));
255  *data = status;
256  if (offset != ALTSTAT_OFFSET)
257  panic("Invalid IDE control register offset: %#x\n", offset);
258  DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
259 }
260 
261 void
262 IdeDisk::writeCommand(const Addr offset, int size, const uint8_t *data)
263 {
264  if (offset == DATA_OFFSET) {
265  if (size == sizeof(uint16_t)) {
266  cmdReg.data = *(const uint16_t *)data;
267  } else if (size == sizeof(uint32_t)) {
268  cmdReg.data = *(const uint16_t *)data;
270  cmdReg.data = *((const uint16_t *)data + 1);
271  } else {
272  panic("Data write of unsupported size %d.\n", size);
273  }
275  return;
276  }
277 
278  assert(size == sizeof(uint8_t));
279  switch (offset) {
280  case FEATURES_OFFSET:
281  break;
282  case NSECTOR_OFFSET:
283  cmdReg.sec_count = *data;
284  break;
285  case SECTOR_OFFSET:
286  cmdReg.sec_num = *data;
287  break;
288  case LCYL_OFFSET:
289  cmdReg.cyl_low = *data;
290  break;
291  case HCYL_OFFSET:
292  cmdReg.cyl_high = *data;
293  break;
294  case DRIVE_OFFSET:
295  cmdReg.drive = *data;
297  break;
298  case COMMAND_OFFSET:
299  cmdReg.command = *data;
301  break;
302  default:
303  panic("Invalid IDE command register offset: %#x\n", offset);
304  }
305  DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
306  (uint32_t)*data);
307 }
308 
309 void
310 IdeDisk::writeControl(const Addr offset, int size, const uint8_t *data)
311 {
312  if (offset != CONTROL_OFFSET)
313  panic("Invalid IDE control register offset: %#x\n", offset);
314 
315  if (*data & CONTROL_RST_BIT) {
316  // force the device into the reset state
319  } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) {
321  }
322 
324 
325  DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
326  (uint32_t)*data);
327 }
328 
330 // Perform DMA transactions
332 
333 void
335 {
336  if (dmaAborted) {
337  DPRINTF(IdeDisk, "DMA Aborted before reading PRD entry\n");
339  return;
340  }
341 
343  panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
344  dmaState, devState);
345 
348  return;
349  } else
351  (uint8_t*)&curPrd.entry);
352 }
353 
354 void
356 {
357  if (dmaAborted) {
358  DPRINTF(IdeDisk, "DMA Aborted while reading PRD entry\n");
360  return;
361  }
362 
364  "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
367  curPrd.getEOT(), curSector);
368 
369  // the prd pointer has already been translated, so just do an increment
370  curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
371 
372  if (dmaRead)
373  doDmaDataRead();
374  else
375  doDmaDataWrite();
376 }
377 
378 void
380 {
382  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
383 
384  DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
385  diskDelay, totalDiskDelay);
386 
387  schedule(dmaReadWaitEvent, curTick() + totalDiskDelay);
388 }
389 
390 IdeDisk::
392  : Stats::Group(parent, "IdeDisk"),
393  ADD_STAT(dmaReadFullPages, UNIT_COUNT,
394  "Number of full page size DMA reads (not PRD)."),
395  ADD_STAT(dmaReadBytes, UNIT_BYTE,
396  "Number of bytes transfered via DMA reads (not PRD)."),
397  ADD_STAT(dmaReadTxs, UNIT_COUNT,
398  "Number of DMA read transactions (not PRD)."),
399  ADD_STAT(dmaWriteFullPages, UNIT_COUNT,
400  "Number of full page size DMA writes."),
401  ADD_STAT(dmaWriteBytes, UNIT_BYTE,
402  "Number of bytes transfered via DMA writes."),
403  ADD_STAT(dmaWriteTxs, UNIT_COUNT, "Number of DMA write transactions.")
404 {
405 }
406 
407 void
409 {
410  if (dmaAborted) {
411  DPRINTF(IdeDisk, "DMA Aborted in middle of Dma Read\n");
412  if (dmaReadCG)
413  delete dmaReadCG;
414  dmaReadCG = NULL;
416  return;
417  }
418 
419  if (!dmaReadCG) {
420  // clear out the data buffer
421  memset(dataBuffer, 0, MAX_DMA_SIZE);
424 
425  }
428  return;
429  } else if (!dmaReadCG->done()) {
430  assert(dmaReadCG->complete() < MAX_DMA_SIZE);
435  if (dmaReadCG->size() == chunkBytes)
437  dmaReadCG->next();
438  } else {
439  assert(dmaReadCG->done());
440  delete dmaReadCG;
441  dmaReadCG = NULL;
442  dmaReadDone();
443  }
444 }
445 
446 void
448 {
449  uint32_t bytesWritten = 0;
450 
451  // write the data to the disk image
452  for (bytesWritten = 0; bytesWritten < curPrd.getByteCount();
453  bytesWritten += SectorSize) {
454 
456  writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
457  }
458 
459  // check for the EOT
460  if (curPrd.getEOT()) {
461  assert(cmdBytesLeft == 0);
462  dmaState = Dma_Idle;
464  } else {
465  doDmaTransfer();
466  }
467 }
468 
469 void
471 {
473  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
474  uint32_t bytesRead = 0;
475 
476  DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
477  diskDelay, totalDiskDelay);
478 
479  memset(dataBuffer, 0, MAX_DMA_SIZE);
480  assert(cmdBytesLeft <= MAX_DMA_SIZE);
481  while (bytesRead < curPrd.getByteCount()) {
482  readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
483  bytesRead += SectorSize;
485  }
486  DPRINTF(IdeDisk, "doDmaWrite, bytesRead: %d cmdBytesLeft: %d\n",
487  bytesRead, cmdBytesLeft);
488 
489  schedule(dmaWriteWaitEvent, curTick() + totalDiskDelay);
490 }
491 
492 void
494 {
495  if (dmaAborted) {
496  DPRINTF(IdeDisk, "DMA Aborted while doing DMA Write\n");
497  if (dmaWriteCG)
498  delete dmaWriteCG;
499  dmaWriteCG = NULL;
501  return;
502  }
503  if (!dmaWriteCG) {
504  // clear out the data buffer
507  }
510  DPRINTF(IdeDisk, "doDmaWrite: rescheduling\n");
511  return;
512  } else if (!dmaWriteCG->done()) {
513  assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
516  DPRINTF(IdeDisk, "doDmaWrite: not done curPrd byte count %d, eot %#x\n",
520  if (dmaWriteCG->size() == chunkBytes)
522  dmaWriteCG->next();
523  } else {
524  DPRINTF(IdeDisk, "doDmaWrite: done curPrd byte count %d, eot %#x\n",
526  assert(dmaWriteCG->done());
527  delete dmaWriteCG;
528  dmaWriteCG = NULL;
529  dmaWriteDone();
530  }
531 }
532 
533 void
535 {
536  DPRINTF(IdeDisk, "doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
538  // check for the EOT
539  if (curPrd.getEOT()) {
540  assert(cmdBytesLeft == 0);
541  dmaState = Dma_Idle;
543  } else {
544  doDmaTransfer();
545  }
546 }
547 
549 // Disk utility routines
551 
552 void
553 IdeDisk::readDisk(uint32_t sector, uint8_t *data)
554 {
555  uint32_t bytesRead = image->read(data, sector);
556 
557  if (bytesRead != SectorSize)
558  panic("Can't read from %s. Only %d of %d read. errno=%d\n",
559  name(), bytesRead, SectorSize, errno);
560 }
561 
562 void
563 IdeDisk::writeDisk(uint32_t sector, uint8_t *data)
564 {
565  uint32_t bytesWritten = image->write(data, sector);
566 
567  if (bytesWritten != SectorSize)
568  panic("Can't write to %s. Only %d of %d written. errno=%d\n",
569  name(), bytesWritten, SectorSize, errno);
570 }
571 
573 // Setup and handle commands
575 
576 void
577 IdeDisk::startDma(const uint32_t &prdTableBase)
578 {
579  if (dmaState != Dma_Start)
580  panic("Inconsistent DMA state, should be in Dma_Start!\n");
581 
583  panic("Inconsistent device state for DMA start!\n");
584 
585  // PRD base address is given by bits 31:2
586  curPrdAddr = pciToDma((Addr)(prdTableBase & ~ULL(0x3)));
587 
589 
590  // schedule dma transfer (doDmaTransfer)
592 }
593 
594 void
596 {
597  if (dmaState == Dma_Idle)
598  panic("Inconsistent DMA state, should be Start or Transfer!");
599 
601  panic("Inconsistent device state, should be Transfer or Prepare!\n");
602 
604 }
605 
606 void
608 {
609  DevAction_t action = ACT_NONE;
610  uint32_t size = 0;
611  dmaRead = false;
612 
613  // Decode commands
614  switch (cmdReg.command) {
615  // Supported non-data commands
617  size = (uint32_t)image->size() - 1;
618  cmdReg.sec_num = (size & 0xff);
619  cmdReg.cyl_low = ((size & 0xff00) >> 8);
620  cmdReg.cyl_high = ((size & 0xff0000) >> 16);
621  cmdReg.head = ((size & 0xf000000) >> 24);
622 
624  action = ACT_CMD_COMPLETE;
625  break;
626 
627  case WDCC_RECAL:
628  case WDCC_IDP:
629  case WDCC_STANDBY_IMMED:
630  case WDCC_FLUSHCACHE:
631  case WDSF_VERIFY:
632  case WDSF_SEEK:
633  case SET_FEATURES:
634  case WDCC_SETMULTI:
635  case WDCC_IDLE:
637  action = ACT_CMD_COMPLETE;
638  break;
639 
640  // Supported PIO data-in commands
641  case WDCC_IDENTIFY:
643  cmdBytes = cmdBytesLeft = sizeof(struct ataparams);
645  action = ACT_DATA_READY;
646  break;
647 
648  case WDCC_READMULTI:
649  case WDCC_READ:
650  if (!(cmdReg.drive & DRIVE_LBA_BIT))
651  panic("Attempt to perform CHS access, only supports LBA\n");
652 
653  if (cmdReg.sec_count == 0)
654  cmdBytes = cmdBytesLeft = (256 * SectorSize);
655  else
657 
658  curSector = getLBABase();
659 
662  action = ACT_DATA_READY;
663  break;
664 
665  // Supported PIO data-out commands
666  case WDCC_WRITEMULTI:
667  case WDCC_WRITE:
668  if (!(cmdReg.drive & DRIVE_LBA_BIT))
669  panic("Attempt to perform CHS access, only supports LBA\n");
670 
671  if (cmdReg.sec_count == 0)
672  cmdBytes = cmdBytesLeft = (256 * SectorSize);
673  else
675  DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d\n", cmdBytesLeft);
676  curSector = getLBABase();
677 
679  action = ACT_DATA_READY;
680  break;
681 
682  // Supported DMA commands
683  case WDCC_WRITEDMA:
684  dmaRead = true; // a write to the disk is a DMA read from memory
686  case WDCC_READDMA:
687  if (!(cmdReg.drive & DRIVE_LBA_BIT))
688  panic("Attempt to perform CHS access, only supports LBA\n");
689 
690  if (cmdReg.sec_count == 0)
691  cmdBytes = cmdBytesLeft = (256 * SectorSize);
692  else
694  DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d in readdma\n", cmdBytesLeft);
695 
696  curSector = getLBABase();
697 
699  action = ACT_DMA_READY;
700  break;
701 
702  default:
703  panic("Unsupported ATA command: %#x\n", cmdReg.command);
704  }
705 
706  if (action != ACT_NONE) {
707  // set the BSY bit
709  // clear the DRQ bit
711  // clear the DF bit
712  status &= ~STATUS_DF_BIT;
713 
714  updateState(action);
715  }
716 }
717 
719 // Handle setting and clearing interrupts
721 
722 void
724 {
725  DPRINTF(IdeDisk, "Posting Interrupt\n");
726  if (intrPending)
727  panic("Attempt to post an interrupt with one pending\n");
728 
729  intrPending = true;
730 
731  // talk to controller to set interrupt
732  if (ctrl) {
733  ctrl->intrPost();
734  }
735 }
736 
737 void
739 {
740  DPRINTF(IdeDisk, "Clearing Interrupt\n");
741  if (!intrPending)
742  panic("Attempt to clear a non-pending interrupt\n");
743 
744  intrPending = false;
745 
746  // talk to controller to clear interrupt
747  if (ctrl)
748  ctrl->intrClear();
749 }
750 
752 // Manage the device internal state machine
754 
755 void
757 {
758  switch (devState) {
759  case Device_Srst:
760  if (action == ACT_SRST_SET) {
761  // set the BSY bit
763  } else if (action == ACT_SRST_CLEAR) {
764  // clear the BSY bit
766 
767  // reset the device state
768  reset(devID);
769  }
770  break;
771 
772  case Device_Idle_S:
773  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
775  } else if (action == ACT_CMD_WRITE) {
776  startCommand();
777  }
778 
779  break;
780 
781  case Device_Idle_SI:
782  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
784  intrClear();
785  } else if (action == ACT_STAT_READ || isIENSet()) {
787  intrClear();
788  } else if (action == ACT_CMD_WRITE) {
789  intrClear();
790  startCommand();
791  }
792 
793  break;
794 
795  case Device_Idle_NS:
796  if (action == ACT_SELECT_WRITE && isDEVSelect()) {
797  if (!isIENSet() && intrPending) {
799  intrPost();
800  }
801  if (isIENSet() || !intrPending) {
803  }
804  }
805  break;
806 
807  case Command_Execution:
808  if (action == ACT_CMD_COMPLETE) {
809  // clear the BSY bit
810  setComplete();
811 
812  if (!isIENSet()) {
814  intrPost();
815  } else {
817  }
818  }
819  break;
820 
821  case Prepare_Data_In:
822  if (action == ACT_CMD_ERROR) {
823  // clear the BSY bit
824  setComplete();
825 
826  if (!isIENSet()) {
828  intrPost();
829  } else {
831  }
832  } else if (action == ACT_DATA_READY) {
833  // clear the BSY bit
835  // set the DRQ bit
837 
838  // copy the data into the data buffer
839  if (cmdReg.command == WDCC_IDENTIFY ||
841  // Reset the drqBytes for this block
842  drqBytesLeft = sizeof(struct ataparams);
843 
844  memcpy((void *)dataBuffer, (void *)&driveID,
845  sizeof(struct ataparams));
846  } else {
847  // Reset the drqBytes for this block
849 
851  }
852 
853  // put the first two bytes into the data register
854  memcpy((void *)&cmdReg.data, (void *)dataBuffer,
855  sizeof(uint16_t));
856 
857  if (!isIENSet()) {
859  intrPost();
860  } else {
862  }
863  }
864  break;
865 
866  case Data_Ready_INTRQ_In:
867  if (action == ACT_STAT_READ) {
869  intrClear();
870  }
871  break;
872 
873  case Transfer_Data_In:
874  if (action == ACT_DATA_READ_BYTE || action == ACT_DATA_READ_SHORT) {
875  if (action == ACT_DATA_READ_BYTE) {
876  panic("DEBUG: READING DATA ONE BYTE AT A TIME!\n");
877  } else {
878  drqBytesLeft -= 2;
879  cmdBytesLeft -= 2;
880 
881  // copy next short into data registers
882  if (drqBytesLeft)
883  memcpy((void *)&cmdReg.data,
884  (void *)&dataBuffer[SectorSize - drqBytesLeft],
885  sizeof(uint16_t));
886  }
887 
888  if (drqBytesLeft == 0) {
889  if (cmdBytesLeft == 0) {
890  // Clear the BSY bit
891  setComplete();
893  } else {
895  // set the BSY_BIT
897  // clear the DRQ_BIT
899 
903  }
904  }
905  }
906  break;
907 
908  case Prepare_Data_Out:
909  if (action == ACT_CMD_ERROR || cmdBytesLeft == 0) {
910  // clear the BSY bit
911  setComplete();
912 
913  if (!isIENSet()) {
915  intrPost();
916  } else {
918  }
919  } else if (action == ACT_DATA_READY && cmdBytesLeft != 0) {
920  // clear the BSY bit
922  // set the DRQ bit
924 
925  // clear the data buffer to get it ready for writes
926  memset(dataBuffer, 0, MAX_DMA_SIZE);
927 
928  // reset the drqBytes for this block
930 
931  if (cmdBytesLeft == cmdBytes || isIENSet()) {
933  } else {
935  intrPost();
936  }
937  }
938  break;
939 
941  if (action == ACT_STAT_READ) {
943  intrClear();
944  }
945  break;
946 
947  case Transfer_Data_Out:
948  if (action == ACT_DATA_WRITE_BYTE ||
949  action == ACT_DATA_WRITE_SHORT) {
950 
951  if (action == ACT_DATA_READ_BYTE) {
952  panic("DEBUG: WRITING DATA ONE BYTE AT A TIME!\n");
953  } else {
954  // copy the latest short into the data buffer
955  memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
956  (void *)&cmdReg.data,
957  sizeof(uint16_t));
958 
959  drqBytesLeft -= 2;
960  cmdBytesLeft -= 2;
961  }
962 
963  if (drqBytesLeft == 0) {
964  // copy the block to the disk
966 
967  // set the BSY bit
969  // set the seek bit
971  // clear the DRQ bit
973 
975 
979  }
980  }
981  break;
982 
983  case Prepare_Data_Dma:
984  if (action == ACT_CMD_ERROR) {
985  // clear the BSY bit
986  setComplete();
987 
988  if (!isIENSet()) {
990  intrPost();
991  } else {
993  }
994  } else if (action == ACT_DMA_READY) {
995  // clear the BSY bit
997  // set the DRQ bit
999 
1001 
1002  if (dmaState != Dma_Idle)
1003  panic("Inconsistent DMA state, should be Dma_Idle\n");
1004 
1005  dmaState = Dma_Start;
1006  // wait for the write to the DMA start bit
1007  }
1008  break;
1009 
1010  case Transfer_Data_Dma:
1011  if (action == ACT_CMD_ERROR) {
1012  dmaAborted = true;
1014  } else if (action == ACT_DMA_DONE) {
1015  // clear the BSY bit
1016  setComplete();
1017  // set the seek bit
1019  // clear the controller state for DMA transfer
1020  ctrl->setDmaComplete(this);
1021 
1022  if (!isIENSet()) {
1024  intrPost();
1025  } else {
1027  }
1028  }
1029  break;
1030 
1031  case Device_Dma_Abort:
1032  if (action == ACT_CMD_ERROR) {
1033  setComplete();
1035  ctrl->setDmaComplete(this);
1036  dmaAborted = false;
1037  dmaState = Dma_Idle;
1038 
1039  if (!isIENSet()) {
1041  intrPost();
1042  } else {
1044  }
1045  } else {
1046  DPRINTF(IdeDisk, "Disk still busy aborting previous DMA command\n");
1047  }
1048  break;
1049 
1050  default:
1051  panic("Unknown IDE device state: %#x\n", devState);
1052  }
1053 }
1054 
1055 void
1057 {
1058  // Check all outstanding events to see if they are scheduled
1059  // these are all mutually exclusive
1060  Tick reschedule = 0;
1061  Events_t event = None;
1062 
1063  int eventCount = 0;
1064 
1065  if (dmaTransferEvent.scheduled()) {
1067  event = Transfer;
1068  eventCount++;
1069  }
1070  if (dmaReadWaitEvent.scheduled()) {
1072  event = ReadWait;
1073  eventCount++;
1074  }
1075  if (dmaWriteWaitEvent.scheduled()) {
1077  event = WriteWait;
1078  eventCount++;
1079  }
1080  if (dmaPrdReadEvent.scheduled()) {
1082  event = PrdRead;
1083  eventCount++;
1084  }
1085  if (dmaReadEvent.scheduled()) {
1087  event = DmaRead;
1088  eventCount++;
1089  }
1090  if (dmaWriteEvent.scheduled()) {
1092  event = DmaWrite;
1093  eventCount++;
1094  }
1095 
1096  assert(eventCount <= 1);
1097 
1100 
1101  // Serialize device registers
1112 
1113  // Serialize the PRD related information
1118 
1120  // Serialize current transfer related information
1131 }
1132 
1133 void
1135 {
1136  // Reschedule events that were outstanding
1137  // these are all mutually exclusive
1138  Tick reschedule = 0;
1139  Events_t event = None;
1140 
1143 
1144  switch (event) {
1145  case None : break;
1146  case Transfer : schedule(dmaTransferEvent, reschedule); break;
1147  case ReadWait : schedule(dmaReadWaitEvent, reschedule); break;
1149  case PrdRead : schedule(dmaPrdReadEvent, reschedule); break;
1150  case DmaRead : schedule(dmaReadEvent, reschedule); break;
1151  case DmaWrite : schedule(dmaWriteEvent, reschedule); break;
1152  }
1153 
1154  // Unserialize device registers
1165 
1166  // Unserialize the PRD related information
1171 
1173  // Unserialize current transfer related information
1184 }
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:1056
Prepare_Data_In
@ Prepare_Data_In
Definition: ide_disk.hh:179
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:462
ACT_DMA_READY
@ ACT_DMA_READY
Definition: ide_disk.hh:160
WDSF_SEEK
#define WDSF_SEEK
Definition: ide_wdcreg.h:157
ChunkGenerator::complete
Addr complete() const
Number of bytes we have already chunked up.
Definition: chunk_generator.hh:129
IdeDisk::getLBABase
uint32_t getLBABase()
Definition: ide_disk.hh:357
UNIT_BYTE
#define UNIT_BYTE
Definition: units.hh:43
WDCC_IDP
#define WDCC_IDP
Definition: ide_wdcreg.h:87
IdeDisk::curPrdAddr
uint32_t curPrdAddr
PRD table base address.
Definition: ide_disk.hh:245
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:47
WDCC_FLUSHCACHE
#define WDCC_FLUSHCACHE
Definition: ide_wdcreg.h:100
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:591
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:136
EventManager::reschedule
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:1034
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:379
WDCC_READ
#define WDCC_READ
Definition: ide_wdcreg.h:80
IdeDisk::dmaWriteDone
void dmaWriteDone()
Definition: ide_disk.cc:534
IdeDisk::IdeDisk
IdeDisk(const Params &p)
Definition: ide_disk.cc:61
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:59
IdeDisk::updateState
void updateState(DevAction_t action)
Definition: ide_disk.cc:756
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:447
PciDevice::intrClear
void intrClear()
Definition: device.hh:362
IdeDisk::chunkBytes
Addr chunkBytes
Size of chunks to DMA.
Definition: ide_disk.hh:243
ACT_STAT_READ
@ ACT_STAT_READ
Definition: ide_disk.hh:154
IdeDisk::doDmaTransfer
void doDmaTransfer()
Definition: ide_disk.cc:334
DRIVE_LBA_BIT
#define DRIVE_LBA_BIT
Definition: ide_disk.hh:119
IdeDisk::startDma
void startDma(const uint32_t &prdTableBase)
Definition: ide_disk.cc:577
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:595
Stats::reset
void reset()
Definition: statistics.cc:299
IdeDisk::IdeDiskStats::IdeDiskStats
IdeDiskStats(Stats::Group *parent)
Definition: ide_disk.cc:391
Event::when
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:505
IdeDisk::IdeDiskStats::dmaReadTxs
Stats::Scalar dmaReadTxs
Definition: ide_disk.hh:261
DiskImage::size
virtual std::streampos size() const =0
CommandReg::command
uint8_t command
Definition: ide_disk.hh:135
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
IdeDisk::IdeDiskStats::dmaWriteTxs
Stats::Scalar dmaWriteTxs
Definition: ide_disk.hh:264
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:563
CommandReg::drive
uint8_t drive
Definition: ide_disk.hh:132
IdeDisk::dmaPrdReadDone
void dmaPrdReadDone()
Definition: ide_disk.cc:355
SERIALIZE_ENUM
#define SERIALIZE_ENUM(scalar)
Definition: serialize.hh:607
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:116
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:225
IdeController::isDiskSelected
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
Definition: ide_ctrl.cc:129
IdeDisk::readControl
void readControl(const Addr offset, int size, uint8_t *data)
Definition: ide_disk.cc:252
cp
Definition: cprintf.cc:37
IdeDisk::dmaWriteEvent
EventFunctionWrapper dmaWriteEvent
Definition: ide_disk.hh:333
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1016
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:211
WDC_VER_ATA7
#define WDC_VER_ATA7
Definition: ide_atareg.h:182
None
@ None
Definition: ide_disk.hh:139
STATUS_BSY_BIT
#define STATUS_BSY_BIT
Definition: ide_disk.hh:114
IdeDisk::IdeDiskStats::dmaWriteBytes
Stats::Scalar dmaWriteBytes
Definition: ide_disk.hh:263
IdeDisk::isIENSet
bool isIENSet()
Definition: ide_disk.hh:344
IdeDisk::doDmaDataWrite
void doDmaDataWrite()
Definition: ide_disk.cc:470
IdeDisk::intrClear
void intrClear()
Definition: ide_disk.cc:738
STATUS_OFFSET
#define STATUS_OFFSET
Definition: ide_disk.hh:105
IdeDisk::pciToDma
Addr pciToDma(Addr pciAddr)
Definition: ide_disk.cc:193
IdeDisk::writeControl
void writeControl(const Addr offset, int size, const uint8_t *data)
Definition: ide_disk.cc:310
sim_object.hh
IdeController::setDmaComplete
void setDmaComplete(IdeDisk *disk)
Definition: ide_ctrl.cc:142
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
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:607
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
PrdTableEntry::entry
PrdEntry_t entry
Definition: ide_disk.hh:77
ide_disk.hh
ataparams
Definition: ide_atareg.h:67
IdeDisk::ideDiskStats
IdeDisk::IdeDiskStats ideDiskStats
IdeDisk::IdeDiskStats::dmaReadBytes
Stats::Scalar dmaReadBytes
Definition: ide_disk.hh:260
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:59
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:143
ChunkGenerator::next
bool next()
Advance generator to next chunk.
Definition: chunk_generator.hh:182
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:626
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
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
WDCC_WRITEDMA
#define WDCC_WRITEDMA
Definition: ide_wdcreg.h:94
IdeDisk::IdeDiskStats::dmaWriteFullPages
Stats::Scalar dmaWriteFullPages
Definition: ide_disk.hh:262
core.hh
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
IdeDisk::setComplete
void setComplete()
Definition: ide_disk.hh:347
IdeDisk::doDmaRead
void doDmaRead()
Definition: ide_disk.cc:408
DMA_BACKOFF_PERIOD
#define DMA_BACKOFF_PERIOD
Definition: ide_disk.hh:59
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:138
name
const std::string & name()
Definition: trace.cc:48
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:584
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:182
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:634
Dma_Start
@ Dma_Start
Definition: ide_disk.hh:196
ReadWait
@ ReadWait
Definition: ide_disk.hh:141
Stats::Group
Statistics container.
Definition: group.hh:87
PrdRead
@ PrdRead
Definition: ide_disk.hh:143
IdeDisk::readCommand
void readCommand(const Addr offset, int size, uint8_t *data)
Definition: ide_disk.cc:206
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
ChunkGenerator::size
Addr size() const
Return size in bytes of current chunk.
Definition: chunk_generator.hh:122
ATAPI_IDENTIFY_DEVICE
#define ATAPI_IDENTIFY_DEVICE
Definition: ide_wdcreg.h:171
IdeDisk::IdeDiskStats::dmaReadFullPages
Stats::Scalar dmaReadFullPages
Definition: ide_disk.hh:259
IdeDisk::Params
IdeDiskParams Params
Definition: ide_disk.hh:268
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:187
DiskImage::read
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
Data_Ready_INTRQ_In
@ Data_Ready_INTRQ_In
Definition: ide_disk.hh:180
ACT_DMA_DONE
@ ACT_DMA_DONE
Definition: ide_disk.hh:161
IdeController::intrPost
void intrPost()
Definition: ide_ctrl.cc:135
IdeDisk::intrPost
void intrPost()
Definition: ide_disk.cc:723
Stats
Definition: statistics.cc:53
IdeDisk::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: ide_disk.cc:1134
UNSERIALIZE_ENUM
#define UNSERIALIZE_ENUM(scalar)
Definition: serialize.hh:614
ChunkGenerator
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
Definition: chunk_generator.hh:56
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
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:68
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
DmaDevice::dmaPending
bool dmaPending() const
Definition: dma_device.hh:238
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:262
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:46
MAX_DMA_SIZE
#define MAX_DMA_SIZE
Definition: ide_disk.hh:61
IdeDisk::doDmaWrite
void doDmaWrite()
Definition: ide_disk.cc:493
PciDevice::pciToDma
Addr pciToDma(Addr pci_addr) const
Definition: device.hh:356
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:553
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:141

Generated on Tue Mar 23 2021 19:41:26 for gem5 by doxygen 1.8.17