EHCI Transactions(等时传输描述符)处理错误 EHCI HC Reset
EHCI Transactions (Isochronous transfer descriptor) processing error EHCI HC Reset
我正在为 EHCI 编写驱动程序,该驱动程序检测到 EHCI 控制器,将其重置(目前已禁用中断)并对其进行配置,没有任何问题,并且在真实硬件上运行良好。但是当我尝试创建一个空的 同步传输描述符 时。 Qemu 给我这个错误“处理错误 - 重置 ehci HC”。
我通过仔细阅读 Intel EHCI 规范 创建了驱动程序,但我被困在这里
到现在我有几个问题:
- 如何设置同步传输描述符
- 如何检测连接到 USB 端口的设备
- 如何使用端点(端点是否有限制,据我所知,端点就像 window 连接设备或访问端口)
- 在真实硬件上配置 EHC 后(与 QEMU 不同,它具有 64 位功能),鼠标和键盘电源关闭(这可能是正常的)
这是我的代码所做的一些事情:
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 控制器上有哪些设备。
我正在为 EHCI 编写驱动程序,该驱动程序检测到 EHCI 控制器,将其重置(目前已禁用中断)并对其进行配置,没有任何问题,并且在真实硬件上运行良好。但是当我尝试创建一个空的 同步传输描述符 时。 Qemu 给我这个错误“处理错误 - 重置 ehci HC”。
我通过仔细阅读 Intel EHCI 规范 创建了驱动程序,但我被困在这里
到现在我有几个问题:
- 如何设置同步传输描述符
- 如何检测连接到 USB 端口的设备
- 如何使用端点(端点是否有限制,据我所知,端点就像 window 连接设备或访问端口)
- 在真实硬件上配置 EHC 后(与 QEMU 不同,它具有 64 位功能),鼠标和键盘电源关闭(这可能是正常的)
这是我的代码所做的一些事情:
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 控制器上有哪些设备。