diff --git a/Kernel/Bus/PCI/Definitions.h b/Kernel/Bus/PCI/Definitions.h index e1f085b85d8..ebdee86ed9b 100644 --- a/Kernel/Bus/PCI/Definitions.h +++ b/Kernel/Bus/PCI/Definitions.h @@ -79,10 +79,12 @@ static constexpr size_t mmio_device_space_size = 4096; static constexpr u16 none_value = 0xffff; static constexpr size_t memory_range_per_bus = mmio_device_space_size * to_underlying(Limits::MaxFunctionsPerDevice) * to_underlying(Limits::MaxDevicesPerBus); static constexpr u32 bar_address_mask = 0xfffffff0; +static constexpr u8 msi_control_offset = 2; +static constexpr u16 msi_address_format_mask = 0x80; +static constexpr u8 msi_mmc_format_mask = 0xe; static constexpr u16 msix_control_table_mask = 0x07ff; static constexpr u8 msix_table_bir_mask = 0x7; static constexpr u16 msix_table_offset_mask = 0xfff8; -static constexpr u8 msi_control_offset = 2; static constexpr u16 msix_control_enable = 0x8000; // Taken from https://pcisig.com/sites/default/files/files/PCI_Code-ID_r_1_11__v24_Jan_2019.pdf @@ -340,6 +342,20 @@ public: u32 table_offset {}; }; +class MSIInfo { +public: + MSIInfo(bool message_address_64_bit_support, u8 count) + : message_address_64_bit_format(message_address_64_bit_support) + , count(count) + { + } + + MSIInfo() = default; + + bool message_address_64_bit_format { false }; + u8 count {}; +}; + class DeviceIdentifier : public RefCounted , public EnumerableDeviceIdentifier { @@ -353,6 +369,9 @@ public: u8 get_msix_table_bar() const { return m_msix_info.table_bar; } u32 get_msix_table_offset() const { return m_msix_info.table_offset; } + bool is_msi_capable() const { return m_msi_info.count > 0; } + bool is_msi_64bit_address_format() { return m_msi_info.message_address_64_bit_format; }; + Spinlock& operation_lock() { return m_operation_lock; } Spinlock& operation_lock() const { return m_operation_lock; } @@ -376,6 +395,7 @@ private: mutable Spinlock m_operation_lock; MSIxInfo m_msix_info {}; + MSIInfo m_msi_info {}; }; class Domain; diff --git a/Kernel/Bus/PCI/DeviceIdentifier.cpp b/Kernel/Bus/PCI/DeviceIdentifier.cpp index ee07737402b..42cae6e67c7 100644 --- a/Kernel/Bus/PCI/DeviceIdentifier.cpp +++ b/Kernel/Bus/PCI/DeviceIdentifier.cpp @@ -26,7 +26,15 @@ void DeviceIdentifier::initialize() auto msix_count = (cap.read16(2) & msix_control_table_mask) + 1; m_msix_info = MSIxInfo(msix_count, msix_bir_bar, msix_bir_offset); } + + if (cap.id() == PCI::Capabilities::ID::MSI) { + bool message_address_64_bit_format = (cap.read8(msi_control_offset) & msi_address_format_mask); + u8 count = 1; + u8 mme_count = (cap.read8(msi_control_offset) & msi_mmc_format_mask) >> 1; + if (mme_count) + count = mme_count; + m_msi_info = MSIInfo(message_address_64_bit_format, count); + } } } - }