/** @file
  This library will parse the coreboot table in memory and extract those required
  information.

  Copyright (c) 2014 - 2016, 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 <Uefi/UefiBaseType.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/CbParseLib.h>

#include <IndustryStandard/Acpi.h>

#include "Coreboot.h"


/**
  Convert a packed value from cbuint64 to a UINT64 value.

  @param  val      The pointer to packed data.

  @return          the UNIT64 value after convertion.

**/
UINT64
cb_unpack64 (
  IN struct cbuint64 val
  )
{
  return LShiftU64 (val.hi, 32) | val.lo;
}


/**
  Returns the sum of all elements in a buffer of 16-bit values.  During
  calculation, the carry bits are also been added.

  @param  Buffer      The pointer to the buffer to carry out the sum operation.
  @param  Length      The size, in bytes, of Buffer.

  @return Sum         The sum of Buffer with carry bits included during additions.

**/
UINT16
CbCheckSum16 (
  IN UINT16   *Buffer,
  IN UINTN    Length
  )
{
  UINT32 Sum, TmpValue;
  UINTN  Idx;
  UINT8  *TmpPtr;

  Sum = 0;
  TmpPtr = (UINT8 *)Buffer;
  for(Idx = 0; Idx < Length; Idx++) {
    TmpValue  = TmpPtr[Idx];
    if (Idx % 2 == 1) {
      TmpValue <<= 8;
    }

    Sum += TmpValue;

    // Wrap
    if (Sum >= 0x10000) {
      Sum = (Sum + (Sum >> 16)) & 0xFFFF;
    }
  }

  return (UINT16)((~Sum) & 0xFFFF);
}


/**
  Find coreboot record with given Tag from the memory Start in 4096
  bytes range.

  @param  Start              The start memory to be searched in
  @param  Tag                The tag id to be found

  @retval NULL              The Tag is not found.
  @retval Others            The poiter to the record found.

**/
VOID *
EFIAPI
FindCbTag (
  IN  VOID     *Start,
  IN  UINT32   Tag
  )
{
  struct cb_header   *Header;
  struct cb_record   *Record;
  UINT8              *TmpPtr;
  UINT8              *TagPtr;
  UINTN              Idx;
  UINT16             CheckSum;

  Header = NULL;
  TmpPtr = (UINT8 *)Start;
  for (Idx = 0; Idx < 4096; Idx += 16, TmpPtr += 16) {
    Header = (struct cb_header *)TmpPtr;
    if (Header->signature == CB_HEADER_SIGNATURE) {
      break;
    }
  }

  if (Idx >= 4096) {
    return NULL;
  }

  if ((Header == NULL) || (Header->table_bytes == 0)) {
    return NULL;
  }

  //
  // Check the checksum of the coreboot table header
  //
  CheckSum = CbCheckSum16 ((UINT16 *)Header, sizeof (*Header));
  if (CheckSum != 0) {
    DEBUG ((EFI_D_ERROR, "Invalid coreboot table header checksum\n"));
    return NULL;
  }

  CheckSum = CbCheckSum16 ((UINT16 *)(TmpPtr + sizeof (*Header)), Header->table_bytes);
  if (CheckSum != Header->table_checksum) {
    DEBUG ((EFI_D_ERROR, "Incorrect checksum of all the coreboot table entries\n"));
    return NULL;
  }

  TagPtr = NULL;
  TmpPtr += Header->header_bytes;
  for (Idx = 0; Idx < Header->table_entries; Idx++) {
    Record = (struct cb_record *)TmpPtr;
    if (Record->tag == CB_TAG_FORWARD) {
      TmpPtr = (VOID *)(UINTN)((struct cb_forward *)(UINTN)Record)->forward;
      if (Tag == CB_TAG_FORWARD) {
        return TmpPtr;
      } else {
        return FindCbTag (TmpPtr, Tag);
      }
    }
    if (Record->tag == Tag) {
      TagPtr = TmpPtr;
      break;
    }
    TmpPtr += Record->size;
  }

  return TagPtr;
}


/**
  Find the given table with TableId from the given coreboot memory Root.

  @param  Root               The coreboot memory table to be searched in
  @param  TableId            Table id to be found
  @param  pMemTable          To save the base address of the memory table found
  @param  pMemTableSize      To save the size of memory table found

  @retval RETURN_SUCCESS            Successfully find out the memory table.
  @retval RETURN_INVALID_PARAMETER  Invalid input parameters.
  @retval RETURN_NOT_FOUND          Failed to find the memory table.

**/
RETURN_STATUS
EFIAPI
FindCbMemTable (
  IN  struct cbmem_root  *Root,
  IN  UINT32             TableId,
  OUT VOID               **pMemTable,
  OUT UINT32             *pMemTableSize
  )
{
  UINTN                Idx;
  BOOLEAN              IsImdEntry;
  struct cbmem_entry  *Entries;

  if ((Root == NULL) || (pMemTable == NULL)) {
    return RETURN_INVALID_PARAMETER;
  }
  //
  // Check if the entry is CBMEM or IMD
  // and handle them separately
  //
  Entries = Root->entries;
  if (Entries[0].magic == CBMEM_ENTRY_MAGIC) {
    IsImdEntry = FALSE;
  } else {
    Entries = (struct cbmem_entry *)((struct imd_root *)Root)->entries;
    if (Entries[0].magic == IMD_ENTRY_MAGIC) {
      IsImdEntry = TRUE;
    } else {
      return RETURN_NOT_FOUND;
    }
  }

  for (Idx = 0; Idx < Root->num_entries; Idx++) {
    if (Entries[Idx].id == TableId) {
      if (IsImdEntry) {
        *pMemTable = (VOID *) ((UINTN)Entries[Idx].start + (UINTN)Root);
      } else {
        *pMemTable = (VOID *) (UINTN)Entries[Idx].start;
      }
      if (pMemTableSize != NULL) {
        *pMemTableSize = Entries[Idx].size;
      }

      DEBUG ((EFI_D_INFO, "Find CbMemTable Id 0x%x, base %p, size 0x%x\n",
        TableId, *pMemTable, Entries[Idx].size));
      return RETURN_SUCCESS;
    }
  }

  return RETURN_NOT_FOUND;
}


/**
  Acquire the memory information from the coreboot table in memory.

  @param  MemInfoCallback     The callback routine
  @param  pParam              Pointer to the callback routine parameter

  @retval RETURN_SUCCESS     Successfully find out the memory information.
  @retval RETURN_NOT_FOUND   Failed to find the memory information.

**/
RETURN_STATUS
EFIAPI
CbParseMemoryInfo (
  IN  CB_MEM_INFO_CALLBACK  MemInfoCallback,
  IN  VOID                  *pParam
  )
{
  struct cb_memory         *rec;
  struct cb_memory_range   *Range;
  UINT64                   Start;
  UINT64                   Size;
  UINTN                    Index;

  //
  // Get the coreboot memory table
  //
  rec = (struct cb_memory *)FindCbTag (0, CB_TAG_MEMORY);
  if (rec == NULL) {
    rec = (struct cb_memory *)FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_MEMORY);
  }

  if (rec == NULL) {
    return RETURN_NOT_FOUND;
  }

  for (Index = 0; Index < MEM_RANGE_COUNT(rec); Index++) {
    Range = MEM_RANGE_PTR(rec, Index);
    Start = cb_unpack64(Range->start);
    Size = cb_unpack64(Range->size);
    DEBUG ((EFI_D_INFO, "%d. %016lx - %016lx [%02x]\n",
            Index, Start, Start + Size - 1, Range->type));

    MemInfoCallback (Start, Size, Range->type, pParam);
  }

  return RETURN_SUCCESS;
}


/**
  Acquire the coreboot memory table with the given table id

  @param  TableId            Table id to be searched
  @param  pMemTable          Pointer to the base address of the memory table
  @param  pMemTableSize      Pointer to the size of the memory table

  @retval RETURN_SUCCESS     Successfully find out the memory table.
  @retval RETURN_INVALID_PARAMETER  Invalid input parameters.
  @retval RETURN_NOT_FOUND   Failed to find the memory table.

**/
RETURN_STATUS
EFIAPI
CbParseCbMemTable (
  IN  UINT32     TableId,
  OUT VOID       **pMemTable,
  OUT UINT32     *pMemTableSize
  )
{
  struct cb_memory         *rec;
  struct cb_memory_range   *Range;
  UINT64                   Start;
  UINT64                   Size;
  UINTN                    Index;

  if (pMemTable == NULL) {
    return RETURN_INVALID_PARAMETER;
  }
  *pMemTable = NULL;

  //
  // Get the coreboot memory table
  //
  rec = (struct cb_memory *)FindCbTag (0, CB_TAG_MEMORY);
  if (rec == NULL) {
    rec = (struct cb_memory *)FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_MEMORY);
  }

  if (rec == NULL) {
    return RETURN_NOT_FOUND;
  }

  for (Index = 0; Index < MEM_RANGE_COUNT(rec); Index++) {
    Range = MEM_RANGE_PTR(rec, Index);
    Start = cb_unpack64(Range->start);
    Size = cb_unpack64(Range->size);

    if ((Range->type == CB_MEM_TABLE) && (Start > 0x1000)) {
      if (FindCbMemTable ((struct  cbmem_root *)(UINTN)(Start + Size - DYN_CBMEM_ALIGN_SIZE), TableId, pMemTable, pMemTableSize) == RETURN_SUCCESS)
        return RETURN_SUCCESS;
    }
  }

  return RETURN_NOT_FOUND;
}


/**
  Acquire the acpi table from coreboot

  @param  pMemTable          Pointer to the base address of the memory table
  @param  pMemTableSize      Pointer to the size of the memory table

  @retval RETURN_SUCCESS     Successfully find out the memory table.
  @retval RETURN_INVALID_PARAMETER  Invalid input parameters.
  @retval RETURN_NOT_FOUND   Failed to find the memory table.

**/
RETURN_STATUS
EFIAPI
CbParseAcpiTable (
  OUT VOID       **pMemTable,
  OUT UINT32     *pMemTableSize
  )
{
  return CbParseCbMemTable (SIGNATURE_32 ('I', 'P', 'C', 'A'), pMemTable, pMemTableSize);
}

/**
  Acquire the smbios table from coreboot

  @param  pMemTable          Pointer to the base address of the memory table
  @param  pMemTableSize      Pointer to the size of the memory table

  @retval RETURN_SUCCESS     Successfully find out the memory table.
  @retval RETURN_INVALID_PARAMETER  Invalid input parameters.
  @retval RETURN_NOT_FOUND   Failed to find the memory table.

**/
RETURN_STATUS
EFIAPI
CbParseSmbiosTable (
  OUT VOID       **pMemTable,
  OUT UINT32     *pMemTableSize
  )
{
  return CbParseCbMemTable (SIGNATURE_32 ('T', 'B', 'M', 'S'), pMemTable, pMemTableSize);
}

/**
  Find the required fadt information

  @param  pPmCtrlReg         Pointer to the address of power management control register
  @param  pPmTimerReg        Pointer to the address of power management timer register
  @param  pResetReg          Pointer to the address of system reset register
  @param  pResetValue        Pointer to the value to be writen to the system reset register
  @param  pPmEvtReg          Pointer to the address of power management event register
  @param  pPmGpeEnReg        Pointer to the address of power management GPE enable register

  @retval RETURN_SUCCESS     Successfully find out all the required fadt information.
  @retval RETURN_NOT_FOUND   Failed to find the fadt table.

**/
RETURN_STATUS
EFIAPI
CbParseFadtInfo (
  OUT UINTN      *pPmCtrlReg,
  OUT UINTN      *pPmTimerReg,
  OUT UINTN      *pResetReg,
  OUT UINTN      *pResetValue,
  OUT UINTN      *pPmEvtReg,
  OUT UINTN      *pPmGpeEnReg
  )
{
  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt;
  UINT32                                        *Entry32;
  UINTN                                         Entry32Num;
  EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE     *Fadt;
  EFI_ACPI_DESCRIPTION_HEADER                   *Xsdt;
  UINT64                                        *Entry64;
  UINTN                                         Entry64Num;
  UINTN                                         Idx;
  RETURN_STATUS                                 Status;

  Rsdp = NULL;
  Status = RETURN_SUCCESS;

  Status = CbParseAcpiTable ((VOID **)&Rsdp, NULL);
  if (RETURN_ERROR(Status)) {
    return Status;
  }

  if (Rsdp == NULL) {
    return RETURN_NOT_FOUND;
  }

  DEBUG ((EFI_D_INFO, "Find Rsdp at %p\n", Rsdp));
  DEBUG ((EFI_D_INFO, "Find Rsdt 0x%x, Xsdt 0x%lx\n", Rsdp->RsdtAddress, Rsdp->XsdtAddress));

  //
  // Search Rsdt First
  //
  Rsdt     = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->RsdtAddress);
  if (Rsdt != NULL) {
    Entry32  = (UINT32 *)(Rsdt + 1);
    Entry32Num = (Rsdt->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) >> 2;
    for (Idx = 0; Idx < Entry32Num; Idx++) {
      if (*(UINT32 *)(UINTN)(Entry32[Idx]) == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
        Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)(Entry32[Idx]);
        if (pPmCtrlReg != NULL) {
          *pPmCtrlReg = Fadt->Pm1aCntBlk;
        }
        DEBUG ((EFI_D_INFO, "PmCtrl Reg 0x%x\n", Fadt->Pm1aCntBlk));

        if (pPmTimerReg != NULL) {
          *pPmTimerReg = Fadt->PmTmrBlk;
        }
        DEBUG ((EFI_D_INFO, "PmTimer Reg 0x%x\n", Fadt->PmTmrBlk));

        if (pResetReg != NULL) {
          *pResetReg = (UINTN)Fadt->ResetReg.Address;
        }
        DEBUG ((EFI_D_INFO, "Reset Reg 0x%lx\n", Fadt->ResetReg.Address));

        if (pResetValue != NULL) {
          *pResetValue = Fadt->ResetValue;
        }
        DEBUG ((EFI_D_INFO, "Reset Value 0x%x\n", Fadt->ResetValue));

        if (pPmEvtReg != NULL) {
          *pPmEvtReg = Fadt->Pm1aEvtBlk;
          DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk));
        }

        if (pPmGpeEnReg != NULL) {
          *pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;
          DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg));
        }

        //
        // Verify values for proper operation
        //
        ASSERT(Fadt->Pm1aCntBlk != 0);
        ASSERT(Fadt->PmTmrBlk != 0);
        ASSERT(Fadt->ResetReg.Address != 0);
        ASSERT(Fadt->Pm1aEvtBlk != 0);
        ASSERT(Fadt->Gpe0Blk != 0);

        return RETURN_SUCCESS;
      }
    }
  }

  //
  // Search Xsdt Second
  //
  Xsdt     = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->XsdtAddress);
  if (Xsdt != NULL) {
    Entry64  = (UINT64 *)(Xsdt + 1);
    Entry64Num = (Xsdt->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) >> 3;
    for (Idx = 0; Idx < Entry64Num; Idx++) {
      if (*(UINT32 *)(UINTN)(Entry64[Idx]) == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
        Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)(Entry64[Idx]);
        if (pPmCtrlReg)
          *pPmCtrlReg = Fadt->Pm1aCntBlk;
        DEBUG ((EFI_D_ERROR, "PmCtrl Reg 0x%x\n", Fadt->Pm1aCntBlk));

        if (pPmTimerReg)
          *pPmTimerReg = Fadt->PmTmrBlk;
        DEBUG ((EFI_D_ERROR, "PmTimer Reg 0x%x\n", Fadt->PmTmrBlk));

        if (pResetReg)
          *pResetReg = (UINTN)Fadt->ResetReg.Address;
        DEBUG ((EFI_D_ERROR, "Reset Reg 0x%lx\n", Fadt->ResetReg.Address));

        if (pResetValue)
          *pResetValue = Fadt->ResetValue;
        DEBUG ((EFI_D_ERROR, "Reset Value 0x%x\n", Fadt->ResetValue));

        if (pPmEvtReg != NULL) {
          *pPmEvtReg = Fadt->Pm1aEvtBlk;
           DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk));
        }

        if (pPmGpeEnReg != NULL) {
          *pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;
          DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg));
        }
        return RETURN_SUCCESS;
      }
    }
  }

  return RETURN_NOT_FOUND;
}

/**
  Find the serial port information

  @param  pRegBase           Pointer to the base address of serial port registers
  @param  pRegAccessType     Pointer to the access type of serial port registers
  @param  pRegWidth          Pointer to the register width in bytes
  @param  pBaudrate          Pointer to the serial port baudrate
  @param  pInputHertz        Pointer to the input clock frequency
  @param  pUartPciAddr       Pointer to the UART PCI bus, dev and func address

  @retval RETURN_SUCCESS     Successfully find the serial port information.
  @retval RETURN_NOT_FOUND   Failed to find the serial port information .

**/
RETURN_STATUS
EFIAPI
CbParseSerialInfo (
  OUT UINT32      *pRegBase,
  OUT UINT32      *pRegAccessType,
  OUT UINT32      *pRegWidth,
  OUT UINT32      *pBaudrate,
  OUT UINT32      *pInputHertz,
  OUT UINT32      *pUartPciAddr
  )
{
  struct cb_serial    *CbSerial;

  CbSerial = FindCbTag (0, CB_TAG_SERIAL);
  if (CbSerial == NULL) {
    CbSerial = FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_SERIAL);
  }

  if (CbSerial == NULL) {
    return RETURN_NOT_FOUND;
  }

  if (pRegBase != NULL) {
    *pRegBase = CbSerial->baseaddr;
  }

  if (pRegWidth != NULL) {
    *pRegWidth = CbSerial->regwidth;
  }

  if (pRegAccessType != NULL) {
    *pRegAccessType = CbSerial->type;
  }

  if (pBaudrate != NULL) {
    *pBaudrate = CbSerial->baud;
  }

  if (pInputHertz != NULL) {
    *pInputHertz = CbSerial->input_hertz;
  }

  if (pUartPciAddr != NULL) {
    *pUartPciAddr = CbSerial->uart_pci_addr;
  }

  return RETURN_SUCCESS;
}

/**
  Search for the coreboot table header

  @param  Level              Level of the search depth
  @param  HeaderPtr          Pointer to the pointer of coreboot table header

  @retval RETURN_SUCCESS     Successfully find the coreboot table header .
  @retval RETURN_NOT_FOUND   Failed to find the coreboot table header .

**/
RETURN_STATUS
EFIAPI
CbParseGetCbHeader (
  IN  UINTN  Level,
  OUT VOID   **HeaderPtr
  )
{
  UINTN Index;
  VOID  *TempPtr;

  if (HeaderPtr == NULL) {
    return RETURN_NOT_FOUND;
  }

  TempPtr = NULL;
  for (Index = 0; Index < Level; Index++) {
    TempPtr = FindCbTag (TempPtr, CB_TAG_FORWARD);
    if (TempPtr == NULL) {
      break;
    }
  }

  if ((Index >= Level) && (TempPtr != NULL)) {
    *HeaderPtr = TempPtr;
    return RETURN_SUCCESS;
  }

  return RETURN_NOT_FOUND;
}

/**
  Find the video frame buffer information

  @param  pFbInfo            Pointer to the FRAME_BUFFER_INFO structure

  @retval RETURN_SUCCESS     Successfully find the video frame buffer information.
  @retval RETURN_NOT_FOUND   Failed to find the video frame buffer information .

**/
RETURN_STATUS
EFIAPI
CbParseFbInfo (
  OUT FRAME_BUFFER_INFO       *pFbInfo
  )
{
  struct cb_framebuffer       *CbFbRec;

  if (pFbInfo == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  CbFbRec = FindCbTag (0, CB_TAG_FRAMEBUFFER);
  if (CbFbRec == NULL) {
    CbFbRec = FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_FRAMEBUFFER);
  }

  if (CbFbRec == NULL) {
    return RETURN_NOT_FOUND;
  }

  DEBUG ((EFI_D_INFO, "Found coreboot video frame buffer information\n"));
  DEBUG ((EFI_D_INFO, "physical_address: 0x%lx\n", CbFbRec->physical_address));
  DEBUG ((EFI_D_INFO, "x_resolution: 0x%x\n", CbFbRec->x_resolution));
  DEBUG ((EFI_D_INFO, "y_resolution: 0x%x\n", CbFbRec->y_resolution));
  DEBUG ((EFI_D_INFO, "bits_per_pixel: 0x%x\n", CbFbRec->bits_per_pixel));
  DEBUG ((EFI_D_INFO, "bytes_per_line: 0x%x\n", CbFbRec->bytes_per_line));

  DEBUG ((EFI_D_INFO, "red_mask_size: 0x%x\n", CbFbRec->red_mask_size));
  DEBUG ((EFI_D_INFO, "red_mask_pos: 0x%x\n", CbFbRec->red_mask_pos));
  DEBUG ((EFI_D_INFO, "green_mask_size: 0x%x\n", CbFbRec->green_mask_size));
  DEBUG ((EFI_D_INFO, "green_mask_pos: 0x%x\n", CbFbRec->green_mask_pos));
  DEBUG ((EFI_D_INFO, "blue_mask_size: 0x%x\n", CbFbRec->blue_mask_size));
  DEBUG ((EFI_D_INFO, "blue_mask_pos: 0x%x\n", CbFbRec->blue_mask_pos));
  DEBUG ((EFI_D_INFO, "reserved_mask_size: 0x%x\n", CbFbRec->reserved_mask_size));
  DEBUG ((EFI_D_INFO, "reserved_mask_pos: 0x%x\n", CbFbRec->reserved_mask_pos));

  pFbInfo->LinearFrameBuffer    = CbFbRec->physical_address;
  pFbInfo->HorizontalResolution = CbFbRec->x_resolution;
  pFbInfo->VerticalResolution   = CbFbRec->y_resolution;
  pFbInfo->BitsPerPixel         = CbFbRec->bits_per_pixel;
  pFbInfo->BytesPerScanLine     = (UINT16)CbFbRec->bytes_per_line;
  pFbInfo->Red.Mask             = (1 << CbFbRec->red_mask_size) - 1;
  pFbInfo->Red.Position         = CbFbRec->red_mask_pos;
  pFbInfo->Green.Mask           = (1 << CbFbRec->green_mask_size) - 1;
  pFbInfo->Green.Position       = CbFbRec->green_mask_pos;
  pFbInfo->Blue.Mask            = (1 << CbFbRec->blue_mask_size) - 1;
  pFbInfo->Blue.Position        = CbFbRec->blue_mask_pos;
  pFbInfo->Reserved.Mask        = (1 << CbFbRec->reserved_mask_size) - 1;
  pFbInfo->Reserved.Position    = CbFbRec->reserved_mask_pos;

  return RETURN_SUCCESS;
}

