Ive been writing an XHCI driver. This is my first USB host controller driver, so I haven't seperated USB stuff from the host controller stuff, yet. Not that there's much specific USB stuff anyway.
On QEMU, I am able to reset the controller, and get device descriptors and strings.
However, on real hardware, I seem to be losing interrupts, causing hangs (when enabling the device slot, or addressing the device). Before refactoring, sometimes I would be able to get a device string from my first device (Logitech USB 1 speakers). However, I then got stall conditions from my keyboard (and every other device), which is a Full Speed USB 2.0 device.
Clearly, I'm doing something wrong, but I cannot figure out what it is.
Update: the lack of interrupt was because I was doing read-modify-write on the CRCR. However, the stall condition remains.
https://github.com/ChaiSoft/ChaiOS/blob ... l/xhci.cpp
This is the log output from QEMU:
Major XHCI Problems
- bellezzasolo
- Member
- Posts: 110
- Joined: Sun Feb 20, 2011 2:01 pm
Major XHCI Problems
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
https://github.com/ChaiSoft/ChaiOS
Re: Major XHCI Problems
Hi guys,
Sorry I haven't been around this forum too much lately. I have been quite busy with other things as well as a new job.
As for the xHCI, make sure that your Slot and EP contexts are properly aligned and formatted. I have found that even a slight irregularity in the EP context will make a device stall.
Also, is your keyboard really a full-speed device? That would surprise me. A mouse and a keyboard should be a low-speed device. Make sure you have indicated this correctly in the Slot and EP context data. This will make a difference in the xHCI's bandwidth calculations.
Sorry I don't have much more time to help you with this. Hopefully things start to slow down a bit and I can come back to this forum more frequently.
Ben
- http://www.fysnet.net/the_universal_serial_bus.htm
Sorry I haven't been around this forum too much lately. I have been quite busy with other things as well as a new job.
As for the xHCI, make sure that your Slot and EP contexts are properly aligned and formatted. I have found that even a slight irregularity in the EP context will make a device stall.
Also, is your keyboard really a full-speed device? That would surprise me. A mouse and a keyboard should be a low-speed device. Make sure you have indicated this correctly in the Slot and EP context data. This will make a difference in the xHCI's bandwidth calculations.
Sorry I don't have much more time to help you with this. Hopefully things start to slow down a bit and I can come back to this forum more frequently.
Ben
- http://www.fysnet.net/the_universal_serial_bus.htm
- bellezzasolo
- Member
- Posts: 110
- Joined: Sun Feb 20, 2011 2:01 pm
Re: Major XHCI Problems
Here's my Input Context initialization (I've created a struct with bitfileds for debugging):BenLunt wrote:Hi guys,
Sorry I haven't been around this forum too much lately. I have been quite busy with other things as well as a new job.
As for the xHCI, make sure that your Slot and EP contexts are properly aligned and formatted. I have found that even a slight irregularity in the EP context will make a device stall.
Also, is your keyboard really a full-speed device? That would surprise me. A mouse and a keyboard should be a low-speed device. Make sure you have indicated this correctly in the Slot and EP context data. This will make a difference in the xHCI's bandwidth calculations.
Sorry I don't have much more time to help you with this. Hopefully things start to slow down a bit and I can come back to this forum more frequently.
Ben
- http://www.fysnet.net/the_universal_serial_bus.htm
Code: Select all
bool createSlotContext(size_t portspeed, xhci_port_info* pinfo)
{
//Allocate input context
paddr_t incontext = pmmngr_allocate(1);
volatile input_context* mapincontxt = (input_context*)find_free_paging(PAGESIZE);
paging_map((void*)mapincontxt, incontext, PAGESIZE, PAGE_ATTRIBUTE_WRITABLE | PAGE_ATTRIBUTE_NO_CACHING);
memset((void*)mapincontxt, 0, PAGESIZE);
//Set input control context
mapincontxt->AddContext = 3;
//Setup slot context
mapincontxt->SlotContext.rootHubPort = pinfo->portindex;
mapincontxt->SlotContext.routeString = 0;
mapincontxt->SlotContext.ContextEntries = 1;
mapincontxt->SlotContext.speed = portspeed;
//Initialise endpoint 0 context
//Control endpoint, CErr = 3
mapincontxt->EndpointContexts[0].MaxPacketSize = max_packet_size(portSpeed(portspeed));
mapincontxt->EndpointContexts[0].EPType = 4; //Control
mapincontxt->EndpointContexts[0].TRDequeuePtr = pinfo->cmdring.getBaseAddress() | 1;
mapincontxt->EndpointContexts[0].Cerr = 3;
mapincontxt->EndpointContexts[0].AvgTRBLength = 8;
mapincontxt->EndpointContexts[0].MaxBurstSize = 0;
mapincontxt->EndpointContexts[0].MaxESITPayloadLow = mapincontxt->EndpointContexts[0].MaxPacketSize * (mapincontxt->EndpointContexts[0].MaxBurstSize + 1);
//Allocate device context
paddr_t dctxt = pmmngr_allocate(1);
void* mapdctxt = find_free_paging(PAGESIZE);
paging_map(mapdctxt, dctxt, PAGESIZE, PAGE_ATTRIBUTE_WRITABLE | PAGE_ATTRIBUTE_NO_CACHING);
memset(mapdctxt, 0, PAGESIZE);
//Write to device context array slot
*raw_offset<volatile uint64_t*>(devctxt, pinfo->slotid * 8) = dctxt;
//Issue address device command
void* last_command = cmdring.enqueue(create_address_command(true, incontext, pinfo->slotid));
uint64_t* curevt = (uint64_t*)waitComplete(last_command, 1000);
if (get_trb_completion_code(curevt) != XHCI_COMPLETION_SUCCESS)
{
kprintf(u"Error addressing device\n");
return false;
}
pinfo->device_context = mapdctxt;
//If the device is full speed, we need to work out the correct packet size
if (portSpeed(portspeed) == FULL_SPEED)
{
//kprintf(u"Full speed device, calculating packet size\n");
if (!update_packet_size_fs(pinfo))
return false;
}
last_command = cmdring.enqueue(create_address_command(false, incontext, pinfo->slotid));
curevt = (uint64_t*)waitComplete(last_command, 1000);
if (get_trb_completion_code(curevt) != XHCI_COMPLETION_SUCCESS)
{
kprintf(u"Error addressing device\n");
return false;
}
return true;
}
Device Manufacturer: E-Signal
Product Name: USB Gaming Keyboard
Serial Number: N/A
USB Version Supported: 2.00
USB Device Speed: USB 1.1 Full-speed
Driver Description: USB Composite Device
Hardware ID: USB\VID_0518&PID_5111
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
https://github.com/ChaiSoft/ChaiOS
Re: Major XHCI Problems
Hi,
You need to check the port bits at reset. (It has been a while since I have actually done anything with it, I don't remember exactly which bits. I would actually have to look it up.)
Ben
Remember that there is a machine page, which probably is 4096 in size, and there is an xHCI page, which might be 4096 bytes in size, but could be different. The xHCI will indicate the size for you.bellezzasolo wrote: Alignment can't be an issue, give that it's page aligned.
I wouldn't trust this. Windows is probably just indicating that it is of the Low-, Full-speed era of the USB. USB 1.1 had a max speed of Full-speed, so it displays that.bellezzasolo wrote: Regarding the speed of my keyboard, HwInfo reports the following on Windows:
USB Version Supported: 2.00
USB Device Speed: USB 1.1 Full-speed
You need to check the port bits at reset. (It has been a while since I have actually done anything with it, I don't remember exactly which bits. I would actually have to look it up.)
Ben
- bellezzasolo
- Member
- Posts: 110
- Joined: Sun Feb 20, 2011 2:01 pm
Re: Major XHCI Problems
I've had a dig through what Linux puts out wrt my USB.
The quirks are:
XHCI_SPURIOUS_SUCCESS, XHCI_LPM_SUPPORT, XHCI_INTEL_HOST, XHCI_AVOID_BEI
So it looks like I'm reading the full speed correctly. My full speed packet size code works for the speakers (setting a default of 64 leads to a babble condition, 8 does not, and then I update the context). It seems to fall down with the keyboard though.
Code: Select all
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.383751] xhci_hcd 0000:00:14.0: xHCI Host Controller
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.383753] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 1
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.384822] xhci_hcd 0000:00:14.0: hcc params 0x200077c1 hci version 0x110 quirks 0x0000000000009810
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.384829] xhci_hcd 0000:00:14.0: cache line size of 64 is not supported
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.724050] usb 1-3: new full-speed USB device number 2 using xhci_hcd
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.878006] usb 1-3: New USB device found, idVendor=1130, idProduct=1620, bcdDevice= 1.87
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.878007] usb 1-3: New USB device strings: Mfr=0, Product=2, SerialNumber=0
May 3 17:55:49 nathaniel-desktoplin kernel: [ 1.878008] usb 1-3: Product: USB AUDIO
May 3 17:55:49 nathaniel-desktoplin kernel: [ 2.004052] usb 1-7: new full-speed USB device number 3 using xhci_hcd
May 3 17:55:49 nathaniel-desktoplin kernel: [ 2.158641] usb 1-7: New USB device found, idVendor=0518, idProduct=5111, bcdDevice= 2.01
May 3 17:55:49 nathaniel-desktoplin kernel: [ 2.158642] usb 1-7: New USB device strings: Mfr=1, Product=2, SerialNumber=0
May 3 17:55:49 nathaniel-desktoplin kernel: [ 2.158642] usb 1-7: Product: USB Gaming Keyboard
May 3 17:55:49 nathaniel-desktoplin kernel: [ 2.158643] usb 1-7: Manufacturer: E-Signal
May 3 17:55:49 nathaniel-desktoplin kernel: [ 2.288149] usb 1-8: new full-speed USB device number 4 using xhci_hcd
May 3 17:55:49 nathaniel-desktoplin kernel: [ 3.086150] usb 1-8: New USB device found, idVendor=04d9, idProduct=a0d6, bcdDevice= 1.05
May 3 17:55:49 nathaniel-desktoplin kernel: [ 3.086150] usb 1-8: New USB device strings: Mfr=1, Product=2, SerialNumber=0
May 3 17:55:49 nathaniel-desktoplin kernel: [ 3.086151] usb 1-8: Product: USB Gaming Mouse
May 3 17:55:49 nathaniel-desktoplin kernel: [ 3.086152] usb 1-8: Manufacturer: E-Signal/A-One
XHCI_SPURIOUS_SUCCESS, XHCI_LPM_SUPPORT, XHCI_INTEL_HOST, XHCI_AVOID_BEI
So it looks like I'm reading the full speed correctly. My full speed packet size code works for the speakers (setting a default of 64 leads to a babble condition, 8 does not, and then I update the context). It seems to fall down with the keyboard though.
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
https://github.com/ChaiSoft/ChaiOS