This code is used with EFI_LOADER but is also useful (with some
modifications) for the EFI app and payload. Move it into a shared
file.
Show the address of the table so it can be examined if needed. Also show
the table name as unknown if necessary. Our list of GUIDs is fairly
small.
Signed-off-by: Simon Glass <sjg@chromium.org>
Current U-Boot implements 64-bit boundary for efi_guid_t structure.
It follows the UEFI specification, page 21 of the UEFI Specification v2.10
says about EFI_GUID:
128-bit buffer containing a unique identifier value. Unless
otherwise specified, aligned on a 64-bit boundary.
On the other hand, page 163 of the UEFI specification v2.10 and
EDK2 reference implementation both define EFI_GUID as
struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied
alignment is 32-bit not 64-bit like U-Boot efi_guid_t.
Due to this alignment difference, EDK2 application "CapsuleApp.efi -P"
does not work as expected.
This calls EFI_FIRMWARE_MANAGEMENT_PROTOCOL.GetImageInfo()
and dump the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure,
offsetof(EFI_FIRMWARE_IMAGE_DESCRIPTOR, ImageTypeId) is different,
8 in U-Boot and 4 in EDK2(CapsuleApp.efi).
Here is the wrong EFI_GUID dump.
wrong dump : ImageTypeId - 00000000-7D83-058B-D550-474CA19560D8
expected : ImageTypeId - 058B7D83-50D5-4C47-A195-60D86AD341C4
EFI_FIRMWARE_IMAGE_DESCRIPTOR structure is defined in UEFI specification:
typedef struct {
UINT8 ImageIndex;
EFI_GUID ImageTypeId;
UINT64 ImageId
<snip>
} EFI_FIRMWARE_IMAGE_DESCRIPTOR;
There was the relevant patch for linux kernel to use 32-bit alignment
for efi_guid_t [1].
U-Boot should get aligned to EDK2 reference implementation and
linux kernel.
Due to this alignment change, efi_hii_ref structure in include/efi_api.h
is affected, but it is not used in the current U-Boot code.
[1] https://lore.kernel.org/all/20190202094119.13230-5-ard.biesheuvel@linaro.org/
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
A following patch is cleaning up the core EFI code trying to remove
sequences of efi_create_handle, efi_add_protocol.
Although this works fine there's a problem with the latter since it is
usually combined with efi_delete_handle() which blindly removes all
protocols on a handle and deletes the handle. We should try to adhere to
the EFI spec which only deletes a handle if the last instance of a protocol
has been removed. Another problem is that efi_delete_handle() never checks
for opened protocols, but the EFI spec defines that the caller is
responsible for ensuring that there are no references to a protocol
interface that is going to be removed.
So let's fix this by replacing all callsites of
efi_create_handle(), efi_add_protocol() , efi_delete_handle() with
Install/UninstallMultipleProtocol.
In order to do that redefine functions that can be used by the U-Boot
proper internally and add '_ext' variants that will be used from the
EFI API
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Document the return value in efi_init(). Fix up @sizep in efi_info_get().
Use Return: instead of @return
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
At present the 'efi' command only works in the EFI payload. Update it to
work in the app too, so the memory map can be examined.
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
At present this function requires a pointer to struct efi_entry_memmap
but the only field used in there is the desc_size. We want to be able
to use it from the app, so update it to use desc_size directly.
Signed-off-by: Simon Glass <sjg@chromium.org>
At present this code is inline in the app and stub. But they do the same
thing. The difference is that the stub does it immediately and the app
doesn't want to do it until the end (when it boots a kernel) or not at
all, if returning to UEFI.
Move it into a function so it can be called as needed.
Add a comment showing how to store the memory map so that it can be
accessed within the app if needed, for debugging purposes only. The map
can change without notice.
Signed-off-by: Simon Glass <sjg@chromium.org>
This provides access to EFI tables after U-Boot has exited boot services.
It is not needed in the app since boot services remain alive and we can
just call them whenever needed.
Add a comment to explain this.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
At present each of these has its own static variable and helper functions.
Move them into a shared file.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
When starting the app, locate all block devices and make them available
to U-Boot. This allows listing partitions and accessing files in
filesystems.
EFI also has the concept of 'disks', meaning boot media. For now, this
is not obviously useful in U-Boot, but add code to at least locate these.
This can be expanded later as needed.
We cannot use printf() in the early stub or app since it is not compiled
in
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Add a block driver which handles read/write for EFI block devices. This
driver actually already exists ('efi_block') but is not really suitable
for use as a real U-Boot driver:
- The operations do not provide a udevice
- The code is designed for running as part of EFI loader, so uses
EFI_PRINT() and EFI_CALL().
- The bind method probes the device, which is not permitted
- It uses 'EFI' as its parent device
The new driver is more 'normal', just requiring its platform data be set
up in advance.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Add a function to return this information along with a stub for the
efi_info_get() function, since calling it otherwise hangs U-Boot.
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* UEFI spec 2.9 introduced a new memory type EFI_UNACCEPTED_MEMORY_TYPE.
Add it to enum EFI_MEMORY_TYPE.
* Add missing EFI_MEMORY_CPU_CRYPTO constant
* Improve description of EFI_PERSISTENT_MEMORY_TYPE
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* Eliminate superfluous enum value EFI_TABLE_END.
* Use correct variable type for the memory type.
* Check validity of memory type.
* Make efi_build_mem_table static.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
The UEFI 2.8 specification has introduced the EFI_MEMORY_SP memory
attribute. Add it to the 'efidebug memmap' and 'efi mem' commands.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Of all warning status codes up to now only EFI_WARN_DELETE_FAILURE is
defined.
The patch adds the missing definitions for later usage.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
There are Cubox-i machines out there with nearly 4 GiB of RAM. The
RAM starts at 0x10000000 with a size of 0xf0000000. Thus the end
of RAM is at 0x100000000. This overflows a 32-bit integer, which
should be fine since in the EFI memory code the variables used are
all 64-bit with a fixed size. Unfortunately EFI_PAGE_MASK, which is
used in the EFI memory code to remove the lower bits, is based on
the EFI_PAGE_SIZE macro which, uses 1UL with a shift. This means
the resulting mask is UL, which is only 32-bit on ARMv7. Use ULL to
make sure that even on 32-bit platforms we use a 64-bit long mask.
Without this there will be no memory available in the EFI memory map
and bootefi will fail allocating pages.
Signed-off-by: Patrick Wildt <patrick@blueri.se>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Patrick Delaunay <patrick.delaunay@st.com>
The UEFI Specification Version 2.7 Errata A defines:
"EFI_GUID
128-bit buffer containing a unique identifier value.
Unless otherwise specified, aligned on a 64-bit boundary."
Before this patch efi_guid_t was 8-bit aligned.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
All our handles point to a struct efi_object. So let's define the
efi_handle_t accordingly. This helps us to discover coding errors much
more easily. This becomes evident by the corrections to the usage of
handles in this patch.
Rename variable image_handle to image_obj where applicable.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Add the missing SPDX-License-Identifier based on Linux kernel commit
b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to
files with no license").
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
At present Linux kernel loaded from U-Boot as an EFI payload does
not boot. This fills in kernel's boot params structure with the
required critical EFI information like system table address and
memory map stuff so that kernel can obtain essential data like
runtime services and ACPI table to boot.
With this patch, now U-Boot as an EFI payload becomes much more
practical: it is another option of kernel bootloader, ie, can be
a replacement for grub.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This updates the EFI stub codes to pass UEFI BIOS's system table
address to U-Boot payload so that U-Boot can utilize it.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
With this update, the memory attributes are in sync with Linux
kernel v4.18-rc4. They also match page 190 of UEFI 2.7 spec [1].
[1] http://www.uefi.org/sites/default/files/resources/UEFI_Spec_2_7.pdf
Suggested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Starting with commit 867a6ac86d ("efi: Add start-up library code"),
sparse constantly complains about truncated constant value in efi.h:
include/efi.h:176:35: warning: cast truncates bits from constant value (8000000000000000 becomes 0)
This can get quite noisy, preventing real issues to be noticed:
$ make defconfig
*** Default configuration is based on 'sandbox_defconfig'
$ make C=2 -j12 2>&1 | grep truncates | wc -l
441
After the patch is applied:
$ make C=2 -j12 2>&1 | grep truncates | wc -l
0
$ sparse --version
v0.5.2
Following the suggestion of Heinrich Schuchardt, instead of only
fixing the root-cause, I replaced the whole enum of _SHIFT values
by ULL defines. This matches both the UEFI 2.7 spec and the Linux
kernel implementation.
Some ELF size comparison before and after the patch (gcc 7.3.0):
efi-x86_payload64_defconfig:
text data bss dec hex filename
407174 29432 278676 715282 aea12 u-boot.old
407152 29464 278676 715292 aea1c u-boot.new
-22 +32 0 +10
efi-x86_payload32_defconfig:
text data bss dec hex filename
447075 30308 280076 757459 b8ed3 u-boot.old
447053 30340 280076 757469 b8edd u-boot.new
-22 +32 0 +10
Fixes: 867a6ac86d ("efi: Add start-up library code")
Suggested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Varargs differ between sysv and ms abi. On x86_64 we have to follow the ms
abi though, so we also need to make sure we use x86_64 varargs helpers.
This patch introduces generic efi vararg helpers that adhere to the
respective EFI ABI. That way we can deal with them properly from efi
loader code and properly interpret variable arguments.
This fixes the InstallMultipleProtocolInterfaces tests in the efi selftests
on x86_64 for me.
Signed-off-by: Alexander Graf <agraf@suse.de>
Currently efi.h determines a few bits of its environment according to
config options. This falls apart with the efi stub support which may
result in efi.h getting pulled into the stub as well as real U-Boot
code. In that case, one may be 32bit while the other one is 64bit.
This patch changes the conditionals to use compiler provided defines
instead. That way we always adhere to the build environment we're in
and the definitions adjust automatically.
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
[bmeng: added some comments to describe the __x86_64__ check]
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
If UEFI BIOS has the graphics output protocol (GOP), let's pass its
information to U-Boot payload so that U-Boot can utilize it (eg:
an EFI framebuffer driver).
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
When building with -pedantic the current definition of EFI_GUID() causes
an error 'initializer element is not constant'.
Currently EFI_GUID() is used both as an anonymous constant and as an
intializer. A conversion to efi_guid_t is not allowable when using
EFI_GUID() as an initializer. But it is needed when using it as an
anonymous constant.
We should not use EFI_GUID() for anything but an initializer. So let's
introduce a variable where needed and remove the conversion.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
We have 2 users of the EFI headers: efi_loader and the EFI stub. Efi_loader
always expects that the bitness of the definitions it uses is identical to
the execution.
The EFI stub however allows to run x86_64 U-Boot on 32bit EFI and the other
way around, so it allows for different bitness of EFI definitions and U-Boot
environment.
This patch explicitly requests via Kconfig that efi_loader can only be enabled
if the bitness is identical. Because we can run efi_loader on x86_64 without
EFI stub enabled, it also ensures that this case propagates the correct ABI
constraints.
Signed-off-by: Alexander Graf <agraf@suse.de>
Constants should be capitalized.
So rename the values of enum efi_locate_search_type.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
Add EFI variable support, mapping to u-boot environment variables.
Variables are pretty important for setting up boot order, among other
things. If the board supports saveenv, then it will be called in
ExitBootServices() to persist variables set by the efi payload. (For
example, fallback.efi configuring BootOrder and BootXXXX load-option
variables.)
Variables are *not* currently exposed at runtime, post ExitBootServices.
On boards without a dedicated device for storage, which the loaded OS
is not trying to also use, this is rather tricky. One idea, at least
for boards that can persist RAM across reboot, is to keep a "journal"
of modified variables in RAM, and then turn halt into a reboot into
u-boot, plus store variables, plus halt. Whatever the solution, it
likely involves some per-board support.
Mapping between EFI variables and u-boot variables:
efi_$guid_$varname = {attributes}(type)value
For example:
efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported=
"{ro,boot,run}(blob)0000000000000000"
efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder=
"(blob)00010000"
The attributes are a comma separated list of these possible
attributes:
+ ro - read-only
+ boot - boot-services access
+ run - runtime access
NOTE: with current implementation, no variables are available after
ExitBootServices, and all are persisted (if possible).
If not specified, the attributes default to "{boot}".
The required type is one of:
+ utf8 - raw utf8 string
+ blob - arbitrary length hex string
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
fallback.efi (and probably other things) use UEFI's simple-file-system
protocol and file support to search for OS's to boot.
Signed-off-by: Rob Clark <robdclark@gmail.com>
[agraf: whitespace fixes, unsigned fixes]
Signed-off-by: Alexander Graf <agraf@suse.de>
Prep work for next patch.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Fix typo in teh EFI_BOOT_SERVICES_CODE description.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
efi.h held only a few EFI status codes.
The patch adds the missing definitions for later usage.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
At present we use a CONFIG option in efi.h to determine whether we are
building the EFI stub or not. This means that the same header cannot be
used for EFI_LOADER support. The CONFIG option will be enabled for the
whole build, even when not building the stub.
Use a different define instead, set up just for the files that make up the
stub.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
This is required for x86 and is also correct for ARM (since it is empty).
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Provide version of struct efi_mem_desc in efi_get_memory_map().
EFI_BOOT_SERVICES.GetMemoryMap() in UEFI specification v2.6 defines
memory descriptor version to 1. Linux kernel also expects descriptor
version to be 1 and prints following warning during boot if its not:
Unexpected EFI_MEMORY_DESCRIPTOR version 0
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@gmail.com>
There are lots of warnings when building EFI 64-bit payload.
include/asm-generic/bitops/__fls.h:17:2:
warning: left shift count >= width of type
if (!(word & (~0ul << 32))) {
^
In fact, U-Boot itself as EFI payload is running in 32-bit mode.
So BITS_PER_LONG needs to still be 32, but EFI status codes are
64-bit when booting from 64-bit EFI. Introduce EFI_BITS_PER_LONG
to bridge those status codes with U-Boot's BITS_PER_LONG.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Since commit 73c5c39 "Makefile: Drop unnecessary -dtb suffixes",
EFI payload does not build anymore. This fixes the build.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
The EFI API header is great, but missing a good chunk of function prototype,
GUID defines and enum declarations.
This patch extends it to cover more of the EFI API. It's still not 100%
complete, but sufficient enough for our EFI payload interface.
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
Most EFI implementations use 64-bit. Add a way to build U-Boot as a 64-bit
EFI payload. The payload unpacks a (32-bit) U-Boot and starts it. This can
be enabled for x86 boards at present.
Signed-off-by: Simon Glass <sjg@chromium.org>
Improvements to how the payload is built:
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>