dev: Stop using the OS page size in the IDE controller.
authorGabe Black <gabeblack@google.com>
Mon, 7 Sep 2020 07:51:54 +0000 (00:51 -0700)
committerGabe Black <gabeblack@google.com>
Sun, 20 Sep 2020 07:26:04 +0000 (07:26 +0000)
This size was used to break up DMA transactions so that a single
transaction would not cross a page boundary. This was because on Alpha,
there was an actual page table which translated between PCI and DMA
address spaces. On all currently implemented systems, the mapping is
simply to add a scalar offset, so it's not possible for a legal region
of memory to be contiguous in one space but not in the other.

Additionally, if it *was* possible for there to be a mismatch, it was
only coincidence that Alpha used a page table which had the same sized
pages as it normally used. There is no requirement that there even would
be fixed sized pages in the first place.

To avoid this artificial dependency between the IDE controller and the
ISA, this change simply changes the chunk size for DMA accesses to 4K.
That's the page size at least on x86 and probably other architectures,
and will be a pretty close approximation of the previous behavior.

It's possible that even having this chunking in the first place is
unnecessary and functionally useless, but there are some checks which
happen between chunks, and changing how big they are would change the
frequency of those checks. For instance, the controller/disk may not
notice in the same amount of time if a DMA was cancelled somehow.

Change-Id: I1ec840d1f158c3faa31ba0184458b69bf654c252
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/34178
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/dev/storage/ide_ctrl.cc
src/dev/storage/ide_disk.cc
src/dev/storage/ide_disk.hh

index 47cdd10278158f8c3baac3bb593553188182c9ff..5efa42b1861d2ec8cd7eb258d6af11edcf82df2e 100644 (file)
@@ -120,7 +120,8 @@ IdeController::IdeController(Params *p)
             panic("IDE controllers support a maximum "
                   "of 4 devices attached!\n");
         }
-        params()->disks[i]->setController(this, sys->getPageBytes());
+        // Arbitrarily set the chunk size to 4K.
+        params()->disks[i]->setController(this, 4 * 1024);
     }
 
     primary.select(false);
index e97e23b8e46a16b1c7206c1e91121170539536ce..57fa07632d90faef87f44cc290eeecb40b3773d7 100644 (file)
@@ -435,7 +435,7 @@ IdeDisk::doDmaRead()
         // clear out the data buffer
         memset(dataBuffer, 0, MAX_DMA_SIZE);
         dmaReadCG = new ChunkGenerator(curPrd.getBaseAddr(),
-                curPrd.getByteCount(), pageBytes);
+                curPrd.getByteCount(), chunkBytes);
 
     }
     if (ctrl->dmaPending() || ctrl->drainState() != DrainState::Running) {
@@ -447,7 +447,7 @@ IdeDisk::doDmaRead()
                 &dmaReadWaitEvent, dataBuffer + dmaReadCG->complete());
         dmaReadBytes += dmaReadCG->size();
         dmaReadTxs++;
-        if (dmaReadCG->size() == pageBytes)
+        if (dmaReadCG->size() == chunkBytes)
             dmaReadFullPages++;
         dmaReadCG->next();
     } else {
@@ -518,7 +518,7 @@ IdeDisk::doDmaWrite()
     if (!dmaWriteCG) {
         // clear out the data buffer
         dmaWriteCG = new ChunkGenerator(curPrd.getBaseAddr(),
-                curPrd.getByteCount(), pageBytes);
+                curPrd.getByteCount(), chunkBytes);
     }
     if (ctrl->dmaPending() || ctrl->drainState() != DrainState::Running) {
         schedule(dmaWriteWaitEvent, curTick() + DMA_BACKOFF_PERIOD);
@@ -532,7 +532,7 @@ IdeDisk::doDmaWrite()
                 curPrd.getByteCount(), curPrd.getEOT());
         dmaWriteBytes += dmaWriteCG->size();
         dmaWriteTxs++;
-        if (dmaWriteCG->size() == pageBytes)
+        if (dmaWriteCG->size() == chunkBytes)
             dmaWriteFullPages++;
         dmaWriteCG->next();
     } else {
index 9f42941798070da3d6f41ee4294338e11539b69c..90cbf57059fac52f7aaa4ebee5a2da29d3e36750 100644 (file)
@@ -239,8 +239,8 @@ class IdeDisk : public SimObject
     DmaState_t dmaState;
     /** Dma transaction is a read */
     bool dmaRead;
-    /** Size of OS pages. */
-    Addr pageBytes;
+    /** Size of chunks to DMA. */
+    Addr chunkBytes;
     /** PRD table base address */
     uint32_t curPrdAddr;
     /** PRD entry */
@@ -283,11 +283,11 @@ class IdeDisk : public SimObject
      * @param c The IDE controller
      */
     void
-    setController(IdeController *c, Addr page_bytes)
+    setController(IdeController *c, Addr chunk_bytes)
     {
         panic_if(ctrl, "Cannot change the controller once set!\n");
         ctrl = c;
-        pageBytes = page_bytes;
+        chunkBytes = chunk_bytes;
     }
 
     // Device register read/write