gem5  v22.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/bitfield.hh"
53 #include "base/chunk_generator.hh"
54 #include "base/compiler.hh"
55 #include "base/cprintf.hh" // csprintf
56 #include "base/trace.hh"
57 #include "debug/IdeDisk.hh"
59 #include "dev/storage/ide_ctrl.hh"
60 #include "sim/cur_tick.hh"
61 #include "sim/sim_object.hh"
62 
63 namespace gem5
64 {
65 
67  : SimObject(p), image(p.image), diskDelay(p.delay), ideDiskStats(this),
68  dmaTransferEvent([this]{ doDmaTransfer(); }, name()),
69  dmaReadWaitEvent([this]{ doDmaRead(); }, name()),
70  dmaWriteWaitEvent([this]{ doDmaWrite(); }, name()),
71  dmaPrdReadEvent([this]{ dmaPrdReadDone(); }, name()),
72  dmaReadEvent([this]{ dmaReadDone(); }, name()),
73  dmaWriteEvent([this]{ dmaWriteDone(); }, name())
74 {
75  // Reset the device state
76  reset(p.driveID);
77 
78  // fill out the drive ID structure
79  memset(&driveID, 0, sizeof(struct ataparams));
80 
81  // Calculate LBA and C/H/S values
82  uint16_t cylinders;
83  uint8_t heads;
84  uint8_t sectors;
85 
86  uint32_t lba_size = image->size();
87  if (lba_size >= 16383*16*63) {
88  cylinders = 16383;
89  heads = 16;
90  sectors = 63;
91  } else {
92  if (lba_size >= 63)
93  sectors = 63;
94  else if (lba_size == 0)
95  panic("Bad IDE image size: 0\n");
96  else
97  sectors = lba_size;
98 
99  if ((lba_size / sectors) >= 16)
100  heads = 16;
101  else
102  heads = (lba_size / sectors);
103 
104  cylinders = lba_size / (heads * sectors);
105  }
106 
107  // Setup the model name
108  strncpy((char *)driveID.atap_model, "5MI EDD si k",
109  sizeof(driveID.atap_model));
110  // Set the maximum multisector transfer size
111  driveID.atap_multi = MAX_MULTSECT;
112  // IORDY supported, IORDY disabled, LBA enabled, DMA enabled
113  driveID.atap_capabilities1 = 0x7;
114  // UDMA support, EIDE support
115  driveID.atap_extensions = 0x6;
116  // Setup default C/H/S settings
117  driveID.atap_cylinders = cylinders;
118  driveID.atap_sectors = sectors;
119  driveID.atap_heads = heads;
120  // Setup the current multisector transfer size
121  driveID.atap_curmulti = MAX_MULTSECT;
122  driveID.atap_curmulti_valid = 0x1;
123  // Number of sectors on disk
124  driveID.atap_capacity = lba_size;
125  // Multiword DMA mode 2 and below supported
126  driveID.atap_dmamode_supp = 0x4;
127  // Set PIO mode 4 and 3 supported
128  driveID.atap_piomode_supp = 0x3;
129  // Set DMA mode 4 and below supported
130  driveID.atap_udmamode_supp = 0x1f;
131  // Statically set hardware config word
132  driveID.atap_hwreset_res = 0x4001;
133 
134  //arbitrary for now...
135  driveID.atap_ata_major = WDC_VER_ATA7;
136 }
137 
139 {
140  // destroy the data buffer
141  delete [] dataBuffer;
142 }
143 
144 void
146 {
147  // initialize the data buffer and shadow registers
148  dataBuffer = new uint8_t[MAX_DMA_SIZE];
149 
150  memset(dataBuffer, 0, MAX_DMA_SIZE);
151  memset(&cmdReg, 0, sizeof(CommandReg_t));
152  memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
153 
154  curPrdAddr = 0;
155  curSector = 0;
156  cmdBytes = 0;
157  cmdBytesLeft = 0;
158  drqBytesLeft = 0;
159  dmaRead = false;
160  pendingInterrupt = false;
161  dmaAborted = false;
162 
163  // set the device state to idle
164  dmaState = Dma_Idle;
165 
166  if (id == DEV0) {
168  devID = DEV0;
169  } else if (id == DEV1) {
171  devID = DEV1;
172  } else {
173  panic("Invalid device ID: %#x\n", id);
174  }
175 
176  // set the device ready bit
178 
179  /* The error register must be set to 0x1 on start-up to
180  indicate that no diagnostic error was detected */
181  cmdReg.error = 0x1;
182 }
183 
185 // Utility functions
187 
188 bool
190 {
191  return channel->selected() == this;
192 }
193 
194 Addr
196 {
197  panic_if(!ctrl, "Access to unset controller!");
198  return ctrl->pciToDma(pciAddr);
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  }
346 
349  return;
350  } else {
352  (uint8_t*)&curPrd.entry);
353  }
354 }
355 
356 void
358 {
359  if (dmaAborted) {
360  DPRINTF(IdeDisk, "DMA Aborted while reading PRD entry\n");
362  return;
363  }
364 
366  "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
369  curPrd.getEOT(), curSector);
370 
371  // the prd pointer has already been translated, so just do an increment
372  curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
373 
374  if (dmaRead)
375  doDmaDataRead();
376  else
377  doDmaDataWrite();
378 }
379 
380 void
382 {
384  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
385 
386  DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
387  diskDelay, totalDiskDelay);
388 
389  schedule(dmaReadWaitEvent, curTick() + totalDiskDelay);
390 }
391 
392 IdeDisk::
394  : statistics::Group(parent, "IdeDisk"),
395  ADD_STAT(dmaReadFullPages, statistics::units::Count::get(),
396  "Number of full page size DMA reads (not PRD)."),
397  ADD_STAT(dmaReadBytes, statistics::units::Byte::get(),
398  "Number of bytes transfered via DMA reads (not PRD)."),
399  ADD_STAT(dmaReadTxs, statistics::units::Count::get(),
400  "Number of DMA read transactions (not PRD)."),
401  ADD_STAT(dmaWriteFullPages, statistics::units::Count::get(),
402  "Number of full page size DMA writes."),
403  ADD_STAT(dmaWriteBytes, statistics::units::Byte::get(),
404  "Number of bytes transfered via DMA writes."),
405  ADD_STAT(dmaWriteTxs, statistics::units::Count::get(),
406  "Number of DMA write transactions.")
407 {
408 }
409 
410 void
412 {
413  if (dmaAborted) {
414  DPRINTF(IdeDisk, "DMA Aborted in middle of Dma Read\n");
415  if (dmaReadCG)
416  delete dmaReadCG;
417  dmaReadCG = NULL;
419  return;
420  }
421 
422  if (!dmaReadCG) {
423  // clear out the data buffer
424  memset(dataBuffer, 0, MAX_DMA_SIZE);
427 
428  }
431  return;
432  } else if (!dmaReadCG->done()) {
433  assert(dmaReadCG->complete() < MAX_DMA_SIZE);
438  if (dmaReadCG->size() == chunkBytes)
440  dmaReadCG->next();
441  } else {
442  assert(dmaReadCG->done());
443  delete dmaReadCG;
444  dmaReadCG = NULL;
445  dmaReadDone();
446  }
447 }
448 
449 void
451 {
452  uint32_t bytesWritten = 0;
453 
454  // write the data to the disk image
455  for (bytesWritten = 0; bytesWritten < curPrd.getByteCount();
456  bytesWritten += SectorSize) {
457 
459  writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
460  }
461 
462  // check for the EOT
463  if (curPrd.getEOT()) {
464  assert(cmdBytesLeft == 0);
465  dmaState = Dma_Idle;
467  } else {
468  doDmaTransfer();
469  }
470 }
471 
472 void
474 {
476  Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
477  uint32_t bytesRead = 0;
478 
479  DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
480  diskDelay, totalDiskDelay);
481 
482  memset(dataBuffer, 0, MAX_DMA_SIZE);
483  assert(cmdBytesLeft <= MAX_DMA_SIZE);
484  while (bytesRead < curPrd.getByteCount()) {
485  readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
486  bytesRead += SectorSize;
488  }
489  DPRINTF(IdeDisk, "doDmaWrite, bytesRead: %d cmdBytesLeft: %d\n",
490  bytesRead, cmdBytesLeft);
491 
492  schedule(dmaWriteWaitEvent, curTick() + totalDiskDelay);
493 }
494 
495 void
497 {
498  if (dmaAborted) {
499  DPRINTF(IdeDisk, "DMA Aborted while doing DMA Write\n");
500  if (dmaWriteCG)
501  delete dmaWriteCG;
502  dmaWriteCG = NULL;
504  return;
505  }
506  if (!dmaWriteCG) {
507  // clear out the data buffer
510  }
513  DPRINTF(IdeDisk, "doDmaWrite: rescheduling\n");
514  return;
515  } else if (!dmaWriteCG->done()) {
516  assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
519  DPRINTF(IdeDisk, "doDmaWrite: not done curPrd byte count %d, eot %#x\n",
523  if (dmaWriteCG->size() == chunkBytes)
525  dmaWriteCG->next();
526  } else {
527  DPRINTF(IdeDisk, "doDmaWrite: done curPrd byte count %d, eot %#x\n",
529  assert(dmaWriteCG->done());
530  delete dmaWriteCG;
531  dmaWriteCG = NULL;
532  dmaWriteDone();
533  }
534 }
535 
536 void
538 {
540  "doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
542  // check for the EOT
543  if (curPrd.getEOT()) {
544  assert(cmdBytesLeft == 0);
545  dmaState = Dma_Idle;
547  } else {
548  doDmaTransfer();
549  }
550 }
551 
553 // Disk utility routines
555 
556 void
557 IdeDisk::readDisk(uint32_t sector, uint8_t *data)
558 {
559  uint32_t bytesRead = image->read(data, sector);
560 
561  panic_if(bytesRead != SectorSize,
562  "Can't read from %s. Only %d of %d read. errno=%d",
563  name(), bytesRead, SectorSize, errno);
564 }
565 
566 void
567 IdeDisk::writeDisk(uint32_t sector, uint8_t *data)
568 {
569  uint32_t bytesWritten = image->write(data, sector);
570 
571  panic_if(bytesWritten != SectorSize,
572  "Can't write to %s. Only %d of %d written. errno=%d",
573  name(), bytesWritten, SectorSize, errno);
574 }
575 
577 // Setup and handle commands
579 
580 void
581 IdeDisk::startDma(const uint32_t &prdTableBase)
582 {
584  "Inconsistent DMA state, should be in Dma_Start!");
585 
587  "Inconsistent device state for DMA start!");
588 
589  // PRD base address is given by bits 31:2
590  curPrdAddr = pciToDma((Addr)(prdTableBase & ~0x3ULL));
591 
593 
594  // schedule dma transfer (doDmaTransfer)
596 }
597 
598 void
600 {
602  "Inconsistent DMA state, should be Start or Transfer!");
603 
605  "Inconsistent device state, should be Transfer or Prepare!");
606 
608 }
609 
610 void
612 {
613  DevAction_t action = ACT_NONE;
614  uint32_t size = 0;
615  dmaRead = false;
616 
617  // Clear any existing errors.
618  replaceBits(status, 0, 0);
619  replaceBits(cmdReg.error, 2, 0);
620 
621  // Decode commands
622  switch (cmdReg.command) {
623  // Supported non-data commands
625  size = (uint32_t)image->size() - 1;
626  cmdReg.sec_num = (size & 0xff);
627  cmdReg.cyl_low = ((size & 0xff00) >> 8);
628  cmdReg.cyl_high = ((size & 0xff0000) >> 16);
629  cmdReg.head = ((size & 0xf000000) >> 24);
630 
632  action = ACT_CMD_COMPLETE;
633  break;
634 
635  case WDCC_RECAL:
636  case WDCC_IDP:
637  case WDCC_STANDBY_IMMED:
638  case WDCC_FLUSHCACHE:
639  case WDSF_VERIFY:
640  case WDSF_SEEK:
641  case SET_FEATURES:
642  case WDCC_SETMULTI:
643  case WDCC_IDLE:
645  action = ACT_CMD_COMPLETE;
646  break;
647 
648  // Supported PIO data-in commands
649  case WDCC_IDENTIFY:
650  cmdBytes = cmdBytesLeft = sizeof(struct ataparams);
652  action = ACT_DATA_READY;
653  break;
654 
656  // We're not an ATAPI device, so this command isn't implemented.
658  action = ACT_CMD_ERROR;
659  replaceBits(cmdReg.error, 2, 1);
660  replaceBits(status, 0, 1);
661  break;
662 
663  case WDCC_READMULTI:
664  case WDCC_READ:
666  "Attempt to perform CHS access, only supports LBA");
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:
684  "Attempt to perform CHS access, only supports LBA");
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
700  [[fallthrough]];
701  case WDCC_READDMA:
703  "Attempt to perform CHS access, only supports LBA");
704 
705  if (cmdReg.sec_count == 0)
706  cmdBytes = cmdBytesLeft = (256 * SectorSize);
707  else
709  DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d in readdma\n",
710  cmdBytesLeft);
711 
712  curSector = getLBABase();
713 
715  action = ACT_DMA_READY;
716  break;
717 
718  default:
719  panic("Unsupported ATA command: %#x\n", cmdReg.command);
720  }
721 
722  if (action != ACT_NONE) {
723  // set the BSY bit
725  // clear the DRQ bit
727  // clear the DF bit
728  status &= ~STATUS_DF_BIT;
729 
730  updateState(action);
731  }
732 }
733 
735 // Handle setting and clearing interrupts
737 
738 void
740 {
741  DPRINTF(IdeDisk, "Posting Interrupt\n");
743  "Attempt to post an interrupt with one pending");
744 
745  pendingInterrupt = true;
746 
747  assert(channel);
749 }
750 
751 void
753 {
754  DPRINTF(IdeDisk, "Clearing Interrupt\n");
755  panic_if(!pendingInterrupt, "Attempt to clear a non-pending interrupt");
756 
757  pendingInterrupt = false;
758 
759  assert(channel);
761 }
762 
764 // Manage the device internal state machine
766 
767 void
769 {
770  switch (devState) {
771  case Device_Srst:
772  if (action == ACT_SRST_SET) {
773  // set the BSY bit
775  } else if (action == ACT_SRST_CLEAR) {
776  // clear the BSY bit
778 
779  // reset the device state
780  reset(devID);
781  }
782  break;
783 
784  case Device_Idle_S:
785  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
787  } else if (action == ACT_CMD_WRITE) {
788  startCommand();
789  }
790 
791  break;
792 
793  case Device_Idle_SI:
794  if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
796  clearInterrupt();
797  } else if (action == ACT_STAT_READ || isIENSet()) {
799  clearInterrupt();
800  } else if (action == ACT_CMD_WRITE) {
801  clearInterrupt();
802  startCommand();
803  }
804 
805  break;
806 
807  case Device_Idle_NS:
808  if (action == ACT_SELECT_WRITE && isDEVSelect()) {
809  if (!isIENSet() && pendingInterrupt) {
811  postInterrupt();
812  }
813  if (isIENSet() || !pendingInterrupt) {
815  }
816  }
817  break;
818 
819  case Command_Execution:
820  if (action == ACT_CMD_ERROR || action == ACT_CMD_COMPLETE) {
821  // clear the BSY bit
822  setComplete();
823 
824  if (!isIENSet()) {
826  postInterrupt();
827  } else {
829  }
830  }
831  break;
832 
833  case Prepare_Data_In:
834  if (action == ACT_CMD_ERROR) {
835  // clear the BSY bit
836  setComplete();
837 
838  if (!isIENSet()) {
840  postInterrupt();
841  } else {
843  }
844  } else if (action == ACT_DATA_READY) {
845  // clear the BSY bit
847  // set the DRQ bit
849 
850  // copy the data into the data buffer
851  if (cmdReg.command == WDCC_IDENTIFY ||
853  // Reset the drqBytes for this block
854  drqBytesLeft = sizeof(struct ataparams);
855 
856  memcpy((void *)dataBuffer, (void *)&driveID,
857  sizeof(struct ataparams));
858  } else {
859  // Reset the drqBytes for this block
861 
863  }
864 
865  // put the first two bytes into the data register
866  memcpy((void *)&cmdReg.data, (void *)dataBuffer,
867  sizeof(uint16_t));
868 
869  if (!isIENSet()) {
871  postInterrupt();
872  } else {
874  }
875  }
876  break;
877 
878  case Data_Ready_INTRQ_In:
879  if (action == ACT_STAT_READ) {
881  clearInterrupt();
882  }
883  break;
884 
885  case Transfer_Data_In:
886  if (action == ACT_DATA_READ_BYTE || action == ACT_DATA_READ_SHORT) {
887  if (action == ACT_DATA_READ_BYTE) {
888  panic("DEBUG: READING DATA ONE BYTE AT A TIME!\n");
889  } else {
890  drqBytesLeft -= 2;
891  cmdBytesLeft -= 2;
892 
893  // copy next short into data registers
894  if (drqBytesLeft)
895  memcpy((void *)&cmdReg.data,
896  (void *)&dataBuffer[SectorSize - drqBytesLeft],
897  sizeof(uint16_t));
898  }
899 
900  if (drqBytesLeft == 0) {
901  if (cmdBytesLeft == 0) {
902  // Clear the BSY bit
903  setComplete();
905  } else {
907  // set the BSY_BIT
909  // clear the DRQ_BIT
911 
915  }
916  }
917  }
918  break;
919 
920  case Prepare_Data_Out:
921  if (action == ACT_CMD_ERROR || cmdBytesLeft == 0) {
922  // clear the BSY bit
923  setComplete();
924 
925  if (!isIENSet()) {
927  postInterrupt();
928  } else {
930  }
931  } else if (action == ACT_DATA_READY && cmdBytesLeft != 0) {
932  // clear the BSY bit
934  // set the DRQ bit
936 
937  // clear the data buffer to get it ready for writes
938  memset(dataBuffer, 0, MAX_DMA_SIZE);
939 
940  // reset the drqBytes for this block
942 
943  if (cmdBytesLeft == cmdBytes || isIENSet()) {
945  } else {
947  postInterrupt();
948  }
949  }
950  break;
951 
953  if (action == ACT_STAT_READ) {
955  clearInterrupt();
956  }
957  break;
958 
959  case Transfer_Data_Out:
960  if (action == ACT_DATA_WRITE_BYTE ||
961  action == ACT_DATA_WRITE_SHORT) {
962 
963  if (action == ACT_DATA_READ_BYTE) {
964  panic("DEBUG: WRITING DATA ONE BYTE AT A TIME!\n");
965  } else {
966  // copy the latest short into the data buffer
967  memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
968  (void *)&cmdReg.data,
969  sizeof(uint16_t));
970 
971  drqBytesLeft -= 2;
972  cmdBytesLeft -= 2;
973  }
974 
975  if (drqBytesLeft == 0) {
976  // copy the block to the disk
978 
979  // set the BSY bit
981  // set the seek bit
983  // clear the DRQ bit
985 
987 
991  }
992  }
993  break;
994 
995  case Prepare_Data_Dma:
996  if (action == ACT_CMD_ERROR) {
997  // clear the BSY bit
998  setComplete();
999 
1000  if (!isIENSet()) {
1002  postInterrupt();
1003  } else {
1005  }
1006  } else if (action == ACT_DMA_READY) {
1007  // clear the BSY bit
1008  status &= ~STATUS_BSY_BIT;
1009  // set the DRQ bit
1011 
1013 
1014  if (dmaState != Dma_Idle)
1015  panic("Inconsistent DMA state, should be Dma_Idle\n");
1016 
1017  dmaState = Dma_Start;
1018  // wait for the write to the DMA start bit
1019  }
1020  break;
1021 
1022  case Transfer_Data_Dma:
1023  if (action == ACT_CMD_ERROR) {
1024  dmaAborted = true;
1026  } else if (action == ACT_DMA_DONE) {
1027  // clear the BSY bit
1028  setComplete();
1029  // set the seek bit
1031  // clear the controller state for DMA transfer
1033 
1034  if (!isIENSet()) {
1036  postInterrupt();
1037  } else {
1039  }
1040  }
1041  break;
1042 
1043  case Device_Dma_Abort:
1044  if (action == ACT_CMD_ERROR) {
1045  setComplete();
1048  dmaAborted = false;
1049  dmaState = Dma_Idle;
1050 
1051  if (!isIENSet()) {
1053  postInterrupt();
1054  } else {
1056  }
1057  } else {
1058  DPRINTF(IdeDisk, "Disk still busy aborting previous DMA command\n");
1059  }
1060  break;
1061 
1062  default:
1063  panic("Unknown IDE device state: %#x\n", devState);
1064  }
1065 }
1066 
1067 void
1069 {
1070  // Check all outstanding events to see if they are scheduled
1071  // these are all mutually exclusive
1072  Tick reschedule = 0;
1073  Events_t event = None;
1074 
1075  int eventCount = 0;
1076 
1077  if (dmaTransferEvent.scheduled()) {
1079  event = Transfer;
1080  eventCount++;
1081  }
1082  if (dmaReadWaitEvent.scheduled()) {
1084  event = ReadWait;
1085  eventCount++;
1086  }
1087  if (dmaWriteWaitEvent.scheduled()) {
1089  event = WriteWait;
1090  eventCount++;
1091  }
1092  if (dmaPrdReadEvent.scheduled()) {
1094  event = PrdRead;
1095  eventCount++;
1096  }
1097  if (dmaReadEvent.scheduled()) {
1099  event = DmaRead;
1100  eventCount++;
1101  }
1102  if (dmaWriteEvent.scheduled()) {
1104  event = DmaWrite;
1105  eventCount++;
1106  }
1107 
1108  assert(eventCount <= 1);
1109 
1112 
1113  // Serialize device registers
1124 
1125  // Serialize the PRD related information
1130 
1132  // Serialize current transfer related information
1138  paramOut(cp, "intrPending", pendingInterrupt);
1143 }
1144 
1145 void
1147 {
1148  // Reschedule events that were outstanding
1149  // these are all mutually exclusive
1150  Tick reschedule = 0;
1151  Events_t event = None;
1152 
1155 
1156  switch (event) {
1157  case None : break;
1158  case Transfer : schedule(dmaTransferEvent, reschedule); break;
1159  case ReadWait : schedule(dmaReadWaitEvent, reschedule); break;
1161  case PrdRead : schedule(dmaPrdReadEvent, reschedule); break;
1162  case DmaRead : schedule(dmaReadEvent, reschedule); break;
1163  case DmaWrite : schedule(dmaWriteEvent, reschedule); break;
1164  }
1165 
1166  // Unserialize device registers
1177 
1178  // Unserialize the PRD related information
1183 
1185  // Unserialize current transfer related information
1191  paramIn(cp, "intrPending", pendingInterrupt);
1196 }
1197 
1198 } // namespace gem5
CONTROL_OFFSET
#define CONTROL_OFFSET
Definition: ide_disk.hh:113
gem5::IdeDisk::updateState
void updateState(DevAction_t action)
Definition: ide_disk.cc:768
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:195
gem5::IdeDisk::IdeDisk
IdeDisk(const Params &p)
Definition: ide_disk.cc:66
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:362
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:496
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:276
gem5::IdeDisk::curSector
uint32_t curSector
Current sector in access.
Definition: ide_disk.hh:242
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:260
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:277
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:145
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::Events_t
Events_t
Definition: ide_disk.hh:145
gem5::IdeDisk::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: ide_disk.cc:1146
SectorSize
#define SectorSize
Definition: disk_image.hh:44
gem5::IdeDisk::startCommand
void startCommand()
Definition: ide_disk.cc:611
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:275
WDCC_READ
#define WDCC_READ
Definition: ide_wdcreg.h:80
gem5::MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:300
gem5::replaceBits
constexpr void replaceBits(T &val, unsigned first, unsigned last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:197
gem5::IdeDisk::~IdeDisk
~IdeDisk()
Delete the data buffer.
Definition: ide_disk.cc:138
gem5::PrdEntry_t::byteCount
uint16_t byteCount
Definition: ide_disk.hh:75
cur_tick.hh
gem5::IdeDisk::doDmaTransfer
void doDmaTransfer()
Definition: ide_disk.cc:334
ALTSTAT_OFFSET
#define ALTSTAT_OFFSET
Definition: ide_disk.hh:114
gem5::IdeDisk::dmaWriteCG
ChunkGenerator * dmaWriteCG
Definition: ide_disk.hh:337
disk_image.hh
gem5::IdeDisk::driveID
struct ataparams driveID
Drive identification structure for this disk.
Definition: ide_disk.hh:232
gem5::IdeDisk::isDEVSelect
bool isDEVSelect()
Definition: ide_disk.cc:189
SET_FEATURES
#define SET_FEATURES
Definition: ide_wdcreg.h:102
gem5::IdeDisk::curPrdAddr
uint32_t curPrdAddr
PRD table base address.
Definition: ide_disk.hh:258
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:206
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::IdeDisk::chunkBytes
Addr chunkBytes
Size of chunks to DMA.
Definition: ide_disk.hh:256
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
gem5::IdeController::Channel::postInterrupt
void postInterrupt()
Definition: ide_ctrl.cc:124
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:581
gem5::DmaRead
@ DmaRead
Definition: ide_disk.hh:152
gem5::IdeDisk::IdeDiskStats::IdeDiskStats
IdeDiskStats(statistics::Group *parent)
Definition: ide_disk.cc:393
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:238
gem5::IdeController::Channel::selected
IdeDisk * selected() const
Definition: ide_ctrl.hh:134
gem5::PrdTableEntry::getBaseAddr
uint32_t getBaseAddr()
Definition: ide_disk.hh:84
gem5::IdeDisk::doDmaDataWrite
void doDmaDataWrite()
Definition: ide_disk.cc:473
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:381
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:254
gem5::IdeDisk::devState
DevState_t devState
Device state.
Definition: ide_disk.hh:250
gem5::Device_Idle_S
@ Device_Idle_S
Definition: ide_disk.hh:178
gem5::IdeDisk::pendingInterrupt
bool pendingInterrupt
Interrupt pending.
Definition: ide_disk.hh:264
gem5::IdeDisk::dmaReadCG
ChunkGenerator * dmaReadCG
Definition: ide_disk.hh:331
gem5::ACT_DATA_WRITE_BYTE
@ ACT_DATA_WRITE_BYTE
Definition: ide_disk.hh:167
gem5::IdeDisk::doDmaRead
void doDmaRead()
Definition: ide_disk.cc:411
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:248
STATUS_BSY_BIT
#define STATUS_BSY_BIT
Definition: ide_disk.hh:119
bitfield.hh
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
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:338
gem5::Prepare_Data_In
@ Prepare_Data_In
Definition: ide_disk.hh:189
gem5::IdeDisk::dmaReadDone
void dmaReadDone()
Definition: ide_disk.cc:450
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:252
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::IdeDisk::cmdBytes
uint32_t cmdBytes
Number of bytes in command data transfer.
Definition: ide_disk.hh:236
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::IdeDisk::clearInterrupt
void clearInterrupt()
Definition: ide_disk.cc:752
gem5::DmaWrite
@ DmaWrite
Definition: ide_disk.hh:153
gem5::IdeDisk::IdeDiskStats::dmaReadTxs
statistics::Scalar dmaReadTxs
Definition: ide_disk.hh:274
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:344
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:262
cprintf.hh
compiler.hh
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:610
gem5::IdeDisk::channel
IdeController::Channel * channel
The channel this disk is connected to.
Definition: ide_disk.hh:222
gem5::IdeDisk::writeCommand
void writeCommand(const Addr offset, int size, const uint8_t *data)
Definition: ide_disk.cc:262
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
gem5::IdeDisk::postInterrupt
void postInterrupt()
Definition: ide_disk.cc:739
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:281
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:373
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:224
CONTROL_IEN_BIT
#define CONTROL_IEN_BIT
Definition: ide_disk.hh:118
gem5::IdeDisk::isIENSet
bool isIENSet()
Definition: ide_disk.hh:358
gem5::IdeDisk::dmaPrdReadDone
void dmaPrdReadDone()
Definition: ide_disk.cc:357
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:246
FEATURES_OFFSET
#define FEATURES_OFFSET
Definition: ide_disk.hh:103
gem5::IdeDisk::dmaReadWaitEvent
EventFunctionWrapper dmaReadWaitEvent
Definition: ide_disk.hh:332
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
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
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:567
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:557
gem5::paramOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition: types.cc:40
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
ide_ctrl.hh
gem5::CommandReg_t
Definition: ide_disk.hh:129
gem5::IdeController::Channel::clearInterrupt
void clearInterrupt()
Definition: ide_ctrl.cc:132
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:341
gem5::paramIn
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition: types.cc:72
gem5::IdeDisk::drqBytesLeft
uint32_t drqBytesLeft
Number of bytes left in DRQ block.
Definition: ide_disk.hh:240
gem5::IdeDisk::dmaWriteDone
void dmaWriteDone()
Definition: ide_disk.cc:537
gem5::IdeDisk::IdeDiskStats::dmaReadFullPages
statistics::Scalar dmaReadFullPages
Definition: ide_disk.hh:272
STATUS_DRDY_BIT
#define STATUS_DRDY_BIT
Definition: ide_disk.hh:120
gem5::IdeDisk::readControl
void readControl(const Addr offset, int size, uint8_t *data)
Definition: ide_disk.cc:252
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
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::IdeController::Channel::setDmaComplete
void setDmaComplete()
Definition: ide_ctrl.cc:379
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:273
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:599
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: gpu_translation_state.hh:37
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:1068
gem5::IdeDisk::dmaTransferEvent
EventFunctionWrapper dmaTransferEvent
Definition: ide_disk.hh:326
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:234
STATUS_DRQ_BIT
#define STATUS_DRQ_BIT
Definition: ide_disk.hh:121
gem5::IdeDisk::dmaAborted
bool dmaAborted
DMA Aborted.
Definition: ide_disk.hh:266
gem5::IdeDisk::cmdReg
CommandReg_t cmdReg
Command block registers.
Definition: ide_disk.hh:244
gem5::IdeDisk::diskDelay
int diskDelay
The disk delay in microseconds.
Definition: ide_disk.hh:228
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:310
gem5::PrdRead
@ PrdRead
Definition: ide_disk.hh:151
gem5::IdeDisk::dmaWriteEvent
EventFunctionWrapper dmaWriteEvent
Definition: ide_disk.hh:347
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 Thu Jun 16 2022 10:41:53 for gem5 by doxygen 1.8.17