main.c revision 344412
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: stable/11/stand/efi/loader/main.c 344412 2019-02-21 02:52:27Z kevans $");
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
57struct arch_switch archsw;	/* MI/MD interface boundary */
58
59EFI_GUID acpi = ACPI_TABLE_GUID;
60EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
61EFI_GUID devid = DEVICE_PATH_PROTOCOL;
62EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
63EFI_GUID mps = MPS_TABLE_GUID;
64EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
65EFI_GUID smbios = SMBIOS_TABLE_GUID;
66EFI_GUID smbios3 = SMBIOS3_TABLE_GUID;
67EFI_GUID dxe = DXE_SERVICES_TABLE_GUID;
68EFI_GUID hoblist = HOB_LIST_TABLE_GUID;
69EFI_GUID lzmadecomp = LZMA_DECOMPRESSION_GUID;
70EFI_GUID mpcore = ARM_MP_CORE_INFO_TABLE_GUID;
71EFI_GUID esrt = ESRT_TABLE_GUID;
72EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
73EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
74EFI_GUID fdtdtb = FDT_TABLE_GUID;
75EFI_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 */
84static int fail_timeout = 5;
85
86static bool
87has_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	}
163out:
164	free(hin);
165	return retval;
166}
167
168static void
169set_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
176static void
177set_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
186static void
187set_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
197static void
198set_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
225static bool
226sanity_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
235static bool
236probe_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
253static bool
254try_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
277static int
278find_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	}
342
343	/*
344	 * Try the device handle from our loaded image first.  If that
345	 * fails, use the device path from the loaded image and see if
346	 * any of the nodes in that path match one of the enumerated
347	 * handles. Currently, this handle list is only for netboot.
348	 */
349	if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &extra) == 0) {
350		set_currdev_devsw(dev, unit);
351		if (sanity_check_currdev())
352			return (0);
353	}
354
355	copy = NULL;
356	devpath = efi_lookup_image_devpath(IH);
357	while (devpath != NULL) {
358		h = efi_devpath_handle(devpath);
359		if (h == NULL)
360			break;
361
362		free(copy);
363		copy = NULL;
364
365		if (efi_handle_lookup(h, &dev, &unit, &extra) == 0) {
366			set_currdev_devsw(dev, unit);
367			if (sanity_check_currdev())
368				return (0);
369		}
370
371		devpath = efi_lookup_devpath(h);
372		if (devpath != NULL) {
373			copy = efi_devpath_trim(devpath);
374			devpath = copy;
375		}
376	}
377	free(copy);
378
379	return (ENOENT);
380}
381
382static bool
383interactive_interrupt(const char *msg)
384{
385	time_t now, then, last;
386
387	last = 0;
388	now = then = getsecs();
389	printf("%s\n", msg);
390	if (fail_timeout == -2)		/* Always break to OK */
391		return (true);
392	if (fail_timeout == -1)		/* Never break to OK */
393		return (false);
394	do {
395		if (last != now) {
396			printf("press any key to interrupt reboot in %d seconds\r",
397			    fail_timeout - (int)(now - then));
398			last = now;
399		}
400
401		/* XXX no pause or timeout wait for char */
402		if (ischar())
403			return (true);
404		now = getsecs();
405	} while (now - then < fail_timeout);
406	return (false);
407}
408
409static int
410parse_args(int argc, CHAR16 *argv[])
411{
412	int i, j, howto;
413	bool vargood;
414	char var[128];
415
416	/*
417	 * Parse the args to set the console settings, etc
418	 * boot1.efi passes these in, if it can read /boot.config or /boot/config
419	 * or iPXE may be setup to pass these in. Or the optional argument in the
420	 * boot environment was used to pass these arguments in (in which case
421	 * neither /boot.config nor /boot/config are consulted).
422	 *
423	 * Loop through the args, and for each one that contains an '=' that is
424	 * not the first character, add it to the environment.  This allows
425	 * loader and kernel env vars to be passed on the command line.  Convert
426	 * args from UCS-2 to ASCII (16 to 8 bit) as they are copied (though this
427	 * method is flawed for non-ASCII characters).
428	 */
429	howto = 0;
430	for (i = 1; i < argc; i++) {
431		cpy16to8(argv[i], var, sizeof(var));
432		howto |= boot_parse_arg(var);
433	}
434
435	return (howto);
436}
437
438static void
439setenv_int(const char *key, int val)
440{
441	char buf[20];
442
443	snprintf(buf, sizeof(buf), "%d", val);
444	setenv(key, buf, 1);
445}
446
447/*
448 * Parse ConOut (the list of consoles active) and see if we can find a
449 * serial port and/or a video port. It would be nice to also walk the
450 * ACPI name space to map the UID for the serial port to a port. The
451 * latter is especially hard.
452 */
453static int
454parse_uefi_con_out(void)
455{
456	int how, rv;
457	int vid_seen = 0, com_seen = 0, seen = 0;
458	size_t sz;
459	char buf[4096], *ep;
460	EFI_DEVICE_PATH *node;
461	ACPI_HID_DEVICE_PATH  *acpi;
462	UART_DEVICE_PATH  *uart;
463	bool pci_pending;
464
465	how = 0;
466	sz = sizeof(buf);
467	rv = efi_global_getenv("ConOut", buf, &sz);
468	if (rv != EFI_SUCCESS)
469		goto out;
470	ep = buf + sz;
471	node = (EFI_DEVICE_PATH *)buf;
472	while ((char *)node < ep) {
473		pci_pending = false;
474		if (DevicePathType(node) == ACPI_DEVICE_PATH &&
475		    DevicePathSubType(node) == ACPI_DP) {
476			/* Check for Serial node */
477			acpi = (void *)node;
478			if (EISA_ID_TO_NUM(acpi->HID) == 0x501) {
479				setenv_int("efi_8250_uid", acpi->UID);
480				com_seen = ++seen;
481			}
482		} else if (DevicePathType(node) == MESSAGING_DEVICE_PATH &&
483		    DevicePathSubType(node) == MSG_UART_DP) {
484
485			uart = (void *)node;
486			setenv_int("efi_com_speed", uart->BaudRate);
487		} else if (DevicePathType(node) == ACPI_DEVICE_PATH &&
488		    DevicePathSubType(node) == ACPI_ADR_DP) {
489			/* Check for AcpiAdr() Node for video */
490			vid_seen = ++seen;
491		} else if (DevicePathType(node) == HARDWARE_DEVICE_PATH &&
492		    DevicePathSubType(node) == HW_PCI_DP) {
493			/*
494			 * Note, vmware fusion has a funky console device
495			 *	PciRoot(0x0)/Pci(0xf,0x0)
496			 * which we can only detect at the end since we also
497			 * have to cope with:
498			 *	PciRoot(0x0)/Pci(0x1f,0x0)/Serial(0x1)
499			 * so only match it if it's last.
500			 */
501			pci_pending = true;
502		}
503		node = NextDevicePathNode(node); /* Skip the end node */
504	}
505	if (pci_pending && vid_seen == 0)
506		vid_seen = ++seen;
507
508	/*
509	 * Truth table for RB_MULTIPLE | RB_SERIAL
510	 * Value		Result
511	 * 0			Use only video console
512	 * RB_SERIAL		Use only serial console
513	 * RB_MULTIPLE		Use both video and serial console
514	 *			(but video is primary so gets rc messages)
515	 * both			Use both video and serial console
516	 *			(but serial is primary so gets rc messages)
517	 *
518	 * Try to honor this as best we can. If only one of serial / video
519	 * found, then use that. Otherwise, use the first one we found.
520	 * This also implies if we found nothing, default to video.
521	 */
522	how = 0;
523	if (vid_seen && com_seen) {
524		how |= RB_MULTIPLE;
525		if (com_seen < vid_seen)
526			how |= RB_SERIAL;
527	} else if (com_seen)
528		how |= RB_SERIAL;
529out:
530	return (how);
531}
532
533EFI_STATUS
534main(int argc, CHAR16 *argv[])
535{
536	EFI_GUID *guid;
537	int howto, i, uhowto;
538	UINTN k;
539	bool has_kbd;
540	char *s;
541	EFI_DEVICE_PATH *imgpath;
542	CHAR16 *text;
543	EFI_STATUS status;
544	UINT16 boot_current;
545	size_t sz;
546	UINT16 boot_order[100];
547	EFI_LOADED_IMAGE *img;
548
549	archsw.arch_autoload = efi_autoload;
550	archsw.arch_getdev = efi_getdev;
551	archsw.arch_copyin = efi_copyin;
552	archsw.arch_copyout = efi_copyout;
553	archsw.arch_readin = efi_readin;
554#ifdef EFI_ZFS_BOOT
555	/* Note this needs to be set before ZFS init. */
556	archsw.arch_zfs_probe = efi_zfs_probe;
557#endif
558
559        /* Get our loaded image protocol interface structure. */
560	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
561
562#ifdef EFI_ZFS_BOOT
563	/* Tell ZFS probe code where we booted from */
564	efizfs_set_preferred(img->DeviceHandle);
565#endif
566	/* Init the time source */
567	efi_time_init();
568
569	has_kbd = has_keyboard();
570
571	/*
572	 * XXX Chicken-and-egg problem; we want to have console output
573	 * early, but some console attributes may depend on reading from
574	 * eg. the boot device, which we can't do yet.  We can use
575	 * printf() etc. once this is done.
576	 */
577	setenv("console", "efi", 1);
578	cons_probe();
579
580	/*
581	 * Initialise the block cache. Set the upper limit.
582	 */
583	bcache_init(32768, 512);
584
585	howto = parse_args(argc, argv);
586	if (!has_kbd && (howto & RB_PROBE))
587		howto |= RB_SERIAL | RB_MULTIPLE;
588	howto &= ~RB_PROBE;
589	uhowto = parse_uefi_con_out();
590
591	/*
592	 * We now have two notions of console. howto should be viewed as
593	 * overrides. If console is already set, don't set it again.
594	 */
595#define	VIDEO_ONLY	0
596#define	SERIAL_ONLY	RB_SERIAL
597#define	VID_SER_BOTH	RB_MULTIPLE
598#define	SER_VID_BOTH	(RB_SERIAL | RB_MULTIPLE)
599#define	CON_MASK	(RB_SERIAL | RB_MULTIPLE)
600	if (strcmp(getenv("console"), "efi") == 0) {
601		if ((howto & CON_MASK) == 0) {
602			/* No override, uhowto is controlling and efi cons is perfect */
603			howto = howto | (uhowto & CON_MASK);
604			setenv("console", "efi", 1);
605		} else if ((howto & CON_MASK) == (uhowto & CON_MASK)) {
606			/* override matches what UEFI told us, efi console is perfect */
607			setenv("console", "efi", 1);
608		} else if ((uhowto & (CON_MASK)) != 0) {
609			/*
610			 * We detected a serial console on ConOut. All possible
611			 * overrides include serial. We can't really override what efi
612			 * gives us, so we use it knowing it's the best choice.
613			 */
614			setenv("console", "efi", 1);
615		} else {
616			/*
617			 * We detected some kind of serial in the override, but ConOut
618			 * has no serial, so we have to sort out which case it really is.
619			 */
620			switch (howto & CON_MASK) {
621			case SERIAL_ONLY:
622				setenv("console", "comconsole", 1);
623				break;
624			case VID_SER_BOTH:
625				setenv("console", "efi comconsole", 1);
626				break;
627			case SER_VID_BOTH:
628				setenv("console", "comconsole efi", 1);
629				break;
630				/* case VIDEO_ONLY can't happen -- it's the first if above */
631			}
632		}
633	}
634	/*
635	 * howto is set now how we want to export the flags to the kernel, so
636	 * set the env based on it.
637	 */
638	boot_howto_to_env(howto);
639
640	if (efi_copy_init()) {
641		printf("failed to allocate staging area\n");
642		return (EFI_BUFFER_TOO_SMALL);
643	}
644
645	if ((s = getenv("fail_timeout")) != NULL)
646		fail_timeout = strtol(s, NULL, 10);
647
648	/*
649	 * Scan the BLOCK IO MEDIA handles then
650	 * march through the device switch probing for things.
651	 */
652	i = efipart_inithandles();
653	if (i != 0 && i != ENOENT) {
654		printf("efipart_inithandles failed with ERRNO %d, expect "
655		    "failures\n", i);
656	}
657
658	for (i = 0; devsw[i] != NULL; i++)
659		if (devsw[i]->dv_init != NULL)
660			(devsw[i]->dv_init)();
661
662	printf("%s\n", bootprog_info);
663	printf("   Command line arguments:");
664	for (i = 0; i < argc; i++)
665		printf(" %S", argv[i]);
666	printf("\n");
667
668	printf("   EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
669	    ST->Hdr.Revision & 0xffff);
670	printf("   EFI Firmware: %S (rev %d.%02d)\n", ST->FirmwareVendor,
671	    ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
672
673
674	/* Determine the devpath of our image so we can prefer it. */
675	text = efi_devpath_name(img->FilePath);
676	if (text != NULL) {
677		printf("   Load Path: %S\n", text);
678		efi_setenv_freebsd_wcs("LoaderPath", text);
679		efi_free_devpath_name(text);
680	}
681
682	status = BS->HandleProtocol(img->DeviceHandle, &devid, (void **)&imgpath);
683	if (status == EFI_SUCCESS) {
684		text = efi_devpath_name(imgpath);
685		if (text != NULL) {
686			printf("   Load Device: %S\n", text);
687			efi_setenv_freebsd_wcs("LoaderDev", text);
688			efi_free_devpath_name(text);
689		}
690	}
691
692	boot_current = 0;
693	sz = sizeof(boot_current);
694	efi_global_getenv("BootCurrent", &boot_current, &sz);
695	printf("   BootCurrent: %04x\n", boot_current);
696
697	sz = sizeof(boot_order);
698	efi_global_getenv("BootOrder", &boot_order, &sz);
699	printf("   BootOrder:");
700	for (i = 0; i < sz / sizeof(boot_order[0]); i++)
701		printf(" %04x%s", boot_order[i],
702		    boot_order[i] == boot_current ? "[*]" : "");
703	printf("\n");
704
705	/*
706	 * Disable the watchdog timer. By default the boot manager sets
707	 * the timer to 5 minutes before invoking a boot option. If we
708	 * want to return to the boot manager, we have to disable the
709	 * watchdog timer and since we're an interactive program, we don't
710	 * want to wait until the user types "quit". The timer may have
711	 * fired by then. We don't care if this fails. It does not prevent
712	 * normal functioning in any way...
713	 */
714	BS->SetWatchdogTimer(0, 0, 0, NULL);
715
716	/*
717	 * Try and find a good currdev based on the image that was booted.
718	 * It might be desirable here to have a short pause to allow falling
719	 * through to the boot loader instead of returning instantly to follow
720	 * the boot protocol and also allow an escape hatch for users wishing
721	 * to try something different.
722	 */
723	if (find_currdev(img) != 0)
724		if (!interactive_interrupt("Failed to find bootable partition"))
725			return (EFI_NOT_FOUND);
726
727	efi_init_environment();
728
729#if !defined(__arm__)
730	for (k = 0; k < ST->NumberOfTableEntries; k++) {
731		guid = &ST->ConfigurationTable[k].VendorGuid;
732		if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) {
733			char buf[40];
734
735			snprintf(buf, sizeof(buf), "%p",
736			    ST->ConfigurationTable[k].VendorTable);
737			setenv("hint.smbios.0.mem", buf, 1);
738			smbios_detect(ST->ConfigurationTable[k].VendorTable);
739			break;
740		}
741	}
742#endif
743
744	interact();			/* doesn't return */
745
746	return (EFI_SUCCESS);		/* keep compiler happy */
747}
748
749COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
750
751static int
752command_reboot(int argc, char *argv[])
753{
754	int i;
755
756	for (i = 0; devsw[i] != NULL; ++i)
757		if (devsw[i]->dv_cleanup != NULL)
758			(devsw[i]->dv_cleanup)();
759
760	RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
761
762	/* NOTREACHED */
763	return (CMD_ERROR);
764}
765
766COMMAND_SET(quit, "quit", "exit the loader", command_quit);
767
768static int
769command_quit(int argc, char *argv[])
770{
771	exit(0);
772	return (CMD_OK);
773}
774
775COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
776
777static int
778command_memmap(int argc, char *argv[])
779{
780	UINTN sz;
781	EFI_MEMORY_DESCRIPTOR *map, *p;
782	UINTN key, dsz;
783	UINT32 dver;
784	EFI_STATUS status;
785	int i, ndesc;
786	char line[80];
787	static char *types[] = {
788	    "Reserved",
789	    "LoaderCode",
790	    "LoaderData",
791	    "BootServicesCode",
792	    "BootServicesData",
793	    "RuntimeServicesCode",
794	    "RuntimeServicesData",
795	    "ConventionalMemory",
796	    "UnusableMemory",
797	    "ACPIReclaimMemory",
798	    "ACPIMemoryNVS",
799	    "MemoryMappedIO",
800	    "MemoryMappedIOPortSpace",
801	    "PalCode"
802	};
803
804	sz = 0;
805	status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
806	if (status != EFI_BUFFER_TOO_SMALL) {
807		printf("Can't determine memory map size\n");
808		return (CMD_ERROR);
809	}
810	map = malloc(sz);
811	status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
812	if (EFI_ERROR(status)) {
813		printf("Can't read memory map\n");
814		return (CMD_ERROR);
815	}
816
817	ndesc = sz / dsz;
818	snprintf(line, sizeof(line), "%23s %12s %12s %8s %4s\n",
819	    "Type", "Physical", "Virtual", "#Pages", "Attr");
820	pager_open();
821	if (pager_output(line)) {
822		pager_close();
823		return (CMD_OK);
824	}
825
826	for (i = 0, p = map; i < ndesc;
827	     i++, p = NextMemoryDescriptor(p, dsz)) {
828		printf("%23s %012jx %012jx %08jx ", types[p->Type],
829		    (uintmax_t)p->PhysicalStart, (uintmax_t)p->VirtualStart,
830		    (uintmax_t)p->NumberOfPages);
831		if (p->Attribute & EFI_MEMORY_UC)
832			printf("UC ");
833		if (p->Attribute & EFI_MEMORY_WC)
834			printf("WC ");
835		if (p->Attribute & EFI_MEMORY_WT)
836			printf("WT ");
837		if (p->Attribute & EFI_MEMORY_WB)
838			printf("WB ");
839		if (p->Attribute & EFI_MEMORY_UCE)
840			printf("UCE ");
841		if (p->Attribute & EFI_MEMORY_WP)
842			printf("WP ");
843		if (p->Attribute & EFI_MEMORY_RP)
844			printf("RP ");
845		if (p->Attribute & EFI_MEMORY_XP)
846			printf("XP ");
847		if (pager_output("\n"))
848			break;
849	}
850
851	pager_close();
852	return (CMD_OK);
853}
854
855COMMAND_SET(configuration, "configuration", "print configuration tables",
856    command_configuration);
857
858static const char *
859guid_to_string(EFI_GUID *guid)
860{
861	static char buf[40];
862
863	sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
864	    guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
865	    guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
866	    guid->Data4[5], guid->Data4[6], guid->Data4[7]);
867	return (buf);
868}
869
870static int
871command_configuration(int argc, char *argv[])
872{
873	char line[80];
874	UINTN i;
875
876	snprintf(line, sizeof(line), "NumberOfTableEntries=%lu\n",
877		(unsigned long)ST->NumberOfTableEntries);
878	pager_open();
879	if (pager_output(line)) {
880		pager_close();
881		return (CMD_OK);
882	}
883
884	for (i = 0; i < ST->NumberOfTableEntries; i++) {
885		EFI_GUID *guid;
886
887		printf("  ");
888		guid = &ST->ConfigurationTable[i].VendorGuid;
889		if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
890			printf("MPS Table");
891		else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
892			printf("ACPI Table");
893		else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
894			printf("ACPI 2.0 Table");
895		else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
896			printf("SMBIOS Table %p",
897			    ST->ConfigurationTable[i].VendorTable);
898		else if (!memcmp(guid, &smbios3, sizeof(EFI_GUID)))
899			printf("SMBIOS3 Table");
900		else if (!memcmp(guid, &dxe, sizeof(EFI_GUID)))
901			printf("DXE Table");
902		else if (!memcmp(guid, &hoblist, sizeof(EFI_GUID)))
903			printf("HOB List Table");
904		else if (!memcmp(guid, &lzmadecomp, sizeof(EFI_GUID)))
905			printf("LZMA Compression");
906		else if (!memcmp(guid, &mpcore, sizeof(EFI_GUID)))
907			printf("ARM MpCore Information Table");
908		else if (!memcmp(guid, &esrt, sizeof(EFI_GUID)))
909			printf("ESRT Table");
910		else if (!memcmp(guid, &memtype, sizeof(EFI_GUID)))
911			printf("Memory Type Information Table");
912		else if (!memcmp(guid, &debugimg, sizeof(EFI_GUID)))
913			printf("Debug Image Info Table");
914		else if (!memcmp(guid, &fdtdtb, sizeof(EFI_GUID)))
915			printf("FDT Table");
916		else
917			printf("Unknown Table (%s)", guid_to_string(guid));
918		snprintf(line, sizeof(line), " at %p\n",
919		    ST->ConfigurationTable[i].VendorTable);
920		if (pager_output(line))
921			break;
922	}
923
924	pager_close();
925	return (CMD_OK);
926}
927
928
929COMMAND_SET(mode, "mode", "change or display EFI text modes", command_mode);
930
931static int
932command_mode(int argc, char *argv[])
933{
934	UINTN cols, rows;
935	unsigned int mode;
936	int i;
937	char *cp;
938	char rowenv[8];
939	EFI_STATUS status;
940	SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
941	extern void HO(void);
942
943	conout = ST->ConOut;
944
945	if (argc > 1) {
946		mode = strtol(argv[1], &cp, 0);
947		if (cp[0] != '\0') {
948			printf("Invalid mode\n");
949			return (CMD_ERROR);
950		}
951		status = conout->QueryMode(conout, mode, &cols, &rows);
952		if (EFI_ERROR(status)) {
953			printf("invalid mode %d\n", mode);
954			return (CMD_ERROR);
955		}
956		status = conout->SetMode(conout, mode);
957		if (EFI_ERROR(status)) {
958			printf("couldn't set mode %d\n", mode);
959			return (CMD_ERROR);
960		}
961		sprintf(rowenv, "%u", (unsigned)rows);
962		setenv("LINES", rowenv, 1);
963		HO();		/* set cursor */
964		return (CMD_OK);
965	}
966
967	printf("Current mode: %d\n", conout->Mode->Mode);
968	for (i = 0; i <= conout->Mode->MaxMode; i++) {
969		status = conout->QueryMode(conout, i, &cols, &rows);
970		if (EFI_ERROR(status))
971			continue;
972		printf("Mode %d: %u columns, %u rows\n", i, (unsigned)cols,
973		    (unsigned)rows);
974	}
975
976	if (i != 0)
977		printf("Select a mode with the command \"mode <number>\"\n");
978
979	return (CMD_OK);
980}
981
982#ifdef LOADER_FDT_SUPPORT
983extern int command_fdt_internal(int argc, char *argv[]);
984
985/*
986 * Since proper fdt command handling function is defined in fdt_loader_cmd.c,
987 * and declaring it as extern is in contradiction with COMMAND_SET() macro
988 * (which uses static pointer), we're defining wrapper function, which
989 * calls the proper fdt handling routine.
990 */
991static int
992command_fdt(int argc, char *argv[])
993{
994
995	return (command_fdt_internal(argc, argv));
996}
997
998COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
999#endif
1000
1001/*
1002 * Chain load another efi loader.
1003 */
1004static int
1005command_chain(int argc, char *argv[])
1006{
1007	EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
1008	EFI_HANDLE loaderhandle;
1009	EFI_LOADED_IMAGE *loaded_image;
1010	EFI_STATUS status;
1011	struct stat st;
1012	struct devdesc *dev;
1013	char *name, *path;
1014	void *buf;
1015	int fd;
1016
1017	if (argc < 2) {
1018		command_errmsg = "wrong number of arguments";
1019		return (CMD_ERROR);
1020	}
1021
1022	name = argv[1];
1023
1024	if ((fd = open(name, O_RDONLY)) < 0) {
1025		command_errmsg = "no such file";
1026		return (CMD_ERROR);
1027	}
1028
1029	if (fstat(fd, &st) < -1) {
1030		command_errmsg = "stat failed";
1031		close(fd);
1032		return (CMD_ERROR);
1033	}
1034
1035	status = BS->AllocatePool(EfiLoaderCode, (UINTN)st.st_size, &buf);
1036	if (status != EFI_SUCCESS) {
1037		command_errmsg = "failed to allocate buffer";
1038		close(fd);
1039		return (CMD_ERROR);
1040	}
1041	if (read(fd, buf, st.st_size) != st.st_size) {
1042		command_errmsg = "error while reading the file";
1043		(void)BS->FreePool(buf);
1044		close(fd);
1045		return (CMD_ERROR);
1046	}
1047	close(fd);
1048	status = BS->LoadImage(FALSE, IH, NULL, buf, st.st_size, &loaderhandle);
1049	(void)BS->FreePool(buf);
1050	if (status != EFI_SUCCESS) {
1051		command_errmsg = "LoadImage failed";
1052		return (CMD_ERROR);
1053	}
1054	status = BS->HandleProtocol(loaderhandle, &LoadedImageGUID,
1055	    (void **)&loaded_image);
1056
1057	if (argc > 2) {
1058		int i, len = 0;
1059		CHAR16 *argp;
1060
1061		for (i = 2; i < argc; i++)
1062			len += strlen(argv[i]) + 1;
1063
1064		len *= sizeof (*argp);
1065		loaded_image->LoadOptions = argp = malloc (len);
1066		loaded_image->LoadOptionsSize = len;
1067		for (i = 2; i < argc; i++) {
1068			char *ptr = argv[i];
1069			while (*ptr)
1070				*(argp++) = *(ptr++);
1071			*(argp++) = ' ';
1072		}
1073		*(--argv) = 0;
1074	}
1075
1076	if (efi_getdev((void **)&dev, name, (const char **)&path) == 0) {
1077#ifdef EFI_ZFS_BOOT
1078		struct zfs_devdesc *z_dev;
1079#endif
1080		struct disk_devdesc *d_dev;
1081		pdinfo_t *hd, *pd;
1082
1083		switch (dev->d_dev->dv_type) {
1084#ifdef EFI_ZFS_BOOT
1085		case DEVT_ZFS:
1086			z_dev = (struct zfs_devdesc *)dev;
1087			loaded_image->DeviceHandle =
1088			    efizfs_get_handle_by_guid(z_dev->pool_guid);
1089			break;
1090#endif
1091		case DEVT_NET:
1092			loaded_image->DeviceHandle =
1093			    efi_find_handle(dev->d_dev, dev->d_unit);
1094			break;
1095		default:
1096			hd = efiblk_get_pdinfo(dev);
1097			if (STAILQ_EMPTY(&hd->pd_part)) {
1098				loaded_image->DeviceHandle = hd->pd_handle;
1099				break;
1100			}
1101			d_dev = (struct disk_devdesc *)dev;
1102			STAILQ_FOREACH(pd, &hd->pd_part, pd_link) {
1103				/*
1104				 * d_partition should be 255
1105				 */
1106				if (pd->pd_unit == (uint32_t)d_dev->d_slice) {
1107					loaded_image->DeviceHandle =
1108					    pd->pd_handle;
1109					break;
1110				}
1111			}
1112			break;
1113		}
1114	}
1115
1116	dev_cleanup();
1117	status = BS->StartImage(loaderhandle, NULL, NULL);
1118	if (status != EFI_SUCCESS) {
1119		command_errmsg = "StartImage failed";
1120		free(loaded_image->LoadOptions);
1121		loaded_image->LoadOptions = NULL;
1122		status = BS->UnloadImage(loaded_image);
1123		return (CMD_ERROR);
1124	}
1125
1126	return (CMD_ERROR);	/* not reached */
1127}
1128
1129COMMAND_SET(chain, "chain", "chain load file", command_chain);
1130