ppc64le-edk2 icon indicating copy to clipboard operation
ppc64le-edk2 copied to clipboard

TianoCore UEFI for OPAL/PowerNV (PPC64/PowerPC64 Little-Endian)

TianoCore on PowerPC 64 Little-Endian (OPAL/PowerNV)

This is "UEFI" on top of OPAL firmware.

"UEFI" because the specification doesn't include PowerPC yet (ever?).

At some point this experiment will implement reduced-hardware "ACPI" support, mapping the OPAL-based FDT into "ACPI" structures.

"ACPI" because it's also not specced out for PowerPC.

It's getting prototyped on top of QEMU and Skiboot (OPAL firmware).

I feel a sense of Deja Vu...

This is not at all related to Benjamin Herrenschmidt's PowerNV EDK2 tree over at his GitHub.

That tree is the one you should probably be looking at.

https://github.com/ozbenh/edk2

But if are interested in an alternate and completely unrelated implementation, that is most certainly never going to go anywhere beyond a proof of concept, then read on :-).

Why

It's thought experiment gone too far. In short, there's IMO value in presenting a common firmware environment shared with other servers (X64, AARCH64). UEFI+ACPI keep the OEMs and IHVs in their comfort zone, and reduce pointless platform boot and configuration variance across different architectures. It also allows plug-in cards to work (assuming EBC ROMs). Petitboot is a nice idea in theory, but in practice it's probably more suitable to embedded environments rather than whitebox servers that can compete with Intel boxes.

UEFI gets us a bootloader environment and device drivers for I/O and booting via storage and networking. OPAL is the abstraction layer for the machine.

Status

Can boot to UEFI shell. As far as devices only the OPAL console is available.

See outstanding milestones and issues: https://github.com/andreiw/ppc64le-edk2/issues

Building

You will need a LE 64-bit toolchain to build (i.e. ppc64le-linux). A good source of toolchains is kernel.org.

After running ./edksetup.sh, modify your Conf/target.txt: ACTIVE_PLATFORM = PPC64Pkg/PPC64Pkg.dsc TOOL_CHAIN_TAG = GCC49

Then: $ GCC49_PPC64_PREFIX=ppc64le-linux- build

Running

You will need Skiboot and Benjamin Herrenschmidt's PowerNV QEMU tree.

Good directions for both QEMU/PowerNV and Skiboot: https://www.flamingspork.com/blog/2015/08/28/running-opal-in-qemu-the-powernv-platform/

After that, assuming skiboot.lid is in current working directory, $ qemu-system-ppc64 -m 4G -M powernv -nographic -kernel ~/src/edk2/Build/PPC64/DEBUG_GCC49/FV/POWERNV.fd

More invocation notes:

  • You may provide a FAT filesystem image via -initrd to be accessible from UEFI.
  • You may provide more RAM (-m 6G)
  • You may run with -s for gdb stubs. See section at end on debugging.

You should see skiboot messages, followed UEFI booting, eventually booting you to the shell.

Shell> Shell> devtree Ctrl[03] MemoryMapped(0xB,0x40000000,0x4035DFFF) Ctrl[18] VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1) Ctrl[33] Tty Terminal Serial Console Ctrl[2F] VenHw(3EBFA8E6-511D-4B5B-A95F-FB38260F1C27) Ctrl[30] VenHw(F76E0A70-B5ED-4C38-AC9A-E5F54BF16E34) Ctrl[31] VenHw(847BC3FE-B974-446D-9449-5AD5412E993B) Ctrl[32] VenHw(9E0C30BC-3F06-4BA6-8288-09179B855DBE) Shell> Shell> ver -_fv UEFI Interactive Shell v2.1 EDK II UEFI v2.50 (EDK II, 0x00010000) PPC64LE Prototype ABIv2 Shell>

Architecture considerations

TianoCore runs in HV mode and uses the hypervisor decrementer. Future work may consider autodetecting and being capable of running in priviledged mode only (such as in a VM).

Code is built as PIE ABIv2 or PIE ABIv1. The early work was done done with non-PIE ABIv1 (it's not possible to build non-PIE ABIv2).

Platform considerations

The booting flow on a PowerNV machine would look something like:


| hostboot | This is the low-level initialization.

 |

-----v------ | skiboot | This is the OPAL firmware.

 |

-----v------ | Ipl | This is UEFI loader that uses passed FDT and OPAL.

 |

-----v------ | DXE | This is proper UEFI.

 |

-----v------ | BDS | This is proper UEFI: we chose to boot an OS here.

 |

-----v------ | OS | OS can use FDT or ACPI.

The approach taken is encouraged by AArch32 UEFI implementations and by AArch64 Xen/QEMU virtual UEFI. A lot of EmbeddedPkg components and design decisions are leveraged.

Debugging

If you run qemu with -s you can debug UEFI with gdb via my DebugPkg. Last tested with gdb 7.10. You will need python support. I built my GDB with:

$ ./configure --target=ppc64le-linux --with-python && make

( needless to say the Python stuff won't work unless you make install or otherwise ensure that gdb's data-directory matches reality. I build my toolchains with a local prefix )

Then you can invoke gdb:

$ ppc64le-linux-gdb ~/src/edk2/Build/PPC64/DEBUG_GCC49/PPC64/GdbSyms.debug (gdb) (gdb) target remote localhost:1234 (gdb) (gdb) source ~/src/edk2/DebugPkg/Scripts/gdb_uefi.py (gdb) (gdb) reload-uefi -o ~/src/edk2/Build/PPC64/DEBUG_GCC49/PPC64/GdbSyms.debug EFI_SYSTEM_TABLE @ 0x208ca018 Connected to EDK II (Rev. 0x10000) ConfigurationTable @ 0x208ca0d8, 0x6 entries DebugImageInfoTable @ 0x11fffe018, 0x1d entries Loading new symbols... add-symbol-file /home/andreiw/src/edk2/Build/PPC64/DEBUG_GCC49/PPC64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll 0x208cd000 ... ... (gdb) (gdb) bt #0 0x000000011fd38200 in CpuPause () #1 0x000000011fd37c7c in TickDelay (Ticks=512000000) at /home/andreiw/src/edk2/PPC64Pkg/Library/TBTimerLib/TBTimerLib.c:41 #2 0x000000011fd37d0c in MicroSecondDelay (MicroSeconds=1000000) at /home/andreiw/src/edk2/PPC64Pkg/Library/TBTimerLib/TBTimerLib.c:68 ... ... (gdb)

Note that Ipl symbols won't be present since it's not accounted for in the EFI_DEBUG_IMAGE_INFO structures. You may want to consider applying the GDB module scope patch to ease some deubbing. See https://github.com/andreiw/andreiw-wip/tree/master/gdb

Contact Info

Andrei Warkentin ([email protected]).