diff --git a/kernel/driver/pci/pci.c b/kernel/driver/pci/pci.c index 479f7b32..f8822723 100644 --- a/kernel/driver/pci/pci.c +++ b/kernel/driver/pci/pci.c @@ -501,11 +501,11 @@ int pci_enable_msi(void *header, uint8_t vector, uint32_t processor, uint8_t edg { case 0x00: // general device if (!(ptr->Status & 0x10)) - return E_NOT_SUPPORT_MSI; + return E_NOT_SUPPORT_MSI; + cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer; tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值 - message_control = (tmp >> 16) & 0xffff; if (tmp & 0xff != 0x5) diff --git a/kernel/driver/usb/xhci/xhci.c b/kernel/driver/usb/xhci/xhci.c index 255478db..87d5ff9f 100644 --- a/kernel/driver/usb/xhci/xhci.c +++ b/kernel/driver/usb/xhci/xhci.c @@ -557,8 +557,9 @@ uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg) return -EINVAL; struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg; - - pci_enable_msi(xhci_hc[cid].pci_dev_hdr, irq_num, info->processor, info->edge_trigger, info->assert); + // todo: QEMU是使用msix的,因此要先在pci中实现msix + int retval = pci_enable_msi(xhci_hc[cid].pci_dev_hdr, irq_num, info->processor, info->edge_trigger, info->assert); + kdebug("pci retval = %d", retval); kdebug("xhci irq %d installed.", irq_num); return 0; } @@ -596,7 +597,7 @@ static int xhci_reset_port(const int id, const int port) int retval = 0; // 相对于op寄存器基地址的偏移量 uint64_t port_status_offset = XHCI_OPS_PRS + port * 16; - kdebug("to reset %d, offset=%#018lx", port, port_status_offset); + // kdebug("to reset %d, offset=%#018lx", port, port_status_offset); // 检查端口电源状态 if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0) { @@ -610,7 +611,7 @@ static int xhci_reset_port(const int id, const int port) return -EAGAIN; } } - kdebug("port:%d, power check ok", port); + // kdebug("port:%d, power check ok", port); // 确保端口的status被清0 xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS); @@ -622,20 +623,23 @@ static int xhci_reset_port(const int id, const int port) xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 4)); retval = -ETIMEDOUT; - kdebug("val = %#010lx", xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC)); + // 等待portsc的port reset change位被置位,说明reset完成 int timeout = 200; while (timeout) { uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC); - // if (timeout % 100) - // kdebug("val = %#010lx", val); - if (val & (1 << 21)) + if (XHCI_PORT_IS_USB3(id, port) && (val & (1 << 31)) == 0) break; + else if (XHCI_PORT_IS_USB2(id, port) && (val & (1 << 4)) == 0) + break; + else if (val & (1 << 21)) + break; + --timeout; usleep(500); } - kdebug("timeout= %d", timeout); + // kdebug("timeout= %d", timeout); if (timeout > 0) { diff --git a/run.sh b/run.sh index 193dd056..5b74ed8e 100644 --- a/run.sh +++ b/run.sh @@ -101,13 +101,17 @@ bash u* cd .. allflags=$(qemu-system-x86_64 -cpu help | awk '/flags/ {y=1; getline}; y {print}' | tr ' ' '\n' | grep -Ev "^$" | sed -r 's|^|+|' | tr '\n' ',' | sed -r "s|,$||") +# 调试usb的trace +qemu_trace_usb=trace:usb_xhci_reset,trace:usb_xhci_run,trace:usb_xhci_stop,trace:usb_xhci_irq_msi,trace:usb_xhci_irq_msix,trace:usb_xhci_port_reset + if [ $flag_can_run -eq 1 ]; then if [ ${IA32_USE_QEMU} == 0 ]; then bochs -q -f ${bochsrc} -rc ./tools/bochsinit else qemu-system-x86_64 -cdrom ${iso} -m 512M -smp 2,cores=2,threads=1,sockets=1 \ -boot order=d \ - -monitor stdio -d cpu_reset,guest_errors,trace:check_exception,exec,cpu,out_asm,in_asm -s -S -cpu "IvyBridge,+apic,+x2apic,+fpu,check,${allflags}" --enable-kvm -rtc clock=host,base=localtime -serial file:serial_opt.txt \ + -monitor stdio -d cpu_reset,guest_errors,trace:check_exception,exec,cpu,out_asm,in_asm,${qemu_trace_usb} \ + -s -S -cpu "IvyBridge,+apic,+x2apic,+fpu,check,${allflags}" --enable-kvm -rtc clock=host,base=localtime -serial file:serial_opt.txt \ -drive id=disk,file=bin/disk.img,if=none \ -device ahci,id=ahci \ -device ide-hd,drive=disk,bus=ahci.0 \