xref: /netbsd-src/sys/arch/x86/x86/efi_machdep.c (revision ad8e3babd1abaf61b58ac12d0941adc1c1a0b863)
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
efi_getva(paddr_t pa)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
efi_relva(paddr_t pa,vaddr_t va)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
efi_uuideq(const struct uuid * a,const struct uuid * b)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
efi_aprintuuid(const struct uuid * uuid)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 *
efi_getcfgtblhead(void)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
efi_aprintcfgtbl(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 *
efi_getcfgtbl(const struct uuid * uuid)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
efi_getcfgtblpa(const struct uuid * uuid)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
efi_getsystblpa(void)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 *
efi_getsystbl(void)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
efi_init(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
efi_probe(void)444 efi_probe(void)
445 {
446 
447 	return bootmethod_efi;
448 }
449 
450 int
efi_getbiosmemtype(uint32_t type,uint64_t attr)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 *
efi_getmemtype_str(uint32_t type)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 *
efi_get_e820memmap(void)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
efi_runtime_init(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
efi_runtime_enter(struct efi_runtime_cookie * cookie)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
efi_runtime_exit(struct efi_runtime_cookie * cookie)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
efi_runtime_gettime(struct efi_tm * tm,struct efi_tmcap * tmcap)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
efi_runtime_settime(struct efi_tm * tm)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
efi_runtime_getvar(efi_char * name,struct uuid * vendor,uint32_t * attrib,unsigned long * datasize,void * data)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
efi_runtime_nextvar(unsigned long * namesize,efi_char * name,struct uuid * vendor)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
efi_runtime_setvar(efi_char * name,struct uuid * vendor,uint32_t attrib,unsigned long datasize,void * data)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
efi_runtime_gettab(const struct uuid * vendor,uint64_t * addrp)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