Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Merge pull request #9 from RotatingFans/opregion-decoding
Browse files Browse the repository at this point in the history
Added Automatic Display Detection. Also General Fixes.
  • Loading branch information
Patrick Magauran committed Nov 30, 2020
2 parents 593549e + fe9faed commit fce6788
Show file tree
Hide file tree
Showing 22 changed files with 2,775 additions and 130 deletions.
89 changes: 33 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,43 @@
# VBIOS for Intel GPU Passthrough

This project attempts to create a UEFI driver for the intel integrated GPUS so that they can be used in VFIO Passthrough. Prior to this driver, there was no easy or reliable solution to both virtualized and direct passthrough(GVT-G/D). This driver adds an opRegion for the iGPU to utilize during the Boot Process, allowing for access to the UEFI menus and any other interfaces that are created before an operating system level driver is initialized. As a bonus, this allows for MacOS to boot in this virtual environment.

## Notice

*This Software deals directly with the graphics hardware and interfaces. I assume no responsibility should it cause any damage to your GPUs, Cables, Displays, Other hardware, or persons. It has been tested on my personal machine, but **you are using this software at your own risk.***

Disclaimer: When used in direct passthrough, this VBIOS could produce bad pixel clock that can potentially damage your monitor! Make sure your monitor has protections against that. I'm not responsible for any monitor damage.

## Current Feature Support

* Boot a virtual intel GPU(GVT-G)
* Passthrough the entire Intel GPU (GVT-D)
* Display Port interfaces
* eDP interfaces, including Laptop Screens
* HDMI interfaces
* Theoretically compatible with any 14nm chip(Skylake, Kaby lake, Coffee Lake, Amber Lake, Whiskey Lake, Comet Lake).
* Auto detect Outputs and types(**NEW**)

## Possible Features to come

* Allow for generation Specific Quirks
* Allow for other it to work with other intel CPU Generations.

## Known Issues

* May have issues with thunderbolt eGPUs. If you encounter problems, try with it unplugged
* GVT-G may struggle with external displays(even if through an eGPU or other GPU)

## What is this

This is an independent Video BIOS for Intel integrated GPUs. It provides a boot display and sets up an OpRegion so that Windows guests can produce monitor output.

The OpRegion code comes from IgdAssignmentDxe and should work everywhere. The boot display works for GVT-g and can safely replace ramfb. For direct passthrough, the boot display only works with the exact combination of an HDMI monitor and an Intel Skylake processor.

## How to build

1. Make a workspace folder, for example: `i915-development`
2. Clone the EDK II, EDKII-Platforms, and this repo into the folder you just created
3. In the EDK II folder, run `git submodule update --init` to download the submodules
4. In the workspace folder, make a new folder called `Conf`
5. Run `cp i915ovmfPkg/target.txt Conf/target.txt`
6. Run:

```
ln -s ./i915ovmfPkg ./edk2/
# Create an empty FAT disk image
dd if=/dev/zero of=disk bs=128M count=1
sudo mkfs.vfat disk
mkdir i915_simple
cp disk i915_simple/
```

7. Edit i915ovmfpkg/test and i915ovmfpkg/test-gvt-d to update the WORKSPACE variable to your workspace you created earlier.
8. Then run `./t` to build and test. Due to GVT-g and EFI shenanigans, the testing process needs root.

**NOTE** Compilation requires the following dependencies(names are not correct):

- lib-uuid-devel
- iasl
- nasm
- git
- clang
- lld-devel
- llvm-devel

If you just want to use it for your VM, grab the rom file in Releases.
**NOTE** Currently, using this rom causes the intel thunderbolt controller to reset. Using a thunderbolt e-gpu may cause the system to crash.

## VFIO Setup
Refer to the [Arch Linux wiki Guide for passthrough](https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF) and [for GVT-G](https://wiki.archlinux.org/index.php/Intel_GVT-g)
1. Install QEMU & the ovmf packages as appropriate for your distributions
2. Copy the ovmf.fd file from the appropriate locati
3. Add the following kernel parameters: `intel_iommu=on iommu=pt`
4. Reboot and run the included `iommu.sh` script to list your iommu groups and PCI ids. Script courtesy of Arch Linux Guide
5. In the ouput, search for the intel GPU. Note both the PCI location(eg 00:02.0) and the id(eg 8086:1234)
6. Follow the appropriate instructions below for what you are doing (GVT-d/g)

### GVT-G
1. Enable the kernel modules: `kvmgt`,`vfio-iommu-type1`,`vfio-mdev`
2. Add the following kernel parameter: `i915.enable_gvt=1`
3. Reboot and determine your avaiable GVT-g modes by running the folloiwng command: `ls /sys/devices/pci${GVT_DOM}/$GVT_PCI/mdev_supported_types` where GVT_DOM is the PCI Domain(Typically 0000) and GVT_PCI is the PCI location noted earlier. If you have trouble, use the command lspci -D -nn and locate the intel gpu to get the correct domain/location.
4. Update the Type variable in test to one of the listed modes for your gpu.

### GVT-d
1. Add the following kernel parameter: `vfio-pci.ids=PCIID` where PCIID is the ID obtained earlier(eg 8086:1234)
2. Enable the following kernel modules: `vfio_pci vfio vfio_iommu_type1 vfio_virqfd`
3. Reboot
4. Update the test-gvt-d with the correct PCI location
The OpRegion code comes from IgdAssignmentDxe and should work everywhere. The boot display works for GVT-g and can safely replace ramfb. For direct passthrough, the boot display Works on intel 14nm based CPUS and HDMI/DP/eDP displays(Inlcuding laptop Screens!).

## Usage

Please see the Wiki for more information regarding compiling, usage, or further information.

## License

I have no idea what this should be licensed in, but the code came from:
Expand All @@ -70,3 +46,4 @@ I have no idea what this should be licensed in, but the code came from:
- IgdAssignmentDxe: non-upstreamed Intel patch to OVMF
- EDK II: https://github.com/tianocore/edk2
- The Linux kernel
- Intel-gpu-tools: https://cgit.freedesktop.org/xorg/app/intel-gpu-tools/tree/tools
8 changes: 8 additions & 0 deletions Release/iommu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
shopt -s nullglob
for g in /sys/kernel/iommu_groups/*; do
echo "IOMMU Group ${g##*/}:"
for d in $g/devices/*; do
echo -e "\t$(lspci -nns ${d##*/})"
done;
done;
22 changes: 22 additions & 0 deletions Release/test-gvt-d.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
export WORKSPACE=/home/patrick/i915dev/Release
export PCILOC=0000:00:02.0
export PCIID=8086:9bca

cd $WORKSPACE

cd ./i915_simple

# Create an UEFI disk that immediately shuts down the VM when booted
mkdir -p tmpfat
mount disk tmpfat
mkdir -p tmpfat/EFI/BOOT
umount tmpfat
rmdir tmpfat
systemctl stop display-manager.service
echo $PCIID > /sys/bus/pci/drivers/vfio-pci/new_id
echo $PCILOC> /sys/bus/pci/devices/$PCILOC/driver/unbind
echo $PCILOC > /sys/bus/pci/drivers/vfio-pci/bind
#qemu-system-x86_64 -k en-us -name uefitest,debug-threads=on -nographic -vga none -serial stdio -m 2048 -M pc -cpu host -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -machine kernel_irqchip=on -nodefaults -rtc base=localtime,driftfix=slew -no-hpet -global kvm-pit.lost_tick_policy=discard -enable-kvm -bios $WORKSPACE/OVMF_CODE.fd -device vfio-pci,host=$PCILOC,romfile=`pwd`/i915ovmf.rom -device qemu-xhci,p2=8,p3=8 -device usb-kbd -device usb-tablet -drive format=raw,file=disk -usb
timeout --foreground -k 1 8 qemu-system-x86_64 -k en-us -name uefitest,debug-threads=on -nographic -vga none -chardev stdio,id=char0,logfile=serial.log,signal=off \
-serial chardev:char0 -m 2048 -M pc -cpu host -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -machine kernel_irqchip=on -nodefaults -rtc base=localtime,driftfix=slew -no-hpet -global kvm-pit.lost_tick_policy=discard -enable-kvm -bios $WORKSPACE/OVMF_CODE.fd -device vfio-pci,host=$PCILOC,romfile=`pwd`/i915ovmf.rom -device qemu-xhci,p2=8,p3=8 -device usb-kbd -device usb-tablet -drive format=raw,file=disk -usb
26 changes: 26 additions & 0 deletions Release/test-gvt-g.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
export WORKSPACE=/home/patrick/development
export PCILOC=00:02.0
export PCIID=8086:9bca
export GVTMODE=i915-GVTg_V5_4


cd ./i915_simple

if [ -e /sys/bus/pci/devices/0000:$PCILOC/2aee154e-7d0d-11e8-88b8-6f45320c7162 ]
then
true
else
modprobe kvmgt || exit
#sudo dd if=/sys/class/drm/card0-HDMI-A-1/edid of=/sys/class/drm/card0/gvt_edid bs=128 count=1
echo 2aee154e-7d0d-11e8-88b8-6f45320c7162 > /sys/bus/pci/devices/0000:$PCILOC/mdev_supported_types/$GVTMODE/create || exit
fi

# Create an UEFI disk that immediately shuts down the VM when booted
mkdir -p tmpfat
mount disk tmpfat
mkdir -p tmpfat/EFI/BOOT
umount tmpfat
rmdir tmpfat

qemu-system-x86_64 -k en-us -name uefitest,debug-threads=on -serial stdio -m 2048 -M pc -cpu host -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -machine kernel_irqchip=on -nodefaults -rtc base=localtime,driftfix=slew -no-hpet -global kvm-pit.lost_tick_policy=discard -enable-kvm -bios $WORKSPACE/OVMF_CODE.fd -display gtk,gl=on,grab-on-hover=on -full-screen -vga none -device vfio-pci,sysfsdev=/sys/bus/pci/devices/0000:$PCILOC/2aee154e-7d0d-11e8-88b8-6f45320c7162,addr=02.0,display=on,x-igd-opregion=on,romfile=`pwd`/i915ovmf.rom -device qemu-xhci,p2=8,p3=8 -device usb-kbd -device usb-tablet -drive format=raw,file=disk
Loading

0 comments on commit fce6788

Please sign in to comment.