banan-os/kernel/include/kernel/USB/XHCI/Controller.h

108 lines
2.9 KiB
C++

#pragma once
#include <BAN/Vector.h>
#include <kernel/Lock/Mutex.h>
#include <kernel/Memory/DMARegion.h>
#include <kernel/ThreadBlocker.h>
#include <kernel/USB/Definitions.h>
#include <kernel/USB/USBManager.h>
#include <kernel/USB/XHCI/Definitions.h>
namespace Kernel
{
class XHCIDevice;
class XHCIController : public USBController, public Interruptable
{
BAN_NON_COPYABLE(XHCIController);
BAN_NON_MOVABLE(XHCIController);
public:
struct Port
{
uint8_t revision_major { 0 };
uint8_t revision_minor { 0 };
uint8_t slot_id { 0 };
};
public:
static BAN::ErrorOr<void> take_ownership(PCI::Device&);
static BAN::ErrorOr<BAN::UniqPtr<XHCIController>> create(PCI::Device&);
void handle_irq() final override;
private:
XHCIController(PCI::Device& pci_device);
~XHCIController();
BAN::ErrorOr<void> initialize_impl();
BAN::ErrorOr<void> initialize_ports();
BAN::ErrorOr<void> initialize_primary_interrupter();
BAN::ErrorOr<void> initialize_scratchpad();
BAN::ErrorOr<void> reset_controller();
void port_updater_task();
BAN::ErrorOr<uint8_t> initialize_device(uint32_t route_string, uint8_t depth, USB::SpeedClass speed_class, XHCIDevice* parent_hub, uint8_t parent_port_id);
void deinitialize_slot(uint8_t slot_id);
BAN::ErrorOr<XHCI::TRB> send_command(const XHCI::TRB&);
void advance_command_enqueue();
bool context_size_set() { return capability_regs().hccparams1.context_size; }
const Port& port(uint32_t port_id) const { return m_ports[port_id - 1]; }
volatile XHCI::CapabilityRegs& capability_regs();
volatile XHCI::OperationalRegs& operational_regs();
volatile XHCI::RuntimeRegs& runtime_regs();
volatile uint32_t& doorbell_reg(uint32_t slot_id);
volatile uint64_t& dcbaa_reg(uint32_t slot_id);
const volatile XHCI::TRB& current_event_trb();
uint8_t speed_class_to_id(USB::SpeedClass speed_class) const;
USB::SpeedClass speed_id_to_class(uint8_t) const;
private:
static constexpr uint32_t m_command_ring_trb_count = 256;
static constexpr uint32_t m_event_ring_trb_count = 252;
Mutex m_mutex;
BAN::Atomic<Process*> m_port_updater { nullptr };
ThreadBlocker m_port_thread_blocker;
BAN::Atomic<bool> m_port_changed { false };
bool m_running { true };
bool m_ports_initialized { false };
PCI::Device& m_pci_device;
BAN::UniqPtr<PCI::BarRegion> m_configuration_bar;
BAN::UniqPtr<DMARegion> m_dcbaa_region;
BAN::UniqPtr<DMARegion> m_command_ring_region;
uint32_t m_command_enqueue { 0 };
bool m_command_cycle { 1 };
BAN::UniqPtr<DMARegion> m_scratchpad_buffer_array;
BAN::Vector<paddr_t> m_scratchpad_buffers;
BAN::UniqPtr<DMARegion> m_event_ring_region;
uint32_t m_event_dequeue { 0 };
bool m_event_cycle { 1 };
BAN::Vector<XHCI::TRB> m_command_completions;
BAN::Vector<Port> m_ports;
BAN::Vector<BAN::UniqPtr<XHCIDevice>> m_slots;
friend class XHCIDevice;
friend class BAN::UniqPtr<XHCIController>;
};
}