/* * Copyright (c) 2020, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #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(I386) || 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(Address address, u32 field, u8 value); void write16_field(Address address, u32 field, u16 value); void write32_field(Address address, u32 field, u32 value); u8 read8_field(Address address, u32 field); u16 read16_field(Address address, u32 field); u32 read32_field(Address address, u32 field); DeviceIdentifier 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_enumerate_attached_devices(NonnullOwnPtr, Function callback); private: u8 read8_field(Address address, RegisterOffset field); u16 read16_field(Address address, RegisterOffset field); void add_host_controller(NonnullOwnPtr); bool find_and_register_pci_host_bridges_from_acpi_mcfg_table(PhysicalAddress mcfg); Access(); Vector get_capabilities(Address); Optional get_capabilities_pointer(Address address); mutable RecursiveSpinlock m_access_lock { LockRank::None }; mutable Spinlock m_scan_lock { LockRank::None }; HashMap> m_host_controllers; Vector m_device_identifiers; }; }