Commit Graph

237 Commits

Author SHA1 Message Date
Heinrich Schuchardt
04298686a4 efi_loader: return NULL from device path functions
For the construction of device paths we need to call the
AllocatePool service. We should not ignore if it fails due to an
out of memory situation.

This patch changes the device path functions to return NULL if
the memory allocation fails.

Additional patches will be needed to fix the callers.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
2074f70064 efi_loader: consistently use efi_handle_t for handles
We should consistently use the efi_handle_t typedef when
referring to handles.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
ad97373ba9 efi_loader: disconnect controllers in UninstallProtocol
The UninstallProtocol boot service should first try to
disconnect controllers that have been connected with
EFI_OPEN_PROTOCOL_BY_DRIVER.

If the protocol is still opened by an agent, it should be
closed.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
3f9b00425a efi_loader: implement DisconnectController
Unfortunately we need a forward declaration because both
OpenProtocol and CloseProtocol have to call DisconnectController.
And DisconnectController calls both OpenProtcol and CloseProtocol.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
3ebcd0071f efi_loader: fix signature of efi_disconnect_controller
Handles should be passed as efi_handle_t and not as void *.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
f0959dbee2 efi_loader: implement ConnectController
Implement the ConnectController boot service.

A unit test is supplied in a subsequent patch.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
d550414434 efi_loader: debug output installed device path
When a device path protocol is installed write the device
path to the console in debug mode.

For printing the new macro EFI_PRINT is used, which can be reused
for future diagnostic output.

Remove unused EFI_PRINT_GUID macro

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
e3fbbc36f2 efi_loader: implement OpenProtocolInformation
efi_open_protocol_information provides the agent and controller
handles as well as the attributes and open count of an protocol
on a handle.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
[agraf: fix counting error]
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
3b8a489c9f efi_loader: open_info in CloseProtocol
efi_open_protocol and efi_close_protocol have to keep track of
opened protocols.

Check if the protocol was opened for the same agent and
controller.

Remove all open protocol information for this pair.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
191a41cc32 efi_loader: open_info in OpenProtocol
efi_open_protocol has to keep track of opened protocols.

OpenProtocol enters the agent and controller handle
information into this list.

A unit test is supplied with a subsequent patch.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
fe1599daf5 efi_loader: list of open protocol infos
Add a list of open protocol infos to each protocol of a handle.

Provide helper functions to access the list items.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:13 +01:00
Heinrich Schuchardt
32e6fed6e9 efi_loader: simplify efi_remove_all_protocols
Replace list_for_each_safe() and list_entry() by
list_for_each_entry_safe().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Heinrich Schuchardt
727a1afb34 efi_loader: correctly call images
Avoid a failed assertion when an EFI app calls an EFI app.

Avoid that the indent level increases when calling 'bootefi hello'
repeatedly.

Avoid negative indent level when an EFI app calls an EFI app that
calls an EFI app (e.g. iPXE loads grub which starts the kernel).

Return the status code of a loaded image that returns without
calling the Exit boot service.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Heinrich Schuchardt
3c950b3178 efi_loader: text output for device path end node
Without the patch a device path consisting only of an end node is
displayed as '/UNKNOWN(007f,00ff)'. It should be displayed as '/'.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Heinrich Schuchardt
e540c48636 efi_loader: use correct format string for unsigned long
virt_size is of type unsigned long.
So it should be printed with %ul.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Heinrich Schuchardt
474a6f5aa1 efi_loader: add comments to memory functions
Add comments describing memory functions.

Fix the formatting of a function declaration.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Heinrich Schuchardt
05b6f56ead efi_loader: use wide string do define firmware vendor
As the U-Boot is compiled with -fshort-wchar we can define
the firmware vendor constant as wide string.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Heinrich Schuchardt
af3106a12d efi_loader: support device path for IDE and SCSI disks
Correctly create the device path for IDE and SCSI disks.

Support for SATA remains to be done in a future patch.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Heinrich Schuchardt
2bc61b8352 efi_loader: create full device path for block devices
When creating the device path of a block device it has to
comprise the block device itself and should not end at
its parent.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-01-22 23:09:12 +01:00
Emmanuel Vadot
5f77083628 efi_loader: Setup logical_partition media information
When adding a partition, set the logical_partition member in the media
structure as mandated by the UEFI spec.

Signed-off-by: Emmanuel Vadot <manu@freebsd.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2017-12-19 07:57:02 -05:00
Heinrich Schuchardt
bde6bfe4c3 efi_loader: comments for dp_part_fill()
Add a description for dp_part_fill().
Reword a comment in the function.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 23:07:56 +01:00
Heinrich Schuchardt
6ea8b580f0 efi_loader: correct DeviceNodeToText for media types
When converting device nodes and paths to text we should
stick to the UEFI spec.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 23:07:56 +01:00
Heinrich Schuchardt
7b982f009b efi_loader: correctly setup device paths for block devices
According to the UEFI spec the numbering of partitions has to
start with 1.

Partion number 0 is reserved for the optional device path for
the complete block device.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 23:07:55 +01:00
Heinrich Schuchardt
66b051d51f efi_loader: correctly determine if an MMC device is an SD-card
The SD cards and eMMC devices have different device nodes.
The current coding interpretes all MMC devices as eMMC.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 23:07:55 +01:00
Heinrich Schuchardt
b9b17598f4 efi_loader: error handling in efi_load_image()
If a failure occurs when trying to load an image, it is insufficient
to free() the EFI object. We must remove it from the object list,
too. Otherwise a use after free will occur the next time we
iterate over the object list.

Furthermore errors in setting up the image should be handled.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 23:07:55 +01:00
Heinrich Schuchardt
678e03a00c efi_loader: new function efi_delete_handle()
Provide a function to remove a handle from the object list
after removing all protocols.

To avoid forward declarations other functions have to move up
in the coding.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 23:07:36 +01:00
Heinrich Schuchardt
56d9288858 efi_loader: return status from efi_setup_loaded_image()
efi_setup_loaded_image() should return an error code indicating if
an error has occurred.

An error occurs if a protocol cannot be installed.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 23:07:25 +01:00
Alexander Graf
905cb9e172 efi_loader: Ensure efi_dp_find_obj() finds exact matches
When calling efi_dp_find_obj(), we usually want to find the *exact* match
of an object for a given device path. However, I ran into a nasty corner case
where I had the following objects with paths available:

Handle 0x9feffa70
  /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/EndEntire
Handle 0x9feffb58
  /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/HD(1,800,32000,2de808cb00000000,1,1)/EndEntire

and was searching for

  /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/HD(1,800,32000,2de808cb00000000,1,1)/EndEntire

But because our device path search looked for any substring match, it would
return

  /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/EndEntire

because that path is a full substring of the path we were searching for.

So this patch adapts the device path search logic to always look for exact
matches first. The way we distinguish between those cases is by looking at
whether our caller actually deals with remainders.

As a side effect, the code as is from all I can tell now never does a
substring match anymore, because it always gets called with rem=NULL, so
we always only do exact matches now.

Reported-by: Jonathan Gray <jsg@jsg.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-16 22:51:19 +01:00
Alexander Graf
ae67dca5e6 efi_loader: helloworld.c: Explicitly use .rodata for loaded_image_guid
Commit bbf75dd934 ("efi_loader: output load options in helloworld")
introduced a const variable in efi_main() called loaded_image_guid which
got populated from a constant struct.

While you would usually expect a compiler to realize that this variable
should really just be a global pointer to .rodata, gcc disagrees and instead
puts it on the stack. Unfortunately in some implementations of gcc it does
so my calling memcpy() which we do not implement in our hello world
environment.

So let's explicitly move it to a global variable which in turn puts it in
.rodata reliably and gets rid of the memcpy().

Fixes: bbf75dd934 ("efi_loader: output load options in helloworld")
Reported-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
2017-12-16 22:51:19 +01:00
Alexander Graf
3bb74f9800 efi_loader helloworld.efi: Fix building with -Os
Depending on your compiler, when compiling the hello world efi binary
with -Os, gcc might think it's a smart idea to replace common patterns
such as memory copies with explicit calls to memcpy().

While that sounds great at first, we don't have any memcpy() available
in our helloworld build target. So let's indicate to gcc that we really
do want to have the code be built as freestanding.

Fixes: bbf75dd9 ("efi_loader: output load options in helloworld")
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 22:31:00 +01:00
Alexander Graf
c034b7fd41 efi_loader: Fix partition offsets
Commit 884bcf6f65 (efi_loader: use proper device-paths for partitions) tried
to introduce the el torito scheme to all partition table types: Spawn
individual disk objects for each partition on a disk.

Unfortunately, that code ended up creating partitions with offset=0 which meant
that anyone accessing these objects gets data from the raw block device instead
of the partition.

Furthermore, all the el torito logic to spawn devices for partitions was
duplicated. So let's merge the two code paths and give partition disk objects
good offsets to work from, so that payloads can actually make use of them.

Fixes: 884bcf6f65 (efi_loader: use proper device-paths for partitions)
Reported-by: Yousaf Kaukab <yousaf.kaukab@suse.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 22:30:47 +01:00
Rob Clark
1a0b4d22a9 efi_loader: add missing breaks
Otherwise with GUID partition types you would end up with things like:

  .../HD(Part0,Sig6252c819-4624-4995-8d16-abc9cd5d4130)/HD(Part0,MBRType=02,SigType=02)

Signed-off-by: Rob Clark <robdclark@gmail.com>
[agraf: rebased]
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 22:29:02 +01:00
Heinrich Schuchardt
c4574208b0 efi_loader: comments for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
Provide comments for efi_convert_device_node_to_text()
and efi_convert_device_path_to_text().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:43:00 +01:00
Heinrich Schuchardt
44549d62c3 efi_loader: helper function to add EFI object to list
To avoid duplicate coding provide a helper function that
initializes an EFI object and adds it to the EFI object
list.

efi_exit() is the only place where we dereference a handle
to obtain a protocol interface. Add a comment to the function.

Suggested-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:41:01 +01:00
Heinrich Schuchardt
ea54ad5928 efi_loader: pass handle of loaded image
The handle of a loaded image is the value of the handle
member of the loaded image info object and not the
address of the loaded image info.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:40:07 +01:00
Heinrich Schuchardt
bbf75dd934 efi_loader: output load options in helloworld
We need to test if we pass a valid image handle when loading
and EFI application. This cannot be done in efi_selftest as
it is not loaded as an image.

So let's enhance helloworld a bit.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:39:20 +01:00
Heinrich Schuchardt
69fb6b1afc efi_loader: manage protocols in a linked list
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:37:49 +01:00
Heinrich Schuchardt
72292aba4f efi_loader: simplify find_obj
Use function efi_search_protocol().

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:37:20 +01:00
Heinrich Schuchardt
80286e8f81 efi_loader: simplify efi_open_protocol
Use function efi_search_protocol.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:37:06 +01:00
Heinrich Schuchardt
9449358a71 efi_loader: efi_gop: use efi_add_protocol
Use efi_add_protocol to add protocol.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:36:49 +01:00
Heinrich Schuchardt
84d14568ca efi_loader: efi_net: use efi_add_protocol
Use efi_add_protocol to add protocols.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:36:40 +01:00
Heinrich Schuchardt
4b9f7aaf7c efi_loader: efi_disk: use efi_add_protocol
Use efi_add_protocol to install protocols.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:36:17 +01:00
Heinrich Schuchardt
ae2c85c1ce efi_loader: reimplement LocateDevicePath
The current implementation of efi_locate_device_path does not match
the UEFI specification. It completely ignores the protocol
parameters.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:35:30 +01:00
Heinrich Schuchardt
61aba1931a efi_loader: fix efi_convert_device_node_to_text
We need to implement to different functions for the
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL:
ConvertDeviceNodeToText
ConvertDevicePathToText

A recent patch screwed up efi_convert_device_node_to_text
to expect a device path and not a node.

The patch makes both service functions work again.

efi_convert_device_node_to_text is renamed to
efi_convert_single_device_node_to_text and
efi_convert_device_node_to_text_ext is renamed to
efi_convert_device_node_to_text to avoid future
confusion.

A test of ConvertDeviceNodeToText will be provided in
a follow-up patch.

Fixes: adae4313cd efi_loader: flesh out device-path to text
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:35:05 +01:00
Heinrich Schuchardt
908cf9a3ff efi_loader: efi_dp_str should print path not node
efi_dp_str is meant to print a device path and not a device
node.

The old coding only worked because efi_convert_device_node_to_text
was screwed up to expect paths instead of nodes.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:33:22 +01:00
Heinrich Schuchardt
0741226f65 efi_loader: size of media device path node represenation
In the format specifier we want to specify the maximum width
in case an ending \0 is missing.

So slen must be used as precision and not as field width.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:32:41 +01:00
Heinrich Schuchardt
362f00f979 efi_loader: helloworld.c: remove superfluous include
Remove a superfluous include from helloworld.c

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:25:43 +01:00
Jonathan Gray
b6e9e09770 efi_loader: initialise partition_signature memory
Zero partition_signature in the efi_device_path_hard_drive_path
structure when signature_type is 0 (no signature) as required by the
UEFI specification.

This is required so that efi_dp_match() will work as expected
when doing memcmp() comparisons.  Previously uninitialised memory
would cause it not match nodes when it should have when the signature
type was not GUID.

Corrects a problem where the loaded image protocol would not return a
device path with MEDIA_DEVICE causing the OpenBSD bootloader to fail
on rpi_3 and other targets.

v2: Also handle signature_type 1 (MBR) as described in the specification

Signed-off-by: Jonathan Gray <jsg@jsg.id.au>
Tested-by: Artturi Alm <artturi.alm@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:23:02 +01:00
Heinrich Schuchardt
ebb4dd5bc3 efi_loader: efi_console: use helper functions
Use helper functions efi_created_handle and efi_add_protocol
for creating the console handles and instaling the respective
protocols.

This change is needed if we want to move from an array of
protocols to a linked list of protocols.

Eliminate EFI_PROTOCOL_OBJECT which is not used anymore.

Currently we have not defined protocol interfaces to be const.
So efi_con_out and efi_console_control cannot be defined as const.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:22:56 +01:00
Heinrich Schuchardt
48b66230ee efi_loader: refactor efi_setup_loaded_image
Use helper functions to add protocols.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01 13:22:56 +01:00