diff --git a/headers/os/drivers/bus/PCI.h b/headers/os/drivers/bus/PCI.h index a57f2ab41e..756cb85c4b 100644 --- a/headers/os/drivers/bus/PCI.h +++ b/headers/os/drivers/bus/PCI.h @@ -38,6 +38,23 @@ typedef struct pci_device_module_info { uint16 *offset); uint8 (*get_powerstate)(pci_device *device); void (*set_powerstate)(pci_device *device, uint8 state); + + // MSI/MSI-X + uint8 (*get_msi_count)(pci_device *device); + status_t (*configure_msi)(pci_device *device, + uint8 count, + uint8 *startVector); + status_t (*unconfigure_msi)(pci_device *device); + + status_t (*enable_msi)(pci_device *device); + status_t (*disable_msi)(pci_device *device); + + uint8 (*get_msix_count)(pci_device *device); + status_t (*configure_msix)(pci_device *device, + uint8 count, + uint8 *startVector); + status_t (*enable_msix)(pci_device *device); + } pci_device_module_info; diff --git a/headers/private/kernel/arch/generic/msi.h b/headers/private/kernel/arch/generic/msi.h new file mode 100644 index 0000000000..7b38ef3984 --- /dev/null +++ b/headers/private/kernel/arch/generic/msi.h @@ -0,0 +1,35 @@ +/* + * Copyright 2022, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_GENERIC_MSI_H +#define _KERNEL_ARCH_GENERIC_MSI_H + +#include + + +#ifdef __cplusplus + +class MSIInterface { +public: + virtual status_t AllocateVectors( + uint8 count, uint8& startVector, uint64& address, uint16& data) = 0; + virtual void FreeVectors(uint8 count, uint8 startVector) = 0; +}; + + +extern "C" { +void msi_set_interface(MSIInterface* interface); +#endif + +bool msi_supported(); +status_t msi_allocate_vectors(uint8 count, uint8 *startVector, + uint64 *address, uint16 *data); +void msi_free_vectors(uint8 count, uint8 startVector); + +#ifdef __cplusplus +} +#endif + + +#endif // _KERNEL_ARCH_GENERIC_MSI_H diff --git a/headers/private/kernel/arch/x86/msi.h b/headers/private/kernel/arch/x86/msi.h index 04e0cd9674..6fdf67fe93 100644 --- a/headers/private/kernel/arch/x86/msi.h +++ b/headers/private/kernel/arch/x86/msi.h @@ -1,7 +1,7 @@ #ifndef _KERNEL_ARCH_x86_MSI_H #define _KERNEL_ARCH_x86_MSI_H -#include +#include // address register #define MSI_ADDRESS_BASE 0xfee00000 @@ -24,10 +24,7 @@ #define MSI_DELIVERY_MODE_EXT_INT 0x00000700 -bool msi_supported(); -status_t msi_allocate_vectors(uint8 count, uint8 *startVector, - uint64 *address, uint16 *data); -void msi_free_vectors(uint8 count, uint8 startVector); void msi_assign_interrupt_to_cpu(uint8 irq, int32 cpu); + #endif // _KERNEL_ARCH_x86_MSI_H diff --git a/src/add-ons/kernel/bus_managers/pci/Jamfile b/src/add-ons/kernel/bus_managers/pci/Jamfile index 8694903957..1b52dfd72a 100644 --- a/src/add-ons/kernel/bus_managers/pci/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/Jamfile @@ -12,6 +12,7 @@ KernelAddon pci : pci_module.cpp pci_root.cpp pci_device.cpp + pci_msi.cpp : pci_arch_bus_manager.a ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.cpp b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.cpp index 22d79ecc3b..1108668c79 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.cpp @@ -75,20 +75,29 @@ PCIFU740::InitMSI(int32 msiIrq) return result; } + msi_set_interface(static_cast(this)); + dprintf(" fMsiStartIrq: %ld\n", fMsiStartIrq); return B_OK; } -int32 -PCIFU740::AllocateMSIIrq() +status_t +PCIFU740::AllocateVectors(uint8 count, uint8& startVector, uint64& address, uint16& data) { + if (count != 1) + return B_ERROR; + for (int i = 0; i < 32; i++) { if (((1 << i) & fAllocatedMsiIrqs[0]) == 0) { fAllocatedMsiIrqs[0] |= (1 << i); GetDbuRegs()->msiIntr[0].mask &= ~(1 << i); - return i; + + startVector = fMsiStartIrq + i; + address = fMsiPhysAddr; + data = i; + return B_OK; } } return B_ERROR; @@ -96,11 +105,16 @@ PCIFU740::AllocateMSIIrq() void -PCIFU740::FreeMSIIrq(int32 irq) +PCIFU740::FreeVectors(uint8 count, uint8 startVector) { - if (irq >= 0 && irq < 32 && ((1 << irq) & fAllocatedMsiIrqs[0]) != 0) { - GetDbuRegs()->msiIntr[0].mask |= (1 << (uint32)irq); - fAllocatedMsiIrqs[0] &= ~(1 << (uint32)irq); + int32 irq = (int32)startVector - fMsiStartIrq; + while (count > 0) { + if (irq >= 0 && irq < 32 && ((1 << irq) & fAllocatedMsiIrqs[0]) != 0) { + GetDbuRegs()->msiIntr[0].mask |= (1 << (uint32)irq); + fAllocatedMsiIrqs[0] &= ~(1 << (uint32)irq); + } + irq++; + count--; } } @@ -400,68 +414,3 @@ PCIFU740::ConfigAddress(uint8 bus, uint8 device, uint8 function, uint16 offset) return fConfigBase + offset; } - - -void -PCIFU740::InitDeviceMSI(uint8 bus, uint8 device, uint8 function) -{ - uint32 status; - uint32 capPtr; - uint32 capId; - - ReadConfig(NULL, bus, device, function, PCI_status, 2, &status); - if ((status & PCI_status_capabilities) == 0) - return; - - uint32 headerType; - ReadConfig(NULL, bus, device, function, PCI_header_type, 1, &headerType); - - switch (headerType & PCI_header_type_mask) { - case PCI_header_type_generic: - case PCI_header_type_PCI_to_PCI_bridge: - ReadConfig(NULL, bus, device, function, PCI_capabilities_ptr, 1, &capPtr); - break; - case PCI_header_type_cardbus: - ReadConfig(NULL, bus, device, function, PCI_capabilities_ptr_2, 1, &capPtr); - break; - default: - return; - } - - capPtr &= ~3; - if (capPtr == 0) - return; - - for (int i = 0; i < 48; i++) { - ReadConfig(NULL, bus, device, function, capPtr + 0, 1, &capId); - - if (capId == PCI_cap_id_msi) - break; - - ReadConfig(NULL, bus, device, function, capPtr + 1, 1, &capPtr); - capPtr &= ~3; - if (capPtr == 0) - return; - } - - dprintf(" MSI offset: %#x\n", capPtr); - - int32 msiIrq = AllocateMSIIrq(); - dprintf(" msiIrq: %" B_PRId32 "\n", msiIrq); - - uint32 control; - ReadConfig(NULL, bus, device, function, capPtr + PCI_msi_control, 2, &control); - - WriteConfig(NULL, bus, device, function, capPtr + PCI_msi_address, 4, (uint32)fMsiPhysAddr); - if ((control & PCI_msi_control_64bit) != 0) { - WriteConfig(NULL, bus, device, function, capPtr + PCI_msi_address_high, 4, (uint32)(fMsiPhysAddr >> 32)); - WriteConfig(NULL, bus, device, function, capPtr + PCI_msi_data_64bit, 2, msiIrq); - } else - WriteConfig(NULL, bus, device, function, capPtr + PCI_msi_data, 2, msiIrq); - - control &= ~PCI_msi_control_mme_mask; - control |= (ffs(1) - 1) << 4; - control |= PCI_msi_control_enable; - WriteConfig(NULL, bus, device, function, capPtr + PCI_msi_control, 2, control); - WriteConfig(NULL, bus, device, function, PCI_interrupt_line, 1, fMsiStartIrq + msiIrq); -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.h b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.h index e8f1b6b789..bbbda2a352 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.h +++ b/src/add-ons/kernel/bus_managers/pci/arch/riscv64/fu740/pci_fu740.h @@ -5,6 +5,7 @@ #include "arch_pci_controller.h" +#include enum { @@ -39,22 +40,82 @@ struct PciAtuRegs { }; -class PCIFU740 : public ArchPCIController { +struct PciDbiRegs { + uint8 unknown0[0x700]; + + uint32 unknown1[3]; + uint32 portAfr; + uint32 linkControl; + uint32 unknown2[5]; + uint32 portDebug0; + uint32 portDebug1; + uint32 unknown3[55]; + uint32 linkWidthSpeedControl; + uint32 unknown4[4]; + uint32 msiAddrLo; + uint32 msiAddrHi; + struct { + uint32 enable; + uint32 mask; + uint32 status; + } msiIntr[8]; + uint32 unknown5[13]; + uint32 miscControl1Off; + uint32 miscPortMultiLaneCtrl; + uint32 unknown6[15]; + + uint32 atuViewport; + uint32 atuCr1; + uint32 atuCr2; + uint32 atuBaseLo; + uint32 atuBaseHi; + uint32 atuLimit; + uint32 atuTargetLo; + uint32 atuTargetHi; + uint32 unknown7; + uint32 atuLimitHi; + uint32 unknown8[8]; + + uint32 msixDoorbell; + uint32 unknown9[117]; + + uint32 plChkRegControlStatus; + uint32 unknown10; + uint32 plChkRegErrAddr; + uint32 unknown11[309]; +}; + + +class PCIFU740 : public ArchPCIController, public MSIInterface { status_t Init(device_node* pciRootNode); - status_t InitMSI(int32 irq); - int32 AllocateMSIIrq(); - void FreeMSIIrq(int32 irq); - int32 HandleMSIIrq(void* arg); + PciDbiRegs volatile* GetDbuRegs() {return (PciDbiRegs volatile*)fDbiBase;} + status_t InitMSI(int32 irq); + status_t AllocateVectors(uint8 count, uint8& startVector, uint64& address, + uint16& data) final; + void FreeVectors(uint8 count, uint8 startVector) final; + static int32 HandleMSIIrq(void* arg); + inline int32 HandleMSIIrqInt(); + + void EnableIoInterrupt(int irq) final; + void DisableIoInterrupt(int irq) final; + void ConfigureIoInterrupt(int irq, uint32 config) final; + int32 AssignToCpu(int32 irq, int32 cpu) final; addr_t ConfigAddress(uint8 bus, uint8 device, uint8 function, uint16 offset); - void InitDeviceMSI(uint8 bus, uint8 device, uint8 function); bool AllocateBar() { return false; } private: status_t AtuMap(uint32 index, uint32 direction, uint32 type, uint64 parentAdr, uint64 childAdr, uint32 size); void AtuDump(); + +private: + AreaDeleter fDbiArea; + addr_t fDbiPhysBase{}; + addr_t fDbiBase{}; + size_t fDbiSize{}; }; + diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile index 8d2e505be0..cd8a162008 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile @@ -11,11 +11,8 @@ SubDirHdrs $(HAIKU_TOP) src add-ons kernel bus_managers acpi arch $(TARGET_KERNE KernelStaticLibrary pci_arch_bus_manager : pci_acpi.cpp - pci_arch_info.cpp - pci_arch_module.cpp pci_bios.cpp pci_controller.cpp pci_io.cpp pci_irq.cpp - pci_msi.cpp ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_info.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_info.cpp deleted file mode 100644 index 38f18df191..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_info.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2010, Michael Lotz, mmlr@mlotz.ch. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - -#include "pci_arch_info.h" - -void -pci_read_arch_info(PCIDev *dev) -{ - pci_read_msi_info(dev); - pci_read_msix_info(dev); - pci_read_ht_mapping_info(dev); -} diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_info.h b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_info.h deleted file mode 100644 index 7e36c7bf4b..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_info.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2010, Michael Lotz, mmlr@mlotz.ch. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _PCI_ARCH_INFO_H -#define _PCI_ARCH_INFO_H - -#include "pci_msi.h" - -typedef struct pci_arch_info { - msi_info msi; - msix_info msix; - ht_mapping_info ht_mapping; -} pci_arch_info; - - -void pci_read_arch_info(PCIDev *device); - -#endif // _PCI_ARCH_INFO_H diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_module.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_module.cpp deleted file mode 100644 index b0f8952371..0000000000 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_arch_module.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2010, Michael Lotz, mmlr@mlotz.ch. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ - -#include -#include -#include "pci_msi.h" - - -static int32 -pci_arch_module_std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - { - module_info *dummy; - status_t result = get_module(B_PCI_MODULE_NAME, &dummy); - if (result != B_OK) - return result; - - return B_OK; - } - - case B_MODULE_UNINIT: - put_module(B_PCI_MODULE_NAME); - return B_OK; - } - - return B_BAD_VALUE; -} - - -pci_x86_module_info gPCIArchModule = { - { - B_PCI_X86_MODULE_NAME, - 0, - pci_arch_module_std_ops - }, - - &pci_get_msi_count, - &pci_configure_msi, - &pci_unconfigure_msi, - &pci_enable_msi, - &pci_disable_msi, - &pci_get_msix_count, - &pci_configure_msix, - &pci_enable_msix -}; diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index a4a7ebc497..fd31ffa2b2 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -1551,9 +1551,9 @@ PCI::_RefreshDeviceInfo(PCIBus *bus) for (PCIDev *dev = bus->child; dev; dev = dev->next) { _ReadBasicInfo(dev); _ReadHeaderInfo(dev); -#if defined(__i386__) || defined(__x86_64__) - pci_read_arch_info(dev); -#endif + pci_read_msi_info(dev); + pci_read_msix_info(dev); + pci_read_ht_mapping_info(dev); if (dev->child) _RefreshDeviceInfo(dev->child); } diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index b3a057b234..81efd85dc8 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -14,10 +14,8 @@ #endif #include "pci_controller.h" +#include "pci_msi.h" -#if defined(__i386__) || defined(__x86_64__) -#include "pci_arch_info.h" -#endif #define TRACE_PCI #ifndef TRACE_PCI @@ -47,9 +45,10 @@ struct PCIDev { uint8 device; uint8 function; pci_info info; -#if defined(__i386__) || defined(__x86_64__) - pci_arch_info arch_info; -#endif + + msi_info msi; + msix_info msix; + ht_mapping_info ht_mapping; }; @@ -105,7 +104,7 @@ public: uint8 *offset); status_t FindHTCapability(PCIDev *device, uint16 capID, uint8 *offset = NULL); - + status_t ResolveVirtualBus(uint8 virtualBus, uint8 *domain, uint8 *bus); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp index 585aace2f6..d405761ecb 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp @@ -7,6 +7,8 @@ #include +#include +#include "pci_msi.h" #include "pci_private.h" #include "pci_info.h" @@ -14,7 +16,6 @@ device_manager_info *gDeviceManager; -extern struct pci_arch_module gPCIArchModule; static int32 pci_old_module_std_ops(int32 op, ...) @@ -45,6 +46,29 @@ pci_old_module_std_ops(int32 op, ...) } +static int32 +pci_arch_module_std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + { + module_info *dummy; + status_t result = get_module(B_PCI_MODULE_NAME, &dummy); + if (result != B_OK) + return result; + + return B_OK; + } + + case B_MODULE_UNINIT: + put_module(B_PCI_MODULE_NAME); + return B_OK; + } + + return B_BAD_VALUE; +} + + static struct pci_module_info sOldPCIModule = { { { @@ -73,6 +97,25 @@ static struct pci_module_info sOldPCIModule = { &pci_set_powerstate }; + +static pci_x86_module_info sPCIArchModule = { + { + B_PCI_X86_MODULE_NAME, + 0, + pci_arch_module_std_ops + }, + + &pci_get_msi_count, + &pci_configure_msi, + &pci_unconfigure_msi, + &pci_enable_msi, + &pci_disable_msi, + &pci_get_msix_count, + &pci_configure_msix, + &pci_enable_msix +}; + + module_dependency module_dependencies[] = { {B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager}, {} @@ -92,9 +135,6 @@ module_info *modules[] = { (module_info *)&gPCIRootModule, (module_info *)&gPCIDeviceModule, (module_info *)&gPCILegacyDriverModule, -#if defined(__i386__) || defined(__x86_64__) - // add platforms when they provide an arch specific module - (module_info *)&gPCIArchModule, -#endif + (module_info *)&sPCIArchModule, NULL }; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp b/src/add-ons/kernel/bus_managers/pci/pci_msi.cpp similarity index 95% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp rename to src/add-ons/kernel/bus_managers/pci/pci_msi.cpp index b54ec18dc5..362a7e5684 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_msi.cpp @@ -5,7 +5,6 @@ */ #include "pci_msi.h" -#include "pci_arch_info.h" #include "pci.h" #include "pci_private.h" @@ -24,7 +23,7 @@ static status_t pci_disable_msix(PCIDev *device); static void pci_ht_msi_map(PCIDev *device, uint64 address) { - ht_mapping_info *info = &device->arch_info.ht_mapping; + ht_mapping_info *info = &device->ht_mapping; if (!info->ht_mapping_capable) return; @@ -50,7 +49,7 @@ pci_read_ht_mapping_info(PCIDev *device) if (!msi_supported()) return; - ht_mapping_info *info = &device->arch_info.ht_mapping; + ht_mapping_info *info = &device->ht_mapping; info->ht_mapping_capable = false; uint8 offset = 0; @@ -90,7 +89,7 @@ pci_get_msi_count(uint8 virtualBus, uint8 _device, uint8 function) if (device == NULL) return 0; - msi_info *info = &device->arch_info.msi; + msi_info *info = &device->msi; if (!info->msi_capable) return 0; @@ -118,7 +117,7 @@ pci_configure_msi(uint8 virtualBus, uint8 _device, uint8 function, if (device == NULL) return B_ERROR; - msi_info *info = &device->arch_info.msi; + msi_info *info = &device->msi; if (!info->msi_capable) return B_UNSUPPORTED; @@ -177,7 +176,7 @@ pci_unconfigure_msi(uint8 virtualBus, uint8 _device, uint8 function) if (result != B_UNSUPPORTED && result != B_NO_INIT) return result; - msi_info *info = &device->arch_info.msi; + msi_info *info = &device->msi; if (!info->msi_capable) return B_UNSUPPORTED; @@ -213,7 +212,7 @@ pci_enable_msi(uint8 virtualBus, uint8 _device, uint8 function) if (device == NULL) return B_ERROR; - msi_info *info = &device->arch_info.msi; + msi_info *info = &device->msi; if (!info->msi_capable) return B_UNSUPPORTED; @@ -259,7 +258,7 @@ pci_disable_msi(uint8 virtualBus, uint8 _device, uint8 function) if (result != B_UNSUPPORTED && result != B_NO_INIT) return result; - msi_info *info = &device->arch_info.msi; + msi_info *info = &device->msi; if (!info->msi_capable) return B_UNSUPPORTED; @@ -284,7 +283,7 @@ pci_read_msi_info(PCIDev *device) if (!msi_supported()) return; - msi_info *info = &device->arch_info.msi; + msi_info *info = &device->msi; info->msi_capable = false; status_t result = gPCI->FindCapability(device->domain, device->bus, device->device, device->function, PCI_cap_id_msi, @@ -319,7 +318,7 @@ pci_get_msix_count(uint8 virtualBus, uint8 _device, uint8 function) if (device == NULL) return 0; - msix_info *info = &device->arch_info.msix; + msix_info *info = &device->msix; if (!info->msix_capable) return 0; @@ -347,7 +346,7 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, if (device == NULL) return B_ERROR; - msix_info *info = &device->arch_info.msix; + msix_info *info = &device->msix; if (!info->msix_capable) return B_UNSUPPORTED; @@ -432,7 +431,7 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, static status_t pci_unconfigure_msix(PCIDev *device) { - msix_info *info = &device->arch_info.msix; + msix_info *info = &device->msix; if (!info->msix_capable) return B_UNSUPPORTED; @@ -481,7 +480,7 @@ pci_enable_msix(uint8 virtualBus, uint8 _device, uint8 function) if (device == NULL) return B_ERROR; - msix_info *info = &device->arch_info.msix; + msix_info *info = &device->msix; if (!info->msix_capable) return B_UNSUPPORTED; @@ -509,7 +508,7 @@ pci_enable_msix(uint8 virtualBus, uint8 _device, uint8 function) status_t pci_disable_msix(PCIDev *device) { - msix_info *info = &device->arch_info.msix; + msix_info *info = &device->msix; if (!info->msix_capable) return B_UNSUPPORTED; @@ -534,7 +533,7 @@ pci_read_msix_info(PCIDev *device) if (!msi_supported()) return; - msix_info *info = &device->arch_info.msix; + msix_info *info = &device->msix; info->msix_capable = false; status_t result = gPCI->FindCapability(device->domain, device->bus, device->device, device->function, PCI_cap_id_msix, diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.h b/src/add-ons/kernel/bus_managers/pci/pci_msi.h similarity index 100% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.h rename to src/add-ons/kernel/bus_managers/pci/pci_msi.h diff --git a/src/system/kernel/arch/arm/Jamfile b/src/system/kernel/arch/arm/Jamfile index 2690513322..17839c7427 100644 --- a/src/system/kernel/arch/arm/Jamfile +++ b/src/system/kernel/arch/arm/Jamfile @@ -28,6 +28,8 @@ KernelMergeObject kernel_arch_arm.o : arch_vm_translation_map.cpp arch_asm.S + generic_msi.cpp + # Serial UART and drivers debug_uart.cpp debug_uart_8250.cpp diff --git a/src/system/kernel/arch/arm64/Jamfile b/src/system/kernel/arch/arm64/Jamfile index 74e9f7bcea..41c3771e1b 100644 --- a/src/system/kernel/arch/arm64/Jamfile +++ b/src/system/kernel/arch/arm64/Jamfile @@ -31,6 +31,8 @@ KernelMergeObject kernel_arch_arm64.o : VMSAv8TranslationMap.cpp PMAPPhysicalPageMapper.cpp + generic_msi.cpp + # Serial UART and drivers debug_uart.cpp debug_uart_8250.cpp diff --git a/src/system/kernel/arch/generic/generic_msi.cpp b/src/system/kernel/arch/generic/generic_msi.cpp new file mode 100644 index 0000000000..67d9cce84a --- /dev/null +++ b/src/system/kernel/arch/generic/generic_msi.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2022, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include + + +MSIInterface* sMSIInterface; + + +void +msi_set_interface(MSIInterface* interface) +{ + sMSIInterface = interface; +} + + +bool +msi_supported() +{ + return sMSIInterface != NULL; +} + + +status_t +msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address, uint16 *data) +{ + return sMSIInterface->AllocateVectors(count, *startVector, *address, *data); +} + + +void +msi_free_vectors(uint8 count, uint8 startVector) +{ + sMSIInterface->FreeVectors(count, startVector); +} + diff --git a/src/system/kernel/arch/riscv64/Jamfile b/src/system/kernel/arch/riscv64/Jamfile index d7dfde41f1..8045a9276c 100644 --- a/src/system/kernel/arch/riscv64/Jamfile +++ b/src/system/kernel/arch/riscv64/Jamfile @@ -27,6 +27,8 @@ KernelMergeObject kernel_arch_riscv64.o : Htif.cpp sbi_syscalls.S + generic_msi.cpp + # Serial UART drivers debug_uart.cpp debug_uart_8250.cpp