| /** @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; | |
| } |