xhci.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include "xhci.h"
  2. #include <common/kprint.h>
  3. #include <debug/bug.h>
  4. #include <process/spinlock.h>
  5. #include <mm/mm.h>
  6. #include <debug/traceback/traceback.h>
  7. #include <common/time.h>
  8. spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁(在usb_init中被初始化)
  9. static int xhci_ctrl_count = 0; // xhci控制器计数
  10. static struct xhci_host_controller_t xhci_hc[MAX_XHCI_HOST_CONTROLLERS] = {0};
  11. #define xhci_read_cap_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase + offset))
  12. #define xhci_write_cap_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase + offset) = (uint8_t)value)
  13. #define xhci_read_cap_reg32(id, offset) (*(uint32_t *)(xhci_hc[id].vbase + offset))
  14. #define xhci_write_cap_reg32(id, offset, value) (*(uint32_t *)(xhci_hc[id].vbase + offset) = (uint32_t)value)
  15. #define xhci_read_cap_reg64(id, offset) (*(uint64_t *)(xhci_hc[id].vbase + offset))
  16. #define xhci_write_cap_reg64(id, offset, value) (*(uint64_t *)(xhci_hc[id].vbase + offset) = (uint64_t)value)
  17. #define xhci_read_op_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase_op + offset))
  18. #define xhci_write_op_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase_op + offset) = (uint8_t)value)
  19. #define xhci_read_op_reg32(id, offset) (*(uint32_t *)(xhci_hc[id].vbase_op + offset))
  20. #define xhci_write_op_reg32(id, offset, value) (*(uint32_t *)(xhci_hc[id].vbase_op + offset) = (uint32_t)value)
  21. #define xhci_read_op_reg64(id, offset) (*(uint64_t *)(xhci_hc[id].vbase_op + offset))
  22. #define xhci_write_op_reg64(id, offset, value) (*(uint64_t *)(xhci_hc[id].vbase_op + offset) = (uint64_t)value)
  23. /**
  24. * @brief 停止xhci主机控制器
  25. *
  26. * @param id 主机控制器id
  27. * @return int
  28. */
  29. static int xhci_hc_stop(int id)
  30. {
  31. // todo: 停止usb控制器
  32. }
  33. /**
  34. * @brief reset xHCI主机控制器
  35. *
  36. * @param id 主机控制器id
  37. * @return int
  38. */
  39. static int xhci_hc_reset(int id)
  40. {
  41. int retval = 0;
  42. // 判断HCHalted是否置位
  43. if ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
  44. {
  45. // 未置位,需要先尝试停止usb主机控制器
  46. retval = xhci_hc_stop(id);
  47. if (retval)
  48. return retval;
  49. }
  50. int timeout = 500; // wait 500ms
  51. // reset
  52. xhci_write_cap_reg32(id, XHCI_OPS_USBCMD, (1 << 1));
  53. usleep(1000);
  54. while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1))
  55. {
  56. usleep(1000);
  57. if (--timeout == 0)
  58. return -ETIMEDOUT;
  59. }
  60. kdebug("reset done!, timeout=%d", timeout);
  61. return retval;
  62. }
  63. /**
  64. * @brief 初始化xhci控制器
  65. *
  66. * @param header 指定控制器的pci device头部
  67. */
  68. void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
  69. {
  70. spin_lock(&xhci_controller_init_lock);
  71. kinfo("Initializing xhci host controller: bus=%#02x, device=%#02x, func=%#02x, VendorID=%#04x, irq_line=%d, irq_pin=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, dev_hdr->header.Vendor_ID, dev_hdr->Interrupt_Line, dev_hdr->Interrupt_PIN);
  72. xhci_hc[xhci_ctrl_count].controller_id = xhci_ctrl_count;
  73. xhci_hc[xhci_ctrl_count].pci_dev_hdr = dev_hdr;
  74. pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4, 0x0006); // mem I/O access enable and bus master enable
  75. // 为当前控制器映射寄存器地址空间
  76. xhci_hc[xhci_ctrl_count].vbase = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + PAGE_2M_SIZE * xhci_hc[xhci_ctrl_count].controller_id;
  77. kdebug("dev_hdr->BAR0 & (~0xf)=%#018lx", dev_hdr->BAR0 & (~0xf));
  78. mm_map_phys_addr(xhci_hc[xhci_ctrl_count].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true);
  79. // 读取xhci控制寄存器
  80. uint16_t iversion = *(uint16_t *)(xhci_hc[xhci_ctrl_count].vbase + XHCI_CAPS_HCIVERSION);
  81. // 计算operational registers的地址
  82. xhci_hc[xhci_ctrl_count].vbase_op = xhci_hc[xhci_ctrl_count].vbase + xhci_read_cap_reg8(xhci_ctrl_count, XHCI_CAPS_CAPLENGTH);
  83. if (iversion < 0x95)
  84. {
  85. kwarn("Unsupported/Unknowned xHCI controller version: %#06x. This may cause unexpected behavior.", iversion);
  86. }
  87. // if it is a Panther Point device, make sure sockets are xHCI controlled.
  88. if (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) & 0xffff) == 0x8086) &&
  89. ((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 2) & 0xffff) == 0x1E31) &&
  90. ((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 8) & 0xff) == 4))
  91. {
  92. kdebug("Is a Panther Point device");
  93. pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd8, 0xffffffff);
  94. pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd0, 0xffffffff);
  95. }
  96. xhci_hc_reset(xhci_ctrl_count);
  97. ++xhci_ctrl_count;
  98. spin_unlock(&xhci_controller_init_lock);
  99. return;
  100. failed:;
  101. // 取消地址映射
  102. mm_unmap(xhci_hc[xhci_ctrl_count].vbase, 65536);
  103. // 清空数组
  104. memset((void *)&xhci_hc[xhci_ctrl_count], 0, sizeof(struct xhci_host_controller_t));
  105. spin_unlock(&xhci_controller_init_lock);
  106. }