fix lintian complaints
[debian/elilo] / elilo.c
diff --git a/elilo.c b/elilo.c
index 6bdd6bd28a86d781f6451b69f906ac962348b4e0..31c7294076b804d8cd55fbb7d91ba7e8d625a0d7 100644 (file)
--- a/elilo.c
+++ b/elilo.c
@@ -1,5 +1,5 @@
 /* 
- * elilo.c - IA-64/IA-32 EFI Linux loader
+ * elilo.c - IA-64/IA-32/x86_64 EFI Linux loader
  *
  *  Copyright (C) 1999-2003 Hewlett-Packard Co.
  *     Contributed by David Mosberger <davidm@hpl.hp.com>.
@@ -8,6 +8,11 @@
  *  Copyright (C) 1999-2000 VA Linux Systems
  *       Contributed by Johannes Erdfelt <jerdfelt@valinux.com>.
  *
+ *  Copyright (C) 2006-2009 Intel Corporation
+ *     Contributed by Fenghua Yu <fenghua.yu@intel.com>
+ *     Contributed by Bibo Mao <bibo.mao@intel.com>
+ *     Contributed by Chandramouli Narayanan <mouli@linux.intel.com>
+ *
  * This file is part of the ELILO, the EFI Linux boot loader.
  *
  *  ELILO is free software; you can redistribute it and/or modify
 #include "loader.h"
 #include "config.h" /* for config_init() */
 
-#define ELILO_VERSION                  L"3.4"
 #define ELILO_SHARED_CMDLINE_OPTS      L"pPMC:aDhd:i:vVc:E"
 
 elilo_config_t elilo_opt;
 
 EFI_SYSTEM_TABLE *systab;      /* pointer to EFI system table */
 
+extern INTN wait_timeout (UINTN);
+
 /*
  * Load the Linux kernel in memory from the boot media
  * Output:
@@ -122,11 +128,12 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memde
                        return ELILO_LOAD_RETRY;        
        }
 
-       VERB_PRT(3, Print(L"kernel loaded in [0x%lx-0x%lx] entry=0x%lx\n", 
-                         (unsigned long)kd->kstart, (unsigned long)kd->kend, (unsigned long)kd->kentry));
+       VERB_PRT(3, Print(L"kernel loaded in [" PTR_FMT "-" PTR_FMT "] entry=" PTR_FMT "\n", 
+                         kd->kstart, kd->kend, kd->kentry));
 
        if (elilo_opt.initrd[0]) {
 
+               /* ramdisk image is moved to the top of available extended memory later by start_kernel() */
                if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error;
 
                switch(load_file(elilo_opt.initrd, imem)) {
@@ -207,7 +214,7 @@ main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image
        EFI_STATUS status = EFI_SUCCESS;
        kdesc_t kd;
        memdesc_t imem, mmem;
-       INTN r;
+       INTN r, retries=0;
 
        /*
         * First place where we potentially do system dependent
@@ -237,15 +244,49 @@ do_launch:
 
        VERB_PRT(3, Print(L"final cmdline(%d): %s\n", r, cmdline));
 
+       /* Give user time to see the output before launch */
+       if (elilo_opt.debug || elilo_opt.verbose) {
+               r = wait_timeout(150);
+       /* have to turn off all console output(except error output) now before final get_mmemap()
+        * call or it can cause the efi map key to change and the ExitBootSvc call to fail,
+        * forcing debug and verbose options off is the surest way to enforce this.
+        */
+               elilo_opt.debug=0;
+               elilo_opt.verbose=0; 
+       }
+
        /* free resources associated with file accesses (before ExitBootServices) */
        close_devices();
 
        /* No console output permitted after create_boot_params()! */
        if ((bp=create_boot_params(cmdline, &imem, &mmem, &cookie)) == 0) goto error;
 
-       /* terminate bootservices */
-       status = BS->ExitBootServices(image, cookie);
-       if (EFI_ERROR(status)) goto bad_exit;
+       /* terminate bootservices 
+       * efi ExitBootSvcs spec: *note, get_memmap is called by create_boot_params() 
+       * An EFI OS loader must ensure that it has the system's current memory map at the time 
+       * it calls ExitBootServices(). This is done by passing in the current memory map's 
+       * MapKey value as returned by GetMemoryMap(). Care must be taken to ensure that the 
+       * memory map does not change between these two calls. It is suggested that 
+       * GetMemoryMap()be called immediately before calling ExitBootServices(). */
+
+retry:
+       status = uefi_call_wrapper(BS->ExitBootServices, 2, image, cookie);
+       if (EFI_ERROR(status)) 
+       {
+               ERR_PRT((L"\nExitBootSvcs: failed, memory map has changed.\n"));
+               if (retries < 2)
+               {       
+                       ERR_PRT((L"Main_Loop: Retrying,... have to rebuild boot params"));
+                       retries++;
+                       free_boot_params(bp);
+                       if ((bp=create_boot_params(cmdline, &imem, &mmem, &cookie)) == 0) goto error;                   
+                       goto retry;
+               } else {
+                       ERR_PRT((L"\nMain_Loop: tried ExitBootSvcs 3 times... retries exceeded.... giving up\n"));
+                       goto bad_exit;
+               }
+       }
+
 
        start_kernel(kd.kentry, bp);
        /* NOT REACHED */
@@ -259,6 +300,7 @@ bad_exit:
 error:
        free_kmem();
        if (imem.start_addr) free(imem.start_addr);
+       if (mmem.start_addr) free(mmem.start_addr);
        if (bp) free_boot_params(bp);
 exit_error:
        return ELILO_LOAD_ERROR;
@@ -307,7 +349,7 @@ fixupargs(EFI_LOADED_IMAGE *info)
 
 #define FAKE_ELILONAME L"elilo-forced"
 
-       status = BS->HandleProtocol (info->DeviceHandle, &PxeBaseCodeProtocol, (VOID **)&pxe);
+       status = uefi_call_wrapper(BS->HandleProtocol, 3, info->DeviceHandle, &PxeBaseCodeProtocol, (VOID **)&pxe);
        if (EFI_ERROR(status)) return;
 
        default_load_options      = info->LoadOptions;
@@ -365,7 +407,7 @@ check_edd30(VOID)
        UINT8           bool = FALSE;
        INTN            ret = -1;
 
-       status = RT->GetVariable(L"EDD30", &edd30_guid, NULL, &l, &bool);
+       status = uefi_call_wrapper(RT->GetVariable, 5, L"EDD30", &edd30_guid, NULL, &l, &bool);
        if (status == EFI_BUFFER_TOO_SMALL || (bool != TRUE && bool != FALSE)) {
                ERR_PRT((L"Warning: EDD30 EFI variable is not boolean value: forcing it to TRUE"));
                return -1;
@@ -395,7 +437,7 @@ force_edd30(VOID)
        UINT8           bool;
 
        bool = TRUE;
-       status = RT->SetVariable(L"EDD30", &edd30_guid, EDD30_ATTR, l, &bool);
+       status = uefi_call_wrapper(RT->SetVariable, 5, L"EDD30", &edd30_guid, EDD30_ATTR, l, &bool);
        if (EFI_ERROR(status)) {
                ERR_PRT((L"can't set EDD30 variable: ignoring it"));
                return -1;
@@ -439,19 +481,18 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
         * mode.
         * XXX: clean this up !
         */
-       BS->SetWatchdogTimer(0, 0x0, 0, NULL);
+       uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x0, 0, NULL);
 
        /* initialize memory allocator */
        if (alloc_init() == -1) return EFI_LOAD_ERROR;
 
-       status = BS->HandleProtocol(image, &LoadedImageProtocol, (VOID **) &info);
+       status = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (VOID **) &info);
        if (EFI_ERROR(status)) {
                ERR_PRT((L"image handle does not support LOADED_IMAGE protocol"));
                return EFI_LOAD_ERROR;
        }
 
-       VERB_PRT(5,Print(L"Loaded at 0x%lx size=%d bytes code=%d data=%d\n", info->ImageBase, info->ImageSize, info->ImageCodeType, info->ImageDataType));
-
+       VERB_PRT(5,Print(L"Loaded at " PTR_FMT " size=%ld bytes code=%d data=%d\n", info->ImageBase, info->ImageSize, info->ImageCodeType, info->ImageDataType));
        /*
         * verify EDD3.0 status. Users may have to reboot 
         */
@@ -595,7 +636,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
                                goto do_exit;
                }
        }
-       DBG_PRT((L"Optind=%d optarg=%x argc=%d", Optind, Optarg, argc));
+       DBG_PRT((L"Optind=%d optarg=" PTR_FMT " argc=%d", Optind, Optarg, argc));
 
        /*
         * we can't defer this phase any longer...