OSDev.org

The Place to Start for Operating System Developers
It is currently Tue May 21, 2019 6:41 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: UHCI can find usb on emulators but not on real hardware
PostPosted: Wed Nov 28, 2018 11:34 am 
Offline

Joined: Tue Aug 30, 2016 1:31 pm
Posts: 6
So im working on a UHCI driver. I initialised the controller and I want to see which ports are connected. On qemu and bochs this goes well. On real hardware it keeps rising interrupts and saying there is nothing in the ports. This is my code: https://github.com/AdeRegt/SanderOSUSB/ ... CI?files=1


Top
 Profile  
 
 Post subject: Re: UHCI can find usb on emulators but not on real hardware
PostPosted: Wed Nov 28, 2018 2:00 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 556
Location: USA
I haven't had a chance to look over your code yet, but I plan on it soon.

One of the biggest things to recognize when it works on emulators, whom are horrible at absolute timing, and real hardware, which is excellent at real timing, is, well you guessed it, timing.

You must allow the hardware to actually do what it is asked to do. On an emulator, the emulation is already there. i.e.: as soon as you request the data, the data is already there waiting to be sent. On real hardware, this is not necessarily the case.

Also, the reset of the device has a lot of differences between emulators and hardware. On an emulator, it simply is the setting and clearing of the reset bit. Done. On real hardware, it is the timing between the time the reset bit is set, then cleared, as well as which other bits are set or cleared at the same time. If my memory serves, one of the bits in the Ports register *must* be cleared before or at the same time you clear the reset bit or a device will not reset.

Welcome to the art of real hardware testing. I will tell you, a hardware analyzer, such as the Beagle I got, is a wonderful piece of hardware to help with this stuff, if you can afford the expense.

When I get a chance, I will have a look at your code. In the meantime, check your reset timing and other timing code.

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


Top
 Profile  
 
 Post subject: Re: UHCI can find usb on emulators but not on real hardware
PostPosted: Wed Nov 28, 2018 3:45 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 556
Location: USA
In your
Code:
void irq_uhci(){
  ...
   outportb(0x20,0x20);
   outportb(0xA0,0x20);
}
code, you acknowledge the Master before the Slave. This is backwards. You should acknowledge the slave first. If not, the master might try to "fire" the slave pin while the slave is still "busy".

In your
Code:
void init_uhci_port(unsigned long BAR){
   uhciBAR = BAR;
   printstring("UHCI: initialising port at BAR ");
   ...
   outportw(BAR,0b0000000010000100);
   ...
}
you say that you are initializing the port. However, you are writing to the first register of the address space, yes? This isn't where the first port is.

In
Code:
void init_uhci(unsigned long BAR,unsigned char intnum){
   ...
   outportw(BAR,0b0000000000000010);
   ...
}
I send the Global Reset (bit 2) instead of the HCReset (bit 1). This makes sure that all devices attached also see a reset.

Just for your information, it is much easier to read the following:
Code:
   outportw(BAR,(1<<1));   // set bit 1
than
Code:
   outportw(BAR,0b0000000000000010);
i.e.: Using "(1<<8)" is much easier to read than "0b0000000100000000". You don't have to count bits with (1<<8).

A few more notes:
- Some controllers/devices require the schedule to be running before a port reset.
- You *must* check the "HcHalted" bit after starting/stopping the schedule. Simply setting or clearing the "Run" bit does not mean it is started/stopped. The "HcHalted" bit indicates if the schedule is running or not.
- Write your port initialize code so that sending a port index value will indicate which port you are initializing. i.e:
Code:
void init_uhci_port(unsigned long BAR){
should be
Code:
void init_uhci_port(const phy_address BAR, const int portnum) {
All routines that manipulate a port should have an index such as this.
("phy_address" is defined/typedef as 32-bits or 64-bits depending on the machine it is compiled for. However, for PORT I/O, this isn't must of a need. For MEM-MAPPED I/O, this is a great need.)

- Use #define's for registers. i.e.:
Code:
#define UHCI_COMMAND 0x0000
etc., then use
Code:
  outportw(BAR + UHCI_COMMAND, value);
This is so much easier to read, allowing the reader (you) to know which register you are writing to. Go a little further and use #define's for each bit as well.

Hope this helps,
Ben
- http://www.fysnet.net/osdesign_book_series.htm


Top
 Profile  
 
 Post subject: Re: UHCI can find usb on emulators but not on real hardware
PostPosted: Wed Nov 28, 2018 5:02 pm 
Offline

Joined: Tue Aug 30, 2016 1:31 pm
Posts: 6
Thank you very much for the fast answer.
I tried to add the things you have said.
I uploaded the new code to GitHub.

When I change the code to
Code:
   outportw(BAR,0b0000000000000000);
   resetTicks(); // 1 tick is on real hardware one second
   while(1){
      if(getTicks()==10){
         break;
      }
   }
   outportw(BAR,0b0000000000000100);
   while(1){
      volatile unsigned short duringreset = inportw(BAR+USBCMD);
      if((duringreset & 0b0000000000000110)==0){
         break;
      }
   }
   printstring("UHCI: reset completed!\n");

it keeps hanging in there "forever" and shows this (emulator snapshot) :
Code:
-elcome to the Sanderslando Kernel!!
Loading core components...
=> Global Description Table...
=> Interrupt Description Table...
Loading utilities...
=> Programmable Interrupt Timer...
=> PS2...
PS2: data for controller
PS2: port1 interrupt enabled
PS2: port2 clock enabled
PS2: porttranslation enabled
PS2: keyboard
PS2: keyboard enabled!
PS2: mouse disabled!
=> PCI...
PCI: detecting devices....
PCI: device detected, bridge device:  host bridge
PCI: device detected, bridge device:  ISA bridge
PCI: device detected, mass storage device:  IDE controller
PCI: device detected, serial buss controller:  USB controller, UHCI [USB 1]
UHCI: Initialising UHCI
UHCI: using I/O port c020 and irq 9
UHCI: USBCMD register before reset: 0
UHCI: USBSTS register before reset: 20


Also, must I set the runbit in order to detect the devices? since I have no commands for my queue.

Thank you.


Top
 Profile  
 
 Post subject: Re: UHCI can find usb on emulators but not on real hardware
PostPosted: Wed Nov 28, 2018 5:18 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 556
Location: USA
SanderR wrote:
When I change the code to
Code:
   outportw(BAR,0b0000000000000000);
   resetTicks(); // 1 tick is on real hardware one second
   while(1){
      if(getTicks()==10){
         break;
      }
   }
   outportw(BAR,0b0000000000000100);
   while(1){
      volatile unsigned short duringreset = inportw(BAR+USBCMD);
      if((duringreset & 0b0000000000000110)==0){
         break;
      }
   }
   printstring("UHCI: reset completed!\n");

it keeps hanging in there "forever" and shows this (emulator snapshot) :
Because the controller will not clear bit 2 when it is done. You must clear it after 10ms. Please note that this is 10 milliseconds, not 10 seconds. Your code suggests that you are waiting one (1) second per tick. This is way too long. Also, after the reset, clearing the bit, you need to delay again for USB_TRSTRCY milliseconds. This is the recovery wait.

All of this is explained in the UHCI specification sheet. A quick search for "UHCI specs" will bring it up. (Hint, this is the first)

SanderR wrote:
Also, must I set the run bit in order to detect the devices? since I have no commands for my queue.
Thank you.
You shouldn't have to, per the specification, but I have found that if the run bit is not set, some controllers don't perform as advertised. I have seen comments to this in other code/documentation as well.

Ben


Top
 Profile  
 
 Post subject: Re: UHCI can find usb on emulators but not on real hardware
PostPosted: Mon Dec 03, 2018 4:22 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 556
Location: USA
Just curious to see if you made any progress on this?

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


Top
 Profile  
 
 Post subject: Re: UHCI can find usb on emulators but not on real hardware
PostPosted: Mon Feb 11, 2019 4:21 pm 
Offline

Joined: Tue Aug 30, 2016 1:31 pm
Posts: 6
No, I have not made any progress.
I had a small pause and then started again with hope this time it would go better.
Still, on the emulators (BOCHS and QEMU) it is working while on real hardware it is still refusing.
I am currently working on a way to make the queue work and maybe it is detected that way.
The system is booted from USB, but LEGACY says it is 0xFFFF so probably it will not change the outcome of my code.

https://github.com/AdeRegt/SanderOSUSB/tree/uhci_2 is the newest link


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: kzinti and 6 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