/*++

Copyright (c) 2006, Intel Corporation                                                         
All rights reserved. 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.             

Module Name:

  Capsules.c

Abstract:

  BDS routines to handle capsules.

--*/


#include <Common/FlashMap.h>

VOID
BdsLockFv (
  IN EFI_CPU_IO_PROTOCOL          *CpuIo,
  IN EFI_FLASH_SUBAREA_ENTRY      *FlashEntry
  );

VOID
BdsLockFv (
  IN EFI_CPU_IO_PROTOCOL          *CpuIo,
  IN EFI_FLASH_SUBAREA_ENTRY      *FlashEntry
  )
{
  EFI_FV_BLOCK_MAP_ENTRY      *BlockMap;
  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
  UINT64                      BaseAddress;
  UINT8                       Data;
  UINT32                      BlockLength;
  UINTN                       Index;

  BaseAddress = FlashEntry->Base - 0x400000 + 2;
  FvHeader    = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (FlashEntry->Base));
  BlockMap    = &(FvHeader->FvBlockMap[0]);

  while ((BlockMap->NumBlocks != 0) && (BlockMap->BlockLength != 0)) {
    BlockLength = BlockMap->BlockLength;
    for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
      CpuIo->Mem.Read (
                  CpuIo,
                  EfiCpuIoWidthUint8,
                  BaseAddress,
                  1,
                  &Data
                  );
      Data = (UINT8) (Data | 0x3);
      CpuIo->Mem.Write (
                  CpuIo,
                  EfiCpuIoWidthUint8,
                  BaseAddress,
                  1,
                  &Data
                  );
      BaseAddress += BlockLength;
    }

    BlockMap++;
  }
}

VOID
BdsLockNonUpdatableFlash (
  VOID
  )
{
  EFI_FLASH_MAP_ENTRY_DATA  *FlashMapEntryData;
  EFI_PEI_HOB_POINTERS      GuidHob;
  EFI_STATUS                Status;
  EFI_CPU_IO_PROTOCOL       *CpuIo;

  Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID**)&CpuIo);
  ASSERT_EFI_ERROR (Status);
  
  GuidHob.Raw = GetHobList ();
  while ((GuidHob.Raw = GetNextGuidHob (&gEfiFlashMapHobGuid, GuidHob.Raw)) != NULL) {
    FlashMapEntryData = (EFI_FLASH_MAP_ENTRY_DATA *) GET_GUID_HOB_DATA (GuidHob.Guid);

    //
    // Get the variable store area
    //
    if ((FlashMapEntryData->AreaType == EFI_FLASH_AREA_RECOVERY_BIOS) ||
        (FlashMapEntryData->AreaType == EFI_FLASH_AREA_MAIN_BIOS)
        ) {
      BdsLockFv (CpuIo, &(FlashMapEntryData->Entries[0]));
    }
    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
  }

  return ;
}

EFI_STATUS
ProcessCapsules (
  EFI_BOOT_MODE BootMode
  )
/*++

Routine Description:

  This routine is called to see if there are any capsules we need to process.
  If the boot mode is not UPDATE, then we do nothing. Otherwise find the
  capsule HOBS and produce firmware volumes for them via the DXE service.
  Then call the dispatcher to dispatch drivers from them. Finally, check
  the status of the updates.

Arguments:

  BootMode - the current boot mode

Returns:
  
  EFI_INVALID_PARAMETER - boot mode is not correct for an update

Note:
 
 This function should be called by BDS in case we need to do some
 sort of processing even if there is no capsule to process. We
 need to do this if an earlier update went awry and we need to
 clear the capsule variable so on the next reset PEI does not see it and 
 think there is a capsule available.

--*/
{
  EFI_STATUS                  Status;
  EFI_HOB_CAPSULE_VOLUME      *CvHob;
  EFI_PHYSICAL_ADDRESS        BaseAddress;
  UINT64                      Length;
  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
  EFI_HANDLE                  FvProtocolHandle;

  //
  // We don't do anything else if the boot mode is not flash-update
  //
  if (BootMode != BOOT_ON_FLASH_UPDATE) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Only one capsule HOB allowed.
  //
  CvHob = GetFirstHob (EFI_HOB_TYPE_CV);
  if (CvHob == NULL) {
    //
    // We didn't find a hob, so had no errors.
    //
    BdsLockNonUpdatableFlash ();
    return EFI_SUCCESS;
  }
  
  BaseAddress = CvHob->BaseAddress;
  Length      = CvHob->Length;

  Status      = EFI_SUCCESS;
  //
  // Now walk the capsule and call the core to process each
  // firmware volume in it.
  //
  while (Length != 0) {
    //
    // Point to the next firmware volume header, and then
    // call the DXE service to process it.
    //
    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
    if (FwVolHeader->FvLength > Length) {
      //
      // Notes: need to stuff this status somewhere so that the
      // error can be detected at OS runtime
      //
      Status = EFI_VOLUME_CORRUPTED;
      break;
    }

    Status = gDS->ProcessFirmwareVolume (
                    (VOID *) (UINTN) BaseAddress,
                    (UINTN) FwVolHeader->FvLength,
                    &FvProtocolHandle
                    );
    if (EFI_ERROR (Status)) {
      break;
    }
    //
    // Call the dispatcher to dispatch any drivers from the produced firmware volume
    //
    gDS->Dispatch ();
    //
    // On to the next FV in the capsule
    //
    Length -= FwVolHeader->FvLength;
    BaseAddress = (EFI_PHYSICAL_ADDRESS) ((UINTN) BaseAddress + FwVolHeader->FvLength);
    //
    // Notes: when capsule spec is finalized, if the requirement is made to
    // have each FV in a capsule aligned, then we will need to align the
    // BaseAddress and Length here.
    //
  }
   

  BdsLockNonUpdatableFlash ();

  return Status;
}

