@@ -27,77 +27,10 @@ xhci_init:
2727 bts eax , 1 ; Enable Memory Space
2828 call os_bus_write ; Write updated Status/Command
2929
30- ; Check for MSI-X in PCI Capabilities
31- xhci_init_msix_check:
32- mov dl , 1
33- call os_bus_read ; Read register 1 for Status/Command
34- bt eax , 20 ; Check bit 4 of the Status word (31:16)
35- jnc xhci_init_error ; If if doesn't exist then bail out
36- mov dl , 13
37- call os_bus_read ; Read register 13 for the Capabilities Pointer (7:0)
38- and al , 0xFC ; Clear the bottom two bits as they are reserved
39- xhci_init_msix_check_cap_next:
40- shr al , 2 ; Quick divide by 4
41- mov dl , al
42- call os_bus_read
43- cmp al , 0x11
44- je xhci_init_msix
45- xhci_init_msix_check_cap_next_offset:
46- shr eax , 8 ; Shift pointer to AL
47- cmp al , 0x00 ; End of linked list?
48- jne xhci_init_msix_check_cap_next ; If not, continue reading
49- jmp xhci_init_msi_check ; Otherwise bail out and check for MSI
50- xhci_init_msix:
51- push rdx
52- ; Enable MSI-X, Mask it, Get Table Size
53- ; Example MSI-X Entry (From QEMU xHCI Controller)
54- ; 000FA011 <- Cap ID 0x11 (MSI-X), next ptr 0xA0, message control 0x000F - Table size is bits 10:0 so 0x0F
55- ; 00003000 <- BIR (2:0) is 0x0 so BAR0, Table Offset (31:3) - 8-byte aligned so clear low 3 bits - 0x3000 in this case
56- ; 00003800 <- Pending Bit BIR (2:0) and Pending Bit Offset (31:3) - 0x3800 in this case
57- ; Message Control - Enable (15), Function Mask (14), Table Size (10:0)
58- call os_bus_read
59- mov ecx , eax ; Save for Table Size
60- bts eax , 31 ; Enable MSIX
61- bts eax , 30 ; Set Function Mask
62- call os_bus_write
63- shr ecx , 16 ; Shift Message Control to low 16-bits
64- and cx , 0x7FF ; Keep bits 10:0
65- ; Read the BIR and Table Offset
66- push rdx
67- add dl , 1
68- call os_bus_read
69- mov ebx , eax ; EBX for the Table Offset
70- and ebx , 0xFFFFFFF8 ; Clear bits 2:0
71- and eax , 0x00000007 ; Keep bits 2:0 for the BIR
72- add al , 0x04 ; Add offset to start of BARs
73- mov dl , al
74- call os_bus_read ; Read the BAR address
75- add rax , rbx ; Add offset to base
76- sub rax , 0x04
77- mov rdi , rax
78- pop rdx
79- ; Configure MSI-X Table
80- add cx , 1 ; Table Size is 0-indexed
81- mov ebx , 0x000040A0 ; Trigger Mode (15), Level (14), Delivery Mode (10:8), Vector (7:0)
82- xhci_init_msix_entry:
83- mov rax , [ os_LocalAPICAddress ] ; 0xFEE for bits 31:20, Dest (19:12), RH (3), DM (2)
84- stosd ; Store Message Address Low
85- shr rax , 32 ; Rotate the high bits to EAX
86- stosd ; Store Message Address High
87- mov eax , ebx
88- inc ebx
89- stosd ; Store Message Data
90- xor eax , eax ; Bits 31:1 are reserved, Masked (0) - 1 for masked
91- stosd ; Store Vector Control
92- dec cx
93- cmp cx , 0
94- jne xhci_init_msix_entry
95- ; Unmask MSI-X
96- pop rdx
97- call os_bus_read
98- btr eax , 30 ; Clear Function Mask
99- call os_bus_write
100- jmp xhci_init_msix_msi_done
30+ ; Configure MSI-X (if available)
31+ mov al , 0xA0
32+ call msix_init
33+ jnc xhci_init_msix_msi_done
10134
10235 ; Check for MSI in PCI Capabilities
10336xhci_init_msi_check:
0 commit comments