Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Base/usr/share/man/man7/boot_parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ List of options:

- **`nvme_poll`** - This parameter configures the NVMe drive to use polling instead of interrupt driven completion.

- **`xhci_poll`** - This parameter configures the xHCI driver to use polling instead of interrupt driven completion.

- **`system_mode`** - This parameter is not interpreted by the Kernel, and is made available at `/sys/kernel/system_mode`. SystemServer uses it to select the set of services that should be started. Common values are:

- **`graphical`** (default) - Boots the system in the normal graphical mode.
Expand Down
5 changes: 5 additions & 0 deletions Kernel/Boot/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ bool CommandLine::is_nvme_polling_enabled() const
return contains("nvme_poll"sv);
}

bool CommandLine::is_xhci_polling_enabled() const
{
return contains("xhci_poll"sv);
}

UNMAP_AFTER_INIT AcpiFeatureLevel CommandLine::acpi_feature_level() const
{
auto value = kernel_command_line().lookup("acpi"sv).value_or("limited"sv);
Expand Down
1 change: 1 addition & 0 deletions Kernel/Boot/CommandLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class CommandLine {
[[nodiscard]] Vector<NonnullOwnPtr<KString>> userspace_init_args() const;
[[nodiscard]] StringView root_device() const;
[[nodiscard]] bool is_nvme_polling_enabled() const;
[[nodiscard]] bool is_xhci_polling_enabled() const;
[[nodiscard]] size_t switch_to_tty() const;

private:
Expand Down
12 changes: 6 additions & 6 deletions Kernel/Bus/USB/UHCI/UHCIRootHub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ ErrorOr<size_t> UHCIRootHub::handle_control_transfer(Transfer& transfer)
auto* request_data = transfer.buffer().as_ptr() + sizeof(USBRequestData);

if constexpr (UHCI_DEBUG) {
dbgln("UHCIRootHub: Received control transfer.");
dbgln("UHCIRootHub: Request Type: {:#02x}", request.request_type);
dbgln("UHCIRootHub: Request: {:#02x}", request.request);
dbgln("UHCIRootHub: Value: {:#04x}", request.value);
dbgln("UHCIRootHub: Index: {:#04x}", request.index);
dbgln("UHCIRootHub: Length: {:#04x}", request.length);
dbgln("UHCIRootHub: Received control transfer:");
dbgln("UHCIRootHub: bmRequestType: {:#02x}", request.request_type);
dbgln("UHCIRootHub: bRequest: {:#02x}", request.request);
dbgln("UHCIRootHub: wValue: {:#04x}", request.value);
dbgln("UHCIRootHub: wIndex: {:#04x}", request.index);
dbgln("UHCIRootHub: wLength: {:#04x}", request.length);
}

size_t length = 0;
Expand Down
295 changes: 293 additions & 2 deletions Kernel/Bus/USB/xHCI/DataStructures.cpp

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Kernel/Bus/USB/xHCI/DataStructures.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
namespace Kernel::USB::xHCI {

union TransferRequestBlock {
void dump(StringView prefix) const;

enum class TRBType : u32 {
Normal = 1,
Setup_Stage = 2,
Expand Down
40 changes: 38 additions & 2 deletions Kernel/Bus/USB/xHCI/xHCIController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <Kernel/Arch/Delay.h>
#include <Kernel/Arch/MemoryFences.h>
#include <Kernel/Boot/CommandLine.h>
#include <Kernel/Bus/USB/USBClasses.h>
#include <Kernel/Bus/USB/USBHub.h>
#include <Kernel/Bus/USB/USBRequest.h>
Expand Down Expand Up @@ -255,9 +256,11 @@ ErrorOr<void> xHCIController::initialize()
m_runtime_registers.interrupter_registers[0].interrupter_management.interrupt_enabled = 1;

m_using_message_signalled_interrupts = using_message_signalled_interrupts();
m_interrupter = TRY(create_interrupter(0));

// Fall back to polling if we failed to set up interrupts for the host controller.
if (!kernel_command_line().is_xhci_polling_enabled())
m_interrupter = TRY(create_interrupter(0));

// Fall back to polling if we failed to set up interrupts or xHCI polling was enabled from the command line.
if (m_interrupter == nullptr)
(void)TRY(m_process->create_kernel_thread("xHCI Poll"sv, [this]() { poll_thread(); }));

Expand Down Expand Up @@ -341,6 +344,13 @@ void xHCIController::enqueue_command(TransferRequestBlock& transfer_request_bloc
transfer_request_block.generic.cycle_bit = m_command_ring_producer_cycle_state;
m_command_ring[m_command_ring_enqueue_index] = transfer_request_block;

if constexpr (XHCI_VERBOSE_DEBUG) {
auto vaddr = VirtualAddress { &m_command_ring[m_command_ring_enqueue_index] };
auto paddr = m_command_and_event_rings_region->physical_page(0)->paddr().offset(offsetof(CommandAndEventRings, command_ring) + (m_command_ring_enqueue_index * sizeof(TransferRequestBlock)));
dbgln("-> enqueue_command: {} @ {} {}", enum_to_string(m_command_ring[m_command_ring_enqueue_index].generic.transfer_request_block_type), vaddr, paddr);
m_command_ring[m_command_ring_enqueue_index].dump("-> "sv);
}

m_command_ring_enqueue_index++;

if (m_command_ring_enqueue_index == (command_ring_size - 1)) {
Expand Down Expand Up @@ -738,13 +748,22 @@ ErrorOr<void> xHCIController::enqueue_transfer(u8 slot, u8 endpoint, Pipe::Direc
return ENOBUFS;
endpoint_ring.free_transfer_request_blocks -= transfer_request_blocks.size();

dbgln_if(XHCI_VERBOSE_DEBUG, "-> enqueue_transfer slot={} endpoint={} dir={}:", slot, endpoint, to_underlying(direction));

auto* ring_memory = endpoint_ring.ring_vaddr();
auto first_trb_index = endpoint_ring.enqueue_index;
auto last_trb_index = 0u;
for (auto i = 0u; i < transfer_request_blocks.size(); i++) {
transfer_request_blocks[i].generic.cycle_bit = endpoint_ring.producer_cycle_state ^ (i == 0);
ring_memory[endpoint_ring.enqueue_index] = transfer_request_blocks[i];

if constexpr (XHCI_VERBOSE_DEBUG) {
auto vaddr = VirtualAddress { &ring_memory[endpoint_ring.enqueue_index] };
auto paddr = PhysicalAddress { endpoint_ring.ring_paddr() + (endpoint_ring.enqueue_index * sizeof(TransferRequestBlock)) };
dbgln("-> {}: {} @ {} {}", i, enum_to_string(ring_memory[endpoint_ring.enqueue_index].generic.transfer_request_block_type), vaddr, paddr);
ring_memory[endpoint_ring.enqueue_index].dump("-> "sv);
}

last_trb_index = endpoint_ring.enqueue_index;
endpoint_ring.enqueue_index++;

Expand Down Expand Up @@ -1343,13 +1362,30 @@ void xHCIController::event_handling_thread()
{
while (!Process::current().is_dying()) {
m_event_queue.wait_forever("xHCI"sv);

bool header_printed = false;

// Handle up to ring-size events each time
for (auto i = 0u; i < event_ring_segment_size; ++i) {
// If the Cycle bit of the Event TRB pointed to by the Event Ring Dequeue Pointer equals CCS, then the Event TRB is a valid event,
// software processes it and advances the Event Ring Dequeue Pointer.
if (m_event_ring_segment[m_event_ring_dequeue_index].generic.cycle_bit != m_event_ring_consumer_cycle_state)
break;

if constexpr (XHCI_VERBOSE_DEBUG) {
auto const& trb = m_event_ring_segment[m_event_ring_dequeue_index];

if (!header_printed) {
dbgln("<- Event(s):");
header_printed = true;
}

auto vaddr = VirtualAddress { &trb };
auto paddr = m_command_and_event_rings_region->physical_page(0)->paddr().offset(offsetof(CommandAndEventRings, event_ring_segment) + (m_event_ring_dequeue_index * sizeof(TransferRequestBlock)));
dbgln("<- {}: {} @ {} {}", i, enum_to_string(trb.generic.transfer_request_block_type), vaddr, paddr);
trb.dump("<- "sv);
}

auto event_type = m_event_ring_segment[m_event_ring_dequeue_index].generic.transfer_request_block_type;
switch (event_type) {
case TransferRequestBlock::TRBType::Transfer_Event:
Expand Down
8 changes: 8 additions & 0 deletions Kernel/Bus/USB/xHCI/xHCIController.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,33 +136,41 @@ class xHCIController

size_t context_entry_size() const { return m_large_contexts ? 64 : 32; }
size_t input_context_size() const { return context_entry_size() * 33; }

u8* input_context(u8 slot, u8 index) const
{
auto* base = m_slots_state[slot - 1].input_context_region->vaddr().as_ptr();
return base + (context_entry_size() * index);
}

InputControlContext* input_control_context(u8 slot) const
{
return reinterpret_cast<InputControlContext*>(input_context(slot, 0));
}

SlotContext* input_slot_context(u8 slot) const
{
return reinterpret_cast<SlotContext*>(input_context(slot, 1));
}

EndpointContext* input_endpoint_context(u8 slot, u8 endpoint, Pipe::Direction direction) const
{
return reinterpret_cast<EndpointContext*>(input_context(slot, endpoint_index(endpoint, direction) + 1));
}

size_t device_context_size() const { return context_entry_size() * 32; }

u8* device_context(u8 slot, u8 index) const
{
auto* base = m_slots_state[slot - 1].device_context_region->vaddr().as_ptr();
return base + (context_entry_size() * index);
}

SlotContext* device_slot_context(u8 slot) const
{
return reinterpret_cast<SlotContext*>(device_context(slot, 0));
}

EndpointContext* device_endpoint_context(u8 slot, u8 endpoint, Pipe::Direction direction) const
{
return reinterpret_cast<EndpointContext*>(device_context(slot, endpoint_index(endpoint, direction)));
Expand Down
12 changes: 6 additions & 6 deletions Kernel/Bus/USB/xHCI/xHCIRootHub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ ErrorOr<size_t> xHCIRootHub::handle_control_transfer(Transfer& transfer)
auto* request_data = transfer.buffer().as_ptr() + sizeof(USBRequestData);

if constexpr (XHCI_DEBUG) {
dbgln("xHCIRootHub: Received control transfer.");
dbgln("xHCIRootHub: Request Type: {:#02x}", request.request_type);
dbgln("xHCIRootHub: Request: {:#02x}", request.request);
dbgln("xHCIRootHub: Value: {:#04x}", request.value);
dbgln("xHCIRootHub: Index: {:#04x}", request.index);
dbgln("xHCIRootHub: Length: {:#04x}", request.length);
dbgln("xHCIRootHub: Received control transfer:");
dbgln("xHCIRootHub: bmRequestType: {:#02x}", request.request_type);
dbgln("xHCIRootHub: bRequest: {:#02x}", request.request);
dbgln("xHCIRootHub: wValue: {:#04x}", request.value);
dbgln("xHCIRootHub: wIndex: {:#04x}", request.index);
dbgln("xHCIRootHub: wLength: {:#04x}", request.length);
}

size_t length = 0;
Expand Down
76 changes: 40 additions & 36 deletions Kernel/Debug.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
#cmakedefine01 AC97_DEBUG
#endif

#ifndef AHCI_DEBUG
#cmakedefine01 AHCI_DEBUG
#endif

#ifndef ACPI_DEBUG
#cmakedefine01 ACPI_DEBUG
#endif

#ifndef AHCI_DEBUG
#cmakedefine01 AHCI_DEBUG
#endif

#ifndef APIC_DEBUG
#cmakedefine01 APIC_DEBUG
#endif
Expand Down Expand Up @@ -91,14 +91,14 @@
#cmakedefine01 FUSE_DEBUG
#endif

#ifndef FUTEX_DEBUG
#cmakedefine01 FUTEX_DEBUG
#endif

#ifndef FUTEXQUEUE_DEBUG
#cmakedefine01 FUTEXQUEUE_DEBUG
#endif

#ifndef FUTEX_DEBUG
#cmakedefine01 FUTEX_DEBUG
#endif

#ifndef HID_DEBUG
#cmakedefine01 HID_DEBUG
#endif
Expand All @@ -111,14 +111,14 @@
#cmakedefine01 HPET_DEBUG
#endif

#ifndef ICMP_DEBUG
#cmakedefine01 ICMP_DEBUG
#endif

#ifndef ICMPV6_DEBUG
#cmakedefine01 ICMPV6_DEBUG
#endif

#ifndef ICMP_DEBUG
#cmakedefine01 ICMP_DEBUG
#endif

#ifndef INTEL_GRAPHICS_DEBUG
#cmakedefine01 INTEL_GRAPHICS_DEBUG
#endif
Expand All @@ -131,38 +131,38 @@
#cmakedefine01 INTERRUPT_DEBUG
#endif

#ifndef IO_DEBUG
#cmakedefine01 IO_DEBUG
#endif

#ifndef IOAPIC_DEBUG
#cmakedefine01 IOAPIC_DEBUG
#endif

#ifndef ISO9660_DEBUG
#cmakedefine01 ISO9660_DEBUG
#endif

#ifndef ISO9660_VERY_DEBUG
#cmakedefine01 ISO9660_VERY_DEBUG
#ifndef IO_DEBUG
#cmakedefine01 IO_DEBUG
#endif

#ifndef IPV4_DEBUG
#cmakedefine01 IPV4_DEBUG
#endif

#ifndef IPV6_DEBUG
#cmakedefine01 IPV6_DEBUG
#endif

#ifndef IPV4_SOCKET_DEBUG
#cmakedefine01 IPV4_SOCKET_DEBUG
#endif

#ifndef IPV6_DEBUG
#cmakedefine01 IPV6_DEBUG
#endif

#ifndef IRQ_DEBUG
#cmakedefine01 IRQ_DEBUG
#endif

#ifndef ISO9660_DEBUG
#cmakedefine01 ISO9660_DEBUG
#endif

#ifndef ISO9660_VERY_DEBUG
#cmakedefine01 ISO9660_VERY_DEBUG
#endif

#ifndef KEYBOARD_DEBUG
#cmakedefine01 KEYBOARD_DEBUG
#endif
Expand Down Expand Up @@ -211,14 +211,14 @@
#cmakedefine01 MASTERPTY_DEBUG
#endif

#ifndef MOUSE_DEBUG
#cmakedefine01 MOUSE_DEBUG
#endif

#ifndef MEMORY_DEVICE_DEBUG
#cmakedefine01 MEMORY_DEVICE_DEBUG
#endif

#ifndef MOUSE_DEBUG
#cmakedefine01 MOUSE_DEBUG
#endif

#ifndef MULTIPROCESSOR_DEBUG
#cmakedefine01 MULTIPROCESSOR_DEBUG
#endif
Expand Down Expand Up @@ -343,12 +343,12 @@
#cmakedefine01 USB_DEBUG
#endif

#ifndef VFS_DEBUG
#cmakedefine01 VFS_DEBUG
#ifndef USB_MASS_STORAGE_DEBUG
#cmakedefine01 USB_MASS_STORAGE_DEBUG
#endif

#ifndef VMWARE_BACKDOOR_DEBUG
#cmakedefine01 VMWARE_BACKDOOR_DEBUG
#ifndef VFS_DEBUG
#cmakedefine01 VFS_DEBUG
#endif

#ifndef VIRTIO_DEBUG
Expand All @@ -359,6 +359,10 @@
#cmakedefine01 VIRTUAL_CONSOLE_DEBUG
#endif

#ifndef VMWARE_BACKDOOR_DEBUG
#cmakedefine01 VMWARE_BACKDOOR_DEBUG
#endif

#ifndef WAITBLOCK_DEBUG
#cmakedefine01 WAITBLOCK_DEBUG
#endif
Expand All @@ -371,6 +375,6 @@
#cmakedefine01 XHCI_DEBUG
#endif

#ifndef USB_MASS_STORAGE_DEBUG
#cmakedefine01 USB_MASS_STORAGE_DEBUG
#ifndef XHCI_VERBOSE_DEBUG
#cmakedefine01 XHCI_VERBOSE_DEBUG
#endif
Loading
Loading