xref: /freebsd/stand/efi/loader/main.c (revision 1f8b431d185416f70e96f03b8fd69b98442b1913)
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 __FBSDID("$FreeBSD$");
30 
31 #include <stand.h>
32 
33 #include <sys/disk.h>
34 #include <sys/param.h>
35 #include <sys/reboot.h>
36 #include <sys/boot.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <setjmp.h>
40 #include <disk.h>
41 
42 #include <efi.h>
43 #include <efilib.h>
44 
45 #include <uuid.h>
46 
47 #include <bootstrap.h>
48 #include <smbios.h>
49 
50 #ifdef EFI_ZFS_BOOT
51 #include <libzfs.h>
52 #include "efizfs.h"
53 #endif
54 
55 #include "loader_efi.h"
56 
57 struct arch_switch archsw;	/* MI/MD interface boundary */
58 
59 EFI_GUID acpi = ACPI_TABLE_GUID;
60 EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
61 EFI_GUID devid = DEVICE_PATH_PROTOCOL;
62 EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
63 EFI_GUID mps = MPS_TABLE_GUID;
64 EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
65 EFI_GUID smbios = SMBIOS_TABLE_GUID;
66 EFI_GUID smbios3 = SMBIOS3_TABLE_GUID;
67 EFI_GUID dxe = DXE_SERVICES_TABLE_GUID;
68 EFI_GUID hoblist = HOB_LIST_TABLE_GUID;
69 EFI_GUID lzmadecomp = LZMA_DECOMPRESSION_GUID;
70 EFI_GUID mpcore = ARM_MP_CORE_INFO_TABLE_GUID;
71 EFI_GUID esrt = ESRT_TABLE_GUID;
72 EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
73 EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
74 EFI_GUID fdtdtb = FDT_TABLE_GUID;
75 EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL;
76 
77 /*
78  * Number of seconds to wait for a keystroke before exiting with failure
79  * in the event no currdev is found. -2 means always break, -1 means
80  * never break, 0 means poll once and then reboot, > 0 means wait for
81  * that many seconds. "fail_timeout" can be set in the environment as
82  * well.
83  */
84 static int fail_timeout = 5;
85 
86 static bool
87 has_keyboard(void)
88 {
89 	EFI_STATUS status;
90 	EFI_DEVICE_PATH *path;
91 	EFI_HANDLE *hin, *hin_end, *walker;
92 	UINTN sz;
93 	bool retval = false;
94 
95 	/*
96 	 * Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and
97 	 * do the typical dance to get the right sized buffer.
98 	 */
99 	sz = 0;
100 	hin = NULL;
101 	status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz, 0);
102 	if (status == EFI_BUFFER_TOO_SMALL) {
103 		hin = (EFI_HANDLE *)malloc(sz);
104 		status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz,
105 		    hin);
106 		if (EFI_ERROR(status))
107 			free(hin);
108 	}
109 	if (EFI_ERROR(status))
110 		return retval;
111 
112 	/*
113 	 * Look at each of the handles. If it supports the device path protocol,
114 	 * use it to get the device path for this handle. Then see if that
115 	 * device path matches either the USB device path for keyboards or the
116 	 * legacy device path for keyboards.
117 	 */
118 	hin_end = &hin[sz / sizeof(*hin)];
119 	for (walker = hin; walker < hin_end; walker++) {
120 		status = BS->HandleProtocol(*walker, &devid, (VOID **)&path);
121 		if (EFI_ERROR(status))
122 			continue;
123 
124 		while (!IsDevicePathEnd(path)) {
125 			/*
126 			 * Check for the ACPI keyboard node. All PNP3xx nodes
127 			 * are keyboards of different flavors. Note: It is
128 			 * unclear of there's always a keyboard node when
129 			 * there's a keyboard controller, or if there's only one
130 			 * when a keyboard is detected at boot.
131 			 */
132 			if (DevicePathType(path) == ACPI_DEVICE_PATH &&
133 			    (DevicePathSubType(path) == ACPI_DP ||
134 				DevicePathSubType(path) == ACPI_EXTENDED_DP)) {
135 				ACPI_HID_DEVICE_PATH  *acpi;
136 
137 				acpi = (ACPI_HID_DEVICE_PATH *)(void *)path;
138 				if ((EISA_ID_TO_NUM(acpi->HID) & 0xff00) == 0x300 &&
139 				    (acpi->HID & 0xffff) == PNP_EISA_ID_CONST) {
140 					retval = true;
141 					goto out;
142 				}
143 			/*
144 			 * Check for USB keyboard node, if present. Unlike a
145 			 * PS/2 keyboard, these definitely only appear when
146 			 * connected to the system.
147 			 */
148 			} else if (DevicePathType(path) == MESSAGING_DEVICE_PATH &&
149 			    DevicePathSubType(path) == MSG_USB_CLASS_DP) {
150 				USB_CLASS_DEVICE_PATH *usb;
151 
152 				usb = (USB_CLASS_DEVICE_PATH *)(void *)path;
153 				if (usb->DeviceClass == 3 && /* HID */
154 				    usb->DeviceSubClass == 1 && /* Boot devices */
155 				    usb->DeviceProtocol == 1) { /* Boot keyboards */
156 					retval = true;
157 					goto out;
158 				}
159 			}
160 			path = NextDevicePathNode(path);
161 		}
162 	}
163 out:
164 	free(hin);
165 	return retval;
166 }
167 
168 static void
169 set_currdev(const char *devname)
170 {
171 
172 	env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, env_nounset);
173 	env_setenv("loaddev", EV_VOLATILE, devname, env_noset, env_nounset);
174 }
175 
176 static void
177 set_currdev_devdesc(struct devdesc *currdev)
178 {
179 	const char *devname;
180 
181 	devname = efi_fmtdev(currdev);
182 	printf("Setting currdev to %s\n", devname);
183 	set_currdev(devname);
184 }
185 
186 static void
187 set_currdev_devsw(struct devsw *dev, int unit)
188 {
189 	struct devdesc currdev;
190 
191 	currdev.d_dev = dev;
192 	currdev.d_unit = unit;
193 
194 	set_currdev_devdesc(&currdev);
195 }
196 
197 static void
198 set_currdev_pdinfo(pdinfo_t *dp)
199 {
200 
201 	/*
202 	 * Disks are special: they have partitions. if the parent
203 	 * pointer is non-null, we're a partition not a full disk
204 	 * and we need to adjust currdev appropriately.
205 	 */
206 	if (dp->pd_devsw->dv_type == DEVT_DISK) {
207 		struct disk_devdesc currdev;
208 
209 		currdev.dd.d_dev = dp->pd_devsw;
210 		if (dp->pd_parent == NULL) {
211 			currdev.dd.d_unit = dp->pd_unit;
212 			currdev.d_slice = -1;
213 			currdev.d_partition = -1;
214 		} else {
215 			currdev.dd.d_unit = dp->pd_parent->pd_unit;
216 			currdev.d_slice = dp->pd_unit;
217 			currdev.d_partition = 255;	/* Assumes GPT */
218 		}
219 		set_currdev_devdesc((struct devdesc *)&currdev);
220 	} else {
221 		set_currdev_devsw(dp->pd_devsw, dp->pd_unit);
222 	}
223 }
224 
225 static bool
226 sanity_check_currdev(void)
227 {
228 	struct stat st;
229 
230 	return (stat("/boot/defaults/loader.conf", &st) == 0 ||
231 	    stat("/boot/kernel/kernel", &st) == 0);
232 }
233 
234 #ifdef EFI_ZFS_BOOT
235 static bool
236 probe_zfs_currdev(uint64_t guid)
237 {
238 	char *devname;
239 	struct zfs_devdesc currdev;
240 
241 	currdev.dd.d_dev = &zfs_dev;
242 	currdev.dd.d_unit = 0;
243 	currdev.pool_guid = guid;
244 	currdev.root_guid = 0;
245 	set_currdev_devdesc((struct devdesc *)&currdev);
246 	devname = efi_fmtdev(&currdev);
247 	init_zfs_bootenv(devname);
248 
249 	return (sanity_check_currdev());
250 }
251 #endif
252 
253 static bool
254 try_as_currdev(pdinfo_t *hd, pdinfo_t *pp)
255 {
256 	uint64_t guid;
257 
258 #ifdef EFI_ZFS_BOOT
259 	/*
260 	 * If there's a zpool on this device, try it as a ZFS
261 	 * filesystem, which has somewhat different setup than all
262 	 * other types of fs due to imperfect loader integration.
263 	 * This all stems from ZFS being both a device (zpool) and
264 	 * a filesystem, plus the boot env feature.
265 	 */
266 	if (efizfs_get_guid_by_handle(pp->pd_handle, &guid))
267 		return (probe_zfs_currdev(guid));
268 #endif
269 	/*
270 	 * All other filesystems just need the pdinfo
271 	 * initialized in the standard way.
272 	 */
273 	set_currdev_pdinfo(pp);
274 	return (sanity_check_currdev());
275 }
276 
277 static int
278 find_currdev(EFI_LOADED_IMAGE *img)
279 {
280 	pdinfo_t *dp, *pp;
281 	EFI_DEVICE_PATH *devpath, *copy;
282 	EFI_HANDLE h;
283 	CHAR16 *text;
284 	struct devsw *dev;
285 	int unit;
286 	uint64_t extra;
287 	char *rootdev;
288 
289 	rootdev = getenv("rootdev");
290 	if (rootdev != NULL) {
291 		printf("Setting currdev to configured rootdev %s\n", rootdev);
292 		set_currdev(rootdev);
293 		return (0);
294 	}
295 
296 #ifdef EFI_ZFS_BOOT
297 	/*
298 	 * Did efi_zfs_probe() detect the boot pool? If so, use the zpool
299 	 * it found, if it's sane. ZFS is the only thing that looks for
300 	 * disks and pools to boot. This may change in the future, however,
301 	 * if we allow specifying which pool to boot from via UEFI variables
302 	 * rather than the bootenv stuff that FreeBSD uses today.
303 	 */
304 	if (pool_guid != 0) {
305 		printf("Trying ZFS pool\n");
306 		if (probe_zfs_currdev(pool_guid))
307 			return (0);
308 	}
309 #endif /* EFI_ZFS_BOOT */
310 
311 	/*
312 	 * Try to find the block device by its handle based on the
313 	 * image we're booting. If we can't find a sane partition,
314 	 * search all the other partitions of the disk. We do not
315 	 * search other disks because it's a violation of the UEFI
316 	 * boot protocol to do so. We fail and let UEFI go on to
317 	 * the next candidate.
318 	 */
319 	dp = efiblk_get_pdinfo_by_handle(img->DeviceHandle);
320 	if (dp != NULL) {
321 		text = efi_devpath_name(dp->pd_devpath);
322 		if (text != NULL) {
323 			printf("Trying ESP: %S\n", text);
324 			efi_free_devpath_name(text);
325 		}
326 		set_currdev_pdinfo(dp);
327 		if (sanity_check_currdev())
328 			return (0);
329 		if (dp->pd_parent != NULL) {
330 			dp = dp->pd_parent;
331 			STAILQ_FOREACH(pp, &dp->pd_part, pd_link) {
332 				/*
333 				 * Roll up the ZFS special case
334 				 * for those partitions that have
335 				 * zpools on them
336 				 */
337 				if (try_as_currdev(dp, pp))
338 					return (0);
339 			}
340 		}
341 	} else {
342 		printf("Can't find device by handle\n");
343 	}
344 
345 	/*
346 	 * Try the device handle from our loaded image first.  If that
347 	 * fails, use the device path from the loaded image and see if
348 	 * any of the nodes in that path match one of the enumerated
349 	 * handles. Currently, this handle list is only for netboot.
350 	 */
351 	if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &extra) == 0) {
352 		set_currdev_devsw(dev, unit);
353 		if (sanity_check_currdev())
354 			return (0);
355 	}
356 
357 	copy = NULL;
358 	devpath = efi_lookup_image_devpath(IH);
359 	while (devpath != NULL) {
360 		h = efi_devpath_handle(devpath);
361 		if (h == NULL)
362 			break;
363 
364 		free(copy);
365 		copy = NULL;
366 
367 		if (efi_handle_lookup(h, &dev, &unit, &extra) == 0) {
368 			set_currdev_devsw(dev, unit);
369 			if (sanity_check_currdev())
370 				return (0);
371 		}
372 
373 		devpath = efi_lookup_devpath(h);
374 		if (devpath != NULL) {
375 			copy = efi_devpath_trim(devpath);
376 			devpath = copy;
377 		}
378 	}
379 	free(copy);
380 
381 	return (ENOENT);
382 }
383 
384 static bool
385 interactive_interrupt(const char *msg)
386 {
387 	time_t now, then, last;
388 
389 	last = 0;
390 	now = then = getsecs();
391 	printf("%s\n", msg);
392 	if (fail_timeout == -2)		/* Always break to OK */
393 		return (true);
394 	if (fail_timeout == -1)		/* Never break to OK */
395 		return (false);
396 	do {
397 		if (last != now) {
398 			printf("press any key to interrupt reboot in %d seconds\r",
399 			    fail_timeout - (int)(now - then));
400 			last = now;
401 		}
402 
403 		/* XXX no pause or timeout wait for char */
404 		if (ischar())
405 			return (true);
406 		now = getsecs();
407 	} while (now - then < fail_timeout);
408 	return (false);
409 }
410 
411 static int
412 parse_args(int argc, CHAR16 *argv[])
413 {
414 	int i, j, howto;
415 	bool vargood;
416 	char var[128];
417 
418 	/*
419 	 * Parse the args to set the console settings, etc
420 	 * boot1.efi passes these in, if it can read /boot.config or /boot/config
421 	 * or iPXE may be setup to pass these in. Or the optional argument in the
422 	 * boot environment was used to pass these arguments in (in which case
423 	 * neither /boot.config nor /boot/config are consulted).
424 	 *
425 	 * Loop through the args, and for each one that contains an '=' that is
426 	 * not the first character, add it to the environment.  This allows
427 	 * loader and kernel env vars to be passed on the command line.  Convert
428 	 * args from UCS-2 to ASCII (16 to 8 bit) as they are copied (though this
429 	 * method is flawed for non-ASCII characters).
430 	 */
431 	howto = 0;
432 	for (i = 1; i < argc; i++) {
433 		cpy16to8(argv[i], var, sizeof(var));
434 		howto |= boot_parse_arg(var);
435 	}
436 
437 	return (howto);
438 }
439 
440 /*
441  * Parse ConOut (the list of consoles active) and see if we can find a
442  * serial port and/or a video port. It would be nice to also walk the
443  * ACPI name space to map the UID for the serial port to a port. The
444  * latter is especially hard.
445  */
446 static int
447 parse_uefi_con_out(void)
448 {
449 	int how, rv;
450 	int vid_seen = 0, com_seen = 0, seen = 0;
451 	size_t sz;
452 	char buf[4096], *ep;
453 	EFI_DEVICE_PATH *node;
454 	ACPI_HID_DEVICE_PATH  *acpi;
455 	UART_DEVICE_PATH  *uart;
456 	bool pci_pending;
457 
458 	how = 0;
459 	sz = sizeof(buf);
460 	rv = efi_global_getenv("ConOut", buf, &sz);
461 	if (rv != EFI_SUCCESS)
462 		goto out;
463 	ep = buf + sz;
464 	node = (EFI_DEVICE_PATH *)buf;
465 	while ((char *)node < ep) {
466 		pci_pending = false;
467 		if (DevicePathType(node) == ACPI_DEVICE_PATH &&
468 		    DevicePathSubType(node) == ACPI_DP) {
469 			/* Check for Serial node */
470 			acpi = (void *)node;
471 			if (EISA_ID_TO_NUM(acpi->HID) == 0x501)
472 				com_seen = ++seen;
473 		} else if (DevicePathType(node) == MESSAGING_DEVICE_PATH &&
474 		    DevicePathSubType(node) == MSG_UART_DP) {
475 			char bd[16];
476 
477 			uart = (void *)node;
478 			snprintf(bd, sizeof(bd), "%d", uart->BaudRate);
479 			setenv("efi_com_speed", bd, 1);
480 		} else if (DevicePathType(node) == ACPI_DEVICE_PATH &&
481 		    DevicePathSubType(node) == ACPI_ADR_DP) {
482 			/* Check for AcpiAdr() Node for video */
483 			vid_seen = ++seen;
484 		} else if (DevicePathType(node) == HARDWARE_DEVICE_PATH &&
485 		    DevicePathSubType(node) == HW_PCI_DP) {
486 			/*
487 			 * Note, vmware fusion has a funky console device
488 			 *	PciRoot(0x0)/Pci(0xf,0x0)
489 			 * which we can only detect at the end since we also
490 			 * have to cope with:
491 			 *	PciRoot(0x0)/Pci(0x1f,0x0)/Serial(0x1)
492 			 * so only match it if it's last.
493 			 */
494 			pci_pending = true;
495 		}
496 		node = NextDevicePathNode(node); /* Skip the end node */
497 	}
498 	if (pci_pending && vid_seen == 0)
499 		vid_seen = ++seen;
500 
501 	/*
502 	 * Truth table for RB_MULTIPLE | RB_SERIAL
503 	 * Value		Result
504 	 * 0			Use only video console
505 	 * RB_SERIAL		Use only serial console
506 	 * RB_MULTIPLE		Use both video and serial console
507 	 *			(but video is primary so gets rc messages)
508 	 * both			Use both video and serial console
509 	 *			(but serial is primary so gets rc messages)
510 	 *
511 	 * Try to honor this as best we can. If only one of serial / video
512 	 * found, then use that. Otherwise, use the first one we found.
513 	 * This also implies if we found nothing, default to video.
514 	 */
515 	how = 0;
516 	if (vid_seen && com_seen) {
517 		how |= RB_MULTIPLE;
518 		if (com_seen < vid_seen)
519 			how |= RB_SERIAL;
520 	} else if (com_seen)
521 		how |= RB_SERIAL;
522 out:
523 	return (how);
524 }
525 
526 EFI_STATUS
527 main(int argc, CHAR16 *argv[])
528 {
529 	EFI_GUID *guid;
530 	int howto, i, uhowto;
531 	UINTN k;
532 	bool has_kbd;
533 	char *s;
534 	EFI_DEVICE_PATH *imgpath;
535 	CHAR16 *text;
536 	EFI_STATUS status;
537 	UINT16 boot_current;
538 	size_t sz;
539 	UINT16 boot_order[100];
540 	EFI_LOADED_IMAGE *img;
541 
542 	archsw.arch_autoload = efi_autoload;
543 	archsw.arch_getdev = efi_getdev;
544 	archsw.arch_copyin = efi_copyin;
545 	archsw.arch_copyout = efi_copyout;
546 	archsw.arch_readin = efi_readin;
547 #ifdef EFI_ZFS_BOOT
548 	/* Note this needs to be set before ZFS init. */
549 	archsw.arch_zfs_probe = efi_zfs_probe;
550 #endif
551 
552         /* Get our loaded image protocol interface structure. */
553 	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
554 
555 #ifdef EFI_ZFS_BOOT
556 	/* Tell ZFS probe code where we booted from */
557 	efizfs_set_preferred(img->DeviceHandle);
558 #endif
559 	/* Init the time source */
560 	efi_time_init();
561 
562 	has_kbd = has_keyboard();
563 
564 	/*
565 	 * XXX Chicken-and-egg problem; we want to have console output
566 	 * early, but some console attributes may depend on reading from
567 	 * eg. the boot device, which we can't do yet.  We can use
568 	 * printf() etc. once this is done.
569 	 */
570 	cons_probe();
571 
572 	/*
573 	 * Initialise the block cache. Set the upper limit.
574 	 */
575 	bcache_init(32768, 512);
576 
577 	howto = parse_args(argc, argv);
578 	if (!has_kbd && (howto & RB_PROBE))
579 		howto |= RB_SERIAL | RB_MULTIPLE;
580 	howto &= ~RB_PROBE;
581 	uhowto = parse_uefi_con_out();
582 
583 	/*
584 	 * We now have two notions of console. howto should be viewed as
585 	 * overrides. If console is already set, don't set it again.
586 	 */
587 #define	VIDEO_ONLY	0
588 #define	SERIAL_ONLY	RB_SERIAL
589 #define	VID_SER_BOTH	RB_MULTIPLE
590 #define	SER_VID_BOTH	(RB_SERIAL | RB_MULTIPLE)
591 #define	CON_MASK	(RB_SERIAL | RB_MULTIPLE)
592 	if (getenv("console") == NULL) {
593 		if ((howto & CON_MASK) == 0) {
594 			/* No override, uhowto is controlling and efi cons is perfect */
595 			howto = howto | (uhowto & CON_MASK);
596 			setenv("console", "efi", 1);
597 		} else if ((howto & CON_MASK) == (uhowto & CON_MASK)) {
598 			/* override matches what UEFI told us, efi console is perfect */
599 			setenv("console", "efi", 1);
600 		} else if ((uhowto & (CON_MASK)) != 0) {
601 			/*
602 			 * We detected a serial console on ConOut. All possible
603 			 * overrides include serial. We can't really override what efi
604 			 * gives us, so we use it knowing it's the best choice.
605 			 */
606 			setenv("console", "efi", 1);
607 		} else {
608 			/*
609 			 * We detected some kind of serial in the override, but ConOut
610 			 * has no serial, so we have to sort out which case it really is.
611 			 */
612 			switch (howto & CON_MASK) {
613 			case SERIAL_ONLY:
614 				setenv("console", "comconsole", 1);
615 				break;
616 			case VID_SER_BOTH:
617 				setenv("console", "efi comconsole", 1);
618 				break;
619 			case SER_VID_BOTH:
620 				setenv("console", "comconsole efi", 1);
621 				break;
622 				/* case VIDEO_ONLY can't happen -- it's the first if above */
623 			}
624 		}
625 	}
626 	/*
627 	 * howto is set now how we want to export the flags to the kernel, so
628 	 * set the env based on it.
629 	 */
630 	boot_howto_to_env(howto);
631 
632 	if (efi_copy_init()) {
633 		printf("failed to allocate staging area\n");
634 		return (EFI_BUFFER_TOO_SMALL);
635 	}
636 
637 	if ((s = getenv("fail_timeout")) != NULL)
638 		fail_timeout = strtol(s, NULL, 10);
639 
640 	/*
641 	 * Scan the BLOCK IO MEDIA handles then
642 	 * march through the device switch probing for things.
643 	 */
644 	if ((i = efipart_inithandles()) == 0) {
645 		for (i = 0; devsw[i] != NULL; i++)
646 			if (devsw[i]->dv_init != NULL)
647 				(devsw[i]->dv_init)();
648 	} else
649 		printf("efipart_inithandles failed %d, expect failures", i);
650 
651 	printf("%s\n", bootprog_info);
652 	printf("   Command line arguments:");
653 	for (i = 0; i < argc; i++)
654 		printf(" %S", argv[i]);
655 	printf("\n");
656 
657 	printf("   EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
658 	    ST->Hdr.Revision & 0xffff);
659 	printf("   EFI Firmware: %S (rev %d.%02d)\n", ST->FirmwareVendor,
660 	    ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
661 
662 
663 	/* Determine the devpath of our image so we can prefer it. */
664 	text = efi_devpath_name(img->FilePath);
665 	if (text != NULL) {
666 		printf("   Load Path: %S\n", text);
667 		efi_setenv_freebsd_wcs("LoaderPath", text);
668 		efi_free_devpath_name(text);
669 	}
670 
671 	status = BS->HandleProtocol(img->DeviceHandle, &devid, (void **)&imgpath);
672 	if (status == EFI_SUCCESS) {
673 		text = efi_devpath_name(imgpath);
674 		if (text != NULL) {
675 			printf("   Load Device: %S\n", text);
676 			efi_setenv_freebsd_wcs("LoaderDev", text);
677 			efi_free_devpath_name(text);
678 		}
679 	}
680 
681 	boot_current = 0;
682 	sz = sizeof(boot_current);
683 	efi_global_getenv("BootCurrent", &boot_current, &sz);
684 	printf("   BootCurrent: %04x\n", boot_current);
685 
686 	sz = sizeof(boot_order);
687 	efi_global_getenv("BootOrder", &boot_order, &sz);
688 	printf("   BootOrder:");
689 	for (i = 0; i < sz / sizeof(boot_order[0]); i++)
690 		printf(" %04x%s", boot_order[i],
691 		    boot_order[i] == boot_current ? "[*]" : "");
692 	printf("\n");
693 
694 	/*
695 	 * Disable the watchdog timer. By default the boot manager sets
696 	 * the timer to 5 minutes before invoking a boot option. If we
697 	 * want to return to the boot manager, we have to disable the
698 	 * watchdog timer and since we're an interactive program, we don't
699 	 * want to wait until the user types "quit". The timer may have
700 	 * fired by then. We don't care if this fails. It does not prevent
701 	 * normal functioning in any way...
702 	 */
703 	BS->SetWatchdogTimer(0, 0, 0, NULL);
704 
705 	/*
706 	 * Try and find a good currdev based on the image that was booted.
707 	 * It might be desirable here to have a short pause to allow falling
708 	 * through to the boot loader instead of returning instantly to follow
709 	 * the boot protocol and also allow an escape hatch for users wishing
710 	 * to try something different.
711 	 */
712 	if (find_currdev(img) != 0)
713 		if (!interactive_interrupt("Failed to find bootable partition"))
714 			return (EFI_NOT_FOUND);
715 
716 	efi_init_environment();
717 
718 #if !defined(__arm__)
719 	for (k = 0; k < ST->NumberOfTableEntries; k++) {
720 		guid = &ST->ConfigurationTable[k].VendorGuid;
721 		if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) {
722 			char buf[40];
723 
724 			snprintf(buf, sizeof(buf), "%p",
725 			    ST->ConfigurationTable[k].VendorTable);
726 			setenv("hint.smbios.0.mem", buf, 1);
727 			smbios_detect(ST->ConfigurationTable[k].VendorTable);
728 			break;
729 		}
730 	}
731 #endif
732 
733 	interact();			/* doesn't return */
734 
735 	return (EFI_SUCCESS);		/* keep compiler happy */
736 }
737 
738 COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
739 
740 static int
741 command_reboot(int argc, char *argv[])
742 {
743 	int i;
744 
745 	for (i = 0; devsw[i] != NULL; ++i)
746 		if (devsw[i]->dv_cleanup != NULL)
747 			(devsw[i]->dv_cleanup)();
748 
749 	RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
750 
751 	/* NOTREACHED */
752 	return (CMD_ERROR);
753 }
754 
755 COMMAND_SET(quit, "quit", "exit the loader", command_quit);
756 
757 static int
758 command_quit(int argc, char *argv[])
759 {
760 	exit(0);
761 	return (CMD_OK);
762 }
763 
764 COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
765 
766 static int
767 command_memmap(int argc, char *argv[])
768 {
769 	UINTN sz;
770 	EFI_MEMORY_DESCRIPTOR *map, *p;
771 	UINTN key, dsz;
772 	UINT32 dver;
773 	EFI_STATUS status;
774 	int i, ndesc;
775 	char line[80];
776 	static char *types[] = {
777 	    "Reserved",
778 	    "LoaderCode",
779 	    "LoaderData",
780 	    "BootServicesCode",
781 	    "BootServicesData",
782 	    "RuntimeServicesCode",
783 	    "RuntimeServicesData",
784 	    "ConventionalMemory",
785 	    "UnusableMemory",
786 	    "ACPIReclaimMemory",
787 	    "ACPIMemoryNVS",
788 	    "MemoryMappedIO",
789 	    "MemoryMappedIOPortSpace",
790 	    "PalCode"
791 	};
792 
793 	sz = 0;
794 	status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
795 	if (status != EFI_BUFFER_TOO_SMALL) {
796 		printf("Can't determine memory map size\n");
797 		return (CMD_ERROR);
798 	}
799 	map = malloc(sz);
800 	status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
801 	if (EFI_ERROR(status)) {
802 		printf("Can't read memory map\n");
803 		return (CMD_ERROR);
804 	}
805 
806 	ndesc = sz / dsz;
807 	snprintf(line, sizeof(line), "%23s %12s %12s %8s %4s\n",
808 	    "Type", "Physical", "Virtual", "#Pages", "Attr");
809 	pager_open();
810 	if (pager_output(line)) {
811 		pager_close();
812 		return (CMD_OK);
813 	}
814 
815 	for (i = 0, p = map; i < ndesc;
816 	     i++, p = NextMemoryDescriptor(p, dsz)) {
817 		printf("%23s %012jx %012jx %08jx ", types[p->Type],
818 		    (uintmax_t)p->PhysicalStart, (uintmax_t)p->VirtualStart,
819 		    (uintmax_t)p->NumberOfPages);
820 		if (p->Attribute & EFI_MEMORY_UC)
821 			printf("UC ");
822 		if (p->Attribute & EFI_MEMORY_WC)
823 			printf("WC ");
824 		if (p->Attribute & EFI_MEMORY_WT)
825 			printf("WT ");
826 		if (p->Attribute & EFI_MEMORY_WB)
827 			printf("WB ");
828 		if (p->Attribute & EFI_MEMORY_UCE)
829 			printf("UCE ");
830 		if (p->Attribute & EFI_MEMORY_WP)
831 			printf("WP ");
832 		if (p->Attribute & EFI_MEMORY_RP)
833 			printf("RP ");
834 		if (p->Attribute & EFI_MEMORY_XP)
835 			printf("XP ");
836 		if (pager_output("\n"))
837 			break;
838 	}
839 
840 	pager_close();
841 	return (CMD_OK);
842 }
843 
844 COMMAND_SET(configuration, "configuration", "print configuration tables",
845     command_configuration);
846 
847 static const char *
848 guid_to_string(EFI_GUID *guid)
849 {
850 	static char buf[40];
851 
852 	sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
853 	    guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
854 	    guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
855 	    guid->Data4[5], guid->Data4[6], guid->Data4[7]);
856 	return (buf);
857 }
858 
859 static int
860 command_configuration(int argc, char *argv[])
861 {
862 	char line[80];
863 	UINTN i;
864 
865 	snprintf(line, sizeof(line), "NumberOfTableEntries=%lu\n",
866 		(unsigned long)ST->NumberOfTableEntries);
867 	pager_open();
868 	if (pager_output(line)) {
869 		pager_close();
870 		return (CMD_OK);
871 	}
872 
873 	for (i = 0; i < ST->NumberOfTableEntries; i++) {
874 		EFI_GUID *guid;
875 
876 		printf("  ");
877 		guid = &ST->ConfigurationTable[i].VendorGuid;
878 		if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
879 			printf("MPS Table");
880 		else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
881 			printf("ACPI Table");
882 		else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
883 			printf("ACPI 2.0 Table");
884 		else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
885 			printf("SMBIOS Table %p",
886 			    ST->ConfigurationTable[i].VendorTable);
887 		else if (!memcmp(guid, &smbios3, sizeof(EFI_GUID)))
888 			printf("SMBIOS3 Table");
889 		else if (!memcmp(guid, &dxe, sizeof(EFI_GUID)))
890 			printf("DXE Table");
891 		else if (!memcmp(guid, &hoblist, sizeof(EFI_GUID)))
892 			printf("HOB List Table");
893 		else if (!memcmp(guid, &lzmadecomp, sizeof(EFI_GUID)))
894 			printf("LZMA Compression");
895 		else if (!memcmp(guid, &mpcore, sizeof(EFI_GUID)))
896 			printf("ARM MpCore Information Table");
897 		else if (!memcmp(guid, &esrt, sizeof(EFI_GUID)))
898 			printf("ESRT Table");
899 		else if (!memcmp(guid, &memtype, sizeof(EFI_GUID)))
900 			printf("Memory Type Information Table");
901 		else if (!memcmp(guid, &debugimg, sizeof(EFI_GUID)))
902 			printf("Debug Image Info Table");
903 		else if (!memcmp(guid, &fdtdtb, sizeof(EFI_GUID)))
904 			printf("FDT Table");
905 		else
906 			printf("Unknown Table (%s)", guid_to_string(guid));
907 		snprintf(line, sizeof(line), " at %p\n",
908 		    ST->ConfigurationTable[i].VendorTable);
909 		if (pager_output(line))
910 			break;
911 	}
912 
913 	pager_close();
914 	return (CMD_OK);
915 }
916 
917 
918 COMMAND_SET(mode, "mode", "change or display EFI text modes", command_mode);
919 
920 static int
921 command_mode(int argc, char *argv[])
922 {
923 	UINTN cols, rows;
924 	unsigned int mode;
925 	int i;
926 	char *cp;
927 	char rowenv[8];
928 	EFI_STATUS status;
929 	SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
930 	extern void HO(void);
931 
932 	conout = ST->ConOut;
933 
934 	if (argc > 1) {
935 		mode = strtol(argv[1], &cp, 0);
936 		if (cp[0] != '\0') {
937 			printf("Invalid mode\n");
938 			return (CMD_ERROR);
939 		}
940 		status = conout->QueryMode(conout, mode, &cols, &rows);
941 		if (EFI_ERROR(status)) {
942 			printf("invalid mode %d\n", mode);
943 			return (CMD_ERROR);
944 		}
945 		status = conout->SetMode(conout, mode);
946 		if (EFI_ERROR(status)) {
947 			printf("couldn't set mode %d\n", mode);
948 			return (CMD_ERROR);
949 		}
950 		sprintf(rowenv, "%u", (unsigned)rows);
951 		setenv("LINES", rowenv, 1);
952 		HO();		/* set cursor */
953 		return (CMD_OK);
954 	}
955 
956 	printf("Current mode: %d\n", conout->Mode->Mode);
957 	for (i = 0; i <= conout->Mode->MaxMode; i++) {
958 		status = conout->QueryMode(conout, i, &cols, &rows);
959 		if (EFI_ERROR(status))
960 			continue;
961 		printf("Mode %d: %u columns, %u rows\n", i, (unsigned)cols,
962 		    (unsigned)rows);
963 	}
964 
965 	if (i != 0)
966 		printf("Select a mode with the command \"mode <number>\"\n");
967 
968 	return (CMD_OK);
969 }
970 
971 #ifdef LOADER_FDT_SUPPORT
972 extern int command_fdt_internal(int argc, char *argv[]);
973 
974 /*
975  * Since proper fdt command handling function is defined in fdt_loader_cmd.c,
976  * and declaring it as extern is in contradiction with COMMAND_SET() macro
977  * (which uses static pointer), we're defining wrapper function, which
978  * calls the proper fdt handling routine.
979  */
980 static int
981 command_fdt(int argc, char *argv[])
982 {
983 
984 	return (command_fdt_internal(argc, argv));
985 }
986 
987 COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
988 #endif
989 
990 /*
991  * Chain load another efi loader.
992  */
993 static int
994 command_chain(int argc, char *argv[])
995 {
996 	EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
997 	EFI_HANDLE loaderhandle;
998 	EFI_LOADED_IMAGE *loaded_image;
999 	EFI_STATUS status;
1000 	struct stat st;
1001 	struct devdesc *dev;
1002 	char *name, *path;
1003 	void *buf;
1004 	int fd;
1005 
1006 	if (argc < 2) {
1007 		command_errmsg = "wrong number of arguments";
1008 		return (CMD_ERROR);
1009 	}
1010 
1011 	name = argv[1];
1012 
1013 	if ((fd = open(name, O_RDONLY)) < 0) {
1014 		command_errmsg = "no such file";
1015 		return (CMD_ERROR);
1016 	}
1017 
1018 	if (fstat(fd, &st) < -1) {
1019 		command_errmsg = "stat failed";
1020 		close(fd);
1021 		return (CMD_ERROR);
1022 	}
1023 
1024 	status = BS->AllocatePool(EfiLoaderCode, (UINTN)st.st_size, &buf);
1025 	if (status != EFI_SUCCESS) {
1026 		command_errmsg = "failed to allocate buffer";
1027 		close(fd);
1028 		return (CMD_ERROR);
1029 	}
1030 	if (read(fd, buf, st.st_size) != st.st_size) {
1031 		command_errmsg = "error while reading the file";
1032 		(void)BS->FreePool(buf);
1033 		close(fd);
1034 		return (CMD_ERROR);
1035 	}
1036 	close(fd);
1037 	status = BS->LoadImage(FALSE, IH, NULL, buf, st.st_size, &loaderhandle);
1038 	(void)BS->FreePool(buf);
1039 	if (status != EFI_SUCCESS) {
1040 		command_errmsg = "LoadImage failed";
1041 		return (CMD_ERROR);
1042 	}
1043 	status = BS->HandleProtocol(loaderhandle, &LoadedImageGUID,
1044 	    (void **)&loaded_image);
1045 
1046 	if (argc > 2) {
1047 		int i, len = 0;
1048 		CHAR16 *argp;
1049 
1050 		for (i = 2; i < argc; i++)
1051 			len += strlen(argv[i]) + 1;
1052 
1053 		len *= sizeof (*argp);
1054 		loaded_image->LoadOptions = argp = malloc (len);
1055 		loaded_image->LoadOptionsSize = len;
1056 		for (i = 2; i < argc; i++) {
1057 			char *ptr = argv[i];
1058 			while (*ptr)
1059 				*(argp++) = *(ptr++);
1060 			*(argp++) = ' ';
1061 		}
1062 		*(--argv) = 0;
1063 	}
1064 
1065 	if (efi_getdev((void **)&dev, name, (const char **)&path) == 0) {
1066 #ifdef EFI_ZFS_BOOT
1067 		struct zfs_devdesc *z_dev;
1068 #endif
1069 		struct disk_devdesc *d_dev;
1070 		pdinfo_t *hd, *pd;
1071 
1072 		switch (dev->d_dev->dv_type) {
1073 #ifdef EFI_ZFS_BOOT
1074 		case DEVT_ZFS:
1075 			z_dev = (struct zfs_devdesc *)dev;
1076 			loaded_image->DeviceHandle =
1077 			    efizfs_get_handle_by_guid(z_dev->pool_guid);
1078 			break;
1079 #endif
1080 		case DEVT_NET:
1081 			loaded_image->DeviceHandle =
1082 			    efi_find_handle(dev->d_dev, dev->d_unit);
1083 			break;
1084 		default:
1085 			hd = efiblk_get_pdinfo(dev);
1086 			if (STAILQ_EMPTY(&hd->pd_part)) {
1087 				loaded_image->DeviceHandle = hd->pd_handle;
1088 				break;
1089 			}
1090 			d_dev = (struct disk_devdesc *)dev;
1091 			STAILQ_FOREACH(pd, &hd->pd_part, pd_link) {
1092 				/*
1093 				 * d_partition should be 255
1094 				 */
1095 				if (pd->pd_unit == (uint32_t)d_dev->d_slice) {
1096 					loaded_image->DeviceHandle =
1097 					    pd->pd_handle;
1098 					break;
1099 				}
1100 			}
1101 			break;
1102 		}
1103 	}
1104 
1105 	dev_cleanup();
1106 	status = BS->StartImage(loaderhandle, NULL, NULL);
1107 	if (status != EFI_SUCCESS) {
1108 		command_errmsg = "StartImage failed";
1109 		free(loaded_image->LoadOptions);
1110 		loaded_image->LoadOptions = NULL;
1111 		status = BS->UnloadImage(loaded_image);
1112 		return (CMD_ERROR);
1113 	}
1114 
1115 	return (CMD_ERROR);	/* not reached */
1116 }
1117 
1118 COMMAND_SET(chain, "chain", "chain load file", command_chain);
1119