xref: /titanic_52/usr/src/boot/sys/boot/efi/boot1/boot1.c (revision 7ee590ef2b77e6a6869db9afcfa46e4950e11128)
1 /*-
2  * Copyright (c) 1998 Robert Nordier
3  * All rights reserved.
4  * Copyright (c) 2001 Robert Drehmel
5  * All rights reserved.
6  * Copyright (c) 2014 Nathan Whitehorn
7  * All rights reserved.
8  * Copyright (c) 2015 Eric McCorkle
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms are freely
12  * permitted provided that the above copyright notice and this
13  * paragraph and the following disclaimer are duplicated in all
14  * such forms.
15  *
16  * This software is provided "AS IS" and without any express or
17  * implied warranties, including, without limitation, the implied
18  * warranties of merchantability and fitness for a particular
19  * purpose.
20  */
21 
22 #include <sys/cdefs.h>
23 
24 #include <sys/param.h>
25 #include <machine/elf.h>
26 #include <machine/stdarg.h>
27 #include <stand.h>
28 
29 #include <efi.h>
30 #include <eficonsctl.h>
31 
32 #include <bootstrap.h>
33 #include "boot_module.h"
34 #include "paths.h"
35 
36 struct arch_switch archsw;
37 struct fs_ops *file_system[] = {
38 	NULL
39 };
40 
41 static const boot_module_t *boot_modules[] =
42 {
43 #ifdef EFI_ZFS_BOOT
44 	&zfs_module,
45 #endif
46 #ifdef EFI_UFS_BOOT
47 	&ufs_module
48 #endif
49 };
50 
51 #define NUM_BOOT_MODULES	nitems(boot_modules)
52 /* The initial number of handles used to query EFI for partitions. */
53 #define NUM_HANDLES_INIT	24
54 
55 EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
56 
57 EFI_SYSTEM_TABLE *systab;
58 EFI_BOOT_SERVICES *bs;
59 static EFI_HANDLE *image;
60 
61 static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
62 static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
63 static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
64 static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
65 
66 /*
67  * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
68  * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
69  * EFI methods.
70  */
71 void *
72 Malloc(size_t len, const char *file __unused, int line __unused)
73 {
74 	void *out;
75 
76 	if (bs->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS)
77 		return (out);
78 
79 	return (NULL);
80 }
81 
82 void
83 Free(void *buf, const char *file __unused, int line __unused)
84 {
85 	if (buf != NULL)
86 		(void)bs->FreePool(buf);
87 }
88 
89 /*
90  * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match,
91  * FALSE otherwise.
92  */
93 static BOOLEAN
94 nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
95 {
96 	int len;
97 
98 	if (imgpath == NULL || imgpath->Type != devpath->Type ||
99 	    imgpath->SubType != devpath->SubType)
100 		return (FALSE);
101 
102 	len = DevicePathNodeLength(imgpath);
103 	if (len != DevicePathNodeLength(devpath))
104 		return (FALSE);
105 
106 	return (memcmp(imgpath, devpath, (size_t)len) == 0);
107 }
108 
109 /*
110  * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes
111  * in imgpath and devpath match up to their respective occurences of a
112  * media node, FALSE otherwise.
113  */
114 static BOOLEAN
115 device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
116 {
117 
118 	if (imgpath == NULL)
119 		return (FALSE);
120 
121 	while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) {
122 		if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) &&
123 		    IsDevicePathType(devpath, MEDIA_DEVICE_PATH))
124 			return (TRUE);
125 
126 		if (!nodes_match(imgpath, devpath))
127 			return (FALSE);
128 
129 		imgpath = NextDevicePathNode(imgpath);
130 		devpath = NextDevicePathNode(devpath);
131 	}
132 
133 	return (FALSE);
134 }
135 
136 /*
137  * devpath_last returns the last non-path end node in devpath.
138  */
139 static EFI_DEVICE_PATH *
140 devpath_last(EFI_DEVICE_PATH *devpath)
141 {
142 
143 	while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
144 		devpath = NextDevicePathNode(devpath);
145 
146 	return (devpath);
147 }
148 
149 /*
150  * devpath_node_str is a basic output method for a devpath node which
151  * only understands a subset of the available sub types.
152  *
153  * If we switch to UEFI 2.x then we should update it to use:
154  * EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
155  */
156 static int
157 devpath_node_str(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
158 {
159 
160 	switch (devpath->Type) {
161 	case MESSAGING_DEVICE_PATH:
162 		switch (devpath->SubType) {
163 		case MSG_ATAPI_DP: {
164 			ATAPI_DEVICE_PATH *atapi;
165 
166 			atapi = (ATAPI_DEVICE_PATH *)(void *)devpath;
167 			return snprintf(buf, size, "ata(%s,%s,0x%x)",
168 			    (atapi->PrimarySecondary == 1) ?  "Sec" : "Pri",
169 			    (atapi->SlaveMaster == 1) ?  "Slave" : "Master",
170 			    atapi->Lun);
171 		}
172 		case MSG_USB_DP: {
173 			USB_DEVICE_PATH *usb;
174 
175 			usb = (USB_DEVICE_PATH *)devpath;
176 			return snprintf(buf, size, "usb(0x%02x,0x%02x)",
177 			    usb->ParentPortNumber, usb->InterfaceNumber);
178 		}
179 		case MSG_SCSI_DP: {
180 			SCSI_DEVICE_PATH *scsi;
181 
182 			scsi = (SCSI_DEVICE_PATH *)(void *)devpath;
183 			return snprintf(buf, size, "scsi(0x%02x,0x%02x)",
184 			    scsi->Pun, scsi->Lun);
185 		}
186 		case MSG_SATA_DP: {
187 			SATA_DEVICE_PATH *sata;
188 
189 			sata = (SATA_DEVICE_PATH *)(void *)devpath;
190 			return snprintf(buf, size, "sata(0x%x,0x%x,0x%x)",
191 			    sata->HBAPortNumber, sata->PortMultiplierPortNumber,
192 			    sata->Lun);
193 		}
194 		default:
195 			return snprintf(buf, size, "msg(0x%02x)",
196 			    devpath->SubType);
197 		}
198 		break;
199 	case HARDWARE_DEVICE_PATH:
200 		switch (devpath->SubType) {
201 		case HW_PCI_DP: {
202 			PCI_DEVICE_PATH *pci;
203 
204 			pci = (PCI_DEVICE_PATH *)devpath;
205 			return snprintf(buf, size, "pci(0x%02x,0x%02x)",
206 			    pci->Device, pci->Function);
207 		}
208 		default:
209 			return snprintf(buf, size, "hw(0x%02x)",
210 			    devpath->SubType);
211 		}
212 		break;
213 	case ACPI_DEVICE_PATH: {
214 		ACPI_HID_DEVICE_PATH *acpi;
215 
216 		acpi = (ACPI_HID_DEVICE_PATH *)(void *)devpath;
217 		if ((acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
218 			switch (EISA_ID_TO_NUM(acpi->HID)) {
219 			case 0x0a03:
220 				return snprintf(buf, size, "pciroot(0x%x)",
221 				    acpi->UID);
222 			case 0x0a08:
223 				return snprintf(buf, size, "pcieroot(0x%x)",
224 				    acpi->UID);
225 			case 0x0604:
226 				return snprintf(buf, size, "floppy(0x%x)",
227 				    acpi->UID);
228 			case 0x0301:
229 				return snprintf(buf, size, "keyboard(0x%x)",
230 				    acpi->UID);
231 			case 0x0501:
232 				return snprintf(buf, size, "serial(0x%x)",
233 				    acpi->UID);
234 			case 0x0401:
235 				return snprintf(buf, size, "parallelport(0x%x)",
236 				    acpi->UID);
237 			default:
238 				return snprintf(buf, size, "acpi(pnp%04x,0x%x)",
239 				    EISA_ID_TO_NUM(acpi->HID), acpi->UID);
240 			}
241 		}
242 
243 		return snprintf(buf, size, "acpi(0x%08x,0x%x)", acpi->HID,
244 		    acpi->UID);
245 	}
246 	case MEDIA_DEVICE_PATH:
247 		switch (devpath->SubType) {
248 		case MEDIA_CDROM_DP: {
249 			CDROM_DEVICE_PATH *cdrom;
250 
251 			cdrom = (CDROM_DEVICE_PATH *)(void *)devpath;
252 			return snprintf(buf, size, "cdrom(%x)",
253 			    cdrom->BootEntry);
254 		}
255 		case MEDIA_HARDDRIVE_DP: {
256 			HARDDRIVE_DEVICE_PATH *hd;
257 
258 			hd = (HARDDRIVE_DEVICE_PATH *)(void *)devpath;
259 			return snprintf(buf, size, "hd(%x)",
260 			    hd->PartitionNumber);
261 		}
262 		default:
263 			return snprintf(buf, size, "media(0x%02x)",
264 			    devpath->SubType);
265 		}
266 	case BBS_DEVICE_PATH:
267 		return snprintf(buf, size, "bbs(0x%02x)", devpath->SubType);
268 	case END_DEVICE_PATH_TYPE:
269 		return (0);
270 	}
271 
272 	return snprintf(buf, size, "type(0x%02x, 0x%02x)", devpath->Type,
273 	    devpath->SubType);
274 }
275 
276 /*
277  * devpath_strlcat appends a text description of devpath to buf but not more
278  * than size - 1 characters followed by NUL-terminator.
279  */
280 int
281 devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
282 {
283 	size_t len, used;
284 	const char *sep;
285 
286 	sep = "";
287 	used = 0;
288 	while (!IsDevicePathEnd(devpath)) {
289 		len = snprintf(buf, size - used, "%s", sep);
290 		used += len;
291 		if (used > size)
292 			return (used);
293 		buf += len;
294 
295 		len = devpath_node_str(buf, size - used, devpath);
296 		used += len;
297 		if (used > size)
298 			return (used);
299 		buf += len;
300 		devpath = NextDevicePathNode(devpath);
301 		sep = ":";
302 	}
303 
304 	return (used);
305 }
306 
307 /*
308  * devpath_str is convenience method which returns the text description of
309  * devpath using a static buffer, so it isn't thread safe!
310  */
311 char *
312 devpath_str(EFI_DEVICE_PATH *devpath)
313 {
314 	static char buf[256];
315 
316 	devpath_strlcat(buf, sizeof(buf), devpath);
317 
318 	return buf;
319 }
320 
321 /*
322  * load_loader attempts to load the loader image data.
323  *
324  * It tries each module and its respective devices, identified by mod->probe,
325  * in order until a successful load occurs at which point it returns EFI_SUCCESS
326  * and EFI_NOT_FOUND otherwise.
327  *
328  * Only devices which have preferred matching the preferred parameter are tried.
329  */
330 static EFI_STATUS
331 load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
332     size_t *bufsize, BOOLEAN preferred)
333 {
334 	UINTN i;
335 	dev_info_t *dev;
336 	const boot_module_t *mod;
337 
338 	for (i = 0; i < NUM_BOOT_MODULES; i++) {
339 		mod = boot_modules[i];
340 		for (dev = mod->devices(); dev != NULL; dev = dev->next) {
341 			if (dev->preferred != preferred)
342 				continue;
343 
344 			if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) ==
345 			    EFI_SUCCESS) {
346 				*devinfop = dev;
347 				*modp = mod;
348 				return (EFI_SUCCESS);
349 			}
350 		}
351 	}
352 
353 	return (EFI_NOT_FOUND);
354 }
355 
356 /*
357  * try_boot only returns if it fails to load the loader. If it succeeds
358  * it simply boots, otherwise it returns the status of last EFI call.
359  */
360 static EFI_STATUS
361 try_boot(void)
362 {
363 	size_t bufsize, loadersize, cmdsize;
364 	void *buf, *loaderbuf;
365 	char *cmd;
366 	dev_info_t *dev;
367 	const boot_module_t *mod;
368 	EFI_HANDLE loaderhandle;
369 	EFI_LOADED_IMAGE *loaded_image;
370 	EFI_STATUS status;
371 
372 	status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE);
373 	if (status != EFI_SUCCESS) {
374 		status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
375 		    FALSE);
376 		if (status != EFI_SUCCESS) {
377 			printf("Failed to load '%s'\n", PATH_LOADER_EFI);
378 			return (status);
379 		}
380 	}
381 
382 	/*
383 	 * Read in and parse the command line from /boot.config or /boot/config,
384 	 * if present. We'll pass it the next stage via a simple ASCII
385 	 * string. loader.efi has a hack for ASCII strings, so we'll use that to
386 	 * keep the size down here. We only try to read the alternate file if
387 	 * we get EFI_NOT_FOUND because all other errors mean that the boot_module
388 	 * had troubles with the filesystem. We could return early, but we'll let
389 	 * loading the actual kernel sort all that out. Since these files are
390 	 * optional, we don't report errors in trying to read them.
391 	 */
392 	cmd = NULL;
393 	cmdsize = 0;
394 	status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize);
395 	if (status == EFI_NOT_FOUND)
396 		status = mod->load(PATH_CONFIG, dev, &buf, &bufsize);
397 	if (status == EFI_SUCCESS) {
398 		cmdsize = bufsize + 1;
399 		cmd = malloc(cmdsize);
400 		if (cmd == NULL)
401 			goto errout;
402 		memcpy(cmd, buf, bufsize);
403 		cmd[bufsize] = '\0';
404 		free(buf);
405 		buf = NULL;
406 	}
407 
408 	if ((status = bs->LoadImage(TRUE, image, devpath_last(dev->devpath),
409 	    loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) {
410 		printf("Failed to load image provided by %s, size: %zu, (%lu)\n",
411 		     mod->name, loadersize, EFI_ERROR_CODE(status));
412 		goto errout;
413 	}
414 
415 	if ((status = bs->HandleProtocol(loaderhandle, &LoadedImageGUID,
416 	    (VOID**)&loaded_image)) != EFI_SUCCESS) {
417 		printf("Failed to query LoadedImage provided by %s (%lu)\n",
418 		    mod->name, EFI_ERROR_CODE(status));
419 		goto errout;
420 	}
421 
422 	if (cmd != NULL)
423 		printf("    command args: %s\n", cmd);
424 
425 	loaded_image->DeviceHandle = dev->devhandle;
426 	loaded_image->LoadOptionsSize = cmdsize;
427 	loaded_image->LoadOptions = cmd;
428 
429 	DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
430 	DSTALL(1000000);
431 	DPRINTF(".");
432 	DSTALL(1000000);
433 	DPRINTF(".");
434 	DSTALL(1000000);
435 	DPRINTF(".");
436 	DSTALL(1000000);
437 	DPRINTF(".");
438 	DSTALL(1000000);
439 	DPRINTF(".\n");
440 
441 	if ((status = bs->StartImage(loaderhandle, NULL, NULL)) !=
442 	    EFI_SUCCESS) {
443 		printf("Failed to start image provided by %s (%lu)\n",
444 		    mod->name, EFI_ERROR_CODE(status));
445 		loaded_image->LoadOptionsSize = 0;
446 		loaded_image->LoadOptions = NULL;
447 	}
448 
449 errout:
450 	if (cmd != NULL)
451 		free(cmd);
452 	if (buf != NULL)
453 		free(buf);
454 	if (loaderbuf != NULL)
455 		free(loaderbuf);
456 
457 	return (status);
458 }
459 
460 /*
461  * probe_handle determines if the passed handle represents a logical partition
462  * if it does it uses each module in order to probe it and if successful it
463  * returns EFI_SUCCESS.
464  */
465 static EFI_STATUS
466 probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred)
467 {
468 	dev_info_t *devinfo;
469 	EFI_BLOCK_IO *blkio;
470 	EFI_DEVICE_PATH *devpath;
471 	EFI_STATUS status;
472 	UINTN i;
473 
474 	/* Figure out if we're dealing with an actual partition. */
475 	status = bs->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
476 	if (status == EFI_UNSUPPORTED)
477 		return (status);
478 
479 	if (status != EFI_SUCCESS) {
480 		DPRINTF("\nFailed to query DevicePath (%lu)\n",
481 		    EFI_ERROR_CODE(status));
482 		return (status);
483 	}
484 
485 	DPRINTF("probing: %s\n", devpath_str(devpath));
486 
487 	status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
488 	if (status == EFI_UNSUPPORTED)
489 		return (status);
490 
491 	if (status != EFI_SUCCESS) {
492 		DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
493 		    EFI_ERROR_CODE(status));
494 		return (status);
495 	}
496 
497 	if (!blkio->Media->LogicalPartition)
498 		return (EFI_UNSUPPORTED);
499 
500 	*preferred = device_paths_match(imgpath, devpath);
501 
502 	/* Run through each module, see if it can load this partition */
503 	for (i = 0; i < NUM_BOOT_MODULES; i++) {
504 		if ((status = bs->AllocatePool(EfiLoaderData,
505 		    sizeof(*devinfo), (void **)&devinfo)) !=
506 		    EFI_SUCCESS) {
507 			DPRINTF("\nFailed to allocate devinfo (%lu)\n",
508 			    EFI_ERROR_CODE(status));
509 			continue;
510 		}
511 		devinfo->dev = blkio;
512 		devinfo->devpath = devpath;
513 		devinfo->devhandle = h;
514 		devinfo->devdata = NULL;
515 		devinfo->preferred = *preferred;
516 		devinfo->next = NULL;
517 
518 		status = boot_modules[i]->probe(devinfo);
519 		if (status == EFI_SUCCESS)
520 			return (EFI_SUCCESS);
521 		(void)bs->FreePool(devinfo);
522 	}
523 
524 	return (EFI_UNSUPPORTED);
525 }
526 
527 /*
528  * probe_handle_status calls probe_handle and outputs the returned status
529  * of the call.
530  */
531 static void
532 probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath)
533 {
534 	EFI_STATUS status;
535 	BOOLEAN preferred = false;
536 
537 	status = probe_handle(h, imgpath, &preferred);
538 
539 	DPRINTF("probe: ");
540 	switch (status) {
541 	case EFI_UNSUPPORTED:
542 		printf(".");
543 		DPRINTF(" not supported\n");
544 		break;
545 	case EFI_SUCCESS:
546 		if (preferred) {
547 			printf("%c", '*');
548 			DPRINTF(" supported (preferred)\n");
549 		} else {
550 			printf("%c", '+');
551 			DPRINTF(" supported\n");
552 		}
553 		break;
554 	default:
555 		printf("x");
556 		DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status));
557 		break;
558 	}
559 	DSTALL(500000);
560 }
561 
562 EFI_STATUS
563 efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
564 {
565 	EFI_HANDLE *handles;
566 	EFI_LOADED_IMAGE *img;
567 	EFI_DEVICE_PATH *imgpath;
568 	EFI_STATUS status;
569 	EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
570 	SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
571 	UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
572 
573 	/* Basic initialization*/
574 	systab = Xsystab;
575 	image = Ximage;
576 	bs = Xsystab->BootServices;
577 
578 	/* Set up the console, so printf works. */
579 	status = bs->LocateProtocol(&ConsoleControlGUID, NULL,
580 	    (VOID **)&ConsoleControl);
581 	if (status == EFI_SUCCESS)
582 		(void)ConsoleControl->SetMode(ConsoleControl,
583 		    EfiConsoleControlScreenText);
584 	/*
585 	 * Reset the console and find the best text mode.
586 	 */
587 	conout = systab->ConOut;
588 	conout->Reset(conout, TRUE);
589 	max_dim = best_mode = 0;
590 	for (i = 0; ; i++) {
591 		status = conout->QueryMode(conout, i, &cols, &rows);
592 		if (EFI_ERROR(status))
593 			break;
594 		if (cols * rows > max_dim) {
595 			max_dim = cols * rows;
596 			best_mode = i;
597 		}
598 	}
599 	if (max_dim > 0)
600 		conout->SetMode(conout, best_mode);
601 	conout->EnableCursor(conout, TRUE);
602 	conout->ClearScreen(conout);
603 
604 	printf("\n>> illumos EFI boot block\n");
605 	printf("   Loader path: %s\n\n", PATH_LOADER_EFI);
606 	printf("   Initializing modules:");
607 	for (i = 0; i < NUM_BOOT_MODULES; i++) {
608 		printf(" %s", boot_modules[i]->name);
609 		if (boot_modules[i]->init != NULL)
610 			boot_modules[i]->init();
611 	}
612 	putchar('\n');
613 
614 	/* Get all the device handles */
615 	hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE);
616 	if ((status = bs->AllocatePool(EfiLoaderData, hsize, (void **)&handles))
617 	    != EFI_SUCCESS)
618 		panic("Failed to allocate %d handles (%lu)", NUM_HANDLES_INIT,
619 		    EFI_ERROR_CODE(status));
620 
621 	status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL,
622 	    &hsize, handles);
623 	switch (status) {
624 	case EFI_SUCCESS:
625 		break;
626 	case EFI_BUFFER_TOO_SMALL:
627 		(void)bs->FreePool(handles);
628 		if ((status = bs->AllocatePool(EfiLoaderData, hsize,
629 		    (void **)&handles)) != EFI_SUCCESS) {
630 			panic("Failed to allocate %zu handles (%lu)", hsize /
631 			    sizeof(*handles), EFI_ERROR_CODE(status));
632 		}
633 		status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID,
634 		    NULL, &hsize, handles);
635 		if (status != EFI_SUCCESS)
636 			panic("Failed to get device handles (%lu)\n",
637 			    EFI_ERROR_CODE(status));
638 		break;
639 	default:
640 		panic("Failed to get device handles (%lu)",
641 		    EFI_ERROR_CODE(status));
642 	}
643 
644 	/* Scan all partitions, probing with all modules. */
645 	nhandles = hsize / sizeof(*handles);
646 	printf("   Probing %zu block devices...", nhandles);
647 	DPRINTF("\n");
648 
649 	/* Determine the devpath of our image so we can prefer it. */
650 	status = bs->HandleProtocol(image, &LoadedImageGUID, (VOID**)&img);
651 	imgpath = NULL;
652 	if (status == EFI_SUCCESS) {
653 		status = bs->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
654 		    (void **)&imgpath);
655 		if (status != EFI_SUCCESS)
656 			DPRINTF("Failed to get image DevicePath (%lu)\n",
657 			    EFI_ERROR_CODE(status));
658 		DPRINTF("boot1 imagepath: %s\n", devpath_str(imgpath));
659 	}
660 
661 	for (i = 0; i < nhandles; i++)
662 		probe_handle_status(handles[i], imgpath);
663 	printf(" done\n");
664 
665 	/* Status summary. */
666 	for (i = 0; i < NUM_BOOT_MODULES; i++) {
667 		printf("    ");
668 		boot_modules[i]->status();
669 	}
670 
671 	try_boot();
672 
673 	/* If we get here, we're out of luck... */
674 	panic("No bootable partitions found!");
675 }
676 
677 /*
678  * add_device adds a device to the passed devinfo list.
679  */
680 void
681 add_device(dev_info_t **devinfop, dev_info_t *devinfo)
682 {
683 	dev_info_t *dev;
684 
685 	if (*devinfop == NULL) {
686 		*devinfop = devinfo;
687 		return;
688 	}
689 
690 	for (dev = *devinfop; dev->next != NULL; dev = dev->next)
691 		;
692 
693 	dev->next = devinfo;
694 }
695 
696 void
697 panic(const char *fmt, ...)
698 {
699 	va_list ap;
700 
701 	printf("panic: ");
702 	va_start(ap, fmt);
703 	vprintf(fmt, ap);
704 	va_end(ap);
705 	printf("\n");
706 
707 	while (1) {}
708 }
709 
710 void
711 putchar(int c)
712 {
713 	CHAR16 buf[2];
714 
715 	if (c == '\n') {
716 		buf[0] = '\r';
717 		buf[1] = 0;
718 		systab->ConOut->OutputString(systab->ConOut, buf);
719 	}
720 	buf[0] = c;
721 	buf[1] = 0;
722 	systab->ConOut->OutputString(systab->ConOut, buf);
723 }
724 
725 int
726 getchar(void)
727 {
728 	EFI_INPUT_KEY key;
729 	EFI_STATUS status;
730 	UINTN junk;
731 
732 	status = systab->ConIn->ReadKeyStroke(systab->ConIn, &key);
733         if (status == EFI_NOT_READY) {
734                 bs->WaitForEvent(1, &systab->ConIn->WaitForKey, &junk);
735                 status = systab->ConIn->ReadKeyStroke(systab->ConIn, &key);
736         }
737 	return (key.UnicodeChar);
738 }
739