Re: Setting up EHCI queue heads
Posted: Wed Aug 09, 2017 11:45 am
HM... it looks like on my physical hardware it cannot even detect the presence of devices on the ports...
The Place to Start for Operating System Developers
http://f.osdev.org/
Yes, I set it to 1.Korona wrote:Do you set the CONFIGFLAG register?
I booted and looked at the results of your .ISO you sent me. It does the following:mariuszp wrote:The power bit is set, just checked. However is my reset sequence correct?Code: Select all
sleep(100); ehciRegs->ports[i] |= EHCI_PORT_RESET; sleep(50); ehciRegs->ports[i] &= ~EHCI_PORT_RESET;
Code: Select all
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.
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.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)
Is VirtualBox clearing the bit and allowing your code to continue? If so, VirtualBox is in error.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)
Code: Select all
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
Code: Select all
TOKEN WAS: 0x00080E80, TOKEN IS: 0x80000E00
TOKEN WAS: 0x00080E80, TOKEN IS: 0x80000E00
TOKEN WAS: 0x00080E80, TOKEN IS: 0x80000E00
Code: Select all
// 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;
};
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.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
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: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.
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.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.
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.BenLunt wrote: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: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.
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.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.