150149ea3SAlexander Graf /*
250149ea3SAlexander Graf * EFI application runtime services
350149ea3SAlexander Graf *
450149ea3SAlexander Graf * Copyright (c) 2016 Alexander Graf
550149ea3SAlexander Graf *
650149ea3SAlexander Graf * SPDX-License-Identifier: GPL-2.0+
750149ea3SAlexander Graf */
850149ea3SAlexander Graf
950149ea3SAlexander Graf #include <common.h>
1050149ea3SAlexander Graf #include <command.h>
1150149ea3SAlexander Graf #include <dm.h>
1250149ea3SAlexander Graf #include <efi_loader.h>
1350149ea3SAlexander Graf #include <rtc.h>
1450149ea3SAlexander Graf #include <asm/global_data.h>
1550149ea3SAlexander Graf
1650149ea3SAlexander Graf /* For manual relocation support */
1750149ea3SAlexander Graf DECLARE_GLOBAL_DATA_PTR;
1850149ea3SAlexander Graf
1980a4800eSAlexander Graf struct efi_runtime_mmio_list {
2080a4800eSAlexander Graf struct list_head link;
2180a4800eSAlexander Graf void **ptr;
2280a4800eSAlexander Graf u64 paddr;
2380a4800eSAlexander Graf u64 len;
2480a4800eSAlexander Graf };
2580a4800eSAlexander Graf
2680a4800eSAlexander Graf /* This list contains all runtime available mmio regions */
2780a4800eSAlexander Graf LIST_HEAD(efi_runtime_mmio);
2880a4800eSAlexander Graf
293c63db9cSAlexander Graf static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void);
303c63db9cSAlexander Graf static efi_status_t __efi_runtime EFIAPI efi_device_error(void);
313c63db9cSAlexander Graf static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
3250149ea3SAlexander Graf
3336c37a84SAlexander Graf #ifdef CONFIG_SYS_CACHELINE_SIZE
3436c37a84SAlexander Graf #define EFI_CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
3536c37a84SAlexander Graf #else
3636c37a84SAlexander Graf /* Just use the greatest cache flush alignment requirement I'm aware of */
3736c37a84SAlexander Graf #define EFI_CACHELINE_SIZE 128
3836c37a84SAlexander Graf #endif
3936c37a84SAlexander Graf
4050149ea3SAlexander Graf #if defined(CONFIG_ARM64)
4150149ea3SAlexander Graf #define R_RELATIVE 1027
4250149ea3SAlexander Graf #define R_MASK 0xffffffffULL
4350149ea3SAlexander Graf #define IS_RELA 1
4450149ea3SAlexander Graf #elif defined(CONFIG_ARM)
4550149ea3SAlexander Graf #define R_RELATIVE 23
4650149ea3SAlexander Graf #define R_MASK 0xffULL
4765e4c0b1SSimon Glass #elif defined(CONFIG_X86)
4865e4c0b1SSimon Glass #include <asm/elf.h>
4965e4c0b1SSimon Glass #define R_RELATIVE R_386_RELATIVE
5065e4c0b1SSimon Glass #define R_MASK 0xffULL
5150149ea3SAlexander Graf #else
5250149ea3SAlexander Graf #error Need to add relocation awareness
5350149ea3SAlexander Graf #endif
5450149ea3SAlexander Graf
5550149ea3SAlexander Graf struct elf_rel {
5650149ea3SAlexander Graf ulong *offset;
5750149ea3SAlexander Graf ulong info;
5850149ea3SAlexander Graf };
5950149ea3SAlexander Graf
6050149ea3SAlexander Graf struct elf_rela {
6150149ea3SAlexander Graf ulong *offset;
6250149ea3SAlexander Graf ulong info;
6350149ea3SAlexander Graf long addend;
6450149ea3SAlexander Graf };
6550149ea3SAlexander Graf
6650149ea3SAlexander Graf /*
6750149ea3SAlexander Graf * EFI Runtime code lives in 2 stages. In the first stage, U-Boot and an EFI
6850149ea3SAlexander Graf * payload are running concurrently at the same time. In this mode, we can
6950149ea3SAlexander Graf * handle a good number of runtime callbacks
7050149ea3SAlexander Graf */
7150149ea3SAlexander Graf
efi_reset_system_boottime(enum efi_reset_type reset_type,efi_status_t reset_status,unsigned long data_size,void * reset_data)7280a4800eSAlexander Graf static void EFIAPI efi_reset_system_boottime(
7380a4800eSAlexander Graf enum efi_reset_type reset_type,
7450149ea3SAlexander Graf efi_status_t reset_status,
7550149ea3SAlexander Graf unsigned long data_size, void *reset_data)
7650149ea3SAlexander Graf {
7750149ea3SAlexander Graf EFI_ENTRY("%d %lx %lx %p", reset_type, reset_status, data_size,
7850149ea3SAlexander Graf reset_data);
7950149ea3SAlexander Graf
8050149ea3SAlexander Graf switch (reset_type) {
8150149ea3SAlexander Graf case EFI_RESET_COLD:
8250149ea3SAlexander Graf case EFI_RESET_WARM:
8350149ea3SAlexander Graf do_reset(NULL, 0, 0, NULL);
8450149ea3SAlexander Graf break;
8550149ea3SAlexander Graf case EFI_RESET_SHUTDOWN:
8650149ea3SAlexander Graf /* We don't have anything to map this to */
8750149ea3SAlexander Graf break;
8850149ea3SAlexander Graf }
8950149ea3SAlexander Graf
9080a4800eSAlexander Graf while (1) { }
9150149ea3SAlexander Graf }
9250149ea3SAlexander Graf
efi_get_time_boottime(struct efi_time * time,struct efi_time_cap * capabilities)9380a4800eSAlexander Graf static efi_status_t EFIAPI efi_get_time_boottime(
9480a4800eSAlexander Graf struct efi_time *time,
9550149ea3SAlexander Graf struct efi_time_cap *capabilities)
9650149ea3SAlexander Graf {
9750149ea3SAlexander Graf #if defined(CONFIG_CMD_DATE) && defined(CONFIG_DM_RTC)
9850149ea3SAlexander Graf struct rtc_time tm;
9950149ea3SAlexander Graf int r;
10050149ea3SAlexander Graf struct udevice *dev;
10150149ea3SAlexander Graf
10250149ea3SAlexander Graf EFI_ENTRY("%p %p", time, capabilities);
10350149ea3SAlexander Graf
10450149ea3SAlexander Graf r = uclass_get_device(UCLASS_RTC, 0, &dev);
10550149ea3SAlexander Graf if (r)
10650149ea3SAlexander Graf return EFI_EXIT(EFI_DEVICE_ERROR);
10750149ea3SAlexander Graf
10850149ea3SAlexander Graf r = dm_rtc_get(dev, &tm);
10950149ea3SAlexander Graf if (r)
11050149ea3SAlexander Graf return EFI_EXIT(EFI_DEVICE_ERROR);
11150149ea3SAlexander Graf
11250149ea3SAlexander Graf memset(time, 0, sizeof(*time));
11350149ea3SAlexander Graf time->year = tm.tm_year;
11450149ea3SAlexander Graf time->month = tm.tm_mon;
11550149ea3SAlexander Graf time->day = tm.tm_mday;
11650149ea3SAlexander Graf time->hour = tm.tm_hour;
11750149ea3SAlexander Graf time->minute = tm.tm_min;
11850149ea3SAlexander Graf time->daylight = tm.tm_isdst;
11950149ea3SAlexander Graf
12050149ea3SAlexander Graf return EFI_EXIT(EFI_SUCCESS);
12150149ea3SAlexander Graf #else
12250149ea3SAlexander Graf return EFI_DEVICE_ERROR;
12350149ea3SAlexander Graf #endif
12450149ea3SAlexander Graf }
12550149ea3SAlexander Graf
12680a4800eSAlexander Graf /* Boards may override the helpers below to implement RTS functionality */
12780a4800eSAlexander Graf
efi_reset_system(enum efi_reset_type reset_type,efi_status_t reset_status,unsigned long data_size,void * reset_data)1283c63db9cSAlexander Graf void __weak __efi_runtime EFIAPI efi_reset_system(
12980a4800eSAlexander Graf enum efi_reset_type reset_type,
13080a4800eSAlexander Graf efi_status_t reset_status,
13180a4800eSAlexander Graf unsigned long data_size, void *reset_data)
13280a4800eSAlexander Graf {
13380a4800eSAlexander Graf /* Nothing we can do */
13480a4800eSAlexander Graf while (1) { }
13580a4800eSAlexander Graf }
13680a4800eSAlexander Graf
efi_reset_system_init(void)13780a4800eSAlexander Graf void __weak efi_reset_system_init(void)
13880a4800eSAlexander Graf {
13980a4800eSAlexander Graf }
14080a4800eSAlexander Graf
efi_get_time(struct efi_time * time,struct efi_time_cap * capabilities)1413c63db9cSAlexander Graf efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
14280a4800eSAlexander Graf struct efi_time *time,
14380a4800eSAlexander Graf struct efi_time_cap *capabilities)
14480a4800eSAlexander Graf {
14580a4800eSAlexander Graf /* Nothing we can do */
14680a4800eSAlexander Graf return EFI_DEVICE_ERROR;
14780a4800eSAlexander Graf }
14880a4800eSAlexander Graf
efi_get_time_init(void)14980a4800eSAlexander Graf void __weak efi_get_time_init(void)
15080a4800eSAlexander Graf {
15180a4800eSAlexander Graf }
15280a4800eSAlexander Graf
15350149ea3SAlexander Graf struct efi_runtime_detach_list_struct {
15450149ea3SAlexander Graf void *ptr;
15550149ea3SAlexander Graf void *patchto;
15650149ea3SAlexander Graf };
15750149ea3SAlexander Graf
15850149ea3SAlexander Graf static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = {
15950149ea3SAlexander Graf {
16050149ea3SAlexander Graf /* do_reset is gone */
16150149ea3SAlexander Graf .ptr = &efi_runtime_services.reset_system,
16280a4800eSAlexander Graf .patchto = efi_reset_system,
16350149ea3SAlexander Graf }, {
16450149ea3SAlexander Graf /* invalidate_*cache_all are gone */
16550149ea3SAlexander Graf .ptr = &efi_runtime_services.set_virtual_address_map,
16650149ea3SAlexander Graf .patchto = &efi_invalid_parameter,
16750149ea3SAlexander Graf }, {
16850149ea3SAlexander Graf /* RTC accessors are gone */
16950149ea3SAlexander Graf .ptr = &efi_runtime_services.get_time,
17080a4800eSAlexander Graf .patchto = &efi_get_time,
171ae874405SAlexander Graf }, {
172ae874405SAlexander Graf /* Clean up system table */
173ae874405SAlexander Graf .ptr = &systab.con_in,
174ae874405SAlexander Graf .patchto = NULL,
175ae874405SAlexander Graf }, {
176ae874405SAlexander Graf /* Clean up system table */
177ae874405SAlexander Graf .ptr = &systab.con_out,
178ae874405SAlexander Graf .patchto = NULL,
179ae874405SAlexander Graf }, {
180ae874405SAlexander Graf /* Clean up system table */
181ae874405SAlexander Graf .ptr = &systab.std_err,
182ae874405SAlexander Graf .patchto = NULL,
183ae874405SAlexander Graf }, {
184ae874405SAlexander Graf /* Clean up system table */
185ae874405SAlexander Graf .ptr = &systab.boottime,
186ae874405SAlexander Graf .patchto = NULL,
18750149ea3SAlexander Graf },
18850149ea3SAlexander Graf };
18950149ea3SAlexander Graf
efi_runtime_tobedetached(void * p)19050149ea3SAlexander Graf static bool efi_runtime_tobedetached(void *p)
19150149ea3SAlexander Graf {
19250149ea3SAlexander Graf int i;
19350149ea3SAlexander Graf
19450149ea3SAlexander Graf for (i = 0; i < ARRAY_SIZE(efi_runtime_detach_list); i++)
19550149ea3SAlexander Graf if (efi_runtime_detach_list[i].ptr == p)
19650149ea3SAlexander Graf return true;
19750149ea3SAlexander Graf
19850149ea3SAlexander Graf return false;
19950149ea3SAlexander Graf }
20050149ea3SAlexander Graf
efi_runtime_detach(ulong offset)20150149ea3SAlexander Graf static void efi_runtime_detach(ulong offset)
20250149ea3SAlexander Graf {
20350149ea3SAlexander Graf int i;
20450149ea3SAlexander Graf ulong patchoff = offset - (ulong)gd->relocaddr;
20550149ea3SAlexander Graf
20650149ea3SAlexander Graf for (i = 0; i < ARRAY_SIZE(efi_runtime_detach_list); i++) {
20750149ea3SAlexander Graf ulong patchto = (ulong)efi_runtime_detach_list[i].patchto;
20850149ea3SAlexander Graf ulong *p = efi_runtime_detach_list[i].ptr;
20950149ea3SAlexander Graf ulong newaddr = patchto ? (patchto + patchoff) : 0;
21050149ea3SAlexander Graf
211edcef3baSAlexander Graf debug("%s: Setting %p to %lx\n", __func__, p, newaddr);
21250149ea3SAlexander Graf *p = newaddr;
21350149ea3SAlexander Graf }
21450149ea3SAlexander Graf }
21550149ea3SAlexander Graf
21650149ea3SAlexander Graf /* Relocate EFI runtime to uboot_reloc_base = offset */
efi_runtime_relocate(ulong offset,struct efi_mem_desc * map)21750149ea3SAlexander Graf void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
21850149ea3SAlexander Graf {
21950149ea3SAlexander Graf #ifdef IS_RELA
22050149ea3SAlexander Graf struct elf_rela *rel = (void*)&__efi_runtime_rel_start;
22150149ea3SAlexander Graf #else
22250149ea3SAlexander Graf struct elf_rel *rel = (void*)&__efi_runtime_rel_start;
22350149ea3SAlexander Graf static ulong lastoff = CONFIG_SYS_TEXT_BASE;
22450149ea3SAlexander Graf #endif
22550149ea3SAlexander Graf
226edcef3baSAlexander Graf debug("%s: Relocating to offset=%lx\n", __func__, offset);
22750149ea3SAlexander Graf for (; (ulong)rel < (ulong)&__efi_runtime_rel_stop; rel++) {
22850149ea3SAlexander Graf ulong base = CONFIG_SYS_TEXT_BASE;
22950149ea3SAlexander Graf ulong *p;
23050149ea3SAlexander Graf ulong newaddr;
23150149ea3SAlexander Graf
23250149ea3SAlexander Graf p = (void*)((ulong)rel->offset - base) + gd->relocaddr;
23350149ea3SAlexander Graf
23450149ea3SAlexander Graf if ((rel->info & R_MASK) != R_RELATIVE) {
23550149ea3SAlexander Graf continue;
23650149ea3SAlexander Graf }
23750149ea3SAlexander Graf
23850149ea3SAlexander Graf #ifdef IS_RELA
23950149ea3SAlexander Graf newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE;
24050149ea3SAlexander Graf #else
24150149ea3SAlexander Graf newaddr = *p - lastoff + offset;
24250149ea3SAlexander Graf #endif
24350149ea3SAlexander Graf
24450149ea3SAlexander Graf /* Check if the relocation is inside bounds */
24550149ea3SAlexander Graf if (map && ((newaddr < map->virtual_start) ||
24650149ea3SAlexander Graf newaddr > (map->virtual_start + (map->num_pages << 12)))) {
24750149ea3SAlexander Graf if (!efi_runtime_tobedetached(p))
24850149ea3SAlexander Graf printf("U-Boot EFI: Relocation at %p is out of "
24950149ea3SAlexander Graf "range (%lx)\n", p, newaddr);
25050149ea3SAlexander Graf continue;
25150149ea3SAlexander Graf }
25250149ea3SAlexander Graf
253edcef3baSAlexander Graf debug("%s: Setting %p to %lx\n", __func__, p, newaddr);
25450149ea3SAlexander Graf *p = newaddr;
25536c37a84SAlexander Graf flush_dcache_range((ulong)p & ~(EFI_CACHELINE_SIZE - 1),
25636c37a84SAlexander Graf ALIGN((ulong)&p[1], EFI_CACHELINE_SIZE));
25750149ea3SAlexander Graf }
25850149ea3SAlexander Graf
25950149ea3SAlexander Graf #ifndef IS_RELA
26050149ea3SAlexander Graf lastoff = offset;
26150149ea3SAlexander Graf #endif
26250149ea3SAlexander Graf
26350149ea3SAlexander Graf invalidate_icache_all();
26450149ea3SAlexander Graf }
26550149ea3SAlexander Graf
efi_set_virtual_address_map(unsigned long memory_map_size,unsigned long descriptor_size,uint32_t descriptor_version,struct efi_mem_desc * virtmap)26650149ea3SAlexander Graf static efi_status_t EFIAPI efi_set_virtual_address_map(
26750149ea3SAlexander Graf unsigned long memory_map_size,
26850149ea3SAlexander Graf unsigned long descriptor_size,
26950149ea3SAlexander Graf uint32_t descriptor_version,
27050149ea3SAlexander Graf struct efi_mem_desc *virtmap)
27150149ea3SAlexander Graf {
27250149ea3SAlexander Graf ulong runtime_start = (ulong)&__efi_runtime_start & ~0xfffULL;
27350149ea3SAlexander Graf int n = memory_map_size / descriptor_size;
27450149ea3SAlexander Graf int i;
27550149ea3SAlexander Graf
27650149ea3SAlexander Graf EFI_ENTRY("%lx %lx %x %p", memory_map_size, descriptor_size,
27750149ea3SAlexander Graf descriptor_version, virtmap);
27850149ea3SAlexander Graf
27980a4800eSAlexander Graf /* Rebind mmio pointers */
28080a4800eSAlexander Graf for (i = 0; i < n; i++) {
28180a4800eSAlexander Graf struct efi_mem_desc *map = (void*)virtmap +
28280a4800eSAlexander Graf (descriptor_size * i);
28380a4800eSAlexander Graf struct list_head *lhandle;
28480a4800eSAlexander Graf efi_physical_addr_t map_start = map->physical_start;
28580a4800eSAlexander Graf efi_physical_addr_t map_len = map->num_pages << EFI_PAGE_SHIFT;
28680a4800eSAlexander Graf efi_physical_addr_t map_end = map_start + map_len;
28780a4800eSAlexander Graf
28880a4800eSAlexander Graf /* Adjust all mmio pointers in this region */
28980a4800eSAlexander Graf list_for_each(lhandle, &efi_runtime_mmio) {
29080a4800eSAlexander Graf struct efi_runtime_mmio_list *lmmio;
29180a4800eSAlexander Graf
29280a4800eSAlexander Graf lmmio = list_entry(lhandle,
29380a4800eSAlexander Graf struct efi_runtime_mmio_list,
29480a4800eSAlexander Graf link);
29580a4800eSAlexander Graf if ((map_start <= lmmio->paddr) &&
29680a4800eSAlexander Graf (map_end >= lmmio->paddr)) {
29780a4800eSAlexander Graf u64 off = map->virtual_start - map_start;
29880a4800eSAlexander Graf uintptr_t new_addr = lmmio->paddr + off;
29980a4800eSAlexander Graf *lmmio->ptr = (void *)new_addr;
30080a4800eSAlexander Graf }
30180a4800eSAlexander Graf }
30280a4800eSAlexander Graf }
30380a4800eSAlexander Graf
30480a4800eSAlexander Graf /* Move the actual runtime code over */
30550149ea3SAlexander Graf for (i = 0; i < n; i++) {
30650149ea3SAlexander Graf struct efi_mem_desc *map;
30750149ea3SAlexander Graf
30850149ea3SAlexander Graf map = (void*)virtmap + (descriptor_size * i);
30950149ea3SAlexander Graf if (map->type == EFI_RUNTIME_SERVICES_CODE) {
31080a4800eSAlexander Graf ulong new_offset = map->virtual_start -
31180a4800eSAlexander Graf (runtime_start - gd->relocaddr);
31250149ea3SAlexander Graf
31350149ea3SAlexander Graf efi_runtime_relocate(new_offset, map);
31450149ea3SAlexander Graf /* Once we're virtual, we can no longer handle
31550149ea3SAlexander Graf complex callbacks */
31650149ea3SAlexander Graf efi_runtime_detach(new_offset);
31750149ea3SAlexander Graf return EFI_EXIT(EFI_SUCCESS);
31850149ea3SAlexander Graf }
31950149ea3SAlexander Graf }
32050149ea3SAlexander Graf
32150149ea3SAlexander Graf return EFI_EXIT(EFI_INVALID_PARAMETER);
32250149ea3SAlexander Graf }
32350149ea3SAlexander Graf
efi_add_runtime_mmio(void * mmio_ptr,u64 len)32480a4800eSAlexander Graf void efi_add_runtime_mmio(void *mmio_ptr, u64 len)
32580a4800eSAlexander Graf {
32680a4800eSAlexander Graf struct efi_runtime_mmio_list *newmmio;
32780a4800eSAlexander Graf
328*aee4f06dSxypron.glpk@gmx.de u64 pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
32980a4800eSAlexander Graf efi_add_memory_map(*(uintptr_t *)mmio_ptr, pages, EFI_MMAP_IO, false);
33080a4800eSAlexander Graf
33180a4800eSAlexander Graf newmmio = calloc(1, sizeof(*newmmio));
33280a4800eSAlexander Graf newmmio->ptr = mmio_ptr;
33380a4800eSAlexander Graf newmmio->paddr = *(uintptr_t *)mmio_ptr;
33480a4800eSAlexander Graf newmmio->len = len;
33580a4800eSAlexander Graf list_add_tail(&newmmio->link, &efi_runtime_mmio);
33680a4800eSAlexander Graf }
33780a4800eSAlexander Graf
33850149ea3SAlexander Graf /*
33950149ea3SAlexander Graf * In the second stage, U-Boot has disappeared. To isolate our runtime code
34050149ea3SAlexander Graf * that at this point still exists from the rest, we put it into a special
34150149ea3SAlexander Graf * section.
34250149ea3SAlexander Graf *
34350149ea3SAlexander Graf * !!WARNING!!
34450149ea3SAlexander Graf *
34550149ea3SAlexander Graf * This means that we can not rely on any code outside of this file in any
34650149ea3SAlexander Graf * function or variable below this line.
34750149ea3SAlexander Graf *
34850149ea3SAlexander Graf * Please keep everything fully self-contained and annotated with
3493c63db9cSAlexander Graf * __efi_runtime and __efi_runtime_data markers.
35050149ea3SAlexander Graf */
35150149ea3SAlexander Graf
35250149ea3SAlexander Graf /*
35350149ea3SAlexander Graf * Relocate the EFI runtime stub to a different place. We need to call this
35450149ea3SAlexander Graf * the first time we expose the runtime interface to a user and on set virtual
35550149ea3SAlexander Graf * address map calls.
35650149ea3SAlexander Graf */
35750149ea3SAlexander Graf
efi_unimplemented(void)3583c63db9cSAlexander Graf static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void)
35950149ea3SAlexander Graf {
36050149ea3SAlexander Graf return EFI_UNSUPPORTED;
36150149ea3SAlexander Graf }
36250149ea3SAlexander Graf
efi_device_error(void)3633c63db9cSAlexander Graf static efi_status_t __efi_runtime EFIAPI efi_device_error(void)
36450149ea3SAlexander Graf {
36550149ea3SAlexander Graf return EFI_DEVICE_ERROR;
36650149ea3SAlexander Graf }
36750149ea3SAlexander Graf
efi_invalid_parameter(void)3683c63db9cSAlexander Graf static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void)
36950149ea3SAlexander Graf {
37050149ea3SAlexander Graf return EFI_INVALID_PARAMETER;
37150149ea3SAlexander Graf }
37250149ea3SAlexander Graf
3733c63db9cSAlexander Graf struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
37450149ea3SAlexander Graf .hdr = {
37550149ea3SAlexander Graf .signature = EFI_RUNTIME_SERVICES_SIGNATURE,
37650149ea3SAlexander Graf .revision = EFI_RUNTIME_SERVICES_REVISION,
37750149ea3SAlexander Graf .headersize = sizeof(struct efi_table_hdr),
37850149ea3SAlexander Graf },
37980a4800eSAlexander Graf .get_time = &efi_get_time_boottime,
38050149ea3SAlexander Graf .set_time = (void *)&efi_device_error,
38150149ea3SAlexander Graf .get_wakeup_time = (void *)&efi_unimplemented,
38250149ea3SAlexander Graf .set_wakeup_time = (void *)&efi_unimplemented,
38350149ea3SAlexander Graf .set_virtual_address_map = &efi_set_virtual_address_map,
38450149ea3SAlexander Graf .convert_pointer = (void *)&efi_invalid_parameter,
38550149ea3SAlexander Graf .get_variable = (void *)&efi_device_error,
38650149ea3SAlexander Graf .get_next_variable = (void *)&efi_device_error,
38750149ea3SAlexander Graf .set_variable = (void *)&efi_device_error,
38850149ea3SAlexander Graf .get_next_high_mono_count = (void *)&efi_device_error,
38980a4800eSAlexander Graf .reset_system = &efi_reset_system_boottime,
39050149ea3SAlexander Graf };
391