浏览代码

Kernel: Use rep insw/outsw for IDE transfers.

There are much faster ways to do disk transfers, but I'm not implementing
those today. In the meantime, this is slightly nicer. :^)
Andreas Kling 6 年之前
父节点
当前提交
243e1d8462
共有 2 个文件被更改,包括 17 次插入15 次删除
  1. 6 15
      Kernel/Devices/IDEDiskDevice.cpp
  2. 11 0
      Kernel/IO.h

+ 6 - 15
Kernel/Devices/IDEDiskDevice.cpp

@@ -202,17 +202,12 @@ bool IDEDiskDevice::read_sectors(dword start_sector, word count, byte* outbuf)
         return false;
         return false;
 
 
     byte status = IO::in8(0x1f7);
     byte status = IO::in8(0x1f7);
-    if (status & DRQ) {
+    ASSERT(status & DRQ);
 #ifdef DISK_DEBUG
 #ifdef DISK_DEBUG
-        kprintf("Retrieving %u bytes (status=%b), outbuf=%p...\n", count * 512, status, outbuf);
+    kprintf("Retrieving %u bytes (status=%b), outbuf=%p...\n", count * 512, status, outbuf);
 #endif
 #endif
-        for (dword i = 0; i < (count * 512); i += 2) {
-            word w = IO::in16(IDE0_DATA);
-            outbuf[i] = LSB(w);
-            outbuf[i+1] = MSB(w);
-        }
-    }
 
 
+    IO::repeated_in16(IDE0_DATA, outbuf, count * 256);
     return true;
     return true;
 }
 }
 
 
@@ -246,13 +241,8 @@ bool IDEDiskDevice::write_sectors(dword start_sector, word count, const byte* da
     while (!(IO::in8(IDE0_STATUS) & DRQ));
     while (!(IO::in8(IDE0_STATUS) & DRQ));
 
 
     byte status = IO::in8(0x1f7);
     byte status = IO::in8(0x1f7);
-    if (status & DRQ) {
-        //dbgprintf("Sending %u bytes (status=%b), data=%p...\n", count * 512, status, data);
-        auto* data_as_words = (const word*)data;
-        for (dword i = 0; i < (count * 512) / 2; ++i) {
-            IO::out16(IDE0_DATA, data_as_words[i]);
-        }
-    }
+    ASSERT(status & DRQ);
+    IO::repeated_out16(IDE0_DATA, data, count * 256);
 
 
     m_interrupted = false;
     m_interrupted = false;
     enable_irq();
     enable_irq();
@@ -261,6 +251,7 @@ bool IDEDiskDevice::write_sectors(dword start_sector, word count, const byte* da
     disable_irq();
     disable_irq();
     IO::out8(IDE0_COMMAND, FLUSH_CACHE);
     IO::out8(IDE0_COMMAND, FLUSH_CACHE);
     while (IO::in8(IDE0_STATUS) & BUSY);
     while (IO::in8(IDE0_STATUS) & BUSY);
+    m_interrupted = false;
     enable_irq();
     enable_irq();
     wait_for_irq();
     wait_for_irq();
 
 

+ 11 - 0
Kernel/IO.h

@@ -25,6 +25,11 @@ inline dword in32(word port)
     return value;
     return value;
 }
 }
 
 
+inline void repeated_in16(word port, byte* buffer, int buffer_size)
+{
+    asm volatile("rep insw" : "+D"(buffer), "+c"(buffer_size) : "d"(port) : "memory");
+}
+
 inline void out8(word port, byte value)
 inline void out8(word port, byte value)
 {
 {
     asm volatile("outb %0, %1"::"a"(value), "Nd"(port));
     asm volatile("outb %0, %1"::"a"(value), "Nd"(port));
@@ -39,4 +44,10 @@ inline void out32(word port, dword value)
 {
 {
     asm volatile("outl %0, %1"::"a"(value), "Nd"(port));
     asm volatile("outl %0, %1"::"a"(value), "Nd"(port));
 }
 }
+
+inline void repeated_out16(word port, const byte* data, int data_size)
+{
+    asm volatile("rep outsw" : "+S"(data), "+c"(data_size) : "d"(port));
+}
+
 }
 }