/* * Copyright (c) 2020, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include namespace Kernel::PCI { class Access { public: static bool initialize_for_multiple_pci_domains(PhysicalAddress mcfg_table); #if ARCH(X86_64) static bool initialize_for_one_pci_domain(); #endif ErrorOr fast_enumerate(Function&) const; void rescan_hardware(); static Access& the(); static bool is_initialized(); static bool is_disabled(); static bool is_hardware_disabled(); void write8_field(DeviceIdentifier const&, u32 field, u8 value); void write16_field(DeviceIdentifier const&, u32 field, u16 value); void write32_field(DeviceIdentifier const&, u32 field, u32 value); u8 read8_field(DeviceIdentifier const&, u32 field); u16 read16_field(DeviceIdentifier const&, u32 field); u32 read32_field(DeviceIdentifier const&, u32 field); // FIXME: Remove this once we can use PCI::Capability with inline buffer // so we don't need this method DeviceIdentifier const& get_device_identifier(Address address) const; Spinlock const& scan_lock() const { return m_scan_lock; } RecursiveSpinlock const& access_lock() const { return m_access_lock; } ErrorOr add_host_controller_and_scan_for_devices(NonnullOwnPtr); private: u8 read8_field(DeviceIdentifier const&, RegisterOffset field); u16 read16_field(DeviceIdentifier const&, RegisterOffset field); void add_host_controller(NonnullOwnPtr); bool find_and_register_pci_host_bridges_from_acpi_mcfg_table(PhysicalAddress mcfg); Access(); mutable RecursiveSpinlock m_access_lock {}; mutable Spinlock m_scan_lock {}; HashMap> m_host_controllers; Vector> m_device_identifiers; }; }