/** @file

  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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 ((EFI_D_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 ((
        EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "Jumping to kernel\n"));
  DisableInterrupts ();
  SetLinuxDescriptorTables ();
  JumpToKernel (Kernel, (VOID*) KernelSetup);

  return EFI_SUCCESS;
}

