From 629f071bb906679da56af85134f72e69778b3e19 Mon Sep 17 00:00:00 2001 From: X512 Date: Tue, 27 Feb 2024 19:06:14 +0900 Subject: [PATCH] pci: extend MSI interrupt vector number to 32 bits Also increase MSI message data size to 32 bits according to PCIe spec. Remove 0xff check for MSI interrupts because it is potentially valid interrupt vector number. Reject 0xff only for legacy pin interrupts. - MSI-X supports up to 2048 interrupts per device that do not fit to `uint8`. - Non-x86 systems may use separate interrupt vector ranges for hard-wired interrupts and MSI interrupts so `uint8` is not enough to represent all of them. Change-Id: Iaf9ffb197ec23db0f97ffe3ea756d28d7bfc8705 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7433 Reviewed-by: waddlesplash Tested-by: Commit checker robot --- headers/os/drivers/PCI.h | 12 ++++----- headers/os/drivers/bus/PCI.h | 12 ++++----- headers/private/kernel/arch/generic/msi.h | 10 ++++---- headers/private/kernel/arch/x86/msi.h | 2 +- src/add-ons/kernel/bus_managers/pci/pci.cpp | 10 ++++---- src/add-ons/kernel/bus_managers/pci/pci.h | 8 +++--- .../kernel/bus_managers/pci/pci_device.cpp | 4 +-- .../kernel/bus_managers/pci/pci_module.cpp | 10 +++++--- src/add-ons/kernel/bus_managers/pci/pci_msi.h | 16 ++++++------ src/add-ons/kernel/busses/i2c/pch/pch_i2c.cpp | 2 +- src/add-ons/kernel/busses/i2c/pch/pch_i2c.h | 4 +-- .../kernel/busses/i2c/pch/pch_i2c_pci.cpp | 15 ++++++----- .../busses/pci/designware/DWPCIController.h | 6 ++--- .../pci/designware/MsiInterruptCtrlDW.cpp | 5 ++-- .../busses/scsi/ahci/ahci_controller.cpp | 11 +++++--- .../kernel/busses/scsi/ahci/ahci_controller.h | 2 +- src/add-ons/kernel/busses/usb/ehci.cpp | 7 ++++-- src/add-ons/kernel/busses/usb/ehci.h | 2 +- src/add-ons/kernel/busses/usb/ohci.cpp | 7 ++++-- src/add-ons/kernel/busses/usb/ohci.h | 2 +- src/add-ons/kernel/busses/usb/uhci.cpp | 7 ++++-- src/add-ons/kernel/busses/usb/uhci.h | 2 +- src/add-ons/kernel/busses/usb/xhci.cpp | 7 ++++-- src/add-ons/kernel/busses/usb/xhci.h | 2 +- .../busses/virtio/virtio_pci/virtio_pci.cpp | 25 +++++++++++-------- .../drivers/audio/hda/hda_controller.cpp | 12 +++++++-- .../kernel/drivers/disk/nvme/nvme_disk.cpp | 11 +++++--- .../graphics/intel_extreme/intel_extreme.cpp | 11 +++++--- src/libs/compat/freebsd_network/pci.cpp | 4 +-- .../kernel/arch/generic/generic_msi.cpp | 5 ++-- src/system/kernel/arch/x86/msi.cpp | 16 ++++++------ 31 files changed, 143 insertions(+), 106 deletions(-) diff --git a/headers/os/drivers/PCI.h b/headers/os/drivers/PCI.h index 2821e8cf11..0d38df0d5d 100644 --- a/headers/os/drivers/PCI.h +++ b/headers/os/drivers/PCI.h @@ -186,7 +186,7 @@ struct pci_module_info { status_t (*get_powerstate)(uint8 bus, uint8 device, uint8 function, uint8* state); status_t (*set_powerstate)(uint8 bus, uint8 device, uint8 function, uint8 newState); - uint8 (*get_msi_count)( + uint32 (*get_msi_count)( uint8 bus, /* bus number */ uint8 device, /* device # on bus */ uint8 function); /* function # in device */ @@ -195,8 +195,8 @@ struct pci_module_info { uint8 bus, /* bus number */ uint8 device, /* device # on bus */ uint8 function, /* function # in device */ - uint8 count, /* count of vectors desired */ - uint8 *startVector); /* first configured vector */ + uint32 count, /* count of vectors desired */ + uint32 *startVector); /* first configured vector */ status_t (*unconfigure_msi)( uint8 bus, /* bus number */ uint8 device, /* device # on bus */ @@ -211,7 +211,7 @@ struct pci_module_info { uint8 device, /* device # on bus */ uint8 function); /* function # in device */ - uint8 (*get_msix_count)( + uint32 (*get_msix_count)( uint8 bus, /* bus number */ uint8 device, /* device # on bus */ uint8 function); /* function # in device */ @@ -220,8 +220,8 @@ struct pci_module_info { uint8 bus, /* bus number */ uint8 device, /* device # on bus */ uint8 function, /* function # in device */ - uint8 count, /* count of vectors desired */ - uint8 *startVector); /* first configured vector */ + uint32 count, /* count of vectors desired */ + uint32 *startVector); /* first configured vector */ status_t (*enable_msix)( uint8 bus, /* bus number */ uint8 device, /* device # on bus */ diff --git a/headers/os/drivers/bus/PCI.h b/headers/os/drivers/bus/PCI.h index 46c4dd72ff..c227fb3aee 100644 --- a/headers/os/drivers/bus/PCI.h +++ b/headers/os/drivers/bus/PCI.h @@ -40,19 +40,19 @@ typedef struct pci_device_module_info { void (*set_powerstate)(pci_device *device, uint8 state); // MSI/MSI-X - uint8 (*get_msi_count)(pci_device *device); + uint32 (*get_msi_count)(pci_device *device); status_t (*configure_msi)(pci_device *device, - uint8 count, - uint8 *startVector); + uint32 count, + uint32 *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); + uint32 (*get_msix_count)(pci_device *device); status_t (*configure_msix)(pci_device *device, - uint8 count, - uint8 *startVector); + uint32 count, + uint32 *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 index 7b38ef3984..dab480e6f0 100644 --- a/headers/private/kernel/arch/generic/msi.h +++ b/headers/private/kernel/arch/generic/msi.h @@ -13,8 +13,8 @@ class MSIInterface { public: virtual status_t AllocateVectors( - uint8 count, uint8& startVector, uint64& address, uint16& data) = 0; - virtual void FreeVectors(uint8 count, uint8 startVector) = 0; + uint32 count, uint32& startVector, uint64& address, uint32& data) = 0; + virtual void FreeVectors(uint32 count, uint32 startVector) = 0; }; @@ -23,9 +23,9 @@ 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); +status_t msi_allocate_vectors(uint32 count, uint32 *startVector, + uint64 *address, uint32 *data); +void msi_free_vectors(uint32 count, uint32 startVector); #ifdef __cplusplus } diff --git a/headers/private/kernel/arch/x86/msi.h b/headers/private/kernel/arch/x86/msi.h index 6fdf67fe93..c9d5f7e5b8 100644 --- a/headers/private/kernel/arch/x86/msi.h +++ b/headers/private/kernel/arch/x86/msi.h @@ -24,7 +24,7 @@ #define MSI_DELIVERY_MODE_EXT_INT 0x00000700 -void msi_assign_interrupt_to_cpu(uint8 irq, int32 cpu); +void msi_assign_interrupt_to_cpu(uint32 irq, int32 cpu); #endif // _KERNEL_ARCH_x86_MSI_H diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 7794369291..d6b4cdb40b 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -1917,7 +1917,7 @@ PCI::SetPowerstate(uint8 domain, uint8 bus, uint8 _device, uint8 function, //#pragma mark - MSI -uint8 +uint32 PCI::GetMSICount(PCIDev *device) { if (!msi_supported()) @@ -1932,7 +1932,7 @@ PCI::GetMSICount(PCIDev *device) status_t -PCI::ConfigureMSI(PCIDev *device, uint8 count, uint8 *startVector) +PCI::ConfigureMSI(PCIDev *device, uint32 count, uint32 *startVector) { if (!msi_supported()) return B_UNSUPPORTED; @@ -2070,7 +2070,7 @@ PCI::DisableMSI(PCIDev *device) } -uint8 +uint32 PCI::GetMSIXCount(PCIDev *device) { if (!msi_supported()) @@ -2085,7 +2085,7 @@ PCI::GetMSIXCount(PCIDev *device) status_t -PCI::ConfigureMSIX(PCIDev *device, uint8 count, uint8 *startVector) +PCI::ConfigureMSIX(PCIDev *device, uint32 count, uint32 *startVector) { if (!msi_supported()) return B_UNSUPPORTED; @@ -2170,7 +2170,7 @@ PCI::ConfigureMSIX(PCIDev *device, uint8 count, uint8 *startVector) info->configured_count = count; *startVector = info->start_vector; - dprintf("msix configured for %d vectors\n", count); + dprintf("msix configured for %" B_PRIu32 " vectors\n", count); return B_OK; } diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 56b413de71..13f9e5ee9a 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -140,13 +140,13 @@ public: uint8 device, uint8 function, uint8 newInterruptLineValue); - uint8 GetMSICount(PCIDev *device); - status_t ConfigureMSI(PCIDev *device, uint8 count, uint8 *startVector); + uint32 GetMSICount(PCIDev *device); + status_t ConfigureMSI(PCIDev *device, uint32 count, uint32 *startVector); status_t UnconfigureMSI(PCIDev *device); status_t EnableMSI(PCIDev *device); status_t DisableMSI(PCIDev *device); - uint8 GetMSIXCount(PCIDev *device); - status_t ConfigureMSIX(PCIDev *device, uint8 count, uint8 *startVector); + uint32 GetMSIXCount(PCIDev *device); + status_t ConfigureMSIX(PCIDev *device, uint32 count, uint32 *startVector); status_t EnableMSIX(PCIDev *device); private: diff --git a/src/add-ons/kernel/bus_managers/pci/pci_device.cpp b/src/add-ons/kernel/bus_managers/pci/pci_device.cpp index 2e3531e3d5..805a6ae988 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_device.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_device.cpp @@ -134,7 +134,7 @@ pci_device_module_info gPCIDeviceModule = { .get_msi_count = [](pci_device *device) { return gPCI->GetMSICount(device->device); }, - .configure_msi = [](pci_device *device, uint8 count, uint8 *startVector) { + .configure_msi = [](pci_device *device, uint32 count, uint32 *startVector) { return gPCI->ConfigureMSI(device->device, count, startVector); }, .unconfigure_msi = [](pci_device *device) { @@ -149,7 +149,7 @@ pci_device_module_info gPCIDeviceModule = { .get_msix_count = [](pci_device *device) { return gPCI->GetMSIXCount(device->device); }, - .configure_msix = [](pci_device *device, uint8 count, uint8 *startVector) { + .configure_msix = [](pci_device *device, uint32 count, uint32 *startVector) { return gPCI->ConfigureMSIX(device->device, count, startVector); }, .enable_msix = [](pci_device *device) { 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 49a8192801..0ccafafe0a 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp @@ -95,10 +95,11 @@ static struct pci_module_info sOldPCIModule = { .get_msi_count = [](uint8 bus, uint8 device, uint8 function) { PCIDev* dev; if (ResolveBDF(bus, device, function, dev) < B_OK) - return (uint8)0; + return (uint32)0; return gPCI->GetMSICount(dev); }, - .configure_msi = [](uint8 bus, uint8 device, uint8 function, uint8 count, uint8 *startVector) { + .configure_msi = [](uint8 bus, uint8 device, uint8 function, uint32 count, + uint32 *startVector) { PCIDev* dev; CHECK_RET(ResolveBDF(bus, device, function, dev)); return gPCI->ConfigureMSI(dev, count, startVector); @@ -121,10 +122,11 @@ static struct pci_module_info sOldPCIModule = { .get_msix_count = [](uint8 bus, uint8 device, uint8 function) { PCIDev* dev; if (ResolveBDF(bus, device, function, dev) < B_OK) - return (uint8)0; + return (uint32)0; return gPCI->GetMSIXCount(dev); }, - .configure_msix = [](uint8 bus, uint8 device, uint8 function, uint8 count, uint8 *startVector) { + .configure_msix = [](uint8 bus, uint8 device, uint8 function, uint32 count, + uint32 *startVector) { PCIDev* dev; CHECK_RET(ResolveBDF(bus, device, function, dev)); return gPCI->ConfigureMSIX(dev, count, startVector); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_msi.h b/src/add-ons/kernel/bus_managers/pci/pci_msi.h index d32da7afe7..084513faa2 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_msi.h +++ b/src/add-ons/kernel/bus_managers/pci/pci_msi.h @@ -17,11 +17,11 @@ typedef struct msi_info { bool msi_capable; uint8 capability_offset; - uint8 message_count; - uint8 configured_count; - uint8 start_vector; + uint32 message_count; + uint32 configured_count; + uint32 start_vector; uint16 control_value; - uint16 data_value; + uint32 data_value; uint64 address_value; } msi_info; @@ -30,7 +30,7 @@ typedef struct msi_info { typedef struct msix_info { bool msix_capable; uint8 capability_offset; - uint8 message_count; + uint32 message_count; uint8 table_bar; uint32 table_offset; area_id table_area_id; @@ -39,10 +39,10 @@ typedef struct msix_info { uint32 pba_offset; area_id pba_area_id; addr_t pba_address; - uint8 configured_count; - uint8 start_vector; + uint32 configured_count; + uint32 start_vector; uint16 control_value; - uint16 data_value; + uint32 data_value; uint64 address_value; } msix_info; diff --git a/src/add-ons/kernel/busses/i2c/pch/pch_i2c.cpp b/src/add-ons/kernel/busses/i2c/pch/pch_i2c.cpp index dbe451f499..19a4bd20ef 100644 --- a/src/add-ons/kernel/busses/i2c/pch/pch_i2c.cpp +++ b/src/add-ons/kernel/busses/i2c/pch/pch_i2c.cpp @@ -402,7 +402,7 @@ init_bus(device_node* node, void** bus_cookie) gDeviceManager->put_node(parent); TRACE_ALWAYS("init_bus() addr 0x%" B_PRIxPHYSADDR " size 0x%" B_PRIx64 - " irq 0x%x\n", bus->base_addr, bus->map_size, bus->irq); + " irq 0x%" B_PRIx32 "\n", bus->base_addr, bus->map_size, bus->irq); bus->registersArea = map_physical_memory("PCHI2C memory mapped registers", bus->base_addr, bus->map_size, B_ANY_KERNEL_ADDRESS, diff --git a/src/add-ons/kernel/busses/i2c/pch/pch_i2c.h b/src/add-ons/kernel/busses/i2c/pch/pch_i2c.h index 360323e12e..c28cade999 100644 --- a/src/add-ons/kernel/busses/i2c/pch/pch_i2c.h +++ b/src/add-ons/kernel/busses/i2c/pch/pch_i2c.h @@ -53,7 +53,7 @@ acpi_status pch_i2c_scan_bus_callback(acpi_handle object, uint32 nestingLevel, struct pch_i2c_crs { uint16 i2c_addr; - uint8 irq; + uint32 irq; uint8 irq_triggering; uint8 irq_polarity; uint8 irq_shareable; @@ -73,7 +73,7 @@ typedef enum { typedef struct { phys_addr_t base_addr; uint64 map_size; - uint8 irq; + uint32 irq; i2c_bus sim; device_node* node; diff --git a/src/add-ons/kernel/busses/i2c/pch/pch_i2c_pci.cpp b/src/add-ons/kernel/busses/i2c/pch/pch_i2c_pci.cpp index 9d58078f5e..f65043e9ac 100644 --- a/src/add-ons/kernel/busses/i2c/pch/pch_i2c_pci.cpp +++ b/src/add-ons/kernel/busses/i2c/pch/pch_i2c_pci.cpp @@ -150,10 +150,10 @@ init_device(device_node* node, void** device_cookie) // try MSI-X if (pci->get_msix_count(device) >= 1) { - uint8 vector; + uint32 vector; if (pci->configure_msix(device, 1, &vector) == B_OK && pci->enable_msix(device) == B_OK) { - TRACE_ALWAYS("using MSI-X vector %u\n", vector); + TRACE_ALWAYS("using MSI-X vector %" B_PRIu32 "\n", vector); bus->info.irq = vector; bus->irq_type = PCH_I2C_IRQ_MSI_X_SHARED; } else { @@ -161,10 +161,10 @@ init_device(device_node* node, void** device_cookie) } } else if (pci->get_msi_count(device) >= 1) { // try MSI - uint8 vector; + uint32 vector; if (pci->configure_msi(device, 1, &vector) == B_OK && pci->enable_msi(device) == B_OK) { - TRACE_ALWAYS("using MSI vector %u\n", vector); + TRACE_ALWAYS("using MSI vector %" B_PRIu32 "\n", vector); bus->info.irq = vector; bus->irq_type = PCH_I2C_IRQ_MSI; } else { @@ -173,9 +173,12 @@ init_device(device_node* node, void** device_cookie) } if (bus->irq_type == PCH_I2C_IRQ_LEGACY) { bus->info.irq = pciInfo->u.h0.interrupt_line; - TRACE_ALWAYS("using legacy interrupt %u\n", bus->info.irq); + if (bus->info.irq == 0xff) + bus->info.irq = 0; + + TRACE_ALWAYS("using legacy interrupt %" B_PRIu32 "\n", bus->info.irq); } - if (bus->info.irq == 0 || bus->info.irq == 0xff) { + if (bus->info.irq == 0) { ERROR("PCI IRQ not assigned\n"); status = B_ERROR; goto err; diff --git a/src/add-ons/kernel/busses/pci/designware/DWPCIController.h b/src/add-ons/kernel/busses/pci/designware/DWPCIController.h index 0a1a07964b..c61934e69e 100644 --- a/src/add-ons/kernel/busses/pci/designware/DWPCIController.h +++ b/src/add-ons/kernel/busses/pci/designware/DWPCIController.h @@ -165,9 +165,9 @@ public: status_t Init(PciDbiRegs volatile* dbiRegs, int32 msiIrq); - status_t AllocateVectors(uint8 count, uint8& startVector, uint64& address, - uint16& data) final; - void FreeVectors(uint8 count, uint8 startVector) final; + status_t AllocateVectors(uint32 count, uint32& startVector, uint64& address, + uint32& data) final; + void FreeVectors(uint32 count, uint32 startVector) final; private: diff --git a/src/add-ons/kernel/busses/pci/designware/MsiInterruptCtrlDW.cpp b/src/add-ons/kernel/busses/pci/designware/MsiInterruptCtrlDW.cpp index 932fde4157..9b29f619ae 100644 --- a/src/add-ons/kernel/busses/pci/designware/MsiInterruptCtrlDW.cpp +++ b/src/add-ons/kernel/busses/pci/designware/MsiInterruptCtrlDW.cpp @@ -53,7 +53,8 @@ MsiInterruptCtrlDW::Init(PciDbiRegs volatile* dbiRegs, int32 msiIrq) status_t -MsiInterruptCtrlDW::AllocateVectors(uint8 count, uint8& startVector, uint64& address, uint16& data) +MsiInterruptCtrlDW::AllocateVectors(uint32 count, uint32& startVector, uint64& address, + uint32& data) { if (count != 1) return B_ERROR; @@ -74,7 +75,7 @@ MsiInterruptCtrlDW::AllocateVectors(uint8 count, uint8& startVector, uint64& add void -MsiInterruptCtrlDW::FreeVectors(uint8 count, uint8 startVector) +MsiInterruptCtrlDW::FreeVectors(uint32 count, uint32 startVector) { int32 irq = (int32)startVector - fMsiStartIrq; while (count > 0) { diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp index 362f864b9c..b52f81b813 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp @@ -102,18 +102,21 @@ AHCIController::Init() } fIRQ = pciInfo.u.h0.interrupt_line; + if (fIRQ == 0xff) + fIRQ = 0; + if (fPCI->get_msi_count(fPCIDevice) >= 1) { - uint8 vector; + uint32 vector; if (fPCI->configure_msi(fPCIDevice, 1, &vector) == B_OK && fPCI->enable_msi(fPCIDevice) == B_OK) { - TRACE("using MSI vector %u\n", vector); + TRACE("using MSI vector %" B_PRIu32 "\n", vector); fIRQ = vector; fUseMSI = true; } else { TRACE("couldn't use MSI\n"); } } - if (fIRQ == 0 || fIRQ == 0xff) { + if (fIRQ == 0) { TRACE("Error: PCI IRQ not assigned\n"); return B_ERROR; } @@ -215,7 +218,7 @@ AHCIController::Init() TRACE("Ports Implemented Mask: %#08" B_PRIx32 " Number of Available Ports:" " %d\n", fPortImplementedMask, count_bits_set(fPortImplementedMask)); TRACE("AHCI Version %02" B_PRIx32 "%02" B_PRIx32 ".%02" B_PRIx32 ".%02" - B_PRIx32 " Interrupt %u\n", fRegs->vs >> 24, (fRegs->vs >> 16) & 0xff, + B_PRIx32 " Interrupt %" B_PRIu32 "\n", fRegs->vs >> 24, (fRegs->vs >> 16) & 0xff, (fRegs->vs >> 8) & 0xff, fRegs->vs & 0xff, fIRQ); // setup interrupt handler diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h index ccbba641f5..d4e2efb4c0 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h @@ -51,7 +51,7 @@ private: int fCommandSlotCount; int fPortCount; uint32 fPortImplementedMask; - uint8 fIRQ; + uint32 fIRQ; bool fUseMSI; AHCIPort * fPort[32]; diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index e294692a62..b9185e91cd 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -572,8 +572,11 @@ EHCI::EHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stac } else { // Find the right interrupt vector, using MSIs if available. fIRQ = fPCIInfo->u.h0.interrupt_line; + if (fIRQ == 0xFF) + fIRQ = 0; + if (fPci->get_msi_count(fDevice) >= 1) { - uint8 msiVector = 0; + uint32 msiVector = 0; if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK && fPci->enable_msi(fDevice) == B_OK) { TRACE_ALWAYS("using message signaled interrupts\n"); @@ -582,7 +585,7 @@ EHCI::EHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stac } } - if (fIRQ == 0 || fIRQ == 0xFF) { + if (fIRQ == 0) { TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n", fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function); return; diff --git a/src/add-ons/kernel/busses/usb/ehci.h b/src/add-ons/kernel/busses/usb/ehci.h index eaba43d881..d4eba12f2b 100644 --- a/src/add-ons/kernel/busses/usb/ehci.h +++ b/src/add-ons/kernel/busses/usb/ehci.h @@ -255,7 +255,7 @@ inline uint32 ReadCapReg32(uint32 reg); // Interrupt polling thread_id fInterruptPollThread; - uint8 fIRQ; + uint32 fIRQ; bool fUseMSI; }; diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index 5c27752eb2..e7b679c351 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -544,8 +544,11 @@ OHCI::OHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stac // Find the right interrupt vector, using MSIs if available. fIRQ = fPCIInfo->u.h0.interrupt_line; + if (fIRQ == 0xFF) + fIRQ = 0; + if (fPci->get_msi_count(fDevice) >= 1) { - uint8 msiVector = 0; + uint32 msiVector = 0; if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK && fPci->enable_msi(fDevice) == B_OK) { TRACE_ALWAYS("using message signaled interrupts\n"); @@ -554,7 +557,7 @@ OHCI::OHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stac } } - if (fIRQ == 0 || fIRQ == 0xFF) { + if (fIRQ == 0) { TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n", fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function); return; diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index cf3e43efa4..98a31d7bfe 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -220,7 +220,7 @@ inline uint32 _ReadReg(uint32 reg); // Port management uint8 fPortCount; - uint8 fIRQ; + uint32 fIRQ; bool fUseMSI; }; diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp b/src/add-ons/kernel/busses/usb/uhci.cpp index 0581b09042..8256c8b8a5 100644 --- a/src/add-ons/kernel/busses/usb/uhci.cpp +++ b/src/add-ons/kernel/busses/usb/uhci.cpp @@ -684,8 +684,11 @@ UHCI::UHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stac // Find the right interrupt vector, using MSIs if available. fIRQ = fPCIInfo->u.h0.interrupt_line; + if (fIRQ == 0xFF) + fIRQ = 0; + if (fPci->get_msi_count(fDevice) >= 1) { - uint8 msiVector = 0; + uint32 msiVector = 0; if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK && fPci->enable_msi(fDevice) == B_OK) { TRACE_ALWAYS("using message signaled interrupts\n"); @@ -694,7 +697,7 @@ UHCI::UHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stac } } - if (fIRQ == 0 || fIRQ == 0xFF) { + if (fIRQ == 0) { TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n", fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function); return; diff --git a/src/add-ons/kernel/busses/usb/uhci.h b/src/add-ons/kernel/busses/usb/uhci.h index 61046567b9..a6db03bb30 100644 --- a/src/add-ons/kernel/busses/usb/uhci.h +++ b/src/add-ons/kernel/busses/usb/uhci.h @@ -256,7 +256,7 @@ inline uint32 ReadReg32(uint32 reg); uint8 fRootHubAddress; uint8 fPortResetChange; - uint8 fIRQ; + uint32 fIRQ; bool fUseMSI; }; diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index 6121ca4a1b..3aef714ece 100644 --- a/src/add-ons/kernel/busses/usb/xhci.cpp +++ b/src/add-ons/kernel/busses/usb/xhci.cpp @@ -528,6 +528,9 @@ XHCI::XHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Sta // Find the right interrupt vector, using MSIs if available. fIRQ = fPCIInfo->u.h0.interrupt_line; + if (fIRQ == 0xFF) + fIRQ = 0; + #if 0 if (fPci->get_msix_count(fDevice) >= 1) { uint8 msiVector = 0; @@ -540,7 +543,7 @@ XHCI::XHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Sta } else #endif if (fPci->get_msi_count(fDevice) >= 1) { - uint8 msiVector = 0; + uint32 msiVector = 0; if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK && fPci->enable_msi(fDevice) == B_OK) { TRACE_ALWAYS("using message signaled interrupts\n"); @@ -549,7 +552,7 @@ XHCI::XHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Sta } } - if (fIRQ == 0 || fIRQ == 0xFF) { + if (fIRQ == 0) { TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n", fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function); return; diff --git a/src/add-ons/kernel/busses/usb/xhci.h b/src/add-ons/kernel/busses/usb/xhci.h index fbc7307331..e38f2db76e 100644 --- a/src/add-ons/kernel/busses/usb/xhci.h +++ b/src/add-ons/kernel/busses/usb/xhci.h @@ -236,7 +236,7 @@ private: pci_device* fDevice; Stack * fStack; - uint8 fIRQ; + uint32 fIRQ; bool fUseMSI; area_id fErstArea; diff --git a/src/add-ons/kernel/busses/virtio/virtio_pci/virtio_pci.cpp b/src/add-ons/kernel/busses/virtio/virtio_pci/virtio_pci.cpp index 1a7e72a457..03dd2bd123 100644 --- a/src/add-ons/kernel/busses/virtio/virtio_pci/virtio_pci.cpp +++ b/src/add-ons/kernel/busses/virtio/virtio_pci/virtio_pci.cpp @@ -54,7 +54,7 @@ typedef struct { addr_t isrAddr; addr_t notifyAddr; uint32 notifyOffsetMultiplier; - uint8 irq; + uint32 irq; virtio_irq_type irq_type; virtio_sim sim; uint16 queue_count; @@ -460,28 +460,29 @@ setup_interrupt(void* cookie, uint16 queueCount) bus->queue_count = queueCount; // try MSI-X - uint8 msixCount = bus->pci->get_msix_count(bus->device); + uint32 msixCount = bus->pci->get_msix_count(bus->device); if (msixCount >= 2) { - if (msixCount >= (queueCount + 1)) { - uint8 vector; + uint32 vectorCount = queueCount + 1; + if (msixCount >= vectorCount) { + uint32 vector; bus->cookies = new(std::nothrow) virtio_pci_queue_cookie[queueCount]; if (bus->cookies != NULL - && bus->pci->configure_msix(bus->device, queueCount + 1, + && bus->pci->configure_msix(bus->device, vectorCount, &vector) == B_OK && bus->pci->enable_msix(bus->device) == B_OK) { - TRACE_ALWAYS("using MSI-X count %u starting at %d\n", - queueCount + 1, vector); + TRACE_ALWAYS("using MSI-X count %" B_PRIu32 " starting at %" B_PRIu32 "\n", + vectorCount, vector); bus->irq = vector; bus->irq_type = VIRTIO_IRQ_MSI_X; } else { ERROR("couldn't use MSI-X\n"); } } else { - uint8 vector; + uint32 vector; if (bus->pci->configure_msix(bus->device, 2, &vector) == B_OK && bus->pci->enable_msix(bus->device) == B_OK) { - TRACE_ALWAYS("using MSI-X vector shared %u\n", vector); + TRACE_ALWAYS("using MSI-X vector shared %" B_PRIu32 "\n", vector); bus->irq = vector; bus->irq_type = VIRTIO_IRQ_MSI_X_SHARED; } else { @@ -492,9 +493,11 @@ setup_interrupt(void* cookie, uint16 queueCount) if (bus->irq_type == VIRTIO_IRQ_LEGACY) { bus->irq = pciInfo->u.h0.interrupt_line; - TRACE_ALWAYS("using legacy interrupt %u\n", bus->irq); + if (bus->irq == 0xff) + bus->irq = 0; + TRACE_ALWAYS("using legacy interrupt %" B_PRIu32 "\n", bus->irq); } - if (bus->irq == 0 || bus->irq == 0xff) { + if (bus->irq == 0) { ERROR("PCI IRQ not assigned\n"); delete bus; return B_ERROR; diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp index 7a328f4ef6..b202173ffb 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp @@ -1153,20 +1153,28 @@ hda_hw_init(hda_controller* controller) controller->irq = pciInfo.u.h0.interrupt_line; controller->msi = false; + if (controller->irq == 0xff) + controller->irq = 0; + if ((quirks & HDA_QUIRK_NO_MSI) == 0 && gPci->get_msi_count(pciInfo.bus, pciInfo.device, pciInfo.function) >= 1) { // Try MSI first - uint8 vector; + uint32 vector; if (gPci->configure_msi(pciInfo.bus, pciInfo.device, pciInfo.function, 1, &vector) == B_OK && gPci->enable_msi( pciInfo.bus, pciInfo.device, pciInfo.function) == B_OK) { - dprintf("hda: using MSI vector %u\n", vector); + dprintf("hda: using MSI vector %" B_PRIu32 "\n", vector); controller->irq = vector; controller->msi = true; } } + if (controller->irq == 0) { + status = ENODEV; + goto no_irq_handler; + } + status = install_io_interrupt_handler(controller->irq, (interrupt_handler)hda_interrupt_handler, controller, 0); if (status != B_OK) diff --git a/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp b/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp index d127d022f0..f259f8a9b3 100644 --- a/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp @@ -229,16 +229,19 @@ nvme_disk_init_device(void* _info, void** _cookie) command &= ~(PCI_command_int_disable); pci->write_pci_config(pcidev, PCI_command, 2, command); - uint8 irq = info->info.u.h0.interrupt_line; + uint32 irq = info->info.u.h0.interrupt_line; + if (irq == 0xFF) + irq = 0; + if (pci->get_msix_count(pcidev)) { - uint8 msixVector = 0; + uint32 msixVector = 0; if (pci->configure_msix(pcidev, 1, &msixVector) == B_OK && pci->enable_msix(pcidev) == B_OK) { TRACE_ALWAYS("using MSI-X\n"); irq = msixVector; } } else if (pci->get_msi_count(pcidev) >= 1) { - uint8 msiVector = 0; + uint32 msiVector = 0; if (pci->configure_msi(pcidev, 1, &msiVector) == B_OK && pci->enable_msi(pcidev) == B_OK) { TRACE_ALWAYS("using message signaled interrupts\n"); @@ -246,7 +249,7 @@ nvme_disk_init_device(void* _info, void** _cookie) } } - if (irq == 0 || irq == 0xFF) { + if (irq == 0) { TRACE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n", info->info.bus, info->info.device, info->info.function); info->polling = 1; diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index b25991e3db..8f8c575ef9 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -443,13 +443,16 @@ init_interrupt_handler(intel_info &info) } // Find the right interrupt vector, using MSIs if available. - info.irq = 0xff; + info.irq = 0; info.use_msi = false; - if (info.pci->u.h0.interrupt_pin != 0x00) + if (info.pci->u.h0.interrupt_pin != 0x00) { info.irq = info.pci->u.h0.interrupt_line; + if (info.irq == 0xff) + info.irq = 0; + } if (gPCI->get_msi_count(info.pci->bus, info.pci->device, info.pci->function) >= 1) { - uint8 msiVector = 0; + uint32 msiVector = 0; if (gPCI->configure_msi(info.pci->bus, info.pci->device, info.pci->function, 1, &msiVector) == B_OK && gPCI->enable_msi(info.pci->bus, info.pci->device, @@ -460,7 +463,7 @@ init_interrupt_handler(intel_info &info) } } - if (status == B_OK && info.irq != 0xff) { + if (status == B_OK && info.irq != 0) { // we've gotten an interrupt line for us to use info.fake_interrupts = false; diff --git a/src/libs/compat/freebsd_network/pci.cpp b/src/libs/compat/freebsd_network/pci.cpp index a3f827fcff..774b8b378a 100644 --- a/src/libs/compat/freebsd_network/pci.cpp +++ b/src/libs/compat/freebsd_network/pci.cpp @@ -265,7 +265,7 @@ int pci_alloc_msi(device_t dev, int *count) { pci_info* info = get_device_pci_info(dev); - uint8 startVector = 0; + uint32 startVector = 0; if (gPci->configure_msi(info->bus, info->device, info->function, *count, &startVector) != B_OK) { return ENODEV; @@ -318,7 +318,7 @@ int pci_alloc_msix(device_t dev, int *count) { pci_info* info = get_device_pci_info(dev); - uint8 startVector = 0; + uint32 startVector = 0; if (gPci->configure_msix(info->bus, info->device, info->function, *count, &startVector) != B_OK) { return ENODEV; diff --git a/src/system/kernel/arch/generic/generic_msi.cpp b/src/system/kernel/arch/generic/generic_msi.cpp index 67d9cce84a..b2f0cc0082 100644 --- a/src/system/kernel/arch/generic/generic_msi.cpp +++ b/src/system/kernel/arch/generic/generic_msi.cpp @@ -25,15 +25,14 @@ msi_supported() status_t -msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address, uint16 *data) +msi_allocate_vectors(uint32 count, uint32 *startVector, uint64 *address, uint32 *data) { return sMSIInterface->AllocateVectors(count, *startVector, *address, *data); } void -msi_free_vectors(uint8 count, uint8 startVector) +msi_free_vectors(uint32 count, uint32 startVector) { sMSIInterface->FreeVectors(count, startVector); } - diff --git a/src/system/kernel/arch/x86/msi.cpp b/src/system/kernel/arch/x86/msi.cpp index 64dc74ae45..1f11b73de7 100644 --- a/src/system/kernel/arch/x86/msi.cpp +++ b/src/system/kernel/arch/x86/msi.cpp @@ -14,7 +14,7 @@ struct MSIConfiguration { uint64* fAddress; - uint16* fData; + uint32* fData; }; static MSIConfiguration sMSIConfigurations[NUM_IO_VECTORS]; @@ -45,8 +45,8 @@ msi_supported() status_t -msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address, - uint16 *data) +msi_allocate_vectors(uint32 count, uint32 *startVector, uint64 *address, + uint32 *data) { if (!sMSISupported) return B_UNSUPPORTED; @@ -66,27 +66,27 @@ msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address, sMSIConfigurations[vector].fData = data; x86_set_irq_source(vector, IRQ_SOURCE_MSI); - *startVector = (uint8)vector; + *startVector = (uint32)vector; *address = MSI_ADDRESS_BASE | (sBootCPUAPICId << MSI_DESTINATION_ID_SHIFT) | MSI_NO_REDIRECTION | MSI_DESTINATION_MODE_PHYSICAL; *data = MSI_TRIGGER_MODE_EDGE | MSI_DELIVERY_MODE_FIXED | ((uint16)vector + ARCH_INTERRUPT_BASE); - dprintf("msi_allocate_vectors: allocated %u vectors starting from %u\n", + dprintf("msi_allocate_vectors: allocated %" B_PRIu32 " vectors starting from %" B_PRIu32 "\n", count, *startVector); return B_OK; } void -msi_free_vectors(uint8 count, uint8 startVector) +msi_free_vectors(uint32 count, uint32 startVector) { if (!sMSISupported) { panic("trying to free msi vectors but msi not supported\n"); return; } - dprintf("msi_free_vectors: freeing %u vectors starting from %u\n", count, + dprintf("msi_free_vectors: freeing %" B_PRIu32 " vectors starting from %" B_PRIu32 "\n", count, startVector); free_io_interrupt_vectors(count, startVector); @@ -94,7 +94,7 @@ msi_free_vectors(uint8 count, uint8 startVector) void -msi_assign_interrupt_to_cpu(uint8 irq, int32 cpu) +msi_assign_interrupt_to_cpu(uint32 irq, int32 cpu) { uint32 apic_id = x86_get_cpu_apic_id(cpu);