2 * Copyright (C) 2001-2003 Hewlett-Packard Co.
3 * Contributed by Stephane Eranian <eranian@hpl.hp.com>
5 * Copyright (C) 2001 Silicon Graphics, Inc.
6 * Contributed by Brent Casavant <bcasavan@sgi.com>
8 * Copyright (C) 2006-2009 Intel Corporation
9 * Contributed by Fenghua Yu <fenghua.yu@intel.com>
10 * Contributed by Bibo Mao <bibo.mao@intel.com>
11 * Contributed by Chandramouli Narayanan <mouli@linux.intel.com>
13 * This file is part of the ELILO, the EFI Linux boot loader.
15 * ELILO is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
20 * ELILO is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with ELILO; see the file COPYING. If not, write to the Free
27 * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 * Please check out the elilo.txt for complete documentation on how
31 * to use this program.
39 #define TENTH_SEC 1000000 /* 1/10th second in 100ns unit */
40 #define READ_BLOCK_SIZE (4*EFI_PAGE_SIZE) /* block size for read_file */
42 #define is_cr(k) (((k)==CHAR_LINEFEED)||((k)==CHAR_CARRIAGE_RETURN))
43 #define CHAR_SPACE L' '
46 read_keypress(EFI_INPUT_KEY *key)
48 return uefi_call_wrapper(systab->ConIn->ReadKeyStroke,
60 return read_keypress(&key);
66 uefi_call_wrapper(systab->ConIn->Reset,
74 wait_keypress_abort(VOID)
76 SIMPLE_INPUT_INTERFACE *conin = systab->ConIn;
82 Print(L"Hit ENTER to continue or ANY other key to cancel");
84 /* cleanup buffer first */
85 while (uefi_call_wrapper(conin->ReadKeyStroke, 2, conin, &key) == EFI_SUCCESS);
87 while ((status=uefi_call_wrapper(conin->ReadKeyStroke,2, conin, &key)) == EFI_NOT_READY );
89 if (EFI_ERROR(status)) return ELILO_LOAD_ERROR;
93 return is_cr(key.UnicodeChar) ? ELILO_LOAD_SUCCESS: ELILO_BOOT_ABORTED;
98 * wait for timeout to expire or keypress
100 * 0 : timeout expired
101 * 1 : a key was pressed (still input stream to process)
102 * -1: an error occured
105 wait_timeout(UINTN timeout)
113 if (timeout == 0) return 0;
115 /* Create a timeout timer */
116 status = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &timer);
117 if (EFI_ERROR(status)) {
118 ERR_PRT((L" waitkey CreateEvent failed %r", status));
121 /* In 100ns increments */
122 status = uefi_call_wrapper(BS->SetTimer, 3, timer, TimerPeriodic, TENTH_SEC);
123 if (EFI_ERROR(status)) {
124 ERR_PRT((L"waitkey SetTimer failed %r", status));
129 list[1] = systab->ConIn->WaitForKey;
132 status = uefi_call_wrapper(BS->WaitForEvent, 3, 2, list, &idx);
133 if (EFI_ERROR(status)) {
134 ERR_PRT((L"waitkey WaitForEvent failed %r", status));
137 if (timeout % 10 == 1) Print(L".");
139 } while (timeout-- && idx == 0);
143 * SetTimer(timer, TimerCancel, 0) is causing problems on IA-32 and gcc3
144 * I do not know why it dies with EFI12.35. So let's fake a key stroke.
146 status = uefi_call_wrapper(BS->SetTimer, 3, timer, TimerCancel, 0);
147 if (EFI_ERROR(status)) {
148 ERR_PRT((L"waitkey SetTimer(TimerCancel) failed %r", status));
152 uefi_call_wrapper(BS->CloseEvent, 1, timer);
158 argify(CHAR16 *buf, UINTN len, CHAR16 **argv)
168 /* len represents the number of bytes, not the number of 16 bytes chars */
172 * Here we use CHAR_NULL as the terminator rather than the length
173 * because it seems like the EFI shell return rather bogus values for it.
174 * Apparently, we are guaranteed to find the '\0' character in the buffer
175 * where the real input arguments stop, so we use it instead.
178 while (buf[i] == CHAR_SPACE && buf[i] != CHAR_NULL && i < len) i++;
180 if (buf[i] == CHAR_NULL || i == len) goto end;
185 while (buf[i] != CHAR_SPACE && buf[i] != CHAR_NULL && i < len) i++;
189 if (buf[i] == CHAR_NULL) goto end;
193 if (i == len) goto end;
197 if (j == MAX_ARGS-1) {
198 ERR_PRT((L"too many arguments (%d) truncating", j));
205 ERR_PRT((L"ignoring trailing %d characters on command line", len-i));
213 unargify(CHAR16 **argv, CHAR16 **args)
221 (*argv)[StrLen(*argv)] = CHAR_SPACE;
227 split_args(CHAR16 *buffer, CHAR16 *kname, CHAR16 *args)
231 /* find beginning of kernel name */
232 while (*buffer && *buffer == CHAR_SPACE) buffer++;
236 /* scan through kernel name */
237 while (*buffer && *buffer != CHAR_SPACE) buffer++;
240 *buffer++ = CHAR_NULL;
244 /* skip space between kernel and args */
245 while (*buffer && *buffer == CHAR_SPACE) buffer++;
247 StrCpy(args, buffer);
251 read_file(UINTN fd, UINTN total_size, CHAR8 *buffer)
255 CHAR16 helicopter[4] = { L'|' , L'/' , L'-' , L'\\' };
256 INTN ret = ELILO_LOAD_SUCCESS;
259 * We load by chunks rather than a single big read because
260 * early versions of EFI had troubles loading files
261 * from floppies in a single big request. Breaking
262 * the read down into chunks of 4KB fixed that
263 * problem. While this problem has been fixed, we still prefer
264 * this method because it tells us whether or not we're making
268 while (total_size > 0) {
269 size = total_size < READ_BLOCK_SIZE? total_size : READ_BLOCK_SIZE;
271 status = fops_read(fd, buffer, &size);
272 if (EFI_ERROR(status)) {
273 ERR_PRT((L"read_file failed %r", status));
274 return ELILO_LOAD_ERROR;
278 Print(L"%c\b",helicopter[j++%4]);
283 if (check_abort() == EFI_SUCCESS) {
284 ret = ELILO_LOAD_ABORTED;
292 get_memmap(mmap_desc_t *desc)
294 #define ELILO_MEMMAP_SIZE_DEFAULT (EFI_PAGE_SIZE*2)
295 #define ELILO_MEMMAP_INC (sizeof(EFI_MEMORY_DESCRIPTOR)<<1)
299 desc->map_size = ELILO_MEMMAP_SIZE_DEFAULT;
302 desc->md = (EFI_MEMORY_DESCRIPTOR *)alloc(desc->map_size, EfiLoaderData);
304 if (desc->md == NULL) {
305 ERR_PRT((L"failed to allocate memory map buffer"));
308 status = uefi_call_wrapper(BS->GetMemoryMap, 5, &desc->map_size, desc->md,
309 &desc->cookie, &desc->desc_size, &desc->desc_version);
310 if (status == EFI_SUCCESS) break;
314 if (status != EFI_BUFFER_TOO_SMALL) {
315 ERR_PRT((L"failed to obtain memory map %r"));
318 desc->map_size += ELILO_MEMMAP_INC;
320 DBG_PRT((L"final get_memmap map_size=%d", desc->map_size));
327 get_memmap(mmap_desc_t *desc)
331 /* will get the right size in return */
334 status = BS->GetMemoryMap(&desc->map_size, desc->md, &desc->cookie, &desc->desc_size, &desc->desc_version);
335 if (status != EFI_BUFFER_TOO_SMALL) return -1;
337 desc->md = (EFI_MEMORY_DESCRIPTOR *)alloc(desc->map_size, EfiLoaderData);
338 if (desc->md == NULL) {
339 ERR_PRT((L"failed to allocate memory map buffer"));
344 status = BS->GetMemoryMap(&desc->map_size, desc->md, &desc->cookie, &desc->desc_size, &desc->desc_version);
345 if (EFI_ERROR(status)) {
346 ERR_PRT((L"failed to obtain memory map %d: %r", desc->map_size, status));
350 DBG_PRT((L"final get_memmap map_size=%d", desc->map_size));
358 free_memmap(mmap_desc_t *desc)
367 print_memmap(mmap_desc_t *desc)
369 EFI_MEMORY_DESCRIPTOR *md;
377 static CHAR16 *memtypes[]={
378 L"ReservedMemoryType",
383 L"RuntimeServicesCode",
384 L"RuntimeServicesData",
385 L"ConventionalMemory",
387 L"ACPIReclaimMemory",
390 L"MemoryMappedIOPortSpace",
395 md_end = ((VOID *)desc->md)+desc->map_size;
396 desc_size = desc->desc_size;
398 ntypes = sizeof(memtypes)/sizeof(CHAR16 *);
400 for(p = desc->md; p < md_end; p += desc_size) {
403 str = md->Type < ntypes ? memtypes[md->Type] : L"Unknown";
405 Print(L"%24s %lx-%lx %8lx", str, md->PhysicalStart,
406 md->PhysicalStart+(md->NumberOfPages<<EFI_PAGE_SHIFT),
411 Print(L" %s %s", printed ? L"|":L"", f); \
415 if (md->Attribute & EFI_MEMORY_UC) {
418 if (md->Attribute & EFI_MEMORY_WC) {
421 if (md->Attribute & EFI_MEMORY_WT) {
424 if (md->Attribute & EFI_MEMORY_WB) {
427 if (md->Attribute & EFI_MEMORY_UCE) {
430 if (md->Attribute & EFI_MEMORY_WP) {
433 if (md->Attribute & EFI_MEMORY_RP) {
436 if (md->Attribute & EFI_MEMORY_XP) {
439 if (md->Attribute & EFI_MEMORY_RUNTIME) {
447 find_kernel_memory(VOID* low_addr, VOID* max_addr, UINTN alignment, VOID** start)
449 #define HIGHEST_ADDR (VOID*)(~0)
451 EFI_MEMORY_DESCRIPTOR *md;
454 VOID *desc_end, *md_end, *best_addr = HIGHEST_ADDR;
457 * first get up-to-date memory map
459 * XXX: is there a danger of not seeing the latest version if interrupted
463 if (get_memmap(&mdesc) == -1) {
464 ERR_PRT((L"find_kernel_memory :GetMemoryMap() failed"));
468 desc_end = ((VOID *)mdesc.md) + mdesc.map_size;
469 size = max_addr - low_addr;
471 * Find memory which covers the desired range
473 for(p = mdesc.md; p < desc_end; p += mdesc.desc_size) {
477 * restrict to decent memory types.
479 * the EFI memory map report where memory is and how it is currently used
482 * EfiLoaderData which is used by the AllocatePages() cannot be used
483 * here because it may hold some valid information. Same thing for most
484 * of the memory types with the exception of EfiConventional which
485 * can be assumed as being free to use.
487 if (md->Type != EfiConventionalMemory) continue;
490 * compute aligned address and upper boundary for range
492 md_end = (VOID*)(md->PhysicalStart + md->NumberOfPages * EFI_PAGE_SIZE);
493 addr = (VOID*)ROUNDUP(md->PhysicalStart, alignment);
497 * - aligned address still in the range
498 * - the range [addr-addr+size) still fits into memory range
499 * if so we have a match. We do not assume that the memory ranges
500 * are sorted by EFI, therefore we must record the match and only
501 * keep the lowest possible one.
503 if (addr < best_addr && addr < md_end && addr+size <= md_end) best_addr = addr;
505 if (best_addr == HIGHEST_ADDR) {
507 ERR_PRT((L"Could not find memory suitable for loading image"));