1Haiku PCI Driver Development Under QEMU on Linux
2====================================================
3
4> WARNING: This is an older guide under kernel 3.x using pci-stub
5> On newer kernels, you have to use vfio.
6
7Developing Haiku drivers for PCI and PCI Express cards is now a lot easier
8given advancements in IOMMU under Linux. You can effectively detach PCI cards
9from their host operating system and attach them to guest VM's resulting in
10true hardware emulation. In this guide we will be configuring a secondary
11graphics card to be attached to a Haiku virtual machine.
12
13**Warning**: Any device attached to a VM will be unavailable to the host operating
14system. This means you **cannot** use your primary graphics card, network device,
15etc within a VM and the host operating system at the same time. In this
16example, we have two graphics cards installed in the Linux system.
17
18IOMMU Setup
19-----------------------
20You will need to have IOMMU hardware support on your motherboard for this
21to function. Most modern AMD A3 socket chips and Intel i3/i5/i7 devices
22have IOMMU built in. If your board does indeed have IOMMU, you will likely
23need to enable IOMMU within the bios of your motherboard before proceeding.
24
25Linux Setup
26-----------------------
27Now that you have an IOMMU enabled system, you will need to tell Linux to
28fully utilize IOMMU. To do this, you will need to add a few kernel boot
29parameters. Depending on how your system is configured, there may be a few
30places to do this. Here are some example config files:
31
32 * `/etc/default/grub` (`GRUB_CMDLINE_LINUX_DEFAULT`)
33 * `/boot/grub/grub.cfg`
34 * `/boot/grub/menu.lst`
35 * `/boot/refind_linux.conf`
36
37Enabling OS support IOMMU for IOMMU involves adding one of the following
38kernel boot parameters:
39
40**AMD:**
41```
42iommu=pt iommu=1
43```
44**Intel:**
45```
46intel_iommu=on
47```
48
49Now, all we need to do is to reserve the PCI device. We want to make sure
50no host drivers attempt to attach to the PCI device in question.
51
52First we need to find the PCIID for the device in question. We can find
53this through lcpci. Running lspci shows a bunch of devices. I've identified
54this device as my target:
55
56```
5707:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Cedar [Radeon HD 5000]
58```
59
60Now, to get the PCI ID, I run lspci again with the -n flag (lspci -n). We find
61the matching BUS ID and we get our PCI ID:
62
63```
6407:00.0 0300: 1002:68f9
65```
66
67Now that we have our target PCI ID (`1002:68f9`), we can bind this device to
68a special pci-stub driver.
69
70We will create two files for this graphics card:
71
72**`/lib/modprobe.d/pci-stub.conf`:**
73```
74options pci-stub ids=1002:68f9
75```
76
77**`/lib/modprobe.d/drm.conf`:**
78```
79softdep drm pre: pci-stub
80```
81
82The first line tells the pci-stub driver to bind to the device in question.
83The second line tells DRM (graphics driver stack) that it should make sure
84pci-stub loads before DRM (ensuring the device is stubbed and not loaded by
85DRM).
86
87Now we reboot and cross our fingers.
88
89On my AMD Linux system, we can see that IOMMU is active and functional:
90
91```
92kallisti5@eris ~ $ dmesg | grep AMD-Vi
93[    0.119400] [Firmware Bug]: AMD-Vi: IOAPIC[9] not in IVRS table
94[    0.119406] [Firmware Bug]: AMD-Vi: IOAPIC[10] not in IVRS table
95[    0.119409] [Firmware Bug]: AMD-Vi: No southbridge IOAPIC found
96[    0.119412] AMD-Vi: Disabling interrupt remapping
97[    1.823122] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
98[    1.823253] AMD-Vi: Initialized for Passthrough Mode
99```
100
101And checking for pci-stub we can see it successfully took over my graphics card:
102```
103kallisti5@eris ~ $ dmesg | grep pci-stub
104[    3.685970] pci-stub: add 1002:68F9 sub=FFFFFFFF:FFFFFFFF cls=00000000/00000000
105[    3.686002] pci-stub 0000:07:00.0: claimed by stub
106```
107
108On every boot, the device will be available for attachment to VM's
109Now, we simply attach the device to a VM:
110
111```
112sudo qemu-system-x86_64 --enable-kvm -hda haiku-nightly-anyboot.image -m 2048 -device pci-assign,host=07:00.0
113```
114
115If you experience any problems, try looking at kvm messages:
116```
117kallisti5@eris ~ $ dmesg | grep kvm
118```
119
120If you're doing this for a graphics card generally the qemu window will
121lock up at the bootsplash and the video will appear on the second window.
122Click the qemu window to control the Haiku machine.
123
124If things go well you will see:
125```
126[ 1966.132176] kvm: Nested Virtualization enabled
127[ 1966.132185] kvm: Nested Paging enabled
128[ 1972.212231] pci-stub 0000:07:00.0: kvm assign device
129[ 1974.186382] kvm: zapping shadow pages for mmio generation wraparound
130```
131