Adding upstream version 6.02~pre8+dfsg.
[syslinux-debian/hramrach.git] / efi / main.c
blobb2debfafd910b9ea753347c66db8b824ec6ac788
1 #include <codepage.h>
2 #include <core.h>
3 #include <fs.h>
4 #include <com32.h>
5 #include <syslinux/memscan.h>
6 #include <syslinux/firmware.h>
7 #include <syslinux/linux.h>
8 #include <sys/ansi.h>
10 #include "efi.h"
11 #include "fio.h"
13 __export uint16_t PXERetry;
14 __export char copyright_str[] = "Copyright (C) 2011\n";
15 uint8_t SerialNotice = 1;
16 __export char syslinux_banner[] = "Syslinux 5.x (EFI)\n";
17 char CurrentDirName[CURRENTDIR_MAX];
18 struct com32_sys_args __com32;
20 uint32_t _IdleTimer = 0;
21 char __lowmem_heap[32];
22 uint32_t BIOS_timer_next;
23 uint32_t timer_irq;
24 __export uint8_t KbdMap[256];
25 char aux_seg[256];
27 static inline EFI_STATUS
28 efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid, EFI_HANDLE agent,
29 EFI_HANDLE controller)
31 return uefi_call_wrapper(BS->CloseProtocol, 4, handle,
32 guid, agent, controller);
35 struct efi_binding *efi_create_binding(EFI_GUID *bguid, EFI_GUID *pguid)
37 EFI_SERVICE_BINDING *sbp;
38 struct efi_binding *b;
39 EFI_STATUS status;
40 EFI_HANDLE protocol, child, *handles = NULL;
41 UINTN i, nr_handles = 0;
43 b = malloc(sizeof(*b));
44 if (!b)
45 return NULL;
47 status = LibLocateHandle(ByProtocol, bguid, NULL, &nr_handles, &handles);
48 if (status != EFI_SUCCESS)
49 goto free_binding;
51 for (i = 0; i < nr_handles; i++) {
52 status = uefi_call_wrapper(BS->OpenProtocol, 6, handles[i],
53 bguid, (void **)&sbp,
54 image_handle, handles[i],
55 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
56 if (status == EFI_SUCCESS)
57 break;
59 uefi_call_wrapper(BS->CloseProtocol, 4, handles[i], bguid,
60 image_handle, handles[i]);
63 if (i == nr_handles)
64 goto free_binding;
66 child = NULL;
68 status = uefi_call_wrapper(sbp->CreateChild, 2, sbp, (EFI_HANDLE *)&child);
69 if (status != EFI_SUCCESS)
70 goto close_protocol;
72 status = uefi_call_wrapper(BS->OpenProtocol, 6, child,
73 pguid, (void **)&protocol,
74 image_handle, sbp,
75 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
76 if (status != EFI_SUCCESS)
77 goto destroy_child;
79 b->parent = handles[i];
80 b->binding = sbp;
81 b->child = child;
82 b->this = protocol;
84 return b;
86 destroy_child:
87 uefi_call_wrapper(sbp->DestroyChild, 2, sbp, child);
89 close_protocol:
90 uefi_call_wrapper(BS->CloseProtocol, 4, handles[i], bguid,
91 image_handle, handles[i]);
93 free_binding:
94 free(b);
95 return NULL;
98 void efi_destroy_binding(struct efi_binding *b, EFI_GUID *guid)
100 efi_close_protocol(b->child, guid, image_handle, b->binding);
101 uefi_call_wrapper(b->binding->DestroyChild, 2, b->binding, b->child);
102 efi_close_protocol(b->parent, guid, image_handle, b->parent);
104 free(b);
107 #undef kaboom
108 void kaboom(void)
112 void comboot_cleanup_api(void)
116 void printf_init(void)
120 __export void local_boot(uint16_t ax)
124 void bios_timer_cleanup(void)
128 char trackbuf[4096];
130 void __cdecl core_farcall(uint32_t c, const com32sys_t *a, com32sys_t *b)
134 __export struct firmware *firmware = NULL;
135 void *__syslinux_adv_ptr;
136 size_t __syslinux_adv_size;
137 char core_xfer_buf[65536];
138 struct iso_boot_info {
139 uint32_t pvd; /* LBA of primary volume descriptor */
140 uint32_t file; /* LBA of boot file */
141 uint32_t length; /* Length of boot file */
142 uint32_t csum; /* Checksum of boot file */
143 uint32_t reserved[10]; /* Currently unused */
144 } iso_boot_info;
146 uint8_t DHCPMagic;
147 uint32_t RebootTime;
149 void pxenv(void)
153 uint16_t BIOS_fbm = 1;
154 far_ptr_t InitStack;
155 far_ptr_t PXEEntry;
156 __export unsigned int __bcopyxx_len = 0;
158 void gpxe_unload(void)
162 void do_idle(void)
166 void pxe_int1a(void)
170 uint8_t KeepPXE;
172 struct semaphore;
173 mstime_t sem_down(struct semaphore *sem, mstime_t time)
175 /* EFI is single threaded */
176 return 0;
179 void sem_up(struct semaphore *sem)
181 /* EFI is single threaded */
184 __export volatile uint32_t __ms_timer = 0;
185 volatile uint32_t __jiffies = 0;
187 void efi_write_char(uint8_t ch, uint8_t attribute)
189 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
190 uint16_t c[2];
192 uefi_call_wrapper(out->SetAttribute, 2, out, attribute);
194 /* Lookup primary Unicode encoding in the system codepage */
195 c[0] = codepage.uni[0][ch];
196 c[1] = '\0';
198 uefi_call_wrapper(out->OutputString, 2, out, c);
201 static void efi_showcursor(const struct term_state *st)
203 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
204 bool cursor = st->cursor ? true : false;
206 uefi_call_wrapper(out->EnableCursor, 2, out, cursor);
209 static void efi_set_cursor(int x, int y, bool visible)
211 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
213 uefi_call_wrapper(out->SetCursorPosition, 3, out, x, y);
216 static void efi_scroll_up(uint8_t cols, uint8_t rows, uint8_t attribute)
218 efi_write_char('\n', 0);
219 efi_write_char('\r', 0);
222 static void efi_get_mode(int *cols, int *rows)
224 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
225 UINTN c, r;
227 uefi_call_wrapper(out->QueryMode, 4, out, out->Mode->Mode, &c, &r);
228 *rows = r;
229 *cols = c;
232 static void efi_erase(int x0, int y0, int x1, int y1, uint8_t attribute)
234 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
235 int cols, rows;
237 efi_get_mode(&cols, &rows);
240 * The BIOS version of this function has the ability to erase
241 * parts or all of the screen - the UEFI console doesn't
242 * support this so we just set the cursor position unless
243 * we're clearing the whole screen.
245 if (!x0 && y0 == (cols - 1)) {
246 /* Really clear the screen */
247 uefi_call_wrapper(out->ClearScreen, 1, out);
248 } else {
249 uefi_call_wrapper(out->SetCursorPosition, 3, out, y1, x1);
253 static void efi_text_mode(void)
257 static void efi_get_cursor(uint8_t *x, uint8_t *y)
259 SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
260 *x = out->Mode->CursorColumn;
261 *y = out->Mode->CursorRow;
264 struct output_ops efi_ops = {
265 .erase = efi_erase,
266 .write_char = efi_write_char,
267 .showcursor = efi_showcursor,
268 .set_cursor = efi_set_cursor,
269 .scroll_up = efi_scroll_up,
270 .get_mode = efi_get_mode,
271 .text_mode = efi_text_mode,
272 .get_cursor = efi_get_cursor,
275 char SubvolName[2];
276 static inline EFI_MEMORY_DESCRIPTOR *
277 get_memory_map(UINTN *nr_entries, UINTN *key, UINTN *desc_sz,
278 uint32_t *desc_ver)
280 return LibMemoryMap(nr_entries, key, desc_sz, desc_ver);
284 int efi_scan_memory(scan_memory_callback_t callback, void *data)
286 UINTN i, nr_entries, key, desc_sz;
287 UINTN buf, bufpos;
288 UINT32 desc_ver;
289 int rv = 0;
291 buf = (UINTN)get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
292 if (!buf)
293 return -1;
294 bufpos = buf;
296 for (i = 0; i < nr_entries; bufpos += desc_sz, i++) {
297 EFI_MEMORY_DESCRIPTOR *m;
298 UINT64 region_sz;
299 enum syslinux_memmap_types type;
301 m = (EFI_MEMORY_DESCRIPTOR *)bufpos;
302 region_sz = m->NumberOfPages * EFI_PAGE_SIZE;
304 switch (m->Type) {
305 case EfiConventionalMemory:
306 type = SMT_FREE;
307 break;
308 default:
309 type = SMT_RESERVED;
310 break;
313 rv = callback(data, m->PhysicalStart, region_sz, type);
314 if (rv)
315 break;
318 FreePool((void *)buf);
319 return rv;
322 static struct syslinux_memscan efi_memscan = {
323 .func = efi_scan_memory,
326 extern uint16_t *bios_free_mem;
327 void efi_init(void)
329 /* XXX timer */
330 *bios_free_mem = 0;
331 syslinux_memscan_add(&efi_memscan);
332 mem_init();
335 char efi_getchar(char *hi)
337 SIMPLE_INPUT_INTERFACE *in = ST->ConIn;
338 EFI_INPUT_KEY key;
339 EFI_STATUS status;
341 do {
342 status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
343 } while (status == EFI_NOT_READY);
345 if (!key.ScanCode)
346 return (char)key.UnicodeChar;
349 * We currently only handle scan codes that fit in 8 bits.
351 *hi = (char)key.ScanCode;
352 return 0;
355 int efi_pollchar(void)
357 SIMPLE_INPUT_INTERFACE *in = ST->ConIn;
358 EFI_STATUS status;
360 status = WaitForSingleEvent(in->WaitForKey, 1);
361 return status != EFI_TIMEOUT;
364 struct input_ops efi_iops = {
365 .getchar = efi_getchar,
366 .pollchar = efi_pollchar,
369 extern void efi_adv_init(void);
370 extern int efi_adv_write(void);
372 struct adv_ops efi_adv_ops = {
373 .init = efi_adv_init,
374 .write = efi_adv_write,
377 struct efi_info {
378 uint32_t load_signature;
379 uint32_t systab;
380 uint32_t desc_size;
381 uint32_t desc_version;
382 uint32_t memmap;
383 uint32_t memmap_size;
384 uint32_t systab_hi;
385 uint32_t memmap_hi;
388 #define E820MAX 128
389 #define E820_RAM 1
390 #define E820_RESERVED 2
391 #define E820_ACPI 3
392 #define E820_NVS 4
393 #define E820_UNUSABLE 5
395 #define BOOT_SIGNATURE 0xaa55
396 #define SYSLINUX_EFILDR 0x30 /* Is this published value? */
397 #define DEFAULT_TIMER_TICK_DURATION 500000 /* 500000 == 500000 * 100 * 10^-9 == 50 msec */
398 #define DEFAULT_MSTIMER_INC 0x32 /* 50 msec */
399 struct e820_entry {
400 uint64_t start;
401 uint64_t len;
402 uint32_t type;
403 } __packed;
405 struct boot_params {
406 struct screen_info screen_info;
407 uint8_t _pad[0x1c0 - sizeof(struct screen_info)];
408 struct efi_info efi;
409 uint8_t _pad2[8];
410 uint8_t e820_entries;
411 uint8_t _pad3[0x2d0 - 0x1e8 - sizeof(uint8_t)];
412 struct e820_entry e820_map[E820MAX];
413 } __packed;
415 /* Allocate boot parameter block aligned to page */
416 #define BOOT_PARAM_BLKSIZE EFI_SIZE_TO_PAGES(sizeof(struct boot_params)) * EFI_PAGE_SIZE
418 /* Routines in support of efi boot loader were obtained from
419 * http://git.kernel.org/?p=boot/efilinux/efilinux.git:
420 * kernel_jump(), handover_jump(),
421 * emalloc()/efree, alloc_pages/free_pages
422 * allocate_pool()/free_pool()
423 * memory_map()
425 extern void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start,
426 struct boot_params *boot_params);
427 #if __SIZEOF_POINTER__ == 4
428 #define EFI_LOAD_SIG "EL32"
429 #elif __SIZEOF_POINTER__ == 8
430 #define EFI_LOAD_SIG "EL64"
431 #else
432 #error "unsupported architecture"
433 #endif
435 struct dt_desc {
436 uint16_t limit;
437 uint64_t *base;
438 } __packed;
440 struct dt_desc gdt = { 0x800, (uint64_t *)0 };
441 struct dt_desc idt = { 0, 0 };
443 static inline EFI_MEMORY_DESCRIPTOR *
444 get_mem_desc(unsigned long memmap, UINTN desc_sz, int i)
446 return (EFI_MEMORY_DESCRIPTOR *)(memmap + (i * desc_sz));
449 EFI_HANDLE image_handle;
451 static inline UINT64 round_up(UINT64 x, UINT64 y)
453 return (((x - 1) | (y - 1)) + 1);
456 static inline UINT64 round_down(UINT64 x, UINT64 y)
458 return (x & ~(y - 1));
461 static void find_addr(EFI_PHYSICAL_ADDRESS *first,
462 EFI_PHYSICAL_ADDRESS *last,
463 EFI_PHYSICAL_ADDRESS min,
464 EFI_PHYSICAL_ADDRESS max,
465 size_t size, size_t align)
467 EFI_MEMORY_DESCRIPTOR *map;
468 UINT32 desc_ver;
469 UINTN i, nr_entries, key, desc_sz;
471 map = get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
472 if (!map)
473 return;
475 for (i = 0; i < nr_entries; i++) {
476 EFI_MEMORY_DESCRIPTOR *m;
477 EFI_PHYSICAL_ADDRESS best;
478 UINT64 start, end;
480 m = get_mem_desc((unsigned long)map, desc_sz, i);
481 if (m->Type != EfiConventionalMemory)
482 continue;
484 if (m->NumberOfPages < EFI_SIZE_TO_PAGES(size))
485 continue;
487 start = m->PhysicalStart;
488 end = m->PhysicalStart + (m->NumberOfPages << EFI_PAGE_SHIFT);
489 if (first) {
490 if (end < min)
491 continue;
493 /* What's the best address? */
494 if (start < min && min < end)
495 best = min;
496 else
497 best = m->PhysicalStart;
499 start = round_up(best, align);
500 if (start > max)
501 continue;
503 /* Have we run out of space in this region? */
504 if (end < start || (start + size) > end)
505 continue;
507 if (start < *first)
508 *first = start;
511 if (last) {
512 if (start > max)
513 continue;
515 /* What's the best address? */
516 if (start < max && max < end)
517 best = max - size;
518 else
519 best = end - size;
521 start = round_down(best, align);
522 if (start < min || start < m->PhysicalStart)
523 continue;
525 if (start > *last)
526 *last = start;
530 FreePool(map);
534 * allocate_pages - Allocate memory pages from the system
535 * @atype: type of allocation to perform
536 * @mtype: type of memory to allocate
537 * @num_pages: number of contiguous 4KB pages to allocate
538 * @memory: used to return the address of allocated pages
540 * Allocate @num_pages physically contiguous pages from the system
541 * memory and return a pointer to the base of the allocation in
542 * @memory if the allocation succeeds. On success, the firmware memory
543 * map is updated accordingly.
545 * If @atype is AllocateAddress then, on input, @memory specifies the
546 * address at which to attempt to allocate the memory pages.
548 static inline EFI_STATUS
549 allocate_pages(EFI_ALLOCATE_TYPE atype, EFI_MEMORY_TYPE mtype,
550 UINTN num_pages, EFI_PHYSICAL_ADDRESS *memory)
552 return uefi_call_wrapper(BS->AllocatePages, 4, atype,
553 mtype, num_pages, memory);
556 * free_pages - Return memory allocated by allocate_pages() to the firmware
557 * @memory: physical base address of the page range to be freed
558 * @num_pages: number of contiguous 4KB pages to free
560 * On success, the firmware memory map is updated accordingly.
562 static inline EFI_STATUS
563 free_pages(EFI_PHYSICAL_ADDRESS memory, UINTN num_pages)
565 return uefi_call_wrapper(BS->FreePages, 2, memory, num_pages);
568 static EFI_STATUS allocate_addr(EFI_PHYSICAL_ADDRESS *addr, size_t size)
570 UINTN npages = EFI_SIZE_TO_PAGES(size);
572 return uefi_call_wrapper(BS->AllocatePages, 4,
573 AllocateAddress,
574 EfiLoaderData, npages,
575 addr);
578 * allocate_pool - Allocate pool memory
579 * @type: the type of pool to allocate
580 * @size: number of bytes to allocate from pool of @type
581 * @buffer: used to return the address of allocated memory
583 * Allocate memory from pool of @type. If the pool needs more memory
584 * pages are allocated from EfiConventionalMemory in order to grow the
585 * pool.
587 * All allocations are eight-byte aligned.
589 static inline EFI_STATUS
590 allocate_pool(EFI_MEMORY_TYPE type, UINTN size, void **buffer)
592 return uefi_call_wrapper(BS->AllocatePool, 3, type, size, buffer);
596 * free_pool - Return pool memory to the system
597 * @buffer: the buffer to free
599 * Return @buffer to the system. The returned memory is marked as
600 * EfiConventionalMemory.
602 static inline EFI_STATUS free_pool(void *buffer)
604 return uefi_call_wrapper(BS->FreePool, 1, buffer);
607 static void free_addr(EFI_PHYSICAL_ADDRESS addr, size_t size)
609 UINTN npages = EFI_SIZE_TO_PAGES(size);
611 uefi_call_wrapper(BS->FreePages, 2, addr, npages);
614 /* cancel the established timer */
615 static EFI_STATUS cancel_timer(EFI_EVENT ev)
617 return uefi_call_wrapper(BS->SetTimer, 3, ev, TimerCancel, 0);
620 /* Check if timer went off and update default timer counter */
621 void timer_handler(EFI_EVENT ev, VOID *ctx)
623 __ms_timer += DEFAULT_MSTIMER_INC;
624 ++__jiffies;
627 /* Setup a default periodic timer */
628 static EFI_STATUS setup_default_timer(EFI_EVENT *ev)
630 EFI_STATUS efi_status;
632 *ev = NULL;
633 efi_status = uefi_call_wrapper( BS->CreateEvent, 5, EVT_TIMER|EVT_NOTIFY_SIGNAL, TPL_NOTIFY, (EFI_EVENT_NOTIFY)timer_handler, NULL, ev);
634 if (efi_status == EFI_SUCCESS) {
635 efi_status = uefi_call_wrapper(BS->SetTimer, 3, *ev, TimerPeriodic, DEFAULT_TIMER_TICK_DURATION);
637 return efi_status;
641 * emalloc - Allocate memory with a strict alignment requirement
642 * @size: size in bytes of the requested allocation
643 * @align: the required alignment of the allocation
644 * @addr: a pointer to the allocated address on success
646 * If we cannot satisfy @align we return 0.
648 EFI_STATUS emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr)
650 UINTN i, nr_entries, map_key, desc_size;
651 EFI_MEMORY_DESCRIPTOR *map_buf;
652 UINTN d;
653 UINT32 desc_version;
654 EFI_STATUS err;
655 UINTN nr_pages = EFI_SIZE_TO_PAGES(size);
657 map_buf = get_memory_map(&nr_entries, &map_key,
658 &desc_size, &desc_version);
659 if (!map_buf)
660 goto fail;
662 d = (UINTN)map_buf;
664 for (i = 0; i < nr_entries; i++, d += desc_size) {
665 EFI_MEMORY_DESCRIPTOR *desc;
666 EFI_PHYSICAL_ADDRESS start, end, aligned;
668 desc = (EFI_MEMORY_DESCRIPTOR *)d;
669 if (desc->Type != EfiConventionalMemory)
670 continue;
672 if (desc->NumberOfPages < nr_pages)
673 continue;
675 start = desc->PhysicalStart;
676 end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT);
678 /* Low-memory is super-precious! */
679 if (end <= 1 << 20)
680 continue;
681 if (start < 1 << 20) {
682 size -= (1 << 20) - start;
683 start = (1 << 20);
686 aligned = (start + align -1) & ~(align -1);
688 if ((aligned + size) <= end) {
689 err = allocate_pages(AllocateAddress, EfiLoaderData,
690 nr_pages, &aligned);
691 if (err == EFI_SUCCESS) {
692 *addr = aligned;
693 break;
698 if (i == nr_entries)
699 err = EFI_OUT_OF_RESOURCES;
701 free_pool(map_buf);
702 fail:
703 return err;
706 * efree - Return memory allocated with emalloc
707 * @memory: the address of the emalloc() allocation
708 * @size: the size of the allocation
710 void efree(EFI_PHYSICAL_ADDRESS memory, UINTN size)
712 UINTN nr_pages = EFI_SIZE_TO_PAGES(size);
714 free_pages(memory, nr_pages);
718 * Check whether 'buf' contains a PE/COFF header and that the PE/COFF
719 * file can be executed by this architecture.
721 static bool valid_pecoff_image(char *buf)
723 struct pe_header {
724 uint16_t signature;
725 uint8_t _pad[0x3a];
726 uint32_t offset;
727 } *pehdr = (struct pe_header *)buf;
728 struct coff_header {
729 uint32_t signature;
730 uint16_t machine;
731 } *chdr;
733 if (pehdr->signature != 0x5a4d) {
734 dprintf("Invalid MS-DOS header signature\n");
735 return false;
738 if (!pehdr->offset || pehdr->offset > 512) {
739 dprintf("Invalid PE header offset\n");
740 return false;
743 chdr = (struct coff_header *)&buf[pehdr->offset];
744 if (chdr->signature != 0x4550) {
745 dprintf("Invalid PE header signature\n");
746 return false;
749 #if defined(__x86_64__)
750 if (chdr->machine != 0x8664) {
751 dprintf("Invalid PE machine field\n");
752 return false;
754 #else
755 if (chdr->machine != 0x14c) {
756 dprintf("Invalid PE machine field\n");
757 return false;
759 #endif
761 return true;
765 * Boot a Linux kernel using the EFI boot stub handover protocol.
767 * This function will not return to its caller if booting the kernel
768 * image succeeds. If booting the kernel image fails, a legacy boot
769 * method should be attempted.
771 static void handover_boot(struct linux_header *hdr, struct boot_params *bp)
773 unsigned long address = hdr->code32_start + hdr->handover_offset;
774 handover_func_t *func = efi_handover;
776 dprintf("Booting kernel using handover protocol\n");
779 * Ensure that the kernel is a valid PE32(+) file and that the
780 * architecture of the file matches this version of Syslinux - we
781 * can't mix firmware and kernel bitness (e.g. 32-bit kernel on
782 * 64-bit EFI firmware) using the handover protocol.
784 if (!valid_pecoff_image((char *)hdr))
785 return;
787 if (hdr->version >= 0x20c) {
788 if (hdr->xloadflags & XLF_EFI_HANDOVER_32)
789 func = efi_handover_32;
791 if (hdr->xloadflags & XLF_EFI_HANDOVER_64)
792 func = efi_handover_64;
795 efi_console_restore();
796 func(image_handle, ST, bp, address);
799 static int check_linux_header(struct linux_header *hdr)
801 if (hdr->version < 0x205)
802 hdr->relocatable_kernel = 0;
804 /* FIXME: check boot sector signature */
805 if (hdr->boot_flag != BOOT_SIGNATURE) {
806 printf("Invalid Boot signature 0x%x, bailing out\n", hdr->boot_flag);
807 return -1;
810 return 0;
813 static char *build_cmdline(char *str)
815 EFI_PHYSICAL_ADDRESS addr;
816 EFI_STATUS status;
817 char *cmdline = NULL; /* internal, in efi_physical below 0x3FFFFFFF */
820 * The kernel expects cmdline to be allocated pretty low,
821 * Documentation/x86/boot.txt says,
823 * "The kernel command line can be located anywhere
824 * between the end of the setup heap and 0xA0000"
826 addr = 0xA0000;
827 status = allocate_pages(AllocateMaxAddress, EfiLoaderData,
828 EFI_SIZE_TO_PAGES(strlen(str) + 1),
829 &addr);
830 if (status != EFI_SUCCESS) {
831 printf("Failed to allocate memory for kernel command line, bailing out\n");
832 return NULL;
834 cmdline = (char *)(UINTN)addr;
835 memcpy(cmdline, str, strlen(str) + 1);
836 return cmdline;
839 static int build_gdt(void)
841 EFI_STATUS status;
843 /* Allocate gdt consistent with the alignment for architecture */
844 status = emalloc(gdt.limit, __SIZEOF_POINTER__ , (EFI_PHYSICAL_ADDRESS *)&gdt.base);
845 if (status != EFI_SUCCESS) {
846 printf("Failed to allocate memory for GDT, bailing out\n");
847 return -1;
849 memset(gdt.base, 0x0, gdt.limit);
852 * 4Gb - (0x100000*0x1000 = 4Gb)
853 * base address=0
854 * code read/exec
855 * granularity=4096, 386 (+5th nibble of limit)
857 gdt.base[2] = 0x00cf9a000000ffff;
860 * 4Gb - (0x100000*0x1000 = 4Gb)
861 * base address=0
862 * data read/write
863 * granularity=4096, 386 (+5th nibble of limit)
865 gdt.base[3] = 0x00cf92000000ffff;
867 /* Task segment value */
868 gdt.base[4] = 0x0080890000000000;
870 return 0;
874 * Callers use ->ramdisk_size to check whether any memory was
875 * allocated (and therefore needs free'ing). The return value indicates
876 * hard error conditions, such as failing to alloc memory for the
877 * ramdisk image. Having no initramfs is not an error.
879 static int handle_ramdisks(struct linux_header *hdr,
880 struct initramfs *initramfs)
882 EFI_PHYSICAL_ADDRESS last;
883 struct initramfs *ip;
884 EFI_STATUS status;
885 addr_t irf_size;
886 addr_t next_addr, len, pad;
888 hdr->ramdisk_image = 0;
889 hdr->ramdisk_size = 0;
892 * Figure out the size of the initramfs, and where to put it.
893 * We should put it at the highest possible address which is
894 * <= hdr->initrd_addr_max, which fits the entire initramfs.
896 irf_size = initramfs_size(initramfs); /* Handles initramfs == NULL */
897 if (!irf_size)
898 return 0;
900 last = 0;
901 find_addr(NULL, &last, 0x1000, hdr->initrd_addr_max,
902 irf_size, INITRAMFS_MAX_ALIGN);
903 if (last)
904 status = allocate_addr(&last, irf_size);
906 if (!last || status != EFI_SUCCESS) {
907 printf("Failed to allocate initramfs memory, bailing out\n");
908 return -1;
911 hdr->ramdisk_image = (uint32_t)last;
912 hdr->ramdisk_size = irf_size;
914 /* Copy initramfs into allocated memory */
915 for (ip = initramfs->next; ip->len; ip = ip->next) {
916 len = ip->len;
917 next_addr = last + len;
920 * If this isn't the last entry, extend the
921 * zero-pad region to enforce the alignment of
922 * the next chunk.
924 if (ip->next->len) {
925 pad = -next_addr & (ip->next->align - 1);
926 len += pad;
927 next_addr += pad;
930 if (ip->data_len)
931 memcpy((void *)(UINTN)last, ip->data, ip->data_len);
933 if (len > ip->data_len)
934 memset((void *)(UINTN)(last + ip->data_len), 0,
935 len - ip->data_len);
937 last = next_addr;
939 return 0;
942 static int exit_boot(struct boot_params *bp)
944 struct e820_entry *e820buf, *e;
945 EFI_MEMORY_DESCRIPTOR *map;
946 EFI_STATUS status;
947 uint32_t e820_type;
948 UINTN i, nr_entries, key, desc_sz;
949 UINT32 desc_ver;
951 /* Build efi memory map */
952 map = get_memory_map(&nr_entries, &key, &desc_sz, &desc_ver);
953 if (!map)
954 return -1;
956 bp->efi.memmap = (uint32_t)(unsigned long)map;
957 bp->efi.memmap_size = nr_entries * desc_sz;
958 bp->efi.systab = (uint32_t)(unsigned long)ST;
959 bp->efi.desc_size = desc_sz;
960 bp->efi.desc_version = desc_ver;
961 #if defined(__x86_64__)
962 bp->efi.systab_hi = ((unsigned long)ST) >> 32;
963 bp->efi.memmap_hi = ((unsigned long)map) >> 32;
964 #endif
968 * Even though 'memmap' contains the memory map we provided
969 * previously in efi_scan_memory(), we should recalculate the
970 * e820 map because it will most likely have changed in the
971 * interim.
973 e = e820buf = bp->e820_map;
974 for (i = 0; i < nr_entries && i < E820MAX; i++) {
975 struct e820_entry *prev = NULL;
977 if (e > e820buf)
978 prev = e - 1;
980 map = get_mem_desc(bp->efi.memmap, desc_sz, i);
981 e->start = map->PhysicalStart;
982 e->len = map->NumberOfPages << EFI_PAGE_SHIFT;
984 switch (map->Type) {
985 case EfiReservedMemoryType:
986 case EfiRuntimeServicesCode:
987 case EfiRuntimeServicesData:
988 case EfiMemoryMappedIO:
989 case EfiMemoryMappedIOPortSpace:
990 case EfiPalCode:
991 e820_type = E820_RESERVED;
992 break;
994 case EfiUnusableMemory:
995 e820_type = E820_UNUSABLE;
996 break;
998 case EfiACPIReclaimMemory:
999 e820_type = E820_ACPI;
1000 break;
1002 case EfiLoaderCode:
1003 case EfiLoaderData:
1004 case EfiBootServicesCode:
1005 case EfiBootServicesData:
1006 case EfiConventionalMemory:
1007 e820_type = E820_RAM;
1008 break;
1010 case EfiACPIMemoryNVS:
1011 e820_type = E820_NVS;
1012 break;
1013 default:
1014 continue;
1017 e->type = e820_type;
1019 /* Check for adjacent entries we can merge. */
1020 if (prev && (prev->start + prev->len) == e->start &&
1021 prev->type == e->type)
1022 prev->len += e->len;
1023 else
1024 e++;
1027 bp->e820_entries = e - e820buf;
1029 status = uefi_call_wrapper(BS->ExitBootServices, 2, image_handle, key);
1030 if (status != EFI_SUCCESS) {
1031 printf("Failed to exit boot services: 0x%016lx\n", status);
1032 FreePool(map);
1033 return -1;
1036 return 0;
1039 /* efi_boot_linux:
1040 * Boots the linux kernel using the image and parameters to boot with.
1041 * The EFI boot loader is reworked taking the cue from
1042 * http://git.kernel.org/?p=boot/efilinux/efilinux.git on the need to
1043 * cap key kernel data structures at * 0x3FFFFFFF.
1044 * The kernel image, kernel command line and boot parameter block are copied
1045 * into allocated memory areas that honor the address capping requirement
1046 * prior to kernel handoff.
1048 * FIXME
1049 * Can we move this allocation requirement to com32 linux loader in order
1050 * to avoid double copying kernel image?
1052 int efi_boot_linux(void *kernel_buf, size_t kernel_size,
1053 struct initramfs *initramfs,
1054 struct setup_data *setup_data,
1055 char *cmdline)
1057 struct linux_header *hdr;
1058 struct boot_params *bp;
1059 EFI_STATUS status;
1060 EFI_PHYSICAL_ADDRESS addr, pref_address, kernel_start = 0;
1061 UINT64 setup_sz, init_size = 0;
1062 char *_cmdline;
1064 if (check_linux_header(kernel_buf))
1065 goto bail;
1067 /* allocate for boot parameter block */
1068 addr = 0x3FFFFFFF;
1069 status = allocate_pages(AllocateMaxAddress, EfiLoaderData,
1070 BOOT_PARAM_BLKSIZE, &addr);
1071 if (status != EFI_SUCCESS) {
1072 printf("Failed to allocate memory for kernel boot parameter block, bailing out\n");
1073 goto bail;
1076 bp = (struct boot_params *)(UINTN)addr;
1078 memset((void *)bp, 0x0, BOOT_PARAM_BLKSIZE);
1079 /* Copy the first two sectors to boot_params */
1080 memcpy((char *)bp, kernel_buf, 2 * 512);
1081 hdr = (struct linux_header *)bp;
1083 setup_sz = (hdr->setup_sects + 1) * 512;
1084 if (hdr->version >= 0x20a) {
1085 pref_address = hdr->pref_address;
1086 init_size = hdr->init_size;
1087 } else {
1088 pref_address = 0x100000;
1091 * We need to account for the fact that the kernel
1092 * needs room for decompression, otherwise we could
1093 * end up trashing other chunks of allocated memory.
1095 init_size = (kernel_size - setup_sz) * 3;
1097 hdr->type_of_loader = SYSLINUX_EFILDR; /* SYSLINUX boot loader module */
1098 _cmdline = build_cmdline(cmdline);
1099 if (!_cmdline)
1100 goto bail;
1102 hdr->cmd_line_ptr = (UINT32)(UINTN)_cmdline;
1104 addr = pref_address;
1105 status = allocate_pages(AllocateAddress, EfiLoaderData,
1106 EFI_SIZE_TO_PAGES(init_size), &addr);
1107 if (status != EFI_SUCCESS) {
1109 * We failed to allocate the preferred address, so
1110 * just allocate some memory and hope for the best.
1112 if (!hdr->relocatable_kernel) {
1113 printf("Cannot relocate kernel, bailing out\n");
1114 goto bail;
1117 status = emalloc(init_size, hdr->kernel_alignment, &addr);
1118 if (status != EFI_SUCCESS) {
1119 printf("Failed to allocate memory for kernel image, bailing out\n");
1120 goto free_map;
1123 kernel_start = addr;
1124 /* FIXME: we copy the kernel into the physical memory allocated here
1125 * The syslinux kernel image load elsewhere could allocate the EFI memory from here
1126 * prior to copying kernel and save an extra copy
1128 memcpy((void *)(UINTN)kernel_start, kernel_buf+setup_sz, kernel_size-setup_sz);
1130 hdr->code32_start = (UINT32)((UINT64)kernel_start);
1132 dprintf("efi_boot_linux: kernel_start 0x%x kernel_size 0x%x initramfs 0x%x setup_data 0x%x cmdline 0x%x\n",
1133 kernel_start, kernel_size, initramfs, setup_data, _cmdline);
1135 if (handle_ramdisks(hdr, initramfs))
1136 goto free_map;
1138 /* Attempt to use the handover protocol if available */
1139 if (hdr->version >= 0x20b && hdr->handover_offset)
1140 handover_boot(hdr, bp);
1142 setup_screen(&bp->screen_info);
1144 if (build_gdt())
1145 goto free_map;
1147 dprintf("efi_boot_linux: setup_sects %d kernel_size %d\n", hdr->setup_sects, kernel_size);
1149 efi_console_restore();
1151 if (exit_boot(bp))
1152 goto free_map;
1154 memcpy(&bp->efi.load_signature, EFI_LOAD_SIG, sizeof(uint32_t));
1156 asm volatile ("lidt %0" :: "m" (idt));
1157 asm volatile ("lgdt %0" :: "m" (gdt));
1159 kernel_jump(kernel_start, bp);
1161 /* NOTREACHED */
1163 free_map:
1164 if (_cmdline)
1165 efree((EFI_PHYSICAL_ADDRESS)(unsigned long)_cmdline,
1166 strlen(_cmdline) + 1);
1168 if (bp)
1169 efree((EFI_PHYSICAL_ADDRESS)(unsigned long)bp,
1170 BOOT_PARAM_BLKSIZE);
1171 if (kernel_start) efree(kernel_start, init_size);
1172 if (hdr->ramdisk_size)
1173 free_addr(hdr->ramdisk_image, hdr->ramdisk_size);
1174 bail:
1175 return -1;
1178 extern struct disk *efi_disk_init(EFI_HANDLE);
1179 extern void serialcfg(uint16_t *, uint16_t *, uint16_t *);
1181 extern struct vesa_ops efi_vesa_ops;
1183 struct mem_ops efi_mem_ops = {
1184 .malloc = efi_malloc,
1185 .realloc = efi_realloc,
1186 .free = efi_free,
1189 struct firmware efi_fw = {
1190 .init = efi_init,
1191 .disk_init = efi_disk_init,
1192 .o_ops = &efi_ops,
1193 .i_ops = &efi_iops,
1194 .get_serial_console_info = serialcfg,
1195 .adv_ops = &efi_adv_ops,
1196 .boot_linux = efi_boot_linux,
1197 .vesa = &efi_vesa_ops,
1198 .mem = &efi_mem_ops,
1201 static inline void syslinux_register_efi(void)
1203 firmware = &efi_fw;
1206 extern void init(void);
1207 extern const struct fs_ops vfat_fs_ops;
1208 extern const struct fs_ops pxe_fs_ops;
1210 char free_high_memory[4096];
1212 extern char __bss_start[];
1213 extern char __bss_end[];
1215 static void efi_setcwd(CHAR16 *dp)
1217 CHAR16 *c16;
1218 char *c8;
1219 int i, j;
1221 /* Search for the start of the last path component */
1222 for (i = StrLen(dp) - 1; i >= 0; i--) {
1223 if (dp[i] == '\\' || dp[i] == '/')
1224 break;
1227 if (i < 0 || i > CURRENTDIR_MAX) {
1228 dp = L"\\";
1229 i = 1;
1232 c8 = CurrentDirName;
1233 c16 = dp;
1235 for (j = 0; j < i; j++) {
1236 if (*c16 == '\\') {
1237 *c8++ = '/';
1238 c16++;
1239 } else
1240 *c8++ = *c16++;
1243 *c8 = '\0';
1246 EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
1248 EFI_PXE_BASE_CODE *pxe;
1249 EFI_LOADED_IMAGE *info;
1250 EFI_STATUS status = EFI_SUCCESS;
1251 const struct fs_ops *ops[] = { NULL, NULL };
1252 unsigned long len = (unsigned long)__bss_end - (unsigned long)__bss_start;
1253 static struct efi_disk_private priv;
1254 SIMPLE_INPUT_INTERFACE *in;
1255 EFI_INPUT_KEY key;
1256 EFI_EVENT timer_ev;
1258 memset(__bss_start, 0, len);
1259 InitializeLib(image, table);
1261 image_handle = image;
1262 syslinux_register_efi();
1264 efi_console_save();
1265 init();
1267 status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
1268 &LoadedImageProtocol, (void **)&info);
1269 if (status != EFI_SUCCESS) {
1270 Print(L"Failed to lookup LoadedImageProtocol\n");
1271 goto out;
1274 status = uefi_call_wrapper(BS->HandleProtocol, 3, info->DeviceHandle,
1275 &PxeBaseCodeProtocol, (void **)&pxe);
1276 if (status != EFI_SUCCESS) {
1278 * Use device handle to set up the volume root to
1279 * proceed with ADV init.
1281 if (EFI_ERROR(efi_set_volroot(info->DeviceHandle))) {
1282 Print(L"Failed to locate root device to prep for ");
1283 Print(L"file operations & ADV initialization\n");
1284 goto out;
1287 efi_derivative(SYSLINUX_FS_SYSLINUX);
1288 ops[0] = &vfat_fs_ops;
1289 } else {
1290 efi_derivative(SYSLINUX_FS_PXELINUX);
1291 ops[0] = &pxe_fs_ops;
1294 /* setup timer for boot menu system support */
1295 status = setup_default_timer(&timer_ev);
1296 if (status != EFI_SUCCESS) {
1297 Print(L"Failed to set up EFI timer support, bailing out\n");
1298 goto out;
1301 /* TODO: once all errors are captured in efi_errno, bail out if necessary */
1303 priv.dev_handle = info->DeviceHandle;
1306 * Set the current working directory, which should be the
1307 * directory that syslinux.efi resides in.
1309 efi_setcwd(DevicePathToStr(info->FilePath));
1311 fs_init(ops, (void *)&priv);
1314 * There may be pending user input that wasn't processed by
1315 * whatever application invoked us. Consume and discard that
1316 * data now.
1318 in = ST->ConIn;
1319 do {
1320 status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
1321 } while (status != EFI_NOT_READY);
1323 load_env32(NULL);
1325 /* load_env32() failed.. cancel timer and bailout */
1326 status = cancel_timer(timer_ev);
1327 if (status != EFI_SUCCESS)
1328 Print(L"Failed to cancel EFI timer: %x\n", status);
1331 * Tell the firmware that Syslinux failed to load.
1333 status = EFI_LOAD_ERROR;
1334 out:
1335 efi_console_restore();
1336 return status;