Major XHCI Problems

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
bellezzasolo
Member
Member
Posts: 110
Joined: Sun Feb 20, 2011 2:01 pm

Major XHCI Problems

Post by bellezzasolo »

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.
Capture.jpg
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:
QEMU XHCI.txt
(27.9 KiB) Downloaded 46 times
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Major XHCI Problems

Post by BenLunt »

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
User avatar
bellezzasolo
Member
Member
Posts: 110
Joined: Sun Feb 20, 2011 2:01 pm

Re: Major XHCI Problems

Post by bellezzasolo »

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
Here's my Input Context initialization (I've created a struct with bitfileds for debugging):

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;
	}
Alignment can't be an issue, give that it's page aligned. Regarding the speed of my keyboard, HwInfo reports the following on Windows:
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
FA68D294-6CFA-401C-9742-07C9295C9429.jpeg
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Major XHCI Problems

Post by BenLunt »

Hi,
bellezzasolo wrote: Alignment can't be an issue, give that it's page aligned.
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: 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
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.

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
User avatar
bellezzasolo
Member
Member
Posts: 110
Joined: Sun Feb 20, 2011 2:01 pm

Re: Major XHCI Problems

Post by bellezzasolo »

I've had a dig through what Linux puts out wrt my USB.

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
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.
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
Post Reply