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>;
 | |
| 	};
 | |
| 
 | |
| }
 |