diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 3228792..49eb68a 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -56,8 +56,10 @@ for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { void *data = malloc(0x1000); - memcpy(elfStart + programHeader->dataOffset + page, data, - MIN(0x1000, programHeader->segmentFileSize - page)); + if (programHeader->segmentFileSize > page) { + memcpy(elfStart + programHeader->dataOffset + page, data, + MIN(0x1000, programHeader->segmentFileSize - page)); + } sharePage(&service->pagingInfo, data, PTR(programHeader->virtualAddress + page)); } diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 3228792..49eb68a 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -56,8 +56,10 @@ for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { void *data = malloc(0x1000); - memcpy(elfStart + programHeader->dataOffset + page, data, - MIN(0x1000, programHeader->segmentFileSize - page)); + if (programHeader->segmentFileSize > page) { + memcpy(elfStart + programHeader->dataOffset + page, data, + MIN(0x1000, programHeader->segmentFileSize - page)); + } sharePage(&service->pagingInfo, data, PTR(programHeader->virtualAddress + page)); } diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index e8ef161..5662180 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -48,9 +48,19 @@ } __attribute__((packed)) UsbInterfaceDescriptor; typedef struct { + uint8_t size; + uint8_t descriptorType; + uint8_t address; + uint8_t attributes; + uint16_t maxPacketSize; + uint8_t interval; +} __attribute__((packed)) UsbEndpointDescriptor; + +typedef struct { uint32_t pciClass; void *(*initialize)(uint32_t, uint32_t, uint32_t); void (*getDeviceDescriptor)(void *, uint32_t, uint32_t, void *); + void (*setupEndpoints)(void *, ListElement *, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 3228792..49eb68a 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -56,8 +56,10 @@ for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { void *data = malloc(0x1000); - memcpy(elfStart + programHeader->dataOffset + page, data, - MIN(0x1000, programHeader->segmentFileSize - page)); + if (programHeader->segmentFileSize > page) { + memcpy(elfStart + programHeader->dataOffset + page, data, + MIN(0x1000, programHeader->segmentFileSize - page)); + } sharePage(&service->pagingInfo, data, PTR(programHeader->virtualAddress + page)); } diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index e8ef161..5662180 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -48,9 +48,19 @@ } __attribute__((packed)) UsbInterfaceDescriptor; typedef struct { + uint8_t size; + uint8_t descriptorType; + uint8_t address; + uint8_t attributes; + uint16_t maxPacketSize; + uint8_t interval; +} __attribute__((packed)) UsbEndpointDescriptor; + +typedef struct { uint32_t pciClass; void *(*initialize)(uint32_t, uint32_t, uint32_t); void (*getDeviceDescriptor)(void *, uint32_t, uint32_t, void *); + void (*setupEndpoints)(void *, ListElement *, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 57c7f11..30b43fb 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -24,6 +24,30 @@ return string; } +void setupInterfaces(UsbSlot *slot, void *start, uint32_t configurationValue) { + UsbInterfaceDescriptor *interface = start; + // only doing blank interface descriptors for now, there are + // also interface assosciations... + ListElement *endpointConfigurations = NULL; + while (interface->descriptorType == 4) { + printf("interface %i: %i endpoint(s), class %i, subclass %i\n", + interface->interfaceNumber, interface->endpointCount, + interface->interfaceClass, interface->subClass); + void *nextInterface = (void *)interface + interface->size; + for (uint32_t i = 0; i < interface->endpointCount; i++) { + UsbEndpointDescriptor *endpoint = nextInterface; + listAdd(&endpointConfigurations, endpoint); + nextInterface += endpoint->size; + printf("endpoint %i: address: %x, attributes: %x\n", i, + endpoint->address, endpoint->attributes); + } + interface = nextInterface; + } + slot->interface->setupEndpoints(slot->data, endpointConfigurations, + configurationValue); + // clear list +} + void resetPort(UsbSlot *slot) { printf("--------\n"); void *buffer = requestMemory(1, 0, 0); @@ -55,17 +79,8 @@ slot->portIndex, configuration->interfaceCount, configurationString, configuration->totalLength); - UsbInterfaceDescriptor *interface = - (void *)configuration + configuration->size; - // only doing blank interface descriptors for now, there are - // also interface assosciations... - while (interface->descriptorType == 4) { - printf("port %i: interface %i, %i endpoints, class %i, subclass %i\n", - slot->portIndex, interface->interfaceNumber, - interface->endpointCount, interface->interfaceClass, - interface->subClass); - interface = (void *)interface + interface->size; - } + setupInterfaces(slot, (void *)configuration + configuration->size, + configuration->configurationValue); } extern UsbHostControllerInterface xhci; @@ -83,7 +98,6 @@ continue; } enableBusMaster(pciDevice, 0); - printf("init: %x\n", interface->initialize); uint32_t interrupt = getPCIInterrupt(pciDevice, 0); // I don't know why void *(*initialize)(uint32_t, uint32_t, uint32_t) = diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 3228792..49eb68a 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -56,8 +56,10 @@ for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { void *data = malloc(0x1000); - memcpy(elfStart + programHeader->dataOffset + page, data, - MIN(0x1000, programHeader->segmentFileSize - page)); + if (programHeader->segmentFileSize > page) { + memcpy(elfStart + programHeader->dataOffset + page, data, + MIN(0x1000, programHeader->segmentFileSize - page)); + } sharePage(&service->pagingInfo, data, PTR(programHeader->virtualAddress + page)); } diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index e8ef161..5662180 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -48,9 +48,19 @@ } __attribute__((packed)) UsbInterfaceDescriptor; typedef struct { + uint8_t size; + uint8_t descriptorType; + uint8_t address; + uint8_t attributes; + uint16_t maxPacketSize; + uint8_t interval; +} __attribute__((packed)) UsbEndpointDescriptor; + +typedef struct { uint32_t pciClass; void *(*initialize)(uint32_t, uint32_t, uint32_t); void (*getDeviceDescriptor)(void *, uint32_t, uint32_t, void *); + void (*setupEndpoints)(void *, ListElement *, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 57c7f11..30b43fb 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -24,6 +24,30 @@ return string; } +void setupInterfaces(UsbSlot *slot, void *start, uint32_t configurationValue) { + UsbInterfaceDescriptor *interface = start; + // only doing blank interface descriptors for now, there are + // also interface assosciations... + ListElement *endpointConfigurations = NULL; + while (interface->descriptorType == 4) { + printf("interface %i: %i endpoint(s), class %i, subclass %i\n", + interface->interfaceNumber, interface->endpointCount, + interface->interfaceClass, interface->subClass); + void *nextInterface = (void *)interface + interface->size; + for (uint32_t i = 0; i < interface->endpointCount; i++) { + UsbEndpointDescriptor *endpoint = nextInterface; + listAdd(&endpointConfigurations, endpoint); + nextInterface += endpoint->size; + printf("endpoint %i: address: %x, attributes: %x\n", i, + endpoint->address, endpoint->attributes); + } + interface = nextInterface; + } + slot->interface->setupEndpoints(slot->data, endpointConfigurations, + configurationValue); + // clear list +} + void resetPort(UsbSlot *slot) { printf("--------\n"); void *buffer = requestMemory(1, 0, 0); @@ -55,17 +79,8 @@ slot->portIndex, configuration->interfaceCount, configurationString, configuration->totalLength); - UsbInterfaceDescriptor *interface = - (void *)configuration + configuration->size; - // only doing blank interface descriptors for now, there are - // also interface assosciations... - while (interface->descriptorType == 4) { - printf("port %i: interface %i, %i endpoints, class %i, subclass %i\n", - slot->portIndex, interface->interfaceNumber, - interface->endpointCount, interface->interfaceClass, - interface->subClass); - interface = (void *)interface + interface->size; - } + setupInterfaces(slot, (void *)configuration + configuration->size, + configuration->configurationValue); } extern UsbHostControllerInterface xhci; @@ -83,7 +98,6 @@ continue; } enableBusMaster(pciDevice, 0); - printf("init: %x\n", interface->initialize); uint32_t interrupt = getPCIInterrupt(pciDevice, 0); // I don't know why void *(*initialize)(uint32_t, uint32_t, uint32_t) = diff --git a/src/userland/usb/xhci/commands.h b/src/userland/usb/xhci/commands.h index cae27b6..e5fb82e 100644 --- a/src/userland/usb/xhci/commands.h +++ b/src/userland/usb/xhci/commands.h @@ -4,6 +4,9 @@ #include "xhci.h" #include +extern CommandCompletionEvent *xhciCommand(XHCIController *controller, + uint32_t dataLow, uint32_t dataHigh, + uint32_t status, uint32_t control); extern void addressDevice(SlotXHCI *slot, bool BSR); extern void configureEndpoint(XHCIController *controller, void *inputContext, uint32_t slotNumber, bool deconfigure); diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 3228792..49eb68a 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -56,8 +56,10 @@ for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { void *data = malloc(0x1000); - memcpy(elfStart + programHeader->dataOffset + page, data, - MIN(0x1000, programHeader->segmentFileSize - page)); + if (programHeader->segmentFileSize > page) { + memcpy(elfStart + programHeader->dataOffset + page, data, + MIN(0x1000, programHeader->segmentFileSize - page)); + } sharePage(&service->pagingInfo, data, PTR(programHeader->virtualAddress + page)); } diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index e8ef161..5662180 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -48,9 +48,19 @@ } __attribute__((packed)) UsbInterfaceDescriptor; typedef struct { + uint8_t size; + uint8_t descriptorType; + uint8_t address; + uint8_t attributes; + uint16_t maxPacketSize; + uint8_t interval; +} __attribute__((packed)) UsbEndpointDescriptor; + +typedef struct { uint32_t pciClass; void *(*initialize)(uint32_t, uint32_t, uint32_t); void (*getDeviceDescriptor)(void *, uint32_t, uint32_t, void *); + void (*setupEndpoints)(void *, ListElement *, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 57c7f11..30b43fb 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -24,6 +24,30 @@ return string; } +void setupInterfaces(UsbSlot *slot, void *start, uint32_t configurationValue) { + UsbInterfaceDescriptor *interface = start; + // only doing blank interface descriptors for now, there are + // also interface assosciations... + ListElement *endpointConfigurations = NULL; + while (interface->descriptorType == 4) { + printf("interface %i: %i endpoint(s), class %i, subclass %i\n", + interface->interfaceNumber, interface->endpointCount, + interface->interfaceClass, interface->subClass); + void *nextInterface = (void *)interface + interface->size; + for (uint32_t i = 0; i < interface->endpointCount; i++) { + UsbEndpointDescriptor *endpoint = nextInterface; + listAdd(&endpointConfigurations, endpoint); + nextInterface += endpoint->size; + printf("endpoint %i: address: %x, attributes: %x\n", i, + endpoint->address, endpoint->attributes); + } + interface = nextInterface; + } + slot->interface->setupEndpoints(slot->data, endpointConfigurations, + configurationValue); + // clear list +} + void resetPort(UsbSlot *slot) { printf("--------\n"); void *buffer = requestMemory(1, 0, 0); @@ -55,17 +79,8 @@ slot->portIndex, configuration->interfaceCount, configurationString, configuration->totalLength); - UsbInterfaceDescriptor *interface = - (void *)configuration + configuration->size; - // only doing blank interface descriptors for now, there are - // also interface assosciations... - while (interface->descriptorType == 4) { - printf("port %i: interface %i, %i endpoints, class %i, subclass %i\n", - slot->portIndex, interface->interfaceNumber, - interface->endpointCount, interface->interfaceClass, - interface->subClass); - interface = (void *)interface + interface->size; - } + setupInterfaces(slot, (void *)configuration + configuration->size, + configuration->configurationValue); } extern UsbHostControllerInterface xhci; @@ -83,7 +98,6 @@ continue; } enableBusMaster(pciDevice, 0); - printf("init: %x\n", interface->initialize); uint32_t interrupt = getPCIInterrupt(pciDevice, 0); // I don't know why void *(*initialize)(uint32_t, uint32_t, uint32_t) = diff --git a/src/userland/usb/xhci/commands.h b/src/userland/usb/xhci/commands.h index cae27b6..e5fb82e 100644 --- a/src/userland/usb/xhci/commands.h +++ b/src/userland/usb/xhci/commands.h @@ -4,6 +4,9 @@ #include "xhci.h" #include +extern CommandCompletionEvent *xhciCommand(XHCIController *controller, + uint32_t dataLow, uint32_t dataHigh, + uint32_t status, uint32_t control); extern void addressDevice(SlotXHCI *slot, bool BSR); extern void configureEndpoint(XHCIController *controller, void *inputContext, uint32_t slotNumber, bool deconfigure); diff --git a/src/userland/usb/xhci/controller.c b/src/userland/usb/xhci/controller.c index d7dd5bf..e5a63b1 100644 --- a/src/userland/usb/xhci/controller.c +++ b/src/userland/usb/xhci/controller.c @@ -123,9 +123,9 @@ controller->capabilities->doorbellOffset); uint32_t slotInfo = controller->capabilities->structuralParameters[0]; - printf("%i available slots, %i available ports\n", slotInfo & 0xFF, - slotInfo >> 24); controller->portCount = slotInfo >> 24; + printf("%i available slots, %i available ports\n", slotInfo & 0xFF, + controller->portCount); return controller; } diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 3228792..49eb68a 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -56,8 +56,10 @@ for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { void *data = malloc(0x1000); - memcpy(elfStart + programHeader->dataOffset + page, data, - MIN(0x1000, programHeader->segmentFileSize - page)); + if (programHeader->segmentFileSize > page) { + memcpy(elfStart + programHeader->dataOffset + page, data, + MIN(0x1000, programHeader->segmentFileSize - page)); + } sharePage(&service->pagingInfo, data, PTR(programHeader->virtualAddress + page)); } diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index e8ef161..5662180 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -48,9 +48,19 @@ } __attribute__((packed)) UsbInterfaceDescriptor; typedef struct { + uint8_t size; + uint8_t descriptorType; + uint8_t address; + uint8_t attributes; + uint16_t maxPacketSize; + uint8_t interval; +} __attribute__((packed)) UsbEndpointDescriptor; + +typedef struct { uint32_t pciClass; void *(*initialize)(uint32_t, uint32_t, uint32_t); void (*getDeviceDescriptor)(void *, uint32_t, uint32_t, void *); + void (*setupEndpoints)(void *, ListElement *, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 57c7f11..30b43fb 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -24,6 +24,30 @@ return string; } +void setupInterfaces(UsbSlot *slot, void *start, uint32_t configurationValue) { + UsbInterfaceDescriptor *interface = start; + // only doing blank interface descriptors for now, there are + // also interface assosciations... + ListElement *endpointConfigurations = NULL; + while (interface->descriptorType == 4) { + printf("interface %i: %i endpoint(s), class %i, subclass %i\n", + interface->interfaceNumber, interface->endpointCount, + interface->interfaceClass, interface->subClass); + void *nextInterface = (void *)interface + interface->size; + for (uint32_t i = 0; i < interface->endpointCount; i++) { + UsbEndpointDescriptor *endpoint = nextInterface; + listAdd(&endpointConfigurations, endpoint); + nextInterface += endpoint->size; + printf("endpoint %i: address: %x, attributes: %x\n", i, + endpoint->address, endpoint->attributes); + } + interface = nextInterface; + } + slot->interface->setupEndpoints(slot->data, endpointConfigurations, + configurationValue); + // clear list +} + void resetPort(UsbSlot *slot) { printf("--------\n"); void *buffer = requestMemory(1, 0, 0); @@ -55,17 +79,8 @@ slot->portIndex, configuration->interfaceCount, configurationString, configuration->totalLength); - UsbInterfaceDescriptor *interface = - (void *)configuration + configuration->size; - // only doing blank interface descriptors for now, there are - // also interface assosciations... - while (interface->descriptorType == 4) { - printf("port %i: interface %i, %i endpoints, class %i, subclass %i\n", - slot->portIndex, interface->interfaceNumber, - interface->endpointCount, interface->interfaceClass, - interface->subClass); - interface = (void *)interface + interface->size; - } + setupInterfaces(slot, (void *)configuration + configuration->size, + configuration->configurationValue); } extern UsbHostControllerInterface xhci; @@ -83,7 +98,6 @@ continue; } enableBusMaster(pciDevice, 0); - printf("init: %x\n", interface->initialize); uint32_t interrupt = getPCIInterrupt(pciDevice, 0); // I don't know why void *(*initialize)(uint32_t, uint32_t, uint32_t) = diff --git a/src/userland/usb/xhci/commands.h b/src/userland/usb/xhci/commands.h index cae27b6..e5fb82e 100644 --- a/src/userland/usb/xhci/commands.h +++ b/src/userland/usb/xhci/commands.h @@ -4,6 +4,9 @@ #include "xhci.h" #include +extern CommandCompletionEvent *xhciCommand(XHCIController *controller, + uint32_t dataLow, uint32_t dataHigh, + uint32_t status, uint32_t control); extern void addressDevice(SlotXHCI *slot, bool BSR); extern void configureEndpoint(XHCIController *controller, void *inputContext, uint32_t slotNumber, bool deconfigure); diff --git a/src/userland/usb/xhci/controller.c b/src/userland/usb/xhci/controller.c index d7dd5bf..e5a63b1 100644 --- a/src/userland/usb/xhci/controller.c +++ b/src/userland/usb/xhci/controller.c @@ -123,9 +123,9 @@ controller->capabilities->doorbellOffset); uint32_t slotInfo = controller->capabilities->structuralParameters[0]; - printf("%i available slots, %i available ports\n", slotInfo & 0xFF, - slotInfo >> 24); controller->portCount = slotInfo >> 24; + printf("%i available slots, %i available ports\n", slotInfo & 0xFF, + controller->portCount); return controller; } diff --git a/src/userland/usb/xhci/xhci.c b/src/userland/usb/xhci/xhci.c index 5eddf3e..b8fcae1 100644 --- a/src/userland/usb/xhci/xhci.c +++ b/src/userland/usb/xhci/xhci.c @@ -1,6 +1,7 @@ #include "xhci.h" #include "commands.h" #include "controller.h" +#include "trbRing.h" #include #include @@ -20,7 +21,7 @@ inputContext->deviceContext.endpoints[0].maxPrimaryStreams = 0; inputContext->deviceContext.endpoints[0].multiplier = 0; inputContext->deviceContext.endpoints[0].errorCount = 3; - inputContext->deviceContext.endpoints[0].averageTRBLength = 8; + inputContext->deviceContext.endpoints[0].averageTRBLength = 1024; return inputContext; } @@ -42,10 +43,13 @@ } slot->inputContext = createInputContext(slot); slot->controlRing = createSlotTRB(slot); + controller->deviceContexts[slot->slotIndex] = malloc(sizeof(XHCIDevice)); slot->controller->deviceContextBaseAddressArray[slot->slotIndex] = - U32(getPhysicalAddress(malloc(sizeof(XHCIDevice)))); + U32(getPhysicalAddress( + (void *)controller->deviceContexts[slot->slotIndex])); printf("port %i: addressing slot\n", portIndex); addressDevice(slot, true); + addressDevice(slot, false); UsbSlot *result = malloc(sizeof(UsbSlot)); result->data = slot; result->interface = &xhci; @@ -66,10 +70,74 @@ return host; } -void *(*test)(uint32_t, uint32_t, uint32_t) = init; +void xhciSetupEndpoints(SlotXHCI *slot, ListElement *endpoints, + uint32_t configValue) { + XHCIController *controller = slot->controller; + XHCIInputContext *inputContext = slot->inputContext; + memcpy((void *)controller->deviceContexts[slot->slotIndex], + (void *)&inputContext->deviceContext, sizeof(XHCIDevice)); + inputContext->inputControl.addContextFlags = 1; + printf("slot context state: %x, address: %x\n", + inputContext->deviceContext.slot.slotState, + inputContext->deviceContext.slot.deviceAddress); + foreach (endpoints, UsbEndpointDescriptor *, endpoint, { + uint8_t endpointNumber = endpoint->address & 0xF; // never 0 + uint8_t direction = endpoint->address >> 7; + uint8_t endpointIndex = (endpointNumber + direction) * 2 - 1; + XHCIEndpointContext *endpointContext = + &inputContext->deviceContext.endpoints[endpointIndex]; + endpointContext->endpointState = 0; + endpointContext->maxPrimaryStreams = 0; + endpointContext->interval = endpoint->interval; + endpointContext->errorCount = 3; + endpointContext->endpointType = + 4 * direction + endpoint->attributes & 3; + endpointContext->maxPacketSize = endpoint->maxPacketSize; + slot->endpointRings[endpointIndex] = malloc(sizeof(TrbRing)); + setupTrbRing(slot->endpointRings[endpointIndex], 256); + endpointContext->transferDequeuePointerLow = + U32(slot->endpointRings[endpointIndex]->physical) | 0; + endpointContext->transferDequeuePointerHigh = 0; + endpointContext->averageTRBLength = 2048; + inputContext->inputControl.addContextFlags |= 1 << (endpointIndex + 1); + inputContext->deviceContext.slot.contextEntryCount = MAX( + inputContext->deviceContext.slot.contextEntryCount, endpointIndex); + }) + ; + + XHCISetupStageTRB setup = {0}; + setup.requestType = 0x00; + setup.request = 9; + setup.value = configValue; + setup.index = 0; + setup.length = 0; + setup.transferLength = 8; + setup.interruptOnCompletion = 0; + setup.interrupterTarget = 0; + setup.type = 2; + setup.transferType = 3; + setup.immediateData = 1; + + XHCIStatusStageTRB status = {0}; + status.inDirection = 0; + status.evaluateNext = 0; + status.interruptOnCompletion = 1; + status.type = 4; + + uint32_t control = COMMAND_TYPE(12) | COMMAND_SLOT_ID(slot->slotIndex); + xhciCommand(controller, U32(getPhysicalAddress((void *)inputContext)), 0, 0, + control); + enqueueCommand(slot->controlRing, (void *)&setup); + uint32_t commandAddress = + U32(enqueueCommand(slot->controlRing, (void *)&status)); + uint32_t eventId = createDirectEventSave(commandAddress); + slot->controller->doorbells[slot->slotIndex] = 1; + await(serviceId, eventId); +} UsbHostControllerInterface xhci = { .initialize = init, .getDeviceDescriptor = (void *)usbGetDeviceDescriptor, + .setupEndpoints = (void *)xhciSetupEndpoints, .pciClass = 0x0C0330, }; diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 3228792..49eb68a 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -56,8 +56,10 @@ for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { void *data = malloc(0x1000); - memcpy(elfStart + programHeader->dataOffset + page, data, - MIN(0x1000, programHeader->segmentFileSize - page)); + if (programHeader->segmentFileSize > page) { + memcpy(elfStart + programHeader->dataOffset + page, data, + MIN(0x1000, programHeader->segmentFileSize - page)); + } sharePage(&service->pagingInfo, data, PTR(programHeader->virtualAddress + page)); } diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index e8ef161..5662180 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -48,9 +48,19 @@ } __attribute__((packed)) UsbInterfaceDescriptor; typedef struct { + uint8_t size; + uint8_t descriptorType; + uint8_t address; + uint8_t attributes; + uint16_t maxPacketSize; + uint8_t interval; +} __attribute__((packed)) UsbEndpointDescriptor; + +typedef struct { uint32_t pciClass; void *(*initialize)(uint32_t, uint32_t, uint32_t); void (*getDeviceDescriptor)(void *, uint32_t, uint32_t, void *); + void (*setupEndpoints)(void *, ListElement *, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 57c7f11..30b43fb 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -24,6 +24,30 @@ return string; } +void setupInterfaces(UsbSlot *slot, void *start, uint32_t configurationValue) { + UsbInterfaceDescriptor *interface = start; + // only doing blank interface descriptors for now, there are + // also interface assosciations... + ListElement *endpointConfigurations = NULL; + while (interface->descriptorType == 4) { + printf("interface %i: %i endpoint(s), class %i, subclass %i\n", + interface->interfaceNumber, interface->endpointCount, + interface->interfaceClass, interface->subClass); + void *nextInterface = (void *)interface + interface->size; + for (uint32_t i = 0; i < interface->endpointCount; i++) { + UsbEndpointDescriptor *endpoint = nextInterface; + listAdd(&endpointConfigurations, endpoint); + nextInterface += endpoint->size; + printf("endpoint %i: address: %x, attributes: %x\n", i, + endpoint->address, endpoint->attributes); + } + interface = nextInterface; + } + slot->interface->setupEndpoints(slot->data, endpointConfigurations, + configurationValue); + // clear list +} + void resetPort(UsbSlot *slot) { printf("--------\n"); void *buffer = requestMemory(1, 0, 0); @@ -55,17 +79,8 @@ slot->portIndex, configuration->interfaceCount, configurationString, configuration->totalLength); - UsbInterfaceDescriptor *interface = - (void *)configuration + configuration->size; - // only doing blank interface descriptors for now, there are - // also interface assosciations... - while (interface->descriptorType == 4) { - printf("port %i: interface %i, %i endpoints, class %i, subclass %i\n", - slot->portIndex, interface->interfaceNumber, - interface->endpointCount, interface->interfaceClass, - interface->subClass); - interface = (void *)interface + interface->size; - } + setupInterfaces(slot, (void *)configuration + configuration->size, + configuration->configurationValue); } extern UsbHostControllerInterface xhci; @@ -83,7 +98,6 @@ continue; } enableBusMaster(pciDevice, 0); - printf("init: %x\n", interface->initialize); uint32_t interrupt = getPCIInterrupt(pciDevice, 0); // I don't know why void *(*initialize)(uint32_t, uint32_t, uint32_t) = diff --git a/src/userland/usb/xhci/commands.h b/src/userland/usb/xhci/commands.h index cae27b6..e5fb82e 100644 --- a/src/userland/usb/xhci/commands.h +++ b/src/userland/usb/xhci/commands.h @@ -4,6 +4,9 @@ #include "xhci.h" #include +extern CommandCompletionEvent *xhciCommand(XHCIController *controller, + uint32_t dataLow, uint32_t dataHigh, + uint32_t status, uint32_t control); extern void addressDevice(SlotXHCI *slot, bool BSR); extern void configureEndpoint(XHCIController *controller, void *inputContext, uint32_t slotNumber, bool deconfigure); diff --git a/src/userland/usb/xhci/controller.c b/src/userland/usb/xhci/controller.c index d7dd5bf..e5a63b1 100644 --- a/src/userland/usb/xhci/controller.c +++ b/src/userland/usb/xhci/controller.c @@ -123,9 +123,9 @@ controller->capabilities->doorbellOffset); uint32_t slotInfo = controller->capabilities->structuralParameters[0]; - printf("%i available slots, %i available ports\n", slotInfo & 0xFF, - slotInfo >> 24); controller->portCount = slotInfo >> 24; + printf("%i available slots, %i available ports\n", slotInfo & 0xFF, + controller->portCount); return controller; } diff --git a/src/userland/usb/xhci/xhci.c b/src/userland/usb/xhci/xhci.c index 5eddf3e..b8fcae1 100644 --- a/src/userland/usb/xhci/xhci.c +++ b/src/userland/usb/xhci/xhci.c @@ -1,6 +1,7 @@ #include "xhci.h" #include "commands.h" #include "controller.h" +#include "trbRing.h" #include #include @@ -20,7 +21,7 @@ inputContext->deviceContext.endpoints[0].maxPrimaryStreams = 0; inputContext->deviceContext.endpoints[0].multiplier = 0; inputContext->deviceContext.endpoints[0].errorCount = 3; - inputContext->deviceContext.endpoints[0].averageTRBLength = 8; + inputContext->deviceContext.endpoints[0].averageTRBLength = 1024; return inputContext; } @@ -42,10 +43,13 @@ } slot->inputContext = createInputContext(slot); slot->controlRing = createSlotTRB(slot); + controller->deviceContexts[slot->slotIndex] = malloc(sizeof(XHCIDevice)); slot->controller->deviceContextBaseAddressArray[slot->slotIndex] = - U32(getPhysicalAddress(malloc(sizeof(XHCIDevice)))); + U32(getPhysicalAddress( + (void *)controller->deviceContexts[slot->slotIndex])); printf("port %i: addressing slot\n", portIndex); addressDevice(slot, true); + addressDevice(slot, false); UsbSlot *result = malloc(sizeof(UsbSlot)); result->data = slot; result->interface = &xhci; @@ -66,10 +70,74 @@ return host; } -void *(*test)(uint32_t, uint32_t, uint32_t) = init; +void xhciSetupEndpoints(SlotXHCI *slot, ListElement *endpoints, + uint32_t configValue) { + XHCIController *controller = slot->controller; + XHCIInputContext *inputContext = slot->inputContext; + memcpy((void *)controller->deviceContexts[slot->slotIndex], + (void *)&inputContext->deviceContext, sizeof(XHCIDevice)); + inputContext->inputControl.addContextFlags = 1; + printf("slot context state: %x, address: %x\n", + inputContext->deviceContext.slot.slotState, + inputContext->deviceContext.slot.deviceAddress); + foreach (endpoints, UsbEndpointDescriptor *, endpoint, { + uint8_t endpointNumber = endpoint->address & 0xF; // never 0 + uint8_t direction = endpoint->address >> 7; + uint8_t endpointIndex = (endpointNumber + direction) * 2 - 1; + XHCIEndpointContext *endpointContext = + &inputContext->deviceContext.endpoints[endpointIndex]; + endpointContext->endpointState = 0; + endpointContext->maxPrimaryStreams = 0; + endpointContext->interval = endpoint->interval; + endpointContext->errorCount = 3; + endpointContext->endpointType = + 4 * direction + endpoint->attributes & 3; + endpointContext->maxPacketSize = endpoint->maxPacketSize; + slot->endpointRings[endpointIndex] = malloc(sizeof(TrbRing)); + setupTrbRing(slot->endpointRings[endpointIndex], 256); + endpointContext->transferDequeuePointerLow = + U32(slot->endpointRings[endpointIndex]->physical) | 0; + endpointContext->transferDequeuePointerHigh = 0; + endpointContext->averageTRBLength = 2048; + inputContext->inputControl.addContextFlags |= 1 << (endpointIndex + 1); + inputContext->deviceContext.slot.contextEntryCount = MAX( + inputContext->deviceContext.slot.contextEntryCount, endpointIndex); + }) + ; + + XHCISetupStageTRB setup = {0}; + setup.requestType = 0x00; + setup.request = 9; + setup.value = configValue; + setup.index = 0; + setup.length = 0; + setup.transferLength = 8; + setup.interruptOnCompletion = 0; + setup.interrupterTarget = 0; + setup.type = 2; + setup.transferType = 3; + setup.immediateData = 1; + + XHCIStatusStageTRB status = {0}; + status.inDirection = 0; + status.evaluateNext = 0; + status.interruptOnCompletion = 1; + status.type = 4; + + uint32_t control = COMMAND_TYPE(12) | COMMAND_SLOT_ID(slot->slotIndex); + xhciCommand(controller, U32(getPhysicalAddress((void *)inputContext)), 0, 0, + control); + enqueueCommand(slot->controlRing, (void *)&setup); + uint32_t commandAddress = + U32(enqueueCommand(slot->controlRing, (void *)&status)); + uint32_t eventId = createDirectEventSave(commandAddress); + slot->controller->doorbells[slot->slotIndex] = 1; + await(serviceId, eventId); +} UsbHostControllerInterface xhci = { .initialize = init, .getDeviceDescriptor = (void *)usbGetDeviceDescriptor, + .setupEndpoints = (void *)xhciSetupEndpoints, .pciClass = 0x0C0330, }; diff --git a/src/userland/usb/xhci/xhci.h b/src/userland/usb/xhci/xhci.h index 47fd9fa..8a21958 100644 --- a/src/userland/usb/xhci/xhci.h +++ b/src/userland/usb/xhci/xhci.h @@ -164,6 +164,7 @@ XHCIEventRingSegmentTableEntry *eventRingSegmentTable, *eventRingSegmentTablePhysical; uint64_t *deviceContextBaseAddressArray; + XHCIDevice *deviceContexts[16]; uint32_t portCount; XHCIInputContext *inputContexts[32]; } XHCIController; @@ -174,6 +175,7 @@ XHCIInputContext *inputContext; XHCIPort *port; TrbRing *controlRing; + TrbRing *endpointRings[32]; } SlotXHCI; #endif