On 2015-03-25 17:09, Alex Williamson wrote:
> On Wed, 2015-03-25 at 16:00 +0000, Gordan Bobic wrote:
>> On 2015-03-25 15:46, Alex Williamson wrote:
>> > On Wed, 2015-03-25 at 16:25 +0100, Laszlo Ersek wrote:
>> >> On 03/25/15 11:12, Gordan Bobic wrote:
>> >> > Hi,
>> >> >
>> >> > I'm trying to solve what should be a relatively simple problem
>> >> > of side-loading a GPU VBIOS but I am running into an unexpected
>> >> > problem.
>> >> >
>> >> > The setup is a laptop with Optimus setup (Intel primary + Nvidia
>> >> > headless), and I want to pass the headless Nvidia GPU to the KVM
>> >> > virtual machine. Unfortunately, the GPU appears to be
>> >> > uninitialized in the VM, judging by the GPU-Z symptoms.
>> >> >
>> >> > The VBIOS in question isn't on an EEPROM attached to the GPU, it
>> >> > is instead in the main system BIOS payload (which actually contains
>> >> > 3 Nvidia BIOS-es, presumably for different compatible GPUs). I
>> >> > extracted all the BIOS blobs using PhoenixTool and deduced the
>> >> > correct one, but the blob in question appears to have the EFI
>> >> > header missing - which means it looks much like a legacy BIOS,
>> >> > rather than an EFI one (type 0 header is there, but type 3
>> >> > header is not. But the crypto certs are in fact there in the
>> >> > BIOS payload, which indicates it is an EFI BIOS after all,
>> >> > only with the type 3 header stripped out.
>> >>
>> >> You can use the EfiRom utility from the edk2 git tree, with the
>> >> "--dump"
>> >> option, to "Dump the headers of an existing option ROM image".
>> >>
>> >> I don't know of any utility offhand that extracts images from
>> >> expansion
>> >> ROMs (splitting off the expansion ROM header and the PCI Data
>> >> Structure
>> >> etc).
>> >>
>> >> > Is the EFI header as described (usually 1KB on Nvidia Kepler
>> >> > BIOS-es and 1.5KB on Nvidia Maxwell BIOS-es) only applicable
>> >> > to discrete EFI BIOS-es? Is it handled differently if the
>> >> > GPU BIOS is integrated into the main system BIOS payload?
>> >>
>> >> Normally the UEFI driver is built as a UEFI executable. The EfiRom
>> >> utility (or another equivalent tool) is used to build it (possibly
>> >> together with other such executables) into an expansion ROM. This
>> >> procedure formats the "PCI Data Structure" and "PCI Expansion ROM
>> >> Header" structs into the output file, as specified in the "PCI (TM)
>> >> Firmware Specification Revision 3.1".
>> >>
>> >> > If so, is there a method for incorporating the GPU firmware
>> >> > I have extracted into the OVMF core instead of side-loading
>> >> > it?
>> >>
>> >> Yes, there is. (Well, assuming that whatever you extracted is indeed a
>> >> UEFI binary.)
>> >>
>> >> Method #1 is to place the binary somewhere appropriate in the edk2
>> >> tree,
>> >> write an INF file for it, include the INF file in
>> >> "OvmfPkg/OvmfPkgX64.fdf", and rebuild OVMF. Since this is going to be
>> >> a
>> >> binary-only module, you can refer to the following examples:
>> >> - FatBinPkg/EnhancedFatDxe/Fat.inf
>> >> - EdkShellBinPkg/FullShell/FullShell.inf
>> >>
>> >> Method #2 is similar, except you don't need to write an INF file.
>> >> Search
>> >> the same FDF file for "Intel3.5/EFIX64/E3507X2.EFI".
>> >>
>> >> Method #3 is to prepare a disk image with a FAT32 partition. Then copy
>> >> the extracted binary to this filesystem, using mtools or guestfish.
>> >> During OVMF boot, enter the UEFI shell, and load the driver binary
>> >> with
>> >> the "load" command from this filesystem. (This should also connect the
>> >> driver to matching devices at once.)
>> >>
>> >> Hm, I'm just noticing method #4: the UEFI shell has a command called
>> >> "loadpcirom", which "Loads a UEFI driver from a file in the format of
>> >> a
>> >> PCI Option ROM".
>> >
>> > That's really cool that there are so many ways to do it, but IMHO the
>> > most maintenance-free solution seems like it would be to stuff that
>> > UEFI
>> > binary into a PCI option ROM format and expose it to the VM as if the
>> > GPU had a PCI option ROM, using the romfile= parameter (or <rom
>> > file=''/> in libvirt).  Then you don't need a custom OVMF build, nor do
>> > you need to do any prep work to pre-load the UEFI driver into the EFI
>> > partition.  Thanks,
>> 
>> That was the first thing I tried, but I'm finding it difficult to
>> spot from the OVMF debug log to even tell if it is being loaded
>> and executed, let alone of it works.
> 
> If the ROM doesn't start with AA55, then it's not a valid PCI option 
> ROM
> and won't be processed.

It does begin with AA55 (well, 55AA, but it's in little-endian order):

# xxd GTX860M.rom | head -20
0000000: 55aa cbeb 4b37 3430 30e9 4c19 77cc 5649  U...K7400.L.w.VI
0000010: 4445 4f20 0d00 0000 9001 f71a 0000 4942  DEO ..........IB
0000020: 4d20 5647 4120 436f 6d70 6174 6962 6c65  M VGA Compatible
0000030: 0100 0000 4000 5a57 3033 2f31 382f 3134  [email protected]/18/14
0000040: 0000 0000 0000 0000 8010 5000 51fc 0000  ..........P.Q...
0000050: e978 2b00 aa17 1238 ffff ffff 0000 0000  .x+....8........
0000060: efff ffff 0000 0080 5c56 a541 e925 49e9  ........\V.A.%I.
0000070: 2c49 504d 4944 6c00 6f00 0000 00a0 00b0  ,IPMIDl.o.......
0000080: 00b8 00c0 0033 474d 3130 3720 4532 3730  .....3GM107 E270
0000090: 3420 534b 5520 3130 2056 4741 2042 494f  4 SKU 10 VGA BIO
00000a0: 5320 2848 5744 4941 4729 0d0a 0000 0000  S (HWDIAG)......
00000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000d0: 0000 0000 0000 0056 6572 7369 6f6e 2038  .......Version 8
00000e0: 322e 3037 2e33 342e 3030 2e30 3820 0d0a  2.07.34.00.08 ..
00000f0: 0043 6f70 7972 6967 6874 2028 4329 2031  .Copyright (C) 1
0000100: 3939 362d 3230 3134 204e 5649 4449 4120  996-2014 NVIDIA
0000110: 436f 7270 2e0d 0a00 0000 ffff 0000 0000  Corp............
0000120: ffff 474d 3130 3720 426f 6172 6420 2d20  ..GM107 Board -
0000130: 3237 3034 3030 3130 0000 0000 0000 0000  27040010........


> If you're running a version of OVMF without CSM
> support and the ROM doesn't include a valid type 3 header, then it will
> not be processed, regardless of whether you believe it's actually a 
> UEFI
> payload.  What you have in the other reply looks like a legacy BIOS, 
> and
> it very well may work as such, but it's going to require the CSM and
> likely make callbacks that require VGA support, which is what I expect
> you're trying to avoid by using OVMF.

I tried the OVMF-with-csm firmware, and that seems to take quite a long
time to get to the shell, but in the end the result is the same.

On Nvidia cards starting with 6xx series, the legacy BIOS is
essentially wrapped - there is a type 3 header (1024 bytes on Kepler
GPUs, 1536 bytes on Maxwell GPUs), followed by the legacy BIOS payload,
followed by the EFI crypto certs.

What appears to have been extracted from the system BIOS on my laptop
is a front-truncated EFI VBIOS, with the EFI header missing. But
looking at what PhoenixTool reports about the structures, the numbers
are correct - there is no extra payload being reported.

Which makes me wonder if Insyde UEFI system firmware is just being
weird and proprietary.

> If the blob you suspect as being
> a raw UEFI binary (I'm not as hopeful as you and Laszlo seem to be) can
> be used as a ROM, it would at least need to be wrapped in a PCI option
> ROM header.  Thanks,

I'm pretty sure it is a valid PCI option ROM, it's just the type 3
header that seems to be missing. :( Does that mean I am plain out
of luck?

Gordan

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to