/** @file | |
An instance of Platform Sec Lib. | |
Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR> | |
Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "PlatformSecLib.h" | |
typedef struct { | |
EFI_HOB_GUID_TYPE HobGuidHeader; | |
RISCV_SEC_HANDOFF_DATA SecHandoffData; | |
EFI_HOB_GENERIC_HEADER HobEnd; | |
} SEC_HOBLIST_DATA; | |
EFI_STATUS | |
EFIAPI | |
RiscVSecGetHobData ( | |
IN CONST EFI_SEC_HOB_DATA_PPI *This, | |
OUT EFI_HOB_GENERIC_HEADER **HobList | |
); | |
STATIC EFI_SEC_HOB_DATA_PPI mSecHobDataPpi = { | |
RiscVSecGetHobData | |
}; | |
STATIC EFI_PEI_PPI_DESCRIPTOR mPpiSecHobData = { | |
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), | |
&gEfiSecHobDataPpiGuid, | |
&mSecHobDataPpi | |
}; | |
VOID | |
EFIAPI | |
ProcessLibraryConstructorList ( | |
VOID | |
); | |
/** | |
After the SEC assembly code has initialized some temporary memory and set up | |
the stack, the control is transferred to this function for PEI booting. | |
@param SizeOfRam Size of the temporary memory available for use. | |
@param TempRamBase Base address of temporary ram | |
@param BootFirmwareVolume Base address of the Boot Firmware Volume. | |
**/ | |
VOID | |
NORETURN | |
EFIAPI | |
SecStartup ( | |
IN UINT32 SizeOfRam, | |
IN UINT32 TempRamBase, | |
IN VOID *BootFirmwareVolume | |
); | |
STATIC | |
VOID * | |
GetSecHobData ( | |
VOID | |
) | |
{ | |
return (VOID *)(FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) - SEC_HANDOFF_DATA_RESERVE_SIZE); | |
} | |
#ifndef RISCVVIRT_PEI_BOOTING | |
/** | |
After the SEC assembly code has initialized some temporary memory and set up | |
the stack, the control is transferred to this function for PEIless booting. | |
@param SizeOfRam Size of the temporary memory available for use. | |
@param TempRamBase Base address of temporary ram | |
@param BootFirmwareVolume Base address of the Boot Firmware Volume. | |
**/ | |
STATIC | |
VOID | |
NORETURN | |
SecPEIlessStartup ( | |
IN UINT32 SizeOfRam, | |
IN UINT32 TempRamBase, | |
IN VOID *BootFirmwareVolume | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_HOB_HANDOFF_INFO_TABLE *HobList; | |
UINTN SecStackBase; | |
UINTN SecStackSize; | |
EFI_PEI_FILE_HANDLE FileHandle = NULL; | |
DEBUG (( | |
DEBUG_INFO, | |
"%a(): TempRAM Base: 0x%x, TempRAM Size: 0x%x\n", | |
__func__, | |
TempRamBase, | |
SizeOfRam | |
)); | |
SecStackSize = SIZE_16KB; | |
SecStackBase = TempRamBase + SizeOfRam - SecStackSize; | |
// | |
// Initialize floating point operating environment | |
// to be compliant with UEFI spec. | |
// | |
InitializeFloatingPointUnits (); | |
// | |
// Setup the default exception handlers | |
// | |
Status = InitializeCpuExceptionHandlers (NULL); | |
ASSERT_EFI_ERROR (Status); | |
DEBUG (( | |
DEBUG_INFO, | |
"%a() BFV Base: 0x%p, StackBase: 0x%x, StackSize: 0x%x\n", | |
__func__, | |
BootFirmwareVolume, | |
SecStackBase, | |
SecStackSize | |
)); | |
// | |
// Declare the temporary memory region | |
// | |
HobList = HobConstructor ( | |
(VOID *)(UINTN)TempRamBase, | |
SizeOfRam, | |
(VOID *)(UINTN)TempRamBase, | |
(VOID *)SecStackBase | |
); | |
PrePeiSetHobList (HobList); | |
BuildStackHob (SecStackBase, SecStackSize); | |
// | |
// Initialize platform devices | |
// | |
SecPlatformMain (NULL); | |
// | |
// Process all libraries constructor function linked to SecMain. | |
// | |
ProcessLibraryConstructorList (); | |
// | |
// Decompress BFV first | |
// | |
Status = FfsFindNextFile ( | |
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, | |
(EFI_PEI_FV_HANDLE)BootFirmwareVolume, | |
&FileHandle | |
); | |
ASSERT_EFI_ERROR (Status); | |
Status = FfsProcessFvFile (FileHandle); | |
ASSERT_EFI_ERROR (Status); | |
// | |
// Load the DXE Core and transfer control to it | |
// | |
Status = LoadDxeCoreFromFv (NULL, 0); | |
ASSERT_EFI_ERROR (Status); | |
// | |
// Should not come here. | |
// | |
UNREACHABLE (); | |
} | |
#endif /* RISCVVIRT_PEI_BOOTING */ | |
/** | |
Entry point to the C language phase of SEC for this platform. After the SEC assembly | |
code has initialized some temporary memory and set up the stack, | |
the control is transferred to this function. | |
@param BootHartId The hardware thread (Hart) ID of the current CPU. | |
@param DeviceTreeAddress Address of the device tree provided to the SEC phase. | |
@param TempRamBase Base address of the temporary memory. | |
@param TempRamSize Size of the temporary memory region. | |
**/ | |
VOID | |
NORETURN | |
EFIAPI | |
SecStartupPlatform ( | |
IN UINTN BootHartId, | |
IN VOID *DeviceTreeAddress, | |
IN UINT32 TempRamBase, | |
IN UINT32 TempRamSize | |
) | |
{ | |
SEC_HOBLIST_DATA *SecHobList; | |
DEBUG (( | |
DEBUG_INFO, | |
"%a() BootHartId: 0x%x, DeviceTreeAddress=0x%p\n", | |
__func__, | |
BootHartId, | |
DeviceTreeAddress | |
)); | |
// | |
// Set hob list data that will be passed to PEI | |
// | |
SecHobList = (SEC_HOBLIST_DATA *)GetSecHobData (); | |
SecHobList->SecHandoffData.BootHartId = BootHartId; | |
SecHobList->SecHandoffData.FdtPointer = DeviceTreeAddress; | |
TempRamSize -= SEC_HANDOFF_DATA_RESERVE_SIZE; | |
#ifdef RISCVVIRT_PEI_BOOTING | |
SecStartup (TempRamSize, TempRamBase, (VOID *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase)); | |
#else | |
// Default PEIless booting | |
SecPEIlessStartup (TempRamSize, TempRamBase, (VOID *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase)); | |
#endif | |
// | |
// Should not come here. | |
// | |
UNREACHABLE (); | |
} | |
/** | |
A developer supplied function to perform platform specific operations. | |
It's a developer supplied function to perform any operations appropriate to a | |
given platform. It's invoked just before passing control to PEI/DXE core by SEC | |
core. Platform developer may modify the SecCoreData passed to PEI Core. | |
It returns a platform specific PPI list that platform wishes to pass to PEI core. | |
The Generic SEC core module will merge this list to join the final list passed to | |
PEI core. | |
@param SecCoreData The same parameter as passing to PEI core. It | |
could be overridden by this function. | |
@return The platform specific PPI list to be passed to PEI core or | |
NULL if there is no need of such platform specific PPI list. | |
**/ | |
EFI_PEI_PPI_DESCRIPTOR * | |
EFIAPI | |
SecPlatformMain ( | |
IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData | |
) | |
{ | |
SEC_HOBLIST_DATA *SecHobList; | |
const EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID; | |
SecHobList = (SEC_HOBLIST_DATA *)GetSecHobData (); | |
if (SecCoreData == NULL) { | |
// | |
// PEIless booting, initializing platform devices now | |
// | |
SetBootMode (BOOT_WITH_FULL_CONFIGURATION); | |
MemoryInitialization (SecHobList->SecHandoffData.FdtPointer); | |
CpuInitialization (SecHobList->SecHandoffData.FdtPointer); | |
PlatformInitialization (SecHobList->SecHandoffData.FdtPointer); | |
// | |
// Pass Sec Hob data to DXE | |
// | |
BuildGuidDataHob (&SecHobDataGuid, &SecHobList->SecHandoffData, sizeof (SecHobList->SecHandoffData)); | |
return NULL; | |
} | |
// | |
// Public our PEI PPI | |
// | |
return &mPpiSecHobData; | |
} | |
/** | |
This interface conveys state information out of the Security (SEC) phase into PEI. | |
@param PeiServices Pointer to the PEI Services Table. | |
@param StructureSize Pointer to the variable describing size of the input buffer. | |
@param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. | |
@retval EFI_SUCCESS The data was successfully returned. | |
@retval EFI_BUFFER_TOO_SMALL The buffer was too small. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
SecPlatformInformation ( | |
IN CONST EFI_PEI_SERVICES **PeiServices, | |
IN OUT UINT64 *StructureSize, | |
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord | |
) | |
{ | |
// | |
// Not available for RISC-V | |
// | |
return EFI_SUCCESS; | |
} | |
/** | |
This interface disables temporary memory in SEC Phase. | |
**/ | |
VOID | |
EFIAPI | |
SecPlatformDisableTemporaryMemory ( | |
VOID | |
) | |
{ | |
// | |
// Not available | |
// | |
} | |
EFI_STATUS | |
EFIAPI | |
RiscVSecGetHobData ( | |
IN CONST EFI_SEC_HOB_DATA_PPI *This, | |
OUT EFI_HOB_GENERIC_HEADER **HobList | |
) | |
{ | |
SEC_HOBLIST_DATA *SecHobList; | |
const EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID; | |
SecHobList = (SEC_HOBLIST_DATA *)GetSecHobData (); | |
SecHobList->HobGuidHeader.Header.HobType = EFI_HOB_TYPE_GUID_EXTENSION; | |
SecHobList->HobGuidHeader.Header.HobLength = sizeof (SecHobList->HobGuidHeader) + sizeof (SecHobList->SecHandoffData); | |
SecHobList->HobGuidHeader.Header.Reserved = 0; | |
CopyGuid (&(SecHobList->HobGuidHeader.Name), &SecHobDataGuid); | |
SecHobList->HobEnd.HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; | |
SecHobList->HobEnd.HobLength = sizeof (SecHobList->HobEnd); | |
SecHobList->HobEnd.Reserved = 0; | |
*HobList = (EFI_HOB_GENERIC_HEADER *)&(SecHobList->HobGuidHeader); | |
return EFI_SUCCESS; | |
} |