dmi: check both the AC and ID flags at the same time
[syslinux.git] / efi / main.c
blob6a748412ee7f83457dff23fd4072a145ac0f020f
1 /*
2 * Copyright 2011-2014 Intel Corporation - All Rights Reserved
3 */
5 #include <codepage.h>
6 #include <core.h>
7 #include <fs.h>
8 #include <com32.h>
9 #include <syslinux/memscan.h>
10 #include <syslinux/firmware.h>
11 #include <syslinux/linux.h>
12 #include <sys/ansi.h>
14 #include "efi.h"
15 #include "fio.h"
16 #include "version.h"
17 #include "efi_pxe.h"
19 __export uint16_t PXERetry;
20 __export char copyright_str[] = "Copyright (C) 2011-" YEAR_STR "\n";
21 uint8_t SerialNotice = 1;
22 __export char syslinux_banner[] = "Syslinux " VERSION_STR " (EFI; " DATE_STR ")\n";
23 char CurrentDirName[CURRENTDIR_MAX];
24 struct com32_sys_args __com32;
26 uint32_t _IdleTimer = 0;
27 char __lowmem_heap[32];
28 uint32_t BIOS_timer_next;
29 uint32_t timer_irq;
30 __export uint8_t KbdMap[256];
31 char aux_seg[256];
33 static jmp_buf load_error_buf;
35 EFI_HANDLE image_handle, image_device_handle, mnpsb_handle;
37 static inline EFI_STATUS
38 efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid, EFI_HANDLE agent,
39 EFI_HANDLE controller)
41 return uefi_call_wrapper(BS->CloseProtocol, 4, handle,
42 guid, agent, controller);
45 bool efi_get_MAC( EFI_DEVICE_PATH * pDevPath, uint8_t * mac, uint16_t mac_size)
48 * in case the DevPath contains more than one instance we consider all of them
49 * contain "the same" MAC Address Device Path structure
51 EFI_DEVICE_PATH *DevPathNode;
52 MAC_ADDR_DEVICE_PATH *MAC;
54 if (!pDevPath)
55 return FALSE;
57 pDevPath = UnpackDevicePath(pDevPath);
59 /* Process each device path node */
60 DevPathNode = pDevPath;
61 while (!IsDevicePathEnd(DevPathNode)) {
62 /* Find the handler to dump this device path node */
63 if (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH &&
64 DevicePathSubType(DevPathNode) == MSG_MAC_ADDR_DP) {
65 MAC = (MAC_ADDR_DEVICE_PATH *)DevPathNode;
66 CopyMem(mac, MAC->MacAddress.Addr, PXE_MAC_LENGTH);
67 FreePool(pDevPath);
68 return TRUE;
71 /* Next device path node */
72 DevPathNode = NextDevicePathNode(DevPathNode);
75 FreePool(pDevPath);
76 return FALSE;
80 /* As of UEFI-2.4.0, all EFI_SERVICE_BINDINGs are for networking */
81 struct efi_binding *efi_create_binding(EFI_GUID *bguid, EFI_GUID *pguid)
83 EFI_SERVICE_BINDING *sbp = NULL;
84 struct efi_binding *b;
85 EFI_STATUS status;
86 EFI_HANDLE sb_handle, protocol, child;
88 b = malloc(sizeof(*b));
89 if (!b)
90 return NULL;
92 sb_handle = (mnpsb_handle ? mnpsb_handle : image_device_handle);
93 status = uefi_call_wrapper(BS->OpenProtocol, 6, sb_handle,
94 bguid, (void **)&sbp,
95 image_handle, sb_handle,
96 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
97 if (status != EFI_SUCCESS) {
98 EFI_HANDLE *handles = NULL;
99 UINTN i, nr_handles = 0;
100 EFI_DEVICE_PATH *DevicePath = NULL;
101 uint8_t mac_1[PXE_MAC_LENGTH], mac_2[PXE_MAC_LENGTH];
102 DevicePath = DevicePathFromHandle(image_device_handle);
103 if (DevicePath == NULL) {
104 status = EFI_UNSUPPORTED;
105 goto free_binding;
107 efi_get_MAC(DevicePath, mac_1, PXE_MAC_LENGTH);
108 status = LibLocateHandle(ByProtocol, bguid, NULL, &nr_handles, &handles);
109 if (status != EFI_SUCCESS)
110 goto free_binding;
111 for (i = 0; i < nr_handles; i++) {
112 DevicePath = DevicePathFromHandle(handles[i]);
113 if (efi_get_MAC(DevicePath, mac_2, PXE_MAC_LENGTH)
114 && memcmp(mac_1, mac_2, PXE_MAC_LENGTH) == 0) {
115 sb_handle = handles[i];
116 status = uefi_call_wrapper(BS->OpenProtocol, 6, sb_handle,
117 bguid, (void **)&sbp,
118 image_handle, sb_handle,
119 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
120 if (status == EFI_SUCCESS) {
121 mnpsb_handle = sb_handle;
122 break;
128 if (status != EFI_SUCCESS || sbp == NULL)
129 goto free_binding;
131 child = NULL;
133 status = uefi_call_wrapper(sbp->CreateChild, 2, sbp, (EFI_HANDLE *)&child);
134 if (status != EFI_SUCCESS)
135 goto close_protocol;
137 status = uefi_call_wrapper(BS->OpenProtocol, 6, child,
138 pguid, (void **)&protocol,
139 image_handle, sbp,
140 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
141 if (status != EFI_SUCCESS)
142 goto destroy_child;
144 b->parent = image_device_handle;
145 b->binding = sbp;
146 b->child = child;
147 b->this = protocol;
149 return b;
151 destroy_child:
152 uefi_call_wrapper(sbp->DestroyChild, 2, sbp, child);
154 close_protocol:
155 uefi_call_wrapper(BS->CloseProtocol, 4, sb_handle, bguid,
156 image_handle, sb_handle);
158 free_binding:
159 free(b);
160 return NULL;
163 void efi_destroy_binding(struct efi_binding *b, EFI_GUID *guid)
165 efi_close_protocol(b->child, guid, image_handle, b->binding);
166 uefi_call_wrapper(b->binding->DestroyChild, 2, b->binding, b->child);
167 efi_close_protocol(b->parent, guid, image_handle, b->parent);
169 free(b);
172 __export __noreturn _kaboom(void)
174 /* Return to EFI here somehow? */
175 for (;;)
176 asm volatile("hlt");
179 void printf_init(void)
183 __export void local_boot(uint16_t ax)
186 * Inform the firmware that we failed to execute correctly, which
187 * will trigger the next entry in the EFI Boot Manager list.
189 longjmp(&load_error_buf, 1);
192 void bios_timer_cleanup(void)
196 char trackbuf[4096];
198 void __cdecl core_farcall(uint32_t c, const com32sys_t *a, com32sys_t *b)
202 __export struct firmware *firmware = NULL;
203 __export void *__syslinux_adv_ptr;
204 __export size_t __syslinux_adv_size;
205 char core_xfer_buf[65536];
206 struct iso_boot_info {
207 uint32_t pvd; /* LBA of primary volume descriptor */
208 uint32_t file; /* LBA of boot file */
209 uint32_t length; /* Length of boot file */
210 uint32_t csum; /* Checksum of boot file */
211 uint32_t reserved[10]; /* Currently unused */
212 } iso_boot_info;
214 uint8_t DHCPMagic;
215 uint32_t RebootTime;
217 void pxenv(void)
221 uint16_t BIOS_fbm = 1;
222 far_ptr_t InitStack;
223 far_ptr_t PXEEntry;
225 void gpxe_unload(void)
229 void do_idle(void)
233 void pxe_int1a(void)
237 uint8_t KeepPXE;
239 struct semaphore;
240 mstime_t sem_down(struct semaphore *sem, mstime_t time)
242 /* EFI is single threaded */
243 return 0;
246 void sem_up(struct semaphore *sem)
248 /* EFI is single threaded */
251 __export volatile uint32_t __ms_timer = 0;
252 volatile uint32_t __jiffies = 0;
254 void efi_write_char(uint8_t ch, uint8_t attribute)
256 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
257 uint16_t c[2];
259 uefi_call_wrapper(out->SetAttribute, 2, out, attribute);
261 /* Lookup primary Unicode encoding in the system codepage */
262 c[0] = codepage.uni[0][ch];
263 c[1] = '\0';
265 uefi_call_wrapper(out->OutputString, 2, out, c);
268 static void efi_showcursor(const struct term_state *st)
270 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
271 bool cursor = st->cursor ? true : false;
273 uefi_call_wrapper(out->EnableCursor, 2, out, cursor);
276 static void efi_set_cursor(int x, int y, bool visible)
278 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
280 uefi_call_wrapper(out->SetCursorPosition, 3, out, x, y);
283 static void efi_scroll_up(uint8_t cols, uint8_t rows, uint8_t attribute)
285 efi_write_char('\n', 0);
286 efi_write_char('\r', 0);
289 static void efi_get_mode(int *cols, int *rows)
291 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
292 UINTN c, r;
294 uefi_call_wrapper(out->QueryMode, 4, out, out->Mode->Mode, &c, &r);
295 *rows = r;
296 *cols = c;
299 static void efi_erase(int x0, int y0, int x1, int y1, uint8_t attribute)
301 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
302 int cols, rows;
304 efi_get_mode(&cols, &rows);
307 * The BIOS version of this function has the ability to erase
308 * parts or all of the screen - the UEFI console doesn't
309 * support this so we just set the cursor position unless
310 * we're clearing the whole screen.
312 if (!x0 && y0 == (cols - 1)) {
313 /* Really clear the screen */
314 uefi_call_wrapper(out->ClearScreen, 1, out);
315 } else {
316 uefi_call_wrapper(out->SetCursorPosition, 3, out, y1, x1);
320 static void efi_text_mode(void)
324 static void efi_get_cursor(uint8_t *x, uint8_t *y)
326 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
327 *x = out->Mode->CursorColumn;
328 *y = out->Mode->CursorRow;
331 struct output_ops efi_ops = {
332 .erase = efi_erase,
333 .write_char = efi_write_char,
334 .showcursor = efi_showcursor,
335 .set_cursor = efi_set_cursor,
336 .scroll_up = efi_scroll_up,
337 .get_mode = efi_get_mode,
338 .text_mode = efi_text_mode,
339 .get_cursor = efi_get_cursor,
342 char SubvolName[2];
343 static inline EFI_MEMORY_DESCRIPTOR *
344 get_memory_map(UINTN *nr_entries, UINTN *key, UINTN *desc_sz,
345 uint32_t *desc_ver)
347 return LibMemoryMap(nr_entries, key, desc_sz, desc_ver);
351 int efi_scan_memory(scan_memory_callback_t callback, void *data)
353 UINTN i, nr_entries, key, desc_sz;
354 UINTN buf, bufpos;
355 UINT32 desc_ver;
356 int rv = 0;
358 buf = (UINTN)get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
359 if (!buf)
360 return -1;
361 bufpos = buf;
363 for (i = 0; i < nr_entries; bufpos += desc_sz, i++) {
364 EFI_MEMORY_DESCRIPTOR *m;
365 UINT64 region_sz;
366 enum syslinux_memmap_types type;
368 m = (EFI_MEMORY_DESCRIPTOR *)bufpos;
369 region_sz = m->NumberOfPages * EFI_PAGE_SIZE;
371 switch (m->Type) {
372 case EfiConventionalMemory:
373 type = SMT_FREE;
374 break;
375 default:
376 type = SMT_RESERVED;
377 break;
380 rv = callback(data, m->PhysicalStart, region_sz, type);
381 if (rv)
382 break;
385 FreePool((void *)buf);
386 return rv;
389 static struct syslinux_memscan efi_memscan = {
390 .func = efi_scan_memory,
393 extern uint16_t *bios_free_mem;
394 void efi_init(void)
396 /* XXX timer */
397 *bios_free_mem = 0;
398 syslinux_memscan_add(&efi_memscan);
399 mem_init();
402 char efi_getchar(char *hi)
404 SIMPLE_INPUT_INTERFACE *in = ST->ConIn;
405 EFI_INPUT_KEY key;
406 EFI_STATUS status;
408 do {
409 status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
410 } while (status == EFI_NOT_READY);
412 if (!key.ScanCode)
413 return (char)key.UnicodeChar;
416 * We currently only handle scan codes that fit in 8 bits.
418 *hi = (char)key.ScanCode;
419 return 0;
422 int efi_pollchar(void)
424 SIMPLE_INPUT_INTERFACE *in = ST->ConIn;
425 EFI_STATUS status;
427 status = WaitForSingleEvent(in->WaitForKey, 1);
428 return status != EFI_TIMEOUT;
431 struct input_ops efi_iops = {
432 .getchar = efi_getchar,
433 .pollchar = efi_pollchar,
436 extern void efi_adv_init(void);
437 extern int efi_adv_write(void);
439 struct adv_ops efi_adv_ops = {
440 .init = efi_adv_init,
441 .write = efi_adv_write,
444 struct efi_info {
445 uint32_t load_signature;
446 uint32_t systab;
447 uint32_t desc_size;
448 uint32_t desc_version;
449 uint32_t memmap;
450 uint32_t memmap_size;
451 uint32_t systab_hi;
452 uint32_t memmap_hi;
455 #define E820MAX 128
456 #define E820_RAM 1
457 #define E820_RESERVED 2
458 #define E820_ACPI 3
459 #define E820_NVS 4
460 #define E820_UNUSABLE 5
462 #define BOOT_SIGNATURE 0xaa55
463 #define SYSLINUX_EFILDR 0x30 /* Is this published value? */
464 #define DEFAULT_TIMER_TICK_DURATION 500000 /* 500000 == 500000 * 100 * 10^-9 == 50 msec */
465 #define DEFAULT_MSTIMER_INC 0x32 /* 50 msec */
466 struct e820_entry {
467 uint64_t start;
468 uint64_t len;
469 uint32_t type;
470 } __packed;
472 struct boot_params {
473 struct screen_info screen_info;
474 uint8_t _pad[0x1c0 - sizeof(struct screen_info)];
475 struct efi_info efi;
476 uint8_t _pad2[8];
477 uint8_t e820_entries;
478 uint8_t _pad3[0x2d0 - 0x1e8 - sizeof(uint8_t)];
479 struct e820_entry e820_map[E820MAX];
480 } __packed;
482 /* Allocate boot parameter block aligned to page */
483 #define BOOT_PARAM_BLKSIZE EFI_SIZE_TO_PAGES(sizeof(struct boot_params)) * EFI_PAGE_SIZE
485 /* Routines in support of efi boot loader were obtained from
486 * http://git.kernel.org/?p=boot/efilinux/efilinux.git:
487 * kernel_jump(), handover_jump(),
488 * emalloc()/efree, alloc_pages/free_pages
489 * allocate_pool()/free_pool()
490 * memory_map()
492 extern void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start,
493 struct boot_params *boot_params);
494 #if __SIZEOF_POINTER__ == 4
495 #define EFI_LOAD_SIG "EL32"
496 #elif __SIZEOF_POINTER__ == 8
497 #define EFI_LOAD_SIG "EL64"
498 #else
499 #error "unsupported architecture"
500 #endif
502 struct dt_desc {
503 uint16_t limit;
504 uint64_t *base;
505 } __packed;
507 struct dt_desc gdt = { 0x800, (uint64_t *)0 };
508 struct dt_desc idt = { 0, 0 };
510 static inline EFI_MEMORY_DESCRIPTOR *
511 get_mem_desc(unsigned long memmap, UINTN desc_sz, int i)
513 return (EFI_MEMORY_DESCRIPTOR *)(memmap + (i * desc_sz));
516 static inline UINT64 round_up(UINT64 x, UINT64 y)
518 return (((x - 1) | (y - 1)) + 1);
521 static inline UINT64 round_down(UINT64 x, UINT64 y)
523 return (x & ~(y - 1));
526 static void find_addr(EFI_PHYSICAL_ADDRESS *first,
527 EFI_PHYSICAL_ADDRESS *last,
528 EFI_PHYSICAL_ADDRESS min,
529 EFI_PHYSICAL_ADDRESS max,
530 size_t size, size_t align)
532 EFI_MEMORY_DESCRIPTOR *map;
533 UINT32 desc_ver;
534 UINTN i, nr_entries, key, desc_sz;
536 map = get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
537 if (!map)
538 return;
540 for (i = 0; i < nr_entries; i++) {
541 EFI_MEMORY_DESCRIPTOR *m;
542 EFI_PHYSICAL_ADDRESS best;
543 UINT64 start, end;
545 m = get_mem_desc((unsigned long)map, desc_sz, i);
546 if (m->Type != EfiConventionalMemory)
547 continue;
549 if (m->NumberOfPages < EFI_SIZE_TO_PAGES(size))
550 continue;
552 start = m->PhysicalStart;
553 end = m->PhysicalStart + (m->NumberOfPages << EFI_PAGE_SHIFT);
554 if (first) {
555 if (end < min)
556 continue;
558 /* What's the best address? */
559 if (start < min && min < end)
560 best = min;
561 else
562 best = m->PhysicalStart;
564 start = round_up(best, align);
565 if (start > max)
566 continue;
568 /* Have we run out of space in this region? */
569 if (end < start || (start + size) > end)
570 continue;
572 if (start < *first)
573 *first = start;
576 if (last) {
577 if (start > max)
578 continue;
580 /* What's the best address? */
581 if (start < max && max < end)
582 best = max - size;
583 else
584 best = end - size;
586 start = round_down(best, align);
587 if (start < min || start < m->PhysicalStart)
588 continue;
590 if (start > *last)
591 *last = start;
595 FreePool(map);
599 * allocate_pages - Allocate memory pages from the system
600 * @atype: type of allocation to perform
601 * @mtype: type of memory to allocate
602 * @num_pages: number of contiguous 4KB pages to allocate
603 * @memory: used to return the address of allocated pages
605 * Allocate @num_pages physically contiguous pages from the system
606 * memory and return a pointer to the base of the allocation in
607 * @memory if the allocation succeeds. On success, the firmware memory
608 * map is updated accordingly.
610 * If @atype is AllocateAddress then, on input, @memory specifies the
611 * address at which to attempt to allocate the memory pages.
613 static inline EFI_STATUS
614 allocate_pages(EFI_ALLOCATE_TYPE atype, EFI_MEMORY_TYPE mtype,
615 UINTN num_pages, EFI_PHYSICAL_ADDRESS *memory)
617 return uefi_call_wrapper(BS->AllocatePages, 4, atype,
618 mtype, num_pages, memory);
621 * free_pages - Return memory allocated by allocate_pages() to the firmware
622 * @memory: physical base address of the page range to be freed
623 * @num_pages: number of contiguous 4KB pages to free
625 * On success, the firmware memory map is updated accordingly.
627 static inline EFI_STATUS
628 free_pages(EFI_PHYSICAL_ADDRESS memory, UINTN num_pages)
630 return uefi_call_wrapper(BS->FreePages, 2, memory, num_pages);
633 static EFI_STATUS allocate_addr(EFI_PHYSICAL_ADDRESS *addr, size_t size)
635 UINTN npages = EFI_SIZE_TO_PAGES(size);
637 return uefi_call_wrapper(BS->AllocatePages, 4,
638 AllocateAddress,
639 EfiLoaderData, npages,
640 addr);
643 * allocate_pool - Allocate pool memory
644 * @type: the type of pool to allocate
645 * @size: number of bytes to allocate from pool of @type
646 * @buffer: used to return the address of allocated memory
648 * Allocate memory from pool of @type. If the pool needs more memory
649 * pages are allocated from EfiConventionalMemory in order to grow the
650 * pool.
652 * All allocations are eight-byte aligned.
654 static inline EFI_STATUS
655 allocate_pool(EFI_MEMORY_TYPE type, UINTN size, void **buffer)
657 return uefi_call_wrapper(BS->AllocatePool, 3, type, size, buffer);
661 * free_pool - Return pool memory to the system
662 * @buffer: the buffer to free
664 * Return @buffer to the system. The returned memory is marked as
665 * EfiConventionalMemory.
667 static inline EFI_STATUS free_pool(void *buffer)
669 return uefi_call_wrapper(BS->FreePool, 1, buffer);
672 static void free_addr(EFI_PHYSICAL_ADDRESS addr, size_t size)
674 UINTN npages = EFI_SIZE_TO_PAGES(size);
676 uefi_call_wrapper(BS->FreePages, 2, addr, npages);
679 /* cancel the established timer */
680 static EFI_STATUS cancel_timer(EFI_EVENT ev)
682 return uefi_call_wrapper(BS->SetTimer, 3, ev, TimerCancel, 0);
685 /* Check if timer went off and update default timer counter */
686 void timer_handler(EFI_EVENT ev, VOID *ctx)
688 __ms_timer += DEFAULT_MSTIMER_INC;
689 ++__jiffies;
692 /* Setup a default periodic timer */
693 static EFI_STATUS setup_default_timer(EFI_EVENT *ev)
695 EFI_STATUS efi_status;
697 *ev = NULL;
698 efi_status = uefi_call_wrapper( BS->CreateEvent, 5, EVT_TIMER|EVT_NOTIFY_SIGNAL, TPL_NOTIFY, (EFI_EVENT_NOTIFY)timer_handler, NULL, ev);
699 if (efi_status == EFI_SUCCESS) {
700 efi_status = uefi_call_wrapper(BS->SetTimer, 3, *ev, TimerPeriodic, DEFAULT_TIMER_TICK_DURATION);
702 return efi_status;
706 * emalloc - Allocate memory with a strict alignment requirement
707 * @size: size in bytes of the requested allocation
708 * @align: the required alignment of the allocation
709 * @addr: a pointer to the allocated address on success
711 * If we cannot satisfy @align we return 0.
713 EFI_STATUS emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr)
715 UINTN i, nr_entries, map_key, desc_size;
716 EFI_MEMORY_DESCRIPTOR *map_buf;
717 UINTN d;
718 UINT32 desc_version;
719 EFI_STATUS err;
720 UINTN nr_pages = EFI_SIZE_TO_PAGES(size);
722 map_buf = get_memory_map(&nr_entries, &map_key,
723 &desc_size, &desc_version);
724 if (!map_buf)
725 goto fail;
727 d = (UINTN)map_buf;
729 for (i = 0; i < nr_entries; i++, d += desc_size) {
730 EFI_MEMORY_DESCRIPTOR *desc;
731 EFI_PHYSICAL_ADDRESS start, end, aligned;
733 desc = (EFI_MEMORY_DESCRIPTOR *)d;
734 if (desc->Type != EfiConventionalMemory)
735 continue;
737 if (desc->NumberOfPages < nr_pages)
738 continue;
740 start = desc->PhysicalStart;
741 end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT);
743 /* Low-memory is super-precious! */
744 if (end <= 1 << 20)
745 continue;
746 if (start < 1 << 20)
747 start = (1 << 20);
749 aligned = (start + align -1) & ~(align -1);
751 if ((aligned + size) <= end) {
752 err = allocate_pages(AllocateAddress, EfiLoaderData,
753 nr_pages, &aligned);
754 if (err == EFI_SUCCESS) {
755 *addr = aligned;
756 break;
761 if (i == nr_entries)
762 err = EFI_OUT_OF_RESOURCES;
764 free_pool(map_buf);
765 fail:
766 return err;
769 * efree - Return memory allocated with emalloc
770 * @memory: the address of the emalloc() allocation
771 * @size: the size of the allocation
773 void efree(EFI_PHYSICAL_ADDRESS memory, UINTN size)
775 UINTN nr_pages = EFI_SIZE_TO_PAGES(size);
777 free_pages(memory, nr_pages);
781 * Check whether 'buf' contains a PE/COFF header and that the PE/COFF
782 * file can be executed by this architecture.
784 static bool valid_pecoff_image(char *buf)
786 struct pe_header {
787 uint16_t signature;
788 uint8_t _pad[0x3a];
789 uint32_t offset;
790 } *pehdr = (struct pe_header *)buf;
791 struct coff_header {
792 uint32_t signature;
793 uint16_t machine;
794 } *chdr;
796 if (pehdr->signature != 0x5a4d) {
797 dprintf("Invalid MS-DOS header signature\n");
798 return false;
801 if (!pehdr->offset || pehdr->offset > 512) {
802 dprintf("Invalid PE header offset\n");
803 return false;
806 chdr = (struct coff_header *)&buf[pehdr->offset];
807 if (chdr->signature != 0x4550) {
808 dprintf("Invalid PE header signature\n");
809 return false;
812 #if defined(__x86_64__)
813 if (chdr->machine != 0x8664) {
814 dprintf("Invalid PE machine field\n");
815 return false;
817 #else
818 if (chdr->machine != 0x14c) {
819 dprintf("Invalid PE machine field\n");
820 return false;
822 #endif
824 return true;
828 * Boot a Linux kernel using the EFI boot stub handover protocol.
830 * This function will not return to its caller if booting the kernel
831 * image succeeds. If booting the kernel image fails, a legacy boot
832 * method should be attempted.
834 static void handover_boot(struct linux_header *hdr, struct boot_params *bp)
836 unsigned long address = hdr->code32_start + hdr->handover_offset;
837 handover_func_t *func = efi_handover;
839 dprintf("Booting kernel using handover protocol\n");
842 * Ensure that the kernel is a valid PE32(+) file and that the
843 * architecture of the file matches this version of Syslinux - we
844 * can't mix firmware and kernel bitness (e.g. 32-bit kernel on
845 * 64-bit EFI firmware) using the handover protocol.
847 if (!valid_pecoff_image((char *)hdr))
848 return;
850 if (hdr->version >= 0x20c) {
851 if (hdr->xloadflags & XLF_EFI_HANDOVER_32)
852 func = efi_handover_32;
854 if (hdr->xloadflags & XLF_EFI_HANDOVER_64)
855 func = efi_handover_64;
858 efi_console_restore();
859 func(image_handle, ST, bp, address);
862 static int check_linux_header(struct linux_header *hdr)
864 if (hdr->version < 0x205)
865 hdr->relocatable_kernel = 0;
867 /* FIXME: check boot sector signature */
868 if (hdr->boot_flag != BOOT_SIGNATURE) {
869 printf("Invalid Boot signature 0x%x, bailing out\n", hdr->boot_flag);
870 return -1;
873 return 0;
876 static char *build_cmdline(char *str)
878 EFI_PHYSICAL_ADDRESS addr;
879 EFI_STATUS status;
880 char *cmdline = NULL; /* internal, in efi_physical below 0x3FFFFFFF */
883 * The kernel expects cmdline to be allocated pretty low,
884 * Documentation/x86/boot.txt says,
886 * "The kernel command line can be located anywhere
887 * between the end of the setup heap and 0xA0000"
889 addr = 0xA0000;
890 status = allocate_pages(AllocateMaxAddress, EfiLoaderData,
891 EFI_SIZE_TO_PAGES(strlen(str) + 1),
892 &addr);
893 if (status != EFI_SUCCESS) {
894 printf("Failed to allocate memory for kernel command line, bailing out\n");
895 return NULL;
897 cmdline = (char *)(UINTN)addr;
898 memcpy(cmdline, str, strlen(str) + 1);
899 return cmdline;
902 static int build_gdt(void)
904 EFI_STATUS status;
906 /* Allocate gdt consistent with the alignment for architecture */
907 status = emalloc(gdt.limit, __SIZEOF_POINTER__ , (EFI_PHYSICAL_ADDRESS *)&gdt.base);
908 if (status != EFI_SUCCESS) {
909 printf("Failed to allocate memory for GDT, bailing out\n");
910 return -1;
912 memset(gdt.base, 0x0, gdt.limit);
915 * 4Gb - (0x100000*0x1000 = 4Gb)
916 * base address=0
917 * code read/exec
918 * granularity=4096, 386 (+5th nibble of limit)
920 gdt.base[2] = 0x00cf9a000000ffff;
923 * 4Gb - (0x100000*0x1000 = 4Gb)
924 * base address=0
925 * data read/write
926 * granularity=4096, 386 (+5th nibble of limit)
928 gdt.base[3] = 0x00cf92000000ffff;
930 /* Task segment value */
931 gdt.base[4] = 0x0080890000000000;
933 return 0;
937 * Callers use ->ramdisk_size to check whether any memory was
938 * allocated (and therefore needs free'ing). The return value indicates
939 * hard error conditions, such as failing to alloc memory for the
940 * ramdisk image. Having no initramfs is not an error.
942 static int handle_ramdisks(struct linux_header *hdr,
943 struct initramfs *initramfs)
945 EFI_PHYSICAL_ADDRESS last;
946 struct initramfs *ip;
947 EFI_STATUS status;
948 addr_t irf_size;
949 addr_t next_addr, len, pad;
951 hdr->ramdisk_image = 0;
952 hdr->ramdisk_size = 0;
955 * Figure out the size of the initramfs, and where to put it.
956 * We should put it at the highest possible address which is
957 * <= hdr->initrd_addr_max, which fits the entire initramfs.
959 irf_size = initramfs_size(initramfs); /* Handles initramfs == NULL */
960 if (!irf_size)
961 return 0;
963 last = 0;
964 find_addr(NULL, &last, 0x1000, hdr->initrd_addr_max,
965 irf_size, INITRAMFS_MAX_ALIGN);
966 if (last)
967 status = allocate_addr(&last, irf_size);
969 if (!last || status != EFI_SUCCESS) {
970 printf("Failed to allocate initramfs memory, bailing out\n");
971 return -1;
974 hdr->ramdisk_image = (uint32_t)last;
975 hdr->ramdisk_size = irf_size;
977 /* Copy initramfs into allocated memory */
978 for (ip = initramfs->next; ip->len; ip = ip->next) {
979 len = ip->len;
980 next_addr = last + len;
983 * If this isn't the last entry, extend the
984 * zero-pad region to enforce the alignment of
985 * the next chunk.
987 if (ip->next->len) {
988 pad = -next_addr & (ip->next->align - 1);
989 len += pad;
990 next_addr += pad;
993 if (ip->data_len)
994 memcpy((void *)(UINTN)last, ip->data, ip->data_len);
996 if (len > ip->data_len)
997 memset((void *)(UINTN)(last + ip->data_len), 0,
998 len - ip->data_len);
1000 last = next_addr;
1002 return 0;
1005 static int exit_boot(struct boot_params *bp)
1007 struct e820_entry *e820buf, *e;
1008 EFI_MEMORY_DESCRIPTOR *map;
1009 EFI_STATUS status;
1010 uint32_t e820_type;
1011 UINTN i, nr_entries, key, desc_sz;
1012 UINT32 desc_ver;
1014 /* Build efi memory map */
1015 map = get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
1016 if (!map)
1017 return -1;
1019 bp->efi.memmap = (uint32_t)(unsigned long)map;
1020 bp->efi.memmap_size = nr_entries * desc_sz;
1021 bp->efi.systab = (uint32_t)(unsigned long)ST;
1022 bp->efi.desc_size = desc_sz;
1023 bp->efi.desc_version = desc_ver;
1024 #if defined(__x86_64__)
1025 bp->efi.systab_hi = ((unsigned long)ST) >> 32;
1026 bp->efi.memmap_hi = ((unsigned long)map) >> 32;
1027 #endif
1031 * Even though 'memmap' contains the memory map we provided
1032 * previously in efi_scan_memory(), we should recalculate the
1033 * e820 map because it will most likely have changed in the
1034 * interim.
1036 e = e820buf = bp->e820_map;
1037 for (i = 0; i < nr_entries && i < E820MAX; i++) {
1038 struct e820_entry *prev = NULL;
1040 if (e > e820buf)
1041 prev = e - 1;
1043 map = get_mem_desc(bp->efi.memmap, desc_sz, i);
1044 e->start = map->PhysicalStart;
1045 e->len = map->NumberOfPages << EFI_PAGE_SHIFT;
1047 switch (map->Type) {
1048 case EfiReservedMemoryType:
1049 case EfiRuntimeServicesCode:
1050 case EfiRuntimeServicesData:
1051 case EfiMemoryMappedIO:
1052 case EfiMemoryMappedIOPortSpace:
1053 case EfiPalCode:
1054 e820_type = E820_RESERVED;
1055 break;
1057 case EfiUnusableMemory:
1058 e820_type = E820_UNUSABLE;
1059 break;
1061 case EfiACPIReclaimMemory:
1062 e820_type = E820_ACPI;
1063 break;
1065 case EfiLoaderCode:
1066 case EfiLoaderData:
1067 case EfiBootServicesCode:
1068 case EfiBootServicesData:
1069 case EfiConventionalMemory:
1070 e820_type = E820_RAM;
1071 break;
1073 case EfiACPIMemoryNVS:
1074 e820_type = E820_NVS;
1075 break;
1076 default:
1077 continue;
1080 e->type = e820_type;
1082 /* Check for adjacent entries we can merge. */
1083 if (prev && (prev->start + prev->len) == e->start &&
1084 prev->type == e->type)
1085 prev->len += e->len;
1086 else
1087 e++;
1090 bp->e820_entries = e - e820buf;
1092 status = uefi_call_wrapper(BS->ExitBootServices, 2, image_handle, key);
1093 if (status != EFI_SUCCESS) {
1094 printf("Failed to exit boot services: 0x%016lx\n", status);
1095 FreePool(map);
1096 return -1;
1099 return 0;
1102 /* efi_boot_linux:
1103 * Boots the linux kernel using the image and parameters to boot with.
1104 * The EFI boot loader is reworked taking the cue from
1105 * http://git.kernel.org/?p=boot/efilinux/efilinux.git on the need to
1106 * cap key kernel data structures at * 0x3FFFFFFF.
1107 * The kernel image, kernel command line and boot parameter block are copied
1108 * into allocated memory areas that honor the address capping requirement
1109 * prior to kernel handoff.
1111 * FIXME
1112 * Can we move this allocation requirement to com32 linux loader in order
1113 * to avoid double copying kernel image?
1115 int efi_boot_linux(void *kernel_buf, size_t kernel_size,
1116 struct initramfs *initramfs,
1117 struct setup_data *setup_data,
1118 char *cmdline)
1120 struct linux_header *hdr;
1121 struct boot_params *bp;
1122 EFI_STATUS status;
1123 EFI_PHYSICAL_ADDRESS addr, pref_address, kernel_start = 0;
1124 UINT64 setup_sz, init_size = 0;
1125 char *_cmdline;
1127 if (check_linux_header(kernel_buf))
1128 goto bail;
1130 /* allocate for boot parameter block */
1131 addr = 0x3FFFFFFF;
1132 status = allocate_pages(AllocateMaxAddress, EfiLoaderData,
1133 BOOT_PARAM_BLKSIZE, &addr);
1134 if (status != EFI_SUCCESS) {
1135 printf("Failed to allocate memory for kernel boot parameter block, bailing out\n");
1136 goto bail;
1139 bp = (struct boot_params *)(UINTN)addr;
1141 memset((void *)bp, 0x0, BOOT_PARAM_BLKSIZE);
1142 /* Copy the first two sectors to boot_params */
1143 memcpy((char *)bp, kernel_buf, 2 * 512);
1144 hdr = (struct linux_header *)bp;
1146 setup_sz = (hdr->setup_sects + 1) * 512;
1147 if (hdr->version >= 0x20a) {
1148 pref_address = hdr->pref_address;
1149 init_size = hdr->init_size;
1150 } else {
1151 pref_address = 0x100000;
1154 * We need to account for the fact that the kernel
1155 * needs room for decompression, otherwise we could
1156 * end up trashing other chunks of allocated memory.
1158 init_size = (kernel_size - setup_sz) * 3;
1160 hdr->type_of_loader = SYSLINUX_EFILDR; /* SYSLINUX boot loader module */
1161 _cmdline = build_cmdline(cmdline);
1162 if (!_cmdline)
1163 goto bail;
1165 hdr->cmd_line_ptr = (UINT32)(UINTN)_cmdline;
1167 addr = pref_address;
1168 status = allocate_pages(AllocateAddress, EfiLoaderData,
1169 EFI_SIZE_TO_PAGES(init_size), &addr);
1170 if (status != EFI_SUCCESS) {
1172 * We failed to allocate the preferred address, so
1173 * just allocate some memory and hope for the best.
1175 if (!hdr->relocatable_kernel) {
1176 printf("Cannot relocate kernel, bailing out\n");
1177 goto bail;
1180 status = emalloc(init_size, hdr->kernel_alignment, &addr);
1181 if (status != EFI_SUCCESS) {
1182 printf("Failed to allocate memory for kernel image, bailing out\n");
1183 goto free_map;
1186 kernel_start = addr;
1187 /* FIXME: we copy the kernel into the physical memory allocated here
1188 * The syslinux kernel image load elsewhere could allocate the EFI memory from here
1189 * prior to copying kernel and save an extra copy
1191 memcpy((void *)(UINTN)kernel_start, kernel_buf+setup_sz, kernel_size-setup_sz);
1193 hdr->code32_start = (UINT32)((UINT64)kernel_start);
1195 dprintf("efi_boot_linux: kernel_start 0x%x kernel_size 0x%x initramfs 0x%x setup_data 0x%x cmdline 0x%x\n",
1196 kernel_start, kernel_size, initramfs, setup_data, _cmdline);
1198 if (handle_ramdisks(hdr, initramfs))
1199 goto free_map;
1201 /* Attempt to use the handover protocol if available */
1202 if (hdr->version >= 0x20b && hdr->handover_offset)
1203 handover_boot(hdr, bp);
1205 setup_screen(&bp->screen_info);
1207 if (build_gdt())
1208 goto free_map;
1210 dprintf("efi_boot_linux: setup_sects %d kernel_size %d\n", hdr->setup_sects, kernel_size);
1212 efi_console_restore();
1214 if (exit_boot(bp))
1215 goto free_map;
1217 memcpy(&bp->efi.load_signature, EFI_LOAD_SIG, sizeof(uint32_t));
1219 asm volatile ("lidt %0" :: "m" (idt));
1220 asm volatile ("lgdt %0" :: "m" (gdt));
1222 kernel_jump(kernel_start, bp);
1224 /* NOTREACHED */
1226 free_map:
1227 if (_cmdline)
1228 efree((EFI_PHYSICAL_ADDRESS)(unsigned long)_cmdline,
1229 strlen(_cmdline) + 1);
1231 if (bp)
1232 efree((EFI_PHYSICAL_ADDRESS)(unsigned long)bp,
1233 BOOT_PARAM_BLKSIZE);
1234 if (kernel_start) efree(kernel_start, init_size);
1235 if (hdr->ramdisk_size)
1236 free_addr(hdr->ramdisk_image, hdr->ramdisk_size);
1237 bail:
1238 return -1;
1241 extern struct disk *efi_disk_init(EFI_HANDLE);
1242 static void serialcfg(uint16_t *iobase, uint16_t *divisor, uint16_t *flowctl)
1244 *iobase = *divisor = *flowctl = 0;
1247 extern struct vesa_ops efi_vesa_ops;
1249 struct mem_ops efi_mem_ops = {
1250 .malloc = efi_malloc,
1251 .realloc = efi_realloc,
1252 .free = efi_free,
1255 struct firmware efi_fw = {
1256 .init = efi_init,
1257 .disk_init = efi_disk_init,
1258 .o_ops = &efi_ops,
1259 .i_ops = &efi_iops,
1260 .get_serial_console_info = serialcfg,
1261 .adv_ops = &efi_adv_ops,
1262 .boot_linux = efi_boot_linux,
1263 .vesa = &efi_vesa_ops,
1264 .mem = &efi_mem_ops,
1267 static inline void syslinux_register_efi(void)
1269 firmware = &efi_fw;
1272 extern void init(void);
1273 extern const struct fs_ops vfat_fs_ops;
1274 extern const struct fs_ops pxe_fs_ops;
1276 char free_high_memory[4096];
1278 extern char __bss_start[];
1279 extern char __bss_end[];
1281 static void efi_setcwd(CHAR16 *dp)
1283 CHAR16 *c16;
1284 char *c8;
1285 int i, j;
1287 /* Search for the start of the last path component */
1288 for (i = StrLen(dp) - 1; i >= 0; i--) {
1289 if (dp[i] == '\\' || dp[i] == '/')
1290 break;
1293 if (i < 0 || i > CURRENTDIR_MAX) {
1294 dp = L"\\";
1295 i = 1;
1298 c8 = CurrentDirName;
1299 c16 = dp;
1301 for (j = 0; j < i; j++) {
1302 if (*c16 == '\\') {
1303 *c8++ = '/';
1304 c16++;
1305 } else
1306 *c8++ = *c16++;
1309 *c8 = '\0';
1312 EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
1314 EFI_PXE_BASE_CODE *pxe;
1315 EFI_LOADED_IMAGE *info;
1316 EFI_STATUS status = EFI_SUCCESS;
1317 const struct fs_ops *ops[] = { NULL, NULL };
1318 unsigned long len = (unsigned long)__bss_end - (unsigned long)__bss_start;
1319 static struct efi_disk_private priv;
1320 SIMPLE_INPUT_INTERFACE *in;
1321 EFI_INPUT_KEY key;
1322 EFI_EVENT timer_ev;
1324 memset(__bss_start, 0, len);
1325 InitializeLib(image, table);
1327 image_handle = image;
1328 syslinux_register_efi();
1330 efi_console_save();
1331 init();
1333 status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
1334 &LoadedImageProtocol, (void **)&info);
1335 if (status != EFI_SUCCESS) {
1336 Print(L"Failed to lookup LoadedImageProtocol\n");
1337 goto out;
1340 status = uefi_call_wrapper(BS->HandleProtocol, 3, info->DeviceHandle,
1341 &PxeBaseCodeProtocol, (void **)&pxe);
1342 if (status != EFI_SUCCESS) {
1344 * Use device handle to set up the volume root to
1345 * proceed with ADV init.
1347 if (EFI_ERROR(efi_set_volroot(info->DeviceHandle))) {
1348 Print(L"Failed to locate root device to prep for ");
1349 Print(L"file operations & ADV initialization\n");
1350 goto out;
1353 efi_derivative(SYSLINUX_FS_SYSLINUX);
1354 ops[0] = &vfat_fs_ops;
1355 } else {
1356 efi_derivative(SYSLINUX_FS_PXELINUX);
1357 ops[0] = &pxe_fs_ops;
1358 image_device_handle = info->DeviceHandle;
1361 /* setup timer for boot menu system support */
1362 status = setup_default_timer(&timer_ev);
1363 if (status != EFI_SUCCESS) {
1364 Print(L"Failed to set up EFI timer support, bailing out\n");
1365 goto out;
1368 /* TODO: once all errors are captured in efi_errno, bail out if necessary */
1370 priv.dev_handle = info->DeviceHandle;
1373 * Set the current working directory, which should be the
1374 * directory that syslinux.efi resides in.
1376 efi_setcwd(DevicePathToStr(info->FilePath));
1378 fs_init(ops, (void *)&priv);
1381 * There may be pending user input that wasn't processed by
1382 * whatever application invoked us. Consume and discard that
1383 * data now.
1385 in = ST->ConIn;
1386 do {
1387 status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
1388 } while (status == EFI_SUCCESS);
1390 if (!setjmp(&load_error_buf))
1391 load_env32(NULL);
1393 /* load_env32() failed.. cancel timer and bailout */
1394 status = cancel_timer(timer_ev);
1395 if (status != EFI_SUCCESS)
1396 Print(L"Failed to cancel EFI timer: %x\n", status);
1399 * Tell the firmware that Syslinux failed to load.
1401 status = EFI_LOAD_ERROR;
1402 out:
1403 efi_console_restore();
1404 return status;