diff options
-rw-r--r-- | cmd/efidebug.c | 2 | ||||
-rw-r--r-- | doc/usage/askenv.rst | 87 | ||||
-rw-r--r-- | doc/usage/index.rst | 1 | ||||
-rw-r--r-- | drivers/core/device.c | 7 | ||||
-rw-r--r-- | include/efi_loader.h | 6 | ||||
-rw-r--r-- | include/smbios.h | 2 | ||||
-rw-r--r-- | lib/efi_driver/Makefile | 1 | ||||
-rw-r--r-- | lib/efi_driver/efi_dm_integration.c | 36 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_disk.c | 72 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_tpl.c | 2 | ||||
-rw-r--r-- | lib/smbios.c | 24 |
12 files changed, 201 insertions, 40 deletions
diff --git a/cmd/efidebug.c b/cmd/efidebug.c index c635271..8211a58 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -1340,7 +1340,7 @@ static int show_efi_boot_order(void) num = size / sizeof(u16); for (i = 0; i < num; i++) { efi_create_indexed_name(var_name16, sizeof(var_name16), - "Boot", i); + "Boot", bootorder[i]); size = 0; ret = EFI_CALL(efi_get_variable(var_name16, diff --git a/doc/usage/askenv.rst b/doc/usage/askenv.rst new file mode 100644 index 0000000..5c4ca35 --- /dev/null +++ b/doc/usage/askenv.rst @@ -0,0 +1,87 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +askenv command +=============== + +Synopsis +-------- + +:: + + askenv name [message] [size] + +Description +----------- + +Display message and get environment variable name of max size characters +from stdin. + +name + name of the environment variable + +message + message is displayed while the command waits for the value to be + entered from stdin.if no message is specified,a default message + "Please enter name:" will be displayed. + +size + maximum number of characters that will be stored in environment + variable name.this is in decimal number format (unlike in + other commands where size values are in hexa-decimal). Default + value of size is 1023 (CONFIG_SYS_CBSIZE - 1). + +Example +------- + +Value of a environment variable env1 without message and size parameters: + +:: + + => askenv env1;echo $? + Please enter 'env1': val1 + 0 + => printenv env1 + env1=val1 + +Value of a environment variable env2 with message and size parameters: + +:: + + => askenv env2 Please type-in a value for env2: 10;echo $? + Please type-in a value for env2: 1234567890123 + 0 + => printenv env2 + env2=1234567890 + +Value of a environment variable env3 with size parameter only: + +:: + + => askenv env3 10;echo $? + Please enter 'env3': val3 + 0 + => printenv env3 + env3=val3 + +Return Value of askenv command, when used without any other arguments: + +:: + + => askenv;echo $? + askenv - get environment variables from stdin + + Usage: + askenv name [message] [size] + - display 'message' and get environment variable 'name' from stdin (max 'size' chars) + 1 + +Configuration +------------- + +The askenv command is only available if CMD_ASKENV=y + +Return value +------------ + +The return value $? is set to 0 (true). +If no other arguments are specified (along with askenv), it is set to 1 (false). diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 843b437..40b796a 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -17,6 +17,7 @@ Shell commands :maxdepth: 1 addrmap + askenv base bootefi booti diff --git a/drivers/core/device.c b/drivers/core/device.c index cb960f8..7355a5c 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -14,6 +14,7 @@ #include <asm/global_data.h> #include <asm/io.h> #include <clk.h> +#include <efi_loader.h> #include <fdtdec.h> #include <fdt_support.h> #include <malloc.h> @@ -579,6 +580,12 @@ int device_probe(struct udevice *dev) if (dev->parent && device_get_uclass_id(dev) == UCLASS_PINCTRL) pinctrl_select_state(dev, "default"); + if (CONFIG_IS_ENABLED(EFI_LOADER)) { + ret = efi_post_probe_device(dev); + if (ret) + goto fail_uclass; + } + return 0; fail_uclass: if (device_remove(dev, DM_REMOVE_NORMAL)) { diff --git a/include/efi_loader.h b/include/efi_loader.h index 0a9c82a..78dd687 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -17,6 +17,7 @@ #include <pe.h> struct blk_desc; +struct udevice; static inline int guidcmp(const void *g1, const void *g2) { @@ -28,6 +29,9 @@ static inline void *guidcpy(void *dst, const void *src) return memcpy(dst, src, sizeof(efi_guid_t)); } +/* Called by device_probe() */ +int efi_post_probe_device(struct udevice *dev); + /* No need for efi loader support in SPL */ #if CONFIG_IS_ENABLED(EFI_LOADER) @@ -420,6 +424,8 @@ efi_status_t EFIAPI efi_convert_pointer(efi_uintn_t debug_disposition, void efi_carve_out_dt_rsv(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); +/* Called when a block devices has been probed */ +efi_status_t efi_block_device_register(struct udevice *dev); /* Called by bootefi to make all disk storage accessible as EFI objects */ efi_status_t efi_disk_register(void); /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ diff --git a/include/smbios.h b/include/smbios.h index ffeefb4..fc49fc1 100644 --- a/include/smbios.h +++ b/include/smbios.h @@ -60,7 +60,7 @@ struct __packed smbios_entry { #define BIOS_CHARACTERISTICS_SELECTABLE_BOOT (1 << 16) #define BIOS_CHARACTERISTICS_EXT1_ACPI (1 << 0) -#define BIOS_CHARACTERISTICS_EXT1_UEFI (1 << 3) +#define BIOS_CHARACTERISTICS_EXT2_UEFI (1 << 3) #define BIOS_CHARACTERISTICS_EXT2_TARGET (1 << 2) struct __packed smbios_type0 { diff --git a/lib/efi_driver/Makefile b/lib/efi_driver/Makefile index 83baa1c..f0d5fa5 100644 --- a/lib/efi_driver/Makefile +++ b/lib/efi_driver/Makefile @@ -5,6 +5,7 @@ # This file only gets included with CONFIG_EFI_LOADER set, so all # object inclusion implicitly depends on it +obj-y += efi_dm_integration.o obj-y += efi_uclass.o ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy) obj-y += efi_block_device.o diff --git a/lib/efi_driver/efi_dm_integration.c b/lib/efi_driver/efi_dm_integration.c new file mode 100644 index 0000000..9c6c339 --- /dev/null +++ b/lib/efi_driver/efi_dm_integration.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021, Heinrich Schuchardt <xypron.glpk@gmx.de> + */ + +#define LOG_CATEGORY LOGC_EFI + +#include <common.h> +#include <dm.h> +#include <efi_loader.h> +#include <log.h> + +/** + * efi_post_probe_device() - set up handle for probed device + * + * This function is called by device_probe(). After the UEFI sub-system is + * initialized this function adds handles for new devices. + * + * @dev: probed device + * Return: 0 on success + */ +int efi_post_probe_device(struct udevice *dev) +{ + if (!dev || !dev->uclass) + return -EINVAL; + + switch (dev->uclass->uc_drv->id) { + case UCLASS_BLK: + if (efi_block_device_register(dev) != EFI_SUCCESS) + log_err("Failed to register %s\n", dev->name); + default: + break; + } + + return 0; +} diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 4777b35..f6d5ba0 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -264,7 +264,6 @@ efi_status_t is_valid_tpl(efi_uintn_t tpl) case TPL_APPLICATION: case TPL_CALLBACK: case TPL_NOTIFY: - case TPL_HIGH_LEVEL: return EFI_SUCCESS; default: return EFI_INVALID_PARAMETER; diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 988907e..b798cab 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -10,6 +10,7 @@ #include <common.h> #include <blk.h> #include <dm.h> +#include <dm/device-internal.h> #include <efi_loader.h> #include <fs.h> #include <log.h> @@ -536,6 +537,41 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, } /** + * efi_block_device_register() - register a block device in the UEFI sub-system + * + * @dev: block device + * Return: status code + */ +efi_status_t efi_block_device_register(struct udevice *dev) +{ + struct blk_desc *desc = dev_get_uclass_plat(dev); + const char *if_typename = blk_get_if_type_name(desc->if_type); + struct efi_disk_obj *disk; + efi_status_t ret; + + /* Add block device for the full device */ + ret = device_probe(dev); + if (ret) + return EFI_NOT_FOUND; + log_info("Scanning disk %s...\n", dev->name); + ret = efi_disk_add_dev(NULL, NULL, if_typename, + desc, desc->devnum, NULL, 0, &disk); + if (ret == EFI_NOT_READY) { + log_notice("Disk %s not ready\n", dev->name); + return ret; + } else if (ret != EFI_SUCCESS) { + log_err("ERROR: failure to add disk device %s, r = %lu\n", + dev->name, ret & ~EFI_ERROR_MASK); + return ret; + } + + /* Partitions show up as block devices in EFI */ + efi_disk_create_partitions(&disk->header, desc, if_typename, + desc->devnum, dev->name); + return ret; +} + +/** * efi_disk_register() - register block devices * * U-Boot doesn't have a list of all online disk devices. So when running our @@ -552,38 +588,16 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, */ efi_status_t efi_disk_register(void) { - struct efi_disk_obj *disk; - int disks = 0; - efi_status_t ret; #ifdef CONFIG_BLK struct udevice *dev; - + /* Probe all block devices */ for (uclass_first_device_check(UCLASS_BLK, &dev); dev; - uclass_next_device_check(&dev)) { - struct blk_desc *desc = dev_get_uclass_plat(dev); - const char *if_typename = blk_get_if_type_name(desc->if_type); - - /* Add block device for the full device */ - log_info("Scanning disk %s...\n", dev->name); - ret = efi_disk_add_dev(NULL, NULL, if_typename, - desc, desc->devnum, NULL, 0, &disk); - if (ret == EFI_NOT_READY) { - log_notice("Disk %s not ready\n", dev->name); - continue; - } - if (ret) { - log_err("ERROR: failure to add disk device %s, r = %lu\n", - dev->name, ret & ~EFI_ERROR_MASK); - return ret; - } - disks++; - - /* Partitions show up as block devices in EFI */ - disks += efi_disk_create_partitions( - &disk->header, desc, if_typename, - desc->devnum, dev->name); - } + uclass_next_device_check(&dev)) + ; #else + struct efi_disk_obj *disk; + int disks = 0; + efi_status_t ret; int i, if_type; /* Search for all available disk devices */ @@ -630,8 +644,8 @@ efi_status_t efi_disk_register(void) if_typename, i, devname); } } -#endif log_info("Found %d disks\n", disks); +#endif return EFI_SUCCESS; } diff --git a/lib/efi_selftest/efi_selftest_tpl.c b/lib/efi_selftest/efi_selftest_tpl.c index 70a355e..0c0e412 100644 --- a/lib/efi_selftest/efi_selftest_tpl.c +++ b/lib/efi_selftest/efi_selftest_tpl.c @@ -55,7 +55,7 @@ static int setup(const efi_handle_t handle, return EFI_ST_FAILURE; } ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT, - TPL_HIGH_LEVEL, notify, NULL, &event_wait); + TPL_NOTIFY, notify, NULL, &event_wait); if (ret != EFI_SUCCESS) { efi_st_error("could not create event\n"); return EFI_ST_FAILURE; diff --git a/lib/smbios.c b/lib/smbios.c index 9eb226e..b52e125 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -47,7 +47,7 @@ struct smbios_ctx { * @addr: start address to write the structure * @handle: the structure's handle, a unique 16-bit number * @ctx: context for writing the tables - * @return: size of the structure + * Return: size of the structure */ typedef int (*smbios_write_type)(ulong *addr, int handle, struct smbios_ctx *ctx); @@ -72,7 +72,7 @@ struct smbios_write_method { * * @ctx: SMBIOS context * @str: string to add - * @return: string number in the string area (1 or more) + * Return: string number in the string area (1 or more) */ static int smbios_add_string(struct smbios_ctx *ctx, const char *str) { @@ -111,7 +111,7 @@ static int smbios_add_string(struct smbios_ctx *ctx, const char *str) * * @ctx: context for writing the tables * @prop: property to write - * @return 0 if not found, else SMBIOS string number (1 or more) + * Return: 0 if not found, else SMBIOS string number (1 or more) */ static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop, int sysinfo_id) @@ -139,7 +139,7 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop, * smbios_add_prop() - Add a property from the devicetree * * @prop: property to write - * @return 0 if not found, else SMBIOS string number (1 or more) + * Return: 0 if not found, else SMBIOS string number (1 or more) */ static int smbios_add_prop(struct smbios_ctx *ctx, const char *prop) { @@ -187,7 +187,7 @@ int smbios_update_version(const char *version) * This computes the size of the string area including the string terminator. * * @ctx: SMBIOS context - * @return: string area size + * Return: string area size */ static int smbios_string_table_len(const struct smbios_ctx *ctx) { @@ -229,9 +229,9 @@ static int smbios_write_type0(ulong *current, int handle, t->bios_characteristics_ext1 = BIOS_CHARACTERISTICS_EXT1_ACPI; #endif #ifdef CONFIG_EFI_LOADER - t->bios_characteristics_ext1 |= BIOS_CHARACTERISTICS_EXT1_UEFI; + t->bios_characteristics_ext2 |= BIOS_CHARACTERISTICS_EXT2_UEFI; #endif - t->bios_characteristics_ext2 = BIOS_CHARACTERISTICS_EXT2_TARGET; + t->bios_characteristics_ext2 |= BIOS_CHARACTERISTICS_EXT2_TARGET; /* bios_major_release has only one byte, so drop century */ t->bios_major_release = U_BOOT_VERSION_NUM % 100; @@ -258,7 +258,11 @@ static int smbios_write_type1(ulong *current, int handle, fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); t->manufacturer = smbios_add_prop(ctx, "manufacturer"); + if (!t->manufacturer) + t->manufacturer = smbios_add_string(ctx, "Unknown"); t->product_name = smbios_add_prop(ctx, "product"); + if (!t->product_name) + t->product_name = smbios_add_string(ctx, "Unknown Product"); t->version = smbios_add_prop_si(ctx, "version", SYSINFO_ID_SMBIOS_SYSTEM_VERSION); if (serial_str) { @@ -288,7 +292,11 @@ static int smbios_write_type2(ulong *current, int handle, fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); t->manufacturer = smbios_add_prop(ctx, "manufacturer"); + if (!t->manufacturer) + t->manufacturer = smbios_add_string(ctx, "Unknown"); t->product_name = smbios_add_prop(ctx, "product"); + if (!t->product_name) + t->product_name = smbios_add_string(ctx, "Unknown Product"); t->version = smbios_add_prop_si(ctx, "version", SYSINFO_ID_SMBIOS_BASEBOARD_VERSION); t->asset_tag_number = smbios_add_prop(ctx, "asset-tag"); @@ -313,6 +321,8 @@ static int smbios_write_type3(ulong *current, int handle, fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle); smbios_set_eos(ctx, t->eos); t->manufacturer = smbios_add_prop(ctx, "manufacturer"); + if (!t->manufacturer) + t->manufacturer = smbios_add_string(ctx, "Unknown"); t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP; t->bootup_state = SMBIOS_STATE_SAFE; t->power_supply_state = SMBIOS_STATE_SAFE; |