Selaa lähdekoodia

完成xhci端口初始化

fslongjin 2 vuotta sitten
vanhempi
commit
49bbba17ec
3 muutettua tiedostoa jossa 20 lisäystä ja 12 poistoa
  1. 2 2
      kernel/driver/pci/pci.c
  2. 13 9
      kernel/driver/usb/xhci/xhci.c
  3. 5 1
      run.sh

+ 2 - 2
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)

+ 13 - 9
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)
     {

+ 5 - 1
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    \