EHCI Transactions(等时传输描述符)处理错误 EHCI HC Reset

EHCI Transactions (Isochronous transfer descriptor) processing error EHCI HC Reset

我正在为 EHCI 编写驱动程序,该驱动程序检测到 EHCI 控制器,将其重置(目前已禁用中断)并对其进行配置,没有任何问题,并且在真实硬件上运行良好。但是当我尝试创建一个空的 同步传输描述符 时。 Qemu 给我这个错误“处理错误 - 重置 ehci HC”。

我通过仔细阅读 Intel EHCI 规范 创建了驱动程序,但我被困在这里

到现在我有几个问题:

这是我的代码所做的一些事情:

KERNELSTATUS    EhcInitialize(PCI_CONFIGURATION_HEADER* PciConfiguration, EHCI_DEVICE* Ehci){
Ehci->EhciBase = PciGetBaseAddress(0);
OperationnalRegisters->UsbCommand.RunStop = 0; /*OperationnalRegisters will be named (OpRegs)*/
OpRegs->ConfigurationFlag = 0;
EhciResetController(Ehci);
if(CapabilityRegs->CapParams.ProgrammableFrameList) UsbCommand.FrameListSize = 0;

GetFrameListSize(Ehci); // Stores frame list size on the EHCI Device
if(x64AddressingCapability) Ehci->QwordBitWidth = 1;

// EhciAllocateMemory checks for the 64 bit capability, if not then KeExtendedAlloc With MaxAddress = (UINT32)-1;
// My kernel provides this option

Ehci->AssignedMemory = EhciAllocateMemory(EHCI_INTIAL_MEMORY_SIZE(Ehci), /*Alignement Field*/ 0x1000)
Ehci->High32Bits = AssignedMemory >> 32;
if(Ehci->QwordBitWidth) OpRegs->ControlDataSegment = Ehci->High32Bits;

// Sets base address for all the entries on the periodic frame list, and sets their Terminate Bit (T-Bit) to 1
EhciSetupPeriodicFrameList(Ehci)
}

UsbCommand->InterruptTresholdControl = 8
UsbCommand->PeriodicScheduleEnable = 1
OpRegs->ConfigurationFlag = 1
UsbCommand->RunStop = 1

// Ehci Setup Ports: Ehci->NumPorts = CapRegs->StructuralParams.NumPorts
// for i = 0,i<NumPorts,i++
// PortStatusControl[i].PortOwner = 1
// PortStatusControl[i].PortEnabled = 0
// PortStatusControl[i].PortPower = 1
EhciSetupPorts(Ehci)

for(UINT i = 0;i<Ehci->NumPorts;i++){
    // Ehci Enable Port: Reset Port, then enables it
    // if(!Port->CurrentConnectStatus) return FALSE; // Port cannot be enabled until its connected
    // Port->PortEnable = 0
    // Port->PortReset = 1
    // while(Port->PortReset) Port->PortReset = 0 // wait until port reset is read as 0
    // if(!Port->PortEnabled) return FALSE;

    // switch Port->LineStatus, case FULL_SPEED, HIGH_SPEED, LOW_SPEED ....
    EhciEnablePort(Ehci, i);

}

到目前为止一切正常。

// processing error resetting EHCI HC
   EhciCreateIsochronousTransferDescriptor(Ehci);

这里是创建ITD的代码

DWORD PeriodicListPointerIndex = EhciAllocatePeriodicListPointer(Ehci);
if(PeriodicListPointerIndex == (DWORD)-1) return FALSE;

EHCI_ISOCHRONOUS_TRANSFER_DESCRIPTOR* Itd = (EHCI_ISOCHRONOUS_TRANSFER_DESCRIPTOR*)(((UINT64)Ehci->High32Bits << 32) | ((UINT64)Ehci->PeriodicPointerList[PeriodicListPointerIndex].FrameListLinkPointer << 12));
Itd->Direction = 0;
Itd->Multi = 1;
Itd->DeviceAddress = 0;
Itd->EndPointNumber = 0;
Itd->NextLinkPointer.Terminate = 1;

Ehci->PeriodicPointerList[PeriodicListPointerIndex].Type = EHCI_TYPE_ITD;

// Here Crashes
Ehci->PeriodicPointerList[PeriodicListPointerIndex].Terminate = 0;

我现在找到了,我对 4K 字节对齐感到震惊,所以在 EhciSetupPeriodicFrameList() 上,我 bit-shifting 指针增加了 12(使 4K 字节对齐)而不仅仅是 5(因为它是 32 字节对齐的)。在我开始尝试异步列表之前,我并没有预料到这一点,因为它会让我知道使用控制传输的 USB 控制器上有哪些设备。