Skip to content

Commit eeb3247

Browse files
author
Ian Seyler
committed
Build out virtio-input driver
1 parent 57654e8 commit eeb3247

File tree

3 files changed

+141
-2
lines changed

3 files changed

+141
-2
lines changed

src/drivers/hid/virtio-input.asm

Lines changed: 137 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,150 @@
88

99
; -----------------------------------------------------------------------------
1010
virtio_input_init:
11+
mov ebx, [virtio_input_driverid]
12+
mov rsi, bus_table
13+
add rsi, 4
14+
virtio_input_init_search:
15+
mov eax, [rsi]
16+
cmp eax, 0xFFFFFFFF
17+
je virtio_input_init_done
18+
cmp eax, ebx
19+
je virtio_input_init_config
20+
add rsi, 16
21+
jmp virtio_input_init_search
22+
23+
virtio_input_init_config:
24+
sub rsi, 4
25+
mov edx, [rsi]
26+
27+
mov eax, 4 ; Read BAR4
28+
call os_bus_read_bar
29+
mov [os_virtio_input_base], rax ; Save it as the base
30+
mov rsi, rax ; RSI holds the base for MMIO
31+
32+
; Set PCI Status/Command values
33+
mov dl, 0x01 ; Read Status/Command
34+
call os_bus_read
35+
bts eax, 10 ; Set Interrupt Disable
36+
bts eax, 2 ; Enable Bus Master
37+
bts eax, 1 ; Enable Memory Space
38+
call os_bus_write ; Write updated Status/Command
39+
40+
; Device Initialization (section 3.1)
41+
42+
; 3.1.1 - Step 1 - Reset the device (section 2.4)
43+
mov al, 0x00
44+
mov [rsi+VIRTIO_DEVICE_STATUS], al
45+
virtio_input_init_reset_wait:
46+
mov al, [rsi+VIRTIO_DEVICE_STATUS]
47+
cmp al, 0x00
48+
jne virtio_input_init_reset_wait
49+
50+
; 3.1.1 - Step 2 - Set the ACKNOWLEDGE bit - Tell the device we see it
51+
mov al, VIRTIO_STATUS_ACKNOWLEDGE
52+
mov [rsi+VIRTIO_DEVICE_STATUS], al
53+
54+
; 3.1.1 - Step 3 - Set the DRIVER bit - Tell the device we support it
55+
mov al, VIRTIO_STATUS_ACKNOWLEDGE | VIRTIO_STATUS_DRIVER
56+
mov [rsi+VIRTIO_DEVICE_STATUS], al
57+
58+
; 3.1.1 - Step 4 - Read device feature bits and write supported driver bits back
59+
; Process the first 32-bits of Feature bits
60+
xor eax, eax
61+
mov [rsi+VIRTIO_DEVICE_FEATURE_SELECT], eax
62+
mov eax, [rsi+VIRTIO_DEVICE_FEATURE]
63+
push rax
64+
xor eax, eax
65+
mov [rsi+VIRTIO_DRIVER_FEATURE_SELECT], eax
66+
pop rax
67+
mov [rsi+VIRTIO_DRIVER_FEATURE], eax
68+
; Process the next 32-bits of Feature bits
69+
mov eax, 1
70+
mov [rsi+VIRTIO_DEVICE_FEATURE_SELECT], eax
71+
mov eax, [rsi+VIRTIO_DEVICE_FEATURE]
72+
and eax, 1
73+
push rax
74+
mov eax, 1
75+
mov [rsi+VIRTIO_DRIVER_FEATURE_SELECT], eax
76+
pop rax
77+
mov [rsi+VIRTIO_DRIVER_FEATURE], eax
78+
79+
; 3.1.1 - Step 5 - Set the FEATURES_OK bit - Tell the device we will init with those features
80+
mov al, VIRTIO_STATUS_ACKNOWLEDGE | VIRTIO_STATUS_DRIVER | VIRTIO_STATUS_FEATURES_OK
81+
mov [rsi+VIRTIO_DEVICE_STATUS], al
82+
83+
; 3.1.1 - Step 6 - Re-read device status to make sure FEATURES_OK is still set
84+
mov al, [rsi+VIRTIO_DEVICE_STATUS]
85+
bt ax, 3 ; VIRTIO_STATUS_FEATURES_OK
86+
jnc virtio_input_init_error
87+
88+
; 3.1.1 - Step 7
89+
; Set up the device and the queues
90+
; discovery of virtqueues for the device
91+
; optional per-bus setup
92+
; reading and possibly writing the device’s virtio configuration space
93+
; population of virtqueues
94+
95+
; Set up Queue 0
96+
xor eax, eax
97+
mov [rsi+VIRTIO_QUEUE_SELECT], ax
98+
mov ax, [rsi+VIRTIO_QUEUE_SIZE] ; Return the size of the queue
99+
mov ecx, eax ; Store queue size in ECX
100+
mov eax, 0xA00000
101+
mov [rsi+VIRTIO_QUEUE_DESC], eax
102+
rol rax, 32
103+
mov [rsi+VIRTIO_QUEUE_DESC+8], eax
104+
rol rax, 32
105+
add rax, 4096
106+
mov [rsi+VIRTIO_QUEUE_DRIVER], eax
107+
rol rax, 32
108+
mov [rsi+VIRTIO_QUEUE_DRIVER+8], eax
109+
rol rax, 32
110+
add rax, 4096
111+
mov [rsi+VIRTIO_QUEUE_DEVICE], eax
112+
rol rax, 32
113+
mov [rsi+VIRTIO_QUEUE_DEVICE+8], eax
114+
rol rax, 32
115+
mov ax, 1
116+
mov [rsi+VIRTIO_QUEUE_ENABLE], ax
117+
118+
; Populate the Next entries in the description ring
119+
; FIXME - Don't expect exactly 256 entries
120+
mov eax, 1
121+
mov rdi, 0xA00000
122+
add rdi, 14
123+
virtio_input_init_pop:
124+
mov [rdi], al
125+
add rdi, 16
126+
add al, 1
127+
cmp al, 0
128+
jne virtio_input_init_pop
129+
130+
; 3.1.1 - Step 8 - Set the DRIVER_OK bit - At this point the device is “live”
131+
mov al, VIRTIO_STATUS_ACKNOWLEDGE | VIRTIO_STATUS_DRIVER | VIRTIO_STATUS_DRIVER_OK | VIRTIO_STATUS_FEATURES_OK
132+
mov [rsi+VIRTIO_DEVICE_STATUS], al
133+
134+
135+
136+
; DEBUG
137+
; mov r9, 0x1234
138+
; jmp $
139+
140+
virtio_input_init_done:
141+
ret
142+
143+
virtio_input_init_error:
144+
mov al, VIRTIO_STATUS_FAILED
145+
mov [rsi+VIRTIO_DEVICE_STATUS], al
146+
11147
ret
12148
; -----------------------------------------------------------------------------
13149

14150

15151
; Driver
16152
virtio_input_driverid:
17153
dw 0x1AF4 ; Vendor ID
18-
dw 0x1052 ; Device ID - v1.0
19-
dw 0x0000 ; End of list
154+
dw 0x1052 ; Device ID (0x1040 + 18)
20155

21156
; =============================================================================
22157
; EOF

src/init/hid.asm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ init_hid:
1111
; Configure the PS/2 keyboard and mouse (if they exist)
1212
call ps2_init
1313

14+
; Configure Virtio Input (if it is present)
15+
call virtio_input_init
16+
1417
; Enumerate USB devices
1518
bt qword [os_SysConfEn], 5
1619
jnc init_hid_done

src/sysvar.asm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ os_virtioblk_base: equ os_SystemVariables + 0x00C8
7979
os_MouseCallback: equ os_SystemVariables + 0x00D8
8080
os_xHCI_Base: equ os_SystemVariables + 0x00E0
8181
os_usb_evtoken: equ os_SystemVariables + 0x00E8
82+
os_virtio_input_base: equ os_SystemVariables + 0x00F0
8283

8384

8485
; DD - Starting at offset 256, increments by 4

0 commit comments

Comments
 (0)