From 9500d140874369eff5029c6d70674d34593d5dc1 Mon Sep 17 00:00:00 2001
From: apio <blobs.trading@gmail.com>
Date: Sun, 14 May 2023 21:45:18 +0200
Subject: [PATCH] kernel/x86_64: Implement writing to PCI fields

---
 kernel/src/arch/x86_64/PCI.cpp | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/kernel/src/arch/x86_64/PCI.cpp b/kernel/src/arch/x86_64/PCI.cpp
index 0ce6d920..16fd0815 100644
--- a/kernel/src/arch/x86_64/PCI.cpp
+++ b/kernel/src/arch/x86_64/PCI.cpp
@@ -33,19 +33,32 @@ namespace PCI
 
     void write8(const Device::Address& address, u32 field, u8 value)
     {
-        ignore(address, field, value);
-        todo();
+        u8 offset = (u8)(field & ~0x3);
+        union {
+            u8 split[4];
+            u32 full;
+        };
+        full = read32(address, offset);
+        split[(field & 0x3)] = value;
+        write32(address, offset, full);
     }
 
-    void write16(const Device::Address& address, u32 field, u8 value)
+    void write16(const Device::Address& address, u32 field, u16 value)
     {
-        ignore(address, field, value);
-        todo();
+        u8 offset = (u8)(field & ~0x3);
+        union {
+            u8 split[4];
+            u32 full;
+        };
+        full = read32(address, offset);
+        split[(field & 0x3)] = (u8)(value >> 8);
+        split[(field & 0x3) + 1] = (u8)(value & 0xff);
+        write32(address, offset, full);
     }
 
-    void write32(const Device::Address& address, u32 field, u8 value)
+    void write32(const Device::Address& address, u32 field, u32 value)
     {
-        ignore(address, field, value);
-        todo();
+        IO::outl(PCI_ADDRESS_PORT, make_pci_address(address, field));
+        IO::outl(PCI_VALUE_PORT, value);
     }
 }