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