Search notes:

arch/x86/boot/compressed/efi_mixed.S

Early support for invoking 32-bit EFI services from a 64-bit kernel.
Because this thunking occurs before ExitBootServices() we have to restore the firmware's 32-bit GDT and IDT before we make EFI service calls.
On the plus side, we don't have to worry about mangling 64-bit addresses into 32-bits because we're executing with an identity mapped pagetable and haven't transitioned to 64-bit virtual addresses yet.

Diagram

When booting in 64-bit mode on 32-bit EFI firmware, startup_64_mixed_mode() is the first thing that runs after switching to long mode. Depending on whether the EFI handover protocol or the compat entry point was used to enter the kernel, it will either branch to the common 64-bit EFI stub entrypoint efi_stub_entry() directly, or via the 64-bit EFI PE/COFF entrypoint efi_pe_entry(). In the former case, the bootloader must provide a struct bootparams pointer as the third argument, so the presence of such a pointer is used to disambiguate.
                                                           +--------------+
+------------------+     +------------+            +------>| efi_pe_entry |
| efi32_pe_entry   |---->|            |            |       +-----------+--+
+------------------+     |            |     +------+----------------+  |
                         | startup_32 |---->| startup_64_mixed_mode |  |
+------------------+     |            |     +------+----------------+  |
| efi32_stub_entry |---->|            |            |                   |
+------------------+     +------------+            |                   |
                                                   V                   |
                         +------------+     +----------------+         |
                         | startup_64 |<----| efi_stub_entry |<--------+
                         +------------+     +----------------+

Index