REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the OvmfPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			670 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			670 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
 | 
						|
  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "LoadLinuxLib.h"
 | 
						|
 | 
						|
/**
 | 
						|
  A simple check of the kernel setup image
 | 
						|
 | 
						|
  An assumption is made that the size of the data is at least the
 | 
						|
  size of struct boot_params.
 | 
						|
 | 
						|
  @param[in]    KernelSetup - The kernel setup image
 | 
						|
 | 
						|
  @retval    EFI_SUCCESS - The kernel setup looks valid and supported
 | 
						|
  @retval    EFI_INVALID_PARAMETER - KernelSetup was NULL
 | 
						|
  @retval    EFI_UNSUPPORTED - The kernel setup is not valid or supported
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BasicKernelSetupCheck (
 | 
						|
  IN VOID  *KernelSetup
 | 
						|
  )
 | 
						|
{
 | 
						|
  return LoadLinuxCheckKernelSetup (KernelSetup, sizeof (struct boot_params));
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LoadLinuxCheckKernelSetup (
 | 
						|
  IN VOID   *KernelSetup,
 | 
						|
  IN UINTN  KernelSetupSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  struct boot_params  *Bp;
 | 
						|
 | 
						|
  if (KernelSetup == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (KernelSetupSize < sizeof (*Bp)) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature
 | 
						|
      (Bp->hdr.header != SETUP_HDR) ||
 | 
						|
      (Bp->hdr.version < 0x205) || // We only support relocatable kernels
 | 
						|
      (!Bp->hdr.relocatable_kernel)
 | 
						|
      )
 | 
						|
  {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  } else {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
LoadLinuxGetKernelSize (
 | 
						|
  IN VOID   *KernelSetup,
 | 
						|
  IN UINTN  KernelSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  struct boot_params  *Bp;
 | 
						|
 | 
						|
  if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  if (Bp->hdr.version > 0x20a) {
 | 
						|
    return Bp->hdr.init_size;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Add extra size for kernel decompression
 | 
						|
    //
 | 
						|
    return 3 * KernelSize;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID *
 | 
						|
EFIAPI
 | 
						|
LoadLinuxAllocateKernelSetupPages (
 | 
						|
  IN UINTN  Pages
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  EFI_PHYSICAL_ADDRESS  Address;
 | 
						|
 | 
						|
  Address = BASE_1GB;
 | 
						|
  Status  = gBS->AllocatePages (
 | 
						|
                   AllocateMaxAddress,
 | 
						|
                   EfiLoaderData,
 | 
						|
                   Pages,
 | 
						|
                   &Address
 | 
						|
                   );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    return (VOID *)(UINTN)Address;
 | 
						|
  } else {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LoadLinuxInitializeKernelSetup (
 | 
						|
  IN VOID  *KernelSetup
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  UINTN               SetupEnd;
 | 
						|
  struct boot_params  *Bp;
 | 
						|
 | 
						|
  Status = BasicKernelSetupCheck (KernelSetup);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  SetupEnd = 0x202 + (Bp->hdr.jump & 0xff);
 | 
						|
 | 
						|
  //
 | 
						|
  // Clear all but the setup_header
 | 
						|
  //
 | 
						|
  ZeroMem (KernelSetup, 0x1f1);
 | 
						|
  ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd);
 | 
						|
  DEBUG ((
 | 
						|
    DEBUG_INFO,
 | 
						|
    "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n",
 | 
						|
    (UINT64)SetupEnd
 | 
						|
    ));
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID *
 | 
						|
EFIAPI
 | 
						|
LoadLinuxAllocateKernelPages (
 | 
						|
  IN VOID   *KernelSetup,
 | 
						|
  IN UINTN  Pages
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  EFI_PHYSICAL_ADDRESS  KernelAddress;
 | 
						|
  UINT32                Loop;
 | 
						|
  struct boot_params    *Bp;
 | 
						|
 | 
						|
  if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  for (Loop = 1; Loop < 512; Loop++) {
 | 
						|
    KernelAddress = MultU64x32 (
 | 
						|
                      2 * Bp->hdr.kernel_alignment,
 | 
						|
                      Loop
 | 
						|
                      );
 | 
						|
    Status = gBS->AllocatePages (
 | 
						|
                    AllocateAddress,
 | 
						|
                    EfiLoaderData,
 | 
						|
                    Pages,
 | 
						|
                    &KernelAddress
 | 
						|
                    );
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      return (VOID *)(UINTN)KernelAddress;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
VOID *
 | 
						|
EFIAPI
 | 
						|
LoadLinuxAllocateCommandLinePages (
 | 
						|
  IN UINTN  Pages
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  EFI_PHYSICAL_ADDRESS  Address;
 | 
						|
 | 
						|
  Address = 0xa0000;
 | 
						|
  Status  = gBS->AllocatePages (
 | 
						|
                   AllocateMaxAddress,
 | 
						|
                   EfiLoaderData,
 | 
						|
                   Pages,
 | 
						|
                   &Address
 | 
						|
                   );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    return (VOID *)(UINTN)Address;
 | 
						|
  } else {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID *
 | 
						|
EFIAPI
 | 
						|
LoadLinuxAllocateInitrdPages (
 | 
						|
  IN VOID   *KernelSetup,
 | 
						|
  IN UINTN  Pages
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  EFI_PHYSICAL_ADDRESS  Address;
 | 
						|
 | 
						|
  struct boot_params  *Bp;
 | 
						|
 | 
						|
  if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  Address = (EFI_PHYSICAL_ADDRESS)(UINTN)Bp->hdr.ramdisk_max;
 | 
						|
  Status  = gBS->AllocatePages (
 | 
						|
                   AllocateMaxAddress,
 | 
						|
                   EfiLoaderData,
 | 
						|
                   Pages,
 | 
						|
                   &Address
 | 
						|
                   );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    return (VOID *)(UINTN)Address;
 | 
						|
  } else {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
SetupLinuxMemmap (
 | 
						|
  IN OUT struct boot_params  *Bp
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS             Status;
 | 
						|
  UINT8                  TmpMemoryMap[1];
 | 
						|
  UINTN                  MapKey;
 | 
						|
  UINTN                  DescriptorSize;
 | 
						|
  UINT32                 DescriptorVersion;
 | 
						|
  UINTN                  MemoryMapSize;
 | 
						|
  EFI_MEMORY_DESCRIPTOR  *MemoryMap;
 | 
						|
  EFI_MEMORY_DESCRIPTOR  *MemoryMapPtr;
 | 
						|
  UINTN                  Index;
 | 
						|
  struct efi_info        *Efi;
 | 
						|
  struct e820_entry      *LastE820;
 | 
						|
  struct e820_entry      *E820;
 | 
						|
  UINTN                  E820EntryCount;
 | 
						|
  EFI_PHYSICAL_ADDRESS   LastEndAddr;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get System MemoryMapSize
 | 
						|
  //
 | 
						|
  MemoryMapSize = sizeof (TmpMemoryMap);
 | 
						|
  Status        = gBS->GetMemoryMap (
 | 
						|
                         &MemoryMapSize,
 | 
						|
                         (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,
 | 
						|
                         &MapKey,
 | 
						|
                         &DescriptorSize,
 | 
						|
                         &DescriptorVersion
 | 
						|
                         );
 | 
						|
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
 | 
						|
  //
 | 
						|
  // Enlarge space here, because we will allocate pool now.
 | 
						|
  //
 | 
						|
  MemoryMapSize += EFI_PAGE_SIZE;
 | 
						|
  Status         = gBS->AllocatePool (
 | 
						|
                          EfiLoaderData,
 | 
						|
                          MemoryMapSize,
 | 
						|
                          (VOID **)&MemoryMap
 | 
						|
                          );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Get System MemoryMap
 | 
						|
  //
 | 
						|
  Status = gBS->GetMemoryMap (
 | 
						|
                  &MemoryMapSize,
 | 
						|
                  MemoryMap,
 | 
						|
                  &MapKey,
 | 
						|
                  &DescriptorSize,
 | 
						|
                  &DescriptorVersion
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  LastE820       = NULL;
 | 
						|
  E820           = &Bp->e820_map[0];
 | 
						|
  E820EntryCount = 0;
 | 
						|
  LastEndAddr    = 0;
 | 
						|
  MemoryMapPtr   = MemoryMap;
 | 
						|
  for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
 | 
						|
    UINTN  E820Type = 0;
 | 
						|
 | 
						|
    if (MemoryMap->NumberOfPages == 0) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (MemoryMap->Type) {
 | 
						|
      case EfiReservedMemoryType:
 | 
						|
      case EfiRuntimeServicesCode:
 | 
						|
      case EfiRuntimeServicesData:
 | 
						|
      case EfiMemoryMappedIO:
 | 
						|
      case EfiMemoryMappedIOPortSpace:
 | 
						|
      case EfiPalCode:
 | 
						|
        E820Type = E820_RESERVED;
 | 
						|
        break;
 | 
						|
 | 
						|
      case EfiUnusableMemory:
 | 
						|
        E820Type = E820_UNUSABLE;
 | 
						|
        break;
 | 
						|
 | 
						|
      case EfiACPIReclaimMemory:
 | 
						|
        E820Type = E820_ACPI;
 | 
						|
        break;
 | 
						|
 | 
						|
      case EfiLoaderCode:
 | 
						|
      case EfiLoaderData:
 | 
						|
      case EfiBootServicesCode:
 | 
						|
      case EfiBootServicesData:
 | 
						|
      case EfiConventionalMemory:
 | 
						|
        E820Type = E820_RAM;
 | 
						|
        break;
 | 
						|
 | 
						|
      case EfiACPIMemoryNVS:
 | 
						|
        E820Type = E820_NVS;
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        DEBUG ((
 | 
						|
          DEBUG_ERROR,
 | 
						|
          "Invalid EFI memory descriptor type (0x%x)!\n",
 | 
						|
          MemoryMap->Type
 | 
						|
          ));
 | 
						|
        continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((LastE820 != NULL) &&
 | 
						|
        (LastE820->type == (UINT32)E820Type) &&
 | 
						|
        (MemoryMap->PhysicalStart == LastEndAddr))
 | 
						|
    {
 | 
						|
      LastE820->size += EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages);
 | 
						|
      LastEndAddr    += EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages);
 | 
						|
    } else {
 | 
						|
      if (E820EntryCount >= ARRAY_SIZE (Bp->e820_map)) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      E820->type  = (UINT32)E820Type;
 | 
						|
      E820->addr  = MemoryMap->PhysicalStart;
 | 
						|
      E820->size  = EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages);
 | 
						|
      LastE820    = E820;
 | 
						|
      LastEndAddr = E820->addr + E820->size;
 | 
						|
      E820++;
 | 
						|
      E820EntryCount++;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Get next item
 | 
						|
    //
 | 
						|
    MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize);
 | 
						|
  }
 | 
						|
 | 
						|
  Bp->e820_entries = (UINT8)E820EntryCount;
 | 
						|
 | 
						|
  Efi                      = &Bp->efi_info;
 | 
						|
  Efi->efi_systab          = (UINT32)(UINTN)gST;
 | 
						|
  Efi->efi_memdesc_size    = (UINT32)DescriptorSize;
 | 
						|
  Efi->efi_memdesc_version = DescriptorVersion;
 | 
						|
  Efi->efi_memmap          = (UINT32)(UINTN)MemoryMapPtr;
 | 
						|
  Efi->efi_memmap_size     = (UINT32)MemoryMapSize;
 | 
						|
 #ifdef MDE_CPU_IA32
 | 
						|
  Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2');
 | 
						|
 #else
 | 
						|
  Efi->efi_systab_hi        = (UINT32)(((UINT64)(UINTN)gST) >> 32);
 | 
						|
  Efi->efi_memmap_hi        = (UINT32)(((UINT64)(UINTN)MemoryMapPtr) >> 32);
 | 
						|
  Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4');
 | 
						|
 #endif
 | 
						|
 | 
						|
  gBS->ExitBootServices (gImageHandle, MapKey);
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LoadLinuxSetCommandLine (
 | 
						|
  IN OUT VOID  *KernelSetup,
 | 
						|
  IN CHAR8     *CommandLine
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  struct boot_params  *Bp;
 | 
						|
 | 
						|
  Status = BasicKernelSetupCheck (KernelSetup);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  Bp->hdr.cmd_line_ptr = (UINT32)(UINTN)CommandLine;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LoadLinuxSetInitrd (
 | 
						|
  IN OUT VOID  *KernelSetup,
 | 
						|
  IN VOID      *Initrd,
 | 
						|
  IN UINTN     InitrdSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  struct boot_params  *Bp;
 | 
						|
 | 
						|
  Status = BasicKernelSetupCheck (KernelSetup);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  Bp->hdr.ramdisk_start = (UINT32)(UINTN)Initrd;
 | 
						|
  Bp->hdr.ramdisk_len   = (UINT32)InitrdSize;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
STATIC VOID
 | 
						|
FindBits (
 | 
						|
  unsigned long  Mask,
 | 
						|
  UINT8          *Pos,
 | 
						|
  UINT8          *Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8  First, Len;
 | 
						|
 | 
						|
  First = 0;
 | 
						|
  Len   = 0;
 | 
						|
 | 
						|
  if (Mask) {
 | 
						|
    while (!(Mask & 0x1)) {
 | 
						|
      Mask = Mask >> 1;
 | 
						|
      First++;
 | 
						|
    }
 | 
						|
 | 
						|
    while (Mask & 0x1) {
 | 
						|
      Mask = Mask >> 1;
 | 
						|
      Len++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  *Pos  = First;
 | 
						|
  *Size = Len;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
SetupGraphicsFromGop (
 | 
						|
  struct screen_info            *Si,
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
 | 
						|
  EFI_STATUS                            Status;
 | 
						|
  UINTN                                 Size;
 | 
						|
 | 
						|
  Status = Gop->QueryMode (Gop, Gop->Mode->Mode, &Size, &Info);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  /* We found a GOP */
 | 
						|
 | 
						|
  /* EFI framebuffer */
 | 
						|
  Si->orig_video_isVGA = 0x70;
 | 
						|
 | 
						|
  Si->orig_x            = 0;
 | 
						|
  Si->orig_y            = 0;
 | 
						|
  Si->orig_video_page   = 0;
 | 
						|
  Si->orig_video_mode   = 0;
 | 
						|
  Si->orig_video_cols   = 0;
 | 
						|
  Si->orig_video_lines  = 0;
 | 
						|
  Si->orig_video_ega_bx = 0;
 | 
						|
  Si->orig_video_points = 0;
 | 
						|
 | 
						|
  Si->lfb_base   = (UINT32)Gop->Mode->FrameBufferBase;
 | 
						|
  Si->lfb_size   = (UINT32)Gop->Mode->FrameBufferSize;
 | 
						|
  Si->lfb_width  = (UINT16)Info->HorizontalResolution;
 | 
						|
  Si->lfb_height = (UINT16)Info->VerticalResolution;
 | 
						|
  Si->pages      = 1;
 | 
						|
  Si->vesapm_seg = 0;
 | 
						|
  Si->vesapm_off = 0;
 | 
						|
 | 
						|
  if (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
 | 
						|
    Si->lfb_depth      = 32;
 | 
						|
    Si->red_size       = 8;
 | 
						|
    Si->red_pos        = 0;
 | 
						|
    Si->green_size     = 8;
 | 
						|
    Si->green_pos      = 8;
 | 
						|
    Si->blue_size      = 8;
 | 
						|
    Si->blue_pos       = 16;
 | 
						|
    Si->rsvd_size      = 8;
 | 
						|
    Si->rsvd_pos       = 24;
 | 
						|
    Si->lfb_linelength = (UINT16)(Info->PixelsPerScanLine * 4);
 | 
						|
  } else if (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
 | 
						|
    Si->lfb_depth      = 32;
 | 
						|
    Si->red_size       = 8;
 | 
						|
    Si->red_pos        = 16;
 | 
						|
    Si->green_size     = 8;
 | 
						|
    Si->green_pos      = 8;
 | 
						|
    Si->blue_size      = 8;
 | 
						|
    Si->blue_pos       = 0;
 | 
						|
    Si->rsvd_size      = 8;
 | 
						|
    Si->rsvd_pos       = 24;
 | 
						|
    Si->lfb_linelength = (UINT16)(Info->PixelsPerScanLine * 4);
 | 
						|
  } else if (Info->PixelFormat == PixelBitMask) {
 | 
						|
    FindBits (
 | 
						|
      Info->PixelInformation.RedMask,
 | 
						|
      &Si->red_pos,
 | 
						|
      &Si->red_size
 | 
						|
      );
 | 
						|
    FindBits (
 | 
						|
      Info->PixelInformation.GreenMask,
 | 
						|
      &Si->green_pos,
 | 
						|
      &Si->green_size
 | 
						|
      );
 | 
						|
    FindBits (
 | 
						|
      Info->PixelInformation.BlueMask,
 | 
						|
      &Si->blue_pos,
 | 
						|
      &Si->blue_size
 | 
						|
      );
 | 
						|
    FindBits (
 | 
						|
      Info->PixelInformation.ReservedMask,
 | 
						|
      &Si->rsvd_pos,
 | 
						|
      &Si->rsvd_size
 | 
						|
      );
 | 
						|
    Si->lfb_depth = Si->red_size + Si->green_size +
 | 
						|
                    Si->blue_size + Si->rsvd_size;
 | 
						|
    Si->lfb_linelength = (UINT16)((Info->PixelsPerScanLine * Si->lfb_depth) / 8);
 | 
						|
  } else {
 | 
						|
    Si->lfb_depth      = 4;
 | 
						|
    Si->red_size       = 0;
 | 
						|
    Si->red_pos        = 0;
 | 
						|
    Si->green_size     = 0;
 | 
						|
    Si->green_pos      = 0;
 | 
						|
    Si->blue_size      = 0;
 | 
						|
    Si->blue_pos       = 0;
 | 
						|
    Si->rsvd_size      = 0;
 | 
						|
    Si->rsvd_pos       = 0;
 | 
						|
    Si->lfb_linelength = Si->lfb_width / 2;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
SetupGraphics (
 | 
						|
  IN OUT struct boot_params  *Bp
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  EFI_HANDLE                    *HandleBuffer;
 | 
						|
  UINTN                         HandleCount;
 | 
						|
  UINTN                         Index;
 | 
						|
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop;
 | 
						|
 | 
						|
  ZeroMem ((VOID *)&Bp->screen_info, sizeof (Bp->screen_info));
 | 
						|
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
                  ByProtocol,
 | 
						|
                  &gEfiGraphicsOutputProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  &HandleCount,
 | 
						|
                  &HandleBuffer
 | 
						|
                  );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    for (Index = 0; Index < HandleCount; Index++) {
 | 
						|
      Status = gBS->HandleProtocol (
 | 
						|
                      HandleBuffer[Index],
 | 
						|
                      &gEfiGraphicsOutputProtocolGuid,
 | 
						|
                      (VOID *)&Gop
 | 
						|
                      );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      Status = SetupGraphicsFromGop (&Bp->screen_info, Gop);
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        FreePool (HandleBuffer);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    FreePool (HandleBuffer);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_NOT_FOUND;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
SetupLinuxBootParams (
 | 
						|
  IN OUT struct boot_params  *Bp
 | 
						|
  )
 | 
						|
{
 | 
						|
  SetupGraphics (Bp);
 | 
						|
 | 
						|
  SetupLinuxMemmap (Bp);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LoadLinux (
 | 
						|
  IN VOID      *Kernel,
 | 
						|
  IN OUT VOID  *KernelSetup
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  struct boot_params  *Bp;
 | 
						|
 | 
						|
  Status = BasicKernelSetupCheck (KernelSetup);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Bp = (struct boot_params *)KernelSetup;
 | 
						|
 | 
						|
  if ((Bp->hdr.version < 0x205) || !Bp->hdr.relocatable_kernel) {
 | 
						|
    //
 | 
						|
    // We only support relocatable kernels
 | 
						|
    //
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  InitLinuxDescriptorTables ();
 | 
						|
 | 
						|
  Bp->hdr.code32_start = (UINT32)(UINTN)Kernel;
 | 
						|
  if ((Bp->hdr.version >= 0x20c) && Bp->hdr.handover_offset &&
 | 
						|
      (Bp->hdr.xloadflags & ((sizeof (UINTN) == 4) ? BIT2 : BIT3)))
 | 
						|
  {
 | 
						|
    DEBUG ((DEBUG_INFO, "Jumping to kernel EFI handover point at ofs %x\n", Bp->hdr.handover_offset));
 | 
						|
 | 
						|
    DisableInterrupts ();
 | 
						|
    JumpToUefiKernel ((VOID *)gImageHandle, (VOID *)gST, KernelSetup, Kernel);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Old kernels without EFI handover protocol
 | 
						|
  //
 | 
						|
  SetupLinuxBootParams (KernelSetup);
 | 
						|
 | 
						|
  DEBUG ((DEBUG_INFO, "Jumping to kernel\n"));
 | 
						|
  DisableInterrupts ();
 | 
						|
  SetLinuxDescriptorTables ();
 | 
						|
  JumpToKernel (Kernel, (VOID *)KernelSetup);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |