[U-Boot] [PATCH 3/4] efi_loader: implement ConvertPointer()
Heinrich Schuchardt
xypron.glpk at gmx.de
Mon Jul 29 05:51:48 UTC 2019
On 7/29/19 3:37 AM, AKASHI Takahiro wrote:
> On Sat, Jul 27, 2019 at 11:00:03PM +0200, Heinrich Schuchardt wrote:
>> Implement the ConvertPointer() runtime service.
Thank you for reviewing.
>
> I already submitted a similar patch:
> https://lists.denx.de/pipermail/u-boot/2019-June/371773.html
Unfortunately I do not see any follow up version of the patch after I
started reviewing.
>
> Anyhow,
Should I put a
Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org> or a
Suggested-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
before my signature?
>
>> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
>> ---
>> lib/efi_loader/efi_runtime.c | 75 ++++++++++++++++++++++++++++++++++--
>> 1 file changed, 71 insertions(+), 4 deletions(-)
>>
>> diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
>> index a8f0b5eae3..2286e847a7 100644
>> --- a/lib/efi_loader/efi_runtime.c
>> +++ b/lib/efi_loader/efi_runtime.c
>> @@ -81,6 +81,10 @@ struct elf_rela {
>> long addend;
>> };
>>
>> +static __efi_runtime_data struct efi_mem_desc *efi_virtmap;
>> +static __efi_runtime_data efi_uintn_t efi_descriptor_count;
>> +static __efi_runtime_data efi_uintn_t efi_descriptor_size;
>> +
>> /*
>> * EFI runtime code lives in two stages. In the first stage, U-Boot and an EFI
>> * payload are running concurrently at the same time. In this mode, we can
>> @@ -89,7 +93,9 @@ struct elf_rela {
>>
>> efi_status_t efi_init_runtime_supported(void)
>> {
>> - u16 efi_runtime_services_supported = 0;
>> + u16 efi_runtime_services_supported =
>> + EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP ||
>
> "||" -> "|"
I will fix this?
>
>> + EFI_RT_SUPPORTED_CONVERT_POINTER;
>>
>> /*
>> * This value must be synced with efi_runtime_detach_list
>> @@ -98,8 +104,7 @@ efi_status_t efi_init_runtime_supported(void)
>> #ifdef CONFIG_EFI_HAVE_RUNTIME_RESET
>> efi_runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM;
>> #endif
>> - efi_runtime_services_supported |=
>> - EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP;
>> +
>> return EFI_CALL(efi_set_variable(L"RuntimeServicesSupported",
>> &efi_global_variable_guid,
>> EFI_VARIABLE_BOOTSERVICE_ACCESS |
>> @@ -454,6 +459,58 @@ static __efi_runtime efi_status_t EFIAPI efi_convert_pointer_runtime(
>> return EFI_UNSUPPORTED;
>> }
>>
>> +/**
>> + * efi_convert_pointer_runtime() - convert from physical to virtual pointer
>> + *
>> + * This function implements the ConvertPointer() runtime service until
>> + * the first call to SetVirtualAddressMap().
>> + *
>> + * See the Unified Extensible Firmware Interface (UEFI) specification for
>> + * details.
>> + *
>> + * @debug_disposition: indicates if pointer may be converted to NULL
>> + * @address: pointer to be converted
>> + * Return: status code EFI_UNSUPPORTED
>> + */
>> +static __efi_runtime efi_status_t EFIAPI efi_convert_pointer(
>> + efi_uintn_t debug_disposition, void **address)
>> +{
>> + efi_physical_addr_t addr = (uintptr_t)*address;
>> + efi_uintn_t i;
>> + efi_status_t ret = EFI_NOT_FOUND;
>> +
>> + EFI_ENTRY("%zu %p", debug_disposition, address);
>> +
>> + if (!efi_virtmap) {
>> + ret = EFI_UNSUPPORTED;
>> + goto out;
>> + }
>> +
>> + if (!address) {
>> + ret = EFI_INVALID_PARAMETER;
>> + goto out;
>> + }
>> +
>> + for (i = 0; i < efi_descriptor_count; i++) {
>> + struct efi_mem_desc *map = (void *)efi_virtmap +
>> + (efi_descriptor_size * i);
>> +
>> + if (addr >= map->physical_start &&
>> + (addr < map->physical_start
>> + + (map->num_pages << EFI_PAGE_SHIFT))) {
>> + *address = (void *)(uintptr_t)
>> + (addr + map->virtual_start -
>> + map->physical_start);
>> +
>> + ret = EFI_SUCCESS;
>> + break;
>> + }
>> + }
>> +
>> +out:
>> + return EFI_EXIT(ret);
>> +}
>> +
>> static __efi_runtime void efi_relocate_runtime_table(ulong offset)
>> {
>> ulong patchoff;
>> @@ -480,6 +537,12 @@ static __efi_runtime void efi_relocate_runtime_table(ulong offset)
>> */
>> efi_runtime_services.convert_pointer = &efi_convert_pointer_runtime;
>>
>> + /*
>> + * TODO: Update UEFI variable RuntimeServicesSupported removing flags
>> + * EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP and
>> + * EFI_RT_SUPPORTED_CONVERT_POINTER as required by the UEFI spec 2.8.
>> + */
>> +
>> /* Update CRC32 */
>> efi_update_table_header_crc32(&efi_runtime_services.hdr);
>> }
>> @@ -584,6 +647,10 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
>> EFI_ENTRY("%zx %zx %x %p", memory_map_size, descriptor_size,
>> descriptor_version, virtmap);
>>
>> + efi_virtmap = virtmap;
>> + efi_descriptor_size = descriptor_size;
>> + efi_descriptor_count = n;
>> +
>
> As I mentioned in the patch above,
>
> ! /* Rebind mmio pointers */
> ! for (i = 0; i < n; i++) {
> ! ...
>
> This part of code in efi_set_virtual_address_map() is fragile as
> entries in efi_runtime_mmio belong to memory allocated by calloc(),
> which means that they are no longer accessible at runtime.
This should be addressed in a separate patch.
Best regards
Heinrich
>
> -Takahiro Akashi
>
>> /*
>> * TODO:
>> * Further down we are cheating. While really we should implement
>> @@ -800,7 +867,7 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
>> .get_wakeup_time = (void *)&efi_unimplemented,
>> .set_wakeup_time = (void *)&efi_unimplemented,
>> .set_virtual_address_map = &efi_set_virtual_address_map,
>> - .convert_pointer = (void *)&efi_unimplemented,
>> + .convert_pointer = efi_convert_pointer,
>> .get_variable = efi_get_variable,
>> .get_next_variable_name = efi_get_next_variable_name,
>> .set_variable = efi_set_variable,
>> --
>> 2.20.1
>>
>
More information about the U-Boot
mailing list