summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-23 03:45:55 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-23 03:45:55 +0200
commit243e1d84627c20a39f5464bb61cafae9fa2fe456 (patch)
tree12ca0a546ac87fd71b60babf8d31df91a585ee75
parent37498c156653d2633000c9b4fd2fc60fcbf12a03 (diff)
downloadserenity-243e1d84627c20a39f5464bb61cafae9fa2fe456.zip
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. :^)
-rw-r--r--Kernel/Devices/IDEDiskDevice.cpp21
-rw-r--r--Kernel/IO.h11
2 files changed, 17 insertions, 15 deletions
diff --git a/Kernel/Devices/IDEDiskDevice.cpp b/Kernel/Devices/IDEDiskDevice.cpp
index b84a72acf6..1f57aa2d11 100644
--- a/Kernel/Devices/IDEDiskDevice.cpp
+++ b/Kernel/Devices/IDEDiskDevice.cpp
@@ -202,17 +202,12 @@ bool IDEDiskDevice::read_sectors(dword start_sector, word count, byte* outbuf)
return false;
byte status = IO::in8(0x1f7);
- if (status & DRQ) {
+ ASSERT(status & DRQ);
#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
- 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;
}
@@ -246,13 +241,8 @@ bool IDEDiskDevice::write_sectors(dword start_sector, word count, const byte* da
while (!(IO::in8(IDE0_STATUS) & DRQ));
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;
enable_irq();
@@ -261,6 +251,7 @@ bool IDEDiskDevice::write_sectors(dword start_sector, word count, const byte* da
disable_irq();
IO::out8(IDE0_COMMAND, FLUSH_CACHE);
while (IO::in8(IDE0_STATUS) & BUSY);
+ m_interrupted = false;
enable_irq();
wait_for_irq();
diff --git a/Kernel/IO.h b/Kernel/IO.h
index cf99ca5ee6..5453b98494 100644
--- a/Kernel/IO.h
+++ b/Kernel/IO.h
@@ -25,6 +25,11 @@ inline dword in32(word port)
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)
{
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));
}
+
+inline void repeated_out16(word port, const byte* data, int data_size)
+{
+ asm volatile("rep outsw" : "+S"(data), "+c"(data_size) : "d"(port));
+}
+
}