From b7a1261eefe4fa12bd106047fe87afa4e79a12a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 19 Oct 2021 19:40:58 +0200 Subject: [PATCH] pci: support 64-bit BAR addressing for MSI-X memory mappings Change-Id: I463de6aeb45d34e68e888a7648546acddb3fd57a Reviewed-on: https://review.haiku-os.org/c/haiku/+/4613 Tested-by: Commit checker robot Reviewed-by: Adrien Destugues --- .../bus_managers/pci/arch/x86/pci_msi.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp index 8a1f3f2b8c..b54ec18dc5 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp @@ -361,9 +361,14 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, // map the table bar size_t tableSize = info->message_count * 16; addr_t address; + phys_addr_t barAddr = device->info.u.h0.base_registers[info->table_bar]; + uchar flags = device->info.u.h0.base_register_flags[info->table_bar]; + if ((flags & PCI_address_type) == PCI_address_type_64) { + barAddr |= (uint64)device->info.u.h0.base_registers[ + info->table_bar + 1] << 32; + } area_id area = map_physical_memory("msi table map", - device->info.u.h0.base_registers[info->table_bar], - tableSize + info->table_offset, + barAddr, tableSize + info->table_offset, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&address); if (area < 0) @@ -373,9 +378,14 @@ pci_configure_msix(uint8 virtualBus, uint8 _device, uint8 function, // and the pba bar if necessary if (info->table_bar != info->pba_bar) { + barAddr = device->info.u.h0.base_registers[info->pba_bar]; + flags = device->info.u.h0.base_register_flags[info->pba_bar]; + if ((flags & PCI_address_type) == PCI_address_type_64) { + barAddr |= (uint64)device->info.u.h0.base_registers[ + info->pba_bar + 1] << 32; + } area = map_physical_memory("msi pba map", - device->info.u.h0.base_registers[info->pba_bar], - tableSize + info->pba_offset, + barAddr, tableSize + info->pba_offset, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&address); if (area < 0) {