Adding support for BeagleBoard.
ArmPkg - Supoprt for ARM specific things that can change as the architecture changes. Plus semihosting JTAG drivers. EmbeddedPkg - Generic support for an embeddded platform. Including a light weight command line shell. BeagleBoardPkg - Platform specifics for BeagleBoard. SD Card works, but USB has issues. Looks like a bug in the open source USB stack (Our internal stack works fine). git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9518 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
288
EmbeddedPkg/Library/HalRuntimeServicesExampleLib/Capsule.c
Normal file
288
EmbeddedPkg/Library/HalRuntimeServicesExampleLib/Capsule.c
Normal file
@ -0,0 +1,288 @@
|
||||
/** @file
|
||||
Generic Capsule services
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#include <Common/CapsuleName.h>
|
||||
|
||||
|
||||
//
|
||||
//Max size capsule services support are platform policy,to populate capsules we just need
|
||||
//memory to maintain them across reset,it is not a problem. And to special capsules ,for
|
||||
//example,update flash,it is mostly decided by the platform. Here is a sample size for
|
||||
//different type capsules.
|
||||
//
|
||||
#define MAX_SIZE_POPULATE (0)
|
||||
#define MAX_SIZE_NON_POPULATE (0)
|
||||
#define MAX_SUPPORT_CAPSULE_NUM 0x10
|
||||
|
||||
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
SupportUpdateCapsuleRest (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
//
|
||||
//If the platform has a way to guarantee the memory integrity across a system reset, return
|
||||
//TRUE, else FALSE.
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SupportCapsuleSize (
|
||||
IN OUT UINT32 *MaxSizePopulate,
|
||||
IN OUT UINT32 *MaxSizeNonPopulate
|
||||
)
|
||||
{
|
||||
//
|
||||
//Here is a sample size, different platforms have different sizes.
|
||||
//
|
||||
*MaxSizePopulate = MAX_SIZE_POPULATE;
|
||||
*MaxSizeNonPopulate = MAX_SIZE_NON_POPULATE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
LibUpdateCapsule (
|
||||
IN UEFI_CAPSULE_HEADER **CapsuleHeaderArray,
|
||||
IN UINTN CapsuleCount,
|
||||
IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This code finds if the capsule needs reset to update, if no, update immediately.
|
||||
|
||||
Arguments:
|
||||
|
||||
CapsuleHeaderArray A array of pointers to capsule headers passed in
|
||||
CapsuleCount The number of capsule
|
||||
ScatterGatherList Physical address of datablock list points to capsule
|
||||
|
||||
Returns:
|
||||
|
||||
EFI STATUS
|
||||
EFI_SUCCESS Valid capsule was passed.If CAPSULE_FLAG_PERSIT_ACROSS_RESET is
|
||||
not set, the capsule has been successfully processed by the firmware.
|
||||
If it set, the ScattlerGatherList is successfully to be set.
|
||||
EFI_INVALID_PARAMETER CapsuleCount is less than 1,CapsuleGuid is not supported.
|
||||
EFI_DEVICE_ERROR Failed to SetVariable or AllocatePool or ProcessFirmwareVolume.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN CapsuleSize;
|
||||
UINTN ArrayNumber;
|
||||
VOID *BufferPtr;
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE FvHandle;
|
||||
UEFI_CAPSULE_HEADER *CapsuleHeader;
|
||||
|
||||
if ((CapsuleCount < 1) || (CapsuleCount > MAX_SUPPORT_CAPSULE_NUM)){
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
BufferPtr = NULL;
|
||||
CapsuleHeader = NULL;
|
||||
|
||||
//
|
||||
//Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET
|
||||
//and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is ,the service supports.
|
||||
//
|
||||
for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
|
||||
CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
|
||||
if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (!CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiCapsuleGuid)) {
|
||||
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//Assume that capsules have the same flags on reseting or not.
|
||||
//
|
||||
CapsuleHeader = CapsuleHeaderArray[0];
|
||||
|
||||
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
|
||||
//
|
||||
//Check if the platform supports update capsule across a system reset
|
||||
//
|
||||
if (!SupportUpdateCapsuleRest()) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (ScatterGatherList == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
} else {
|
||||
Status = EfiSetVariable (
|
||||
EFI_CAPSULE_VARIABLE_NAME,
|
||||
&gEfiCapsuleVendorGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||||
sizeof (UINTN),
|
||||
(VOID *) &ScatterGatherList
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
//The rest occurs in the condition of non-reset mode
|
||||
//
|
||||
if (EfiAtRuntime ()) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
//Here should be in the boot-time
|
||||
//
|
||||
for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) {
|
||||
CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
|
||||
CapsuleSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;
|
||||
Status = gBS->AllocatePool (EfiBootServicesData, CapsuleSize, &BufferPtr);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
gBS->CopyMem (BufferPtr, (UINT8*)CapsuleHeader+ CapsuleHeader->HeaderSize, CapsuleSize);
|
||||
|
||||
//
|
||||
//Call DXE service ProcessFirmwareVolume to process immediatelly
|
||||
//
|
||||
Status = gDS->ProcessFirmwareVolume (BufferPtr, CapsuleSize, &FvHandle);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
gBS->FreePool (BufferPtr);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
gDS->Dispatch ();
|
||||
gBS->FreePool (BufferPtr);
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
|
||||
Done:
|
||||
if (BufferPtr != NULL) {
|
||||
gBS->FreePool (BufferPtr);
|
||||
}
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
QueryCapsuleCapabilities (
|
||||
IN UEFI_CAPSULE_HEADER **CapsuleHeaderArray,
|
||||
IN UINTN CapsuleCount,
|
||||
OUT UINT64 *MaxiumCapsuleSize,
|
||||
OUT EFI_RESET_TYPE *ResetType
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This code is query about capsule capability.
|
||||
|
||||
Arguments:
|
||||
|
||||
CapsuleHeaderArray A array of pointers to capsule headers passed in
|
||||
CapsuleCount The number of capsule
|
||||
MaxiumCapsuleSize Max capsule size is supported
|
||||
ResetType Reset type the capsule indicates, if reset is not needed,return EfiResetCold.
|
||||
If reset is needed, return EfiResetWarm.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI STATUS
|
||||
EFI_SUCCESS Valid answer returned
|
||||
EFI_INVALID_PARAMETER MaxiumCapsuleSize is NULL,ResetType is NULL.CapsuleCount is less than 1,CapsuleGuid is not supported.
|
||||
EFI_UNSUPPORTED The capsule type is not supported.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN ArrayNumber;
|
||||
UEFI_CAPSULE_HEADER *CapsuleHeader;
|
||||
UINT32 MaxSizePopulate;
|
||||
UINT32 MaxSizeNonPopulate;
|
||||
|
||||
|
||||
if ((CapsuleCount < 1) || (CapsuleCount > MAX_SUPPORT_CAPSULE_NUM)){
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((MaxiumCapsuleSize == NULL) ||(ResetType == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CapsuleHeader = NULL;
|
||||
|
||||
//
|
||||
//Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET
|
||||
//and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is ,the service supports.
|
||||
//
|
||||
for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
|
||||
CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
|
||||
if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (!CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiCapsuleGuid)) {
|
||||
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SupportCapsuleSize(&MaxSizePopulate,&MaxSizeNonPopulate);
|
||||
//
|
||||
//Assume that capsules have the same flags on reseting or not.
|
||||
//
|
||||
CapsuleHeader = CapsuleHeaderArray[0];
|
||||
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
|
||||
//
|
||||
//Check if the platform supports update capsule across a system reset
|
||||
//
|
||||
if (!SupportUpdateCapsuleRest()) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
*ResetType = EfiResetWarm;
|
||||
*MaxiumCapsuleSize = MaxSizePopulate;
|
||||
} else {
|
||||
*ResetType = EfiResetCold;
|
||||
*MaxiumCapsuleSize = MaxSizeNonPopulate;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
LibCapsuleVirtualAddressChangeEvent (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
LibCapsuleInitialize (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
}
|
Reference in New Issue
Block a user