need help on writing a driver for intel vmd
-
- Member
- Posts: 70
- Joined: Tue Jul 14, 2020 4:01 am
- Libera.chat IRC: clementttttttttt
need help on writing a driver for intel vmd
i want to write a driver for intel vmd since disabling it is really troublesome on my laptop (need to recreate boot entries for firmware because it's buggy), and was unable to find any documentation for it aside from the linux driver source for it which was pretty hard to understand, need some help
-
- Member
- Posts: 5560
- Joined: Mon Mar 25, 2013 7:01 pm
Re: need help on writing a driver for intel vmd
The Linux driver is complicated mostly because Linux is complicated. Your driver can be simpler.
Enumerating devices behind VMD works exactly the same as ordinary PCIe ECAM enumeration. The downstream configuration space is mapped by BAR0 (CFGBAR). For device ID 0x201D, it always starts at bus 0. For other device IDs, read the word at offset 0x40 in VMD's configuration space and check bit 0. If that bit is clear, it starts at bus 0. If that bit is set, read the word at offset 0x44 and check bits 8 and 9. A value of 0b00 indicates bus 0, 0b01 indicates bus 128, and 0b10 indicates bus 224. The size of the downstream configuration space determines how many buses you can enumerate.
MMIO behind VMD works pretty much the same as MMIO behind a normal PCI bridge. VMD uses BAR2 (MEMBAR1) and BAR4 (MEMBAR2) to provide the MMIO windows.
DMA through VMD also works pretty much the same as DMA through a normal PCI bridge. In a virtual machine, you have to take extra care to avoid IOMMU address conflicts, but that shouldn't be a concern on bare metal.
VMD remaps message-signaled interrupts to its own MSI-X interrupts. Program the devices behind VMD to use message address (0xFEE00000 | (msix_interrupt_number << 12)) and message data 0. On all device IDs except 0x201D and 0x28C0, VMD may generate its own interrupts using MSI-X interrupt 0, so you shouldn't configure downstream devices to use that interrupt. On device ID 0x28C0, you can turn off interrupt remapping by setting bit 1 of configuration word 0x44.
VMD doesn't support port-mapped I/O. Devices behind VMD can't use I/O ports.
VMD doesn't support line-based interrupts. Devices behind VMD must use message-signaled interrupts.
Enumerating devices behind VMD works exactly the same as ordinary PCIe ECAM enumeration. The downstream configuration space is mapped by BAR0 (CFGBAR). For device ID 0x201D, it always starts at bus 0. For other device IDs, read the word at offset 0x40 in VMD's configuration space and check bit 0. If that bit is clear, it starts at bus 0. If that bit is set, read the word at offset 0x44 and check bits 8 and 9. A value of 0b00 indicates bus 0, 0b01 indicates bus 128, and 0b10 indicates bus 224. The size of the downstream configuration space determines how many buses you can enumerate.
MMIO behind VMD works pretty much the same as MMIO behind a normal PCI bridge. VMD uses BAR2 (MEMBAR1) and BAR4 (MEMBAR2) to provide the MMIO windows.
DMA through VMD also works pretty much the same as DMA through a normal PCI bridge. In a virtual machine, you have to take extra care to avoid IOMMU address conflicts, but that shouldn't be a concern on bare metal.
VMD remaps message-signaled interrupts to its own MSI-X interrupts. Program the devices behind VMD to use message address (0xFEE00000 | (msix_interrupt_number << 12)) and message data 0. On all device IDs except 0x201D and 0x28C0, VMD may generate its own interrupts using MSI-X interrupt 0, so you shouldn't configure downstream devices to use that interrupt. On device ID 0x28C0, you can turn off interrupt remapping by setting bit 1 of configuration word 0x44.
VMD doesn't support port-mapped I/O. Devices behind VMD can't use I/O ports.
VMD doesn't support line-based interrupts. Devices behind VMD must use message-signaled interrupts.