Again, did you give Bochs a try?
Here is an example of the log file when you have debug set for the xHCI.
The following shows the Guest reading/writing the PCI registers:
Code: Select all
00000579384d[XHCI ] read PCI register 0x00 value 0x00151912 (len=4)
00000579413d[XHCI ] read PCI register 0x08 value 0x0C033002 (len=4)
00000579440d[XHCI ] read PCI register 0x0C value 0x00000010 (len=4)
00000579478d[XHCI ] read PCI register 0x04 value 0x00100106 (len=4)
00000579508d[XHCI ] read PCI register 0x04 value 0x00100106 (len=4)
00000579510d[XHCI ] write PCI register 0x04 value 0x00100104 (len=4)
00000579555d[XHCI ] write PCI register 0x10 value 0xFFFFFFFF (len=4)
00000579577d[XHCI ] read PCI register 0x10 value 0xFFFFE004 (len=4)
00000579633d[XHCI ] write PCI register 0x10 value 0xC0000000 (len=4)
The following shows the Guest reading/writing the xHCI's Operational Registers:
Code: Select all
00002397114d[XHCI ] register read from offset 0x0000: 0x0000000001000020 (len=4)
00002397114d[XHCI ] register read from offset 0x0020: 0x0000000000000000 (len=4)
00002397114d[XHCI ] register write to offset 0x0020: 0x0000000000000000 (len=4)
00002397114d[XHCI ] register read from offset 0x0024: 0x0000000000000001 (len=4)
00002397114d[XHCI ] register read from offset 0x0020: 0x0000000000000000 (len=4)
00002397114d[XHCI ] register write to offset 0x0020: 0x0000000000000002 (len=4)
00002397114i[XHCI ] Reset port #1, type=0
00002397114i[XHCI ] Reset port #2, type=0
00002397114d[XHCI ] register read from offset 0x0020: 0x0000000000000000 (len=4)
00002397114d[XHCI ] register read from offset 0x0024: 0x0000000000000001 (len=4)
00002397181d[XHCI ] register read from offset 0x0010: 0x000000000140530F (len=4)
The following shows when the Guest has a valid Schedule and rang the Doorbell for Slot 1, Endpoint 1:
Code: Select all
00002483521d[XHCI ] Rang Doorbell: slot = 1 ep = 1 (IN)
00002483521d[XHCI ] Found TRB: address = 0x000000001ffb0740 0x0200000001000680 0x00000008 0x00030841 1 (SPD occurred = 0)
00002483521d[XHCI ] 0x000000001ffb0740: Transfer Ring (slot = 1) (ep = 1) (len = 8): Found SETUP TRB
00002483521d[XHCI ] OUT: Transferred 8 bytes (ret = 18)
00002483521d[XHCI ] Found TRB: address = 0x000000001ffb0750 0x000000001ffc8810 0x00000200 0x00010C13 1 (SPD occurred = 0)
00002483521d[XHCI ] 0x000000001ffb0750: Transfer Ring (slot = 1) (ep = 1) (len = 512): Found DATA STAGE TRB
00002483521d[XHCI ] IN: Transferred 18 bytes, requested 512 bytes
00002483521d[XHCI ] Found TRB: address = 0x000000001ffb0760 0x000000001ffc807c 0x00000000 0x00001C21 1 (SPD occurred = 1)
00002483521d[XHCI ] Write Event TRB: table index: 0, trb index: 3
00002483521d[XHCI ] Write Event TRB: address = 0x000000001ffb02c0 0x000000001ffc807c 0x0D000012 0x01018004 (type = 32)
00002483521d[XHCI ] Interrupt Fired.
The following shows when the Guest resets the port, then sends the GET_DESCRIPTOR request, showing the 18-byte return.
Code: Select all
00002478133i[XHCI ] Reset port #1, type=1
00002483521i[USBMSD] packet hexdump (8 bytes)
00002483521i[USBMSD] 80 06 00 01 00 00 00 02
00002483521i[USBMSD] packet hexdump (18 bytes)
00002483521i[USBMSD] 12 01 00 03 00 00 00 09-00 00 00 00 00 01 01 02
00002483521i[USBMSD] 03 01
If you set the debug flags to show all of this, it will show you exactly what is happening, and will attempt to show you where the error is.
If that isn't enough, Bochs will break at a specified trigger and show you the exact state of the xHCI controller.
Have a look at
https://www.fysnet.net/bochs/documentation.php and section 5.8, especially Figure 5-1 shown below:
Notice that all aspects of the xHCI controller are shown and will allow you to modify some of them.
- Clicking on the "<>" button next to the PORT will allow you to modify the bits of the Port Register (though it isn't recommended you do so).
- You can change the values in the other registers if you wish, though again, not really recommended.
However, the highlight of this figure is that it stopped when the Command Ring found the Enable Slot command. If you click on that line and then the "View TRB" button, you can see the TRB and modify it if you wish.
I highly recommend that you read the documentation, especially section 4.3.29 and then section 5.8 and give it a try.
Side note: I tried to add everything I could to the function of this part of Bochs, though I am sure I left something out, or incorrectly implemented something. If you find something in error, I would like to know.
Another side note: This is an example of the xHCI. Bochs will do the same for the UHCI... (I haven't got to the OHCI or EHCI yet).
If you, or anyone reading this, is serious about implementing USB in their projects, I recommend using the vast functionality of the Bochs USB debugger.
Ben
-
https://www.fysnet.net/the_universal_serial_bus.htm