forked from Bananymous/banan-os
				
			Kernel: Add support for scratchpad buffers in xHCI
This commit is contained in:
		
							parent
							
								
									e620068416
								
							
						
					
					
						commit
						40c13043b3
					
				| 
						 | 
					@ -51,6 +51,7 @@ namespace Kernel
 | 
				
			||||||
		BAN::ErrorOr<void> initialize_impl();
 | 
							BAN::ErrorOr<void> initialize_impl();
 | 
				
			||||||
		BAN::ErrorOr<void> initialize_ports();
 | 
							BAN::ErrorOr<void> initialize_ports();
 | 
				
			||||||
		BAN::ErrorOr<void> initialize_primary_interrupter();
 | 
							BAN::ErrorOr<void> initialize_primary_interrupter();
 | 
				
			||||||
 | 
							BAN::ErrorOr<void> initialize_scratchpad();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::ErrorOr<void> reset_controller();
 | 
							BAN::ErrorOr<void> reset_controller();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +92,9 @@ namespace Kernel
 | 
				
			||||||
		uint32_t m_command_enqueue { 0 };
 | 
							uint32_t m_command_enqueue { 0 };
 | 
				
			||||||
		bool m_command_cycle { 1 };
 | 
							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;
 | 
							BAN::UniqPtr<DMARegion> m_event_ring_region;
 | 
				
			||||||
		uint32_t m_event_dequeue { 0 };
 | 
							uint32_t m_event_dequeue { 0 };
 | 
				
			||||||
		bool m_event_cycle { 1 };
 | 
							bool m_event_cycle { 1 };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,10 @@ namespace Kernel
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (m_port_updater)
 | 
							if (m_port_updater)
 | 
				
			||||||
			m_port_updater->exit(0, SIGKILL);
 | 
								m_port_updater->exit(0, SIGKILL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (auto paddr : m_scratchpad_buffers)
 | 
				
			||||||
 | 
								if (paddr)
 | 
				
			||||||
 | 
									Heap::get().release_page(paddr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<void> XHCIController::take_ownership(PCI::Device& pci_device)
 | 
						BAN::ErrorOr<void> XHCIController::take_ownership(PCI::Device& pci_device)
 | 
				
			||||||
| 
						 | 
					@ -123,6 +127,8 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		TRY(initialize_primary_interrupter());
 | 
							TRY(initialize_primary_interrupter());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TRY(initialize_scratchpad());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// enable the controller
 | 
							// enable the controller
 | 
				
			||||||
		operational.usbcmd.run_stop = 1;
 | 
							operational.usbcmd.run_stop = 1;
 | 
				
			||||||
		while (operational.usbsts & XHCI::USBSTS::HCHalted)
 | 
							while (operational.usbsts & XHCI::USBSTS::HCHalted)
 | 
				
			||||||
| 
						 | 
					@ -238,6 +244,33 @@ namespace Kernel
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<void> XHCIController::initialize_scratchpad()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto& capabilities = capability_regs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const uint32_t max_scratchpads = (capabilities.hcsparams2.max_scratchpad_buffers_hi << 5) | capabilities.hcsparams2.max_scratchpad_buffers_lo;
 | 
				
			||||||
 | 
							if (max_scratchpads == 0)
 | 
				
			||||||
 | 
								return {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_scratchpad_buffer_array = TRY(DMARegion::create(max_scratchpads * sizeof(uint64_t)));
 | 
				
			||||||
 | 
							TRY(m_scratchpad_buffers.resize(max_scratchpads));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* scratchpad_buffer_array = reinterpret_cast<uint64_t*>(m_scratchpad_buffer_array->vaddr());
 | 
				
			||||||
 | 
							for (size_t i = 0; i < max_scratchpads; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								const paddr_t paddr = Heap::get().take_free_page();
 | 
				
			||||||
 | 
								if (paddr == 0)
 | 
				
			||||||
 | 
									return BAN::Error::from_errno(ENOMEM);
 | 
				
			||||||
 | 
								m_scratchpad_buffers[i] = paddr;
 | 
				
			||||||
 | 
								scratchpad_buffer_array[i] = paddr;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ASSERT(m_dcbaa_region);
 | 
				
			||||||
 | 
							*reinterpret_cast<uint64_t*>(m_dcbaa_region->vaddr()) = m_scratchpad_buffer_array->paddr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static Mutex s_port_mutex;
 | 
						static Mutex s_port_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void XHCIController::port_updater_task()
 | 
						void XHCIController::port_updater_task()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue