Possible mistake on Virtio page
Posted: Sat Aug 18, 2018 2:54 pm
Hi All,
It says on OSDev's virtio page that the Subsystem ID field in the PCI Configuration Space should be 2 for a block device. This is a bit ambiguous because on the PCI page we see fields called Subsystem Vendor ID and Subsystem Device ID, but neither was 2 in my experiment, namely, starting qemu with:
qemu-system-x86_64 -S -gdb tcp::9000 --nographic --enable-kvm -cpu host -m 8192 -drive id=c,file=hard.disk,format=raw,if=none -device virtio-blk-pci,drive=c -fda floppy.img
(or with the simpler form "-drive file=hard.disk,format=raw,if=virtio" and no -device)
and hunting through the PCI devices for anything with vendor ID 1AF4 using the code at the bottom. I find just this one:
Base (i.e. what I shove into 0xCF8 after adding the register number): 0x80002000
Register 2 (class code, subclass, prog if, revision): 0x01000000
Register 0 (device id, vendor id): 0x10011af4
Register 0x10 (subsystem): 0x01100009 (Plan 9 according to your page?)
Reading through the virtio specs linked from the bottom of your page, I see that the 1001 (just before the 1af4) confirms this as a block device.
So what's the story on the subsystem codes. Did they change something?
Here's that PCI scanning code in nasm:
It says on OSDev's virtio page that the Subsystem ID field in the PCI Configuration Space should be 2 for a block device. This is a bit ambiguous because on the PCI page we see fields called Subsystem Vendor ID and Subsystem Device ID, but neither was 2 in my experiment, namely, starting qemu with:
qemu-system-x86_64 -S -gdb tcp::9000 --nographic --enable-kvm -cpu host -m 8192 -drive id=c,file=hard.disk,format=raw,if=none -device virtio-blk-pci,drive=c -fda floppy.img
(or with the simpler form "-drive file=hard.disk,format=raw,if=virtio" and no -device)
and hunting through the PCI devices for anything with vendor ID 1AF4 using the code at the bottom. I find just this one:
Base (i.e. what I shove into 0xCF8 after adding the register number): 0x80002000
Register 2 (class code, subclass, prog if, revision): 0x01000000
Register 0 (device id, vendor id): 0x10011af4
Register 0x10 (subsystem): 0x01100009 (Plan 9 according to your page?)
Reading through the virtio specs linked from the bottom of your page, I see that the 1001 (just before the 1af4) confirms this as a block device.
So what's the story on the subsystem codes. Did they change something?
Here's that PCI scanning code in nasm:
Code: Select all
BITS 64
SECTION .text
GLOBAL PciFindVirtio
GLOBAL PciSearchResults
GLOBAL PciSearchResultsCount
%define PCI_C 0xCF8
%define PCI_D 0xCFC
%macro PCI_READ 1
mov eax, ecx
add eax, %1
mov dx, PCI_C
out dx, eax
mov dx, PCI_D
in eax, dx
%endmacro
PciFindVirtio:
mov R8, PciSearchResults
mov R9, PciSearchResultsEnd
; Top bit enables, middle is bus and slot:function, low byte is register
mov ecx, 0x80000000
.loop:
PCI_READ 0 ;Vendor
mov ebp, eax
PCI_READ 0x40 ;Subsystem
mov esi, eax
PCI_READ 8 ;Class
mov ebx, eax
and eax, 0xff000000
cmp eax, 0x01000000 ; block device
je .relevant
mov eax, ebp
and eax, 0x0000ffff
cmp eax, 0x00001AF4 ;virtio vendor
je .relevant
jmp .irrel
.relevant:
mov [R8], ecx
mov [R8+4], ebx
mov [R8+8], ebp
mov [R8+12], esi
; inc and bail if out of space
add R8, 16
cmp R8, R9
je .done
.irrel:
; next slot
add ecx, 0x100
cmp ecx, 0x80ffff00
jne .loop
.done:
sub R8, PciSearchResults
shr R8, 3
mov [PciSearchResultsCount], R8
ret
SECTION .data
PciSearchResultsCount:
dq 0
PciSearchResults:
times 16 dq 0, 0
PciSearchResultsEnd: