summaryrefslogtreecommitdiff
path: root/Kernel/PCI
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-01-02 19:33:30 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-17 10:21:23 +0200
commit172d23deaef7f646f7a79bfad86a88a70adf8b32 (patch)
tree505d2f8394fbdfc7fb688ad24a6362cb49161d63 /Kernel/PCI
parentdfb23babbb131e22fe7035a30bce4e933738a664 (diff)
downloadserenity-172d23deaef7f646f7a79bfad86a88a70adf8b32.zip
Kernel: Convert PCI Capability struct to class with convenience methods
Based on pull #3236 by tomuta Co-authored-by: Tom <tomut@yahoo.com>
Diffstat (limited to 'Kernel/PCI')
-rw-r--r--Kernel/PCI/Access.cpp32
-rw-r--r--Kernel/PCI/Definitions.h32
-rw-r--r--Kernel/PCI/DeviceController.cpp4
3 files changed, 61 insertions, 7 deletions
diff --git a/Kernel/PCI/Access.cpp b/Kernel/PCI/Access.cpp
index 6197e6a7f1..e877cf150e 100644
--- a/Kernel/PCI/Access.cpp
+++ b/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);
+}
+
}
}
diff --git a/Kernel/PCI/Definitions.h b/Kernel/PCI/Definitions.h
index a23b473a86..1cc92144e8 100644
--- a/Kernel/PCI/Definitions.h
+++ b/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());
}
}
diff --git a/Kernel/PCI/DeviceController.cpp b/Kernel/PCI/DeviceController.cpp
index ea9455e75c..abbccbf221 100644
--- a/Kernel/PCI/DeviceController.cpp
+++ b/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;