Fix doxgyen comments
[gem5.git] / dev / ide_disk.cc
index dcaaf64c84b45f7a78162f4aa74d1502b3a15bf4..dbb2792e135dabb57a779cac799281b9aff8fa6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,6 @@
 #include <deque>
 #include <string>
 
-#include "arch/alpha/pmap.h"
 #include "base/cprintf.hh" // csprintf
 #include "base/trace.hh"
 #include "dev/disk_image.hh"
 #include "mem/bus/pio_interface_impl.hh"
 #include "sim/builder.hh"
 #include "sim/sim_object.hh"
-#include "sim/universe.hh"
+#include "sim/root.hh"
+#include "targetarch/isa_traits.hh"
 
 using namespace std;
 
 IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
-                 int id, int delay)
-    : SimObject(name), ctrl(NULL), image(img), physmem(phys),
+                 int id, Tick delay)
+    : SimObject(name), ctrl(NULL), image(img), physmem(phys), diskDelay(delay),
       dmaTransferEvent(this), dmaReadWaitEvent(this),
       dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
       dmaReadEvent(this), dmaWriteEvent(this)
@@ -64,11 +64,8 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
     // Reset the device state
     reset(id);
 
-    // calculate disk delay in microseconds
-    diskDelay = (delay * ticksPerSecond / 100000);
-
     // fill out the drive ID structure
-    memset(&driveID, 0, sizeof(struct hd_driveid));
+    memset(&driveID, 0, sizeof(struct ataparams));
 
     // Calculate LBA and C/H/S values
     uint16_t cylinders;
@@ -95,30 +92,30 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
     }
 
     // Setup the model name
-    sprintf((char *)driveID.model, "5MI EDD si k");
+    sprintf((char *)driveID.atap_model, "5MI EDD si k");
     // Set the maximum multisector transfer size
-    driveID.max_multsect = MAX_MULTSECT;
+    driveID.atap_multi = MAX_MULTSECT;
     // IORDY supported, IORDY disabled, LBA enabled, DMA enabled
-    driveID.capability = 0x7;
+    driveID.atap_capabilities1 = 0x7;
     // UDMA support, EIDE support
-    driveID.field_valid = 0x6;
+    driveID.atap_extensions = 0x6;
     // Setup default C/H/S settings
-    driveID.cyls = cylinders;
-    driveID.sectors = sectors;
-    driveID.heads = heads;
+    driveID.atap_cylinders = cylinders;
+    driveID.atap_sectors = sectors;
+    driveID.atap_heads = heads;
     // Setup the current multisector transfer size
-    driveID.multsect = MAX_MULTSECT;
-    driveID.multsect_valid = 0x1;
+    driveID.atap_curmulti = MAX_MULTSECT;
+    driveID.atap_curmulti_valid = 0x1;
     // Number of sectors on disk
-    driveID.lba_capacity = lba_size;
+    driveID.atap_capacity = lba_size;
     // Multiword DMA mode 2 and below supported
-    driveID.dma_mword = 0x400;
+    driveID.atap_dmamode_supp = 0x400;
     // Set PIO mode 4 and 3 supported
-    driveID.eide_pio_modes = 0x3;
+    driveID.atap_piomode_supp = 0x3;
     // Set DMA mode 4 and below supported
-    driveID.dma_ultra = 0x10;
+    driveID.atap_udmamode_supp = 0x10;
     // Statically set hardware config word
-    driveID.hw_config = 0x4001;
+    driveID.atap_hwreset_res = 0x4001;
 }
 
 IdeDisk::~IdeDisk()
@@ -167,11 +164,17 @@ IdeDisk::reset(int id)
 // Utility functions
 ////
 
+bool
+IdeDisk::isDEVSelect()
+{
+    return ctrl->isDiskSelected(this);
+}
+
 Addr
 IdeDisk::pciToDma(Addr pciAddr)
 {
     if (ctrl)
-        return ctrl->tsunami->pchip->translatePciToDma(pciAddr);
+        return ctrl->plat->pciToDma(pciAddr);
     else
         panic("Access to unset controller!\n");
 }
@@ -182,14 +185,14 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
     uint32_t bytesInPage = 0;
 
     // First calculate how many bytes could be in the page
-    if (bytesLeft > ALPHA_PGBYTES)
-        bytesInPage = ALPHA_PGBYTES;
+    if (bytesLeft > TheISA::PageBytes)
+        bytesInPage = TheISA::PageBytes;
     else
         bytesInPage = bytesLeft;
 
     // Next, see if we have crossed a page boundary, and adjust
     Addr upperBound = curAddr + bytesInPage;
-    Addr pageBound = alpha_trunc_page(curAddr) + ALPHA_PGBYTES;
+    Addr pageBound = TheISA::TruncPage(curAddr) + TheISA::PageBytes;
 
     assert(upperBound >= curAddr && "DMA read wraps around address space!\n");
 
@@ -330,13 +333,14 @@ IdeDisk::dmaPrdReadDone()
            physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)),
            sizeof(PrdEntry_t));
 
-    DPRINTF(IdeDisk, "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
+    DPRINTF(IdeDisk,
+            "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
             curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()),
             curPrd.getByteCount(), (cmdBytesLeft/SectorSize),
             curPrd.getEOT(), curSector);
 
-    // make sure the new curPrdAddr is properly translated from PCI to system
-    curPrdAddr = pciToDma(curPrdAddr + sizeof(PrdEntry_t));
+    // the prd pointer has already been translated, so just do an increment
+    curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
 
     if (dmaRead)
         doDmaRead();
@@ -347,8 +351,11 @@ IdeDisk::dmaPrdReadDone()
 void
 IdeDisk::doDmaRead()
 {
+    /** @TODO we need to figure out what the delay actually will be */
     Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
 
+    DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
+            diskDelay, totalDiskDelay);
     if (dmaInterface) {
         if (dmaInterface->busy()) {
             // reschedule after waiting period
@@ -435,29 +442,8 @@ IdeDisk::dmaReadDone()
         writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
     }
 
-#if 0
-    // actually copy the data from memory to data buffer
-    Addr dmaAddr =
-        ctrl->tsunami->pchip->translatePciToDma(curPrd.getBaseAddr());
-    memcpy((void *)dataBuffer,
-           physmem->dma_addr(dmaAddr, curPrd.getByteCount()),
-           curPrd.getByteCount());
-
-    uint32_t bytesWritten = 0;
-
-    while (bytesWritten < curPrd.getByteCount()) {
-        if (cmdBytesLeft <= 0)
-            panic("DMA data is larger than # sectors specified\n");
-
-        writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
-
-        bytesWritten += SectorSize;
-        cmdBytesLeft -= SectorSize;
-    }
-#endif
-
     // check for the EOT
-    if (curPrd.getEOT()){
+    if (curPrd.getEOT()) {
         assert(cmdBytesLeft == 0);
         dmaState = Dma_Idle;
         updateState(ACT_DMA_DONE);
@@ -469,8 +455,12 @@ IdeDisk::dmaReadDone()
 void
 IdeDisk::doDmaWrite()
 {
+    /** @TODO we need to figure out what the delay actually will be */
     Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
 
+    DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
+            diskDelay, totalDiskDelay);
+
     if (dmaInterface) {
         if (dmaInterface->busy()) {
             // reschedule after waiting period
@@ -525,7 +515,7 @@ IdeDisk::dmaWriteDone()
 
     // setup the initial page and DMA address
     curAddr = curPrd.getBaseAddr();
-    pageAddr = alpha_trunc_page(curAddr);
+    pageAddr = TheISA::TruncPage(curAddr);
     dmaAddr = pciToDma(curAddr);
 
     // clear out the data buffer
@@ -533,14 +523,14 @@ IdeDisk::dmaWriteDone()
 
     while (bytesRead < curPrd.getByteCount()) {
         // see if we have crossed into a new page
-        if (pageAddr != alpha_trunc_page(curAddr)) {
+        if (pageAddr != TheISA::TruncPage(curAddr)) {
             // write the data to memory
             memcpy(physmem->dma_addr(dmaAddr, bytesInPage),
                    (void *)(dataBuffer + (bytesRead - bytesInPage)),
                    bytesInPage);
 
             // update the DMA address and page address
-            pageAddr = alpha_trunc_page(curAddr);
+            pageAddr = TheISA::TruncPage(curAddr);
             dmaAddr = pciToDma(curAddr);
 
             bytesInPage = 0;
@@ -564,14 +554,6 @@ IdeDisk::dmaWriteDone()
                bytesInPage);
     }
 
-#if 0
-    Addr dmaAddr = ctrl->tsunami->pchip->
-        translatePciToDma(curPrd.getBaseAddr());
-
-    memcpy(physmem->dma_addr(dmaAddr, curPrd.getByteCount()),
-           (void *)dataBuffer, curPrd.getByteCount());
-#endif
-
     // check for the EOT
     if (curPrd.getEOT()) {
         assert(cmdBytesLeft == 0);
@@ -632,10 +614,10 @@ void
 IdeDisk::abortDma()
 {
     if (dmaState == Dma_Idle)
-        panic("Inconsistent DMA state, should be in Dma_Start or Dma_Transfer!\n");
+        panic("Inconsistent DMA state, should be Start or Transfer!");
 
     if (devState != Transfer_Data_Dma && devState != Prepare_Data_Dma)
-        panic("Inconsistent device state, should be in Transfer or Prepare!\n");
+        panic("Inconsistent device state, should be Transfer or Prepare!\n");
 
     updateState(ACT_CMD_ERROR);
 }
@@ -650,7 +632,7 @@ IdeDisk::startCommand()
     // Decode commands
     switch (cmdReg.command) {
         // Supported non-data commands
-      case WIN_READ_NATIVE_MAX:
+      case WDSF_READ_NATIVE_MAX:
         size = image->size() - 1;
         cmdReg.sec_num = (size & 0xff);
         cmdReg.cyl_low = ((size & 0xff00) >> 8);
@@ -661,27 +643,27 @@ IdeDisk::startCommand()
         action = ACT_CMD_COMPLETE;
         break;
 
-      case WIN_RECAL:
-      case WIN_SPECIFY:
-      case WIN_STANDBYNOW1:
-      case WIN_FLUSH_CACHE:
-      case WIN_VERIFY:
-      case WIN_SEEK:
-      case WIN_SETFEATURES:
-      case WIN_SETMULT:
+      case WDCC_RECAL:
+      case WDCC_IDP:
+      case WDCC_STANDBY_IMMED:
+      case WDCC_FLUSHCACHE:
+      case WDSF_VERIFY:
+      case WDSF_SEEK:
+      case SET_FEATURES:
+      case WDCC_SETMULTI:
         devState = Command_Execution;
         action = ACT_CMD_COMPLETE;
         break;
 
         // Supported PIO data-in commands
-      case WIN_IDENTIFY:
-        cmdBytes = cmdBytesLeft = sizeof(struct hd_driveid);
+      case WDCC_IDENTIFY:
+        cmdBytes = cmdBytesLeft = sizeof(struct ataparams);
         devState = Prepare_Data_In;
         action = ACT_DATA_READY;
         break;
 
-      case WIN_MULTREAD:
-      case WIN_READ:
+      case WDCC_READMULTI:
+      case WDCC_READ:
         if (!(cmdReg.drive & DRIVE_LBA_BIT))
             panic("Attempt to perform CHS access, only supports LBA\n");
 
@@ -698,8 +680,8 @@ IdeDisk::startCommand()
         break;
 
         // Supported PIO data-out commands
-      case WIN_MULTWRITE:
-      case WIN_WRITE:
+      case WDCC_WRITEMULTI:
+      case WDCC_WRITE:
         if (!(cmdReg.drive & DRIVE_LBA_BIT))
             panic("Attempt to perform CHS access, only supports LBA\n");
 
@@ -715,9 +697,9 @@ IdeDisk::startCommand()
         break;
 
         // Supported DMA commands
-      case WIN_WRITEDMA:
+      case WDCC_WRITEDMA:
         dmaRead = true;  // a write to the disk is a DMA read from memory
-      case WIN_READDMA:
+      case WDCC_READDMA:
         if (!(cmdReg.drive & DRIVE_LBA_BIT))
             panic("Attempt to perform CHS access, only supports LBA\n");
 
@@ -755,6 +737,7 @@ IdeDisk::startCommand()
 void
 IdeDisk::intrPost()
 {
+    DPRINTF(IdeDisk, "Posting Interrupt\n");
     if (intrPending)
         panic("Attempt to post an interrupt with one pending\n");
 
@@ -768,6 +751,7 @@ IdeDisk::intrPost()
 void
 IdeDisk::intrClear()
 {
+    DPRINTF(IdeDisk, "Clearing Interrupt\n");
     if (!intrPending)
         panic("Attempt to clear a non-pending interrupt\n");
 
@@ -866,12 +850,12 @@ IdeDisk::updateState(DevAction_t action)
             status |= STATUS_DRQ_BIT;
 
             // copy the data into the data buffer
-            if (cmdReg.command == WIN_IDENTIFY) {
+            if (cmdReg.command == WDCC_IDENTIFY) {
                 // Reset the drqBytes for this block
-                drqBytesLeft = sizeof(struct hd_driveid);
+                drqBytesLeft = sizeof(struct ataparams);
 
                 memcpy((void *)dataBuffer, (void *)&driveID,
-                       sizeof(struct hd_driveid));
+                       sizeof(struct ataparams));
             } else {
                 // Reset the drqBytes for this block
                 drqBytesLeft = SectorSize;
@@ -1067,26 +1051,41 @@ IdeDisk::serialize(ostream &os)
     Tick reschedule = 0;
     Events_t event = None;
 
+    int eventCount = 0;
+
     if (dmaTransferEvent.scheduled()) {
         reschedule = dmaTransferEvent.when();
         event = Transfer;
-    } else if (dmaReadWaitEvent.scheduled()) {
+        eventCount++;
+    }
+    if (dmaReadWaitEvent.scheduled()) {
         reschedule = dmaReadWaitEvent.when();
         event = ReadWait;
-    } else if (dmaWriteWaitEvent.scheduled()) {
+        eventCount++;
+    }
+    if (dmaWriteWaitEvent.scheduled()) {
         reschedule = dmaWriteWaitEvent.when();
         event = WriteWait;
-    } else if (dmaPrdReadEvent.scheduled()) {
+        eventCount++;
+    }
+    if (dmaPrdReadEvent.scheduled()) {
         reschedule = dmaPrdReadEvent.when();
         event = PrdRead;
-    } else if (dmaReadEvent.scheduled()) {
+        eventCount++;
+    }
+    if (dmaReadEvent.scheduled()) {
         reschedule = dmaReadEvent.when();
         event = DmaRead;
-    } else if (dmaWriteEvent.scheduled()) {
+        eventCount++;
+    }
+    if (dmaWriteEvent.scheduled()) {
         reschedule = dmaWriteEvent.when();
         event = DmaWrite;
+        eventCount++;
     }
 
+    assert(eventCount <= 1);
+
     SERIALIZE_SCALAR(reschedule);
     SERIALIZE_ENUM(event);
 
@@ -1098,6 +1097,7 @@ IdeDisk::serialize(ostream &os)
     SERIALIZE_SCALAR(cmdReg.cyl_low);
     SERIALIZE_SCALAR(cmdReg.cyl_high);
     SERIALIZE_SCALAR(cmdReg.drive);
+    SERIALIZE_SCALAR(cmdReg.command);
     SERIALIZE_SCALAR(status);
     SERIALIZE_SCALAR(nIENBit);
     SERIALIZE_SCALAR(devID);
@@ -1150,6 +1150,7 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
     UNSERIALIZE_SCALAR(cmdReg.cyl_low);
     UNSERIALIZE_SCALAR(cmdReg.cyl_high);
     UNSERIALIZE_SCALAR(cmdReg.drive);
+    UNSERIALIZE_SCALAR(cmdReg.command);
     UNSERIALIZE_SCALAR(status);
     UNSERIALIZE_SCALAR(nIENBit);
     UNSERIALIZE_SCALAR(devID);
@@ -1175,12 +1176,14 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
+enum DriveID { master, slave };
+static const char *DriveID_strings[] = { "master", "slave" };
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
 
     SimObjectParam<DiskImage *> image;
     SimObjectParam<PhysicalMemory *> physmem;
-    Param<int> driveID;
-    Param<int> disk_delay;
+    SimpleEnumParam<DriveID> driveID;
+    Param<int> delay;
 
 END_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
 
@@ -1188,16 +1191,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeDisk)
 
     INIT_PARAM(image, "Disk image"),
     INIT_PARAM(physmem, "Physical memory"),
-    INIT_PARAM(driveID, "Drive ID (0=master 1=slave)"),
-    INIT_PARAM_DFLT(disk_delay, "Fixed disk delay in microseconds", 1)
+    INIT_ENUM_PARAM(driveID, "Drive ID (0=master 1=slave)", DriveID_strings),
+    INIT_PARAM_DFLT(delay, "Fixed disk delay in microseconds", 1)
 
 END_INIT_SIM_OBJECT_PARAMS(IdeDisk)
 
 
 CREATE_SIM_OBJECT(IdeDisk)
 {
-    return new IdeDisk(getInstanceName(), image, physmem, driveID,
-                       disk_delay);
+    return new IdeDisk(getInstanceName(), image, physmem, driveID, delay);
 }
 
 REGISTER_SIM_OBJECT("IdeDisk", IdeDisk)