commit fa9230d5d6d42b6140253eb097a7963a1fc89e93
parent 342a21e17ee7c78454f593cda204808267787a6c
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 23 Apr 2024 08:27:58 +0900
reset xhc
Diffstat:
M | sys/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;
}
}