Sfoglia il codice sorgente

Kernel: Convert PCI Capability struct to class with convenience methods

Based on pull #3236 by tomuta

Co-authored-by: Tom <tomut@yahoo.com>
Idan Horowitz 4 anni fa
parent
commit
172d23deae
3 ha cambiato i file con 61 aggiunte e 7 eliminazioni
  1. 31 1
      Kernel/PCI/Access.cpp
  2. 28 4
      Kernel/PCI/Definitions.h
  3. 2 2
      Kernel/PCI/DeviceController.cpp

+ 31 - 1
Kernel/PCI/Access.cpp

@@ -178,8 +178,8 @@ Vector<Capability> get_capabilities(Address address)
         dbgln_if(PCI_DEBUG, "PCI: Reading in capability at {:#02x} for {}", capability_pointer, address);
         u16 capability_header = PCI::read16(address, capability_pointer);
         u8 capability_id = capability_header & 0xff;
+        capabilities.append({ address, capability_id, capability_pointer });
         capability_pointer = capability_header >> 8;
-        capabilities.append({ capability_id, capability_pointer });
     }
     return capabilities;
 }
@@ -312,5 +312,35 @@ size_t get_BAR_space_size(Address address, u8 bar_number)
     return space_size;
 }
 
+u8 Capability::read8(u32 field) const
+{
+    return PCI::read8(m_address, m_ptr + field);
+}
+
+u16 Capability::read16(u32 field) const
+{
+    return PCI::read16(m_address, m_ptr + field);
+}
+
+u32 Capability::read32(u32 field) const
+{
+    return PCI::read32(m_address, m_ptr + field);
+}
+
+void Capability::write8(u32 field, u8 value)
+{
+    PCI::write8(m_address, m_ptr + field, value);
+}
+
+void Capability::write16(u32 field, u16 value)
+{
+    PCI::write16(m_address, m_ptr + field, value);
+}
+
+void Capability::write32(u32 field, u32 value)
+{
+    PCI::write32(m_address, m_ptr + field, value);
+}
+
 }
 }

+ 28 - 4
Kernel/PCI/Definitions.h

@@ -67,6 +67,11 @@ namespace Kernel {
 #define PCI_MAX_BUSES 256
 #define PCI_MAX_FUNCTIONS_PER_DEVICE 8
 
+#define PCI_CAPABILITY_NULL 0x0
+#define PCI_CAPABILITY_MSI 0x5
+#define PCI_CAPABILITY_VENDOR_SPECIFIC 0x9
+#define PCI_CAPABILITY_MSIX 0x11
+
 namespace PCI {
 struct ID {
     u16 vendor_id { 0 };
@@ -171,9 +176,28 @@ struct ChangeableAddress : public Address {
     }
 };
 
-struct Capability {
-    u8 m_id;
-    u8 m_next_pointer;
+class Capability {
+public:
+    Capability(const Address& address, u8 id, u8 ptr)
+        : m_address(address)
+        , m_id(id)
+        , m_ptr(ptr)
+    {
+    }
+
+    u8 id() const { return m_id; }
+
+    u8 read8(u32) const;
+    u16 read16(u32) const;
+    u32 read32(u32) const;
+    void write8(u32, u8);
+    void write16(u32, u16);
+    void write32(u32, u32);
+
+private:
+    Address m_address;
+    const u8 m_id;
+    const u8 m_ptr;
 };
 
 class PhysicalID {
@@ -185,7 +209,7 @@ public:
     {
         if constexpr (PCI_DEBUG) {
             for (auto capability : capabilities)
-                dbgln("{} has capability {}", address, capability.m_id);
+                dbgln("{} has capability {}", address, capability.id());
         }
     }
 

+ 2 - 2
Kernel/PCI/DeviceController.cpp

@@ -37,7 +37,7 @@ DeviceController::DeviceController(Address address)
 bool DeviceController::is_msi_capable() const
 {
     for (auto capability : PCI::get_physical_id(pci_address()).capabilities()) {
-        if (capability.m_id == 0x5)
+        if (capability.id() == PCI_CAPABILITY_MSI)
             return true;
     }
     return false;
@@ -45,7 +45,7 @@ bool DeviceController::is_msi_capable() const
 bool DeviceController::is_msix_capable() const
 {
     for (auto capability : PCI::get_physical_id(pci_address()).capabilities()) {
-        if (capability.m_id == 0x11)
+        if (capability.id() == PCI_CAPABILITY_MSIX)
             return true;
     }
     return false;