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 |