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