Commit Graph

1628 Commits

Author SHA1 Message Date
Heinrich Schuchardt
7950e8e2eb efi_selftest: unit test for OpenProtocolInformation()
Provide a unit test that checks that the open protocol information is
correctly updated when opening and closing protocols.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-06-01 22:40:24 +02:00
Heinrich Schuchardt
7e572cf69d efi_loader: CloseProtocol() fix open protocol information
CloseProtocol() must delete all open protocol information records relating
to import parameters not only one.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-06-01 22:40:24 +02:00
Heinrich Schuchardt
b4863baa68 efi_loader: open protocol information
When a protocol is opened the open protocol information must be updated.
The key fields of the open protocol information records are ImageHandle,
ControllerHandle, and Attributes.

Consider the Attributes field when determining if an open protocol
information record has to be updated or a new one has to be created.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-06-01 22:40:23 +02:00
Heinrich Schuchardt
755d42d420 efi_loader: correct HandleProtocol()
The UEFI specification requires that when a protocol is opened via
HandleProtocol() the agent handle is the image handle of the EFI firmware
(see chapter on EFI_BOOT_SERVICES.OpenProtocol()).

Let efi_handle_protocol() pass efi_root as agent handle to
efi_open_protocol().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-06-01 22:40:23 +02:00
Heinrich Schuchardt
5ec48e38ee efi_loader: Kconfig entries for GetTime(), SetTime()
The GetTime() and the SetTime() runtime services are not obligatory. So
let's make them customizable.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-06-01 04:53:13 +02:00
Heinrich Schuchardt
38b9a79c63 efi_loader: handling of daylight saving time
If SetTime() is meant to set daylight saving time it will be called with
Time.Daylight == EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT.

Return 0 from GetTime() if time is not in daylight because we cannot
determine if we are in a time zone with daylight saving time.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:20 +02:00
Heinrich Schuchardt
e6bcc35452 efi_loader: check time in SetTime()
The UEFI spec prescribes that we check that the timestamp passed to
SetTime() is checked for validity.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:12 +02:00
Heinrich Schuchardt
a248bc8055 efi_loader: correct UninstallProtocolInterface()
When uninstalling a protocol the following steps are needed:
* request all drivers to disconnect
* close protocol for all non-drivers
* check if any open instance of the protocol exists on the handle and
  return EFI_ACCESS_DENIED in this case
* remove the protocol interface

By tort we tested for remaining open protocol instances already after
requesting drivers to disconnect.

With this correction the UEFI SCT II tests for UninstallProtocolInterface()
and ReinstallProtocolInterface are passed.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:12 +02:00
Heinrich Schuchardt
dae7ce451c efi_loader: avoid crash in OpenProtocol()
When trying to open a protocol exclusively attached drivers have to be
removed. This removes entries in the open protocol information linked list
over which we are looping. As additionally child controllers may have been
removed the only safe thing to do is to restart the loop over the linked
list when a driver is removed.

By observing the return code of DisconnectController() we can eliminate a
loop.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:12 +02:00
Heinrich Schuchardt
399a39e34a efi_loader: correct OpenProtocol()
If a protocol is opened BY_DRIVER it cannot be opened by another agent
BY_DRIVER.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:12 +02:00
Heinrich Schuchardt
e31b3b1622 efi_loader: registration key in LocateProtocol()
In LocateProtocol() implement searching by the registration key returned by
RegisterNotifyProtocol().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:12 +02:00
Heinrich Schuchardt
b8abd743ff efi_loader: factor out efi_check_register_notify_event()
The code to check if a registration key is a valid key returned by
RegisterProtocolNotify() can be reused. So let us factor it out into a new
function efi_check_register_notify_event().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:11 +02:00
AKASHI Takahiro
8eee1d3ec6 efi_loader: bootmgr: print a message when loading from BootNext failed
If a user defines BootNext but not BootOrder and loading from BootNext
fails, you will see only a message like this:
	BootOrder not defined

This may confuse a user. Adding an error message will be helpful.

An example output looks like this:

=> efidebug boot add 0001 label1 scsi 0:1 "\path1\file1.efi" "--option foo"
=> efidebug boot add 0002 label2 scsi 0:1 "\path2\file2.efi" "--option bar"
=> efidebug boot add 0003 label3 scsi 0:1 "\path3\file3.efi" "--option no"
=> efidebug boot order 0001 0002
=> efidebug boot next 0003
=> bootefi bootmgr
Loading from Boot0003 'label3' failed
Loading from BootNext failed, falling back to BootOrder
Loading from Boot0001 'label1' failed
Loading from Boot0002 'label2' failed
EFI boot manager: Cannot load any image

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Adjust messages.
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:11 +02:00
Heinrich Schuchardt
f09cea36ca efi_loader: correct notification of protocol installation
When a protocol is installed the handle should be queued for the
registration key of each registered event. LocateHandle() should return the
first handle from the queue for the registration key and delete it from the
queue.

Implement the queueing.

Correct the selftest.

With the patch the UEFI SCT tests for LocateHandle() are passed without
failure.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-31 23:27:11 +02:00
AKASHI Takahiro
a2c6983740 efi_loader: variable: attributes may not be changed if a variable exists
If a variable already exists, efi_set_variable() should not change
the variable's attributes. This patch enforces it.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-24 18:58:14 +02:00
AKASHI Takahiro
dbebae5ec7 efi_loader: variable: return error for APPEND_WRITE
The current efi_st_variable() doesn't support EFI_VARIABLE_APPEND_WRITE
attiribute for now, and so should return an error.

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

Fix typos is commit message.
Add TODO comment.

Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-24 18:58:14 +02:00
AKASHI Takahiro
609b6ba61d efi: selftest: APPEND_WRITE is not supported
The error here should be marked *todo*.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-24 18:58:14 +02:00
Heinrich Schuchardt
2d51bd2926 efi_loader: DEL is an illegal file name character
According to the FAT32 specification 0x7f (DEL) is not a legal character
for file names.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-24 18:58:13 +02:00
Heinrich Schuchardt
20562893fa efi_loader: correct device path check
Since commit 226cddbe32 ("efi_loader: check device path in
InstallMultipleProtocolInterfaces") iPXE fails to access the network.

LocateDevicePath() returns EFI_SUCCESS even if a shorter path is found as a
partial match. It returns the remaining path. So to be sure that we found a
complete match we need to check that the remaining path refers to an end
node.

Provide debug output if a device path has already been installed.

Fixes: 226cddbe32 ("efi_loader: check device path in
       InstallMultipleProtocolInterfaces")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-24 18:58:13 +02:00
Heinrich Schuchardt
bb2b13d528 efi_loader: return values of GetTime()
According to the UEFI spec 2.8 the GetTime() runtime service should return
EFI_UNSUPPORTED if the real time clock is not available.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-24 18:58:13 +02:00
Heinrich Schuchardt
433bfe7b12 efi_loader: implement SetTime
Implement the SetTime() runtime service.

Extend the real time clock selftest to check setting the clock.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-24 18:58:13 +02:00
Thierry Reding
3bf2f15351 fdtdec: Remove fdt_{addr,size}_unpack()
U-Boot already defines the {upper,lower}_32_bits() macros that have the
same purpose. Use the existing macros instead of defining new APIs.

Signed-off-by: Thierry Reding <treding@nvidia.com>
2019-05-21 17:33:23 -06:00
Heinrich Schuchardt
b31ca6bf84 efi_loader: parameter check OutputString
Check the parameters against NULL.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
acee965263 efi_loader: EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.SetState() correct parameter
KeyToggleState is a pointer according to UEFI spec 2.8.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
1344f7d0f6 efi_loader: GetNextMonotonicCount() check parameter
Do not write to address indicated by NULL pointer.

UEFI SCT II 2.6 (2017), 3.6.5 GetNextMonotonicCount(), 5.1.5.5.1

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
db80fe3866 efi_loader: parameter checks CalculateCrc32()
Not checking the parameters may lead reading or writing from NULL.
Implement the parameter checks prescribed in the UEFI spec.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
226cddbe32 efi_loader: check device path in InstallMultipleProtocolInterfaces
According to the UEFI spec InstallMultipleProtocolInterfaces() must check
if a device path has already been installed. In this case it must return
EFI_ALREADY_STARTED.

Cf. UEFI SCT II 2.6 A (2017),
3.3.16 InstallMultipleProtocolInterfaces(), 5.1.3.16.1.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
b1b782d306 efi_loader: implement deprecated Unicode collation protocol
In EFI 1.10 a version of the Unicode collation protocol using ISO 639-2
language codes existed. This protocol is not part of the UEFI specification
any longer. Unfortunately it is required to run the UEFI Self Certification
Test (SCT) II, version 2.6, 2017. So we implement it here for the sole
purpose of running the SCT. It can be removed once a compliant SCT is
available.

The configuration option defaults to no.

Signed-off-by: Rob Clark <robdclark@gmail.com>

Most of Rob's original patch is already merged. Only the deprecated
protocol is missing. Rebase it and make it configurable.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
95ab381676 efi_loader: rename Unicode collation protocol 2 variables
Rename variables to make it clear they refer to the Unicode collation
protocol identified by the EFI_UNICODE_PROTOCOL2_GUID.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
f005f573a8 efi_loader: merge adjacent sprintf()
In the implementation of the device path to text protocol join adjacent
sprintf() statements.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
ce54fdc492 efi_loader: parameter checks simple network protocol
Check buffer pointers are not NULL as required by the UEFI 2.7 spec.

Return EFI_UNSUPPORTED instead of EFI_INVALID_PARAMETER when trying to
transmit with non-zero header_size.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
487d8c75f1 efi_loader: GetVariable set attributes for EFI_BUFFER_TOO_SMALL
UEFI spec 2.7 erratum A leaves it undefined if Attributes should be set if
GetVariable() returns EFI_BUFFER_TOO_SMALL.

UEFI spec 2.8 defines that Attributes should be set if the return value is
either EFI_SUCCESS or EFI_BUFFER_TOO_SMALL.

Set Attributes if the return value is EFI_BUFFER_TOO_SMALL.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-19 08:10:10 +02:00
Heinrich Schuchardt
05fefe7681 efi_loader: ACPI device node to text
The device path to text protocol renders ACPI device nodes incorrectly.

Use capital hexadecimal numbers as shown in the UEFI spec examples.

Always output the optional UID. This matches what UEFI SCT expects and
saves us an `if`.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
3b985113be efi_loader: infinite recursion notifying events
UEFI SCT uses this call sequence to determine the current TPL level inside
notification functions:

    OldTpl = BS->RaiseTPL(TPL_HIGH_LEVEL);
    BS->RestoreTPL(OldTpl);

In RestoreTPL() we trigger the notification function of queued events. If
we do not mark the event as non-queued before calling the notification
function, this results in an infinite recursive call sequence.

Mark the event as non-queued before entering the notification function.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
8ae39857b9 efi_loader: simplify efi_allocate_pages()
Replace unnecessary control structures by using return statements.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
f756fe83b0 efi_loader: AllocateAdress error handling
If AllocatePages() is called with AllocateAddress, the UEFI spec requires
to return EFI_NOT_FOUND in case the memory page does not exist.

The UEFI SCT II 2017 spec additionally requires to return EFI_NOT_FOUND if
the page is already allocated.

Check that *Memory refers to an unallocated page.

UEFI SCT II (2017): AllocatePages(), 5.1.2.1.9 - 5.1.2.1.10

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
735fd22800 efi_loader: out of resources in AllocatePages()
According to the UEFI AllocatePages() has to return EFI_OUT_OF_RESOURCES if
sufficient memory is not available.

Change the return value.

UEFI SCT II (2017): 3.2.1 AllocatePages(), 5.1.2.1.8

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
7d3af58ed9 efi_loader: check memory address before freeing
When we call FreePages() we essentially add memory to our memory map. We
shouldn't do this for memory that does not exit.

Check if the memory that is to be freed via FreePages() or FreePool() is in
our memory map and is not EFI_CONVENTIONAL_MEMORY.

This check is mandated by the UEFI specification.

Cf. UEFI SCT  II (2017), 3.2.2 FreePages(), 5.1.2.1 - 5.1.2.2

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
96aa99cded efi_loader: error code in UninstallProtocolInterface()
According to the UEFI specification UninstallProtocolInteface() has to
return EFI_NOT_FOUND if the interface is not found.

Correct the return value.

Cf. UEFI SCT II spec (2017), 3.3.2 UninstallProtocolInterface(), 5.1.3.2.4

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
61c63db7fe efi_loader: superfluous check in efi_remove_protocol()
efi_search_protocol() already checks that the GUID matches. Don't check
a second time.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
ab557141c2 efi_loader: LocateDevicePath() incorrect parameter check
A parameter check in LocateDevicePath() does not match the requirements of
the UEFI spec.

If device is NULL, only return EFI_INVALID_PARAMETER if a matching handle
is found.

Cf. UEFI SCT II specification (2017)3.3.7 LocateDevicePath(), 5.1.3.7.3

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
0a84319665 efi_loader: fix typo in efi_locate_handle() comment
%s/not buffer/no buffer/

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
64b5ba4d29 efi_loader: make device path to text protocol customizable
The device path to text protocol is not needed for EBBR compliance. So
let's make it a customizable option.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
334997356e efi_loader: make Unicode collation protocol customizable
The Unicode collation protocol is not needed for EBBR compliance. So let's
make it a customizable option.

The Unicode capitalization table is only needed by this protocol. So let it
depend on the Unicode collation protocol.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
9363fd22df efi_loader: reword the EFI_LOADER config option
No need to mention U-Boot in brief description.
Fix several typos, mention iPXE.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
5684c8d1ea efi_loader: format Kconfig
Use if/endif for dependencies to give structure to the configuration menu.

Sort important settings to the top.

Abbreviate the short description of EFI_LOADER_HII.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
5ad3877448 efi_loader: observe CONFIG_EFI_LOADER_HII
If EFI_LOADER_HII is not set, do not unnecessarily compile files for HII
protocols.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12 20:54:22 +02:00
Heinrich Schuchardt
b015ab57bf efi_loader: signature of ExitBootServices()
Consistently use efi_uintn_t as type of memory keys.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Alexander Graf <graf@amazon.com>
2019-05-07 21:10:04 +02:00
Heinrich Schuchardt
470dfa50da efi_loader: LoadImage() check source size
If the size of the source buffer is 0, return EFI_LOAD_ERROR.
(UEFI SCT II 2017: 3.4.1 LoadImage() - 5.1.4.1.6)

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-07 21:10:04 +02:00
Heinrich Schuchardt
84a918e8ce efi_loader: LoadImage() check parent image
If the parent image handle does not refer to a loaded image return
EFI_INVALID_PARAMETER.
(UEFI SCT II 2017: 3.4.1 LoadImage() - 5.1.4.1.1)

Mark our root node as a loaded image to avoid an error when using it as
parent image.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-07 21:10:04 +02:00