So you are trying to enable the slot:
XHCI on Bochs is saying the command doorbell is rang and successfull.
00126191490d[XHCI ] Command Doorbell Rang
00126191490d[XHCI ] Dump command trb: 9(dec) (0x0000000000000000 0x00000000 0x00002400) (0)
00126191490d[XHCI ] 0x0000000000054000: Command Ring: Found Enable Slot TRB (slot = 1) (returning 1)
The command is returning a value of 1, which is expected. A completion code of 1.
This means that your command ring is most likely correct. However, since you are not receiving an event ring entry, you need to look at your event ring code and setup.
Your event ring register should point to a Segment Table, which in turn will point to one or more Ring Segments. These Segment Rings must be 64-byte aligned, must not be more than 64k in size, and must not cross a 64k boundary.
Does your Event Ring Base Address Register point to a Segment Table?
Code: Select all
// setting up "Event Ring Segment Table"
unsigned long rsb1 = 0x1000;
unsigned long rsb2 = 0x1008;
((unsigned long*)rsb1)[0] |= 0x41400; // pointer to event ring queue
((unsigned long*)rsb2)[0] |= 16; // size of ring segment (minimal length)
// setting up "Event Ring Segment Table Base Address Register (ERSTBA)"
unsigned long erstba_addr = rtsoff + 0x030;
((unsigned long*)erstba_addr)[0] |= 0x1000; // table at 0x1000 for now
Looks like it does. However, is your Segment Table actually at physical address 0x00001000? This seems a bit odd, but okay.
You should be writing the Dequeue Pointer Register with bit 3 set, clearing the bit. This should be done to clear the Busy bit. If the bit happens to be set (remembering that it is Write Clear), the Interrupter won't write an event.
Also, you should write the Interrupter Address register last, after all the other writes. The specification states that it must be written to last (of all the other Interrupter registers). This way when the hardware recognizes this write, it may read all the other registers and initialize its internal interrupter state. If you haven't written the other registers yet, this may cause some problems.
Make a few changes to your code so that you write the Interrupter Address register last, clear bit 3 of the Dequeue pointer register, and see what happens.
Ben
-
http://www.fysnet.net/the_universal_serial_bus.htm