88
99; -----------------------------------------------------------------------------
1010virtio_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
16152virtio_input_driverid:
17153dw 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
0 commit comments