mirror of https://github.com/acidanthera/audk.git
378 lines
8.7 KiB
C
378 lines
8.7 KiB
C
/** @file
|
|
|
|
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
|
|
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
|
|
|
|
|
|
|
|
Module Name:
|
|
|
|
IchS3Save.c
|
|
|
|
Abstract:
|
|
|
|
SMM S3 handler Driver implementation file
|
|
|
|
Revision History
|
|
|
|
**/
|
|
#include "SmmPlatform.h"
|
|
|
|
extern UINT16 mAcpiBaseAddr;
|
|
EFI_PHYSICAL_ADDRESS mRuntimeScriptTableBase;
|
|
|
|
EFI_STATUS
|
|
InitRuntimeScriptTable (
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 VarAttrib;
|
|
UINTN VarSize;
|
|
ACPI_VARIABLE_SET_COMPATIBILITY *AcpiVariableBase;
|
|
|
|
//
|
|
// Allocate runtime ACPI script table space. We need it to save some
|
|
// settings done by CSM, which runs after normal script table closed
|
|
//
|
|
Status = gBS->AllocatePages (
|
|
AllocateAnyPages,
|
|
EfiACPIReclaimMemory,
|
|
1,
|
|
&mRuntimeScriptTableBase
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return EFI_OUT_OF_RESOURCES ;
|
|
}
|
|
|
|
//
|
|
// Save runtime script table base into global ACPI variable
|
|
//
|
|
VarAttrib = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
|
|
| EFI_VARIABLE_NON_VOLATILE;
|
|
VarSize = sizeof (UINTN);
|
|
Status = SystemTable->RuntimeServices->GetVariable (
|
|
ACPI_GLOBAL_VARIABLE,
|
|
&gEfiAcpiVariableCompatiblityGuid,
|
|
&VarAttrib,
|
|
&VarSize,
|
|
&AcpiVariableBase
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
AcpiVariableBase->RuntimeScriptTableBase = mRuntimeScriptTableBase;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
SaveRuntimeScriptTable (
|
|
VOID
|
|
)
|
|
{
|
|
SMM_PCI_IO_ADDRESS PciAddress;
|
|
UINT32 Data32;
|
|
UINT16 Data16;
|
|
UINT8 Data8;
|
|
UINT8 Mask;
|
|
UINTN Index;
|
|
UINTN Offset;
|
|
UINT8 RegTable[] = {
|
|
|
|
//
|
|
//Bus , Dev, Func, DMI
|
|
//
|
|
0x00 , 0x00, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x00 , 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xa0,
|
|
|
|
//
|
|
//Bus , Dev, Func, LPC device
|
|
//
|
|
0x00 , 0x1F, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x00 , 0x08, 0x00, 0x07, 0x00, 0x00, 0x90, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, PCIE device
|
|
//
|
|
0x00 , 0x1C, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0xC0 , 0x83, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, PCIE device
|
|
//
|
|
0x00 , 0x1C, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x03 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, SATA device
|
|
//
|
|
0x00 , 0x13, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0xf4 , 0xab, 0x27, 0x10, 0xf1, 0x1d, 0x00, 0x40,
|
|
|
|
//
|
|
//Bus , Dev, Func, EHCI device
|
|
//
|
|
0x00 , 0x1D, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x10 , 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
|
|
|
//
|
|
//Bus , Dev, Func, SMBUS device
|
|
//
|
|
0x00 , 0x1f, 0x03,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x10 , 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, SMBUS device
|
|
//
|
|
0x00 , 0x1f, 0x03,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, VGA bus1
|
|
//
|
|
0x01 , 0x00, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x58 , 0x81, 0x18, 0x01, 0xb0, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, VGA bus1
|
|
//
|
|
0x01 , 0x00, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, VGA bus1 function 1
|
|
//
|
|
0x01 , 0x00, 0x01,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x51 , 0x80, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, VGA bus1 function 1
|
|
//
|
|
0x01 , 0x00, 0x01,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, IGD bus0 function 0
|
|
//
|
|
0x00 , 0x02, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x42 , 0x81, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, USB bus0 function 0
|
|
//
|
|
0x00 , 0x16, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
//
|
|
//Bus , Dev, Func, HD Audio bus0 function 0
|
|
//
|
|
0x00 , 0x1B, 0x00,
|
|
|
|
//
|
|
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
|
|
//
|
|
0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
|
|
//
|
|
//0xFF indicates the end of the table
|
|
//
|
|
0xFF
|
|
};
|
|
|
|
//
|
|
// These registers have to set in byte order
|
|
//
|
|
UINT8 ExtReg[] = { 0x9E, 0x9D }; // SMRAM settings
|
|
|
|
|
|
|
|
//
|
|
// Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
|
|
// and vital to S3 resume. That's why we put save code here
|
|
//
|
|
PciAddress.Bus = 0;
|
|
PciAddress.Device = 0;
|
|
PciAddress.Function = 0;
|
|
PciAddress.ExtendedRegister = 0;
|
|
|
|
for (Index = 0; Index < 2; Index++) {
|
|
//
|
|
// Read SRAM setting from Pci(0, 0, 0)
|
|
//
|
|
PciAddress.Register = ExtReg[Index];
|
|
Data8 = MmioRead8 (
|
|
MmPciAddress (0,
|
|
PciAddress.Bus,
|
|
PciAddress.Device,
|
|
PciAddress.Function,
|
|
PciAddress.Register
|
|
)
|
|
);
|
|
|
|
//
|
|
// Save latest settings to runtime script table
|
|
//
|
|
S3BootScriptSavePciCfgWrite(
|
|
S3BootScriptWidthUint8,
|
|
*(UINT64*)&PciAddress,
|
|
1,
|
|
&Data8
|
|
);
|
|
}
|
|
|
|
|
|
//
|
|
// Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
|
|
// and vital to S3 resume. That's why we put save code here
|
|
//
|
|
Index = 0;
|
|
while (RegTable[Index] != 0xFF) {
|
|
|
|
PciAddress.Bus = RegTable[Index++];
|
|
PciAddress.Device = RegTable[Index++];
|
|
PciAddress.Function = RegTable[Index++];
|
|
PciAddress.Register = 0;
|
|
PciAddress.ExtendedRegister = 0;
|
|
|
|
Data16 = MmioRead16 (
|
|
MmPciAddress (0,
|
|
PciAddress.Bus,
|
|
PciAddress.Device,
|
|
PciAddress.Function,
|
|
PciAddress.Register
|
|
)
|
|
);
|
|
|
|
if (Data16 == 0xFFFF) {
|
|
Index+=8;
|
|
continue;
|
|
}
|
|
|
|
for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) {
|
|
|
|
if (Mask == 0x00) {
|
|
Mask = 0x01;
|
|
}
|
|
|
|
if (RegTable[Index + Offset/32] & Mask ) {
|
|
|
|
PciAddress.Register = (UINT8)Offset;
|
|
Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
|
|
|
|
//
|
|
// Save latest settings to runtime script table
|
|
//
|
|
S3BootScriptSavePciCfgWrite (
|
|
S3BootScriptWidthUint32,
|
|
*(UINT64*)&PciAddress,
|
|
1,
|
|
&Data32
|
|
);
|
|
}
|
|
}
|
|
|
|
Index += 8;
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// Save I/O ports to S3 script table
|
|
//
|
|
|
|
//
|
|
// Selftest KBC
|
|
//
|
|
Data8 = 0xAA;
|
|
S3BootScriptSaveIoWrite (
|
|
S3BootScriptWidthUint8,
|
|
0x64,
|
|
(UINTN)1,
|
|
&Data8
|
|
);
|
|
|
|
Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
|
|
|
|
S3BootScriptSaveIoWrite (
|
|
S3BootScriptWidthUint32,
|
|
(mAcpiBaseAddr + R_PCH_SMI_EN),
|
|
1,
|
|
&Data32
|
|
);
|
|
|
|
//
|
|
// Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
|
|
//
|
|
Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT);
|
|
|
|
S3BootScriptSaveIoWrite (
|
|
S3BootScriptWidthUint16,
|
|
mAcpiBaseAddr + R_PCH_TCO_CNT,
|
|
1,
|
|
&Data16
|
|
);
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
}
|