Commit Graph

19 Commits

Author SHA1 Message Date
Michael Brown 32a9408217 [efi] Allow use of typed pointers for efi_open() et al
Provide wrapper macros to allow efi_open() and related functions to
accept a pointer to any pointer type as the "interface" argument, in
order to allow a substantial amount of type adjustment boilerplate to
be removed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-03-24 15:43:56 +00:00
Michael Brown bac3187439 [efi] Use efi_open() for all ephemeral protocol opens
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-03-24 13:19:26 +00:00
Michael Brown 1a602c92ac [efi] Allow wrapping the global boot services table in situ
When DEBUG=efi_wrap is enabled, we construct a patched copy of the
boot services table and patch the global system table to point to this
copy.  This ensures that any subsequently loaded EFI binaries will
call our wrappers.

Previously loaded EFI binaries will typically have cached the boot
services table pointer (in the gBS variable used by EDK2 code), and
therefore will not pick up the updated pointer and so will not call
our wrappers.  In most cases, this is what we want to happen: we are
interested in tracing the calls issued by the newly loaded binary and
we do not want to be distracted by the high volume of boot services
calls issued by existing UEFI drivers.

In some circumstances (such as when a badly behaved OEM driver is
causing the system to lock up during the ExitBootServices() call), it
can be very useful to be able to patch the global boot services table
in situ, so that we can trace calls issued by existing drivers.

Restructure the wrapping code to allow wrapping to be enabled or
disabled at any time, and to allow for patching the global boot
services table in situ.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-03-20 12:35:42 +00:00
Michael Brown f68c8b09e3 [efi] Fix debug wrappers for CloseEvent() and CheckEvent()
The debug wrappers for CloseEvent() and CheckEvent() are currently
both calling SignalEvent() instead (presumably due to copy-paste
errors).  Astonishingly, this has generally not prevented a successful
boot in the (very rare) case that DEBUG=efi_wrap is enabled.

Fix the wrappers to call the intended functions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-03-19 16:20:27 +00:00
Michael Brown 6e4196baff [efi] Prescroll the display after a failed wrapped ExitBootServices() call
On some systems (observed with an HP Elitebook 840 G10), writing
console output that happens to cause the display to scroll will modify
the system memory map.  This causes builds with DEBUG=efi_wrap to
typically fail to boot, since the debug output from the wrapped
ExitBootServices() call itself is sufficient to change the memory map
and therefore cause ExitBootServices() to fail due to an invalid
memory map key.

Work around these UEFI firmware bugs by prescrolling the display after
a failed ExitBootServices() attempt, in order to minimise the chance
that further scrolling will happen during the subsequent attempt.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-03-18 14:13:56 +00:00
Michael Brown 670810bed8 [efi] Use standard va_args macros instead of VA_START() etc
The EDK2 header macros VA_START(), VA_ARG() etc produce build errors
on some CPU architectures (notably on 32-bit RISC-V, which is not yet
supported by EDK2).

Fix by using the standard variable argument list macros.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-15 10:01:35 +01:00
Michael Brown b6045a8cbb [efi] Modify global system table when wrapping a loaded image
The EFI loaded image protocol allows an image to be provided with a
custom system table, and we currently use this mechanism to wrap any
boot services calls made by the loaded image in order to provide
strace-like debugging via DEBUG=efi_wrap.

The ExitBootServices() call will modify the global system table,
leaving the loaded image using a system table that is no longer
current.  When DEBUG=efi_wrap is used, this generally results in the
machine locking up at the point that the loaded operating system calls
ExitBootServices().

Fix by modifying the global EFI system table to point to our wrapper
functions, instead of providing a custom system table via the loaded
image protocol.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-11-21 13:34:10 +00:00
Michael Brown 51612b6e69 [efi] Do not attempt to use console output after ExitBootServices()
A successful call to ExitBootServices() will result in the EFI console
becoming unusable.  Ensure that the EFI wrapper produces a complete
line of debug output before calling the wrapped ExitBootServices()
method, and attempt subsequent debug output only if the call fails.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-11-21 13:24:24 +00:00
Michael Brown 7151fa3ffa [efi] Allow DEBUG=efi_wrap to be used independently of a loaded image
Allow temporary debugging code to call efi_wrap_systab() to obtain a
pointer to the wrapper EFI system table.  This can then be used to
e.g. forcibly overwrite the boot services table pointer used by an
already loaded and running UEFI driver, in order to trace calls made
by that driver.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-10-01 15:44:05 +01:00
Michael Brown fe69934191 [efi] Show memory map returned by wrapped calls to GetMemoryMap
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-09-22 13:59:37 +01:00
Michael Brown e08ad61bf7 [efi] Add debug wrappers for all boot services functions of interest
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-09-18 23:16:46 +01:00
Michael Brown c522c11c7b [efi] Improve efi_wrap debugging
Add debug wrappers for more boot services functions, and print
symbolic values rather than raw numbers where possible.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2015-08-27 15:54:25 +01:00
Michael Brown 9501eaf68d [efi] Remove raw EFI_HANDLE values from debug messages
The raw EFI_HANDLE value is almost never useful to know, and simply
adds noise to the already verbose debug messages.  Improve the
legibility of debug messages by using only the name generated by
efi_handle_name().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2015-08-27 15:40:44 +01:00
Michael Brown b6ee89ffb5 [legal] Relicense files under GPL2_OR_LATER_OR_UBDL
Relicense files for which I am the sole author (as identified by
util/relicense.pl).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2015-03-02 14:17:31 +00:00
Michael Brown 0cc2f42f46 [efi] Wrap any images loaded by our wrapped image
Propagate our modified EFI system table to any images loaded by the
image that we wrap, thereby allowing us to observe boot services calls
made by all subsequent EFI images.

Also show details of intercepted ExitBootServices() calls.  When
wrapping is used, exiting boot services will almost certainly fail,
but this at least allows us to see when it happens.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2014-08-29 13:10:18 +01:00
Michael Brown 3357a8e369 [efi] Show details of intercepted LoadImage() calls
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2014-08-27 03:13:12 +01:00
Michael Brown 2e0821b9ed [efi] Use efi_handle_name() instead of efi_handle_devpath_text()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2014-07-31 11:56:44 +01:00
Michael Brown 410f50c2ee [efi] Show more diagnostic information when building with DEBUG=efi_wrap
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2014-07-26 11:24:24 +01:00
Michael Brown c3b6ccf65b [efi] Allow for interception of boot services calls by loaded image
When building with DEBUG=efi_wrap, print details of calls made by the
loaded image to selected boot services functions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2014-07-16 01:58:19 +01:00