diff options
Diffstat (limited to 'Core/EM/S3')
-rw-r--r-- | Core/EM/S3/AcpiPeiS3Func.c | 141 | ||||
-rw-r--r-- | Core/EM/S3/AcpiPeiS3Func.h | 83 | ||||
-rw-r--r-- | Core/EM/S3/AcpiS3Save.c | 468 | ||||
-rw-r--r-- | Core/EM/S3/AcpiS3Save.dxs | 70 | ||||
-rw-r--r-- | Core/EM/S3/AcpiS3Wake.asm | 339 | ||||
-rw-r--r-- | Core/EM/S3/BootScriptExecuter.c | 1053 | ||||
-rw-r--r-- | Core/EM/S3/BootScriptPrivate.h | 732 | ||||
-rw-r--r-- | Core/EM/S3/BootScriptSave.c | 2540 | ||||
-rw-r--r-- | Core/EM/S3/S3Restore.cif | 15 | ||||
-rw-r--r-- | Core/EM/S3/S3Restore.mak | 88 | ||||
-rw-r--r-- | Core/EM/S3/S3Restore.sdl | 25 | ||||
-rw-r--r-- | Core/EM/S3/S3Resume.c | 582 | ||||
-rw-r--r-- | Core/EM/S3/S3Resume.dxs | 85 | ||||
-rw-r--r-- | Core/EM/S3/S3Save.cif | 14 | ||||
-rw-r--r-- | Core/EM/S3/S3Save.mak | 99 | ||||
-rw-r--r-- | Core/EM/S3/S3Save.sdl | 25 | ||||
-rw-r--r-- | Core/EM/S3/S3Support.cif | 12 | ||||
-rw-r--r-- | Core/EM/S3/S3Support.sdl | 9 | ||||
-rw-r--r-- | Core/EM/S3/SmmS3Save.dxs | 70 |
19 files changed, 6450 insertions, 0 deletions
diff --git a/Core/EM/S3/AcpiPeiS3Func.c b/Core/EM/S3/AcpiPeiS3Func.c new file mode 100644 index 0000000..966ddcb --- /dev/null +++ b/Core/EM/S3/AcpiPeiS3Func.c @@ -0,0 +1,141 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.c 2 7/19/11 11:34a Oleksiyy $ +// +// $Revision: 2 $ +// +// $Date: 7/19/11 11:34a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.c $ +// +// 2 7/19/11 11:34a Oleksiyy +// [TAG] EIP64108 +// [Category] Improvement +// [Description] ACPI, convert or update all eModules to be compliant +// with PI 1.2, and UEFI 2.3.1 specifications. +// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs, +// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c +// +// 1 2/03/11 4:09p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Restore.cif +// S3Restore.sdl +// S3Restore.mak +// S3Resume.dxs +// AcpiS3Wake.asm +// S3Resume.c +// AcpiPeiS3Func.c +// AcpiPeiS3Func.h +// BootScriptExecuter.c +// +// 7 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 6 4/29/08 4:38p Felixp +// Bug fix in GetAcpiS3Info: Initialize AcpiVariableSet variable with NULL +// to make sure there is no junk in the high 4 bytes in x64 mode. +// +// 5 4/15/08 9:15p Yakovlevs +// Functions Headers added + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: AcpiPeiS3Func.c +// +// Description: ACPI S3 PEI support functions +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <EFI.h> +#include <Pei.h> +#include <Ppi\ReadOnlyVariable2.h> +#include <AmiPeiLib.h> +#include "AcpiS3.h" + +CHAR16 gAcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE; +EFI_GUID gEfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID; + +extern EFI_GUID gEfiPeiReadOnlyVariable2PpiGuid; + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetAcpiS3Info +// +// Description: +// This function reads ACPI_VARIABLE_SET data from NVRAM and returns pointer to it +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices - pointer to pointer to PEI services +// +// Output: +// ACPI_VARIABLE_SET* - pointer to ACPI_VARIABLE_SET structure (NULL if error occured) +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +ACPI_VARIABLE_SET * GetAcpiS3Info( + IN EFI_PEI_SERVICES **PeiServices +) +{ + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + ACPI_VARIABLE_SET *AcpiVariableSet = NULL; + + UINTN VariableSize = sizeof(ACPI_VARIABLE_SET*); + EFI_STATUS Status; + + Status = (*PeiServices)->LocatePpi( + PeiServices, + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + &ReadOnlyVariable + ); + ASSERT_PEI_ERROR(PeiServices, Status); + + Status = ReadOnlyVariable->GetVariable( + ReadOnlyVariable, + gAcpiGlobalVariable, + &gEfiAcpiVariableGuid, + NULL, + &VariableSize, + &AcpiVariableSet + ); + if (EFI_ERROR(Status)) return NULL; + return AcpiVariableSet; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + diff --git a/Core/EM/S3/AcpiPeiS3Func.h b/Core/EM/S3/AcpiPeiS3Func.h new file mode 100644 index 0000000..5afbf84 --- /dev/null +++ b/Core/EM/S3/AcpiPeiS3Func.h @@ -0,0 +1,83 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.h 1 2/03/11 4:09p Oleksiyy $ +// +// $Revision: 1 $ +// +// $Date: 2/03/11 4:09p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.h $ +// +// 1 2/03/11 4:09p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Restore.cif +// S3Restore.sdl +// S3Restore.mak +// S3Resume.dxs +// AcpiS3Wake.asm +// S3Resume.c +// AcpiPeiS3Func.c +// AcpiPeiS3Func.h +// BootScriptExecuter.c +// +// 3 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 2 8/22/05 4:06p Markw +// Removed get cpu info. +// +// 1 5/06/05 1:44p Markw +// +//********************************************************************** + +#ifndef __ACPI_PEI_S3_FUNC_H__ +#define __ACPI_PEI_S3_FUNC_H__ + +#include <Efi.h> +#include "AcpiS3.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +ACPI_VARIABLE_SET * GetAcpiS3Info( + IN EFI_PEI_SERVICES **PeiServices +); + + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/S3/AcpiS3Save.c b/Core/EM/S3/AcpiS3Save.c new file mode 100644 index 0000000..944c6f5 --- /dev/null +++ b/Core/EM/S3/AcpiS3Save.c @@ -0,0 +1,468 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.c 8 7/11/14 11:36a Oleksiyy $ +// +// $Revision: 8 $ +// +// $Date: 7/11/14 11:36a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.c $ +// +// 8 7/11/14 11:36a Oleksiyy +// [TAG] EIP175962 +// [Category] Improvement +// [Description] Memory allocation logic made more clear. +// [Files] AcpiS3Save.c +// +// 7 7/01/14 4:13p Oleksiyy +// [TAG] EIP175962 +// [Category] Improvement +// [Description] Memory type for AcpiGlobalVariable changed to Reserved to +// prevent OS from restoring it on thertain scenarious. +// [Files] AcpiS3Save.c +// +// 6 6/05/14 3:22p Oleksiyy +// [TAG] EIP165196 +// [Category] Improvement +// [Description] Previous check in updated with better logic. +// [Files] AcpiS3Save.c +// +// 5 6/03/14 6:13p Oleksiyy +// [TAG] EIP165196 +// [Category] Improvement +// [Description] Taken care of case when BIOS will be updated with +// preserved NVRAM and AcpiGlobalVariable will still has runtime attribute +// [Files] AcpiS3Save.c +// +// 4 4/22/14 3:35p Oleksiyy +// [TAG] EIP165196 +// [Category] Improvement +// [Description] Runtime attribute removed when setting +// AcpiGlobalVariable. +// [Files] AcpiS3Save.c +// +// 3 7/19/11 11:32a Oleksiyy +// [TAG] EIP64108 +// [Category] Improvement +// [Description] ACPI, convert or update all eModules to be compliant +// with PI 1.2, and UEFI 2.3.1 specifications. +// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs, +// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c +// +// 2 4/15/11 5:53p Oleksiyy +// [TAG] EIP58481 +// [Category] Improvement +// [Description] AllocatePages used instead of AllocatePool to make +// AcpiMemoryBase aligned on 4KB boundary +// [Files] AcpiS3Save.c +// +// 1 2/03/11 4:08p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Save.cif +// S3Save.sdl +// S3Save.mak +// AcpiS3.h +// AcpiS3Save.c +// BootScriptPrivate.h +// BootScriptSave.c +// AcpiS3Save.dxs +// SmmS3Save.dxs +// +// 19 4/28/10 2:49p Oleksiyy +// EIP 35563 Added logic to handle only ACPI 1.1 case in saving FACS. +// +// 18 5/18/09 10:41a Yakovlevs +// Changed token name from S3_BASE_MEMORY to S3_BASE_MEMORY_SIZE for +// better token meaning. +// +// 17 4/28/09 6:02p Markw +// EIP #16665 - Unable to allocate enough memory in S3. Added allocation +// of base + memory per cpu. +// +// 16 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 15 10/06/08 2:06p Yakovlevs +// Added NUM_S3_PAGES_RESERVED token support +// +// 14 4/15/08 9:14p Yakovlevs +// Functions Headers added +// +// 13 4/09/08 5:13p Yakovlevs +// Make S3Save code remember all possible locations of FACS. +// +// 12 4/23/07 1:31p Felixp +// Boot Script related code moved from Core to ACPI module. +// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver. +// +// 11 10/13/06 12:29a Felixp +// UEFI2.0 compliance: use CreateReadyToBootEvent instead of +// CreateEvent(READY_TO_BOOT) +// +// 10 9/18/06 6:51p Markw +// Fix AcpiGlobalVariable Size below 4GB. +// +// 9 8/24/06 3:00p Felixp +// x64 support (warnings/errors fixed) +// +// 7 8/22/05 4:05p Markw +// Removed IDT saving to CPU. +// +// 6 7/20/05 3:35p Girim +// Fix for S3 Resume. +// +// 5 5/31/05 6:05p Markw +// Number of pages reported to PEI S3 resume and reserved for windows +// different. Added a #define, so are the same. +// +// 4 5/31/05 10:26a Markw +// Changed reserving ACPI memory from 32k to 128k. +// +// 3 5/04/05 12:24p Markw +// Moved structure definitions to AcpiS3.h. +// +// 2 4/29/05 3:26p Markw +// +// 1 4/29/05 12:17p Sivagarn +// +// 5 4/22/05 2:45p Markw +// Only save S3 Resume Info once. +// +// 4 3/31/05 11:00a Markw +// Storing the FACS table for S3 resume is working. +// +// 3 3/30/05 2:56p Markw +// Added getting ACPI FACS table. +// +// 2 3/24/05 5:40p Markw +// + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: AcpiS3Save.c +// +// Description: ACPI S3 support functions +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <Efi.h> +#include <Dxe.h> +#include <Hob.h> +#include <Protocol\BootScriptSave.h> +#include <Protocol\MpService.h> +#include <AmiDxeLib.h> +#include <Acpi20.h> +#include "AcpiS3.h" +#include <token.h> + +EFI_BOOT_SCRIPT_SAVE_PROTOCOL *gBootScriptSave; +EFI_MP_SERVICES_PROTOCOL *gMpServices; +CHAR16 gAcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE; + +EFI_GUID gAcpi20TableGuid = ACPI_20_TABLE_GUID; +EFI_GUID gAcpi11TAbleGuid = ACPI_10_TABLE_GUID; +EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID; +EFI_GUID gEfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID; +EFI_GUID gHobListGuid = HOB_LIST_GUID; +EFI_GUID gEfiMpServicesGuid = EFI_MP_SERVICES_PROTOCOL_GUID; + +//Declaration of Boot Script Save module initializarion routine +EFI_STATUS InitBootScript( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetAcpiFacsTable +// +// Description: +// This function returns address of memory where FACS ACPI table resides +// +// Input: +// VOID +// +// Output: +// EFI_PHYSICAL_ADDRESS - address of FACS table +// +// Notes: +// The routine may fail if the FACS table is in a different location for +// ACPI 1.0 and ACPI 2.0 (e.g. 1 above 4G and 1 below 4G). WIN98 will read the +// RSDT, and WINXP will read the XSDT. If the XSDT and RSDT aren't pointing to +// the same tables, a S3 resume failure will occur. +// Currently, the variable from Intel only supports one FACS table. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID GetAcpiFacsTable(EFI_PHYSICAL_ADDRESS *FacsTable) +{ + RSDT_PTR_20 *RSDP = NULL; + RSDT_20 *RSDT = NULL; + XSDT_20 *XSDT = NULL; + FACP_20 *FADT = 0; + UINT32 i; + BOOLEAN Ver1 = FALSE; + + // Initialize each pointer to 0 + for (i = 0; i < 3; i++) FacsTable[i] = 0; + + RSDP = GetEfiConfigurationTable(pST,&gAcpi20TableGuid); + if (!RSDP) + { + RSDP = GetEfiConfigurationTable(pST,&gAcpi11TAbleGuid); + Ver1 = TRUE; + } + if (!RSDP) return; + + RSDT = (RSDT_20*)RSDP->RsdtAddr; // 32-bit pointer table + if (!Ver1) XSDT = (XSDT_20*)RSDP->XsdtAddr; // 64-bit pointer table. + + // Get XSDT FACS Pointers + if (XSDT) { + UINT32 NumPtrs = (XSDT->Header.Length - sizeof(ACPI_HDR)) / 8; + for(i = 0; i < NumPtrs; ++i) { + if (((ACPI_HDR*)XSDT->Ptrs[i])->Signature == 'PCAF') { + FADT = (FACP_20*)XSDT->Ptrs[i]; + FacsTable[0] = (EFI_PHYSICAL_ADDRESS)FADT->X_FIRMWARE_CTRL; + FacsTable[1] = (EFI_PHYSICAL_ADDRESS)FADT->FIRMWARE_CTRL; + break; + } + } + } + + // Get RSDT FACS Pointer + if (RSDT) { + UINT32 NumPtrs = (RSDT->Header.Length - sizeof(ACPI_HDR)) / 4; + for(i = 0; i < NumPtrs; ++i) { + if (((ACPI_HDR*)RSDT->Ptrs[i])->Signature == 'PCAF') { + FADT = (FACP_20*)RSDT->Ptrs[i]; + FacsTable[2] = (EFI_PHYSICAL_ADDRESS)FADT->FIRMWARE_CTRL; + break; + } + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CallbackReadyToBoot +// +// Description: +// This function will be called when ReadyToBoot event will be signaled and +// will update data, needed for S3 resume control flow. +// +// Input: +// IN EFI_EVENT Event - signalled event +// IN VOID *Context - calling context +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID CallbackReadyToBoot( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_HOB_RESOURCE_DESCRIPTOR *ResDescHob; + ACPI_VARIABLE_SET *AcpiVariableSet; + EFI_PHYSICAL_ADDRESS AcpiMemoryBase; + EFI_PHYSICAL_ADDRESS ScriptAddress; + UINT64 SystemMemoryLength; + VOID *FirstHob; + EFI_STATUS Status; + UINTN NumCpus = 1; + EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF; + + static BOOLEAN S3ResumeInfo = FALSE; + if (S3ResumeInfo) return; + + //Get number of CPUs. + Status = pBS->LocateProtocol( + &gEfiMpServicesGuid, + NULL, + &gMpServices + ); + ASSERT_EFI_ERROR(Status); + if (!EFI_ERROR(Status)) { +#if PI_SPECIFICATION_VERSION < 0x0001000A || BACKWARD_COMPATIBLE_MODE && defined(NO_PI_MP_SERVICES_SUPPORT) + Status = gMpServices->GetGeneralMPInfo( + gMpServices, &NumCpus, NULL, NULL, NULL, NULL + ); +#else + UINTN NumEnCpus; + Status = gMpServices->GetNumberOfProcessors( + gMpServices, &NumCpus, &NumEnCpus + ); +#endif + + ASSERT_EFI_ERROR(Status); + } + + Status = pBS->AllocatePages( + AllocateMaxAddress, + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES(sizeof(ACPI_VARIABLE_SET)), + &MaxAddress + ); + + ASSERT_EFI_ERROR(Status); + + AcpiVariableSet = (VOID*)(UINTN)MaxAddress; + + pBS->SetMem(AcpiVariableSet, sizeof(ACPI_VARIABLE_SET),0); + + Status = pBS->LocateProtocol( + &gEfiBootScriptSaveGuid, + NULL, + &gBootScriptSave + ); + ASSERT_EFI_ERROR(Status); + + Status = gBootScriptSave->CloseTable( + gBootScriptSave, + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + &ScriptAddress); + ASSERT_EFI_ERROR(Status); + + // Allocate ACPI reserved memory for S3 resume. + Status = pBS->AllocatePages ( + AllocateAnyPages, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES(S3_BASE_MEMORY_SIZE + S3_MEMORY_SIZE_PER_CPU * NumCpus), + &AcpiMemoryBase + ); + + ASSERT_EFI_ERROR(Status); + + // Calculate the system memory length by memory hobs + SystemMemoryLength = 0x100000; + + FirstHob = GetEfiConfigurationTable(pST,&gHobListGuid); + if (!FirstHob) ASSERT_EFI_ERROR(EFI_NOT_FOUND); + + ResDescHob = (EFI_HOB_RESOURCE_DESCRIPTOR*) FirstHob; + + //Find APIC ID Hob. + while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,&ResDescHob))) + { + if (ResDescHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) + { + if (ResDescHob->PhysicalStart >= 0x100000) + SystemMemoryLength += ResDescHob->ResourceLength; + } + } + if (SystemMemoryLength == 0x100000) ASSERT_EFI_ERROR(EFI_NOT_FOUND); + + AcpiVariableSet->AcpiReservedMemoryBase = (EFI_PHYSICAL_ADDRESS)AcpiMemoryBase; + AcpiVariableSet->AcpiReservedMemorySize = S3_BASE_MEMORY_SIZE + S3_MEMORY_SIZE_PER_CPU * (UINT32)NumCpus; + AcpiVariableSet->AcpiBootScriptTable = (EFI_PHYSICAL_ADDRESS) ScriptAddress; + AcpiVariableSet->SystemMemoryLength = SystemMemoryLength; + GetAcpiFacsTable(&AcpiVariableSet->AcpiFacsTable[0]); + + Status = pRS->SetVariable( + gAcpiGlobalVariable, + &gEfiAcpiVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(UINT32), + &AcpiVariableSet + ); + //In case BIOS was updated with preserved NVRAM and AcpiGlobalVariable still has runtime attribute + if (Status == EFI_INVALID_PARAMETER) + { + Status = pRS->SetVariable( + gAcpiGlobalVariable, + &gEfiAcpiVariableGuid, + 0, + 0, + NULL + ); + ASSERT_EFI_ERROR(Status); + + Status = pRS->SetVariable( + gAcpiGlobalVariable, + &gEfiAcpiVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(UINT32), + &AcpiVariableSet + ); + } + + ASSERT_EFI_ERROR(Status); + + S3ResumeInfo = TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: AcpiS3SaveEntryPoint +// +// Description: +// This function is ACPI S3 driver entry point +// +// Input: +// IN EFI_HANDLE ImageHandle - Image handle +// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table +// +// Output: +// EFI_SUCCESS - Function executed successfully +// +// Notes: +// This function also creates ReadyToBoot event to save data +// needed for S3 resume control flow. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS AcpiS3SaveEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + InitAmiLib(ImageHandle,SystemTable); + + //Initialize Boot Script Save module + Status = InitBootScript(ImageHandle,SystemTable); + + return Status; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/S3/AcpiS3Save.dxs b/Core/EM/S3/AcpiS3Save.dxs new file mode 100644 index 0000000..5aa1806 --- /dev/null +++ b/Core/EM/S3/AcpiS3Save.dxs @@ -0,0 +1,70 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.dxs 1 2/03/11 4:08p Oleksiyy $ +// +// $Revision: 1 $ +// +// $Date: 2/03/11 4:08p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.dxs $ +// +// 1 2/03/11 4:08p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Save.cif +// S3Save.sdl +// S3Save.mak +// AcpiS3.h +// AcpiS3Save.c +// BootScriptPrivate.h +// BootScriptSave.c +// AcpiS3Save.dxs +// SmmS3Save.dxs +// +// 3 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 2 4/24/07 6:27p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: AcpiS3Save.dxs +// +// Description: Dependency expression for the AcpiS3Save component +// +//<AMI_FHDR_END> +//********************************************************************** +DEPENDENCY_START + TRUE +DEPENDENCY_END +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/S3/AcpiS3Wake.asm b/Core/EM/S3/AcpiS3Wake.asm new file mode 100644 index 0000000..642e5d5 --- /dev/null +++ b/Core/EM/S3/AcpiS3Wake.asm @@ -0,0 +1,339 @@ +;********************************************************************** +;********************************************************************** +;** ** +;** (C)Copyright 1985-2009, American Megatrends, Inc. ** +;** ** +;** All Rights Reserved. ** +;** ** +;** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +;** ** +;** Phone: (770)-246-8600 ** +;** ** +;********************************************************************** +;********************************************************************** + +;********************************************************************** +; $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiS3Wake.asm 1 2/03/11 4:09p Oleksiyy $ +; +; $Revision: 1 $ +; +; $Date: 2/03/11 4:09p $ +;********************************************************************** +; Revision History +; ---------------- +; $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiS3Wake.asm $ +; +; 1 2/03/11 4:09p Oleksiyy +; [TAG] EIP53402 +; [Category] Improvement +; [Description] Create new label of ACPI with separate S3 Functionality +; [Files] S3Restore.cif +; S3Restore.sdl +; S3Restore.mak +; S3Resume.dxs +; AcpiS3Wake.asm +; S3Resume.c +; AcpiPeiS3Func.c +; AcpiPeiS3Func.h +; BootScriptExecuter.c +; +; 9 3/26/09 4:51p Oleksiyy +; New ACPI Core implementation - improves logic, execution time and +; memory usage of ACPI module. +; +; 8 4/29/08 5:36p Yakovlevs +; +; 7 4/15/08 12:28p Markw +; Add cs overrides. Option rom may change ds. +; +; 6 1/23/07 4:24p Markw +; Added thunk support for a call for S3 video repost. +; +; 5 5/27/05 4:18p Markw +; Added comment. +; +; 4 5/10/05 3:00p Markw +; Corrected wakeup vector address. Uses 16 bit data selector and adjusts +; base of data selector to pointer to wake up vector. +; +; 3 5/09/05 10:19a Markw +; Fixed cs and eip backwards. The OS is now given control. +; +; 2 5/07/05 11:54p Markw +; Goes to real mode. But when resuming to windows cs and ip switched. +; Will fix. +; +; 1 5/06/05 1:44p Markw +; +;********************************************************************** +;<AMI_FHDR_START> +; +; Name: AcpiS3Wake.asm +; +; Description: Provide the thunk S3 resume. +; +;<AMI_FHDR_END> +;********************************************************************** + +.586P +.model small +include token.equ + +ACPI_S3_SEG SEGMENT USE32 'CODE' +assume DS:ACPI_S3_SEG + +public _RealModeThunkStart +public _RealModeThunkSize + +align 16 +;This code may be exexuted + +REAL_MODE_BASE equ (MKF_ACPI_THUNK_REAL_MODE_SEGMENT * 16) + +;<AMI_PHDR_START> +;--------------------------------------------------------------------------- +; +; Procedure: RealModeThunk +; +; Description: Switch to 16-bit to jump/call to an address. +; This may be executed in place for a jump +; or copied to a location if a call. +; +; Input: +; GdtDesc:DWORD -- pointer descriptors with 16-bit. +; JmpAddress: DWORD -- Address to jump or call to. +; IsCall:BYTE -- TRUE - if call. FALSE - if jump. +; +; +; Output: None +;--------------------------------------------------------------------------- +;<AMI_PHDR_END> +REAL_MODE_THUNK_START equ $ +RealModeThunk proc C public, GdtDesc:DWORD, JmpAddress: DWORD, IsCall:BYTE + pushad + call get_base_addr ;push the eip. +get_base_addr: + pop ebx ;ebx = eip. + sub ebx, offset get_base_addr - REAL_MODE_THUNK_START ;ebx = Start address + + cmp IsCall, 0 + je @f + + ;If call, this function will return, so save original state. + ;Save 32 bit stack address of this module. + ;mov [ebx + offset StackSave - REAL_MODE_THUNK_START], esp + db 89h, 0a3h + dd offset StackSave - REAL_MODE_THUNK_START + ;sgdt fword ptr [ebx + offset GdtSave - REAL_MODE_THUNK_START] + db 0fh, 1, 83h + dd offset GdtSave - REAL_MODE_THUNK_START + ;sidt fword ptr [ebx + offset IdtSave - REAL_MODE_THUNK_START] + db 0fh, 1, 8bh + dd offset IdtSave - REAL_MODE_THUNK_START +@@: + +;--Switch to real mode-- + ;lidt fword ptr [ebx + offset LegacyLdtDescriptor - REAL_MODE_THUNK_START] + db 0fh, 1, 9bh + dd offset LegacyLdtDescriptor - REAL_MODE_THUNK_START + + mov edx, GdtDesc ;Get discriptor table with 16-bit descriptors. + mov ecx, [edx + 2] ;ecx = GDT Base + + ;---Set the code selector base address of the memory location + ; to jump to 16-bit protected mode above 1MB for execute in place. + mov eax, offset Next + mov ebx, eax + and eax, 00ffffffh ;eax = [23:00] of next + shr ebx, 24 ;ebx = [31:24] of next + + or [ecx + 8 + 2], eax ;GDT[1] (Code segment) base [23:00] of next + or [ecx + 8 + 7], bl ;GDT[1] base [24:31] of next + + ;---Set the data selector base address of the memory location + ; that contains the location to jump to for thunking. + ; This is so 16-bit protected mode can read the jump address + ; on the caller stack above 1MB. This is needed because the + ; jump code will be executed in place. + ; For call code, this will not do anything useful. + lea edx, JmpAddress + mov ebx, edx + and edx, 00ffffffh ;edx = [23:00] address of wakeup vector + shr ebx, 24 ;ebx = [31:24] address of wakeup vector + + or [ecx + 16 + 2], edx ;GDT[2] (Data segment) base [23:00] of next + or [ecx + 16 + 7], bl ;GDT[2] base [24:31] of next + ;--- + + + xor esp, esp ;esp will be set to a non-zero if a call. + ;This will also to be used to determine + ; if call or not call. This is because + ; IsCall is not available in 16-bit mode. + cmp IsCall, 0 + je @f + + ;Set real mode stack except the linear stack address. + mov esp, REAL_MODE_BASE + MKF_ACPI_THUNK_STACK_TOP + + ;------------------------------------------------- + ;Setup the stack to simulate a int xx or call. + ;------------------------------------------------- + + mov eax, offset ReturnFromPtr + sub eax, REAL_MODE_THUNK_START ;ax = return address. + + ;push the flags and return address to simulate the + ; return address on the stack for int xx or call. + pushf ;push flags in case intxx + push word ptr MKF_ACPI_THUNK_REAL_MODE_SEGMENT + push ax ;ax = return ip + + ;push to stack the cs:ip of the address to call to + push JmpAddress ;push cs:eip to jump to. + + ;------------------------------------------------- + ;Now the stack is setup, so that a retf will jump + ;to the address on stack. + ;------------------------------------------------- + + ;Adjust the stack address, so it will be relative to ss. + sub esp, REAL_MODE_BASE +@@: + + ;---Switch to 16-bit protected mode--- + mov edx, GdtDesc + lgdt fword ptr [edx] + + ;ITP doesn't display disassembly correctly until jump to 16 bit code. + mov ax, 10h ;16 bit data segment + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax + + ;jmp 08:next + db 0eah + dd 0 ;offset of next with new selector + dw 08 ;16 bit code selector +next: + ;---16 bit mode. Must use 16 bit instructions from here on.--- + ;------------------------------------------------------------- + + ;---Switch to real mode--- + mov eax, cr0 + and al, 0feh + mov cr0, eax ;switch to real mode + ;---In real mode--- + + db 66h + or esp, esp ;IsCall? + jnz @f + + ;jmp far ptr [0] ;Jump to the address stored in ds:0. + db 0ffh, 2eh ;The descriptor's base is in stack. + dw 0 + ;Does not return. +@@: + + ; jmp REAL_MODE_SEGMENT:real_mode_adr + db 0eah + dw offset real_mode_adr - REAL_MODE_THUNK_START + dw MKF_ACPI_THUNK_REAL_MODE_SEGMENT + +real_mode_adr: + db 8ch, 0c8h ;mov ax, cs + db 8eh, 0d8h ;mov ds, ax + db 8eh, 0c0h ;mov es, ax + db 8eh, 0d0h ;mov ss, ax + db 8eh, 0e0h ;mov fs, ax + db 8eh, 0e8h ;mov gs, ax + + retf ;call JmpAddress on stack. + +ReturnFromPtr: +;--------------End Real Mode operations--------- + + ;--Switch to protected mode-- + + ;mov esp, cs:[offset StackSave - REAL_MODE_THUNK_START] ;Get original stack back. + db 2eh, 66h, 8bh, 26h + dw offset StackSave - REAL_MODE_THUNK_START + + ;lgdt fword ptr cs:[offset GdtSave - REAL_MODE_THUNK_START] + db 2eh, 66h, 0fh, 1, 16h + dw offset GdtSave - REAL_MODE_THUNK_START + + mov eax, cr0 + or al, 1 ;Set PE bit + mov cr0, eax ;Turn on Protected Mode + + ;jmp 10:P32MODE + db 66h, 0eah + dd REAL_MODE_BASE + offset P32Mode - REAL_MODE_THUNK_START + dw 10h +P32Mode:: + mov ax, 08 + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax + + ;lidt fword ptr [REAL_MODE_BASE + offset IdtSave - REAL_MODE_THUNK_START] + db 0fh, 1, 1dh + dd REAL_MODE_BASE + offset IdtSave - REAL_MODE_THUNK_START + popad + ret +RealModeThunk endp + +align 8 + public LegacyLdtDescriptor +LegacyLdtDescriptor label fword + dw 3ffh + dd 0 + +;Note: The following below is only used in a call when this is copied to below 1MB. +;The data below can not be changed when this is executed from ROM. + + public StackSave +StackSave label dword + dd 0 + +align 8 + public GdtSave +GdtSave label fword + dw 0 + dd 0 + +align 8 + public IdtSave +IdtSave label fword + dw 0 + dd 0 + +REAL_MODE_THUNK_END EQU $ + +_RealModeThunkStart label dword + dd REAL_MODE_THUNK_START + +_RealModeThunkSize label dword + dd REAL_MODE_THUNK_END - REAL_MODE_THUNK_START + +ACPI_S3_SEG ENDS +end + +;********************************************************************** +;********************************************************************** +;** ** +;** (C)Copyright 1985-2009, American Megatrends, Inc. ** +;** ** +;** All Rights Reserved. ** +;** ** +;** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +;** ** +;** Phone: (770)-246-8600 ** +;** ** +;********************************************************************** +;********************************************************************** diff --git a/Core/EM/S3/BootScriptExecuter.c b/Core/EM/S3/BootScriptExecuter.c new file mode 100644 index 0000000..35ac423 --- /dev/null +++ b/Core/EM/S3/BootScriptExecuter.c @@ -0,0 +1,1053 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptExecuter.c 2 9/17/13 10:02p Thomaschen $ +// +// $Revision: 2 $ +// +// $Date: 9/17/13 10:02p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptExecuter.c $ +// +// 2 9/17/13 10:02p Thomaschen +// update for ACPI module labeled 47 +// +// 8 12/13/12 12:03p Oleksiyy +// [TAG] EIP109290 +// [Category] Improvement +// [Description] Issues found by CppCheck in ACPI eModule +// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and +// BootScriptExecuter.c +// +// 7 9/29/11 5:05p Oleksiyy +// [TAG] EIP71372 +// [Category] Improvement +// [Description] EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE added. +// [Files] BootScriptExecuter.c and BootScriptSave.c +// +// 6 7/19/11 11:34a Oleksiyy +// [TAG] EIP64108 +// [Category] Improvement +// [Description] ACPI, convert or update all eModules to be compliant +// with PI 1.2, and UEFI 2.3.1 specifications. +// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs, +// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c +// +// 5 6/01/11 10:27a Oleksiyy +// [TAG] EIP56650 +// [Category] New Feature +// [Description] S3 Save State Protocol and S3 Smm Save State Protocol +// backward compatibility improved. +// [Files] BootScriptExecuter.c +// +// 4 5/19/11 10:40a Oleksiyy +// [TAG] EIP60727 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Dispatch opcode invalid +// [RootCause] Dispatch opcode realization was commented out mistakenly. +// [Solution] Commented out code restored. +// [Files] BootScriptExecuter.c +// +// 3 5/13/11 3:23p Oleksiyy +// [TAG] EIP56650 +// [Category] New Feature +// [Description] S3 Save State Protocol and S3 Smm Save State Protocol +// functions added. Support for opcodes introduced in PI 1.2 added. +// [Files] BootScriptCommon.h, BootScriptExecuter.c, +// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h +// +// 2 3/18/11 3:51p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Improving backward computability and architecture. +// [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak, +// S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h, +// S3smmSaveState.h +// +// 2 3/09/11 6:09p Artems +// +// 1 3/09/11 6:09p Artems +// +// 1 2/03/11 4:09p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Restore.cif +// S3Restore.sdl +// S3Restore.mak +// S3Resume.dxs +// AcpiS3Wake.asm +// S3Resume.c +// AcpiPeiS3Func.c +// AcpiPeiS3Func.h +// BootScriptExecuter.c +// +// 11 3/04/10 2:06p Oleksiyy +// EIP 35847: Bug Fix +// +// 10 11/05/09 4:00p Oleksiyy +// EIP 27821 Support for 64 bit operations in Bootscript added. To use +// this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c, x64AsmLib.asm +// files should be updated also. +// +// 9 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 8 10/10/08 8:16p Felixp +// Performance measurement support added +// +// 6 6/06/08 11:54a Felixp +// Performance measurement support added +// +// 5 4/16/08 12:10p Yakovlevs +// fixed compilation issue +// +// 4 4/15/08 9:20p Yakovlevs +// Functions Headers added; Removed definition of EFI_BOOT_SCRIPT WDTH +// +// 3 6/07/07 3:09p Felixp +// +// 2 6/05/07 12:17a Felixp +// Added SmmBus support +// +// 1 4/23/07 1:31p Felixp +// +// 15 12/26/06 2:56p Markw +// Add BootScript Polling. +// +// 14 11/22/06 4:35p Markw +// Move certain Mem/Io write trace statments before instead of after the +// write. This is so if the write causes a hang, it can be seen on serial +// redirection. +// +// 13 9/22/06 6:08p Markw +// 64-bit fix. +// +// 12 3/15/06 2:41p Markw +// +// 11 3/15/06 2:37p Markw +// Fixed bug, used value instead of Mask. +// +// 10 3/13/06 9:51a Felixp +// +// 9 10/09/05 11:25a Felixp +// Performance measurements added. +// +// 8 6/23/05 5:37p Markw +// Added defintions from Boot Script Save Protocol. +// +// 7 6/15/05 4:20p Markw +// Modified dispatch function to pass in PeiServices. +// +// 6 6/06/05 7:49p Felixp +// +// 5 6/06/05 1:26p Felixp +// Usage of CPU I/O and PCI Cfg changed to match PEI CIS 0.91 +// +// 4 5/27/05 1:36a Felixp +// +// 3 5/16/05 3:03p Markw +// Added more trace messages. +// +// 2 4/04/05 2:38p Markw +// Fix write to pci register bug. +// Add temporary trace statements. +// + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: BootScriptExecuter.c +// +// Description: Boot script execution support functions +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <Ppi\BootScriptExecuter.h> +#include <Ppi\CpuIo.h> +#include <Ppi\PciCfg2.h> +#if PI_SPECIFICATION_VERSION>=0x10000 +#include <Ppi\Smbus2.h> +#else +#include <Ppi\Smbus.h> +#endif +#include <Ppi\Stall.h> +#include "BootScriptPrivate.h" +#include <AmiPeiLib.h> + +#if (CORE_REVISION >= 0x5) +#include <BootScriptCommon.h> +#else + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) +//******************************************* +// EFI Save State Script Opcode definitions (PI) +//******************************************* + +#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00 +#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01 +#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02 +#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03 +#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04 +#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05 +#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06 +#define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07 +#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08 + +#define EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE 0x09 +#define EFI_BOOT_SCRIPT_INFORMATION_OPCODE 0x0A +#define EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE 0x0B +#define EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE 0x0C +#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE 0x0D +#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE 0x0E +#define EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE 0x0F +#define EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE 0x10 +#define EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM 0x83 + +#else +//******************************************* +// EFI Boot Script Opcode definitions (Framework) +//******************************************* + +#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00 +#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01 +#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02 +#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03 +#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04 +#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05 +#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06 +#define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07 +#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08 + +#endif +// +// Extensions to boot script definitions +// +//OEM +#ifndef EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM +#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM 0x80 +#endif + +#ifndef EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM +#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM 0x81 +#endif + +#ifndef EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM +#define EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM 0x82 +#endif + + + +#define EFI_BOOT_SCRIPT_TABLE_OPCODE 0xAA +#define EFI_BOOT_SCRIPT_TERMINATE_OPCODE 0xFF + + + +//******************************************* +// EFI_BOOT_SCRIPT_WIDTH +//******************************************* +typedef enum { + EfiBootScriptWidthUint8, + EfiBootScriptWidthUint16, + EfiBootScriptWidthUint32, + EfiBootScriptWidthUint64, + EfiBootScriptWidthFifoUint8, + EfiBootScriptWidthFifoUint16, + EfiBootScriptWidthFifoUint32, + EfiBootScriptWidthFifoUint64, + EfiBootScriptWidthFillUint8, + EfiBootScriptWidthFillUint16, + EfiBootScriptWidthFillUint32, + EfiBootScriptWidthFillUint64, + EfiBootScriptWidthMaximum +} EFI_BOOT_SCRIPT_WIDTH; + +#endif //#if (CORE_REVISION >= 0x5) + +typedef EFI_STATUS (EFIAPI *DISPATCH_ENTRYPOINT_FUNC) ( + IN EFI_HANDLE ImageHandle, + IN VOID* Context +); + + +EFI_GUID gBootScriptExecuterGuid = EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID; +#if PI_SPECIFICATION_VERSION>=0x10000 +EFI_GUID gSmBusGuid = EFI_PEI_SMBUS2_PPI_GUID; +#else +EFI_GUID gSmBusGuid = EFI_PEI_SMBUS_PPI_GUID; +#endif +EFI_GUID gStallGuid = EFI_PEI_STALL_PPI_GUID; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PciRegAdd +// +// Description: Increase the Pci register number by a value. +// +// Input: +// IN UINT64 Address - Pci Address +// IN UINT8 ValueSize - Add value to register. +// +// Output: +// UINT64 New Pci Address. +// +// Notes: +// Here is the control flow of this function: +// 1. Get extended register. +// 2. If extended register, increment it by ValueSize +// else increment the non-extended register. +// 3. Return the Address. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT64 PciRegAdd(UINT64 Address,UINT8 ValueSize) +{ + UINT32 ExtReg; + + ExtReg = (UINT32) (*((UINT32*)&Address +1)); + if (ExtReg) + (*((UINT32*)&Address + 1)) += ValueSize; + + else (*(UINT8*)&Address) = (*(UINT8*)&Address) + ValueSize; + + return Address; +} +#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x0001000A) +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwitchPciCfgPpi +// +// Description: Serchs for PCI_CFG2_PPI with corresponding Segment +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices +// IN UINT16 SegmentSwitchTo + +// +// Output: +// EFI_PEI_PCI_CFG2_PPI* Pointer to Pci Cfg PPI with Segment wanted +// NULL if not found +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_PEI_PCI_CFG2_PPI* SwitchPciCfgPpi( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT16 SegmentSwitchTo + ) +{ + UINT32 i = 0; + EFI_GUID PciCfg2PpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID; + EFI_PEI_PCI_CFG2_PPI *PciCfg2Ppi; + EFI_STATUS Status; + while (TRUE) { + + Status = (**PeiServices).LocatePpi( PeiServices, + &PciCfg2PpiGuid, i, NULL, &PciCfg2Ppi ); + + if ( EFI_ERROR( Status ) ) { + break; + } + + if (PciCfg2Ppi->Segment == SegmentSwitchTo) //We found PPI we need + return PciCfg2Ppi; //return pointer + i++; + } + return NULL; +} +#endif +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ExecuteScript +// +// Description: +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices +// IN EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *This +// IN EFI_PHYSICAL_ADDRESS Address +// IN EFI_GUID *FvFile OPTIONAL +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Locate Ppis: CpuIo PciCfg SmBus. +// 2. If any of the Ppis doesn't exist return EFI_UNSUPPORTED. +// ---Execute table Script--- +// 3. Read Opcode type: +// a. EFI_BOOT_SCRIPT_IO_WRITE_OPCODE +// b. EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE +// etc. +// If TABLE_END_OP_CODE, return EFI_SUCCESS. +// If unknown opcode return EFI_UNSUPPORTED. +// +// 4. Copy the Opcode type to its structure. Structure will be aligned. +// 5. If it has a buffer, get Buffer address in table. +// 6. Get address of in table for next Opcode. +// 7. Call appropriate Ppi for OpCode with parameters from the structure. +// +// Check BootScript spec for better understanding of code. +// Note for writes there are EfiBootScriptWidthUintxx, +// EfiBootScriptWidthFifoUintxx, and EfiBootScriptWidthFillUintxx. +// xx Denotes 8,16,32,or 64(unsupported). +// +// 8. Go to step 3. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ExecuteScript( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *This, + IN EFI_PHYSICAL_ADDRESS Address, + IN EFI_GUID *FvFile OPTIONAL + ) +{ + VOID *TableAddr = (VOID *)(UINTN) Address; + BOOT_SCRIPT_DATA BootScript; + UINT16 Type; + UINT32 AddressCount; + UINT8 ValueSize; + UINT8 Width; + UINT64 Count; + VOID *Buffer; +// UINT32 Value32; + UINT64 Value64; + UINTN i; + + EFI_STATUS Status; + + EFI_PEI_CPU_IO_PPI *CpuIoPpi; + + EFI_PEI_PCI_CFG2_PPI *PciCfgPpi; +#if PI_SPECIFICATION_VERSION>=0x1000A + BOOLEAN Pi12Spec = FALSE; + UINT64 PollDelay; +#endif +#if PI_SPECIFICATION_VERSION>=0x10000 + EFI_PEI_SMBUS2_PPI *SmBusPpi; +#else + EFI_PEI_SMBUS_PPI *SmBusPpi; +#endif + EFI_PEI_STALL_PPI *StallPpi; + + if (FvFile) return EFI_UNSUPPORTED; + if (!Address) return EFI_INVALID_PARAMETER; + + CpuIoPpi = (*PeiServices)->CpuIo; + PciCfgPpi = (*PeiServices)->PciCfg; + + Status = (**PeiServices).LocatePpi ( + PeiServices, + &gSmBusGuid, + 0, + NULL, + &SmBusPpi + ); + if (EFI_ERROR(Status)) return EFI_UNSUPPORTED; + + Status = (**PeiServices).LocatePpi ( + PeiServices, + &gStallGuid, + 0, + NULL, + &StallPpi + ); + if (EFI_ERROR(Status)) return EFI_UNSUPPORTED; + + for(;;) { +#if PI_SPECIFICATION_VERSION>=0x0001000A + PEI_TRACE((TRACE_ALWAYS,PeiServices,"UniqueIndex %x\n", ((BOOT_SCRIPT_INFO_STRUCTURE*) TableAddr)->UniqueIndex)); + TableAddr = (UINT8*) TableAddr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE); +#endif + Type = *(UINT8*) TableAddr + (*((UINT8*) TableAddr + 1) << 8); //In case not aligned if alignment required. + switch(Type&0xff) { + case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_IO)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_IO); + + Width = (UINT8)(BootScript.WrIo.Type >> 8); + ValueSize = 1 << (Width & 3); + Count = BootScript.WrIo.Count; + Buffer = TableAddr; + + AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1); + TableAddr = (UINT8*)TableAddr + AddressCount; + + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Io Write %x=", BootScript.WrIo.Port)); +#ifdef EFI_DEBUG + switch(ValueSize) { + case 1: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer)); + break; + case 2: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer)); + break; + case 4: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer)); + break; + case 8: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer)); + break; + default: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n")); + } +#endif + CpuIoPpi->Io.Write(PeiServices, + CpuIoPpi, + Width, + BootScript.WrIo.Port, + (UINTN)Count, + Buffer); + break; + case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_IO)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_IO); + + Width = (UINT8)((BootScript.WrIo.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported + + CpuIoPpi->Io.Read(PeiServices, + CpuIoPpi, + Width, + BootScript.RwIo.Port, + 1, + &Value64); + + Value64 &= BootScript.RwIo.Mask; + Value64 |= BootScript.RwIo.Value; + + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Io R/Write %x=%x\n", BootScript.WrIo.Port,Value64)); + CpuIoPpi->Io.Write(PeiServices, + CpuIoPpi, + Width, + BootScript.RwIo.Port, + 1, + &Value64); + break; +#if PI_SPECIFICATION_VERSION>=0x0001000A + case EFI_BOOT_SCRIPT_IO_POLL_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_IO_POLL)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_IO_POLL); + PollDelay = Div64(BootScript.IoPoll.Delay, 10, NULL) + 1; // converting x100 ns units to ms, used in stall + PEI_TRACE((TRACE_ALWAYS,PeiServices,"IO Poll Delay %lx *100ns\n", BootScript.IoPoll.Delay)); + Pi12Spec = TRUE; +#endif + case EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM: +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (!Pi12Spec) +#endif + { + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_IO)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_IO); + } + Width = (UINT8)((BootScript.PollIo.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported + + PEI_TRACE((TRACE_ALWAYS,PeiServices, + "Io Poll: Port = %x, Mask = %lx, Result = %lx\n", + BootScript.PollIo.Port, + BootScript.PollIo.Mask, + BootScript.PollIo.Result + )); + + do { + CpuIoPpi->Io.Read(PeiServices, + CpuIoPpi, + Width, + BootScript.PollIo.Port, + 1, + &Value64); + Value64 &= BootScript.PollIo.Mask; +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (Pi12Spec) + { + StallPpi->Stall(PeiServices, StallPpi, 1); + if (--PollDelay == 0) // delay criteria meet + Value64 = BootScript.PollIo.Result; //terminate cycle + } +#endif + } while (Value64 != BootScript.PollIo.Result); +#if PI_SPECIFICATION_VERSION>=0x0001000A + Pi12Spec = FALSE; +#endif + break; + + case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_MEM)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_MEM); + Buffer = TableAddr; + + Width = (UINT8)(BootScript.WrMem.Type >> 8); + ValueSize = 1 << (Width & 3); + Count = BootScript.WrMem.Count; + + AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1); + TableAddr = (UINT8*)TableAddr + AddressCount; + + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Write %lx=", BootScript.WrMem.Address)); +#ifdef EFI_DEBUG + switch(ValueSize) { + case 1: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer)); + break; + case 2: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer)); + break; + case 4: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer)); + break; + case 8: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer)); + break; + default: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n")); + } +#endif + CpuIoPpi->Mem.Write(PeiServices, + CpuIoPpi, + Width, + BootScript.WrMem.Address, + (UINTN)Count, + Buffer); + break; + case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_MEM)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_MEM); + + Width = (UINT8)((BootScript.WrMem.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported + + CpuIoPpi->Mem.Read(PeiServices, + CpuIoPpi, + Width, + BootScript.RwMem.Address, + 1, + &Value64); + + Value64 &= BootScript.RwMem.Mask; + Value64 |= BootScript.RwMem.Value; + + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem R/Write %lx=%x\n", BootScript.WrMem.Address,(UINT32)Value64)); + CpuIoPpi->Mem.Write(PeiServices, + CpuIoPpi, + Width, + BootScript.RwMem.Address, + 1, + &Value64); + break; +#if PI_SPECIFICATION_VERSION>=0x0001000A + case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_MEM_POLL)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_MEM_POLL); + PollDelay = BootScript.MemPoll.LoopTimes + 1; + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Poll Delay %lx \n", BootScript.MemPoll.Delay)); + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Poll Loop Times %lx \n", BootScript.MemPoll.LoopTimes)); + Pi12Spec = TRUE; +#endif + case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM: +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (!Pi12Spec) +#endif + { + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_MEM)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_MEM); + } + Width = (UINT8)((BootScript.PollMem.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported + + PEI_TRACE((TRACE_ALWAYS,PeiServices, + "Mem Poll: Address = %lx, Mask = %lx, Result = %lx\n", + BootScript.PollMem.Address, + BootScript.PollMem.Mask, + BootScript.PollMem.Result + )); + + do { + CpuIoPpi->Mem.Read(PeiServices, + CpuIoPpi, + Width, + BootScript.PollMem.Address, + 1, + &Value64); + + Value64 &= BootScript.PollMem.Mask; +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (Pi12Spec) + { + UINTN Delay = (UINTN)BootScript.MemPoll.Delay; + + StallPpi->Stall(PeiServices, StallPpi, Delay); + if (--PollDelay == 0) // delay criteria meet + { + PEI_TRACE((TRACE_ALWAYS, PeiServices, + "Mem Poll: Address = %lx, Mask = %lx, Result = %lx\n", + BootScript.PollMem.Address, BootScript.PollMem.Mask, Value64)); + break; + } + } +#endif + + } while (Value64 != BootScript.PollMem.Result); +#if PI_SPECIFICATION_VERSION>=0x0001000A + Pi12Spec = FALSE; +#endif + break; +#if PI_SPECIFICATION_VERSION>=0x0001000A + case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE); + if (BootScript.WrPci2.Segment != 0) + PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.WrPci2.Segment); + if (PciCfgPpi == NULL) + { + PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.WrPci2.Segment)); + return EFI_UNSUPPORTED; + } + PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Write to Segment %x\n = ", BootScript.WrPci2.Segment)); + Pi12Spec = TRUE; + +#endif + case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE: +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (!Pi12Spec) +#endif + { + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_PCI)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_PCI); + } + Width = (UINT8)(BootScript.WrPci.Type >> 8); + ValueSize = 1 << (Width & 3); + Count = BootScript.WrPci.Count; + + Buffer = TableAddr; + + AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1); + TableAddr = (UINT8*)TableAddr + AddressCount; + + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Pci Write %lx=", BootScript.WrPci.Address)); +#ifdef EFI_DEBUG + switch(ValueSize) { + case 1: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer)); + break; + case 2: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer)); + break; + case 4: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer)); + break; + case 8: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer)); + break; + default: + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n")); + } +#endif + for (i = 0; i < Count; ++i) + { + Status = PciCfgPpi->Write(PeiServices, + PciCfgPpi, + Width & 3, + BootScript.WrPci.Address, + Buffer); + ASSERT_PEI_ERROR(PeiServices, Status); + + switch(Width & ~3) + { + case EfiBootScriptWidthUint8: + Buffer = (UINT8*)Buffer + AddressCount; + BootScript.WrPci.Address = PciRegAdd(BootScript.WrPci.Address,ValueSize); + break; + case EfiBootScriptWidthFifoUint8: + Buffer = (UINT8*)Buffer + AddressCount; + break; + case EfiBootScriptWidthFillUint8: + BootScript.WrPci.Address = PciRegAdd(BootScript.WrPci.Address,ValueSize); + } + } +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (Pi12Spec) + { + Pi12Spec = FALSE; + PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer + } +#endif + break; +#if PI_SPECIFICATION_VERSION>=0x0001000A + case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE); + if (BootScript.RwPci2.Segment != 0) + PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.RwPci2.Segment); + if (PciCfgPpi == NULL) + { + PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.RwPci2.Segment)); + return EFI_UNSUPPORTED; + } + PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Read/Write to Segment %x\n = ", BootScript.RwPci2.Segment)); + Pi12Spec = TRUE; +#endif + case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (!Pi12Spec) +#endif + { + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_PCI)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_PCI); + } + Width = (UINT8)((BootScript.RwPci.Type >> 8) & 3); + + PEI_TRACE((TRACE_ALWAYS,PeiServices,"Pci R/Write %x\n", BootScript.RwPci.Address)); + + Status = PciCfgPpi->Read(PeiServices, + PciCfgPpi, + Width, + BootScript.RwPci.Address, + &Value64 + ); + ASSERT_PEI_ERROR(PeiServices, Status); + + Value64 = BootScript.RwPci.Value | (Value64 & BootScript.RwPci.Mask); + + Status = PciCfgPpi->Write(PeiServices, + PciCfgPpi, + Width, + BootScript.RwPci.Address, + &Value64 + ); + ASSERT_PEI_ERROR(PeiServices, Status); +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (Pi12Spec) + { + Pi12Spec = FALSE; + PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer + } +#endif + break; +#if PI_SPECIFICATION_VERSION>=0x0001000A + case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_POLL)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_POLL); + if (BootScript.PciPoll2.Segment != 0) + PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.PciPoll2.Segment); + if (PciCfgPpi == NULL) + { + PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.PciPoll2.Segment)); + return EFI_UNSUPPORTED; + } + PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Poll to Segment %x\n = ", BootScript.PciPoll2.Segment)); + Pi12Spec = TRUE; + + case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: + if (!Pi12Spec) + { + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG_POLL)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG_POLL); + Pi12Spec = TRUE; + } + PollDelay = Div64(BootScript.PciPoll.Delay, 10, NULL) + 1; // converting x100 ns units to ms, used in stall + PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg Poll Delay %lx *100ns\n", BootScript.PciPoll.Delay)); +#endif + case EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM: +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (!Pi12Spec) +#endif + { + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_PCI)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_PCI); + } + Width = (UINT8)((BootScript.PollPci.Type >> 8) & 3); + + PEI_TRACE((TRACE_ALWAYS,PeiServices, + "PCI Poll: Address = %x, Mask = %lx, Result = %lx\n", + BootScript.PollPci.Address, + BootScript.PollPci.Mask, + BootScript.PollPci.Result + )); + + do { + PciCfgPpi->Read(PeiServices, + PciCfgPpi, + Width, + BootScript.PollPci.Address, + &Value64 + ); + Value64 &= BootScript.PollPci.Mask; +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (Pi12Spec) + { + StallPpi->Stall(PeiServices, StallPpi, 1); + if (--PollDelay == 0) // delay criteria meet + Value64 = BootScript.PollPci.Result; //terminate cycle + } +#endif + } while (Value64 != BootScript.PollPci.Result); +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (Pi12Spec) + { + Pi12Spec = FALSE; + PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer + } +#endif + break; + + case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_SMBUS_EXECUTE)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_SMBUS_EXECUTE); + Buffer = TableAddr; + TableAddr = (UINT8*)TableAddr + BootScript.ExecSmbus.Length; + + PEI_TRACE((-1,PeiServices, + "Smbus: Address = %x, Command = %x Operation = %x\n", + BootScript.ExecSmbus.SlaveAddress, + BootScript.ExecSmbus.Command, + BootScript.ExecSmbus.Operation + )); + + //Note: In specification, the length pointer is a IN/OUT. + //However, I do find that its contents updated. + SmBusPpi->Execute( +#if PI_SPECIFICATION_VERSION<0x10000 + PeiServices, +#endif + SmBusPpi, + BootScript.ExecSmbus.SlaveAddress, + BootScript.ExecSmbus.Command, + BootScript.ExecSmbus.Operation, + BootScript.ExecSmbus.PecCheck, + (UINTN*)&BootScript.ExecSmbus.Length, + Buffer + ); + break; + + case EFI_BOOT_SCRIPT_STALL_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_STALL)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_STALL); + + StallPpi->Stall(PeiServices, + StallPpi, + (UINTN)BootScript.Stall.Duration); + break; + + case EFI_BOOT_SCRIPT_DISPATCH_OPCODE: + PEI_TRACE((-1,PeiServices,"Dispatch Opcode.\n")); + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_DISPATCH)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_DISPATCH); + ((DISPATCH_ENTRYPOINT_FUNC)(UINTN)BootScript.Dispatch.EntryPoint)(NULL, PeiServices); + break; + +#if PI_SPECIFICATION_VERSION>=0x0001000A + + case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE: + MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_DISPATCH2)); + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_DISPATCH2); + ((DISPATCH_ENTRYPOINT_FUNC)(UINTN)BootScript.Dispatch.EntryPoint)(NULL, PeiServices); + break; + + case EFI_BOOT_SCRIPT_INFORMATION_OPCODE: + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_INFORMATION); + PEI_TRACE((-1,PeiServices,"Skipping Information opcode in Boot Script.\n")); + break; + case EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM: + TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_LABEL) + + ((BOOT_SCRIPT_LABEL*)TableAddr)->Size; + PEI_TRACE((-1,PeiServices,"Skipping Label opcode in Boot Script.\n")); + break; + +#endif + case TABLE_END_OP_CODE: + PEI_TRACE((-1,PeiServices,"Table End Found.\n")); + return EFI_SUCCESS; + + + default: + PEI_TRACE((-1,PeiServices,"Boot Script Table Invalid. Type = %x\n", Type)); + return EFI_UNSUPPORTED; + } + } +} + + +EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI gBootScriptExecuterPpi = +{ + ExecuteScript +}; + + +EFI_PEI_PPI_DESCRIPTOR gPpiList = +{ + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gBootScriptExecuterGuid, + &gBootScriptExecuterPpi +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitBootScriptExecuter +// +// Description: Increase the Pci register number by a value. +// +// Input: +// IN EFI_FFS_FILE_HEADER *FfsHeader +// IN EFI_PEI_SERVICES **PeiServices +// +// Output: +// EFI_STATUS +// +// Modified: +// +// Referrals: InstallPpi +// +// Notes: +// Here is the control flow of this function: +// 1. Install Boot Script Executer Ppi. +// 2. Return status of InstallPpi. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InitBootScriptExecuter( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + return (**PeiServices).InstallPpi( + PeiServices, + &gPpiList + ); + +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/S3/BootScriptPrivate.h b/Core/EM/S3/BootScriptPrivate.h new file mode 100644 index 0000000..b3c8c63 --- /dev/null +++ b/Core/EM/S3/BootScriptPrivate.h @@ -0,0 +1,732 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptPrivate.h 2 9/17/13 10:02p Thomaschen $ +// +// $Revision: 2 $ +// +// $Date: 9/17/13 10:02p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptPrivate.h $ +// +// 2 9/17/13 10:02p Thomaschen +// update for ACPI module labeled 47 +// +// 3 7/01/11 10:03a Oleksiyy +// [TAG] EIP62200 +// [Category] Improvement +// [Description] Added #pragma statements to declaration of +// BOOT_SCRIPT_SMBUS_EXECUTE_32 and BOOT_SCRIPT_SMBUS_EXECUTE structures. +// [Files] BootScriptPrivate.c +// +// 2 5/13/11 3:18p Oleksiyy +// [TAG] EIP56650 +// [Category] New Feature +// [Description] S3 Save State Protocol and S3 Smm Save State Protocol +// functions added. Support for opcodes introduced in PI 1.2 added. +// [Files] BootScriptCommon.h, BootScriptExecuter.c, +// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h +// +// 1 2/03/11 4:08p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Save.cif +// S3Save.sdl +// S3Save.mak +// AcpiS3.h +// AcpiS3Save.c +// BootScriptPrivate.h +// BootScriptSave.c +// AcpiS3Save.dxs +// SmmS3Save.dxs +// +// 5 11/05/09 4:00p Oleksiyy +// EIP 27821 Support for 64 bit operations in Bootscript added. +// To use this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c, +// x64AsmLib.asm files should be updated also. +// +// 4 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 3 12/01/08 6:17p Yakovlevs +// Fixed isue with UINTN SMBUS_ADDRESS in PEI UINTN=32bit; in DXE UINTN +// for x64 = 64bit. +// +// 2 4/15/08 9:16p Yakovlevs +// Functions Headers added +// +// 1 4/23/07 1:31p Felixp +// +// 4 12/26/06 2:56p Markw +// Add BootScript Polling. +// +// 3 9/22/06 6:09p Markw +// 64-bit fix. +// +// 2 6/23/05 5:38p Markw +// Remove include from boot script save protocol. +// +// 1 1/21/05 12:01p Felixp +// +// 2 1/18/05 3:22p Felixp +// PrintDebugMessage renamed to Trace +// +// 1 12/22/04 6:19p Admin +// +// 1 12/22/04 6:18p Admin +// +// 3 3/25/04 11:23a Markw +// Remove lib include. +// +// 2 3/23/04 4:57p Felixp +// +// 1 3/04/04 3:52p Markw +// +//********************************************************************** + +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: BootScriptPrivate.h +// +// Description: Boot script auxiliary data structures definitions +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#ifndef __BOOT_SCRIPT_PRIVATE__H__ +#define __BOOT_SCRIPT_PRIVATE__H__ + +#include <efi.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define TABLE_TYPE1(OpCode) (OpCode) +#define TABLE_TYPE2(OpCode, Width) ((OpCode) + ((Width) << 8)) + +#define TABLE_END_OP_CODE 0xff + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_WRITE_IO +// +// Description: Boot script Write IO Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Port UINT16 +// Count UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT16 Port; + UINT64 Count; + //UINT8 Buffer[]; +} BOOT_SCRIPT_WRITE_IO; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_READ_WRITE_IO +// +// Description: Boot script Read-Write IO Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Port UINT16 +// Value UINT32 +// Mask UINT32 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT16 Port; + UINT64 Value; + UINT64 Mask; +} BOOT_SCRIPT_READ_WRITE_IO; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_POLL_IO +// +// Description: Boot script Poll IO Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Port UINT16 +// Mask UINT32 +// Result UINT32 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT16 Port; + UINT64 Mask; + UINT64 Result; +} BOOT_SCRIPT_POLL_IO; + + +////////////////////////////////////////////////////////////////////////// +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_WRITE_MEM +// +// Description: Boot script Write memory Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Value UINT8 +// Count UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; +// UINT8 Value; + UINT64 Count; + //UINT8 Buffer[]; +} BOOT_SCRIPT_WRITE_MEM; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_READ_WRITE_MEM +// +// Description: Boot script Read-Write memory Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Value UINT64 +// Mask UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Value; + UINT64 Mask; +} BOOT_SCRIPT_READ_WRITE_MEM; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_POLL_MEM +// +// Description: Boot script Poll memory Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Mask UINT64 +// Result UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Mask; + UINT64 Result; +} BOOT_SCRIPT_POLL_MEM; + +////////////////////////////////////////////////////////////////////////// +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_WRITE_PCI +// +// Description: Boot script Write PCI Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Count UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Count; + //UINT8 Buffer[]; +} BOOT_SCRIPT_WRITE_PCI; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_READ_WRITE_PCI +// +// Description: Boot script Read-Write PCI Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Value UINT64 +// Mask UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Value; + UINT64 Mask; +} BOOT_SCRIPT_READ_WRITE_PCI; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_POLL_PCI +// +// Description: Boot script Poll PCI Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Mask UINT64 +// Result UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Mask; + UINT64 Result; +} BOOT_SCRIPT_POLL_PCI; + +#pragma pack(push,1) +////////////////////////////////////////////////////////////////////////// +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_SMBUS_EXECUTE +// +// Description: Boot script SMBUS command Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// SlaveAddress EFI_SMBUS_DEVICE_ADDRESS +// Command EFI_SMBUS_DEVICE_COMMAND +// Operation EFI_SMBUS_OPERATION +// PecCheck BOOLEAN +// Length UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_SMBUS_DEVICE_COMMAND Command; + EFI_SMBUS_OPERATION Operation; + BOOLEAN PecCheck; + UINT64 Length; + //UINT8 Buffer[]; +} BOOT_SCRIPT_SMBUS_EXECUTE; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_SMBUS_EXECUTE_32 +// +// Description: Boot script SMBUS command Data (32 Bit) +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// SlaveAddress UINT32 +// Command UINT32 +// Operation EFI_SMBUS_OPERATION +// PecCheck BOOLEAN +// Length UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT32 SlaveAddress; + UINT32 Command; + EFI_SMBUS_OPERATION Operation; + BOOLEAN PecCheck; + UINT64 Length; + //UINT8 Buffer[]; +} BOOT_SCRIPT_SMBUS_EXECUTE_32; +#pragma pack(pop) + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_STALL +// +// Description: Boot script stall Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Duration UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Duration; +} BOOT_SCRIPT_STALL; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_DISPATCH +// +// Description: Boot script dispatch Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// EntryPoint EFI_PHYSICAL_ADDRESS +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + EFI_PHYSICAL_ADDRESS EntryPoint; +} BOOT_SCRIPT_DISPATCH; + +#if PI_SPECIFICATION_VERSION>=0x0001000A +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_INFORMATION +// +// Description: Boot script information Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Size UINT32 +// MessagePtr EFI_PHYSICAL_ADDRESS +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct { + UINT16 Type; + UINT32 Size; + EFI_PHYSICAL_ADDRESS MessagePtr; +} BOOT_SCRIPT_INFORMATION; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_DISPATCH2 +// +// Description: Boot script Dispatch2 Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// EntryPoint EFI_PHYSICAL_ADDRESS +// Context EFI_PHYSICAL_ADDRESS +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct { + UINT16 Type; + EFI_PHYSICAL_ADDRESS EntryPoint; + EFI_PHYSICAL_ADDRESS Context; +} BOOT_SCRIPT_DISPATCH2; + +////////////////////////////////////////////////////////////////////////// +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_PCI_CFG2_WRITE +// +// Description: Boot script Write PCI Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Count UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Count; + UINT16 Segment; + //UINT8 Buffer[]; +} BOOT_SCRIPT_PCI_CFG2_WRITE; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_PCI_CFG2_READ_WRITE +// +// Description: Boot script Read-Write PCI Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Value UINT64 +// Mask UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Value; + UINT64 Mask; + UINT16 Segment; +} BOOT_SCRIPT_PCI_CFG2_READ_WRITE; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_IO_POLL +// +// Description: Boot script Poll IO Data (PI 1.1) +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Port UINT16 +// Mask UINT32 +// Result UINT32 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT16 Port; + UINT64 Mask; + UINT64 Result; + UINT64 Delay; +} BOOT_SCRIPT_IO_POLL; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_MEM_POLL +// +// Description: Boot script Poll memory Data (PI 1.1) +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Mask UINT64 +// Result UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Mask; + UINT64 Result; + UINT64 Delay; + UINT64 LoopTimes; +} BOOT_SCRIPT_MEM_POLL; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_PCI_CFG_POLL +// +// Description: Boot script Poll PCI Data (PI 1.1) +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Mask UINT64 +// Result UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Mask; + UINT64 Result; + UINT64 Delay; +} BOOT_SCRIPT_PCI_CFG_POLL; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_PCI_CFG2_POLL +// +// Description: Boot script Poll PCI Data (PI 1.1) +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Address UINT64 +// Mask UINT64 +// Result UINT64 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; + UINT64 Address; + UINT64 Mask; + UINT64 Result; + UINT64 Delay; + UINT16 Segment; +} BOOT_SCRIPT_PCI_CFG2_POLL; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_LABEL +// +// Description: Boot script information Data +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// Size UINT32 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct { + UINT16 Type; + UINT32 Size; + //UINT8 Buffer[]; +} BOOT_SCRIPT_LABEL; + +typedef struct { + UINT32 UniqueIndex; + UINT32 Length; +} BOOT_SCRIPT_INFO_STRUCTURE; +#endif + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_TABLE_END +// +// Description: Boot script end table marker +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT16 +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef struct { + UINT16 Type; +} BOOT_SCRIPT_TABLE_END; + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: BOOT_SCRIPT_DATA +// +// Description: Boot script data union +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// WrIo BOOT_SCRIPT_WRITE_IO +// RwIo BOOT_SCRIPT_READ_WRITE_IO +// PollIo BOOT_SCRIPT_POLL_IO +// WrMem BOOT_SCRIPT_WRITE_MEM +// RwMem BOOT_SCRIPT_READ_WRITE_MEM +// PollMem BOOT_SCRIPT_POLL_MEM +// WrPci BOOT_SCRIPT_WRITE_PCI +// RwPci BOOT_SCRIPT_READ_WRITE_PCI +// PollPci BOOT_SCRIPT_POLL_PCI +// ExecSmbus BOOT_SCRIPT_SMBUS_EXECUTE +// Stall BOOT_SCRIPT_STALL +// Dispatch BOOT_SCRIPT_DISPATCH +// End BOOT_SCRIPT_TABLE_END +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> + +typedef union { + BOOT_SCRIPT_WRITE_IO WrIo; + BOOT_SCRIPT_READ_WRITE_IO RwIo; + BOOT_SCRIPT_POLL_IO PollIo; + BOOT_SCRIPT_WRITE_MEM WrMem; + BOOT_SCRIPT_READ_WRITE_MEM RwMem; + BOOT_SCRIPT_POLL_MEM PollMem; + BOOT_SCRIPT_WRITE_PCI WrPci; + BOOT_SCRIPT_READ_WRITE_PCI RwPci; + BOOT_SCRIPT_POLL_PCI PollPci; + BOOT_SCRIPT_SMBUS_EXECUTE ExecSmbus; + BOOT_SCRIPT_STALL Stall; + BOOT_SCRIPT_DISPATCH Dispatch; +#if PI_SPECIFICATION_VERSION>=0x0001000A + BOOT_SCRIPT_INFORMATION Info; + BOOT_SCRIPT_DISPATCH2 Dispatch2; + BOOT_SCRIPT_PCI_CFG2_WRITE WrPci2; + BOOT_SCRIPT_PCI_CFG2_READ_WRITE RwPci2; + BOOT_SCRIPT_IO_POLL IoPoll; + BOOT_SCRIPT_MEM_POLL MemPoll; + BOOT_SCRIPT_PCI_CFG_POLL PciPoll; + BOOT_SCRIPT_PCI_CFG2_POLL PciPoll2; +#endif + BOOT_SCRIPT_TABLE_END End; +} BOOT_SCRIPT_DATA; + +VOID CallbackReadyToBoot( + IN EFI_EVENT Event, + IN VOID *Context +); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/S3/BootScriptSave.c b/Core/EM/S3/BootScriptSave.c new file mode 100644 index 0000000..46e2bc4 --- /dev/null +++ b/Core/EM/S3/BootScriptSave.c @@ -0,0 +1,2540 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptSave.c 5 7/15/14 9:51p Chienhsieh $ +// +// $Revision: 5 $ +// +// $Date: 7/15/14 9:51p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptSave.c $ +// +// 5 7/15/14 9:51p Chienhsieh +// update for ACPI module labeled 49 +// +// 12 4/14/14 3:10p Oleksiyy +// [TAG] EIP161916 +// [Category] Improvement +// [Description] 32 bit typecasting issue fixed. +// [Files] BootScriptSave.c +// +// 4 9/17/13 10:03p Thomaschen +// update for ACPI module labeled 47 +// +// 11 8/14/13 12:35p Oleksiyy +// [TAG] EIP95347 +// [Category] Improvement +// [Description] Synchronized usage of Allocate/Free memory operations +// on pool/page basis. +// +// [Files] BootScriptSave.c +// +// 10 7/05/13 2:32p Oleksiyy +// [TAG] EIP128054 +// [Category] Improvement +// [Description] USB ports are disabled after resume from S3 with +// special steps +// [Files] BootScriptSave.c +// +// 9 12/27/12 4:00p Oleksiyy +// [TAG] EIP109790 +// [Category] Improvement +// [Description] Code check result - Possible Null pointer acces. +// [Files] BootScriptSave.c +// +// 8 12/13/12 12:03p Oleksiyy +// [TAG] EIP109290 +// [Category] Improvement +// [Description] Issues found by CppCheck in ACPI eModule +// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and +// BootScriptExecuter.c +// +// 7 10/31/12 3:49p Oleksiyy +// [TAG] EIP104782 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Bug in BootScriptSave.c AllocTableEntry() function +// [RootCause] Pointer to ACPI_VARIABLE_SET was not initialized. +// [Solution] Initialize pointer. +// [Files] BootScriptSave.c +// +// 6 12/16/11 4:27p Oleksiyy +// [TAG] EIP78247 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] BootScriptTable problem +// [RootCause] TablePointer was updated uncorectly during CloseTable +// call and any opcodes added after closing was ignored. +// [Solution] Pointer updated correctly now. +// [Files] BootScriptSave.c +// +// 5 9/29/11 5:05p Oleksiyy +// [TAG] EIP71372 +// [Category] Improvement +// [Description] EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE added. +// [Files] BootScriptExecuter.c and BootScriptSave.c +// +// 4 6/16/11 9:57a Felixp +// Bug fix: EFI_BOOT_SCRIPT_PCI_POLL_OPCODE is replaced with +// EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE +// +// 3 5/13/11 4:59p Oleksiyy +// [TAG] EIP56650 +// [Category] Improvement +// [Description] Compatibility with older core fixed. +// [Files] BootScriptSave.c +// +// 2 5/13/11 3:20p Oleksiyy +// [TAG] EIP56650 +// [Category] New Feature +// [Description] S3 Save State Protocol and S3 Smm Save State Protocol +// functions added. Support for opcodes introduced in PI 1.2 added. +// +// [Files] BootScriptCommon.h, BootScriptExecuter.c, +// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h +// +// 1 2/03/11 4:08p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Save.cif +// S3Save.sdl +// S3Save.mak +// AcpiS3.h +// AcpiS3Save.c +// BootScriptPrivate.h +// BootScriptSave.c +// AcpiS3Save.dxs +// SmmS3Save.dxs +// +// 8 1/20/11 12:33p Oleksiyy +// [TAG] EIP48697 +// [Category] Improvement +// [Description] Functionality modified and after Close table is called +// - boot script still added to the end of the table. +// [Files] BootScriptSave.c +// +// 7 11/05/09 4:02p Oleksiyy +// EIP 27821 Support for 64 bit operations in Bootscript added. To use +// this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c, x64AsmLib.asm +// files should be updated also. +// +// 6 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 5 3/26/09 10:10a Oleksiyy +// EIP 20471 : MAX_TABLE_ENTRIES value increased to 2048. +// +// 4 12/01/08 6:52p Yakovlevs +// Fixed BootScript code to support IA32 and x64 CPU Architecture EIP # +// 17317 +// +// 3 4/15/08 9:21p Yakovlevs +// Functions Headers added +// +// 2 6/05/07 12:19a Felixp +// Added SmmBus support +// +// 1 4/23/07 1:31p Felixp +// +// 14 3/21/07 10:53a Markw +// Previous revision over wrote Felix's changes. I put them back. +// +// 13 3/19/07 4:13p Markw +// Update so that PCI functions saving registers 0xfc - 0xff doesn't fail. +// +// 12 2/12/07 11:21a Felixp +// Revision field removed from EFI_BOOT_SCRIPT_SAVE_PROTOCOL structure +// to match BootScript spec (it was earlier their for Tiano compliance. +// Tiano header is fixed now). +// +// 11 12/26/06 2:57p Markw +// Add BootScript Polling. +// +// 10 9/29/06 6:02p Markw +// Fix 64-bit bugs. +// +// 9 9/22/06 6:09p Markw +// 64-bit fix. +// +// 8 8/24/06 10:11a Felixp +// x64 support: warning/error fixes +// +// 7 3/13/06 5:30p Felixp +// +// 6 11/07/05 3:44p Sivagarn +// Included SMBus.H to resolve SMBus related definition errors +// +// 5 6/23/05 5:38p Markw +// Added include to boot script save protocol. Previously was in +// bootscriptprivate.h. +// +// 4 5/13/05 3:19p Markw +// UINT32 -> UINT64 sometimes causes sign extend. Clear bits[64:32] for +// address. +// +// 3 3/23/05 2:53p Markw +// Bug fixes: Pointers, TableLength +// +// 2 3/14/05 4:25p Markw +// Change final memory allocation to Runtime Service Data to ACPI NVS. +// +//********************************************************************** + + +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: BootScriptSave.c +// +// Description: Save Mem/Io/Pci/Smbus/etc into a table. The script will +// be executed on a S3 resume. +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> +#if PI_SPECIFICATION_VERSION>=0x0001000A +#include <Protocol\S3SaveState.h> +#include <Protocol\S3SmmSaveState.h> +#include <Protocol\SmmBase2.h> +#endif +#include <Protocol\BootScriptSave.h> +#include <Protocol\smbus.h> +#include "BootScriptPrivate.h" +#include <AmiDxeLib.h> +#include "AcpiS3.h" +//---For Compatibility Reasons--------------------------------------------------- +#ifndef EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM +#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_IO_POLL_OPCODE +#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_MEM_POLL_OPCODE +#define EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE +#endif +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +// Currently reentrant code could fail if reentered when new table +// is being created. +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +#if PI_SPECIFICATION_VERSION>=0x0001000A +EFI_SMM_SYSTEM_TABLE2 *gSmst2 = NULL; +EFI_SMM_BASE2_PROTOCOL *mInternalSmmBase2 = NULL; +EFI_HANDLE mSmmS3SaveHandle = NULL; +#endif + +EFI_EVENT gEvtReadyToBoot; + +typedef EFI_STATUS (*GENERIC_OPCODE_FUNC) ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list List +); + + +#define INIT_TABLE_SIZE 1024 +#define MAX_TABLE_ENTRIES 2048 +#define TBL_VAR_NAME L"S3SS" + + + +static EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID; +static EFI_GUID gTableDataVarGuid = { 0x4bafc2b4, 0x2dc, 0x4104, 0xb2, 0x36, 0xd6, 0xf1, 0xb9, 0x8d, 0x9e, 0x84}; + + +typedef struct { + VOID *TableBottom; + VOID *TablePtr; + UINTN TableSize; + UINTN NumTableEntries; + BOOLEAN WasClosed; +} TABLE_INFO; + +#if PI_SPECIFICATION_VERSION>=0x0001000A + +typedef struct { + BOOLEAN IsItInsert; + BOOLEAN BeforeOrAfter; + UINTN Position; +} BOOT_SCRIPT_INSERT_INFO; + +BOOT_SCRIPT_INSERT_INFO gInsertInfo = {FALSE, FALSE, 0}; +#define LABEL_MAX_SIZE 0x200 +#endif + +TABLE_INFO *gTableInfo = NULL; + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// Procedure: NewTable +// +// Description: Initialize first table. +// +// Input: +// IN UINT16 Table +// +// Output: +// BOOLEAN - TRUE if new table created. +// +// Notes: +// Return True if successful table creation, otherwise return false. +// Need valid table info even if table fails, because functions may +// attempt to write to the boot script without a table being created. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN NewTable() +{ + EFI_STATUS Status; +//-------------------------------- + + Status = pBS->AllocatePool(EfiBootServicesData, INIT_TABLE_SIZE*2, &(gTableInfo->TableBottom)); + if (EFI_ERROR(Status)) + { + gTableInfo->TableBottom = 0; + return FALSE; + } + gTableInfo->TablePtr = gTableInfo->TableBottom; + gTableInfo->TableSize = INIT_TABLE_SIZE*2; + gTableInfo->NumTableEntries = 0; + gTableInfo->WasClosed = FALSE; + return TRUE; + +} + + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// Procedure: InitBootScriptStructure +// +// Description: Updates Table pointer Before each Write operation. +// +// Input: +// IN UINT16 Table +// +// Output: +// EFI_SATUS - Status of the operation. +// +// Notes: +// Return True if successful table creation, otherwise return false. +// Need valid table info even if table fails, because functions may +// attempt to write to the boot script without a table being created. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InitBootScriptStructure(BOOLEAN IsItSmm) +{ +#if PI_SPECIFICATION_VERSION>=0x0001000A + UINTN sz=sizeof(VOID*); +#endif + EFI_STATUS Status = EFI_SUCCESS; + +//-------------------------------- + if(gTableInfo == NULL) + { +#if PI_SPECIFICATION_VERSION>=0x0001000A + Status = pRS->GetVariable(L"S3SS", &gTableDataVarGuid, NULL, &sz, &gTableInfo); + if(EFI_ERROR(Status) && Status!=EFI_NOT_FOUND && IsItSmm) return EFI_OUT_OF_RESOURCES; + if(Status==EFI_NOT_FOUND) +#endif + { + EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF; + Status = pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType, EFI_SIZE_TO_PAGES(sizeof(TABLE_INFO)), + &MaxAddress); + ASSERT_EFI_ERROR(Status); + if(EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES; + gTableInfo = (VOID*)(UINTN)MaxAddress; + if (!NewTable()) return EFI_OUT_OF_RESOURCES; +#if PI_SPECIFICATION_VERSION>=0x0001000A + Status = pRS->SetVariable(L"S3SS",&gTableDataVarGuid, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), + sz, &gTableInfo); + ASSERT_EFI_ERROR(Status); + if(EFI_ERROR(Status) && IsItSmm) return EFI_OUT_OF_RESOURCES; +#endif + } + + + } + return Status; +} +#if PI_SPECIFICATION_VERSION>=0x0001000A +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// Procedure: InsertPositionInBootScript +// +// Description: Found position and, based on Size, allocate space for Entry, +// that has to be incerted, in table based on parameters in +// gInsertInfo structure. +// +// Input: +// IN UINTN Size - Size of entry to allocate in table. +// +// Output: +// VOID * - Pointer to allocated entry in table. +// +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID* InsertPositionInBootScript (UINTN Size) +{ + TABLE_INFO *Info = gTableInfo; + UINT8 *CopyFrom = Info->TableBottom, *CopyTo; + UINTN i = 0, CopySize = (UINT8*)Info->TablePtr - (UINT8*)Info->TableBottom; + BOOLEAN Found = FALSE; + + if (gInsertInfo.Position != -1) + { + for (i=0; i<Info->NumTableEntries; i++) + { //Found position with supplied + if (((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->UniqueIndex == gInsertInfo.Position) + { + Found = TRUE; + if (gInsertInfo.BeforeOrAfter == FALSE) + CopyFrom += ((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->Length; + break; + } + CopyFrom += ((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->Length; + } + if (!Found) return NULL; + } + if ((Size != 0) && (i != Info->NumTableEntries)) + { + CopyTo = CopyFrom + Size; + CopySize = (UINT8*)Info->TablePtr - CopyFrom; + MemCpy(CopyTo, CopyFrom, CopySize); + } + return CopyFrom; + +} +#endif +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// Procedure: AllocTableEntry +// +// Description: Allocate Entry from table. If not enough space, create +// larger table and return entry. +// +// Input: +// IN UINTN Size - Size of entry to allocate in table. +// +// Output: +// VOID * - Pointer to allocated entry in table. +// +// Notes: +// Here is the control flow of this function: +// 1. Does the BootScript table exist. If no return 0. +// 2. Does table contain max entries? If so assert. +// 3. Enough space in the table for the boot script call? If yes, go to step 8. +// ---Create table--- +// 4. Get Size of table needed for entry. (A multiple of INIT_TABLE_SIZE.) +// 5. Allocate new table. +// 6. Copy old table +// 7. Free old table. +// 8. Update gTableInfo data. +// ------------------ +// 9. Adjust allocation pointer to allocate new space. +// 10. Return newly allocated space. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID * AllocTableEntry(IN UINTN Size) +{ + TABLE_INFO *Info = gTableInfo; + VOID *TempBottom; + VOID *TempPtr; + UINTN TempSize, NewSize; + BOOT_SCRIPT_TABLE_END TableEnd; +#if PI_SPECIFICATION_VERSION>=0x0001000A + //BOOT_SCRIPT_INFO_STRUCTURE BsHeader; + Size += sizeof(BOOT_SCRIPT_INFO_STRUCTURE); +#endif + if (Info->TableBottom == NULL) return NULL; + + //Should not fill table. If table becomes full, then an error is causing too many table entries. + ASSERT(Info->NumTableEntries < MAX_TABLE_ENTRIES); + + if ((UINTN)Info->TableBottom + Info->TableSize < (UINTN) Info->TablePtr + Size + + sizeof(BOOT_SCRIPT_TABLE_END) +#if PI_SPECIFICATION_VERSION>=0x0001000A + + sizeof(BOOT_SCRIPT_INFO_STRUCTURE) +#endif + ) + { +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (gSmst2 != NULL) return NULL; // we can't allocate memory in SMM +#endif + TempSize = Info->TableSize + INIT_TABLE_SIZE * (Size / INIT_TABLE_SIZE + 1); + + if (Info->WasClosed == FALSE) // Use AllocatePool if table was not closed - later it will be copyed under 4 Gb. + { + if (pBS->AllocatePool(EfiBootServicesData, TempSize, &TempBottom) != EFI_SUCCESS) + return NULL; + + NewSize = TempSize; + } + else // Use AllocatePages if table was closed. We need it under 4 Gb. + { + EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF; + + if (pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType, + EFI_SIZE_TO_PAGES(TempSize) + 1, &MaxAddress) != EFI_SUCCESS) + return NULL; + TempBottom = (VOID*)(UINTN)MaxAddress; + NewSize = EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(TempSize) + 1); // Calculate the sieze of new structure from pages + TempSize = EFI_SIZE_TO_PAGES(Info->TableSize); // Save old size in pages to use in FreePages. + } + + MemCpy(TempBottom, Info->TableBottom, Info->TableSize); + + Info->TablePtr = (UINT8*)TempBottom + (UINTN)Info->TablePtr - (UINTN)Info->TableBottom; + TempPtr = Info->TableBottom; // Save old TableBottom to freememory + Info->TableBottom = TempBottom; + Info->TableSize = NewSize; + if (Info->WasClosed == TRUE) + { + EFI_STATUS Status; + ACPI_VARIABLE_SET *AcpiVariableSet = NULL; + CHAR16 AcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE; + EFI_GUID EfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID; + UINTN VariableSize = sizeof(ACPI_VARIABLE_SET*); + Status = pRS->GetVariable( + AcpiGlobalVariable, + &EfiAcpiVariableGuid, + NULL, + &VariableSize, + &AcpiVariableSet + ); + ASSERT_EFI_ERROR(Status); + AcpiVariableSet->AcpiBootScriptTable = (EFI_PHYSICAL_ADDRESS) (UINTN) TempBottom; + pBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) TempPtr, TempSize); // If WasClosed == TRUE use FreePages + } + else pBS->FreePool(TempPtr); // If WasClosed != TRUE use FreePool + + } +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (gInsertInfo.IsItInsert == TRUE) + { + TempPtr = InsertPositionInBootScript (Size); + if (TempPtr == NULL) return TempPtr; + } + else +#endif + TempPtr = (UINT8*)Info->TablePtr; + Info->TablePtr = (UINT8*)Info->TablePtr + Size; +#if PI_SPECIFICATION_VERSION>=0x0001000A + ((BOOT_SCRIPT_INFO_STRUCTURE*)TempPtr)->UniqueIndex = (UINT32) Info->NumTableEntries; + ((BOOT_SCRIPT_INFO_STRUCTURE*)TempPtr)->Length = (UINT32) Size; + TempPtr = (UINT8*) TempPtr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE); +#endif + TableEnd.Type = TABLE_END_OP_CODE; + MemCpy((VOID*)((UINTN)Info->TablePtr +#if PI_SPECIFICATION_VERSION>=0x0001000A + + sizeof(BOOT_SCRIPT_INFO_STRUCTURE) +#endif + ), &TableEnd, sizeof(BOOT_SCRIPT_TABLE_END)); + ++(Info->NumTableEntries); + return TempPtr; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptIoWrite +// +// Description: Write to boot script table an IoWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Add data to end of fixed table. +// 6. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptIoWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + IN va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + + UINT64 Address = va_arg(arglist, UINT64); + UINTN Count = va_arg(arglist, UINTN); + VOID *Buffer = va_arg(arglist, VOID*); + + BOOT_SCRIPT_WRITE_IO WriteIo; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINTN AddressCount; + + AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1); + + //---Validate Inputs--- + if (!Count) return EFI_INVALID_PARAMETER; + if (Address + AddressCount > 0xffff) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_IO) + AddressCount); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + WriteIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,Width); + WriteIo.Port = (UINT16) Address; + WriteIo.Count = Count; + + MemCpy(Ptr, &WriteIo, sizeof(BOOT_SCRIPT_WRITE_IO)); //Use MemCpy to avoid alignment problems. + Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_IO); + + MemCpy(Ptr, Buffer, AddressCount); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptIoReadWrite +// +// Description: Write to boot script table a IoReadWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptIoReadWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataValue = va_arg(arglist, VOID *); + VOID *DataMask = va_arg(arglist, VOID *); + + BOOT_SCRIPT_READ_WRITE_IO ReadWriteIo; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT64 Data, Mask; + + Mask = *(UINT64*)DataMask; + Data = *(UINT64*)DataValue; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + + //---Validate Inputs--- + if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_IO)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + ReadWriteIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE, Width); + ReadWriteIo.Port = (UINT16) Address; + ReadWriteIo.Value = Data & BitMask; + ReadWriteIo.Mask = Mask & BitMask; + + MemCpy(Ptr, &ReadWriteIo, sizeof(ReadWriteIo)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptMemWrite +// +// Description: Write to boot script table an MemWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Add data to end of fixed table. +// 6. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptMemWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + + UINT64 Address = va_arg(arglist, UINT64); + UINTN Count = va_arg(arglist, UINTN); + VOID *Buffer = va_arg(arglist, VOID*); + + BOOT_SCRIPT_WRITE_MEM WriteMem; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINTN AddressCount; + + AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1); + + //---Validate Inputs--- + if (!Count) return EFI_INVALID_PARAMETER; + +#if defined(EFI64) || defined(EFIx64) + if (Address + AddressCount < Address) return EFI_INVALID_PARAMETER; //Overflow +#else + Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends. + if (Address + AddressCount > 0xffffffff) return EFI_INVALID_PARAMETER; + +#endif + + //---Fill and Copy Table--- + Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_MEM) + AddressCount); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + WriteMem.Type = (UINT16)TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,Width); + WriteMem.Address = (UINT64)Address; + WriteMem.Count = Count; + + MemCpy(Ptr, &WriteMem, sizeof(BOOT_SCRIPT_WRITE_MEM)); //Use MemCpy to avoid alignment problems. + Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_MEM); + + MemCpy(Ptr, Buffer, AddressCount); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptMemReadWrite +// +// Description: Write to boot script table an MemReadWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptMemReadWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataValue = va_arg(arglist, VOID *); + VOID *DataMask = va_arg(arglist, VOID *); + + BOOT_SCRIPT_READ_WRITE_MEM ReadWriteMem; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT64 Mask, Data; + + Mask = *(UINT64*)DataMask; + Data = *(UINT64*)DataValue; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + + //---Validate Inputs--- +#if defined(EFI64) || defined(EFIx64) + if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow +#else + Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends. + if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER; + +#endif + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_MEM)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + ReadWriteMem.Type = (UINT16)TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE, Width); + ReadWriteMem.Address = (UINT64)Address; + ReadWriteMem.Value = Data & BitMask; + ReadWriteMem.Mask = Mask & BitMask; + + MemCpy(Ptr, &ReadWriteMem, sizeof(BOOT_SCRIPT_READ_WRITE_MEM)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptPciWrite +// +// Description: Write to boot script table an PciWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Add data to end of fixed table. +// 6. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptPciWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + + UINT64 Address = va_arg(arglist, UINT64); + UINTN Count = va_arg(arglist, UINTN); + VOID *Buffer = va_arg(arglist, VOID*); + + BOOT_SCRIPT_WRITE_PCI WritePci; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINTN AddressCount; + UINT16 Register; + UINT16 RegisterMax; + if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01)) + return EFI_INVALID_PARAMETER; + if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03)) + return EFI_INVALID_PARAMETER; + + AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1); + +#if 0 //<-----For PCI-Express + if (Address & 0xffffffff00000000) //Extended register? + { + if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k + Register = (UINT16) (Address >> 16); + RegisterMax = 0x1000; + } else { +#else + Register = (UINT8) Address; + RegisterMax = 0x100; +#endif +#if 0 + } +#endif + + //---Validate Inputs--- + if (!Count) return EFI_INVALID_PARAMETER; + + if (Register + AddressCount > RegisterMax) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_PCI) + AddressCount); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + WritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,Width); + WritePci.Address = Address; + WritePci.Count = Count; + + MemCpy(Ptr, &WritePci, sizeof(BOOT_SCRIPT_WRITE_PCI)); //Use MemCpy to avoid alignment problems. + Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_PCI); + + MemCpy(Ptr, Buffer, AddressCount); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptPciReadWrite +// +// Description: Write to boot script table an PciReadWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptPciReadWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *Data = va_arg(arglist, VOID *); + VOID *DataMask = va_arg(arglist, VOID *); + + BOOT_SCRIPT_READ_WRITE_PCI ReadWritePci; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT16 Register; + UINT16 RegisterMax; + if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01)) + return EFI_INVALID_PARAMETER; + if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03)) + return EFI_INVALID_PARAMETER; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + +#if 0 //<-----For PCI-Express + if (Address & 0xffffffff00000000) //Extended register? + { + if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k + Register = (UINT16) (Address >> 16); + RegisterMax = 0x1000; + } else { +#else + Register = (UINT8) Address; + RegisterMax = 0x100; +#endif +#if 0 + } +#endif + + //---Validate Inputs--- + if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_PCI)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + ReadWritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE, Width); + ReadWritePci.Address = Address; + ReadWritePci.Value = *(UINT64*) Data & BitMask; + ReadWritePci.Mask = *(UINT64*) DataMask & BitMask; + + MemCpy(Ptr, &ReadWritePci, sizeof(BOOT_SCRIPT_READ_WRITE_PCI)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptSmbusExecute +// +// Description: Write to boot script table an SmbusExecute. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptSmbusExecute ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + VOID *Ptr; + VOID *Buffer; + + BOOT_SCRIPT_SMBUS_EXECUTE_32 Smbus; + + Smbus.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE); + Smbus.SlaveAddress = (UINT32)va_arg(arglist, UINTN); + Smbus.Command = (UINT32)va_arg(arglist, UINTN); + Smbus.Operation = va_arg(arglist, EFI_SMBUS_OPERATION); + Smbus.PecCheck = va_arg(arglist, BOOLEAN); + Smbus.Length = *(va_arg(arglist, UINTN*)); + + Buffer = va_arg(arglist, VOID*); + + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32) + (UINT32)Smbus.Length); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + MemCpy(Ptr, &Smbus, sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32)); //Use MemCpy to avoid alignment problems. + Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32); + + MemCpy(Ptr, Buffer, (UINT32)Smbus.Length); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptStall +// +// Description: Write to boot script table an Stall. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptStall ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + VOID *Ptr; + BOOT_SCRIPT_STALL Stall; + + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_STALL)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + Stall.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_STALL_OPCODE); + Stall.Duration = va_arg(arglist, UINTN); + + MemCpy(Ptr, &Stall, sizeof(BOOT_SCRIPT_STALL)); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptIoPoll +// +// Description: Write to boot script table a IoPoll (OEM specific). +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptIoPoll ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataMask = va_arg(arglist, VOID *); + VOID *DataResult = va_arg(arglist, VOID *); + + BOOT_SCRIPT_POLL_IO PollIo; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT64 Mask, Result; + + Mask = *(UINT64*)DataMask; + Result = *(UINT64*)DataResult; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + + //---Validate Inputs--- + if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_IO)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + PollIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM, Width); + PollIo.Port = (UINT16) Address; + PollIo.Mask = Mask & BitMask; + PollIo.Result = Result & BitMask; + + MemCpy(Ptr, &PollIo, sizeof(BOOT_SCRIPT_POLL_IO)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptMemPoll +// +// Description: Write to boot script table a MemPoll. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptMemPoll ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataMask = va_arg(arglist, VOID *); + VOID *DataResult = va_arg(arglist, VOID *); + + BOOT_SCRIPT_POLL_MEM PollMem; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT64 Mask, Result; + + Mask = *(UINT64*)DataMask; + Result = *(UINT64*)DataResult; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + + //---Validate Inputs--- +#if defined(EFI64) || defined(EFIx64) + if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow +#else + Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends. + if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER; +#endif + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_MEM)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + PollMem.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM, Width); + PollMem.Address = (UINT64)Address; + PollMem.Mask = Mask & BitMask; + PollMem.Result = Result & BitMask; + + MemCpy(Ptr, &PollMem, sizeof(BOOT_SCRIPT_POLL_MEM)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptPciPoll +// +// Description: Write to boot script table an PciPoll. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptPciPoll ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataMask = va_arg(arglist, VOID *); + VOID *DataResult= va_arg(arglist, VOID *); + + BOOT_SCRIPT_POLL_PCI PollPci; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT16 Register; + UINT16 RegisterMax; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + +#if 0 //<-----For PCI-Express + if (Address & 0xffffffff00000000) //Extended register? + { + if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k + Register = (UINT16) (Address >> 16); + RegisterMax = 0x1000; + } else { +#else + Register = (UINT8) Address; + RegisterMax = 0x100; +#endif +#if 0 + } +#endif + + //---Validate Inputs--- + if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER; + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_PCI)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + PollPci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM, Width); + PollPci.Address = Address; + PollPci.Mask = *(UINT64*) DataMask & BitMask; + PollPci.Result = *(UINT64*) DataResult & BitMask; + + MemCpy(Ptr, &PollPci, sizeof(BOOT_SCRIPT_POLL_PCI)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: BootScriptDispatch +// +// Description: Write to boot script table an Dispatch. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BootScriptDispatch ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ +//---------Unsupported by now------------------------ + + VOID *Ptr; + BOOT_SCRIPT_DISPATCH Dispatch; + + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_DISPATCH)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + Dispatch.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_DISPATCH_OPCODE); + Dispatch.EntryPoint = va_arg(arglist, EFI_PHYSICAL_ADDRESS); + + MemCpy(Ptr, &Dispatch, sizeof(BOOT_SCRIPT_DISPATCH)); + + return EFI_SUCCESS; + +// return EFI_UNSUPPORTED; +} +#if PI_SPECIFICATION_VERSION>=0x0001000A +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateDispatch2 +// +// Description: Write to boot script table an Dispatch2. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateDispatch2 ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + VOID *Ptr; + BOOT_SCRIPT_DISPATCH2 Dispatch2; + + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_DISPATCH2)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + Dispatch2.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE); + Dispatch2.EntryPoint = va_arg(arglist, EFI_PHYSICAL_ADDRESS); + Dispatch2.Context = va_arg(arglist, EFI_PHYSICAL_ADDRESS); + + MemCpy(Ptr, &Dispatch2, sizeof(BOOT_SCRIPT_DISPATCH2)); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateInformation +// +// Description: Write to boot script table an Information entry. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateInformation ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + UINT32 InfoSize = va_arg(arglist, UINT32); + EFI_PHYSICAL_ADDRESS InfoBuffer = va_arg(arglist, EFI_PHYSICAL_ADDRESS); + BOOT_SCRIPT_INFORMATION Information; + VOID *Ptr; + + + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_INFORMATION)); + if (Ptr == NULL) return EFI_OUT_OF_RESOURCES; + + Information.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_INFORMATION_OPCODE); + Information.Size = InfoSize; + Information.MessagePtr = InfoBuffer; + + MemCpy(Ptr, &Information, sizeof(BOOT_SCRIPT_INFORMATION)); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStatePciCfg2Write +// +// Description: Write to boot script table an PciWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Add data to end of fixed table. +// 6. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStatePciCfg2Write ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT16 Segment = va_arg(arglist, UINT16); + UINT64 Address = va_arg(arglist, UINT64); + UINTN Count = va_arg(arglist, UINTN); + VOID *Buffer = va_arg(arglist, VOID*); + + BOOT_SCRIPT_PCI_CFG2_WRITE WritePci; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINTN AddressCount; + UINT16 Register; + UINT16 RegisterMax; + if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01)) + return EFI_INVALID_PARAMETER; + if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03)) + return EFI_INVALID_PARAMETER; + + AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1); + +#if 0 //<-----For PCI-Express + if (Address & 0xffffffff00000000) //Extended register? + { + if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k + Register = (UINT16) (Address >> 16); + RegisterMax = 0x1000; + } else { +#else + Register = (UINT8) Address; + RegisterMax = 0x100; +#endif +#if 0 + } +#endif + + //---Validate Inputs--- + if (!Count) return EFI_INVALID_PARAMETER; + + if (Register + AddressCount > RegisterMax) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE) + AddressCount); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + WritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE,Width); + WritePci.Segment = Segment; + WritePci.Address = Address; + WritePci.Count = Count; + + MemCpy(Ptr, &WritePci, sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE)); //Use MemCpy to avoid alignment problems. + Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE); + + MemCpy(Ptr, Buffer, AddressCount); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStatePciCfg2ReadWrite +// +// Description: Write to boot script table an PciReadWrite. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStatePciCfg2ReadWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT16 Segment = va_arg(arglist, UINT16); + UINT64 Address = va_arg(arglist, UINT64); + VOID *Data = va_arg(arglist, VOID *); + VOID *DataMask = va_arg(arglist, VOID *); + + BOOT_SCRIPT_PCI_CFG2_READ_WRITE ReadWritePci; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT16 Register; + UINT16 RegisterMax; + if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01)) + return EFI_INVALID_PARAMETER; + if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03)) + return EFI_INVALID_PARAMETER; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + +#if 0 //<-----For PCI-Express + if (Address & 0xffffffff00000000) //Extended register? + { + if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k + Register = (UINT16) (Address >> 16); + RegisterMax = 0x1000; + } else { +#else + Register = (UINT8) Address; + RegisterMax = 0x100; +#endif +#if 0 + } +#endif + + //---Validate Inputs--- + if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + ReadWritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE, Width); + ReadWritePci.Segment = Segment; + ReadWritePci.Address = Address; + ReadWritePci.Value = *(UINT64*) Data & BitMask; + ReadWritePci.Mask = *(UINT64*) DataMask & BitMask; + + MemCpy(Ptr, &ReadWritePci, sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateIoPoll +// +// Description: Write to boot script table a PI 1.1 IoPoll. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateIoPoll ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataResult = va_arg(arglist, VOID *); + VOID *DataMask = va_arg(arglist, VOID *); + UINT64 Delay = va_arg(arglist, UINT64); + + BOOT_SCRIPT_IO_POLL IoPoll; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT64 Mask, Result; + + Mask = *(UINT64*)DataMask; + Result = *(UINT64*)DataResult; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + + //---Validate Inputs--- + if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER; + + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_IO_POLL)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + IoPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_POLL_OPCODE, Width); + IoPoll.Port = (UINT16) Address; + IoPoll.Mask = Mask & BitMask; + IoPoll.Result = Result & BitMask; + IoPoll.Delay = Delay; + + MemCpy(Ptr, &IoPoll, sizeof(BOOT_SCRIPT_IO_POLL)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateMemPoll +// +// Description: Write to boot script table a MemPoll (PI 1.1). +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateMemPoll ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataMask = va_arg(arglist, VOID *); + VOID *DataResult = va_arg(arglist, VOID *); + UINT64 Delay = va_arg(arglist, UINT64); + UINT64 LoopTimes = va_arg(arglist, UINT64); + + BOOT_SCRIPT_MEM_POLL MemPoll; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT64 Mask, Result; + + Mask = *(UINT64*)DataMask; + Result = *(UINT64*)DataResult; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + + //---Validate Inputs--- +#if defined(EFI64) || defined(EFIx64) + if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow +#else + Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends. + if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER; +#endif + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_MEM_POLL)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + MemPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, Width); + MemPoll.Address = (UINT64)Address; + MemPoll.Mask = Mask & BitMask; + MemPoll.Result = Result & BitMask; + MemPoll.Delay = Delay; + MemPoll.LoopTimes= LoopTimes; + MemCpy(Ptr, &MemPoll, sizeof(BOOT_SCRIPT_MEM_POLL)); //Use MemCpy to avoid alignment problems. + //TRACE((-1,"SaveState Mem poll Mask %lx\n", MemPoll.Mask)); + //TRACE((-1,"SaveState Mem poll Result %lx\n", MemPoll.Result)); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStatePciCfgPoll +// +// Description: Write to boot script table an PciPoll (PI 1.1). +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStatePciCfgPoll ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataResult= va_arg(arglist, VOID *); + VOID *DataMask = va_arg(arglist, VOID *); + UINT64 Delay = va_arg(arglist, UINT64); + + BOOT_SCRIPT_PCI_CFG_POLL PciPoll; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT16 Register; + UINT16 RegisterMax; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + +#if 0 //<-----For PCI-Express + if (Address & 0xffffffff00000000) //Extended register? + { + if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k + Register = (UINT16) (Address >> 16); + RegisterMax = 0x1000; + } else { +#else + Register = (UINT8) Address; + RegisterMax = 0x100; +#endif +#if 0 + } +#endif + + //---Validate Inputs--- + if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER; + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG_POLL)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + PciPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE, Width); + PciPoll.Address = Address; + PciPoll.Mask = *(UINT64*) DataMask & BitMask; + PciPoll.Result = *(UINT64*) DataResult & BitMask; + PciPoll.Delay = Delay; + + MemCpy(Ptr, &PciPoll, sizeof(BOOT_SCRIPT_PCI_CFG_POLL)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStatePciCfg2Poll +// +// Description: Write to boot script table an PciPoll Cfg2 (PI 1.1). +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN va_list arglist +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Get variable argument list from stack. +// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER; +// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES. +// 4. Fill fixed table entries. +// 5. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStatePciCfg2Poll ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + va_list arglist + ) +{ + EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH); + UINT16 Segment = va_arg(arglist, UINT16); + UINT64 Address = va_arg(arglist, UINT64); + VOID *DataResult= va_arg(arglist, VOID *); + VOID *DataMask = va_arg(arglist, VOID *); + UINT64 Delay = va_arg(arglist, UINT64); + + BOOT_SCRIPT_PCI_CFG2_POLL PciPoll2; + VOID *Ptr; + UINT8 ValueSize = (UINT8) (1 << (Width & 3)); + UINT64 BitMask; + UINT16 Register; + UINT16 RegisterMax; + + switch(Width&3) + { + case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break; + case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break; + case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break; + default: BitMask = 0xffffffffffffffff; + } + +#if 0 //<-----For PCI-Express + if (Address & 0xffffffff00000000) //Extended register? + { + if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k + Register = (UINT16) (Address >> 16); + RegisterMax = 0x1000; + } else { +#else + Register = (UINT8) Address; + RegisterMax = 0x100; +#endif +#if 0 + } +#endif + + //---Validate Inputs--- + if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER; + + //---Fill and Copy Table--- + Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG2_POLL)); + if (Ptr == 0) return EFI_OUT_OF_RESOURCES; + + PciPoll2.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE , Width); + PciPoll2.Segment = Segment; + PciPoll2.Address = Address; + PciPoll2.Mask = *(UINT64*) DataMask & BitMask; + PciPoll2.Result = *(UINT64*) DataResult & BitMask; + PciPoll2.Delay = Delay; + + MemCpy(Ptr, &PciPoll2, sizeof(BOOT_SCRIPT_PCI_CFG2_POLL)); //Use MemCpy to avoid alignment problems. + + return EFI_SUCCESS; +} +#endif //#if PI_SPECIFICATION_VERSION>=0x0001000A +GENERIC_OPCODE_FUNC OpCodeFuncs[] = +{ + BootScriptIoWrite, //0 + BootScriptIoReadWrite, //1 + BootScriptMemWrite, //2 + BootScriptMemReadWrite, //3 + BootScriptPciWrite, //4 + BootScriptPciReadWrite, //5 + BootScriptSmbusExecute, //6 + BootScriptStall, //7 + BootScriptDispatch, //8 +#if PI_SPECIFICATION_VERSION>=0x0001000A + SaveStateDispatch2, //9 + SaveStateInformation, //a ->0xA + SaveStatePciCfg2Write, //b ->0xB + SaveStatePciCfg2ReadWrite, //c ->0xC + SaveStateIoPoll, //d + SaveStateMemPoll, //e + SaveStatePciCfgPoll, //f + SaveStatePciCfg2Poll, //10 +#endif +//oem + BootScriptIoPoll, //0x80 -> + BootScriptMemPoll, //0x81 -> + BootScriptPciPoll, //0x82 -> +}; + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: EfiBootScriptWrite +// +// Description: All boot script functions (except close table) call this function. +// This function passes argument list to appropriate function. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN UINT16 OpCode +// ... +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS EfiBootScriptWrite ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + IN UINT16 TableName, + IN UINT16 OpCode, + ... + ) +{ + EFI_STATUS Status; + va_list arglist; + va_start(arglist, OpCode); + + if (TableName != EFI_ACPI_S3_RESUME_SCRIPT_TABLE) + return EFI_INVALID_PARAMETER; + + if (OpCode > 0x82) { + Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE; + } + +#if PI_SPECIFICATION_VERSION>=0x0001000A + if (OpCode > 16 && OpCode < 0x80) {Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;} +#else + if (OpCode > 8 && OpCode < 0x80) {Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;} +#endif + + if (OpCode >= 0x80) + { + OpCode -= (0x80 - 9); +#if PI_SPECIFICATION_VERSION>=0x0001000A + OpCode += 8; +#endif + } + + Status = OpCodeFuncs[OpCode](This, arglist); + +EXIT_BOOT_SCRIPT_WRITE: + va_end(arglist); + return Status; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: EfiBootScriptCloseTable +// +// Description: Save table in runtime closing table and return pointer to table. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// OUT EFI_PHYSICAL_ADDRESS *Address +// +// Output: +// EFI_STATUS +// +// Referrals: +// +// Notes: +// Here is the control flow of this function: +// 1. Allocate table entry for BOOT_SCRIPT_TABLE_END. If no entry, return EFI_OUT_OF_RESOURCES. +// 2. Fill table. +// 3. Allocate space for new table in Runtime. +// 4. Copy table to new table. +// 5. Set *Address to Runtime Table. +// 6. Free old table. +// 7. Create a initial table to start over if more Scripts are added. +// 8. Return EFI_SUCCESS. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS EfiBootScriptCloseTable ( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This, + IN UINT16 TableName, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + TABLE_INFO *Info = gTableInfo; + UINTN TableLength; +//--------------------------------------- + if (TableName != EFI_ACPI_S3_RESUME_SCRIPT_TABLE) + return EFI_INVALID_PARAMETER; + TableLength = (UINTN)Info->TablePtr - (UINTN)Info->TableBottom +#if PI_SPECIFICATION_VERSION>=0x0001000A + + sizeof(BOOT_SCRIPT_INFO_STRUCTURE) +#endif + + (UINTN) sizeof(BOOT_SCRIPT_TABLE_END); + + //Copy to new table. + *Address = 0xFFFFFFFF; + if (pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType, + EFI_SIZE_TO_PAGES(TableLength + INIT_TABLE_SIZE) + 1, Address) != EFI_SUCCESS) + return EFI_OUT_OF_RESOURCES; + + MemCpy((VOID*)(UINTN)*Address,Info->TableBottom, TableLength); + pBS->FreePool(Info->TableBottom); + + //Reasign Table Address; + Info->TableBottom = (VOID*)(UINTN)*Address; + Info->TablePtr = (VOID*)((UINTN) Info->TableBottom + TableLength +#if PI_SPECIFICATION_VERSION>=0x0001000A + - sizeof(BOOT_SCRIPT_INFO_STRUCTURE) +#endif + - (UINTN) sizeof(BOOT_SCRIPT_TABLE_END)); + Info->TableSize = EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(TableLength + INIT_TABLE_SIZE) + 1); + Info->WasClosed = TRUE; + + return EFI_SUCCESS; +} + +EFI_BOOT_SCRIPT_SAVE_PROTOCOL gBootScriptSaveProtocol = +{ + EfiBootScriptWrite, + EfiBootScriptCloseTable +}; + + +//PI 1.1 ++ +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + +VOID ClearInsertInfo() +{ + gInsertInfo.IsItInsert = FALSE; + gInsertInfo.BeforeOrAfter = FALSE; + gInsertInfo.Position = -1; + return; +} +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateWrite +// +// Description: This function is used to store an OpCode to be replayed as part +// of the S3 resume boot path. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN UINT16 OpCode +// ... +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateWrite( + IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This, + IN UINT16 OpCode, + ...) +{ + EFI_STATUS Status=EFI_SUCCESS; + UINTN OpIndex; + va_list arglist; + va_start(arglist, OpCode); +//---------------------------------- + + //map SaveState opcodes to the op code table. + switch(OpCode){ + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 0x9: + case 0xA: + case 0xB: + case 0xC: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + OpIndex=OpCode; + break; + case 0x80: + case 0x81: + case 0x82: + OpIndex= OpCode - (0x6F); + break; + default: + Status = EFI_UNSUPPORTED; + goto EXIT_BOOT_SCRIPT_WRITE; + } + Status = OpCodeFuncs[OpIndex](&gBootScriptSaveProtocol, arglist); + //TRACE((-1,"SaveState UniqueIndex %x\n", gTableInfo->NumTableEntries -1)); + +EXIT_BOOT_SCRIPT_WRITE: + va_end(arglist); + return Status; +} +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateInsert +// +// Description: This function is used to store an OpCode to be replayed as part +// of the S3 resume boot path. The opcode is stored before (TRUE) +// or after (FALSE) the position in the boot script table specified +// by Position. If Position is NULL or points to NULL then the new +// opcode is inserted at the beginning of the table (if TRUE) or end +// of the table (if FALSE). +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN BOOLEAN BeforeOrAfter +// IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL +// IN UINT16 OpCode +// ... +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateInsert( + IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This, + IN BOOLEAN BeforeOrAfter, + IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL, + IN UINT16 OpCode, + ... +){ + + EFI_STATUS Status=EFI_SUCCESS; + UINTN OpIndex; + + va_list arglist; + va_start(arglist, OpCode); +//---------------------------------- + + //map SaveState opcodes to the op code table. + switch(OpCode){ + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 0x9: + case 0xA: + case 0xB: + case 0xC: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + OpIndex=OpCode; + break; + case 0x80: + case 0x81: + case 0x82: + OpIndex= OpCode - (0x6F); + break; + default: + Status = EFI_INVALID_PARAMETER; + goto EXIT_BOOT_SCRIPT_WRITE; + } + + gInsertInfo.IsItInsert = TRUE; + gInsertInfo.BeforeOrAfter = BeforeOrAfter; + if (!Position || !*Position) + if (BeforeOrAfter) gInsertInfo.Position = -1; + else gInsertInfo.IsItInsert = FALSE; + else + { + if ((UINTN) *Position >= gTableInfo->NumTableEntries) + { + ClearInsertInfo(); + return EFI_INVALID_PARAMETER; + } + gInsertInfo.Position = (UINTN)*Position; + } + Status = OpCodeFuncs[OpIndex](&gBootScriptSaveProtocol, arglist); + if (Position) *Position = (VOID*)(gTableInfo->NumTableEntries - 1); + ClearInsertInfo(); +EXIT_BOOT_SCRIPT_WRITE: + va_end(arglist); + return Status; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateLabel +// +// Description: Find a label within the boot script table and, if not present, +// optionally create it. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN BOOLEAN BeforeOrAfter +// IN BOOLEAN CreateIfNotFound +// IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL +// IN CONST CHAR8 *Label +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateLabel( + IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This, + IN BOOLEAN BeforeOrAfter, + IN BOOLEAN CreateIfNotFound, + IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL, + IN CONST CHAR8 *Label) +{ + UINT32 LabelSize, i; + UINT8 *TableHdr = gTableInfo->TableBottom, *TableInfo; + UINT16 Type; + BOOT_SCRIPT_LABEL LabelStr; + + if ((Label == NULL) || (*Label == 0)) + { + TRACE((-1,"First Exit\n")); + return EFI_INVALID_PARAMETER; + } + for(LabelSize=0; LabelSize<= LABEL_MAX_SIZE ; LabelSize++) + { + if (Label[LabelSize] == 0) break; // We assume label is 0 terminated. + + } + if (LabelSize >= LABEL_MAX_SIZE) + { + TRACE((-1,"2-d Exit\n")); + return EFI_INVALID_PARAMETER; // Label is too long or wrong/corrupted pointer + } + for (i=0; i<=gTableInfo->NumTableEntries; i++) + { + TableInfo = TableHdr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE); + Type = *(UINT8*) TableInfo + (*((UINT8*) TableInfo + 1) << 8); //In case not aligned if alignment required. + if (Type == EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM) + { + if (((BOOT_SCRIPT_LABEL*) TableInfo)->Size == LabelSize && + !MemCmp((VOID*)Label, TableInfo + sizeof(BOOT_SCRIPT_LABEL), LabelSize)) + { + if (Position) *Position = ((VOID*)((BOOT_SCRIPT_INFO_STRUCTURE*) TableHdr)->UniqueIndex); + else return EFI_INVALID_PARAMETER; //We found label, but can't return its position + return EFI_SUCCESS; // Label found and position returned + } + } + TableHdr += ((BOOT_SCRIPT_INFO_STRUCTURE*) TableHdr)->Length; + } + //----Label was not found + + if (!CreateIfNotFound) return EFI_NOT_FOUND; + + //----So - lets create it at position + + if (Position && ((UINTN) *Position >= gTableInfo->NumTableEntries)) + return EFI_INVALID_PARAMETER; // Position is not valid + + //---Filling gInsertInfo based on passed parameters + + gInsertInfo.IsItInsert = TRUE; + gInsertInfo.BeforeOrAfter = BeforeOrAfter; + + if (!Position || !*Position) + if (BeforeOrAfter) gInsertInfo.Position = -1; + else gInsertInfo.IsItInsert = FALSE; + else + { + if ((UINTN) *Position >= gTableInfo->NumTableEntries) + { + ClearInsertInfo(); + return EFI_INVALID_PARAMETER; + } + gInsertInfo.Position = (UINTN)*Position; + } + TableHdr = AllocTableEntry(sizeof(BOOT_SCRIPT_LABEL) + LabelSize); + ClearInsertInfo(); + if (!TableHdr) + return EFI_OUT_OF_RESOURCES; + LabelStr.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM); + LabelStr.Size = LabelSize; + MemCpy(TableHdr, &LabelStr, sizeof(BOOT_SCRIPT_LABEL)); + TableHdr += sizeof(BOOT_SCRIPT_LABEL); + MemCpy(TableHdr, (VOID*)Label, LabelSize); + if (Position) + *Position = (VOID*)(gTableInfo->NumTableEntries - 1); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: SaveStateCompare +// +// Description: Compare two positions in the boot script table and return their +// relative position. +// +// Input: +// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This +// IN EFI_S3_BOOT_SCRIPT_POSITION Position1 +// IN EFI_S3_BOOT_SCRIPT_POSITION Position2 +// OUT UINTN *RelativePosition +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SaveStateCompare( + IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This, + IN EFI_S3_BOOT_SCRIPT_POSITION Position1, + IN EFI_S3_BOOT_SCRIPT_POSITION Position2, + OUT UINTN *RelativePosition) +{ + VOID *First, *Second; + if (((UINTN) Position1 > gTableInfo->NumTableEntries) + || ((UINTN) Position2 > gTableInfo->NumTableEntries)) + return EFI_INVALID_PARAMETER; + gInsertInfo.BeforeOrAfter = TRUE; + gInsertInfo.Position = (UINTN)Position1; + First = InsertPositionInBootScript (0); + if (!First) + { + ClearInsertInfo(); + return EFI_INVALID_PARAMETER; + } + gInsertInfo.Position = (UINTN)Position2; + Second = InsertPositionInBootScript (0); + if (!Second) + { + ClearInsertInfo(); + return EFI_INVALID_PARAMETER; + } + if (First == Second) *RelativePosition = 0; + else + if (First < Second) *RelativePosition = -1; + else *RelativePosition = 1; + ClearInsertInfo(); + return EFI_SUCCESS; +} + + + +EFI_S3_SAVE_STATE_PROTOCOL gS3SaveStateProtocol={ + SaveStateWrite, + SaveStateInsert, + SaveStateLabel, + SaveStateCompare +}; + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: InitBootScriptSmm +// +// Description: Initialize table, if not done yet, and install protocols in SMM. +// +// Input: +// IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InitBootScriptSmm( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; +//------------------------------- + Status=InitAmiSmmLib(ImageHandle, SystemTable); + ASSERT_EFI_ERROR (Status); + if(EFI_ERROR(Status)) return Status; + + Status=InitBootScriptStructure(TRUE); + if(EFI_ERROR(Status)) return Status; + + // We are in SMM, retrieve the pointer to SMM System Table + Status=mInternalSmmBase2->GetSmstLocation (mInternalSmmBase2, &gSmst2); + ASSERT (gSmst2 != NULL); + if( EFI_ERROR(Status) || (gSmst2 == NULL)) return EFI_UNSUPPORTED; + + + // Install SMM PCI Root Bridge I/O Protocol + Status=gSmst2->SmmInstallProtocolInterface( + &mSmmS3SaveHandle, + &gEfiS3SmmSaveStateProtocolGuid, + EFI_NATIVE_INTERFACE, + (EFI_S3_SMM_SAVE_STATE_PROTOCOL*)&gS3SaveStateProtocol + ); + + + + + return Status; + + +} + +#endif +//PI 1.1 -- + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: InitBootScriptDxe +// +// Description: Initialize table and install protocols outside SMM. +// +// Input: +// IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS InitBootScriptDxe( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = InitBootScriptStructure(FALSE); + if(EFI_ERROR(Status)) return Status; + + Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces( + &ImageHandle, + &gEfiBootScriptSaveGuid, &gBootScriptSaveProtocol, +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + &gEfiS3SaveStateProtocolGuid, &gS3SaveStateProtocol, +#endif + NULL + ); + + ASSERT_EFI_ERROR(Status); + + Status = CreateReadyToBootEvent( + TPL_CALLBACK, + CallbackReadyToBoot, + NULL, + &gEvtReadyToBoot + ); + ASSERT_EFI_ERROR(Status); + + return Status; +} +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: InitBootScript +// +// Description: Initialize table and install protocols. +// Called twice - in and outside SMM. +// +// Input: +// IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: +// EFI_STATUS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS InitBootScript( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ +#if PI_SPECIFICATION_VERSION>=0x0001000A + EFI_STATUS Status; + BOOLEAN InSmm=FALSE; +#endif + +//------- + InitAmiLib(ImageHandle, SystemTable); +//PI 1.1 ++ +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + // Retrieve SMM Base2 Protocol, Do not use gBS from UefiBootServicesTableLib on purpose + // to prevent inclusion of gBS, gST, and gImageHandle from SMM Drivers unless the + // SMM driver explicity declares that dependency. + Status = SystemTable->BootServices->LocateProtocol ( + &gEfiSmmBase2ProtocolGuid, + NULL, + (VOID **)&mInternalSmmBase2 + ); + if( EFI_ERROR(Status)){ + //if we can't find SMM Protocols that's not InSmm initialization + if(Status==EFI_NOT_FOUND) InSmm=FALSE; + else return EFI_UNSUPPORTED; + } else mInternalSmmBase2->InSmm (mInternalSmmBase2, &InSmm); + + // Check to see if we are already in SMM + if (!InSmm ) { +#endif + // We are not in SMM, so SMST is not needed + return InitBootScriptDxe(ImageHandle,SystemTable); +//PI 1.1 ++ +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + } else { + return InitBootScriptSmm(ImageHandle,SystemTable); + } +#endif +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/S3/S3Restore.cif b/Core/EM/S3/S3Restore.cif new file mode 100644 index 0000000..e4c4c83 --- /dev/null +++ b/Core/EM/S3/S3Restore.cif @@ -0,0 +1,15 @@ +<component> + name = "S3Restore" + category = ModulePart + LocalRoot = "Core\EM\S3\" + RefName = "S3Restore" +[files] +"S3Restore.sdl" +"S3Restore.mak" +"S3Resume.dxs" +"AcpiS3Wake.asm" +"S3Resume.c" +"AcpiPeiS3Func.c" +"AcpiPeiS3Func.h" +"BootScriptExecuter.c" +<endComponent> diff --git a/Core/EM/S3/S3Restore.mak b/Core/EM/S3/S3Restore.mak new file mode 100644 index 0000000..d229d9c --- /dev/null +++ b/Core/EM/S3/S3Restore.mak @@ -0,0 +1,88 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Restore.mak 2 3/18/11 3:51p Oleksiyy $ +# +# $Revision: 2 $ +# +# $Date: 3/18/11 3:51p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Restore.mak $ +# +# 2 3/18/11 3:51p Oleksiyy +# [TAG] EIP53402 +# [Category] Improvement +# [Description] Improving backward computability and architecture. +# [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak, +# S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h, +# S3smmSaveState.h +# +# 1 2/03/11 4:09p Oleksiyy +# [TAG] EIP53402 +# [Category] Improvement +# [Description] Create new label of ACPI with separate S3 Functionality +# [Files] S3Restore.cif +# S3Restore.sdl +# S3Restore.mak +# S3Resume.dxs +# AcpiS3Wake.asm +# S3Resume.c +# AcpiPeiS3Func.c +# AcpiPeiS3Func.h +# BootScriptExecuter.c +# +# 6 1/13/10 2:13p Felixp +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: <ComponentName>.mak +# +# Description: +# +#<AMI_FHDR_END> +#********************************************************************** +all : S3Restore + +S3Restore : $(BUILD_DIR)\S3Restore.mak S3RestoreBin + +$(BUILD_DIR)\S3Restore.mak : $(S3Restore_DIR)\$(@B).cif $(S3Restore_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(S3Restore_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +S3RestoreBin : $(AMIPEILIB) $(AMICSPLib) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\S3Restore.mak all\ + GUID=EFD652CC-0E99-40f0-96C0-E08C089070FC \ + ENTRY_POINT=S3ResumeEntryPoint\ + "MY_INCLUDES=/I$(ACPI_CORE_DIR)" \ + DEPEX1=$(S3Restore_DIR)\S3Resume.DXS \ + DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + TYPE=PEIM \ + COMPRESS=0 +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** diff --git a/Core/EM/S3/S3Restore.sdl b/Core/EM/S3/S3Restore.sdl new file mode 100644 index 0000000..baa1165 --- /dev/null +++ b/Core/EM/S3/S3Restore.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "S3Restore_SUPPORT" + Value = "1" + Help = "Main switch to enable S3Restore support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "S3Restore_DIR" +End + +ELINK + Name = "$(BUILD_DIR)\S3Restore.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +MODULE + Help = "Includes S3Restore.mak to Project" + File = "S3Restore.mak" +End + diff --git a/Core/EM/S3/S3Resume.c b/Core/EM/S3/S3Resume.c new file mode 100644 index 0000000..1749cf2 --- /dev/null +++ b/Core/EM/S3/S3Resume.c @@ -0,0 +1,582 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/S3Resume.c 3 4/16/14 6:18a Chaseliu $ +// +// $Revision: 3 $ +// +// $Date: 4/16/14 6:18a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/S3Resume.c $ +// +// 3 4/16/14 6:18a Chaseliu +// sync to ACPI module 48 +// +// 2 9/18/13 1:04a Thomaschen +// Fix RHEL6.4 S3 resume issue. +// +// 9 3/03/14 5:04p Oleksiyy +// [TAG] EIP154308 +// [Category] Improvement +// [Description] Aptio 4: Intel Doc #542550 4h) FirmwarePerformance EFI +// variable contains address of FPDT ACPI table. +// [Files] AcpiCore.c and S3Resume.c +// +// 8 6/12/12 3:20p Oleksiyy +// TAG] EIP90322 +// [Category] Improvement +// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to +// AmiLib.h. +// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c +// +// 7 6/12/12 11:18a Oleksiyy +// [TAG] EIP88889 +// [Category] Improvement +// [Description] FACP ver 5.0 structure added, FPDT mesurment accuracy +// improved. +// [Files] ACPI50.h, ACPI.sdl, AcpiCore.c, S3Resume.c, Image.c, +// EfiLib.c +// +// 6 5/22/12 4:31p Oleksiyy +// [TAG] EIP90322 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] ChiefRiver SCT Fail, improper variable FPDT_Variable in +// ACPI module +// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined +// variable. +// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used. +// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c +// +// 5 5/08/12 6:05p Oleksiyy +// [TAG] EIP89643 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] S3Resume2 Ppi newer installs +// [RootCause] EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST incorrect usage in +// previous Ppi descriptor entree. +// [Solution] EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LISTremoved. +// [Files] S3Resume.c +// +// 4 11/11/11 5:13p Oleksiyy +// [TAG] EIP64296 +// [Category] New Feature +// [Description] Creation and filling of Firmware Performance Data Table +// is added. FirmPerfDataTab.h renamed to ACPI50.h +// [Files] AcpiCore.c, EfiLib.c, S3Resume.c and ACPI50.h added. +// +// 3 11/08/11 4:45p Oleksiyy +// [TAG] EIP64296 +// [Category] New Feature +// [Description] Creation and filling of Firmware Performance Data Table +// is added. +// [Files] AcpiCore.c, AmiDxeLib.h, CSM.c, DxeMain.c, EfiLib.c, +// Image.c, S3Resume.c and FirmPerfDataTab.h +// +// 2 7/19/11 11:33a Oleksiyy +// [TAG] EIP64108 +// [Category] Improvement +// [Description] ACPI, convert or update all eModules to be compliant +// with PI 1.2, and UEFI 2.3.1 specifications. +// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs, +// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c +// +// 1 2/03/11 4:09p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Restore.cif +// S3Restore.sdl +// S3Restore.mak +// S3Resume.dxs +// AcpiS3Wake.asm +// S3Resume.c +// AcpiPeiS3Func.c +// AcpiPeiS3Func.h +// BootScriptExecuter.c +// +// 25 11/24/09 5:21p Oleksiyy +// EIP 27605: Added ACPI 4.0 support. +// +// 24 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 23 10/03/08 3:20p Felixp +// Performance measurement support added +// +// 19 4/15/08 9:09p Yakovlevs +// Added support to chech for wake vector in all instances of FACS. +// EndOfPEIPhase PPI now installed. +// +// 18 4/09/08 5:52p Markw +// Install End of PEI PPI. +// +// 17 8/07/07 2:51p Felixp +// Additional Status Codes added +// +// 16 5/18/07 11:11a Markw +// Reintialize gdt before calling thunk. +// +// 15 4/23/07 1:31p Felixp +// Boot Script related code moved from Core to ACPI module. +// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver. +// +// 14 3/13/07 11:58a Felixp +// Error reporting updated to use new PEI_ERROR_CODE macro +// +// 13 2/07/07 3:08p Markw +// Add video repost support setup question. +// +// 12 1/23/07 4:24p Markw +// Added thunk support for a call for S3 video repost. +// +// 11 4/03/06 4:01p Felixp +// New Super I/O infrastructure Support +// +// 10 12/12/05 9:25p Yakovlevs +// SIO-specific core surrounded by #ifdefs +// +// 9 12/05/05 11:32a Yakovlevs +// Disabled Generation of SW SMI in order to switch to ACPI mode. +// System waking up from S3 with SCI_ENABLE bit ON. +// +// 8 10/09/05 11:27a Felixp +// Performance measurements added. +// +// 7 5/27/05 4:23p Markw +// Added Keyboard init. +// +// 6 5/10/05 2:50p Markw +// Use 16bit selectors for data segment. +// +// 5 5/07/05 11:53p Markw +// Store GDT in memory. Give pointer to GDT descripteor base/limit to wake +// up. +// +// 4 5/06/05 5:07p Markw +// Added 16 bit wakeup support. +// +// 3 5/04/05 12:24p Markw +// Moved structure definitions to AcpiS3.h. +// +// 2 4/29/05 3:26p Markw +// +// 1 4/29/05 12:17p Sivagarn +// +// 5 4/05/05 2:19p Markw +// Added enable ACPI Mode. +// +// 4 3/31/05 11:11a Markw +// Add wakeup vector support. +// +// 3 3/28/05 6:01p Markw +// Fixed bug. NVRAM variable is address not data. +// +// 2 3/27/05 6:36p Markw +// Execute Boot Script supported added. +// +// 1 3/25/05 5:37p Markw +// + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: S3Resume.c +// +// Description: Restore configuration state from S3 resume. +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <Pei.h> +#include <Ppi\S3Resume.h> +#include <Ppi\S3Resume2.h> +#include <ppi\BootScriptExecuter.h> +#include <Ppi\ReadOnlyVariable2.h> +#include <AmiPeiLib.h> +#include <token.h> +#include <setup.h> +#include "AcpiS3.h" +#include "AcpiPeiS3Func.h" +#include "AMICSPLIBInc.H" +#include <ACPI50.h> + +#pragma pack(1) +typedef struct { + UINT16 GdtLimit; + UINT64 *GdtBase; +} PTR_GDT_DESCS; +#pragma pack() + +extern UINT32 RealModeThunkStart; +extern UINT32 RealModeThunkSize; + +EFI_GUID gEfiPeiS3ResumePpiGuid = EFI_PEI_S3_RESUME_PPI_GUID; +EFI_GUID gEfiPeiBootScriptExecuterPpiGuid = EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID; +EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID; +extern EFI_GUID gEfiPeiReadOnlyVariable2PpiGuid; +EFI_GUID gEfiSetupGuid = SETUP_GUID; + +CHAR16 gSetupVariable[] = L"Setup"; + +VOID RealModeThunk(PTR_GDT_DESCS *GdtDesc, UINT32 Firmware_Waking_Vector, BOOLEAN UseCall); +typedef VOID(*REAL_MODE_THUNK_FUNCTION)(PTR_GDT_DESCS*, UINT32, BOOLEAN); +//Boot Script Executer module initialization routine +EFI_STATUS InitBootScriptExecuter( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ); +//S3 Resume PPI routine +//Defined in this file +EFI_STATUS S3RestoreConfig( + IN EFI_PEI_SERVICES **PeiServices +); +EFI_STATUS S3RestoreConfig2( + IN EFI_PEI_S3_RESUME2_PPI *This +); +//To be copied to memory. +UINT64 gGDT[] = { + 0, //NULL_SEL + 0x00009a000000ffff, //CODE_SEL 0x08 16-bit code selector, limit of 4K + 0x000093000000ffff //DATA_SEL 0x10, 16-bit data selector Data 0-ffffffff +}; + +//PPI to be installed +EFI_PEI_S3_RESUME_PPI S3ResumePpi = {S3RestoreConfig}; +EFI_PEI_S3_RESUME2_PPI S3ResumePpi2 = {S3RestoreConfig2}; + +static EFI_PEI_PPI_DESCRIPTOR gPpiList[] = { + {EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiPeiS3ResumePpiGuid, + &S3ResumePpi}, + + {(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiS3Resume2PpiGuid, + &S3ResumePpi2} +}; + +static EFI_PEI_PPI_DESCRIPTOR gEndOfPpiList[] = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiEndOfPeiPhasePpiGuid, + NULL +}; + +VOID InitLongModeExt( + IN EFI_PEI_SERVICES **PeiServices, + IN VOID *Function, + IN VOID *Parameter1, + IN VOID *Parameter2, + IN UINT8 NumMemBits +); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: S3RestoreConfig +// +// Description: Restore configuration state from S3 resume. +// +// Input: EFI_PEI_SERVICES **PeiServices +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS S3RestoreConfig( + IN EFI_PEI_SERVICES **PeiServices +) +{ + EFI_STATUS Status; + UINT32 i; + PTR_GDT_DESCS *GdtDesc; + UINT64 *Gdt; + + ACPI_VARIABLE_SET *AcpiVariableSet; + EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *BootScript; + EFI_PHYSICAL_ADDRESS BootScriptTable; +#if S3_VIDEO_REPOST_SUPPORT == 1 + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + SETUP_DATA SetupData; + BOOLEAN IsSetupDataValid; + UINTN VariableSize=sizeof(SETUP_DATA); +#endif + void(*X_Firmware_Waking_Vector)(); + UINT32 Firmware_Waking_Vector; + UINTN VarSize = sizeof(UINT32); + EFI_FPDT_STRUCTURE *FpdtVar; + + PEI_PERF_START(PeiServices,S3RESUME_TOK,NULL,0); + PEI_PROGRESS_CODE(PeiServices,PEI_S3_STARTED); +#if S3_VIDEO_REPOST_SUPPORT == 1 + Status = (*PeiServices)->LocatePpi( + PeiServices, + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, NULL, + &ReadOnlyVariable + ); + ASSERT_PEI_ERROR(PeiServices, Status); +#endif + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiBootScriptExecuterPpiGuid, + 0, + NULL, + &BootScript + ); + ASSERT_PEI_ERROR (PeiServices, Status); + if (EFI_ERROR(Status)){ + PEI_ERROR_CODE(PeiServices, PEI_S3_BOOT_SCRIPT_ERROR, EFI_ERROR_MAJOR); + return Status; + } + + AcpiVariableSet = GetAcpiS3Info(PeiServices); + if (!AcpiVariableSet){ + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No Acpi Global Variable\n")); + PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_ERROR, EFI_ERROR_MAJOR); + return EFI_NOT_FOUND; + } + + BootScriptTable = AcpiVariableSet->AcpiBootScriptTable; + +#if S3_VIDEO_REPOST_SUPPORT == 1 + VariableSize = sizeof(SETUP_DATA); + Status = ReadOnlyVariable->GetVariable( + ReadOnlyVariable, + gSetupVariable, &gEfiSetupGuid, + NULL, + &VariableSize, &SetupData + ); + IsSetupDataValid = !EFI_ERROR(Status); +#endif + + PEI_PROGRESS_CODE(PeiServices,PEI_S3_BOOT_SCRIPT); + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Executing Boot Script Table.\n")); + Status = BootScript->Execute( + PeiServices, + BootScript, + BootScriptTable, + NULL + ); + if (EFI_ERROR(Status)) + { + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Error executing Boot Script Table.\n")); + PEI_ERROR_CODE(PeiServices, PEI_S3_BOOT_SCRIPT_ERROR, EFI_ERROR_MAJOR); + } + +//for legacy free systems it will be infinite loop + + //keyboard init + #define KBC_CMDSTS_PORT 0x64 + #define KBC_DATA_PORT 0x60 + #define KBC_IBF 0x02 + if( IoRead8(KBC_CMDSTS_PORT) != 0xff){ + IoWrite8(KBC_CMDSTS_PORT, 0xaa); + for (;;) { + if (!(IoRead8(KBC_CMDSTS_PORT) & KBC_IBF)) { + break; + } + } + } + + _asm cli + + //allocate memory for GDT and copy to Thunk to 16-bit. + (*PeiServices)->AllocatePool(PeiServices,sizeof(gGDT), &Gdt); + + //Allocate memory for descriptor. + (*PeiServices)->AllocatePool(PeiServices,sizeof(PTR_GDT_DESCS), &GdtDesc); + GdtDesc->GdtLimit = sizeof(gGDT)-1; + GdtDesc->GdtBase = Gdt; + + (*PeiServices)->InstallPpi(PeiServices, gEndOfPpiList); + +#if S3_VIDEO_REPOST_SUPPORT == 1 + if (IsSetupDataValid && SetupData.S3ResumeVideoRepost) { + //The following code executes video option ROM at c000:0003. + //For the video option ROM, a thunk is needed to 16-bit. + //The Thunk and the area for 16-bit stack are located starting at + //ACPI_THUNK_REAL_MODE_SEGMENT * 16 with a length ACPI_THUNK_STACK_TOP. + + VOID *RealModeThunkSave; + + PEI_PROGRESS_CODE(PeiServices,PEI_S3_VIDEO_REPOST); + //Allocate memory to perserve the the thunk region. + Status = (*PeiServices)->AllocatePool(PeiServices, ACPI_THUNK_STACK_TOP, &RealModeThunkSave); + ASSERT_PEI_ERROR (PeiServices, Status); + + //Save the thunk and stack region. + MemCpy(RealModeThunkSave, (VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), ACPI_THUNK_STACK_TOP); //Save Region to copy + //Copy the thunk code. + MemCpy((VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), (VOID*)RealModeThunkStart, RealModeThunkSize); + + //Open 0xc0000 region--the video option ROM. + NBPeiProgramPAMRegisters( + PeiServices, + 0xc0000, + 0x10000, + LEGACY_REGION_UNLOCK, + NULL + ); + + //Call video option rom: C000:0003. + for(i = 0; i < sizeof(gGDT)/sizeof(UINT64); ++i) Gdt[i] = gGDT[i]; //Set GDT for Thunk to 16-bit + ((REAL_MODE_THUNK_FUNCTION)(ACPI_THUNK_REAL_MODE_SEGMENT * 16))(GdtDesc, 0xc0000003, TRUE); + + //Close c000 region + NBPeiProgramPAMRegisters( + PeiServices, + 0xc0000, + 0x10000, + LEGACY_REGION_LOCK, + NULL + ); + + //Restore region where THUNK and 16-bit stack was copied over. + MemCpy((VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), RealModeThunkSave, ACPI_THUNK_STACK_TOP); //Restore region. + } +#endif + + PEI_TRACE((-1, PeiServices, "Smm S3 resume -- ACPI Mode Enable.\n")); + if (!AcpiVariableSet->AcpiFacsTable[0] && \ + !AcpiVariableSet->AcpiFacsTable[1] && \ + !AcpiVariableSet->AcpiFacsTable[2]) + { + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No ACPI FACS Table\n")); + PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_ERROR, EFI_ERROR_MAJOR); + } + + PEI_PERF_END(PeiServices,S3RESUME_TOK,NULL,0); + PEI_PERF_SAVE_S3_DATA(PeiServices); + + Status = PeiGetVariable( + PeiServices, + L"FPDT_Variable_NV", &gAmiGlobalVariableGuid, + NULL, &VarSize, &FpdtVar + + ); + if (!EFI_ERROR (Status)) + { + if (((PERF_TAB_HEADER*)(UINT8*)(FpdtVar->S3Pointer))->Signature == 0x54503353) + { + BASIC_S3_RESUME_PERF_REC *S3PerRec; + UINT64 NanoTime; + S3PerRec = (BASIC_S3_RESUME_PERF_REC*)((UINT8*)(FpdtVar->S3Pointer) + sizeof(PERF_TAB_HEADER)); + if ((FpdtVar->NanoFreq !=0) && (S3PerRec->Header.PerfRecType == 0)) + { + NanoTime = Div64 (Mul64 (GetCpuTimer (), (UINTN)FpdtVar->NanoFreq), 1000000 , NULL); + + S3PerRec->AverageResume = Div64 ((Mul64 (S3PerRec->AverageResume, (UINTN)(S3PerRec->ResumeCount)) + NanoTime), + (UINTN)(S3PerRec->ResumeCount + 1), NULL); + S3PerRec->FullResume = NanoTime; + S3PerRec->ResumeCount++; + + } + } + } + + //If given control to X_Firmware_Waking_Vector. It will not return. + // Search each FACS table for a valid vector + for (i = 0; i < 3; i++ ) { + if (!AcpiVariableSet->AcpiFacsTable[i]) continue; + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Trying FACS table #%d.\n", i + 1)); + X_Firmware_Waking_Vector = (void(*)())*(VOID**)((UINT8*)AcpiVariableSet->AcpiFacsTable[i] + 24); + if (X_Firmware_Waking_Vector) + { + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in protected mode.\n")); + PEI_PROGRESS_CODE(PeiServices,PEI_S3_OS_WAKE); + PEI_TRACE((-1, PeiServices, "Smm S3 Vector %x.\n", X_Firmware_Waking_Vector)); + if (((UINT32*)AcpiVariableSet->AcpiFacsTable[i] + 36) && 1) + { + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in protected mode 64 bit enable.\n")); + InitLongModeExt (PeiServices, X_Firmware_Waking_Vector, NULL, NULL, 12); + } + else + X_Firmware_Waking_Vector(); // Will not return + } + + Firmware_Waking_Vector = *(UINT32*)((UINT8*)AcpiVariableSet->AcpiFacsTable[i] + 12); + if (Firmware_Waking_Vector) + { + UINT32 RealModeSegOff; + + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in real mode.\n")); + PEI_TRACE((-1, PeiServices, "Smm S3 Vector %x.\n", Firmware_Waking_Vector)); + RealModeSegOff = ((Firmware_Waking_Vector & ~0xf) << 12) + (Firmware_Waking_Vector & 0xf); + + //Execute this thunk from ROM. + for(i = 0; i < sizeof(gGDT)/sizeof(UINT64); ++i) Gdt[i] = gGDT[i]; //Set GDT for Thunk to 16-bit + PEI_PROGRESS_CODE(PeiServices,PEI_S3_OS_WAKE); + RealModeThunk(GdtDesc, RealModeSegOff, FALSE); //Will not return. + } + } + + PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No waking vector.\n")); + PEI_ERROR_CODE(PeiServices, PEI_S3_OS_WAKE_ERROR, EFI_ERROR_MAJOR); + + return EFI_UNSUPPORTED; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: S3RestoreConfig2 +// +// Description: Restore configuration state from S3 resume. +// +// Input: EFI_PEI_S3_RESUME2_PPI *This +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS S3RestoreConfig2( + IN EFI_PEI_S3_RESUME2_PPI *This +) +{ + EFI_PEI_SERVICES **PeiServices; + + if (This != &S3ResumePpi2) return EFI_INVALID_PARAMETER; + + PeiServices = GetPeiServicesTablePointer (); + + return S3RestoreConfig(PeiServices); + +} + +EFI_STATUS S3ResumeEntryPoint( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + //Initialize Boot Script Executer module + InitBootScriptExecuter(FfsHeader,PeiServices); + return (*PeiServices)->InstallPpi(PeiServices,gPpiList); +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/S3/S3Resume.dxs b/Core/EM/S3/S3Resume.dxs new file mode 100644 index 0000000..194ac48 --- /dev/null +++ b/Core/EM/S3/S3Resume.dxs @@ -0,0 +1,85 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Resume.dxs 2 7/19/11 11:33a Oleksiyy $ +// +// $Revision: 2 $ +// +// $Date: 7/19/11 11:33a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Resume.dxs $ +// +// 2 7/19/11 11:33a Oleksiyy +// [TAG] EIP64108 +// [Category] Improvement +// [Description] ACPI, convert or update all eModules to be compliant +// with PI 1.2, and UEFI 2.3.1 specifications. +// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs, +// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c +// +// 1 2/03/11 4:09p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Restore.cif +// S3Restore.sdl +// S3Restore.mak +// S3Resume.dxs +// AcpiS3Wake.asm +// S3Resume.c +// AcpiPeiS3Func.c +// AcpiPeiS3Func.h +// BootScriptExecuter.c +// +// 3 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 2 4/23/07 1:31p Felixp +// Boot Script related code moved from Core to ACPI module. +// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver. +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: S3Resume.dxs +// +// Description: +// +//<AMI_FHDR_END> +//********************************************************************** + +#include <Ppi/ReadOnlyVariable2.h> + +DEPENDENCY_START + EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID AND + EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI +DEPENDENCY_END + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/S3/S3Save.cif b/Core/EM/S3/S3Save.cif new file mode 100644 index 0000000..423bbc2 --- /dev/null +++ b/Core/EM/S3/S3Save.cif @@ -0,0 +1,14 @@ +<component> + name = "S3Save" + category = ModulePart + LocalRoot = "Core\EM\S3\" + RefName = "S3Save" +[files] +"S3Save.sdl" +"S3Save.mak" +"AcpiS3Save.c" +"BootScriptPrivate.h" +"BootScriptSave.c" +"AcpiS3Save.dxs" +"SmmS3Save.dxs" +<endComponent> diff --git a/Core/EM/S3/S3Save.mak b/Core/EM/S3/S3Save.mak new file mode 100644 index 0000000..9bc43e7 --- /dev/null +++ b/Core/EM/S3/S3Save.mak @@ -0,0 +1,99 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/S3Save.mak 2 3/18/11 3:56p Oleksiyy $ +# +# $Revision: 2 $ +# +# $Date: 3/18/11 3:56p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/S3Save.mak $ +# +# 2 3/18/11 3:56p Oleksiyy +# [TAG] EIP53402 +# [Category] Improvement +# [Description] Improving backward computability and architecture. +# [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak, +# S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h, +# S3smmSaveState.h +# +# 1 2/03/11 4:08p Oleksiyy +# [TAG] EIP53402 +# [Category] Improvement +# [Description] Create new label of ACPI with separate S3 Functionality +# [Files] S3Save.cif +# S3Save.sdl +# S3Save.mak +# AcpiS3.h +# AcpiS3Save.c +# BootScriptPrivate.h +# BootScriptSave.c +# AcpiS3Save.dxs +# SmmS3Save.dxs +# +# 6 1/13/10 2:13p Felixp +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: <ComponentName>.mak +# +# Description: +# +#<AMI_FHDR_END> +#********************************************************************** +all : S3Save + +!IFNDEF PI_SPECIFICATION_VERSION +PI_SPECIFICATION_VERSION = 0 +!ENDIF + +S3Save : $(BUILD_DIR)\S3Save.mak S3SaveBin + +$(BUILD_DIR)\S3Save.mak : $(S3Save_DIR)\$(@B).cif $(S3Save_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(S3Save_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +S3SaveBin : $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\S3Save.mak all\ + GUID=26A2481E-4424-46a2-9943-CC4039EAD8F8 \ + ENTRY_POINT=AcpiS3SaveEntryPoint\ + "MY_INCLUDES=/I$(ACPI_CORE_DIR)" \ +!IF $(PI_SPECIFICATION_VERSION) >= 0x00001000A + TYPE=DXESMM_DRIVER \ + DEPEX1=$(S3Save_DIR)\SmmS3Save.dxs \ + DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \ + DEPEX2=$(S3Save_DIR)\AcpiS3Save.dxs \ + DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \ +!ELSE + DEPEX1=$(S3Save_DIR)\AcpiS3Save.dxs \ + TYPE=BS_DRIVER \ +!ENDIF + COMPRESS=1\ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#**********************************************************************
\ No newline at end of file diff --git a/Core/EM/S3/S3Save.sdl b/Core/EM/S3/S3Save.sdl new file mode 100644 index 0000000..fc09ec2 --- /dev/null +++ b/Core/EM/S3/S3Save.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "S3Save_SUPPORT" + Value = "1" + Help = "Main switch to enable S3Save Support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "S3Save_DIR" +End + +MODULE + Help = "Includes S3Save.mak to Project" + File = "S3Save.mak" +End + +ELINK + Name = "$(BUILD_DIR)\S3Save.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/Core/EM/S3/S3Support.cif b/Core/EM/S3/S3Support.cif new file mode 100644 index 0000000..af97bb6 --- /dev/null +++ b/Core/EM/S3/S3Support.cif @@ -0,0 +1,12 @@ +<component> + name = "S3Support" + category = ModulePart + LocalRoot = "Core\EM\S3\" + RefName = "S3Support" +[files] +"S3Support.sdl" +[parts] +"S3Save" +"S3Restore" +"S3Common" +<endComponent> diff --git a/Core/EM/S3/S3Support.sdl b/Core/EM/S3/S3Support.sdl new file mode 100644 index 0000000..f5a858b --- /dev/null +++ b/Core/EM/S3/S3Support.sdl @@ -0,0 +1,9 @@ +TOKEN + Name = S3Support_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable S3Support support in Project" +End diff --git a/Core/EM/S3/SmmS3Save.dxs b/Core/EM/S3/SmmS3Save.dxs new file mode 100644 index 0000000..abbc621 --- /dev/null +++ b/Core/EM/S3/SmmS3Save.dxs @@ -0,0 +1,70 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/SmmS3Save.dxs 1 2/03/11 4:08p Oleksiyy $ +// +// $Revision: 1 $ +// +// $Date: 2/03/11 4:08p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/SmmS3Save.dxs $ +// +// 1 2/03/11 4:08p Oleksiyy +// [TAG] EIP53402 +// [Category] Improvement +// [Description] Create new label of ACPI with separate S3 Functionality +// [Files] S3Save.cif +// S3Save.sdl +// S3Save.mak +// AcpiS3.h +// AcpiS3Save.c +// BootScriptPrivate.h +// BootScriptSave.c +// AcpiS3Save.dxs +// SmmS3Save.dxs +// +// 3 3/26/09 4:51p Oleksiyy +// New ACPI Core implementation - improves logic, execution time and +// memory usage of ACPI module. +// +// 2 4/24/07 6:27p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: AcpiS3Save.dxs +// +// Description: Dependency expression for the AcpiS3Save component +// +//<AMI_FHDR_END> +//********************************************************************** +DEPENDENCY_START + TRUE +DEPENDENCY_END +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file |