mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:17:44 +00:00
Kernel/PCI: Convert PCI BAR number to a strong typed enum class
This commit is contained in:
parent
f510c0ba04
commit
bb6f61ee5d
10 changed files with 26 additions and 17 deletions
|
@ -94,10 +94,10 @@ u32 get_BAR5(Address address)
|
||||||
return read32(address, PCI::RegisterOffset::BAR5);
|
return read32(address, PCI::RegisterOffset::BAR5);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 get_BAR(Address address, u8 bar)
|
u32 get_BAR(Address address, HeaderType0BaseRegister pci_bar)
|
||||||
{
|
{
|
||||||
VERIFY(bar <= 5);
|
VERIFY(to_underlying(pci_bar) <= 5);
|
||||||
switch (bar) {
|
switch (to_underlying(pci_bar)) {
|
||||||
case 0:
|
case 0:
|
||||||
return get_BAR0(address);
|
return get_BAR0(address);
|
||||||
case 1:
|
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 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); }
|
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
|
// See PCI Spec 2.3, Page 222
|
||||||
VERIFY(bar_number < 6);
|
VERIFY(to_underlying(pci_bar) < 6);
|
||||||
u8 field = to_underlying(PCI::RegisterOffset::BAR0) + (bar_number << 2);
|
u8 field = to_underlying(PCI::RegisterOffset::BAR0) + (to_underlying(pci_bar) << 2);
|
||||||
u32 bar_reserved = read32_offsetted(address, field);
|
u32 bar_reserved = read32_offsetted(address, field);
|
||||||
write32_offsetted(address, field, 0xFFFFFFFF);
|
write32_offsetted(address, field, 0xFFFFFFFF);
|
||||||
u32 space_size = read32_offsetted(address, field);
|
u32 space_size = read32_offsetted(address, field);
|
||||||
|
|
|
@ -31,8 +31,8 @@ u32 get_BAR2(Address);
|
||||||
u32 get_BAR3(Address);
|
u32 get_BAR3(Address);
|
||||||
u32 get_BAR4(Address);
|
u32 get_BAR4(Address);
|
||||||
u32 get_BAR5(Address);
|
u32 get_BAR5(Address);
|
||||||
u32 get_BAR(Address address, u8 bar);
|
u32 get_BAR(Address address, HeaderType0BaseRegister);
|
||||||
size_t get_BAR_space_size(Address, u8);
|
size_t get_BAR_space_size(Address, HeaderType0BaseRegister);
|
||||||
void enable_bus_mastering(Address);
|
void enable_bus_mastering(Address);
|
||||||
void disable_bus_mastering(Address);
|
void disable_bus_mastering(Address);
|
||||||
void enable_io_space(Address);
|
void enable_io_space(Address);
|
||||||
|
|
|
@ -21,6 +21,15 @@ enum class HeaderType {
|
||||||
Bridge = 1,
|
Bridge = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class HeaderType0BaseRegister {
|
||||||
|
BAR0 = 0,
|
||||||
|
BAR1,
|
||||||
|
BAR2,
|
||||||
|
BAR3,
|
||||||
|
BAR4,
|
||||||
|
BAR5,
|
||||||
|
};
|
||||||
|
|
||||||
enum class RegisterOffset {
|
enum class RegisterOffset {
|
||||||
VENDOR_ID = 0x00, // word
|
VENDOR_ID = 0x00, // word
|
||||||
DEVICE_ID = 0x02, // word
|
DEVICE_ID = 0x02, // word
|
||||||
|
|
|
@ -129,14 +129,14 @@ UNMAP_AFTER_INIT void Device::initialize()
|
||||||
if (m_use_mmio) {
|
if (m_use_mmio) {
|
||||||
for (auto& cfg : m_configs) {
|
for (auto& cfg : m_configs) {
|
||||||
auto& mapping = m_mmio[cfg.bar];
|
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<PCI::HeaderType0BaseRegister>(cfg.bar));
|
||||||
if (!mapping.base && mapping.size) {
|
if (!mapping.base && mapping.size) {
|
||||||
auto region_size_or_error = Memory::page_round_up(mapping.size);
|
auto region_size_or_error = Memory::page_round_up(mapping.size);
|
||||||
if (region_size_or_error.is_error()) {
|
if (region_size_or_error.is_error()) {
|
||||||
dbgln_if(VIRTIO_DEBUG, "{}: Failed to round up size={} to pages", m_class_name, mapping.size);
|
dbgln_if(VIRTIO_DEBUG, "{}: Failed to round up size={} to pages", m_class_name, mapping.size);
|
||||||
continue;
|
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<PCI::HeaderType0BaseRegister>(cfg.bar)))), region_size_or_error.value(), "VirtIO MMIO"sv, Memory::Region::Access::ReadWrite, Memory::Region::Cacheable::No);
|
||||||
if (region_or_error.is_error()) {
|
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());
|
dbgln_if(VIRTIO_DEBUG, "{}: Failed to map bar {} - (size={}) {}", m_class_name, cfg.bar, mapping.size, region_or_error.error());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,7 +20,7 @@ UNMAP_AFTER_INIT void PCISerialDevice::detect()
|
||||||
if (board_definition.device_id != device_identifier.hardware_id())
|
if (board_definition.device_id != device_identifier.hardware_id())
|
||||||
continue;
|
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<PCI::HeaderType0BaseRegister>(board_definition.pci_bar)) & ~1;
|
||||||
auto port_base = IOAddress(bar_base + board_definition.first_offset);
|
auto port_base = IOAddress(bar_base + board_definition.first_offset);
|
||||||
for (size_t i = 0; i < board_definition.port_count; i++) {
|
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++);
|
auto serial_device = new SerialDevice(port_base.offset(board_definition.port_size * i), current_device_minor++);
|
||||||
|
|
|
@ -41,7 +41,7 @@ UNMAP_AFTER_INIT ErrorOr<void> BochsGraphicsAdapter::initialize_adapter(PCI::Dev
|
||||||
// Note: Bochs (the real bochs graphics adapter in the Bochs emulator) uses revision ID of 0x0
|
// Note: Bochs (the real bochs graphics adapter in the Bochs emulator) uses revision ID of 0x0
|
||||||
// and doesn't support memory-mapped IO registers.
|
// 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);
|
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) {
|
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);
|
m_display_connector = BochsDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), bar0_space_size, virtual_box_hardware);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -40,9 +40,9 @@ ErrorOr<void> IntelNativeGraphicsAdapter::initialize_adapter()
|
||||||
{
|
{
|
||||||
auto address = pci_address();
|
auto address = pci_address();
|
||||||
dbgln_if(INTEL_GRAPHICS_DEBUG, "Intel Native Graphics Adapter @ {}", 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);
|
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 @ {}, 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)));
|
dmesgln("Intel Native Graphics Adapter @ {}, framebuffer @ {}", address, PhysicalAddress(PCI::get_BAR2(address)));
|
||||||
PCI::enable_bus_mastering(address);
|
PCI::enable_bus_mastering(address);
|
||||||
|
|
|
@ -180,7 +180,7 @@ UNMAP_AFTER_INIT ErrorOr<void> VMWareGraphicsAdapter::initialize_adapter()
|
||||||
// Note: enable the device by modesetting the primary screen resolution
|
// Note: enable the device by modesetting the primary screen resolution
|
||||||
modeset_primary_screen_resolution(640, 480);
|
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);
|
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());
|
TRY(m_display_connector->set_safe_mode_setting());
|
||||||
|
|
|
@ -208,7 +208,7 @@ UNMAP_AFTER_INIT bool E1000ENetworkAdapter::initialize()
|
||||||
|
|
||||||
enable_bus_mastering(pci_address());
|
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);
|
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())
|
if (region_or_error.is_error())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -199,7 +199,7 @@ UNMAP_AFTER_INIT bool E1000NetworkAdapter::initialize()
|
||||||
|
|
||||||
m_io_base = IOAddress(PCI::get_BAR1(pci_address()) & ~1);
|
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);
|
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())
|
if (region_or_error.is_error())
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue