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