Commit graph

294 commits

Author SHA1 Message Date
Rob Clark
c160d2f5ec efi_loader: add checking for incorrect use of EFI_ENTRY/EXIT
Missing an EFI_ENTRY() or doubling up EFI_EXIT() leads to non-obvious
crashes.  Let's add some error checking.

Signed-off-by: Rob Clark <robdclark@gmail.com>
[agraf: fix bogus assert() and fix app_gd breakage]
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-29 00:18:24 +02:00
Rob Clark
a095aadffa efi_loader: Add an EFI_CALL() macro
Rather than open-coding EFI_EXIT() + callback + EFI_ENTRY(), introduce
an EFI_CALL() macro.  This makes callbacks into UEFI world (of which
there will be more in the future) more concise and easier to locate in
the code.

Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-28 09:15:45 +02:00
Alexander Graf
d98cdf6a92 efi_loader: Improve install_configuration_table
The INSTALL_CONFIGURATION_TABLE callback also provides the ability to
remove table entries. This patch adds that functionality.

Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-26 15:23:54 +02:00
Rob Clark
b5104821c1 efi_loader: remove double EFI_EXIT() with efi_unsupported
Probably this went unnoticed before, but it causes problems with
addition of 804b1d73 ("efi_loader: log EFI return values too")

Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-26 08:56:03 +02:00
xypron.glpk@gmx.de
c0ebfc8664 efi_loader: implement ProtocolsPerHandle
Boot service ProtocolsPerHandle is implemented in
efi_protocols_per_handle.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-25 10:03:50 +02:00
xypron.glpk@gmx.de
b521d29eb1 efi_loader: parameter types for CreateEvent, SetTimer
The first argument 'type' of CreateEvent is an 32bit unsigned
integer bitmap and not an enum.

The second argument 'type' of SetTimer take values of an
enum which is called EFI_TIMER_DELAY in the UEFI standard.
To avoid confusion rename efi_event_type to efi_timer_delay.

Reported-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-24 14:54:29 +02:00
Rob Clark
661c8327a6 efi_loader: workaround for grub lsefi bug
Patch has also been sent to fix grub to not ignore the error returned
and treat protocol_buffer_count as valid.  But that that might take a
while to trickle into distro's, so this workaround might be useful.

Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-24 14:47:36 +02:00
Rob Clark
3e094c592b efi_loader: move guidcmp to header
Want to re-use this for file protocol, which I'm working on.

Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-24 14:38:21 +02:00
xypron.glpk@gmx.de
8787b02e32 efi_loader: correctly implement 100ns conversion
In efi_set_timer we receive the trigger time in intervals of 100 ns.
We should convert it to intervals of 1000 ns by 64bit division.

The patch supplies function efi_div10 that uses multiplication to
implement the missing 64 bit division.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:36:14 +02:00
xypron.glpk@gmx.de
91be9a77b7 efi_console: set up events
Set up a timer event and the WaitForKey event.
In the notify function of the timer event check for console input
and signal the WaitForKey event accordingly.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:36:04 +02:00
xypron.glpk@gmx.de
bfc724625f efi_loader: refactor efi_set_timer
efi_set_timer is refactored to make the function callable internally.
Wrapper function efi_set_timer_ext is provided for EFI applications.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:31:40 +02:00
xypron.glpk@gmx.de
49deb455e6 efi_loader: refactor efi_create_event
efi_create_event is refactored to make it possible to call it
internally. For EFI applications wrapper function
efi_create_event_ext is created.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:31:35 +02:00
xypron.glpk@gmx.de
503f269554 efi_loader: correct size for tpl level
The UEFI standard defines the type for the tpl level as EFI_TPL
alias UINTN.

UINTN is an integer is defined as an unsigned integer of native
width. So we can use size_t for the definition.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:31:04 +02:00
xypron.glpk@gmx.de
c68415922b efi_loader: implement multiple event support
Up to now the boot time supported only a single event.
This patch now allows four events.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:26:09 +02:00
xypron.glpk@gmx.de
2fd945fe72 efi_loader: use struct efi_event * instead of void *
In our implementation the internal structure of events is known.
So use the known type instead of void.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:26:01 +02:00
xypron.glpk@gmx.de
88adae5ef0 efi_loader: reimplement efi_locate_protocol
The UEFI specification requires that LocateProtol finds the first
handle supporting the protocol and to return a pointer to its
interface.

So we have to assign the protocols to an efi_object and not use
any separate storage.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:40 +02:00
xypron.glpk@gmx.de
c2e703f903 efi_loader: implement LocateHandleBuffer
UEFI boot service LocateHandleBuffer is implemented by calling
efi_allocate_handle and efi_locate_handle.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:39 +02:00
xypron.glpk@gmx.de
26329584f3 efi_loader: refactor efi_locate_handle
To implement LocateHandleBuffer we need to call efi_locate_handle
internally without running through EFI_EXIT.

So put EFI_ENTRY and EFI_EXIT into a new wrapper function
efi_locate_handle_ext.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:39 +02:00
xypron.glpk@gmx.de
58b8358606 efi_loader: implement InstallMultipleProtocolInterfaces
Implement InstallMultipleProtocolInterfaces in function
efi_install_multiple_protocol_interfaces by repeatedly
calling efi_install_protocol_interface.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:39 +02:00
xypron.glpk@gmx.de
3d8e145608 efi_loader: refactor efi_uninstall_protocol_interface
For the implementation of UninstallMultipleProtocolInterfaces we
need to call efi_uninstall_protocol_interface. In internal calls
we should not pass through EFI_EXIT.

The patch introduces a wrapper function
efi_uninstall_protocol_interface_ext.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:39 +02:00
xypron.glpk@gmx.de
8bee5a3c13 efi_loader: refactor efi_install_protocol_interface
For the implementation of InstallMultipleProtocolInterfaces we
need to call efi_install_protocol_interface. In internal calls
we should not pass through EFI_EXIT.

The patch introduces a wrapper function
efi_install_protocol_interface_ext.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:38 +02:00
xypron.glpk@gmx.de
4b6ed0d7a1 efi_loader: implement UninstallProtocolInterface
Without the patch efi_uninstall_protocol_interface always returns an
error.

With the patch protocols without interface can be uninstalled.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:38 +02:00
xypron.glpk@gmx.de
e0549f8a17 efi_loader: implement InstallProtocolInterface
efi_install_protocol_interface up to now only returned an error code.

The patch implements the UEFI specification for InstallProtocolInterface
with the exception that it will not create new handles.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:38 +02:00
xypron.glpk@gmx.de
69baec6781 efi_loader: efi_open_protocol: parameter checks
Add all parameter checks for function efi_open_protocol that do not
depend on a locking table.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:38 +02:00
xypron.glpk@gmx.de
b5349f742a efi_loader: refactor efi_open_protocol
efi_open_protocol was implemented to call a protocol specific open
function to retrieve the protocol interface.

The UEFI specification does not know of such a function.

It is not possible to implement InstallProtocolInterface with the
current design.

With the patch the protocol interface itself is stored in the list
of installed protocols of an efi_object instead of an open function.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
[agraf: fix efi gop support]
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19 14:14:23 +02:00
xypron.glpk@gmx.de
8e1d329ff5 efi_loader: efi_handle_protocol set attributes
UEFI spec 2.7 indicates that HandleProtocol can be implemented
by calling OpenProtocol with
attributes = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL.

Currently we pass attributes = 0 to efi_open_protocol. 0 is not a
valid value when calling OpenProtocol. This does not cause any errors
yet because our implementation of OpenProtocol is incomplete.

We should pass the correct value to enable a fully compliant
implementation of OpenProtocol in the future.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-04 09:01:23 +02:00
Masahiro Yamada
6e0bf8d8b4 efi_loader: add static to local functions
These are locally used in lib/efi_loader/efi_boottime.c

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-03 14:41:13 +02:00
Jonathan Gray
a95343b8d3 efi_loader: check CreateEvent() parameters
Add some of the invalid parameter checks described in the UEFI
specification for CreateEvent().  This does not include checking
the validity of the type and tpl parameters.

Signed-off-by: Jonathan Gray <jsg@jsg.id.au>
Acked-By: Heinrich Schuchardt <xypron.glpk@gmx.de>
[agraf: fix checkpatch.pl indent warning]
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-03 13:54:48 +02:00
Jonathan Gray
37a980b3fa efi_loader: run CreateEvent() notify function based on flags
The UEFI specification states that the tpl, function and context
arguments are to be ignored if neither EVT_NOTIFY_WAIT or
EVT_NOTIFY_SIGNAL are specified.  This matches observed behaviour with
an AMI EDK2 based UEFI implementation.

Skip calling the notify function if neither flag is present.

Signed-off-by: Jonathan Gray <jsg@jsg.id.au>
Acked-By: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-03 13:48:51 +02:00
Alexander Graf
b7b8410a8f ls2080: Exit dpaa only right before exiting U-Boot
On ls2080 we have a separate network fabric component which we need to
shut down before we enter Linux (or any other OS). Along with that also
comes configuration of the fabric using a description file.

Today we always stop and configure the fabric in the boot script and
(again) exit it on device tree generation. This works ok for the normal
booti case, but with bootefi the payload we're running may still want to
access the network.

So let's add a new fsl_mc command that defers configuration and stopping
the hardware to when we actually exit U-Boot, so that we can still use
the fabric from an EFI payload.

For existing boot scripts, nothing should change with this patch.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: York Sun <york.sun@nxp.com>
[agraf: Fix x86 build]
2016-11-17 14:18:55 +01:00
Alexander Graf
3c63db9ca9 efi_loader: Rename EFI_RUNTIME_{TEXT, DATA} to __efi_runtime{, _data}
Compiler attributes are more commonly __foo style tags rather than big
upper case eye sores like EFI_RUNTIME_TEXT.

Simon Glass felt quite strongly about this, so this patch converts our
existing defines over to more eye friendly ones.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
2016-10-19 09:01:54 +02:00
Simon Glass
65e4c0b168 x86: efi: Add EFI loader support for x86
Add the required pieces to support the EFI loader on x86.

Since U-Boot only builds for 32-bit on x86, only a 32-bit EFI application
is supported. If a 64-bit kernel must be booted, U-Boot supports this
directly using FIT (see doc/uImage.FIT/kernel.its). U-Boot can act as a
payload for both 32-bit and 64-bit EFI.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2016-10-19 09:01:53 +02:00
Simon Glass
e275458c2f efi: Fix missing EFIAPI specifiers
These are missing in some functions. Add them to keep things consistent.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2016-10-19 09:01:53 +02:00
Alexander Graf
aba5e9194b efi_loader: Fix efi_install_configuration_table
So far we were only installing the FDT table and didn't have space
to store any other. Hence nobody realized that our efi table allocation
was broken in that it didn't set the indicator for the number of tables
plus one.

This patch fixes it, allowing code to allocate new efi tables.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
2016-10-19 09:01:52 +02:00
Alexander Graf
488bf12d84 efi_loader: Expose efi_install_configuration_table
We want to be able to add configuration table entries from our own code as
well as from EFI payload code. Export the boot service function internally
too, so that we can reuse it.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
2016-10-19 09:01:51 +02:00
Stefan Brüns
42417bc84d efi_loader: Track size of pool allocations to allow freeing
We need a functional free_pool implementation, as otherwise each
allocate_pool causes growth of the memory descriptor table.

Different to free_pages, free_pool does not provide the size for the
to be freed allocation, thus we have to track the size ourselves.

As the only EFI requirement for pool allocation is an alignment of
8 bytes, we can keep allocating a range using the page allocator,
reserve the first 8 bytes for our bookkeeping and hand out the
remainder to the caller. This saves us from having to use any
independent data structures for tracking.

To simplify the conversion between pool allocations and the corresponding
page allocation, we create an auxiliary struct efi_pool_allocation.

Given the allocation size free_pool size can handoff freeing the page
range, which was indirectly allocated by a call to allocate_pool,
to free_pages.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2016-10-18 09:08:07 +02:00
Stefan Brüns
ead1274b7f efi_loader: Move efi_allocate_pool implementation to efi_memory.c
We currently handle efi_allocate_pool() in our boot time service
file. In the following patch, pool allocation will receive additional
internal semantics that we should preserve inside efi_memory.c instead.

As foundation for those changes, split the function into an externally
facing efi_allocate_pool_ext() for use by payloads and an internal helper
efi_allocate_pool() in efi_memory.c that handles the actual allocation.

While at it, change the magic 0xfff / 12 constants to the more obvious
EFI_PAGE_MASK/SHIFT defines.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2016-10-18 09:08:07 +02:00
Robin Randhawa
991d62fa73 efi_loader: Fix crash on 32-bit systems
A type mismatch in the efi_allocate_pool boot service flow causes
hazardous memory scribbling on 32-bit systems.

This is efi_allocate_pool's prototype:

static efi_status_t EFIAPI efi_allocate_pool(int pool_type,
						    unsigned long size,
						    void **buffer);

Internally, it invokes efi_allocate_pages as follows:

efi_allocate_pages(0, pool_type, (size + 0xfff) >> 12,
					    (void*)buffer);

This is efi_allocate_pages' prototype:

efi_status_t efi_allocate_pages(int type, int memory_type,
					unsigned long pages,
					uint64_t *memory);

The problem: efi_allocate_pages does this internally:

    *memory = addr;

This fix in efi_allocate_pool uses a transitional uintptr_t cast to
ensure the correct outcome, irrespective of the system's native word
size.

This was observed when bootefi'ing the EFI instance of FreeBSD's first
stage bootstrap (boot1.efi) on a 32-bit ARM platform (Qemu VExpress +
Cortex-a9).

Signed-off-by: Robin Randhawa <robin.randhawa@arm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2016-10-18 09:08:07 +02:00
Alexander Graf
692fcdd800 arm: Add return value argument to longjmp
The normal longjmp command allows for a caller to pass the return value
of the setjmp() invocation. This patch adds that semantic to the arm
implementation of it and adjusts the efi_loader call respectively.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
2016-10-08 09:33:34 -04:00
Alexander Graf
edcef3ba1d efi_loader: Move to normal debug infrastructure
We introduced special "DEBUG_EFI" defines when the efi loader
support was new. After giving it a bit of thought, turns out
we really didn't have to - the normal #define DEBUG infrastructure
works well enough for efi loader as well.

So this patch switches to the common debug() and #define DEBUG
way of printing debug information.

Signed-off-by: Alexander Graf <agraf@suse.de>
2016-06-06 13:39:16 -04:00
Alexander Graf
a86aeaf228 efi_loader: Add exit support
Some times you may want to exit an EFI payload again, for example
to default boot into a PXE installation and decide that you would
rather want to boot from the local disk instead.

This patch adds exit functionality to the EFI implementation, allowing
EFI payloads to exit.

Signed-off-by: Alexander Graf <agraf@suse.de>
2016-06-06 13:39:15 -04:00
Alexander Graf
1cd29f0abd efi_loader: Fix some entry/exit points
When switching between EFI context and U-Boot context we need to swap
the register that "gd" resides in.

Some functions slipped through here, with efi_allocate_pool / efi_free_pool
not doing the switch correctly and efi_return_handle switching too often.

Fix them all up to make sure we always have consistent register state.

Signed-off-by: Alexander Graf <agraf@suse.de>
2016-03-27 09:13:02 -04:00
Alexander Graf
50149ea37a efi_loader: Add runtime services
After booting has finished, EFI allows firmware to still interact with the OS
using the "runtime services". These callbacks live in a separate address space,
since they are available long after U-Boot has been overwritten by the OS.

This patch adds enough framework for arbitrary code inside of U-Boot to become
a runtime service with the right section attributes set. For now, we don't make
use of it yet though.

We could maybe in the future map U-boot environment variables to EFI variables
here.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
2016-03-15 18:03:10 -04:00
Alexander Graf
bee91169f5 efi_loader: Add boot time services
When an EFI application runs, it has access to a few descriptor and callback
tables to instruct the EFI compliant firmware to do things for it. The bulk
of those interfaces are "boot time services". They handle all object management,
and memory allocation.

This patch adds support for the boot time services and also exposes a system
table, which is the point of entry descriptor table for EFI payloads.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
2016-03-15 18:03:06 -04:00