Page 1 of 1

[SOLVED]Cannot detect connections of USB devices

Posted: Thu Nov 05, 2020 2:17 am
by tokusan
Hello. After solving a problem (viewtopic.php?f=1&t=37366), I confirmed that the event ring and the command ring of xHC worked (at least on QEMU) by sending a No-op TRB after running xHC. However, this OS cannot detect the connections of USB devices. Reading CCS bit of all port_sc registers returns 0.

I use this command to run QEMU:

Code: Select all

qemu-system-x86_64 -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,file=OVMF_VARS.fd,readonly=on -drive format=raw,file=build/ramen_os.img -no-reboot -m 4G -d int -device isa-debug-exit,iobase=0xf4,iosize=0x04 -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 --trace events=trace.event -no-shutdown -monitor stdio
Code: https://github.com/toku-sa-n/ramen/tree/check_each_port xHCI codes are in kernel/src/device/pci/xhci/
Trace log: https://gist.github.com/0d088d581a61c74 ... 6dc66dbecd

Am I missing something?

Thanks,

(Note that I don't enable interruptions from xHC. I just poll the event ring.)

EDIT: I confirmed that the port 0 is in RxDetect state and the state didn't change. According to Ben's book, this indicates that the device has a fault (or broken?). However, my mouse device is not broken, and even if I specify `-device usb-mouse`, the state doesn't change.

Re: Cannot detect connections of USB devices

Posted: Thu Nov 05, 2020 7:20 pm
by BenLunt
tokusan wrote:Hello. After solving a problem (viewtopic.php?f=1&t=37366), I confirmed that the event ring and the command ring of xHC worked (at least on QEMU) by sending a No-op TRB after running xHC. However, this OS cannot detect the connections of USB devices. Reading CCS bit of all port_sc registers returns 0.

I use this command to run QEMU:

Code: Select all

qemu-system-x86_64 -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,file=OVMF_VARS.fd,readonly=on -drive format=raw,file=build/ramen_os.img -no-reboot -m 4G -d int -device isa-debug-exit,iobase=0xf4,iosize=0x04 -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 --trace events=trace.event -no-shutdown -monitor stdio
Code: https://github.com/toku-sa-n/ramen/tree/check_each_port xHCI codes are in kernel/src/device/pci/xhci/
Trace log: https://gist.github.com/0d088d581a61c74 ... 6dc66dbecd

Am I missing something?

Thanks,

(Note that I don't enable interruptions from xHC. I just poll the event ring.)

EDIT: I confirmed that the port 0 is in RxDetect state and the state didn't change. According to Ben's book, this indicates that the device has a fault (or broken?). However, my mouse device is not broken, and even if I specify `-device usb-mouse`, the state doesn't change.
Hi,

First, have you powered the port. Bit 0 (CCS) will be zero no matter the connection status if there is no power to the port.

Next, since QEMU is an emulator, the device is either connected or it is not. One or the other. There shouldn't be any RxDetect state.

Are you reading the registers as DWORDs and DWORDs only? i.e.: you cannot read them as BYTEs or WORDs. Even if your code is written to read as DWORDs, you need to make sure the compiler is not optimizing the read to a BYTE or WORD. QEMU will not return a valid value if you do not read as a DWORD.

Ben

Re: Cannot detect connections of USB devices

Posted: Thu Nov 05, 2020 8:01 pm
by tokusan
BenLunt wrote:
tokusan wrote:Hello. After solving a problem (viewtopic.php?f=1&t=37366), I confirmed that the event ring and the command ring of xHC worked (at least on QEMU) by sending a No-op TRB after running xHC. However, this OS cannot detect the connections of USB devices. Reading CCS bit of all port_sc registers returns 0.

I use this command to run QEMU:

Code: Select all

qemu-system-x86_64 -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,file=OVMF_VARS.fd,readonly=on -drive format=raw,file=build/ramen_os.img -no-reboot -m 4G -d int -device isa-debug-exit,iobase=0xf4,iosize=0x04 -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 --trace events=trace.event -no-shutdown -monitor stdio
Code: https://github.com/toku-sa-n/ramen/tree/check_each_port xHCI codes are in kernel/src/device/pci/xhci/
Trace log: https://gist.github.com/0d088d581a61c74 ... 6dc66dbecd

Am I missing something?

Thanks,

(Note that I don't enable interruptions from xHC. I just poll the event ring.)

EDIT: I confirmed that the port 0 is in RxDetect state and the state didn't change. According to Ben's book, this indicates that the device has a fault (or broken?). However, my mouse device is not broken, and even if I specify `-device usb-mouse`, the state doesn't change.
Hi,

First, have you powered the port. Bit 0 (CCS) will be zero no matter the connection status if there is no power to the port.

Next, since QEMU is an emulator, the device is either connected or it is not. One or the other. There shouldn't be any RxDetect state.

Are you reading the registers as DWORDs and DWORDs only? i.e.: you cannot read them as BYTEs or WORDs. Even if your code is written to read as DWORDs, you need to make sure the compiler is not optimizing the read to a BYTE or WORD. QEMU will not return a valid value if you do not read as a DWORD.

Ben
Thank you for your reply.

I checked that all ports are powered. Reading the port power bits of all ports returns 1.

I found that the problem was that I didn't access to PORTSC registers as DWORD. Instead of accessing via bitfields, I tried just (port_sc & 1) then it returned 1 from port 5 and 0 from the other.
Now I'm confusing because not port 1 but port 5 returns 1. QEMU says:

Code: Select all

(qemu) info usb
  Device 0.1, Port 1, Speed 480 Mb/s, Product QEMU USB Mouse
Why?

Also QEMU says:

Code: Select all

[email protected]:usb_xhci_port_read port 1, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 2, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 3, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 4, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 5, off 0x0000, ret 0x00020ee1
[email protected]:usb_xhci_port_read port 6, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 7, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 8, off 0x0000, ret 0x000202a0
(I didn't get these outputs when I accessed via bitfields.)

Re: Cannot detect connections of USB devices

Posted: Thu Nov 05, 2020 9:49 pm
by BenLunt
tokusan wrote:I found that the problem was that I didn't access to PORTSC registers as DWORD.
All Operational Registers, QEMU or other, must be accessed via DWORD reads and writes.
All Capability Registers, on QEMU, must be DWORD accessed. However, on real hardware, they can be BYTE or WORD accessed.
tokusan wrote:Now I'm confusing because not port 1 but port 5 returns 1. QEMU says:

Code: Select all

(qemu) info usb
  Device 0.1, Port 1, Speed 480 Mb/s, Product QEMU USB Mouse
Why?

Also QEMU says:

Code: Select all

[email protected]:usb_xhci_port_read port 1, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 2, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 3, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 4, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 5, off 0x0000, ret 0x00020ee1
[email protected]:usb_xhci_port_read port 6, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 7, off 0x0000, ret 0x000202a0
[email protected]:usb_xhci_port_read port 8, off 0x0000, ret 0x000202a0
(I didn't get these outputs when I accessed via bitfields.)
In my book, read Chapter 9, "Port Routing and Control" and look at Figure 9-1.

xHCI has a register set for the USB3 port *and* a register set for the USB2 port of a single socket.

i.e.: If a socket supports both USB 2 *and* USB 3, it will have two register sets.

QEMU, by default, supports four sockets, giving eight register sets. Four for the USB 3 and four for the USB 2. The first four are the USB 3 and the second four are the USB 2.

In the figure you show above, Port 5 is the first USB 2 register set.

If your keyboard (which is a USB 2 device) is plugged into the first socket, it will use the first USB 2 register set.

You have to parse the capabilities to find out where the Register sets are located. A controller can have the register sets any way it wants.

For example, QEMU has it as (if memory serves):
USB 3 - Socket 0
USB 3 - Socket 1
USB 3 - Socket 2
USB 3 - Socket 3
USB 2 - Socket 0
USB 2 - Socket 1
USB 2 - Socket 2
USB 2 - Socket 3

However, real hardware could have it as:
USB 2 - Socket 0
USB 2 - Socket 1
USB 2 - Socket 2
USB 2 - Socket 3
USB 3 - Socket 0
USB 3 - Socket 1
USB 3 - Socket 2
USB 3 - Socket 3

Or even:
USB 3 - Socket 0
USB 2 - Socket 0
USB 3 - Socket 1
USB 2 - Socket 1
USB 3 - Socket 2
USB 2 - Socket 2
USB 3 - Socket 3
USB 2 - Socket 3

You have to parse the controllers capabilities to find out.

Ben
- http://www.fysnet.net/the_universal_serial_bus.htm

Re: Cannot detect connections of USB devices

Posted: Fri Nov 06, 2020 7:40 pm
by tokusan
Thank you for your reply. Now I fully understand. Thanks!

P.S.
BenLunt wrote:In my book, read Chapter 9, "Port Routing and Control" and look at Figure 9-1.
Figure 9-2?