xhci.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  1. #include "xhci.h"
  2. #include <common/kprint.h>
  3. #include <debug/bug.h>
  4. #include <common/spinlock.h>
  5. #include <mm/mm.h>
  6. #include <mm/slab.h>
  7. #include <debug/traceback/traceback.h>
  8. #include <common/time.h>
  9. #include <exception/irq.h>
  10. #include <driver/interrupt/apic/apic.h>
  11. // 由于xhci寄存器读取需要对齐,因此禁用GCC优化选项
  12. #pragma GCC optimize("O0")
  13. spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化)
  14. static int xhci_ctrl_count = 0; // xhci控制器计数
  15. static struct xhci_host_controller_t xhci_hc[XHCI_MAX_HOST_CONTROLLERS] = {0};
  16. void xhci_hc_irq_enable(uint64_t irq_num);
  17. void xhci_hc_irq_disable(uint64_t irq_num);
  18. uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg);
  19. void xhci_hc_irq_uninstall(uint64_t irq_num);
  20. static int xhci_hc_find_available_id();
  21. static int xhci_hc_stop(int id);
  22. static int xhci_hc_reset(int id);
  23. static int xhci_hc_stop_legacy(int id);
  24. static int xhci_hc_start_sched(int id);
  25. static int xhci_hc_stop_sched(int id);
  26. static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset, uint32_t *count, uint16_t *protocol_flag);
  27. static int xhci_hc_pair_ports(int id);
  28. static uint64_t xhci_create_ring(int trbs);
  29. static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr);
  30. void xhci_hc_irq_handler(uint64_t irq_num, uint64_t cid, struct pt_regs *regs);
  31. static int xhci_hc_init_intr(int id);
  32. static int xhci_hc_start_ports(int id);
  33. static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring);
  34. hardware_intr_controller xhci_hc_intr_controller =
  35. {
  36. .enable = xhci_hc_irq_enable,
  37. .disable = xhci_hc_irq_disable,
  38. .install = xhci_hc_irq_install,
  39. .uninstall = xhci_hc_irq_uninstall,
  40. .ack = apic_local_apic_edge_ack,
  41. };
  42. /*
  43. 注意!!!
  44. 尽管采用MMI/O的方式访问寄存器,但是对于指定大小的寄存器,
  45. 在发起读请求的时候,只能从寄存器的起始地址位置开始读取。
  46. 例子:不能在一个32bit的寄存器中的偏移量8的位置开始读取1个字节
  47. 这种情况下,我们必须从32bit的寄存器的0地址处开始读取32bit,然后通过移位的方式得到其中的字节。
  48. */
  49. #define xhci_read_cap_reg32(id, offset) (*(uint32_t *)(xhci_hc[id].vbase + offset))
  50. #define xhci_get_ptr_cap_reg32(id, offset) ((uint32_t *)(xhci_hc[id].vbase + offset))
  51. #define xhci_write_cap_reg32(id, offset, value) (*(uint32_t *)(xhci_hc[id].vbase + offset) = (uint32_t)value)
  52. #define xhci_read_cap_reg64(id, offset) (*(uint64_t *)(xhci_hc[id].vbase + offset))
  53. #define xhci_get_ptr_reg64(id, offset) ((uint64_t *)(xhci_hc[id].vbase + offset))
  54. #define xhci_write_cap_reg64(id, offset, value) (*(uint64_t *)(xhci_hc[id].vbase + offset) = (uint64_t)value)
  55. #define xhci_read_op_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase_op + offset))
  56. #define xhci_get_ptr_op_reg8(id, offset) ((uint8_t *)(xhci_hc[id].vbase_op + offset))
  57. #define xhci_write_op_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase_op + offset) = (uint8_t)value)
  58. #define xhci_read_op_reg32(id, offset) (*(uint32_t *)(xhci_hc[id].vbase_op + offset))
  59. #define xhci_get_ptr_op_reg32(id, offset) ((uint32_t *)(xhci_hc[id].vbase_op + offset))
  60. #define xhci_write_op_reg32(id, offset, value) (*(uint32_t *)(xhci_hc[id].vbase_op + offset) = (uint32_t)value)
  61. #define xhci_read_op_reg64(id, offset) (*(uint64_t *)(xhci_hc[id].vbase_op + offset))
  62. #define xhci_get_ptr_op_reg64(id, offset) ((uint64_t *)(xhci_hc[id].vbase_op + offset))
  63. #define xhci_write_op_reg64(id, offset, value) (*(uint64_t *)(xhci_hc[id].vbase_op + offset) = (uint64_t)value)
  64. #define xhci_write_mem32(vaddr, value) (*(uint32_t *)(vaddr) = value)
  65. #define xhci_write_mem64(vaddr, value) (*(uint64_t *)(vaddr) = value)
  66. #define xhci_read_mem32(vaddr) (*(uint32_t *)(vaddr))
  67. #define xhci_read_mem64(vaddr) (*(uint64_t *)(vaddr))
  68. // 读取xhci中断寄存器组的值
  69. #define xhci_read_intr_reg32(id, set_id, offset) (*(uint32_t *)(xhci_hc[id].vbase + xhci_hc[id].rts_offset + 0x20 * (set_id + 1) + offset))
  70. // 向xhci中断寄存器组写入值
  71. #define xhci_write_intr_reg32(id, set_id, offset, value) (*(uint32_t *)(xhci_hc[id].vbase + xhci_hc[id].rts_offset + 0x20 * (set_id + 1) + offset) = value)
  72. /**
  73. * @brief 计算中断寄存器组虚拟地址
  74. * @param id 主机控制器id
  75. * @param num xhci中断寄存器组号
  76. */
  77. #define xhci_calc_intr_vaddr(id, num) (xhci_hc[id].vbase + xhci_hc[id].rts_offset + XHCI_RT_IR0 + num * XHCI_IR_SIZE)
  78. /**
  79. * @brief 读取/写入中断寄存器
  80. * @param id 主机控制器id
  81. * @param num xhci中断寄存器组号
  82. * @param intr_offset 寄存器在当前寄存器组中的偏移量
  83. */
  84. #define xhci_read_intr_reg32(id, num, intr_offset) (*(uint32_t *)(xhci_calc_intr_vaddr(id, num) + intr_offset))
  85. #define xhci_write_intr_reg32(id, num, intr_offset, value) (*(uint32_t *)(xhci_calc_intr_vaddr(id, num) + intr_offset) = value)
  86. #define xhci_read_intr_reg64(id, num, intr_offset) (*(uint64_t *)(xhci_calc_intr_vaddr(id, num) + intr_offset))
  87. #define xhci_write_intr_reg64(id, num, intr_offset, value) (*(uint64_t *)(xhci_calc_intr_vaddr(id, num) + intr_offset) = value)
  88. #define xhci_is_aligned64(addr) ((addr & 0x3f) == 0) // 是否64bytes对齐
  89. /**
  90. * @brief 判断端口信息
  91. * @param cid 主机控制器id
  92. * @param pid 端口id
  93. */
  94. #define XHCI_PORT_IS_USB2(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_INFO) == XHCI_PROTOCOL_USB2)
  95. #define XHCI_PORT_IS_USB3(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_INFO) == XHCI_PROTOCOL_USB3)
  96. #define XHCI_PORT_IS_USB2_HSO(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_HSO) == XHCI_PROTOCOL_HSO)
  97. #define XHCI_PORT_HAS_PAIR(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_HAS_PAIR) == XHCI_PROTOCOL_HAS_PAIR)
  98. #define XHCI_PORT_IS_ACTIVE(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_ACTIVE) == XHCI_PROTOCOL_ACTIVE)
  99. /**
  100. * @brief 设置link TRB的命令(dword3)
  101. *
  102. */
  103. #define xhci_TRB_set_link_cmd(trb_vaddr) \
  104. do \
  105. { \
  106. struct xhci_TRB_normal_t *ptr = (struct xhci_TRB_normal_t *)(trb_vaddr); \
  107. ptr->TRB_type = TRB_TYPE_LINK; \
  108. ptr->ioc = 0; \
  109. ptr->chain = 0; \
  110. ptr->ent = 0; \
  111. ptr->cycle = 1; \
  112. } while (0)
  113. /**
  114. * @brief 在controller数组之中寻找可用插槽
  115. *
  116. * 注意:该函数只能被获得init锁的进程所调用
  117. * @return int 可用id(无空位时返回-1)
  118. */
  119. static int xhci_hc_find_available_id()
  120. {
  121. if (unlikely(xhci_ctrl_count >= XHCI_MAX_HOST_CONTROLLERS))
  122. return -1;
  123. for (int i = 0; i < XHCI_MAX_HOST_CONTROLLERS; ++i)
  124. {
  125. if (xhci_hc[i].pci_dev_hdr == NULL)
  126. return i;
  127. }
  128. return -1;
  129. }
  130. /**
  131. * @brief 从指定地址读取trb
  132. *
  133. * @param trb 要存储到的trb的地址
  134. * @param address 待读取trb的地址
  135. */
  136. static __always_inline void xhci_get_trb(struct xhci_TRB_t *trb, const uint32_t address)
  137. {
  138. trb->param = xhci_read_mem64(address);
  139. trb->status = xhci_read_mem32(address + 8);
  140. trb->command = xhci_read_mem32(address + 12);
  141. }
  142. /**
  143. * @brief 将给定的trb写入指定的地址
  144. *
  145. * @param trb 源trb
  146. * @param address 拷贝的目标地址
  147. */
  148. static __always_inline void xhci_set_trb(struct xhci_TRB_t *trb, const uint32_t address)
  149. {
  150. xhci_write_mem64(address, trb->param);
  151. xhci_write_mem32(address + 8, trb->status);
  152. xhci_write_mem32(address + 12, trb->command);
  153. }
  154. /**
  155. * @brief 停止xhci主机控制器
  156. *
  157. * @param id 主机控制器id
  158. * @return int
  159. */
  160. static int xhci_hc_stop(int id)
  161. {
  162. // 判断是否已经停止
  163. if (unlikely((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 1))
  164. return 0;
  165. io_mfence();
  166. xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00000000);
  167. io_mfence();
  168. char timeout = 17;
  169. while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
  170. {
  171. io_mfence();
  172. usleep(1000);
  173. if (--timeout == 0)
  174. return -ETIMEDOUT;
  175. }
  176. return 0;
  177. }
  178. /**
  179. * @brief reset xHCI主机控制器
  180. *
  181. * @param id 主机控制器id
  182. * @return int
  183. */
  184. static int xhci_hc_reset(int id)
  185. {
  186. int retval = 0;
  187. kdebug("usbsts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS));
  188. io_mfence();
  189. // 判断HCHalted是否置位
  190. if ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
  191. {
  192. io_mfence();
  193. kdebug("stopping usb hc...");
  194. // 未置位,需要先尝试停止usb主机控制器
  195. retval = xhci_hc_stop(id);
  196. if (unlikely(retval))
  197. return retval;
  198. }
  199. int timeout = 500; // wait 500ms
  200. // reset
  201. uint32_t cmd = xhci_read_op_reg32(id, XHCI_OPS_USBCMD);
  202. io_mfence();
  203. kdebug("cmd=%#010lx", cmd);
  204. cmd |= (1 << 1);
  205. xhci_write_op_reg32(id, XHCI_OPS_USBCMD, cmd);
  206. io_mfence();
  207. kdebug("after rst, sts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS));
  208. io_mfence();
  209. while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1))
  210. {
  211. io_mfence();
  212. usleep(1000);
  213. if (--timeout == 0)
  214. return -ETIMEDOUT;
  215. }
  216. // kdebug("reset done!, timeout=%d", timeout);
  217. return retval;
  218. }
  219. /**
  220. * @brief 停止指定xhci控制器的legacy support
  221. *
  222. * @param id 控制器id
  223. * @return int
  224. */
  225. static int xhci_hc_stop_legacy(int id)
  226. {
  227. uint64_t current_offset = xhci_hc[id].ext_caps_off;
  228. do
  229. {
  230. // 判断当前entry是否为legacy support entry
  231. if ((xhci_read_cap_reg32(id, current_offset) & 0xff) == XHCI_XECP_ID_LEGACY)
  232. {
  233. io_mfence();
  234. // 接管控制权
  235. xhci_write_cap_reg32(id, current_offset, xhci_read_cap_reg32(id, current_offset) | XHCI_XECP_LEGACY_OS_OWNED);
  236. io_mfence();
  237. // 等待响应完成
  238. int timeout = XHCI_XECP_LEGACY_TIMEOUT;
  239. while ((xhci_read_cap_reg32(id, current_offset) & XHCI_XECP_LEGACY_OWNING_MASK) != XHCI_XECP_LEGACY_OS_OWNED)
  240. {
  241. io_mfence();
  242. usleep(1000);
  243. if (--timeout == 0)
  244. {
  245. kerror("The BIOS doesn't stop legacy support.");
  246. return -ETIMEDOUT;
  247. }
  248. }
  249. // 处理完成
  250. return 0;
  251. }
  252. io_mfence();
  253. // 读取下一个entry的偏移增加量
  254. int next_off = ((xhci_read_cap_reg32(id, current_offset) & 0xff00) >> 8) << 2;
  255. io_mfence();
  256. // 将指针跳转到下一个entry
  257. current_offset = next_off ? (current_offset + next_off) : 0;
  258. } while (current_offset);
  259. // 当前controller不存在legacy支持,也问题不大,不影响
  260. return 0;
  261. }
  262. /**
  263. * @brief 启用指定xhci控制器的调度
  264. *
  265. * @param id 控制器id
  266. * @return int
  267. */
  268. static int xhci_hc_start_sched(int id)
  269. {
  270. io_mfence();
  271. xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 0) | (1 << 2) | (1 << 3));
  272. io_mfence();
  273. usleep(100 * 1000);
  274. }
  275. /**
  276. * @brief 停止指定xhci控制器的调度
  277. *
  278. * @param id 控制器id
  279. * @return int
  280. */
  281. static int xhci_hc_stop_sched(int id)
  282. {
  283. io_mfence();
  284. xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00);
  285. io_mfence();
  286. }
  287. /**
  288. * @brief 在Ex capability list中寻找符合指定的协议号的寄存器offset、count、flag信息
  289. *
  290. * @param id 主机控制器id
  291. * @param list_off 列表项位置距离控制器虚拟基地址的偏移量
  292. * @param version 要寻找的端口版本号(2或3)
  293. * @param offset 返回的 Compatible Port Offset
  294. * @param count 返回的 Compatible Port Count
  295. * @param protocol_flag 返回的与协议相关的flag
  296. * @return uint32_t 下一个列表项的偏移量
  297. */
  298. static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset, uint32_t *count, uint16_t *protocol_flag)
  299. {
  300. if (count)
  301. *count = 0;
  302. do
  303. {
  304. uint32_t dw0 = xhci_read_cap_reg32(id, list_off);
  305. io_mfence();
  306. uint32_t next_list_off = (dw0 >> 8) & 0xff;
  307. next_list_off = next_list_off ? (list_off + (next_list_off << 2)) : 0;
  308. if ((dw0 & 0xff) == XHCI_XECP_ID_PROTOCOL && ((dw0 & 0xff000000) >> 24) == version)
  309. {
  310. uint32_t dw2 = xhci_read_cap_reg32(id, list_off + 8);
  311. io_mfence();
  312. if (offset != NULL)
  313. *offset = (uint32_t)(dw2 & 0xff) - 1; // 使其转换为zero based
  314. if (count != NULL)
  315. *count = (uint32_t)((dw2 & 0xff00) >> 8);
  316. if (protocol_flag != NULL && version == 2)
  317. *protocol_flag = (uint16_t)((dw2 >> 16) & 0x0fff);
  318. return next_list_off;
  319. }
  320. list_off = next_list_off;
  321. } while (list_off);
  322. return 0;
  323. }
  324. /**
  325. * @brief 配对xhci主机控制器的usb2、usb3端口
  326. *
  327. * @param id 主机控制器id
  328. * @return int 返回码
  329. */
  330. static int xhci_hc_pair_ports(int id)
  331. {
  332. struct xhci_caps_HCSPARAMS1_reg_t hcs1;
  333. io_mfence();
  334. memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
  335. io_mfence();
  336. // 从hcs1获取端口数量
  337. xhci_hc[id].port_num = hcs1.max_ports;
  338. // 找到所有的端口并标记其端口信息
  339. xhci_hc[id].port_num_u2 = 0;
  340. xhci_hc[id].port_num_u3 = 0;
  341. uint32_t next_off = xhci_hc[id].ext_caps_off;
  342. uint32_t offset, cnt;
  343. uint16_t protocol_flags = 0;
  344. // 寻找所有的usb2端口
  345. while (next_off)
  346. {
  347. io_mfence();
  348. next_off = xhci_hc_get_protocol_offset(id, next_off, 2, &offset, &cnt, &protocol_flags);
  349. io_mfence();
  350. if (cnt)
  351. {
  352. for (int i = 0; i < cnt; ++i)
  353. {
  354. io_mfence();
  355. xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u2++;
  356. xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB2;
  357. io_mfence();
  358. // usb2 high speed only
  359. if (protocol_flags & 2)
  360. xhci_hc[id].ports[offset + i].flags |= XHCI_PROTOCOL_HSO;
  361. }
  362. }
  363. }
  364. // 寻找所有的usb3端口
  365. next_off = xhci_hc[id].ext_caps_off;
  366. while (next_off)
  367. {
  368. io_mfence();
  369. next_off = xhci_hc_get_protocol_offset(id, next_off, 3, &offset, &cnt, &protocol_flags);
  370. io_mfence();
  371. if (cnt)
  372. {
  373. for (int i = 0; i < cnt; ++i)
  374. {
  375. io_mfence();
  376. xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u3++;
  377. xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB3;
  378. }
  379. }
  380. }
  381. // 将对应的USB2端口和USB3端口进行配对
  382. for (int i = 0; i < xhci_hc[id].port_num; ++i)
  383. {
  384. for (int j = 0; j < xhci_hc[id].port_num; ++j)
  385. {
  386. if (unlikely(i == j))
  387. continue;
  388. io_mfence();
  389. if ((xhci_hc[id].ports[i].offset == xhci_hc[id].ports[j].offset) &&
  390. ((xhci_hc[id].ports[i].flags & XHCI_PROTOCOL_INFO) != (xhci_hc[id].ports[j].flags & XHCI_PROTOCOL_INFO)))
  391. {
  392. xhci_hc[id].ports[i].paired_port_num = j;
  393. xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_HAS_PAIR;
  394. io_mfence();
  395. xhci_hc[id].ports[j].paired_port_num = i;
  396. xhci_hc[id].ports[j].flags |= XHCI_PROTOCOL_HAS_PAIR;
  397. }
  398. }
  399. }
  400. // 标记所有的usb3、单独的usb2端口为激活状态
  401. for (int i = 0; i < xhci_hc[id].port_num; ++i)
  402. {
  403. io_mfence();
  404. if (XHCI_PORT_IS_USB3(id, i) ||
  405. (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i))))
  406. xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_ACTIVE;
  407. }
  408. kinfo("Found %d ports on root hub, usb2 ports:%d, usb3 ports:%d", xhci_hc[id].port_num, xhci_hc[id].port_num_u2, xhci_hc[id].port_num_u3);
  409. /*
  410. // 打印配对结果
  411. for (int i = 1; i <= xhci_hc[id].port_num; ++i)
  412. {
  413. if (XHCI_PORT_IS_USB3(id, i))
  414. {
  415. kdebug("USB3 port %d, offset=%d, pair with usb2 port %d, current port is %s", i, xhci_hc[id].ports[i].offset,
  416. xhci_hc[id].ports[i].paired_port_num, XHCI_PORT_IS_ACTIVE(id, i) ? "active" : "inactive");
  417. }
  418. else if (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i))) // 单独的2.0接口
  419. {
  420. kdebug("Stand alone USB2 port %d, offset=%d, current port is %s", i, xhci_hc[id].ports[i].offset,
  421. XHCI_PORT_IS_ACTIVE(id, i) ? "active" : "inactive");
  422. }
  423. else if (XHCI_PORT_IS_USB2(id, i))
  424. {
  425. kdebug("USB2 port %d, offset=%d, current port is %s, has pair=%s", i, xhci_hc[id].ports[i].offset,
  426. XHCI_PORT_IS_ACTIVE(id, i) ? "active" : "inactive", XHCI_PORT_HAS_PAIR(id, i) ? "true" : "false");
  427. }
  428. }
  429. */
  430. return 0;
  431. }
  432. /**
  433. * @brief 创建ring,并将最后一个trb指向头一个trb
  434. *
  435. * @param trbs 要创建的trb数量
  436. * @return uint64_t trb数组的起始虚拟地址
  437. */
  438. static uint64_t xhci_create_ring(int trbs)
  439. {
  440. int total_size = trbs * sizeof(struct xhci_TRB_t);
  441. const uint64_t vaddr = (uint64_t)kmalloc(total_size, 0);
  442. io_mfence();
  443. memset((void *)vaddr, 0, total_size);
  444. io_mfence();
  445. // 设置最后一个trb为link trb
  446. xhci_TRB_set_link_cmd(vaddr + total_size - sizeof(struct xhci_TRB_t));
  447. io_mfence();
  448. return vaddr;
  449. }
  450. /**
  451. * @brief 创建新的event ring table和对应的ring segment
  452. *
  453. * @param trbs 包含的trb的数量
  454. * @param ret_ring_addr 返回的第一个event ring segment的基地址(虚拟)
  455. * @return uint64_t trb table的虚拟地址
  456. */
  457. static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr)
  458. {
  459. const uint64_t table_vaddr = (const uint64_t)kmalloc(64, 0); // table支持8个segment
  460. io_mfence();
  461. if (unlikely(table_vaddr == NULL))
  462. return -ENOMEM;
  463. memset((void *)table_vaddr, 0, 64);
  464. // 暂时只创建1个segment
  465. const uint64_t seg_vaddr = (const uint64_t)kmalloc(trbs * sizeof(struct xhci_TRB_t), 0);
  466. io_mfence();
  467. if (unlikely(seg_vaddr == NULL))
  468. return -ENOMEM;
  469. memset((void *)seg_vaddr, 0, trbs * sizeof(struct xhci_TRB_t));
  470. io_mfence();
  471. // 将segment地址和大小写入table
  472. *(uint64_t *)(table_vaddr) = virt_2_phys(seg_vaddr);
  473. *(uint64_t *)(table_vaddr + 8) = trbs;
  474. *ret_ring_addr = seg_vaddr;
  475. return table_vaddr;
  476. }
  477. void xhci_hc_irq_enable(uint64_t irq_num)
  478. {
  479. int cid = xhci_find_hcid_by_irq_num(irq_num);
  480. io_mfence();
  481. if (WARN_ON(cid == -1))
  482. return;
  483. kdebug("start msi");
  484. io_mfence();
  485. pci_start_msi(xhci_hc[cid].pci_dev_hdr);
  486. kdebug("start sched");
  487. io_mfence();
  488. xhci_hc_start_sched(cid);
  489. kdebug("start ports");
  490. io_mfence();
  491. xhci_hc_start_ports(cid);
  492. kdebug("enabled");
  493. }
  494. void xhci_hc_irq_disable(uint64_t irq_num)
  495. {
  496. int cid = xhci_find_hcid_by_irq_num(irq_num);
  497. io_mfence();
  498. if (WARN_ON(cid == -1))
  499. return;
  500. xhci_hc_stop_sched(cid);
  501. io_mfence();
  502. pci_disable_msi(xhci_hc[cid].pci_dev_hdr);
  503. io_mfence();
  504. }
  505. uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
  506. {
  507. int cid = xhci_find_hcid_by_irq_num(irq_num);
  508. io_mfence();
  509. if (WARN_ON(cid == -1))
  510. return -EINVAL;
  511. struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg;
  512. struct msi_desc_t msi_desc;
  513. memset(&msi_desc, 0, sizeof(struct msi_desc_t));
  514. io_mfence();
  515. msi_desc.irq_num = irq_num;
  516. msi_desc.msi_index = 0;
  517. msi_desc.pci_dev = (struct pci_device_structure_header_t *)xhci_hc[cid].pci_dev_hdr;
  518. msi_desc.assert = info->assert;
  519. msi_desc.edge_trigger = info->edge_trigger;
  520. msi_desc.processor = info->processor;
  521. msi_desc.pci.msi_attribute.is_64 = 1;
  522. msi_desc.pci.msi_attribute.is_msix = 1;
  523. io_mfence();
  524. int retval = pci_enable_msi(&msi_desc);
  525. kdebug("pci retval = %d", retval);
  526. kdebug("xhci irq %d installed.", irq_num);
  527. return 0;
  528. }
  529. void xhci_hc_irq_uninstall(uint64_t irq_num)
  530. {
  531. // todo
  532. int cid = xhci_find_hcid_by_irq_num(irq_num);
  533. io_mfence();
  534. if (WARN_ON(cid == -1))
  535. return;
  536. xhci_hc_stop(cid);
  537. io_mfence();
  538. }
  539. /**
  540. * @brief xhci主机控制器的中断处理函数
  541. *
  542. * @param irq_num 中断向量号
  543. * @param cid 控制器号
  544. * @param regs 寄存器值
  545. */
  546. void xhci_hc_irq_handler(uint64_t irq_num, uint64_t cid, struct pt_regs *regs)
  547. {
  548. // todo: handle irq
  549. kdebug("USB irq received.");
  550. /*
  551. 写入usb status寄存器,以表明当前收到了中断,清除usb status寄存器中的EINT位
  552. 需要先清除这个位,再清除interrupter中的pending bit)
  553. */
  554. xhci_write_op_reg32(cid, XHCI_OPS_USBSTS, xhci_read_op_reg32(cid, XHCI_OPS_USBSTS));
  555. // 读取第0个usb interrupter的intr management寄存器
  556. const uint32_t iman0 = xhci_read_intr_reg32(cid, 0, XHCI_IR_MAN);
  557. kdebug("iman0=%d", iman0);
  558. if ((iman0 & 3) == 3) // 中断被启用,且pending不为0
  559. {
  560. // 写入1以清除该interrupter的pending bit
  561. xhci_write_intr_reg32(cid, 0, XHCI_IR_MAN, iman0 | 3);
  562. struct xhci_TRB_t event_trb, origin_trb; // event ring trb以及其对应的command trb
  563. uint64_t origin_vaddr;
  564. // 暂存当前trb的起始地址
  565. uint64_t last_event_ring_vaddr = xhci_hc[cid].current_event_ring_vaddr;
  566. xhci_get_trb(&event_trb, xhci_hc[cid].current_event_ring_vaddr);
  567. while ((event_trb.command & 1) == xhci_hc[cid].current_event_ring_cycle) // 循环处理处于当前周期的所有event ring
  568. {
  569. struct xhci_TRB_cmd_complete_t *event_trb_ptr = (struct xhci_TRB_cmd_complete_t *)&event_trb;
  570. if ((event_trb.command & (1 << 2)) == 0) // 当前event trb不是由于short packet产生的
  571. {
  572. switch (event_trb_ptr->code) // 判断它的完成码
  573. {
  574. case TRB_COMP_TRB_SUCCESS: // trb执行成功,则将结果返回到对应的command ring的trb里面
  575. switch (event_trb_ptr->TRB_type) // 根据event trb类型的不同,采取不同的措施
  576. {
  577. case TRB_TYPE_COMMAND_COMPLETION: // 命令已经完成
  578. origin_vaddr = event_trb.param;
  579. // 获取对应的command trb
  580. xhci_get_trb(&origin_trb, origin_vaddr);
  581. switch (((struct xhci_TRB_normal_t *)&origin_trb)->TRB_type)
  582. {
  583. case TRB_TYPE_ENABLE_SLOT: // 源命令为enable slot
  584. // 将slot id返回到命令TRB的command字段中
  585. origin_trb.command &= 0x00ffffff;
  586. origin_trb.command |= (event_trb.command & 0xff000000);
  587. origin_trb.status = event_trb.status;
  588. break;
  589. default:
  590. origin_trb.status = event_trb.status;
  591. break;
  592. }
  593. // 标记该命令已经执行完成
  594. origin_trb.status |= XHCI_IRQ_DONE;
  595. // 将command trb写入到表中
  596. xhci_set_trb(&origin_trb, origin_vaddr);
  597. break;
  598. }
  599. break;
  600. default:
  601. break;
  602. }
  603. }
  604. else // 当前TRB是由short packet产生的
  605. {
  606. switch (event_trb_ptr->TRB_type)
  607. {
  608. case TRB_TYPE_TRANS_EVENT: // 当前 event trb是 transfer event TRB
  609. // If SPD was encountered in this TD, comp_code will be SPD, else it should be SUCCESS (specs 4.10.1.1)
  610. xhci_write_mem32(event_trb.param, (event_trb.status | XHCI_IRQ_DONE)); // return code + bytes *not* transferred
  611. break;
  612. default:
  613. break;
  614. }
  615. }
  616. // 获取下一个event ring TRB
  617. last_event_ring_vaddr = xhci_hc[cid].current_event_ring_vaddr;
  618. xhci_hc[cid].current_event_ring_vaddr += sizeof(struct xhci_TRB_t);
  619. xhci_get_trb(&event_trb, xhci_hc[cid].current_event_ring_vaddr);
  620. }
  621. // 当前event ring cycle的TRB处理结束
  622. // 更新dequeue指针, 并清除event handler busy标志位
  623. xhci_write_intr_reg64(cid, 0, XHCI_IR_DEQUEUE, last_event_ring_vaddr | (1 << 3));
  624. }
  625. }
  626. /**
  627. * @brief 重置端口
  628. *
  629. * @param id 控制器id
  630. * @param port 端口id
  631. * @return int
  632. */
  633. static int xhci_reset_port(const int id, const int port)
  634. {
  635. int retval = 0;
  636. // 相对于op寄存器基地址的偏移量
  637. uint64_t port_status_offset = XHCI_OPS_PRS + port * 16;
  638. // kdebug("to reset %d, offset=%#018lx", port, port_status_offset);
  639. io_mfence();
  640. // 检查端口电源状态
  641. if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
  642. {
  643. kdebug("port is power off, starting...");
  644. io_mfence();
  645. xhci_write_cap_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9));
  646. io_mfence();
  647. usleep(2000);
  648. // 检测端口是否被启用, 若未启用,则报错
  649. if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
  650. {
  651. kdebug("cannot power on %d", port);
  652. return -EAGAIN;
  653. }
  654. }
  655. // kdebug("port:%d, power check ok", port);
  656. io_mfence();
  657. // 确保端口的status被清0
  658. xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
  659. io_mfence();
  660. // 重置当前端口
  661. if (XHCI_PORT_IS_USB3(id, port))
  662. xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 31));
  663. else
  664. xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 4));
  665. retval = -ETIMEDOUT;
  666. // 等待portsc的port reset change位被置位,说明reset完成
  667. int timeout = 200;
  668. while (timeout)
  669. {
  670. io_mfence();
  671. uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
  672. io_mfence();
  673. if (XHCI_PORT_IS_USB3(id, port) && (val & (1 << 31)) == 0)
  674. break;
  675. else if (XHCI_PORT_IS_USB2(id, port) && (val & (1 << 4)) == 0)
  676. break;
  677. else if (val & (1 << 21))
  678. break;
  679. --timeout;
  680. usleep(500);
  681. }
  682. // kdebug("timeout= %d", timeout);
  683. if (timeout > 0)
  684. {
  685. // 等待恢复
  686. usleep(USB_TIME_RST_REC * 1000);
  687. uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
  688. io_mfence();
  689. // 如果reset之后,enable bit仍然是1,那么说明reset成功
  690. if (val & (1 << 1))
  691. {
  692. io_mfence();
  693. // 清除status change bit
  694. xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
  695. io_mfence();
  696. }
  697. retval = 0;
  698. }
  699. // 如果usb2端口成功reset,则处理该端口的active状态
  700. if (retval == 0 && XHCI_PORT_IS_USB2(id, port))
  701. {
  702. xhci_hc[id].ports[port].flags |= XHCI_PROTOCOL_ACTIVE;
  703. if (XHCI_PORT_HAS_PAIR(id, port)) // 如果有对应的usb3端口,则将usb3端口设置为未激活
  704. xhci_hc[id].ports[xhci_hc[id].ports[port].paired_port_num].flags &= ~(XHCI_PROTOCOL_ACTIVE);
  705. }
  706. // 如果usb3端口reset失败,则启用与之配对的usb2端口
  707. if (retval != 0 && XHCI_PORT_IS_USB3(id, port))
  708. {
  709. xhci_hc[id].ports[port].flags &= ~XHCI_PROTOCOL_ACTIVE;
  710. xhci_hc[id].ports[xhci_hc[id].ports[port].paired_port_num].flags |= XHCI_PROTOCOL_ACTIVE;
  711. }
  712. return retval;
  713. }
  714. /**
  715. * @brief 启用xhci控制器的端口
  716. *
  717. * @param id 控制器id
  718. * @return int
  719. */
  720. static int xhci_hc_start_ports(int id)
  721. {
  722. int cnt = 0;
  723. // 注意,这两个循环应该不能合并到一起,因为可能存在usb2端口offset在前,usb3端口在后的情况,那样的话就会出错
  724. // 循环启动所有的usb3端口
  725. for (int i = 0; i < xhci_hc[id].port_num; ++i)
  726. {
  727. if (XHCI_PORT_IS_USB3(id, i) && XHCI_PORT_IS_ACTIVE(id, i))
  728. {
  729. io_mfence();
  730. // reset该端口
  731. if (likely(xhci_reset_port(id, i) == 0)) // 如果端口reset成功,就获取它的描述符
  732. // 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的
  733. {
  734. // xhci_hc_get_descriptor(id, i);
  735. ++cnt;
  736. }
  737. }
  738. }
  739. kdebug("active usb3 ports:%d", cnt);
  740. // 循环启动所有的usb2端口
  741. for (int i = 0; i < xhci_hc[id].port_num; ++i)
  742. {
  743. if (XHCI_PORT_IS_USB2(id, i) && XHCI_PORT_IS_ACTIVE(id, i))
  744. {
  745. // reset该端口
  746. if (likely(xhci_reset_port(id, i) == 0)) // 如果端口reset成功,就获取它的描述符
  747. // 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的
  748. {
  749. // xhci_hc_get_descriptor(id, i);
  750. ++cnt;
  751. }
  752. }
  753. }
  754. kinfo("xHCI controller %d: Started %d ports.", id, cnt);
  755. return 0;
  756. }
  757. /**
  758. * @brief 初始化xhci主机控制器的中断控制
  759. *
  760. * @param id 主机控制器id
  761. * @return int 返回码
  762. */
  763. static int xhci_hc_init_intr(int id)
  764. {
  765. uint64_t retval = 0;
  766. struct xhci_caps_HCSPARAMS1_reg_t hcs1;
  767. struct xhci_caps_HCSPARAMS2_reg_t hcs2;
  768. io_mfence();
  769. memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
  770. io_mfence();
  771. memcpy(&hcs2, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCSPARAMS2_reg_t));
  772. io_mfence();
  773. uint32_t max_segs = (1 << (uint32_t)(hcs2.ERST_Max));
  774. uint32_t max_interrupters = hcs1.max_intrs;
  775. // 创建 event ring
  776. retval = xhci_create_event_ring(4096, &xhci_hc[id].event_ring_vaddr);
  777. io_mfence();
  778. if (unlikely((int64_t)(retval) == -ENOMEM))
  779. return -ENOMEM;
  780. xhci_hc[id].event_ring_table_vaddr = retval;
  781. xhci_hc[id].current_event_ring_vaddr = xhci_hc[id].event_ring_vaddr; // 设置驱动程序要读取的下一个event ring trb的地址
  782. retval = 0;
  783. xhci_hc[id].current_event_ring_cycle = 1;
  784. // 写入第0个中断寄存器组
  785. io_mfence();
  786. xhci_write_intr_reg32(id, 0, XHCI_IR_MAN, 0x3); // 使能中断并清除pending位(这个pending位是写入1就清0的)
  787. io_mfence();
  788. xhci_write_intr_reg32(id, 0, XHCI_IR_MOD, 0); // 关闭中断管制
  789. io_mfence();
  790. xhci_write_intr_reg32(id, 0, XHCI_IR_TABLE_SIZE, 1); // 当前只有1个segment
  791. io_mfence();
  792. xhci_write_intr_reg64(id, 0, XHCI_IR_DEQUEUE, virt_2_phys(xhci_hc[id].event_ring_vaddr) | (1 << 3)); // 写入dequeue寄存器,并清除busy位(写1就会清除)
  793. io_mfence();
  794. xhci_write_intr_reg64(id, 0, XHCI_IR_TABLE_ADDR, virt_2_phys(xhci_hc[id].event_ring_table_vaddr)); // 写入table地址
  795. io_mfence();
  796. // 清除状态位
  797. xhci_write_op_reg32(id, XHCI_OPS_USBSTS, (1 << 10) | (1 << 4) | (1 << 3) | (1 << 2));
  798. io_mfence();
  799. // 开启usb中断
  800. // 注册中断处理程序
  801. struct xhci_hc_irq_install_info_t install_info;
  802. install_info.assert = 1;
  803. install_info.edge_trigger = 1;
  804. install_info.processor = 0; // 投递到bsp
  805. char *buf = (char *)kmalloc(16, 0);
  806. memset(buf, 0, 16);
  807. sprintk(buf, "xHCI HC%d", id);
  808. io_mfence();
  809. irq_register(xhci_controller_irq_num[id], &install_info, &xhci_hc_irq_handler, id, &xhci_hc_intr_controller, buf);
  810. io_mfence();
  811. kfree(buf);
  812. kdebug("xhci host controller %d: interrupt registered. irq num=%d", id, xhci_controller_irq_num[id]);
  813. return 0;
  814. }
  815. /**
  816. * @brief 写入doorbell寄存器
  817. *
  818. * @param id 主机控制器id
  819. * @param slot_id usb控制器插槽id(0用作命令门铃,其他的用于具体的设备的门铃)
  820. * @param value 要写入的值
  821. */
  822. static __always_inline void __xhci_write_doorbell(const int id, const uint16_t slot_id, const uint32_t value)
  823. {
  824. // 确保写入门铃寄存器之前,所有的写操作均已完成
  825. io_sfence();
  826. xhci_write_cap_reg32(id, xhci_hc[id].db_offset + slot_id * sizeof(uint32_t), value);
  827. io_sfence();
  828. }
  829. /**
  830. * @brief 往xhci控制器发送命令
  831. *
  832. * @param id xhci控制器号
  833. * @param trb 传输请求块
  834. * @param do_ring 是否通知doorbell register
  835. * @return int 错误码
  836. */
  837. static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring)
  838. {
  839. uint64_t origin_trb_vaddr = xhci_hc[id].cmd_trb_vaddr;
  840. // 必须先写入参数和状态数据,最后写入command
  841. xhci_write_mem64(xhci_hc[id].cmd_trb_vaddr, trb->param); // 参数
  842. xhci_write_mem32(xhci_hc[id].cmd_trb_vaddr + 8, trb->status); // 状态
  843. xhci_write_mem32(xhci_hc[id].cmd_trb_vaddr + 12, trb->command); // 命令
  844. xhci_hc[id].cmd_trb_vaddr += sizeof(struct xhci_TRB_t); // 跳转到下一个trb
  845. {
  846. // 如果下一个trb是link trb,则将下一个要操作的地址是设置为第一个trb
  847. struct xhci_TRB_normal_t *ptr = (struct xhci_TRB_normal_t *)xhci_hc[id].cmd_trb_vaddr;
  848. if (ptr->TRB_type == TRB_TYPE_LINK)
  849. {
  850. ptr->cycle = xhci_hc[id].cmd_trb_cycle;
  851. xhci_hc[id].cmd_trb_vaddr = xhci_hc[id].cmd_ring_vaddr;
  852. xhci_hc[id].cmd_trb_cycle ^= 1;
  853. }
  854. }
  855. if (do_ring) // 按响命令门铃
  856. {
  857. kdebug("to ring..");
  858. __xhci_write_doorbell(id, 0, 0);
  859. kdebug("ring..");
  860. // 等待中断产生
  861. int timer = 20;
  862. // Now wait for the interrupt to happen
  863. // We use bit 31 of the command dword since it is reserved
  864. while (timer && ((xhci_read_mem32(origin_trb_vaddr + 12) & (1 << 31)) == 0))
  865. {
  866. usleep(1000);
  867. --timer;
  868. }
  869. uint32_t x = xhci_read_cap_reg32(id, xhci_hc[id].rts_offset + 0x20);
  870. kdebug("ip=%#010lx", x);
  871. if (timer == 0)
  872. kwarn("USB xHCI Command Interrupt wait timed out.");
  873. else
  874. {
  875. kdebug("interrupt done");
  876. }
  877. }
  878. return 0;
  879. }
  880. /**
  881. * @brief 初始化xhci控制器
  882. *
  883. * @param header 指定控制器的pci device头部
  884. */
  885. void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
  886. {
  887. if (xhci_ctrl_count >= XHCI_MAX_HOST_CONTROLLERS)
  888. {
  889. kerror("Initialize xhci controller failed: exceed the limit of max controllers.");
  890. return;
  891. }
  892. spin_lock(&xhci_controller_init_lock);
  893. 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);
  894. io_mfence();
  895. int cid = xhci_hc_find_available_id();
  896. if (cid < 0)
  897. {
  898. kerror("Initialize xhci controller failed: exceed the limit of max controllers.");
  899. goto failed_exceed_max;
  900. }
  901. memset(&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
  902. xhci_hc[cid].controller_id = cid;
  903. xhci_hc[cid].pci_dev_hdr = dev_hdr;
  904. io_mfence();
  905. {
  906. uint32_t tmp = pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4);
  907. tmp |= 0x6;
  908. // mem I/O access enable and bus master enable
  909. pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4, tmp);
  910. }
  911. io_mfence();
  912. // 为当前控制器映射寄存器地址空间
  913. xhci_hc[cid].vbase = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + 65536 * xhci_hc[cid].controller_id;
  914. // kdebug("dev_hdr->BAR0 & (~0xf)=%#018lx", dev_hdr->BAR0 & (~0xf));
  915. mm_map_phys_addr(xhci_hc[cid].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true);
  916. io_mfence();
  917. // 读取xhci控制寄存器
  918. uint16_t iversion = *(uint16_t *)(xhci_hc[cid].vbase + XHCI_CAPS_HCIVERSION);
  919. struct xhci_caps_HCCPARAMS1_reg_t hcc1;
  920. struct xhci_caps_HCCPARAMS2_reg_t hcc2;
  921. struct xhci_caps_HCSPARAMS1_reg_t hcs1;
  922. struct xhci_caps_HCSPARAMS2_reg_t hcs2;
  923. memcpy(&hcc1, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCCPARAMS1), sizeof(struct xhci_caps_HCCPARAMS1_reg_t));
  924. memcpy(&hcc2, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCCPARAMS2), sizeof(struct xhci_caps_HCCPARAMS2_reg_t));
  925. memcpy(&hcs1, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
  926. memcpy(&hcs2, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCSPARAMS2_reg_t));
  927. // kdebug("hcc1.xECP=%#010lx", hcc1.xECP);
  928. // 计算operational registers的地址
  929. xhci_hc[cid].vbase_op = xhci_hc[cid].vbase + (xhci_read_cap_reg32(cid, XHCI_CAPS_CAPLENGTH) & 0xff);
  930. io_mfence();
  931. xhci_hc[cid].db_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_DBOFF) & (~0x3); // bits [1:0] reserved
  932. io_mfence();
  933. xhci_hc[cid].rts_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_RTSOFF) & (~0x1f); // bits [4:0] reserved.
  934. io_mfence();
  935. xhci_hc[cid].ext_caps_off = 1UL * (hcc1.xECP) * 4;
  936. xhci_hc[cid].context_size = (hcc1.csz) ? 64 : 32;
  937. if (iversion < 0x95)
  938. kwarn("Unsupported/Unknowned xHCI controller version: %#06x. This may cause unexpected behavior.", iversion);
  939. {
  940. // Write to the FLADJ register incase the BIOS didn't
  941. uint32_t tmp = pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x60);
  942. tmp |= (0x20 << 8);
  943. pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x60, tmp);
  944. }
  945. // if it is a Panther Point device, make sure sockets are xHCI controlled.
  946. if (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) & 0xffff) == 0x8086) &&
  947. (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) >> 16) & 0xffff) == 0x1E31) &&
  948. ((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 8) & 0xff) == 4))
  949. {
  950. kdebug("Is a Panther Point device");
  951. pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd8, 0xffffffff);
  952. pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd0, 0xffffffff);
  953. }
  954. io_mfence();
  955. // 关闭legacy支持
  956. FAIL_ON_TO(xhci_hc_stop_legacy(cid), failed);
  957. io_mfence();
  958. // 重置xhci控制器
  959. FAIL_ON_TO(xhci_hc_reset(cid), failed);
  960. io_mfence();
  961. // 端口配对
  962. FAIL_ON_TO(xhci_hc_pair_ports(cid), failed);
  963. io_mfence();
  964. // ========== 设置USB host controller =========
  965. // 获取页面大小
  966. xhci_hc[cid].page_size = (xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE) & 0xffff) << 12;
  967. io_mfence();
  968. // 获取设备上下文空间
  969. xhci_hc[cid].dcbaap_vaddr = (uint64_t)kmalloc(2048, 0); // 分配2KB的设备上下文地址数组空间
  970. memset((void *)xhci_hc[cid].dcbaap_vaddr, 0, 2048);
  971. io_mfence();
  972. kdebug("dcbaap_vaddr=%#018lx", xhci_hc[cid].dcbaap_vaddr);
  973. if (unlikely(!xhci_is_aligned64(xhci_hc[cid].dcbaap_vaddr))) // 地址不是按照64byte对齐
  974. {
  975. kerror("dcbaap isn't 64 byte aligned.");
  976. goto failed_free_dyn;
  977. }
  978. // 写入dcbaap
  979. xhci_write_op_reg64(cid, XHCI_OPS_DCBAAP, virt_2_phys(xhci_hc[cid].dcbaap_vaddr));
  980. io_mfence();
  981. // 创建command ring
  982. xhci_hc[cid].cmd_ring_vaddr = xhci_create_ring(XHCI_CMND_RING_TRBS);
  983. xhci_hc[cid].cmd_trb_vaddr = xhci_hc[cid].cmd_ring_vaddr;
  984. if (unlikely(!xhci_is_aligned64(xhci_hc[cid].cmd_ring_vaddr))) // 地址不是按照64byte对齐
  985. {
  986. kerror("cmd ring isn't 64 byte aligned.");
  987. goto failed_free_dyn;
  988. }
  989. // 设置初始cycle bit为1
  990. xhci_hc[cid].cmd_trb_cycle = XHCI_TRB_CYCLE_ON;
  991. io_mfence();
  992. // 写入command ring控制寄存器
  993. xhci_write_op_reg64(cid, XHCI_OPS_CRCR, virt_2_phys(xhci_hc[cid].cmd_ring_vaddr) | xhci_hc[cid].cmd_trb_cycle);
  994. // 写入配置寄存器
  995. uint32_t max_slots = hcs1.max_slots;
  996. kdebug("max slots = %d", max_slots);
  997. io_mfence();
  998. xhci_write_op_reg32(cid, XHCI_OPS_CONFIG, max_slots);
  999. io_mfence();
  1000. // 写入设备通知控制寄存器
  1001. xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持
  1002. io_mfence();
  1003. FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn);
  1004. io_mfence();
  1005. ++xhci_ctrl_count;
  1006. io_mfence();
  1007. spin_unlock(&xhci_controller_init_lock);
  1008. io_mfence();
  1009. // 发送nop
  1010. struct xhci_TRB_normal_t nop_trb = {0};
  1011. nop_trb.cycle = xhci_hc[cid].cmd_trb_cycle;
  1012. nop_trb.TRB_type = TRB_TYPE_ENABLE_SLOT;
  1013. nop_trb.ioc = 1;
  1014. kdebug("to send nop TRB");
  1015. xhci_send_command(cid, &nop_trb, true);
  1016. xhci_send_command(cid, &nop_trb, true);
  1017. kdebug("nop TRB send OK");
  1018. return;
  1019. failed_free_dyn:; // 释放动态申请的内存
  1020. if (xhci_hc[cid].dcbaap_vaddr)
  1021. kfree((void *)xhci_hc[cid].dcbaap_vaddr);
  1022. if (xhci_hc[cid].cmd_ring_vaddr)
  1023. kfree((void *)xhci_hc[cid].cmd_ring_vaddr);
  1024. if (xhci_hc[cid].event_ring_table_vaddr)
  1025. kfree((void *)xhci_hc[cid].event_ring_table_vaddr);
  1026. if (xhci_hc[cid].event_ring_vaddr)
  1027. kfree((void *)xhci_hc[cid].event_ring_vaddr);
  1028. failed:;
  1029. io_mfence();
  1030. // 取消地址映射
  1031. mm_unmap_addr(xhci_hc[cid].vbase, 65536);
  1032. io_mfence();
  1033. // 清空数组
  1034. memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
  1035. failed_exceed_max:;
  1036. kerror("Failed to initialize controller: bus=%d, dev=%d, func=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func);
  1037. spin_unlock(&xhci_controller_init_lock);
  1038. }