/** @file Source code file for S3 DXE module Copyright (c) 2022, Baruch Binyamin Doron.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include #define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE) /** Get the mem size in memory type information table. @return the mem size in memory type information table. **/ UINT64 EFIAPI GetMemorySizeInMemoryTypeInformation ( VOID ) { EFI_STATUS Status; EFI_MEMORY_TYPE_INFORMATION *MemoryData; UINT8 Index; UINTN TempPageNum; Status = EfiGetSystemConfigurationTable (&gEfiMemoryTypeInformationGuid, (VOID **) &MemoryData); if (EFI_ERROR (Status) || MemoryData == NULL) { return 0; } TempPageNum = 0; for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) { // // Accumulate default memory size requirements // TempPageNum += MemoryData[Index].NumberOfPages; } return TempPageNum * EFI_PAGE_SIZE; } /** Get the mem size need to be consumed and reserved for PEI phase resume. @return the mem size to be reserved for PEI phase resume. **/ UINT64 EFIAPI GetPeiMemSize ( VOID ) { UINT64 Size; Size = GetMemorySizeInMemoryTypeInformation (); return PcdGet32 (PcdPeiMinMemSize) + Size + PEI_ADDITIONAL_MEMORY_SIZE; } /** Allocate EfiACPIMemoryNVS below 4G memory address. This function allocates EfiACPIMemoryNVS below 4G memory address. @param Size Size of memory to allocate. @return Allocated address for output. **/ VOID * EFIAPI AllocateAcpiNvsMemoryBelow4G ( IN UINTN Size ) { UINTN Pages; EFI_PHYSICAL_ADDRESS Address; EFI_STATUS Status; VOID *Buffer; Pages = EFI_SIZE_TO_PAGES (Size); Address = 0xffffffff; Status = gBS->AllocatePages ( AllocateMaxAddress, EfiACPIMemoryNVS, Pages, &Address ); ASSERT_EFI_ERROR (Status); Buffer = (VOID *)(UINTN)Address; ZeroMem (Buffer, Size); return Buffer; } /** Allocates memory to use on S3 resume. @param[in] ImageHandle Not used. @param[in] SystemTable General purpose services available to every DXE driver. @retval EFI_SUCCESS The function completes successfully @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database **/ EFI_STATUS EFIAPI S3DxeEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINTN S3PeiMemSize; UINTN S3PeiMemBase; ACPI_S3_MEMORY S3MemoryInfo; EFI_STATUS Status; DEBUG ((DEBUG_INFO, "%a() Start\n", __func__)); S3PeiMemSize = (UINTN) GetPeiMemSize (); S3PeiMemBase = (UINTN) AllocateAcpiNvsMemoryBelow4G (S3PeiMemSize); ASSERT (S3PeiMemBase != 0); S3MemoryInfo.S3PeiMemBase = (EFI_PHYSICAL_ADDRESS) S3PeiMemBase; S3MemoryInfo.S3PeiMemSize = (UINT64) S3PeiMemSize; DEBUG ((DEBUG_INFO, "S3PeiMemBase: 0x%x\n", S3PeiMemBase)); DEBUG ((DEBUG_INFO, "S3PeiMemSize: 0x%x\n", S3PeiMemSize)); Status = gRT->SetVariable ( ACPI_S3_MEMORY_NV_NAME, &gEfiAcpiVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof (S3MemoryInfo), &S3MemoryInfo ); ASSERT_EFI_ERROR (Status); DEBUG ((DEBUG_INFO, "%a() End\n", __func__)); return EFI_SUCCESS; }