From 6c39d0ef1eece4d8aa966b77a1362a53abd254a8 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 8 Jan 2023 00:23:06 +0100 Subject: [PATCH 1/8] doc: fix description of u16_strcasecmp() Remove non-existent parameter 'n' from function description. Fixes: 7a9b366cd9b7 ("lib: add function u16_strcasecmp()") Signed-off-by: Heinrich Schuchardt --- include/charset.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/charset.h b/include/charset.h index 6e79d7152e..44034c71d3 100644 --- a/include/charset.h +++ b/include/charset.h @@ -178,7 +178,6 @@ s32 utf_to_upper(const s32 code); * * @s1: first string to compare * @s2: second string to compare - * @n: maximum number of u16 to compare * Return: 0 if the first n u16 are the same in s1 and s2 * < 0 if the first different u16 in s1 is less than the * corresponding u16 in s2 From e9cc7029e881f470369ae2fc2c80029ef9e03923 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 12 Jan 2023 20:30:58 +0100 Subject: [PATCH 2/8] doc: build infodocs target on Gitlab CI, Azure Add infodocs target to CI testing. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass Reviewed-by: Tom Rini --- .azure-pipelines.yml | 5 +++-- .gitlab-ci.yml | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 5fe3b8751d..49fc34fbf2 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -76,8 +76,8 @@ stages: steps: - script: cppcheck -j$(nproc) --force --quiet --inline-suppr . - - job: htmldocs - displayName: 'Build HTML documentation' + - job: docs + displayName: 'Build documentation' pool: vmImage: $(ubuntu_vm) container: @@ -89,6 +89,7 @@ stages: . /tmp/venvhtml/bin/activate pip install -r doc/sphinx/requirements.txt make htmldocs + make infodocs - job: todo displayName: 'Search for TODO within source tree' diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8d981a388a..398fa2b45e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -149,14 +149,15 @@ grep TODO/FIXME/HACK: # search for HACK within source tree and ignore HACKKIT board - grep -r HACK . | grep -v HACKKIT -# build HTML documentation -htmldocs: +# build documentation +docs: stage: testsuites script: - virtualenv -p /usr/bin/python3 /tmp/venvhtml - . /tmp/venvhtml/bin/activate - pip install -r doc/sphinx/requirements.txt - make htmldocs + - make infodocs # some statistics about the code base sloccount: From 0763c02eee5ee2be4d291719e7d72f7ce5ef33bd Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 8 Jan 2023 01:00:00 +0100 Subject: [PATCH 3/8] efi_loader: fix description of memory functions * Add missing function descriptions * Adjust to Sphinx style Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/efi_loader/efi_memory.c | 82 ++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 32254d2433..b7bee98f79 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -78,12 +78,19 @@ static u64 checksum(struct efi_pool_allocation *alloc) return ret; } -/* +/** + * efi_mem_cmp() - comparator function for sorting memory map + * * Sorts the memory list from highest address to lowest address * * When allocating memory we should always start from the highest * address chunk, so sort the memory list such that the first list * iterator gets the highest address and goes lower from there. + * + * @priv: unused + * @a: first memory area + * @b: second memory area + * Return: 1 if @a is before @b, -1 if @b is before @a, 0 if equal */ static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b) { @@ -98,11 +105,22 @@ static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b) return -1; } +/** + * desc_get_end() - get end address of memory area + * + * @desc: memory descriptor + * Return: end address + 1 + */ static uint64_t desc_get_end(struct efi_mem_desc *desc) { return desc->physical_start + (desc->num_pages << EFI_PAGE_SHIFT); } +/** + * efi_mem_sort() - sort memory map + * + * Sort the memory map and then try to merge adjacent memory areas. + */ static void efi_mem_sort(void) { struct list_head *lhandle; @@ -148,12 +166,13 @@ static void efi_mem_sort(void) } } -/** efi_mem_carve_out - unmap memory region +/** + * efi_mem_carve_out() - unmap memory region * * @map: memory map * @carve_desc: memory region to unmap * @overlap_only_ram: the carved out region may only overlap RAM - * Return Value: the number of overlapping pages which have been + * Return: the number of overlapping pages which have been * removed from the map, * EFI_CARVE_NO_OVERLAP, if the regions don't overlap, * EFI_CARVE_OVERLAPS_NONRAM, if the carve and map overlap, @@ -403,6 +422,13 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated) return EFI_NOT_FOUND; } +/** + * efi_find_free_memory() - find free memory pages + * + * @len: size of memory area needed + * @max_addr: highest address to allocate + * Return: pointer to free memory area or 0 + */ static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) { struct list_head *lhandle; @@ -445,13 +471,13 @@ static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) return 0; } -/* - * Allocate memory pages. +/** + * efi_allocate_pages - allocate memory pages * - * @type type of allocation to be performed - * @memory_type usage type of the allocated memory - * @pages number of pages to be allocated - * @memory allocated memory + * @type: type of allocation to be performed + * @memory_type: usage type of the allocated memory + * @pages: number of pages to be allocated + * @memory: allocated memory * Return: status code */ efi_status_t efi_allocate_pages(enum efi_allocate_type type, @@ -507,6 +533,13 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, return EFI_SUCCESS; } +/** + * efi_alloc() - allocate memory pages + * + * @len: size of the memory to be allocated + * @memory_type: usage type of the allocated memory + * Return: pointer to the allocated memory area or NULL + */ void *efi_alloc(uint64_t len, int memory_type) { uint64_t ret = 0; @@ -552,7 +585,7 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) } /** - * efi_alloc_aligned_pages - allocate + * efi_alloc_aligned_pages() - allocate aligned memory pages * * @len: len in bytes * @memory_type: usage type of the allocated memory @@ -673,15 +706,15 @@ efi_status_t efi_free_pool(void *buffer) return ret; } -/* - * Get map describing memory usage. +/** + * efi_get_memory_map() - get map describing memory usage. * - * @memory_map_size on entry the size, in bytes, of the memory map buffer, + * @memory_map_size: on entry the size, in bytes, of the memory map buffer, * on exit the size of the copied memory map - * @memory_map buffer to which the memory map is written - * @map_key key for the memory map - * @descriptor_size size of an individual memory descriptor - * @descriptor_version version number of the memory descriptor structure + * @memory_map: buffer to which the memory map is written + * @map_key: key for the memory map + * @descriptor_size: size of an individual memory descriptor + * @descriptor_version: version number of the memory descriptor structure * Return: status code */ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, @@ -741,8 +774,8 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, * * The caller is responsible for calling FreePool() if the call succeeds. * - * @memory_map buffer to which the memory map is written - * @map_size size of the memory map + * @map_size: size of the memory map + * @memory_map: buffer to which the memory map is written * Return: status code */ efi_status_t efi_get_memory_map_alloc(efi_uintn_t *map_size, @@ -818,6 +851,11 @@ efi_status_t efi_add_conventional_memory_map(u64 ram_start, u64 ram_end, return EFI_SUCCESS; } +/** + * efi_add_known_memory() - add memory banks to map + * + * This function may be overridden for specific architectures. + */ __weak void efi_add_known_memory(void) { u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK; @@ -844,7 +882,11 @@ __weak void efi_add_known_memory(void) } } -/* Add memory regions for U-Boot's memory and for the runtime services code */ +/** + * add_u_boot_and_runtime() - add U-Boot code to memory map + * + * Add memory regions for U-Boot's memory and for the runtime services code. + */ static void add_u_boot_and_runtime(void) { unsigned long runtime_start, runtime_end, runtime_pages; From 7e808fcc97ff3fe2f16d178e34f9811368696276 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 8 Jan 2023 19:00:47 +0100 Subject: [PATCH 4/8] efi_loader: add .rela sections to .text on arm64 _relocate() needs the information in .rela* for self relocation of the EFI binary. Fixes: d7ddeb66a6ce ("efi_loader: fix building aarch64 EFI binaries") Signed-off-by: Heinrich Schuchardt --- arch/arm/lib/elf_aarch64_efi.lds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds index 3e3da47d6a..5dd9809169 100644 --- a/arch/arm/lib/elf_aarch64_efi.lds +++ b/arch/arm/lib/elf_aarch64_efi.lds @@ -28,6 +28,10 @@ SECTIONS *(.dynamic); . = ALIGN(512); } + .rela.dyn : { *(.rela.dyn) } + .rela.plt : { *(.rela.plt) } + .rela.got : { *(.rela.got) } + .rela.data : { *(.rela.data) *(.rela.data*) } _etext = .; _text_size = . - _text; . = ALIGN(4096); @@ -57,10 +61,6 @@ SECTIONS _edata = .; } :data _data_size = _edata - _data; - .rela.dyn : { *(.rela.dyn) } - .rela.plt : { *(.rela.plt) } - .rela.got : { *(.rela.got) } - .rela.data : { *(.rela.data) *(.rela.data*) } . = ALIGN(4096); .dynsym : { *(.dynsym) } From 851456693a385be9dc462ba5eb9977ff62e8350c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 11 Jan 2023 19:08:01 +0100 Subject: [PATCH 5/8] efi_loader: use EFI_EXIT in efi_riscv_get_boot_hartid After calling EFI_ENTRY we have to call EFI_EXIT before returning. Add a missing EFI_EXIT(). Fixes: 1ccf87165e38 ("efi_loader: Enable RISCV_EFI_BOOT_PROTOCOL support") Reported-by: Dave Jones Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas Reviewed-by: Sunil V L --- lib/efi_loader/efi_riscv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_riscv.c b/lib/efi_loader/efi_riscv.c index bccfefd8fb..064172755b 100644 --- a/lib/efi_loader/efi_riscv.c +++ b/lib/efi_loader/efi_riscv.c @@ -31,7 +31,7 @@ efi_riscv_get_boot_hartid(struct riscv_efi_boot_protocol *this, EFI_ENTRY("%p, %p", this, boot_hartid); if (this != &riscv_efi_boot_prot || !boot_hartid) - return EFI_INVALID_PARAMETER; + return EFI_EXIT(EFI_INVALID_PARAMETER); *boot_hartid = gd->arch.boot_hart; From 65b91a346ebed631494b6ad405dbd91e07157ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Fri, 6 Jan 2023 10:46:40 +0100 Subject: [PATCH 6/8] efi_loader: refine set_keyboard_layout() status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per the EFI specification, the HII database protocol function set_keyboard_layout() must return EFI_INVALID_PARAMETER when it is called with a NULL key_guid argument. Modify the function accordingly to improve conformance. Signed-off-by: Vincent Stehlé Cc: Heinrich Schuchardt Cc: Ilias Apalodimas Reviewed-by: Ilias Apalodimas --- lib/efi_loader/efi_hii.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/efi_loader/efi_hii.c b/lib/efi_loader/efi_hii.c index 27db3be6a1..3b54ecb11a 100644 --- a/lib/efi_loader/efi_hii.c +++ b/lib/efi_loader/efi_hii.c @@ -758,6 +758,9 @@ set_keyboard_layout(const struct efi_hii_database_protocol *this, { EFI_ENTRY("%p, %pUs", this, key_guid); + if (!key_guid) + return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_EXIT(EFI_NOT_FOUND); } From 4d4ec2581065c2437f90661530e30f907bd6b62f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Fri, 6 Jan 2023 10:46:41 +0100 Subject: [PATCH 7/8] efi_selftest: add hii set keyboard layout test case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a test for the case when the HII database protocol set_keyboard_layout() function is called with a NULL key_guid argument. Signed-off-by: Vincent Stehlé Cc: Heinrich Schuchardt Cc: Ilias Apalodimas --- lib/efi_selftest/efi_selftest_hii.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/efi_selftest/efi_selftest_hii.c b/lib/efi_selftest/efi_selftest_hii.c index eaf3b0995d..f4b55889e2 100644 --- a/lib/efi_selftest/efi_selftest_hii.c +++ b/lib/efi_selftest/efi_selftest_hii.c @@ -564,7 +564,19 @@ out: */ static int test_hii_database_set_keyboard_layout(void) { + efi_status_t ret; + PRINT_TESTNAME; + + /* Invalid key guid. */ + ret = hii_database_protocol->set_keyboard_layout( + hii_database_protocol, NULL); + if (ret != EFI_INVALID_PARAMETER) { + efi_st_error("set_keyboard_layout returned %u not invalid\n", + (unsigned int)ret); + return EFI_ST_FAILURE; + } + /* set_keyboard_layout() not implemented yet */ return EFI_ST_SUCCESS; } From 8e4ec3e947d47b1af04b3b913cdf55882c0e728e Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 8 Oct 2022 09:11:54 +0200 Subject: [PATCH 8/8] efi_loader: provide agent_handle to efi_disk_add_dev() In efi_disk_add_dev() we have to open protocols with BY_DRIVER and BY_CHILD_CONTROLLER. Provide the handle of the EFI block driver. The actual usage of the value will follow in a later patch. Change function descriptions to Sphinx style. Remove a TODO: tag. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_disk.c | 50 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 7ea0334083..d170a86460 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -386,6 +387,7 @@ static int efi_fs_exists(struct blk_desc *desc, int part) * @part_info: partition info * @part: partition * @disk: pointer to receive the created handle + * @agent_handle: handle of the EFI block driver * Return: disk object */ static efi_status_t efi_disk_add_dev( @@ -395,7 +397,8 @@ static efi_status_t efi_disk_add_dev( int dev_index, struct disk_partition *part_info, unsigned int part, - struct efi_disk_obj **disk) + struct efi_disk_obj **disk, + efi_handle_t agent_handle) { struct efi_disk_obj *diskobj; struct efi_object *handle; @@ -529,17 +532,18 @@ error: return ret; } -/* - * Create a handle for a whole raw disk +/** + * efi_disk_create_raw() - create a handle for a whole raw disk * - * @dev uclass device (UCLASS_BLK) + * @dev: udevice (UCLASS_BLK) + * @agent_handle: handle of the EFI block driver * * Create an efi_disk object which is associated with @dev. * The type of @dev must be UCLASS_BLK. * - * @return 0 on success, -1 otherwise + * Return: 0 on success, -1 otherwise */ -static int efi_disk_create_raw(struct udevice *dev) +static int efi_disk_create_raw(struct udevice *dev, efi_handle_t agent_handle) { struct efi_disk_obj *disk; struct blk_desc *desc; @@ -550,7 +554,7 @@ static int efi_disk_create_raw(struct udevice *dev) diskid = desc->devnum; ret = efi_disk_add_dev(NULL, NULL, desc, - diskid, NULL, 0, &disk); + diskid, NULL, 0, &disk, agent_handle); if (ret != EFI_SUCCESS) { if (ret == EFI_NOT_READY) log_notice("Disk %s not ready\n", dev->name); @@ -569,17 +573,18 @@ static int efi_disk_create_raw(struct udevice *dev) return 0; } -/* - * Create a handle for a disk partition +/** + * efi_disk_create_part() - create a handle for a disk partition * - * @dev uclass device (UCLASS_PARTITION) + * @dev: udevice (UCLASS_PARTITION) + * @agent_handle: handle of the EFI block driver * * Create an efi_disk object which is associated with @dev. * The type of @dev must be UCLASS_PARTITION. * - * @return 0 on success, -1 otherwise + * Return: 0 on success, -1 otherwise */ -static int efi_disk_create_part(struct udevice *dev) +static int efi_disk_create_part(struct udevice *dev, efi_handle_t agent_handle) { efi_handle_t parent; struct blk_desc *desc; @@ -608,7 +613,7 @@ static int efi_disk_create_part(struct udevice *dev) dp_parent = (struct efi_device_path *)handler->protocol_interface; ret = efi_disk_add_dev(parent, dp_parent, desc, diskid, - info, part, &disk); + info, part, &disk, agent_handle); if (ret != EFI_SUCCESS) { log_err("Adding partition for %s failed\n", dev->name); return -1; @@ -623,17 +628,18 @@ static int efi_disk_create_part(struct udevice *dev) return 0; } -/* - * Create efi_disk objects for a block device +/** + * efi_disk_probe() - create efi_disk objects for a block device * - * @dev uclass device (UCLASS_BLK) + * @ctx: event context - driver binding protocol + * @event: EV_PM_POST_PROBE event * * Create efi_disk objects for partitions as well as a raw disk * which is associated with @dev. * The type of @dev must be UCLASS_BLK. * This function is expected to be called at EV_PM_POST_PROBE. * - * @return 0 on success, -1 otherwise + * Return: 0 on success, -1 otherwise */ int efi_disk_probe(void *ctx, struct event *event) { @@ -641,28 +647,30 @@ int efi_disk_probe(void *ctx, struct event *event) enum uclass_id id; struct blk_desc *desc; struct udevice *child; + struct efi_driver_binding_extended_protocol *db_prot = ctx; + efi_handle_t agent_handle = db_prot->bp.driver_binding_handle; int ret; dev = event->data.dm.dev; id = device_get_uclass_id(dev); - /* TODO: We won't support partitions in a partition */ + /* We won't support partitions in a partition */ if (id != UCLASS_BLK) return 0; /* - * avoid creating duplicated objects now that efi_driver + * Avoid creating duplicated objects now that efi_driver * has already created an efi_disk at this moment. */ desc = dev_get_uclass_plat(dev); if (desc->uclass_id != UCLASS_EFI_LOADER) { - ret = efi_disk_create_raw(dev); + ret = efi_disk_create_raw(dev, agent_handle); if (ret) return -1; } device_foreach_child(child, dev) { - ret = efi_disk_create_part(child); + ret = efi_disk_create_part(child, agent_handle); if (ret) return -1; }