forked from Bananymous/banan-os
108 lines
2.9 KiB
C++
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>;
|
|
};
|
|
|
|
}
|