. My processor is at long mode, but ehci x64 bit flag isn't set. Maybe I need somehow to connect x64 EHCI to qemu? But I didn't find any flags to do it. Is QEMU supports x64 EHCI?processing error - resetting ehci HC
Code: Select all
ehci_controller.caps = (struct EhciCaps*)((uintptr_t)bar0);
ehci_controller.regs = (struct EhciRegs*)((uintptr_t)bar0 + ehci_controller.caps->cap_length);
ehci_controller.ehci_base2 = (uint32_t)(bar0);
ehci_controller.ehci_base = (uint32_t)(uintptr_t)&ehci_controller.regs->usb_cmd;
ehci_controller.frame_list = (uint32_t *)((uintptr_t)frame_list - KERN_BASE_ADDR);
#ifdef EHCI_DEBUG
cprintf("frame_list: %p\n", ehci_controller.frame_list);
#endif // EHCI_DEBUG
/* Init queue and td pools */
ehci_controller.qh_pool = (struct EhciQueueHeader *)((uintptr_t)queues_pool - KERN_BASE_ADDR);
ehci_controller.td_pool = (struct EhciTransferDescriptor *)((uintptr_t)transfer_descriptors_pool - KERN_BASE_ADDR);
memset(ehci_controller.qh_pool, 0, sizeof (struct EhciQueueHeader) * EHCI_QH_MAX);
memset(ehci_controller.td_pool, 0, sizeof (struct EhciTransferDescriptor) * EHCI_TD_MAX);
#ifdef EHCI_DEBUG
cprintf("EHCI pools allocated\n");
#endif // EHCI_DEBUG
/* Make sure we reset the controller */
ehci_reset_controller();
/* Async queue setup */
struct EhciQueueHeader *async_qh = ehci_alloc_queue_header();
async_qh->qh_link_pointer = ((uint32_t)((uintptr_t)async_qh)) | PTR_QH;
async_qh->chars = QH_CHARS_HEAD;
async_qh->caps = 0;
async_qh->cur_link = 0;
async_qh->next_link = PTR_TERMINATE;
async_qh->alt_link = 0;
async_qh->token = 0;
for (uint32_t i = 0; i < QUEUE_BUFFERS_AMOUNT; ++i) {
async_qh->buffer[i] = 0;
}
async_qh->transfer = 0;
async_qh->queue_list.prev = &async_qh->queue_list;
async_qh->queue_list.next = &async_qh->queue_list;
ehci_controller.async_qh = async_qh;
/* Periodic table setup */
struct EhciQueueHeader *periodic_qh = ehci_alloc_queue_header();
periodic_qh->qh_link_pointer = PTR_TERMINATE;
periodic_qh->chars = 0;
periodic_qh->caps = 0;
periodic_qh->cur_link = 0;
periodic_qh->next_link = PTR_TERMINATE;
periodic_qh->alt_link = 0;
periodic_qh->token = 0;
for (uint32_t i = 0; i < QUEUE_BUFFERS_AMOUNT; ++i) {
periodic_qh->buffer[i] = 0;
}
periodic_qh->transfer = 0;
periodic_qh->queue_list.prev = &periodic_qh->queue_list;
periodic_qh->queue_list.next = &periodic_qh->queue_list;
ehci_controller.periodic_qh = periodic_qh;
for (uint32_t i = 0; i < FRAME_LIST_SIZE; i++) {
ehci_controller.frame_list[i] = PTR_QH | ((uint32_t)(uintptr_t)periodic_qh);
}
/* Check extended capabilities */
uint32_t eecp = (RCR(HCC_PARAMS) & HCCPARAMS_EECP_MASK) >> HCCPARAMS_EECP_SHIFT;
if (eecp >= 0x40) {
uint32_t legacy_support = pci_config_read_dword(info->bus, info->device, info->function, eecp + USBLEGSUP);
if (legacy_support & USBLEGSUP_HC_BIOS) {
#ifdef EHCI_DEBUG
cprintf("Disabling BIOS legacy support\n");
#endif
pci_config_write_dword(info->bus, info->device, info->function, eecp + USBLEGSUP, legacy_support | USBLEGSUP_HC_OS);
for (;;) {
legacy_support = pci_config_read_dword(info->bus, info->device, info->function, eecp + USBLEGSUP);
if (((legacy_support & USBLEGSUP_HC_BIOS) == 0) && (legacy_support & USBLEGSUP_HC_OS)) {
break;
}
}
}
}
/* Disable interrupts */
WOR(USB_INTR, 0);
/* Setup frame list */
WOR(FRAME_INDEX, 0);
WOR(PERIODIC_LIST_BASE, (uint32_t)(uintptr_t)ehci_controller.frame_list);
WOR(ASYNC_LIST_ADDR, (uint32_t)(uintptr_t)ehci_controller.async_qh);
WOR(CTRL_D_SEGMENT, 0);
/* Clear USB status, just set first bits to 1's to discard last changes */
WOR(USB_STS, ~0);
/* Enable controller */
/* (8 << CMD_ITC_SHIFT) - interrupt threshold control - 8 micro-frames */
WOR(USB_CMD, (8 << CMD_ITC_SHIFT) | CMD_ASE | CMD_PSE | CMD_RS);
/* Wait for halt */
while (ROR(USB_STS) & STS_HCHALTED);
#ifdef EHCI_DEBUG
cprintf("Ctrl d segment reg is 0x%x\n", ROR(CTRL_D_SEGMENT));
cprintf("Async list address is 0x%x\n", ROR(ASYNC_LIST_ADDR));
cprintf("Periodic list base if 0x%x\n", ROR(PERIODIC_LIST_BASE));
#endif
/* Sets that all devices should be managed by the EHCI */
WOR(CONFIG_FLAG, 1);
#ifdef EHCI_DEBUG
cprintf("EHCI setup done. Probing ports.\n");
#endif