diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/acpi/acpi_table.c | 1 | ||||
-rw-r--r-- | lib/asm-offsets.c | 1 | ||||
-rw-r--r-- | lib/efi/efi_app.c | 1 | ||||
-rw-r--r-- | lib/efi/efi_info.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_capsule.c | 22 | ||||
-rw-r--r-- | lib/efi_loader/efi_device_path_to_text.c | 32 | ||||
-rw-r--r-- | lib/efi_loader/efi_disk.c | 19 | ||||
-rw-r--r-- | lib/efi_loader/efi_dt_fixup.c | 26 | ||||
-rw-r--r-- | lib/efi_loader/efi_gop.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_image_loader.c | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_memory.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_rng.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_runtime.c | 1 | ||||
-rw-r--r-- | lib/efi_selftest/Makefile | 2 | ||||
-rw-r--r-- | lib/efi_selftest/dtbdump.c | 86 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_devicepath.c | 65 | ||||
-rw-r--r-- | lib/fdtdec.c | 5 | ||||
-rw-r--r-- | lib/optee/optee.c | 1 | ||||
-rw-r--r-- | lib/smbios.c | 248 | ||||
-rw-r--r-- | lib/time.c | 1 | ||||
-rw-r--r-- | lib/trace.c | 1 | ||||
-rw-r--r-- | lib/zlib/zlib.c | 2 |
23 files changed, 385 insertions, 136 deletions
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index a0f0961be5b..2f077417841 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -13,6 +13,7 @@ #include <tables_csum.h> #include <version.h> #include <acpi/acpi_table.h> +#include <asm/global_data.h> #include <dm/acpi.h> int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags) diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c index b17651ed63d..ee592cfda1c 100644 --- a/lib/asm-offsets.c +++ b/lib/asm-offsets.c @@ -13,6 +13,7 @@ #include <common.h> #include <asm-offsets.h> +#include <asm/global_data.h> #include <linux/kbuild.h> diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index b7e19c34750..907bacd716a 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -15,6 +15,7 @@ #include <errno.h> #include <init.h> #include <malloc.h> +#include <asm/global_data.h> #include <linux/err.h> #include <linux/types.h> #include <efi.h> diff --git a/lib/efi/efi_info.c b/lib/efi/efi_info.c index 35a8a9325f8..4d78923c4d4 100644 --- a/lib/efi/efi_info.c +++ b/lib/efi/efi_info.c @@ -9,6 +9,7 @@ #include <efi.h> #include <errno.h> #include <mapmem.h> +#include <asm/global_data.h> int efi_info_get(enum efi_entry_t type, void **datap, int *sizep) { diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index ce658a8e733..41b8949b042 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -19,6 +19,7 @@ #include <u-boot/crc.h> #include <usb.h> #include <watchdog.h> +#include <asm/global_data.h> #include <linux/libfdt_env.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 0d5a7b63ec8..b57f0302c59 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -42,20 +42,28 @@ static struct efi_file_handle *bootdev_root; static __maybe_unused unsigned int get_last_capsule(void) { u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */ - char value[11], *p; + char value[5]; efi_uintn_t size; unsigned long index = 0xffff; efi_status_t ret; + int i; size = sizeof(value16); ret = efi_get_variable_int(L"CapsuleLast", &efi_guid_capsule_report, NULL, &size, value16, NULL); - if (ret != EFI_SUCCESS || u16_strncmp(value16, L"Capsule", 7)) + if (ret != EFI_SUCCESS || size != 22 || + u16_strncmp(value16, L"Capsule", 7)) goto err; + for (i = 0; i < 4; ++i) { + u16 c = value16[i + 7]; - p = value; - utf16_utf8_strcpy(&p, value16); - strict_strtoul(&value[7], 16, &index); + if (!c || c > 0x7f) + goto err; + value[i] = c; + } + value[4] = 0; + if (strict_strtoul(value, 16, &index)) + index = 0xffff; err: return index; } @@ -753,9 +761,7 @@ static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num) if (!tmp_size) break; - if (!(dirent->attribute & EFI_FILE_DIRECTORY) && - u16_strcmp(dirent->file_name, L".") && - u16_strcmp(dirent->file_name, L"..")) + if (!(dirent->attribute & EFI_FILE_DIRECTORY)) count++; } diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 5ae4833fa78..81b8ac23ba5 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -244,6 +244,21 @@ static char *dp_media(char *s, struct efi_device_path *dp) cddp->partition_start, cddp->partition_size); break; } + case DEVICE_PATH_SUB_TYPE_VENDOR_PATH: { + int i, n; + struct efi_device_path_vendor *vdp = + (struct efi_device_path_vendor *)dp; + + s += sprintf(s, "VenMedia(%pUl", &vdp->guid); + n = (int)vdp->dp.length - sizeof(struct efi_device_path_vendor); + if (n > 0) { + s += sprintf(s, ","); + for (i = 0; i < n; ++i) + s += sprintf(s, "%02x", vdp->vendor_data[i]); + } + s += sprintf(s, ")"); + break; + } case DEVICE_PATH_SUB_TYPE_FILE_PATH: { struct efi_device_path_file_path *fp = (struct efi_device_path_file_path *)dp; @@ -354,11 +369,18 @@ static uint16_t EFIAPI *efi_convert_device_path_to_text( if (!device_path) goto out; - while (device_path && - str + MAX_NODE_LEN < buffer + MAX_PATH_LEN) { - *str++ = '/'; - str = efi_convert_single_device_node_to_text(str, device_path); - device_path = efi_dp_next(device_path); + while (device_path && str + MAX_NODE_LEN < buffer + MAX_PATH_LEN) { + if (device_path->type == DEVICE_PATH_TYPE_END) { + if (device_path->sub_type != + DEVICE_PATH_SUB_TYPE_INSTANCE_END) + break; + *str++ = ','; + } else { + *str++ = '/'; + str = efi_convert_single_device_node_to_text( + str, device_path); + } + *(u8 **)&device_path += device_path->length; } text = efi_str_to_u16(buffer); diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index d0aad0252a5..307d5d759b8 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -19,6 +19,7 @@ struct efi_system_partition efi_system_partition; const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID; +const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID; /** * struct efi_disk_obj - EFI disk object @@ -147,7 +148,7 @@ static efi_status_t EFIAPI efi_disk_read_blocks(struct efi_block_io *this, (uintptr_t)buffer & (this->media->io_align - 1)) return EFI_INVALID_PARAMETER; if (lba * this->media->block_size + buffer_size > - this->media->last_block * this->media->block_size) + (this->media->last_block + 1) * this->media->block_size) return EFI_INVALID_PARAMETER; #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER @@ -215,7 +216,7 @@ static efi_status_t EFIAPI efi_disk_write_blocks(struct efi_block_io *this, (uintptr_t)buffer & (this->media->io_align - 1)) return EFI_INVALID_PARAMETER; if (lba * this->media->block_size + buffer_size > - this->media->last_block * this->media->block_size) + (this->media->last_block + 1) * this->media->block_size) return EFI_INVALID_PARAMETER; #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER @@ -362,6 +363,7 @@ static efi_status_t efi_disk_add_dev( { struct efi_disk_obj *diskobj; struct efi_object *handle; + const efi_guid_t *guid = NULL; efi_status_t ret; /* Don't add empty devices */ @@ -400,6 +402,8 @@ static efi_status_t efi_disk_add_dev( efi_free_pool(node); diskobj->offset = part_info->start; diskobj->media.last_block = part_info->size - 1; + if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) + guid = &efi_system_partition_guid; } else { diskobj->dp = efi_dp_from_part(desc, part); diskobj->offset = 0; @@ -417,7 +421,8 @@ static efi_status_t efi_disk_add_dev( handle = &diskobj->header; ret = EFI_CALL(efi_install_multiple_protocol_interfaces( &handle, &efi_guid_device_path, diskobj->dp, - &efi_block_io_guid, &diskobj->ops, NULL)); + &efi_block_io_guid, &diskobj->ops, + guid, NULL, NULL)); if (ret != EFI_SUCCESS) return ret; @@ -467,13 +472,7 @@ static efi_status_t efi_disk_add_dev( /* Store first EFI system partition */ if (part && !efi_system_partition.if_type) { - int r; - struct disk_partition info; - - r = part_get_info(desc, part, &info); - if (r) - return EFI_DEVICE_ERROR; - if (info.bootable & PART_EFI_SYSTEM_PARTITION) { + if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) { efi_system_partition.if_type = desc->if_type; efi_system_partition.devnum = desc->devnum; efi_system_partition.part = part; diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index 3850ab3b0fe..a4529ee3ef2 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -8,6 +8,7 @@ #include <common.h> #include <efi_dt_fixup.h> #include <efi_loader.h> +#include <fdtdec.h> #include <mapmem.h> const efi_guid_t efi_guid_dt_fixup_protocol = EFI_DT_FIXUP_PROTOCOL_GUID; @@ -110,6 +111,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, { efi_status_t ret; size_t required_size; + size_t total_size; bootm_headers_t img = { 0 }; EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags); @@ -124,20 +126,20 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, goto out; } if (flags & EFI_DT_APPLY_FIXUPS) { + /* Check size */ required_size = fdt_off_dt_strings(dtb) + fdt_size_dt_strings(dtb) + 0x3000; - } else { - required_size = fdt_totalsize(dtb); - } - if (required_size > *buffer_size) { - *buffer_size = required_size; - ret = EFI_BUFFER_TOO_SMALL; - goto out; - } - fdt_set_totalsize(dtb, *buffer_size); + total_size = fdt_totalsize(dtb); + if (required_size < total_size) + required_size = total_size; + if (required_size > *buffer_size) { + *buffer_size = required_size; + ret = EFI_BUFFER_TOO_SMALL; + goto out; + } - if (flags & EFI_DT_APPLY_FIXUPS) { + fdt_set_totalsize(dtb, *buffer_size); if (image_setup_libfdt(&img, dtb, 0, NULL)) { log_err("failed to process device tree\n"); ret = EFI_INVALID_PARAMETER; @@ -147,10 +149,10 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, if (flags & EFI_DT_RESERVE_MEMORY) efi_carve_out_dt_rsv(dtb); - if (EFI_DT_INSTALL_TABLE) { + if (flags & EFI_DT_INSTALL_TABLE) { ret = efi_install_configuration_table(&efi_guid_fdt, dtb); if (ret != EFI_SUCCESS) { - log_err("ERROR: failed to install device tree\n"); + log_err("failed to install device tree\n"); goto out; } } diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c index 53f6d970f73..1206b2d7a2c 100644 --- a/lib/efi_loader/efi_gop.c +++ b/lib/efi_loader/efi_gop.c @@ -12,6 +12,7 @@ #include <log.h> #include <malloc.h> #include <video.h> +#include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index d4dd9e94339..f53ef367ec1 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -843,7 +843,7 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, sec->Misc.VirtualSize); memcpy(efi_reloc + sec->VirtualAddress, efi + sec->PointerToRawData, - sec->SizeOfRawData); + min(sec->Misc.VirtualSize, sec->SizeOfRawData)); } /* Run through relocations */ diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index a3106aba7f2..be2f655dffd 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -12,6 +12,7 @@ #include <mapmem.h> #include <watchdog.h> #include <asm/cache.h> +#include <asm/global_data.h> #include <linux/list_sort.h> #include <linux/sizes.h> diff --git a/lib/efi_loader/efi_rng.c b/lib/efi_loader/efi_rng.c index 8bdadad0a95..0e065468562 100644 --- a/lib/efi_loader/efi_rng.c +++ b/lib/efi_loader/efi_rng.c @@ -11,6 +11,7 @@ #include <efi_rng.h> #include <log.h> #include <rng.h> +#include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 93c9478b225..93a695fc27e 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -14,6 +14,7 @@ #include <log.h> #include <malloc.h> #include <rtc.h> +#include <asm/global_data.h> #include <u-boot/crc.h> /* For manual relocation support */ diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 7d6ea30102e..b02fd56e0a7 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -8,7 +8,7 @@ asflags-y += -DHOST_ARCH="$(HOST_ARCH)" ccflags-y += -DHOST_ARCH="$(HOST_ARCH)" -CFLAGS_dtbdump_exit.o := $(CFLAGS_EFI) -Os -ffreestanding +CFLAGS_dtbdump.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_REMOVE_dtbdump.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI) diff --git a/lib/efi_selftest/dtbdump.c b/lib/efi_selftest/dtbdump.c index 953b264d9d4..f6ddaa30726 100644 --- a/lib/efi_selftest/dtbdump.c +++ b/lib/efi_selftest/dtbdump.c @@ -9,6 +9,8 @@ #include <common.h> #include <efi_api.h> #include <efi_dt_fixup.h> +#include <part.h> +#include <linux/libfdt.h> #define BUFFER_SIZE 64 #define ESC 0x17 @@ -27,6 +29,7 @@ static efi_handle_t handle; static struct efi_system_table *systable; static const efi_guid_t efi_dt_fixup_protocol_guid = EFI_DT_FIXUP_PROTOCOL_GUID; static const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID; +static const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID; /** * print() - print string @@ -231,6 +234,52 @@ void do_help(void) } /** + * open_file_system() - open simple file system protocol + * + * file_system: interface of the simple file system protocol + * Return: status code + */ +static efi_status_t +open_file_system(struct efi_simple_file_system_protocol **file_system) +{ + struct efi_loaded_image *loaded_image; + efi_status_t ret; + efi_handle_t *handle_buffer = NULL; + efi_uintn_t count; + + ret = bs->open_protocol(handle, &loaded_image_guid, + (void **)&loaded_image, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + error(L"Loaded image protocol not found\r\n"); + return ret; + } + + /* Open the simple file system protocol on the same partition */ + ret = bs->open_protocol(loaded_image->device_handle, + &guid_simple_file_system_protocol, + (void **)file_system, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret == EFI_SUCCESS) + return ret; + + /* Open the simple file system protocol on the UEFI system partition */ + ret = bs->locate_handle_buffer(BY_PROTOCOL, &efi_system_partition_guid, + NULL, &count, &handle_buffer); + if (ret == EFI_SUCCESS && handle_buffer) + ret = bs->open_protocol(handle_buffer[0], + &guid_simple_file_system_protocol, + (void **)file_system, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + error(L"Failed to open simple file system protocol\r\n"); + if (handle) + bs->free_pool(handle_buffer); + + return ret; +} + +/** * do_load() - load and install device-tree * * @filename: file name @@ -239,7 +288,6 @@ void do_help(void) efi_status_t do_load(u16 *filename) { struct efi_dt_fixup_protocol *dt_fixup_prot; - struct efi_loaded_image *loaded_image; struct efi_simple_file_system_protocol *file_system; struct efi_file_handle *root = NULL, *file = NULL; u64 addr = 0; @@ -258,22 +306,9 @@ efi_status_t do_load(u16 *filename) filename = skip_whitespace(filename); - ret = bs->open_protocol(handle, &loaded_image_guid, - (void **)&loaded_image, NULL, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (ret != EFI_SUCCESS) { - error(L"Loaded image protocol not found\r\n"); - return ret; - } - /* Open the simple file system protocol */ - ret = bs->open_protocol(loaded_image->device_handle, - &guid_simple_file_system_protocol, - (void **)&file_system, NULL, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (ret != EFI_SUCCESS) { - error(L"Failed to open simple file system protocol\r\n"); + ret = open_file_system(&file_system); + if (ret != EFI_SUCCESS) goto out; - } /* Open volume */ ret = file_system->open_volume(file_system, &root); @@ -389,7 +424,6 @@ out: */ efi_status_t do_save(u16 *filename) { - struct efi_loaded_image *loaded_image; struct efi_simple_file_system_protocol *file_system; efi_uintn_t dtb_size; struct efi_file_handle *root, *file; @@ -409,23 +443,9 @@ efi_status_t do_save(u16 *filename) filename = skip_whitespace(filename); - ret = bs->open_protocol(handle, &loaded_image_guid, - (void **)&loaded_image, NULL, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (ret != EFI_SUCCESS) { - error(L"Loaded image protocol not found\r\n"); - return ret; - } - - /* Open the simple file system protocol */ - ret = bs->open_protocol(loaded_image->device_handle, - &guid_simple_file_system_protocol, - (void **)&file_system, NULL, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (ret != EFI_SUCCESS) { - error(L"Failed to open simple file system protocol\r\n"); + ret = open_file_system(&file_system); + if (ret != EFI_SUCCESS) return ret; - } /* Open volume */ ret = file_system->open_volume(file_system, &root); diff --git a/lib/efi_selftest/efi_selftest_devicepath.c b/lib/efi_selftest/efi_selftest_devicepath.c index 4ce3fad8959..d87b9f7dcd0 100644 --- a/lib/efi_selftest/efi_selftest_devicepath.c +++ b/lib/efi_selftest/efi_selftest_devicepath.c @@ -45,6 +45,55 @@ static u8 *dp1; static u8 *dp2; static u8 *dp3; +static struct { + struct efi_device_path_sd_mmc_path sd1; + struct efi_device_path sep1; + struct efi_device_path_sd_mmc_path sd2; + struct efi_device_path sep2; + struct efi_device_path_sd_mmc_path sd3; + struct efi_device_path end; +} multi_part_dp = { + { + { + DEVICE_PATH_TYPE_MESSAGING_DEVICE, + DEVICE_PATH_SUB_TYPE_MSG_SD, + sizeof(struct efi_device_path_sd_mmc_path), + }, + 0, + }, + { + DEVICE_PATH_TYPE_END, + DEVICE_PATH_SUB_TYPE_INSTANCE_END, + sizeof(struct efi_device_path), + }, + { + { + DEVICE_PATH_TYPE_MESSAGING_DEVICE, + DEVICE_PATH_SUB_TYPE_MSG_SD, + sizeof(struct efi_device_path_sd_mmc_path), + }, + 1, + }, + { + DEVICE_PATH_TYPE_END, + DEVICE_PATH_SUB_TYPE_INSTANCE_END, + sizeof(struct efi_device_path), + }, + { + { + DEVICE_PATH_TYPE_MESSAGING_DEVICE, + DEVICE_PATH_SUB_TYPE_MSG_SD, + sizeof(struct efi_device_path_sd_mmc_path), + }, + 2, + }, + { + DEVICE_PATH_TYPE_END, + DEVICE_PATH_SUB_TYPE_END, + sizeof(struct efi_device_path), + }, +}; + struct efi_device_path_to_text_protocol *device_path_to_text; /* @@ -340,6 +389,22 @@ static int execute(void) return EFI_ST_FAILURE; } + string = device_path_to_text->convert_device_path_to_text( + (struct efi_device_path *)&multi_part_dp, true, false); + if (efi_st_strcmp_16_8( + string, + "/SD(0),/SD(1),/SD(2)") + ) { + efi_st_printf("multi_part_dp: %ps\n", string); + efi_st_error("Incorrect text from ConvertDevicePathToText\n"); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(string); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + return EFI_ST_FAILURE; + } + /* Test ConvertDeviceNodeToText */ string = device_path_to_text->convert_device_node_to_text( (struct efi_device_path *)&dp_node, true, false); diff --git a/lib/fdtdec.c b/lib/fdtdec.c index a2d2fb4e1fe..864589193b4 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -21,6 +21,7 @@ #include <mapmem.h> #include <linux/libfdt.h> #include <serial.h> +#include <asm/global_data.h> #include <asm/sections.h> #include <linux/ctype.h> #include <linux/lzo.h> @@ -1253,7 +1254,7 @@ __weak void *board_fdt_blob_setup(void) void *fdt_blob = NULL; #ifdef CONFIG_SPL_BUILD /* FDT is at end of BSS unless it is in a different memory region */ - if (CONFIG_IS_ENABLED(SEPARATE_BSS)) + if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) fdt_blob = (ulong *)&_image_binary_end; else fdt_blob = (ulong *)&__bss_end; @@ -1572,7 +1573,7 @@ int fdtdec_setup(void) return -1; } # elif defined(CONFIG_OF_PRIOR_STAGE) - gd->fdt_blob = (void *)prior_stage_fdt_address; + gd->fdt_blob = (void *)(uintptr_t)prior_stage_fdt_address; # endif # ifndef CONFIG_SPL_BUILD /* Allow the early environment to override the fdt address */ diff --git a/lib/optee/optee.c b/lib/optee/optee.c index 9e6606568f3..4dcf6f93099 100644 --- a/lib/optee/optee.c +++ b/lib/optee/optee.c @@ -5,6 +5,7 @@ */ #include <common.h> +#include <fdtdec.h> #include <image.h> #include <log.h> #include <malloc.h> diff --git a/lib/smbios.c b/lib/smbios.c index 1e10fa84207..7d463c84a93 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -10,6 +10,7 @@ #include <env.h> #include <mapmem.h> #include <smbios.h> +#include <sysinfo.h> #include <tables_csum.h> #include <version.h> #ifdef CONFIG_CPU @@ -17,6 +18,44 @@ #include <dm/uclass-internal.h> #endif +DECLARE_GLOBAL_DATA_PTR; + +enum { + SMBIOS_STR_MAX = 64, /* Maximum length allowed for a string */ +}; + +/** + * struct smbios_ctx - context for writing SMBIOS tables + * + * @node: node containing the information to write (ofnode_null() if none) + * @dev: sysinfo device to use (NULL if none) + * @eos: end-of-string pointer for the table being processed. This is set + * up when we start processing a table + * @next_ptr: pointer to the start of the next string to be added. When the + * table is nopt empty, this points to the byte after the \0 of the + * previous string. + * @last_str: points to the last string that was written to the table, or NULL + * if none + */ +struct smbios_ctx { + ofnode node; + struct udevice *dev; + char *eos; + char *next_ptr; + char *last_str; +}; + +/** + * Function prototype to write a specific type of SMBIOS structure + * + * @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 + */ +typedef int (*smbios_write_type)(ulong *addr, int handle, + struct smbios_ctx *ctx); + /** * struct smbios_write_method - Information about a table-writing function * @@ -35,29 +74,34 @@ struct smbios_write_method { * This adds a string to the string area which is appended directly after * the formatted portion of an SMBIOS structure. * - * @start: string area start address + * @ctx: SMBIOS context * @str: string to add * @return: string number in the string area (1 or more) */ -static int smbios_add_string(char *start, const char *str) +static int smbios_add_string(struct smbios_ctx *ctx, const char *str) { int i = 1; - char *p = start; + char *p = ctx->eos; + if (!*str) str = "Unknown"; for (;;) { if (!*p) { + ctx->last_str = p; strcpy(p, str); p += strlen(str); *p++ = '\0'; + ctx->next_ptr = p; *p++ = '\0'; return i; } - if (!strcmp(p, str)) + if (!strcmp(p, str)) { + ctx->last_str = p; return i; + } p += strlen(p) + 1; i++; @@ -65,50 +109,98 @@ static int smbios_add_string(char *start, const char *str) } /** - * smbios_add_prop() - Add a property from the device tree + * smbios_add_prop_si() - Add a property from the devicetree or sysinfo * - * @start: string area start address - * @node: node containing the information to write (ofnode_null() if none) + * Sysinfo is used if available, with a fallback to devicetree + * + * @ctx: context for writing the tables * @prop: property to write * @return 0 if not found, else SMBIOS string number (1 or more) */ -static int smbios_add_prop(char *start, ofnode node, const char *prop) +static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop, + int sysinfo_id) { + if (sysinfo_id && ctx->dev) { + char val[SMBIOS_STR_MAX]; + int ret; + ret = sysinfo_get_str(ctx->dev, sysinfo_id, sizeof(val), val); + if (!ret) + return smbios_add_string(ctx, val); + } if (IS_ENABLED(CONFIG_OF_CONTROL)) { const char *str; - str = ofnode_read_string(node, prop); + str = ofnode_read_string(ctx->node, prop); if (str) - return smbios_add_string(start, str); + return smbios_add_string(ctx, str); } return 0; } /** + * 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) + */ +static int smbios_add_prop(struct smbios_ctx *ctx, const char *prop) +{ + return smbios_add_prop_si(ctx, prop, SYSINFO_ID_NONE); +} + +static void smbios_set_eos(struct smbios_ctx *ctx, char *eos) +{ + ctx->eos = eos; + ctx->next_ptr = eos; + ctx->last_str = NULL; +} + +int smbios_update_version(const char *version) +{ + char *ptr = gd->smbios_version; + uint old_len, len; + + if (!ptr) + return log_ret(-ENOENT); + + /* + * This string is supposed to have at least enough bytes and is + * padded with spaces. Update it, taking care not to move the + * \0 terminator, so that other strings in the string table + * are not disturbed. See smbios_add_string() + */ + old_len = strnlen(ptr, SMBIOS_STR_MAX); + len = strnlen(version, SMBIOS_STR_MAX); + if (len > old_len) + return log_ret(-ENOSPC); + + log_debug("Replacing SMBIOS type 0 version string '%s'\n", ptr); + memcpy(ptr, version, len); +#ifdef LOG_DEBUG + print_buffer((ulong)ptr, ptr, 1, old_len + 1, 0); +#endif + + return 0; +} + +/** * smbios_string_table_len() - compute the string area size * * This computes the size of the string area including the string terminator. * - * @start: string area start address + * @ctx: SMBIOS context * @return: string area size */ -static int smbios_string_table_len(char *start) +static int smbios_string_table_len(const struct smbios_ctx *ctx) { - char *p = start; - int i, len = 0; - - while (*p) { - i = strlen(p) + 1; - p += i; - len += i; - } - - return len + 1; + /* Allow for the final \0 after all strings */ + return (ctx->next_ptr + 1) - ctx->eos; } -static int smbios_write_type0(ulong *current, int handle, ofnode node) +static int smbios_write_type0(ulong *current, int handle, + struct smbios_ctx *ctx) { struct smbios_type0 *t; int len = sizeof(struct smbios_type0); @@ -116,9 +208,21 @@ static int smbios_write_type0(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type0)); fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle); - t->vendor = smbios_add_string(t->eos, "U-Boot"); - t->bios_ver = smbios_add_string(t->eos, PLAIN_VERSION); - t->bios_release_date = smbios_add_string(t->eos, U_BOOT_DMI_DATE); + smbios_set_eos(ctx, t->eos); + t->vendor = smbios_add_string(ctx, "U-Boot"); + + t->bios_ver = smbios_add_prop(ctx, "version"); + if (!t->bios_ver) + t->bios_ver = smbios_add_string(ctx, PLAIN_VERSION); + if (t->bios_ver) + gd->smbios_version = ctx->last_str; + log_debug("smbios_version = %p: '%s'\n", gd->smbios_version, + gd->smbios_version); +#ifdef LOG_DEBUG + print_buffer((ulong)gd->smbios_version, gd->smbios_version, + 1, strlen(gd->smbios_version) + 1, 0); +#endif + t->bios_release_date = smbios_add_string(ctx, U_BOOT_DMI_DATE); #ifdef CONFIG_ROM_SIZE t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1; #endif @@ -133,19 +237,21 @@ static int smbios_write_type0(ulong *current, int handle, ofnode node) #endif t->bios_characteristics_ext2 = BIOS_CHARACTERISTICS_EXT2_TARGET; - t->bios_major_release = 0xff; - t->bios_minor_release = 0xff; + /* bios_major_release has only one byte, so drop century */ + t->bios_major_release = U_BOOT_VERSION_NUM % 100; + t->bios_minor_release = U_BOOT_VERSION_NUM_PATCH; t->ec_major_release = 0xff; t->ec_minor_release = 0xff; - len = t->length + smbios_string_table_len(t->eos); + len = t->length + smbios_string_table_len(ctx); *current += len; unmap_sysmem(t); return len; } -static int smbios_write_type1(ulong *current, int handle, ofnode node) +static int smbios_write_type1(ulong *current, int handle, + struct smbios_ctx *ctx) { struct smbios_type1 *t; int len = sizeof(struct smbios_type1); @@ -154,26 +260,29 @@ static int smbios_write_type1(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type1)); fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); - t->manufacturer = smbios_add_prop(t->eos, node, "manufacturer"); - t->product_name = smbios_add_prop(t->eos, node, "product"); - t->version = smbios_add_prop(t->eos, node, "version"); + smbios_set_eos(ctx, t->eos); + t->manufacturer = smbios_add_prop(ctx, "manufacturer"); + t->product_name = smbios_add_prop(ctx, "product"); + t->version = smbios_add_prop_si(ctx, "version", + SYSINFO_ID_SMBIOS_SYSTEM_VERSION); if (serial_str) { - t->serial_number = smbios_add_string(t->eos, serial_str); + t->serial_number = smbios_add_string(ctx, serial_str); strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); } else { - t->serial_number = smbios_add_prop(t->eos, node, "serial"); + t->serial_number = smbios_add_prop(ctx, "serial"); } - t->sku_number = smbios_add_prop(t->eos, node, "sku"); - t->family = smbios_add_prop(t->eos, node, "family"); + t->sku_number = smbios_add_prop(ctx, "sku"); + t->family = smbios_add_prop(ctx, "family"); - len = t->length + smbios_string_table_len(t->eos); + len = t->length + smbios_string_table_len(ctx); *current += len; unmap_sysmem(t); return len; } -static int smbios_write_type2(ulong *current, int handle, ofnode node) +static int smbios_write_type2(ulong *current, int handle, + struct smbios_ctx *ctx) { struct smbios_type2 *t; int len = sizeof(struct smbios_type2); @@ -181,20 +290,24 @@ static int smbios_write_type2(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type2)); fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); - t->manufacturer = smbios_add_prop(t->eos, node, "manufacturer"); - t->product_name = smbios_add_prop(t->eos, node, "product"); - t->asset_tag_number = smbios_add_prop(t->eos, node, "asset-tag"); + smbios_set_eos(ctx, t->eos); + t->manufacturer = smbios_add_prop(ctx, "manufacturer"); + t->product_name = smbios_add_prop(ctx, "product"); + t->version = smbios_add_prop_si(ctx, "version", + SYSINFO_ID_SMBIOS_BASEBOARD_VERSION); + t->asset_tag_number = smbios_add_prop(ctx, "asset-tag"); t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING; t->board_type = SMBIOS_BOARD_MOTHERBOARD; - len = t->length + smbios_string_table_len(t->eos); + len = t->length + smbios_string_table_len(ctx); *current += len; unmap_sysmem(t); return len; } -static int smbios_write_type3(ulong *current, int handle, ofnode node) +static int smbios_write_type3(ulong *current, int handle, + struct smbios_ctx *ctx) { struct smbios_type3 *t; int len = sizeof(struct smbios_type3); @@ -202,21 +315,23 @@ static int smbios_write_type3(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type3)); fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle); - t->manufacturer = smbios_add_prop(t->eos, node, "manufacturer"); + smbios_set_eos(ctx, t->eos); + t->manufacturer = smbios_add_prop(ctx, "manufacturer"); t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP; t->bootup_state = SMBIOS_STATE_SAFE; t->power_supply_state = SMBIOS_STATE_SAFE; t->thermal_state = SMBIOS_STATE_SAFE; t->security_status = SMBIOS_SECURITY_NONE; - len = t->length + smbios_string_table_len(t->eos); + len = t->length + smbios_string_table_len(ctx); *current += len; unmap_sysmem(t); return len; } -static void smbios_write_type4_dm(struct smbios_type4 *t, ofnode node) +static void smbios_write_type4_dm(struct smbios_type4 *t, + struct smbios_ctx *ctx) { u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN; const char *vendor = "Unknown"; @@ -244,11 +359,12 @@ static void smbios_write_type4_dm(struct smbios_type4 *t, ofnode node) #endif t->processor_family = processor_family; - t->processor_manufacturer = smbios_add_string(t->eos, vendor); - t->processor_version = smbios_add_string(t->eos, name); + t->processor_manufacturer = smbios_add_string(ctx, vendor); + t->processor_version = smbios_add_string(ctx, name); } -static int smbios_write_type4(ulong *current, int handle, ofnode node) +static int smbios_write_type4(ulong *current, int handle, + struct smbios_ctx *ctx) { struct smbios_type4 *t; int len = sizeof(struct smbios_type4); @@ -256,8 +372,9 @@ static int smbios_write_type4(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type4)); fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle); + smbios_set_eos(ctx, t->eos); t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL; - smbios_write_type4_dm(t, node); + smbios_write_type4_dm(t, ctx); t->status = SMBIOS_PROCESSOR_STATUS_ENABLED; t->processor_upgrade = SMBIOS_PROCESSOR_UPGRADE_NONE; t->l1_cache_handle = 0xffff; @@ -265,14 +382,15 @@ static int smbios_write_type4(ulong *current, int handle, ofnode node) t->l3_cache_handle = 0xffff; t->processor_family2 = t->processor_family; - len = t->length + smbios_string_table_len(t->eos); + len = t->length + smbios_string_table_len(ctx); *current += len; unmap_sysmem(t); return len; } -static int smbios_write_type32(ulong *current, int handle, ofnode node) +static int smbios_write_type32(ulong *current, int handle, + struct smbios_ctx *ctx) { struct smbios_type32 *t; int len = sizeof(struct smbios_type32); @@ -280,6 +398,7 @@ static int smbios_write_type32(ulong *current, int handle, ofnode node) t = map_sysmem(*current, len); memset(t, 0, sizeof(struct smbios_type32)); fill_smbios_header(t, SMBIOS_SYSTEM_BOOT_INFORMATION, len, handle); + smbios_set_eos(ctx, t->eos); *current += len; unmap_sysmem(t); @@ -287,7 +406,8 @@ static int smbios_write_type32(ulong *current, int handle, ofnode node) return len; } -static int smbios_write_type127(ulong *current, int handle, ofnode node) +static int smbios_write_type127(ulong *current, int handle, + struct smbios_ctx *ctx) { struct smbios_type127 *t; int len = sizeof(struct smbios_type127); @@ -303,7 +423,7 @@ static int smbios_write_type127(ulong *current, int handle, ofnode node) } static struct smbios_write_method smbios_write_funcs[] = { - { smbios_write_type0, }, + { smbios_write_type0, "bios", }, { smbios_write_type1, "system", }, { smbios_write_type2, "baseboard", }, { smbios_write_type3, "chassis", }, @@ -316,7 +436,7 @@ ulong write_smbios_table(ulong addr) { ofnode parent_node = ofnode_null(); struct smbios_entry *se; - struct udevice *dev; + struct smbios_ctx ctx; ulong table_addr; ulong tables; int len = 0; @@ -326,10 +446,13 @@ ulong write_smbios_table(ulong addr) int isize; int i; + ctx.node = ofnode_null(); if (IS_ENABLED(CONFIG_OF_CONTROL)) { - uclass_first_device(UCLASS_SYSINFO, &dev); - if (dev) - parent_node = dev_read_subnode(dev, "smbios"); + uclass_first_device(UCLASS_SYSINFO, &ctx.dev); + if (ctx.dev) + parent_node = dev_read_subnode(ctx.dev, "smbios"); + } else { + ctx.dev = NULL; } /* 16 byte align the table address */ @@ -345,14 +468,13 @@ ulong write_smbios_table(ulong addr) /* populate minimum required tables */ for (i = 0; i < ARRAY_SIZE(smbios_write_funcs); i++) { const struct smbios_write_method *method; - ofnode node = ofnode_null(); int tmp; method = &smbios_write_funcs[i]; if (IS_ENABLED(CONFIG_OF_CONTROL) && method->subnode_name) - node = ofnode_find_subnode(parent_node, - method->subnode_name); - tmp = method->write((ulong *)&addr, handle++, node); + ctx.node = ofnode_find_subnode(parent_node, + method->subnode_name); + tmp = method->write((ulong *)&addr, handle++, &ctx); max_struct_size = max(max_struct_size, tmp); len += tmp; diff --git a/lib/time.c b/lib/time.c index cc6944ec345..38a9758292a 100644 --- a/lib/time.c +++ b/lib/time.c @@ -14,6 +14,7 @@ #include <timer.h> #include <watchdog.h> #include <div64.h> +#include <asm/global_data.h> #include <asm/io.h> #include <linux/delay.h> diff --git a/lib/trace.c b/lib/trace.c index defc9716d80..9e34b195375 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -7,6 +7,7 @@ #include <mapmem.h> #include <time.h> #include <trace.h> +#include <asm/global_data.h> #include <asm/io.h> #include <asm/sections.h> diff --git a/lib/zlib/zlib.c b/lib/zlib/zlib.c index 90e05e7d4d9..493fe19eda6 100644 --- a/lib/zlib/zlib.c +++ b/lib/zlib/zlib.c @@ -12,7 +12,7 @@ * - added inflateIncomp */ -#include <common.h> +#include <compiler.h> #ifdef CONFIG_GZIP_COMPRESSED #define NO_DUMMY_DECL |