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

Collapse All | Expand All

(-)sys/boot/efi/boot1/boot1.c (-26 / +169 lines)
Lines 28-34 Link Here
28
#include <stand.h>
28
#include <stand.h>
29
29
30
#include <efi.h>
30
#include <efi.h>
31
#include <eficonsctl.h>
31
#include <efilib.h>
32
32
33
#include "boot_module.h"
33
#include "boot_module.h"
34
#include "paths.h"
34
#include "paths.h"
Lines 47-52 Link Here
47
/* The initial number of handles used to query EFI for partitions. */
47
/* The initial number of handles used to query EFI for partitions. */
48
#define NUM_HANDLES_INIT	24
48
#define NUM_HANDLES_INIT	24
49
49
50
void efi_cons_putchar(int);
51
int efi_cons_getchar(void);
52
int efi_cons_poll(void);
53
int getchar(void);
50
void putchar(int c);
54
void putchar(int c);
51
EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
55
EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
52
56
Lines 53-64 Link Here
53
EFI_SYSTEM_TABLE *systab;
57
EFI_SYSTEM_TABLE *systab;
54
EFI_BOOT_SERVICES *bs;
58
EFI_BOOT_SERVICES *bs;
55
static EFI_HANDLE *image;
59
static EFI_HANDLE *image;
60
static SIMPLE_TEXT_OUTPUT_INTERFACE	*conout;
61
static SIMPLE_INPUT_INTERFACE		*conin;
56
62
57
static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
63
static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
58
static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
64
static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
59
static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
65
static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
60
static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
61
66
67
#define DEFAULT_FGCOLOR EFI_LIGHTGRAY
68
#define DEFAULT_BGCOLOR EFI_BLACK
69
62
/*
70
/*
63
 * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
71
 * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
64
 * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
72
 * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
Lines 350-355 Link Here
350
	return (EFI_NOT_FOUND);
358
	return (EFI_NOT_FOUND);
351
}
359
}
352
360
361
/* quick dirty work. */
362
#define	NUM_DEV_LIST	10
363
364
static struct dev_list_t {
365
	const boot_module_t	*modp;
366
	dev_info_t	*devinfop;
367
} dev_list[NUM_DEV_LIST];
368
369
static int
370
list_devices(void)
371
{
372
	UINTN i, j;
373
	dev_info_t *dev;
374
	const boot_module_t *mod;
375
376
	j = 0;
377
	for (i = 0; i < NUM_BOOT_MODULES; i++) {
378
		if (boot_modules[i] == NULL)
379
			continue;
380
		mod = boot_modules[i];
381
		for (dev = mod->devices(); dev != NULL; dev = dev->next) {
382
			dev_list[j].devinfop = dev;
383
			dev_list[j].modp = mod;
384
			j++;
385
			if (j >= NUM_DEV_LIST)
386
			    break;
387
		}
388
	}
389
390
	return (j);
391
}
392
393
static int
394
select_dev(int ndevs)
395
{
396
	int i;
397
	int c;
398
399
	for (i = 0; i < ndevs; i++) {
400
		if (dev_list[i].devinfop->preferred == TRUE)
401
			c = '*';
402
		else
403
			c = ' ';
404
		printf(" %c%d: %s: %s\n", c, i, dev_list[i].modp->name,
405
		  devpath_str(dev_list[i].devinfop->devpath));
406
	}
407
	/* One digit selection only. Is this big enough ?? */
408
	printf("Select from 0 to %d: ", ndevs - 1);
409
	while (1) {
410
		c = getchar();
411
		i = (c - '0') & 0xff;
412
		if ((i >= 0) && (i < ndevs)) {
413
			return (i);
414
		}
415
		printf("\nInvalid num. Try again: ");
416
	}
417
}
418
353
/*
419
/*
354
 * try_boot only returns if it fails to load the loader. If it succeeds
420
 * 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.
421
 * it simply boots, otherwise it returns the status of last EFI call.
Lines 358-364 Link Here
358
try_boot()
424
try_boot()
359
{
425
{
360
	size_t bufsize, loadersize, cmdsize;
426
	size_t bufsize, loadersize, cmdsize;
361
	void *buf, *loaderbuf;
427
	void *buf = NULL, *loaderbuf = NULL;
362
	char *cmd;
428
	char *cmd;
363
	dev_info_t *dev;
429
	dev_info_t *dev;
364
	const boot_module_t *mod;
430
	const boot_module_t *mod;
Lines 365-381 Link Here
365
	EFI_HANDLE loaderhandle;
431
	EFI_HANDLE loaderhandle;
366
	EFI_LOADED_IMAGE *loaded_image;
432
	EFI_LOADED_IMAGE *loaded_image;
367
	EFI_STATUS status;
433
	EFI_STATUS status;
434
	int i, ndevs;
368
435
369
	status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE);
436
	ndevs = list_devices();
370
	if (status != EFI_SUCCESS) {
437
	if (ndevs == 0) {
438
		printf("Failed to load '%s'\n", PATH_LOADER_EFI);
439
		return (EFI_NOT_FOUND);
440
	} else if (ndevs == 1) {
441
		mod = dev_list[0].modp;
442
		dev = dev_list[0].devinfop;
371
		status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
443
		status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
372
		    FALSE);
444
			dev_list[0].devinfop->preferred);
373
		if (status != EFI_SUCCESS) {
445
		if (status != EFI_SUCCESS) {
374
			printf("Failed to load '%s'\n", PATH_LOADER_EFI);
446
			printf("Failed to load '%s'\n", PATH_LOADER_EFI);
375
			return (status);
447
			return (status);
376
		}
448
		}
449
	} else {
450
		while (1) {
451
			i = select_dev(ndevs);	
452
			printf(" %d is selected.\n", i);
453
			mod = dev_list[i].modp;
454
			dev = dev_list[i].devinfop;
455
			status = mod->load(PATH_LOADER_EFI, dev,
456
				 &loaderbuf, &loadersize);
457
			if (status == EFI_SUCCESS) 
458
				break;
459
			printf("Failed to load '%s'\n", PATH_LOADER_EFI);
460
			printf("Please select again.\n");
461
		}
377
	}
462
	}
378
463
464
	printf("Boot from: %s\n", devpath_str(dev->devpath));
465
379
	/*
466
	/*
380
	 * Read in and parse the command line from /boot.config or /boot/config,
467
	 * 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
468
	 * if present. We'll pass it the next stage via a simple ASCII
Lines 423-428 Link Here
423
	loaded_image->LoadOptionsSize = cmdsize;
510
	loaded_image->LoadOptionsSize = cmdsize;
424
	loaded_image->LoadOptions = cmd;
511
	loaded_image->LoadOptions = cmd;
425
512
513
	printf("Press ANY key to boot\n");
514
	getchar();
515
426
	DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
516
	DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
427
	DSTALL(1000000);
517
	DSTALL(1000000);
428
	DPRINTF(".");
518
	DPRINTF(".");
Lines 559-591 Link Here
559
	DSTALL(500000);
649
	DSTALL(500000);
560
}
650
}
561
651
562
EFI_STATUS
652
static EFI_STATUS
563
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
653
init_console()
564
{
654
{
565
	EFI_HANDLE *handles;
566
	EFI_LOADED_IMAGE *img;
567
	EFI_DEVICE_PATH *imgpath;
568
	EFI_STATUS status;
655
	EFI_STATUS status;
569
	EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
656
	UINTN i, max_dim, best_mode, cols, rows;
570
	SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
571
	UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
572
657
573
	/* Basic initialization*/
574
	systab = Xsystab;
575
	image = Ximage;
576
	bs = Xsystab->BootServices;
577
578
	/* Set up the console, so printf works. */
658
	/* 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
	/*
659
	/*
585
	 * Reset the console and find the best text mode.
660
	 * Reset the console and find the best text mode.
586
	 */
661
	 */
662
	conin = systab->ConIn;
587
	conout = systab->ConOut;
663
	conout = systab->ConOut;
664
	conin->Reset(conin, TRUE);
588
	conout->Reset(conout, TRUE);
665
	conout->Reset(conout, TRUE);
666
589
	max_dim = best_mode = 0;
667
	max_dim = best_mode = 0;
590
	for (i = 0; ; i++) {
668
	for (i = 0; ; i++) {
591
		status = conout->QueryMode(conout, i, &cols, &rows);
669
		status = conout->QueryMode(conout, i, &cols, &rows);
Lines 598-606 Link Here
598
	}
676
	}
599
	if (max_dim > 0)
677
	if (max_dim > 0)
600
		conout->SetMode(conout, best_mode);
678
		conout->SetMode(conout, best_mode);
679
680
	conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
681
	    DEFAULT_BGCOLOR));
601
	conout->EnableCursor(conout, TRUE);
682
	conout->EnableCursor(conout, TRUE);
602
	conout->ClearScreen(conout);
683
	conout->ClearScreen(conout);
603
684
685
	return (status);
686
}
687
688
EFI_STATUS
689
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
690
{
691
	EFI_HANDLE *handles;
692
	EFI_LOADED_IMAGE *img;
693
	EFI_DEVICE_PATH *imgpath;
694
	EFI_STATUS status;
695
	UINTN i, hsize, nhandles;
696
697
	/* Basic initialization*/
698
	systab = Xsystab;
699
	image = Ximage;
700
	bs = Xsystab->BootServices;
701
702
	init_console();
703
604
	printf("\n>> FreeBSD EFI boot block\n");
704
	printf("\n>> FreeBSD EFI boot block\n");
605
	printf("   Loader path: %s\n\n", PATH_LOADER_EFI);
705
	printf("   Loader path: %s\n\n", PATH_LOADER_EFI);
606
	printf("   Initializing modules:");
706
	printf("   Initializing modules:");
Lines 715-728 Link Here
715
void
815
void
716
putchar(int c)
816
putchar(int c)
717
{
817
{
818
	efi_cons_putchar(c);
819
}
820
821
void
822
efi_cons_putchar(int c)
823
{
718
	CHAR16 buf[2];
824
	CHAR16 buf[2];
719
825
720
	if (c == '\n') {
826
	if (c == '\n') {
721
		buf[0] = '\r';
827
		buf[0] = '\r';
722
		buf[1] = 0;
828
		buf[1] = 0;
723
		systab->ConOut->OutputString(systab->ConOut, buf);
829
		conout->OutputString(conout, buf);
724
	}
830
	}
725
	buf[0] = c;
831
	buf[0] = c;
726
	buf[1] = 0;
832
	buf[1] = 0;
727
	systab->ConOut->OutputString(systab->ConOut, buf);
833
	conout->OutputString(conout, buf);
728
}
834
}
835
836
int
837
getchar(void)
838
{
839
	return efi_cons_getchar();
840
}
841
842
843
int
844
efi_cons_getchar()
845
{
846
	EFI_INPUT_KEY key;
847
	EFI_STATUS status;
848
	UINTN junk;
849
850
	/* Try to read a key stroke. We wait for one if none is pending. */
851
	status = conin->ReadKeyStroke(conin, &key);
852
	if (status == EFI_NOT_READY) {
853
		bs->WaitForEvent(1, &conin->WaitForKey, &junk);
854
		status = conin->ReadKeyStroke(conin, &key);
855
	}
856
	switch (key.ScanCode) {
857
	case 0x17: /* ESC */
858
		return (0x1b);  /* esc */
859
	}
860
861
	/* this can return  */
862
	return (key.UnicodeChar);
863
}
864
865
int
866
efi_cons_poll()
867
{
868
	/* This can clear the signaled state. */
869
	return (bs->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
870
}
871

Return to bug 207940