Does anyone have the idea about writing XHCI Driver?

Programming, for all ages and all languages.
Post Reply
TYDQSoft
Posts: 21
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Does anyone have the idea about writing XHCI Driver?

Post by TYDQSoft »

My full repository is on https://github.com/TYDQSoft/UEFIPascalOS.
These days I have code an XHCI Driver for my kernel.
However,this XHCI Driver(usb.pas) is errorous when I trying to receive the data from my XHCI Driver,and I don't know where the error occurs,everything seems to be proper.
Does anyone have the idea to edit this XHCI driver(usb.pas)?If you have any problem about comprehend these errorous driver source code,I will reply in 2 days.
The usb.pas is too large to place in this topic,So I provide github link for you to look up my kernel's usb.pas.
User avatar
BenLunt
Member
Member
Posts: 965
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Does anyone have the idea about writing XHCI Driver?

Post by BenLunt »

Have you ran it through an emulator?

Have you tried Bochs (https://github.com/bochs-emu/Bochs)? If you set the debug option for the xHCI, it will display quite a bit of debug messages to your log file which will help you narrow the error further.

(Just as a small suggestion, I would rename the usb.pas file to xhci.pas since there are at least three other controllers and multiple layers to the USB.)

Ben
- https://www.fysnet.net/the_universal_serial_bus.htm
TYDQSoft
Posts: 21
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Re: Does anyone have the idea about writing XHCI Driver?

Post by TYDQSoft »

BenLunt wrote: Tue Apr 22, 2025 4:57 pm Have you ran it through an emulator?

Have you tried Bochs (https://github.com/bochs-emu/Bochs)? If you set the debug option for the xHCI, it will display quite a bit of debug messages to your log file which will help you narrow the error further.

(Just as a small suggestion, I would rename the usb.pas file to xhci.pas since there are at least three other controllers and multiple layers to the USB.)

Ben
- https://www.fysnet.net/the_universal_serial_bus.htm
I have used QEMU to test for my XHCI Driver.
I just running my buggy driver just trying to receive some data from xhci however I don't receive anything from xhci.
Rename is advisable,Thank you.
User avatar
BenLunt
Member
Member
Posts: 965
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Does anyone have the idea about writing XHCI Driver?

Post by BenLunt »

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:

Image

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
TYDQSoft
Posts: 21
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Re: Does anyone have the idea about writing XHCI Driver?

Post by TYDQSoft »

BenLunt wrote: Tue Apr 22, 2025 9:16 pm 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:

Image

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
It seems no alternative option for me to debug the USB Controller without Bochs and I use QEMU as my debugger.I will try this.
Post Reply