OSDev.org https://forum.osdev.org/ |
|
Bochs OHCI stalls and stops after I mess around with STATUS https://forum.osdev.org/viewtopic.php?f=1&t=56717 |
Page 1 of 1 |
Author: | sounds [ Wed Feb 01, 2023 5:42 pm ] |
Post subject: | Bochs OHCI stalls and stops after I mess around with STATUS |
I was reading here: viewtopic.php?p=317896#p317896 BenLunt wrote: This is not exactly the case. If the stall is on the Control Pipe, you don't necessarily ignore it. The stall remains until the next SETUP packet is found. Since the Control Pipe uses SETUP packets almost exclusively, then an ignore of the stall is almost correct. However, if the stall happens during an IN or OUT packet, you still need to remove the remaining scheduled packets before you sent the next SETUP packet. I decided to add more cases to my OHCI tests and Bochs' OHCI controller did something unexpected. Ben wrote the OHCI code in Bochs, so I'm hoping this turns out to be something easy - First, this is the log when things are working. (I added comments starting with ";") Code: rh_rst ; detected device connection status change rh_~rst: 50ms ; port reset bit cleared. wait 50ms hdr 80,6,0,1:0 8 ; GET_DEVICE_DESCRIPTOR len=8 HcControl = bf HcCommandStatus = 0 td0 phys=5208220 ; submit ED and TDs td[0].nxt=5208560 inf=f2000000 buf=52082e0 end=52082e7 td=373f49008220 td[1].nxt=5208570 inf=f2100000 buf=52082e8 end=52082ef td=373f49008550 td[2].nxt=5208300 inf=f3080000 buf=52082f0 end=52082ef TD[0] inf=3000000 buf=0 end=52082e7 ; dump contents of TDs after WDH TD[1] inf=3100000 buf=0 end=52082ef TD[2] inf=2080000 buf=0 end=52082ef rh_rst ; assert another port reset rh_~rst: 50ms ; port reset bit cleared. wait 50ms hdr 80,6,0,1:0 12 ; GET_DEVICE_DESCRIPTOR len=18==0x12 HcControl = bf HcCommandStatus = 0 td0 phys=5208300 ; submit ED and TDs td[0].nxt=52085a0 inf=f2000000 buf=5208560 end=5208567 td=373f49008300 td[1].nxt=52085b0 inf=f2100000 buf=5208568 end=520856f td=373f49008590 td[2].nxt=52085c0 inf=f2100000 buf=5208570 end=5208577 td=373f49008590 td[3].nxt=52085d0 inf=f2100000 buf=5208578 end=5208579 td=373f49008590 td[4].nxt=52082e0 inf=f3080000 buf=520857a end=5208579 TD[0] inf=3000000 buf=0 end=5208567 ; dump contents of TDs after WDH TD[1] inf=3100000 buf=0 end=520856f TD[2] inf=3100000 buf=0 end=5208577 TD[3] inf=3100000 buf=0 end=5208579 TD[4] inf=2080000 buf=0 end=5208579 DEVICE_DESCRIPTOR: 12 1 10 1 0 0 0 8 b4 4 1 1 1 0 1 2 3 1 hdr 0,5,1,0:0 0 ; SET_ADDRESS len=0 td0 phys=52082e0 td[0].nxt=5208320 inf=f2000000 buf=5208300 end=5208307 td=373f490082e0 td[1].nxt=5208220 inf=f3080000 buf=5208308 end=5208307 TD[0] inf=3000000 buf=0 end=5208307 TD[1] inf=2080000 buf=0 end=5208307 Ok, now I'm going to intentionally cause a stall. I do it by setting td[2].end to == td[2].buf, which is 1 more than what it should be. It's the STATUS packet, so the pipe will stall because a STATUS packet's length should be 0 but it's 1 here: Code: rh_rst rh_~rst: 50ms hdr 80,6,0,1:0 8 HcControl = bf HcCommandStatus = 0 td0 phys=fa08220 td[0].nxt=fa08560 inf=f2000000 buf=fa082e0 end=fa082e7 td=ffff959ba8e08220 td[1].nxt=fa08570 inf=f2100000 buf=fa082e8 end=fa082ef td=ffff959ba8e08550 td[2].nxt=fa08300 inf=f3080000 buf=fa082f0 end=fa082f0 TD[0] inf=3000000 buf=0 end=fa082e7 TD[1] inf=3100000 buf=0 end=fa082ef TD[2] inf=4e080000 buf=fa082f0 end=fa082f0 *stall bit set* rh_rst rh_~rst: 50ms hdr 80,6,0,1:0 12 HcControl = bf HcCommandStatus = 0 td0 phys=fa08300 td[0].nxt=fa085a0 inf=f2000000 buf=fa08560 end=fa08567 td=ffff959ba8e08300 td[1].nxt=fa085b0 inf=f2100000 buf=fa08568 end=fa0856f td=ffff959ba8e08590 td[2].nxt=fa085c0 inf=f2100000 buf=fa08570 end=fa08577 td=ffff959ba8e08590 td[3].nxt=fa085d0 inf=f2100000 buf=fa08578 end=fa08579 td=ffff959ba8e08590 td[4].nxt=fa082e0 inf=f3080000 buf=fa0857a end=fa0857a *timeout* And here's the Bochs log: Notice ret = -3 (that's the stall) Code: 00023061352 d [OHCI ] read PCI register 0x04 value 0x0006 (len=2) 00023061368 d [OHCI ] write PCI register 0x04 value 0x0006 (len=2) 00023271051 i [OHCI ] Ben: BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.psm == 1 00023395301 d [OHCI ] read PCI register 0x3C value 0x09 (len=1) 00023395326 d [OHCI ] read PCI register 0x04 value 0x0006 (len=2) 00023571000 d [OHCI ] Found a valid ED that points to an control/bulk/int TD 00023571000 d [OHCI ] Head: 0x0FA08220 Tail: 0x0FA08300 Next: 0x0FA08560 00023571000 d [OHCI ] pid = SETUP addr = 0 endpnt = 0 len = 8 mps = 8 (td->cbp = 0x0FA082E0, td->be = 0x0FA0 82E7) 00023571000 d [OHCI ] td->t = 2 ed->c = 0 td->di = 0 td->r = 0 00023571000 d [OHCI ] td->cbp = 0x00000000 ret = 8 len = 8 td->cc = 0 td->ec = 0 ed->h = 0 00023571000 d [OHCI ] td->t = 3 ed->c = 1 00023571000 d [OHCI ] Head: 0x0FA08560 Tail: 0x0FA08300 Next: 0x0FA08570 00023571000 d [OHCI ] pid = IN addr = 0 endpnt = 0 len = 8 mps = 8 (td->cbp = 0x0FA082E8, td->be = 0x0FA082E F) 00023571000 d [OHCI ] td->t = 2 ed->c = 1 td->di = 0 td->r = 0 00023571000 d [OHCI ] td->cbp = 0x00000000 ret = 8 len = 8 td->cc = 0 td->ec = 0 ed->h = 0 00023571000 d [OHCI ] td->t = 3 ed->c = 1 00023571000 d [OHCI ] Head: 0x0FA08570 Tail: 0x0FA08300 Next: 0x0FA08300 00023571000 d [OHCI ] pid = OUT addr = 0 endpnt = 0 len = 1 mps = 8 (td->cbp = 0x0FA082F0, td->be = 0x0FA082F0) 00023571000 d [OHCI ] td->t = 3 ed->c = 1 td->di = 0 td->r = 0 00023571000 d [OHCI ] td->cbp = 0x0FA082F0 ret = 0 len = 1 td->cc = 15 td->ec = 0 ed->h = 0 00023571000 d [OHCI ] td->t = 2 ed->c = 0 00023571000 d [OHCI ] Head: 0x0FA08570 Tail: 0x0FA08300 Next: 0x0FA08300 00023571000 d [OHCI ] pid = OUT addr = 0 endpnt = 0 len = 1 mps = 8 (td->cbp = 0x0FA082F0, td->be = 0x0FA082F0) 00023571000 d [OHCI ] td->t = 2 ed->c = 0 td->di = 0 td->r = 0 00023571000 d [OHCI ] td->cbp = 0x0FA082F0 ret = -3 len = 1 td->cc = 4 td->ec = 3 ed->h = 1 00023571000 d [OHCI ] td->t = 2 ed->c = 0 00023574000 d [OHCI ] done_count = 0, status.wdh = 0 00023574000 d [OHCI ] Updating the hcca.DoneHead field to 0x0FA08570 and setting the wdh flag 00023577000 d [OHCI ] done_count = 7, status.wdh = 1 00023580000 d [OHCI ] done_count = 7, status.wdh = 1 00023583000 d [OHCI ] done_count = 7, status.wdh = 1 00023577000 d [OHCI ] done_count = 7, status.wdh = 0 The Bochs ohci controler seems to not reset when a SETUP TD is written to the ED. Since the stall is on a Control Pipe, and I am also resetting the port before enqueueing the next SETUP packet, I wonder why? |
Author: | BenLunt [ Wed Feb 01, 2023 7:18 pm ] |
Post subject: | Re: Bochs OCHI stalls and stops after I mess around with STA |
First, I am pleased that there are a few people working on their USB code. It is interesting to see the work, and of course the comments. Thanks. Now, for the answer. I didn't write any Stall handling code in the OHCI. I wasn't expecting anyone to intentionally cause a stall. :-) Anyway, I am currently working on the USB emulation in Bochs, so if you have a (smallish) bootable hard drive image that you can share, that intentionally creates the stall you show, I will see what I can do to add function to the OHCI code to handle the stall. Thank you, Ben |
Author: | sounds [ Thu Feb 02, 2023 1:54 pm ] |
Post subject: | Re: Bochs OHCI stalls and stops after I mess around with STA |
That'd probably be fine. I've sent a PM with some questions. |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |