xref: /openbmc/u-boot/lib/efi_loader/efi_runtime.c (revision cc0bfc01220a95ebd1f0c5370a66c93b631b6eb7)
1  // SPDX-License-Identifier: GPL-2.0+
2  /*
3   *  EFI application runtime services
4   *
5   *  Copyright (c) 2016 Alexander Graf
6   */
7  
8  #include <common.h>
9  #include <command.h>
10  #include <dm.h>
11  #include <elf.h>
12  #include <efi_loader.h>
13  #include <rtc.h>
14  
15  /* For manual relocation support */
16  DECLARE_GLOBAL_DATA_PTR;
17  
18  struct efi_runtime_mmio_list {
19  	struct list_head link;
20  	void **ptr;
21  	u64 paddr;
22  	u64 len;
23  };
24  
25  /* This list contains all runtime available mmio regions */
26  LIST_HEAD(efi_runtime_mmio);
27  
28  static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void);
29  static efi_status_t __efi_runtime EFIAPI efi_device_error(void);
30  static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
31  
32  /*
33   * TODO(sjg@chromium.org): These defines and structures should come from the ELF
34   * header for each architecture (or a generic header) rather than being repeated
35   * here.
36   */
37  #if defined(__aarch64__)
38  #define R_RELATIVE	R_AARCH64_RELATIVE
39  #define R_MASK		0xffffffffULL
40  #define IS_RELA		1
41  #elif defined(__arm__)
42  #define R_RELATIVE	R_ARM_RELATIVE
43  #define R_MASK		0xffULL
44  #elif defined(__x86_64__) || defined(__i386__)
45  #define R_RELATIVE	R_386_RELATIVE
46  #define R_MASK		0xffULL
47  #elif defined(__riscv)
48  #define R_RELATIVE	R_RISCV_RELATIVE
49  #define R_MASK		0xffULL
50  #define IS_RELA		1
51  
52  struct dyn_sym {
53  	ulong foo1;
54  	ulong addr;
55  	u32 foo2;
56  	u32 foo3;
57  };
58  #if (__riscv_xlen == 32)
59  #define R_ABSOLUTE	R_RISCV_32
60  #define SYM_INDEX	8
61  #elif (__riscv_xlen == 64)
62  #define R_ABSOLUTE	R_RISCV_64
63  #define SYM_INDEX	32
64  #else
65  #error unknown riscv target
66  #endif
67  #else
68  #error Need to add relocation awareness
69  #endif
70  
71  struct elf_rel {
72  	ulong *offset;
73  	ulong info;
74  };
75  
76  struct elf_rela {
77  	ulong *offset;
78  	ulong info;
79  	long addend;
80  };
81  
82  /*
83   * EFI runtime code lives in two stages. In the first stage, U-Boot and an EFI
84   * payload are running concurrently at the same time. In this mode, we can
85   * handle a good number of runtime callbacks
86   */
87  
88  /**
89   * efi_update_table_header_crc32() - Update crc32 in table header
90   *
91   * @table:	EFI table
92   */
93  void __efi_runtime efi_update_table_header_crc32(struct efi_table_hdr *table)
94  {
95  	table->crc32 = 0;
96  	table->crc32 = crc32(0, (const unsigned char *)table,
97  			     table->headersize);
98  }
99  
100  /**
101   * efi_reset_system_boottime() - reset system at boot time
102   *
103   * This function implements the ResetSystem() runtime service before
104   * SetVirtualAddressMap() is called.
105   *
106   * See the Unified Extensible Firmware Interface (UEFI) specification for
107   * details.
108   *
109   * @reset_type:		type of reset to perform
110   * @reset_status:	status code for the reset
111   * @data_size:		size of reset_data
112   * @reset_data:		information about the reset
113   */
114  static void EFIAPI efi_reset_system_boottime(
115  			enum efi_reset_type reset_type,
116  			efi_status_t reset_status,
117  			unsigned long data_size, void *reset_data)
118  {
119  	struct efi_event *evt;
120  
121  	EFI_ENTRY("%d %lx %lx %p", reset_type, reset_status, data_size,
122  		  reset_data);
123  
124  	/* Notify reset */
125  	list_for_each_entry(evt, &efi_events, link) {
126  		if (evt->group &&
127  		    !guidcmp(evt->group,
128  			     &efi_guid_event_group_reset_system)) {
129  			efi_signal_event(evt, false);
130  			break;
131  		}
132  	}
133  	switch (reset_type) {
134  	case EFI_RESET_COLD:
135  	case EFI_RESET_WARM:
136  	case EFI_RESET_PLATFORM_SPECIFIC:
137  		do_reset(NULL, 0, 0, NULL);
138  		break;
139  	case EFI_RESET_SHUTDOWN:
140  		/* We don't have anything to map this to */
141  		break;
142  	}
143  
144  	while (1) { }
145  }
146  
147  /**
148   * efi_get_time_boottime() - get current time at boot time
149   *
150   * This function implements the GetTime runtime service before
151   * SetVirtualAddressMap() is called.
152   *
153   * See the Unified Extensible Firmware Interface (UEFI) specification
154   * for details.
155   *
156   * @time:		pointer to structure to receive current time
157   * @capabilities:	pointer to structure to receive RTC properties
158   * Returns:		status code
159   */
160  static efi_status_t EFIAPI efi_get_time_boottime(
161  			struct efi_time *time,
162  			struct efi_time_cap *capabilities)
163  {
164  #ifdef CONFIG_DM_RTC
165  	efi_status_t ret = EFI_SUCCESS;
166  	int r;
167  	struct rtc_time tm;
168  	struct udevice *dev;
169  
170  	EFI_ENTRY("%p %p", time, capabilities);
171  
172  	if (!time) {
173  		ret = EFI_INVALID_PARAMETER;
174  		goto out;
175  	}
176  
177  	r = uclass_get_device(UCLASS_RTC, 0, &dev);
178  	if (!r)
179  		r = dm_rtc_get(dev, &tm);
180  	if (r) {
181  		ret = EFI_DEVICE_ERROR;
182  		goto out;
183  	}
184  
185  	memset(time, 0, sizeof(*time));
186  	time->year = tm.tm_year;
187  	time->month = tm.tm_mon;
188  	time->day = tm.tm_mday;
189  	time->hour = tm.tm_hour;
190  	time->minute = tm.tm_min;
191  	time->second = tm.tm_sec;
192  	time->daylight = EFI_TIME_ADJUST_DAYLIGHT;
193  	if (tm.tm_isdst > 0)
194  		time->daylight |= EFI_TIME_IN_DAYLIGHT;
195  	time->timezone = EFI_UNSPECIFIED_TIMEZONE;
196  
197  	if (capabilities) {
198  		/* Set reasonable dummy values */
199  		capabilities->resolution = 1;		/* 1 Hz */
200  		capabilities->accuracy = 100000000;	/* 100 ppm */
201  		capabilities->sets_to_zero = false;
202  	}
203  out:
204  	return EFI_EXIT(ret);
205  #else
206  	EFI_ENTRY("%p %p", time, capabilities);
207  	return EFI_EXIT(EFI_DEVICE_ERROR);
208  #endif
209  }
210  
211  
212  /**
213   * efi_reset_system() - reset system
214   *
215   * This function implements the ResetSystem() runtime service after
216   * SetVirtualAddressMap() is called. It only executes an endless loop.
217   * Boards may override the helpers below to implement reset functionality.
218   *
219   * See the Unified Extensible Firmware Interface (UEFI) specification for
220   * details.
221   *
222   * @reset_type:		type of reset to perform
223   * @reset_status:	status code for the reset
224   * @data_size:		size of reset_data
225   * @reset_data:		information about the reset
226   */
227  void __weak __efi_runtime EFIAPI efi_reset_system(
228  			enum efi_reset_type reset_type,
229  			efi_status_t reset_status,
230  			unsigned long data_size, void *reset_data)
231  {
232  	/* Nothing we can do */
233  	while (1) { }
234  }
235  
236  /**
237   * efi_reset_system_init() - initialize the reset driver
238   *
239   * Boards may override this function to initialize the reset driver.
240   */
241  efi_status_t __weak efi_reset_system_init(void)
242  {
243  	return EFI_SUCCESS;
244  }
245  
246  /**
247   * efi_get_time() - get current time
248   *
249   * This function implements the GetTime runtime service after
250   * SetVirtualAddressMap() is called. As the U-Boot driver are not available
251   * anymore only an error code is returned.
252   *
253   * See the Unified Extensible Firmware Interface (UEFI) specification
254   * for details.
255   *
256   * @time:		pointer to structure to receive current time
257   * @capabilities:	pointer to structure to receive RTC properties
258   * Returns:		status code
259   */
260  efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
261  			struct efi_time *time,
262  			struct efi_time_cap *capabilities)
263  {
264  	/* Nothing we can do */
265  	return EFI_DEVICE_ERROR;
266  }
267  
268  struct efi_runtime_detach_list_struct {
269  	void *ptr;
270  	void *patchto;
271  };
272  
273  static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = {
274  	{
275  		/* do_reset is gone */
276  		.ptr = &efi_runtime_services.reset_system,
277  		.patchto = efi_reset_system,
278  	}, {
279  		/* invalidate_*cache_all are gone */
280  		.ptr = &efi_runtime_services.set_virtual_address_map,
281  		.patchto = &efi_invalid_parameter,
282  	}, {
283  		/* RTC accessors are gone */
284  		.ptr = &efi_runtime_services.get_time,
285  		.patchto = &efi_get_time,
286  	}, {
287  		/* Clean up system table */
288  		.ptr = &systab.con_in,
289  		.patchto = NULL,
290  	}, {
291  		/* Clean up system table */
292  		.ptr = &systab.con_out,
293  		.patchto = NULL,
294  	}, {
295  		/* Clean up system table */
296  		.ptr = &systab.std_err,
297  		.patchto = NULL,
298  	}, {
299  		/* Clean up system table */
300  		.ptr = &systab.boottime,
301  		.patchto = NULL,
302  	}, {
303  		.ptr = &efi_runtime_services.get_variable,
304  		.patchto = &efi_device_error,
305  	}, {
306  		.ptr = &efi_runtime_services.get_next_variable_name,
307  		.patchto = &efi_device_error,
308  	}, {
309  		.ptr = &efi_runtime_services.set_variable,
310  		.patchto = &efi_device_error,
311  	}
312  };
313  
314  static bool efi_runtime_tobedetached(void *p)
315  {
316  	int i;
317  
318  	for (i = 0; i < ARRAY_SIZE(efi_runtime_detach_list); i++)
319  		if (efi_runtime_detach_list[i].ptr == p)
320  			return true;
321  
322  	return false;
323  }
324  
325  static void efi_runtime_detach(ulong offset)
326  {
327  	int i;
328  	ulong patchoff = offset - (ulong)gd->relocaddr;
329  
330  	for (i = 0; i < ARRAY_SIZE(efi_runtime_detach_list); i++) {
331  		ulong patchto = (ulong)efi_runtime_detach_list[i].patchto;
332  		ulong *p = efi_runtime_detach_list[i].ptr;
333  		ulong newaddr = patchto ? (patchto + patchoff) : 0;
334  
335  		debug("%s: Setting %p to %lx\n", __func__, p, newaddr);
336  		*p = newaddr;
337  	}
338  
339  	/* Update CRC32 */
340  	efi_update_table_header_crc32(&efi_runtime_services.hdr);
341  }
342  
343  /* Relocate EFI runtime to uboot_reloc_base = offset */
344  void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
345  {
346  #ifdef IS_RELA
347  	struct elf_rela *rel = (void*)&__efi_runtime_rel_start;
348  #else
349  	struct elf_rel *rel = (void*)&__efi_runtime_rel_start;
350  	static ulong lastoff = CONFIG_SYS_TEXT_BASE;
351  #endif
352  
353  	debug("%s: Relocating to offset=%lx\n", __func__, offset);
354  	for (; (ulong)rel < (ulong)&__efi_runtime_rel_stop; rel++) {
355  		ulong base = CONFIG_SYS_TEXT_BASE;
356  		ulong *p;
357  		ulong newaddr;
358  
359  		p = (void*)((ulong)rel->offset - base) + gd->relocaddr;
360  
361  		debug("%s: rel->info=%#lx *p=%#lx rel->offset=%p\n", __func__, rel->info, *p, rel->offset);
362  
363  		switch (rel->info & R_MASK) {
364  		case R_RELATIVE:
365  #ifdef IS_RELA
366  		newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE;
367  #else
368  		newaddr = *p - lastoff + offset;
369  #endif
370  			break;
371  #ifdef R_ABSOLUTE
372  		case R_ABSOLUTE: {
373  			ulong symidx = rel->info >> SYM_INDEX;
374  			extern struct dyn_sym __dyn_sym_start[];
375  			newaddr = __dyn_sym_start[symidx].addr + offset;
376  			break;
377  		}
378  #endif
379  		default:
380  			continue;
381  		}
382  
383  		/* Check if the relocation is inside bounds */
384  		if (map && ((newaddr < map->virtual_start) ||
385  		    newaddr > (map->virtual_start +
386  			      (map->num_pages << EFI_PAGE_SHIFT)))) {
387  			if (!efi_runtime_tobedetached(p))
388  				printf("U-Boot EFI: Relocation at %p is out of "
389  				       "range (%lx)\n", p, newaddr);
390  			continue;
391  		}
392  
393  		debug("%s: Setting %p to %lx\n", __func__, p, newaddr);
394  		*p = newaddr;
395  		flush_dcache_range((ulong)p & ~(EFI_CACHELINE_SIZE - 1),
396  			ALIGN((ulong)&p[1], EFI_CACHELINE_SIZE));
397  	}
398  
399  #ifndef IS_RELA
400  	lastoff = offset;
401  #endif
402  
403          invalidate_icache_all();
404  }
405  
406  /**
407   * efi_set_virtual_address_map() - change from physical to virtual mapping
408   *
409   * This function implements the SetVirtualAddressMap() runtime service.
410   *
411   * See the Unified Extensible Firmware Interface (UEFI) specification for
412   * details.
413   *
414   * @memory_map_size:	size of the virtual map
415   * @descriptor_size:	size of an entry in the map
416   * @descriptor_version:	version of the map entries
417   * @virtmap:		virtual address mapping information
418   * Return:		status code
419   */
420  static efi_status_t EFIAPI efi_set_virtual_address_map(
421  			unsigned long memory_map_size,
422  			unsigned long descriptor_size,
423  			uint32_t descriptor_version,
424  			struct efi_mem_desc *virtmap)
425  {
426  	ulong runtime_start = (ulong)&__efi_runtime_start &
427  			      ~(ulong)EFI_PAGE_MASK;
428  	int n = memory_map_size / descriptor_size;
429  	int i;
430  
431  	EFI_ENTRY("%lx %lx %x %p", memory_map_size, descriptor_size,
432  		  descriptor_version, virtmap);
433  
434  	/* Rebind mmio pointers */
435  	for (i = 0; i < n; i++) {
436  		struct efi_mem_desc *map = (void*)virtmap +
437  					   (descriptor_size * i);
438  		struct list_head *lhandle;
439  		efi_physical_addr_t map_start = map->physical_start;
440  		efi_physical_addr_t map_len = map->num_pages << EFI_PAGE_SHIFT;
441  		efi_physical_addr_t map_end = map_start + map_len;
442  		u64 off = map->virtual_start - map_start;
443  
444  		/* Adjust all mmio pointers in this region */
445  		list_for_each(lhandle, &efi_runtime_mmio) {
446  			struct efi_runtime_mmio_list *lmmio;
447  
448  			lmmio = list_entry(lhandle,
449  					   struct efi_runtime_mmio_list,
450  					   link);
451  			if ((map_start <= lmmio->paddr) &&
452  			    (map_end >= lmmio->paddr)) {
453  				uintptr_t new_addr = lmmio->paddr + off;
454  				*lmmio->ptr = (void *)new_addr;
455  			}
456  		}
457  		if ((map_start <= (uintptr_t)systab.tables) &&
458  		    (map_end >= (uintptr_t)systab.tables)) {
459  			char *ptr = (char *)systab.tables;
460  
461  			ptr += off;
462  			systab.tables = (struct efi_configuration_table *)ptr;
463  		}
464  	}
465  
466  	/* Move the actual runtime code over */
467  	for (i = 0; i < n; i++) {
468  		struct efi_mem_desc *map;
469  
470  		map = (void*)virtmap + (descriptor_size * i);
471  		if (map->type == EFI_RUNTIME_SERVICES_CODE) {
472  			ulong new_offset = map->virtual_start -
473  					   (runtime_start - gd->relocaddr);
474  
475  			efi_runtime_relocate(new_offset, map);
476  			/* Once we're virtual, we can no longer handle
477  			   complex callbacks */
478  			efi_runtime_detach(new_offset);
479  			return EFI_EXIT(EFI_SUCCESS);
480  		}
481  	}
482  
483  	return EFI_EXIT(EFI_INVALID_PARAMETER);
484  }
485  
486  /**
487   * efi_add_runtime_mmio() - add memory-mapped IO region
488   *
489   * This function adds a memory-mapped IO region to the memory map to make it
490   * available at runtime.
491   *
492   * @mmio_ptr:		address of the memory-mapped IO region
493   * @len:		size of the memory-mapped IO region
494   * Returns:		status code
495   */
496  efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len)
497  {
498  	struct efi_runtime_mmio_list *newmmio;
499  	u64 pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
500  	uint64_t addr = *(uintptr_t *)mmio_ptr;
501  	uint64_t retaddr;
502  
503  	retaddr = efi_add_memory_map(addr, pages, EFI_MMAP_IO, false);
504  	if (retaddr != addr)
505  		return EFI_OUT_OF_RESOURCES;
506  
507  	newmmio = calloc(1, sizeof(*newmmio));
508  	if (!newmmio)
509  		return EFI_OUT_OF_RESOURCES;
510  	newmmio->ptr = mmio_ptr;
511  	newmmio->paddr = *(uintptr_t *)mmio_ptr;
512  	newmmio->len = len;
513  	list_add_tail(&newmmio->link, &efi_runtime_mmio);
514  
515  	return EFI_SUCCESS;
516  }
517  
518  /*
519   * In the second stage, U-Boot has disappeared. To isolate our runtime code
520   * that at this point still exists from the rest, we put it into a special
521   * section.
522   *
523   *        !!WARNING!!
524   *
525   * This means that we can not rely on any code outside of this file in any
526   * function or variable below this line.
527   *
528   * Please keep everything fully self-contained and annotated with
529   * __efi_runtime and __efi_runtime_data markers.
530   */
531  
532  /*
533   * Relocate the EFI runtime stub to a different place. We need to call this
534   * the first time we expose the runtime interface to a user and on set virtual
535   * address map calls.
536   */
537  
538  /**
539   * efi_unimplemented() - replacement function, returns EFI_UNSUPPORTED
540   *
541   * This function is used after SetVirtualAddressMap() is called as replacement
542   * for services that are not available anymore due to constraints of the U-Boot
543   * implementation.
544   *
545   * Return:	EFI_UNSUPPORTED
546   */
547  static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void)
548  {
549  	return EFI_UNSUPPORTED;
550  }
551  
552  /**
553   * efi_device_error() - replacement function, returns EFI_DEVICE_ERROR
554   *
555   * This function is used after SetVirtualAddressMap() is called as replacement
556   * for services that are not available anymore due to constraints of the U-Boot
557   * implementation.
558   *
559   * Return:	EFI_DEVICE_ERROR
560   */
561  static efi_status_t __efi_runtime EFIAPI efi_device_error(void)
562  {
563  	return EFI_DEVICE_ERROR;
564  }
565  
566  /**
567   * efi_invalid_parameter() - replacement function, returns EFI_INVALID_PARAMETER
568   *
569   * This function is used after SetVirtualAddressMap() is called as replacement
570   * for services that are not available anymore due to constraints of the U-Boot
571   * implementation.
572   *
573   * Return:	EFI_INVALID_PARAMETER
574   */
575  static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void)
576  {
577  	return EFI_INVALID_PARAMETER;
578  }
579  
580  /**
581   * efi_update_capsule() - process information from operating system
582   *
583   * This function implements the UpdateCapsule() runtime service.
584   *
585   * See the Unified Extensible Firmware Interface (UEFI) specification for
586   * details.
587   *
588   * @capsule_header_array:	pointer to array of virtual pointers
589   * @capsule_count:		number of pointers in capsule_header_array
590   * @scatter_gather_list:	pointer to arry of physical pointers
591   * Returns:			status code
592   */
593  efi_status_t __efi_runtime EFIAPI efi_update_capsule(
594  			struct efi_capsule_header **capsule_header_array,
595  			efi_uintn_t capsule_count,
596  			u64 scatter_gather_list)
597  {
598  	return EFI_UNSUPPORTED;
599  }
600  
601  /**
602   * efi_query_capsule_caps() - check if capsule is supported
603   *
604   * This function implements the QueryCapsuleCapabilities() runtime service.
605   *
606   * See the Unified Extensible Firmware Interface (UEFI) specification for
607   * details.
608   *
609   * @capsule_header_array:	pointer to array of virtual pointers
610   * @capsule_count:		number of pointers in capsule_header_array
611   * @maximum_capsule_size:	maximum capsule size
612   * @reset_type:			type of reset needed for capsule update
613   * Returns:			status code
614   */
615  efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
616  			struct efi_capsule_header **capsule_header_array,
617  			efi_uintn_t capsule_count,
618  			u64 maximum_capsule_size,
619  			u32 reset_type)
620  {
621  	return EFI_UNSUPPORTED;
622  }
623  
624  /**
625   * efi_query_variable_info() - get information about EFI variables
626   *
627   * This function implements the QueryVariableInfo() runtime service.
628   *
629   * See the Unified Extensible Firmware Interface (UEFI) specification for
630   * details.
631   *
632   * @attributes:				bitmask to select variables to be
633   *					queried
634   * @maximum_variable_storage_size:	maximum size of storage area for the
635   *					selected variable types
636   * @remaining_variable_storage_size:	remaining size of storage are for the
637   *					selected variable types
638   * @maximum_variable_size:		maximum size of a variable of the
639   *					selected type
640   * Returns:				status code
641   */
642  efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
643  			u32 attributes,
644  			u64 *maximum_variable_storage_size,
645  			u64 *remaining_variable_storage_size,
646  			u64 *maximum_variable_size)
647  {
648  	return EFI_UNSUPPORTED;
649  }
650  
651  struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
652  	.hdr = {
653  		.signature = EFI_RUNTIME_SERVICES_SIGNATURE,
654  		.revision = EFI_SPECIFICATION_VERSION,
655  		.headersize = sizeof(struct efi_runtime_services),
656  	},
657  	.get_time = &efi_get_time_boottime,
658  	.set_time = (void *)&efi_device_error,
659  	.get_wakeup_time = (void *)&efi_unimplemented,
660  	.set_wakeup_time = (void *)&efi_unimplemented,
661  	.set_virtual_address_map = &efi_set_virtual_address_map,
662  	.convert_pointer = (void *)&efi_invalid_parameter,
663  	.get_variable = efi_get_variable,
664  	.get_next_variable_name = efi_get_next_variable_name,
665  	.set_variable = efi_set_variable,
666  	.get_next_high_mono_count = (void *)&efi_device_error,
667  	.reset_system = &efi_reset_system_boottime,
668  	.update_capsule = efi_update_capsule,
669  	.query_capsule_caps = efi_query_capsule_caps,
670  	.query_variable_info = efi_query_variable_info,
671  };
672