From: "Ard Biesheuvel" <ardb@kernel.org>
To: devel@edk2.groups.io, nathaniel.l.desimone@intel.com
Cc: Andrew Fish <afish@apple.com>, Ray Ni <ray.ni@intel.com>,
Leif Lindholm <quic_llindhol@quicinc.com>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
Sami Mujawar <sami.mujawar@arm.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Chasel Chiu <chasel.chiu@intel.com>
Subject: Re: [edk2-devel] [PATCH v1 0/6] Add Raspberry Pi Support to EmulatorPkg
Date: Fri, 10 Mar 2023 17:45:41 +0100 [thread overview]
Message-ID: <CAMj1kXEmszKEA=nH061Rhc1w-ZExA0zHDBLYMN9tVYva2CXDBQ@mail.gmail.com> (raw)
In-Reply-To: <20230306002205.1640-1-nathaniel.l.desimone@intel.com>
Hello Nate,
On Mon, 6 Mar 2023 at 01:22, Nate DeSimone
<nathaniel.l.desimone@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@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@apple.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Sami Mujawar <sami.mujawar@arm.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Signed-off-by: Nate DeSimone <nathaniel.l.desimone@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
>
>
>
>
>
>
next prev parent reply other threads:[~2023-03-10 16:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-06 0:21 [PATCH v1 0/6] Add Raspberry Pi Support to EmulatorPkg Nate DeSimone
2023-03-06 0:22 ` [PATCH v1 1/6] ArmPkg: Add ArmMmuNullLib Nate DeSimone
2023-03-06 0:22 ` [PATCH v1 2/6] EmulatorPkg: Add ARM Build Target Nate DeSimone
2023-03-06 0:22 ` [PATCH v1 3/6] EmulatorPkg: Fix PosixFileSystem function misspellings Nate DeSimone
2023-03-06 0:22 ` [PATCH v1 4/6] EmulatorPkg: Add ARM support to UNIX Host App Nate DeSimone
2023-03-06 0:22 ` [PATCH v1 5/6] EmulatorPkg: Add ARM support to EmuSec Nate DeSimone
2023-03-06 0:22 ` [PATCH v1 6/6] EmulatorPkg: Add EmuCacheMaintenanceLib Nate DeSimone
2023-03-10 16:45 ` Ard Biesheuvel [this message]
[not found] <1749AC9E6FAD5EA2.26261@groups.io>
2023-03-06 0:27 ` [edk2-devel] [PATCH v1 0/6] Add Raspberry Pi Support to EmulatorPkg Nate DeSimone
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAMj1kXEmszKEA=nH061Rhc1w-ZExA0zHDBLYMN9tVYva2CXDBQ@mail.gmail.com' \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox