/** @file Platform PEI driver Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Glossary: - Mem - Memory **/ // // The package level header files this module uses // #include // // The Library classes this module consumes // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Platform.h" STATIC EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { { EfiReservedMemoryType, 0x004 }, { EfiRuntimeServicesData, 0x024 }, { EfiRuntimeServicesCode, 0x030 }, { EfiBootServicesCode, 0x180 }, { EfiBootServicesData, 0xF00 }, { EfiMaxMemoryType, 0x000 } }; // // Module globals // CONST EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiPeiMasterBootModePpiGuid, NULL }; STATIC EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION; /** Create system type memory range hand off block. @param MemoryBase memory base address. @param MemoryLimit memory length. @return VOID **/ STATIC VOID AddMemoryBaseSizeHob ( EFI_PHYSICAL_ADDRESS MemoryBase, UINT64 MemorySize ) { BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED, MemoryBase, MemorySize ); } /** Create memory range hand off block. @param MemoryBase memory base address. @param MemoryLimit memory length. @return VOID **/ VOID AddMemoryRangeHob ( EFI_PHYSICAL_ADDRESS MemoryBase, EFI_PHYSICAL_ADDRESS MemoryLimit ) { AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); } STATIC VOID SaveRtcRegisterAddressHob ( UINT64 RtcRegisterBase ) { UINT64 Data64; // // Build location of RTC register base address buffer in HOB // Data64 = (UINT64)(UINTN)RtcRegisterBase; BuildGuidDataHob ( &gRtcRegisterBaseAddressHobGuid, (VOID *)&Data64, sizeof (UINT64) ); } /** Create memory type information hand off block. @param VOID @return VOID **/ STATIC VOID MemMapInitialization ( VOID ) { DEBUG ((DEBUG_INFO, "==%a==\n", __func__)); // // Create Memory Type Information HOB // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); } /** Get the Rtc base address from the DT. This function fetches the node referenced in the "loongson,ls7a-rtc" property of the "reg" node and returns the base address of the RTC. @param [in] Fdt Pointer to a Flattened Device Tree (Fdt). @param [out] RtcBaseAddress If success, contains the base address of the Rtc. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND RTC info not found in DT. @retval EFI_INVALID_PARAMETER Invalid parameter. **/ STATIC EFI_STATUS EFIAPI GetRtcAddress ( IN CONST VOID *Fdt, OUT UINT64 *RtcBaseAddress ) { INT32 Node; INT32 Prev; CONST CHAR8 *Type; INT32 Len; CONST UINT64 *RegProp; EFI_STATUS Status; if ((Fdt == NULL) || (fdt_check_header (Fdt) != 0)) { return EFI_INVALID_PARAMETER; } Status = EFI_NOT_FOUND; for (Prev = 0; ; Prev = Node) { Node = fdt_next_node (Fdt, Prev, NULL); if (Node < 0) { break; } // // Check for memory node // Type = fdt_getprop (Fdt, Node, "compatible", &Len); if ((Type) && (AsciiStrnCmp (Type, "loongson,ls7a-rtc", Len) == 0)) { // // Get the 'reg' property of this node. For now, we will assume // two 8 byte quantities for base and size, respectively. // RegProp = fdt_getprop (Fdt, Node, "reg", &Len); if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) { *RtcBaseAddress = SwapBytes64 (RegProp[0]); Status = RETURN_SUCCESS; DEBUG ((DEBUG_INFO, "%a Len %d RtcBase %llx\n", __func__, Len, *RtcBaseAddress)); break; } else { DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT rtc node\n", __func__)); break; } } } return Status; } /** Misc Initialization. @param VOID @return VOID **/ STATIC VOID MiscInitialization ( VOID ) { CPUCFG_REG1_INFO_DATA CpucfgReg1Data; UINT8 CpuPhysMemAddressWidth; DEBUG ((DEBUG_INFO, "==%a==\n", __func__)); // // Get the the CPU physical memory address width. // AsmCpucfg (CPUCFG_REG1_INFO, &CpucfgReg1Data.Uint32); CpuPhysMemAddressWidth = (UINT8)(CpucfgReg1Data.Bits.PALEN + 1); // // Creat CPU HOBs. // BuildCpuHob (CpuPhysMemAddressWidth, FixedPcdGet8 (PcdPrePiCpuIoSize)); } /** add fdt hand off block. @param VOID @return VOID **/ STATIC VOID AddFdtHob ( VOID ) { VOID *Base; VOID *NewBase; UINTN FdtSize; UINTN FdtPages; UINT64 *FdtHobData; UINT64 RtcBaseAddress; RETURN_STATUS Status; Base = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); ASSERT (Base != NULL); Status = GetRtcAddress (Base, &RtcBaseAddress); if (RETURN_ERROR (Status)) { return; } SaveRtcRegisterAddressHob (RtcBaseAddress); FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding); FdtPages = EFI_SIZE_TO_PAGES (FdtSize); NewBase = AllocatePages (FdtPages); ASSERT (NewBase != NULL); fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages)); FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData); ASSERT (FdtHobData != NULL); *FdtHobData = (UINTN)NewBase; } /** Fetch the size of system memory from QEMU. @param VOID @return VOID **/ STATIC VOID ReportSystemMemorySize ( VOID ) { UINT64 RamSize; QemuFwCfgSelectItem (QemuFwCfgItemRamSize); RamSize = QemuFwCfgRead64 (); DEBUG (( DEBUG_INFO, "%a: QEMU reports %dM system memory\n", __func__, RamSize/1024/1024 )); } /** Perform Platform PEI initialization. @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. @return EFI_SUCCESS The PEIM initialized successfully. **/ EFI_STATUS EFIAPI InitializePlatform ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_MEMORY_DESCRIPTOR *MemoryTable; DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n")); Status = PeiServicesSetBootMode (mBootMode); ASSERT_EFI_ERROR (Status); Status = PeiServicesInstallPpi (&mPpiListBootMode); ASSERT_EFI_ERROR (Status); ReportSystemMemorySize (); PublishPeiMemory (); PeiFvInitialization (); InitializeRamRegions (); MemMapInitialization (); Status = PlatformHookSerialPortInitialize (); ASSERT_EFI_ERROR (Status); MiscInitialization (); AddFdtHob (); // // Initialization MMU // GetMemoryMapPolicy (&MemoryTable); Status = ConfigureMemoryManagementUnit (MemoryTable); ASSERT_EFI_ERROR (Status); MpInitLibInitialize (); return EFI_SUCCESS; }