1 /*- 2 * Copyright (c) 2004 Marcel Moolenaar 3 * Copyright (c) 2001 Doug Rabson 4 * Copyright (c) 2016, 2018 The FreeBSD Foundation 5 * All rights reserved. 6 * 7 * Portions of this software were developed by Konstantin Belousov 8 * under sponsorship from the FreeBSD Foundation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include "opt_acpi.h" 36 37 #include <sys/param.h> 38 #include <sys/efi.h> 39 #include <sys/eventhandler.h> 40 #include <sys/kernel.h> 41 #include <sys/linker.h> 42 #include <sys/lock.h> 43 #include <sys/malloc.h> 44 #include <sys/module.h> 45 #include <sys/msan.h> 46 #include <sys/mutex.h> 47 #include <sys/clock.h> 48 #include <sys/proc.h> 49 #include <sys/reboot.h> 50 #include <sys/rwlock.h> 51 #include <sys/sched.h> 52 #include <sys/sysctl.h> 53 #include <sys/systm.h> 54 #include <sys/uio.h> 55 #include <sys/vmmeter.h> 56 57 #include <machine/fpu.h> 58 #include <machine/efi.h> 59 #include <machine/metadata.h> 60 #include <machine/vmparam.h> 61 62 #include <vm/vm.h> 63 #include <vm/pmap.h> 64 #include <vm/vm_map.h> 65 66 #ifdef DEV_ACPI 67 #include <contrib/dev/acpica/include/acpi.h> 68 #endif 69 70 #define EFI_TABLE_ALLOC_MAX 0x800000 71 72 static struct efi_systbl *efi_systbl; 73 static eventhandler_tag efi_shutdown_tag; 74 /* 75 * The following pointers point to tables in the EFI runtime service data pages. 76 * Care should be taken to make sure that we've properly entered the EFI runtime 77 * environment (efi_enter()) before dereferencing them. 78 */ 79 static struct efi_cfgtbl *efi_cfgtbl; 80 static struct efi_rt *efi_runtime; 81 82 static int efi_status2err[25] = { 83 0, /* EFI_SUCCESS */ 84 ENOEXEC, /* EFI_LOAD_ERROR */ 85 EINVAL, /* EFI_INVALID_PARAMETER */ 86 ENOSYS, /* EFI_UNSUPPORTED */ 87 EMSGSIZE, /* EFI_BAD_BUFFER_SIZE */ 88 EOVERFLOW, /* EFI_BUFFER_TOO_SMALL */ 89 EBUSY, /* EFI_NOT_READY */ 90 EIO, /* EFI_DEVICE_ERROR */ 91 EROFS, /* EFI_WRITE_PROTECTED */ 92 EAGAIN, /* EFI_OUT_OF_RESOURCES */ 93 EIO, /* EFI_VOLUME_CORRUPTED */ 94 ENOSPC, /* EFI_VOLUME_FULL */ 95 ENXIO, /* EFI_NO_MEDIA */ 96 ESTALE, /* EFI_MEDIA_CHANGED */ 97 ENOENT, /* EFI_NOT_FOUND */ 98 EACCES, /* EFI_ACCESS_DENIED */ 99 ETIMEDOUT, /* EFI_NO_RESPONSE */ 100 EADDRNOTAVAIL, /* EFI_NO_MAPPING */ 101 ETIMEDOUT, /* EFI_TIMEOUT */ 102 EDOOFUS, /* EFI_NOT_STARTED */ 103 EALREADY, /* EFI_ALREADY_STARTED */ 104 ECANCELED, /* EFI_ABORTED */ 105 EPROTO, /* EFI_ICMP_ERROR */ 106 EPROTO, /* EFI_TFTP_ERROR */ 107 EPROTO /* EFI_PROTOCOL_ERROR */ 108 }; 109 110 enum efi_table_type { 111 TYPE_ESRT = 0, 112 TYPE_PROP 113 }; 114 115 static int efi_enter(void); 116 static void efi_leave(void); 117 118 int 119 efi_status_to_errno(efi_status status) 120 { 121 u_long code; 122 123 code = status & 0x3ffffffffffffffful; 124 return (code < nitems(efi_status2err) ? efi_status2err[code] : EDOOFUS); 125 } 126 127 static struct mtx efi_lock; 128 static SYSCTL_NODE(_hw, OID_AUTO, efi, CTLFLAG_RWTUN | CTLFLAG_MPSAFE, NULL, 129 "EFI"); 130 static bool efi_poweroff = true; 131 SYSCTL_BOOL(_hw_efi, OID_AUTO, poweroff, CTLFLAG_RWTUN, &efi_poweroff, 0, 132 "If true, use EFI runtime services to power off in preference to ACPI"); 133 134 static bool 135 efi_is_in_map(struct efi_md *map, int ndesc, int descsz, vm_offset_t addr) 136 { 137 struct efi_md *p; 138 int i; 139 140 for (i = 0, p = map; i < ndesc; i++, p = efi_next_descriptor(p, 141 descsz)) { 142 if ((p->md_attr & EFI_MD_ATTR_RT) == 0) 143 continue; 144 145 if (addr >= p->md_virt && 146 addr < p->md_virt + p->md_pages * EFI_PAGE_SIZE) 147 return (true); 148 } 149 150 return (false); 151 } 152 153 static void 154 efi_shutdown_final(void *dummy __unused, int howto) 155 { 156 157 /* 158 * On some systems, ACPI S5 is missing or does not function properly. 159 * When present, shutdown via EFI Runtime Services instead, unless 160 * disabled. 161 */ 162 if ((howto & RB_POWEROFF) != 0 && efi_poweroff) 163 (void)efi_reset_system(EFI_RESET_SHUTDOWN); 164 } 165 166 static int 167 efi_init(void) 168 { 169 struct efi_map_header *efihdr; 170 struct efi_md *map; 171 struct efi_rt *rtdm; 172 caddr_t kmdp; 173 size_t efisz; 174 int ndesc, rt_disabled; 175 176 rt_disabled = 0; 177 TUNABLE_INT_FETCH("efi.rt.disabled", &rt_disabled); 178 if (rt_disabled == 1) 179 return (0); 180 mtx_init(&efi_lock, "efi", NULL, MTX_DEF); 181 182 if (efi_systbl_phys == 0) { 183 if (bootverbose) 184 printf("EFI systbl not available\n"); 185 return (0); 186 } 187 188 efi_systbl = (struct efi_systbl *)efi_phys_to_kva(efi_systbl_phys); 189 if (efi_systbl == NULL || efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) { 190 efi_systbl = NULL; 191 if (bootverbose) 192 printf("EFI systbl signature invalid\n"); 193 return (0); 194 } 195 efi_cfgtbl = (efi_systbl->st_cfgtbl == 0) ? NULL : 196 (struct efi_cfgtbl *)efi_systbl->st_cfgtbl; 197 if (efi_cfgtbl == NULL) { 198 if (bootverbose) 199 printf("EFI config table is not present\n"); 200 } 201 202 kmdp = preload_search_by_type("elf kernel"); 203 if (kmdp == NULL) 204 kmdp = preload_search_by_type("elf64 kernel"); 205 efihdr = (struct efi_map_header *)preload_search_info(kmdp, 206 MODINFO_METADATA | MODINFOMD_EFI_MAP); 207 if (efihdr == NULL) { 208 if (bootverbose) 209 printf("EFI map is not present\n"); 210 return (0); 211 } 212 efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; 213 map = (struct efi_md *)((uint8_t *)efihdr + efisz); 214 if (efihdr->descriptor_size == 0) 215 return (ENOMEM); 216 217 ndesc = efihdr->memory_size / efihdr->descriptor_size; 218 if (!efi_create_1t1_map(map, ndesc, efihdr->descriptor_size)) { 219 if (bootverbose) 220 printf("EFI cannot create runtime map\n"); 221 return (ENOMEM); 222 } 223 224 efi_runtime = (efi_systbl->st_rt == 0) ? NULL : 225 (struct efi_rt *)efi_systbl->st_rt; 226 if (efi_runtime == NULL) { 227 if (bootverbose) 228 printf("EFI runtime services table is not present\n"); 229 efi_destroy_1t1_map(); 230 return (ENXIO); 231 } 232 233 #if defined(__aarch64__) || defined(__amd64__) 234 /* 235 * Some UEFI implementations have multiple implementations of the 236 * RS->GetTime function. They switch from one we can only use early 237 * in the boot process to one valid as a RunTime service only when we 238 * call RS->SetVirtualAddressMap. As this is not always the case, e.g. 239 * with an old loader.efi, check if the RS->GetTime function is within 240 * the EFI map, and fail to attach if not. 241 */ 242 rtdm = (struct efi_rt *)efi_phys_to_kva((uintptr_t)efi_runtime); 243 if (rtdm == NULL || !efi_is_in_map(map, ndesc, efihdr->descriptor_size, 244 (vm_offset_t)rtdm->rt_gettime)) { 245 if (bootverbose) 246 printf( 247 "EFI runtime services table has an invalid pointer\n"); 248 efi_runtime = NULL; 249 efi_destroy_1t1_map(); 250 return (ENXIO); 251 } 252 #endif 253 254 /* 255 * We use SHUTDOWN_PRI_LAST - 1 to trigger after IPMI, but before ACPI. 256 */ 257 efi_shutdown_tag = EVENTHANDLER_REGISTER(shutdown_final, 258 efi_shutdown_final, NULL, SHUTDOWN_PRI_LAST - 1); 259 260 return (0); 261 } 262 263 static void 264 efi_uninit(void) 265 { 266 267 /* Most likely disabled by tunable */ 268 if (efi_runtime == NULL) 269 return; 270 if (efi_shutdown_tag != NULL) 271 EVENTHANDLER_DEREGISTER(shutdown_final, efi_shutdown_tag); 272 efi_destroy_1t1_map(); 273 274 efi_systbl = NULL; 275 efi_cfgtbl = NULL; 276 efi_runtime = NULL; 277 278 mtx_destroy(&efi_lock); 279 } 280 281 static int 282 rt_ok(void) 283 { 284 285 if (efi_runtime == NULL) 286 return (ENXIO); 287 return (0); 288 } 289 290 static int 291 efi_enter(void) 292 { 293 struct thread *td; 294 pmap_t curpmap; 295 int error; 296 297 if (efi_runtime == NULL) 298 return (ENXIO); 299 td = curthread; 300 curpmap = &td->td_proc->p_vmspace->vm_pmap; 301 PMAP_LOCK(curpmap); 302 mtx_lock(&efi_lock); 303 fpu_kern_enter(td, NULL, FPU_KERN_NOCTX); 304 error = efi_arch_enter(); 305 if (error != 0) { 306 fpu_kern_leave(td, NULL); 307 mtx_unlock(&efi_lock); 308 PMAP_UNLOCK(curpmap); 309 } 310 return (error); 311 } 312 313 static void 314 efi_leave(void) 315 { 316 struct thread *td; 317 pmap_t curpmap; 318 319 efi_arch_leave(); 320 321 curpmap = &curproc->p_vmspace->vm_pmap; 322 td = curthread; 323 fpu_kern_leave(td, NULL); 324 mtx_unlock(&efi_lock); 325 PMAP_UNLOCK(curpmap); 326 } 327 328 static int 329 get_table(struct uuid *uuid, void **ptr) 330 { 331 struct efi_cfgtbl *ct; 332 u_long count; 333 int error; 334 335 if (efi_cfgtbl == NULL || efi_systbl == NULL) 336 return (ENXIO); 337 error = efi_enter(); 338 if (error != 0) 339 return (error); 340 count = efi_systbl->st_entries; 341 ct = efi_cfgtbl; 342 while (count--) { 343 if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) { 344 *ptr = ct->ct_data; 345 efi_leave(); 346 return (0); 347 } 348 ct++; 349 } 350 351 efi_leave(); 352 return (ENOENT); 353 } 354 355 static int 356 get_table_length(enum efi_table_type type, size_t *table_len, void **taddr) 357 { 358 switch (type) { 359 case TYPE_ESRT: 360 { 361 struct efi_esrt_table *esrt = NULL; 362 struct uuid uuid = EFI_TABLE_ESRT; 363 uint32_t fw_resource_count = 0; 364 size_t len = sizeof(*esrt); 365 int error; 366 void *buf; 367 368 error = efi_get_table(&uuid, (void **)&esrt); 369 if (error != 0) 370 return (error); 371 372 buf = malloc(len, M_TEMP, M_WAITOK); 373 error = physcopyout((vm_paddr_t)esrt, buf, len); 374 if (error != 0) { 375 free(buf, M_TEMP); 376 return (error); 377 } 378 379 /* Check ESRT version */ 380 if (((struct efi_esrt_table *)buf)->fw_resource_version != 381 ESRT_FIRMWARE_RESOURCE_VERSION) { 382 free(buf, M_TEMP); 383 return (ENODEV); 384 } 385 386 fw_resource_count = ((struct efi_esrt_table *)buf)-> 387 fw_resource_count; 388 if (fw_resource_count > EFI_TABLE_ALLOC_MAX / 389 sizeof(struct efi_esrt_entry_v1)) { 390 free(buf, M_TEMP); 391 return (ENOMEM); 392 } 393 394 len += fw_resource_count * sizeof(struct efi_esrt_entry_v1); 395 *table_len = len; 396 397 if (taddr != NULL) 398 *taddr = esrt; 399 free(buf, M_TEMP); 400 return (0); 401 } 402 case TYPE_PROP: 403 { 404 struct uuid uuid = EFI_PROPERTIES_TABLE; 405 struct efi_prop_table *prop; 406 size_t len = sizeof(*prop); 407 uint32_t prop_len; 408 int error; 409 void *buf; 410 411 error = efi_get_table(&uuid, (void **)&prop); 412 if (error != 0) 413 return (error); 414 415 buf = malloc(len, M_TEMP, M_WAITOK); 416 error = physcopyout((vm_paddr_t)prop, buf, len); 417 if (error != 0) { 418 free(buf, M_TEMP); 419 return (error); 420 } 421 422 prop_len = ((struct efi_prop_table *)buf)->length; 423 if (prop_len > EFI_TABLE_ALLOC_MAX) { 424 free(buf, M_TEMP); 425 return (ENOMEM); 426 } 427 *table_len = prop_len; 428 429 if (taddr != NULL) 430 *taddr = prop; 431 free(buf, M_TEMP); 432 return (0); 433 } 434 } 435 return (ENOENT); 436 } 437 438 static int 439 copy_table(struct uuid *uuid, void **buf, size_t buf_len, size_t *table_len) 440 { 441 static const struct known_table { 442 struct uuid uuid; 443 enum efi_table_type type; 444 } tables[] = { 445 { EFI_TABLE_ESRT, TYPE_ESRT }, 446 { EFI_PROPERTIES_TABLE, TYPE_PROP } 447 }; 448 size_t table_idx; 449 void *taddr; 450 int rc; 451 452 for (table_idx = 0; table_idx < nitems(tables); table_idx++) { 453 if (!bcmp(&tables[table_idx].uuid, uuid, sizeof(*uuid))) 454 break; 455 } 456 457 if (table_idx == nitems(tables)) 458 return (EINVAL); 459 460 rc = get_table_length(tables[table_idx].type, table_len, &taddr); 461 if (rc != 0) 462 return rc; 463 464 /* return table length to userspace */ 465 if (buf == NULL) 466 return (0); 467 468 *buf = malloc(*table_len, M_TEMP, M_WAITOK); 469 rc = physcopyout((vm_paddr_t)taddr, *buf, *table_len); 470 return (rc); 471 } 472 473 static int efi_rt_handle_faults = EFI_RT_HANDLE_FAULTS_DEFAULT; 474 SYSCTL_INT(_machdep, OID_AUTO, efi_rt_handle_faults, CTLFLAG_RWTUN, 475 &efi_rt_handle_faults, 0, 476 "Call EFI RT methods with fault handler wrapper around"); 477 478 static int 479 efi_rt_arch_call_nofault(struct efirt_callinfo *ec) 480 { 481 482 switch (ec->ec_argcnt) { 483 case 0: 484 ec->ec_efi_status = ((register_t (*)(void))ec->ec_fptr)(); 485 break; 486 case 1: 487 ec->ec_efi_status = ((register_t (*)(register_t))ec->ec_fptr) 488 (ec->ec_arg1); 489 break; 490 case 2: 491 ec->ec_efi_status = ((register_t (*)(register_t, register_t)) 492 ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2); 493 break; 494 case 3: 495 ec->ec_efi_status = ((register_t (*)(register_t, register_t, 496 register_t))ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2, 497 ec->ec_arg3); 498 break; 499 case 4: 500 ec->ec_efi_status = ((register_t (*)(register_t, register_t, 501 register_t, register_t))ec->ec_fptr)(ec->ec_arg1, 502 ec->ec_arg2, ec->ec_arg3, ec->ec_arg4); 503 break; 504 case 5: 505 ec->ec_efi_status = ((register_t (*)(register_t, register_t, 506 register_t, register_t, register_t))ec->ec_fptr)( 507 ec->ec_arg1, ec->ec_arg2, ec->ec_arg3, ec->ec_arg4, 508 ec->ec_arg5); 509 break; 510 default: 511 panic("efi_rt_arch_call: %d args", (int)ec->ec_argcnt); 512 } 513 514 return (0); 515 } 516 517 static int 518 efi_call(struct efirt_callinfo *ecp) 519 { 520 int error; 521 522 error = efi_enter(); 523 if (error != 0) 524 return (error); 525 error = efi_rt_handle_faults ? efi_rt_arch_call(ecp) : 526 efi_rt_arch_call_nofault(ecp); 527 efi_leave(); 528 if (error == 0) 529 error = efi_status_to_errno(ecp->ec_efi_status); 530 else if (bootverbose) 531 printf("EFI %s call faulted, error %d\n", ecp->ec_name, error); 532 return (error); 533 } 534 535 #define EFI_RT_METHOD_PA(method) \ 536 ((uintptr_t)((struct efi_rt *)efi_phys_to_kva((uintptr_t) \ 537 efi_runtime))->method) 538 539 static int 540 efi_get_time_locked(struct efi_tm *tm, struct efi_tmcap *tmcap) 541 { 542 struct efirt_callinfo ec; 543 int error; 544 545 EFI_TIME_OWNED(); 546 if (efi_runtime == NULL) 547 return (ENXIO); 548 bzero(&ec, sizeof(ec)); 549 ec.ec_name = "rt_gettime"; 550 ec.ec_argcnt = 2; 551 ec.ec_arg1 = (uintptr_t)tm; 552 ec.ec_arg2 = (uintptr_t)tmcap; 553 ec.ec_fptr = EFI_RT_METHOD_PA(rt_gettime); 554 error = efi_call(&ec); 555 if (error == 0) 556 kmsan_mark(tm, sizeof(*tm), KMSAN_STATE_INITED); 557 return (error); 558 } 559 560 static int 561 get_time(struct efi_tm *tm) 562 { 563 struct efi_tmcap dummy; 564 int error; 565 566 if (efi_runtime == NULL) 567 return (ENXIO); 568 EFI_TIME_LOCK(); 569 /* 570 * UEFI spec states that the Capabilities argument to GetTime is 571 * optional, but some UEFI implementations choke when passed a NULL 572 * pointer. Pass a dummy efi_tmcap, even though we won't use it, 573 * to workaround such implementations. 574 */ 575 error = efi_get_time_locked(tm, &dummy); 576 EFI_TIME_UNLOCK(); 577 return (error); 578 } 579 580 static int 581 get_waketime(uint8_t *enabled, uint8_t *pending, struct efi_tm *tm) 582 { 583 struct efirt_callinfo ec; 584 int error; 585 #ifdef DEV_ACPI 586 UINT32 acpiRtcEnabled; 587 #endif 588 589 if (efi_runtime == NULL) 590 return (ENXIO); 591 592 EFI_TIME_LOCK(); 593 bzero(&ec, sizeof(ec)); 594 ec.ec_name = "rt_getwaketime"; 595 ec.ec_argcnt = 3; 596 ec.ec_arg1 = (uintptr_t)enabled; 597 ec.ec_arg2 = (uintptr_t)pending; 598 ec.ec_arg3 = (uintptr_t)tm; 599 ec.ec_fptr = EFI_RT_METHOD_PA(rt_getwaketime); 600 error = efi_call(&ec); 601 EFI_TIME_UNLOCK(); 602 603 #ifdef DEV_ACPI 604 if (error == 0) { 605 error = AcpiReadBitRegister(ACPI_BITREG_RT_CLOCK_ENABLE, 606 &acpiRtcEnabled); 607 if (ACPI_SUCCESS(error)) { 608 *enabled = *enabled && acpiRtcEnabled; 609 } else 610 error = EIO; 611 } 612 #endif 613 614 return (error); 615 } 616 617 static int 618 set_waketime(uint8_t enable, struct efi_tm *tm) 619 { 620 struct efirt_callinfo ec; 621 int error; 622 623 if (efi_runtime == NULL) 624 return (ENXIO); 625 626 EFI_TIME_LOCK(); 627 bzero(&ec, sizeof(ec)); 628 ec.ec_name = "rt_setwaketime"; 629 ec.ec_argcnt = 2; 630 ec.ec_arg1 = (uintptr_t)enable; 631 ec.ec_arg2 = (uintptr_t)tm; 632 ec.ec_fptr = EFI_RT_METHOD_PA(rt_setwaketime); 633 error = efi_call(&ec); 634 EFI_TIME_UNLOCK(); 635 636 #ifdef DEV_ACPI 637 if (error == 0) { 638 error = AcpiWriteBitRegister(ACPI_BITREG_RT_CLOCK_ENABLE, 639 (enable != 0) ? 1 : 0); 640 if (ACPI_FAILURE(error)) 641 error = EIO; 642 } 643 #endif 644 645 return (error); 646 } 647 648 static int 649 get_time_capabilities(struct efi_tmcap *tmcap) 650 { 651 struct efi_tm dummy; 652 int error; 653 654 if (efi_runtime == NULL) 655 return (ENXIO); 656 EFI_TIME_LOCK(); 657 error = efi_get_time_locked(&dummy, tmcap); 658 EFI_TIME_UNLOCK(); 659 return (error); 660 } 661 662 static int 663 reset_system(enum efi_reset type) 664 { 665 struct efirt_callinfo ec; 666 667 switch (type) { 668 case EFI_RESET_COLD: 669 case EFI_RESET_WARM: 670 case EFI_RESET_SHUTDOWN: 671 break; 672 default: 673 return (EINVAL); 674 } 675 if (efi_runtime == NULL) 676 return (ENXIO); 677 bzero(&ec, sizeof(ec)); 678 ec.ec_name = "rt_reset"; 679 ec.ec_argcnt = 4; 680 ec.ec_arg1 = (uintptr_t)type; 681 ec.ec_arg2 = (uintptr_t)0; 682 ec.ec_arg3 = (uintptr_t)0; 683 ec.ec_arg4 = (uintptr_t)NULL; 684 ec.ec_fptr = EFI_RT_METHOD_PA(rt_reset); 685 return (efi_call(&ec)); 686 } 687 688 static int 689 efi_set_time_locked(struct efi_tm *tm) 690 { 691 struct efirt_callinfo ec; 692 693 EFI_TIME_OWNED(); 694 if (efi_runtime == NULL) 695 return (ENXIO); 696 bzero(&ec, sizeof(ec)); 697 ec.ec_name = "rt_settime"; 698 ec.ec_argcnt = 1; 699 ec.ec_arg1 = (uintptr_t)tm; 700 ec.ec_fptr = EFI_RT_METHOD_PA(rt_settime); 701 return (efi_call(&ec)); 702 } 703 704 static int 705 set_time(struct efi_tm *tm) 706 { 707 int error; 708 709 if (efi_runtime == NULL) 710 return (ENXIO); 711 EFI_TIME_LOCK(); 712 error = efi_set_time_locked(tm); 713 EFI_TIME_UNLOCK(); 714 return (error); 715 } 716 717 static int 718 var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, 719 size_t *datasize, void *data) 720 { 721 struct efirt_callinfo ec; 722 int error; 723 724 if (efi_runtime == NULL) 725 return (ENXIO); 726 bzero(&ec, sizeof(ec)); 727 ec.ec_argcnt = 5; 728 ec.ec_name = "rt_getvar"; 729 ec.ec_arg1 = (uintptr_t)name; 730 ec.ec_arg2 = (uintptr_t)vendor; 731 ec.ec_arg3 = (uintptr_t)attrib; 732 ec.ec_arg4 = (uintptr_t)datasize; 733 ec.ec_arg5 = (uintptr_t)data; 734 ec.ec_fptr = EFI_RT_METHOD_PA(rt_getvar); 735 error = efi_call(&ec); 736 if (error == 0) 737 kmsan_mark(data, *datasize, KMSAN_STATE_INITED); 738 return (error); 739 } 740 741 static int 742 var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) 743 { 744 struct efirt_callinfo ec; 745 int error; 746 747 if (efi_runtime == NULL) 748 return (ENXIO); 749 bzero(&ec, sizeof(ec)); 750 ec.ec_argcnt = 3; 751 ec.ec_name = "rt_scanvar"; 752 ec.ec_arg1 = (uintptr_t)namesize; 753 ec.ec_arg2 = (uintptr_t)name; 754 ec.ec_arg3 = (uintptr_t)vendor; 755 ec.ec_fptr = EFI_RT_METHOD_PA(rt_scanvar); 756 error = efi_call(&ec); 757 if (error == 0) 758 kmsan_mark(name, *namesize, KMSAN_STATE_INITED); 759 return (error); 760 } 761 762 static int 763 var_set(efi_char *name, struct uuid *vendor, uint32_t attrib, 764 size_t datasize, void *data) 765 { 766 struct efirt_callinfo ec; 767 768 if (efi_runtime == NULL) 769 return (ENXIO); 770 bzero(&ec, sizeof(ec)); 771 ec.ec_argcnt = 5; 772 ec.ec_name = "rt_setvar"; 773 ec.ec_arg1 = (uintptr_t)name; 774 ec.ec_arg2 = (uintptr_t)vendor; 775 ec.ec_arg3 = (uintptr_t)attrib; 776 ec.ec_arg4 = (uintptr_t)datasize; 777 ec.ec_arg5 = (uintptr_t)data; 778 ec.ec_fptr = EFI_RT_METHOD_PA(rt_setvar); 779 return (efi_call(&ec)); 780 } 781 782 const static struct efi_ops efi_ops = { 783 .rt_ok = rt_ok, 784 .get_table = get_table, 785 .copy_table = copy_table, 786 .get_time = get_time, 787 .get_time_capabilities = get_time_capabilities, 788 .reset_system = reset_system, 789 .set_time = set_time, 790 .get_waketime = get_waketime, 791 .set_waketime = set_waketime, 792 .var_get = var_get, 793 .var_nextname = var_nextname, 794 .var_set = var_set, 795 }; 796 const struct efi_ops *active_efi_ops = &efi_ops; 797 798 static int 799 efirt_modevents(module_t m, int event, void *arg __unused) 800 { 801 802 switch (event) { 803 case MOD_LOAD: 804 return (efi_init()); 805 806 case MOD_UNLOAD: 807 efi_uninit(); 808 return (0); 809 810 case MOD_SHUTDOWN: 811 return (0); 812 813 default: 814 return (EOPNOTSUPP); 815 } 816 } 817 818 static moduledata_t efirt_moddata = { 819 .name = "efirt", 820 .evhand = efirt_modevents, 821 .priv = NULL, 822 }; 823 /* After fpuinitstate, before efidev */ 824 DECLARE_MODULE(efirt, efirt_moddata, SI_SUB_DRIVERS, SI_ORDER_SECOND); 825 MODULE_VERSION(efirt, 1); 826