diff --git a/src/userland/usb/Makefile b/src/userland/usb/Makefile index f3ac86a..ceb41ed 100644 --- a/src/userland/usb/Makefile +++ b/src/userland/usb/Makefile @@ -7,7 +7,7 @@ BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) NAME = usb diff --git a/src/userland/usb/Makefile b/src/userland/usb/Makefile index f3ac86a..ceb41ed 100644 --- a/src/userland/usb/Makefile +++ b/src/userland/usb/Makefile @@ -7,7 +7,7 @@ BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) NAME = usb diff --git a/src/userland/usb/compile_flags.txt b/src/userland/usb/compile_flags.txt new file mode 100644 index 0000000..f084bb0 --- /dev/null +++ b/src/userland/usb/compile_flags.txt @@ -0,0 +1,6 @@ +clang +-Iinclude +-I../../include +-fms-extensions +-Wno-microsoft-anon-tag +-Wno-incompatible-library-redeclaration diff --git a/src/userland/usb/Makefile b/src/userland/usb/Makefile index f3ac86a..ceb41ed 100644 --- a/src/userland/usb/Makefile +++ b/src/userland/usb/Makefile @@ -7,7 +7,7 @@ BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) NAME = usb diff --git a/src/userland/usb/compile_flags.txt b/src/userland/usb/compile_flags.txt new file mode 100644 index 0000000..f084bb0 --- /dev/null +++ b/src/userland/usb/compile_flags.txt @@ -0,0 +1,6 @@ +clang +-Iinclude +-I../../include +-fms-extensions +-Wno-microsoft-anon-tag +-Wno-incompatible-library-redeclaration diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h new file mode 100644 index 0000000..39281a9 --- /dev/null +++ b/src/userland/usb/include/usb.h @@ -0,0 +1,189 @@ +#ifndef USB_H +#define USB_H + +#include + +#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) + +typedef volatile struct { + uint8_t capabilitiesLength; + uint8_t reserved; + uint16_t interfaceVersion; + uint32_t structuralParameters[3]; + uint32_t capabilityParameter1; + uint32_t doorbellOffset; + uint32_t runtimeOffset; + uint32_t capabilityParameter2; +} __attribute__((packed)) XHCICapabilities; + +typedef volatile struct { + uint32_t status; + uint32_t powerStatus; + uint32_t linkInfo; + uint32_t hardwareLPM; +} __attribute__((packed)) XHCIPort; + +typedef volatile struct { + uint32_t command; + uint32_t status; + uint32_t pageSize; + uint32_t reserved[2]; + uint32_t notification; + uint32_t commandRingControl[2]; + uint32_t reserved1[4]; + uint32_t deviceContextBaseAddressArray[2]; + uint32_t config; + uint8_t reserved2[964]; + XHCIPort ports[256]; +} __attribute__((packed)) XHCIOperational; + +typedef volatile struct { + uint32_t dataLow; + uint32_t dataHigh; + uint32_t status; + uint32_t control; +} __attribute__((packed)) XHCITRB; + +#define COMMAND_TYPE(x) (x << 10) +#define COMMAND_CYCLE(x) (x) +#define COMMAND_BSR(x) (x << 9) +#define COMMAND_SLOT_ID(x) (x << 24) + +typedef volatile struct { + uint32_t commandLow; + uint32_t commandHigh; + uint32_t completionParameter : 24, completionCode : 8; + uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; +} __attribute__((packed)) CommandCompletionEvent; + +typedef volatile struct { + uint32_t management; + uint32_t moderationCounter : 16, moderationInterval : 16; + uint32_t eventRingSegmentTableSize; // MAX 16 bit + uint32_t reserved2; + uint32_t eventRingSegmentTableAddress[2]; + uint32_t eventRingDequeuePointer[2]; +} __attribute__((packed)) XHCIInterrupter; + +typedef volatile struct { + uint8_t microframeIndex; + uint8_t reserved[0x20 - 1]; + XHCIInterrupter interrupters[1023]; +} __attribute__((packed)) XHCIRuntime; + +typedef volatile struct { + uint32_t ringSegmentBaseAddress[2]; + uint16_t ringSegmentSize, reserved; + uint32_t reserved1; +} __attribute__((packed)) XHCIEventRingSegmentTableEntry; + +typedef volatile struct { + uint32_t requestType : 8, request : 8, value : 16; + uint32_t index : 16, length : 16; + + uint32_t transferLength : 17, // always 8 + reserved : 5, interrupterTarget : 10; + + uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, + immediateData : 1, // here 1 + reserved2 : 3, type : 6, transferType : 2; +} __attribute__((packed)) XHCISetupStageTRB; + +typedef volatile struct { + uint32_t reserved[2]; + + uint32_t reserved1 : 22, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, + interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIStatusStageTRB; + +typedef volatile struct { + uint32_t dataBuffer[2]; + + uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, + noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, + reserved : 3, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIDataStageTRB; + +typedef volatile struct { + uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, + contextEntryCount : 5; + uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; + uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, + reserved1 : 4, interrupterTarget : 10; + uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; + uint32_t reserved3[4]; +} __attribute__((packed)) XHCISlotContext; + +typedef volatile struct { + uint32_t endpointState : 3, reserved : 5, multiplier : 2, + maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, + maxEISTPayloadHigh : 8; + uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, + hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; + uint32_t transferDequeuePointerLow; + uint32_t transferDequeuePointerHigh; + uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; + uint32_t reserved4[3]; +} __attribute__((packed)) XHCIEndpointContext; + +typedef volatile struct { + XHCISlotContext slot; + XHCIEndpointContext endpoints[32]; +} __attribute__((packed)) XHCIDevice; + +typedef volatile struct { + uint32_t dropContextFlags; + uint32_t addContextFlags; + uint32_t reserved[5]; + uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, + reserved1 : 8; +} __attribute__((packed)) XHCIInputControl; + +typedef volatile struct { + XHCIInputControl inputControl; + XHCIDevice deviceContext; +} __attribute__((packed)) XHCIInputContext; + +typedef volatile struct { + uint8_t size; + uint8_t descriptorType; + uint16_t usbVersion; + uint8_t deviceClass; + uint8_t deviceSubclass; + uint8_t deviceProtocol; + uint8_t maxPacketSize; + uint16_t vendor; + uint16_t product; + uint16_t deviceRelease; + uint8_t manufacturerStringDescriptor; + uint8_t deviceStringDescriptor; + uint8_t serialNumberStringDescriptor; + uint8_t configurationCount; +} __attribute__((packed)) UsbDeviceDescriptor; + +typedef struct { + XHCITRB *trbs, *physical; + uint32_t size, enqueue, dequeue; + bool cycle; +} TrbRing; + +typedef struct { + XHCICapabilities *capabilities; + XHCIOperational *operational; + XHCIRuntime *runtime; + TrbRing commands; + TrbRing events; + uint32_t pciDevice; + volatile uint32_t *doorbells; + XHCIEventRingSegmentTableEntry *eventRingSegmentTable, + *eventRingSegmentTablePhysical; + uint64_t *deviceContextBaseAddressArray; + uint32_t portCount; + XHCIInputContext *inputContexts[32]; +} XHCIController; + +#endif diff --git a/src/userland/usb/Makefile b/src/userland/usb/Makefile index f3ac86a..ceb41ed 100644 --- a/src/userland/usb/Makefile +++ b/src/userland/usb/Makefile @@ -7,7 +7,7 @@ BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) NAME = usb diff --git a/src/userland/usb/compile_flags.txt b/src/userland/usb/compile_flags.txt new file mode 100644 index 0000000..f084bb0 --- /dev/null +++ b/src/userland/usb/compile_flags.txt @@ -0,0 +1,6 @@ +clang +-Iinclude +-I../../include +-fms-extensions +-Wno-microsoft-anon-tag +-Wno-incompatible-library-redeclaration diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h new file mode 100644 index 0000000..39281a9 --- /dev/null +++ b/src/userland/usb/include/usb.h @@ -0,0 +1,189 @@ +#ifndef USB_H +#define USB_H + +#include + +#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) + +typedef volatile struct { + uint8_t capabilitiesLength; + uint8_t reserved; + uint16_t interfaceVersion; + uint32_t structuralParameters[3]; + uint32_t capabilityParameter1; + uint32_t doorbellOffset; + uint32_t runtimeOffset; + uint32_t capabilityParameter2; +} __attribute__((packed)) XHCICapabilities; + +typedef volatile struct { + uint32_t status; + uint32_t powerStatus; + uint32_t linkInfo; + uint32_t hardwareLPM; +} __attribute__((packed)) XHCIPort; + +typedef volatile struct { + uint32_t command; + uint32_t status; + uint32_t pageSize; + uint32_t reserved[2]; + uint32_t notification; + uint32_t commandRingControl[2]; + uint32_t reserved1[4]; + uint32_t deviceContextBaseAddressArray[2]; + uint32_t config; + uint8_t reserved2[964]; + XHCIPort ports[256]; +} __attribute__((packed)) XHCIOperational; + +typedef volatile struct { + uint32_t dataLow; + uint32_t dataHigh; + uint32_t status; + uint32_t control; +} __attribute__((packed)) XHCITRB; + +#define COMMAND_TYPE(x) (x << 10) +#define COMMAND_CYCLE(x) (x) +#define COMMAND_BSR(x) (x << 9) +#define COMMAND_SLOT_ID(x) (x << 24) + +typedef volatile struct { + uint32_t commandLow; + uint32_t commandHigh; + uint32_t completionParameter : 24, completionCode : 8; + uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; +} __attribute__((packed)) CommandCompletionEvent; + +typedef volatile struct { + uint32_t management; + uint32_t moderationCounter : 16, moderationInterval : 16; + uint32_t eventRingSegmentTableSize; // MAX 16 bit + uint32_t reserved2; + uint32_t eventRingSegmentTableAddress[2]; + uint32_t eventRingDequeuePointer[2]; +} __attribute__((packed)) XHCIInterrupter; + +typedef volatile struct { + uint8_t microframeIndex; + uint8_t reserved[0x20 - 1]; + XHCIInterrupter interrupters[1023]; +} __attribute__((packed)) XHCIRuntime; + +typedef volatile struct { + uint32_t ringSegmentBaseAddress[2]; + uint16_t ringSegmentSize, reserved; + uint32_t reserved1; +} __attribute__((packed)) XHCIEventRingSegmentTableEntry; + +typedef volatile struct { + uint32_t requestType : 8, request : 8, value : 16; + uint32_t index : 16, length : 16; + + uint32_t transferLength : 17, // always 8 + reserved : 5, interrupterTarget : 10; + + uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, + immediateData : 1, // here 1 + reserved2 : 3, type : 6, transferType : 2; +} __attribute__((packed)) XHCISetupStageTRB; + +typedef volatile struct { + uint32_t reserved[2]; + + uint32_t reserved1 : 22, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, + interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIStatusStageTRB; + +typedef volatile struct { + uint32_t dataBuffer[2]; + + uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, + noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, + reserved : 3, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIDataStageTRB; + +typedef volatile struct { + uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, + contextEntryCount : 5; + uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; + uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, + reserved1 : 4, interrupterTarget : 10; + uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; + uint32_t reserved3[4]; +} __attribute__((packed)) XHCISlotContext; + +typedef volatile struct { + uint32_t endpointState : 3, reserved : 5, multiplier : 2, + maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, + maxEISTPayloadHigh : 8; + uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, + hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; + uint32_t transferDequeuePointerLow; + uint32_t transferDequeuePointerHigh; + uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; + uint32_t reserved4[3]; +} __attribute__((packed)) XHCIEndpointContext; + +typedef volatile struct { + XHCISlotContext slot; + XHCIEndpointContext endpoints[32]; +} __attribute__((packed)) XHCIDevice; + +typedef volatile struct { + uint32_t dropContextFlags; + uint32_t addContextFlags; + uint32_t reserved[5]; + uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, + reserved1 : 8; +} __attribute__((packed)) XHCIInputControl; + +typedef volatile struct { + XHCIInputControl inputControl; + XHCIDevice deviceContext; +} __attribute__((packed)) XHCIInputContext; + +typedef volatile struct { + uint8_t size; + uint8_t descriptorType; + uint16_t usbVersion; + uint8_t deviceClass; + uint8_t deviceSubclass; + uint8_t deviceProtocol; + uint8_t maxPacketSize; + uint16_t vendor; + uint16_t product; + uint16_t deviceRelease; + uint8_t manufacturerStringDescriptor; + uint8_t deviceStringDescriptor; + uint8_t serialNumberStringDescriptor; + uint8_t configurationCount; +} __attribute__((packed)) UsbDeviceDescriptor; + +typedef struct { + XHCITRB *trbs, *physical; + uint32_t size, enqueue, dequeue; + bool cycle; +} TrbRing; + +typedef struct { + XHCICapabilities *capabilities; + XHCIOperational *operational; + XHCIRuntime *runtime; + TrbRing commands; + TrbRing events; + uint32_t pciDevice; + volatile uint32_t *doorbells; + XHCIEventRingSegmentTableEntry *eventRingSegmentTable, + *eventRingSegmentTablePhysical; + uint64_t *deviceContextBaseAddressArray; + uint32_t portCount; + XHCIInputContext *inputContexts[32]; +} XHCIController; + +#endif diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index b6d1558..90a3bc5 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -2,31 +2,13 @@ #include #include "../hlib/include/syscalls.h" -#include "usb.h" +#include "xhci/trbRing.h" +#include uint32_t serviceId; XHCIController *controller; -XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb) { - trb->control |= ring->cycle; - memcpy((void *)trb, (void *)&ring->trbs[ring->enqueue], sizeof(XHCITRB)); - XHCITRB *result = &ring->physical[ring->enqueue]; - ring->enqueue++; - if (ring->enqueue == ring->size - 1) { - if (ring->trbs[ring->enqueue].control & 1) { - ring->trbs[ring->enqueue].control &= ~1; - } else { - ring->trbs[ring->enqueue].control |= 1; - } - if (ring->trbs[ring->enqueue].control & 1) { - ring->cycle ^= 1; - } - ring->enqueue = 0; - } - return result; -} - CommandCompletionEvent *xhciCommand(XHCIController *controller, uint32_t dataLow, uint32_t dataHigh, uint32_t status, uint32_t control) { @@ -75,34 +57,6 @@ ; } -XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) { - if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) { - return NULL; - } - if (index) { - *index = ring->dequeue; - } - XHCITRB *result = &ring->trbs[ring->dequeue]; - ring->dequeue++; - if (ring->dequeue == ring->size) { - ring->dequeue = 0; - ring->cycle ^= -1; - } - return result; -} - -void setupTrbRing(TrbRing *ring, uint32_t size) { - ring->trbs = requestMemory(1, 0, 0); - ring->physical = getPhysicalAddress((void *)ring->trbs); - ring->cycle = true; - ring->enqueue = 0; - ring->dequeue = 0; - ring->size = size; - // define link to beginning - ring->trbs[ring->size - 1].dataLow = U32(ring->physical); - ring->trbs[ring->size - 1].control |= COMMAND_CYCLE(true) | COMMAND_TYPE(6); -} - void setupRuntime(XHCIController *controller) { controller->runtime = OFFSET(controller->capabilities, controller->capabilities->runtimeOffset); @@ -362,10 +316,6 @@ printf("manufacturer: %s, device: %s, serial: %s\n", manufacturer, device, serial); printf("--------\n"); - // configure endpoint gives a trb error as of now ... - // configureEndpoint(getPhysicalAddress((void - // *)&inputContext->inputControl), - // slotIndex, false); } void xhciInterrupt() { diff --git a/src/userland/usb/Makefile b/src/userland/usb/Makefile index f3ac86a..ceb41ed 100644 --- a/src/userland/usb/Makefile +++ b/src/userland/usb/Makefile @@ -7,7 +7,7 @@ BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) NAME = usb diff --git a/src/userland/usb/compile_flags.txt b/src/userland/usb/compile_flags.txt new file mode 100644 index 0000000..f084bb0 --- /dev/null +++ b/src/userland/usb/compile_flags.txt @@ -0,0 +1,6 @@ +clang +-Iinclude +-I../../include +-fms-extensions +-Wno-microsoft-anon-tag +-Wno-incompatible-library-redeclaration diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h new file mode 100644 index 0000000..39281a9 --- /dev/null +++ b/src/userland/usb/include/usb.h @@ -0,0 +1,189 @@ +#ifndef USB_H +#define USB_H + +#include + +#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) + +typedef volatile struct { + uint8_t capabilitiesLength; + uint8_t reserved; + uint16_t interfaceVersion; + uint32_t structuralParameters[3]; + uint32_t capabilityParameter1; + uint32_t doorbellOffset; + uint32_t runtimeOffset; + uint32_t capabilityParameter2; +} __attribute__((packed)) XHCICapabilities; + +typedef volatile struct { + uint32_t status; + uint32_t powerStatus; + uint32_t linkInfo; + uint32_t hardwareLPM; +} __attribute__((packed)) XHCIPort; + +typedef volatile struct { + uint32_t command; + uint32_t status; + uint32_t pageSize; + uint32_t reserved[2]; + uint32_t notification; + uint32_t commandRingControl[2]; + uint32_t reserved1[4]; + uint32_t deviceContextBaseAddressArray[2]; + uint32_t config; + uint8_t reserved2[964]; + XHCIPort ports[256]; +} __attribute__((packed)) XHCIOperational; + +typedef volatile struct { + uint32_t dataLow; + uint32_t dataHigh; + uint32_t status; + uint32_t control; +} __attribute__((packed)) XHCITRB; + +#define COMMAND_TYPE(x) (x << 10) +#define COMMAND_CYCLE(x) (x) +#define COMMAND_BSR(x) (x << 9) +#define COMMAND_SLOT_ID(x) (x << 24) + +typedef volatile struct { + uint32_t commandLow; + uint32_t commandHigh; + uint32_t completionParameter : 24, completionCode : 8; + uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; +} __attribute__((packed)) CommandCompletionEvent; + +typedef volatile struct { + uint32_t management; + uint32_t moderationCounter : 16, moderationInterval : 16; + uint32_t eventRingSegmentTableSize; // MAX 16 bit + uint32_t reserved2; + uint32_t eventRingSegmentTableAddress[2]; + uint32_t eventRingDequeuePointer[2]; +} __attribute__((packed)) XHCIInterrupter; + +typedef volatile struct { + uint8_t microframeIndex; + uint8_t reserved[0x20 - 1]; + XHCIInterrupter interrupters[1023]; +} __attribute__((packed)) XHCIRuntime; + +typedef volatile struct { + uint32_t ringSegmentBaseAddress[2]; + uint16_t ringSegmentSize, reserved; + uint32_t reserved1; +} __attribute__((packed)) XHCIEventRingSegmentTableEntry; + +typedef volatile struct { + uint32_t requestType : 8, request : 8, value : 16; + uint32_t index : 16, length : 16; + + uint32_t transferLength : 17, // always 8 + reserved : 5, interrupterTarget : 10; + + uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, + immediateData : 1, // here 1 + reserved2 : 3, type : 6, transferType : 2; +} __attribute__((packed)) XHCISetupStageTRB; + +typedef volatile struct { + uint32_t reserved[2]; + + uint32_t reserved1 : 22, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, + interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIStatusStageTRB; + +typedef volatile struct { + uint32_t dataBuffer[2]; + + uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, + noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, + reserved : 3, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIDataStageTRB; + +typedef volatile struct { + uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, + contextEntryCount : 5; + uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; + uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, + reserved1 : 4, interrupterTarget : 10; + uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; + uint32_t reserved3[4]; +} __attribute__((packed)) XHCISlotContext; + +typedef volatile struct { + uint32_t endpointState : 3, reserved : 5, multiplier : 2, + maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, + maxEISTPayloadHigh : 8; + uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, + hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; + uint32_t transferDequeuePointerLow; + uint32_t transferDequeuePointerHigh; + uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; + uint32_t reserved4[3]; +} __attribute__((packed)) XHCIEndpointContext; + +typedef volatile struct { + XHCISlotContext slot; + XHCIEndpointContext endpoints[32]; +} __attribute__((packed)) XHCIDevice; + +typedef volatile struct { + uint32_t dropContextFlags; + uint32_t addContextFlags; + uint32_t reserved[5]; + uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, + reserved1 : 8; +} __attribute__((packed)) XHCIInputControl; + +typedef volatile struct { + XHCIInputControl inputControl; + XHCIDevice deviceContext; +} __attribute__((packed)) XHCIInputContext; + +typedef volatile struct { + uint8_t size; + uint8_t descriptorType; + uint16_t usbVersion; + uint8_t deviceClass; + uint8_t deviceSubclass; + uint8_t deviceProtocol; + uint8_t maxPacketSize; + uint16_t vendor; + uint16_t product; + uint16_t deviceRelease; + uint8_t manufacturerStringDescriptor; + uint8_t deviceStringDescriptor; + uint8_t serialNumberStringDescriptor; + uint8_t configurationCount; +} __attribute__((packed)) UsbDeviceDescriptor; + +typedef struct { + XHCITRB *trbs, *physical; + uint32_t size, enqueue, dequeue; + bool cycle; +} TrbRing; + +typedef struct { + XHCICapabilities *capabilities; + XHCIOperational *operational; + XHCIRuntime *runtime; + TrbRing commands; + TrbRing events; + uint32_t pciDevice; + volatile uint32_t *doorbells; + XHCIEventRingSegmentTableEntry *eventRingSegmentTable, + *eventRingSegmentTablePhysical; + uint64_t *deviceContextBaseAddressArray; + uint32_t portCount; + XHCIInputContext *inputContexts[32]; +} XHCIController; + +#endif diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index b6d1558..90a3bc5 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -2,31 +2,13 @@ #include #include "../hlib/include/syscalls.h" -#include "usb.h" +#include "xhci/trbRing.h" +#include uint32_t serviceId; XHCIController *controller; -XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb) { - trb->control |= ring->cycle; - memcpy((void *)trb, (void *)&ring->trbs[ring->enqueue], sizeof(XHCITRB)); - XHCITRB *result = &ring->physical[ring->enqueue]; - ring->enqueue++; - if (ring->enqueue == ring->size - 1) { - if (ring->trbs[ring->enqueue].control & 1) { - ring->trbs[ring->enqueue].control &= ~1; - } else { - ring->trbs[ring->enqueue].control |= 1; - } - if (ring->trbs[ring->enqueue].control & 1) { - ring->cycle ^= 1; - } - ring->enqueue = 0; - } - return result; -} - CommandCompletionEvent *xhciCommand(XHCIController *controller, uint32_t dataLow, uint32_t dataHigh, uint32_t status, uint32_t control) { @@ -75,34 +57,6 @@ ; } -XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) { - if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) { - return NULL; - } - if (index) { - *index = ring->dequeue; - } - XHCITRB *result = &ring->trbs[ring->dequeue]; - ring->dequeue++; - if (ring->dequeue == ring->size) { - ring->dequeue = 0; - ring->cycle ^= -1; - } - return result; -} - -void setupTrbRing(TrbRing *ring, uint32_t size) { - ring->trbs = requestMemory(1, 0, 0); - ring->physical = getPhysicalAddress((void *)ring->trbs); - ring->cycle = true; - ring->enqueue = 0; - ring->dequeue = 0; - ring->size = size; - // define link to beginning - ring->trbs[ring->size - 1].dataLow = U32(ring->physical); - ring->trbs[ring->size - 1].control |= COMMAND_CYCLE(true) | COMMAND_TYPE(6); -} - void setupRuntime(XHCIController *controller) { controller->runtime = OFFSET(controller->capabilities, controller->capabilities->runtimeOffset); @@ -362,10 +316,6 @@ printf("manufacturer: %s, device: %s, serial: %s\n", manufacturer, device, serial); printf("--------\n"); - // configure endpoint gives a trb error as of now ... - // configureEndpoint(getPhysicalAddress((void - // *)&inputContext->inputControl), - // slotIndex, false); } void xhciInterrupt() { diff --git a/src/userland/usb/usb.h b/src/userland/usb/usb.h deleted file mode 100644 index 39281a9..0000000 --- a/src/userland/usb/usb.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef USB_H -#define USB_H - -#include - -#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) - -typedef volatile struct { - uint8_t capabilitiesLength; - uint8_t reserved; - uint16_t interfaceVersion; - uint32_t structuralParameters[3]; - uint32_t capabilityParameter1; - uint32_t doorbellOffset; - uint32_t runtimeOffset; - uint32_t capabilityParameter2; -} __attribute__((packed)) XHCICapabilities; - -typedef volatile struct { - uint32_t status; - uint32_t powerStatus; - uint32_t linkInfo; - uint32_t hardwareLPM; -} __attribute__((packed)) XHCIPort; - -typedef volatile struct { - uint32_t command; - uint32_t status; - uint32_t pageSize; - uint32_t reserved[2]; - uint32_t notification; - uint32_t commandRingControl[2]; - uint32_t reserved1[4]; - uint32_t deviceContextBaseAddressArray[2]; - uint32_t config; - uint8_t reserved2[964]; - XHCIPort ports[256]; -} __attribute__((packed)) XHCIOperational; - -typedef volatile struct { - uint32_t dataLow; - uint32_t dataHigh; - uint32_t status; - uint32_t control; -} __attribute__((packed)) XHCITRB; - -#define COMMAND_TYPE(x) (x << 10) -#define COMMAND_CYCLE(x) (x) -#define COMMAND_BSR(x) (x << 9) -#define COMMAND_SLOT_ID(x) (x << 24) - -typedef volatile struct { - uint32_t commandLow; - uint32_t commandHigh; - uint32_t completionParameter : 24, completionCode : 8; - uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; -} __attribute__((packed)) CommandCompletionEvent; - -typedef volatile struct { - uint32_t management; - uint32_t moderationCounter : 16, moderationInterval : 16; - uint32_t eventRingSegmentTableSize; // MAX 16 bit - uint32_t reserved2; - uint32_t eventRingSegmentTableAddress[2]; - uint32_t eventRingDequeuePointer[2]; -} __attribute__((packed)) XHCIInterrupter; - -typedef volatile struct { - uint8_t microframeIndex; - uint8_t reserved[0x20 - 1]; - XHCIInterrupter interrupters[1023]; -} __attribute__((packed)) XHCIRuntime; - -typedef volatile struct { - uint32_t ringSegmentBaseAddress[2]; - uint16_t ringSegmentSize, reserved; - uint32_t reserved1; -} __attribute__((packed)) XHCIEventRingSegmentTableEntry; - -typedef volatile struct { - uint32_t requestType : 8, request : 8, value : 16; - uint32_t index : 16, length : 16; - - uint32_t transferLength : 17, // always 8 - reserved : 5, interrupterTarget : 10; - - uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, - immediateData : 1, // here 1 - reserved2 : 3, type : 6, transferType : 2; -} __attribute__((packed)) XHCISetupStageTRB; - -typedef volatile struct { - uint32_t reserved[2]; - - uint32_t reserved1 : 22, interrupterTarget : 10; - - uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, - interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; -} __attribute__((packed)) XHCIStatusStageTRB; - -typedef volatile struct { - uint32_t dataBuffer[2]; - - uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; - - uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, - noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, - reserved : 3, type : 6, inDirection : 1; -} __attribute__((packed)) XHCIDataStageTRB; - -typedef volatile struct { - uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, - contextEntryCount : 5; - uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; - uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, - reserved1 : 4, interrupterTarget : 10; - uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; - uint32_t reserved3[4]; -} __attribute__((packed)) XHCISlotContext; - -typedef volatile struct { - uint32_t endpointState : 3, reserved : 5, multiplier : 2, - maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, - maxEISTPayloadHigh : 8; - uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, - hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; - uint32_t transferDequeuePointerLow; - uint32_t transferDequeuePointerHigh; - uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; - uint32_t reserved4[3]; -} __attribute__((packed)) XHCIEndpointContext; - -typedef volatile struct { - XHCISlotContext slot; - XHCIEndpointContext endpoints[32]; -} __attribute__((packed)) XHCIDevice; - -typedef volatile struct { - uint32_t dropContextFlags; - uint32_t addContextFlags; - uint32_t reserved[5]; - uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, - reserved1 : 8; -} __attribute__((packed)) XHCIInputControl; - -typedef volatile struct { - XHCIInputControl inputControl; - XHCIDevice deviceContext; -} __attribute__((packed)) XHCIInputContext; - -typedef volatile struct { - uint8_t size; - uint8_t descriptorType; - uint16_t usbVersion; - uint8_t deviceClass; - uint8_t deviceSubclass; - uint8_t deviceProtocol; - uint8_t maxPacketSize; - uint16_t vendor; - uint16_t product; - uint16_t deviceRelease; - uint8_t manufacturerStringDescriptor; - uint8_t deviceStringDescriptor; - uint8_t serialNumberStringDescriptor; - uint8_t configurationCount; -} __attribute__((packed)) UsbDeviceDescriptor; - -typedef struct { - XHCITRB *trbs, *physical; - uint32_t size, enqueue, dequeue; - bool cycle; -} TrbRing; - -typedef struct { - XHCICapabilities *capabilities; - XHCIOperational *operational; - XHCIRuntime *runtime; - TrbRing commands; - TrbRing events; - uint32_t pciDevice; - volatile uint32_t *doorbells; - XHCIEventRingSegmentTableEntry *eventRingSegmentTable, - *eventRingSegmentTablePhysical; - uint64_t *deviceContextBaseAddressArray; - uint32_t portCount; - XHCIInputContext *inputContexts[32]; -} XHCIController; - -#endif diff --git a/src/userland/usb/Makefile b/src/userland/usb/Makefile index f3ac86a..ceb41ed 100644 --- a/src/userland/usb/Makefile +++ b/src/userland/usb/Makefile @@ -7,7 +7,7 @@ BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) NAME = usb diff --git a/src/userland/usb/compile_flags.txt b/src/userland/usb/compile_flags.txt new file mode 100644 index 0000000..f084bb0 --- /dev/null +++ b/src/userland/usb/compile_flags.txt @@ -0,0 +1,6 @@ +clang +-Iinclude +-I../../include +-fms-extensions +-Wno-microsoft-anon-tag +-Wno-incompatible-library-redeclaration diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h new file mode 100644 index 0000000..39281a9 --- /dev/null +++ b/src/userland/usb/include/usb.h @@ -0,0 +1,189 @@ +#ifndef USB_H +#define USB_H + +#include + +#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) + +typedef volatile struct { + uint8_t capabilitiesLength; + uint8_t reserved; + uint16_t interfaceVersion; + uint32_t structuralParameters[3]; + uint32_t capabilityParameter1; + uint32_t doorbellOffset; + uint32_t runtimeOffset; + uint32_t capabilityParameter2; +} __attribute__((packed)) XHCICapabilities; + +typedef volatile struct { + uint32_t status; + uint32_t powerStatus; + uint32_t linkInfo; + uint32_t hardwareLPM; +} __attribute__((packed)) XHCIPort; + +typedef volatile struct { + uint32_t command; + uint32_t status; + uint32_t pageSize; + uint32_t reserved[2]; + uint32_t notification; + uint32_t commandRingControl[2]; + uint32_t reserved1[4]; + uint32_t deviceContextBaseAddressArray[2]; + uint32_t config; + uint8_t reserved2[964]; + XHCIPort ports[256]; +} __attribute__((packed)) XHCIOperational; + +typedef volatile struct { + uint32_t dataLow; + uint32_t dataHigh; + uint32_t status; + uint32_t control; +} __attribute__((packed)) XHCITRB; + +#define COMMAND_TYPE(x) (x << 10) +#define COMMAND_CYCLE(x) (x) +#define COMMAND_BSR(x) (x << 9) +#define COMMAND_SLOT_ID(x) (x << 24) + +typedef volatile struct { + uint32_t commandLow; + uint32_t commandHigh; + uint32_t completionParameter : 24, completionCode : 8; + uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; +} __attribute__((packed)) CommandCompletionEvent; + +typedef volatile struct { + uint32_t management; + uint32_t moderationCounter : 16, moderationInterval : 16; + uint32_t eventRingSegmentTableSize; // MAX 16 bit + uint32_t reserved2; + uint32_t eventRingSegmentTableAddress[2]; + uint32_t eventRingDequeuePointer[2]; +} __attribute__((packed)) XHCIInterrupter; + +typedef volatile struct { + uint8_t microframeIndex; + uint8_t reserved[0x20 - 1]; + XHCIInterrupter interrupters[1023]; +} __attribute__((packed)) XHCIRuntime; + +typedef volatile struct { + uint32_t ringSegmentBaseAddress[2]; + uint16_t ringSegmentSize, reserved; + uint32_t reserved1; +} __attribute__((packed)) XHCIEventRingSegmentTableEntry; + +typedef volatile struct { + uint32_t requestType : 8, request : 8, value : 16; + uint32_t index : 16, length : 16; + + uint32_t transferLength : 17, // always 8 + reserved : 5, interrupterTarget : 10; + + uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, + immediateData : 1, // here 1 + reserved2 : 3, type : 6, transferType : 2; +} __attribute__((packed)) XHCISetupStageTRB; + +typedef volatile struct { + uint32_t reserved[2]; + + uint32_t reserved1 : 22, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, + interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIStatusStageTRB; + +typedef volatile struct { + uint32_t dataBuffer[2]; + + uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, + noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, + reserved : 3, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIDataStageTRB; + +typedef volatile struct { + uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, + contextEntryCount : 5; + uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; + uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, + reserved1 : 4, interrupterTarget : 10; + uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; + uint32_t reserved3[4]; +} __attribute__((packed)) XHCISlotContext; + +typedef volatile struct { + uint32_t endpointState : 3, reserved : 5, multiplier : 2, + maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, + maxEISTPayloadHigh : 8; + uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, + hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; + uint32_t transferDequeuePointerLow; + uint32_t transferDequeuePointerHigh; + uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; + uint32_t reserved4[3]; +} __attribute__((packed)) XHCIEndpointContext; + +typedef volatile struct { + XHCISlotContext slot; + XHCIEndpointContext endpoints[32]; +} __attribute__((packed)) XHCIDevice; + +typedef volatile struct { + uint32_t dropContextFlags; + uint32_t addContextFlags; + uint32_t reserved[5]; + uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, + reserved1 : 8; +} __attribute__((packed)) XHCIInputControl; + +typedef volatile struct { + XHCIInputControl inputControl; + XHCIDevice deviceContext; +} __attribute__((packed)) XHCIInputContext; + +typedef volatile struct { + uint8_t size; + uint8_t descriptorType; + uint16_t usbVersion; + uint8_t deviceClass; + uint8_t deviceSubclass; + uint8_t deviceProtocol; + uint8_t maxPacketSize; + uint16_t vendor; + uint16_t product; + uint16_t deviceRelease; + uint8_t manufacturerStringDescriptor; + uint8_t deviceStringDescriptor; + uint8_t serialNumberStringDescriptor; + uint8_t configurationCount; +} __attribute__((packed)) UsbDeviceDescriptor; + +typedef struct { + XHCITRB *trbs, *physical; + uint32_t size, enqueue, dequeue; + bool cycle; +} TrbRing; + +typedef struct { + XHCICapabilities *capabilities; + XHCIOperational *operational; + XHCIRuntime *runtime; + TrbRing commands; + TrbRing events; + uint32_t pciDevice; + volatile uint32_t *doorbells; + XHCIEventRingSegmentTableEntry *eventRingSegmentTable, + *eventRingSegmentTablePhysical; + uint64_t *deviceContextBaseAddressArray; + uint32_t portCount; + XHCIInputContext *inputContexts[32]; +} XHCIController; + +#endif diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index b6d1558..90a3bc5 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -2,31 +2,13 @@ #include #include "../hlib/include/syscalls.h" -#include "usb.h" +#include "xhci/trbRing.h" +#include uint32_t serviceId; XHCIController *controller; -XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb) { - trb->control |= ring->cycle; - memcpy((void *)trb, (void *)&ring->trbs[ring->enqueue], sizeof(XHCITRB)); - XHCITRB *result = &ring->physical[ring->enqueue]; - ring->enqueue++; - if (ring->enqueue == ring->size - 1) { - if (ring->trbs[ring->enqueue].control & 1) { - ring->trbs[ring->enqueue].control &= ~1; - } else { - ring->trbs[ring->enqueue].control |= 1; - } - if (ring->trbs[ring->enqueue].control & 1) { - ring->cycle ^= 1; - } - ring->enqueue = 0; - } - return result; -} - CommandCompletionEvent *xhciCommand(XHCIController *controller, uint32_t dataLow, uint32_t dataHigh, uint32_t status, uint32_t control) { @@ -75,34 +57,6 @@ ; } -XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) { - if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) { - return NULL; - } - if (index) { - *index = ring->dequeue; - } - XHCITRB *result = &ring->trbs[ring->dequeue]; - ring->dequeue++; - if (ring->dequeue == ring->size) { - ring->dequeue = 0; - ring->cycle ^= -1; - } - return result; -} - -void setupTrbRing(TrbRing *ring, uint32_t size) { - ring->trbs = requestMemory(1, 0, 0); - ring->physical = getPhysicalAddress((void *)ring->trbs); - ring->cycle = true; - ring->enqueue = 0; - ring->dequeue = 0; - ring->size = size; - // define link to beginning - ring->trbs[ring->size - 1].dataLow = U32(ring->physical); - ring->trbs[ring->size - 1].control |= COMMAND_CYCLE(true) | COMMAND_TYPE(6); -} - void setupRuntime(XHCIController *controller) { controller->runtime = OFFSET(controller->capabilities, controller->capabilities->runtimeOffset); @@ -362,10 +316,6 @@ printf("manufacturer: %s, device: %s, serial: %s\n", manufacturer, device, serial); printf("--------\n"); - // configure endpoint gives a trb error as of now ... - // configureEndpoint(getPhysicalAddress((void - // *)&inputContext->inputControl), - // slotIndex, false); } void xhciInterrupt() { diff --git a/src/userland/usb/usb.h b/src/userland/usb/usb.h deleted file mode 100644 index 39281a9..0000000 --- a/src/userland/usb/usb.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef USB_H -#define USB_H - -#include - -#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) - -typedef volatile struct { - uint8_t capabilitiesLength; - uint8_t reserved; - uint16_t interfaceVersion; - uint32_t structuralParameters[3]; - uint32_t capabilityParameter1; - uint32_t doorbellOffset; - uint32_t runtimeOffset; - uint32_t capabilityParameter2; -} __attribute__((packed)) XHCICapabilities; - -typedef volatile struct { - uint32_t status; - uint32_t powerStatus; - uint32_t linkInfo; - uint32_t hardwareLPM; -} __attribute__((packed)) XHCIPort; - -typedef volatile struct { - uint32_t command; - uint32_t status; - uint32_t pageSize; - uint32_t reserved[2]; - uint32_t notification; - uint32_t commandRingControl[2]; - uint32_t reserved1[4]; - uint32_t deviceContextBaseAddressArray[2]; - uint32_t config; - uint8_t reserved2[964]; - XHCIPort ports[256]; -} __attribute__((packed)) XHCIOperational; - -typedef volatile struct { - uint32_t dataLow; - uint32_t dataHigh; - uint32_t status; - uint32_t control; -} __attribute__((packed)) XHCITRB; - -#define COMMAND_TYPE(x) (x << 10) -#define COMMAND_CYCLE(x) (x) -#define COMMAND_BSR(x) (x << 9) -#define COMMAND_SLOT_ID(x) (x << 24) - -typedef volatile struct { - uint32_t commandLow; - uint32_t commandHigh; - uint32_t completionParameter : 24, completionCode : 8; - uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; -} __attribute__((packed)) CommandCompletionEvent; - -typedef volatile struct { - uint32_t management; - uint32_t moderationCounter : 16, moderationInterval : 16; - uint32_t eventRingSegmentTableSize; // MAX 16 bit - uint32_t reserved2; - uint32_t eventRingSegmentTableAddress[2]; - uint32_t eventRingDequeuePointer[2]; -} __attribute__((packed)) XHCIInterrupter; - -typedef volatile struct { - uint8_t microframeIndex; - uint8_t reserved[0x20 - 1]; - XHCIInterrupter interrupters[1023]; -} __attribute__((packed)) XHCIRuntime; - -typedef volatile struct { - uint32_t ringSegmentBaseAddress[2]; - uint16_t ringSegmentSize, reserved; - uint32_t reserved1; -} __attribute__((packed)) XHCIEventRingSegmentTableEntry; - -typedef volatile struct { - uint32_t requestType : 8, request : 8, value : 16; - uint32_t index : 16, length : 16; - - uint32_t transferLength : 17, // always 8 - reserved : 5, interrupterTarget : 10; - - uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, - immediateData : 1, // here 1 - reserved2 : 3, type : 6, transferType : 2; -} __attribute__((packed)) XHCISetupStageTRB; - -typedef volatile struct { - uint32_t reserved[2]; - - uint32_t reserved1 : 22, interrupterTarget : 10; - - uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, - interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; -} __attribute__((packed)) XHCIStatusStageTRB; - -typedef volatile struct { - uint32_t dataBuffer[2]; - - uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; - - uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, - noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, - reserved : 3, type : 6, inDirection : 1; -} __attribute__((packed)) XHCIDataStageTRB; - -typedef volatile struct { - uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, - contextEntryCount : 5; - uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; - uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, - reserved1 : 4, interrupterTarget : 10; - uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; - uint32_t reserved3[4]; -} __attribute__((packed)) XHCISlotContext; - -typedef volatile struct { - uint32_t endpointState : 3, reserved : 5, multiplier : 2, - maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, - maxEISTPayloadHigh : 8; - uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, - hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; - uint32_t transferDequeuePointerLow; - uint32_t transferDequeuePointerHigh; - uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; - uint32_t reserved4[3]; -} __attribute__((packed)) XHCIEndpointContext; - -typedef volatile struct { - XHCISlotContext slot; - XHCIEndpointContext endpoints[32]; -} __attribute__((packed)) XHCIDevice; - -typedef volatile struct { - uint32_t dropContextFlags; - uint32_t addContextFlags; - uint32_t reserved[5]; - uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, - reserved1 : 8; -} __attribute__((packed)) XHCIInputControl; - -typedef volatile struct { - XHCIInputControl inputControl; - XHCIDevice deviceContext; -} __attribute__((packed)) XHCIInputContext; - -typedef volatile struct { - uint8_t size; - uint8_t descriptorType; - uint16_t usbVersion; - uint8_t deviceClass; - uint8_t deviceSubclass; - uint8_t deviceProtocol; - uint8_t maxPacketSize; - uint16_t vendor; - uint16_t product; - uint16_t deviceRelease; - uint8_t manufacturerStringDescriptor; - uint8_t deviceStringDescriptor; - uint8_t serialNumberStringDescriptor; - uint8_t configurationCount; -} __attribute__((packed)) UsbDeviceDescriptor; - -typedef struct { - XHCITRB *trbs, *physical; - uint32_t size, enqueue, dequeue; - bool cycle; -} TrbRing; - -typedef struct { - XHCICapabilities *capabilities; - XHCIOperational *operational; - XHCIRuntime *runtime; - TrbRing commands; - TrbRing events; - uint32_t pciDevice; - volatile uint32_t *doorbells; - XHCIEventRingSegmentTableEntry *eventRingSegmentTable, - *eventRingSegmentTablePhysical; - uint64_t *deviceContextBaseAddressArray; - uint32_t portCount; - XHCIInputContext *inputContexts[32]; -} XHCIController; - -#endif diff --git a/src/userland/usb/xhci/trbRing.c b/src/userland/usb/xhci/trbRing.c new file mode 100644 index 0000000..a31e28d --- /dev/null +++ b/src/userland/usb/xhci/trbRing.c @@ -0,0 +1,48 @@ +#include + +XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb) { + trb->control |= ring->cycle; + memcpy((void *)trb, (void *)&ring->trbs[ring->enqueue], sizeof(XHCITRB)); + XHCITRB *result = &ring->physical[ring->enqueue]; + ring->enqueue++; + if (ring->enqueue == ring->size - 1) { + if (ring->trbs[ring->enqueue].control & 1) { + ring->trbs[ring->enqueue].control &= ~1; + } else { + ring->trbs[ring->enqueue].control |= 1; + } + if (ring->trbs[ring->enqueue].control & 1) { + ring->cycle ^= 1; + } + ring->enqueue = 0; + } + return result; +} + +XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) { + if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) { + return NULL; + } + if (index) { + *index = ring->dequeue; + } + XHCITRB *result = &ring->trbs[ring->dequeue]; + ring->dequeue++; + if (ring->dequeue == ring->size) { + ring->dequeue = 0; + ring->cycle ^= -1; + } + return result; +} + +void setupTrbRing(TrbRing *ring, uint32_t size) { + ring->trbs = requestMemory(1, 0, 0); + ring->physical = getPhysicalAddress((void *)ring->trbs); + ring->cycle = true; + ring->enqueue = 0; + ring->dequeue = 0; + ring->size = size; + // define link to beginning + ring->trbs[ring->size - 1].dataLow = U32(ring->physical); + ring->trbs[ring->size - 1].control |= 1 << 1 | COMMAND_TYPE(6); +} diff --git a/src/userland/usb/Makefile b/src/userland/usb/Makefile index f3ac86a..ceb41ed 100644 --- a/src/userland/usb/Makefile +++ b/src/userland/usb/Makefile @@ -7,7 +7,7 @@ BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) NAME = usb diff --git a/src/userland/usb/compile_flags.txt b/src/userland/usb/compile_flags.txt new file mode 100644 index 0000000..f084bb0 --- /dev/null +++ b/src/userland/usb/compile_flags.txt @@ -0,0 +1,6 @@ +clang +-Iinclude +-I../../include +-fms-extensions +-Wno-microsoft-anon-tag +-Wno-incompatible-library-redeclaration diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h new file mode 100644 index 0000000..39281a9 --- /dev/null +++ b/src/userland/usb/include/usb.h @@ -0,0 +1,189 @@ +#ifndef USB_H +#define USB_H + +#include + +#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) + +typedef volatile struct { + uint8_t capabilitiesLength; + uint8_t reserved; + uint16_t interfaceVersion; + uint32_t structuralParameters[3]; + uint32_t capabilityParameter1; + uint32_t doorbellOffset; + uint32_t runtimeOffset; + uint32_t capabilityParameter2; +} __attribute__((packed)) XHCICapabilities; + +typedef volatile struct { + uint32_t status; + uint32_t powerStatus; + uint32_t linkInfo; + uint32_t hardwareLPM; +} __attribute__((packed)) XHCIPort; + +typedef volatile struct { + uint32_t command; + uint32_t status; + uint32_t pageSize; + uint32_t reserved[2]; + uint32_t notification; + uint32_t commandRingControl[2]; + uint32_t reserved1[4]; + uint32_t deviceContextBaseAddressArray[2]; + uint32_t config; + uint8_t reserved2[964]; + XHCIPort ports[256]; +} __attribute__((packed)) XHCIOperational; + +typedef volatile struct { + uint32_t dataLow; + uint32_t dataHigh; + uint32_t status; + uint32_t control; +} __attribute__((packed)) XHCITRB; + +#define COMMAND_TYPE(x) (x << 10) +#define COMMAND_CYCLE(x) (x) +#define COMMAND_BSR(x) (x << 9) +#define COMMAND_SLOT_ID(x) (x << 24) + +typedef volatile struct { + uint32_t commandLow; + uint32_t commandHigh; + uint32_t completionParameter : 24, completionCode : 8; + uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; +} __attribute__((packed)) CommandCompletionEvent; + +typedef volatile struct { + uint32_t management; + uint32_t moderationCounter : 16, moderationInterval : 16; + uint32_t eventRingSegmentTableSize; // MAX 16 bit + uint32_t reserved2; + uint32_t eventRingSegmentTableAddress[2]; + uint32_t eventRingDequeuePointer[2]; +} __attribute__((packed)) XHCIInterrupter; + +typedef volatile struct { + uint8_t microframeIndex; + uint8_t reserved[0x20 - 1]; + XHCIInterrupter interrupters[1023]; +} __attribute__((packed)) XHCIRuntime; + +typedef volatile struct { + uint32_t ringSegmentBaseAddress[2]; + uint16_t ringSegmentSize, reserved; + uint32_t reserved1; +} __attribute__((packed)) XHCIEventRingSegmentTableEntry; + +typedef volatile struct { + uint32_t requestType : 8, request : 8, value : 16; + uint32_t index : 16, length : 16; + + uint32_t transferLength : 17, // always 8 + reserved : 5, interrupterTarget : 10; + + uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, + immediateData : 1, // here 1 + reserved2 : 3, type : 6, transferType : 2; +} __attribute__((packed)) XHCISetupStageTRB; + +typedef volatile struct { + uint32_t reserved[2]; + + uint32_t reserved1 : 22, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, + interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIStatusStageTRB; + +typedef volatile struct { + uint32_t dataBuffer[2]; + + uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; + + uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, + noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, + reserved : 3, type : 6, inDirection : 1; +} __attribute__((packed)) XHCIDataStageTRB; + +typedef volatile struct { + uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, + contextEntryCount : 5; + uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; + uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, + reserved1 : 4, interrupterTarget : 10; + uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; + uint32_t reserved3[4]; +} __attribute__((packed)) XHCISlotContext; + +typedef volatile struct { + uint32_t endpointState : 3, reserved : 5, multiplier : 2, + maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, + maxEISTPayloadHigh : 8; + uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, + hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; + uint32_t transferDequeuePointerLow; + uint32_t transferDequeuePointerHigh; + uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; + uint32_t reserved4[3]; +} __attribute__((packed)) XHCIEndpointContext; + +typedef volatile struct { + XHCISlotContext slot; + XHCIEndpointContext endpoints[32]; +} __attribute__((packed)) XHCIDevice; + +typedef volatile struct { + uint32_t dropContextFlags; + uint32_t addContextFlags; + uint32_t reserved[5]; + uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, + reserved1 : 8; +} __attribute__((packed)) XHCIInputControl; + +typedef volatile struct { + XHCIInputControl inputControl; + XHCIDevice deviceContext; +} __attribute__((packed)) XHCIInputContext; + +typedef volatile struct { + uint8_t size; + uint8_t descriptorType; + uint16_t usbVersion; + uint8_t deviceClass; + uint8_t deviceSubclass; + uint8_t deviceProtocol; + uint8_t maxPacketSize; + uint16_t vendor; + uint16_t product; + uint16_t deviceRelease; + uint8_t manufacturerStringDescriptor; + uint8_t deviceStringDescriptor; + uint8_t serialNumberStringDescriptor; + uint8_t configurationCount; +} __attribute__((packed)) UsbDeviceDescriptor; + +typedef struct { + XHCITRB *trbs, *physical; + uint32_t size, enqueue, dequeue; + bool cycle; +} TrbRing; + +typedef struct { + XHCICapabilities *capabilities; + XHCIOperational *operational; + XHCIRuntime *runtime; + TrbRing commands; + TrbRing events; + uint32_t pciDevice; + volatile uint32_t *doorbells; + XHCIEventRingSegmentTableEntry *eventRingSegmentTable, + *eventRingSegmentTablePhysical; + uint64_t *deviceContextBaseAddressArray; + uint32_t portCount; + XHCIInputContext *inputContexts[32]; +} XHCIController; + +#endif diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index b6d1558..90a3bc5 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -2,31 +2,13 @@ #include #include "../hlib/include/syscalls.h" -#include "usb.h" +#include "xhci/trbRing.h" +#include uint32_t serviceId; XHCIController *controller; -XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb) { - trb->control |= ring->cycle; - memcpy((void *)trb, (void *)&ring->trbs[ring->enqueue], sizeof(XHCITRB)); - XHCITRB *result = &ring->physical[ring->enqueue]; - ring->enqueue++; - if (ring->enqueue == ring->size - 1) { - if (ring->trbs[ring->enqueue].control & 1) { - ring->trbs[ring->enqueue].control &= ~1; - } else { - ring->trbs[ring->enqueue].control |= 1; - } - if (ring->trbs[ring->enqueue].control & 1) { - ring->cycle ^= 1; - } - ring->enqueue = 0; - } - return result; -} - CommandCompletionEvent *xhciCommand(XHCIController *controller, uint32_t dataLow, uint32_t dataHigh, uint32_t status, uint32_t control) { @@ -75,34 +57,6 @@ ; } -XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) { - if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) { - return NULL; - } - if (index) { - *index = ring->dequeue; - } - XHCITRB *result = &ring->trbs[ring->dequeue]; - ring->dequeue++; - if (ring->dequeue == ring->size) { - ring->dequeue = 0; - ring->cycle ^= -1; - } - return result; -} - -void setupTrbRing(TrbRing *ring, uint32_t size) { - ring->trbs = requestMemory(1, 0, 0); - ring->physical = getPhysicalAddress((void *)ring->trbs); - ring->cycle = true; - ring->enqueue = 0; - ring->dequeue = 0; - ring->size = size; - // define link to beginning - ring->trbs[ring->size - 1].dataLow = U32(ring->physical); - ring->trbs[ring->size - 1].control |= COMMAND_CYCLE(true) | COMMAND_TYPE(6); -} - void setupRuntime(XHCIController *controller) { controller->runtime = OFFSET(controller->capabilities, controller->capabilities->runtimeOffset); @@ -362,10 +316,6 @@ printf("manufacturer: %s, device: %s, serial: %s\n", manufacturer, device, serial); printf("--------\n"); - // configure endpoint gives a trb error as of now ... - // configureEndpoint(getPhysicalAddress((void - // *)&inputContext->inputControl), - // slotIndex, false); } void xhciInterrupt() { diff --git a/src/userland/usb/usb.h b/src/userland/usb/usb.h deleted file mode 100644 index 39281a9..0000000 --- a/src/userland/usb/usb.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef USB_H -#define USB_H - -#include - -#define OFFSET(ptr, off) (((void *)(ptr)) + (off)) - -typedef volatile struct { - uint8_t capabilitiesLength; - uint8_t reserved; - uint16_t interfaceVersion; - uint32_t structuralParameters[3]; - uint32_t capabilityParameter1; - uint32_t doorbellOffset; - uint32_t runtimeOffset; - uint32_t capabilityParameter2; -} __attribute__((packed)) XHCICapabilities; - -typedef volatile struct { - uint32_t status; - uint32_t powerStatus; - uint32_t linkInfo; - uint32_t hardwareLPM; -} __attribute__((packed)) XHCIPort; - -typedef volatile struct { - uint32_t command; - uint32_t status; - uint32_t pageSize; - uint32_t reserved[2]; - uint32_t notification; - uint32_t commandRingControl[2]; - uint32_t reserved1[4]; - uint32_t deviceContextBaseAddressArray[2]; - uint32_t config; - uint8_t reserved2[964]; - XHCIPort ports[256]; -} __attribute__((packed)) XHCIOperational; - -typedef volatile struct { - uint32_t dataLow; - uint32_t dataHigh; - uint32_t status; - uint32_t control; -} __attribute__((packed)) XHCITRB; - -#define COMMAND_TYPE(x) (x << 10) -#define COMMAND_CYCLE(x) (x) -#define COMMAND_BSR(x) (x << 9) -#define COMMAND_SLOT_ID(x) (x << 24) - -typedef volatile struct { - uint32_t commandLow; - uint32_t commandHigh; - uint32_t completionParameter : 24, completionCode : 8; - uint32_t cycle : 1, reserved : 9, type : 6, vfId : 8, slotId : 8; -} __attribute__((packed)) CommandCompletionEvent; - -typedef volatile struct { - uint32_t management; - uint32_t moderationCounter : 16, moderationInterval : 16; - uint32_t eventRingSegmentTableSize; // MAX 16 bit - uint32_t reserved2; - uint32_t eventRingSegmentTableAddress[2]; - uint32_t eventRingDequeuePointer[2]; -} __attribute__((packed)) XHCIInterrupter; - -typedef volatile struct { - uint8_t microframeIndex; - uint8_t reserved[0x20 - 1]; - XHCIInterrupter interrupters[1023]; -} __attribute__((packed)) XHCIRuntime; - -typedef volatile struct { - uint32_t ringSegmentBaseAddress[2]; - uint16_t ringSegmentSize, reserved; - uint32_t reserved1; -} __attribute__((packed)) XHCIEventRingSegmentTableEntry; - -typedef volatile struct { - uint32_t requestType : 8, request : 8, value : 16; - uint32_t index : 16, length : 16; - - uint32_t transferLength : 17, // always 8 - reserved : 5, interrupterTarget : 10; - - uint32_t cycle : 1, reserved1 : 4, interruptOnCompletion : 1, - immediateData : 1, // here 1 - reserved2 : 3, type : 6, transferType : 2; -} __attribute__((packed)) XHCISetupStageTRB; - -typedef volatile struct { - uint32_t reserved[2]; - - uint32_t reserved1 : 22, interrupterTarget : 10; - - uint32_t cycle : 1, evaluateNext : 1, reserved2 : 2, chain : 1, - interruptOnCompletion : 1, reserved3 : 4, type : 6, inDirection : 1; -} __attribute__((packed)) XHCIStatusStageTRB; - -typedef volatile struct { - uint32_t dataBuffer[2]; - - uint32_t transferSize : 17, tdSize : 5, interrupterTarget : 10; - - uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, - noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, - reserved : 3, type : 6, inDirection : 1; -} __attribute__((packed)) XHCIDataStageTRB; - -typedef volatile struct { - uint32_t routeString : 20, speed : 4, reserved : 1, multiTT : 1, isHub : 1, - contextEntryCount : 5; - uint32_t maxLatency : 16, rootHubPort : 8, portCount : 8; - uint32_t parentHubSlotId : 8, partentPortNumber : 8, thinkTime : 2, - reserved1 : 4, interrupterTarget : 10; - uint32_t deviceAddress : 8, reserved2 : 19, slotState : 5; - uint32_t reserved3[4]; -} __attribute__((packed)) XHCISlotContext; - -typedef volatile struct { - uint32_t endpointState : 3, reserved : 5, multiplier : 2, - maxPrimaryStreams : 5, linearStreamArray : 1, interval : 8, - maxEISTPayloadHigh : 8; - uint32_t reserved1 : 1, errorCount : 2, endpointType : 3, reserved2 : 1, - hostInitiateDisable : 1, maxBurstSize : 8, maxPacketSize : 16; - uint32_t transferDequeuePointerLow; - uint32_t transferDequeuePointerHigh; - uint32_t averageTRBLength : 16, maxEISTPayloadLow : 16; - uint32_t reserved4[3]; -} __attribute__((packed)) XHCIEndpointContext; - -typedef volatile struct { - XHCISlotContext slot; - XHCIEndpointContext endpoints[32]; -} __attribute__((packed)) XHCIDevice; - -typedef volatile struct { - uint32_t dropContextFlags; - uint32_t addContextFlags; - uint32_t reserved[5]; - uint32_t configuration : 8, interfaceNumber : 8, AlternateSetting : 8, - reserved1 : 8; -} __attribute__((packed)) XHCIInputControl; - -typedef volatile struct { - XHCIInputControl inputControl; - XHCIDevice deviceContext; -} __attribute__((packed)) XHCIInputContext; - -typedef volatile struct { - uint8_t size; - uint8_t descriptorType; - uint16_t usbVersion; - uint8_t deviceClass; - uint8_t deviceSubclass; - uint8_t deviceProtocol; - uint8_t maxPacketSize; - uint16_t vendor; - uint16_t product; - uint16_t deviceRelease; - uint8_t manufacturerStringDescriptor; - uint8_t deviceStringDescriptor; - uint8_t serialNumberStringDescriptor; - uint8_t configurationCount; -} __attribute__((packed)) UsbDeviceDescriptor; - -typedef struct { - XHCITRB *trbs, *physical; - uint32_t size, enqueue, dequeue; - bool cycle; -} TrbRing; - -typedef struct { - XHCICapabilities *capabilities; - XHCIOperational *operational; - XHCIRuntime *runtime; - TrbRing commands; - TrbRing events; - uint32_t pciDevice; - volatile uint32_t *doorbells; - XHCIEventRingSegmentTableEntry *eventRingSegmentTable, - *eventRingSegmentTablePhysical; - uint64_t *deviceContextBaseAddressArray; - uint32_t portCount; - XHCIInputContext *inputContexts[32]; -} XHCIController; - -#endif diff --git a/src/userland/usb/xhci/trbRing.c b/src/userland/usb/xhci/trbRing.c new file mode 100644 index 0000000..a31e28d --- /dev/null +++ b/src/userland/usb/xhci/trbRing.c @@ -0,0 +1,48 @@ +#include + +XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb) { + trb->control |= ring->cycle; + memcpy((void *)trb, (void *)&ring->trbs[ring->enqueue], sizeof(XHCITRB)); + XHCITRB *result = &ring->physical[ring->enqueue]; + ring->enqueue++; + if (ring->enqueue == ring->size - 1) { + if (ring->trbs[ring->enqueue].control & 1) { + ring->trbs[ring->enqueue].control &= ~1; + } else { + ring->trbs[ring->enqueue].control |= 1; + } + if (ring->trbs[ring->enqueue].control & 1) { + ring->cycle ^= 1; + } + ring->enqueue = 0; + } + return result; +} + +XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) { + if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) { + return NULL; + } + if (index) { + *index = ring->dequeue; + } + XHCITRB *result = &ring->trbs[ring->dequeue]; + ring->dequeue++; + if (ring->dequeue == ring->size) { + ring->dequeue = 0; + ring->cycle ^= -1; + } + return result; +} + +void setupTrbRing(TrbRing *ring, uint32_t size) { + ring->trbs = requestMemory(1, 0, 0); + ring->physical = getPhysicalAddress((void *)ring->trbs); + ring->cycle = true; + ring->enqueue = 0; + ring->dequeue = 0; + ring->size = size; + // define link to beginning + ring->trbs[ring->size - 1].dataLow = U32(ring->physical); + ring->trbs[ring->size - 1].control |= 1 << 1 | COMMAND_TYPE(6); +} diff --git a/src/userland/usb/xhci/trbRing.h b/src/userland/usb/xhci/trbRing.h new file mode 100644 index 0000000..bd31092 --- /dev/null +++ b/src/userland/usb/xhci/trbRing.h @@ -0,0 +1,10 @@ +#ifndef TRB_RING_H +#define TRB_RING_H + +#include + +extern XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb); +extern XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index); +extern void setupTrbRing(TrbRing *ring, uint32_t size); + +#endif