Usually, on AArch64 systems with proprietary UEFI firmware, a HDMI/DP display does not light up until the point where the OS driver takes control. This makes it tedious to access the UEFI configuration menus or the GRUB bootloader menu, since it either requires connecting a VGA monitor to the BMC, or finding it on the network and connecting to it.
Also, OS drivers for GPUs are all developed and tested under the assumption that the option ROM driver has executed when the OS takes over. This means any errata handling or OEM tweaks may not take effect as they would otherwise.
For AMD cards, it is possible to address this problem by replacing the x86 EFI driver on the card with an AArch64 one (or adding one if only a legacy x86 driver was there in the first place)
- Build
flashrom
from theati
branch at https://github.com/ardbiesheuvel/flashrom - Check out
edk2
(https://github.com/tianocore/edk2) and build the base tools (make -C BaseTools/
) -
Dump the option ROM (as root)
# ./flashrom -p ati_spi -r vbios.rom
(Note that the ati_spi driver is currently hardcoded to support PCI domain/segment #0 only. )
- List the table of contents
$ edk2/BaseTools/Source/C/bin/EfiRom -d vbios.rom Image 1 -- Offset 0x0 ROM header contents Signature 0xAA55 PCIR offset 0x0244 Signature PCIR Vendor ID 0x1002 Device ID 0x67DF Length 0x0018 Revision 0x0000 DeviceListOffset 0x00 Class Code 0x030000 Image size 0xEA00 Code revision: 0x0F32 MaxRuntimeImageLength 0x00 ConfigUtilityCodeHeaderOffset 0x4D41 DMTFCLPEntryPointOffset 0x2044 Indicator 0x00 Code type 0x00 Image 2 -- Offset 0xEA00 ROM header contents Signature 0xAA55 PCIR offset 0x001C Signature PCIR Vendor ID 0x1002 Device ID 0x67DF Length 0x0018 Revision 0x0000 DeviceListOffset 0x00 Class Code 0x030000 Image size 0xE600 Code revision: 0x0000 MaxRuntimeImageLength 0x00 ConfigUtilityCodeHeaderOffset 0x4F47 DMTFCLPEntryPointOffset 0x2050 Indicator 0x80 (last image) Code type 0x03 (EFI image) EFI ROM header contents EFI Signature 0x0EF1 Compression Type 0x0001 (compressed) Machine type 0x8664 (X64) Subsystem 0x000B (EFI boot service driver) EFI image offset 0x0058 (@0xEA58)
The first image contains the ATOM BIOS code, and should be kept – it is loaded by the OS driver when it probes the card. The second image is the existing x86 EFI driver.
- Create a compressed option ROM image from the AMD GOP driver for arm64 (https://www.amd.com/en/support/kb/release-notes/rn-aar), using the vendor and device IDs taken from the output above.
$ edk2/BaseTools/Source/C/bin/EfiRom -f 0x1002 -i 0x67DF -l 0x030000 -ec Arm64Gop_1_68.efi
This will create a file called
Arm64Gop_1_68.rom
in the current directory. -
Copy the ROM image to a new file, and store the old one for safe keeping.
-
If the ROM image has sufficient space for an additional driver and you want to keep the x86 EFI driver, or if it does not have a EFI driver in the first place, you will need to use a hex editor to find the 0x80 ‘indicator’ byte at offset 22 of the last header that starts with
PCIR
, and change it to 0x0. -
Insert the AMD GOP option ROM image into the copy of the option ROM
$ dd if=Arm64Gop_1_68.rom of=vbios_new.rom conv=notrunc seek=<byte offset>
where byte offset equals offset + size of the preceding image. Note that this must be a multiple of 512. For the image above, this would be
0xea00 + 0xe600
, assuming we are keeping the x86 driver (or 0xea00 if not). - Dump the new image contents to double check that everything looks as expected.
$ edk2/BaseTools/Source/C/bin/EfiRom -d vbios_new.rom Image 1 -- Offset 0x0 ROM header contents Signature 0xAA55 PCIR offset 0x0244 Signature PCIR Vendor ID 0x1002 Device ID 0x67DF Length 0x0018 Revision 0x0000 DeviceListOffset 0x00 Class Code 0x030000 Image size 0xEA00 Code revision: 0x0F32 MaxRuntimeImageLength 0x00 ConfigUtilityCodeHeaderOffset 0x4D41 DMTFCLPEntryPointOffset 0x2044 Indicator 0x00 Code type 0x00 Image 2 -- Offset 0xEA00 ROM header contents Signature 0xAA55 PCIR offset 0x001C Signature PCIR Vendor ID 0x1002 Device ID 0x67DF Length 0x0018 Revision 0x0000 DeviceListOffset 0x00 Class Code 0x030000 Image size 0xE600 Code revision: 0x0000 MaxRuntimeImageLength 0x00 ConfigUtilityCodeHeaderOffset 0x4F47 DMTFCLPEntryPointOffset 0x2050 Indicator 0x00 Code type 0x03 (EFI image) EFI ROM header contents EFI Signature 0x0EF1 Compression Type 0x0001 (compressed) Machine type 0x8664 (X64) Subsystem 0x000B (EFI boot service driver) EFI image offset 0x0058 (@0xEA58) Image 3 -- Offset 0x1D000 ROM header contents Signature 0xAA55 PCIR offset 0x001C Signature PCIR Vendor ID 0x1002 Device ID 0x67DF Length 0x001C Revision 0x0003 DeviceListOffset 0x00 Class Code 0x030000 Image size 0xFA00 Code revision: 0x0000 MaxRuntimeImageLength 0x00 ConfigUtilityCodeHeaderOffset 0x00 DMTFCLPEntryPointOffset 0x00 Indicator 0x80 (last image) Code type 0x03 (EFI image) EFI ROM header contents EFI Signature 0x0EF1 Compression Type 0x0001 (compressed) Machine type 0xAA64 (AA64) Subsystem 0x000B (EFI boot service driver) EFI image offset 0x0038 (@0x1D038)
- Use
flashrom
with the -w switch to write the new image back to the device. -
In the UEFI shell, the ‘drivers’ command will list all the UEFI drivers that have been loaded. E.g.,
D1 00014400 D - - 1 - AMD GOP ARM64 Release Driver, Rev. Offset(0x1D000,...
where the ‘D’ in the third column signifies that it has attached to the device.