Prepare v2024.10
[platform/kernel/u-boot.git] / lib / efi_loader / efi_runtime.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  EFI application runtime services
4  *
5  *  Copyright (c) 2016 Alexander Graf
6  */
7
8 #include <command.h>
9 #include <cpu_func.h>
10 #include <dm.h>
11 #include <elf.h>
12 #include <efi_loader.h>
13 #include <efi_variable.h>
14 #include <log.h>
15 #include <malloc.h>
16 #include <rtc.h>
17 #include <asm/global_data.h>
18 #include <u-boot/crc.h>
19 #include <asm/sections.h>
20
21 /* For manual relocation support */
22 DECLARE_GLOBAL_DATA_PTR;
23
24 /* GUID of the runtime properties table */
25 static const efi_guid_t efi_rt_properties_table_guid =
26                                 EFI_RT_PROPERTIES_TABLE_GUID;
27
28 struct efi_runtime_mmio_list {
29         struct list_head link;
30         void **ptr;
31         u64 paddr;
32         u64 len;
33 };
34
35 /* This list contains all runtime available mmio regions */
36 static LIST_HEAD(efi_runtime_mmio);
37
38 static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void);
39
40 /*
41  * TODO(sjg@chromium.org): These defines and structures should come from the ELF
42  * header for each architecture (or a generic header) rather than being repeated
43  * here.
44  */
45 #if defined(__aarch64__)
46 #define R_RELATIVE      R_AARCH64_RELATIVE
47 #define R_MASK          0xffffffffULL
48 #define IS_RELA         1
49 #elif defined(__arm__)
50 #define R_RELATIVE      R_ARM_RELATIVE
51 #define R_MASK          0xffULL
52 #elif defined(__i386__)
53 #define R_RELATIVE      R_386_RELATIVE
54 #define R_MASK          0xffULL
55 #elif defined(__x86_64__)
56 #define R_RELATIVE      R_X86_64_RELATIVE
57 #define R_MASK          0xffffffffULL
58 #define IS_RELA         1
59 #elif defined(__riscv)
60 #define R_RELATIVE      R_RISCV_RELATIVE
61 #define R_MASK          0xffULL
62 #define IS_RELA         1
63
64 struct dyn_sym {
65         ulong foo1;
66         ulong addr;
67         u32 foo2;
68         u32 foo3;
69 };
70 #if (__riscv_xlen == 32)
71 #define R_ABSOLUTE      R_RISCV_32
72 #define SYM_INDEX       8
73 #elif (__riscv_xlen == 64)
74 #define R_ABSOLUTE      R_RISCV_64
75 #define SYM_INDEX       32
76 #else
77 #error unknown riscv target
78 #endif
79 #else
80 #error Need to add relocation awareness
81 #endif
82
83 struct elf_rel {
84         ulong *offset;
85         ulong info;
86 };
87
88 struct elf_rela {
89         ulong *offset;
90         ulong info;
91         long addend;
92 };
93
94 static __efi_runtime_data struct efi_mem_desc *efi_virtmap;
95 static __efi_runtime_data efi_uintn_t efi_descriptor_count;
96 static __efi_runtime_data efi_uintn_t efi_descriptor_size;
97
98 /*
99  * EFI runtime code lives in two stages. In the first stage, U-Boot and an EFI
100  * payload are running concurrently at the same time. In this mode, we can
101  * handle a good number of runtime callbacks
102  */
103
104 /**
105  * efi_init_runtime_supported() - create runtime properties table
106  *
107  * Create a configuration table specifying which services are available at
108  * runtime.
109  *
110  * Return:      status code
111  */
112 efi_status_t efi_init_runtime_supported(void)
113 {
114         const efi_guid_t efi_guid_efi_rt_var_file = U_BOOT_EFI_RT_VAR_FILE_GUID;
115         efi_status_t ret;
116         struct efi_rt_properties_table *rt_table;
117
118         ret = efi_allocate_pool(EFI_RUNTIME_SERVICES_DATA,
119                                 sizeof(struct efi_rt_properties_table),
120                                 (void **)&rt_table);
121         if (ret != EFI_SUCCESS)
122                 return ret;
123
124         rt_table->version = EFI_RT_PROPERTIES_TABLE_VERSION;
125         rt_table->length = sizeof(struct efi_rt_properties_table);
126         rt_table->runtime_services_supported =
127                                 EFI_RT_SUPPORTED_GET_VARIABLE |
128                                 EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME |
129                                 EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP |
130                                 EFI_RT_SUPPORTED_CONVERT_POINTER;
131
132         if (IS_ENABLED(CONFIG_EFI_VARIABLE_FILE_STORE))
133                 rt_table->runtime_services_supported |=
134                         EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO;
135
136         if (IS_ENABLED(CONFIG_EFI_RT_VOLATILE_STORE)) {
137                 u8 s = 0;
138
139                 ret = efi_set_variable_int(u"RTStorageVolatile",
140                                            &efi_guid_efi_rt_var_file,
141                                            EFI_VARIABLE_BOOTSERVICE_ACCESS |
142                                            EFI_VARIABLE_RUNTIME_ACCESS |
143                                            EFI_VARIABLE_READ_ONLY,
144                                            sizeof(EFI_VAR_FILE_NAME),
145                                            EFI_VAR_FILE_NAME, false);
146                 if (ret != EFI_SUCCESS) {
147                         log_err("Failed to set RTStorageVolatile\n");
148                         return ret;
149                 }
150                 /*
151                  * This variable needs to be visible so users can read it,
152                  * but the real contents are going to be filled during
153                  * GetVariable
154                  */
155                 ret = efi_set_variable_int(u"VarToFile",
156                                            &efi_guid_efi_rt_var_file,
157                                            EFI_VARIABLE_BOOTSERVICE_ACCESS |
158                                            EFI_VARIABLE_RUNTIME_ACCESS |
159                                            EFI_VARIABLE_READ_ONLY,
160                                            sizeof(s),
161                                            &s, false);
162                 if (ret != EFI_SUCCESS) {
163                         log_err("Failed to set VarToFile\n");
164                         efi_set_variable_int(u"RTStorageVolatile",
165                                              &efi_guid_efi_rt_var_file,
166                                              EFI_VARIABLE_BOOTSERVICE_ACCESS |
167                                              EFI_VARIABLE_RUNTIME_ACCESS |
168                                              EFI_VARIABLE_READ_ONLY,
169                                              0, NULL, false);
170
171                         return ret;
172                 }
173                 rt_table->runtime_services_supported |= EFI_RT_SUPPORTED_SET_VARIABLE;
174         }
175
176         /*
177          * This value must be synced with efi_runtime_detach_list
178          * as well as efi_runtime_services.
179          */
180 #ifdef CONFIG_EFI_HAVE_RUNTIME_RESET
181         rt_table->runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM;
182 #endif
183
184         ret = efi_install_configuration_table(&efi_rt_properties_table_guid,
185                                               rt_table);
186         return ret;
187 }
188
189 /**
190  * efi_memcpy_runtime() - copy memory area
191  *
192  * At runtime memcpy() is not available.
193  *
194  * Overlapping memory areas can be copied safely if src >= dest.
195  *
196  * @dest:       destination buffer
197  * @src:        source buffer
198  * @n:          number of bytes to copy
199  * Return:      pointer to destination buffer
200  */
201 void __efi_runtime efi_memcpy_runtime(void *dest, const void *src, size_t n)
202 {
203         u8 *d = dest;
204         const u8 *s = src;
205
206         for (; n; --n)
207                 *d++ = *s++;
208 }
209
210 /**
211  * efi_update_table_header_crc32() - Update crc32 in table header
212  *
213  * @table:      EFI table
214  */
215 void __efi_runtime efi_update_table_header_crc32(struct efi_table_hdr *table)
216 {
217         table->crc32 = 0;
218         table->crc32 = crc32(0, (const unsigned char *)table,
219                              table->headersize);
220 }
221
222 /**
223  * efi_reset_system_boottime() - reset system at boot time
224  *
225  * This function implements the ResetSystem() runtime service before
226  * SetVirtualAddressMap() is called.
227  *
228  * See the Unified Extensible Firmware Interface (UEFI) specification for
229  * details.
230  *
231  * @reset_type:         type of reset to perform
232  * @reset_status:       status code for the reset
233  * @data_size:          size of reset_data
234  * @reset_data:         information about the reset
235  */
236 static void EFIAPI efi_reset_system_boottime(
237                         enum efi_reset_type reset_type,
238                         efi_status_t reset_status,
239                         unsigned long data_size, void *reset_data)
240 {
241         struct efi_event *evt;
242
243         EFI_ENTRY("%d %lx %lx %p", reset_type, reset_status, data_size,
244                   reset_data);
245
246         /* Notify reset */
247         list_for_each_entry(evt, &efi_events, link) {
248                 if (evt->group &&
249                     !guidcmp(evt->group,
250                              &efi_guid_event_group_reset_system)) {
251                         efi_signal_event(evt);
252                         break;
253                 }
254         }
255         switch (reset_type) {
256         case EFI_RESET_COLD:
257         case EFI_RESET_WARM:
258         case EFI_RESET_PLATFORM_SPECIFIC:
259                 do_reset(NULL, 0, 0, NULL);
260                 break;
261         case EFI_RESET_SHUTDOWN:
262 #ifdef CONFIG_CMD_POWEROFF
263                 do_poweroff(NULL, 0, 0, NULL);
264 #endif
265                 break;
266         }
267
268         while (1) { }
269 }
270
271 /**
272  * efi_get_time_boottime() - get current time at boot time
273  *
274  * This function implements the GetTime runtime service before
275  * SetVirtualAddressMap() is called.
276  *
277  * See the Unified Extensible Firmware Interface (UEFI) specification
278  * for details.
279  *
280  * @time:               pointer to structure to receive current time
281  * @capabilities:       pointer to structure to receive RTC properties
282  * Returns:             status code
283  */
284 static efi_status_t EFIAPI efi_get_time_boottime(
285                         struct efi_time *time,
286                         struct efi_time_cap *capabilities)
287 {
288 #ifdef CONFIG_EFI_GET_TIME
289         efi_status_t ret = EFI_SUCCESS;
290         struct rtc_time tm;
291         struct udevice *dev;
292
293         EFI_ENTRY("%p %p", time, capabilities);
294
295         if (!time) {
296                 ret = EFI_INVALID_PARAMETER;
297                 goto out;
298         }
299         if (uclass_get_device(UCLASS_RTC, 0, &dev) ||
300             dm_rtc_get(dev, &tm)) {
301                 ret = EFI_UNSUPPORTED;
302                 goto out;
303         }
304         if (dm_rtc_get(dev, &tm)) {
305                 ret = EFI_DEVICE_ERROR;
306                 goto out;
307         }
308
309         memset(time, 0, sizeof(*time));
310         time->year = tm.tm_year;
311         time->month = tm.tm_mon;
312         time->day = tm.tm_mday;
313         time->hour = tm.tm_hour;
314         time->minute = tm.tm_min;
315         time->second = tm.tm_sec;
316         if (tm.tm_isdst > 0)
317                 time->daylight =
318                         EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT;
319         else if (!tm.tm_isdst)
320                 time->daylight = EFI_TIME_ADJUST_DAYLIGHT;
321         else
322                 time->daylight = 0;
323         time->timezone = EFI_UNSPECIFIED_TIMEZONE;
324
325         if (capabilities) {
326                 /* Set reasonable dummy values */
327                 capabilities->resolution = 1;           /* 1 Hz */
328                 capabilities->accuracy = 100000000;     /* 100 ppm */
329                 capabilities->sets_to_zero = false;
330         }
331 out:
332         return EFI_EXIT(ret);
333 #else
334         EFI_ENTRY("%p %p", time, capabilities);
335         return EFI_EXIT(EFI_UNSUPPORTED);
336 #endif
337 }
338
339 #ifdef CONFIG_EFI_SET_TIME
340
341 /**
342  * efi_validate_time() - checks if timestamp is valid
343  *
344  * @time:       timestamp to validate
345  * Returns:     0 if timestamp is valid, 1 otherwise
346  */
347 static int efi_validate_time(struct efi_time *time)
348 {
349         return (!time ||
350                 time->year < 1900 || time->year > 9999 ||
351                 !time->month || time->month > 12 || !time->day ||
352                 time->day > rtc_month_days(time->month - 1, time->year) ||
353                 time->hour > 23 || time->minute > 59 || time->second > 59 ||
354                 time->nanosecond > 999999999 ||
355                 time->daylight &
356                 ~(EFI_TIME_IN_DAYLIGHT | EFI_TIME_ADJUST_DAYLIGHT) ||
357                 ((time->timezone < -1440 || time->timezone > 1440) &&
358                 time->timezone != EFI_UNSPECIFIED_TIMEZONE));
359 }
360
361 #endif
362
363 /**
364  * efi_set_time_boottime() - set current time
365  *
366  * This function implements the SetTime() runtime service before
367  * SetVirtualAddressMap() is called.
368  *
369  * See the Unified Extensible Firmware Interface (UEFI) specification
370  * for details.
371  *
372  * @time:               pointer to structure to with current time
373  * Returns:             status code
374  */
375 static efi_status_t EFIAPI efi_set_time_boottime(struct efi_time *time)
376 {
377 #ifdef CONFIG_EFI_SET_TIME
378         efi_status_t ret = EFI_SUCCESS;
379         struct rtc_time tm;
380         struct udevice *dev;
381
382         EFI_ENTRY("%p", time);
383
384         if (efi_validate_time(time)) {
385                 ret = EFI_INVALID_PARAMETER;
386                 goto out;
387         }
388
389         if (uclass_get_device(UCLASS_RTC, 0, &dev)) {
390                 ret = EFI_UNSUPPORTED;
391                 goto out;
392         }
393
394         memset(&tm, 0, sizeof(tm));
395         tm.tm_year = time->year;
396         tm.tm_mon = time->month;
397         tm.tm_mday = time->day;
398         tm.tm_hour = time->hour;
399         tm.tm_min = time->minute;
400         tm.tm_sec = time->second;
401         switch (time->daylight) {
402         case EFI_TIME_ADJUST_DAYLIGHT:
403                 tm.tm_isdst = 0;
404                 break;
405         case EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT:
406                 tm.tm_isdst = 1;
407                 break;
408         default:
409                 tm.tm_isdst = -1;
410                 break;
411         }
412         /* Calculate day of week */
413         rtc_calc_weekday(&tm);
414
415         if (dm_rtc_set(dev, &tm))
416                 ret = EFI_DEVICE_ERROR;
417 out:
418         return EFI_EXIT(ret);
419 #else
420         EFI_ENTRY("%p", time);
421         return EFI_EXIT(EFI_UNSUPPORTED);
422 #endif
423 }
424 /**
425  * efi_reset_system() - reset system
426  *
427  * This function implements the ResetSystem() runtime service after
428  * SetVirtualAddressMap() is called. As this placeholder cannot reset the
429  * system it simply return to the caller.
430  *
431  * Boards may override the helpers below to implement reset functionality.
432  *
433  * See the Unified Extensible Firmware Interface (UEFI) specification for
434  * details.
435  *
436  * @reset_type:         type of reset to perform
437  * @reset_status:       status code for the reset
438  * @data_size:          size of reset_data
439  * @reset_data:         information about the reset
440  */
441 void __weak __efi_runtime EFIAPI efi_reset_system(
442                         enum efi_reset_type reset_type,
443                         efi_status_t reset_status,
444                         unsigned long data_size, void *reset_data)
445 {
446         return;
447 }
448
449 /**
450  * efi_reset_system_init() - initialize the reset driver
451  *
452  * Boards may override this function to initialize the reset driver.
453  */
454 efi_status_t __weak efi_reset_system_init(void)
455 {
456         return EFI_SUCCESS;
457 }
458
459 /**
460  * efi_get_time() - get current time
461  *
462  * This function implements the GetTime runtime service after
463  * SetVirtualAddressMap() is called. As the U-Boot driver are not available
464  * anymore only an error code is returned.
465  *
466  * See the Unified Extensible Firmware Interface (UEFI) specification
467  * for details.
468  *
469  * @time:               pointer to structure to receive current time
470  * @capabilities:       pointer to structure to receive RTC properties
471  * Returns:             status code
472  */
473 efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
474                         struct efi_time *time,
475                         struct efi_time_cap *capabilities)
476 {
477         return EFI_UNSUPPORTED;
478 }
479
480 /**
481  * efi_set_time() - set current time
482  *
483  * This function implements the SetTime runtime service after
484  * SetVirtualAddressMap() is called. As the U-Boot driver are not available
485  * anymore only an error code is returned.
486  *
487  * See the Unified Extensible Firmware Interface (UEFI) specification
488  * for details.
489  *
490  * @time:               pointer to structure to with current time
491  * Returns:             status code
492  */
493 efi_status_t __weak __efi_runtime EFIAPI efi_set_time(struct efi_time *time)
494 {
495         return EFI_UNSUPPORTED;
496 }
497
498 /**
499  * efi_update_capsule_unsupported() - process information from operating system
500  *
501  * This function implements the UpdateCapsule() runtime service.
502  *
503  * See the Unified Extensible Firmware Interface (UEFI) specification for
504  * details.
505  *
506  * @capsule_header_array:       pointer to array of virtual pointers
507  * @capsule_count:              number of pointers in capsule_header_array
508  * @scatter_gather_list:        pointer to array of physical pointers
509  * Returns:                     status code
510  */
511 static efi_status_t __efi_runtime EFIAPI efi_update_capsule_unsupported(
512                         struct efi_capsule_header **capsule_header_array,
513                         efi_uintn_t capsule_count,
514                         u64 scatter_gather_list)
515 {
516         return EFI_UNSUPPORTED;
517 }
518
519 /**
520  * efi_query_capsule_caps_unsupported() - check if capsule is supported
521  *
522  * This function implements the QueryCapsuleCapabilities() runtime service.
523  *
524  * See the Unified Extensible Firmware Interface (UEFI) specification for
525  * details.
526  *
527  * @capsule_header_array:       pointer to array of virtual pointers
528  * @capsule_count:              number of pointers in capsule_header_array
529  * @maximum_capsule_size:       maximum capsule size
530  * @reset_type:                 type of reset needed for capsule update
531  * Returns:                     status code
532  */
533 static efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps_unsupported(
534                         struct efi_capsule_header **capsule_header_array,
535                         efi_uintn_t capsule_count,
536                         u64 *maximum_capsule_size,
537                         u32 *reset_type)
538 {
539         return EFI_UNSUPPORTED;
540 }
541
542 /**
543  * efi_is_runtime_service_pointer() - check if pointer points to runtime table
544  *
545  * @p:          pointer to check
546  * Return:      true if the pointer points to a service function pointer in the
547  *              runtime table
548  */
549 static bool efi_is_runtime_service_pointer(void *p)
550 {
551         return (p >= (void *)&efi_runtime_services.get_time &&
552                 p <= (void *)&efi_runtime_services.query_variable_info) ||
553                p == (void *)&efi_events.prev ||
554                p == (void *)&efi_events.next;
555 }
556
557 /**
558  * efi_runtime_detach() - detach unimplemented runtime functions
559  */
560 void efi_runtime_detach(void)
561 {
562         efi_runtime_services.reset_system = efi_reset_system;
563         efi_runtime_services.get_time = efi_get_time;
564         efi_runtime_services.set_time = efi_set_time;
565         if (IS_ENABLED(CONFIG_EFI_RUNTIME_UPDATE_CAPSULE)) {
566                 /* won't support at runtime */
567                 efi_runtime_services.update_capsule =
568                                 efi_update_capsule_unsupported;
569                 efi_runtime_services.query_capsule_caps =
570                                 efi_query_capsule_caps_unsupported;
571         }
572
573         /* Update CRC32 */
574         efi_update_table_header_crc32(&efi_runtime_services.hdr);
575 }
576
577 /**
578  * efi_set_virtual_address_map_runtime() - change from physical to virtual
579  *                                         mapping
580  *
581  * This function implements the SetVirtualAddressMap() runtime service after
582  * it is first called.
583  *
584  * See the Unified Extensible Firmware Interface (UEFI) specification for
585  * details.
586  *
587  * @memory_map_size:    size of the virtual map
588  * @descriptor_size:    size of an entry in the map
589  * @descriptor_version: version of the map entries
590  * @virtmap:            virtual address mapping information
591  * Return:              status code EFI_UNSUPPORTED
592  */
593 static __efi_runtime efi_status_t EFIAPI efi_set_virtual_address_map_runtime(
594                         efi_uintn_t memory_map_size,
595                         efi_uintn_t descriptor_size,
596                         uint32_t descriptor_version,
597                         struct efi_mem_desc *virtmap)
598 {
599         return EFI_UNSUPPORTED;
600 }
601
602 /**
603  * efi_convert_pointer_runtime() - convert from physical to virtual pointer
604  *
605  * This function implements the ConvertPointer() runtime service after
606  * the first call to SetVirtualAddressMap().
607  *
608  * See the Unified Extensible Firmware Interface (UEFI) specification for
609  * details.
610  *
611  * @debug_disposition:  indicates if pointer may be converted to NULL
612  * @address:            pointer to be converted
613  * Return:              status code EFI_UNSUPPORTED
614  */
615 static __efi_runtime efi_status_t EFIAPI efi_convert_pointer_runtime(
616                         efi_uintn_t debug_disposition, void **address)
617 {
618         return EFI_UNSUPPORTED;
619 }
620
621 /**
622  * efi_convert_pointer() - convert from physical to virtual pointer
623  *
624  * This function implements the ConvertPointer() runtime service until
625  * the first call to SetVirtualAddressMap().
626  *
627  * See the Unified Extensible Firmware Interface (UEFI) specification for
628  * details.
629  *
630  * @debug_disposition:  indicates if pointer may be converted to NULL
631  * @address:            pointer to be converted
632  * Return:              status code
633  */
634 __efi_runtime efi_status_t EFIAPI
635 efi_convert_pointer(efi_uintn_t debug_disposition, void **address)
636 {
637         efi_physical_addr_t addr;
638         efi_uintn_t i;
639         efi_status_t ret = EFI_NOT_FOUND;
640
641         if (!efi_virtmap) {
642                 ret = EFI_UNSUPPORTED;
643                 goto out;
644         }
645
646         if (!address) {
647                 ret = EFI_INVALID_PARAMETER;
648                 goto out;
649         }
650         if (!*address) {
651                 if (debug_disposition & EFI_OPTIONAL_PTR)
652                         return EFI_SUCCESS;
653                 else
654                         return EFI_INVALID_PARAMETER;
655         }
656
657         addr = (uintptr_t)*address;
658         for (i = 0; i < efi_descriptor_count; i++) {
659                 struct efi_mem_desc *map = (void *)efi_virtmap +
660                                            (efi_descriptor_size * i);
661
662                 if (addr >= map->physical_start &&
663                     (addr < map->physical_start
664                             + (map->num_pages << EFI_PAGE_SHIFT))) {
665                         *address = (void *)(uintptr_t)
666                                    (addr + map->virtual_start -
667                                     map->physical_start);
668
669                         ret = EFI_SUCCESS;
670                         break;
671                 }
672         }
673
674 out:
675         return ret;
676 }
677
678 static __efi_runtime void efi_relocate_runtime_table(ulong offset)
679 {
680         ulong patchoff;
681         void **pos;
682
683         /* Relocate the runtime services pointers */
684         patchoff = offset - gd->relocaddr;
685         for (pos = (void **)&efi_runtime_services.get_time;
686              pos <= (void **)&efi_runtime_services.query_variable_info; ++pos) {
687                 if (*pos)
688                         *pos += patchoff;
689         }
690
691         /*
692          * The entry for SetVirtualAddress() must point to a physical address.
693          * After the first execution the service must return EFI_UNSUPPORTED.
694          */
695         efi_runtime_services.set_virtual_address_map =
696                         &efi_set_virtual_address_map_runtime;
697
698         /*
699          * The entry for ConvertPointer() must point to a physical address.
700          * The service is not usable after SetVirtualAddress().
701          */
702         efi_runtime_services.convert_pointer = &efi_convert_pointer_runtime;
703
704         /*
705          * TODO: Update UEFI variable RuntimeServicesSupported removing flags
706          * EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP and
707          * EFI_RT_SUPPORTED_CONVERT_POINTER as required by the UEFI spec 2.8.
708          */
709
710         /* Update CRC32 */
711         efi_update_table_header_crc32(&efi_runtime_services.hdr);
712 }
713
714 /* Relocate EFI runtime to uboot_reloc_base = offset */
715 void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
716 {
717 #ifdef IS_RELA
718         struct elf_rela *rel = (void *)__efi_runtime_rel_start;
719 #else
720         struct elf_rel *rel = (void *)__efi_runtime_rel_start;
721         static ulong lastoff = CONFIG_TEXT_BASE;
722 #endif
723
724         debug("%s: Relocating to offset=%lx\n", __func__, offset);
725         for (; (uintptr_t)rel < (uintptr_t)__efi_runtime_rel_stop; rel++) {
726                 ulong base = CONFIG_TEXT_BASE;
727                 ulong *p;
728                 ulong newaddr;
729
730                 p = (void*)((ulong)rel->offset - base) + gd->relocaddr;
731
732                 /*
733                  * The runtime services table is updated in
734                  * efi_relocate_runtime_table()
735                  */
736                 if (map && efi_is_runtime_service_pointer(p))
737                         continue;
738
739                 debug("%s: rel->info=%#lx *p=%#lx rel->offset=%p\n", __func__,
740                       rel->info, *p, rel->offset);
741
742                 switch (rel->info & R_MASK) {
743                 case R_RELATIVE:
744 #ifdef IS_RELA
745                 newaddr = rel->addend + offset - CONFIG_TEXT_BASE;
746 #else
747                 newaddr = *p - lastoff + offset;
748 #endif
749                         break;
750 #ifdef R_ABSOLUTE
751                 case R_ABSOLUTE: {
752                         ulong symidx = rel->info >> SYM_INDEX;
753                         extern struct dyn_sym __dyn_sym_start[];
754                         newaddr = __dyn_sym_start[symidx].addr + offset;
755 #ifdef IS_RELA
756                         newaddr -= CONFIG_TEXT_BASE;
757 #endif
758                         break;
759                 }
760 #endif
761                 default:
762                         printf("%s: Unknown relocation type %llx\n",
763                                __func__, rel->info & R_MASK);
764                         continue;
765                 }
766
767                 /* Check if the relocation is inside bounds */
768                 if (map && ((newaddr < map->virtual_start) ||
769                     newaddr > (map->virtual_start +
770                               (map->num_pages << EFI_PAGE_SHIFT)))) {
771                         printf("%s: Relocation at %p is out of range (%lx)\n",
772                                __func__, p, newaddr);
773                         continue;
774                 }
775
776                 debug("%s: Setting %p to %lx\n", __func__, p, newaddr);
777                 *p = newaddr;
778                 flush_dcache_range((ulong)p & ~(EFI_CACHELINE_SIZE - 1),
779                         ALIGN((ulong)&p[1], EFI_CACHELINE_SIZE));
780         }
781
782 #ifndef IS_RELA
783         lastoff = offset;
784 #endif
785
786         /*
787          * If on x86 a write affects a prefetched instruction,
788          * the prefetch queue is invalidated.
789          */
790         if (!CONFIG_IS_ENABLED(X86))
791                 invalidate_icache_all();
792 }
793
794 /**
795  * efi_set_virtual_address_map() - change from physical to virtual mapping
796  *
797  * This function implements the SetVirtualAddressMap() runtime service.
798  *
799  * See the Unified Extensible Firmware Interface (UEFI) specification for
800  * details.
801  *
802  * @memory_map_size:    size of the virtual map
803  * @descriptor_size:    size of an entry in the map
804  * @descriptor_version: version of the map entries
805  * @virtmap:            virtual address mapping information
806  * Return:              status code
807  */
808 static efi_status_t EFIAPI efi_set_virtual_address_map(
809                         efi_uintn_t memory_map_size,
810                         efi_uintn_t descriptor_size,
811                         uint32_t descriptor_version,
812                         struct efi_mem_desc *virtmap)
813 {
814         efi_uintn_t n = memory_map_size / descriptor_size;
815         efi_uintn_t i;
816         efi_status_t ret = EFI_INVALID_PARAMETER;
817         int rt_code_sections = 0;
818         struct efi_event *event;
819
820         EFI_ENTRY("%zx %zx %x %p", memory_map_size, descriptor_size,
821                   descriptor_version, virtmap);
822
823         if (descriptor_version != EFI_MEMORY_DESCRIPTOR_VERSION ||
824             descriptor_size < sizeof(struct efi_mem_desc))
825                 goto out;
826
827         efi_virtmap = virtmap;
828         efi_descriptor_size = descriptor_size;
829         efi_descriptor_count = n;
830
831         /*
832          * TODO:
833          * Further down we are cheating. While really we should implement
834          * SetVirtualAddressMap() events and ConvertPointer() to allow
835          * dynamically loaded drivers to expose runtime services, we don't
836          * today.
837          *
838          * So let's ensure we see exactly one single runtime section, as
839          * that is the built-in one. If we see more (or less), someone must
840          * have tried adding or removing to that which we don't support yet.
841          * In that case, let's better fail rather than expose broken runtime
842          * services.
843          */
844         for (i = 0; i < n; i++) {
845                 struct efi_mem_desc *map = (void*)virtmap +
846                                            (descriptor_size * i);
847
848                 if (map->type == EFI_RUNTIME_SERVICES_CODE)
849                         rt_code_sections++;
850         }
851
852         if (rt_code_sections != 1) {
853                 /*
854                  * We expose exactly one single runtime code section, so
855                  * something is definitely going wrong.
856                  */
857                 goto out;
858         }
859
860         /* Notify EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE */
861         list_for_each_entry(event, &efi_events, link) {
862                 if (event->notify_function)
863                         EFI_CALL_VOID(event->notify_function(
864                                         event, event->notify_context));
865         }
866
867         /* Rebind mmio pointers */
868         for (i = 0; i < n; i++) {
869                 struct efi_mem_desc *map = (void*)virtmap +
870                                            (descriptor_size * i);
871                 struct list_head *lhandle;
872                 efi_physical_addr_t map_start = map->physical_start;
873                 efi_physical_addr_t map_len = map->num_pages << EFI_PAGE_SHIFT;
874                 efi_physical_addr_t map_end = map_start + map_len;
875                 u64 off = map->virtual_start - map_start;
876
877                 /* Adjust all mmio pointers in this region */
878                 list_for_each(lhandle, &efi_runtime_mmio) {
879                         struct efi_runtime_mmio_list *lmmio;
880
881                         lmmio = list_entry(lhandle,
882                                            struct efi_runtime_mmio_list,
883                                            link);
884                         if ((map_start <= lmmio->paddr) &&
885                             (map_end >= lmmio->paddr)) {
886                                 uintptr_t new_addr = lmmio->paddr + off;
887                                 *lmmio->ptr = (void *)new_addr;
888                         }
889                 }
890                 if ((map_start <= (uintptr_t)systab.tables) &&
891                     (map_end >= (uintptr_t)systab.tables)) {
892                         char *ptr = (char *)systab.tables;
893
894                         ptr += off;
895                         systab.tables = (struct efi_configuration_table *)ptr;
896                 }
897         }
898
899         /* Relocate the runtime. See TODO above */
900         for (i = 0; i < n; i++) {
901                 struct efi_mem_desc *map;
902
903                 map = (void*)virtmap + (descriptor_size * i);
904                 if (map->type == EFI_RUNTIME_SERVICES_CODE) {
905                         ulong new_offset = map->virtual_start -
906                                            map->physical_start + gd->relocaddr;
907
908                         efi_relocate_runtime_table(new_offset);
909                         efi_runtime_relocate(new_offset, map);
910                         ret = EFI_SUCCESS;
911                         goto out;
912                 }
913         }
914
915 out:
916         return EFI_EXIT(ret);
917 }
918
919 /**
920  * efi_add_runtime_mmio() - add memory-mapped IO region
921  *
922  * This function adds a memory-mapped IO region to the memory map to make it
923  * available at runtime.
924  *
925  * @mmio_ptr:           pointer to a pointer to the start of the memory-mapped
926  *                      IO region
927  * @len:                size of the memory-mapped IO region
928  * Returns:             status code
929  */
930 efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len)
931 {
932         struct efi_runtime_mmio_list *newmmio;
933         uint64_t addr = *(uintptr_t *)mmio_ptr;
934         efi_status_t ret;
935
936         ret = efi_add_memory_map(addr, len, EFI_MMAP_IO);
937         if (ret != EFI_SUCCESS)
938                 return EFI_OUT_OF_RESOURCES;
939
940         newmmio = calloc(1, sizeof(*newmmio));
941         if (!newmmio)
942                 return EFI_OUT_OF_RESOURCES;
943         newmmio->ptr = mmio_ptr;
944         newmmio->paddr = *(uintptr_t *)mmio_ptr;
945         newmmio->len = len;
946         list_add_tail(&newmmio->link, &efi_runtime_mmio);
947
948         return EFI_SUCCESS;
949 }
950
951 /*
952  * In the second stage, U-Boot has disappeared. To isolate our runtime code
953  * that at this point still exists from the rest, we put it into a special
954  * section.
955  *
956  *        !!WARNING!!
957  *
958  * This means that we can not rely on any code outside of this file in any
959  * function or variable below this line.
960  *
961  * Please keep everything fully self-contained and annotated with
962  * __efi_runtime and __efi_runtime_data markers.
963  */
964
965 /*
966  * Relocate the EFI runtime stub to a different place. We need to call this
967  * the first time we expose the runtime interface to a user and on set virtual
968  * address map calls.
969  */
970
971 /**
972  * efi_unimplemented() - replacement function, returns EFI_UNSUPPORTED
973  *
974  * This function is used after SetVirtualAddressMap() is called as replacement
975  * for services that are not available anymore due to constraints of the U-Boot
976  * implementation.
977  *
978  * Return:      EFI_UNSUPPORTED
979  */
980 static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void)
981 {
982         return EFI_UNSUPPORTED;
983 }
984
985 struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
986         .hdr = {
987                 .signature = EFI_RUNTIME_SERVICES_SIGNATURE,
988                 .revision = EFI_SPECIFICATION_VERSION,
989                 .headersize = sizeof(struct efi_runtime_services),
990         },
991         .get_time = &efi_get_time_boottime,
992         .set_time = &efi_set_time_boottime,
993         .get_wakeup_time = (void *)&efi_unimplemented,
994         .set_wakeup_time = (void *)&efi_unimplemented,
995         .set_virtual_address_map = &efi_set_virtual_address_map,
996         .convert_pointer = efi_convert_pointer,
997         .get_variable = efi_get_variable,
998         .get_next_variable_name = efi_get_next_variable_name,
999         .set_variable = efi_set_variable,
1000         .get_next_high_mono_count = (void *)&efi_unimplemented,
1001         .reset_system = &efi_reset_system_boottime,
1002 #ifdef CONFIG_EFI_RUNTIME_UPDATE_CAPSULE
1003         .update_capsule = efi_update_capsule,
1004         .query_capsule_caps = efi_query_capsule_caps,
1005 #else
1006         .update_capsule = efi_update_capsule_unsupported,
1007         .query_capsule_caps = efi_query_capsule_caps_unsupported,
1008 #endif
1009         .query_variable_info = efi_query_variable_info,
1010 };