blob: 26e58bf196d24b2490823fd051c700f45b9dc9af [file] [log] [blame]
/** @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;
}