/** @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;
}

