View | Details | Raw Unified | Return to bug 207940 | Differences between
and this patch

Collapse All | Expand All

(-)stand/efi/boot1/boot1.c (+526 lines)
Lines 29-34 Link Here
29
29
30
#include <efi.h>
30
#include <efi.h>
31
#include <eficonsctl.h>
31
#include <eficonsctl.h>
32
#ifdef BOOT1EFI_BOOT1
33
#include <efilib.h>
34
#endif
32
#include <efichar.h>
35
#include <efichar.h>
33
36
34
#include "boot_module.h"
37
#include "boot_module.h"
Lines 48-58 static const boot_module_t *boot_modules Link Here
48
};
49
};
49
const UINTN num_boot_modules = nitems(boot_modules);
50
const UINTN num_boot_modules = nitems(boot_modules);
50
51
52
#ifdef BOOT1EFI_BOOT1
53
/* For boot partition menu */
54
static int devpath_node_str(char *, size_t, EFI_DEVICE_PATH *);
55
int devpath_strlcat(char *, size_t, EFI_DEVICE_PATH *);
56
char *devpath_str(EFI_DEVICE_PATH *);
57
void efi_cons_putchar(int);
58
int efi_cons_getchar(void);
59
int efi_cons_poll(void);
60
int getchar(void);
61
char *humanize_number_kmgt(UINT64);
62
static SIMPLE_TEXT_OUTPUT_INTERFACE	*conout;
63
static SIMPLE_INPUT_INTERFACE		*conin;
64
#endif
65
51
static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
66
static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
52
static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
67
static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
53
static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
68
static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
54
static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
69
static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
55
70
71
#ifdef BOOT1EFI_BOOT1
72
#define DEFAULT_FGCOLOR EFI_LIGHTGRAY
73
#define DEFAULT_BGCOLOR EFI_BLACK
74
75
/* For boot partition menu */
76
char *humanize_number_kmgt(UINT64 size) {
77
	static char buf2[6];
78
	UINT64 size0;
79
80
	if (size < 1024)
81
		sprintf(buf2, "%luB", size);
82
	else if (size0 = (size*10+512)/1024, size0 < 100)
83
		sprintf(buf2, "%lu.%luK", size0 / 10, size0 % 10);
84
	else if (size0 = (size+512)/1024, size0 < 1024)
85
		sprintf(buf2, "%luK", size0);
86
	else if (size0 = (size*10/1024+512)/1024, size0 < 100)
87
		sprintf(buf2, "%lu.%luM", size0 / 10, size0 % 10);
88
	else if (size0 = (size/1024+512)/1024, size0 < 1024)
89
		sprintf(buf2, "%luM", size0);
90
	else if (size0 = (size*10/1024/1024+512)/1024, size0 < 100)
91
		sprintf(buf2, "%lu.%luG", size0 / 10, size0 % 10);
92
	else if (size0 = (size/1024/1024+512)/1024, size0 < 1024)
93
		sprintf(buf2, "%luG", size0);
94
	else if (size0 = (size*10/1024/1024/1024+512)/1024, size0 < 100)
95
		sprintf(buf2, "%lu.%luT", size0 / 10, size0 % 10);
96
	else
97
		sprintf(buf2, "%luT", (size/1024/1024/1024+512)/1024);
98
	return(buf2);
99
}
100
#endif
101
56
/*
102
/*
57
 * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
103
 * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
58
 * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
104
 * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
Lines 89-95 devpath_last(EFI_DEVICE_PATH *devpath) Link Here
89
130
90
	return (res);
131
	return (res);
91
}
132
}
92
133
134
#ifdef BOOT1EFI_BOOT1
135
/*
136
 * Put back for boot partition menu support.
137
 * devpath_node_str is a basic output method for a devpath node which
138
 * only understands a subset of the available sub types.
139
 *
140
 * If we switch to UEFI 2.x then we should update it to use:
141
 * EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
142
 */
143
static int
144
devpath_node_str(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
145
{
146
	switch (devpath->Type) {
147
	case MESSAGING_DEVICE_PATH:
148
		switch (devpath->SubType) {
149
		case MSG_ATAPI_DP: {
150
			ATAPI_DEVICE_PATH *atapi;
151
152
			atapi = (ATAPI_DEVICE_PATH *)(void *)devpath;
153
			return snprintf(buf, size, "ata(%s,%s,0x%x)",
154
			    (atapi->PrimarySecondary == 1) ?  "Sec" : "Pri",
155
			    (atapi->SlaveMaster == 1) ?  "Slave" : "Master",
156
			    atapi->Lun);
157
		}
158
		case MSG_USB_DP: {
159
			USB_DEVICE_PATH *usb;
160
161
			usb = (USB_DEVICE_PATH *)devpath;
162
			return snprintf(buf, size, "usb(0x%02x,0x%02x)",
163
			    usb->ParentPortNumber, usb->InterfaceNumber);
164
		}
165
		case MSG_SCSI_DP: {
166
			SCSI_DEVICE_PATH *scsi;
167
168
			scsi = (SCSI_DEVICE_PATH *)(void *)devpath;
169
			return snprintf(buf, size, "scsi(0x%02x,0x%02x)",
170
			    scsi->Pun, scsi->Lun);
171
		}
172
		case MSG_SATA_DP: {
173
			SATA_DEVICE_PATH *sata;
174
175
			sata = (SATA_DEVICE_PATH *)(void *)devpath;
176
			return snprintf(buf, size, "sata(0x%x,0x%x,0x%x)",
177
			    sata->HBAPortNumber, sata->PortMultiplierPortNumber,
178
			    sata->Lun);
179
		}
180
		default:
181
			return snprintf(buf, size, "msg(0x%02x)",
182
			    devpath->SubType);
183
		}
184
		break;
185
	case HARDWARE_DEVICE_PATH:
186
		switch (devpath->SubType) {
187
		case HW_PCI_DP: {
188
			PCI_DEVICE_PATH *pci;
189
190
			pci = (PCI_DEVICE_PATH *)devpath;
191
			return snprintf(buf, size, "pci(0x%02x,0x%02x)",
192
			    pci->Device, pci->Function);
193
		}
194
		default:
195
			return snprintf(buf, size, "hw(0x%02x)",
196
			    devpath->SubType);
197
		}
198
		break;
199
	case ACPI_DEVICE_PATH: {
200
		ACPI_HID_DEVICE_PATH *acpi;
201
202
		acpi = (ACPI_HID_DEVICE_PATH *)(void *)devpath;
203
		if ((acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
204
			switch (EISA_ID_TO_NUM(acpi->HID)) {
205
			case 0x0a03:
206
				return snprintf(buf, size, "pciroot(0x%x)",
207
				    acpi->UID);
208
			case 0x0a08:
209
				return snprintf(buf, size, "pcieroot(0x%x)",
210
				    acpi->UID);
211
			case 0x0604:
212
				return snprintf(buf, size, "floppy(0x%x)",
213
				    acpi->UID);
214
			case 0x0301:
215
				return snprintf(buf, size, "keyboard(0x%x)",
216
				    acpi->UID);
217
			case 0x0501:
218
				return snprintf(buf, size, "serial(0x%x)",
219
				    acpi->UID);
220
			case 0x0401:
221
				return snprintf(buf, size, "parallelport(0x%x)",
222
				    acpi->UID);
223
			default:
224
				return snprintf(buf, size, "acpi(pnp%04x,0x%x)",
225
				    EISA_ID_TO_NUM(acpi->HID), acpi->UID);
226
			}
227
		}
228
229
		return snprintf(buf, size, "acpi(0x%08x,0x%x)", acpi->HID,
230
		    acpi->UID);
231
	}
232
	case MEDIA_DEVICE_PATH:
233
		switch (devpath->SubType) {
234
		case MEDIA_CDROM_DP: {
235
			CDROM_DEVICE_PATH *cdrom;
236
237
			cdrom = (CDROM_DEVICE_PATH *)(void *)devpath;
238
			return snprintf(buf, size, "cdrom(%x)",
239
			    cdrom->BootEntry);
240
		}
241
		case MEDIA_HARDDRIVE_DP: {
242
			HARDDRIVE_DEVICE_PATH *hd;
243
244
			hd = (HARDDRIVE_DEVICE_PATH *)(void *)devpath;
245
			return snprintf(buf, size, "hd(p%d) (%s)",
246
			    hd->PartitionNumber,
247
			    humanize_number_kmgt(hd->PartitionSize * 512));
248
		}
249
		default:
250
			return snprintf(buf, size, "media(0x%02x)",
251
			    devpath->SubType);
252
		}
253
	case BBS_DEVICE_PATH:
254
		return snprintf(buf, size, "bbs(0x%02x)", devpath->SubType);
255
	case END_DEVICE_PATH_TYPE:
256
		return (0);
257
	}
258
259
	return snprintf(buf, size, "type(0x%02x, 0x%02x)", devpath->Type,
260
	    devpath->SubType);
261
}
262
263
/*
264
 * devpath_strlcat appends a text description of devpath to buf but not more
265
 * than size - 1 characters followed by NUL-terminator.
266
 */
267
int
268
devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
269
{
270
	size_t len, used;
271
	const char *sep;
272
273
	sep = "";
274
	used = 0;
275
	while (!IsDevicePathEnd(devpath)) {
276
		len = snprintf(buf, size - used, "%s", sep);
277
		used += len;
278
		if (used > size)
279
			return (used);
280
		buf += len;
281
282
		len = devpath_node_str(buf, size - used, devpath);
283
		used += len;
284
		if (used > size)
285
			return (used);
286
		buf += len;
287
		devpath = NextDevicePathNode(devpath);
288
		sep = ":";
289
	}
290
291
	return (used);
292
}
293
294
/*
295
 * devpath_str is convenience method which returns the text description of
296
 * devpath using a static buffer, so it isn't thread safe!
297
 */
298
char *
299
devpath_str(EFI_DEVICE_PATH *devpath)
300
{
301
	static char buf[256];
302
303
	devpath_strlcat(buf, sizeof(buf), devpath);
304
305
	return buf;
306
}
307
308
309
310
/* quick dirty work. */
311
#define	NUM_DEV_LIST	35
312
313
typedef struct {
314
	const boot_module_t	*modp;
315
	dev_info_t		*devinfop;
316
} moddev_t;
317
318
static moddev_t dev_list[NUM_DEV_LIST];
319
320
static int
321
list_devices(void)
322
{
323
	UINTN i, j;
324
	dev_info_t *dev;
325
	const boot_module_t *mod;
326
327
	j = 0;
328
	for (i = 0; i < num_boot_modules; i++) {
329
		if (boot_modules[i] == NULL)
330
			continue;
331
		mod = boot_modules[i];
332
		for (dev = mod->devices(); dev != NULL; dev = dev->next) {
333
			dev_list[j].devinfop = dev;
334
			dev_list[j].modp = mod;
335
			j++;
336
			if (j >= NUM_DEV_LIST)
337
			    break;
338
		}
339
	}
340
341
	return (j);
342
}
343
344
#define	SELECT_TIMEOUT	10
345
346
static char
347
idx2char(int i)
348
{
349
	return (i<10 ? '0'+i : 'a'+i-10);
350
}
351
352
static int
353
char2idx(char c)
354
{
355
	return ((c >= '0' && c <= '9') ? c - '0' :
356
	    (c >= 'A' && c <= 'Z') ? c - 'A' + 10 :
357
	    (c >= 'a' && c <= 'z') ? c - 'a' + 10 :
358
	    -1 );
359
}
360
361
static void
362
move_to_tol()
363
{
364
	int x,y;
365
366
	x = conout->Mode->CursorColumn;
367
	y = conout->Mode->CursorRow;
368
	conout->SetCursorPosition(conout, 0, y);
369
}
370
371
static EFI_STATUS
372
select_bootdev(int ndevs, const boot_module_t **modp, dev_info_t **devinfop,
373
    void **bufp, size_t *bufsize)
374
{
375
	int i;
376
	int c, n;
377
	int time_left;
378
	EFI_STATUS status;
379
	EFI_EVENT timer;
380
	EFI_EVENT events[2];
381
	UINTN idx;
382
	dev_info_t *dev;
383
	const boot_module_t *mod;
384
385
	if ((ndevs <= 0) || (ndevs >= NUM_DEV_LIST)) {
386
		return (EFI_NOT_FOUND);
387
	} else if (ndevs == 1) {
388
		/* Only one candidate. */
389
		*modp = mod = dev_list[0].modp;
390
		*devinfop = dev = dev_list[0].devinfop;
391
		return (mod->load(PATH_LOADER_EFI, dev,
392
			 bufp, bufsize));
393
	}
394
	/* Two or more candidate exist. */
395
	status = BS->CreateEvent(EVT_TIMER, 0, 0, NULL, &timer);
396
	if (status != EFI_SUCCESS) {
397
		printf("Can't allocate timer event.\n");
398
		return (status);
399
	}
400
	printf("  0: AutoSelected Partition (Default): 0\n"); 
401
	for (i = 0; i < ndevs; i++) {
402
		if (dev_list[i].devinfop->preferred == TRUE)
403
			c = '*';
404
		else
405
			c = ' ';
406
		printf(" %c%c: %s: %s: %c\n", c, idx2char(i+1),
407
		    dev_list[i].modp->name,
408
		    devpath_str(dev_list[i].devinfop->devpath),
409
			idx2char(i+1));
410
	}
411
	/* One alpha-num selection only. Is this big enough ?? */
412
	BS->SetTimer(timer, TimerPeriodic, 10000000); 
413
	events[0] = timer;
414
	events[1] = conin->WaitForKey;
415
	time_left = SELECT_TIMEOUT;
416
417
	while (1) {
418
		if (time_left > 0) {
419
			printf("Select from 0 to %c. Timeout in %2d seconds,"
420
			       " [Space] to pause : ",
421
			       idx2char(ndevs), time_left);
422
		}
423
		status = BS->WaitForEvent(2, events, &idx);
424
		if (status != EFI_SUCCESS) {
425
			BS->CloseEvent(timer);
426
			return (status);
427
		}
428
		if (idx == 0) {
429
			time_left--;
430
			if (time_left <=0) {
431
				printf("\nTimeout. "
432
				       "Partition is AutoSelected.\n");
433
				n = 0;
434
				break;
435
			} else {
436
				move_to_tol();
437
			}
438
		}
439
		if (idx == 1) {
440
			c = getchar();
441
			if ((c == '\n') || (c == '\r')) {
442
				putchar('\n');
443
				n = 0;
444
				break;
445
			} else if ((time_left > 0) && (c == ' ')) {
446
				BS->SetTimer(timer, TimerCancel, 0); 
447
				time_left = -1;
448
				printf("\nTimer stopeed.\n Please Key in: ");
449
			}
450
			n = char2idx(c);
451
			if ((n >= 0) && (n <= ndevs)) {
452
				BS->SetTimer(timer, TimerCancel, 0); 
453
				time_left = -1;
454
				printf("\n %c is selected.\n", c);
455
				if (n == 0) { /* AutoSelect */
456
					break;
457
				} else {
458
					mod = dev_list[n-1].modp;
459
					dev = dev_list[n-1].devinfop;
460
					status = mod->load(PATH_LOADER_EFI,
461
							   dev, bufp, bufsize);
462
					if (status == EFI_SUCCESS) {
463
						break;
464
					}
465
					printf("Failed to load '%s'\n",
466
						 PATH_LOADER_EFI);
467
					printf("Please select again: ");
468
				}
469
			} else {
470
				/* Invalid charecter. */
471
				move_to_tol();
472
			}
473
		}
474
	};
475
	BS->CloseEvent(timer);
476
	if (n == 0) { /* AutoSelect */
477
		status = load_loader(modp, devinfop, bufp, bufsize, 1);
478
		if (status != EFI_SUCCESS) {
479
			status = load_loader(modp, devinfop, bufp, bufsize, 0);
480
		}
481
	} else {
482
		*modp = dev_list[n-1].modp;
483
		*devinfop = dev_list[n-1].devinfop;
484
		status = EFI_SUCCESS;
485
	}
486
	return (status);
487
}
488
#endif
489
93
/*
490
/*
94
 * try_boot only returns if it fails to load the loader. If it succeeds
491
 * try_boot only returns if it fails to load the loader. If it succeeds
95
 * it simply boots, otherwise it returns the status of last EFI call.
492
 * it simply boots, otherwise it returns the status of last EFI call.
Lines 98-108 try_boot(const boot_module_t *mod, dev_info_t *dev, void *loaderbuf, size_t loadersize) Link Here
98
try_boot(const boot_module_t *mod, dev_info_t *dev, void *loaderbuf, size_t loadersize)
527
try_boot(const boot_module_t *mod, dev_info_t *dev, void *loaderbuf, size_t loadersize)
99
{
528
{
100
	size_t bufsize, cmdsize;
529
	size_t bufsize, cmdsize;
101
	void *buf;
530
	void *buf;
102
	char *cmd;
531
	char *cmd;
103
	EFI_HANDLE loaderhandle;
532
	EFI_HANDLE loaderhandle;
104
	EFI_LOADED_IMAGE *loaded_image;
533
	EFI_LOADED_IMAGE *loaded_image;
105
	EFI_STATUS status;
534
	EFI_STATUS status;
535
#ifdef BOOT1EFI_BOOT1
536
	int ndevs;	/* For boot partition menu */
537
538
	/* For boot partition menu */
539
	ndevs = list_devices();
540
	status = select_bootdev(ndevs, &mod, &dev, &loaderbuf, &loadersize);	
541
542
	if (status != EFI_SUCCESS) {
543
	/* For boot partition menu */
544
		printf("Failed to load '%s'\n", PATH_LOADER_EFI);
545
		return (EFI_NOT_FOUND);
546
	}
547
#endif
106
548
107
	/*
549
	/*
108
	 * Read in and parse the command line from /boot.config or /boot/config,
550
	 * Read in and parse the command line from /boot.config or /boot/config,
Lines 151-156 try_boot(void) Link Here
151
	loaded_image->LoadOptionsSize = cmdsize;
677
	loaded_image->LoadOptionsSize = cmdsize;
152
	loaded_image->LoadOptions = cmd;
678
	loaded_image->LoadOptions = cmd;
153
679
680
#ifdef BOOT1EFI_BOOT1
681
	/* For boot partition menu */
682
	DPRINTF("Boot from:'%s' in 5 seconds...", devpath_str(dev->devpath));
683
#else
154
	DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
684
	DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
685
#endif
155
	DSTALL(1000000);
686
	DSTALL(1000000);
156
	DPRINTF(".");
687
	DPRINTF(".");
Lines 182-204 errout: Link Here
182
	return (status);
708
	return (status);
183
}
709
}
184
710
711
#ifndef BOOT1EFI_BOOT1
185
EFI_STATUS
712
EFI_STATUS
186
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
713
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
714
#else
715
716
/* Divide efi_main into two for boot partition menu */
717
static EFI_STATUS
718
init_console()
719
#endif
187
{
720
{
721
#ifndef BOOT1EFI_BOOT1
188
	EFI_HANDLE *handles;
722
	EFI_HANDLE *handles;
189
	EFI_LOADED_IMAGE *img;
723
	EFI_LOADED_IMAGE *img;
190
	EFI_DEVICE_PATH *imgpath;
724
	EFI_DEVICE_PATH *imgpath;
725
#endif
191
	EFI_STATUS status;
726
	EFI_STATUS status;
192
	EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
727
	EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
728
#ifndef BOOT1EFI_BOOT1
193
	SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
729
	SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
194
	UINTN i, hsize, nhandles;
730
	UINTN i, hsize, nhandles;
195
	CHAR16 *text;
731
	CHAR16 *text;
732
#endif
196
733
734
#ifndef BOOT1EFI_BOOT1
197
	/* Basic initialization*/
735
	/* Basic initialization*/
198
	ST = Xsystab;
736
	ST = Xsystab;
199
	IH = Ximage;
737
	IH = Ximage;
200
	BS = ST->BootServices;
738
	BS = ST->BootServices;
201
	RS = ST->RuntimeServices;
739
	RS = ST->RuntimeServices;
740
#endif
202
741
203
	/* Set up the console, so printf works. */
742
	/* Set up the console, so printf works. */
204
	status = BS->LocateProtocol(&ConsoleControlGUID, NULL,
743
	status = BS->LocateProtocol(&ConsoleControlGUID, NULL,
Lines 210-222 efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_T Link Here
210
	 * Reset the console enable the cursor. Later we'll choose a bette
736
	 * Reset the console enable the cursor. Later we'll choose a bette
211
	 * console size through GOP/UGA.
737
	 * console size through GOP/UGA.
212
	 */
738
	 */
739
#ifdef BOOT1EFI_BOOT1
740
	conin = ST->ConIn;
741
#endif
213
	conout = ST->ConOut;
742
	conout = ST->ConOut;
743
#ifdef BOOT1EFI_BOOT1
744
	conin->Reset(conin, TRUE);
745
#endif
214
	conout->Reset(conout, TRUE);
746
	conout->Reset(conout, TRUE);
215
	/* Explicitly set conout to mode 0, 80x25 */
747
	/* Explicitly set conout to mode 0, 80x25 */
216
	conout->SetMode(conout, 0);
748
	conout->SetMode(conout, 0);
749
#ifdef BOOT1EFI_BOOT1
750
751
	conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
752
	    DEFAULT_BGCOLOR));
753
#endif
217
	conout->EnableCursor(conout, TRUE);
754
	conout->EnableCursor(conout, TRUE);
218
	conout->ClearScreen(conout);
755
	conout->ClearScreen(conout);
219
756
757
#ifdef BOOT1EFI_BOOT1
758
	return (status);
759
}
760
761
EFI_STATUS
762
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
763
{
764
	EFI_HANDLE *handles;
765
	EFI_LOADED_IMAGE *img;
766
	EFI_DEVICE_PATH *imgpath;
767
	EFI_STATUS status;
768
	UINTN i, hsize, nhandles;
769
	CHAR16 *text;
770
771
	/* Basic initialization*/
772
	ST = Xsystab;
773
	IH = Ximage;
774
	BS = Xsystab->BootServices;
775
	RS = ST->RuntimeServices;
776
777
	init_console();
778
779
#endif
220
	printf("\n>> FreeBSD EFI boot block\n");
780
	printf("\n>> FreeBSD EFI boot block\n");
221
	printf("   Loader path: %s\n\n", PATH_LOADER_EFI);
781
	printf("   Loader path: %s\n\n", PATH_LOADER_EFI);
222
	printf("   Initializing modules:");
782
	printf("   Initializing modules:");
Lines 310-326 efi_panic(EFI_STATUS s, const char *fmt, Link Here
310
	BS->Exit(IH, s, 0, NULL);
836
	BS->Exit(IH, s, 0, NULL);
311
}
837
}
312
838
839
#ifdef BOOT1EFI_BOOT1
840
/* Make putchar as wrapper for newly added efi_cons_putchar() for boot partition menu */
841
#endif
313
void
842
void
314
putchar(int c)
843
putchar(int c)
315
{
844
{
845
#ifdef BOOT1EFI_BOOT1
846
	efi_cons_putchar(c);
847
}
848
849
void
850
efi_cons_putchar(int c)
851
{
852
#endif
316
	CHAR16 buf[2];
853
	CHAR16 buf[2];
317
854
318
	if (c == '\n') {
855
	if (c == '\n') {
319
		buf[0] = '\r';
856
		buf[0] = '\r';
320
		buf[1] = 0;
857
		buf[1] = 0;
858
#ifdef BOOT1EFI_BOOT1
859
		conout->OutputString(conout, buf);
860
#else
321
		ST->ConOut->OutputString(ST->ConOut, buf);
861
		ST->ConOut->OutputString(ST->ConOut, buf);
862
#endif
322
	}
863
	}
323
	buf[0] = c;
864
	buf[0] = c;
324
	buf[1] = 0;
865
	buf[1] = 0;
866
#ifdef BOOT1EFI_BOOT1
867
	conout->OutputString(conout, buf);
868
}
869
870
int
871
getchar(void)
872
{
873
	return efi_cons_getchar();
874
#else
325
	ST->ConOut->OutputString(ST->ConOut, buf);
875
	ST->ConOut->OutputString(ST->ConOut, buf);
876
#endif
326
}
877
}
878
#ifdef BOOT1EFI_BOOT1
879
880
881
int
882
efi_cons_getchar()
883
{
884
	EFI_INPUT_KEY key;
885
	EFI_STATUS status;
886
	UINTN junk;
887
888
	/* Try to read a key stroke. We wait for one if none is pending. */
889
	status = conin->ReadKeyStroke(conin, &key);
890
	if (status == EFI_NOT_READY) {
891
		BS->WaitForEvent(1, &conin->WaitForKey, &junk);
892
		status = conin->ReadKeyStroke(conin, &key);
893
	}
894
	switch (key.ScanCode) {
895
	case 0x17: /* ESC */
896
		return (0x1b);  /* esc */
897
	}
898
899
	/* this can return  */
900
	return (key.UnicodeChar);
901
}
902
903
int
904
efi_cons_poll()
905
{
906
	/* This can clear the signaled state. */
907
	return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
908
}
909
#endif
(-)stand/efi/boot1/Makefile (+6 lines)
Lines 118-121 Link Here
118
CLEANFILES+= ${BOOT1}.efi ${BOOT1}.efifat
118
CLEANFILES+= ${BOOT1}.efi ${BOOT1}.efifat
119
.endif
119
.endif
120
120
121
.if ${BOOT1} == "gptboot"
122
CFLAGS+=	-DBOOT1EFI_GPTBOOT
123
.else
124
CFLAGS+=	-DBOOT1EFI_BOOT1
125
.endif
126
121
.include <bsd.prog.mk>
127
.include <bsd.prog.mk>
(-)stand/efi/boot1/proto.h (+4 lines)
Lines 27-29 Link Here
27
27
28
void choice_protocol(EFI_HANDLE *handles, UINTN nhandles, EFI_DEVICE_PATH *imgpath);
28
void choice_protocol(EFI_HANDLE *handles, UINTN nhandles, EFI_DEVICE_PATH *imgpath);
29
EFI_STATUS try_boot(const boot_module_t *mod, dev_info_t *dev, void *loaderbuf, size_t loadersize);
29
EFI_STATUS try_boot(const boot_module_t *mod, dev_info_t *dev, void *loaderbuf, size_t loadersize);
30
#ifdef BOOT1EFI_BOOT1
31
EFI_STATUS load_loader(const boot_module_t **modp, dev_info_t **devinfop,
32
    void **bufp, size_t *bufsize, int preferred);
33
#endif
(-)stand/efi/boot1/proto.c (-1 / +1 lines)
Lines 125-131 Link Here
125
 *
125
 *
126
 * Only devices which have preferred matching the preferred parameter are tried.
126
 * Only devices which have preferred matching the preferred parameter are tried.
127
 */
127
 */
128
static EFI_STATUS
128
EFI_STATUS
129
load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
129
load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
130
    size_t *bufsize, int preferred)
130
    size_t *bufsize, int preferred)
131
{
131
{

Return to bug 207940