1 /* 2 * Copyright (c) 2008-2010 Rui Paulo 3 * Copyright (c) 2006 Marcel Moolenaar 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 30 #include <sys/disk.h> 31 #include <sys/param.h> 32 #include <sys/reboot.h> 33 #include <sys/boot.h> 34 #include <sys/consplat.h> 35 #include <sys/zfs_bootenv.h> 36 #include <stand.h> 37 #include <inttypes.h> 38 #include <string.h> 39 #include <setjmp.h> 40 #include <disk.h> 41 42 #include <efi.h> 43 #include <efilib.h> 44 #include <efichar.h> 45 #include <eficonsctl.h> 46 #include <efidevp.h> 47 #include <Guid/SmBios.h> 48 #include <Protocol/DevicePath.h> 49 #include <Protocol/LoadedImage.h> 50 #include <Protocol/SerialIo.h> 51 #include <Protocol/SimpleTextIn.h> 52 #include <Uefi/UefiGpt.h> 53 54 #include <uuid.h> 55 56 #include <bootstrap.h> 57 #include <gfx_fb.h> 58 #include <smbios.h> 59 60 #include <libzfs.h> 61 #include <efizfs.h> 62 63 #include "loader_efi.h" 64 65 struct arch_switch archsw; /* MI/MD interface boundary */ 66 67 EFI_GUID gEfiLoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; 68 EFI_GUID gEfiSmbiosTableGuid = SMBIOS_TABLE_GUID; 69 EFI_GUID gEfiSmbios3TableGuid = SMBIOS3_TABLE_GUID; 70 71 extern void acpi_detect(void); 72 extern void efi_getsmap(void); 73 74 static EFI_LOADED_IMAGE_PROTOCOL *img; 75 76 /* 77 * Number of seconds to wait for a keystroke before exiting with failure 78 * in the event no currdev is found. -2 means always break, -1 means 79 * never break, 0 means poll once and then reboot, > 0 means wait for 80 * that many seconds. "fail_timeout" can be set in the environment as 81 * well. 82 */ 83 static int fail_timeout = 5; 84 85 bool 86 efi_zfs_is_preferred(EFI_HANDLE *h) 87 { 88 EFI_DEVICE_PATH *devpath, *dp, *node; 89 HARDDRIVE_DEVICE_PATH *hd; 90 bool ret; 91 extern UINT64 start_sector; /* from mb_header.S */ 92 93 /* This check is true for chainloader case. */ 94 if (h == img->DeviceHandle) 95 return (true); 96 97 /* 98 * Make sure the image was loaded from the hard disk. 99 */ 100 devpath = efi_lookup_devpath(img->DeviceHandle); 101 if (devpath == NULL) 102 return (false); 103 node = efi_devpath_last_node(devpath); 104 if (node == NULL) 105 return (false); 106 if (DevicePathType(node) != MEDIA_DEVICE_PATH || 107 (DevicePathSubType(node) != MEDIA_FILEPATH_DP && 108 DevicePathSubType(node) != MEDIA_HARDDRIVE_DP)) { 109 return (false); 110 } 111 112 /* 113 * XXX We ignore the MEDIA_FILEPATH_DP here for now as it is 114 * used on arm and we do not support arm. 115 */ 116 ret = false; 117 dp = efi_devpath_trim(devpath); 118 devpath = NULL; 119 if (dp == NULL) 120 goto done; 121 122 devpath = efi_lookup_devpath(h); 123 if (devpath == NULL) 124 goto done; 125 hd = (HARDDRIVE_DEVICE_PATH *)efi_devpath_last_node(devpath); 126 if (hd == NULL) { 127 devpath = NULL; 128 goto done; 129 } 130 devpath = efi_devpath_trim(devpath); 131 if (devpath == NULL) 132 goto done; 133 134 if (!efi_devpath_match(dp, devpath)) 135 goto done; 136 137 /* It is the same disk, do we have partition start? */ 138 if (start_sector == 0) 139 ret = true; 140 else if (start_sector == hd->PartitionStart) 141 ret = true; 142 143 done: 144 free(dp); 145 free(devpath); 146 return (ret); 147 } 148 149 static bool 150 has_keyboard(void) 151 { 152 EFI_STATUS status; 153 EFI_DEVICE_PATH *path; 154 EFI_HANDLE *hin; 155 uint_t i, nhandles; 156 bool retval = false; 157 158 /* 159 * Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and 160 * do the typical dance to get the right sized buffer. 161 */ 162 status = efi_get_protocol_handles(&gEfiSimpleTextInProtocolGuid, 163 &nhandles, &hin); 164 if (EFI_ERROR(status)) 165 return (retval); 166 167 /* 168 * Look at each of the handles. If it supports the device path protocol, 169 * use it to get the device path for this handle. Then see if that 170 * device path matches either the USB device path for keyboards or the 171 * legacy device path for keyboards. 172 */ 173 for (i = 0; i < nhandles; i++) { 174 status = OpenProtocolByHandle(hin[i], 175 &gEfiDevicePathProtocolGuid, (void **)&path); 176 if (EFI_ERROR(status)) 177 continue; 178 179 while (!IsDevicePathEnd(path)) { 180 /* 181 * Check for the ACPI keyboard node. All PNP3xx nodes 182 * are keyboards of different flavors. Note: It is 183 * unclear of there's always a keyboard node when 184 * there's a keyboard controller, or if there's only one 185 * when a keyboard is detected at boot. 186 */ 187 if (DevicePathType(path) == ACPI_DEVICE_PATH && 188 (DevicePathSubType(path) == ACPI_DP || 189 DevicePathSubType(path) == ACPI_EXTENDED_DP)) { 190 ACPI_HID_DEVICE_PATH *acpi; 191 192 acpi = (ACPI_HID_DEVICE_PATH *)(void *)path; 193 if ((EISA_ID_TO_NUM(acpi->HID) & 0xff00) == 194 0x300 && 195 (acpi->HID & 0xffff) == PNP_EISA_ID_CONST) { 196 retval = true; 197 goto out; 198 } 199 /* 200 * Check for USB keyboard node, if present. Unlike a 201 * PS/2 keyboard, these definitely only appear when 202 * connected to the system. 203 */ 204 } else if (DevicePathType(path) == 205 MESSAGING_DEVICE_PATH && 206 DevicePathSubType(path) == MSG_USB_CLASS_DP) { 207 USB_CLASS_DEVICE_PATH *usb; 208 209 /* 210 * Check for: 211 * DeviceClass: HID 212 * DeviceSubClass: Boot devices 213 * DeviceProtocol: Boot keyboards 214 */ 215 usb = (USB_CLASS_DEVICE_PATH *)(void *)path; 216 if (usb->DeviceClass == 3 && 217 usb->DeviceSubClass == 1 && 218 usb->DeviceProtocol == 1) { 219 retval = true; 220 goto out; 221 } 222 } 223 path = NextDevicePathNode(path); 224 } 225 } 226 out: 227 free(hin); 228 return (retval); 229 } 230 231 static void 232 set_currdev(const char *devname) 233 { 234 235 /* 236 * Don't execute hooks here; we may need to try setting these more than 237 * once here if we're probing for the ZFS pool we're supposed to boot. 238 * The currdev hook is intended to just validate user input anyways, 239 * while the loaddev hook makes it immutable once we've determined what 240 * the proper currdev is. 241 */ 242 env_setenv("currdev", EV_VOLATILE | EV_NOHOOK, devname, efi_setcurrdev, 243 env_nounset); 244 env_setenv("loaddev", EV_VOLATILE | EV_NOHOOK, devname, env_noset, 245 env_nounset); 246 } 247 248 static void 249 set_currdev_devdesc(struct devdesc *currdev) 250 { 251 char *devname; 252 253 devname = efi_fmtdev(currdev); 254 255 printf("Setting currdev to %s\n", devname); 256 set_currdev(devname); 257 } 258 259 static void 260 set_currdev_devsw(struct devsw *dev, int unit) 261 { 262 struct devdesc currdev; 263 264 currdev.d_dev = dev; 265 currdev.d_unit = unit; 266 267 set_currdev_devdesc(&currdev); 268 } 269 270 static void 271 set_currdev_pdinfo(pdinfo_t *dp) 272 { 273 274 /* 275 * Disks are special: they have partitions. if the parent 276 * pointer is non-null, we're a partition not a full disk 277 * and we need to adjust currdev appropriately. 278 */ 279 if (dp->pd_devsw->dv_type == DEVT_DISK) { 280 struct disk_devdesc currdev; 281 282 currdev.dd.d_dev = dp->pd_devsw; 283 if (dp->pd_parent == NULL) { 284 currdev.dd.d_unit = dp->pd_unit; 285 currdev.d_slice = D_SLICENONE; 286 currdev.d_partition = D_PARTNONE; 287 } else { 288 currdev.dd.d_unit = dp->pd_parent->pd_unit; 289 currdev.d_slice = dp->pd_unit; 290 currdev.d_partition = D_PARTISGPT; /* Assumes GPT */ 291 } 292 set_currdev_devdesc((struct devdesc *)&currdev); 293 } else { 294 set_currdev_devsw(dp->pd_devsw, dp->pd_unit); 295 } 296 } 297 298 static bool 299 sanity_check_currdev(void) 300 { 301 struct stat st; 302 303 return (stat("/boot/defaults/loader.conf", &st) == 0); 304 } 305 306 static bool 307 probe_zfs_currdev(uint64_t guid) 308 { 309 struct zfs_devdesc currdev; 310 char *bootonce; 311 bool rv; 312 313 currdev.dd.d_dev = &zfs_dev; 314 currdev.dd.d_unit = 0; 315 currdev.pool_guid = guid; 316 currdev.root_guid = 0; 317 set_currdev_devdesc((struct devdesc *)&currdev); 318 319 rv = sanity_check_currdev(); 320 if (rv) { 321 bootonce = malloc(VDEV_PAD_SIZE); 322 if (bootonce != NULL) { 323 if (zfs_get_bootonce(&currdev, OS_BOOTONCE, bootonce, 324 VDEV_PAD_SIZE) == 0) { 325 printf("zfs bootonce: %s\n", bootonce); 326 set_currdev(bootonce); 327 setenv("zfs-bootonce", bootonce, 1); 328 } 329 free(bootonce); 330 (void) zfs_attach_nvstore(&currdev); 331 } else { 332 printf("Failed to process bootonce data: %s\n", 333 strerror(errno)); 334 } 335 } 336 return (rv); 337 } 338 339 static bool 340 try_as_currdev(pdinfo_t *pp) 341 { 342 uint64_t guid; 343 344 /* 345 * If there's a zpool on this device, try it as a ZFS 346 * filesystem, which has somewhat different setup than all 347 * other types of fs due to imperfect loader integration. 348 * This all stems from ZFS being both a device (zpool) and 349 * a filesystem, plus the boot env feature. 350 */ 351 if (efizfs_get_guid_by_handle(pp->pd_handle, &guid)) 352 return (probe_zfs_currdev(guid)); 353 354 /* 355 * All other filesystems just need the pdinfo 356 * initialized in the standard way. 357 */ 358 set_currdev_pdinfo(pp); 359 return (sanity_check_currdev()); 360 } 361 362 static bool 363 find_currdev(EFI_LOADED_IMAGE_PROTOCOL *img) 364 { 365 pdinfo_t *dp, *pp; 366 EFI_DEVICE_PATH *devpath, *copy; 367 EFI_HANDLE h; 368 CHAR16 *text; 369 struct devsw *dev; 370 int unit; 371 uint64_t extra; 372 373 /* 374 * Did efi_zfs_probe() detect the boot pool? If so, use the zpool 375 * it found, if it's sane. ZFS is the only thing that looks for 376 * disks and pools to boot. 377 */ 378 if (pool_guid != 0) { 379 printf("Trying ZFS pool\n"); 380 if (probe_zfs_currdev(pool_guid)) 381 return (true); 382 } 383 384 /* 385 * Try to find the block device by its handle based on the 386 * image we're booting. If we can't find a sane partition, 387 * search all the other partitions of the disk. We do not 388 * search other disks because it's a violation of the UEFI 389 * boot protocol to do so. We fail and let UEFI go on to 390 * the next candidate. 391 */ 392 dp = efiblk_get_pdinfo_by_handle(img->DeviceHandle); 393 if (dp != NULL) { 394 text = efi_devpath_name(dp->pd_devpath); 395 if (text != NULL) { 396 printf("Trying ESP: %S\n", text); 397 efi_free_devpath_name(text); 398 } 399 set_currdev_pdinfo(dp); 400 if (sanity_check_currdev()) 401 return (true); 402 if (dp->pd_parent != NULL) { 403 dp = dp->pd_parent; 404 STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { 405 text = efi_devpath_name(pp->pd_devpath); 406 if (text != NULL) { 407 printf("And now the part: %S\n", text); 408 efi_free_devpath_name(text); 409 } 410 /* 411 * Roll up the ZFS special case 412 * for those partitions that have 413 * zpools on them 414 */ 415 if (try_as_currdev(pp)) 416 return (true); 417 } 418 } 419 } 420 421 /* 422 * Try the device handle from our loaded image first. If that 423 * fails, use the device path from the loaded image and see if 424 * any of the nodes in that path match one of the enumerated 425 * handles. Currently, this handle list is only for netboot. 426 */ 427 if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &extra) == 0) { 428 set_currdev_devsw(dev, unit); 429 if (sanity_check_currdev()) 430 return (true); 431 } 432 433 copy = NULL; 434 devpath = efi_lookup_image_devpath(IH); 435 while (devpath != NULL) { 436 h = efi_devpath_handle(devpath); 437 if (h == NULL) 438 break; 439 440 free(copy); 441 copy = NULL; 442 443 if (efi_handle_lookup(h, &dev, &unit, &extra) == 0) { 444 set_currdev_devsw(dev, unit); 445 if (sanity_check_currdev()) 446 return (true); 447 } 448 449 devpath = efi_lookup_devpath(h); 450 if (devpath != NULL) { 451 copy = efi_devpath_trim(devpath); 452 devpath = copy; 453 } 454 } 455 free(copy); 456 457 return (false); 458 } 459 460 static bool 461 interactive_interrupt(const char *msg) 462 { 463 time_t now, then, last; 464 465 last = 0; 466 now = then = getsecs(); 467 printf("%s\n", msg); 468 if (fail_timeout == -2) /* Always break to OK */ 469 return (true); 470 if (fail_timeout == -1) /* Never break to OK */ 471 return (false); 472 do { 473 if (last != now) { 474 printf("press any key to interrupt reboot " 475 "in %d seconds\r", 476 fail_timeout - (int)(now - then)); 477 last = now; 478 } 479 480 /* XXX no pause or timeout wait for char */ 481 if (ischar()) 482 return (true); 483 now = getsecs(); 484 } while (now - then < fail_timeout); 485 return (false); 486 } 487 488 static void 489 setenv_int(const char *key, int val) 490 { 491 char buf[20]; 492 493 (void) snprintf(buf, sizeof (buf), "%d", val); 494 (void) setenv(key, buf, 1); 495 } 496 497 /* 498 * Parse ConOut (the list of consoles active) and see if we can find a 499 * serial port and/or a video port. It would be nice to also walk the 500 * ACPI name space to map the UID for the serial port to a port. The 501 * latter is especially hard. 502 */ 503 static int 504 parse_uefi_con_out(void) 505 { 506 int how, rv; 507 int vid_seen = 0, com_seen = 0, seen = 0; 508 size_t sz; 509 char buf[4096], *ep; 510 EFI_DEVICE_PATH *node; 511 ACPI_HID_DEVICE_PATH *acpi; 512 UART_DEVICE_PATH *uart; 513 bool pci_pending = false; 514 515 how = 0; 516 sz = sizeof (buf); 517 rv = efi_global_getenv("ConOut", buf, &sz); 518 if (rv != EFI_SUCCESS) 519 rv = efi_global_getenv("ConOutDev", buf, &sz); 520 if (rv != EFI_SUCCESS) { 521 /* 522 * If we don't have any ConOut default to video. 523 * non-server systems may not have serial. 524 */ 525 goto out; 526 } 527 ep = buf + sz; 528 node = (EFI_DEVICE_PATH *)buf; 529 while ((char *)node < ep) { 530 if (IsDevicePathEndType(node)) { 531 if (pci_pending && vid_seen == 0) 532 vid_seen = ++seen; 533 } 534 pci_pending = false; 535 if (DevicePathType(node) == ACPI_DEVICE_PATH && 536 (DevicePathSubType(node) == ACPI_DP || 537 DevicePathSubType(node) == ACPI_EXTENDED_DP)) { 538 /* Check for Serial node */ 539 acpi = (void *)node; 540 if (EISA_ID_TO_NUM(acpi->HID) == 0x501) { 541 setenv_int("efi_8250_uid", acpi->UID); 542 com_seen = ++seen; 543 } 544 } else if (DevicePathType(node) == MESSAGING_DEVICE_PATH && 545 DevicePathSubType(node) == MSG_UART_DP) { 546 com_seen = ++seen; 547 uart = (void *)node; 548 setenv_int("efi_com_speed", uart->BaudRate); 549 } else if (DevicePathType(node) == ACPI_DEVICE_PATH && 550 DevicePathSubType(node) == ACPI_ADR_DP) { 551 /* Check for AcpiAdr() Node for video */ 552 vid_seen = ++seen; 553 } else if (DevicePathType(node) == HARDWARE_DEVICE_PATH && 554 DevicePathSubType(node) == HW_PCI_DP) { 555 /* 556 * Note, vmware fusion has a funky console device 557 * PciRoot(0x0)/Pci(0xf,0x0) 558 * which we can only detect at the end since we also 559 * have to cope with: 560 * PciRoot(0x0)/Pci(0x1f,0x0)/Serial(0x1) 561 * so only match it if it's last. 562 */ 563 pci_pending = true; 564 } 565 node = NextDevicePathNode(node); /* Skip the end node */ 566 } 567 568 /* 569 * Truth table for RB_MULTIPLE | RB_SERIAL 570 * Value Result 571 * 0 Use only video console 572 * RB_SERIAL Use only serial console 573 * RB_MULTIPLE Use both video and serial console 574 * (but video is primary so gets rc messages) 575 * both Use both video and serial console 576 * (but serial is primary so gets rc messages) 577 * 578 * Try to honor this as best we can. If only one of serial / video 579 * found, then use that. Otherwise, use the first one we found. 580 * This also implies if we found nothing, default to video. 581 */ 582 how = 0; 583 if (vid_seen && com_seen) { 584 how |= RB_MULTIPLE; 585 if (com_seen < vid_seen) 586 how |= RB_SERIAL; 587 } else if (com_seen) 588 how |= RB_SERIAL; 589 out: 590 return (how); 591 } 592 593 caddr_t 594 ptov(uintptr_t x) 595 { 596 return ((caddr_t)x); 597 } 598 599 static int 600 efi_serial_get_uid(EFI_DEVICE_PATH *devpath) 601 { 602 ACPI_HID_DEVICE_PATH *acpi; 603 604 while (!IsDevicePathEnd(devpath)) { 605 if (DevicePathType(devpath) == ACPI_DEVICE_PATH && 606 (DevicePathSubType(devpath) == ACPI_DP || 607 DevicePathSubType(devpath) == ACPI_EXTENDED_DP)) { 608 acpi = (ACPI_HID_DEVICE_PATH *)devpath; 609 if (EISA_ID_TO_NUM(acpi->HID) == 0x501) { 610 return (acpi->UID); 611 } 612 } 613 614 devpath = NextDevicePathNode(devpath); 615 } 616 return (-1); 617 } 618 619 /* 620 * Walk serialio protocol handle array and find index for serial console 621 * device. The problem is, we check for acpi UID value, but we can not be sure, 622 * if it will start from 0 or 1. 623 */ 624 static const char * 625 uefi_serial_console(void) 626 { 627 EFI_STATUS status; 628 EFI_HANDLE *handles; 629 uint_t i, nhandles; 630 unsigned long uid, lowest; 631 char *env, *ep; 632 633 env = getenv("efi_8250_uid"); 634 if (env == NULL) 635 return (NULL); 636 (void) unsetenv("efi_8250_uid"); 637 errno = 0; 638 uid = strtoul(env, &ep, 10); 639 if (errno != 0 || *ep != '\0') 640 return (NULL); 641 642 /* if uid is 0, this is first serial port */ 643 if (uid == 0) 644 return ("ttya"); 645 646 status = efi_get_protocol_handles(&gEfiSerialIoProtocolGuid, 647 &nhandles, &handles); 648 if (EFI_ERROR(status)) { 649 return (NULL); 650 } 651 652 lowest = 255; /* high enough value */ 653 for (i = 0; i < nhandles; i++) { 654 EFI_DEVICE_PATH *devpath; 655 unsigned long _uid; 656 657 devpath = efi_lookup_devpath(handles[i]); 658 _uid = efi_serial_get_uid(devpath); 659 if (_uid < lowest) 660 lowest = _uid; 661 } 662 free(handles); 663 switch (uid - lowest) { 664 case 0: 665 return ("ttya"); 666 case 1: 667 return ("ttyb"); 668 case 2: 669 return ("ttyc"); 670 case 3: 671 return ("ttyd"); 672 } 673 return (NULL); 674 } 675 676 EFI_STATUS 677 main(int argc, CHAR16 *argv[]) 678 { 679 char var[128]; 680 int i, j, howto; 681 bool vargood; 682 void *ptr; 683 bool has_kbd; 684 char *s; 685 const char *serial; 686 EFI_DEVICE_PATH *imgpath; 687 CHAR16 *text; 688 EFI_STATUS status; 689 UINT16 boot_current; 690 size_t sz; 691 UINT16 boot_order[100]; 692 693 archsw.arch_autoload = efi_autoload; 694 archsw.arch_getdev = efi_getdev; 695 archsw.arch_copyin = efi_copyin; 696 archsw.arch_copyout = efi_copyout; 697 archsw.arch_readin = efi_readin; 698 archsw.arch_loadaddr = efi_loadaddr; 699 archsw.arch_free_loadaddr = efi_free_loadaddr; 700 #if defined(__amd64) || defined(__i386) 701 archsw.arch_hypervisor = x86_hypervisor; 702 #endif 703 /* Note this needs to be set before ZFS init. */ 704 archsw.arch_zfs_probe = efi_zfs_probe; 705 706 /* Get our loaded image protocol interface structure. */ 707 (void) OpenProtocolByHandle(IH, &gEfiLoadedImageProtocolGuid, 708 (void **)&img); 709 710 /* 711 * XXX Chicken-and-egg problem; we want to have console output 712 * early, but some console attributes may depend on reading from 713 * eg. the boot device, which we can't do yet. We can use 714 * printf() etc. once this is done. 715 */ 716 setenv("console", "text", 1); 717 howto = parse_uefi_con_out(); 718 serial = uefi_serial_console(); 719 cons_probe(); 720 efi_getsmap(); 721 722 if ((s = getenv("efi_com_speed")) != NULL) { 723 char *name; 724 725 (void) snprintf(var, sizeof (var), "%s,8,n,1,-", s); 726 if (asprintf(&name, "%s-mode", serial) > 0) { 727 (void) setenv(name, var, 1); 728 free(name); 729 } 730 if (asprintf(&name, "%s-spcr-mode", serial) > 0) { 731 (void) setenv(name, var, 1); 732 free(name); 733 } 734 (void) unsetenv("efi_com_speed"); 735 } 736 737 /* Init the time source */ 738 efi_time_init(); 739 740 /* 741 * Initialise the block cache. Set the upper limit. 742 */ 743 bcache_init(32768, 512); 744 745 has_kbd = has_keyboard(); 746 747 /* 748 * Parse the args to set the console settings, etc 749 * iPXE may be setup to pass these in. Or the optional argument in the 750 * boot environment was used to pass these arguments in (in which case 751 * neither /boot.config nor /boot/config are consulted). 752 * 753 * Loop through the args, and for each one that contains an '=' that is 754 * not the first character, add it to the environment. This allows 755 * loader and kernel env vars to be passed on the command line. Convert 756 * args from UCS-2 to ASCII (16 to 8 bit) as they are copied (though 757 * this method is flawed for non-ASCII characters). 758 */ 759 for (i = 1; i < argc; i++) { 760 if (argv[i][0] == '-') { 761 for (j = 1; argv[i][j] != 0; j++) { 762 int ch; 763 764 ch = argv[i][j]; 765 switch (ch) { 766 case 'a': 767 howto |= RB_ASKNAME; 768 break; 769 case 'd': 770 howto |= RB_KDB; 771 break; 772 case 'D': 773 howto |= RB_MULTIPLE; 774 break; 775 case 'h': 776 howto |= RB_SERIAL; 777 break; 778 case 'm': 779 howto |= RB_MUTE; 780 break; 781 case 'p': 782 howto |= RB_PAUSE; 783 break; 784 case 'P': 785 if (!has_kbd) { 786 howto |= RB_SERIAL; 787 howto |= RB_MULTIPLE; 788 } 789 break; 790 case 'r': 791 howto |= RB_DFLTROOT; 792 break; 793 case 's': 794 howto |= RB_SINGLE; 795 break; 796 case 'S': 797 if (argv[i][j + 1] == 0) { 798 if (i + 1 == argc) { 799 strncpy(var, "115200", 800 sizeof (var)); 801 } else { 802 CHAR16 *ptr; 803 ptr = &argv[i + 1][0]; 804 cpy16to8(ptr, var, 805 sizeof (var)); 806 } 807 i++; 808 } else { 809 cpy16to8(&argv[i][j + 1], var, 810 sizeof (var)); 811 } 812 strncat(var, ",8,n,1,-", sizeof (var)); 813 setenv("ttya-mode", var, 1); 814 break; 815 case 'v': 816 howto |= RB_VERBOSE; 817 break; 818 } 819 } 820 } else { 821 vargood = false; 822 for (j = 0; argv[i][j] != 0; j++) { 823 if (j == sizeof (var)) { 824 vargood = false; 825 break; 826 } 827 if (j > 0 && argv[i][j] == '=') 828 vargood = true; 829 var[j] = (char)argv[i][j]; 830 } 831 if (vargood) { 832 var[j] = 0; 833 putenv(var); 834 } 835 } 836 } 837 for (i = 0; howto_names[i].ev != NULL; i++) 838 if (howto & howto_names[i].mask) 839 setenv(howto_names[i].ev, "YES", 1); 840 841 /* 842 * XXX we need fallback to this stuff after looking at the ConIn, 843 * ConOut and ConErr variables. 844 */ 845 if (howto & RB_MULTIPLE) { 846 if (howto & RB_SERIAL) 847 (void) snprintf(var, sizeof (var), "%s text", serial); 848 else 849 (void) snprintf(var, sizeof (var), "text %s", serial); 850 } else if (howto & RB_SERIAL) { 851 (void) snprintf(var, sizeof (var), "%s", serial); 852 } else { 853 (void) snprintf(var, sizeof (var), "text"); 854 } 855 (void) setenv("console", var, 1); 856 857 if ((s = getenv("fail_timeout")) != NULL) 858 fail_timeout = strtol(s, NULL, 10); 859 860 /* 861 * Scan the BLOCK IO MEDIA handles then 862 * march through the device switch probing for things. 863 */ 864 if ((i = efipart_inithandles()) == 0) { 865 for (i = 0; devsw[i] != NULL; i++) 866 if (devsw[i]->dv_init != NULL) 867 (devsw[i]->dv_init)(); 868 } else 869 printf("efipart_inithandles failed %d, expect failures", i); 870 871 printf("Command line arguments:"); 872 for (i = 0; i < argc; i++) { 873 printf(" %S", argv[i]); 874 } 875 printf("\n"); 876 877 printf("Image base: 0x%lx\n", (unsigned long)img->ImageBase); 878 printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16, 879 ST->Hdr.Revision & 0xffff); 880 printf("EFI Firmware: %S (rev %d.%02d)\n", ST->FirmwareVendor, 881 ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); 882 883 printf("\n%s", bootprog_info); 884 885 /* Determine the devpath of our image so we can prefer it. */ 886 text = efi_devpath_name(img->FilePath); 887 if (text != NULL) { 888 printf(" Load Path: %S\n", text); 889 efi_setenv_illumos_wcs("LoaderPath", text); 890 efi_free_devpath_name(text); 891 } 892 893 status = OpenProtocolByHandle(img->DeviceHandle, 894 &gEfiDevicePathProtocolGuid, (void **)&imgpath); 895 if (status == EFI_SUCCESS) { 896 text = efi_devpath_name(imgpath); 897 if (text != NULL) { 898 printf(" Load Device: %S\n", text); 899 efi_setenv_illumos_wcs("LoaderDev", text); 900 efi_free_devpath_name(text); 901 } 902 } 903 904 boot_current = 0; 905 sz = sizeof (boot_current); 906 efi_global_getenv("BootCurrent", &boot_current, &sz); 907 printf(" BootCurrent: %04x\n", boot_current); 908 909 sz = sizeof (boot_order); 910 efi_global_getenv("BootOrder", &boot_order, &sz); 911 printf(" BootOrder:"); 912 for (i = 0; i < sz / sizeof (boot_order[0]); i++) 913 printf(" %04x%s", boot_order[i], 914 boot_order[i] == boot_current ? "[*]" : ""); 915 printf("\n"); 916 917 /* 918 * Disable the watchdog timer. By default the boot manager sets 919 * the timer to 5 minutes before invoking a boot option. If we 920 * want to return to the boot manager, we have to disable the 921 * watchdog timer and since we're an interactive program, we don't 922 * want to wait until the user types "quit". The timer may have 923 * fired by then. We don't care if this fails. It does not prevent 924 * normal functioning in any way... 925 */ 926 BS->SetWatchdogTimer(0, 0, 0, NULL); 927 928 /* 929 * Try and find a good currdev based on the image that was booted. 930 * It might be desirable here to have a short pause to allow falling 931 * through to the boot loader instead of returning instantly to follow 932 * the boot protocol and also allow an escape hatch for users wishing 933 * to try something different. 934 */ 935 if (!find_currdev(img)) 936 if (!interactive_interrupt("Failed to find bootable partition")) 937 return (EFI_NOT_FOUND); 938 939 autoload_font(false); /* Set up the font list for console. */ 940 efi_init_environment(); 941 bi_isadir(); /* set ISADIR */ 942 acpi_detect(); 943 944 if ((ptr = efi_get_table(&gEfiSmbios3TableGuid)) == NULL) 945 ptr = efi_get_table(&gEfiSmbiosTableGuid); 946 smbios_detect(ptr); 947 948 interact(NULL); /* doesn't return */ 949 950 return (EFI_SUCCESS); /* keep compiler happy */ 951 } 952 953 COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); 954 955 static void 956 fw_setup(void) 957 { 958 uint64_t os_indications; 959 size_t size; 960 EFI_STATUS status; 961 962 size = sizeof (os_indications); 963 status = efi_global_getenv("OsIndicationsSupported", 964 &os_indications, &size); 965 if (EFI_ERROR(status) || size != sizeof (os_indications) || 966 (os_indications & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) == 0) { 967 printf("Booting to Firmware UI is not supported in " 968 "this system."); 969 for (int i = 0; i < 3; i++) { 970 delay(1000 * 1000); /* 1 second */ 971 if (ischar()) 972 break; 973 } 974 return; 975 } 976 977 os_indications = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; 978 979 status = efi_global_setenv("OsIndications", &os_indications, 980 sizeof (os_indications)); 981 } 982 983 static int 984 command_reboot(int argc, char *argv[]) 985 { 986 int i, ch; 987 bool fw = false; 988 989 optind = 1; 990 optreset = 1; 991 992 while ((ch = getopt(argc, argv, "fh")) != -1) { 993 switch (ch) { 994 case 'f': 995 fw = true; 996 break; 997 case 'h': 998 printf("Usage: reboot [-f]\n"); 999 return (CMD_OK); 1000 case '?': 1001 default: 1002 return (CMD_OK); 1003 } 1004 } 1005 1006 if (fw || getenv("BOOT_TO_FW_UI") != NULL) 1007 fw_setup(); 1008 1009 for (i = 0; devsw[i] != NULL; ++i) 1010 if (devsw[i]->dv_cleanup != NULL) 1011 (devsw[i]->dv_cleanup)(); 1012 1013 RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); 1014 1015 /* NOTREACHED */ 1016 return (CMD_ERROR); 1017 } 1018 1019 COMMAND_SET(poweroff, "poweroff", "power off the system", command_poweroff); 1020 1021 static int 1022 command_poweroff(int argc __unused, char *argv[] __unused) 1023 { 1024 int i; 1025 1026 for (i = 0; devsw[i] != NULL; ++i) 1027 if (devsw[i]->dv_cleanup != NULL) 1028 (devsw[i]->dv_cleanup)(); 1029 1030 RS->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); 1031 1032 /* NOTREACHED */ 1033 return (CMD_ERROR); 1034 } 1035 1036 COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); 1037 1038 static int 1039 command_memmap(int argc __unused, char *argv[] __unused) 1040 { 1041 UINTN sz; 1042 EFI_MEMORY_DESCRIPTOR *map, *p; 1043 UINTN key, dsz; 1044 UINT32 dver; 1045 EFI_STATUS status; 1046 int i, ndesc; 1047 int rv = 0; 1048 char line[80]; 1049 1050 sz = 0; 1051 status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); 1052 if (status != EFI_BUFFER_TOO_SMALL) { 1053 printf("Can't determine memory map size\n"); 1054 return (CMD_ERROR); 1055 } 1056 map = malloc(sz); 1057 status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); 1058 if (EFI_ERROR(status)) { 1059 printf("Can't read memory map\n"); 1060 return (CMD_ERROR); 1061 } 1062 1063 ndesc = sz / dsz; 1064 snprintf(line, 80, "%23s %12s %12s %8s %4s\n", 1065 "Type", "Physical", "Virtual", "#Pages", "Attr"); 1066 pager_open(); 1067 rv = pager_output(line); 1068 if (rv) { 1069 pager_close(); 1070 return (CMD_OK); 1071 } 1072 1073 for (i = 0, p = map; i < ndesc; 1074 i++, p = NextMemoryDescriptor(p, dsz)) { 1075 snprintf(line, 80, "%23s %012jx %012jx %08jx ", 1076 efi_memory_type(p->Type), p->PhysicalStart, 1077 p->VirtualStart, p->NumberOfPages); 1078 rv = pager_output(line); 1079 if (rv) 1080 break; 1081 1082 if (p->Attribute & EFI_MEMORY_UC) 1083 printf("UC "); 1084 if (p->Attribute & EFI_MEMORY_WC) 1085 printf("WC "); 1086 if (p->Attribute & EFI_MEMORY_WT) 1087 printf("WT "); 1088 if (p->Attribute & EFI_MEMORY_WB) 1089 printf("WB "); 1090 if (p->Attribute & EFI_MEMORY_UCE) 1091 printf("UCE "); 1092 if (p->Attribute & EFI_MEMORY_WP) 1093 printf("WP "); 1094 if (p->Attribute & EFI_MEMORY_RP) 1095 printf("RP "); 1096 if (p->Attribute & EFI_MEMORY_XP) 1097 printf("XP "); 1098 if (p->Attribute & EFI_MEMORY_NV) 1099 printf("NV "); 1100 if (p->Attribute & EFI_MEMORY_MORE_RELIABLE) 1101 printf("MR "); 1102 if (p->Attribute & EFI_MEMORY_RO) 1103 printf("RO "); 1104 rv = pager_output("\n"); 1105 if (rv) 1106 break; 1107 } 1108 1109 pager_close(); 1110 return (CMD_OK); 1111 } 1112 1113 COMMAND_SET(configuration, "configuration", "print configuration tables", 1114 command_configuration); 1115 1116 static int 1117 command_configuration(int argc __unused, char *argv[] __unused) 1118 { 1119 UINTN i; 1120 char *name; 1121 1122 printf("NumberOfTableEntries=%lu\n", 1123 (unsigned long)ST->NumberOfTableEntries); 1124 for (i = 0; i < ST->NumberOfTableEntries; i++) { 1125 EFI_GUID *guid; 1126 1127 printf(" "); 1128 guid = &ST->ConfigurationTable[i].VendorGuid; 1129 1130 if (efi_guid_to_name(guid, &name) == true) { 1131 printf(name); 1132 free(name); 1133 } else { 1134 printf("Error while translating UUID to name"); 1135 } 1136 printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); 1137 } 1138 1139 return (CMD_OK); 1140 } 1141 1142 1143 COMMAND_SET(mode, "mode", "change or display EFI text modes", command_mode); 1144 1145 static int 1146 command_mode(int argc, char *argv[]) 1147 { 1148 UINTN cols, rows; 1149 unsigned int mode; 1150 int i; 1151 char *cp; 1152 EFI_STATUS status; 1153 SIMPLE_TEXT_OUTPUT_INTERFACE *conout; 1154 EFI_CONSOLE_CONTROL_SCREEN_MODE sm; 1155 1156 if (plat_stdout_is_framebuffer()) 1157 sm = EfiConsoleControlScreenGraphics; 1158 else 1159 sm = EfiConsoleControlScreenText; 1160 1161 conout = ST->ConOut; 1162 1163 if (argc > 1) { 1164 mode = strtol(argv[1], &cp, 0); 1165 if (cp[0] != '\0') { 1166 printf("Invalid mode\n"); 1167 return (CMD_ERROR); 1168 } 1169 status = conout->QueryMode(conout, mode, &cols, &rows); 1170 if (EFI_ERROR(status)) { 1171 printf("invalid mode %d\n", mode); 1172 return (CMD_ERROR); 1173 } 1174 status = conout->SetMode(conout, mode); 1175 if (EFI_ERROR(status)) { 1176 printf("couldn't set mode %d\n", mode); 1177 return (CMD_ERROR); 1178 } 1179 plat_cons_update_mode(sm); 1180 return (CMD_OK); 1181 } 1182 1183 printf("Current mode: %d\n", conout->Mode->Mode); 1184 for (i = 0; i <= conout->Mode->MaxMode; i++) { 1185 status = conout->QueryMode(conout, i, &cols, &rows); 1186 if (EFI_ERROR(status)) 1187 continue; 1188 printf("Mode %d: %u columns, %u rows\n", i, (unsigned)cols, 1189 (unsigned)rows); 1190 } 1191 1192 if (i != 0) 1193 printf("Select a mode with the command \"mode <number>\"\n"); 1194 1195 return (CMD_OK); 1196 } 1197 1198 COMMAND_SET(lsefi, "lsefi", "list EFI handles", command_lsefi); 1199 1200 static int 1201 command_lsefi(int argc __unused, char *argv[] __unused) 1202 { 1203 char *name; 1204 EFI_HANDLE *buffer = NULL; 1205 EFI_HANDLE handle; 1206 UINTN bufsz = 0, i, j; 1207 EFI_STATUS status; 1208 int ret = 0; 1209 1210 status = BS->LocateHandle(AllHandles, NULL, NULL, &bufsz, buffer); 1211 if (status != EFI_BUFFER_TOO_SMALL) { 1212 snprintf(command_errbuf, sizeof (command_errbuf), 1213 "unexpected error: %lld", (long long)status); 1214 return (CMD_ERROR); 1215 } 1216 if ((buffer = malloc(bufsz)) == NULL) { 1217 sprintf(command_errbuf, "out of memory"); 1218 return (CMD_ERROR); 1219 } 1220 1221 status = BS->LocateHandle(AllHandles, NULL, NULL, &bufsz, buffer); 1222 if (EFI_ERROR(status)) { 1223 free(buffer); 1224 snprintf(command_errbuf, sizeof (command_errbuf), 1225 "LocateHandle() error: %lld", (long long)status); 1226 return (CMD_ERROR); 1227 } 1228 1229 pager_open(); 1230 for (i = 0; i < (bufsz / sizeof (EFI_HANDLE)); i++) { 1231 UINTN nproto = 0; 1232 EFI_GUID **protocols = NULL; 1233 EFI_DEVICE_PATH *dp; 1234 CHAR16 *text; 1235 1236 handle = buffer[i]; 1237 printf("Handle %p", handle); 1238 if (pager_output("\n")) 1239 break; 1240 1241 ret = 0; 1242 dp = efi_lookup_devpath(handle); 1243 if (dp != NULL) { 1244 text = efi_devpath_name(dp); 1245 if (text != NULL) { 1246 printf(" %S", text); 1247 efi_free_devpath_name(text); 1248 ret = pager_output("\n"); 1249 } 1250 efi_close_devpath(handle); 1251 } 1252 if (ret != 0) 1253 break; 1254 1255 status = BS->ProtocolsPerHandle(handle, &protocols, &nproto); 1256 if (EFI_ERROR(status)) { 1257 snprintf(command_errbuf, sizeof (command_errbuf), 1258 "ProtocolsPerHandle() error: %lld", 1259 (long long)status); 1260 continue; 1261 } 1262 1263 for (j = 0; j < nproto; j++) { 1264 if (efi_guid_to_name(protocols[j], &name) == true) { 1265 printf(" %s", name); 1266 free(name); 1267 } else { 1268 printf("Error while translating UUID to name"); 1269 } 1270 if ((ret = pager_output("\n")) != 0) 1271 break; 1272 } 1273 BS->FreePool(protocols); 1274 if (ret != 0) 1275 break; 1276 } 1277 pager_close(); 1278 free(buffer); 1279 return (CMD_OK); 1280 } 1281 1282 #ifdef LOADER_FDT_SUPPORT 1283 extern int command_fdt_internal(int argc, char *argv[]); 1284 1285 /* 1286 * Since proper fdt command handling function is defined in fdt_loader_cmd.c, 1287 * and declaring it as extern is in contradiction with COMMAND_SET() macro 1288 * (which uses static pointer), we're defining wrapper function, which 1289 * calls the proper fdt handling routine. 1290 */ 1291 static int 1292 command_fdt(int argc, char *argv[]) 1293 { 1294 return (command_fdt_internal(argc, argv)); 1295 } 1296 1297 COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt); 1298 #endif 1299 1300 /* 1301 * Chain load another efi loader. 1302 */ 1303 static int 1304 command_chain(int argc, char *argv[]) 1305 { 1306 EFI_HANDLE loaderhandle; 1307 EFI_LOADED_IMAGE_PROTOCOL *loaded_image; 1308 EFI_STATUS status; 1309 struct stat st; 1310 struct devdesc *dev; 1311 char *name, *path; 1312 void *buf; 1313 int fd; 1314 1315 if (argc < 2) { 1316 command_errmsg = "wrong number of arguments"; 1317 return (CMD_ERROR); 1318 } 1319 1320 name = argv[1]; 1321 1322 if ((fd = open(name, O_RDONLY)) < 0) { 1323 command_errmsg = "no such file"; 1324 return (CMD_ERROR); 1325 } 1326 1327 if (fstat(fd, &st) < -1) { 1328 command_errmsg = "stat failed"; 1329 close(fd); 1330 return (CMD_ERROR); 1331 } 1332 1333 status = BS->AllocatePool(EfiLoaderCode, (UINTN)st.st_size, &buf); 1334 if (status != EFI_SUCCESS) { 1335 command_errmsg = "failed to allocate buffer"; 1336 close(fd); 1337 return (CMD_ERROR); 1338 } 1339 if (read(fd, buf, st.st_size) != st.st_size) { 1340 command_errmsg = "error while reading the file"; 1341 (void) BS->FreePool(buf); 1342 close(fd); 1343 return (CMD_ERROR); 1344 } 1345 close(fd); 1346 status = BS->LoadImage(FALSE, IH, NULL, buf, st.st_size, &loaderhandle); 1347 (void) BS->FreePool(buf); 1348 if (status != EFI_SUCCESS) { 1349 printf("LoadImage failed: status code: %lu\n", 1350 DECODE_ERROR(status)); 1351 return (CMD_ERROR); 1352 } 1353 status = OpenProtocolByHandle(loaderhandle, 1354 &gEfiLoadedImageProtocolGuid, (void **)&loaded_image); 1355 1356 if (argc > 2) { 1357 int i, len = 0; 1358 CHAR16 *argp; 1359 1360 for (i = 2; i < argc; i++) 1361 len += strlen(argv[i]) + 1; 1362 1363 len *= sizeof (*argp); 1364 loaded_image->LoadOptions = argp = malloc(len); 1365 if (loaded_image->LoadOptions == NULL) { 1366 command_errmsg = "Adding LoadOptions: out of memory"; 1367 (void) BS->UnloadImage(loaded_image); 1368 return (CMD_ERROR); 1369 } 1370 loaded_image->LoadOptionsSize = len; 1371 for (i = 2; i < argc; i++) { 1372 char *ptr = argv[i]; 1373 while (*ptr) 1374 *(argp++) = *(ptr++); 1375 *(argp++) = ' '; 1376 } 1377 *(--argv) = 0; 1378 } 1379 1380 if (efi_getdev((void **)&dev, name, (const char **)&path) == 0) { 1381 struct zfs_devdesc *z_dev; 1382 struct disk_devdesc *d_dev; 1383 pdinfo_t *hd, *pd; 1384 1385 switch (dev->d_dev->dv_type) { 1386 case DEVT_ZFS: 1387 z_dev = (struct zfs_devdesc *)dev; 1388 loaded_image->DeviceHandle = 1389 efizfs_get_handle_by_guid(z_dev->pool_guid); 1390 break; 1391 case DEVT_NET: 1392 loaded_image->DeviceHandle = 1393 efi_find_handle(dev->d_dev, dev->d_unit); 1394 break; 1395 default: 1396 hd = efiblk_get_pdinfo(dev); 1397 if (STAILQ_EMPTY(&hd->pd_part)) { 1398 loaded_image->DeviceHandle = hd->pd_handle; 1399 break; 1400 } 1401 d_dev = (struct disk_devdesc *)dev; 1402 STAILQ_FOREACH(pd, &hd->pd_part, pd_link) { 1403 /* 1404 * d_partition should be 255 1405 */ 1406 if (pd->pd_unit == d_dev->d_slice) { 1407 loaded_image->DeviceHandle = 1408 pd->pd_handle; 1409 break; 1410 } 1411 } 1412 break; 1413 } 1414 } 1415 1416 dev_cleanup(); 1417 status = BS->StartImage(loaderhandle, NULL, NULL); 1418 if (status != EFI_SUCCESS) { 1419 printf("StartImage failed: status code: %lu\n", 1420 DECODE_ERROR(status)); 1421 free(loaded_image->LoadOptions); 1422 loaded_image->LoadOptions = NULL; 1423 status = BS->UnloadImage(loaded_image); 1424 return (CMD_ERROR); 1425 } 1426 1427 return (CMD_ERROR); 1428 } 1429 1430 COMMAND_SET(chain, "chain", "chain load file", command_chain); 1431