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