Page 1 of 1

UHCI doesn't process queue head

Posted: Sat Sep 26, 2020 7:27 am
by Klakap
Good day,
I writing driver for uhci, but it still isnt work. I use this method:

Code: Select all

uhci_read_conf:
  UHCI_STOP

  ;FRAME ENTRY
  mov dword [0x400000], 0x410002 ;queue head on 0x410000

  ;QUEUE HEAD
  mov dword [0x410000], 0x420100 ;pointer to OUT TD
  mov dword [0x410004], 0x420000 ;pointer to SETUP and IN TDs

  ;TD SETUP
  mov dword [0x420000], 0x420020 ;link pointer to next TD
  mov dword [0x420004], 0x0480000 ;status
  mov dword [0x420008], 0x00E002D ;header toggle 0
  mov dword [0x42000C], 0x4A0000 ;pointer to memory
  ;memory data
  mov dword [0x4A0000], 0x02000680
  mov dword [0x4A0004], 0x002E0000

  ;TD IN
  mov dword [0x420020], 0x420040 ;link pointer to next TD
  mov dword [0x420024], 0x0480000 ;status
  mov dword [0x420028], 0x00E8069 ;header toggle 1
  mov dword [0x42002C], 0x4B0000 ;pointer to memory
  ;TD IN
  mov dword [0x420040], 0x420060 ;link pointer to next TD
  mov dword [0x420044], 0x0480000 ;status
  mov dword [0x420048], 0x00E0069 ;header toggle 0
  mov dword [0x42004C], 0x4B0008 ;pointer to memory
  ;TD IN
  mov dword [0x420060], 0x420080 ;link pointer to next TD
  mov dword [0x420064], 0x0480000 ;status
  mov dword [0x420068], 0x00E8069 ;header toggle 1
  mov dword [0x42006C], 0x4B0010 ;pointer to memory
  ;TD IN
  mov dword [0x420080], 0x4200A0 ;link pointer to next TD
  mov dword [0x420084], 0x0480000 ;status
  mov dword [0x420088], 0x00E0069 ;header toggle 0
  mov dword [0x42008C], 0x4B0018 ;pointer to memory
  ;TD IN
  mov dword [0x4200A0], 0x1 ;end TD
  mov dword [0x4200A4], 0x0480000 ;status
  mov dword [0x4200A8], 0x00E8069 ;header toggle 1
  mov dword [0x4200AC], 0x4B0020 ;pointer to memory

  ;TD OUT
  mov dword [0x420100], 0x1 ;end TD
  mov dword [0x420104], 0x0480000 ;status
  mov dword [0x420108], 0x00E00E1 ;header toggle 0
  mov dword [0x42010C], 0x4B0100 ;pointer to memory

  UHCI_FRAME_NUM 0
  UHCI_RUN

  ret
And after this I wait, but nothing happend. There is bochs debug output:

Code: Select all

00018857018d[UHCI ] read  PCI register 0x08 value 0x0c030001
00018857049d[UHCI ] write PCI register 0xc0 value 0x00008f00
00018857070d[UHCI ] write PCI register 0x04 value 0x00000005
00018857089d[UHCI ] read  PCI register 0x20 value 0x0000c021

00021659877d[UHCI ] register read from address 0xC020:  0x00000000 (16 bits)
00021659879d[UHCI ] register write to  address 0xC020:  0x00000000 (16 bits)
00021659879d[UHCI ] Schedule bit clear in Command register

00021662956d[UHCI ] register write to  address 0xC020:  0x00000004 (16 bits)
00021662956d[UHCI ] Global Reset
00021662956d[UHCI ] Schedule bit clear in Command register
00021692960d[UHCI ] register write to  address 0xC020:  0x00000000 (16 bits)
00021692960d[UHCI ] Schedule bit clear in Command register

00021692963d[UHCI ] register write to  address 0xC020:  0x00000002 (16 bits)
00021692963d[UHCI ] Schedule bit clear in Command register
00021692967d[UHCI ] register read from address 0xC020:  0x00000000 (16 bits)

00021692974d[UHCI ] register write to  address 0xC022:  0x0000003F (16 bits)
00021692978d[UHCI ] register write to  address 0xC02C:  0x00000040 ( 8 bits)
00021692982d[UHCI ] register write to  address 0xC026:  0x00000000 (16 bits)
00021692986d[UHCI ] register write to  address 0xC028:  0x00400000 (32 bits)
00021692990d[UHCI ] register write to  address 0xC024:  0x00000000 (16 bits)

00021692994d[UHCI ] register write to  address 0xC030:  0x00000000 (16 bits)
00021692994d[UHCI ] write to port #1 register bit 7 = 0
00021692997d[UHCI ] register write to  address 0xC032:  0x00000000 (16 bits)
00021692997d[UHCI ] write to port #2 register bit 7 = 0
00021693001d[UHCI ] register write to  address 0xC030:  0x00000200 (16 bits)
00021693001d[UHCI ] write to port #1 register bit 7 = 0
00021693001i[UHCI ] Port1: Reset
00021723006d[UHCI ] register write to  address 0xC030:  0x0000000E (16 bits)
00021723006d[UHCI ] write to port #1 register bit 7 = 0

00021723009d[UHCI ] register read from address 0xC030:  0x000005A5 (16 bits)

here is command call uhci_read_conf
00021727447d[UHCI ] register read from address 0xC020:  0x00000000 (16 bits)
00021727449d[UHCI ] register write to  address 0xC020:  0x00000000 (16 bits)
00021727449d[UHCI ] Schedule bit clear in Command register
00021727486d[UHCI ] register write to  address 0xC026:  0x00000000 (16 bits)
00021727488d[UHCI ] register read from address 0xC020:  0x00000000 (16 bits)
00021727490d[UHCI ] register write to  address 0xC020:  0x000000C1 (16 bits)
00021727490d[UHCI ] Schedule bit set in Command register
00021728000d[UHCI ] Queue   0: 0x00420100 0 0  0x00420000 0 0
00022055180d[UHCI ] register read from address 0xC020:  0x000000C1 (16 bits)
00022055182d[UHCI ] register write to  address 0xC020:  0x000000C0 (16 bits)
00022055182d[UHCI ] Schedule bit clear in Command register
Please where can be error?

Re: UHCI doesn't process queue head

Posted: Sat Sep 26, 2020 12:26 pm
by BenLunt
Klakap wrote:Good day,
I writing driver for uhci, but it still isnt work. I use this method:

Code: Select all

00021727490d[UHCI ] Schedule bit set in Command register
00021728000d[UHCI ] Queue   0: 0x00420100 0 0  0x00420000 0 0
00022055180d[UHCI ] register read from address 0xC020:  0x000000C1 (16 bits)
First, and I can't express this enough, you really need to use the macro mechanism of your assembler (compiler).

For example:

Code: Select all

mov dword [0x420008], 0x00E002D ;header toggle 0
Is very difficult to see what you are actually doing.

However:

Code: Select all

mov dword [0x420008], (SOME_FLAG << 12) | (ANOTHER_FLAG << 4) | (SOME_VALUE << 22)
is much easier to read.

This allows you to go back over your code and make sure you get it correct. Helps in debugging as well.

Second, the Bochs log report above states that it found the Queue, but did not find a TD.

Look at the following line of code:

Code: Select all

mov dword [0x420004], 0x0480000 ;status
Unless I am mistaken, you are off by a zero. This should be

Code: Select all

mov dword [0x420004], 0x04800000 ;status
This all comes back to my first point above. It makes it so much easier when you do:

Code: Select all

mov dword [0x420004], (TD_LOWSPEED | TD_STATUS_ACTIVE)
Ben
- http://www.fysnet.net/the_universal_serial_bus.htm

Re: UHCI doesn't process queue head

Posted: Tue Sep 29, 2020 1:19 am
by Klakap
Thank a milion! What stupid mistake I done. Now Bochs found TD, but it transfer only first TD(setup) next TDs(in) are skipped and transfer continue to horizontal - out packet. I try to make more QH but every QH transfer only first packet and go to next QH. Please what happens?

//EDIT I found the error. I forgot set depth bit. Thank you for your FYSOS USB programming book!