Home | History | Annotate | Line # | Download | only in x86
      1 /*	$NetBSD: efi_machdep.c,v 1.6 2023/05/22 16:28:07 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2016 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: efi_machdep.c,v 1.6 2023/05/22 16:28:07 riastradh Exp $");
     31 
     32 #include "efi.h"
     33 #include "opt_efi.h"
     34 
     35 #include <sys/kmem.h>
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/uuid.h>
     39 
     40 #include <uvm/uvm_extern.h>
     41 
     42 #include <machine/bootinfo.h>
     43 #include <machine/pmap_private.h>
     44 
     45 #include <x86/bus_defs.h>
     46 #include <x86/bus_funcs.h>
     47 #include <x86/efi.h>
     48 #include <x86/fpu.h>
     49 
     50 #include <dev/mm.h>
     51 #if NPCI > 0
     52 #include <dev/pci/pcivar.h> /* for pci_mapreg_map_enable_decode */
     53 #endif
     54 
     55 const struct uuid EFI_UUID_ACPI20 = EFI_TABLE_ACPI20;
     56 const struct uuid EFI_UUID_ACPI10 = EFI_TABLE_ACPI10;
     57 const struct uuid EFI_UUID_SMBIOS = EFI_TABLE_SMBIOS;
     58 const struct uuid EFI_UUID_SMBIOS3 = EFI_TABLE_SMBIOS3;
     59 
     60 static vaddr_t	efi_getva(paddr_t);
     61 static void	efi_relva(paddr_t, vaddr_t);
     62 struct efi_cfgtbl *efi_getcfgtblhead(void);
     63 void		efi_aprintcfgtbl(void);
     64 void		efi_aprintuuid(const struct uuid *);
     65 bool		efi_uuideq(const struct uuid *, const struct uuid *);
     66 
     67 static bool efi_is32x64 = false;
     68 static paddr_t efi_systbl_pa;
     69 static struct efi_systbl *efi_systbl_va = NULL;
     70 static struct efi_cfgtbl *efi_cfgtblhead_va = NULL;
     71 static struct efi_e820memmap {
     72 	struct btinfo_memmap bim;
     73 	struct bi_memmap_entry entry[VM_PHYSSEG_MAX - 1];
     74 } efi_e820memmap;
     75 
     76 #ifdef EFI_RUNTIME
     77 
     78 #include <dev/efivar.h>
     79 
     80 #include <uvm/uvm_extern.h>
     81 
     82 #if !(NEFI > 0)
     83 #error options EFI_RUNTIME makes no sense without pseudo-device efi.
     84 #endif
     85 
     86 struct pmap *efi_runtime_pmap __read_mostly;
     87 
     88 static kmutex_t efi_runtime_lock __cacheline_aligned;
     89 static struct efi_rt efi_rt __read_mostly;
     90 static struct efi_ops efi_runtime_ops __read_mostly;
     91 
     92 static void efi_runtime_init(void);
     93 
     94 #endif
     95 
     96 /*
     97  * Map a physical address (PA) to a newly allocated virtual address (VA).
     98  * The VA must be freed using efi_relva().
     99  */
    100 static vaddr_t
    101 efi_getva(paddr_t pa)
    102 {
    103 	vaddr_t va;
    104 	int rv;
    105 
    106 	rv = _x86_memio_map(x86_bus_space_mem, pa,
    107 	    PAGE_SIZE, 0, (bus_space_handle_t *)&va);
    108 	if (rv != 0) {
    109 		aprint_debug("efi: unable to allocate va\n");
    110 		return 0;
    111 	}
    112 
    113 	return va;
    114 }
    115 
    116 /*
    117  * Free a virtual address (VA) allocated using efi_getva().
    118  */
    119 static void
    120 efi_relva(paddr_t pa, vaddr_t va)
    121 {
    122 	(void)_x86_memio_unmap(x86_bus_space_mem, (bus_space_handle_t)va,
    123 	    PAGE_SIZE, NULL);
    124 }
    125 
    126 /*
    127  * Test if 2 UUIDs matches.
    128  */
    129 bool
    130 efi_uuideq(const struct uuid * a, const struct uuid * b)
    131 {
    132 	return !memcmp(a, b, sizeof(struct uuid));
    133 }
    134 
    135 /*
    136  * Print an UUID in a human-readable manner.
    137  */
    138 void
    139 efi_aprintuuid(const struct uuid * uuid)
    140 {
    141 	int i;
    142 
    143 	aprint_debug(" %08" PRIx32 "", uuid->time_low);
    144 	aprint_debug("-%04" PRIx16 "", uuid->time_mid);
    145 	aprint_debug("-%04" PRIx16 "", uuid->time_hi_and_version);
    146 	aprint_debug("-%02" PRIx8 "", uuid->clock_seq_hi_and_reserved);
    147 	aprint_debug("%02" PRIx8 "", uuid->clock_seq_low);
    148 	aprint_debug("-");
    149 	for (i = 0; i < _UUID_NODE_LEN; i++) {
    150 		aprint_debug("%02" PRIx8 "", uuid->node[i]);
    151 	}
    152 	/* If known, also print the human-readable name */
    153 	if (efi_uuideq(uuid, &EFI_UUID_ACPI20)) {
    154 		aprint_debug(" ACPI 2.0");
    155 	} else if (efi_uuideq(uuid, &EFI_UUID_ACPI10)) {
    156 		aprint_debug(" ACPI 1.0");
    157 	} else if (efi_uuideq(uuid, &EFI_UUID_SMBIOS)) {
    158 		aprint_debug(" SMBIOS");
    159 	} else if (efi_uuideq(uuid, &EFI_UUID_SMBIOS3)) {
    160 		aprint_debug(" SMBIOS3");
    161 	}
    162 }
    163 
    164 /*
    165  * Return the VA of the cfgtbl. Must be freed using efi_relva().
    166  */
    167 struct efi_cfgtbl *
    168 efi_getcfgtblhead(void)
    169 {
    170 	paddr_t	pa;
    171 	vaddr_t	va;
    172 
    173 	if (efi_cfgtblhead_va != NULL)
    174 		return efi_cfgtblhead_va;
    175 
    176 	if (efi_is32x64) {
    177 #if defined(__amd64__)
    178 		struct efi_systbl32 *systbl32 = (void *) efi_systbl_va;
    179 		pa = systbl32->st_cfgtbl;
    180 #elif defined(__i386__)
    181 		struct efi_systbl64 *systbl64 = (void *) efi_systbl_va;
    182 		if (systbl64->st_cfgtbl & 0xffffffff00000000ULL)
    183 			return NULL;
    184 		pa = (paddr_t) systbl64->st_cfgtbl;
    185 #endif
    186 	} else
    187 		pa = (paddr_t)(u_long) efi_systbl_va->st_cfgtbl;
    188 	aprint_debug("efi: cfgtbl at pa %" PRIxPADDR "\n", pa);
    189 	va = efi_getva(pa);
    190 	aprint_debug("efi: cfgtbl mapped at va %" PRIxVADDR "\n", va);
    191 	efi_cfgtblhead_va = (struct efi_cfgtbl *) va;
    192 	efi_aprintcfgtbl();
    193 
    194 	return efi_cfgtblhead_va;
    195 }
    196 
    197 /*
    198  * Print the config tables.
    199  */
    200 void
    201 efi_aprintcfgtbl(void)
    202 {
    203 	struct efi_cfgtbl *ct;
    204 	unsigned long count;
    205 
    206 	if (efi_is32x64) {
    207 #if defined(__amd64__)
    208 		struct efi_systbl32 *systbl32 = (void *) efi_systbl_va;
    209 		struct efi_cfgtbl32 *ct32 = (void *) efi_cfgtblhead_va;
    210 
    211 		count = systbl32->st_entries;
    212 		aprint_debug("efi: %lu cfgtbl entries:\n", count);
    213 		for (; count; count--, ct32++) {
    214 			aprint_debug("efi: %08" PRIx32, ct32->ct_data);
    215 			efi_aprintuuid(&ct32->ct_uuid);
    216 			aprint_debug("\n");
    217 		}
    218 #elif defined(__i386__)
    219 		struct efi_systbl64 *systbl64 = (void *) efi_systbl_va;
    220 		struct efi_cfgtbl64 *ct64 = (void *) efi_cfgtblhead_va;
    221 		uint64_t count64 = systbl64->st_entries;
    222 
    223 		aprint_debug("efi: %" PRIu64 " cfgtbl entries:\n", count64);
    224 		for (; count64; count64--, ct64++) {
    225 			aprint_debug("efi: %016" PRIx64, ct64->ct_data);
    226 			efi_aprintuuid(&ct64->ct_uuid);
    227 			aprint_debug("\n");
    228 		}
    229 #endif
    230 		return;
    231 	}
    232 
    233 	ct = efi_cfgtblhead_va;
    234 	count = efi_systbl_va->st_entries;
    235 	aprint_debug("efi: %lu cfgtbl entries:\n", count);
    236 	for (; count; count--, ct++) {
    237 		aprint_debug("efi: %p", ct->ct_data);
    238 		efi_aprintuuid(&ct->ct_uuid);
    239 		aprint_debug("\n");
    240 	}
    241 }
    242 
    243 /*
    244  * Return the VA of the config table with the given UUID if found.
    245  * The VA must be freed using efi_relva().
    246  */
    247 void *
    248 efi_getcfgtbl(const struct uuid * uuid)
    249 {
    250 	paddr_t pa;
    251 	vaddr_t va;
    252 
    253 	pa = efi_getcfgtblpa(uuid);
    254 	if (pa == 0)
    255 		return NULL;
    256 	va = efi_getva(pa);
    257 	return (void *) va;
    258 }
    259 
    260 /*
    261  * Return the PA of the first config table.
    262  */
    263 paddr_t
    264 efi_getcfgtblpa(const struct uuid * uuid)
    265 {
    266 	struct efi_cfgtbl *ct;
    267 	unsigned long count;
    268 
    269 	if (efi_is32x64) {
    270 #if defined(__amd64__)
    271 		struct efi_systbl32 *systbl32 = (void *) efi_systbl_va;
    272 		struct efi_cfgtbl32 *ct32 = (void *) efi_cfgtblhead_va;
    273 
    274 		count = systbl32->st_entries;
    275 		for (; count; count--, ct32++)
    276 			if (efi_uuideq(&ct32->ct_uuid, uuid))
    277 				return ct32->ct_data;
    278 #elif defined(__i386__)
    279 		struct efi_systbl64 *systbl64 = (void *) efi_systbl_va;
    280 		struct efi_cfgtbl64 *ct64 = (void *) efi_cfgtblhead_va;
    281 		uint64_t count64 = systbl64->st_entries;
    282 
    283 		for (; count64; count64--, ct64++)
    284 			if (efi_uuideq(&ct64->ct_uuid, uuid))
    285 				if (!(ct64->ct_data & 0xffffffff00000000ULL))
    286 					return ct64->ct_data;
    287 #endif
    288 		return 0;	/* Not found. */
    289 	}
    290 
    291 	ct = efi_cfgtblhead_va;
    292 	count = efi_systbl_va->st_entries;
    293 	for (; count; count--, ct++)
    294 		if (efi_uuideq(&ct->ct_uuid, uuid))
    295 			return (paddr_t)(u_long) ct->ct_data;
    296 
    297 	return 0;	/* Not found. */
    298 }
    299 
    300 /* Return the PA of the EFI System Table. */
    301 paddr_t
    302 efi_getsystblpa(void)
    303 {
    304 	struct btinfo_efi *bi;
    305 	paddr_t	pa;
    306 
    307 	bi = lookup_bootinfo(BTINFO_EFI);
    308 	if (bi == NULL) {
    309 		/* Unable to locate the EFI System Table. */
    310 		return 0;
    311 	}
    312 	if (sizeof(paddr_t) == 4 &&	/* XXX i386 with PAE */
    313 	    (bi->systblpa & 0xffffffff00000000ULL)) {
    314 		/* Unable to access EFI System Table. */
    315 		return 0;
    316 	}
    317 	if (bi->common.len > 16 && (bi->flags & BI_EFI_32BIT)) {
    318 		/* boot from 32bit UEFI */
    319 #if defined(__amd64__)
    320 		efi_is32x64 = true;
    321 #endif
    322 	} else {
    323 		/* boot from 64bit UEFI */
    324 #if defined(__i386__)
    325 		efi_is32x64 = true;
    326 #endif
    327 	}
    328 	pa = (paddr_t) bi->systblpa;
    329 	return pa;
    330 }
    331 
    332 /*
    333  * Return a pointer to the EFI System Table. The pointer must be freed using
    334  * efi_relva().
    335  */
    336 struct efi_systbl *
    337 efi_getsystbl(void)
    338 {
    339 	paddr_t pa;
    340 	vaddr_t va;
    341 	struct efi_systbl *systbl;
    342 
    343 	if (efi_systbl_va)
    344 		return efi_systbl_va;
    345 
    346 	pa = efi_getsystblpa();
    347 	if (pa == 0)
    348 		return NULL;
    349 
    350 	aprint_normal("efi: systbl at pa %" PRIxPADDR "\n", pa);
    351 	efi_systbl_pa = pa;
    352 	va = efi_getva(pa);
    353 	aprint_debug("efi: systbl mapped at va %" PRIxVADDR "\n", va);
    354 
    355 	if (efi_is32x64) {
    356 #if defined(__amd64__)
    357 		struct efi_systbl32 *systbl32 = (struct efi_systbl32 *) va;
    358 
    359 		/* XXX Check the signature and the CRC32 */
    360 		aprint_debug("efi: signature %" PRIx64 " revision %" PRIx32
    361 		    " crc32 %" PRIx32 "\n", systbl32->st_hdr.th_sig,
    362 		    systbl32->st_hdr.th_rev, systbl32->st_hdr.th_crc32);
    363 		aprint_debug("efi: firmware revision %" PRIx32 "\n",
    364 		    systbl32->st_fwrev);
    365 		/*
    366 		 * XXX Also print fwvendor, which is an UCS-2 string (use
    367 		 * some UTF-16 routine?)
    368 		 */
    369 		aprint_debug("efi: runtime services at pa 0x%08" PRIx32 "\n",
    370 		    systbl32->st_rt);
    371 		aprint_debug("efi: boot services at pa 0x%08" PRIx32 "\n",
    372 		    systbl32->st_bs);
    373 
    374 		efi_systbl_va = (struct efi_systbl *) systbl32;
    375 #elif defined(__i386__)
    376 		struct efi_systbl64 *systbl64 = (struct efi_systbl64 *) va;
    377 
    378 		/* XXX Check the signature and the CRC32 */
    379 		aprint_debug("efi: signature %" PRIx64 " revision %" PRIx32
    380 		    " crc32 %" PRIx32 "\n", systbl64->st_hdr.th_sig,
    381 		    systbl64->st_hdr.th_rev, systbl64->st_hdr.th_crc32);
    382 		aprint_debug("efi: firmware revision %" PRIx32 "\n",
    383 		    systbl64->st_fwrev);
    384 		/*
    385 		 * XXX Also print fwvendor, which is an UCS-2 string (use
    386 		 * some UTF-16 routine?)
    387 		 */
    388 		aprint_debug("efi: runtime services at pa 0x%016" PRIx64 "\n",
    389 		    systbl64->st_rt);
    390 		aprint_debug("efi: boot services at pa 0x%016" PRIx64 "\n",
    391 		    systbl64->st_bs);
    392 
    393 		efi_systbl_va = (struct efi_systbl *) systbl64;
    394 #endif
    395 		return efi_systbl_va;
    396 	}
    397 
    398 	systbl = (struct efi_systbl *) va;
    399 	/* XXX Check the signature and the CRC32 */
    400 	aprint_debug("efi: signature %" PRIx64 " revision %" PRIx32
    401 	    " crc32 %" PRIx32 "\n", systbl->st_hdr.th_sig,
    402 	    systbl->st_hdr.th_rev, systbl->st_hdr.th_crc32);
    403 	aprint_debug("efi: firmware revision %" PRIx32 "\n", systbl->st_fwrev);
    404 	/*
    405 	 * XXX Also print fwvendor, which is an UCS-2 string (use
    406 	 * some UTF-16 routine?)
    407 	 */
    408 	aprint_debug("efi: runtime services at pa %p\n", systbl->st_rt);
    409 	aprint_debug("efi: boot services at pa %p\n", systbl->st_bs);
    410 
    411 	efi_systbl_va = systbl;
    412 	return efi_systbl_va;
    413 }
    414 
    415 /*
    416  * EFI is available if we are able to locate the EFI System Table.
    417  */
    418 void
    419 efi_init(void)
    420 {
    421 
    422 	if (efi_getsystbl() == NULL) {
    423 		aprint_debug("efi: missing or invalid systbl\n");
    424 		bootmethod_efi = false;
    425 		return;
    426 	}
    427 	if (efi_getcfgtblhead() == NULL) {
    428 		aprint_debug("efi: missing or invalid cfgtbl\n");
    429 		efi_relva(efi_systbl_pa, (vaddr_t) efi_systbl_va);
    430 		bootmethod_efi = false;
    431 		return;
    432 	}
    433 	bootmethod_efi = true;
    434 #if NPCI > 0
    435 	pci_mapreg_map_enable_decode = true; /* PR port-amd64/53286 */
    436 #endif
    437 
    438 #ifdef EFI_RUNTIME
    439 	efi_runtime_init();
    440 #endif
    441 }
    442 
    443 bool
    444 efi_probe(void)
    445 {
    446 
    447 	return bootmethod_efi;
    448 }
    449 
    450 int
    451 efi_getbiosmemtype(uint32_t type, uint64_t attr)
    452 {
    453 
    454 	switch (type) {
    455 	case EFI_MD_TYPE_CODE:
    456 	case EFI_MD_TYPE_DATA:
    457 	case EFI_MD_TYPE_BS_CODE:
    458 	case EFI_MD_TYPE_BS_DATA:
    459 	case EFI_MD_TYPE_FREE:
    460 		return (attr & EFI_MD_ATTR_WB) ? BIM_Memory : BIM_Reserved;
    461 
    462 	case EFI_MD_TYPE_RECLAIM:
    463 		return BIM_ACPI;
    464 
    465 	case EFI_MD_TYPE_FIRMWARE:
    466 		return BIM_NVS;
    467 
    468 	case EFI_MD_TYPE_PMEM:
    469 		return BIM_PMEM;
    470 
    471 	case EFI_MD_TYPE_NULL:
    472 	case EFI_MD_TYPE_RT_CODE:
    473 	case EFI_MD_TYPE_RT_DATA:
    474 	case EFI_MD_TYPE_BAD:
    475 	case EFI_MD_TYPE_IOMEM:
    476 	case EFI_MD_TYPE_IOPORT:
    477 	case EFI_MD_TYPE_PALCODE:
    478 	default:
    479 		return BIM_Reserved;
    480 	}
    481 }
    482 
    483 const char *
    484 efi_getmemtype_str(uint32_t type)
    485 {
    486 	static const char *efimemtypes[] = {
    487 		"Reserved",
    488 		"LoaderCode",
    489 		"LoaderData",
    490 		"BootServicesCode",
    491 		"BootServicesData",
    492 		"RuntimeServicesCode",
    493 		"RuntimeServicesData",
    494 		"ConventionalMemory",
    495 		"UnusableMemory",
    496 		"ACPIReclaimMemory",
    497 		"ACPIMemoryNVS",
    498 		"MemoryMappedIO",
    499 		"MemoryMappedIOPortSpace",
    500 		"PalCode",
    501 		"PersistentMemory",
    502 	};
    503 
    504 	if (type < __arraycount(efimemtypes))
    505 		return efimemtypes[type];
    506 	return "unknown";
    507 }
    508 
    509 struct btinfo_memmap *
    510 efi_get_e820memmap(void)
    511 {
    512 	struct btinfo_efimemmap *efimm;
    513 	struct bi_memmap_entry *entry;
    514 	struct efi_md *md;
    515 	uint64_t addr, size;
    516 	uint64_t start_addr = 0;        /* XXX gcc -Os: maybe-uninitialized */
    517 	uint64_t end_addr = 0;          /* XXX gcc -Os: maybe-uninitialized */
    518 	uint32_t i;
    519 	int n, type, seg_type = -1;
    520 
    521 	if (efi_e820memmap.bim.common.type == BTINFO_MEMMAP)
    522 		return &efi_e820memmap.bim;
    523 
    524 	efimm = lookup_bootinfo(BTINFO_EFIMEMMAP);
    525 	if (efimm == NULL)
    526 		return NULL;
    527 
    528 	for (n = 0, i = 0; i < efimm->num; i++) {
    529 		md = (struct efi_md *)(efimm->memmap + efimm->size * i);
    530 		addr = md->md_phys;
    531 		size = md->md_pages * EFI_PAGE_SIZE;
    532 		type = efi_getbiosmemtype(md->md_type, md->md_attr);
    533 
    534 #ifdef DEBUG_MEMLOAD
    535 		printf("MEMMAP: p0x%016" PRIx64 "-0x%016" PRIx64
    536 		    ", v0x%016" PRIx64 "-0x%016" PRIx64
    537 		    ", size=0x%016" PRIx64 ", attr=0x%016" PRIx64
    538 		    ", type=%d(%s)\n",
    539 		    addr, addr + size - 1,
    540 		    md->md_virt, md->md_virt + size - 1,
    541 		    size, md->md_attr, md->md_type,
    542 		    efi_getmemtype_str(md->md_type));
    543 #endif
    544 
    545 		if (seg_type == -1) {
    546 			/* first entry */
    547 		} else if (seg_type == type && end_addr == addr) {
    548 			/* continuous region */
    549 			end_addr = addr + size;
    550 			continue;
    551 		} else {
    552 			entry = &efi_e820memmap.bim.entry[n];
    553 			entry->addr = start_addr;
    554 			entry->size = end_addr - start_addr;
    555 			entry->type = seg_type;
    556 			if (++n == VM_PHYSSEG_MAX)
    557 				break;
    558 		}
    559 
    560 		start_addr = addr;
    561 		end_addr = addr + size;
    562 		seg_type = type;
    563 	}
    564 	if (i > 0 && n < VM_PHYSSEG_MAX) {
    565 		entry = &efi_e820memmap.bim.entry[n];
    566 		entry->addr = start_addr;
    567 		entry->size = end_addr - start_addr;
    568 		entry->type = seg_type;
    569 		++n;
    570 	} else if (n == VM_PHYSSEG_MAX) {
    571 		printf("WARNING: too many memory segments"
    572 		    "(increase VM_PHYSSEG_MAX)\n");
    573 	}
    574 
    575 	efi_e820memmap.bim.num = n;
    576 	efi_e820memmap.bim.common.len =
    577 	    (intptr_t)&efi_e820memmap.bim.entry[n] - (intptr_t)&efi_e820memmap;
    578 	efi_e820memmap.bim.common.type = BTINFO_MEMMAP;
    579 	return &efi_e820memmap.bim;
    580 }
    581 
    582 #ifdef EFI_RUNTIME
    583 
    584 /*
    585  * efi_runtime_init()
    586  *
    587  *	Set up kernel access to EFI runtime services:
    588  *
    589  *	- Create efi_runtime_pmap.
    590  *	- Enter all the EFI runtime memory mappings into it.
    591  *	- Make a copy of the EFI runtime services table in efi_rt.
    592  *	- Initialize efi_runtime_lock to serialize calls.
    593  *	- Register EFI runtime service operations for /dev/efi.
    594  *
    595  *	On failure, leaves efi_rt zero-initialized and everything else
    596  *	uninitialized.
    597  */
    598 static void
    599 efi_runtime_init(void)
    600 {
    601 	struct efi_systbl *systbl;
    602 	struct btinfo_efimemmap *efimm;
    603 	uint32_t i;
    604 	int error;
    605 
    606 	/*
    607 	 * Refuse to handle EFI runtime services with cross-word-sizes
    608 	 * for now.  We would need logic to handle the cross table
    609 	 * types, and logic to translate between the calling
    610 	 * conventions -- might be easy for 32-bit EFI and 64-bit OS,
    611 	 * but sounds painful to contemplate for 64-bit EFI and 32-bit
    612 	 * OS.
    613 	 */
    614 	if (efi_is32x64) {
    615 		aprint_debug("%s: 32x64 runtime services not supported\n",
    616 		    __func__);
    617 		return;
    618 	}
    619 
    620 	/*
    621 	 * Verify that we have an EFI system table with runtime
    622 	 * services and an EFI memory map.
    623 	 */
    624 	systbl = efi_getsystbl();
    625 	if (systbl->st_rt == NULL) {
    626 		aprint_debug("%s: no runtime\n", __func__);
    627 		return;
    628 	}
    629 	if ((efimm = lookup_bootinfo(BTINFO_EFIMEMMAP)) == NULL) {
    630 		aprint_debug("%s: no efi memmap\n", __func__);
    631 		return;
    632 	}
    633 
    634 	/*
    635 	 * Create a pmap for EFI runtime services and switch to it to
    636 	 * enter all of the mappings needed for EFI runtime services
    637 	 * according to the EFI_MEMORY_DESCRIPTOR records.
    638 	 */
    639 	efi_runtime_pmap = pmap_create();
    640 	void *const cookie = pmap_activate_sync(efi_runtime_pmap);
    641 	for (i = 0; i < efimm->num; i++) {
    642 		struct efi_md *md = (void *)(efimm->memmap + efimm->size * i);
    643 		uint64_t j;
    644 		vaddr_t va;
    645 		paddr_t pa;
    646 		int prot, flags;
    647 
    648 		/*
    649 		 * Only enter mappings tagged EFI_MEMORY_RUNTIME.
    650 		 * Ignore all others.
    651 		 */
    652 		if ((md->md_attr & EFI_MD_ATTR_RT) == 0)
    653 			continue;
    654 
    655 		/*
    656 		 * For debug boots, print the memory descriptor.
    657 		 */
    658 		aprint_debug("%s: map %zu pages at %#"PRIxVADDR
    659 		    " to %#"PRIxPADDR" type %"PRIu32" attrs 0x%08"PRIx64"\n",
    660 		    __func__, (size_t)md->md_pages, (vaddr_t)md->md_virt,
    661 		    (paddr_t)md->md_phys, md->md_type, md->md_attr);
    662 
    663 		/*
    664 		 * Allow read and write access in all of the mappings.
    665 		 * For code mappings, also allow execution by default.
    666 		 *
    667 		 * Even code mappings must be writable, apparently.
    668 		 * The mappings can be marked RO or XP to prevent write
    669 		 * or execute, but the code mappings are usually at the
    670 		 * level of entire PECOFF objects containing both rw-
    671 		 * and r-x sections.  The EFI_MEMORY_ATTRIBUTES_TABLE
    672 		 * provides finer-grained mapping protections, but we
    673 		 * don't currently use it.
    674 		 *
    675 		 * XXX Should parse EFI_MEMORY_ATTRIBUTES_TABLE and use
    676 		 * it to nix W or X access when possible.
    677 		 */
    678 		prot = VM_PROT_READ|VM_PROT_WRITE;
    679 		switch (md->md_type) {
    680 		case EFI_MD_TYPE_RT_CODE:
    681 			prot |= VM_PROT_EXECUTE;
    682 			break;
    683 		}
    684 
    685 		/*
    686 		 * Additionally pass on:
    687 		 *
    688 		 *	EFI_MEMORY_UC (uncacheable) -> PMAP_NOCACHE
    689 		 *	EFI_MEMORY_WC (write-combining) -> PMAP_WRITE_COMBINE
    690 		 *	EFI_MEMORY_RO (read-only) -> clear VM_PROT_WRITE
    691 		 *	EFI_MEMORY_XP (exec protect) -> clear VM_PROT_EXECUTE
    692 		 */
    693 		flags = 0;
    694 		if (md->md_attr & EFI_MD_ATTR_UC)
    695 			flags |= PMAP_NOCACHE;
    696 		else if (md->md_attr & EFI_MD_ATTR_WC)
    697 			flags |= PMAP_WRITE_COMBINE;
    698 		if (md->md_attr & EFI_MD_ATTR_RO)
    699 			prot &= ~VM_PROT_WRITE;
    700 		if (md->md_attr & EFI_MD_ATTR_XP)
    701 			prot &= ~VM_PROT_EXECUTE;
    702 
    703 		/*
    704 		 * Get the physical address, and the virtual address
    705 		 * that the EFI runtime services want mapped to it.
    706 		 *
    707 		 * If the requested virtual address is zero, assume
    708 		 * we're using physical addressing, i.e., VA is the
    709 		 * same as PA.
    710 		 *
    711 		 * This logic is intended to allow the bootloader to
    712 		 * choose whether to use physical addressing or to use
    713 		 * virtual addressing with RT->SetVirtualAddressMap --
    714 		 * the kernel should work either way (although as of
    715 		 * time of writing it has only been tested with
    716 		 * physical addressing).
    717 		 */
    718 		pa = md->md_phys;
    719 		va = md->md_virt;
    720 		if (va == 0)
    721 			va = pa;
    722 
    723 		/*
    724 		 * Fail if EFI runtime services want any virtual pages
    725 		 * of the kernel map.
    726 		 */
    727 		if (VM_MIN_KERNEL_ADDRESS <= va &&
    728 		    va < VM_MAX_KERNEL_ADDRESS) {
    729 			aprint_debug("%s: efi runtime overlaps kernel map"
    730 			    " %"PRIxVADDR" in [%"PRIxVADDR", %"PRIxVADDR")\n",
    731 			    __func__,
    732 			    va,
    733 			    (vaddr_t)VM_MIN_KERNEL_ADDRESS,
    734 			    (vaddr_t)VM_MAX_KERNEL_ADDRESS);
    735 			goto fail;
    736 		}
    737 
    738 		/*
    739 		 * Fail if it would interfere with a direct map.
    740 		 *
    741 		 * (It's possible that it might happen to be identical
    742 		 * to the direct mapping, in which case we could skip
    743 		 * this entry.  Seems unlikely; let's deal with that
    744 		 * edge case as it comes up.)
    745 		 */
    746 #ifdef __HAVE_DIRECT_MAP
    747 		if (PMAP_DIRECT_BASE <= va && va < PMAP_DIRECT_END) {
    748 			aprint_debug("%s: efi runtime overlaps direct map"
    749 			    " %"PRIxVADDR" in [%"PRIxVADDR", %"PRIxVADDR")\n",
    750 			    __func__,
    751 			    va,
    752 			    (vaddr_t)PMAP_DIRECT_BASE,
    753 			    (vaddr_t)PMAP_DIRECT_END);
    754 			goto fail;
    755 		}
    756 #endif
    757 
    758 		/*
    759 		 * Enter each page in the range of this memory
    760 		 * descriptor into efi_runtime_pmap.
    761 		 */
    762 		for (j = 0; j < md->md_pages; j++) {
    763 			error = pmap_enter(efi_runtime_pmap,
    764 			    va + j*PAGE_SIZE, pa + j*PAGE_SIZE, prot, flags);
    765 			KASSERTMSG(error == 0, "error=%d", error);
    766 		}
    767 	}
    768 
    769 	/*
    770 	 * Commit the updates, make a copy of the EFI runtime services
    771 	 * for easy determination of unsupported ones without needing
    772 	 * the pmap, and deactivate the pmap now that we're done with
    773 	 * it for now.
    774 	 */
    775 	pmap_update(efi_runtime_pmap);
    776 	memcpy(&efi_rt, systbl->st_rt, sizeof(efi_rt));
    777 	pmap_deactivate_sync(efi_runtime_pmap, cookie);
    778 
    779 	/*
    780 	 * Initialize efi_runtime_lock for serializing access to the
    781 	 * EFI runtime services from any context up to interrupts at
    782 	 * IPL_VM.
    783 	 */
    784 	mutex_init(&efi_runtime_lock, MUTEX_DEFAULT, IPL_VM);
    785 
    786 	/*
    787 	 * Register the EFI runtime operations for /dev/efi.
    788 	 */
    789 	efi_register_ops(&efi_runtime_ops);
    790 
    791 	return;
    792 
    793 fail:	/*
    794 	 * On failure, deactivate and destroy efi_runtime_pmap -- no
    795 	 * runtime services.
    796 	 */
    797 	pmap_deactivate_sync(efi_runtime_pmap, cookie);
    798 	pmap_destroy(efi_runtime_pmap);
    799 	efi_runtime_pmap = NULL;
    800 	/*
    801 	 * efi_rt is all zero, so will lead to EFI_UNSUPPORTED even if
    802 	 * used outside efi_runtime_ops (which is now not registered)
    803 	 */
    804 }
    805 
    806 struct efi_runtime_cookie {
    807 	void	*erc_pmap_cookie;
    808 };
    809 
    810 /*
    811  * efi_runtime_enter(cookie)
    812  *
    813  *	Prepare to call an EFI runtime service, storing state for the
    814  *	context in cookie.  Caller must call efi_runtime_exit when
    815  *	done.
    816  */
    817 static void
    818 efi_runtime_enter(struct efi_runtime_cookie *cookie)
    819 {
    820 
    821 	KASSERT(efi_runtime_pmap != NULL);
    822 
    823 	/*
    824 	 * Serialize queries to the EFI runtime services.
    825 	 *
    826 	 * The UEFI spec allows some concurrency among them with rules
    827 	 * about which calls can run in parallel with which other
    828 	 * calls, but it is simplest if we just serialize everything --
    829 	 * none of this is performance-critical.
    830 	 */
    831 	mutex_enter(&efi_runtime_lock);
    832 
    833 	/*
    834 	 * EFI runtime services may use the FPU, so stash any user FPU
    835 	 * state and enable kernel use of it.  This has the side
    836 	 * effects of disabling preemption and of blocking interrupts
    837 	 * at up to and including IPL_VM.
    838 	 */
    839 	fpu_kern_enter();
    840 
    841 	/*
    842 	 * Activate the efi_runtime_pmap so that the EFI runtime
    843 	 * services have access to the memory mappings the firmware
    844 	 * requested, but not access to any user mappings.  They still,
    845 	 * however, have access to all kernel mappings, so we can pass
    846 	 * in pointers to buffers in KVA -- the EFI runtime services
    847 	 * run privileged, which they need in order to do I/O anyway.
    848 	 */
    849 	cookie->erc_pmap_cookie = pmap_activate_sync(efi_runtime_pmap);
    850 }
    851 
    852 /*
    853  * efi_runtime_exit(cookie)
    854  *
    855  *	Restore state prior to efi_runtime_enter as stored in cookie
    856  *	for a call to an EFI runtime service.
    857  */
    858 static void
    859 efi_runtime_exit(struct efi_runtime_cookie *cookie)
    860 {
    861 
    862 	pmap_deactivate_sync(efi_runtime_pmap, cookie->erc_pmap_cookie);
    863 	fpu_kern_leave();
    864 	mutex_exit(&efi_runtime_lock);
    865 }
    866 
    867 /*
    868  * efi_runtime_gettime(tm, tmcap)
    869  *
    870  *	Call RT->GetTime, or return EFI_UNSUPPORTED if unsupported.
    871  */
    872 static efi_status
    873 efi_runtime_gettime(struct efi_tm *tm, struct efi_tmcap *tmcap)
    874 {
    875 	efi_status status;
    876 	struct efi_runtime_cookie cookie;
    877 
    878 	if (efi_rt.rt_gettime == NULL)
    879 		return EFI_UNSUPPORTED;
    880 
    881 	efi_runtime_enter(&cookie);
    882 	status = efi_rt.rt_gettime(tm, tmcap);
    883 	efi_runtime_exit(&cookie);
    884 
    885 	return status;
    886 }
    887 
    888 
    889 /*
    890  * efi_runtime_settime(tm)
    891  *
    892  *	Call RT->SetTime, or return EFI_UNSUPPORTED if unsupported.
    893  */
    894 static efi_status
    895 efi_runtime_settime(struct efi_tm *tm)
    896 {
    897 	efi_status status;
    898 	struct efi_runtime_cookie cookie;
    899 
    900 	if (efi_rt.rt_settime == NULL)
    901 		return EFI_UNSUPPORTED;
    902 
    903 	efi_runtime_enter(&cookie);
    904 	status = efi_rt.rt_settime(tm);
    905 	efi_runtime_exit(&cookie);
    906 
    907 	return status;
    908 }
    909 
    910 /*
    911  * efi_runtime_getvar(name, vendor, attrib, datasize, data)
    912  *
    913  *	Call RT->GetVariable.
    914  */
    915 static efi_status
    916 efi_runtime_getvar(efi_char *name, struct uuid *vendor, uint32_t *attrib,
    917     unsigned long *datasize, void *data)
    918 {
    919 	efi_status status;
    920 	struct efi_runtime_cookie cookie;
    921 
    922 	if (efi_rt.rt_getvar == NULL)
    923 		return EFI_UNSUPPORTED;
    924 
    925 	efi_runtime_enter(&cookie);
    926 	status = efi_rt.rt_getvar(name, vendor, attrib, datasize, data);
    927 	efi_runtime_exit(&cookie);
    928 
    929 	return status;
    930 }
    931 
    932 /*
    933  * efi_runtime_nextvar(namesize, name, vendor)
    934  *
    935  *	Call RT->GetNextVariableName.
    936  */
    937 static efi_status
    938 efi_runtime_nextvar(unsigned long *namesize, efi_char *name,
    939     struct uuid *vendor)
    940 {
    941 	efi_status status;
    942 	struct efi_runtime_cookie cookie;
    943 
    944 	if (efi_rt.rt_scanvar == NULL)
    945 		return EFI_UNSUPPORTED;
    946 
    947 	efi_runtime_enter(&cookie);
    948 	status = efi_rt.rt_scanvar(namesize, name, vendor);
    949 	efi_runtime_exit(&cookie);
    950 
    951 	return status;
    952 }
    953 
    954 /*
    955  * efi_runtime_setvar(name, vendor, attrib, datasize, data)
    956  *
    957  *	Call RT->SetVariable.
    958  */
    959 static efi_status
    960 efi_runtime_setvar(efi_char *name, struct uuid *vendor, uint32_t attrib,
    961     unsigned long datasize, void *data)
    962 {
    963 	efi_status status;
    964 	struct efi_runtime_cookie cookie;
    965 
    966 	if (efi_rt.rt_setvar == NULL)
    967 		return EFI_UNSUPPORTED;
    968 
    969 	efi_runtime_enter(&cookie);
    970 	status = efi_rt.rt_setvar(name, vendor, attrib, datasize, data);
    971 	efi_runtime_exit(&cookie);
    972 
    973 	return status;
    974 }
    975 
    976 static efi_status
    977 efi_runtime_gettab(const struct uuid *vendor, uint64_t *addrp)
    978 {
    979 	struct efi_cfgtbl *cfgtbl = efi_getcfgtblhead();
    980 	paddr_t pa;
    981 
    982 	if (cfgtbl == NULL)
    983 		return EFI_UNSUPPORTED;
    984 
    985 	pa = efi_getcfgtblpa(vendor);
    986 	if (pa == 0)
    987 		return EFI_NOT_FOUND;
    988 	*addrp = pa;
    989 	return EFI_SUCCESS;
    990 }
    991 
    992 static struct efi_ops efi_runtime_ops = {
    993 	.efi_gettime = efi_runtime_gettime,
    994 	.efi_settime = efi_runtime_settime,
    995 	.efi_getvar = efi_runtime_getvar,
    996 	.efi_setvar = efi_runtime_setvar,
    997 	.efi_nextvar = efi_runtime_nextvar,
    998 	.efi_gettab = efi_runtime_gettab,
    999 };
   1000 
   1001 #endif	/* EFI_RUNTIME */
   1002