Commit Graph

722 Commits

Author SHA1 Message Date
Heinrich Schuchardt
faadc04180 efi_loader: imply VIDEO_ANSI
UEFI programs like GRUB make change terminal colors which requires support
for ANSI escape sequences.

Let CONFIG_EFI_LOADER=y imply CONFIG_VIDEO_ANSI.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-15 00:51:51 +01:00
Heinrich Schuchardt
55111c5052 efi_loader: describe returning of control
Provide a sober description of how control can be returned by a UEFI
binary.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-15 00:51:51 +01:00
Heinrich Schuchardt
d417b94e57 efi_loader: document functions in efi_rng.c
Add the missing Sphinx documentation.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-15 00:51:51 +01:00
Sughosh Ganu
33c37d9784 efi_rng_protocol: Install the efi_rng_protocol on the root node
Install the EFI_RNG_PROTOCOL implementation for it's subsequent use by
the kernel for features like kaslr.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:22 +01:00
Sughosh Ganu
f552fa496c efi: qemu: arm64: Add efi_rng_protocol implementation for the platform
Add support for the EFI_RNG_PROTOCOL routines for the qemu arm64
platform. EFI_RNG_PROTOCOL is an uefi boottime service which is
invoked by the efi stub in the kernel for getting random seed for
kaslr.

The routines are platform specific, and use the virtio-rng device on
the platform to get random data.

The feature can be enabled through the following config
CONFIG_EFI_RNG_PROTOCOL

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
Changed SPDX header to use /* instead of //.
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:22 +01:00
Sughosh Ganu
61e42d9465 efi_loader: Add guidcpy function
Add guidcpy function to copy the source guid to the destination
guid. Use this function instead of memcpy for copying to the
destination guid.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>

Use void * instead of efi_guid_t * for arguments to allow copying unaligned
GUIDs. The GUIDs of configuration tables are __packed.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:20 +01:00
Heinrich Schuchardt
9bb758aab6 efi_loader: __cyg_profile_func_enter/_exit
U-Boot can be compiled with function tracing enabled.

When compiling with FTRACE __cyg_profile_func_enter() is called when a
function is entered and __cyg_profile_func_exit() when the function is
left.

To avoid a crash we have to define these function for the free-standing
UEFI binaries.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:20 +01:00
Heinrich Schuchardt
b0ad9b5b2a efi_loader: clear screen should move cursor to home
On a VT100 terminal <ESC>[2J should be enough to both clear the whole
screen and set the cursor to position (1, 1). But the Linux console does
not behave like this. So send an extra <ESC>[H. For reference see the
console_codes(4) man page.

Add a function description.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:20 +01:00
Heinrich Schuchardt
07b57ef1eb efi_loader: git ignore helloworld_efi.S
Add *.S to .gitignore.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:20 +01:00
Heinrich Schuchardt
570147275c efi_loader: adjust file system info
When the GetInfo() method of the EFI_FILE_PROTOCOL is called to retrieve
the file system info we claim that the volume is read only and has no free
space. This leads to failures in programs that check this information
before writing to the volume like SCT's InstallSct.efi.

Currently there is no function to determine these parameters in U-Boot. So
let's return optimistic values:

Return that the volume is writable.

Return the volume size as free space.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:20 +01:00
Heinrich Schuchardt
8876e1bc88 efi_loader: imply USB_KEYBOARD_FN_KEYS
UEFI applications like GRUB and SCT assume that function keys are enabled
on the keyboard.

Let EFI_LOADER imply USB_KEYBOARD_FN_KEYS.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2020-01-07 18:08:20 +01:00
Simon Glass
67c4e9f815 common: Move board_get_usable_ram_top() out of common.h
Move this function into init.h which seems to be designed for this sort
of thing. Also update the header to declare struct global_data so that it
can be included without global_data.h being needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
2019-12-02 18:25:04 -05:00
Simon Glass
36bf446b64 common: Move enable/disable_interrupts out of common.h
Move these two functions into the irq_funcs.h header file. Also move
interrupt_handler_t as this is used by the irq_install_handler() function.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
2019-12-02 18:25:01 -05:00
Simon Glass
1eb69ae498 common: Move ARM cache operations out of common.h
These functions are CPU-related and do not use driver model. Move them to
cpu_func.h

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
2019-12-02 18:24:58 -05:00
Simon Glass
1045315df0 common: Move get_ticks() function out of common.h
This function belongs in time.h so move it over and add a comment.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
2019-12-02 18:23:13 -05:00
Simon Glass
3db7110857 crc32: Use the crc.h header for crc functions
Drop inclusion of crc.h in common.h and use the correct header directly
instead.

With this we can drop the conflicting definition in fw_env.h and rely on
the crc.h header, which is already included.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
2019-12-02 18:23:08 -05:00
Heinrich Schuchardt
b7cdecfc19 efi_loader: default EFI_LOADER=n on ARM11
Some of the ARM11 boards have tight limits on the size of U-Boots. Hence
use EFI_LOADER=n as default on ARM11.

Set EFI_LOADER=y for the Raspberry Pi and Raspberry Pi Zero as these boards
have sufficient storage on the SD card.

Suggested-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-23 09:19:31 +01:00
Heinrich Schuchardt
38064ee04c efi_loader: enable EFI_LOADER on arm1136 and arm1176
With an implementation for allow_unaligned() available for arm1136 and
arm1176 UEFI can be supported on these architectures.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-19 12:10:22 +01:00
Heinrich Schuchardt
b20bb09b21 efi_loader: restrict EFI_LOADER to armv7 and armv8 on ARM
fatload USB was reported to fail on the Sheevaplug. Debugging showed that
this was caused by an incorrect unaligned write to memory in
path_to_uefi().

UEFI on ARM requires that unaligned memory access is enabled.

* ARMv5 does not support unaligned access at all.
* ARMv6 supports unaligned access when we clear the A flag and set the
  U flag.
* On ARMv7 unaligned access is possible when clearing the aligned flag,
  which we do in function allow_unaligned() (arch/arm/cpu/armv7/sctlr.S).
  For none of the other cpus in arch/arm/cpu/ we have implemented a
  similar function.
* ARMv8 allows unaligned access.

Let EFI_LOADER on ARM depend on SYS_CPU=armv7 or SYS_CPU=armv8.

Once we have implemented allow_unaligned() for other ARM CPUs we can add
these to Kconfig.

Reported-by: Gray Remlin <gryrmln@gmail.com>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-19 12:10:22 +01:00
Heinrich Schuchardt
246e601846 efi_loader: remove unused function efi_dp_from_dev()
Function efi_dp_from_dev() is not used anywhere. Remove it.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-19 12:10:22 +01:00
Heinrich Schuchardt
3b4847cbee efi_loader: support building UEFI binaries on sandbox
On the sandbox the UEFI binaries must match the host architectures.

Adjust the Makefiles. Provide the PE/COFF header and relocation files.

Allow building helloworld.efi on the sandbox.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-12 23:13:54 +01:00
Heinrich Schuchardt
7264e21fde efi_loader: call add_u_boot_and_runtime() on sandbox
On the sandbox we should mark the stack area as EFI runtime memory like we
do on any other architecture.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-12 23:13:54 +01:00
AKASHI Takahiro
89cb6a5dd6 efi_loader: disk: install file system protocol to a whole disk
Currently, a whole disk without any partitions is not associated
with EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. So even if it houses some
file system, there is a chance that we may not be able to access
it, particularly, when accesses are to be attempted after searching
that protocol against a device handle.

With this patch, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is installed
to such a disk if part_get_info() shows there is no partition
table installed on it.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>

Only if no partition table exists, check for a file system on disk level.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-12 23:13:54 +01:00
Heinrich Schuchardt
cab6f06c14 efi_loader: fix efi_dp_from_name()
Correctly check the return value of efi_dp_from_file().
If we can determine device path for the file, should not depend on the
device path for the device being requested.
Provide a function description for efi_dp_from_name().

Reported-by: Coverity CID 273159, CID 273158
Fixes: 08c51fff30 ("efi_loader: device_path: check against file path length")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-11-12 23:13:54 +01:00
Heinrich Schuchardt
e731af4893 efi_loader: correct includes in efi_variable.c
'make tests' on an 32bit ARM system leads to

In file included from ../lib/efi_loader/efi_variable.c:9:
../include/malloc.h:364:7: error: conflicting types for ‘memset’
 void* memset(void*, int, size_t);
       ^~~~~~
In file included from ../include/compiler.h:126,
                 from ../include/env.h:12,
                 from ../lib/efi_loader/efi_variable.c:8:
../include/linux/string.h:103:15:
note: previous declaration of ‘memset’ was here
 extern void * memset(void *,int,__kernel_size_t);
               ^~~~~~
In file included from ../lib/efi_loader/efi_variable.c:9:
../include/malloc.h:365:7: error: conflicting types for ‘memcpy’
 void* memcpy(void*, const void*, size_t);
       ^~~~~~
In file included from ../include/compiler.h:126,
                 from ../include/env.h:12,
                 from ../lib/efi_loader/efi_variable.c:8:
../include/linux/string.h:106:15:
note: previous declaration of ‘memcpy’ was here
 extern void * memcpy(void *,const void *,__kernel_size_t);
               ^~~~~~

Use common.h as first include as recommended by the U-Boot coding style
guide.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-10-30 17:49:41 +01:00
AKASHI Takahiro
867400677c efi_loader: disk: install FILE_SYSTEM_PROTOCOL only if available
In the current implementation, EFI_SIMPLEFILE_SYSTEM_PROTOCOL is always
installed to all the partitions even if some of them may house no file
system.

With this patch, that protocol will be installed only if any file system
exists.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-10-17 19:19:56 +02:00
AKASHI Takahiro
08c51fff30 efi_loader: device_path: check against file path length
device_path strcuture has 2 bytes of "length" field, and so
file path length should not exceed this limit, 65535.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-10-17 19:19:55 +02:00
Patrick Wildt
f2d247df50 efi: device path for nvme
This allows our EFI API to create a device path node for NVMe
devices.  It adds the necessary device path struct, uses the
nvme namespace accessor to retrieve the id and eui64, and also
provides support for the device path text protocol.

Signed-off-by: Patrick Wildt <patrick@blueri.se>
Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-10-06 16:02:37 +02:00
Heinrich Schuchardt
709292a63a efi_loader: appending to non-existent variable
Appending to a non-existent variable must result in an error of type
EFI_NOT_FOUND.

Fixes: 09c76b79a9db ("efi_loader: SetVariable() deleting variables")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-10-06 16:02:36 +02:00
Heinrich Schuchardt
3545c66143 efi_loader: SetVariable() deleting variables
APPEND_WRITE with data length zero is allowable according to the UEFI
specification.

The EDK2 interpretation of no access attributes is attributes = 0. As
the UEFI specification is vague in this respect let's stick to EDK2 here.

Fixes: commit 6d2f27c5fd ("efi_loader: variable: support APPEND_WRITE")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-23 22:53:25 +02:00
Heinrich Schuchardt
edb6b6842c efi_loader: SetVariable() fix illegal return
We always have to return via EFI_EXIT() from EFIAPI functions.

Coverity reported an unreachable line and a resource leak.

Fixes: commit 6d2f27c5fd ("efi_loader: variable: support APPEND_WRITE")
Reported-by: Coverity Scan CID 253575, CID 184095
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-23 22:53:25 +02:00
Heinrich Schuchardt
be09372a71 efi_loader: description efi_stri_coll()
Remove outdated TODO for efi_stri_coll(). efi_stri_coll() is already using
the Unicode capitalization table.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-23 22:53:25 +02:00
AKASHI Takahiro
6d2f27c5fd efi_loader: variable: support APPEND_WRITE
If EFI_VARIABLE_APPEND_WRITE is specified in attributes at
efi_set_variable(), specified data will be appended to the variable's
original value. Attributes other than APPEND_WRITE should not be
modified.

With this patch, APPEND_WRITE test in 'variables' selftest will pass.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
2019-09-20 20:09:18 +02:00
Heinrich Schuchardt
7dc10c933c efi_loader: incorrect return value form DisconnectController
DisconnectController() should never return EFI_NOT_FOUND.
If EFI_DRIVER_BINDING_PROTOCOL.Stop() fails, return EFI_DEVICE_ERROR.

If the driver handle does not expose the EFI_DRIVER_BINDING_PROTOCOL
return EFI_INVALID_PARAMETER.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-20 20:09:18 +02:00
AKASHI Takahiro
23ad52fff4 efi_loader: device_path: support Sandbox's "host" devices
Sandbox's "host" devices are currently described as UCLASS_ROOT udevice
with DEV_IF_HOST block device. As the current implementation of
efi_device_path doesn't support such a type, any "host" device
on sandbox cannot be seen as a distinct object.

For example,
  => host bind 0 /foo/disk.img

  => efi devices
  Scanning disk host0...
  Found 1 disks
  Device           Device Path
  ================ ====================
  0000000015c19970 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)
  0000000015c19d70 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)

  => efi dh
  Handle           Protocols
  ================ ====================
  0000000015c19970 Device Path, Device Path To Text, Device Path Utilities, Unicode Collation 2, HII String, HII Database, HII Config Routing
  0000000015c19ba0 Driver Binding
  0000000015c19c10 Simple Text Output
  0000000015c19c80 Simple Text Input, Simple Text Input Ex
  0000000015c19d70 Block IO, Device Path, Simple File System

As you can see here, efi_root (0x0000000015c19970) and host0 device
(0x0000000015c19d70) have the same representation of device path.

This is not only inconvenient, but also confusing since two different
efi objects are associated with the same device path and
efi_dp_find_obj() will possibly return a wrong result.

Solution:
Each "host" device should be given an additional device path node
of "vendor device path" to make it distinguishable.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-20 20:09:18 +02:00
Heinrich Schuchardt
8262578535 efi_loader: parameter checks EFI_FILE_PROTOCOL.SetInfo()
We do not support volume label changes. No parameter checks are needed
here.

When the info for as file is changed the buffer must always contain a file
name.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-11 21:51:38 +02:00
Heinrich Schuchardt
11335c0439 efi_loader: check parameters EFI_FILE_PROTOCOL.GetInfo()
Check the parameters of EFI_FILE_PROTOCOL.GetInfo() to avoid possible NULL
dereference.

Check the buffer size for EFI_FILE_SYSTEM_INFO.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-09 15:21:09 +02:00
Heinrich Schuchardt
632834ce6d efi_loader: volume name in EFI_FILE_PROTOCOL.GetInfo()
We cannot determine the volume name in U-Boot. Instead of providing a dummy
volume name in case of EFI_FILE_SYSTEM_INFO and EFI_UNSUPPORTED in case of
EFI_FILE_SYSTEM_VOLUME_LABEL consistently return an empty string.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-09 15:21:09 +02:00
Heinrich Schuchardt
e692ed1d56 efi_loader: EFI_FILE_PROTOCOL rev 2 stub
The UEFI specification requires to implement version 2 of the
EFI_FILE_PROTOCOL. Provide the missing functions as stubs.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-09 15:21:09 +02:00
Heinrich Schuchardt
9bb62fa63b efi_loader: file size checks
The file size has to be determined in multiple places. Factor out a common
function.

If on entry into EFI_FILE_PROTOCOL.Read() the current position is beyond
the end of the file, return EFI_DEVICE_ERROR.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-09 15:21:08 +02:00
Heinrich Schuchardt
83a74ad143 efi_loader: correct reading of directories
EFI_FILE_PROTOCOL.Read() is used both to read files and directories.

When reaching the end of a directory we always have to return buffer size
zero irrespective of the incoming buffer size. (The described scenario for
a Shim quirk cannot arise because every directory has at least '.' and '..'
as entries.)

Even when the buffer_size is too small multiple times we have to keep a
reference to our last read directory entry.

When we return to the start of the directory via SetPosition() we must
remove the reference to a previously kept directory entry.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-09 15:21:08 +02:00
Heinrich Schuchardt
87c4840610 efi_loader: eliminate inline function ascii2unicode()
ascii2unicode() can only convert characters 0x00-0x7f from UTF-8 to UTF-16.
Use utf8_utf16_strcpy() instead.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-09 15:21:08 +02:00
Heinrich Schuchardt
b0f1c728c8 efi_loader: EFI_FILE_PROTOCOL.Write() check args
Check the parameters passed to Write():

* cannot write to directories (UEFI SCT 2017, 5.7.3.5.15)
* cannot write to file opened read only (UEFI SCT 2017, 5.7.3.5.16)

Add missing comments.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-09 15:21:08 +02:00
Heinrich Schuchardt
fe1a81c1a4 doc: UEFI API documentation
Add some more files to the UEFI API documentation.

Correct some Sphinx comments.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-05 23:18:52 +02:00
Heinrich Schuchardt
cda9b35272 efi_loader: EFI_BLOCK_IO_PROTOCOL.Reset()
We cannot do anything in EFI_BLOCK_IO_PROTOCOL.Reset() but this does not
justify to return an error.

Let EFI_BLOCK_IO_PROTOCOL.Reset() return EFI_SUCCESS.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-05 23:18:51 +02:00
Heinrich Schuchardt
9d3f339881 efi_loader: use EFI_PRINT() instead of debug()
EFI_PRINT() offers indention of debug messages. Adjust the debug messages
of the BLOCK_IO_PROTOCOL.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-05 23:18:51 +02:00
Heinrich Schuchardt
f59f0825e8 efi_loader: parameter checks BLOCK_IO_PROTOCOL
Check parameters of ReadBlocks() and WriteBlocks().

If the buffer size is not a multiple of the block size, we have to return
EFI_BAD_BUFFER_SIZE.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-05 23:18:51 +02:00
Heinrich Schuchardt
03446987c5 efi_loader: do not set invalid screen mode
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetMode() should return EFI_UNDEFINED if a
screen mode is not available.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Alexander Graf <agraf@csgraf.de>
2019-09-05 23:18:51 +02:00
Heinrich Schuchardt
97ea0690f4 efi_loader: cursor positioning
When backspacing in column 0 do no set the column index to ULONG_MAX.
Ensure that the row number is not set to ULONG_MAX even if the row count is
advertised as 0.
Ignore control characters other the 0x08, 0x0a, 0x0d when updating the
column.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-05 23:18:51 +02:00
Heinrich Schuchardt
d41f99e179 efi_loader: correctly render UsbClass DP nodes as text
Correct the text representation of UsbClass device path nodes.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-09-05 23:18:51 +02:00