[edk2-devel] [PATCH v1 0/6] Add Raspberry Pi Support to EmulatorPkg
Ard Biesheuvel
ardb at kernel.org
Fri Mar 10 16:45:41 UTC 2023
Hello Nate,
On Mon, 6 Mar 2023 at 01:22, Nate DeSimone
<nathaniel.l.desimone at intel.com> wrote:
>
> This patch series is the result of a fun weekend project that I
> did in my spare time. It implements the changes nessesary for
> EmulatorPkg to run on the Raspberry Pi. It should also work on
> other 32-bit ARM systems, but I only specifically tested on
> Raspberry Pi OS (formerly Raspbian.)
>
It works fine on 64-bit ARM systems that support 32-bit user space as
well. I managed to build and run this on my Qualcomm Snapdragon based
Lenovo Yoga C630 laptop running Debian Linux.
So
Tested-by: Ard Biesheuvel <ardb at kernel.org>
Also, good job!! This is really nice.
One nit: I had to add -mfpu=vfpv3 to the compiler command line in
Host.inf to work around a build error.
> I ran into several interesting issues during the development of
> this patch series and it ended up being a good learning
> experience for me. Some things of note are:
>
> 1 - Assembly Code
>
> There are several pieces of assembly code in EmulatorPkg that need
> to be rewritten when porting to a new machine architecture. This
> code fell into two categories, stack manipulation and "gaskets."
>
> 2 - ABI Differences
>
> The most significant amount of assembly code is the "gasket"
> functions. The gasket functions are responsible for converting from
> the UNIX ABI to the EFI ABI. They enable EmulatorPkg to
> support executing arbitary UEFI binaries without needing
> recompilation specifically for EmulatorPkg. X86 has many ABI
> specifications that vary based on target OS and compiler toolchain.
> There have been several attempts to unify things on the x86 side,
> but they usually just result in the addition of yet another ABI.
> Things are much more uniform on ARM due to wide acceptance of the
> AAPCS. Due to this, the ABI differences between UNIX and EFI boil
> down to passing of variadic arguments and enum values. Neither of
> these cases apply to the function signatures for the gaskets.
> Therefore, on ARM these gaskets can be simple wrapper functions
> written in C since the UNIX and EFI ABIs are identical... at least
> for the set of functions that need gaskets.
>
Glad to hear that. I assume this would apply to AArch64 as well.
> 3 - Instruction Cache Maintenance
>
> Because EmulatorPkg and edk2 in general contains a PE/COFF loader,
> it counts as "self-modifying code". The way self modifying code is
> handled on ARM is considerably more complex than x86. While on x86
> there is no requirement for self-modifying code to flush the
> instruction cache, on ARM failure to do so will result in incorrect
> behavior. Additionally, flushing the cache is considerably more
> difficult on ARM. On x86, one can simply add a CLFLUSH or WBINVD
> instruction; they are perfectly valid to execute while in Ring 3.
> On ARM, flushing the cache requires one to write to system control
> registers, which can only be done in EL1 (kernel mode) or higher.
> Therefore, while flushing the cache can be done on in the x86
> version of EmulatorPkg without any interaction with the OS, on ARM
> we need to invoke OS syscalls.
>
> To accomodate this, I have added a new EMU_IO_THUNK_PROTOCOL that
> implements the CacheMaintenanceLib LibraryClass. This new
> implementation uses the GCC intrinsic function
> __builtin_clear_cache(), which on x86 gets converted into a CLFLUSH
> instruction by the compiler. On ARM, it gets converted into a call
> to the __clear_cache() API in libgcc. The ARM implementation of
> libgcc invokes the ARM_cacheflush syscall (0xF0002), which only
> exists in kernels built for the ARM architecture.
>
> I have added wrapper implementations of the CacheMaintenanceLib
> LibraryClass for PEI and DXE that use the EMU_THUNK infrastructure
> to acquire the EMU_CACHE_THUNK_PROTOCOL and invoke the equivilent
> functions, which in turn will use the GCC intrinsic mentioned
> above.
>
> I have only enable this version of CacheMaintenanceLib on the ARM
> architecture, because it will take several thousand CPU
> instructions to execute, as opposed to about ten on the current x86
> implementation.
>
I think this is reasonable, but I am not a EmulatorPkg maintainer so I
will defer to them to comment on this approach.
> Testing Done:
>
> Boots to shell on Raspberry Pi OS "bullseye."
>
> Cc: Andrew Fish <afish at apple.com>
> Cc: Ray Ni <ray.ni at intel.com>
> Cc: Leif Lindholm <quic_llindhol at quicinc.com>
> Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
> Cc: Sami Mujawar <sami.mujawar at arm.com>
> Cc: Michael D Kinney <michael.d.kinney at intel.com>
> Cc: Chasel Chiu <chasel.chiu at intel.com>
> Signed-off-by: Nate DeSimone <nathaniel.l.desimone at intel.com>
>
> Nate DeSimone (6):
> ArmPkg: Add ArmMmuNullLib
Given the recent focus on memory protections - could we turn this into
a EmuPkg specific one that calls the OS's mprotect() under the hood?
> EmulatorPkg: Add ARM Build Target
> EmulatorPkg: Fix PosixFileSystem function misspellings
> EmulatorPkg: Add ARM support to UNIX Host App
> EmulatorPkg: Add ARM support to EmuSec
> EmulatorPkg: Add EmuCacheMaintenanceLib
>
> ArmPkg/ArmPkg.dsc | 2 +
> ArmPkg/Library/ArmMmuNullLib/ArmMmuNullLib.c | 84 ++
> .../Library/ArmMmuNullLib/ArmMmuNullLib.inf | 36 +
> EmulatorPkg/EmulatorPkg.dec | 4 +-
> EmulatorPkg/EmulatorPkg.dsc | 29 +-
> EmulatorPkg/EmulatorPkg.fdf | 6 +-
> EmulatorPkg/Include/Protocol/EmuCache.h | 217 ++++
> .../DxeEmuCacheMaintenanceLib.c | 337 +++++
> .../DxeEmuCacheMaintenanceLib.inf | 37 +
> .../PeiEmuCacheMaintenanceLib.c | 344 ++++++
> .../PeiEmuCacheMaintenanceLib.inf | 39 +
> EmulatorPkg/Sec/Arm/SwitchRam.S | 32 +
> EmulatorPkg/Sec/Arm/TempRam.c | 58 +
> EmulatorPkg/Sec/Sec.inf | 9 +-
> EmulatorPkg/Unix/Host/Arm/Gasket.c | 895 ++++++++++++++
> .../Unix/Host/Arm/GasketFunctionDefinitions.h | 1092 +++++++++++++++++
> EmulatorPkg/Unix/Host/Arm/SwitchStack.S | 39 +
> EmulatorPkg/Unix/Host/CacheMaintenance.c | 284 +++++
> EmulatorPkg/Unix/Host/Gasket.h | 12 +-
> EmulatorPkg/Unix/Host/Host.c | 5 +-
> EmulatorPkg/Unix/Host/Host.h | 2 +
> EmulatorPkg/Unix/Host/Host.inf | 14 +-
> EmulatorPkg/Unix/Host/Ia32/Gasket.S | 31 +-
> EmulatorPkg/Unix/Host/PosixFileSystem.c | 22 +-
> EmulatorPkg/Unix/Host/X64/Gasket.S | 31 +-
> EmulatorPkg/build.sh | 13 +-
> 26 files changed, 3617 insertions(+), 57 deletions(-)
> create mode 100644 ArmPkg/Library/ArmMmuNullLib/ArmMmuNullLib.c
> create mode 100644 ArmPkg/Library/ArmMmuNullLib/ArmMmuNullLib.inf
> create mode 100644 EmulatorPkg/Include/Protocol/EmuCache.h
> create mode 100644 EmulatorPkg/Library/DxeEmuCacheMaintenanceLib/DxeEmuCacheMaintenanceLib.c
> create mode 100644 EmulatorPkg/Library/DxeEmuCacheMaintenanceLib/DxeEmuCacheMaintenanceLib.inf
> create mode 100644 EmulatorPkg/Library/PeiEmuCacheMaintenanceLib/PeiEmuCacheMaintenanceLib.c
> create mode 100644 EmulatorPkg/Library/PeiEmuCacheMaintenanceLib/PeiEmuCacheMaintenanceLib.inf
> create mode 100644 EmulatorPkg/Sec/Arm/SwitchRam.S
> create mode 100644 EmulatorPkg/Sec/Arm/TempRam.c
> create mode 100644 EmulatorPkg/Unix/Host/Arm/Gasket.c
> create mode 100644 EmulatorPkg/Unix/Host/Arm/GasketFunctionDefinitions.h
> create mode 100644 EmulatorPkg/Unix/Host/Arm/SwitchStack.S
> create mode 100644 EmulatorPkg/Unix/Host/CacheMaintenance.c
>
> --
> 2.30.2
>
>
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#101006): https://edk2.groups.io/g/devel/message/101006
Mute This Topic: https://groups.io/mt/97414907/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
More information about the edk2-devel-archive
mailing list