/* * Copyright (c) 2020, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include namespace Kernel::PCI { class Access { public: enum class AccessType { IO, Memory, }; public: static bool initialize_for_memory_access(PhysicalAddress mcfg_table); static bool initialize_for_io_access(); void fast_enumerate(Function&) const; void rescan_hardware(); static Access& the(); static bool is_initialized(); 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); PhysicalID get_physical_id(Address address) const; private: void enumerate_bus(int type, u8 bus, bool recursive); void enumerate_functions(int type, u8 bus, u8 device, u8 function, bool recursive); void enumerate_device(int type, u8 bus, u8 device, bool recursive); explicit Access(AccessType); bool scan_pci_domains(PhysicalAddress mcfg); Vector get_capabilities(Address); Optional get_capabilities_pointer(Address address); // IO access (legacy) operations u8 io_read8_field(Address address, u32 field); u16 io_read16_field(Address address, u32 field); u32 io_read32_field(Address address, u32 field); void io_write8_field(Address address, u32, u8); void io_write16_field(Address address, u32, u16); void io_write32_field(Address address, u32, u32); u16 io_read_type(Address address); // Memory-mapped access operations void map_bus_region(u32 domain, u8 bus); u8 memory_read8_field(Address address, u32 field); u16 memory_read16_field(Address address, u32 field); u32 memory_read32_field(Address address, u32 field); void memory_write8_field(Address address, u32, u8); void memory_write16_field(Address address, u32, u16); void memory_write32_field(Address address, u32, u32); u16 memory_read_type(Address address); VirtualAddress get_device_configuration_memory_mapped_space(Address address); Optional determine_memory_mapped_bus_base_address(u32 domain, u8 bus) const; // Data-members for accessing Memory mapped PCI devices' configuration spaces u8 m_mapped_bus { 0 }; OwnPtr m_mapped_bus_region; HashMap m_domains; // General Data-members mutable Mutex m_access_lock; mutable Mutex m_scan_lock; Bitmap m_enumerated_buses; AccessType m_access_type; Vector m_physical_ids; }; }