diff --git a/Kernel/Devices/USB/UHCIController.cpp b/Kernel/Devices/USB/UHCIController.cpp index a6a997050b..2f26bdb092 100644 --- a/Kernel/Devices/USB/UHCIController.cpp +++ b/Kernel/Devices/USB/UHCIController.cpp @@ -25,8 +25,10 @@ */ #include +#include +#include -#define UHCI_ENABLED 0 +#define UHCI_ENABLED 1 namespace Kernel::USB { @@ -46,6 +48,11 @@ static constexpr u16 UHCI_USBSTS_RESUME_RECEIVED = 0x0004; static constexpr u16 UHCI_USBSTS_USB_ERROR_INTERRUPT = 0x0002; static constexpr u16 UHCI_USBSTS_USB_INTERRUPT = 0x0001; +static constexpr u8 UHCI_USBINTR_TIMEOUT_CRC_ENABLE = 0x01; +static constexpr u8 UHCI_USBINTR_RESUME_INTR_ENABLE = 0x02; +static constexpr u8 UHCI_USBINTR_IOC_ENABLE = 0x04; +static constexpr u8 UHCI_USBINTR_SHORT_PACKET_INTR_ENABLE = 0x08; + void UHCIController::detect() { #if !UHCI_ENABLED @@ -90,6 +97,17 @@ void UHCIController::reset() break; } + // Let's allocate the physical page for the Frame List (which is 4KiB aligned) + m_framelist = MemoryManager::the().allocate_supervisor_physical_page()->paddr(); + klog() << "UHCI: Allocated framelist at physical address " << m_framelist; + memset(reinterpret_cast(low_physical_to_virtual(m_framelist.as_ptr())), 1, 1024); // All frames are TERMINATE frames + + write_sofmod(64); // 1mS frame time + write_flbaseadd(m_framelist.get()); // Frame list (physical) address + write_frnum(0); // Set the initial frame number + + // Enable all interrupt types + write_frnum(UHCI_USBINTR_TIMEOUT_CRC_ENABLE | UHCI_USBINTR_RESUME_INTR_ENABLE | UHCI_USBINTR_IOC_ENABLE | UHCI_USBINTR_SHORT_PACKET_INTR_ENABLE); klog() << "UHCI: Reset completed!"; } diff --git a/Kernel/Devices/USB/UHCIController.h b/Kernel/Devices/USB/UHCIController.h index 2bea92b24a..aa6715803c 100644 --- a/Kernel/Devices/USB/UHCIController.h +++ b/Kernel/Devices/USB/UHCIController.h @@ -64,6 +64,7 @@ private: virtual void handle_irq(const RegisterState&) override; IOAddress m_io_base; + PhysicalAddress m_framelist; }; }