pci: generic MSI interrupts support
Change-Id: Ib4fd23f6bca867a2b428bf2651234d719ee08672 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6221 Reviewed-by: waddlesplash <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
@@ -12,6 +12,7 @@ KernelAddon pci :
|
||||
pci_module.cpp
|
||||
pci_root.cpp
|
||||
pci_device.cpp
|
||||
pci_msi.cpp
|
||||
: pci_arch_bus_manager.a
|
||||
;
|
||||
|
||||
|
||||
@@ -75,20 +75,29 @@ PCIFU740::InitMSI(int32 msiIrq)
|
||||
return result;
|
||||
}
|
||||
|
||||
msi_set_interface(static_cast<MSIInterface*>(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);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
#include "arch_pci_controller.h"
|
||||
#include <arch/generic/msi.h>
|
||||
|
||||
|
||||
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{};
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010, Michael Lotz, [email protected]. 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);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010, Michael Lotz, [email protected]. 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
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010, Michael Lotz, [email protected]. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <PCI.h>
|
||||
#include <PCI_x86.h>
|
||||
#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
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
|
||||
#include <PCI.h>
|
||||
#include <PCI_x86.h>
|
||||
#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
|
||||
};
|
||||
|
||||
+14
-15
@@ -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,
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2022, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <arch/generic/msi.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user