]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/LoadLinuxLib/Linux.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / LoadLinuxLib / Linux.c
index 96c985bc2d7e574c20030d886b811e8647efe4dd..ce3d760380f7c38f2322d41b1537b75a485f3dc7 100644 (file)
@@ -1,20 +1,13 @@
 /** @file\r
 \r
-  Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
 \r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "LoadLinuxLib.h"\r
 \r
-\r
 /**\r
   A simple check of the kernel setup image\r
 \r
@@ -32,21 +25,20 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 BasicKernelSetupCheck (\r
-  IN VOID        *KernelSetup\r
+  IN VOID  *KernelSetup\r
   )\r
 {\r
-  return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params));\r
+  return LoadLinuxCheckKernelSetup (KernelSetup, sizeof (struct boot_params));\r
 }\r
 \r
-\r
 EFI_STATUS\r
 EFIAPI\r
 LoadLinuxCheckKernelSetup (\r
-  IN VOID        *KernelSetup,\r
-  IN UINTN       KernelSetupSize\r
+  IN VOID   *KernelSetup,\r
+  IN UINTN  KernelSetupSize\r
   )\r
 {\r
-  struct boot_params        *Bp;\r
+  struct boot_params  *Bp;\r
 \r
   if (KernelSetup == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -56,33 +48,34 @@ LoadLinuxCheckKernelSetup (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  Bp = (struct boot_params*) KernelSetup;\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
   if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature\r
       (Bp->hdr.header != SETUP_HDR) ||\r
-      (Bp->hdr.version < 0x205)        // We only support relocatable kernels\r
-     ) {\r
+      (Bp->hdr.version < 0x205) || // We only support relocatable kernels\r
+      (!Bp->hdr.relocatable_kernel)\r
+      )\r
+  {\r
     return EFI_UNSUPPORTED;\r
   } else {\r
     return EFI_SUCCESS;\r
   }\r
 }\r
 \r
-\r
 UINTN\r
 EFIAPI\r
 LoadLinuxGetKernelSize (\r
-  IN VOID        *KernelSetup,\r
-  IN UINTN       KernelSize\r
+  IN VOID   *KernelSetup,\r
+  IN UINTN  KernelSize\r
   )\r
 {\r
-  struct boot_params        *Bp;\r
+  struct boot_params  *Bp;\r
 \r
   if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {\r
     return 0;\r
   }\r
 \r
-  Bp = (struct boot_params*) KernelSetup;\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
   if (Bp->hdr.version > 0x20a) {\r
     return Bp->hdr.init_size;\r
@@ -94,48 +87,79 @@ LoadLinuxGetKernelSize (
   }\r
 }\r
 \r
-\r
-VOID*\r
+VOID *\r
 EFIAPI\r
 LoadLinuxAllocateKernelSetupPages (\r
-  IN UINTN                  Pages\r
+  IN UINTN  Pages\r
   )\r
 {\r
-  EFI_STATUS                Status;\r
-  EFI_PHYSICAL_ADDRESS      Address;\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  Address;\r
 \r
   Address = BASE_1GB;\r
-  Status = gBS->AllocatePages (\r
-                  AllocateMaxAddress,\r
-                  EfiLoaderData,\r
-                  Pages,\r
-                  &Address\r
-                  );\r
+  Status  = gBS->AllocatePages (\r
+                   AllocateMaxAddress,\r
+                   EfiLoaderData,\r
+                   Pages,\r
+                   &Address\r
+                   );\r
   if (!EFI_ERROR (Status)) {\r
-    return (VOID*)(UINTN) Address;\r
+    return (VOID *)(UINTN)Address;\r
   } else {\r
     return NULL;\r
   }\r
 }\r
 \r
+EFI_STATUS\r
+EFIAPI\r
+LoadLinuxInitializeKernelSetup (\r
+  IN VOID  *KernelSetup\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  UINTN               SetupEnd;\r
+  struct boot_params  *Bp;\r
+\r
+  Status = BasicKernelSetupCheck (KernelSetup);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
-VOID*\r
+  SetupEnd = 0x202 + (Bp->hdr.jump & 0xff);\r
+\r
+  //\r
+  // Clear all but the setup_header\r
+  //\r
+  ZeroMem (KernelSetup, 0x1f1);\r
+  ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd);\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n",\r
+    (UINT64)SetupEnd\r
+    ));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+VOID *\r
 EFIAPI\r
 LoadLinuxAllocateKernelPages (\r
-  IN VOID                   *KernelSetup,\r
-  IN UINTN                  Pages\r
+  IN VOID   *KernelSetup,\r
+  IN UINTN  Pages\r
   )\r
 {\r
-  EFI_STATUS                Status;\r
-  EFI_PHYSICAL_ADDRESS      KernelAddress;\r
-  UINT32                    Loop;\r
-  struct boot_params        *Bp;\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  KernelAddress;\r
+  UINT32                Loop;\r
+  struct boot_params    *Bp;\r
 \r
   if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {\r
     return NULL;\r
   }\r
 \r
-  Bp = (struct boot_params*) KernelSetup;\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
   for (Loop = 1; Loop < 512; Loop++) {\r
     KernelAddress = MultU64x32 (\r
@@ -149,110 +173,111 @@ LoadLinuxAllocateKernelPages (
                     &KernelAddress\r
                     );\r
     if (!EFI_ERROR (Status)) {\r
-      return (VOID*)(UINTN) KernelAddress;\r
+      return (VOID *)(UINTN)KernelAddress;\r
     }\r
   }\r
 \r
   return NULL;\r
 }\r
 \r
-\r
-VOID*\r
+VOID *\r
 EFIAPI\r
 LoadLinuxAllocateCommandLinePages (\r
-  IN UINTN                  Pages\r
+  IN UINTN  Pages\r
   )\r
 {\r
-  EFI_STATUS                Status;\r
-  EFI_PHYSICAL_ADDRESS      Address;\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  Address;\r
 \r
   Address = 0xa0000;\r
-  Status = gBS->AllocatePages (\r
-                  AllocateMaxAddress,\r
-                  EfiLoaderData,\r
-                  Pages,\r
-                  &Address\r
-                  );\r
+  Status  = gBS->AllocatePages (\r
+                   AllocateMaxAddress,\r
+                   EfiLoaderData,\r
+                   Pages,\r
+                   &Address\r
+                   );\r
   if (!EFI_ERROR (Status)) {\r
-    return (VOID*)(UINTN) Address;\r
+    return (VOID *)(UINTN)Address;\r
   } else {\r
     return NULL;\r
   }\r
 }\r
 \r
-\r
-VOID*\r
+VOID *\r
 EFIAPI\r
 LoadLinuxAllocateInitrdPages (\r
-  IN VOID                   *KernelSetup,\r
-  IN UINTN                  Pages\r
+  IN VOID   *KernelSetup,\r
+  IN UINTN  Pages\r
   )\r
 {\r
-  EFI_STATUS                Status;\r
-  EFI_PHYSICAL_ADDRESS      Address;\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  Address;\r
 \r
-  struct boot_params        *Bp;\r
+  struct boot_params  *Bp;\r
 \r
   if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {\r
     return NULL;\r
   }\r
 \r
-  Bp = (struct boot_params*) KernelSetup;\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
-  Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Bp->hdr.ramdisk_max;\r
-  Status = gBS->AllocatePages (\r
-                  AllocateMaxAddress,\r
-                  EfiLoaderData,\r
-                  Pages,\r
-                  &Address\r
-                  );\r
+  Address = (EFI_PHYSICAL_ADDRESS)(UINTN)Bp->hdr.ramdisk_max;\r
+  Status  = gBS->AllocatePages (\r
+                   AllocateMaxAddress,\r
+                   EfiLoaderData,\r
+                   Pages,\r
+                   &Address\r
+                   );\r
   if (!EFI_ERROR (Status)) {\r
-    return (VOID*)(UINTN) Address;\r
+    return (VOID *)(UINTN)Address;\r
   } else {\r
     return NULL;\r
   }\r
 }\r
 \r
-\r
 STATIC\r
 VOID\r
 SetupLinuxMemmap (\r
-  IN OUT struct boot_params        *Bp\r
+  IN OUT struct boot_params  *Bp\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
-  UINT8                                TmpMemoryMap[1];\r
-  UINTN                                MapKey;\r
-  UINTN                                DescriptorSize;\r
-  UINT32                               DescriptorVersion;\r
-  UINTN                                MemoryMapSize;\r
-  EFI_MEMORY_DESCRIPTOR                *MemoryMap;\r
-  EFI_MEMORY_DESCRIPTOR                *MemoryMapPtr;\r
-  UINTN                                Index;\r
-  struct efi_info                      *Efi;\r
-  struct e820_entry                    *LastE820;\r
-  struct e820_entry                    *E820;\r
-  UINTN                                E820EntryCount;\r
-  EFI_PHYSICAL_ADDRESS                 LastEndAddr;\r
+  EFI_STATUS             Status;\r
+  UINT8                  TmpMemoryMap[1];\r
+  UINTN                  MapKey;\r
+  UINTN                  DescriptorSize;\r
+  UINT32                 DescriptorVersion;\r
+  UINTN                  MemoryMapSize;\r
+  EFI_MEMORY_DESCRIPTOR  *MemoryMap;\r
+  EFI_MEMORY_DESCRIPTOR  *MemoryMapPtr;\r
+  UINTN                  Index;\r
+  struct efi_info        *Efi;\r
+  struct e820_entry      *LastE820;\r
+  struct e820_entry      *E820;\r
+  UINTN                  E820EntryCount;\r
+  EFI_PHYSICAL_ADDRESS   LastEndAddr;\r
 \r
   //\r
   // Get System MemoryMapSize\r
   //\r
   MemoryMapSize = sizeof (TmpMemoryMap);\r
-  Status = gBS->GetMemoryMap (\r
-                  &MemoryMapSize,\r
-                  (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,\r
-                  &MapKey,\r
-                  &DescriptorSize,\r
-                  &DescriptorVersion\r
-                  );\r
+  Status        = gBS->GetMemoryMap (\r
+                         &MemoryMapSize,\r
+                         (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,\r
+                         &MapKey,\r
+                         &DescriptorSize,\r
+                         &DescriptorVersion\r
+                         );\r
   ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
   //\r
   // Enlarge space here, because we will allocate pool now.\r
   //\r
   MemoryMapSize += EFI_PAGE_SIZE;\r
-  MemoryMap = AllocatePool (MemoryMapSize);\r
-  ASSERT (MemoryMap != NULL);\r
+  Status         = gBS->AllocatePool (\r
+                          EfiLoaderData,\r
+                          MemoryMapSize,\r
+                          (VOID **)&MemoryMap\r
+                          );\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // Get System MemoryMap\r
@@ -266,70 +291,72 @@ SetupLinuxMemmap (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  LastE820 = NULL;\r
-  E820 = &Bp->e820_map[0];\r
+  LastE820       = NULL;\r
+  E820           = &Bp->e820_map[0];\r
   E820EntryCount = 0;\r
-  LastEndAddr = 0;\r
-  MemoryMapPtr = MemoryMap;\r
+  LastEndAddr    = 0;\r
+  MemoryMapPtr   = MemoryMap;\r
   for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {\r
-    UINTN E820Type = 0;\r
+    UINTN  E820Type = 0;\r
 \r
     if (MemoryMap->NumberOfPages == 0) {\r
       continue;\r
     }\r
 \r
-    switch(MemoryMap->Type) {\r
-    case EfiReservedMemoryType:\r
-    case EfiRuntimeServicesCode:\r
-    case EfiRuntimeServicesData:\r
-    case EfiMemoryMappedIO:\r
-    case EfiMemoryMappedIOPortSpace:\r
-    case EfiPalCode:\r
-      E820Type = E820_RESERVED;\r
-      break;\r
-\r
-    case EfiUnusableMemory:\r
-      E820Type = E820_UNUSABLE;\r
-      break;\r
-\r
-    case EfiACPIReclaimMemory:\r
-      E820Type = E820_ACPI;\r
-      break;\r
-\r
-    case EfiLoaderCode:\r
-    case EfiLoaderData:\r
-    case EfiBootServicesCode:\r
-    case EfiBootServicesData:\r
-    case EfiConventionalMemory:\r
-      E820Type = E820_RAM;\r
-      break;\r
-\r
-    case EfiACPIMemoryNVS:\r
-      E820Type = E820_NVS;\r
-      break;\r
-\r
-    default:\r
-      DEBUG ((\r
-        EFI_D_ERROR,\r
-        "Invalid EFI memory descriptor type (0x%x)!\n",\r
-        MemoryMap->Type\r
-        ));\r
-      continue;\r
+    switch (MemoryMap->Type) {\r
+      case EfiReservedMemoryType:\r
+      case EfiRuntimeServicesCode:\r
+      case EfiRuntimeServicesData:\r
+      case EfiMemoryMappedIO:\r
+      case EfiMemoryMappedIOPortSpace:\r
+      case EfiPalCode:\r
+        E820Type = E820_RESERVED;\r
+        break;\r
+\r
+      case EfiUnusableMemory:\r
+        E820Type = E820_UNUSABLE;\r
+        break;\r
+\r
+      case EfiACPIReclaimMemory:\r
+        E820Type = E820_ACPI;\r
+        break;\r
+\r
+      case EfiLoaderCode:\r
+      case EfiLoaderData:\r
+      case EfiBootServicesCode:\r
+      case EfiBootServicesData:\r
+      case EfiConventionalMemory:\r
+        E820Type = E820_RAM;\r
+        break;\r
+\r
+      case EfiACPIMemoryNVS:\r
+        E820Type = E820_NVS;\r
+        break;\r
+\r
+      default:\r
+        DEBUG ((\r
+          DEBUG_ERROR,\r
+          "Invalid EFI memory descriptor type (0x%x)!\n",\r
+          MemoryMap->Type\r
+          ));\r
+        continue;\r
     }\r
 \r
     if ((LastE820 != NULL) &&\r
-        (LastE820->type == (UINT32) E820Type) &&\r
-        (MemoryMap->PhysicalStart == LastEndAddr)) {\r
-      LastE820->size += EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages);\r
-      LastEndAddr += EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages);\r
+        (LastE820->type == (UINT32)E820Type) &&\r
+        (MemoryMap->PhysicalStart == LastEndAddr))\r
+    {\r
+      LastE820->size += EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages);\r
+      LastEndAddr    += EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages);\r
     } else {\r
-      if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof (Bp->e820_map[0]))) {\r
+      if (E820EntryCount >= ARRAY_SIZE (Bp->e820_map)) {\r
         break;\r
       }\r
-      E820->type = (UINT32) E820Type;\r
-      E820->addr = MemoryMap->PhysicalStart;\r
-      E820->size = EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages);\r
-      LastE820 = E820;\r
+\r
+      E820->type  = (UINT32)E820Type;\r
+      E820->addr  = MemoryMap->PhysicalStart;\r
+      E820->size  = EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages);\r
+      LastE820    = E820;\r
       LastEndAddr = E820->addr + E820->size;\r
       E820++;\r
       E820EntryCount++;\r
@@ -340,85 +367,83 @@ SetupLinuxMemmap (
     //\r
     MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize);\r
   }\r
-  Bp->e820_entries = (UINT8) E820EntryCount;\r
 \r
-  Efi = &Bp->efi_info;\r
-  Efi->efi_systab = (UINT32)(UINTN) gST;\r
-  Efi->efi_memdesc_size = (UINT32) DescriptorSize;\r
+  Bp->e820_entries = (UINT8)E820EntryCount;\r
+\r
+  Efi                      = &Bp->efi_info;\r
+  Efi->efi_systab          = (UINT32)(UINTN)gST;\r
+  Efi->efi_memdesc_size    = (UINT32)DescriptorSize;\r
   Efi->efi_memdesc_version = DescriptorVersion;\r
-  Efi->efi_memmap = (UINT32)(UINTN) MemoryMapPtr;\r
-  Efi->efi_memmap_size = (UINT32) MemoryMapSize;\r
-#ifdef MDE_CPU_IA32\r
+  Efi->efi_memmap          = (UINT32)(UINTN)MemoryMapPtr;\r
+  Efi->efi_memmap_size     = (UINT32)MemoryMapSize;\r
+ #ifdef MDE_CPU_IA32\r
   Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2');\r
-#else\r
-  Efi->efi_systab_hi = ((UINT64)(UINTN) gST) >> 32;\r
-  Efi->efi_memmap_hi = ((UINT64)(UINTN) MemoryMapPtr) >> 32;\r
+ #else\r
+  Efi->efi_systab_hi        = (UINT32)(((UINT64)(UINTN)gST) >> 32);\r
+  Efi->efi_memmap_hi        = (UINT32)(((UINT64)(UINTN)MemoryMapPtr) >> 32);\r
   Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4');\r
-#endif\r
+ #endif\r
 \r
   gBS->ExitBootServices (gImageHandle, MapKey);\r
 }\r
 \r
-\r
 EFI_STATUS\r
 EFIAPI\r
 LoadLinuxSetCommandLine (\r
-  IN OUT VOID    *KernelSetup,\r
-  IN CHAR8       *CommandLine\r
+  IN OUT VOID  *KernelSetup,\r
+  IN CHAR8     *CommandLine\r
   )\r
 {\r
-  EFI_STATUS             Status;\r
-  struct boot_params     *Bp;\r
+  EFI_STATUS          Status;\r
+  struct boot_params  *Bp;\r
 \r
   Status = BasicKernelSetupCheck (KernelSetup);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  Bp = (struct boot_params*) KernelSetup;\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
-  Bp->hdr.cmd_line_ptr = (UINT32)(UINTN) CommandLine;\r
+  Bp->hdr.cmd_line_ptr = (UINT32)(UINTN)CommandLine;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 EFI_STATUS\r
 EFIAPI\r
 LoadLinuxSetInitrd (\r
-  IN OUT VOID    *KernelSetup,\r
-  IN VOID        *Initrd,\r
-  IN UINTN       InitrdSize\r
+  IN OUT VOID  *KernelSetup,\r
+  IN VOID      *Initrd,\r
+  IN UINTN     InitrdSize\r
   )\r
 {\r
-  EFI_STATUS             Status;\r
-  struct boot_params     *Bp;\r
+  EFI_STATUS          Status;\r
+  struct boot_params  *Bp;\r
 \r
   Status = BasicKernelSetupCheck (KernelSetup);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  Bp = (struct boot_params*) KernelSetup;\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
-  Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd;\r
-  Bp->hdr.ramdisk_len = (UINT32) InitrdSize;\r
+  Bp->hdr.ramdisk_start = (UINT32)(UINTN)Initrd;\r
+  Bp->hdr.ramdisk_len   = (UINT32)InitrdSize;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 STATIC VOID\r
 FindBits (\r
-  unsigned long Mask,\r
-  UINT8 *Pos,\r
-  UINT8 *Size\r
+  unsigned long  Mask,\r
+  UINT8          *Pos,\r
+  UINT8          *Size\r
   )\r
 {\r
-  UINT8 First, Len;\r
+  UINT8  First, Len;\r
 \r
   First = 0;\r
-  Len = 0;\r
+  Len   = 0;\r
 \r
   if (Mask) {\r
     while (!(Mask & 0x1)) {\r
@@ -431,23 +456,23 @@ FindBits (
       Len++;\r
     }\r
   }\r
-  *Pos = First;\r
+\r
+  *Pos  = First;\r
   *Size = Len;\r
 }\r
 \r
-\r
 STATIC\r
 EFI_STATUS\r
 SetupGraphicsFromGop (\r
-  struct screen_info           *Si,\r
-  EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop\r
+  struct screen_info            *Si,\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop\r
   )\r
 {\r
-  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
-  EFI_STATUS                           Status;\r
-  UINTN                                Size;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;\r
+  EFI_STATUS                            Status;\r
+  UINTN                                 Size;\r
 \r
-  Status = Gop->QueryMode(Gop, Gop->Mode->Mode, &Size, &Info);\r
+  Status = Gop->QueryMode (Gop, Gop->Mode->Mode, &Size, &Info);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -457,88 +482,98 @@ SetupGraphicsFromGop (
   /* EFI framebuffer */\r
   Si->orig_video_isVGA = 0x70;\r
 \r
-  Si->orig_x = 0;\r
-  Si->orig_y = 0;\r
-  Si->orig_video_page = 0;\r
-  Si->orig_video_mode = 0;\r
-  Si->orig_video_cols = 0;\r
-  Si->orig_video_lines = 0;\r
+  Si->orig_x            = 0;\r
+  Si->orig_y            = 0;\r
+  Si->orig_video_page   = 0;\r
+  Si->orig_video_mode   = 0;\r
+  Si->orig_video_cols   = 0;\r
+  Si->orig_video_lines  = 0;\r
   Si->orig_video_ega_bx = 0;\r
   Si->orig_video_points = 0;\r
 \r
-  Si->lfb_base = (UINT32) Gop->Mode->FrameBufferBase;\r
-  Si->lfb_size = (UINT32) Gop->Mode->FrameBufferSize;\r
-  Si->lfb_width = (UINT16) Info->HorizontalResolution;\r
-  Si->lfb_height = (UINT16) Info->VerticalResolution;\r
-  Si->pages = 1;\r
+  Si->lfb_base   = (UINT32)Gop->Mode->FrameBufferBase;\r
+  Si->lfb_size   = (UINT32)Gop->Mode->FrameBufferSize;\r
+  Si->lfb_width  = (UINT16)Info->HorizontalResolution;\r
+  Si->lfb_height = (UINT16)Info->VerticalResolution;\r
+  Si->pages      = 1;\r
   Si->vesapm_seg = 0;\r
   Si->vesapm_off = 0;\r
 \r
   if (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {\r
-    Si->lfb_depth = 32;\r
-    Si->red_size = 8;\r
-    Si->red_pos = 0;\r
-    Si->green_size = 8;\r
-    Si->green_pos = 8;\r
-    Si->blue_size = 8;\r
-    Si->blue_pos = 16;\r
-    Si->rsvd_size = 8;\r
-    Si->rsvd_pos = 24;\r
-    Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);\r
-\r
+    Si->lfb_depth      = 32;\r
+    Si->red_size       = 8;\r
+    Si->red_pos        = 0;\r
+    Si->green_size     = 8;\r
+    Si->green_pos      = 8;\r
+    Si->blue_size      = 8;\r
+    Si->blue_pos       = 16;\r
+    Si->rsvd_size      = 8;\r
+    Si->rsvd_pos       = 24;\r
+    Si->lfb_linelength = (UINT16)(Info->PixelsPerScanLine * 4);\r
   } else if (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r
-    Si->lfb_depth = 32;\r
-    Si->red_size = 8;\r
-    Si->red_pos = 16;\r
-    Si->green_size = 8;\r
-    Si->green_pos = 8;\r
-    Si->blue_size = 8;\r
-    Si->blue_pos = 0;\r
-    Si->rsvd_size = 8;\r
-    Si->rsvd_pos = 24;\r
-    Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);\r
+    Si->lfb_depth      = 32;\r
+    Si->red_size       = 8;\r
+    Si->red_pos        = 16;\r
+    Si->green_size     = 8;\r
+    Si->green_pos      = 8;\r
+    Si->blue_size      = 8;\r
+    Si->blue_pos       = 0;\r
+    Si->rsvd_size      = 8;\r
+    Si->rsvd_pos       = 24;\r
+    Si->lfb_linelength = (UINT16)(Info->PixelsPerScanLine * 4);\r
   } else if (Info->PixelFormat == PixelBitMask) {\r
-    FindBits(Info->PixelInformation.RedMask,\r
-        &Si->red_pos, &Si->red_size);\r
-    FindBits(Info->PixelInformation.GreenMask,\r
-        &Si->green_pos, &Si->green_size);\r
-    FindBits(Info->PixelInformation.BlueMask,\r
-        &Si->blue_pos, &Si->blue_size);\r
-    FindBits(Info->PixelInformation.ReservedMask,\r
-        &Si->rsvd_pos, &Si->rsvd_size);\r
+    FindBits (\r
+      Info->PixelInformation.RedMask,\r
+      &Si->red_pos,\r
+      &Si->red_size\r
+      );\r
+    FindBits (\r
+      Info->PixelInformation.GreenMask,\r
+      &Si->green_pos,\r
+      &Si->green_size\r
+      );\r
+    FindBits (\r
+      Info->PixelInformation.BlueMask,\r
+      &Si->blue_pos,\r
+      &Si->blue_size\r
+      );\r
+    FindBits (\r
+      Info->PixelInformation.ReservedMask,\r
+      &Si->rsvd_pos,\r
+      &Si->rsvd_size\r
+      );\r
     Si->lfb_depth = Si->red_size + Si->green_size +\r
-      Si->blue_size + Si->rsvd_size;\r
-    Si->lfb_linelength = (UINT16) ((Info->PixelsPerScanLine * Si->lfb_depth) / 8);\r
+                    Si->blue_size + Si->rsvd_size;\r
+    Si->lfb_linelength = (UINT16)((Info->PixelsPerScanLine * Si->lfb_depth) / 8);\r
   } else {\r
-    Si->lfb_depth = 4;\r
-    Si->red_size = 0;\r
-    Si->red_pos = 0;\r
-    Si->green_size = 0;\r
-    Si->green_pos = 0;\r
-    Si->blue_size = 0;\r
-    Si->blue_pos = 0;\r
-    Si->rsvd_size = 0;\r
-    Si->rsvd_pos = 0;\r
+    Si->lfb_depth      = 4;\r
+    Si->red_size       = 0;\r
+    Si->red_pos        = 0;\r
+    Si->green_size     = 0;\r
+    Si->green_pos      = 0;\r
+    Si->blue_size      = 0;\r
+    Si->blue_pos       = 0;\r
+    Si->rsvd_size      = 0;\r
+    Si->rsvd_pos       = 0;\r
     Si->lfb_linelength = Si->lfb_width / 2;\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 STATIC\r
 EFI_STATUS\r
 SetupGraphics (\r
-  IN OUT struct boot_params *Bp\r
+  IN OUT struct boot_params  *Bp\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  EFI_HANDLE                      *HandleBuffer;\r
-  UINTN                           HandleCount;\r
-  UINTN                           Index;\r
-  EFI_GRAPHICS_OUTPUT_PROTOCOL    *Gop;\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         HandleCount;\r
+  UINTN                         Index;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop;\r
 \r
-  ZeroMem ((VOID*)&Bp->screen_info, sizeof(Bp->screen_info));\r
+  ZeroMem ((VOID *)&Bp->screen_info, sizeof (Bp->screen_info));\r
 \r
   Status = gBS->LocateHandleBuffer (\r
                   ByProtocol,\r
@@ -552,7 +587,7 @@ SetupGraphics (
       Status = gBS->HandleProtocol (\r
                       HandleBuffer[Index],\r
                       &gEfiGraphicsOutputProtocolGuid,\r
-                      (VOID*) &Gop\r
+                      (VOID *)&Gop\r
                       );\r
       if (EFI_ERROR (Status)) {\r
         continue;\r
@@ -571,24 +606,19 @@ SetupGraphics (
   return EFI_NOT_FOUND;\r
 }\r
 \r
-\r
 STATIC\r
 EFI_STATUS\r
 SetupLinuxBootParams (\r
-  IN VOID                   *Kernel,\r
-  IN OUT struct boot_params *Bp\r
+  IN OUT struct boot_params  *Bp\r
   )\r
 {\r
   SetupGraphics (Bp);\r
 \r
-  Bp->hdr.code32_start = (UINT32)(UINTN) Kernel;\r
-\r
   SetupLinuxMemmap (Bp);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 EFI_STATUS\r
 EFIAPI\r
 LoadLinux (\r
@@ -596,7 +626,7 @@ LoadLinux (
   IN OUT VOID  *KernelSetup\r
   )\r
 {\r
-  EFI_STATUS             Status;\r
+  EFI_STATUS          Status;\r
   struct boot_params  *Bp;\r
 \r
   Status = BasicKernelSetupCheck (KernelSetup);\r
@@ -604,9 +634,9 @@ LoadLinux (
     return Status;\r
   }\r
 \r
-  Bp = (struct boot_params *) KernelSetup;\r
+  Bp = (struct boot_params *)KernelSetup;\r
 \r
-  if (Bp->hdr.version < 0x205) {\r
+  if ((Bp->hdr.version < 0x205) || !Bp->hdr.relocatable_kernel) {\r
     //\r
     // We only support relocatable kernels\r
     //\r
@@ -615,13 +645,25 @@ LoadLinux (
 \r
   InitLinuxDescriptorTables ();\r
 \r
-  SetupLinuxBootParams (Kernel, (struct boot_params*) KernelSetup);\r
+  Bp->hdr.code32_start = (UINT32)(UINTN)Kernel;\r
+  if ((Bp->hdr.version >= 0x20c) && Bp->hdr.handover_offset &&\r
+      (Bp->hdr.xloadflags & ((sizeof (UINTN) == 4) ? BIT2 : BIT3)))\r
+  {\r
+    DEBUG ((DEBUG_INFO, "Jumping to kernel EFI handover point at ofs %x\n", Bp->hdr.handover_offset));\r
+\r
+    DisableInterrupts ();\r
+    JumpToUefiKernel ((VOID *)gImageHandle, (VOID *)gST, KernelSetup, Kernel);\r
+  }\r
 \r
-  DEBUG ((EFI_D_INFO, "Jumping to kernel\n"));\r
+  //\r
+  // Old kernels without EFI handover protocol\r
+  //\r
+  SetupLinuxBootParams (KernelSetup);\r
+\r
+  DEBUG ((DEBUG_INFO, "Jumping to kernel\n"));\r
   DisableInterrupts ();\r
   SetLinuxDescriptorTables ();\r
-  JumpToKernel (Kernel, (VOID*) KernelSetup);\r
+  JumpToKernel (Kernel, (VOID *)KernelSetup);\r
 \r
   return EFI_SUCCESS;\r
 }\r
-\r