summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2018-01-23 07:59:43 -0500
committerTom Rini <trini@konsulko.com>2018-01-23 07:59:43 -0500
commita516416d75a9b0f52e9d63d47f8a7bd53239767c (patch)
tree25c580d1b723821f5f1ddf4a0f4f681141720de8 /include
parentc761a7e29d703d60208585bb7d8415e00aa22556 (diff)
parent003876d4694f1bfdfe6ff9ff0799fda9257cb652 (diff)
Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot
Patch queue for efi - 2018-01-23 This time around we have a lot of EFI patches from Heinrich. Highlights are: - Allow EFI applications to register as drivers - Allow exposure of U-Boot block devices from an EFI payload - Compatibility improvements
Diffstat (limited to 'include')
-rw-r--r--include/blk.h1
-rw-r--r--include/config_fallbacks.h1
-rw-r--r--include/dm/uclass-id.h1
-rw-r--r--include/efi_api.h81
-rw-r--r--include/efi_driver.h30
-rw-r--r--include/efi_loader.h59
-rw-r--r--include/efi_selftest.h27
7 files changed, 160 insertions, 40 deletions
diff --git a/include/blk.h b/include/blk.h
index 41b4d7efa8..69b5a98e56 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -34,6 +34,7 @@ enum if_type {
IF_TYPE_HOST,
IF_TYPE_SYSTEMACE,
IF_TYPE_NVME,
+ IF_TYPE_EFI,
IF_TYPE_COUNT, /* Number of interface types */
};
diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h
index 76b13c3b30..9695ee7ffb 100644
--- a/include/config_fallbacks.h
+++ b/include/config_fallbacks.h
@@ -39,6 +39,7 @@
defined(CONFIG_MMC) || \
defined(CONFIG_NVME) || \
defined(CONFIG_SYSTEMACE) || \
+ (defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)) || \
defined(CONFIG_SANDBOX)
#define HAVE_BLOCK_DEVICE
#endif
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 3fc20834ae..07fabc3ce6 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -34,6 +34,7 @@ enum uclass_id {
UCLASS_CROS_EC, /* Chrome OS EC */
UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */
UCLASS_DMA, /* Direct Memory Access */
+ UCLASS_EFI, /* EFI managed devices */
UCLASS_ETH, /* Ethernet device */
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
UCLASS_FIRMWARE, /* Firmware */
diff --git a/include/efi_api.h b/include/efi_api.h
index 584016dc30..205f8f1f70 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -84,11 +84,12 @@ struct efi_boot_services {
efi_status_t (EFIAPI *reinstall_protocol_interface)(
void *handle, const efi_guid_t *protocol,
void *old_interface, void *new_interface);
- efi_status_t (EFIAPI *uninstall_protocol_interface)(void *handle,
- const efi_guid_t *protocol, void *protocol_interface);
- efi_status_t (EFIAPI *handle_protocol)(efi_handle_t,
- const efi_guid_t *protocol,
- void **protocol_interface);
+ efi_status_t (EFIAPI *uninstall_protocol_interface)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void *protocol_interface);
+ efi_status_t (EFIAPI *handle_protocol)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void **protocol_interface);
void *reserved;
efi_status_t (EFIAPI *register_protocol_notify)(
const efi_guid_t *protocol, struct efi_event *event,
@@ -113,7 +114,7 @@ struct efi_boot_services {
efi_status_t (EFIAPI *exit)(efi_handle_t handle,
efi_status_t exit_status,
unsigned long exitdata_size, s16 *exitdata);
- efi_status_t (EFIAPI *unload_image)(void *image_handle);
+ efi_status_t (EFIAPI *unload_image)(efi_handle_t image_handle);
efi_status_t (EFIAPI *exit_boot_services)(efi_handle_t, unsigned long);
efi_status_t (EFIAPI *get_next_monotonic_count)(u64 *count);
@@ -125,8 +126,10 @@ struct efi_boot_services {
efi_handle_t *driver_image_handle,
struct efi_device_path *remaining_device_path,
bool recursive);
- efi_status_t (EFIAPI *disconnect_controller)(void *controller_handle,
- void *driver_image_handle, void *child_handle);
+ efi_status_t (EFIAPI *disconnect_controller)(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle);
#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
@@ -137,9 +140,10 @@ struct efi_boot_services {
const efi_guid_t *protocol, void **interface,
efi_handle_t agent_handle,
efi_handle_t controller_handle, u32 attributes);
- efi_status_t (EFIAPI *close_protocol)(void *handle,
- const efi_guid_t *protocol, void *agent_handle,
- void *controller_handle);
+ efi_status_t (EFIAPI *close_protocol)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ efi_handle_t agent_handle,
+ efi_handle_t controller_handle);
efi_status_t(EFIAPI *open_protocol_information)(efi_handle_t handle,
const efi_guid_t *protocol,
struct efi_open_protocol_info_entry **entry_buffer,
@@ -243,11 +247,11 @@ struct efi_system_table {
struct efi_table_hdr hdr;
unsigned long fw_vendor; /* physical addr of wchar_t vendor string */
u32 fw_revision;
- unsigned long con_in_handle;
+ efi_handle_t con_in_handle;
struct efi_simple_input_interface *con_in;
- unsigned long con_out_handle;
+ efi_handle_t con_out_handle;
struct efi_simple_text_output_protocol *con_out;
- unsigned long stderr_handle;
+ efi_handle_t stderr_handle;
struct efi_simple_text_output_protocol *std_err;
struct efi_runtime_services *runtime;
struct efi_boot_services *boottime;
@@ -329,12 +333,27 @@ struct efi_device_path_acpi_path {
} __packed;
#define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03
+# define DEVICE_PATH_SUB_TYPE_MSG_ATAPI 0x01
+# define DEVICE_PATH_SUB_TYPE_MSG_SCSI 0x02
# define DEVICE_PATH_SUB_TYPE_MSG_USB 0x05
# define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b
# define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS 0x0f
# define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a
# define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d
+struct efi_device_path_atapi {
+ struct efi_device_path dp;
+ u8 primary_secondary;
+ u8 slave_master;
+ u16 logical_unit_number;
+} __packed;
+
+struct efi_device_path_scsi {
+ struct efi_device_path dp;
+ u16 target_id;
+ u16 logical_unit_number;
+} __packed;
+
struct efi_device_path_usb {
struct efi_device_path dp;
u8 parent_port_number;
@@ -405,18 +424,26 @@ struct efi_block_io_media
u32 io_align;
u8 pad2[4];
u64 last_block;
+ /* Added in revision 2 of the protocol */
+ u64 lowest_aligned_lba;
+ u32 logical_blocks_per_physical_block;
+ /* Added in revision 3 of the protocol */
+ u32 optimal_transfer_length_granualarity;
};
+#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001
+#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x0002001f
+
struct efi_block_io {
u64 revision;
struct efi_block_io_media *media;
efi_status_t (EFIAPI *reset)(struct efi_block_io *this,
char extended_verification);
efi_status_t (EFIAPI *read_blocks)(struct efi_block_io *this,
- u32 media_id, u64 lba, unsigned long buffer_size,
+ u32 media_id, u64 lba, efi_uintn_t buffer_size,
void *buffer);
efi_status_t (EFIAPI *write_blocks)(struct efi_block_io *this,
- u32 media_id, u64 lba, unsigned long buffer_size,
+ u32 media_id, u64 lba, efi_uintn_t buffer_size,
void *buffer);
efi_status_t (EFIAPI *flush_blocks)(struct efi_block_io *this);
};
@@ -790,4 +817,26 @@ struct efi_file_info {
s16 file_name[0];
};
+#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0x18a031ab, 0xb443, 0x4d1a,\
+ 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71)
+struct efi_driver_binding_protocol {
+ efi_status_t (EFIAPI * supported)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path);
+ efi_status_t (EFIAPI * start)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path);
+ efi_status_t (EFIAPI * stop)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ efi_uintn_t number_of_children,
+ efi_handle_t *child_handle_buffer);
+ u32 version;
+ efi_handle_t image_handle;
+ efi_handle_t driver_binding_handle;
+};
+
#endif
diff --git a/include/efi_driver.h b/include/efi_driver.h
new file mode 100644
index 0000000000..2bbe26c6e3
--- /dev/null
+++ b/include/efi_driver.h
@@ -0,0 +1,30 @@
+/*
+ * EFI application loader
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _EFI_DRIVER_H
+#define _EFI_DRIVER_H 1
+
+#include <common.h>
+#include <dm.h>
+#include <efi_loader.h>
+
+struct efi_driver_ops {
+ const efi_guid_t *protocol;
+ const efi_guid_t *child_protocol;
+ int (*bind)(efi_handle_t handle, void *interface);
+};
+
+/*
+ * This structure adds internal fields to the driver binding protocol.
+ */
+struct efi_driver_binding_extended_protocol {
+ struct efi_driver_binding_protocol bp;
+ const struct efi_driver_ops *ops;
+};
+
+#endif /* _EFI_DRIVER_H */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 6185055e78..21c03c5c28 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -69,10 +69,11 @@ const char *__efi_nesting_dec(void);
} while(0)
/*
- * Write GUID
+ * Write an indented message with EFI prefix
*/
-#define EFI_PRINT_GUID(txt, guid) ({ \
- debug("%sEFI: %s %pUl\n", __efi_nesting(), txt, guid); \
+#define EFI_PRINT(format, ...) ({ \
+ debug("%sEFI: " format, __efi_nesting(), \
+ ##__VA_ARGS__); \
})
extern struct efi_runtime_services efi_runtime_services;
@@ -85,9 +86,13 @@ extern const struct efi_device_path_to_text_protocol efi_device_path_to_text;
uint16_t *efi_dp_str(struct efi_device_path *dp);
+/* GUID of the EFI_BLOCK_IO_PROTOCOL */
+extern const efi_guid_t efi_block_io_guid;
extern const efi_guid_t efi_global_variable_guid;
extern const efi_guid_t efi_guid_console_control;
extern const efi_guid_t efi_guid_device_path;
+/* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
+extern const efi_guid_t efi_guid_driver_binding_protocol;
extern const efi_guid_t efi_guid_loaded_image;
extern const efi_guid_t efi_guid_device_path_to_text_protocol;
extern const efi_guid_t efi_simple_file_system_protocol_guid;
@@ -97,14 +102,27 @@ extern unsigned int __efi_runtime_start, __efi_runtime_stop;
extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
/*
+ * When a protocol is opened a open protocol info entry is created.
+ * These are maintained in a list.
+ */
+struct efi_open_protocol_info_item {
+ /* Link to the list of open protocol info entries of a protocol */
+ struct list_head link;
+ struct efi_open_protocol_info_entry info;
+};
+
+/*
* When the UEFI payload wants to open a protocol on an object to get its
* interface (usually a struct with callback functions), this struct maps the
- * protocol GUID to the respective protocol interface */
+ * protocol GUID to the respective protocol interface
+ */
struct efi_handler {
/* Link to the list of protocols of a handle */
struct list_head link;
const efi_guid_t *guid;
void *protocol_interface;
+ /* Link to the list of open protocol info items */
+ struct list_head open_infos;
};
/*
@@ -156,6 +174,10 @@ extern struct list_head efi_obj_list;
int efi_console_register(void);
/* Called by bootefi to make all disk storage accessible as EFI objects */
int efi_disk_register(void);
+/* Create handles and protocols for the partitions of a block device */
+int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
+ const char *if_typename, int diskid,
+ const char *pdevname);
/* Called by bootefi to make GOP (graphical) interface available */
int efi_gop_register(void);
/* Called by bootefi to make the network interface available */
@@ -189,23 +211,25 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path);
/* Add a new object to the object list. */
void efi_add_handle(struct efi_object *obj);
/* Create handle */
-efi_status_t efi_create_handle(void **handle);
+efi_status_t efi_create_handle(efi_handle_t *handle);
/* Delete handle */
void efi_delete_handle(struct efi_object *obj);
/* Call this to validate a handle and find the EFI object for it */
-struct efi_object *efi_search_obj(const void *handle);
+struct efi_object *efi_search_obj(const efi_handle_t handle);
/* Find a protocol on a handle */
-efi_status_t efi_search_protocol(const void *handle,
+efi_status_t efi_search_protocol(const efi_handle_t handle,
const efi_guid_t *protocol_guid,
struct efi_handler **handler);
/* Install new protocol on a handle */
-efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_add_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface);
/* Delete protocol from a handle */
-efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_remove_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface);
/* Delete all protocols from a handle */
-efi_status_t efi_remove_all_protocols(const void *handle);
+efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
/* Call this to create an event */
efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
@@ -216,7 +240,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
uint64_t trigger_time);
/* Call this to signal an event */
-void efi_signal_event(struct efi_event *event);
+void efi_signal_event(struct efi_event *event, bool check_tpl);
/* open file system: */
struct efi_simple_file_system_protocol *efi_simple_file_system(
@@ -247,6 +271,8 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
/* Adds a range into the EFI memory map */
uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
bool overlap_only_ram);
+/* Called by board init to initialize the EFI drivers */
+int efi_driver_init(void);
/* Called by board init to initialize the EFI memory map */
int efi_memory_init(void);
/* Adds new or overrides configuration table entry to the system table */
@@ -280,15 +306,20 @@ struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
struct efi_device_path *efi_dp_from_dev(struct udevice *dev);
struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
+/* Create a device node for a block device partition. */
+struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
const char *path);
struct efi_device_path *efi_dp_from_eth(void);
struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
uint64_t start_address,
uint64_t end_address);
-void efi_dp_split_file_path(struct efi_device_path *full_path,
- struct efi_device_path **device_path,
- struct efi_device_path **file_path);
+/* Determine the last device path node that is not the end node. */
+const struct efi_device_path *efi_dp_last_node(
+ const struct efi_device_path *dp);
+efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
+ struct efi_device_path **device_path,
+ struct efi_device_path **file_path);
#define EFI_DP_TYPE(_dp, _type, _subtype) \
(((_dp)->type == DEVICE_PATH_TYPE_##_type) && \
diff --git a/include/efi_selftest.h b/include/efi_selftest.h
index be5ba4bfa9..08dd8e43ad 100644
--- a/include/efi_selftest.h
+++ b/include/efi_selftest.h
@@ -19,13 +19,19 @@
#define EFI_ST_FAILURE 1
/*
+ * Prints a message.
+ */
+#define efi_st_printf(...) \
+ (efi_st_printc(-1, __VA_ARGS__))
+
+/*
* Prints an error message.
*
* @... format string followed by fields to print
*/
#define efi_st_error(...) \
- (efi_st_printf("%s(%u):\nERROR: ", __FILE__, __LINE__), \
- efi_st_printf(__VA_ARGS__)) \
+ (efi_st_printc(EFI_LIGHTRED, "%s(%u):\nERROR: ", __FILE__, __LINE__), \
+ efi_st_printc(EFI_LIGHTRED, __VA_ARGS__))
/*
* Prints a TODO message.
@@ -33,8 +39,8 @@
* @... format string followed by fields to print
*/
#define efi_st_todo(...) \
- (efi_st_printf("%s(%u):\nTODO: ", __FILE__, __LINE__), \
- efi_st_printf(__VA_ARGS__)) \
+ (efi_st_printc(EFI_YELLOW, "%s(%u):\nTODO: ", __FILE__, __LINE__), \
+ efi_st_printc(EFI_YELLOW, __VA_ARGS__)) \
/*
* A test may be setup and executed at boottime,
@@ -61,14 +67,15 @@ extern struct efi_simple_input_interface *con_in;
void efi_st_exit_boot_services(void);
/*
- * Print a pointer to an u16 string
+ * Print a colored message
*
- * @pointer: pointer
- * @buf: pointer to buffer address
- * on return position of terminating zero word
+ * @color color, see constants in efi_api.h, use -1 for no color
+ * @fmt printf format
+ * @... arguments to be printed
+ * on return position of terminating zero word
*/
-void efi_st_printf(const char *fmt, ...)
- __attribute__ ((format (__printf__, 1, 2)));
+void efi_st_printc(int color, const char *fmt, ...)
+ __attribute__ ((format (__printf__, 2, 3)));
/*
* Compare memory.