Merge git://git.denx.de/u-boot-riscv
[oweals/u-boot.git] / lib / efi_loader / efi_runtime.c
index ca66d33e588200684000480f8bf39a0f66110c34..fff93f0960bf3b193c4cfb5ad32af9c9fc0e3c1b 100644 (file)
@@ -284,7 +284,7 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = {
        }, {
                /* invalidate_*cache_all are gone */
                .ptr = &efi_runtime_services.set_virtual_address_map,
-               .patchto = &efi_invalid_parameter,
+               .patchto = &efi_unimplemented,
        }, {
                /* RTC accessors are gone */
                .ptr = &efi_runtime_services.get_time,
@@ -436,14 +436,42 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
                        uint32_t descriptor_version,
                        struct efi_mem_desc *virtmap)
 {
-       ulong runtime_start = (ulong)&__efi_runtime_start &
-                             ~(ulong)EFI_PAGE_MASK;
        int n = memory_map_size / descriptor_size;
        int i;
+       int rt_code_sections = 0;
 
        EFI_ENTRY("%lx %lx %x %p", memory_map_size, descriptor_size,
                  descriptor_version, virtmap);
 
+       /*
+        * TODO:
+        * Further down we are cheating. While really we should implement
+        * SetVirtualAddressMap() events and ConvertPointer() to allow
+        * dynamically loaded drivers to expose runtime services, we don't
+        * today.
+        *
+        * So let's ensure we see exactly one single runtime section, as
+        * that is the built-in one. If we see more (or less), someone must
+        * have tried adding or removing to that which we don't support yet.
+        * In that case, let's better fail rather than expose broken runtime
+        * services.
+        */
+       for (i = 0; i < n; i++) {
+               struct efi_mem_desc *map = (void*)virtmap +
+                                          (descriptor_size * i);
+
+               if (map->type == EFI_RUNTIME_SERVICES_CODE)
+                       rt_code_sections++;
+       }
+
+       if (rt_code_sections != 1) {
+               /*
+                * We expose exactly one single runtime code section, so
+                * something is definitely going wrong.
+                */
+               return EFI_EXIT(EFI_INVALID_PARAMETER);
+       }
+
        /* Rebind mmio pointers */
        for (i = 0; i < n; i++) {
                struct efi_mem_desc *map = (void*)virtmap +
@@ -483,7 +511,7 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
                map = (void*)virtmap + (descriptor_size * i);
                if (map->type == EFI_RUNTIME_SERVICES_CODE) {
                        ulong new_offset = map->virtual_start -
-                                          (runtime_start - gd->relocaddr);
+                                          map->physical_start + gd->relocaddr;
 
                        efi_runtime_relocate(new_offset, map);
                        /* Once we're virtual, we can no longer handle
@@ -628,8 +656,8 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule(
 efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
                        struct efi_capsule_header **capsule_header_array,
                        efi_uintn_t capsule_count,
-                       u64 maximum_capsule_size,
-                       u32 reset_type)
+                       u64 *maximum_capsule_size,
+                       u32 *reset_type)
 {
        return EFI_UNSUPPORTED;
 }