setos

拙OS
Log | Files | Refs | LICENSE

commit fa9230d5d6d42b6140253eb097a7963a1fc89e93
parent 342a21e17ee7c78454f593cda204808267787a6c
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 23 Apr 2024 08:27:58 +0900

reset xhc

Diffstat:
Msys/src/kernel/main.c | 95++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 51 insertions(+), 44 deletions(-)

diff --git a/sys/src/kernel/main.c b/sys/src/kernel/main.c @@ -48,58 +48,65 @@ kernel_main(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) draw_mouse(&root_window, &m); pci_scan_all_bus(); - cons_printf(&con0, "sizeof(PCIDev) = %d\n", sizeof(PCIDev)); cons_printf(&con0, "pci devices:\n"); + PCIDev *pci_xhc = NULL; for (int i = 0; i < num_pci_dev; i++) { cons_printf(&con0, "%d:\t%x\t%x\t%x\t%x\t%x\n", i, pci_dev[i].vendor_id, pci_dev[i].device_id, pci_dev[i].base_class, pci_dev[i].sub_class, pci_dev[i].prog); - } - cons_printf(&con0, "local apic id: %x\n", *(uint32 *) (0xfee00020) >> 24); - cons_printf(&con0, "xhci devices:\n"); - for (int i = 0; i < num_pci_dev; i++) { if (pci_dev[i].base_class == 0xc && pci_dev[i].sub_class == 0x3 && pci_dev[i].prog == 0x30) { - uintptr pci_config_base = (uintptr) &pci_dev[i]; - PCICap *cap = (PCICap *) (pci_config_base + pci_dev[i].capabilities_pointer); - for (;; cap = (PCICap *) (pci_config_base + cap->next_pointer)) { - switch (cap->capability_id) { - case 0x5: - ((MSICap *)cap)->message_control = - ((MSICap *)cap)->message_control | 1; - cons_printf(&con0, "MSI: %x\n", ((MSICap *)cap)->message_control); - break; - case 0x11: - ((MSIXCap *)cap)->message_control = - ((MSIXCap *)cap)->message_control | 1 << 15; - cons_printf(&con0, "MSI-X: %x\n", ((MSIXCap *)cap)->message_control); - break; - default: - cons_printf(&con0, "unsupported capability: 0x%x\n", - cap->capability_id); - break; - } - if (cap->next_pointer == 0) { - break; - } - } - // TODO: find the following calculation in some specification. - // only article found is osdev's page: - // osdev.org/PCI#Address_and_size_of_the_BAR - uintptr xhc_base = ((uintptr) pci_dev[i].t0.base_address_register[1]) << 32 | (pci_dev[i].t0.base_address_register[0]&0xfffffff0); - cons_printf(&con0, "xhc_base: %x\n", xhc_base); - xhc_capability_registers *xhccr = (xhc_capability_registers *) xhc_base; - xhc_operational_registers *xhcor = (xhc_operational_registers *) (xhc_base + xhccr->CAPLENGTH); - xhc_runtime_registers *xhcrr = (xhc_runtime_registers *) (xhc_base + xhccr->RTSOFF); - xhc_doorbell_registers *xhcdr = (xhc_doorbell_registers *) (xhc_base + xhccr->DBOFF); - cons_printf(&con0, "CAPLENGTH: %x\n", xhccr->CAPLENGTH); - cons_printf(&con0, "HCIVERSION: %x\n", xhccr->HCIVERSION); - cons_printf(&con0, "HCSPARAMS1: %x\n", xhccr->HCSPARAMS1); - cons_printf(&con0, "HCCPARAMS1: %x\n", xhccr->HCCPARAMS1); - cons_printf(&con0, "USBCMD: %x\n", xhcor->USBCMD); - cons_printf(&con0, "USBSTS: %x\n", xhcor->USBSTS); - cons_printf(&con0, "FLADJ: %x\n", pci_dev[i].reg[0x21]); + pci_xhc = &pci_dev[i]; + } + } + if (pci_xhc == NULL) { + cons_printf(&con0, "xhci device not found.\n"); + goto halt; + } + + // populate Xhc struct. + // TODO: find the following calculation in some specification. + // only article found is osdev's page: + // osdev.org/PCI#Address_and_size_of_the_BAR + xhc.base = ((uintptr) pci_xhc->t0.base_address_register[1]) << 32 | + (pci_xhc->t0.base_address_register[0]&0xfffffff0); + xhc.cap = (xhc_capability_registers *) xhc.base; + xhc.op = (xhc_operational_registers *) (xhc.base + xhc.cap->CAPLENGTH); + xhc.runtime = (xhc_runtime_registers *) (xhc.base + xhc.cap->RTSOFF); + xhc.doorbell = (xhc_doorbell_registers *) (xhc.base + xhc.cap->DBOFF); + + // reset xhc. + if ((xhc.op->USBSTS & 0x1) != 1) { // USBSTS.HCH + cons_printf(&con0, "USBSTS.HCH != 1\n"); + goto halt; + } + xhc.op->USBCMD |= 1 << 1; // USBCMD.HCRST + for (;(xhc.op->USBCMD&(1<<1)) != 0;) { + } + cons_printf(&con0, "usb reset done\n"); + for (;(xhc.op->USBSTS&(1<<11)) != 0;) { // USBSTS.CNR + } + cons_printf(&con0, "usb controller ready\n"); + + cons_printf(&con0, "local apic id: %x\n", *(uint32 *) (0xfee00020) >> 24); + uintptr pci_config_base = (uintptr) pci_xhc; + PCICap *cap = (PCICap *) (pci_config_base + pci_xhc->capabilities_pointer); + for (;; cap = (PCICap *) (pci_config_base + cap->next_pointer)) { + switch (cap->capability_id) { + case 0x5: + cons_printf(&con0, "MSI: %x\n", ((MSICap *)cap)->message_control); + break; + case 0x11: + cons_printf(&con0, "MSI-X: %x\n", ((MSIXCap *)cap)->message_control); + break; + default: + cons_printf(&con0, "unsupported capability: 0x%x\n", + cap->capability_id); + break; + } + if (cap->next_pointer == 0) { + break; } }