/* * Copyright (c) 2023, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Kernel::VirtIO { class TransportEntity { public: virtual ~TransportEntity() = default; virtual ErrorOr locate_configurations_and_resources(Badge, VirtIO::Device&) = 0; virtual void disable_interrupts(Badge) = 0; virtual void enable_interrupts(Badge) = 0; virtual StringView determine_device_class_name() const = 0; void accept_device_features(Badge, u64 accepted_features); struct NotifyQueueDescriptor { u16 queue_index; u16 possible_notify_offset; }; void notify_queue(Badge, NotifyQueueDescriptor); ErrorOr activate_queue(Badge, u16 queue_index); ErrorOr> setup_queue(Badge, u16 queue_index); void set_status_bits(Badge, u8 status_bits); void reset_device(Badge); u8 read_status_bits(); u8 isr_status(); u64 get_device_features(); ErrorOr get_config(ConfigurationType cfg_type, u32 index = 0) const { for (auto const& cfg : m_configs) { if (cfg.cfg_type != cfg_type) continue; if (index > 0) { index--; continue; } return &cfg; } return Error::from_errno(ENXIO); } u8 config_read8(Configuration const&, u32); u16 config_read16(Configuration const&, u32); u32 config_read32(Configuration const&, u32); void config_write8(Configuration const&, u32, u8); void config_write16(Configuration const&, u32, u16); void config_write32(Configuration const&, u32, u32); void config_write64(Configuration const&, u32, u64); template void read_config_atomic(F f) { if (m_common_cfg) { u8 generation_before, generation_after; do { generation_before = config_read8(*m_common_cfg, 0x15); f(); generation_after = config_read8(*m_common_cfg, 0x15); } while (generation_before != generation_after); } else { f(); } } protected: TransportEntity() = default; auto mapping_for_resource_index(u8) -> IOWindow&; void set_status_bits(u8 status_bits); Vector m_configs; Configuration const* m_common_cfg { nullptr }; // Cached due to high usage Configuration const* m_notify_cfg { nullptr }; // Cached due to high usage Configuration const* m_isr_cfg { nullptr }; // Cached due to high usage IOWindow& base_io_window(); Array, 6> m_register_bases; bool m_use_mmio { false }; u32 m_notify_multiplier { 0 }; }; };