/**@file Build up platform processor information of SiFive U54 core. Copyright (c) 2019 - 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include // // The Library classes this module consumes // #include #include #include #include #include #include #include #include #include #include /** Function to build core specific information HOB for U54 or E51 core. @param ParentProcessorGuid Parent processor of this core. ParentProcessorGuid could be the same as CoreGuid if one processor has only one core. @param ParentProcessorUid Unique ID of pysical processor which owns this core. @param HartId Hart ID of this core. @param IsBootHart TRUE means this is the boot HART. @param IsManagementCore TRUE means this is for the E51 management core, not U54 @param GuidHobData Pointer to RISC_V_PROCESSOR_SPECIFIC_HOB_DATA. @return EFI_SUCCESS The PEIM initialized successfully. EFI_UNSUPPORTED HART is ignored by platform. EFI_NOT_FOUND Processor specific data hob is not available. **/ EFI_STATUS EFIAPI CreateU54E51CoreProcessorSpecificDataHob ( IN EFI_GUID *ParentProcessorGuid, IN UINTN ParentProcessorUid, IN UINTN HartId, IN BOOLEAN IsBootHart, IN BOOLEAN IsManagementCore, OUT RISC_V_PROCESSOR_SPECIFIC_HOB_DATA **GuidHobData ) { RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *CoreGuidHob; EFI_GUID *ProcessorSpecDataHobGuid; RISC_V_PROCESSOR_SPECIFIC_HOB_DATA ProcessorSpecDataHob; EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext; EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific; DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); if (GuidHobData == NULL) { return EFI_INVALID_PARAMETER; } SbiGetFirmwareContext (&FirmwareContext); ASSERT (FirmwareContext != NULL); if (FirmwareContext == NULL) { DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT of hart %d\n", HartId)); return EFI_NOT_FOUND; } DEBUG ((DEBUG_INFO, " Firmware Context is at 0x%x.\n", FirmwareContext)); FirmwareContextHartSpecific = FirmwareContext->HartSpecific[HartId]; DEBUG ((DEBUG_INFO, " Firmware Context Hart specific is at 0x%x.\n", FirmwareContextHartSpecific)); if (FirmwareContextHartSpecific == NULL) { DEBUG ((DEBUG_INFO, " This hart: %d is ignored by platform.\n", HartId)); return EFI_UNSUPPORTED; } // // Build up RISC_V_PROCESSOR_SPECIFIC_HOB_DATA. // CommonFirmwareContextHartSpecificInfo ( FirmwareContextHartSpecific, ParentProcessorGuid, ParentProcessorUid, (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid), HartId, IsBootHart, &ProcessorSpecDataHob ); ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_L = TO_BE_FILLED; ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_H = TO_BE_FILLED; ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_L = TO_BE_FILLED; ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_H = TO_BE_FILLED; ProcessorSpecDataHob.ProcessorSpecificData.HartXlen = RegisterLen64; ProcessorSpecDataHob.ProcessorSpecificData.MachineModeXlen = RegisterLen64; ProcessorSpecDataHob.ProcessorSpecificData.UserModeXlen = RegisterLen64; if (IsManagementCore) { // Configuration for E51 ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen = RegisterUnsupported; } else { // Configuration for U54 ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen = RegisterLen64; } DebugPrintHartSpecificInfo (&ProcessorSpecDataHob); // // Build GUID HOB for core, this is for SMBIOS type 44 // ProcessorSpecDataHobGuid = PcdGetPtr (PcdProcessorSpecificDataGuidHobGuid); CoreGuidHob = (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *)BuildGuidDataHob (ProcessorSpecDataHobGuid, (VOID *)&ProcessorSpecDataHob, sizeof (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA)); if (CoreGuidHob == NULL) { DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core.\n")); ASSERT (FALSE); } *GuidHobData = CoreGuidHob; return EFI_SUCCESS; } /** Function to build cache related SMBIOS information. RISC-V SMBIOS DXE driver collects this information and builds SMBIOS Type 7 record. The caller can adjust the allocated hob data to their needs. @param ProcessorUid Unique ID of physical processor which owns this core. @param L1CacheDataHobPtr Pointer to allocated HOB data. **/ VOID EFIAPI CreateU54SmbiosType7L1DataHob ( IN UINTN ProcessorUid, OUT RISC_V_PROCESSOR_TYPE7_HOB_DATA **L1CacheDataHobPtr ) { EFI_GUID *GuidPtr; RISC_V_PROCESSOR_TYPE7_HOB_DATA L1CacheDataHob; // // Build up SMBIOS type 7 L1 cache record. // ZeroMem((VOID *)&L1CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); L1CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid)); L1CacheDataHob.ProcessorUid = ProcessorUid; L1CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR; L1CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \ RISC_V_CACHE_CONFIGURATION_LOCATION_INTERNAL | \ RISC_V_CACHE_CONFIGURATION_ENABLED | \ RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN; L1CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR; L1CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR; L1CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1; L1CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1; L1CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR; L1CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR; L1CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified; L1CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR; GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid); *L1CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&L1CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); if (L1CacheDataHobPtr == NULL) { DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC Coreplex L1 cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); ASSERT (FALSE); } } /** Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collects this information and builds SMBIOS Type 4 record. The caller can adjust the allocated hob data to their needs. @param ProcessorUid Unique ID of physical processor which owns this core. @param ProcessorDataHobPtr Pointer to allocated HOB data. **/ VOID EFIAPI CreateU54SmbiosType4DataHob ( IN UINTN ProcessorUid, OUT RISC_V_PROCESSOR_TYPE4_HOB_DATA **ProcessorDataHobPtr ) { EFI_GUID *GuidPtr; RISC_V_PROCESSOR_TYPE4_HOB_DATA ProcessorDataHob; // // Build up SMBIOS type 4 record. // ZeroMem((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); ProcessorDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid)); ProcessorDataHob.ProcessorUid = ProcessorUid; ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor; ProcessorDataHob.SmbiosType4Processor.ProcessorFamily = ProcessorFamilyIndicatorFamily2; ProcessorDataHob.SmbiosType4Processor.ProcessorManufacturer = TO_BE_FILLED_BY_VENDOR; SetMem ((VOID *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE); ProcessorDataHob.SmbiosType4Processor.ProcessorVersion = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapability3_3V = 1; ProcessorDataHob.SmbiosType4Processor.ExternalClock = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.MaxSpeed = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.CurrentSpeed = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE; ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff; ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE; ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.PartNumber = TO_BE_FILLED_BY_VENDOR; ProcessorDataHob.SmbiosType4Processor.CoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported); ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported); ProcessorDataHob.SmbiosType4Processor.ThreadCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported); ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics = (UINT16)(1 << 2); // 64-bit capable ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 = ProcessorFamilyRiscVRV64; ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0; ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0; ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0; GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid); *ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); if (ProcessorDataHobPtr == NULL) { DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_TYPE4_HOB_DATA.\n")); ASSERT (FALSE); } }