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 <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
@@ -186,7 +186,7 @@ struct pci_module_info {
|
|||||||
status_t (*get_powerstate)(uint8 bus, uint8 device, uint8 function, uint8* state);
|
status_t (*get_powerstate)(uint8 bus, uint8 device, uint8 function, uint8* state);
|
||||||
status_t (*set_powerstate)(uint8 bus, uint8 device, uint8 function, uint8 newState);
|
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 bus, /* bus number */
|
||||||
uint8 device, /* device # on bus */
|
uint8 device, /* device # on bus */
|
||||||
uint8 function); /* function # in device */
|
uint8 function); /* function # in device */
|
||||||
@@ -195,8 +195,8 @@ struct pci_module_info {
|
|||||||
uint8 bus, /* bus number */
|
uint8 bus, /* bus number */
|
||||||
uint8 device, /* device # on bus */
|
uint8 device, /* device # on bus */
|
||||||
uint8 function, /* function # in device */
|
uint8 function, /* function # in device */
|
||||||
uint8 count, /* count of vectors desired */
|
uint32 count, /* count of vectors desired */
|
||||||
uint8 *startVector); /* first configured vector */
|
uint32 *startVector); /* first configured vector */
|
||||||
status_t (*unconfigure_msi)(
|
status_t (*unconfigure_msi)(
|
||||||
uint8 bus, /* bus number */
|
uint8 bus, /* bus number */
|
||||||
uint8 device, /* device # on bus */
|
uint8 device, /* device # on bus */
|
||||||
@@ -211,7 +211,7 @@ struct pci_module_info {
|
|||||||
uint8 device, /* device # on bus */
|
uint8 device, /* device # on bus */
|
||||||
uint8 function); /* function # in device */
|
uint8 function); /* function # in device */
|
||||||
|
|
||||||
uint8 (*get_msix_count)(
|
uint32 (*get_msix_count)(
|
||||||
uint8 bus, /* bus number */
|
uint8 bus, /* bus number */
|
||||||
uint8 device, /* device # on bus */
|
uint8 device, /* device # on bus */
|
||||||
uint8 function); /* function # in device */
|
uint8 function); /* function # in device */
|
||||||
@@ -220,8 +220,8 @@ struct pci_module_info {
|
|||||||
uint8 bus, /* bus number */
|
uint8 bus, /* bus number */
|
||||||
uint8 device, /* device # on bus */
|
uint8 device, /* device # on bus */
|
||||||
uint8 function, /* function # in device */
|
uint8 function, /* function # in device */
|
||||||
uint8 count, /* count of vectors desired */
|
uint32 count, /* count of vectors desired */
|
||||||
uint8 *startVector); /* first configured vector */
|
uint32 *startVector); /* first configured vector */
|
||||||
status_t (*enable_msix)(
|
status_t (*enable_msix)(
|
||||||
uint8 bus, /* bus number */
|
uint8 bus, /* bus number */
|
||||||
uint8 device, /* device # on bus */
|
uint8 device, /* device # on bus */
|
||||||
|
|||||||
@@ -40,19 +40,19 @@ typedef struct pci_device_module_info {
|
|||||||
void (*set_powerstate)(pci_device *device, uint8 state);
|
void (*set_powerstate)(pci_device *device, uint8 state);
|
||||||
|
|
||||||
// MSI/MSI-X
|
// MSI/MSI-X
|
||||||
uint8 (*get_msi_count)(pci_device *device);
|
uint32 (*get_msi_count)(pci_device *device);
|
||||||
status_t (*configure_msi)(pci_device *device,
|
status_t (*configure_msi)(pci_device *device,
|
||||||
uint8 count,
|
uint32 count,
|
||||||
uint8 *startVector);
|
uint32 *startVector);
|
||||||
status_t (*unconfigure_msi)(pci_device *device);
|
status_t (*unconfigure_msi)(pci_device *device);
|
||||||
|
|
||||||
status_t (*enable_msi)(pci_device *device);
|
status_t (*enable_msi)(pci_device *device);
|
||||||
status_t (*disable_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,
|
status_t (*configure_msix)(pci_device *device,
|
||||||
uint8 count,
|
uint32 count,
|
||||||
uint8 *startVector);
|
uint32 *startVector);
|
||||||
status_t (*enable_msix)(pci_device *device);
|
status_t (*enable_msix)(pci_device *device);
|
||||||
|
|
||||||
} pci_device_module_info;
|
} pci_device_module_info;
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
class MSIInterface {
|
class MSIInterface {
|
||||||
public:
|
public:
|
||||||
virtual status_t AllocateVectors(
|
virtual status_t AllocateVectors(
|
||||||
uint8 count, uint8& startVector, uint64& address, uint16& data) = 0;
|
uint32 count, uint32& startVector, uint64& address, uint32& data) = 0;
|
||||||
virtual void FreeVectors(uint8 count, uint8 startVector) = 0;
|
virtual void FreeVectors(uint32 count, uint32 startVector) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -23,9 +23,9 @@ void msi_set_interface(MSIInterface* interface);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool msi_supported();
|
bool msi_supported();
|
||||||
status_t msi_allocate_vectors(uint8 count, uint8 *startVector,
|
status_t msi_allocate_vectors(uint32 count, uint32 *startVector,
|
||||||
uint64 *address, uint16 *data);
|
uint64 *address, uint32 *data);
|
||||||
void msi_free_vectors(uint8 count, uint8 startVector);
|
void msi_free_vectors(uint32 count, uint32 startVector);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#define MSI_DELIVERY_MODE_EXT_INT 0x00000700
|
#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
|
#endif // _KERNEL_ARCH_x86_MSI_H
|
||||||
|
|||||||
@@ -1917,7 +1917,7 @@ PCI::SetPowerstate(uint8 domain, uint8 bus, uint8 _device, uint8 function,
|
|||||||
|
|
||||||
//#pragma mark - MSI
|
//#pragma mark - MSI
|
||||||
|
|
||||||
uint8
|
uint32
|
||||||
PCI::GetMSICount(PCIDev *device)
|
PCI::GetMSICount(PCIDev *device)
|
||||||
{
|
{
|
||||||
if (!msi_supported())
|
if (!msi_supported())
|
||||||
@@ -1932,7 +1932,7 @@ PCI::GetMSICount(PCIDev *device)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PCI::ConfigureMSI(PCIDev *device, uint8 count, uint8 *startVector)
|
PCI::ConfigureMSI(PCIDev *device, uint32 count, uint32 *startVector)
|
||||||
{
|
{
|
||||||
if (!msi_supported())
|
if (!msi_supported())
|
||||||
return B_UNSUPPORTED;
|
return B_UNSUPPORTED;
|
||||||
@@ -2070,7 +2070,7 @@ PCI::DisableMSI(PCIDev *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8
|
uint32
|
||||||
PCI::GetMSIXCount(PCIDev *device)
|
PCI::GetMSIXCount(PCIDev *device)
|
||||||
{
|
{
|
||||||
if (!msi_supported())
|
if (!msi_supported())
|
||||||
@@ -2085,7 +2085,7 @@ PCI::GetMSIXCount(PCIDev *device)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PCI::ConfigureMSIX(PCIDev *device, uint8 count, uint8 *startVector)
|
PCI::ConfigureMSIX(PCIDev *device, uint32 count, uint32 *startVector)
|
||||||
{
|
{
|
||||||
if (!msi_supported())
|
if (!msi_supported())
|
||||||
return B_UNSUPPORTED;
|
return B_UNSUPPORTED;
|
||||||
@@ -2170,7 +2170,7 @@ PCI::ConfigureMSIX(PCIDev *device, uint8 count, uint8 *startVector)
|
|||||||
|
|
||||||
info->configured_count = count;
|
info->configured_count = count;
|
||||||
*startVector = info->start_vector;
|
*startVector = info->start_vector;
|
||||||
dprintf("msix configured for %d vectors\n", count);
|
dprintf("msix configured for %" B_PRIu32 " vectors\n", count);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,13 +140,13 @@ public:
|
|||||||
uint8 device, uint8 function,
|
uint8 device, uint8 function,
|
||||||
uint8 newInterruptLineValue);
|
uint8 newInterruptLineValue);
|
||||||
|
|
||||||
uint8 GetMSICount(PCIDev *device);
|
uint32 GetMSICount(PCIDev *device);
|
||||||
status_t ConfigureMSI(PCIDev *device, uint8 count, uint8 *startVector);
|
status_t ConfigureMSI(PCIDev *device, uint32 count, uint32 *startVector);
|
||||||
status_t UnconfigureMSI(PCIDev *device);
|
status_t UnconfigureMSI(PCIDev *device);
|
||||||
status_t EnableMSI(PCIDev *device);
|
status_t EnableMSI(PCIDev *device);
|
||||||
status_t DisableMSI(PCIDev *device);
|
status_t DisableMSI(PCIDev *device);
|
||||||
uint8 GetMSIXCount(PCIDev *device);
|
uint32 GetMSIXCount(PCIDev *device);
|
||||||
status_t ConfigureMSIX(PCIDev *device, uint8 count, uint8 *startVector);
|
status_t ConfigureMSIX(PCIDev *device, uint32 count, uint32 *startVector);
|
||||||
status_t EnableMSIX(PCIDev *device);
|
status_t EnableMSIX(PCIDev *device);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ pci_device_module_info gPCIDeviceModule = {
|
|||||||
.get_msi_count = [](pci_device *device) {
|
.get_msi_count = [](pci_device *device) {
|
||||||
return gPCI->GetMSICount(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);
|
return gPCI->ConfigureMSI(device->device, count, startVector);
|
||||||
},
|
},
|
||||||
.unconfigure_msi = [](pci_device *device) {
|
.unconfigure_msi = [](pci_device *device) {
|
||||||
@@ -149,7 +149,7 @@ pci_device_module_info gPCIDeviceModule = {
|
|||||||
.get_msix_count = [](pci_device *device) {
|
.get_msix_count = [](pci_device *device) {
|
||||||
return gPCI->GetMSIXCount(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);
|
return gPCI->ConfigureMSIX(device->device, count, startVector);
|
||||||
},
|
},
|
||||||
.enable_msix = [](pci_device *device) {
|
.enable_msix = [](pci_device *device) {
|
||||||
|
|||||||
@@ -95,10 +95,11 @@ static struct pci_module_info sOldPCIModule = {
|
|||||||
.get_msi_count = [](uint8 bus, uint8 device, uint8 function) {
|
.get_msi_count = [](uint8 bus, uint8 device, uint8 function) {
|
||||||
PCIDev* dev;
|
PCIDev* dev;
|
||||||
if (ResolveBDF(bus, device, function, dev) < B_OK)
|
if (ResolveBDF(bus, device, function, dev) < B_OK)
|
||||||
return (uint8)0;
|
return (uint32)0;
|
||||||
return gPCI->GetMSICount(dev);
|
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;
|
PCIDev* dev;
|
||||||
CHECK_RET(ResolveBDF(bus, device, function, dev));
|
CHECK_RET(ResolveBDF(bus, device, function, dev));
|
||||||
return gPCI->ConfigureMSI(dev, count, startVector);
|
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) {
|
.get_msix_count = [](uint8 bus, uint8 device, uint8 function) {
|
||||||
PCIDev* dev;
|
PCIDev* dev;
|
||||||
if (ResolveBDF(bus, device, function, dev) < B_OK)
|
if (ResolveBDF(bus, device, function, dev) < B_OK)
|
||||||
return (uint8)0;
|
return (uint32)0;
|
||||||
return gPCI->GetMSIXCount(dev);
|
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;
|
PCIDev* dev;
|
||||||
CHECK_RET(ResolveBDF(bus, device, function, dev));
|
CHECK_RET(ResolveBDF(bus, device, function, dev));
|
||||||
return gPCI->ConfigureMSIX(dev, count, startVector);
|
return gPCI->ConfigureMSIX(dev, count, startVector);
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
typedef struct msi_info {
|
typedef struct msi_info {
|
||||||
bool msi_capable;
|
bool msi_capable;
|
||||||
uint8 capability_offset;
|
uint8 capability_offset;
|
||||||
uint8 message_count;
|
uint32 message_count;
|
||||||
uint8 configured_count;
|
uint32 configured_count;
|
||||||
uint8 start_vector;
|
uint32 start_vector;
|
||||||
uint16 control_value;
|
uint16 control_value;
|
||||||
uint16 data_value;
|
uint32 data_value;
|
||||||
uint64 address_value;
|
uint64 address_value;
|
||||||
} msi_info;
|
} msi_info;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ typedef struct msi_info {
|
|||||||
typedef struct msix_info {
|
typedef struct msix_info {
|
||||||
bool msix_capable;
|
bool msix_capable;
|
||||||
uint8 capability_offset;
|
uint8 capability_offset;
|
||||||
uint8 message_count;
|
uint32 message_count;
|
||||||
uint8 table_bar;
|
uint8 table_bar;
|
||||||
uint32 table_offset;
|
uint32 table_offset;
|
||||||
area_id table_area_id;
|
area_id table_area_id;
|
||||||
@@ -39,10 +39,10 @@ typedef struct msix_info {
|
|||||||
uint32 pba_offset;
|
uint32 pba_offset;
|
||||||
area_id pba_area_id;
|
area_id pba_area_id;
|
||||||
addr_t pba_address;
|
addr_t pba_address;
|
||||||
uint8 configured_count;
|
uint32 configured_count;
|
||||||
uint8 start_vector;
|
uint32 start_vector;
|
||||||
uint16 control_value;
|
uint16 control_value;
|
||||||
uint16 data_value;
|
uint32 data_value;
|
||||||
uint64 address_value;
|
uint64 address_value;
|
||||||
} msix_info;
|
} msix_info;
|
||||||
|
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ init_bus(device_node* node, void** bus_cookie)
|
|||||||
gDeviceManager->put_node(parent);
|
gDeviceManager->put_node(parent);
|
||||||
|
|
||||||
TRACE_ALWAYS("init_bus() addr 0x%" B_PRIxPHYSADDR " size 0x%" B_PRIx64
|
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->registersArea = map_physical_memory("PCHI2C memory mapped registers",
|
||||||
bus->base_addr, bus->map_size, B_ANY_KERNEL_ADDRESS,
|
bus->base_addr, bus->map_size, B_ANY_KERNEL_ADDRESS,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ acpi_status pch_i2c_scan_bus_callback(acpi_handle object, uint32 nestingLevel,
|
|||||||
|
|
||||||
struct pch_i2c_crs {
|
struct pch_i2c_crs {
|
||||||
uint16 i2c_addr;
|
uint16 i2c_addr;
|
||||||
uint8 irq;
|
uint32 irq;
|
||||||
uint8 irq_triggering;
|
uint8 irq_triggering;
|
||||||
uint8 irq_polarity;
|
uint8 irq_polarity;
|
||||||
uint8 irq_shareable;
|
uint8 irq_shareable;
|
||||||
@@ -73,7 +73,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
phys_addr_t base_addr;
|
phys_addr_t base_addr;
|
||||||
uint64 map_size;
|
uint64 map_size;
|
||||||
uint8 irq;
|
uint32 irq;
|
||||||
i2c_bus sim;
|
i2c_bus sim;
|
||||||
|
|
||||||
device_node* node;
|
device_node* node;
|
||||||
|
|||||||
@@ -150,10 +150,10 @@ init_device(device_node* node, void** device_cookie)
|
|||||||
|
|
||||||
// try MSI-X
|
// try MSI-X
|
||||||
if (pci->get_msix_count(device) >= 1) {
|
if (pci->get_msix_count(device) >= 1) {
|
||||||
uint8 vector;
|
uint32 vector;
|
||||||
if (pci->configure_msix(device, 1, &vector) == B_OK
|
if (pci->configure_msix(device, 1, &vector) == B_OK
|
||||||
&& pci->enable_msix(device) == 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->info.irq = vector;
|
||||||
bus->irq_type = PCH_I2C_IRQ_MSI_X_SHARED;
|
bus->irq_type = PCH_I2C_IRQ_MSI_X_SHARED;
|
||||||
} else {
|
} else {
|
||||||
@@ -161,10 +161,10 @@ init_device(device_node* node, void** device_cookie)
|
|||||||
}
|
}
|
||||||
} else if (pci->get_msi_count(device) >= 1) {
|
} else if (pci->get_msi_count(device) >= 1) {
|
||||||
// try MSI
|
// try MSI
|
||||||
uint8 vector;
|
uint32 vector;
|
||||||
if (pci->configure_msi(device, 1, &vector) == B_OK
|
if (pci->configure_msi(device, 1, &vector) == B_OK
|
||||||
&& pci->enable_msi(device) == 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->info.irq = vector;
|
||||||
bus->irq_type = PCH_I2C_IRQ_MSI;
|
bus->irq_type = PCH_I2C_IRQ_MSI;
|
||||||
} else {
|
} else {
|
||||||
@@ -173,9 +173,12 @@ init_device(device_node* node, void** device_cookie)
|
|||||||
}
|
}
|
||||||
if (bus->irq_type == PCH_I2C_IRQ_LEGACY) {
|
if (bus->irq_type == PCH_I2C_IRQ_LEGACY) {
|
||||||
bus->info.irq = pciInfo->u.h0.interrupt_line;
|
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");
|
ERROR("PCI IRQ not assigned\n");
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
|
|||||||
@@ -165,9 +165,9 @@ public:
|
|||||||
|
|
||||||
status_t Init(PciDbiRegs volatile* dbiRegs, int32 msiIrq);
|
status_t Init(PciDbiRegs volatile* dbiRegs, int32 msiIrq);
|
||||||
|
|
||||||
status_t AllocateVectors(uint8 count, uint8& startVector, uint64& address,
|
status_t AllocateVectors(uint32 count, uint32& startVector, uint64& address,
|
||||||
uint16& data) final;
|
uint32& data) final;
|
||||||
void FreeVectors(uint8 count, uint8 startVector) final;
|
void FreeVectors(uint32 count, uint32 startVector) final;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ MsiInterruptCtrlDW::Init(PciDbiRegs volatile* dbiRegs, int32 msiIrq)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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)
|
if (count != 1)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -74,7 +75,7 @@ MsiInterruptCtrlDW::AllocateVectors(uint8 count, uint8& startVector, uint64& add
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MsiInterruptCtrlDW::FreeVectors(uint8 count, uint8 startVector)
|
MsiInterruptCtrlDW::FreeVectors(uint32 count, uint32 startVector)
|
||||||
{
|
{
|
||||||
int32 irq = (int32)startVector - fMsiStartIrq;
|
int32 irq = (int32)startVector - fMsiStartIrq;
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
|
|||||||
@@ -102,18 +102,21 @@ AHCIController::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
fIRQ = pciInfo.u.h0.interrupt_line;
|
fIRQ = pciInfo.u.h0.interrupt_line;
|
||||||
|
if (fIRQ == 0xff)
|
||||||
|
fIRQ = 0;
|
||||||
|
|
||||||
if (fPCI->get_msi_count(fPCIDevice) >= 1) {
|
if (fPCI->get_msi_count(fPCIDevice) >= 1) {
|
||||||
uint8 vector;
|
uint32 vector;
|
||||||
if (fPCI->configure_msi(fPCIDevice, 1, &vector) == B_OK
|
if (fPCI->configure_msi(fPCIDevice, 1, &vector) == B_OK
|
||||||
&& fPCI->enable_msi(fPCIDevice) == 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;
|
fIRQ = vector;
|
||||||
fUseMSI = true;
|
fUseMSI = true;
|
||||||
} else {
|
} else {
|
||||||
TRACE("couldn't use MSI\n");
|
TRACE("couldn't use MSI\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fIRQ == 0 || fIRQ == 0xff) {
|
if (fIRQ == 0) {
|
||||||
TRACE("Error: PCI IRQ not assigned\n");
|
TRACE("Error: PCI IRQ not assigned\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -215,7 +218,7 @@ AHCIController::Init()
|
|||||||
TRACE("Ports Implemented Mask: %#08" B_PRIx32 " Number of Available Ports:"
|
TRACE("Ports Implemented Mask: %#08" B_PRIx32 " Number of Available Ports:"
|
||||||
" %d\n", fPortImplementedMask, count_bits_set(fPortImplementedMask));
|
" %d\n", fPortImplementedMask, count_bits_set(fPortImplementedMask));
|
||||||
TRACE("AHCI Version %02" B_PRIx32 "%02" B_PRIx32 ".%02" B_PRIx32 ".%02"
|
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);
|
(fRegs->vs >> 8) & 0xff, fRegs->vs & 0xff, fIRQ);
|
||||||
|
|
||||||
// setup interrupt handler
|
// setup interrupt handler
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ private:
|
|||||||
int fCommandSlotCount;
|
int fCommandSlotCount;
|
||||||
int fPortCount;
|
int fPortCount;
|
||||||
uint32 fPortImplementedMask;
|
uint32 fPortImplementedMask;
|
||||||
uint8 fIRQ;
|
uint32 fIRQ;
|
||||||
bool fUseMSI;
|
bool fUseMSI;
|
||||||
AHCIPort * fPort[32];
|
AHCIPort * fPort[32];
|
||||||
|
|
||||||
|
|||||||
@@ -572,8 +572,11 @@ EHCI::EHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stac
|
|||||||
} else {
|
} else {
|
||||||
// Find the right interrupt vector, using MSIs if available.
|
// Find the right interrupt vector, using MSIs if available.
|
||||||
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
||||||
|
if (fIRQ == 0xFF)
|
||||||
|
fIRQ = 0;
|
||||||
|
|
||||||
if (fPci->get_msi_count(fDevice) >= 1) {
|
if (fPci->get_msi_count(fDevice) >= 1) {
|
||||||
uint8 msiVector = 0;
|
uint32 msiVector = 0;
|
||||||
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
||||||
&& fPci->enable_msi(fDevice) == B_OK) {
|
&& fPci->enable_msi(fDevice) == B_OK) {
|
||||||
TRACE_ALWAYS("using message signaled interrupts\n");
|
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",
|
TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n",
|
||||||
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ inline uint32 ReadCapReg32(uint32 reg);
|
|||||||
|
|
||||||
// Interrupt polling
|
// Interrupt polling
|
||||||
thread_id fInterruptPollThread;
|
thread_id fInterruptPollThread;
|
||||||
uint8 fIRQ;
|
uint32 fIRQ;
|
||||||
bool fUseMSI;
|
bool fUseMSI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
// Find the right interrupt vector, using MSIs if available.
|
||||||
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
||||||
|
if (fIRQ == 0xFF)
|
||||||
|
fIRQ = 0;
|
||||||
|
|
||||||
if (fPci->get_msi_count(fDevice) >= 1) {
|
if (fPci->get_msi_count(fDevice) >= 1) {
|
||||||
uint8 msiVector = 0;
|
uint32 msiVector = 0;
|
||||||
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
||||||
&& fPci->enable_msi(fDevice) == B_OK) {
|
&& fPci->enable_msi(fDevice) == B_OK) {
|
||||||
TRACE_ALWAYS("using message signaled interrupts\n");
|
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",
|
TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n",
|
||||||
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ inline uint32 _ReadReg(uint32 reg);
|
|||||||
// Port management
|
// Port management
|
||||||
uint8 fPortCount;
|
uint8 fPortCount;
|
||||||
|
|
||||||
uint8 fIRQ;
|
uint32 fIRQ;
|
||||||
bool fUseMSI;
|
bool fUseMSI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
// Find the right interrupt vector, using MSIs if available.
|
||||||
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
||||||
|
if (fIRQ == 0xFF)
|
||||||
|
fIRQ = 0;
|
||||||
|
|
||||||
if (fPci->get_msi_count(fDevice) >= 1) {
|
if (fPci->get_msi_count(fDevice) >= 1) {
|
||||||
uint8 msiVector = 0;
|
uint32 msiVector = 0;
|
||||||
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
||||||
&& fPci->enable_msi(fDevice) == B_OK) {
|
&& fPci->enable_msi(fDevice) == B_OK) {
|
||||||
TRACE_ALWAYS("using message signaled interrupts\n");
|
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",
|
TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n",
|
||||||
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ inline uint32 ReadReg32(uint32 reg);
|
|||||||
uint8 fRootHubAddress;
|
uint8 fRootHubAddress;
|
||||||
uint8 fPortResetChange;
|
uint8 fPortResetChange;
|
||||||
|
|
||||||
uint8 fIRQ;
|
uint32 fIRQ;
|
||||||
bool fUseMSI;
|
bool fUseMSI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
// Find the right interrupt vector, using MSIs if available.
|
||||||
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
fIRQ = fPCIInfo->u.h0.interrupt_line;
|
||||||
|
if (fIRQ == 0xFF)
|
||||||
|
fIRQ = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (fPci->get_msix_count(fDevice) >= 1) {
|
if (fPci->get_msix_count(fDevice) >= 1) {
|
||||||
uint8 msiVector = 0;
|
uint8 msiVector = 0;
|
||||||
@@ -540,7 +543,7 @@ XHCI::XHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Sta
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (fPci->get_msi_count(fDevice) >= 1) {
|
if (fPci->get_msi_count(fDevice) >= 1) {
|
||||||
uint8 msiVector = 0;
|
uint32 msiVector = 0;
|
||||||
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK
|
||||||
&& fPci->enable_msi(fDevice) == B_OK) {
|
&& fPci->enable_msi(fDevice) == B_OK) {
|
||||||
TRACE_ALWAYS("using message signaled interrupts\n");
|
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",
|
TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n",
|
||||||
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ private:
|
|||||||
pci_device* fDevice;
|
pci_device* fDevice;
|
||||||
|
|
||||||
Stack * fStack;
|
Stack * fStack;
|
||||||
uint8 fIRQ;
|
uint32 fIRQ;
|
||||||
bool fUseMSI;
|
bool fUseMSI;
|
||||||
|
|
||||||
area_id fErstArea;
|
area_id fErstArea;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ typedef struct {
|
|||||||
addr_t isrAddr;
|
addr_t isrAddr;
|
||||||
addr_t notifyAddr;
|
addr_t notifyAddr;
|
||||||
uint32 notifyOffsetMultiplier;
|
uint32 notifyOffsetMultiplier;
|
||||||
uint8 irq;
|
uint32 irq;
|
||||||
virtio_irq_type irq_type;
|
virtio_irq_type irq_type;
|
||||||
virtio_sim sim;
|
virtio_sim sim;
|
||||||
uint16 queue_count;
|
uint16 queue_count;
|
||||||
@@ -460,28 +460,29 @@ setup_interrupt(void* cookie, uint16 queueCount)
|
|||||||
bus->queue_count = queueCount;
|
bus->queue_count = queueCount;
|
||||||
|
|
||||||
// try MSI-X
|
// 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 >= 2) {
|
||||||
if (msixCount >= (queueCount + 1)) {
|
uint32 vectorCount = queueCount + 1;
|
||||||
uint8 vector;
|
if (msixCount >= vectorCount) {
|
||||||
|
uint32 vector;
|
||||||
bus->cookies = new(std::nothrow)
|
bus->cookies = new(std::nothrow)
|
||||||
virtio_pci_queue_cookie[queueCount];
|
virtio_pci_queue_cookie[queueCount];
|
||||||
if (bus->cookies != NULL
|
if (bus->cookies != NULL
|
||||||
&& bus->pci->configure_msix(bus->device, queueCount + 1,
|
&& bus->pci->configure_msix(bus->device, vectorCount,
|
||||||
&vector) == B_OK
|
&vector) == B_OK
|
||||||
&& bus->pci->enable_msix(bus->device) == B_OK) {
|
&& bus->pci->enable_msix(bus->device) == B_OK) {
|
||||||
TRACE_ALWAYS("using MSI-X count %u starting at %d\n",
|
TRACE_ALWAYS("using MSI-X count %" B_PRIu32 " starting at %" B_PRIu32 "\n",
|
||||||
queueCount + 1, vector);
|
vectorCount, vector);
|
||||||
bus->irq = vector;
|
bus->irq = vector;
|
||||||
bus->irq_type = VIRTIO_IRQ_MSI_X;
|
bus->irq_type = VIRTIO_IRQ_MSI_X;
|
||||||
} else {
|
} else {
|
||||||
ERROR("couldn't use MSI-X\n");
|
ERROR("couldn't use MSI-X\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint8 vector;
|
uint32 vector;
|
||||||
if (bus->pci->configure_msix(bus->device, 2, &vector) == B_OK
|
if (bus->pci->configure_msix(bus->device, 2, &vector) == B_OK
|
||||||
&& bus->pci->enable_msix(bus->device) == 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 = vector;
|
||||||
bus->irq_type = VIRTIO_IRQ_MSI_X_SHARED;
|
bus->irq_type = VIRTIO_IRQ_MSI_X_SHARED;
|
||||||
} else {
|
} else {
|
||||||
@@ -492,9 +493,11 @@ setup_interrupt(void* cookie, uint16 queueCount)
|
|||||||
|
|
||||||
if (bus->irq_type == VIRTIO_IRQ_LEGACY) {
|
if (bus->irq_type == VIRTIO_IRQ_LEGACY) {
|
||||||
bus->irq = pciInfo->u.h0.interrupt_line;
|
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");
|
ERROR("PCI IRQ not assigned\n");
|
||||||
delete bus;
|
delete bus;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|||||||
@@ -1153,20 +1153,28 @@ hda_hw_init(hda_controller* controller)
|
|||||||
controller->irq = pciInfo.u.h0.interrupt_line;
|
controller->irq = pciInfo.u.h0.interrupt_line;
|
||||||
controller->msi = false;
|
controller->msi = false;
|
||||||
|
|
||||||
|
if (controller->irq == 0xff)
|
||||||
|
controller->irq = 0;
|
||||||
|
|
||||||
if ((quirks & HDA_QUIRK_NO_MSI) == 0
|
if ((quirks & HDA_QUIRK_NO_MSI) == 0
|
||||||
&& gPci->get_msi_count(pciInfo.bus, pciInfo.device,
|
&& gPci->get_msi_count(pciInfo.bus, pciInfo.device,
|
||||||
pciInfo.function) >= 1) {
|
pciInfo.function) >= 1) {
|
||||||
// Try MSI first
|
// Try MSI first
|
||||||
uint8 vector;
|
uint32 vector;
|
||||||
if (gPci->configure_msi(pciInfo.bus, pciInfo.device,
|
if (gPci->configure_msi(pciInfo.bus, pciInfo.device,
|
||||||
pciInfo.function, 1, &vector) == B_OK && gPci->enable_msi(
|
pciInfo.function, 1, &vector) == B_OK && gPci->enable_msi(
|
||||||
pciInfo.bus, pciInfo.device, pciInfo.function) == B_OK) {
|
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->irq = vector;
|
||||||
controller->msi = true;
|
controller->msi = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (controller->irq == 0) {
|
||||||
|
status = ENODEV;
|
||||||
|
goto no_irq_handler;
|
||||||
|
}
|
||||||
|
|
||||||
status = install_io_interrupt_handler(controller->irq,
|
status = install_io_interrupt_handler(controller->irq,
|
||||||
(interrupt_handler)hda_interrupt_handler, controller, 0);
|
(interrupt_handler)hda_interrupt_handler, controller, 0);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
|
|||||||
@@ -229,16 +229,19 @@ nvme_disk_init_device(void* _info, void** _cookie)
|
|||||||
command &= ~(PCI_command_int_disable);
|
command &= ~(PCI_command_int_disable);
|
||||||
pci->write_pci_config(pcidev, PCI_command, 2, command);
|
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)) {
|
if (pci->get_msix_count(pcidev)) {
|
||||||
uint8 msixVector = 0;
|
uint32 msixVector = 0;
|
||||||
if (pci->configure_msix(pcidev, 1, &msixVector) == B_OK
|
if (pci->configure_msix(pcidev, 1, &msixVector) == B_OK
|
||||||
&& pci->enable_msix(pcidev) == B_OK) {
|
&& pci->enable_msix(pcidev) == B_OK) {
|
||||||
TRACE_ALWAYS("using MSI-X\n");
|
TRACE_ALWAYS("using MSI-X\n");
|
||||||
irq = msixVector;
|
irq = msixVector;
|
||||||
}
|
}
|
||||||
} else if (pci->get_msi_count(pcidev) >= 1) {
|
} else if (pci->get_msi_count(pcidev) >= 1) {
|
||||||
uint8 msiVector = 0;
|
uint32 msiVector = 0;
|
||||||
if (pci->configure_msi(pcidev, 1, &msiVector) == B_OK
|
if (pci->configure_msi(pcidev, 1, &msiVector) == B_OK
|
||||||
&& pci->enable_msi(pcidev) == B_OK) {
|
&& pci->enable_msi(pcidev) == B_OK) {
|
||||||
TRACE_ALWAYS("using message signaled interrupts\n");
|
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",
|
TRACE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n",
|
||||||
info->info.bus, info->info.device, info->info.function);
|
info->info.bus, info->info.device, info->info.function);
|
||||||
info->polling = 1;
|
info->polling = 1;
|
||||||
|
|||||||
@@ -443,13 +443,16 @@ init_interrupt_handler(intel_info &info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the right interrupt vector, using MSIs if available.
|
// Find the right interrupt vector, using MSIs if available.
|
||||||
info.irq = 0xff;
|
info.irq = 0;
|
||||||
info.use_msi = false;
|
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;
|
info.irq = info.pci->u.h0.interrupt_line;
|
||||||
|
if (info.irq == 0xff)
|
||||||
|
info.irq = 0;
|
||||||
|
}
|
||||||
if (gPCI->get_msi_count(info.pci->bus,
|
if (gPCI->get_msi_count(info.pci->bus,
|
||||||
info.pci->device, info.pci->function) >= 1) {
|
info.pci->device, info.pci->function) >= 1) {
|
||||||
uint8 msiVector = 0;
|
uint32 msiVector = 0;
|
||||||
if (gPCI->configure_msi(info.pci->bus, info.pci->device,
|
if (gPCI->configure_msi(info.pci->bus, info.pci->device,
|
||||||
info.pci->function, 1, &msiVector) == B_OK
|
info.pci->function, 1, &msiVector) == B_OK
|
||||||
&& gPCI->enable_msi(info.pci->bus, info.pci->device,
|
&& 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
|
// we've gotten an interrupt line for us to use
|
||||||
|
|
||||||
info.fake_interrupts = false;
|
info.fake_interrupts = false;
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ int
|
|||||||
pci_alloc_msi(device_t dev, int *count)
|
pci_alloc_msi(device_t dev, int *count)
|
||||||
{
|
{
|
||||||
pci_info* info = get_device_pci_info(dev);
|
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,
|
if (gPci->configure_msi(info->bus, info->device, info->function, *count,
|
||||||
&startVector) != B_OK) {
|
&startVector) != B_OK) {
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
@@ -318,7 +318,7 @@ int
|
|||||||
pci_alloc_msix(device_t dev, int *count)
|
pci_alloc_msix(device_t dev, int *count)
|
||||||
{
|
{
|
||||||
pci_info* info = get_device_pci_info(dev);
|
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,
|
if (gPci->configure_msix(info->bus, info->device, info->function, *count,
|
||||||
&startVector) != B_OK) {
|
&startVector) != B_OK) {
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
|||||||
@@ -25,15 +25,14 @@ msi_supported()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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);
|
return sMSIInterface->AllocateVectors(count, *startVector, *address, *data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
msi_free_vectors(uint8 count, uint8 startVector)
|
msi_free_vectors(uint32 count, uint32 startVector)
|
||||||
{
|
{
|
||||||
sMSIInterface->FreeVectors(count, startVector);
|
sMSIInterface->FreeVectors(count, startVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
struct MSIConfiguration {
|
struct MSIConfiguration {
|
||||||
uint64* fAddress;
|
uint64* fAddress;
|
||||||
uint16* fData;
|
uint32* fData;
|
||||||
};
|
};
|
||||||
|
|
||||||
static MSIConfiguration sMSIConfigurations[NUM_IO_VECTORS];
|
static MSIConfiguration sMSIConfigurations[NUM_IO_VECTORS];
|
||||||
@@ -45,8 +45,8 @@ msi_supported()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address,
|
msi_allocate_vectors(uint32 count, uint32 *startVector, uint64 *address,
|
||||||
uint16 *data)
|
uint32 *data)
|
||||||
{
|
{
|
||||||
if (!sMSISupported)
|
if (!sMSISupported)
|
||||||
return B_UNSUPPORTED;
|
return B_UNSUPPORTED;
|
||||||
@@ -66,27 +66,27 @@ msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address,
|
|||||||
sMSIConfigurations[vector].fData = data;
|
sMSIConfigurations[vector].fData = data;
|
||||||
x86_set_irq_source(vector, IRQ_SOURCE_MSI);
|
x86_set_irq_source(vector, IRQ_SOURCE_MSI);
|
||||||
|
|
||||||
*startVector = (uint8)vector;
|
*startVector = (uint32)vector;
|
||||||
*address = MSI_ADDRESS_BASE | (sBootCPUAPICId << MSI_DESTINATION_ID_SHIFT)
|
*address = MSI_ADDRESS_BASE | (sBootCPUAPICId << MSI_DESTINATION_ID_SHIFT)
|
||||||
| MSI_NO_REDIRECTION | MSI_DESTINATION_MODE_PHYSICAL;
|
| MSI_NO_REDIRECTION | MSI_DESTINATION_MODE_PHYSICAL;
|
||||||
*data = MSI_TRIGGER_MODE_EDGE | MSI_DELIVERY_MODE_FIXED
|
*data = MSI_TRIGGER_MODE_EDGE | MSI_DELIVERY_MODE_FIXED
|
||||||
| ((uint16)vector + ARCH_INTERRUPT_BASE);
|
| ((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);
|
count, *startVector);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
msi_free_vectors(uint8 count, uint8 startVector)
|
msi_free_vectors(uint32 count, uint32 startVector)
|
||||||
{
|
{
|
||||||
if (!sMSISupported) {
|
if (!sMSISupported) {
|
||||||
panic("trying to free msi vectors but msi not supported\n");
|
panic("trying to free msi vectors but msi not supported\n");
|
||||||
return;
|
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);
|
startVector);
|
||||||
|
|
||||||
free_io_interrupt_vectors(count, startVector);
|
free_io_interrupt_vectors(count, startVector);
|
||||||
@@ -94,7 +94,7 @@ msi_free_vectors(uint8 count, uint8 startVector)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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);
|
uint32 apic_id = x86_get_cpu_apic_id(cpu);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user