diff --git a/Kernel/Bus/PCI/API.cpp b/Kernel/Bus/PCI/API.cpp index f2c45bcb6d..bdc308b0b9 100644 --- a/Kernel/Bus/PCI/API.cpp +++ b/Kernel/Bus/PCI/API.cpp @@ -94,10 +94,10 @@ u32 get_BAR5(Address address) return read32(address, PCI::RegisterOffset::BAR5); } -u32 get_BAR(Address address, u8 bar) +u32 get_BAR(Address address, HeaderType0BaseRegister pci_bar) { - VERIFY(bar <= 5); - switch (bar) { + VERIFY(to_underlying(pci_bar) <= 5); + switch (to_underlying(pci_bar)) { case 0: return get_BAR0(address); case 1: @@ -138,11 +138,11 @@ static u8 read8_offsetted(Address address, u32 field) { return Access::the().rea static u16 read16_offsetted(Address address, u32 field) { return Access::the().read16_field(address, field); } static u32 read32_offsetted(Address address, u32 field) { return Access::the().read32_field(address, field); } -size_t get_BAR_space_size(Address address, u8 bar_number) +size_t get_BAR_space_size(Address address, HeaderType0BaseRegister pci_bar) { // See PCI Spec 2.3, Page 222 - VERIFY(bar_number < 6); - u8 field = to_underlying(PCI::RegisterOffset::BAR0) + (bar_number << 2); + VERIFY(to_underlying(pci_bar) < 6); + u8 field = to_underlying(PCI::RegisterOffset::BAR0) + (to_underlying(pci_bar) << 2); u32 bar_reserved = read32_offsetted(address, field); write32_offsetted(address, field, 0xFFFFFFFF); u32 space_size = read32_offsetted(address, field); diff --git a/Kernel/Bus/PCI/API.h b/Kernel/Bus/PCI/API.h index 6c95db9aa8..92152cb171 100644 --- a/Kernel/Bus/PCI/API.h +++ b/Kernel/Bus/PCI/API.h @@ -31,8 +31,8 @@ u32 get_BAR2(Address); u32 get_BAR3(Address); u32 get_BAR4(Address); u32 get_BAR5(Address); -u32 get_BAR(Address address, u8 bar); -size_t get_BAR_space_size(Address, u8); +u32 get_BAR(Address address, HeaderType0BaseRegister); +size_t get_BAR_space_size(Address, HeaderType0BaseRegister); void enable_bus_mastering(Address); void disable_bus_mastering(Address); void enable_io_space(Address); diff --git a/Kernel/Bus/PCI/Definitions.h b/Kernel/Bus/PCI/Definitions.h index 039edc6584..63f3eae5da 100644 --- a/Kernel/Bus/PCI/Definitions.h +++ b/Kernel/Bus/PCI/Definitions.h @@ -21,6 +21,15 @@ enum class HeaderType { Bridge = 1, }; +enum class HeaderType0BaseRegister { + BAR0 = 0, + BAR1, + BAR2, + BAR3, + BAR4, + BAR5, +}; + enum class RegisterOffset { VENDOR_ID = 0x00, // word DEVICE_ID = 0x02, // word diff --git a/Kernel/Bus/VirtIO/Device.cpp b/Kernel/Bus/VirtIO/Device.cpp index abe960aa59..1b3b3f8f8f 100644 --- a/Kernel/Bus/VirtIO/Device.cpp +++ b/Kernel/Bus/VirtIO/Device.cpp @@ -129,14 +129,14 @@ UNMAP_AFTER_INIT void Device::initialize() if (m_use_mmio) { for (auto& cfg : m_configs) { auto& mapping = m_mmio[cfg.bar]; - mapping.size = PCI::get_BAR_space_size(pci_address(), cfg.bar); + mapping.size = PCI::get_BAR_space_size(pci_address(), static_cast(cfg.bar)); if (!mapping.base && mapping.size) { auto region_size_or_error = Memory::page_round_up(mapping.size); if (region_size_or_error.is_error()) { dbgln_if(VIRTIO_DEBUG, "{}: Failed to round up size={} to pages", m_class_name, mapping.size); continue; } - auto region_or_error = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR(pci_address(), cfg.bar))), region_size_or_error.value(), "VirtIO MMIO"sv, Memory::Region::Access::ReadWrite, Memory::Region::Cacheable::No); + auto region_or_error = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR(pci_address(), static_cast(cfg.bar)))), region_size_or_error.value(), "VirtIO MMIO"sv, Memory::Region::Access::ReadWrite, Memory::Region::Cacheable::No); if (region_or_error.is_error()) { dbgln_if(VIRTIO_DEBUG, "{}: Failed to map bar {} - (size={}) {}", m_class_name, cfg.bar, mapping.size, region_or_error.error()); } else { diff --git a/Kernel/Devices/PCISerialDevice.cpp b/Kernel/Devices/PCISerialDevice.cpp index d7150efac7..32c5905dd6 100644 --- a/Kernel/Devices/PCISerialDevice.cpp +++ b/Kernel/Devices/PCISerialDevice.cpp @@ -20,7 +20,7 @@ UNMAP_AFTER_INIT void PCISerialDevice::detect() if (board_definition.device_id != device_identifier.hardware_id()) continue; - auto bar_base = PCI::get_BAR(device_identifier.address(), board_definition.pci_bar) & ~1; + auto bar_base = PCI::get_BAR(device_identifier.address(), static_cast(board_definition.pci_bar)) & ~1; auto port_base = IOAddress(bar_base + board_definition.first_offset); for (size_t i = 0; i < board_definition.port_count; i++) { auto serial_device = new SerialDevice(port_base.offset(board_definition.port_size * i), current_device_minor++); diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp index 1ec83a933e..7a41ff9217 100644 --- a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp +++ b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp @@ -41,7 +41,7 @@ UNMAP_AFTER_INIT ErrorOr BochsGraphicsAdapter::initialize_adapter(PCI::Dev // Note: Bochs (the real bochs graphics adapter in the Bochs emulator) uses revision ID of 0x0 // and doesn't support memory-mapped IO registers. bool virtual_box_hardware = (pci_device_identifier.hardware_id().vendor_id == 0x80ee && pci_device_identifier.hardware_id().device_id == 0xbeef); - auto bar0_space_size = PCI::get_BAR_space_size(pci_device_identifier.address(), 0); + auto bar0_space_size = PCI::get_BAR_space_size(pci_device_identifier.address(), PCI::HeaderType0BaseRegister::BAR0); if (pci_device_identifier.revision_id().value() == 0x0 || virtual_box_hardware) { m_display_connector = BochsDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), bar0_space_size, virtual_box_hardware); } else { diff --git a/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp b/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp index 2e3ceff367..3029e1c814 100644 --- a/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp +++ b/Kernel/Graphics/Intel/NativeGraphicsAdapter.cpp @@ -40,9 +40,9 @@ ErrorOr IntelNativeGraphicsAdapter::initialize_adapter() { auto address = pci_address(); dbgln_if(INTEL_GRAPHICS_DEBUG, "Intel Native Graphics Adapter @ {}", address); - auto bar0_space_size = PCI::get_BAR_space_size(address, 0); + auto bar0_space_size = PCI::get_BAR_space_size(address, PCI::HeaderType0BaseRegister::BAR0); VERIFY(bar0_space_size == 0x80000); - auto bar2_space_size = PCI::get_BAR_space_size(address, 2); + auto bar2_space_size = PCI::get_BAR_space_size(address, PCI::HeaderType0BaseRegister::BAR2); dmesgln("Intel Native Graphics Adapter @ {}, MMIO @ {}, space size is {:x} bytes", address, PhysicalAddress(PCI::get_BAR0(address)), bar0_space_size); dmesgln("Intel Native Graphics Adapter @ {}, framebuffer @ {}", address, PhysicalAddress(PCI::get_BAR2(address))); PCI::enable_bus_mastering(address); diff --git a/Kernel/Graphics/VMWare/GraphicsAdapter.cpp b/Kernel/Graphics/VMWare/GraphicsAdapter.cpp index d13448bb0b..a7a7b19646 100644 --- a/Kernel/Graphics/VMWare/GraphicsAdapter.cpp +++ b/Kernel/Graphics/VMWare/GraphicsAdapter.cpp @@ -180,7 +180,7 @@ UNMAP_AFTER_INIT ErrorOr VMWareGraphicsAdapter::initialize_adapter() // Note: enable the device by modesetting the primary screen resolution modeset_primary_screen_resolution(640, 480); - auto bar1_space_size = PCI::get_BAR_space_size(pci_address(), 1); + auto bar1_space_size = PCI::get_BAR_space_size(pci_address(), PCI::HeaderType0BaseRegister::BAR1); m_display_connector = VMWareDisplayConnector::must_create(*this, PhysicalAddress(PCI::get_BAR1(pci_address()) & 0xfffffff0), bar1_space_size); TRY(m_display_connector->set_safe_mode_setting()); diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp index 75e7d03829..beb210381b 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp @@ -208,7 +208,7 @@ UNMAP_AFTER_INIT bool E1000ENetworkAdapter::initialize() enable_bus_mastering(pci_address()); - size_t mmio_base_size = PCI::get_BAR_space_size(pci_address(), 0); + size_t mmio_base_size = PCI::get_BAR_space_size(pci_address(), PCI::HeaderType0BaseRegister::BAR0); auto region_or_error = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR0(pci_address()))), Memory::page_round_up(mmio_base_size).release_value_but_fixme_should_propagate_errors(), "E1000e MMIO"sv, Memory::Region::Access::ReadWrite, Memory::Region::Cacheable::No); if (region_or_error.is_error()) return false; diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.cpp b/Kernel/Net/Intel/E1000NetworkAdapter.cpp index 3868d14bae..7ea0fe6379 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000NetworkAdapter.cpp @@ -199,7 +199,7 @@ UNMAP_AFTER_INIT bool E1000NetworkAdapter::initialize() m_io_base = IOAddress(PCI::get_BAR1(pci_address()) & ~1); - size_t mmio_base_size = PCI::get_BAR_space_size(pci_address(), 0); + size_t mmio_base_size = PCI::get_BAR_space_size(pci_address(), PCI::HeaderType0BaseRegister::BAR0); auto region_or_error = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR0(pci_address()))), Memory::page_round_up(mmio_base_size).release_value_but_fixme_should_propagate_errors(), "E1000 MMIO"sv, Memory::Region::Access::ReadWrite, Memory::Region::Cacheable::No); if (region_or_error.is_error()) return false;