OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 10:13 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 55 posts ]  Go to page Previous  1, 2, 3, 4
Author Message
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Wed Aug 09, 2017 11:45 am 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
HM... it looks like on my physical hardware it cannot even detect the presence of devices on the ports...


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Wed Aug 09, 2017 12:28 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
Do you set the CONFIGFLAG register?

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Wed Aug 09, 2017 2:39 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
Korona wrote:
Do you set the CONFIGFLAG register?

Yes, I set it to 1.


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Wed Aug 09, 2017 5:44 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
mariuszp wrote:
The power bit is set, just checked. However is my reset sequence correct?
Code:
                  sleep(100);
                  ehciRegs->ports[i] |= EHCI_PORT_RESET;
                  sleep(50);
                  ehciRegs->ports[i] &= ~EHCI_PORT_RESET;

I booted and looked at the results of your .ISO you sent me. It does the following:
Code:
00649062448d[EHCI  ] register read from offset 0x0024:  0x0000000000000004 (len=4)
00649062448d[EHCI  ] register write to  offset 0x0024:  0x0000000000000004 (len=4)
00649090482d[EHCI  ] register write to  offset 0x0038:  0x0000000001D5E000 (len=4)
00649090482d[EHCI  ] register read from offset 0x0020:  0x0000000000080001 (len=4)
00649090482d[EHCI  ] register write to  offset 0x0020:  0x0000000000080021 (len=4)

00649090509d[EHCI  ] register read from offset 0x0024:  0x0000000000000000 (len=4)
  ... repeated for quite some time
      (you should really set up interrupts.  polling uses a lot of CPU/bus time)
00649090509d[EHCI  ] register read from offset 0x0024:  0x0000000000000000 (len=4)

00649100000d[EHCI  ] register read from offset 0x0024:  0x0000000000008000 (len=4)
00651049433d[EHCI  ] register read from offset 0x0064:  0x000000000000100F (len=4)
00651049433d[EHCI  ] register write to  offset 0x0064:  0x000000000000100F (len=4)
00651049454d[EHCI  ] register read from offset 0x0004:  0x0000000000103206 (len=4)
00656167034d[EHCI  ] register read from offset 0x0064:  0x0000000000001005 (len=4)
00656167034d[EHCI  ] register write to  offset 0x0064:  0x0000000000001105 (len=4)
  ... repeated for quite some time. In fact, it never stops.

In the above code, you set the reset bit in the PORT0 register, then wait for it to become clear.
The controller won't ever clear it.

I misled you:
Ben wrote:
The reset can be complicated.
1) The USBSTS:HcHalted bit must be zero, hence, the schedule must be running
2) Set the Port Reset bit and clear the Port Enabled bit at the same time
3) Since this is a root hub, make sure you assert the reset for 50ms.
4) Wait for the bit to clear
5) Pause for TRSTRCY (recovery time)

I don't know where I got that from. The controller won't clear the bit, you must clear the bit. I apologize for that, my mistake.

So the above should be:
Ben wrote:
1) The USBSTS:HcHalted bit must be zero, hence, the schedule must be running
2) Set the Port Reset bit and clear the Port Enabled bit at the same time
3) Since this is a root hub, make sure you assert the reset for 50ms.
4) Clear the bit
5) Pause for TRSTRCY (recovery time)

Is VirtualBox clearing the bit and allowing your code to continue? If so, VirtualBox is in error.

Anyway, after fixing your code to not wait for the bit to be clear, it looks like your code works just fine. I wonder if VirtualBox is to blame, but I have my doubts. Here is the new results:
Code:
00614699990d[EHCI  ] register read from offset 0x0024:  0x0000000000000000 (len=4)
00614699997d[EHCI  ] register read from offset 0x0024:  0x0000000000000000 (len=4)
00614700004d[EHCI  ] register read from offset 0x0024:  0x0000000000008000 (len=4)
00616649103d[EHCI  ] register read from offset 0x0064:  0x000000000000100F (len=4)
00616649103d[EHCI  ] register write to  offset 0x0064:  0x000000000000100F (len=4)
00616649124d[EHCI  ] register read from offset 0x0004:  0x0000000000103206 (len=4)
00621766708d[EHCI  ] register read from offset 0x0064:  0x0000000000001005 (len=4)
00621766708d[EHCI  ] register write to  offset 0x0064:  0x0000000000001105 (len=4)
00621766708d[EHCI  ] register read from offset 0x0064:  0x0000000000001005 (len=4)
00621766708d[EHCI  ] register read from offset 0x0064:  0x0000000000001005 (len=4)
00621800000d[EHCI  ] submit: qh 1d5e002 next 1d5e002 qtd 1d5f000 pid 2d len 8 (total 8) endp 0 ret 0

00621800000d[EHCI  ] execute_complete: qhaddr 0x1d5e002, next 1d5e002, qtdaddr 0x1d5f000, status 0
00621800000d[EHCI  ] updating tbytes to 0
00621800000d[USBMSD] USB_REQ_SET_ADDRESS:
00621800000d[EHCI  ] submit: qh 1d5e002 next 1d5e002 qtd 1d5f020 pid 69 len 0 (total 0) endp 0 ret 0

00621800000d[EHCI  ] execute_complete: qhaddr 0x1d5e002, next 1d5e002, qtdaddr 0x1d5f020, status 0
00621800000d[EHCI  ] updating tbytes to 0

And now your results:
Code:
TOKEN WAS: 0x00080E80, TOKEN IS: 0x80000E00
TOKEN WAS: 0x00080E80, TOKEN IS: 0x80000E00
TOKEN WAS: 0x00080E80, TOKEN IS: 0x80000E00


The only thing I saw that might be in question is that your QHhorz pointer points back to the same QH instead of the next one in the list.

Fix your reset code to not wait for the bit to be clear (again, sorry about that) and run it on real hardware again.

Ben


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Wed Aug 09, 2017 7:26 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
Yes, in VirtualBox the controller clears the reset bit automatically for some reason. My old code was resetting by waiting 50ms and then clearing the bit and that didn't work either. The current code still fails to work in VirtualBox. To make sure, here's my new reset code:

Code:
                  // check power
                  if (ehci->caps->hcsparams & EHCI_HCS_PPC)
                  {
                     // turn on power
                     ehci->regs->ports[i] |= EHCI_PORT_POWER;
                  };
                  
                  sleep(100);
                  ehci->regs->ports[i] |= EHCI_PORT_RESET;
                  //while (ehci->regs->ports[i] & EHCI_PORT_RESET);
                  sleep(50);
                  ehci->regs->ports[i] &= ~EHCI_PORT_RESET;
                  sleep(100);
                  
                  if ((ehci->regs->ports[i] & EHCI_PORT_ENABLED) == 0)
                  {
                     uint32_t numcc = (ehci->caps->hcsparams >> 12) & 0xF;
                     if (numcc == 0)
                     {
                        // there are no companion controllers;
                        // cannot handle non-high-speed devices
                        continue;
                     };
                     
                     // delegate to companion controller
                     ehci->regs->ports[i] |= EHCI_PORT_OWNER;
                     continue;
                  };


The QH points to itself because it's the only QH in the list at the moment.

Now, in VirtualBox, it continues to fail with the same error. However, I will now try it on real hardware and report back the results.

EDIT: On real hardware, it attempts to initialize 2 ports (although 3 devices are connected) and the "enabled" bit does not get set. Also, taking out the USB memory stick and plugging it back in does not cause glidix to print anything.

It seems that I have skipped the OS-BIOS hand-off, and I'm wondering if maybe all these problems are caused by this (e.g. the clearing of "reset" by VirtualBox). This would also explain why it worked in your case (since whatever you were using might not require the OS-BIOS hand-off for EHCI). I;'m gonna implement that tomorrow (it's 03:00 here) and see what happens.

EDIT 2: In VirtualBox, the extended capabilities pointer is zero... so no OS-BIOS hand-off.


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Thu Aug 10, 2017 5:58 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
After doing the hand-off, the problem on physical hardware is still the same - it attempts to reset 2 ports and they both come back as not enabled (could it be that the BIOS still controls xHCI and the devices are USB 3.0 so I never get the ports routed to EHCI?).

However, it now works in both VirtualBox and Bochs. I'm not sure why it started working in VirtualBox - it didn't even have the hand-off capability.

EDIT: Ugh, it sometimes works in VirtualBox and sometimes does now. The last time I ran it, there was no error, now the "transaction error" occurs again.

EDIT 2: turns out that on real hardware, i put the usb stick into a usb3 port. When in a usb2 port, it works. So only the virtualbox problem occurs


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Thu Aug 10, 2017 7:12 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
After doing a few tests, I found that VirtualBox has a few quirks that you might need to be aware of.
1) VirtualBox clears the Reset bit in the PORT register. This is not correct. The controller should not clear the bit.
2) On actual hardware, the Reset bit may not transition to zero right away (after writing a zero to it). In VirtualBox it does. However, the specification says that the Enable Bit must be set within 2ms of the bit going from 1 to 0. Maybe you need to watch for the bit to turn zero, then wait that 2 ms.

I found a few other quirks/differences with VirtualBox and real hardware and had to adjust my code to compensate to get it to work on VirtualBox. For example, writing a zero to the Enable bit was not clearing the Enable bit right away. The specification (my tests on actual hardware agree) states that the Enable bit from 1 to zero may take some time. Virtual Box changed it to zero instantly. Just some of my observations. Afterall, it is an emulator, though a pretty good one, IMHO.

Ben


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Thu Aug 10, 2017 8:02 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
BenLunt wrote:
After doing a few tests, I found that VirtualBox has a few quirks that you might need to be aware of.
1) VirtualBox clears the Reset bit in the PORT register. This is not correct. The controller should not clear the bit.
2) On actual hardware, the Reset bit may not transition to zero right away (after writing a zero to it). In VirtualBox it does. However, the specification says that the Enable Bit must be set within 2ms of the bit going from 1 to 0. Maybe you need to watch for the bit to turn zero, then wait that 2 ms.

I found a few other quirks/differences with VirtualBox and real hardware and had to adjust my code to compensate to get it to work on VirtualBox. For example, writing a zero to the Enable bit was not clearing the Enable bit right away. The specification (my tests on actual hardware agree) states that the Enable bit from 1 to zero may take some time. Virtual Box changed it to zero instantly. Just some of my observations. Afterall, it is an emulator, though a pretty good one, IMHO.

Ben


Interestingly, if the USB stick in unplugged when I boot VirtualBox, and I plug it in after EHCI is intialized, everything works; the port resets, the transaction is successful. So it seems the problem only occurs if the device is already plugged in when booting. And again, there is no problem on real hardware or Bochs. I will try out your suggestions though.

As a side question, why does it set the "data toggle" bit in the transfer descriptor after the transaction is successful? The specification only seems to mentino that the "dt" bit is used to control the data toggle when sending, so I'm not sure what it means when the controller sets it after the transaction.


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Thu Aug 10, 2017 8:24 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
mariuszp wrote:
Interestingly, if the USB stick in unplugged when I boot VirtualBox, and I plug it in after EHCI is intialized, everything works; the port resets, the transaction is successful. So it seems the problem only occurs if the device is already plugged in when booting. And again, there is no problem on real hardware or Bochs. I will try out your suggestions though.

After a PORT reset, the state of the PORT register should be as if the device was just plugged in, even if the device was plugged in before boot. This could have something to do with your code and/or could be something to do with VirtualBox. Since it works fine on real hardware and Bochs, I would lean toward an error in VirtualBox.

mariuszp wrote:
As a side question, why does it set the "data toggle" bit in the transfer descriptor after the transaction is successful? The specification only seems to mentino that the "dt" bit is used to control the data toggle when sending, so I'm not sure what it means when the controller sets it after the transaction.

Section 4.10.3, top of page 83, of the specification states that the Dt bit is toggled in the overlay area of the QH. Is the Dt bit being toggled in your actual TD? If so, this may be a quirk with VirtualBox, however the Dt bit is read/write by the controller. VirtualBox might be toggling the bit in the TD *before* it is writing it to the overlay area. Since the Dt bit is marked read/write by the controller, this is not necessarily in error.


Top
 Profile  
 
 Post subject: Re: Setting up EHCI queue heads
PostPosted: Thu Aug 10, 2017 8:46 pm 
Offline
Member
Member

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 587
BenLunt wrote:
mariuszp wrote:
Interestingly, if the USB stick in unplugged when I boot VirtualBox, and I plug it in after EHCI is intialized, everything works; the port resets, the transaction is successful. So it seems the problem only occurs if the device is already plugged in when booting. And again, there is no problem on real hardware or Bochs. I will try out your suggestions though.

After a PORT reset, the state of the PORT register should be as if the device was just plugged in, even if the device was plugged in before boot. This could have something to do with your code and/or could be something to do with VirtualBox. Since it works fine on real hardware and Bochs, I would lean toward an error in VirtualBox.

mariuszp wrote:
As a side question, why does it set the "data toggle" bit in the transfer descriptor after the transaction is successful? The specification only seems to mentino that the "dt" bit is used to control the data toggle when sending, so I'm not sure what it means when the controller sets it after the transaction.

Section 4.10.3, top of page 83, of the specification states that the Dt bit is toggled in the overlay area of the QH. Is the Dt bit being toggled in your actual TD? If so, this may be a quirk with VirtualBox, however the Dt bit is read/write by the controller. VirtualBox might be toggling the bit in the TD *before* it is writing it to the overlay area. Since the Dt bit is marked read/write by the controller, this is not necessarily in error.


Linux does not seem to have problems with using the USB stick with EHCI in VirtualBox, even if already plugged in at boot, so there MUST be some difference.

Also, the "dt" bit is set by the controller on ALL platforms (VirtualBox, Bochs, real hardware). It even got set in the example you posted (TOKEN WAS: 0x0...., TOKEN IS: 0x8...)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 55 posts ]  Go to page Previous  1, 2, 3, 4

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 68 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group