add ntfs.sys standalone driver target, change default usb vhd layout formatting to ntfs, implement Fat32CreateDir for directory creation support in the fat32 file system driver, add a dedicated HAL serial output endpoint for COM1 writes in hal_serial.c and subscribe serial to HAL text streams, introduce waitable kernel timers with KeTimerCreate, KeTimerSet, and KeTimerCancel alongside spinlock-protected global timer list initialization and scheduler tick tracking, implement SyscallWriteFileAsync system call for asynchronous non-blocking file writes, refactor NetSocketConnect and NetSocketSendTo to use generic SYS_SOCKET_ADDRESS_K structures instead of being hardcoded to IPv4, update gethostbyname and DNS name resolution to support IPv6 parsing via ResolveNameFamily, update tcpserve.exe with -4 and -6 command-line flags to accept and display IPv6 addresses, append size and version headers to all kernel telemetry and statistics structures including SYS_PMM_STATS, SYS_CPU_STATS, and SYS_SCHEDULER_STATS, update winmm timeGetTime to look up high-resolution hardware frequencies via SysGetTickFrequency, integrate 14 native smoke test applications.
This commit is contained in:
1 parent
2c4a68a75f
commit
ed3d065abd
156 files changed
+10509
-2643
No files matched your search
@@ -7,7 +7,6 @@ uint32_t UsbAlignUp32(uint32_t value, uint32_t align) {
|
||||
return (value + align - 1u) & ~(align - 1u);
|
||||
}
|
||||
|
||||
|
||||
// Implements the barrier operation.
|
||||
void XhciBarrier(void) {
|
||||
_ReadWriteBarrier();
|
||||
@@ -15,31 +14,26 @@ void XhciBarrier(void) {
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
|
||||
|
||||
// Implements the read8 operation.
|
||||
uint8_t XhciRead8(volatile uint8_t* base, uint32_t reg) {
|
||||
return *(volatile uint8_t*)(base + reg);
|
||||
}
|
||||
|
||||
|
||||
// Implements the read16 operation.
|
||||
uint16_t XhciRead16(volatile uint8_t* base, uint32_t reg) {
|
||||
return *(volatile uint16_t*)(base + reg);
|
||||
}
|
||||
|
||||
|
||||
// Implements the read32 operation.
|
||||
uint32_t XhciRead32(volatile uint8_t* base, uint32_t reg) {
|
||||
return *(volatile uint32_t*)(base + reg);
|
||||
}
|
||||
|
||||
|
||||
// Implements the write32 operation.
|
||||
void XhciWrite32(volatile uint8_t* base, uint32_t reg, uint32_t value) {
|
||||
*(volatile uint32_t*)(base + reg) = value;
|
||||
}
|
||||
|
||||
|
||||
// Implements the read64 operation.
|
||||
uint64_t XhciRead64(volatile uint8_t* base, uint32_t reg) {
|
||||
uint32_t lo = XhciRead32(base, reg);
|
||||
@@ -47,14 +41,12 @@ uint64_t XhciRead64(volatile uint8_t* base, uint32_t reg) {
|
||||
return ((uint64_t)hi << 32) | lo;
|
||||
}
|
||||
|
||||
|
||||
// Implements the write64 operation.
|
||||
void XhciWrite64(volatile uint8_t* base, uint32_t reg, uint64_t value) {
|
||||
XhciWrite32(base, reg, (uint32_t)value);
|
||||
XhciWrite32(base, reg + 4u, (uint32_t)(value >> 32));
|
||||
}
|
||||
|
||||
|
||||
// Implements the delay Us operation.
|
||||
void UsbDelayUs(const HAL_API* hal, uint32_t us) {
|
||||
if (hal && hal->Timer.Stall) hal->Timer.Stall(us);
|
||||
@@ -63,7 +55,6 @@ void UsbDelayUs(const HAL_API* hal, uint32_t us) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool UsbWaitSet32(const HAL_API* hal, volatile uint8_t* base, uint32_t reg,
|
||||
uint32_t mask, uint32_t timeoutUs) {
|
||||
for (uint32_t i = 0; i < timeoutUs; i++) {
|
||||
@@ -73,7 +64,6 @@ bool UsbWaitSet32(const HAL_API* hal, volatile uint8_t* base, uint32_t reg,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool UsbWaitClear32(const HAL_API* hal, volatile uint8_t* base, uint32_t reg,
|
||||
uint32_t mask, uint32_t timeoutUs) {
|
||||
for (uint32_t i = 0; i < timeoutUs; i++) {
|
||||
@@ -83,15 +73,14 @@ bool UsbWaitClear32(const HAL_API* hal, volatile uint8_t* base, uint32_t reg,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void* UsbDmaAllocPages(XHCI_CONTROLLER* xhci, size_t pages,
|
||||
PHYSICAL_ADDRESS* outPhys) {
|
||||
if (!outPhys || pages == 0)
|
||||
return NULL;
|
||||
|
||||
// Most xHCI runtime objects are one page. Do not route those through the
|
||||
// Most xHCI runtime objects are one page. Do not route those through the
|
||||
// physically-contiguous allocator: on real machines that allocator is a
|
||||
// scarce DMA primitive, while a single frame is already contiguous. QEMU
|
||||
// scarce DMA primitive, while a single frame is already contiguous. QEMU
|
||||
// hid this because it had simple low memory; laptop firmware does not.
|
||||
PHYSICAL_ADDRESS phys = 0;
|
||||
if (pages == 1) {
|
||||
@@ -112,62 +101,52 @@ void* UsbDmaAllocPages(XHCI_CONTROLLER* xhci, size_t pages,
|
||||
return virt;
|
||||
}
|
||||
|
||||
|
||||
// Implements the scratchpad Count operation.
|
||||
uint16_t XhciScratchpadCount(uint32_t hcs2) {
|
||||
return (uint16_t)((((hcs2 >> 16) & 0x3E0u) | ((hcs2 >> 27) & 0x1Fu)) & 0x3FFu);
|
||||
}
|
||||
|
||||
|
||||
// Implements the trb Type operation.
|
||||
uint32_t XhciTrbType(const XHCI_TRB* trb) {
|
||||
return (trb->Control >> XHCI_TRB_TYPE_SHIFT) & XHCI_TRB_TYPE_MASK;
|
||||
}
|
||||
|
||||
|
||||
// Implements the completion Code operation.
|
||||
uint32_t XhciCompletionCode(const XHCI_TRB* trb) {
|
||||
return (trb->Status >> 24) & 0xFFu;
|
||||
}
|
||||
|
||||
|
||||
// Implements the event Slot Id operation.
|
||||
uint8_t XhciEventSlotId(const XHCI_TRB* trb) {
|
||||
return (uint8_t)(trb->Control >> 24);
|
||||
}
|
||||
|
||||
|
||||
// Implements the event Endpoint Id operation.
|
||||
uint8_t XhciEventEndpointId(const XHCI_TRB* trb) {
|
||||
return (uint8_t)((trb->Control >> 16) & 0x1Fu);
|
||||
}
|
||||
|
||||
|
||||
// Implements the transfer Residue operation.
|
||||
uint32_t XhciTransferResidue(const XHCI_TRB* trb) {
|
||||
return trb->Status & 0xFFFFFFu;
|
||||
}
|
||||
|
||||
|
||||
// Implements the input Control Context operation.
|
||||
uint32_t* XhciInputControlContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
|
||||
(void)xhci;
|
||||
return (uint32_t*)dev->InputContext;
|
||||
}
|
||||
|
||||
|
||||
// Implements the input Slot Context operation.
|
||||
uint32_t* XhciInputSlotContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
|
||||
return (uint32_t*)(dev->InputContext + xhci->ContextBytes);
|
||||
}
|
||||
|
||||
|
||||
uint32_t* XhciInputEndpointContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
uint8_t endpointId) {
|
||||
return (uint32_t*)(dev->InputContext + (uint32_t)(endpointId + 1u) * xhci->ContextBytes);
|
||||
}
|
||||
|
||||
|
||||
// Implements the ep Max Packet operation.
|
||||
uint32_t XhciEpMaxPacket(uint8_t speed) {
|
||||
switch (speed) {
|
||||
@@ -180,7 +159,6 @@ uint32_t XhciEpMaxPacket(uint8_t speed) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implements the setup Packet To U64 operation.
|
||||
uint64_t UsbSetupPacketToU64(const USB_SETUP_PACKET* setup) {
|
||||
uint64_t v = 0;
|
||||
@@ -192,7 +170,6 @@ uint64_t UsbSetupPacketToU64(const USB_SETUP_PACKET* setup) {
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
const char* XhciPortSpeedName(uint32_t speed) {
|
||||
switch (speed) {
|
||||
case 1: return "full";
|
||||
@@ -204,8 +181,6 @@ const char* XhciPortSpeedName(uint32_t speed) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Parses supported Protocols.
|
||||
void XhciParseSupportedProtocols(XHCI_CONTROLLER* xhci) {
|
||||
memset(xhci->PortProtocolMajor, 0, sizeof(xhci->PortProtocolMajor));
|
||||
@@ -253,7 +228,6 @@ void XhciParseSupportedProtocols(XHCI_CONTROLLER* xhci) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implements the port Protocol Major operation.
|
||||
uint8_t XhciPortProtocolMajor(XHCI_CONTROLLER* xhci, uint8_t port, uint32_t portsc) {
|
||||
if (port <= XHCI_MAX_ROOT_PORTS && xhci->PortProtocolMajor[port])
|
||||
@@ -277,12 +251,10 @@ const char* UsbEndpointTypeName(uint8_t type) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char* UsbDirectionName(uint8_t endpointAddress) {
|
||||
return (endpointAddress & USB_ENDPOINT_DIR_IN) ? "in" : "out";
|
||||
}
|
||||
|
||||
|
||||
const char* UsbInterfaceClassName(uint8_t klass, uint8_t subclass, uint8_t proto) {
|
||||
if (klass == USB_CLASS_HID) {
|
||||
if (subclass == 1 && proto == 1) return "hid-boot-keyboard";
|
||||
@@ -297,7 +269,6 @@ const char* UsbInterfaceClassName(uint8_t klass, uint8_t subclass, uint8_t proto
|
||||
return "class";
|
||||
}
|
||||
|
||||
|
||||
// Implements the log Port Status operation.
|
||||
void XhciLogPortStatus(XHCI_CONTROLLER* xhci) {
|
||||
for (uint8_t port = 1; port <= xhci->MaxPorts; port++) {
|
||||
@@ -346,7 +317,6 @@ void XhciPowerRootPorts(XHCI_CONTROLLER* xhci) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implements the ack Interrupter0 operation.
|
||||
void XhciAckInterrupter0(XHCI_CONTROLLER* xhci) {
|
||||
if (!xhci->Runtime) return;
|
||||
@@ -355,7 +325,6 @@ void XhciAckInterrupter0(XHCI_CONTROLLER* xhci) {
|
||||
XhciWrite32(ir0, 0x00u, (iman & XHCI_IMAN_IE) | XHCI_IMAN_IP);
|
||||
}
|
||||
|
||||
|
||||
// Updates erdp.
|
||||
void XhciUpdateErdp(XHCI_CONTROLLER* xhci) {
|
||||
volatile uint8_t* ir0 = xhci->Runtime + 0x20u;
|
||||
@@ -363,7 +332,6 @@ void XhciUpdateErdp(XHCI_CONTROLLER* xhci) {
|
||||
XhciWrite64(ir0, 0x18u, erdp | (1ull << 3)); // EHB clear
|
||||
}
|
||||
|
||||
|
||||
// Returns command Waiter Locked.
|
||||
static XHCI_WAIT_TARGET* XhciFindCommandWaiterLocked(XHCI_CONTROLLER* xhci, uint64_t commandPhys) {
|
||||
for (XHCI_WAIT_TARGET* w = xhci->WaiterList; w; w = w->Next) {
|
||||
@@ -373,7 +341,6 @@ static XHCI_WAIT_TARGET* XhciFindCommandWaiterLocked(XHCI_CONTROLLER* xhci, uint
|
||||
return (XHCI_WAIT_TARGET*)0;
|
||||
}
|
||||
|
||||
|
||||
static XHCI_WAIT_TARGET* XhciFindTransferWaiterLocked(XHCI_CONTROLLER* xhci,
|
||||
uint64_t transferPhys,
|
||||
uint8_t slotId,
|
||||
@@ -389,7 +356,6 @@ static XHCI_WAIT_TARGET* XhciFindTransferWaiterLocked(XHCI_CONTROLLER* xhci,
|
||||
return (XHCI_WAIT_TARGET*)0;
|
||||
}
|
||||
|
||||
|
||||
static XHCI_WAIT_TARGET* XhciClaimCommandWaiter(XHCI_CONTROLLER* xhci,
|
||||
uint64_t commandPhys,
|
||||
uint32_t completionCode,
|
||||
@@ -406,7 +372,6 @@ static XHCI_WAIT_TARGET* XhciClaimCommandWaiter(XHCI_CONTROLLER* xhci,
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
static XHCI_WAIT_TARGET* XhciClaimTransferWaiter(XHCI_CONTROLLER* xhci,
|
||||
uint64_t transferPhys,
|
||||
uint8_t slotId,
|
||||
@@ -427,7 +392,6 @@ static XHCI_WAIT_TARGET* XhciClaimTransferWaiter(XHCI_CONTROLLER* xhci,
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
// Implements the drain Event Ring operation.
|
||||
bool XhciDrainEventRing(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
(void)target;
|
||||
@@ -484,7 +448,6 @@ bool XhciDrainEventRing(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
return processed;
|
||||
}
|
||||
|
||||
|
||||
// Implements the drain Event Ring Locked operation.
|
||||
bool XhciDrainEventRingLocked(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
if (!xhci) return false;
|
||||
@@ -494,7 +457,6 @@ bool XhciDrainEventRingLocked(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
return processed;
|
||||
}
|
||||
|
||||
|
||||
// Waits for target Complete.
|
||||
bool XhciWaitTargetComplete(const XHCI_WAIT_TARGET* target) {
|
||||
if (!target) return false;
|
||||
@@ -503,7 +465,6 @@ bool XhciWaitTargetComplete(const XHCI_WAIT_TARGET* target) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Registers wait Target.
|
||||
void XhciRegisterWaitTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
if (!xhci || !target || target->Registered)
|
||||
@@ -516,7 +477,6 @@ void XhciRegisterWaitTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
KeReleaseSpinlock(&xhci->WaitLock, flags);
|
||||
}
|
||||
|
||||
|
||||
// Implements the unregister Wait Target operation.
|
||||
void XhciUnregisterWaitTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
if (!xhci || !target || !target->Registered)
|
||||
@@ -536,7 +496,6 @@ void XhciUnregisterWaitTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) {
|
||||
KeReleaseSpinlock(&xhci->WaitLock, flags);
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciWaitForArmedTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target,
|
||||
uint32_t timeoutUs) {
|
||||
if (!xhci || !target)
|
||||
@@ -566,7 +525,6 @@ KSTATUS XhciWaitForArmedTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target,
|
||||
return STATUS_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciWaitForTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target,
|
||||
uint32_t timeoutUs) {
|
||||
if (!xhci || !target)
|
||||
@@ -575,7 +533,6 @@ KSTATUS XhciWaitForTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target,
|
||||
return XhciWaitForArmedTarget(xhci, target, timeoutUs);
|
||||
}
|
||||
|
||||
|
||||
void XhciEventDpcRoutine(KDPC* dpc, void* context,
|
||||
void* systemArgument1, void* systemArgument2) {
|
||||
(void)dpc;
|
||||
@@ -592,7 +549,6 @@ void XhciEventDpcRoutine(KDPC* dpc, void* context,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define XHCI_CONTROLLER_MAGIC 0x58484349u // XHCI
|
||||
#define XHCI_MAX_CONTROLLERS 8u
|
||||
|
||||
@@ -630,7 +586,6 @@ void XhciIsr(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implements the bios Handoff operation.
|
||||
KSTATUS XhciBiosHandoff(XHCI_CONTROLLER* xhci) {
|
||||
uint32_t xecp = (xhci->Hcc1 >> 16) & 0xFFFFu;
|
||||
@@ -664,7 +619,7 @@ KSTATUS XhciBiosHandoff(XHCI_CONTROLLER* xhci) {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear legacy SMI enables/status. RW1C status bits tolerate this.
|
||||
// Clear legacy SMI enables/status. RW1C status bits tolerate this.
|
||||
XhciWrite32(xhci->Mmio, off + 4u, 0xFFFFFFFFu);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -675,7 +630,6 @@ KSTATUS XhciBiosHandoff(XHCI_CONTROLLER* xhci) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Implements the stop And Reset operation.
|
||||
KSTATUS XhciStopAndReset(XHCI_CONTROLLER* xhci) {
|
||||
uint32_t cmd = XhciRead32(xhci->Op, XHCI_OP_USBCMD);
|
||||
@@ -709,7 +663,6 @@ KSTATUS XhciStopAndReset(XHCI_CONTROLLER* xhci) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Creates scratchpads.
|
||||
KSTATUS XhciAllocateScratchpads(XHCI_CONTROLLER* xhci) {
|
||||
if (xhci->ScratchpadCount == 0) return STATUS_SUCCESS;
|
||||
@@ -744,7 +697,6 @@ KSTATUS XhciAllocateScratchpads(XHCI_CONTROLLER* xhci) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Creates runtime Memory.
|
||||
KSTATUS XhciAllocateRuntimeMemory(XHCI_CONTROLLER* xhci) {
|
||||
xhci->Dcbaa = (uint64_t*)UsbDmaAllocPages(xhci, 1, &xhci->DcbaaPhys);
|
||||
@@ -786,7 +738,6 @@ KSTATUS XhciAllocateRuntimeMemory(XHCI_CONTROLLER* xhci) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Implements the program Runtime operation.
|
||||
KSTATUS XhciProgramRuntime(XHCI_CONTROLLER* xhci) {
|
||||
uint8_t slots = xhci->MaxSlots;
|
||||
@@ -808,13 +759,11 @@ KSTATUS XhciProgramRuntime(XHCI_CONTROLLER* xhci) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Implements the command Trb Phys operation.
|
||||
uint64_t XhciCommandTrbPhys(XHCI_CONTROLLER* xhci, uint32_t index) {
|
||||
return xhci->CommandRingPhys + (uint64_t)index * sizeof(XHCI_TRB);
|
||||
}
|
||||
|
||||
|
||||
static KSTATUS XhciCommandRingAppend(XHCI_CONTROLLER* xhci,
|
||||
uint64_t parameter,
|
||||
uint32_t status,
|
||||
@@ -850,7 +799,6 @@ static KSTATUS XhciCommandRingAppend(XHCI_CONTROLLER* xhci,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciSubmitCommand(XHCI_CONTROLLER* xhci,
|
||||
uint64_t parameter,
|
||||
uint32_t status,
|
||||
@@ -892,7 +840,6 @@ KSTATUS XhciSubmitCommand(XHCI_CONTROLLER* xhci,
|
||||
return waitStatus;
|
||||
}
|
||||
|
||||
|
||||
// Submits noop Command.
|
||||
KSTATUS XhciSubmitNoopCommand(XHCI_CONTROLLER* xhci) {
|
||||
XHCI_COMMAND_RESULT result;
|
||||
@@ -913,7 +860,6 @@ KSTATUS XhciSubmitNoopCommand(XHCI_CONTROLLER* xhci) {
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
// Enables slot.
|
||||
KSTATUS XhciEnableSlot(XHCI_CONTROLLER* xhci, uint8_t* outSlotId) {
|
||||
XHCI_COMMAND_RESULT result;
|
||||
@@ -938,8 +884,6 @@ KSTATUS XhciEnableSlot(XHCI_CONTROLLER* xhci, uint8_t* outSlotId) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Disables slot.
|
||||
KSTATUS XhciDisableSlot(XHCI_CONTROLLER* xhci, uint8_t slotId) {
|
||||
if (!xhci || slotId == 0)
|
||||
@@ -982,7 +926,6 @@ KSTATUS XhciAddressDevice(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Starts the requested operation.
|
||||
KSTATUS XhciStart(XHCI_CONTROLLER* xhci) {
|
||||
uint32_t cmd = XhciRead32(xhci->Op, XHCI_OP_USBCMD);
|
||||
@@ -1000,7 +943,6 @@ KSTATUS XhciStart(XHCI_CONTROLLER* xhci) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Enables interrupts.
|
||||
void XhciEnableInterrupts(XHCI_CONTROLLER* xhci) {
|
||||
volatile uint8_t* ir0 = xhci->Runtime + 0x20u;
|
||||
@@ -1011,13 +953,11 @@ void XhciEnableInterrupts(XHCI_CONTROLLER* xhci) {
|
||||
XhciWrite32(xhci->Op, XHCI_OP_USBCMD, cmd | XHCI_USBCMD_INTE | XHCI_USBCMD_HSEE);
|
||||
}
|
||||
|
||||
|
||||
// Implements the port Reg operation.
|
||||
uint32_t XhciPortReg(uint8_t port) {
|
||||
return XHCI_OP_PORT_BASE + ((uint32_t)port - 1u) * XHCI_OP_PORT_STRIDE;
|
||||
}
|
||||
|
||||
|
||||
// Clears port Changes.
|
||||
void XhciClearPortChanges(XHCI_CONTROLLER* xhci, uint8_t port) {
|
||||
uint32_t off = XhciPortReg(port);
|
||||
@@ -1025,16 +965,15 @@ void XhciClearPortChanges(XHCI_CONTROLLER* xhci, uint8_t port) {
|
||||
uint32_t changes = portsc & XHCI_PORTSC_CHANGE_MASK;
|
||||
if (changes) {
|
||||
|
||||
// PORTSC is a mixed register. The change bits are RW1C, but many
|
||||
// PORTSC is a mixed register. The change bits are RW1C, but many
|
||||
// other bits are either RO or have side effects when written as one
|
||||
// (PED disables the port; PR starts a reset). Preserve only Port
|
||||
// (PED disables the port; PR starts a reset). Preserve only Port
|
||||
// Power and write one to the RW1C change bits.
|
||||
|
||||
XhciWrite32(xhci->Op, off, (portsc & XHCI_PORTSC_PP) | changes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implements the reset Port operation.
|
||||
KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed) {
|
||||
uint32_t off = XhciPortReg(port);
|
||||
@@ -1050,9 +989,9 @@ KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed) {
|
||||
|
||||
if (protocol >= 3u || speed >= 4u) {
|
||||
|
||||
// SuperSpeed ports are enabled by link training. Do not issue a
|
||||
// SuperSpeed ports are enabled by link training. Do not issue a
|
||||
// USB2-style PORTSC.PR reset; on real Intel controllers that can make
|
||||
// the link drop during early enumeration. If firmware/controller
|
||||
// the link drop during early enumeration. If firmware/controller
|
||||
// already has PR set, just wait for it to settle.
|
||||
|
||||
bool enabled = false;
|
||||
@@ -1118,7 +1057,6 @@ KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Creates device Memory.
|
||||
KSTATUS XhciAllocateDeviceMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
|
||||
dev->InputContext = (uint8_t*)UsbDmaAllocPages(xhci, 1, &dev->InputContextPhys);
|
||||
@@ -1143,7 +1081,6 @@ KSTATUS XhciAllocateDeviceMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Builds default Control Context.
|
||||
void XhciBuildDefaultControlContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
|
||||
memset(dev->InputContext, 0, PAGE_SIZE);
|
||||
@@ -1187,13 +1124,11 @@ void XhciBuildDefaultControlContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
|
||||
XhciBarrier();
|
||||
}
|
||||
|
||||
|
||||
// Implements the ep0 Trb Phys operation.
|
||||
uint64_t XhciEp0TrbPhys(XHCI_DEVICE* dev, uint32_t index) {
|
||||
return dev->Ep0RingPhys + (uint64_t)index * sizeof(XHCI_TRB);
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciEp0AppendTrb(XHCI_DEVICE* dev,
|
||||
uint64_t parameter,
|
||||
uint32_t status,
|
||||
@@ -1229,7 +1164,6 @@ KSTATUS XhciEp0AppendTrb(XHCI_DEVICE* dev,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciControlInTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
const USB_SETUP_PACKET* setup,
|
||||
void* buffer,
|
||||
@@ -1298,7 +1232,6 @@ KSTATUS XhciControlInTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
return STATUS_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciControlIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
const USB_SETUP_PACKET* setup,
|
||||
void* buffer,
|
||||
@@ -1308,7 +1241,6 @@ KSTATUS XhciControlIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
USB_XHCI_CONTROL_TIMEOUT_US);
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciControlNoData(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
const USB_SETUP_PACKET* setup) {
|
||||
uint64_t setupValue = UsbSetupPacketToU64(setup);
|
||||
@@ -1359,7 +1291,6 @@ KSTATUS XhciControlNoData(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
return STATUS_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciGetDeviceDescriptorTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
USB_DEVICE_DESCRIPTOR* outDesc,
|
||||
uint32_t timeoutUs) {
|
||||
@@ -1389,14 +1320,12 @@ KSTATUS XhciGetDeviceDescriptorTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciGetDeviceDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
USB_DEVICE_DESCRIPTOR* outDesc) {
|
||||
return XhciGetDeviceDescriptorTimeout(xhci, dev, outDesc,
|
||||
USB_XHCI_CONTROL_TIMEOUT_US);
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciGetConfigurationDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
uint8_t configurationIndex,
|
||||
USB_CONFIGURATION_DESCRIPTOR* outConfig,
|
||||
@@ -1456,7 +1385,6 @@ KSTATUS XhciGetConfigurationDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Implements the endpoint Id From Address operation.
|
||||
uint8_t XhciEndpointIdFromAddress(uint8_t endpointAddress) {
|
||||
uint8_t number = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
|
||||
@@ -1464,14 +1392,13 @@ uint8_t XhciEndpointIdFromAddress(uint8_t endpointAddress) {
|
||||
return (uint8_t)(number * 2u + ((endpointAddress & USB_ENDPOINT_DIR_IN) ? 1u : 0u));
|
||||
}
|
||||
|
||||
|
||||
// Implements the interrupt Interval operation.
|
||||
uint8_t XhciInterruptInterval(uint8_t speed, uint8_t usbInterval) {
|
||||
if (usbInterval == 0) usbInterval = 1;
|
||||
|
||||
if (speed == 3 || speed == 4 || speed == 5) {
|
||||
// High-speed and newer interrupt endpoints already encode bInterval as
|
||||
// an exponent in USB descriptors. xHCI stores the zero-based exponent.
|
||||
// an exponent in USB descriptors. xHCI stores the zero-based exponent.
|
||||
if (usbInterval > 16) usbInterval = 16;
|
||||
return (uint8_t)(usbInterval - 1u);
|
||||
}
|
||||
@@ -1488,7 +1415,6 @@ uint8_t XhciInterruptInterval(uint8_t speed, uint8_t usbInterval) {
|
||||
return interval;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciRingAppend(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys,
|
||||
uint32_t trbCount, uint32_t* enqueue, uint8_t* cycle,
|
||||
uint64_t parameter, uint32_t status,
|
||||
@@ -1523,7 +1449,6 @@ KSTATUS XhciRingAppend(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void XhciInitialiseTransferRing(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys,
|
||||
uint32_t trbCount, uint8_t cycle) {
|
||||
memset(ring, 0, trbCount * sizeof(XHCI_TRB));
|
||||
@@ -1536,7 +1461,6 @@ void XhciInitialiseTransferRing(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys,
|
||||
cycle;
|
||||
}
|
||||
|
||||
|
||||
KSTATUS XhciBulkTransfer(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
uint8_t endpointId,
|
||||
XHCI_TRB* ring,
|
||||
@@ -1595,9 +1519,6 @@ KSTATUS XhciBulkTransfer(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Implements the configure Pipe Endpoint operation.
|
||||
KSTATUS XhciConfigurePipeEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_PIPE* pipe) {
|
||||
if (!xhci || !dev || !pipe || !pipe->Open)
|
||||
|
||||
Reference in new issue
Block a user