diff options
Diffstat (limited to 'Chipset/SB')
123 files changed, 43719 insertions, 0 deletions
diff --git a/Chipset/SB/AcpiModeEnable.c b/Chipset/SB/AcpiModeEnable.c new file mode 100644 index 0000000..618f9c8 --- /dev/null +++ b/Chipset/SB/AcpiModeEnable.c @@ -0,0 +1,959 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.c 17 5/23/13 1:57a Scottyang $ +// +// $Revision: 17 $ +// +// $Date: 5/23/13 1:57a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.c $ +// +// 17 5/23/13 1:57a Scottyang +// [TAG] EIP120623 +// [Category] Improvement +// [Description] LCD turn on automatically when resume from S3. +// [Files] SBPEI.c, SBDxe.c, AcpiModeEnable.c +// +// 16 5/09/13 6:32a Scottyang +// [TAG] None +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] S3 resume Verb table will error when enable token +// "AMI_INIT_VERB_TABLE_IN_S3". +// [RootCause] The FrontPanel is wrong. +// [Solution] Change FrontPanel to frontSideNo. +// [Files] AcpiModeEnable.c +// +// 15 4/23/13 4:20a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Add token "ONLY_CLEAR_RTC_EN_IN_PEI" for improve +// "EIP120623". +// [Files] AcpiModeEnable.c; SB.SDL; SBPEI.c +// +// 14 4/18/13 12:17a Wesleychen +// [TAG] EIP120623 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] LCD doesn't turn on automatically when resume from S3. +// [RootCause] PM1_STS (PMBASE+00h) are cleared in EnableAcpiMode(). +// [Solution] Avoid PM1_STS clearing behavior is occurring in S3 +// resuming. +// *AcpiModeEnable.c Rev#8~11(EIP101628 & EIP118531) are are +// no need be existence. +// [Files] SBPEI.c; AcpiModeEnable.c +// +// 12 4/08/13 2:27a Wesleychen +// Revise the content of history. +// +// 7 10/12/12 2:08a Scottyang +// [TAG] EIP76432 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] It will BSOD ,while system boot to OS at "starting windows" +// press the KB in succession. +// [RootCause] System BSOD is caused by a large number of SMI generated. +// [Solution] Disable legacy USB SMI in ACPI enable stage. +// [Files] AcpiModeEnable.c; SBDXE.c +// +// 6 10/01/12 5:51a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update EIP#102349 "GPE0 setting and SCI routing for ULT +// platfoem". +// [Files] AcpiModeEnable.c, AcpiModeEnable.sdl +// +// 5 9/26/12 3:57a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Fixed RTC on iFFS failed. +// [Files] AcpiModeEnable.c +// +// 4 9/12/12 5:16a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Modify for ULT GPIO changed by PCH LPT-LP EDS 1.0. +// [Files] SB.H, SB.sdl, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBPEI.c +// +// 3 7/27/12 6:16a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 2 4/25/12 9:25a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Apply AcpiModeEnable support PI 1.2. +// [Files] AcpiModeEnable.c +// +// 1 2/08/12 8:30a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: AcpiModeEnable.C +// +// Description: Provide functions to enable and disable ACPI mode +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- +#include <Token.h> +#include <AmiDxeLib.h> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B) +#include <Protocol\SmmBase2.h> +#include <Protocol\SmmSwDispatch2.h> +#else +#include <Protocol\SmmBase.h> +#include <Protocol\SmmSwDispatch.h> +#endif + +#include <Protocol\DevicePath.h> +#include <Token.h> +#include <AmiCspLib.h> +#include <PchAccess.h> +#include "RTC.h" +#include "HDAVBTBL.h" +#include "AcpiModeEnable.h" + +#if defined(PchDxePlatformPolicy_SUPPORT) && PchDxePlatformPolicy_SUPPORT +#include <PchDxePlatformPolicy.h> +#endif // PchDxePlatformPolicy_SUPPORT end + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +#define AMI_SMM_SW_DISPATCH_PROTOCOL EFI_SMM_SW_DISPATCH2_PROTOCOL +#define AMI_SMM_SW_DISPATCH_CONTEXT EFI_SMM_SW_REGISTER_CONTEXT +#define SMM_CHILD_DISPATCH_SUCCESS EFI_SUCCESS +#else +#define AMI_SMM_SW_DISPATCH_PROTOCOL EFI_SMM_SW_DISPATCH_PROTOCOL +#define AMI_SMM_SW_DISPATCH_CONTEXT EFI_SMM_SW_DISPATCH_CONTEXT +#define SMM_CHILD_DISPATCH_SUCCESS +#endif + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) +VOID InitParts ( + IN VOID* DispatchHandle, + IN CONST VOID *DispatchContext +); + +VOID InitParts2 ( + IN VOID* DispatchHandle, + IN CONST VOID *DispatchContext +); + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +ACPI_DISPATCH_LINK *gAcpiEnDispatchHead = 0, *gAcpiEnDispatchTail = 0; +ACPI_DISPATCH_LINK *gAcpiDisDispatchHead = 0, *gAcpiDisDispatchTail = 0; + +UINT8 gFirstInFlag = 0; +UINT16 wPM1_SaveState; +UINT32 dGPE_SaveState; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_SMM_BASE2_PROTOCOL *gSmmBase2; +#endif + +// GUID Definition(s) + +EFI_GUID gEfiAcpiEnDispatchProtocolGuid = EFI_ACPI_EN_DISPATCH_PROTOCOL_GUID; +EFI_GUID gEfiAcpiDisDispatchProtocolGuid = EFI_ACPI_DIS_DISPATCH_PROTOCOL_GUID; + +// Protocol Definition(s) + +// External Declaration(s) + +// Function Definition(s) +//---------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbGpioSciInit +// +// Description: Programming the corresponding GPIO pin to generate SCI#. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SbGpioSciInit (VOID) +{ + UINT32 GpioRoute; + UINT8 GpioIndex; + UINT32 GpioSmiEnable; + UINT32 GpioNmiEnable; + + if (GetPchSeries() == PchLp) { + GpioRoute = READ_IO32(GPIO_BASE_ADDRESS+GP_IOREG_GPI_ROUT2); + GpioSmiEnable = READ_IO32(GPIO_BASE_ADDRESS+GP_IOREG_ALTGP_SMI_EN); + GpioNmiEnable = READ_IO32(GPIO_BASE_ADDRESS+GP_IOREG_PCHLP_GPI_NMI_EN); + + GpioRoute &= ~GPIO_SCI_BITMAP; + GpioSmiEnable &= ~GPIO_SCI_BITMAP; + GpioNmiEnable &= ~GPIO_SCI_BITMAP; + + WRITE_IO16(GPIO_BASE_ADDRESS+GP_IOREG_GPI_ROUT2, GpioRoute); + WRITE_IO16(GPIO_BASE_ADDRESS+GP_IOREG_ALTGP_SMI_EN, GpioSmiEnable); + WRITE_IO16(GPIO_BASE_ADDRESS+GP_IOREG_PCHLP_GPI_NMI_EN, GpioNmiEnable); + } else { + GpioRoute = READ_PCI32_SB(R_PCH_LPC_GPI_ROUT); + for (GpioIndex = 0; GpioIndex < 16; GpioIndex++) { + if (GPIO_SCI_BITMAP & (UINT16)(1 << GpioIndex)) { + GpioRoute &= ~(3 << (GpioIndex * 2)); + GpioRoute |= (2 << (GpioIndex * 2)); + } + } + WRITE_PCI32_SB(R_PCH_LPC_GPI_ROUT, GpioRoute); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EnableAcpiMode +// +// Description: This function enable ACPI mode by clearing all SMI and +// enabling SCI generation +// This routine is also called on a S3 resume for special ACPI +// programming. +// Status should not be cleared on S3 resume. Enables are +// already taken care of. +// +// Input: PI 0.91, 1.0 +// DispatchHandle - SMI dispatcher handle +// *DispatchContext - Pointer to the dispatch context +// PI 1.1, 1.2 +// DispatchHandle - SMI dispatcher handle +// *DispatchContext- Points to an optional S/W SMI context +// CommBuffer - Points to the optional communication +// buffer +// CommBufferSize - Points to the size of the optional +// communication buffer +// +// Output: EFI_STATUS if the new SMM PI is applied. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS EnableAcpiMode ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID EnableAcpiMode ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext ) +#endif +{ + + ACPI_DISPATCH_LINK *Link; + UINT16 wordValue; + UINT32 dwordValue; + PCH_SERIES PchSeries = GetPchSeries(); + +#if defined EMUL6064_SUPPORT && EMUL6064_SUPPORT == 1 + if (READ_PCI8_SB(R_PCH_LPC_ULKMC)) // 0x94 + WRITE_PCI8_SB(R_PCH_LPC_ULKMC, 0); // 0x94 +#endif + + if ( gFirstInFlag == 0 ) { + gFirstInFlag = 1; + + // Check if WAK bit is set, if yes skip clearing status + wordValue = READ_IO16_PM(ACPI_IOREG_PM1_STS); // 0x00 + if (wordValue & B_PCH_ACPI_PM1_STS_WAK) { + // NAPA-CHANGES Disable and Clear GPE0 Sources + if (PchSeries == PchLp) { + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_EN+0x0c, 0x0000); //GPE0_EN 0x9C + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_STS+0x0c, 0xffffffff); //GPE0_STS 0x8C + } else { + WRITE_IO32_PM(ACPI_IOREG_GPE0_EN, 0x0000); //GPE0_EN 0x28 + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS, 0xffffffff); //GPE0_STS 0x20 + } + } else { + //Disable SMI Sources + dwordValue = READ_IO32_PM(ACPI_IOREG_SMI_EN); //SMI_EN (SMI Control and Enable register.) + + dwordValue &= ~(B_PCH_SMI_EN_ON_SLP_EN | B_PCH_SMI_EN_SWSMI_TMR); // Clear SLP_SMI_EN and SWSMI_TMR bit. + + // [EIP76432]>> +#if defined EMUL6064_SUPPORT && EMUL6064_SUPPORT == 1 + dwordValue &= ~(B_PCH_SMI_EN_LEGACY_USB); +#endif + // <<[EIP76432] + + WRITE_IO32_PM(ACPI_IOREG_SMI_EN, dwordValue); + + //Disable and Clear PM1 Sources except power button + wPM1_SaveState = READ_IO16_PM(ACPI_IOREG_PM1_EN); //PM1_EN + WRITE_IO16_PM(ACPI_IOREG_PM1_EN, (UINT16)B_PCH_ACPI_PM1_EN_PWRBTN); //PM1_EN Bit 8: PWRBTN_EN + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0xffff); //PM1_STS 0x00 + + //Disable and Clear GPE0 Sources + if (PchSeries == PchLp) { + dGPE_SaveState = READ_IO16_PM(ACPI_PCHLP_IOREG_GPE0_EN+0x0c);//GPE0_EN 0x9C + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_EN+0x0c, 0x00000000); //GPE0_EN 0x9C + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_STS+0x0c, 0xffffffff); //GPE0_STS 0x8C + } else { + dGPE_SaveState = READ_IO16_PM(ACPI_IOREG_GPE0_EN);//GPE0_EN 0x28 + WRITE_IO32_PM(ACPI_IOREG_GPE0_EN, 0x00000000); //GPE0_EN 0x28 + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS, 0xffffffff); //GPE0_STS + } + + //Set day of month alarm invalid - ACPI 1.0 section 4.7.2.4 + IoWrite8(CMOS_ADDR_PORT, 0xd | 0x80); //RTC_REGD + IoWrite8(CMOS_DATA_PORT, 0); + } + } + + //SCI_EN = 1 + SET_IO8_PM(ACPI_IOREG_PM1_CNTL, B_PCH_ACPI_PM1_CNT_SCI_EN); //PM1_CNT + + SbGpioSciInit(); + + InitParts(DispatchHandle, DispatchContext); + + for (Link = gAcpiEnDispatchHead; Link; Link = Link->Link) + { + Link->Function(Link); + } + + WRITE_IO8 (PCI_DEBUG_PORT, SW_SMI_ACPI_ENABLE); + + return SMM_CHILD_DISPATCH_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DisableAcpiMode +// +// Description: This function disables ACPI mode by enabling SMI generation +// +// Input: PI 0.91, 1.0 +// DispatchHandle - SMI dispatcher handle +// *DispatchContext - Pointer to the dispatch context +// PI 1.1, 1.2 +// DispatchHandle - SMI dispatcher handle +// *DispatchContext- Points to an optional S/W SMI context +// CommBuffer - Points to the optional communication +// buffer +// CommBufferSize - Points to the size of the optional +// communication buffer +// +// Output: EFI_STATUS if the new SMM PI is applied. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS DisableAcpiMode ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID DisableAcpiMode ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext ) +#endif +{ + ACPI_DISPATCH_LINK *Link; + + //Clear PM Sources and set Enables + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0xffff); // 0x00 + WRITE_IO16_PM(ACPI_IOREG_PM1_EN, wPM1_SaveState); // 0x02 + + //Clear GPE0 Sources and set Enables + if (GetPchSeries() == PchLp) { + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_STS + 0x0c, 0xffffffff); //GPE0_STS 0x8C + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_EN + 0x0c, dGPE_SaveState); //GPE0_EN 0x9C + } else { + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS + 0, 0xffffffff); //GPE0_STS 0x20 + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS + 4, 0xffffffff); //GPE0_STS 0x24 + WRITE_IO32_PM(ACPI_IOREG_GPE0_EN, dGPE_SaveState); //GPE0_EN 0x28 + } + + //Disable SCI + RESET_IO8_PM(ACPI_IOREG_PM1_CNTL, BIT00); // 0x04 + InitParts2(DispatchHandle, DispatchContext); + for (Link = gAcpiDisDispatchHead; Link; Link = Link->Link) + { + Link->Function(Link); + } + + + WRITE_IO8 (PCI_DEBUG_PORT, SW_SMI_ACPI_DISABLE); + + return SMM_CHILD_DISPATCH_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AddLink +// +// Description: Create and add link to specified list. +// +// Input: Size - +// Head - +// Tail - +// +// Output: VOID Pointer +// +// Modified: +// +// Referrals: SmmAllocatePool +// +// Notes: Here is the control flow of this function: +// 1. Allocate Link in Smm Pool. +// 2. Add Link to end. +// 3. Return Link address. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID * AddLink( + IN UINT32 Size, + IN VOID **Head, + IN VOID **Tail) +{ + VOID *Link; + + if (pSmst->SmmAllocatePool(0, Size, &Link) != EFI_SUCCESS) return 0; + + ((GENERIC_LINK*)Link)->Link = 0; + if (!*Head) + { + *Head = *Tail = Link; + } + else + { + ((GENERIC_LINK*)*Tail)->Link = Link; + *Tail = Link; + } + + return Link; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RemoveLink +// +// Description: Remove link from specified list. +// +// Input: Handle - EFI Handle +// Head - +// Tail - +// +// Output: BOOLEAN +// TRUE if link was removed. FALSE if link not in the list. +// +// Modified: +// +// Referrals: SmmFreePool +// +// Notes: Here is the control flow of this function: +// 1. Search link list for Link. +// 2. Remove link from list. +// 3. Free link. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN RemoveLink( + IN EFI_HANDLE Handle, + IN VOID **Head, + IN VOID **Tail) +{ + GENERIC_LINK *PrevLink, *Link; + + PrevLink = *Head; + + // Is link first. Link address is the same as the Handle. + if (((GENERIC_LINK*)*Head) == Handle) + { + if (PrevLink == *Tail) *Tail = 0; // If Tail = Head, then 0. + *Head = PrevLink->Link; + pSmst->SmmFreePool(PrevLink); + return TRUE; + } + + // Find Link. + for (Link = PrevLink->Link; Link; PrevLink = Link, Link = Link->Link) + { + if (Link == Handle) // Link address is the same as the Handle. + { + if (Link == *Tail) *Tail = PrevLink; + PrevLink->Link = Link->Link; + pSmst->SmmFreePool(Link); + return TRUE; + } + } + + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiAcpiEnRegister +// +// Description: Register a Link on ACPI enable SMI. +// +// Input: This - +// Function - +// Context - +// +// +// Output: Handle - +// EFI_STATUS +// +// Modified: gAcpiEnDispatchHead, gAcpiEnDispatchTail +// +// Referrals: AddLink +// +// Notes: Here is the control flow of this function: +// 1. Verify if Context if valid. If invalid, +// return EFI_INVALID_PARAMETER. +// 2. Allocate structure and add to link list. +// 3. Fill link. +// 4. Enable Smi Source. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiAcpiEnRegister( + IN EFI_ACPI_DISPATCH_PROTOCOL *This, + IN EFI_ACPI_DISPATCH Function, + OUT EFI_HANDLE *Handle) +{ + ACPI_DISPATCH_LINK *NewLink; + + NewLink = AddLink(sizeof(ACPI_DISPATCH_LINK), \ + &gAcpiEnDispatchHead, \ + &gAcpiEnDispatchTail); + if (!NewLink) return EFI_OUT_OF_RESOURCES; + + NewLink->Function = Function; + *Handle = NewLink; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiAcpiEnUnregister +// +// Description: Unregister a Link on ACPI enable SMI. +// +// Input: This - +// Handle - +// +// Output: EFI_STATUS +// +// Modified: gAcpiEnDispatchHead, gAcpiEnDispatchTail +// +// Referrals: RemoveLink +// +// Notes: Here is the control flow of this function: +// 1. Remove link. If no link, return EFI_INVALID_PARAMETER. +// 2. Disable SMI Source if no other handlers using source. +// 3. Return EFI_SUCCESS. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiAcpiEnUnregister( + IN EFI_ACPI_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle) +{ + if (!RemoveLink(Handle, &gAcpiEnDispatchHead, &gAcpiEnDispatchTail)) + return EFI_INVALID_PARAMETER; + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiAcpiDisRegister +// +// Description: Register a Link on ACPI disable SMI. +// +// Input: This - +// Function - +// *Context - +// +// +// Output: Handle - EFI Handle +// EFI_STATUS +// +// Modified: gAcpiDisDispatchHead, gAcpiDisDispatchTail +// +// Referrals: AddLink +// +// Notes: Here is the control flow of this function: +// 1. Verify if Context if valid. If invalid, +// return EFI_INVALID_PARAMETER. +// 2. Allocate structure and add to link list. +// 3. Fill link. +// 4. Enable Smi Source. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiAcpiDisRegister( + IN EFI_ACPI_DISPATCH_PROTOCOL *This, + IN EFI_ACPI_DISPATCH Function, + OUT EFI_HANDLE *Handle) +{ + ACPI_DISPATCH_LINK *NewLink; + + NewLink = AddLink(sizeof(ACPI_DISPATCH_LINK), \ + &gAcpiDisDispatchHead, \ + &gAcpiDisDispatchTail); + if (!NewLink) return EFI_OUT_OF_RESOURCES; + + NewLink->Function = Function; + *Handle = NewLink; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiAcpiDisUnregister +// +// Description: Unregister a Link on ACPI Disable SMI. +// +// Input: This - +// Handle - EFI Handle +// +// Output: EFI_STATUS +// +// Modified: gAcpiDisDispatchHead, gAcpiDisDispatchTail +// +// Referrals: RemoveLink +// +// Notes: Here is the control flow of this function: +// 1. Remove link. If no link, return EFI_INVALID_PARAMETER. +// 2. Disable SMI Source if no other handlers using source. +// 3. Return EFI_SUCCESS. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiAcpiDisUnregister( + IN EFI_ACPI_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle) +{ + if (!RemoveLink(Handle, &gAcpiDisDispatchHead, &gAcpiDisDispatchTail)) + return EFI_INVALID_PARAMETER; + return EFI_SUCCESS; +} + +EFI_ACPI_DISPATCH_PROTOCOL gEfiAcpiEnDispatchProtocol = \ + {EfiAcpiEnRegister, EfiAcpiEnUnregister}; + +EFI_ACPI_DISPATCH_PROTOCOL gEfiAcpiDisDispatchProtocol = \ + {EfiAcpiDisRegister, EfiAcpiDisUnregister}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbAcpiS3PatchedFunction +// +// Description: This function will be called when ACPI S3 resuming. +// +// Input: PI 0.91, 1.0 +// DispatchHandle - SMI dispatcher handle +// *DispatchContext - Pointer to the dispatch context +// PI 1.1, 1.2 +// DispatchHandle - SMI dispatcher handle +// *DispatchContext- Points to an optional S/W SMI context +// CommBuffer - Points to the optional communication +// buffer +// CommBufferSize - Points to the size of the optional +// communication buffer +// +// Output: EFI_STATUS if the new SMM PI is applied. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS SbAcpiS3PatchedFunction ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID SbAcpiS3PatchedFunction ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext ) +#endif +{ +#if AMI_INIT_VERB_TABLE_IN_S3 + UINT8 CodecIdx; + UINT8 j; + UINT8 i; + UINT16 Cmd16; + UINT16 TimeOut; + UINT16 SDIPin; + UINT32 Buffer32; + UINT32 CodecId; + UINT32 Base32; + UINT8 VerbTblSize = sizeof(HdaVerbTbl) / \ + sizeof(HDA_VERB_TABLE); + volatile UINT32 *pHdaVerbTbl; + + if ((READ_MEM8_RCRB(RCRB_MMIO_FD) & 0x10) == 0) { // 0x3418 + Base32 = READ_PCI32_HDA(R_PCH_HDA_HDBARL) & B_PCH_HDA_HDBARL_LBA; // 0x10 + Cmd16 = READ_PCI16_HDA(R_PCH_HDA_COMMAND); + WRITE_PCI16_HDA(R_PCH_HDA_COMMAND, Cmd16 | B_PCH_HDA_COMMAND_MSE); + + // Deassert the CRST bit in Azalia to cause the link to start up + SET_MEM8(Base32 | R_HDA_GCTL, B_HDA_GCTL_CRST); + + // Turn off the link by writing a 0 to the Controller Reset bit in + // HD Audio, poll Controller Reset bit until it reads back as 0. + RESET_MEM8(Base32 | R_HDA_GCTL, B_HDA_GCTL_CRST); + + for (TimeOut = 0; TimeOut < 0x8000; TimeOut++) + if ((READ_MEM8(Base32 | R_HDA_GCTL) & B_HDA_GCTL_CRST) == 0) break; + + // Turn on the link again by writing a 1 to Controller Reset bit + // This causes a codec link re-enumeration. Delay for 1ms, + // then poll Controller Reset bit until it reads back 1. + SET_MEM8(Base32 | R_HDA_GCTL, B_HDA_GCTL_CRST); + CountTime(1000, PM_BASE_ADDRESS); // 1ms + + for (TimeOut = 0; TimeOut < 0x8000; TimeOut++) + if (READ_MEM8(Base32 | R_HDA_GCTL) & B_HDA_GCTL_CRST) break; + + // Set the map of SDI pins + SDIPin = READ_MEM8(Base32 | R_HDA_STATESTS); + for (CodecIdx = MAX_NUM_HD_CODECS; CodecIdx; CodecIdx--) { + if (SDIPin & (1 << (CodecIdx - 1))) { + SDIPin &= ~(1 << (CodecIdx - 1)); + for (TimeOut = 0; TimeOut < 0x8000; TimeOut++) { + if ((READ_MEM16(Base32 | R_HDA_IRS) & B_HDA_IRS_ICB) == 0) break; + } + + if (TimeOut == 0x8000) { + RESET_MEM8(Base32 | R_HDA_GCTL, B_HDA_GCTL_CRST); + SET_MEM8(Base32 | R_HDA_GCTL, B_HDA_GCTL_CRST); + } + + Buffer32 = ((CodecIdx - 1) << 28) | 0xf0000; + WRITE_MEM32(Base32|R_HDA_IC, Buffer32); + + SET_MEM16(Base32 | R_HDA_IRS, B_HDA_IRS_ICB | B_HDA_IRS_IRV); + + while ((READ_MEM16(Base32 | R_HDA_IRS) & (B_HDA_IRS_ICB | B_HDA_IRS_IRV)) != B_HDA_IRS_IRV); + + CodecId = READ_MEM32(Base32 | R_HDA_IR); + + // CheckforValidCodec + + if (VerbTblSize == 0) break; + + for (j = 0; j < VerbTblSize; j++) { + if (HdaVerbTbl[j].CodecId32 == CodecId) { + pHdaVerbTbl = HdaVerbTbl[j].VerbPtr; + Buffer32 = *pHdaVerbTbl; + if ((UINT8)(Buffer32 >> 28) == (CodecIdx - 1)) + break; + } + } + + // Program Pin Widget Configuration + if (j != VerbTblSize) { + pHdaVerbTbl = HdaVerbTbl[j].VerbPtr; + for(i = 0; i < (HdaVerbTbl[j].frontSideNo + HdaVerbTbl[j].RearSideNo) * 4; i++) { + // Poll the ICB bit of the ICS register at HDABAR + 68h[0] until it return 0. + for (TimeOut = 0; TimeOut < 0x8000; TimeOut++) { + if ((READ_MEM16(Base32 | R_HDA_IRS) & B_HDA_IRS_ICB) == 0) + break; + } + // Write the current verb(DWORD) to the IC register at HDABAR + 60h + WRITE_MEM32(Base32 | R_HDA_IC, *pHdaVerbTbl++); + // Send verb to Codec + SET_MEM16(Base32 | R_HDA_IRS, (B_HDA_IRS_ICB | B_HDA_IRS_IRV)); + } + } + } + } + } + + // Restore Command Register + WRITE_PCI16_HDA(R_PCH_HDA_COMMAND, Cmd16); +#endif + + return SMM_CHILD_DISPATCH_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InSmmFunction +// +// Description: Install ACPI Software SMI Handlers. +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InSmmFunction ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle = NULL; + EFI_HANDLE DummyHandle = NULL; + AMI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch = NULL; + AMI_SMM_SW_DISPATCH_CONTEXT AcpiEnableContext = {SW_SMI_ACPI_ENABLE}; + AMI_SMM_SW_DISPATCH_CONTEXT AcpiDisableContext = {SW_SMI_ACPI_DISABLE}; + AMI_SMM_SW_DISPATCH_CONTEXT AcpiS3PatchContext = {SW_SMI_SB_ACPI_S3}; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + EFI_SMM_SYSTEM_TABLE2 *pSmst2; +#endif + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = InitAmiSmmLib( ImageHandle, SystemTable ); + if (EFI_ERROR(Status)) return Status; + + // We are in SMM, retrieve the pointer to SMM System Table + Status = gSmmBase2->GetSmstLocation( gSmmBase2, &pSmst2); + if (EFI_ERROR(Status)) return EFI_UNSUPPORTED; + + Status = pSmst2->SmmLocateProtocol( &gEfiSmmSwDispatch2ProtocolGuid , \ + NULL, \ + &SwDispatch ); + TRACE((TRACE_ALWAYS, "Smm Locate Protocol gEfiSmmSwDispatch2ProtocolGuid, Status = %r\n",Status)); +#else + Status = pBS->LocateProtocol( &gEfiSmmSwDispatchProtocolGuid , \ + NULL, \ + &SwDispatch ); +#endif + if (EFI_ERROR(Status)) return Status; + + Status = SwDispatch->Register( SwDispatch, \ + SbAcpiS3PatchedFunction, \ + &AcpiS3PatchContext, \ + &Handle ); + if (EFI_ERROR(Status)) return Status; + + Status = SwDispatch->Register( SwDispatch, \ + EnableAcpiMode, \ + &AcpiEnableContext, \ + &Handle ); + if (EFI_ERROR(Status)) return Status; + + Status = SwDispatch->Register( SwDispatch, \ + DisableAcpiMode, \ + &AcpiDisableContext,\ + &Handle ); + if (EFI_ERROR(Status)) return Status; + + Status = pBS->InstallMultipleProtocolInterfaces( + &DummyHandle, + &gEfiAcpiEnDispatchProtocolGuid, + &gEfiAcpiEnDispatchProtocol, + &gEfiAcpiDisDispatchProtocolGuid, + &gEfiAcpiDisDispatchProtocol, + NULL); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AcpiModeEnableInit +// +// Description: installs appropriate ACPI enable/disable Dispatch Protocol. +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// +// Referrals: InitAmiLib, InitSmmHandler +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS AcpiModeEnableInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + InitAmiLib( ImageHandle, SystemTable ); + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = SystemTable->BootServices->LocateProtocol( \ + &gEfiSmmBase2ProtocolGuid, \ + NULL, \ + &gSmmBase2 ); + ASSERT_EFI_ERROR(Status); +#endif + + return InitSmmHandler( ImageHandle, SystemTable, InSmmFunction, NULL ); +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/AcpiModeEnable.cif b/Chipset/SB/AcpiModeEnable.cif new file mode 100644 index 0000000..371a6da --- /dev/null +++ b/Chipset/SB/AcpiModeEnable.cif @@ -0,0 +1,12 @@ +<component> + name = "AcpiModeEnable" + category = ModulePart + LocalRoot = "Chipset\SB" + RefName = "AcpiModeEnable" +[files] +"AcpiModeEnable.sdl" +"AcpiModeEnable.mak" +"AcpiModeEnable.c" +"AcpiModeEnable.dxs" +"AcpiModeEnable.h" +<endComponent> diff --git a/Chipset/SB/AcpiModeEnable.dxs b/Chipset/SB/AcpiModeEnable.dxs new file mode 100644 index 0000000..ec4f181 --- /dev/null +++ b/Chipset/SB/AcpiModeEnable.dxs @@ -0,0 +1,64 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.dxs 2 4/25/12 9:26a Victortu $ +// +// $Revision: 2 $ +// +// $Date: 4/25/12 9:26a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.dxs $ +// +// 2 4/25/12 9:26a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove unnecessary dependence. +// [Files] AcpiModeEnable.dxs; SBSMI.dxs; SleepSmi.dxs +// +// 1 2/08/12 8:30a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: AcpiModeEnable.DXS +// +// Description: Dependency file for the ACPI mode enable/disable driver +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <Protocol\SmmSwDispatch.h> + +DEPENDENCY_START + EFI_SMM_SW_DISPATCH_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/AcpiModeEnable.h b/Chipset/SB/AcpiModeEnable.h new file mode 100644 index 0000000..91943a8 --- /dev/null +++ b/Chipset/SB/AcpiModeEnable.h @@ -0,0 +1,123 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.h 1 2/08/12 8:30a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:30a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.h $ +// +// 1 2/08/12 8:30a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: AcpiModeEnable.h +// +// Description: +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#ifndef __SMM_ACPI_EN_PROTOCOL_H__ +#define __SMM_ACPI_EN_PROTOCOL_H__ +#ifdef __cplusplus +extern "C" { +#endif +#include <EFI.h> + +#define EFI_ACPI_EN_DISPATCH_PROTOCOL_GUID \ + { 0xbd88ec68, 0xebe4, 0x4f7b, 0x93, 0x5a, 0x4f,\ + 0x66, 0x66, 0x42, 0xe7, 0x5f } + +#define EFI_ACPI_DIS_DISPATCH_PROTOCOL_GUID \ + { 0x9c939ba6, 0x1fcc, 0x46f6, 0xb4, 0xe1, 0x10, \ + 0x2d, 0xbe, 0x18, 0x65, 0x67 } + +#define PM1_CNT 0x04 +#define BIT_WAK_STS 0x8000 +#define BIT_SLP_TYP_MASK 0x1C00 +#define S3_SLP_TYP 0x05 + +typedef struct _EFI_ACPI_DISPATCH_PROTOCOL EFI_ACPI_DISPATCH_PROTOCOL; + +//---------------------------------------------------------------------------- +// EFI_ACPI_DISPATCH +//---------------------------------------------------------------------------- + +#ifndef __SMM_CHILD_DISPATCH__H__ +typedef struct _GENERIC_LINK GENERIC_LINK; +typedef struct _GENERIC_LINK { + void *Link; +}; +#endif + +typedef VOID (EFIAPI *EFI_ACPI_DISPATCH) ( + IN EFI_HANDLE DispatchHandle +); + +typedef struct _ACPI_DISPATCH_LINK ACPI_DISPATCH_LINK; +struct _ACPI_DISPATCH_LINK { + IN ACPI_DISPATCH_LINK *Link; + IN EFI_ACPI_DISPATCH Function; +}; + +typedef EFI_STATUS (EFIAPI *EFI_ACPI_REGISTER) ( + IN EFI_ACPI_DISPATCH_PROTOCOL *This, + IN EFI_ACPI_DISPATCH DispatchFunction, + OUT EFI_HANDLE *DispatchHandle +); + +typedef EFI_STATUS (EFIAPI *EFI_ACPI_UNREGISTER) ( + IN EFI_ACPI_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE DispatchHandle +); + + +struct _EFI_ACPI_DISPATCH_PROTOCOL { + EFI_ACPI_REGISTER Register; + EFI_ACPI_UNREGISTER UnRegister; +}; + + +typedef EFI_STATUS (*EFI_TASK_FUNCTION) (VOID); + + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/AcpiModeEnable.mak b/Chipset/SB/AcpiModeEnable.mak new file mode 100644 index 0000000..260c96e --- /dev/null +++ b/Chipset/SB/AcpiModeEnable.mak @@ -0,0 +1,94 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.mak 2 7/02/12 10:16a Victortu $ +# +# $Revision: 2 $ +# +# $Date: 7/02/12 10:16a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.mak $ +# +# 2 7/02/12 10:16a Victortu +# [TAG] None +# [Category] Bug Fix +# [Severity] Normal +# [Symptom] System may hang at 0xB1 when boot to UEFI Windows 8. +# [Solution] Set Driver type to SMM_DRIVER. +# [Files] AcpiModeEnable.mak +# +# 1 2/08/12 8:29a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: AcpiModeEnable.MAK +# +# Description: Make file to enable/disable ACPI mode +# +#<AMI_FHDR_END> +#************************************************************************* +!IFNDEF PI_SPECIFICATION_VERSION +PI_SPECIFICATION_VERSION = 0 +!ENDIF + +all : AcpiModeEnable + +AcpiModeEnable : $(BUILD_DIR)\AcpiModeEnable.mak AcpiModeEnableBin + +$(BUILD_DIR)\AcpiModeEnable.mak : $(ACPI_MODE_ENABLE_DIR)\AcpiModeEnable.cif $(ACPI_MODE_ENABLE_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(ACPI_MODE_ENABLE_DIR)\AcpiModeEnable.cif $(CIF2MAK_DEFAULTS) + +AcpiModeEnable_INCLUDES=\ + /I$(Foundation_DIR)\ + /I$(PROJECT_DIR)\ + $(INTEL_PCH_INCLUDES)\ + +AcpiModeEnableBin : $(AMIDXELIB) $(AMICSPLib) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\AcpiModeEnable.mak all\ + "CFLAGS=$(CFLAGS) /I$(SB_BOARD_DIR) /D\"OEM_HDA_VERB_TABLE=$(OEM_HDA_VERB_TABLE)\" /D\"OEM_HDA_VERB_TABLE_CONTENT=$(OEM_HDA_VERB_TABLE_CONTENT)\""\ + GUID=750890A6-7ACF-4f4f-81BD-B400C2BEA95A\ + ENTRY_POINT=AcpiModeEnableInit\ + "MY_INCLUDES=$(AcpiModeEnable_INCLUDES)"\ +!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A && $(CORE_COMBINED_VERSION) >= 0x4028B + TYPE=SMM_DRIVER \ + DEPEX1=$(ACPI_MODE_ENABLE_DIR)\AcpiModeEnable.DXS \ +!ELSE + TYPE=BS_DRIVER \ + DEPEX1=$(ACPI_MODE_ENABLE_DIR)\AcpiModeEnable.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ +!ENDIF + COMPRESS=1\ + "INIT_LIST=$(AcpiEnableCallbackList)"\ + "INIT_LIST2=$(AcpiDisableCallbackList)" + +AcpiModeEnableBin : $(CSP_ACPI_OBJ_FILES) + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/AcpiModeEnable.sdl b/Chipset/SB/AcpiModeEnable.sdl new file mode 100644 index 0000000..4778722 --- /dev/null +++ b/Chipset/SB/AcpiModeEnable.sdl @@ -0,0 +1,125 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.sdl 4 10/01/12 5:51a Victortu $ +# +# $Revision: 4 $ +# +# $Date: 10/01/12 5:51a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/AcpiModeEnable/AcpiModeEnable.sdl $ +# +# 4 10/01/12 5:51a Victortu +# +# 3 9/26/12 3:57a Victortu +# [TAG] None +# [Category] Improvement +# [Description] Update for PCH LP GPIO compatible. +# [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +# SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +# SmiHandlerPorting.c, SmiHandlerPorting2.c +# +# 2 9/12/12 5:16a Victortu +# [TAG] None +# [Category] Improvement +# [Description] Modify for ULT GPIO changed by PCH LPT-LP EDS 1.0. +# [Files] SB.H, SB.sdl, AcpiModeEnable.c, AcpiModeEnable.sdl, +# SBPEI.c +# +# 1 2/08/12 8:29a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "AcpiModeEnable_SUPPORT" + Value = "1" + Help = "Main switch to enable AcpiModeEnable support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "SW_SMI_ACPI_ENABLE" + Value = "0xA0" + Help = "Value to be written into SMI command register \to enable SCI generation and switch to ACPI mode" + TokenType = Integer + TargetH = Yes + Range = "0-0xff" +End + +TOKEN + Name = "SW_SMI_ACPI_DISABLE" + Value = "0xA1" + Help = "Value to write into SMI command register to disable \SCI generation and switch to non ACPI mode" + TokenType = Integer + TargetH = Yes + Range = "0 - 0xff" +End + +TOKEN + Name = "GPIO_SCI_BITMAP" + Value = "0x0000" + Help = "Programming the corresponding GPIO pin to generate SCI#.\BIT00: GPIO0\BIT01: GPIO1\BIT02: GPIO2\.\.\.\BIT15: GPIO15" + TokenType = Integer + TargetH = Yes + Range = "0 - 0xffff" +End + +PATH + Name = "ACPI_MODE_ENABLE_DIR" +End + +MODULE + Help = "Includes AcpiModeEnable.mak to Project" + File = "AcpiModeEnable.mak" +End + +ELINK + Name = "$(BUILD_DIR)\AcpiModeEnable.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +ELINK + Name = "CSP_ACPI_OBJ_FILES" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "AcpiEnableCallbackList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "AcpiDisableCallbackList" + InvokeOrder = ReplaceParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, 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/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.c b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.c new file mode 100644 index 0000000..6177f8a --- /dev/null +++ b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.c @@ -0,0 +1,310 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Chipset/SouthBridge/LegacyInterrupt.c 14 7/28/10 2:46p Olegi $ +// +// $Revision: 14 $ +// +// $Date: 7/28/10 2:46p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Chipset/SouthBridge/LegacyInterrupt.c $ +// +// 14 7/28/10 2:46p Olegi +// +// 13 1/12/10 11:51a Olegi +// Copyright message updated. +// +// 12 10/14/09 12:26p Krishnakumarg +// CloseEvent funtion used instead of a static variable in callback +// routines - EIP 27065 +// +// 11 4/27/07 5:43p Olegi +// +// 10 4/27/07 5:39p Olegi +// +// 9 4/27/07 5:21p Olegi +// CSM.CHM preparations. +// +// 8 10/13/06 12:32a Felixp +// UEFI2.0 compliance: use CreateReadyToBootEvent instead of +// CreateEvent(READY_TO_BOOT) +// +// 7 5/27/05 4:24p Markw +// Added Boot Script. +// +// 6 4/04/05 4:19p Sivagarn +// Updated to latest template format +// +// 2 2/22/05 10:00a Sivagarn +// - Updated to latest labeled CSM & Core +// +// 5 1/18/05 3:22p Felixp +// PrintDebugMessage renamed to Trace +// +// 4 12/09/04 10:59a Olegi +// +// 3 12/06/04 9:37a Olegi +// Added interrupt router registers' buffering. +// +// 2 12/03/04 9:55a Olegi +// +// 1 10/26/04 9:48a Olegi +// +// 3 8/31/04 5:46p Markw +// Fixed bug. Using wrong value to index PirqReg. +// +// 2 8/25/04 4:58p Markw +// Added comments. +// +// 1 8/25/04 3:01p Markw +// +// 1 8/13/04 2:39p Markw +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: 8259InterruptController.c +// +// Description: Initialize and provide a protocol to set PIRQ values +// +//<AMI_FHDR_END> +//********************************************************************** + +#include <AmiDxeLib.h> +#include <Protocol\PciRootBridgeIo.h> +#include <Protocol\LegacyInterrupt.h> +#include <Protocol\BootScriptSave.h> + +extern UINT8 bMaxPIRQ; +extern UINT8 bRouterBus; +extern UINT8 bRouterDevice; +extern UINT8 bRouterFunction; + +EFI_GUID gEfiLegacyInterruptProtocolGuid = EFI_LEGACY_INTERRUPT_PROTOCOL_GUID; +EFI_GUID gEfiPciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; +EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID; + +EFI_EVENT gEvtBootScript; + +extern +EFI_STATUS +SBGen_InitializeRouterRegisters ( + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *gPciRootBridgeIo); + +extern +EFI_STATUS +SBGen_ReadPirq ( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + IN UINT8 PirqNumber, + OUT UINT8 *PirqData); + +EFI_STATUS +SBGen_WritePirq( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + IN UINT8 PirqNumber, + IN UINT8 PirqData); + +EFI_STATUS SBGen_WriteBootScript( + IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *BootScriptSave +); + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: GetNumberPirqs +// +// Description: Return number of supported Pirqs. +// +// Input: +// IN EFI_LEGACY_INTERRUPT_PROTOCOL *This +// OUT UINT8 *NumberPirqs +// +// Output: +// Status of the operation +// +// Notes: +// Here is the control flow of this function: +// 1. Set NumberPirqs to number of supported Pirqs. +// 2. Return EFI_SUCCESS; +// +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS GetNumberPirqs( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + OUT UINT8 *NumberPirqs + ) +{ + *NumberPirqs = bMaxPIRQ; + return EFI_SUCCESS; +} + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: GetLocation +// +// Description: Return location of device controlling the Pirqs. +// +// Input: +// IN EFI_LEGACY_INTERRUPT_PROTOCOL *This +// OUT UINT8 *Bus +// OUT UINT8 *Device +// OUT UINT8 *Function +// +// Output: +// Status of the operation +// +// Notes: +// Here is the control flow of this function: +// 1. Set Bus, Device, and Function. +// 2. Return EFI_SUCCESS. +// +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS GetLocation( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + OUT UINT8 *Bus, + OUT UINT8 *Device, + OUT UINT8 *Function + ) +{ + *Bus = bRouterBus; + *Device = bRouterDevice; + *Function = bRouterFunction; + return EFI_SUCCESS; +} + + + +EFI_LEGACY_INTERRUPT_PROTOCOL gEfiLegacyInterruptProtocol = +{ + GetNumberPirqs, GetLocation, + SBGen_ReadPirq, SBGen_WritePirq +}; + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: CallbackBootScript +// +// Description: Saves the PIRQ registers to Boot Script +// +// Input: +// IN EFI_EVENT Event +// IN VOID *Context +// Output: +// None +// +//<AMI_PHDR_END> +//********************************************************************** +VOID CallbackBootScript(IN EFI_EVENT Event, IN VOID *Context) +{ + EFI_BOOT_SCRIPT_SAVE_PROTOCOL *BootScriptSave; + EFI_STATUS Status; + + + Status = pBS->LocateProtocol( + &gEfiBootScriptSaveGuid, + NULL, + &BootScriptSave + ); + if (EFI_ERROR(Status)) return; + + SBGen_WriteBootScript(BootScriptSave); + + // + //Kill the Event + // + pBS->CloseEvent(Event); + +} + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: InitializeLegacyInterrupt +// +// Description: Install Legacy Interrupt Protocol. +// +// Input: +// IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: +// EFI_STATUS +// +// Notes: +// Here is the control flow of this function: +// 1. Intialize Library. +// 2. Locate PciRootBridgeIo. If error, return error. +// 3. Install Legacy Interrupt protocol. +// 4. Return its Status. +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS InitializeLegacyInterrupt( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *gPciRootBridgeIo; + + InitAmiLib(ImageHandle, SystemTable); + + Status = pBS->LocateProtocol( + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &gPciRootBridgeIo + ); + if (EFI_ERROR(Status)) return Status; + + //Create event for boot script + Status = CreateReadyToBootEvent( + TPL_NOTIFY, + CallbackBootScript, + NULL, + &gEvtBootScript + ); + ASSERT_EFI_ERROR(Status); + + // + // Initialize router registers buffer + // + Status = SBGen_InitializeRouterRegisters (gPciRootBridgeIo); + if (EFI_ERROR(Status)) return Status; + + return pBS->InstallMultipleProtocolInterfaces( + &ImageHandle, + &gEfiLegacyInterruptProtocolGuid, &gEfiLegacyInterruptProtocol, + NULL + ); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.cif b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.cif new file mode 100644 index 0000000..381450d --- /dev/null +++ b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.cif @@ -0,0 +1,11 @@ +<component> + name = "LegacyInterrupt" + category = ModulePart + LocalRoot = "Chipset\SB\CSM\LegacyInterrupt\" + RefName = "LegacyInterrupt" +[files] +"\LegacyInterrupt.sdl" +"\LegacyInterrupt.mak" +"\LegacyInterrupt.c" +"\LegacyInterrupt.dxs" +<endComponent> diff --git a/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.dxs b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.dxs new file mode 100644 index 0000000..7aca534 --- /dev/null +++ b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.dxs @@ -0,0 +1,65 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Chipset/SouthBridge/LegacyInterrupt.dxs 5 1/12/10 11:51a Olegi $ +// +// $Revision: 5 $ +// +// $Date: 1/12/10 11:51a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Chipset/SouthBridge/LegacyInterrupt.dxs $ +// +// 5 1/12/10 11:51a Olegi +// Copyright message updated. +// +// 4 4/27/07 5:21p Olegi +// CSM.CHM preparations. +// +// 3 8/23/05 11:51a Girim +// Updated Copyright Year +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: LegacyInterrupt.dxs +// +// Description: Legacy Interrupt dependency file +// +//<AMI_FHDR_END> +//********************************************************************** + +#include <Protocol\PciRootBridgeIo.h> +#include <Protocol\BootScriptSave.h> + +DEPENDENCY_START + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID AND + EFI_BOOT_SCRIPT_SAVE_GUID +DEPENDENCY_END + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.mak b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.mak new file mode 100644 index 0000000..6d23259 --- /dev/null +++ b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.mak @@ -0,0 +1,90 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/CSM/Generic/Chipset/SouthBridge/LegacyInterrupt.mak 8 1/12/10 11:51a Olegi $ +# +# $Revision: 8 $ +# +# $Date: 1/12/10 11:51a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/CSM/Generic/Chipset/SouthBridge/LegacyInterrupt.mak $ +# +# 8 1/12/10 11:51a Olegi +# Copyright message updated. +# +# 7 4/27/07 5:21p Olegi +# CSM.CHM preparations. +# +# 6 12/02/05 11:44a Felixp +# +# 5 4/04/05 4:19p Sivagarn +# Included CSP Library into the build process +# +# 2 2/22/05 10:00a Sivagarn +# - Updated to latest labeled CSM & Core +# +# 4 1/18/05 3:22p Felixp +# PrintDebugMessage renamed to Trace +# +# 3 12/24/04 3:42p Felixp +# +# 2 11/30/04 4:22p Felixp +# Updated in accordance with the latest build process +# +# 1 10/26/04 9:48a Olegi +# +# 1 8/25/04 3:01p Markw +# +# 1 8/13/04 2:39p Markw +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: LegacyInterrupt +# +# Description: Legacy Interrupt make file +# +#<AMI_FHDR_END> +#********************************************************************** +all : LegacyInterrupt + +LegacyInterrupt : $(BUILD_DIR)\LegacyInterrupt.mak LegacyInterruptBin + +$(BUILD_DIR)\LegacyInterrupt.mak : $(LEGACY_INTERRUPT_DIR)\$(@B).cif $(LEGACY_INTERRUPT_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(LEGACY_INTERRUPT_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +LegacyInterruptBin : $(AMIDXELIB) $(AMICSPLib) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\LegacyInterrupt.mak all\ + GUID=71ED12D1-250B-42fb-8C17-10DCFA771701\ + ENTRY_POINT=InitializeLegacyInterrupt\ + TYPE=BS_DRIVER\ + COMPRESS=1 + +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** diff --git a/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.sdl b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.sdl new file mode 100644 index 0000000..d6a7457 --- /dev/null +++ b/Chipset/SB/CSM/LegacyInterrupt/LegacyInterrupt.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "LegacyInterrupt_SUPPORT" + Value = "1" + Help = "Main switch to enable LegacyInterrupt support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "LEGACY_INTERRUPT_DIR" +End + +MODULE + Help = "Includes LegacyInterrupt.mak to Project" + File = "LegacyInterrupt.mak" +End + +ELINK + Name = "$(BUILD_DIR)\LegacyInterrupt.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/Chipset/SB/CSM/csmsb.cif b/Chipset/SB/CSM/csmsb.cif new file mode 100644 index 0000000..5a8509b --- /dev/null +++ b/Chipset/SB/CSM/csmsb.cif @@ -0,0 +1,8 @@ +<component> + name = "CSM SB-Generic" + category = ModulePart + LocalRoot = "Chipset\SB\CSM\" + RefName = "CSMSB" +[parts] +"LegacyInterrupt" +<endComponent> diff --git a/Chipset/SB/GbE_OR.BIN b/Chipset/SB/GbE_OR.BIN Binary files differnew file mode 100644 index 0000000..6668f11 --- /dev/null +++ b/Chipset/SB/GbE_OR.BIN diff --git a/Chipset/SB/IDE.ASL b/Chipset/SB/IDE.ASL new file mode 100644 index 0000000..b7a188e --- /dev/null +++ b/Chipset/SB/IDE.ASL @@ -0,0 +1,380 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/IDE.ASL 2 10/12/12 1:28a Scottyang $ +// +// $Revision: 2 $ +// +// $Date: 10/12/12 1:28a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/IDE.ASL $ +// +// 2 10/12/12 1:28a Scottyang +// [TAG] EIP83353 +// [Category] Improvement +// [Description] Correct IDE Mode SATA2 Ch1 Master timing. +// [Files] IDE.asl +// +// 1 2/08/12 8:25a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +DefinitionBlock ( + "Ide.aml", + "SSDT", + 1, + "IdeRef", + "IdeTable", + 0x1000 + ) +{ + +External(DSSP, IntObj) +External(FHPP, IntObj) +External(\_SB.PCI0.SAT0, DeviceObj) +External(\_SB.PCI0.SAT1, DeviceObj) + +Scope(\) +{ + // SATA Command Set + //---------------------------------------------------------------// + // Reg1 Reg2 Reg3 Reg4 Reg5 Reg6 Reg7 + //---------------------------------------------------------------// + Name(STFE, Buffer(){0x10, 0x06, 0x00, 0x00, 0x00, 0x00, 0xEF,}) // Set Features - Enable USE of SATA Feature + Name(STFD, Buffer(){0x90, 0x06, 0x00, 0x00, 0x00, 0x00, 0xEF,}) // Set Features - Disable USE of SATA Feature + Name(FZTF, Buffer(){0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5 }) // Freeze Lock Command + Name(DCFL, Buffer(){0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1 }) // Device Configuration Freeze Lock Command + + Name(SCBF, Buffer(21){}) // SATA Command Buffer to be returned + + // The number of SATA command + Name (CMDC, 0) // SATA Commands counter + + // Build the return buffer for GTF() control method + Method (GTFB, 2, Serialized) + // Arg0 - Command to write + // Arg1 - Subcommand value for "Set Feature command" + { + Multiply(CMDC, 56, Local0) + CreateField(SCBF, Local0, 56, CMDx) // Command field + Multiply(CMDC, 7, Local0) + CreateByteField(SCBF, Add(Local0, 1), A001) // Subcommand of "Set Feature" command + Store(Arg0, CMDx) // Store command into return buffer + Store(Arg1, A001) // Set Subcommand code + Increment(CMDC) + } +} + +Scope(\_SB.PCI0.SAT0) +{ + Name(REGF, 1) // PCI Bus access Flag + + Method(_REG, 2) // is PCI Config space accessible as OpRegion? + // _REG to update REGF status + { + If(LEqual(Arg0, 0x2)) + { + Store(Arg1, REGF) + } + } + // Buffer to be returned by _GTM + Name(TMD0, Buffer(20){}) // 5 DWORD length + CreateDWordField(TMD0, 00, PIO0) + CreateDWordField(TMD0, 04, DMA0) + CreateDWordField(TMD0, 8, PIO1) // do not use "08" + CreateDWordField(TMD0, 12, DMA1) + CreateDWordField(TMD0, 16, CHNF) + Device(CHN0) + { + Name(_ADR,0x00) + // Get Timing PIO/DMA Mode + Method(_GTM,0 ) { // Return Buffer + // PIO 0 Speed DWORD + // DMA 0 Speed DWORD + // PIO 1 Speed DWORD + // DMA 1 Speed DWORD + // Flags DWORD + + Store(120, PIO0) // Forced to PIO Mode 4 + Store(20, DMA0) // Forced to UDMA Mode 5 + Store(120, PIO1) // Forced to PIO Mode 4 + Store(20, DMA1) // Forced to UDMA Mode 5 + Store(0x05, CHNF) + Return (TMD0) + } // end Method _GTM +//////////////////////////////////////////////////////////////////////////////// + // Set Timing PIO/DMA Mode + Method(_STM, 3) // Arg 0 = Channel Timing Info (Package) + // Arg 1 = ATA Command set Master(Buffer) + // Arg 2 = ATA Command set Slave (Buffer) + { } // end Method _STM +//////////////////////////////////////////////////////////////////////////////// + + Device(DRV0) + { + Name(_ADR,0x00) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + If(LOr(DSSP, FHPP)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + // or FORCE_HDD_PASSWORD_PROMPT SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + Return(SCBF) + } + } + + Device(DRV1) + { + Name(_ADR,0x01) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LOr(DSSP, FHPP)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + // or FORCE_HDD_PASSWORD_PROMPT SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + Return(SCBF) + } + } + } + + Device(CHN1) + { + Name(_ADR,0x01) + +//////////////////////////////////////////////////////////////////////////////// + // Get Timing PIO/DMA Mode + Method(_GTM,0 ) { // Return Buffer + // PIO 0 Speed DWORD + // DMA 0 Speed DWORD + // PIO 1 Speed DWORD + // DMA 1 Speed DWORD + // Flags DWORD + + Store(120, PIO0) // Forced to PIO Mode 4 + Store(20, DMA0) // Forced to UDMA Mode 5 + Store(120, PIO1) // Forced to PIO Mode 4 + Store(20, DMA1) // Forced to UDMA Mode 5 + Store(0x05, CHNF) + + Return (TMD0) + } // end Method _GTM +//////////////////////////////////////////////////////////////////////////////// + // Set Timing PIO/DMA Mode + Method(_STM, 3) // Arg 0 = Channel Timing Info (Package) + // Arg 1 = ATA Command set Master(Buffer) + // Arg 2 = ATA Command set Slave (Buffer) + { } // end Method _STM +//////////////////////////////////////////////////////////////////////////////// + + Device(DRV0) + { + Name(_ADR,0x00) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LOr(DSSP, FHPP)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + // or FORCE_HDD_PASSWORD_PROMPT SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + Return(SCBF) + } + } + + Device(DRV1) + { + Name(_ADR,0x01) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LOr(DSSP, FHPP)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + // or FORCE_HDD_PASSWORD_PROMPT SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + Return(SCBF) + } + } + } +} + +Scope(\_SB.PCI0.SAT1) +{ + Name(REGF, 1) // PCI Bus access Flag + + Method(_REG, 2) // is PCI Config space accessible as OpRegion? + // _REG to update REGF status + { + If(LEqual(Arg0, 0x2)) + { + Store(Arg1, REGF) + } + } + + // Buffer to be returned by _GTM + Name(TMD0, Buffer(20){}) // 5 DWORD length + CreateDWordField(TMD0, 00, PIO0) + CreateDWordField(TMD0, 04, DMA0) + CreateDWordField(TMD0, 8, PIO1) // do not use "08" + CreateDWordField(TMD0, 12, DMA1) + CreateDWordField(TMD0, 16, CHNF) + + Device(CHN0) + { + Name(_ADR,0x00) + +//////////////////////////////////////////////////////////////////////////////// + // Get Timing PIO/DMA Mode + Method(_GTM,0 ) { // Return Buffer + // PIO 0 Speed DWORD + // DMA 0 Speed DWORD + // PIO 1 Speed DWORD + // DMA 1 Speed DWORD + // Flags DWORD + + Store(120, PIO0) // Forced to PIO Mode 4 + Store(20, DMA0) // Forced to UDMA Mode 5 + Store(120, PIO1) // Forced to PIO Mode 4 + Store(20, DMA1) // Forced to UDMA Mode 5 + Store(0x01, CHNF) + + Return (TMD0) + } // end Method _GTM +//////////////////////////////////////////////////////////////////////////////// + // Set Timing PIO/DMA Mode + Method(_STM, 3) // Arg 0 = Channel Timing Info (Package) + // Arg 1 = ATA Command set Master(Buffer) + // Arg 2 = ATA Command set Slave (Buffer) + { } // end Method _STM +//////////////////////////////////////////////////////////////////////////////// + + Device(DRV0) + { + Name(_ADR,0x00) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LOr(DSSP, FHPP)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + // or FORCE_HDD_PASSWORD_PROMPT SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + Return(SCBF) + } + } + } + + Device(CHN1) + { + Name(_ADR,0x01) + +//////////////////////////////////////////////////////////////////////////////// + // Get Timing PIO/DMA Mode + Method(_GTM,0 ) { // Return Buffer + // PIO 0 Speed DWORD + // DMA 0 Speed DWORD + // PIO 1 Speed DWORD + // DMA 1 Speed DWORD + // Flags DWORD + + Store(120, PIO0) // Forced to PIO Mode 4 + Store(20, DMA0) // Forced to UDMA Mode 5 + Store(120, PIO1) // Forced to PIO Mode 4 + Store(20, DMA1) // Forced to UDMA Mode 5 + Store(0x01, CHNF) + + Return (TMD0) + } // end Method _GTM +//////////////////////////////////////////////////////////////////////////////// + // Set Timing PIO/DMA Mode + Method(_STM, 3) // Arg 0 = Channel Timing Info (Package) + // Arg 1 = ATA Command set Master(Buffer) + // Arg 2 = ATA Command set Slave (Buffer) + { } // end Method _STM +//////////////////////////////////////////////////////////////////////////////// + + Device(DRV0) + { + Name(_ADR,0x01) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LOr(DSSP, FHPP)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + // or FORCE_HDD_PASSWORD_PROMPT SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + Return(SCBF) + } + } + } +} +}//end of SSDT + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, 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/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.c b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.c new file mode 100644 index 0000000..237366a --- /dev/null +++ b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.c @@ -0,0 +1,174 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.c 2 11/17/14 7:31a Mirayang $ +// +// $Revision: 2 $ +// +// $Date: 11/17/14 7:31a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.c $ +// +// 2 11/17/14 7:31a Mirayang +// [TAG] EIP191661 +// [Category] Improvement +// [Description] SUT can't generate UEFI SCT2.3.1 report completely. +// +// 1 2/08/12 8:33a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//---------------------------------------------------------------------- +// Includes +#include <AmiDxeLib.h> +#include <Protocol\LoadPe32Image.h> +#include "token.h" + + +static EFI_GUID gDxeSvcTblGuid = DXE_SERVICES_TABLE_GUID; +EFI_GUID gPchSpiRuntimeFFsGuid = \ + {0xC194C6EA,0xB68C,0x4981,0xB6,0x4B,0x9B,0xD2,0x71,0x47,0x4B,0x20}; + +EFI_STATUS +FFsLoaderToRuntime( + IN EFI_HANDLE ImageHandle +); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PchSpiWrapEntry +// +// Description: This function load PchSpi and execute it. +// +// Input: ImageHandle Image handle of this driver. +// SystemTable Global system service table. +// +// Output: EFI_SUCCESS Load and execute complete. +// EFI_UNSUPPORTED Image type is unsupported by this driver. +// EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +PchSpiWrapEntry( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + InitAmiLib(ImageHandle, SystemTable); + + Status = FFsLoaderToRuntime( ImageHandle); + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: FFsLoaderToRuntime +// +// Description: Load FFs to Runtime. +// +// Input: ImageHandle Image handle of this driver. +// +// Output: EFI_SUCCESS FFs Load to Runtime complete. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +FFsLoaderToRuntime( + IN EFI_HANDLE ImageHandle +){ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Dst; + EFI_PHYSICAL_ADDRESS EntryPoint; + EFI_PE32_IMAGE_PROTOCOL *LoadPeImageEx; + VOID *Buffer; + UINTN BufferSize; + UINT32 AuthenticationStatus; + UINTN Pages; + EFI_HANDLE FFsImageHandle; + EFI_DEVICE_PATH_PROTOCOL EndOfDp = { 0x7F, 0xFF, 0x4 , 0x0 }; + + Buffer = 0; + + Status = FvReadPe32Image ( + &gPchSpiRuntimeFFsGuid, + &Buffer, + &BufferSize, + &AuthenticationStatus + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Pages = EFI_SIZE_TO_PAGES (BufferSize) + 2; + Status = pBS->AllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesCode, + Pages, + &Dst + ); + + Status = pBS->LocateProtocol (&gEfiLoadPeImageGuid, NULL, &LoadPeImageEx); + if (EFI_ERROR (Status)) { + pBS->FreePool (&Dst); + return Status; + } + + Status = LoadPeImageEx->LoadPeImage( + LoadPeImageEx, + ImageHandle, +// NULL, + &EndOfDp, + Buffer, + BufferSize, + Dst, + &Pages, + &FFsImageHandle, + &EntryPoint, + EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE + ); + if (EFI_ERROR (Status)) { + pBS->FreePool (&Dst); + return Status; + } + + Status = pBS->StartImage(FFsImageHandle, NULL, NULL); + pBS->FreePool(Buffer); + + return Status; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.cif b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.cif new file mode 100644 index 0000000..7d6847b --- /dev/null +++ b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.cif @@ -0,0 +1,11 @@ +<component> + name = "PchSpiWrap" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\PchSpiWrap\" + RefName = "PchSpiWrap" +[files] +"PchSpiWrap.sdl" +"PchSpiWrap.mak" +"PchSpiWrap.c" +"PchSpiWrap.dxs" +<endComponent> diff --git a/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.dxs b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.dxs new file mode 100644 index 0000000..432fc02 --- /dev/null +++ b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.dxs @@ -0,0 +1,59 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.dxs 1 2/08/12 8:33a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:33a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.dxs $ +// +// 1 2/08/12 8:33a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: PchSpiWrap.dxs +// +// Description: This file is the dependency file for the Pch Spi Wrap driver. +// +//<AMI_FHDR_END> +//************************************************************************* + +#include <Protocol\Runtime.h> +#include <Protocol\PchPlatformPolicy\PchPlatformPolicy.h> + +DEPENDENCY_START + EFI_RUNTIME_ARCH_PROTOCOL_GUID AND + DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.mak b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.mak new file mode 100644 index 0000000..c22d22d --- /dev/null +++ b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.mak @@ -0,0 +1,58 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.mak 1 2/08/12 8:33a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:33a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.mak $ +# +# 1 2/08/12 8:33a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +all : PchSpiWrap + +PchSpiWrap : $(BUILD_DIR)\PchSpiWrap.mak PchSpiWrapBin + +$(BUILD_DIR)\PchSpiWrap.mak : $(PchSpiWrap_DIR)\$(@B).cif $(PchSpiWrap_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PchSpiWrap_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PchSpiWrapBin : $(AMICSPLib) $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\PchSpiWrap.mak all\ + GUID=B716A6F8-F3A1-4b8e-8582-5A303F1CDD64\ + "MY_INCLUDES=$(INTEL_PCH_INCLUDES)"\ + ENTRY_POINT=PchSpiWrapEntry\ + TYPE=RT_DRIVER \ + DEPEX1=$(PchSpiWrap_DIR)\PchSpiWrap.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1 +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.sdl b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.sdl new file mode 100644 index 0000000..950af3e --- /dev/null +++ b/Chipset/SB/PchWrap/PchSpiWrap/PchSpiWrap.sdl @@ -0,0 +1,75 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.sdl 1 2/08/12 8:32a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:32a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchSpiWrap/PchSpiWrap.sdl $ +# +# 1 2/08/12 8:32a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = PchSpiWrap_SUPPORT + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PchSpiWrap support in Project" +End + +MODULE + Help = "Includes PchSpiWrap.mak to Project" + File = "PchSpiWrap.mak" +End + +PATH + Name = "PchSpiWrap_DIR" +End + +TOKEN + Name = "PchSpiRuntime_GUID" + Value = "C194C6EA-B68C-4981-B64B-9BD271474B20" + Help = "GUID of AP initialization file." + TokenType = Expression + TargetMAK = Yes + TargetH = Yes +End + +ELINK + Name = "$(BUILD_DIR)\PchSpiWrap.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, 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/Chipset/SB/PchWrap/PchWrap.cif b/Chipset/SB/PchWrap/PchWrap.cif new file mode 100644 index 0000000..18da186 --- /dev/null +++ b/Chipset/SB/PchWrap/PchWrap.cif @@ -0,0 +1,13 @@ +<component> + name = "PchWrap" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\" + RefName = "PchWrap" +[files] +"PchWrap.sdl" +[parts] +"PchSpiWrap" +"WdtApp" +"PciHotPlug" +"SmBusMemoryDown" +<endComponent> diff --git a/Chipset/SB/PchWrap/PchWrap.sdl b/Chipset/SB/PchWrap/PchWrap.sdl new file mode 100644 index 0000000..ab9167e --- /dev/null +++ b/Chipset/SB/PchWrap/PchWrap.sdl @@ -0,0 +1,52 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchWrap.sdl 1 2/08/12 8:32a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:32a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PchWrap.sdl $ +# +# 1 2/08/12 8:32a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "PchWrap_SUPPORT" + Value = "1" + Help = "Main switch to enable PchWrap support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c new file mode 100644 index 0000000..34540d7 --- /dev/null +++ b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.c @@ -0,0 +1,544 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.c 6 5/16/14 5:56p Barretlin $ +// +// $Revision: 6 $ +// +// $Date: 5/16/14 5:56p $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.c $ +// +// 6 5/16/14 5:56p Barretlin +// [TAG] EIP165410 +// [Category] Improvement +// [Description] Support Thunderbolt AIC at NB PCIE slot +// [Files] PciHotplug.c +// +// 5 5/14/14 1:15p Barretlin +// [TAG] EIP165410 +// [Category] New Feature +// [Description] Support Thunderbolt AIC at NB PCIE slot +// [Files] PciHotPlug.c +// +// 4 4/24/13 5:02a Scottyang +// +// 3 9/12/12 5:15a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Modify for Thunderbolt support. +// [Files] GetSetupData.c, SB.sdl, SB.sd, SB.uni, SbSetupData.h, +// PciHotPlug.c +// +// 2 5/03/12 6:30a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Modify to support Thunderbolt. +// [Files] SB.sd; SB.uni; SB.sdl; SbSetupData.h; PciHotPlug.c +// +// 1 2/08/12 8:37a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +// +// Statements that include other files +// +#include "PciHotPlug.h" +#include <token.h> + +#define PCIE_NUM (11) + +// +// Instantiation of Driver private data. +// +PCIE_HOT_PLUG_DEVICE_PATH mPcieList[PCIE_NUM] = { + { + ACPI, + PCI(0x1C, 0), + END + }, // PCI Express 0 + { + ACPI, + PCI(0x1C, 1), + END + }, // PCI Express 1 + { + ACPI, + PCI(0x1C, 2), + END + }, // PCI Express 2 + { + ACPI, + PCI(0x1C, 3), + END + }, // PCI Express 3 + { + ACPI, + PCI(0x1C, 4), + END + }, // PCI Express 4 + { + ACPI, + PCI(0x1C, 5), + END + }, // PCI Express 5 + { + ACPI, + PCI(0x1C, 6), + END + }, // PCI Express 6 + { + ACPI, + PCI(0x1C, 7), + END + }, // PCI Express 7 + { + ACPI, + PCI(0x01, 0), + END + }, // NB PCI Express 0 + { + ACPI, + PCI(0x01, 1), + END + }, // NB PCI Express 1 + { + ACPI, + PCI(0x01, 2), + END + }, // NB PCI Express 2 +}; + +EFI_HPC_LOCATION mPcieLocation[PCIE_NUM] = { + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[0], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[0] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[1], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[1] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[2], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[2] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[3], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[3] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[4], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[4] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[5], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[5] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[6], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[6] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[7], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[7] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[8], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[8] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[9], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[9] + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[10], + (EFI_DEVICE_PATH_PROTOCOL *) &mPcieList[10] + }, +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PciHotPlug +// +// Description: This routine reads the PlatformType GPI on FWH and produces a protocol +// to be consumed by the chipset driver to effect those settings. +// +// Input: ImageHandle An image handle. +// SystemTable A pointer to the system table. +// +// Output: EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +PciHotPlug ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + PCI_HOT_PLUG_INSTANCE *PciHotPlug; + + + PciHotPlug = AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE)); + ASSERT (PciHotPlug != NULL); + + // + // Initialize driver private data. + // + ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE)); + + PciHotPlug->Signature = PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE; + PciHotPlug->HotPlugInitProtocol.GetRootHpcList = GetRootHpcList; + PciHotPlug->HotPlugInitProtocol.InitializeRootHpc = InitializeRootHpc; + PciHotPlug->HotPlugInitProtocol.GetResourcePadding = GetResourcePadding; + + Status = gBS->InstallProtocolInterface ( + &PciHotPlug->Handle, + &gEfiPciHotPlugInitProtocolGuid, + EFI_NATIVE_INTERFACE, + &PciHotPlug->HotPlugInitProtocol + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetRootHpcList +// +// Description: This procedure returns a list of Root Hot Plug controllers +// that require initialization during boot process +// +// Input: This The pointer to the instance of the +// EFI_PCI_HOT_PLUG_INIT protocol. +// HpcCount The number of Root HPCs returned. +// HpcList The list of Root HPCs. HpcCount defines the +// number of elements in this list. +// +// Output: EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +GetRootHpcList ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + OUT UINTN *HpcCount, + OUT EFI_HPC_LOCATION **HpcList + ) +{ + + *HpcCount = PCIE_NUM; + *HpcList = mPcieLocation; + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitializeRootHpc +// +// Description: This procedure Initializes one Root Hot Plug Controller +// This process may casue initialization of its subordinate buses +// +// Input: This The pointer to the instance of the +// EFI_PCI_HOT_PLUG_INIT protocol. +// HpcDevicePath The Device Path to the HPC that is being initialized. +// HpcPciAddress The address of the Hot Plug Controller function +// on the PCI bus. +// Event The event that should be signaled when the Hot +// Plug Controller initialization is complete. +// Set to NULL if the caller wants to wait until +// the entire initialization process is complete. +// The event must be of the type EFI_EVT_SIGNAL. +// HpcState The state of the Hot Plug Controller hardware. +// The type EFI_Hpc_STATE is defined in section 3.1. +// +// Output: EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +InitializeRootHpc ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + IN UINT64 HpcPciAddress, + IN EFI_EVENT Event, OPTIONAL + OUT EFI_HPC_STATE *HpcState + ) +{ + if (Event) { + gBS->SignalEvent (Event); + } + + *HpcState = EFI_HPC_STATE_INITIALIZED; + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetResourcePadding +// +// Description: Returns the resource padding required by the PCI bus that is +// controlled by the specified Hot Plug Controller. +// +// Input: This The pointer to the instance of the +// EFI_PCI_HOT_PLUG_INIT protocol. +// HpcDevicePath The Device Path to the HPC that is being initialized. +// HpcPciAddress The address of the Hot Plug Controller function +// on the PCI bus. +// HpcState The state of the Hot Plug Controller hardware. +// The type EFI_Hpc_STATE is defined in section 3.1. +// Padding This is the amount of resource padding required +// by the PCI bus under the control of the specified Hpc. +// Since the caller does not know the size of this buffer, +// this buffer is allocated by the callee and freed by the +// caller. +// Attribute Describes how padding is accounted for. +// +// Output: EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +GetResourcePadding ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + IN UINT64 HpcPciAddress, + OUT EFI_HPC_STATE *HpcState, + OUT VOID **Padding, + OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes + ) +{ + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource; + EFI_STATUS Status; + UINT8 FindRP; + UINT8 RsvdExtraBusNum = 0; + // (SB082311A)> + UINT16 RsvdPcieMegaMem = 0; + UINT8 RsvdPcieKiloIo = 0; + UINT16 RsvdPcieMegaPFMem = 0; + UINT8 RsvdPcieMegaMemalig = 0; + UINT8 RsvdPcieMegaPFMemalig = 0; + // <(SB082311A) + UINTN VariableSize; + SETUP_DATA SetupData; + EFI_GUID SetupGuid = SETUP_GUID; + UINT32 RPFN; //Root Port Function Number + UINT8 SwRPFN; + + PaddingResource = AllocatePool (PCIE_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + ASSERT (PaddingResource != NULL); + + *Padding = (VOID *) PaddingResource; + + RPFN = MmioRead32(SB_RCRB_BASE_ADDRESS + R_PCH_RCRB_RPFN); + DEBUG((EFI_D_INFO, "\nRCBA RPFN = %x\n", RPFN)); + // + // Check if PCIe Root Hob Controller need to reserve bus for docking downstream P2P hotplug + // + + VariableSize = sizeof(SETUP_DATA); + Status = gRT->GetVariable(L"Setup", + &SetupGuid, + NULL, + &VariableSize, + &SetupData); + + for (FindRP = 0; FindRP < PCIE_NUM; FindRP ++) { + if (HpcPciAddress == EFI_PCI_ADDRESS(0, 0x1C, FindRP, 0)) { + if (!EFI_ERROR(Status)) { + switch (FindRP){ + case 0: + SwRPFN = (UINT8)(RPFN & B_PCH_RCRB_RPFN_RP1FN); + break; + case 1: + SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP2FN) >> 4); + break; + case 2: + SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP3FN) >> 8); + break; + case 3: + SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP4FN) >> 12); + break; + case 4: + SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP5FN) >> 16); + break; + case 5: + SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP6FN) >> 20); + break; + case 6: + SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP7FN) >> 24); + break; + case 7: + SwRPFN = (UINT8)((RPFN & B_PCH_RCRB_RPFN_RP8FN) >> 28); + break; + default: + ASSERT_EFI_ERROR(EFI_DEVICE_ERROR); + } + DEBUG((EFI_D_INFO, "FindRP = %x\nSwRPFN = %x\n", FindRP, SwRPFN)); +#if (defined SB_SETUP_SUPPORT && SB_SETUP_SUPPORT) || \ + (defined OEM_SB_SETUP_SUPPORT && OEM_SB_SETUP_SUPPORT) + if (SwRPFN == FindRP) { + DEBUG((EFI_D_INFO, "PCIE Root Port#%x does not swap...\n", FindRP)); + if (SetupData.PcieRootPortHPE[FindRP]){ + RsvdExtraBusNum = SetupData.ExtraBusRsvd[FindRP]; + RsvdPcieMegaMem = SetupData.PcieMemRsvd[FindRP]; + RsvdPcieMegaPFMem = SetupData.PciePFMemRsvd[FindRP]; + RsvdPcieKiloIo = SetupData.PcieIoRsvd[FindRP]; + RsvdPcieMegaMemalig = SetupData.PcieMemRsvdalig[FindRP]; + RsvdPcieMegaPFMemalig = SetupData.PciePFMemRsvdalig[FindRP]; + } + } + else{ + DEBUG((EFI_D_INFO, "PCIE Root Port#%x is mapping to PCIE slot#%x...\n", FindRP, SwRPFN)); + if (SetupData.PcieRootPortHPE[SwRPFN]){ + RsvdExtraBusNum = SetupData.ExtraBusRsvd[SwRPFN]; + RsvdPcieMegaMem = SetupData.PcieMemRsvd[SwRPFN]; + RsvdPcieMegaPFMem = SetupData.PciePFMemRsvd[SwRPFN]; + RsvdPcieKiloIo = SetupData.PcieIoRsvd[SwRPFN]; + RsvdPcieMegaMemalig = SetupData.PcieMemRsvdalig[SwRPFN]; + RsvdPcieMegaPFMemalig = SetupData.PciePFMemRsvdalig[SwRPFN]; + } + } +#endif + } + break; + } // SB PCIE root port +#if defined Thunderbolt_SUPPORT && Thunderbolt_SUPPORT == 1 + if (HpcPciAddress == EFI_PCI_ADDRESS(0, 0x01, (FindRP - 8), 0)) { + if (!EFI_ERROR(Status)) { + DEBUG((EFI_D_INFO, "Hotplug root port is NB PCIE root port\n")); + if ((SetupData.TbtEnable != 0) && (SetupData.TbtHostLocation >= 0x20) && (SetupData.TbtHostLocation < 0x23)){ + DEBUG((EFI_D_INFO, "Update resource for NB PCIE root port\n")); + RsvdExtraBusNum = TBT_DEFAULT_EXTRA_BUS_RESERVED; + RsvdPcieMegaMem = TBT_DEFAULT_PCIE_MEM_RESERVED; + RsvdPcieMegaPFMem = TBT_DEFAULT_PCIE_PF_MEM_RESERVED; + RsvdPcieKiloIo = TBT_DEFAULT_PCIE_IO_RESERVED; + RsvdPcieMegaMemalig = 26; + RsvdPcieMegaPFMemalig = 28; + } + } + } // NB PCIE root port +#endif + } // for loop + + // + // Padding for bus + // + ZeroMem (PaddingResource, PCIE_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + *Attributes = EfiPaddingPciBus; + + PaddingResource->Desc = 0x8A; + PaddingResource->Len = 0x2B; + PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS; + PaddingResource->GenFlag = 0x0; + PaddingResource->SpecificFlag = 0; + PaddingResource->AddrRangeMin = 0; + PaddingResource->AddrRangeMax = 0; + PaddingResource->AddrLen = RsvdExtraBusNum; + + // + // Padding for non-prefetchable memory + // + PaddingResource++; + PaddingResource->Desc = 0x8A; + PaddingResource->Len = 0x2B; + PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + PaddingResource->GenFlag = 0x0; + PaddingResource->AddrSpaceGranularity = 32; + PaddingResource->SpecificFlag = 0; + // + // Pad non-prefetchable + // + PaddingResource->AddrRangeMin = 0; + PaddingResource->AddrLen = RsvdPcieMegaMem * 0x100000; + PaddingResource->AddrRangeMax = (1 << RsvdPcieMegaMemalig) - 1; // 0x3FFFFFF + + // + // Padding for prefetchable memory + // + PaddingResource++; + PaddingResource->Desc = 0x8A; + PaddingResource->Len = 0x2B; + PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + PaddingResource->GenFlag = 0x0; + PaddingResource->AddrSpaceGranularity = 32; + PaddingResource->SpecificFlag = 06; + // + // Padding for prefetchable memory + // + PaddingResource->AddrRangeMin = 0; + PaddingResource->AddrLen = RsvdPcieMegaPFMem * 0x100000; + // + // Pad 16 MB of MEM + // + PaddingResource->AddrRangeMax = (1 << RsvdPcieMegaPFMemalig) - 1; // 0xfffffff + // + // Alignment + // + // Padding for I/O + // + PaddingResource++; + PaddingResource->Desc = 0x8A; + PaddingResource->Len = 0x2B; + PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; + PaddingResource->GenFlag = 0x0; + PaddingResource->SpecificFlag = 0; + PaddingResource->AddrRangeMin = 0; + PaddingResource->AddrLen = RsvdPcieKiloIo * 0x400; + // + // Pad 4K of IO + // + PaddingResource->AddrRangeMax = 1; + // + // Alignment + // + // Terminate the entries. + // + PaddingResource++; + ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc = ACPI_END_TAG_DESCRIPTOR; + ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum = 0x0; + + *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED; + + return EFI_SUCCESS; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + diff --git a/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.cif b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.cif new file mode 100644 index 0000000..5a46b95 --- /dev/null +++ b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.cif @@ -0,0 +1,12 @@ +<component> + name = "PciHotPlug" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\PciHotPlug" + RefName = "PciHotPlug" +[files] +"PciHotPlug.sdl" +"PciHotPlug.mak" +"PciHotPlug.c" +"PciHotPlug.h" +"PciHotPlug.dxs" +<endComponent> diff --git a/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.dxs b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.dxs new file mode 100644 index 0000000..d6a5059 --- /dev/null +++ b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.dxs @@ -0,0 +1,61 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.dxs 1 2/08/12 8:37a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:37a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.dxs $ +// +// 1 2/08/12 8:37a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "DxeDepex.h" + +// +// BUILD_WITH_GLUELIB is turned "on" in R8 codebase; +// BUILD_WITH_GLUELIB is turned "off" in R9 codebase. +// +#ifdef BUILD_WITH_GLUELIB +#include "EfiDepex.h" +#endif + +DEPENDENCY_START + TRUE +DEPENDENCY_END +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + diff --git a/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.h b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.h new file mode 100644 index 0000000..295e721 --- /dev/null +++ b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.h @@ -0,0 +1,198 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.h 2 4/24/13 5:02a Scottyang $ +// +// $Revision: 2 $ +// +// $Date: 4/24/13 5:02a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.h $ +// +// 2 4/24/13 5:02a Scottyang +// +// 1 2/08/12 8:37a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +#ifndef _PCI_HOT_PLUG_H_ +#define _PCI_HOT_PLUG_H_ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#if !defined (EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) + +#include "EdkIIGlueDxe.h" + +#include "PchRegs.h" +#include "PchRegsRcrb.h" + +#include EFI_PROTOCOL_DEFINITION (PciHotPlugInit) +#include EFI_PROTOCOL_DEFINITION (PciRootBridgeIo) +#include "Acpi.h" + +// without these include guards, setup.h would include AMI EFI definitions conflicting with those from EDK +#define __UEFI_HII__H__ +#if EFI_SPECIFICATION_VERSION >= 0x2000A +#define __HII_CONFIG_ACCESS__H__ +#else +#define __HII_PROTOCOL_H__ +#define _HII_H_ +#define __FORM_CALLBACK_PROTOCOL_H__ +#endif +#include <Setup.h> +#endif + +#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE EFI_SIGNATURE_32 ('G', 'U', 'L', 'P') + +#define ACPI \ + { \ + ACPI_DEVICE_PATH, ACPI_DP, (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \ + ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), EISA_PNP_ID (0x0A03), 0 \ + } + +#define PCI(device, function) \ + { \ + HARDWARE_DEVICE_PATH, HW_PCI_DP, (UINT8) (sizeof (PCI_DEVICE_PATH)), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8), \ + (UINTN) function, (UINTN) device \ + } + +#define END \ + { \ + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, END_DEVICE_PATH_LENGTH, 0 \ + } + +#define LPC(eisaid, function) \ + { \ + ACPI_DEVICE_PATH, ACPI_DP, (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \ + ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), EISA_PNP_ID (eisaid), function \ + } + +typedef struct PCIE_HOT_PLUG_DEVICE_PATH { + ACPI_HID_DEVICE_PATH PciRootBridgeNode; + PCI_DEVICE_PATH PciRootPortNode; + EFI_DEVICE_PATH_PROTOCOL EndDeviceNode; +} PCIE_HOT_PLUG_DEVICE_PATH; + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; // Handle for protocol this driver installs on + EFI_PCI_HOT_PLUG_INIT_PROTOCOL HotPlugInitProtocol; +} PCI_HOT_PLUG_INSTANCE; + +EFI_STATUS +GetRootHpcList ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + OUT UINTN *PhpcCount, + OUT EFI_HPC_LOCATION **PhpcList + ) +/*++ + +Routine Description: + + This procedure returns a list of Root Hot Plug controllers that require + initialization during boot process + +Arguments: + + This - The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. + PhpcCount - The number of Root HPCs returned. + PhpcList - The list of Root HPCs. HpcCount defines the number of elements in this list. +Returns: + + EFI_SUCCESS. + +--*/ +; + +EFI_STATUS +InitializeRootHpc ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *PhpcDevicePath, + IN UINT64 PhpcPciAddress, + IN EFI_EVENT Event, OPTIONAL + OUT EFI_HPC_STATE *PhpcState + ) +/*++ + +Routine Description: + + This procedure Initializes one Root Hot Plug Controller + This process may casue initialization of its subordinate buses + +Arguments: + + This - The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. + PhpcDevicePath - The Device Path to the HPC that is being initialized. + PhpcPciAddress - The address of the Hot Plug Controller function on the PCI bus. + Event - The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL. + PhpcState - The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1. + +Returns: + + EFI_SUCCESS. +--*/ +; + +EFI_STATUS +GetResourcePadding ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *PhpcDevicePath, + IN UINT64 PhpcPciAddress, + OUT EFI_HPC_STATE *PhpcState, + OUT VOID **Padding, + OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes + ) +/*++ + +Routine Description: + + Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller. + +Arguments: + + This - The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized. + PhpcDevicePath - The Device Path to the Hot Plug Controller. + PhpcPciAddress - The address of the Hot Plug Controller function on the PCI bus. + PhpcState - The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1. + Padding - This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller. + Attributes - Describes how padding is accounted for. + +Returns: + + EFI_SUCCESS. +--*/ +; + +#endif +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + diff --git a/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.mak b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.mak new file mode 100644 index 0000000..62c3a01 --- /dev/null +++ b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.mak @@ -0,0 +1,98 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.mak 2 2/24/12 2:00a Victortu $ +# +# $Revision: 2 $ +# +# $Date: 2/24/12 2:00a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.mak $ +# +# 2 2/24/12 2:00a Victortu +# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00. +# +# 1 2/08/12 8:37a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +#--------------------------------------------------------------------------- +# Create PciHotPlug Driver +#--------------------------------------------------------------------------- +EDK : PciHotPlug + +PciHotPlug : $(BUILD_DIR)\PciHotPlug.mak PciHotPlugBin + +$(BUILD_DIR)\PciHotPlug.mak : $(PciHotPlug_DIR)\$(@B).cif $(PciHotPlug_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PciHotPlug_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PciHotPlug_INCLUDES=\ + $(INTEL_PCH_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(NB_INCLUDES)\ + $(SB_INCLUDES)\ + /I$(PROJECT_DIR)\ + /IInclude\ + +PciHotPlug_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PciHotPlug"\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \ + +PciHotPlug_LIB_LINKS =\ + $(EDKPROTOCOLLIB) \ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueDxeMemoryAllocationLib_LIB)\ + $(EDKFRAMEWORKPROTOCOLLIB) + +PciHotPlugBin: $(PciHotPlug_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PciHotPlug.mak all \ + "MY_INCLUDES=$(PciHotPlug_INCLUDES)"\ + "MY_DEFINES=$(PciHotPlug_DEFINES)"\ + GUID=3022E512-B94A-4f12-806D-7EF1177899D8\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER\ + EDKIIModule=DXEDRIVER\ + DEPEX1=$(PciHotPlug_DIR)\PciHotPlug.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\ + COMPRESS=1 +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.sdl b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.sdl new file mode 100644 index 0000000..4a3cbf9 --- /dev/null +++ b/Chipset/SB/PchWrap/PciHotPlug/PciHotPlug.sdl @@ -0,0 +1,75 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.sdl 1 2/08/12 8:37a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:37a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/PciHotPlug/PciHotPlug.sdl $ +# +# 1 2/08/12 8:37a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "PciHotPlug_SUPPORT" + Value = "1" + Help = "Main switch to enable PciHotPlug support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "AMI_ROOT_BRIDGE_SUPPORT" "=" "0" + Token = "HOTPLUG_SUPPORT" "=" "1" +End + +MODULE + Help = "Includes PciHotPlug to Project" + File = "PciHotPlug.mak" +End + + +ELINK + Name = "PciHotPlug" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PciHotPlug.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +PATH + Name = "PciHotPlug_DIR" +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.c b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.c new file mode 100644 index 0000000..8e081d1 --- /dev/null +++ b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.c @@ -0,0 +1,252 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/SmBusMemoryDown.c 1 12/11/12 1:09a Scottyang $ +// +// $Date: 12/11/12 1:09a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmBusMemoryDown.c +// +// Description: SmBus support MemoryDown functions implementation +// +//<AMI_FHDR_END> +//************************************************************************* + +#include <efi.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include <Protocol\SmBus.h> + +EFI_SMBUS_HC_PROTOCOL *SmBusProtocol = NULL; +static EFI_SMBUS_HC_EXECUTE_OPERATION PchSmBusExecute = NULL; +EFI_EVENT gSmBusMemoryDownEvent; +VOID *gSmBusMemoryDownEventReg; +UINT8 IsRunMemoryDown = 0; +EFI_GUID gEfiSMBusProtocolGuid = EFI_SMBUS_HC_PROTOCOL_GUID; + +#ifndef AMI_OVERRIDE_FOR_MEMORY_DOWN +#if defined(NB_OEM_DIMM1_STATUS) && (NB_OEM_DIMM1_STATUS == 0x02) +static UINT8 Dimm1SpdTbl[] = NB_OEM_DIMM1_SPD_DATA; +#endif +#if defined(NB_OEM_DIMM2_STATUS) && (NB_OEM_DIMM2_STATUS == 0x02) +static UINT8 Dimm2SpdTbl[] = NB_OEM_DIMM2_SPD_DATA; +#endif +#if defined(NB_OEM_DIMM3_STATUS) && (NB_OEM_DIMM3_STATUS == 0x02) +static UINT8 Dimm3SpdTbl[] = NB_OEM_DIMM3_SPD_DATA; +#endif +#if defined(NB_OEM_DIMM4_STATUS) && (NB_OEM_DIMM4_STATUS == 0x02) +static UINT8 Dimm4SpdTbl[] = NB_OEM_DIMM4_SPD_DATA; +#endif +#endif // AMI_OVERRIDE_FOR_MEMORY_DOWN + +VOID OverrideSmBusNotify ( + IN EFI_EVENT Event, + IN VOID *Context +); + + +//************************************************************************* +//<AMI_PHDR_START> +// +// Procedure: OverrideSmBusExecute +// +// Description: Init SmBus MemoryDown Protocol Execute.. +// +// Input: +// +// Output: +// +//<AMI_PHDR_END> +//************************************************************************* +EFI_STATUS +EFIAPI +OverrideSmBusExecute ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + UINT8 *DimmSpd = NULL; + UINT8 *BufferPoint = Buffer; + UINT16 i = 0; + + if (IsRunMemoryDown) { +#ifdef NB_OEM_DIMM1_SPD_DATA + if(SlaveAddress.SmbusDeviceAddress == DIMM1_SMBUS_ADDRESS >> 1) { + DimmSpd = Dimm1SpdTbl; + } +#endif +#ifdef NB_OEM_DIMM2_SPD_DATA + if(SlaveAddress.SmbusDeviceAddress == DIMM2_SMBUS_ADDRESS >> 1) { + DimmSpd = Dimm2SpdTbl; + } +#endif +#ifdef NB_OEM_DIMM3_SPD_DATA + if(SlaveAddress.SmbusDeviceAddress == DIMM3_SMBUS_ADDRESS >> 1) { + DimmSpd = Dimm3SpdTbl; + } +#endif +#ifdef NB_OEM_DIMM4_SPD_DATA + if(SlaveAddress.SmbusDeviceAddress == DIMM4_SMBUS_ADDRESS >> 1) { + DimmSpd = Dimm4SpdTbl; + } +#endif + if (DimmSpd != NULL) { + for (i=0; i <= *Length; i++) { + *BufferPoint = DimmSpd[Command + i]; + BufferPoint++; + } + return EFI_SUCCESS; + } + } + + return PchSmBusExecute ( + This, + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer + ); + +} +//************************************************************************* +//<AMI_PHDR_START> +// +// Procedure: OverrideSmBusNotify +// +// Description: Override SmBus Protocol Execute. +// +// Input: +// IN EFI_LEGACY_REGION_PROTOCOL *This, +// IN UINT32 Start, +// IN UINT32 Length, +// OUT UINT32 *Granularity, +// IN BOOLEAN *On +// +// Output: +// Status of the operation +// +//<AMI_PHDR_END> +//************************************************************************* +VOID OverrideSmBusNotify ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status; + + Status = pBS->LocateProtocol (&gEfiSmbusProtocolGuid, NULL, (VOID**) &SmBusProtocol); + if (!EFI_ERROR (Status)) { + + PchSmBusExecute = SmBusProtocol->Execute; + SmBusProtocol->Execute = OverrideSmBusExecute; + } + // Kill event + pBS->CloseEvent(Event); +} +//************************************************************************* +//<AMI_PHDR_START> +// +// Procedure: InitSmBusMemoryDown +// +// Description: Override the SmBus protocol. +// +// Input: +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: +// Status of the operation +// +// Notes: +// Here is the control flow of this function: +// 1. Get SmBus protocol. +// 2. Override the SmBus protocol. +// +//<AMI_PHDR_END> +//************************************************************************* +EFI_STATUS InitSmBusMemoryDown( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + NB_SETUP_DATA *NBSetupData = NULL; + UINTN VariableSize = sizeof(NB_SETUP_DATA); + + + InitAmiLib(ImageHandle, SystemTable); + + Status = pBS->AllocatePool( EfiBootServicesData, \ + VariableSize, \ + &NBSetupData ); + ASSERT_EFI_ERROR(Status); + + GetNbSetupData( pRS, NBSetupData, FALSE ); + + if (NBSetupData->IsRunMemoryDown) { + IsRunMemoryDown = NBSetupData->IsRunMemoryDown; + + + //NbSetupdata Pass to SaGlobalNvsArea. + Status = pBS->CreateEvent ( + EFI_EVENT_NOTIFY_SIGNAL, + TPL_CALLBACK, + OverrideSmBusNotify, + NULL, + &gSmBusMemoryDownEvent + ); + + if (!EFI_ERROR (Status)) { + Status = pBS->RegisterProtocolNotify ( + &gEfiSMBusProtocolGuid, + gSmBusMemoryDownEvent, + &gSmBusMemoryDownEventReg + ); + } + + } + // Free memory used for setup data + pBS->FreePool( NBSetupData ); + + return Status; + +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.cif b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.cif new file mode 100644 index 0000000..d187e08 --- /dev/null +++ b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.cif @@ -0,0 +1,11 @@ +<component> + name = "SmBusMemoryDown" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\SmBusMemoryDown\" + RefName = "SmBusMemoryDown" +[files] +"SmBusMemoryDown.sdl" +"SmBusMemoryDown.mak" +"SmBusMemoryDown.dxs" +"SmBusMemoryDown.c" +<endComponent> diff --git a/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.dxs b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.dxs new file mode 100644 index 0000000..6b1acfb --- /dev/null +++ b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.dxs @@ -0,0 +1,50 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/SmBusMemoryDown.dxs 1 12/11/12 1:09a Scottyang $ +// +// $Date: 12/11/12 1:09a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmBusMemoryDown.dxs +// +// Description: SmBusMemoryDown dependency file +// +//<AMI_FHDR_END> +//************************************************************************* + +DEPENDENCY_START + TRUE +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.mak b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.mak new file mode 100644 index 0000000..c99931f --- /dev/null +++ b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.mak @@ -0,0 +1,44 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +all : SmBusMemoryDown + +SmBusMemoryDown : $(BUILD_DIR)\SmBusMemoryDown.mak SmBusMemoryDownBin + +$(BUILD_DIR)\SmBusMemoryDown.mak : $(SMBUS_MEMORYDOWN_DIR)\$(@B).cif $(SMBUS_MEMORYDOWN_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SMBUS_MEMORYDOWN_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +SmBusMemoryDownBin : $(AMIDXELIB) $(AMICSPLib) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SmBusMemoryDown.mak all\ + GUID=F6A59595-BB9F-415b-A7F3-DC7C09387BE6 \ + ENTRY_POINT=InitSmBusMemoryDown \ + DEPEX1=$(SMBUS_MEMORYDOWN_DIR)\SmBusMemoryDown.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + TYPE=BS_DRIVER \ + COMPRESS=1\ + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2012, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.sdl b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.sdl new file mode 100644 index 0000000..e5f0206 --- /dev/null +++ b/Chipset/SB/PchWrap/SmBusMemoryDown/SmBusMemoryDown.sdl @@ -0,0 +1,27 @@ +TOKEN + Name = "SmBusMemoryDown_SUPPORT" + Value = "1" + Help = "Main switch to enable SmBusMemoryDown support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "PchSmbusDxe_SUPPORT" "=" "1" + Token = "MRC_MEMORY_DOWN_SUPPORT" "=" "1" +End + +PATH + Name = "SMBUS_MEMORYDOWN_DIR" +End + +MODULE + Help = "Includes SmBusMemoryDown.mak to Project" + File = "SmBusMemoryDown.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SmBusMemoryDown.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.CIF b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.CIF new file mode 100644 index 0000000..c79f8a0 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.CIF @@ -0,0 +1,11 @@ +<component> + name = "WdtAppDxe" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\WdtApp\Dxe" + RefName = "WdtAppDxe" +[files] +"WdtAppDxe.sdl" +"WdtAppDxe.dxs" +"WdtAppDxe.mak" +"WdtAppDxe.c" +<endComponent>
\ No newline at end of file diff --git a/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.c b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.c new file mode 100644 index 0000000..902b521 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.c @@ -0,0 +1,401 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppDxe/WdtAppDxe.c 2 5/14/14 1:10p Barretlin $ +// +// $Revision: 2 $ +// +// $Date: 5/14/14 1:10p $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppDxe/WdtAppDxe.c $ +// +// 2 5/14/14 1:10p Barretlin +// [TAG] EIP167028 +// [Category] Improvement +// [Description] Variable attribute improment +// [Files] SB.sd SBDxe.c WdtAppDxe.c +// +// 1 2/08/12 8:34a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +#include <Efi.h> +#include <token.h> +#include <AmiLib.h> +#include <AmiDxeLib.h> +#include <Dxe.h> +#include <PCI.h> +#include <AmiCspLib.h> +#include <WdtAppVariable.h> +#include <Protocol\Wdt\Wdt.h> +#include <Protocol\WdtApp\WdtApp.h> + +#ifdef EFI_DEBUG +#define WDT_TIMEOUT_VALUE 10 // s +#else +#define WDT_TIMEOUT_VALUE 5 // s +#endif + +#define WDT_RELOAD_TIMER 10000000 // in units of 100ns + +EFI_GUID guidLegacyBoot = EFI_EVENT_LEGACY_BOOT_GUID; +EFI_GUID gWdtProtocolGuid = WDT_PROTOCOL_GUID; + +EFI_STATUS +StopFeedingWatchdog ( + IN EFI_EVENT Event, + IN VOID *Context +); + +EFI_STATUS +FeedWatchdog ( + IN EFI_EVENT Event, + IN VOID *Context +); + +EFI_STATUS +InstallWdtSupport ( + VOID +); + +EFI_STATUS +EFIAPI +RequestWdtAfterReboot ( + VOID +); + +EFI_STATUS +EFIAPI +RequestWdtNow ( + VOID +); + +WDT_APP_PROTOCOL mWdtAppProtocol = { + RequestWdtAfterReboot, + RequestWdtNow +}; + +EFI_EVENT mFeedEvent; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WdtAppDxeEntryPoint +// +// Description: Turns on WDT during DXE phase according to requests made by +// OS overclocking application (through WDT status) and BIOS +// modules (through flash variable) +// +// Input: IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +WdtAppDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + WDT_PROTOCOL *WdtProtocol; + UINTN VariableSize; + UINT32 Attributes; + EFI_GUID WdtPersistentDataGuid = WDT_PERSISTENT_DATA_GUID; + WDT_PERSISTENT_DATA WdtPersistentData; + + InitAmiLib(ImageHandle, SystemTable); + + TRACE ((-1, "(WdtApp) Entry Point to WdtAppDxe\n")); + + Status = pBS->LocateProtocol(&gWdtProtocolGuid, NULL, &WdtProtocol); + if ( EFI_ERROR(Status) ) { + TRACE ((-1, "(WdtApp) Failed to locate Wdt protocol, Status = %r\n",Status)); + return EFI_SUCCESS; + } + + VariableSize = sizeof (WDT_PERSISTENT_DATA); + + Status = pRS->GetVariable ( + L"WdtPersistentData", + &WdtPersistentDataGuid, + &Attributes, + &VariableSize, + &WdtPersistentData + ); + if (EFI_ERROR (Status)) { + WdtPersistentData.Enable = 0; + Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS; + } + + if (WdtProtocol->IsWdtRequired() == TRUE || WdtPersistentData.Enable == 1) { + WdtProtocol->ReloadAndStart(WDT_TIMEOUT_VALUE); + InstallWdtSupport(); + } + + WdtPersistentData.Enable = 0; + pRS->SetVariable( + L"WdtPersistentData", + &WdtPersistentDataGuid, + Attributes, + sizeof (WDT_PERSISTENT_DATA), + &WdtPersistentData + ); + + Status = pBS->InstallProtocolInterface ( + &ImageHandle, + &gWdtAppProtocolGuid, + EFI_NATIVE_INTERFACE, + &mWdtAppProtocol + ); + + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RequestWdtNow +// +// Description: Allows protocol's clients to request that WDT be turned on and periodically kicked, +// starting from now. +// +// Input: None +// +// Output: EFI_SUCCESS if everything's OK +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +EFIAPI +RequestWdtNow ( + VOID + ) +{ + EFI_STATUS Status; + Status = InstallWdtSupport(); + return Status; +}; + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RequestWdtAfterReboot +// +// Description: Allows protocol's clients to request that WDT be turned on and periodically kicked +// during BIOS execution during next boot. +// +// Input: None +// +// Output: EFI_SUCCESS if everything's OK +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +EFIAPI +RequestWdtAfterReboot ( + VOID + ) +{ + EFI_STATUS Status; + EFI_GUID WdtPersistentDataGuid = WDT_PERSISTENT_DATA_GUID; + WDT_PERSISTENT_DATA WdtPersistentData; + UINT32 Attributes; + UINTN VariableSize; + + VariableSize = sizeof (WDT_PERSISTENT_DATA); + + Status = pRS->GetVariable ( + L"WdtPersistentData", + &WdtPersistentDataGuid, + &Attributes, + &VariableSize, + &WdtPersistentData + ); + if (EFI_ERROR(Status)) Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS; + + WdtPersistentData.Enable = 1; + Status = pRS->SetVariable( + L"WdtPersistentData", + &WdtPersistentDataGuid, + Attributes, + sizeof (WDT_PERSISTENT_DATA), + &WdtPersistentData + ); + ASSERT_EFI_ERROR(Status); + + return Status; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InstallWdtSupport +// +// Description: Creates events for FeedWatchdog and StopFeedingWatchdog functions. +// +// Input: None +// +// Output: EFI_SUCCESS if everything's OK +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +InstallWdtSupport ( + VOID + ) +{ + EFI_STATUS Status; + EFI_EVENT BootEvent; + WDT_PROTOCOL* WdtProtocol; + + TRACE ((-1, "(WdtApp) Wdt turned on\n")); + + Status = pBS->LocateProtocol(&gWdtProtocolGuid, NULL, &WdtProtocol); + ASSERT_EFI_ERROR(Status); + Status = WdtProtocol->ReloadAndStart(WDT_TIMEOUT_VALUE); + ASSERT_EFI_ERROR(Status); + + Status = pBS->CreateEvent ( + EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FeedWatchdog, + NULL, + &mFeedEvent + ); + ASSERT_EFI_ERROR (Status); + Status = pBS->SetTimer ( + mFeedEvent, + TimerPeriodic, + WDT_RELOAD_TIMER + ); + ASSERT_EFI_ERROR (Status); + + Status = pBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_CALLBACK, + StopFeedingWatchdog, + NULL, + &BootEvent + ); + + ASSERT_EFI_ERROR (Status); + + Status = pBS->CreateEventEx( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + StopFeedingWatchdog, + NULL, + &guidLegacyBoot, + &BootEvent + ); + + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: FeedWatchdog +// +// Description: Prevents WDT timeout by restarting it. +// +// Input: None +// +// Output: Nothing +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +FeedWatchdog ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + WDT_PROTOCOL* WdtProtocol; + + Status = pBS->LocateProtocol(&gWdtProtocolGuid, NULL, &WdtProtocol); + if ( EFI_ERROR(Status) ) { + TRACE ((-1, "(WdtApp) Failed to locate Wdt protocol, Status = %r\n",Status)); + Status = pBS->SetTimer (mFeedEvent, TimerCancel, 0); + ASSERT_EFI_ERROR(Status); + Status = pBS->CloseEvent (mFeedEvent); + ASSERT_EFI_ERROR(Status); + return Status; + } + Status = WdtProtocol->ReloadAndStart(WDT_TIMEOUT_VALUE); + return Status; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: StopFeedingWatchdog +// +// Description: Stops timer and event that kept on feeding watchdog. +// +// Input: None +// +// Output: Nothing +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +StopFeedingWatchdog ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + WDT_PROTOCOL* WdtProtocol; + + TRACE ((-1, "(WdtApp) Stop feeding WDT\n")); + Status = pBS->SetTimer (mFeedEvent, TimerCancel, 0); + ASSERT_EFI_ERROR(Status); + Status = pBS->CloseEvent (mFeedEvent); + ASSERT_EFI_ERROR(Status); + Status = pBS->LocateProtocol(&gWdtProtocolGuid, NULL, &WdtProtocol); + if ( !EFI_ERROR(Status) ) { + WdtProtocol->Disable(); + } + return EFI_SUCCESS; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.dxs b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.dxs new file mode 100644 index 0000000..22e287c --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.dxs @@ -0,0 +1,25 @@ +/*++ +Copyright (c) 2010 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + WdtAppDxe.dxs + +Abstract: + + Platform-specific ICC code + +--*/ + +#include <Protocol\Wdt\Wdt.h> + +DEPENDENCY_START + WDT_PROTOCOL_GUID +DEPENDENCY_END diff --git a/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.mak b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.mak new file mode 100644 index 0000000..b8576a9 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.mak @@ -0,0 +1,65 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppDxe/WdtAppDxe.mak 1 2/08/12 8:34a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:34a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppDxe/WdtAppDxe.mak $ +# +# 1 2/08/12 8:34a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +all : WdtAppDxe + +$(BUILD_DIR)\WdtAppDxe.mak : $(WdtAppDxe_DIR)\$(@B).cif $(BUILD_RULES) + $(CIF2MAK) $(WdtAppDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +WdtAppDxe : $(BUILD_DIR)\WdtAppDxe.mak WdtAppDxe_Bin + +WdtAppDxe_INCLUDES=\ + $(INTEL_PCH_INCLUDES)\ + $(PROJECT_INCLUDES)\ + $(WDT_APP_INCLUDES)\ + +WdtAppDxe_Bin : $(AMICSPLib) $(AMIDXELIB) $(WdtAppProtocol_LIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\WdtAppDxe.mak all\ + "MY_INCLUDES=$(WdtAppDxe_INCLUDES)"\ + GUID=CE366D33-B057-4c03-8561-CAF17738B66F\ + ENTRY_POINT=WdtAppDxeEntryPoint \ + TYPE=BS_DRIVER \ + DEPEX1=$(WdtAppDxe_DIR)\WdtAppDxe.dxs \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1\ + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.sdl b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.sdl new file mode 100644 index 0000000..9a96355 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Dxe/WdtAppDxe.sdl @@ -0,0 +1,68 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppDxe/WdtAppDxe.sdl 1 2/08/12 8:34a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:34a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppDxe/WdtAppDxe.sdl $ +# +# 1 2/08/12 8:34a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "WdtAppDxe_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch to enable WDT app support in Project in DXE Phase" +End + +MODULE + Help = "Includes WdtAppDxe.mak to Project" + File = "WdtAppDxe.mak" +End + +PATH + Name = "WdtAppDxe_DIR" + Help = "Wdt App dir" +End + +ELINK + Name = "$(BUILD_DIR)\WdtAppDxe.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Include/WdtAppInclude.CIF b/Chipset/SB/PchWrap/WdtApp/Include/WdtAppInclude.CIF new file mode 100644 index 0000000..4a73faa --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Include/WdtAppInclude.CIF @@ -0,0 +1,9 @@ +<component> + name = "WdtAppInclude" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\WdtApp\Include" + RefName = "WdtAppInclude" +[files] +"WdtAppInclude.sdl" +"WdtAppVariable.h" +<endComponent> diff --git a/Chipset/SB/PchWrap/WdtApp/Include/WdtAppInclude.sdl b/Chipset/SB/PchWrap/WdtApp/Include/WdtAppInclude.sdl new file mode 100644 index 0000000..2791219 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Include/WdtAppInclude.sdl @@ -0,0 +1,56 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppInclude/WdtAppInclude.sdl 1 2/08/12 8:35a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:35a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppInclude/WdtAppInclude.sdl $ +# +# 1 2/08/12 8:35a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "WdtAppInclude_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable WdtAppInclude support in Project" +End + +ELINK + Name = "WdtAppInclude" + InvokeOrder = ReplaceParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Include/WdtAppVariable.h b/Chipset/SB/PchWrap/WdtApp/Include/WdtAppVariable.h new file mode 100644 index 0000000..2b8d1c8 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Include/WdtAppVariable.h @@ -0,0 +1,52 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppInclude/WdtAppVariable.h 1 2/08/12 8:35a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:35a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppInclude/WdtAppVariable.h $ +// +// 1 2/08/12 8:35a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +#define WDT_PERSISTENT_DATA_GUID \ +{0x78ce2354, 0xcfbc, 0x4643, 0xae, 0xba, 0x7, 0xa2, 0x7f, 0xa8, 0x92, 0xbf} + +#define WDT_PERSISTENT_DATA_C_NAME L"WdtPersistentData" + +typedef struct _WDT_PERSISTENT_DATA { + UINT8 Enable; +} WDT_PERSISTENT_DATA; +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + diff --git a/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.CIF b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.CIF new file mode 100644 index 0000000..0fabb1c --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.CIF @@ -0,0 +1,11 @@ +<component> + name = "WdtAppPei" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\WdtApp\Pei\" + RefName = "WdtAppPei" +[files] +"WdtAppPei.sdl" +"WdtAppPei.mak" +"WdtAppPei.c" +"WdtAppPei.dxs" +<endComponent> diff --git a/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.c b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.c new file mode 100644 index 0000000..7171b49 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.c @@ -0,0 +1,136 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.c 1 2/08/12 8:34a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:34a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.c $ +// +// 1 2/08/12 8:34a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +#include <Efi.h> +#include <Pei.h> +#include <Token.h> +#include <AmiPeiLib.h> +#include <AmiCspLib.h> + +#include "PchAccess.h" +#include "WdtAppVariable.h" +#include <Ppi\Wdt\Wdt.h> +#include <PPI\ReadOnlyVariable.h> + +#ifdef EFI_DEBUG +#define WDT_TIMEOUT_BETWEEN_PEI_DXE 30 +#else +#define WDT_TIMEOUT_BETWEEN_PEI_DXE 10 +#endif + +EFI_GUID gWdtPpiGuid = WDT_PPI_GUID; + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WdtAppPeiEntryPoint +// +// Description: Turns on WDT during PEI phase according to requests made by +// OS overclocking application (through WDT status) and BIOS +// modules (through flash variable) +// +// Input: *FfsHeader - Pointer to Firmware File System file header. +// *PeiServices - General purpose services available to every PEIM. +// +// Output: EFI_SUCCESS if everything's OK +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +WdtAppPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + WDT_PPI *WdtPei; + EFI_GUID WdtPersistentData = WDT_PERSISTENT_DATA_GUID; + EFI_GUID gPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID; + WDT_PERSISTENT_DATA WdtStateData; + EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable; + UINTN VariableSize; + + PEI_TRACE((-1, PeiServices, "(WdtApp) WdtAppPei Entry Point\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gPeiReadOnlyVariablePpiGuid, + 0, NULL, + &ReadOnlyVariable + ); + ASSERT_PEI_ERROR (PeiServices, Status); + + VariableSize = sizeof(WdtStateData); + + Status = ReadOnlyVariable->GetVariable ( + PeiServices, + WDT_PERSISTENT_DATA_C_NAME, + &WdtPersistentData, + NULL, + &VariableSize, + &WdtStateData + ); + + if (EFI_ERROR(Status)) { + WdtStateData.Enable = 0; + } + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gWdtPpiGuid, + 0, + NULL, + &WdtPei + ); + + ASSERT_PEI_ERROR (PeiServices, Status); + + if (WdtPei->IsWdtRequired() == TRUE || WdtStateData.Enable == 1) { + WdtPei->ReloadAndStart(WDT_TIMEOUT_BETWEEN_PEI_DXE); + } + + return EFI_SUCCESS; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + diff --git a/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.dxs b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.dxs new file mode 100644 index 0000000..e78218e --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.dxs @@ -0,0 +1,47 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.dxs 1 2/08/12 8:34a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:34a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.dxs $ +// +// 1 2/08/12 8:34a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +#include <Ppi\Wdt\Wdt.h> + +DEPENDENCY_START +WDT_PPI_GUID +DEPENDENCY_END +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.mak b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.mak new file mode 100644 index 0000000..c6f3127 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.mak @@ -0,0 +1,66 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.mak 1 2/08/12 8:34a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:34a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.mak $ +# +# 1 2/08/12 8:34a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +all : WdtAppPei + +$(BUILD_DIR)\WdtAppPei.mak : $(WdtAppPei_DIR)\$(@B).cif $(BUILD_RULES) + $(CIF2MAK) $(WdtAppPei_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +WdtAppPei : $(BUILD_DIR)\WdtAppPei.mak WdtAppPeiBin + +WdtAppPei_INCLUDES=\ + $(INTEL_PCH_INCLUDES)\ + $(WDT_APP_INCLUDES)\ + +WdtAppPeiBin : $(AMIPEILIB) $(AMICSPLib) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \ + /f $(BUILD_DIR)\WdtAppPei.mak all \ + "MY_INCLUDES = $(WdtAppPei_INCLUDES)" \ + NAME=WdtAppPei\ + MAKEFILE=$(BUILD_DIR)\WdtAppPei.mak \ + GUID=0F69F6D7-0E4B-43a6-BFC2-6871694369B0 \ + ENTRY_POINT=WdtAppPeiEntryPoint \ + TYPE=PEIM \ + DEPEX1=$(WdtAppPei_DIR)\WdtAppPei.dxs \ + DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.sdl b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.sdl new file mode 100644 index 0000000..8f0c3b9 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Pei/WdtAppPei.sdl @@ -0,0 +1,68 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.sdl 1 2/08/12 8:34a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:34a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppPei/WdtAppPei.sdl $ +# +# 1 2/08/12 8:34a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "WdtAppPei_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch to enable WDT APP support in Project in PEI Phase" +End + +MODULE + Help = "Includes WdtAppPei.mak to Project" + File = "WdtAppPei.mak" +End + +PATH + Name = "WdtAppPei_DIR" + Help = "WdtAppPei dir" +End + +ELINK + Name = "$(BUILD_DIR)\WdtAppPei.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Protocol/WdtApp/WdtApp.c b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtApp/WdtApp.c new file mode 100644 index 0000000..0c3a5f2 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtApp/WdtApp.c @@ -0,0 +1,55 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtApp/WdtApp.c 1 2/08/12 8:36a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:36a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtApp/WdtApp.c $ +// +// 1 2/08/12 8:36a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +#include "WdtApp.h" + +// +// Protocol GUID definition +// +EFI_GUID gWdtAppProtocolGuid = WDT_APP_PROTOCOL_GUID; + +// +// Protocol description +// +//EFI_GUID_STRING +// (&gWdtAppProtocolGuid, "WDT Application Protocol", "Watchdog Timer Application Protocol"); +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + diff --git a/Chipset/SB/PchWrap/WdtApp/Protocol/WdtApp/WdtApp.h b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtApp/WdtApp.h new file mode 100644 index 0000000..f79ddc0 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtApp/WdtApp.h @@ -0,0 +1,78 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtApp/WdtApp.h 1 2/08/12 8:36a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:36a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtApp/WdtApp.h $ +// +// 1 2/08/12 8:36a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +#ifndef _WDT_APP_API_H_ +#define _WDT_APP_API_H_ + +#include <Efi.h> +#include <token.h> +#include <AmiLib.h> +#include <AmiDxeLib.h> +#include <Dxe.h> +#include <AmiCspLib.h> +// +// GUID for the WDT application Protocol +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#define WDT_APP_PROTOCOL_GUID \ + {0x92c7d0bb, 0x679e, 0x479d, 0x87, 0x8d, 0xd4, 0xb8, 0x29, 0x68, 0x57, 0x8b} + +#else + +#define WDT_APP_PROTOCOL_GUID \ + {0x92c7d0bb, 0x679e, 0x479d, { 0x87, 0x8d, 0xd4, 0xb8, 0x29, 0x68, 0x57, 0x8b } } + +#endif +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gWdtAppProtocolGuid; + +typedef EFI_STATUS (EFIAPI *WDT_REQUEST) (VOID); + +typedef struct _WDT_APP_PROTOCOL { + WDT_REQUEST RequestWdtAfterReboot; + WDT_REQUEST RequestWdtNow; +} WDT_APP_PROTOCOL; + +#endif /* _WDT_APP_API_H_ */ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.CIF b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.CIF new file mode 100644 index 0000000..6f76b03 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.CIF @@ -0,0 +1,11 @@ +<component> + name = "WdtAppProtocolLib" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\WdtApp\Protocol" + RefName = "WdtAppProtocolLib" +[files] +"WdtAppProtocolLib.sdl" +"WdtAppProtocolLib.mak" +"WdtApp\WdtApp.h" +"WdtApp\WdtApp.c" +<endComponent> diff --git a/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.mak b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.mak new file mode 100644 index 0000000..2b938ab --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.mak @@ -0,0 +1,56 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtAppProtocolLib.mak 1 2/08/12 8:36a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:36a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtAppProtocolLib.mak $ +# +# 1 2/08/12 8:36a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* + +all : WdtAppProtocolLib + +$(WdtAppProtocol_LIB) : WdtAppProtocolLib + +WdtAppProtocolLib : $(BUILD_DIR)\WdtAppProtocolLib.mak WdtAppProtocolLibBin + +$(BUILD_DIR)\WdtAppProtocolLib.mak : $(WdtAppProtocol_DIR)\$(@B).cif $(WdtAppProtocol_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(WdtAppProtocol_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +WdtAppProtocolLibBin : + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\WdtAppProtocolLib.mak all\ + TYPE=LIBRARY \ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.sdl b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.sdl new file mode 100644 index 0000000..a2cf557 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/Protocol/WdtAppProtocolLib.sdl @@ -0,0 +1,71 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtAppProtocolLib.sdl 1 2/08/12 8:36a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:36a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtAppProtocolLib/WdtAppProtocolLib.sdl $ +# +# 1 2/08/12 8:36a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "WdtAppProtocolLib_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable WdtAppProtocolLib support in Project" +End + +PATH + Name = "WdtAppProtocol_DIR" +End + +MODULE + File = "WdtAppProtocolLib.mak" + Help = "Includes WdtAppProtocolLib.mak to Project" +End + +ELINK + Name = "WdtAppProtocol_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\WdtAppProtocolLib.lib" + Parent = "WdtAppProtocol_LIB" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PchWrap/WdtApp/WdtApp.CIF b/Chipset/SB/PchWrap/WdtApp/WdtApp.CIF new file mode 100644 index 0000000..185f5f9 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/WdtApp.CIF @@ -0,0 +1,14 @@ +<component> + name = "WdtApp" + category = ModulePart + LocalRoot = "Chipset\SB\PchWrap\WdtApp" + RefName = "WdtApp" +[files] +"WdtApp.sdl" +[parts] +"WdtAppDxe" +"WdtAppPei" +"WdtAppInclude" +[parts] +"WdtAppProtocolLib" +<endComponent> diff --git a/Chipset/SB/PchWrap/WdtApp/WdtApp.sdl b/Chipset/SB/PchWrap/WdtApp/WdtApp.sdl new file mode 100644 index 0000000..05197b0 --- /dev/null +++ b/Chipset/SB/PchWrap/WdtApp/WdtApp.sdl @@ -0,0 +1,74 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtApp.sdl 1 2/08/12 8:33a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:33a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/PchWrap/WdtApp/WdtApp.sdl $ +# +# 1 2/08/12 8:33a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "WdtApp_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch to enable WDT app support in Project" +End + +PATH + Name = "WdtApp_DIR" + Help = "Wdt App dir" +End + +ELINK + Name = "WDT_APP_INCLUDES" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "/I$(WdtApp_DIR)" + Parent = "WDT_APP_INCLUDES" + InvokeOrder = AfterParent +End + +ELINK + Name = "/I$(WdtApp_DIR)\Include" + Parent = "WDT_APP_INCLUDES" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PowerButton.c b/Chipset/SB/PowerButton.c new file mode 100644 index 0000000..d9256ff --- /dev/null +++ b/Chipset/SB/PowerButton.c @@ -0,0 +1,265 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SMM/PowerButton/PowerButton.c 9 9/20/11 3:12p Markw $ +// +// $Revision: 9 $ +// +// $Date: 9/20/11 3:12p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SMM/PowerButton/PowerButton.c $ +// +// 9 9/20/11 3:12p Markw +// [TAG] EIP67890 +// [Category] Spec Update +// [Severity] Normal +// [Description] Support power button handler in PI 1.1 +// +// [Files] PowerButton.c, PowerButton.mak, PowerButton. dxs +// +// 8 7/08/09 7:56p Markw +// Update headers. +// +// 7 1/07/08 4:26p Robert +// Updated for coding standard +// +// 6 5/30/07 5:29p Markw +// Use library function to shutdown. +// +// 5 3/28/07 1:27p Markw +// Update headers. +// +// 4 2/26/07 11:44a Yakovlevs +// Added arming PwrButton Smi when registering SMI handler. +// In event handler added check for Sleep SMI enable and disabling it. +// +// 3 11/11/05 11:46a Markw +// Renamed IntallSmmHandler to InitSmmHandler because of build errors +// because another driver used InstallSmmHandler. +// +// 2 11/08/05 6:05p Markw +// Using InstallSmiHandler library function. +// +// 1 1/28/05 4:33p Sivagarn +// Power Button SMM Component - Initial check in +// +// +//********************************************************************** + +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: PowerButton.C +// +// Description: Provide functions to register and handle Powerbutton +// functionality. This code is generic and as long as PM +// base address SDL token is defined properly this should +// work fine. +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> + + +#include <Token.h> +#include <AmiDxeLib.h> +#include <AMICSPLIBInc.h> +#if PI_SPECIFICATION_VERSION < 0x1000A +#include <Protocol\SmmPowerButtonDispatch.h> +#else +#include <Protocol\SmmPowerButtonDispatch2.h> +#endif + +EFI_GUID gThisFileGuid = + {0xe566b097,0x4378,0x485f,0x91,0xd0,0x1c,0x09,0x7c,0x19,0x0c,0xe2}; + //E566B097-4378-485f-91D0-1C097C190CE2 + +#if PI_SPECIFICATION_VERSION < 0x1000A +EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT DispatchContext = {PowerButtonEntry}; +#else +EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT DispatchContext = {EfiPowerButtonExit}; +EFI_SMM_BASE2_PROTOCOL *pSmmBase2; +EFI_SMM_SYSTEM_TABLE2 *pSmst2; +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PowerButtonActivated +// +// Description: If the power button is pressed, then this function is called. +// +// Input: +// IN EFI_HANDLE DispatchHandle +// IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +#if PI_SPECIFICATION_VERSION < 0x1000A +VOID PowerButtonActivated( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext + ) +#else +EFI_STATUS +EFIAPI +PowerButtonActivated( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL) +#endif +{ + SBLib_Shutdown(); + +#if PI_SPECIFICATION_VERSION >= 0x1000A + return EFI_SUCCESS; +#endif +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InSmmFunction +// +// Description: This function is called from SMM during SMM registration. +// +// Input: +// IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS InSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ +#if PI_SPECIFICATION_VERSION >= 0x1000A + EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *PowerButton; +#else + EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *PowerButton; +#endif + EFI_HANDLE hPowerButton; + EFI_STATUS Status; + +#if PI_SPECIFICATION_VERSION >= 0x1000A + Status = pSmmBase2->GetSmstLocation(pSmmBase2, &pSmst2); + if (EFI_ERROR(Status)) return Status; + + Status = pSmst2->SmmLocateProtocol( + &gEfiSmmPowerButtonDispatch2ProtocolGuid, + NULL, + &PowerButton + ); +#else + Status = pBS->LocateProtocol( + &gEfiSmmPowerButtonDispatchProtocolGuid, + NULL, + &PowerButton + ); +#endif + if (EFI_ERROR(Status)) return Status; + + Status = PowerButton->Register( + PowerButton, + PowerButtonActivated, + &DispatchContext, + &hPowerButton + ); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: NotInSmmFunction +// +// Description: This function is called from outside of SMM during SMM registration. +// +// Input: +// IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS NotInSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + UINT16 Value; + //Clear All PM Statuses + Value = IoRead16(PM_BASE_ADDRESS); + IoWrite16(PM_BASE_ADDRESS,Value); + + //Enable PowerButton and Global Enable + IoWrite16(PM_BASE_ADDRESS + 0x02, BIT05 + BIT08); + return EFI_SUCCESS; +} + + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitPowerButton +// +// Description: This is the entrypoint of the Power button driver. +// +// Input: +// IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS InitPowerButton( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ +#if PI_SPECIFICATION_VERSION >= 0x0001000a + EFI_STATUS Status; +#endif + + InitAmiLib(ImageHandle, SystemTable); + +#if PI_SPECIFICATION_VERSION >= 0x0001000a + Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &pSmmBase2); + if (EFI_ERROR(Status)) return Status; + + return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL); +#else + return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction); +#endif +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PowerButton.cif b/Chipset/SB/PowerButton.cif new file mode 100644 index 0000000..4dc4777 --- /dev/null +++ b/Chipset/SB/PowerButton.cif @@ -0,0 +1,11 @@ +<component> + name = "PowerButton" + category = ModulePart + LocalRoot = "Chipset\SB" + RefName = "PowerButton" +[files] +"\PowerButton.sdl" +"\PowerButton.mak" +"\PowerButton.c" +"\PowerButton.dxs" +<endComponent> diff --git a/Chipset/SB/PowerButton.dxs b/Chipset/SB/PowerButton.dxs new file mode 100644 index 0000000..198f3fd --- /dev/null +++ b/Chipset/SB/PowerButton.dxs @@ -0,0 +1,76 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/SMM/PowerButton/PowerButton.dxs 3 9/20/11 3:13p Markw $ +// +// $Revision: 3 $ +// +// $Date: 9/20/11 3:13p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/SMM/PowerButton/PowerButton.dxs $ +// +// 3 9/20/11 3:13p Markw +// [TAG] EIP67890 +// [Category] Spec Update +// [Severity] Normal +// [Description] Support power button handler in PI 1.1 +// +// [Files] PowerButton.c, PowerButton.mak, PowerButton.dxs +// +// 2 7/08/09 7:56p Markw +// Update headers. +// +//********************************************************************** + +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: PowerButton.Dxs +// +// Description: Dependency file for the power button handler driver +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> + + +#if PI_SPECIFICATION_VERSION >= 0x0001000a +#include <Protocol\SmmPowerButtonDispatch2.h> +#else +#include <Protocol\SmmPowerButtonDispatch.h> +#endif + +DEPENDENCY_START +#if PI_SPECIFICATION_VERSION >= 0x0001000a + EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL_GUID +#else + EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL_GUID +#endif +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/PowerButton.mak b/Chipset/SB/PowerButton.mak new file mode 100644 index 0000000..09a4ee8 --- /dev/null +++ b/Chipset/SB/PowerButton.mak @@ -0,0 +1,94 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/SMM/PowerButton/PowerButton.mak 5 9/20/11 3:12p Markw $ +# +# $Revision: 5 $ +# +# $Date: 9/20/11 3:12p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SMM/PowerButton/PowerButton.mak $ +# +# 5 9/20/11 3:12p Markw +# [TAG] EIP67890 +# [Category] Spec Update +# [Severity] Normal +# [Description] Support power button handler in PI 1.1 +# +# [Files] PowerButton.c, PowerButton.mak, PowerButton. dxs +# +# 4 7/08/09 8:24p Markw +# Update header. +# +# 3 5/30/07 5:29p Markw +# Use library function to shutdown. +# +# 2 12/02/05 11:48a Felixp +# +# 1 1/28/05 4:33p Sivagarn +# Power Button SMM Component - Initial check in +# +# +#********************************************************************** + + + +#<AMI_FHDR_START> +#--------------------------------------------------------------------------- +# +# Name: PowerButton.MAK +# +# Description: Make file for the SMM power button handler code +# +#--------------------------------------------------------------------------- +#<AMI_FHDR_END> +!IFNDEF PI_SPECIFICATION_VERSION +PI_SPECIFICATION_VERSION=0 +!ENDIF + +all : PowerButton + +PowerButton : $(BUILD_DIR)\PowerButton.mak PowerButtonBin + +$(BUILD_DIR)\PowerButton.mak : $(POWER_BUTTON_DIR)\PowerButton.cif $(POWER_BUTTON_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(POWER_BUTTON_DIR)\PowerButton.cif $(CIF2MAK_DEFAULTS) + +PowerButtonBin : $(AMIDXELIB) $(AMICSPLib) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\PowerButton.mak all\ + GUID=E566B097-4378-485f-91D0-1C097C190CE2\ + ENTRY_POINT=InitPowerButton\ +!IF $(PI_SPECIFICATION_VERSION) < 0x1000A + TYPE=BS_DRIVER\ +!ELSE + TYPE=SMM_DRIVER\ +!ENDIF + COMPRESS=1 + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/PowerButton.sdl b/Chipset/SB/PowerButton.sdl new file mode 100644 index 0000000..33cffcc --- /dev/null +++ b/Chipset/SB/PowerButton.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = "PowerButton_SUPPORT" + Value = "1" + Help = "Main switch to enable PowerButton support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "POWER_BUTTON_DIR" +End + +MODULE + Help = "Includes PowerButton.mak to Project" + File = "PowerButton.mak" +End + +ELINK + Name = "$(BUILD_DIR)\PowerButton.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/Chipset/SB/RRIORDMA.asl b/Chipset/SB/RRIORDMA.asl new file mode 100644 index 0000000..a535886 --- /dev/null +++ b/Chipset/SB/RRIORDMA.asl @@ -0,0 +1,230 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/RRIORDMA.asl 1 2/08/12 8:24a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:24a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/RRIORDMA.asl $ +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: RRIORDMA.ASL +// +// Description: The ASL file for South Bridge LPC I/O Decoding & DMA +// assignment. +// +//<AMI_FHDR_END> +//************************************************************************* + + OperationRegion(\_SB.PCI0.LPCB.LPCR, PCI_Config, 0x80, 4) + Field(\_SB.PCI0.LPCB.LPCR, ByteAcc, NoLock, Preserve) { + CADR, 3, // COMA Decode Range + , 1, + CBDR, 3, // COMB Decode Range + , 1, + LTDR, 2, // LPT Decode Range + , 2, + FDDR, 1, // FDD Decode Range + , 3, + CALE, 1, // COM Port A Enable + CBLE, 1, // COM Port B Enable + LTLE, 1, // Parallel Port Enable + FDLE, 1, // Floppy Drive Enable + , 4, + GLLE, 1, // Low Game Port Enable + GHLE, 1, // High Game Port Enable + KCLE, 1, // Keyboard Enable + MCLE, 1, // Microcontroller Enable + C1LE, 1, // Super I/O Enable 1 + C2LE, 1, // Super I/O Enable 2 + , 2, + } + +/* +;<AMI_PHDR_START> +;------------------------------------------------------------------------ +; +; Procedure: UXDV +; +; Description: Convert UART port address to the decoded value in LPC bridge +; +; Input: Arg0 = Port to Route/Release +; +; Output: UART Port Decoded Value in the LPC bridge +; +;------------------------------------------------------------------------ +;<AMI_PHDR_END> +*/ + + Method(UXDV, 1) { + Store(0xff, Local0) // Unknown + Switch (Add(Arg0, 0)) { + Case (0x3F8) { Store(0, Local0) } + Case (0x2F8) { Store(1, Local0) } + Case (0x220) { Store(2, Local0) } + Case (0x228) { Store(3, Local0) } + Case (0x238) { Store(4, Local0) } + Case (0x2E8) { Store(5, Local0) } + Case (0x338) { Store(6, Local0) } + Case (0x3E8) { Store(7, Local0) } + } + return (Local0) + } + +/* +;<AMI_PHDR_START> +;------------------------------------------------------------------------ +; +; Procedure: RRIO +; +; Description: Route/Release I/O resources from/to EIO/LPC Bus +; +; Input: Arg0 = Device Category +; Arg1 = 0/1 Disable/Enable resource decoding +; Arg2 = Port to Route/Release +; Arg3 = Port SIZE to Route +; +; Output: Nothing +; +;------------------------------------------------------------------------ +;<AMI_PHDR_END> +*/ + Method(RRIO, 4) { + Switch (Add(Arg0, 0)) { + Case (0) { // UART 0 or 2 + Store(0, CALE) // Disable the decoding + Store (UXDV(Arg2), Local0) + If (LNotEqual(Local0, 0xff)) { Store(Local0, CADR)} + If (Arg1) { Store(1, CALE) } + } + Case (1) { // UART 1 or 3 + Store(0, CBLE) // Disable the decoding + Store (UXDV(Arg2), Local0) + If (LNotEqual(Local0, 0xff)) { Store(Local0, CBDR)} + If (Arg1) { Store(1, CBLE) } + } + Case (2) { // LPT + Store(0, LTLE) // Disable the decoding + If (LEqual(Arg2, 0x378)) { Store(0, LTDR) } + If (LEqual(Arg2, 0x278)) { Store(1, LTDR) } + If (LEqual(Arg2, 0x3BC)) { Store(2, LTDR) } + If (Arg1) { Store(1, LTLE) } + } + Case (3) { // FDD + Store(0, FDLE) // Disable the decoding + If (LEqual(Arg2, 0x3F0)) { Store(0, FDDR) } + If (LEqual(Arg2, 0x370)) { Store(1, FDDR) } + If (Arg1) { Store(1, FDLE) } + } + Case (8) { // Game 1 + If (LEqual(Arg2, 0x200)) { + If (Arg1) { Store(1, GLLE) } + Else { Store(0, GLLE) } + } + If (LEqual(Arg2, 0x208)) { + If (Arg1) { Store(1, GHLE) } + Else { Store(0, GHLE) } + } + } + Case (9) { // Game 2 + If (LEqual(Arg2, 0x200)) { + If (Arg1) { Store(1, GLLE) } + Else { Store(0, GLLE) } + } + If (LEqual(Arg2, 0x208)) { + If (Arg1) { Store(1, GHLE) } + Else { Store(0, GHLE) } + } + } + Case (10) { // Keyboard Controller + If (LOr(LEqual(Arg2, 0x60), LEqual(Arg2, 0x64))) { + If (Arg1) { Store(1, KCLE) } + Else { Store(0, KCLE) } + } + } + Case (11) { // MicroController + If (LOr(LEqual(Arg2, 0x62), LEqual(Arg2, 0x66))) { + If (Arg1) { Store(1, MCLE) } + Else { Store(0, MCLE) } + } + } + Case (12) { // Super I/O Enable 1 + If (LEqual(Arg2, 0x2E)) { + If (Arg1) { Store(1, C1LE) } + Else { Store(0, C1LE) } + } + If (LEqual(Arg2, 0x4E)) { + If (Arg1) { Store(1, C2LE) } + Else { Store(0, C2LE) } + } + } + Case (13) { // Super I/O Enable 2 + If (LEqual(Arg2, 0x2E)) { + If (Arg1) { Store(1, C1LE) } + Else { Store(0, C1LE) } + } + If (LEqual(Arg2, 0x4E)) { + If (Arg1) { Store(1, C2LE) } + Else { Store(0, C2LE) } + } + } + + } + + } + +/* +;<AMI_PHDR_START> +;------------------------------------------------------------------------ +; +; Procedure: rDMA +; +; Description: Route/Release DMA channel from/to being ISA/PCI mode +; +; Input: Arg0 = Device Category +; Arg1 = 0/1 Disable/Enable resource decoding +; Arg2 = DMA channel to Route/Release +; +; Output: Nothing +; +;------------------------------------------------------------------------ +;<AMI_PHDR_END> +*/ + Method(rDMA, 3) { + // Porting If needed. + } + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/RTC.h b/Chipset/SB/RTC.h new file mode 100644 index 0000000..3c88361 --- /dev/null +++ b/Chipset/SB/RTC.h @@ -0,0 +1,206 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/RTC.h 3 7/17/13 1:54a Scottyang $ +// +// $Revision: 3 $ +// +// $Date: 7/17/13 1:54a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/RTC.h $ +// +// 3 7/17/13 1:54a Scottyang +// [TAG] EIP128233 +// [Category] Improvement +// [Description] Improving UEFI PXE image downloading proformance. +// [Files] RTC.h +// SBRun.c +// +// 2 1/11/13 1:51a Scottyang +// [TAG] EIP88358 +// [Category] Improvement +// [Description] Add FORCE_USER_TO_SETUP_IF_CMOS_BAD token +// [Files] SBDex.c, SBPei.c, RTC.h, SB.sdl +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: RTC.h +// +// Description: Real Time Clock and CMOS Data bank registr definitions. +// +//<AMI_FHDR_END> +//************************************************************************* + +#ifndef __RTC__H__ +#define __RTC__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <Efi.h> + +#define EFI_TIME_VARIABLE_GUID \ + {0x9d0da369, 0x540b, 0x46f8, 0x85, 0xa0, 0x2b, 0x5f, 0x2c, 0x30, 0x1e, 0x15} + // [EIP88358] >> +#define CMOS_BAD_HOB_GUID \ + {0x7e7369ce, 0x0188, 0x4183, 0x8c, 0x2d, 0xda, 0xf7, 0xb7, 0x30, 0xe4, 0x2b} + // [EIP88358] << +//--------------------------------------------------------------------------- +// Define Real Time Clock INDEX and DATA registers +//--------------------------------------------------------------------------- +#define RTC_INDEX_REG 0x70 +#define RTC_DATA_REG 0x71 + +//--------------------------------------------------------------------------- +// Define Internal Registers for Real Time Clock +//--------------------------------------------------------------------------- +#define RTC_SECONDS_REG 0x00 // R/W Range 0..59 +#define RTC_SECONDS_ALARM_REG 0x01 // R/W Range 0..59 +#define RTC_MINUTES_REG 0x02 // R/W Range 0..59 +#define RTC_MINUTES_ALARM_REG 0x03 // R/W Range 0..59 +#define RTC_HOURS_REG 0x04 // R/W Range 1..12 or 0..23 + // Bit 7 is AM/PM +#define RTC_HOURS_ALARM_REG 0x05 // R/W Range 1..12 or 0..23 + // Bit 7 is AM/PM +#define RTC_DAY_OF_WEEK_REG 0x06 // R/W Range 1..7 +#define RTC_DAY_OF_MONTH_REG 0x07 // R/W Range 1..31 +#define RTC_MONTH_REG 0x08 // R/W Range 1..12 +#define RTC_YEAR_REG 0x09 // R/W Range 0..99 +#define RTC_REG_A_INDEX 0x0a // R/W[0..6] R0[7] +#define RTC_REG_B_INDEX 0x0b // R/W +#define RTC_REG_C_INDEX 0x0c // RO +#define RTC_REG_D_INDEX 0x0d // RO + +#define RTC_NMI_MASK 0x80 + +#pragma pack(push,1) + +//--------------------------------------------------------------------------- +// Register A Bit definitions +//--------------------------------------------------------------------------- +typedef union { + UINT8 REG_A; + struct { + UINT8 RateSel : 4; + UINT8 Divisor : 3; + UINT8 UpdInProgr : 1; + }; +} RTC_REG_A; + +//--------------------------------------------------------------------------- +// Register B Bit definitions +//--------------------------------------------------------------------------- +typedef union { + UINT8 REG_B; + struct { + UINT8 DaylightSav : 1; // 0 - Daylight saving disabled + // 1 - Daylight savings enabled + UINT8 Mode : 1; // 0 - 12 hour mode + // 1 - 24 hour mode + UINT8 Format : 1; // 0 - BCD Format + // 1 - Binary Format + UINT8 SquareWave : 1; // 0 - Disable SQWE output + // 1 - Enable SQWE output + UINT8 UpdateInt : 1; // 0 - Update INT disabled + // 1 - Update INT enabled + UINT8 AlarmInt : 1; // 0 - Alarm INT disabled + // 1 - Alarm INT Enabled + UINT8 PeriodicInt : 1; // 0 - Periodic INT disabled + // 1 - Periodic INT Enabled + UINT8 Set : 1; // 0 - Normal operation + // 1 - Updates inhibited + }; +} RTC_REG_B; + +//--------------------------------------------------------------------------- +// Register C Bit definitions +//--------------------------------------------------------------------------- +typedef union { + UINT8 REG_C; + struct { + UINT8 Reserved : 4; // Read as zero. Can not be written. + UINT8 UpdEndFlag : 1; // Update End Interrupt Flag + UINT8 AlarmFlag : 1; // Alarm Interrupt Flag + UINT8 PeriodicFlag : 1; // Periodic Interrupt Flag + UINT8 IrqFlag : 1; // Iterrupt Request Flag = + // PF & PIE | AF & AIE | UF & UIE + }; +} RTC_REG_C; + +//--------------------------------------------------------------------------- +// Register D Bit definitions +//--------------------------------------------------------------------------- +typedef union { + UINT8 REG_D; + struct { + UINT8 Reserved : 7; + UINT8 DataValid : 1; // Valid RAM and Time + }; +} RTC_REG_D; + + +//--------------------------------------------------------------------------- +// Bit definitions for Day Alarm Register (Porting Required if needed) +//--------------------------------------------------------------------------- +typedef union { + UINT8 REG_DATE_ALARM; + struct { + UINT8 DateAlarm : 6; + UINT8 Reserved : 2; + }; +} RTC_DATE_ALARM_REG; + +//--------------------------------------------------------------------------- +// Bit definitions for Month Alarm Register (Porting Required if needed) +//--------------------------------------------------------------------------- +typedef union { + UINT8 REG_MONTH_ALARM; + struct { + UINT8 MonthAlarm : 6; + UINT8 Reserved : 2; + }; +} RTC_MONTH_ALARM_REG; + // [EIP88358] >> +typedef struct _CMOS_BAD_HOB { + EFI_HOB_GUID_TYPE Header; +} CMOS_BAD_HOB; + // [EIP88358] << +#pragma pack(pop) + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/ReleaseNotes.chm b/Chipset/SB/ReleaseNotes.chm Binary files differnew file mode 100644 index 0000000..2752298 --- /dev/null +++ b/Chipset/SB/ReleaseNotes.chm diff --git a/Chipset/SB/SATA.ASL b/Chipset/SB/SATA.ASL new file mode 100644 index 0000000..2a3e318 --- /dev/null +++ b/Chipset/SB/SATA.ASL @@ -0,0 +1,297 @@ +// Set of generic ACPI Control Methods to configure SATA Controller and SATA Drives settings +// File is included under SATA controller PCI device scope +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Chipset/SB/SATA.ASL 1 6/17/16 4:05a Chienhsieh $ +// +// $Revision: 1 $ +// +// $Date: 6/17/16 4:05a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Chipset/SB/SATA.ASL $ +// +// 1 6/17/16 4:05a Chienhsieh +// [TAG] EIP255383 +// [Category] Improvement +// [Description] when the FORCE_HDD_PASSWORD_PROMPT sdl token enabled , +// even though use select s4 option, on resume system booted like S5. +// set HDD password and enter Win8 S4(Hibernate) sleep, behaviour of S4 +// resume would be like restart. +// [Files] SATA.ASL +// +// 2 10/23/12 3:19a Scottyang +// [TAG] EIP84560 +// [Category] Bug Fix +// [Symptom] Can't enter Win8 after Win8 AHCI driver version:11.5.0.1122 +// install. +// [Solution] fixed in EIP84560 +// [Files] sb.sdl, sb.mak, sata.asl +// +// 1 2/08/12 8:25a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +DefinitionBlock ( + "Sata.aml", + "SSDT", + 1, + "SataRef", + "SataTabl", + 0x1000 + ) +{ + +External(DSSP, IntObj) +External(\_SB.PCI0.SAT0, DeviceObj) + +Scope(\) +{ + // SATA Command Set + //---------------------------------------------------------------// + // Reg1 Reg2 Reg3 Reg4 Reg5 Reg6 Reg7 + //---------------------------------------------------------------// + Name(STFE, Buffer(){0x10, 0x06, 0x00, 0x00, 0x00, 0x00, 0xEF,}) // Set Features - Enable USE of SATA Feature + Name(STFD, Buffer(){0x90, 0x06, 0x00, 0x00, 0x00, 0x00, 0xEF,}) // Set Features - Disable USE of SATA Feature + Name(FZTF, Buffer(){0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5 }) // Freeze Lock Command + Name(DCFL, Buffer(){0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1 }) // Device Configuration Freeze Lock Command + + Name(SCBF, Buffer(21){}) // SATA Command Buffer to be returned + + // The number of SATA command + Name (CMDC, 0) // SATA Commands counter + + // Build the return buffer for GTF() control method + Method (GTFB, 2, Serialized) + // Arg0 - Command to write + // Arg1 - Subcommand value for "Set Feature command" + { + Multiply(CMDC, 56, Local0) + CreateField(SCBF, Local0, 56, CMDx) // Command field + Multiply(CMDC, 7, Local0) + CreateByteField(SCBF, Add(Local0, 1), A001) // Subcommand of "Set Feature" command + Store(Arg0, CMDx) // Store command into return buffer + Store(Arg1, A001) // Set Subcommand code + Increment(CMDC) + } +} + +Scope(\_SB.PCI0.SAT0) +{ + Name(REGF, 1) // PCI Bus access Flag + + Method(_REG, 2) // is PCI Config space accessible as OpRegion? + // _REG to update REGF status + { + If(LEqual(Arg0, 0x2)) + { + Store(Arg1, REGF) + } + } + // Buffer to be returned by _GTM + Name(TMD0, Buffer(20){}) // 5 DWORD length + CreateDWordField(TMD0, 00, PIO0) + CreateDWordField(TMD0, 04, DMA0) + CreateDWordField(TMD0, 8, PIO1) // do not use "08" + CreateDWordField(TMD0, 12, DMA1) + CreateDWordField(TMD0, 16, CHNF) + + // Get Timing PIO/DMA Mode + Method(_GTM,0 ) { // Return Buffer + // PIO 0 Speed DWORD + // DMA 0 Speed DWORD + // PIO 1 Speed DWORD + // DMA 1 Speed DWORD + // Flags DWORD + + Store(120, PIO0) // Forced to PIO Mode 4 + Store(20, DMA0) // Forced to UDMA Mode 5 + Store(120, PIO1) // Forced to PIO Mode 4 + Store(20, DMA1) // Forced to UDMA Mode 5 + + Or(CHNF, 0x05, CHNF) + + Return (TMD0) + } // end Method _GTM +//////////////////////////////////////////////////////////////////////////////// + // Set Timing PIO/DMA Mode + Method(_STM, 3) // Arg 0 = Channel Timing Info (Package) + // Arg 1 = ATA Command set Master(Buffer) + // Arg 2 = ATA Command set Slave (Buffer) + {} // end Method _STM +//////////////////////////////////////////////////////////////////////////////// +#if defined(ASL_ZPODD_SATA_PORT) && (ASL_ZPODD_SATA_PORT==0) +#else + // SATA PORT0 // + Device(SPT0) + { + Name(_ADR,0x0000FFFF) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LEqual(DSSP, 0x1)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + Return(SCBF) + } + } + +#endif + // SATA PORT1 // +#if defined(ASL_ZPODD_SATA_PORT) && (ASL_ZPODD_SATA_PORT==1) +#else + Device(SPT1) + { + Name(_ADR,0x0001FFFF) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LEqual(DSSP, 0x1)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + Return(SCBF) + } + } + +#endif + // SATA PORT2 // +#if defined(ASL_ZPODD_SATA_PORT) && (ASL_ZPODD_SATA_PORT==2) +#else + Device(SPT2) + { + Name(_ADR,0x0002FFFF) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LEqual(DSSP, 0x1)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + Return(SCBF) + } + } + +#endif + // SATA PORT3 // +#if defined(ASL_ZPODD_SATA_PORT) && (ASL_ZPODD_SATA_PORT==3) +#else + Device(SPT3) + { + Name(_ADR,0x0003FFFF) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LEqual(DSSP, 0x1)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + Return(SCBF) + } + } + +#endif + // SATA PORT4 // +#if defined(ASL_ZPODD_SATA_PORT) && (ASL_ZPODD_SATA_PORT==4) +#else + Device(SPT4) + { + Name(_ADR,0x0004FFFF) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LEqual(DSSP, 0x1)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + Return(SCBF) + } + } + +#endif + // SATA PORT5 // +#if defined(ASL_ZPODD_SATA_PORT) && (ASL_ZPODD_SATA_PORT==5) +#else + Device(SPT5) + { + Name(_ADR,0x0005FFFF) + + // GET TASK FILE METHOD + Method(_GTF, 0, NotSerialized) { + Store(0, CMDC) // SATA Commands counter + + If(LEqual(DSSP, 0x1)) { // Check DISABLE_SOFT_SET_PREV SDL Token Enabled + GTFB(STFD, 0x06) // Disable SW Preservation Settings + } else { + GTFB(STFE, 0x06) // Enable SW Preservation Settings + } + + GTFB(FZTF, 0x00) // Issue Freeze Lock Command + GTFB(DCFL, 0x00) // Issue Device Configuration Freeze Lock Command + Return(SCBF) + } + } +#endif +} +}//end of SSDT + + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, 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/Chipset/SB/SB.ASL b/Chipset/SB/SB.ASL new file mode 100644 index 0000000..2a86c98 --- /dev/null +++ b/Chipset/SB/SB.ASL @@ -0,0 +1,341 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB.ASL 7 7/15/13 3:19a Scottyang $ +// +// $Revision: 7 $ +// +// $Date: 7/15/13 3:19a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB.ASL $ +// +// 7 7/15/13 3:19a Scottyang +// [TAG] EIP129089 +// [Category] Improvement +// [Description] Update PCH RC 1.6.1. +// [Files] SBDxe.c, SB.asl, ..\ReferenceCode\Chipset\LynxPoint\*.* +// +// 6 4/24/13 6:00a Scottyang +// [TAG] EIP121262 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] WOL BSOD +// [RootCause] When resume to OS hardware signal not ready. That made a +// dead loop in OS. +// [Solution] Remove while loop and add sychnorized the object in asl +// code. +// [Files] SB.asl, PchPcie.asl +// +// 5 4/08/13 2:51a Wesleychen +// [TAG] EIP118045 +// [Category] Improvement +// [Description] Creat tokens to support Power Button Notify +// for misc events. +// [Files] SB.SDL; SB.ASL +// +// 4 1/11/13 5:10a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Remove EIP105442 temp solution. +// [Files] SB.ASL, Pch.asl +// +// 3 11/26/12 12:39a Scottyang +// [TAG] EIP105442 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] After S3 resum cannot use FPT win64 +// [RootCause] The SPI HSFS register "Access Error Log" bit has been +// set. +// [Solution] Clear "Access Error Log" bit after resume. +// [Files] SB.ASL, Pch.asl +// +// 2 8/13/12 10:24a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update definition in ASL code for building when +// disabled PCI objects. +// [Files] SB.ASL +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SB.asl +// +// Description: The ASL file is for South Bridge specific function. +// +//<AMI_FHDR_END> +//************************************************************************* +Scope(\_SB.PCI0.LPCB) +{ + + OperationRegion(CPSB, SystemMemory, 0xC0000000, 16) // Relocatable + Field(CPSB, AnyAcc, NoLock, Preserve) //Field + { + RTCX, 1, + SBB0, 7, + SBB1, 8, + SBB2, 8, + SBB3, 8, + SBB4, 8, + SBB5, 8, + SBB6, 8, + SBB7, 8, + SBB8, 8, + SBB9, 8, + SBBA, 8, + SBBB, 8, + SBBC, 8, + SBBD, 8, + SBBE, 8, + SBBF, 8, + } + +/* +;<AMI_PHDR_START> +;------------------------------------------------------------------------ +; +; Procedure: SPTS +; Description: METHOD IS CALLED BY OS PRIOR TO ENTER ANY SLEEP STATE +; Input: Arg0 = Arg0 = Sleep state System about to enter +; Output: Nothing +; +;------------------------------------------------------------------------- +;<AMI_PHDR_END> +*/ + Method (SPTS, 1) { + Store(One, SLPX) // Clear SLP_SMI Status + Store(One, SLPE) // Enable SLP_SMI + +#if defined(ASL_RC_PORT_0) && (ASL_RC_PORT_0==1) + Store(Zero, \_SB.PCI0.RP01.RPAV) +#endif +#if defined(ASL_RC_PORT_1) && (ASL_RC_PORT_1==1) + Store(Zero, \_SB.PCI0.RP02.RPAV) +#endif +#if defined(ASL_RC_PORT_2) && (ASL_RC_PORT_2==1) + Store(Zero, \_SB.PCI0.RP03.RPAV) +#endif +#if defined(ASL_RC_PORT_3) && (ASL_RC_PORT_3==1) + Store(Zero, \_SB.PCI0.RP04.RPAV) +#endif +#if defined(ASL_RC_PORT_4) && (ASL_RC_PORT_4==1) + Store(Zero, \_SB.PCI0.RP05.RPAV) +#endif +#if defined(ASL_RC_PORT_5) && (ASL_RC_PORT_5==1) + Store(Zero, \_SB.PCI0.RP06.RPAV) +#endif +#if defined(ASL_RC_PORT_6) && (ASL_RC_PORT_6==1) + Store(Zero, \_SB.PCI0.RP07.RPAV) +#endif +#if defined(ASL_RC_PORT_7) && (ASL_RC_PORT_7==1) + Store(Zero, \_SB.PCI0.RP08.RPAV) +#endif + } + +/* +;<AMI_PHDR_START> +;------------------------------------------------------------------------ +; +; Procedure: SWAK +; Description: METHOD CALLED ON WAKE UP FROM ANY SLEEP STATE +; Input: Arg0 = Sleep state System is resuming from +; Output: Nothing +; +;------------------------------------------------------------------------ +;<AMI_PHDR_END> +*/ + Method (SWAK, 1) { + Store(Zero, SLPE) // Disable SLP_SMI +#if defined ASL_SX_NOTIFY_PWRB && ASL_SX_NOTIFY_PWRB == 1 + If (RTCS) {} + Else {Notify(\_SB.PWRB, 0x02)} +#endif + } + + OperationRegion (SMIE, SystemIO, PMBS, 4) + Field (SMIE, ByteAcc,NoLock,Preserve) { + ,10, + RTCS, 1, + , 3, + PEXS, 1, + WAKS, 1, + , 8, + PWBT, 1, + , 7, + } + + OperationRegion (SLPR, SystemIO, SMCR, 8) + Field (SLPR, ByteAcc,NoLock,Preserve) { + , 4, + SLPE,1, + ,31, + SLPX,1, + ,27, + } +}//Scope(\_SB.PCI0.LPCB) + +#if defined (ASL_RC_PORT_0) && (ASL_RC_PORT_0==1) +Scope(\_SB.PCI0.RP01) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR1, LTRE) + Store (PML1, LMSL) + Store (PNL1, LNSL) + Store (OBF1, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP01) +#endif + +#if defined (ASL_RC_PORT_1) && (ASL_RC_PORT_1==1) +Scope(\_SB.PCI0.RP02) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR2, LTRE) + Store (PML2, LMSL) + Store (PNL2, LNSL) + Store (OBF2, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP02) +#endif + +#if defined (ASL_RC_PORT_2) && (ASL_RC_PORT_2==1) +Scope(\_SB.PCI0.RP03) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR3, LTRE) + Store (PML3, LMSL) + Store (PNL3, LNSL) + Store (OBF3, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP03) +#endif + +#if defined (ASL_RC_PORT_3) && (ASL_RC_PORT_3==1) +Scope(\_SB.PCI0.RP04) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR4, LTRE) + Store (PML4, LMSL) + Store (PNL4, LNSL) + Store (OBF4, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP04) +#endif + +#if defined (ASL_RC_PORT_4) && (ASL_RC_PORT_4==1) +Scope(\_SB.PCI0.RP05) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR5, LTRE) + Store (PML5, LMSL) + Store (PNL5, LNSL) + Store (OBF5, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP05) +#endif + +#if defined (ASL_RC_PORT_5) && (ASL_RC_PORT_5==1) +Scope(\_SB.PCI0.RP06) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR6, LTRE) + Store (PML6, LMSL) + Store (PNL6, LNSL) + Store (OBF6, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP06) +#endif + +#if defined (ASL_RC_PORT_6) && (ASL_RC_PORT_6==1) +Scope(\_SB.PCI0.RP07) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR7, LTRE) + Store (PML7, LMSL) + Store (PNL7, LNSL) + Store (OBF7, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP07) +#endif + +#if defined (ASL_RC_PORT_7) && (ASL_RC_PORT_7==1) +Scope(\_SB.PCI0.RP08) +{ + // + // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes. + // + Method(_INI) + { + Store (LTR8, LTRE) + Store (PML8, LMSL) + Store (PNL8, LNSL) + Store (OBF8, OBFF) + } + Method(_PRW, 0) { Return(GPRW(0x09, 4)) } +}//Scope(\_SB.PCI0.RP08) +#endif +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBCspLib.h b/Chipset/SB/SBCspLib.h new file mode 100644 index 0000000..e16cf63 --- /dev/null +++ b/Chipset/SB/SBCspLib.h @@ -0,0 +1,1536 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBCspLib.h 11 5/16/14 6:16a Barretlin $ +// +// $Revision: 11 $ +// +// $Date: 5/16/14 6:16a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBCspLib.h $ +// +// 11 5/16/14 6:16a Barretlin +// [TAG] EIP167087 +// [Category] Improvement +// [Description] BIOS security improvement on Haswell CRB project +// [Files] SBGeneric.c SBDxe.c SBCspLib.h Sb.sdl Sb.sd +// +// 10 4/19/13 6:36a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Update GbES02SxWorkaround() and add +// UsbS02SxWorkaround() for SBPwrBtnHandler(). +// [Files] SBSMI.c; SBSMI.h; SBGeneric.c; SBCspLib.h +// +// 9 3/19/13 8:33a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Improve alternate access mode enable/disable routine. +// [Files] SBGeneric.c, SBCspLib.h, SBSMI.c +// +// 8 1/10/13 8:20a Scottyang +// [TAG] EIP111666 +// [Category] New Feature +// [Description] Support OEM reset callback function Elink. +// [Files] SB.mak, SBCspLib.h, SBGeneric.c, SB.sdl, PchReset.c +// +// 7 11/21/12 3:07a Scottyang +// +// 5 9/12/12 5:17a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove useless HdmiVerbTable. +// [Files] SB.sdl, SBCspLib.h, SBDxe.c, SBGeneric.c +// +// 4 8/24/12 6:49a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove useless SB_SHADOW_CONTROL. +// [Files] SB.sdl, SBCspLib.h, SBGeneric.c +// +// 3 8/13/12 10:25a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement BIOS Lock function. +// [Files] SBCspLib.h, SBDxe.c, SBSMI.c, SBSMI.dxs, SBSMI.sdl +// +// 2 7/02/12 10:18a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Updated and modified for PCH RC 0.6.0. +// [Files] SBGeneric.c, SB.sdl, SBCspLib.h, SBDxe.c, SBPEI.c +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBCspLib.h +// +// Description: This file contains South Bridge chipset porting functions +// and data structures definition for both PEI & DXE stage. +// +//<AMI_FHDR_END> +//************************************************************************* + +#ifndef __SBLIB_H__ +#define __SBLIB_H__ + +//--------------------------------------------------------------------------- +#include <Token.h> +#include <Efi.h> +#include <Pei.h> +#include <AmiDxeLib.h> +#include <PciBus.h> +#include <ppi\ReadOnlyVariable2.h> +#include <Protocol\PciRootBridgeIo.h> +#include <Protocol\PciIo.h> +#include <Protocol\AmiSio.h> + +#if ACPI_SUPPORT + #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + #include <Protocol\S3SaveState.h> + #else + #include <Protocol\BootScriptSave.h> + #endif +#endif + + +#if CSM_SUPPORT +#include <Protocol\LegacyInterrupt.h> +#endif + +#ifndef AMI_S3_SAVE_PROTOCOL + #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) +#define AMI_S3_SAVE_PROTOCOL EFI_S3_SAVE_STATE_PROTOCOL +#define AMI_S3_SAVE_PROTOCOL_GUID &gEfiS3SaveStateProtocolGuid + #else +#define AMI_S3_SAVE_PROTOCOL EFI_BOOT_SCRIPT_SAVE_PROTOCOL +#define AMI_S3_SAVE_PROTOCOL_GUID &gEfiBootScriptSaveGuid + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CORE_VERSION +#define CORE_VERSION ( CORE_MAJOR_VERSION * 1000 + \ + CORE_MINOR_VERSION * 100 + \ + CORE_REVISION * 10 + \ + CORE_BUILD_NUMBER ) +#endif + +#ifndef PCIBUS_VERSION +#define PCIBUS_VERSION ( PCI_BUS_MAJOR_VER * 10000 + \ + PCI_BUS_MINOR_VER * 100 + \ + PCI_BUS_REVISION ) +#endif + +#define COMPLETE_SAVE_RESTORE_STD_CMOS 0x00 +#define ENABLE_NMI_BEFORE_SMI_EXIT 0x01 +#define DISABLE_NMI_BEFORE_SMI_EXIT 0x02 + +#ifndef EFI_SIGNATURE_16 +#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8)) +#endif + +#ifndef EFI_SIGNATURE_32 +#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16)) +#endif + +#define KBShift 10 +#define MBShift 20 + +typedef enum { + PchH = 1, + PchLp, + PchUnknownSeries +} PCH_SERIES; + +// Type Definition(s) + +typedef struct { + UINT64 Address; + EFI_BOOT_SCRIPT_WIDTH Width; + UINT32 Mask; +} BOOT_SCRIPT_SB_PCI_REG_SAVE; + +typedef enum { + SbResetFull, + SbResetGlobal +} SB_EXT_RESET_TYPE; + +typedef enum { + AnyType, + DescriptorType, + BiosType, + MeType, + GbeType, + PlatformDataType, + DeviceExpansionType, + SecondaryBiosType, + BfpregType, + PchSpiRangeTypeMax +} AMI_SB_SPI_RANGE_TYPE; + +typedef struct{ + UINTN ProtectedRangeType; + BOOLEAN WriteProtectEnable; + BOOLEAN ReadProtectEnable; + UINTN ProtectedRangeBase; + UINTN ProtectedRangeLength; +} SPI_PROTECTED_RANGE_CONIFG; + +#if CSM_SUPPORT + +EFI_STATUS SBGen_InitializeRouterRegisters ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRBIo +); + +UINT8 SBGen_GetPIRQIndex ( + IN UINT8 PIRQRegister +); + +EFI_STATUS SBGen_ReadPirq ( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + IN UINT8 PirqNumber, + OUT UINT8 *PirqData +); + +EFI_STATUS SBGen_WritePirq ( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + IN UINT8 PirqNumber, + IN UINT8 PirqData +); + +#endif + +EFI_STATUS SBProtectedPciDevice ( + IN PCI_DEV_INFO *PciDevice +); + +EFI_STATUS SBProgramPciDevice ( + IN PCI_DEV_INFO *PciDevice +); + +EFI_STATUS SBUpdatePciDeviceAttributes ( + IN PCI_DEV_INFO *PciDevice, + IN OUT UINT64 *Attributes, + IN UINT64 Capabilities, + IN BOOLEAN Set +); + +EFI_STATUS ReadSPIDescriptor ( + IN UINT8 FDSS, + IN UINT8 FDSI, + OUT UINT32 *FDOD +); + +UINT32 GetTotalFlashRomSize( VOID ); + +EFI_STATUS SbGetSpiRangeAddresses( + IN AMI_SB_SPI_RANGE_TYPE RangeType, + OUT UINT32 *BaseAddress, + OUT UINT32 *EndAddress +); + +EFI_STATUS SbFlashProtectedRange( VOID ); + +UINT32 SbFindCapPtr( + IN UINT64 PciAddress, + IN UINT8 CapId +); + +VOID SBSwSmiWriteToBootScript ( + IN AMI_S3_SAVE_PROTOCOL *BootScriptSave +); + +EFI_STATUS SBGen_WriteBootScript ( + IN AMI_S3_SAVE_PROTOCOL *BootScriptSave +); + +VOID WriteIo8IdxDataS3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBase16, + IN UINT8 IoReg8, + IN UINT8 WriteValue8 +); + +VOID RwIo8IdxDataS3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBase16, + IN UINT8 IoReg8, + IN UINT8 SetBit8, + IN UINT8 ResetBit8 +); + +VOID WriteIo8S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT8 WriteValue8 +); + +VOID WriteIo16S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT16 WriteValue16 +); + +VOID WriteIo32S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT32 WriteValue32 +); + +VOID RwIo8S3( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT8 SetBit8, + IN UINT8 ResetBit8 +); + +VOID RwIo16S3( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT16 SetBit16, + IN UINT16 ResetBit16 +); + +VOID RwIo32S3( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT32 SetBit32, + IN UINT32 ResetBit32 +); + +VOID SBLib_BeforeShutdown ( VOID ); + +VOID SBLib_Shutdown ( VOID ); +VOID GbES0ToS1Workaround(VOID); +VOID GbES0ToSxWorkaround(VOID); +VOID Enable_GbE_PME(VOID); +VOID ClearMeWakeSts(VOID); +VOID EHCIAdditionalRequirement(VOID); + +BOOLEAN SBIsDefaultConfigMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadVariablePpi +); + +UINT8 SBLib_CmosRead( + IN UINT8 Index +); + +VOID SBLib_CmosWrite( + IN UINT8 Index, + IN UINT8 Value +); + +PCH_SERIES +EFIAPI +GetPchSeries ( + VOID +); + +UINT8 +EFIAPI +GetPchMaxPciePortNum ( + VOID +); + +UINT8 +EFIAPI +GetPchMaxSataPortNum ( + VOID +); + +UINT8 +EFIAPI +GetPchUsbMaxPhysicalPortNum ( + VOID +); + +UINT8 +EFIAPI +GetPchXhciMaxUsb3PortNum ( + VOID +); + +UINT8 +EFIAPI +GetPchEhciMaxControllerNum ( + VOID +); + +EFI_STATUS +SbLib_RunTimeResetCallback( + IN EFI_RESET_TYPE ResetType + ); + +#if SB_RESET_PPI_SUPPORT +VOID SBLib_ResetSystem ( + IN EFI_RESET_TYPE ResetType +); +#endif + +VOID SBLib_ExtResetSystem ( + IN SB_EXT_RESET_TYPE ResetType +); + +#if SB_STALL_PPI_SUPPORT +EFI_STATUS CountTime ( + IN UINTN DelayTime, + IN UINT16 BaseAddr // only needs to be 16 bit for I/O address +); +#endif + +#if SMM_SUPPORT +EFI_STATUS SBSmmSaveRestoreStates ( + IN BOOLEAN Save +); +#endif + +//--------------------------------------------------------------------------- +// CMOS Manager Support +// +// Southbridge should implement functions to support access to additional +// CMOS banks that exist beyond the first 128 bytes. +//--------------------------------------------------------------------------- + +#if CMOS_MANAGER_SUPPORT +#include <CmosAccess.h> + +EFI_STATUS ReadWriteCmosBank2 ( + IN EFI_PEI_SERVICES **PeiServices, // NULL in DXE phase + IN CMOS_ACCESS_TYPE AccessType, + IN UINT16 CmosRegister, + IN OUT UINT8 *CmosParameterValue +); + +BOOLEAN SbGetRtcPowerStatus ( + IN EFI_PEI_SERVICES **PeiServices // NULL in DXE phase +); + +#endif // #if CMOS_MANAGER_SUPPORT + +//--------------------------------------------------------------------------- + +//UINT8 ReadCmos (IN UINT8 Index); +//VOID WriteCmos (IN UINT8 Index, IN UINT8 Value); +BOOLEAN SbLib_GetSmiState (VOID); +VOID SbLib_SmiDisable (VOID); +VOID SbLib_SmiEnable (VOID); +VOID CspLibCheckPowerLoss (VOID); + +//--------------------------------------------------------------------------- + +VOID ChipsetFlashDeviceWriteEnable (VOID); +VOID ChipsetFlashDeviceWriteDisable (VOID); + +//--------------------------------------------------------------------------- + +EFI_STATUS SbLib_SetLpcDeviceDecoding ( + IN EFI_PCI_IO_PROTOCOL *LpcPciIo, + IN UINT16 Base, + IN UINT8 DevUid, + IN SIO_DEV_TYPE Type +); + +EFI_STATUS SbLib_SetLpcGenericDecoding ( + IN EFI_PCI_IO_PROTOCOL *LpcPciIo, + IN UINT16 Base, + IN UINT16 Length, + IN BOOLEAN Enable +); + +//--------------------------------------------------------------------------- +UINT8 RtcRead ( + IN UINT8 Location +); + +UINT8 ReadIo8IdxData ( + IN UINT16 IoBase16, + IN UINT8 RegIdx8 +); + +VOID WriteIo8IdxData ( + IN UINT16 IoBase16, + IN UINT8 RegIdx8, + IN UINT8 WriteValue8 +); + +VOID RwIo8IdxData ( + IN UINT16 IoBase16, + IN UINT8 RegIdx8, + IN UINT8 SetBit8, + IN UINT8 ResetBit8 +); + +VOID BiosLockEnableSMIFlashHook ( + IN UINT8 SwSmiNum, + IN OUT UINT64 Buffer +); + +VOID SwitchAlternateAccessMode //Improve alternate access mode >> +( + BOOLEAN Switch +); + +UINT8 ReadPort70h ( VOID ); //Improve alternate access mode << +//--------------------------------------------------------------------------- +// Standard I/O Macros, No Porting Required. +//--------------------------------------------------------------------------- +#define ReadIo8(IoAddr) IoRead8(IoAddr) +#define READ_IO8(IoAddr) IoRead8(IoAddr) +#define WriteIo8(IoAddr, bVal) IoWrite8(IoAddr, bVal) +#define WRITE_IO8(IoAddr, bVal) IoWrite8(IoAddr, bVal) +#define SET_IO8(IoAddr, bSet) IoWrite8(IoAddr, IoRead8(IoAddr) | (bSet)) +#define RESET_IO8(IoAddr, bRst) IoWrite8(IoAddr, IoRead8(IoAddr) & ~(bRst)) +#define RW_IO8(Bx, Set, Rst) IoWrite8(Bx, IoRead8(Bx) & ~(Rst) | (Set)) +#define ReadIo16(IoAddr) IoRead16(IoAddr) +#define READ_IO16(IoAddr) IoRead16(IoAddr) +#define WriteIo16(IoAddr, wVal) IoWrite16(IoAddr, wVal) +#define WRITE_IO16(IoAddr, wVal) IoWrite16(IoAddr, wVal) +#define SET_IO16(IoAddr, wSet) IoWrite16(IoAddr, IoRead16(IoAddr) | (wSet)) +#define RESET_IO16(IoAddr, Rst) IoWrite16(IoAddr, IoRead16(IoAddr) & ~(Rst)) +#define RW_IO16(Bx, Set, Rst) IoWrite16(Bx, IoRead16(Bx) & ~(Rst) | (Set)) +#define ReadIo32(IoAddr) IoRead32(IoAddr) +#define READ_IO32(IoAddr) IoRead32(IoAddr) +#define WriteIo32(IoAddr, dVal) IoWrite32(IoAddr, dVal) +#define WRITE_IO32(IoAddr, dVal) IoWrite32(IoAddr, dVal) +#define SET_IO32(IoAddr, dSet) IoWrite32(IoAddr, IoRead32(IoAddr) | (dSet)) +#define RESET_IO32(IoAddr, Rst) IoWrite32(IoAddr, IoRead32(IoAddr) & ~(Rst)) +#define RW_IO32(Bx, Set, Rst) IoWrite32(Bx, IoRead32(Bx) & ~(Rst) | (Set)) + +#define WRITE_IO8_S3(mBtScSv, IoAddr16, bValue) \ + WriteIo8S3(mBtScSv, IoAddr16, bValue) +#define SET_IO8_S3(mBtScSv, IoAddr16, bSet) \ + RwIo8S3(mBtScSv, IoAddr16, bSet, 0) +#define RESET_IO8_S3(mBtScSv, IoAddr16, bReset) \ + RwIo8S3(mBtScSv, IoAddr16, 0, bReset) +#define RW_IO8_S3(mBtScSv, IoAddr16, bSet, bReset) \ + RwIo8S3(mBtScSv, IoAddr16, bSet, bReset) +#define WRITE_IO16_S3(mBtScSv, IoAddr16, wValue) \ + WriteIo16S3(mBtScSv, IoAddr16, wValue) +#define SET_IO16_S3(mBtScSv, IoAddr16, wSet) \ + RwIo16S3(mBtScSv, IoAddr16, wSet, 0) +#define RESET_IO16_S3(mBtScSv, IoAddr16, wReset) \ + RwIo16S3(mBtScSv, IoAddr16, 0, wReset) +#define RW_IO16_S3(mBtScSv, IoAddr16, wSet, wReset) \ + RwIo16S3(mBtScSv, IoAddr16, wSet, wReset) +#define WRITE_IO32_S3(mBtScSv, IoAddr16, dValue) \ + WriteIo32S3(mBtScSv, IoAddr16, dValue) +#define SET_IO32_S3(mBtScSv, IoAddr16, dSet) \ + RwIo32S3(mBtScSv, IoAddr16, dSet, 0) +#define RESET_IO32_S3(mBtScSv, IoAddr16, dReset) \ + RwIo32S3(mBtScSv, IoAddr16, 0, dReset) +#define RW_IO32_S3(mBtScSv, IoAddr16, dSet, dReset) \ + RwIo32S3(mBtScSv, IoAddr16, dSet, dReset) + +//--------------------------------------------------------------------------- +// Chipset PCI Macros, Porting Required. +//--------------------------------------------------------------------------- + +#define READ_PCI8_SB(Rx) READ_PCI8(SB_BUS, SB_DEV, SB_FUN, Rx) +#define WRITE_PCI8_SB(Rx, Val) WRITE_PCI8(SB_BUS, SB_DEV, SB_FUN, Rx, Val) +#define SET_PCI8_SB(Rx, Set) SET_PCI8(SB_BUS, SB_DEV, SB_FUN, Rx, Set) +#define RESET_PCI8_SB(Rx, Rst) RESET_PCI8(SB_BUS, SB_DEV, SB_FUN, Rx, Rst) +#define RW_PCI8_SB(Rx, St, Rt) RW_PCI8(SB_BUS, SB_DEV, SB_FUN, Rx, St, Rt) +#define READ_PCI16_SB(Rx) READ_PCI16(SB_BUS, SB_DEV, SB_FUN, Rx) +#define WRITE_PCI16_SB(Rx, Val) WRITE_PCI16(SB_BUS, SB_DEV, SB_FUN, Rx, Val) +#define SET_PCI16_SB(Rx, Set) SET_PCI16(SB_BUS, SB_DEV, SB_FUN, Rx, Set) +#define RESET_PCI16_SB(Rx, Rst) RESET_PCI16(SB_BUS, SB_DEV, SB_FUN, Rx, Rst) +#define RW_PCI16_SB(Rx, St, Rt) RW_PCI16(SB_BUS, SB_DEV, SB_FUN, Rx, St, Rt) +#define READ_PCI32_SB(Rx) READ_PCI32(SB_BUS, SB_DEV, SB_FUN, Rx) +#define WRITE_PCI32_SB(Rx, Val) WRITE_PCI32(SB_BUS, SB_DEV, SB_FUN, Rx, Val) +#define SET_PCI32_SB(Rx, Set) SET_PCI32(SB_BUS, SB_DEV, SB_FUN, Rx, Set) +#define RESET_PCI32_SB(Rx, Rst) RESET_PCI32(SB_BUS, SB_DEV, SB_FUN, Rx, Rst) +#define RW_PCI32_SB(Rx, St, Rt) RW_PCI32(SB_BUS, SB_DEV, SB_FUN, Rx, St, Rt) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_SATA(Rx) \ + READ_PCI8(SATA_BUS, SATA_DEV, SATA_FUN, Rx) +#define WRITE_PCI8_SATA(Rx, Val) \ + WRITE_PCI8(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Val) +#define SET_PCI8_SATA(Rx, Set) \ + SET_PCI8(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set) +#define RESET_PCI8_SATA(Rx, Rst) \ + RESET_PCI8(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Rst) +#define RW_PCI8_SATA(Rx, Set, Rst) \ + RW_PCI8(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set, Rst) +#define READ_PCI16_SATA(Rx) \ + READ_PCI16(SATA_BUS, SATA_DEV, SATA_FUN, Rx) +#define WRITE_PCI16_SATA(Rx, Val) \ + WRITE_PCI16(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Val) +#define SET_PCI16_SATA(Rx, Set) \ + SET_PCI16(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set) +#define RESET_PCI16_SATA(Rx, Rst) \ + RESET_PCI16(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Rst) +#define RW_PCI16_SATA(Rx, Set, Rst) \ + RW_PCI16(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set, Rst) +#define READ_PCI32_SATA(Rx) \ + READ_PCI32(SATA_BUS, SATA_DEV, SATA_FUN, Rx) +#define WRITE_PCI32_SATA(Rx, Val) \ + WRITE_PCI32(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Val) +#define SET_PCI32_SATA(Rx, Set) \ + SET_PCI32(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set) +#define RESET_PCI32_SATA(Rx, Rst) \ + RESET_PCI32(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Rst) +#define RW_PCI32_SATA(Rx, Set, Rst) \ + RW_PCI32(SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_SATA2(Rx) \ + READ_PCI8(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx) +#define WRITE_PCI8_SATA2(Rx, Val) \ + WRITE_PCI8(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Val) +#define SET_PCI8_SATA2(Rx, Set) \ + SET_PCI8(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set) +#define RESET_PCI8_SATA2(Rx, Rst) \ + RESET_PCI8(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Rst) +#define RW_PCI8_SATA2(Rx, Set, Rst) \ + RW_PCI8(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set, Rst) +#define READ_PCI16_SATA2(Rx) \ + READ_PCI16(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx) +#define WRITE_PCI16_SATA2(Rx, Val) \ + WRITE_PCI16(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Val) +#define SET_PCI16_SATA2(Rx, Set) \ + SET_PCI16(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set) +#define RESET_PCI16_SATA2(Rx, Rst) \ + RESET_PCI16(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Rst) +#define RW_PCI16_SATA2(Rx, Set, Rst) \ + RW_PCI16(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set, Rst) +#define READ_PCI32_SATA2(Rx) \ + READ_PCI32(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx) +#define WRITE_PCI32_SATA2(Rx, Val) \ + WRITE_PCI32(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Val) +#define SET_PCI32_SATA2(Rx, Set) \ + SET_PCI32(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set) +#define RESET_PCI32_SATA2(Rx, Rst) \ + RESET_PCI32(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Rst) +#define RW_PCI32_SATA2(Rx, Set, Rst) \ + RW_PCI32(SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_PCIEBRS(Rx) \ + READ_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx) +#define WRITE_PCI8_PCIEBRS(Rx, Val) \ + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Val) +#define SET_PCI8_PCIEBRS(Rx, Set) \ + SET_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set) +#define RESET_PCI8_PCIEBRS(Rx, Rst) \ + RESET_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Rst) +#define RW_PCI8_PCIEBRS(Rx, Set, Rst) \ + RW_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set, Rst) +#define READ_PCI16_PCIEBRS(Rx) \ + READ_PCI16(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx) +#define WRITE_PCI16_PCIEBRS(Rx, Val) \ + WRITE_PCI16(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Val) +#define SET_PCI16_PCIEBRS(Rx, Set) \ + SET_PCI16(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set) +#define RESET_PCI16_PCIEBRS(Rx, Rst) \ + RESET_PCI16(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Rst) +#define RW_PCI16_PCIEBRS(Rx, Set, Rst) \ + RW_PCI16(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set, Rst) +#define READ_PCI32_PCIEBRS(Rx) \ + READ_PCI32(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx) +#define WRITE_PCI32_PCIEBRS(Rx, Val) \ + WRITE_PCI32(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Val) +#define SET_PCI32_PCIEBRS(Rx, Set) \ + SET_PCI32(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set) +#define RESET_PCI32_PCIEBRS(Rx, Rst) \ + RESET_PCI32(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Rst) +#define RW_PCI32_PCIEBRS(Rx, Set, Rst) \ + RW_PCI32(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_PCIBR(Rx) \ + READ_PCI8(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx) +#define WRITE_PCI8_PCIBR(Rx, Val) \ + WRITE_PCI8(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Val) +#define SET_PCI8_PCIBR(Rx, Set) \ + SET_PCI8(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set) +#define RESET_PCI8_PCIBR(Rx, Rst) \ + RESET_PCI8(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Rst) +#define RW_PCI8_PCIBR(Rx, Set, Rst) \ + RW_PCI8(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set, Rst) +#define READ_PCI16_PCIBR(Rx) \ + READ_PCI16(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx) +#define WRITE_PCI16_PCIBR(Rx, Val) \ + WRITE_PCI16(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Val) +#define SET_PCI16_PCIBR(Rx, Set) \ + SET_PCI16(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set) +#define RESET_PCI16_PCIBR(Rx, Rst) \ + RESET_PCI16(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Rst) +#define RW_PCI16_PCIBR(Rx, Set, Rst) \ + RW_PCI16(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set, Rst) +#define READ_PCI32_PCIBR(Rx) \ + READ_PCI32(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx) +#define WRITE_PCI32_PCIBR(Rx, Val) \ + WRITE_PCI32(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Val) +#define SET_PCI32_PCIBR(Rx, Set) \ + SET_PCI32(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set) +#define RESET_PCI32_PCIBR(Rx, Rst) \ + RESET_PCI32(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Rst) +#define RW_PCI32_PCIBR(Rx, Set, Rst) \ + RW_PCI32(PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_EHCI(Rx) READ_PCI8(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx) +#define WRITE_PCI8_EHCI(Rx, Vx) WRITE_PCI8(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Vx) +#define SET_PCI8_EHCI(Rx, Set) SET_PCI8(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Set) +#define RESET_PCI8_EHCI(Rx, Rt) RESET_PCI8(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Rt) +#define RW_PCI8_EHCI(Rx,St,Rt) RW_PCI8(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, St, Rt) +#define READ_PCI16_EHCI(Rx) READ_PCI16(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx) +#define WRITE_PCI16_EHCI(Rx, Vx) WRITE_PCI16(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Vx) +#define SET_PCI16_EHCI(Rx, Set) SET_PCI16(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Set) +#define RESET_PCI16_EHCI(Rx, Rt) RESET_PCI16(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Rt) +#define RW_PCI16_EHCI(Rx,St,Rt) RW_PCI16(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, St,Rt) +#define READ_PCI32_EHCI(Rx) READ_PCI32(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx) +#define WRITE_PCI32_EHCI(Rx, Vx) WRITE_PCI32(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Vx) +#define SET_PCI32_EHCI(Rx, Set) SET_PCI32(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Set) +#define RESET_PCI32_EHCI(Rx, Rt) RESET_PCI32(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, Rt) +#define RW_PCI32_EHCI(Rx,St,Rt) RW_PCI32(EHCI_BUS, EHCI_DEV, EHCI_FUN, Rx, St,Rt) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_EHCI2(Rx) \ + READ_PCI8(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx) +#define WRITE_PCI8_EHCI2(Rx, Val) \ + WRITE_PCI8(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Val) +#define SET_PCI8_EHCI2(Rx, Set) \ + SET_PCI8(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set) +#define RESET_PCI8_EHCI2(Rx, Rst) \ + RESET_PCI8(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Rst) +#define RW_PCI8_EHCI2(Rx, Set, Rst) \ + RW_PCI8(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set, Rst) +#define READ_PCI16_EHCI2(Rx) \ + READ_PCI16(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx) +#define WRITE_PCI16_EHCI2(Rx, Val) \ + WRITE_PCI16(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Val) +#define SET_PCI16_EHCI2(Rx, Set) \ + SET_PCI16(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set) +#define RESET_PCI16_EHCI2(Rx, Rst) \ + RESET_PCI16(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Rst) +#define RW_PCI16_EHCI2(Rx, Set, Rst) \ + RW_PCI16(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set, Rst) +#define READ_PCI32_EHCI2(Rx) \ + READ_PCI32(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx) +#define WRITE_PCI32_EHCI2(Rx, Val) \ + WRITE_PCI32(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Val) +#define SET_PCI32_EHCI2(Rx, Set) \ + SET_PCI32(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set) +#define RESET_PCI32_EHCI2(Rx, Rst) \ + RESET_PCI32(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Rst) +#define RW_PCI32_EHCI2(Rx, Set, Rst) \ + RW_PCI32(EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_LAN(Rx) READ_PCI8(LAN_BUS, LAN_DEV, LAN_FUN, Rx) +#define WRITE_PCI8_LAN(Rx, Vx) WRITE_PCI8(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Vx) +#define SET_PCI8_LAN(Rx, Set) SET_PCI8(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set) +#define RESET_PCI8_LAN(Rx, Rt) RESET_PCI8(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Rt) +#define RW_PCI8_LAN(Rx,St,Rt) RW_PCI8(LAN_BUS, LAN_DEV, LAN_FUN, Rx, St, Rt) +#define READ_PCI16_LAN(Rx) READ_PCI16(LAN_BUS, LAN_DEV, LAN_FUN, Rx) +#define WRITE_PCI16_LAN(Rx, Vx) WRITE_PCI16(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Vx) +#define SET_PCI16_LAN(Rx, Set) SET_PCI16(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set) +#define RESET_PCI16_LAN(Rx, Rt) RESET_PCI16(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Rt) +#define RW_PCI16_LAN(Rx,St,Rt) RW_PCI16(LAN_BUS, LAN_DEV, LAN_FUN, Rx, St,Rt) +#define READ_PCI32_LAN(Rx) READ_PCI32(LAN_BUS, LAN_DEV, LAN_FUN, Rx) +#define WRITE_PCI32_LAN(Rx, Vx) WRITE_PCI32(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Vx) +#define SET_PCI32_LAN(Rx, Set) SET_PCI32(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set) +#define RESET_PCI32_LAN(Rx, Rt) RESET_PCI32(LAN_BUS, LAN_DEV, LAN_FUN, Rx, Rt) +#define RW_PCI32_LAN(Rx,St,Rt) RW_PCI32(LAN_BUS, LAN_DEV, LAN_FUN, Rx, St,Rt) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_HDA(Rx) READ_PCI8(HDA_BUS, HDA_DEV, HDA_FUN, Rx) +#define WRITE_PCI8_HDA(Rx, Vx) WRITE_PCI8(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Vx) +#define SET_PCI8_HDA(Rx, Set) SET_PCI8(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set) +#define RESET_PCI8_HDA(Rx, Rt) RESET_PCI8(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Rt) +#define RW_PCI8_HDA(Rx,St,Rt) RW_PCI8(HDA_BUS, HDA_DEV, HDA_FUN, Rx, St, Rt) +#define READ_PCI16_HDA(Rx) READ_PCI16(HDA_BUS, HDA_DEV, HDA_FUN, Rx) +#define WRITE_PCI16_HDA(Rx, Vx) WRITE_PCI16(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Vx) +#define SET_PCI16_HDA(Rx, Set) SET_PCI16(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set) +#define RESET_PCI16_HDA(Rx, Rt) RESET_PCI16(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Rt) +#define RW_PCI16_HDA(Rx,St,Rt) RW_PCI16(HDA_BUS, HDA_DEV, HDA_FUN, Rx, St,Rt) +#define READ_PCI32_HDA(Rx) READ_PCI32(HDA_BUS, HDA_DEV, HDA_FUN, Rx) +#define WRITE_PCI32_HDA(Rx, Vx) WRITE_PCI32(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Vx) +#define SET_PCI32_HDA(Rx, Set) SET_PCI32(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set) +#define RESET_PCI32_HDA(Rx, Rt) RESET_PCI32(HDA_BUS, HDA_DEV, HDA_FUN, Rx, Rt) +#define RW_PCI32_HDA(Rx,St,Rt) RW_PCI32(HDA_BUS, HDA_DEV, HDA_FUN, Rx, St,Rt) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_SMBUS(Rx) \ + READ_PCI8(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx) +#define WRITE_PCI8_SMBUS(Rx, Val) \ + WRITE_PCI8(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Val) +#define SET_PCI8_SMBUS(Rx, Set) \ + SET_PCI8(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set) +#define RESET_PCI8_SMBUS(Rx, Rst) \ + RESET_PCI8(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Rst) +#define RW_PCI8_SMBUS(Rx, Set, Rst) \ + RW_PCI8(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set, Rst) +#define READ_PCI16_SMBUS(Rx) \ + READ_PCI16(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx) +#define WRITE_PCI16_SMBUS(Rx, Val) \ + WRITE_PCI16(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Val) +#define SET_PCI16_SMBUS(Rx, Set) \ + SET_PCI16(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set) +#define RESET_PCI16_SMBUS(Rx, Rst) \ + RESET_PCI16(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Rst) +#define RW_PCI16_SMBUS(Rx, Set, Rst) \ + RW_PCI16(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set, Rst) +#define READ_PCI32_SMBUS(Rx) \ + READ_PCI32(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx) +#define WRITE_PCI32_SMBUS(Rx, Val) \ + WRITE_PCI32(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Val) +#define SET_PCI32_SMBUS(Rx, Set) \ + SET_PCI32(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set) +#define RESET_PCI32_SMBUS(Rx, Rst) \ + RESET_PCI32(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Rst) +#define RW_PCI32_SMBUS(Rx, Set, Rst) \ + RW_PCI32(SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_HECI(Rx) \ + READ_PCI8(HECI_BUS, HECI_DEV, HECI_FUN, Rx) +#define WRITE_PCI8_HECI(Rx, Val) \ + WRITE_PCI8(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Val) +#define SET_PCI8_HECI(Rx, Set) \ + SET_PCI8(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set) +#define RESET_PCI8_HECI(Rx, Rst) \ + RESET_PCI8(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Rst) +#define RW_PCI8_HECI(Rx, Set, Rst) \ + RW_PCI8(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set, Rst) +#define READ_PCI16_HECI(Rx) \ + READ_PCI16(HECI_BUS, HECI_DEV, HECI_FUN, Rx) +#define WRITE_PCI16_HECI(Rx, Val) \ + WRITE_PCI16(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Val) +#define SET_PCI16_HECI(Rx, Set) \ + SET_PCI16(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set) +#define RESET_PCI16_HECI(Rx, Rst) \ + RESET_PCI16(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Rst) +#define RW_PCI16_HECI(Rx, Set, Rst) \ + RW_PCI16(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set, Rst) +#define READ_PCI32_HECI(Rx) \ + READ_PCI32(HECI_BUS, HECI_DEV, HECI_FUN, Rx) +#define WRITE_PCI32_HECI(Rx, Val) \ + WRITE_PCI32(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Val) +#define SET_PCI32_HECI(Rx, Set) \ + SET_PCI32(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set) +#define RESET_PCI32_HECI(Rx, Rst) \ + RESET_PCI32(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Rst) +#define RW_PCI32_HECI(Rx, Set, Rst) \ + RW_PCI32(HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_PCI8_HECI2(Rx) \ + READ_PCI8(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx) +#define WRITE_PCI8_HECI2(Rx, Val) \ + WRITE_PCI8(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Val) +#define SET_PCI8_HECI2(Rx, Set) \ + SET_PCI8(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set) +#define RESET_PCI8_HECI2(Rx, Rst) \ + RESET_PCI8(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Rst) +#define RW_PCI8_HECI2(Rx, Set, Rst) \ + RW_PCI8(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set, Rst) +#define READ_PCI16_HECI2(Rx) \ + READ_PCI16(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx) +#define WRITE_PCI16_HECI2(Rx, Val) \ + WRITE_PCI16(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Val) +#define SET_PCI16_HECI2(Rx, Set) \ + SET_PCI16(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set) +#define RESET_PCI16_HECI2(Rx, Rst) \ + RESET_PCI16(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Rst) +#define RW_PCI16_HECI2(Rx, Set, Rst) \ + RW_PCI16(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set, Rst) +#define READ_PCI32_HECI2(Rx) \ + READ_PCI32(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx) +#define WRITE_PCI32_HECI2(Rx, Val) \ + WRITE_PCI32(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Val) +#define SET_PCI32_HECI2(Rx, Set) \ + SET_PCI32(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set) +#define RESET_PCI32_HECI2(Rx, Rst) \ + RESET_PCI32(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Rst) +#define RW_PCI32_HECI2(Rx, Set, Rst) \ + RW_PCI32(HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_SB_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Val) +#define SET_PCI8_SB_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Set) +#define RESET_PCI8_SB_S3(mBoot, Rx, Reset) \ + RESET_PCI8_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Reset) +#define RW_PCI8_SB_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Set, Rst) +#define WRITE_PCI16_SB_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Val) +#define SET_PCI16_SB_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Set) +#define RESET_PCI16_SB_S3(mBoot, Rx, Reset) \ + RESET_PCI16_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Reset) +#define RW_PCI16_SB_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Set, Rst) +#define WRITE_PCI32_SB_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Val) +#define SET_PCI32_SB_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Set) +#define RESET_PCI32_SB_S3(mBoot, Rx, Reset) \ + RESET_PCI32_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Reset) +#define RW_PCI32_SB_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, SB_BUS, SB_DEV, SB_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_SATA_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Val) +#define SET_PCI8_SATA_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set) +#define RESET_PCI8_SATA_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Rst) +#define RW_PCI8_SATA_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set, Rst) +#define WRITE_PCI16_SATA_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Val) +#define SET_PCI16_SATA_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set) +#define RESET_PCI16_SATA_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Rst) +#define RW_PCI16_SATA_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set, Rst) +#define WRITE_PCI32_SATA_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Val) +#define SET_PCI32_SATA_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set) +#define RESET_PCI32_SATA_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Rst) +#define RW_PCI32_SATA_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, SATA_BUS, SATA_DEV, SATA_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_SATA2_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Val) +#define SET_PCI8_SATA2_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set) +#define RESET_PCI8_SATA2_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Rst) +#define RW_PCI8_SATA2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set, Rst) +#define WRITE_PCI16_SATA2_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Val) +#define SET_PCI16_SATA2_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set) +#define RESET_PCI16_SATA2_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Rst) +#define RW_PCI16_SATA2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set, Rst) +#define WRITE_PCI32_SATA2_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Val) +#define SET_PCI32_SATA2_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set) +#define RESET_PCI32_SATA2_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Rst) +#define RW_PCI32_SATA2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, SATA2_BUS, SATA2_DEV, SATA2_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_PCIEBRS_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Val) +#define SET_PCI8_PCIEBRS_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set) +#define RESET_PCI8_PCIEBRS_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Rst) +#define RW_PCI8_PCIEBRS_S3(mBoot, Rx, St, Rt) \ + RW_PCI8_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, St, Rt) +#define WRITE_PCI16_PCIEBRS_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Val) +#define SET_PCI16_PCIEBRS_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set) +#define RESET_PCI16_PCIEBRS_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Rst) +#define RW_PCI16_PCIEBRS_S3(mBoot, Rx, St, Rt) \ + RW_PCI16_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, St, Rt) +#define WRITE_PCI32_PCIEBRS_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Val) +#define SET_PCI32_PCIEBRS_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Set) +#define RESET_PCI32_PCIEBRS_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, Rst) +#define RW_PCI32_PCIEBRS_S3(mBoot, Rx, St, Rt) \ + RW_PCI32_S3(mBoot, PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, Rx, St, Rt) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_PCIBR_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Val) +#define SET_PCI8_PCIBR_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set) +#define RESET_PCI8_PCIBR_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Rst) +#define RW_PCI8_PCIBR_S3(mBoot, Rx, St, Rt) \ + RW_PCI8_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, St, Rt) +#define WRITE_PCI16_PCIBR_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Val) +#define SET_PCI16_PCIBR_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set) +#define RESET_PCI16_PCIBR_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Rst) +#define RW_PCI16_PCIBR_S3(mBoot, Rx, St, Rt) \ + RW_PCI16_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, St, Rt) +#define WRITE_PCI32_PCIBR_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Val) +#define SET_PCI32_PCIBR_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Set) +#define RESET_PCI32_PCIBR_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, Rst) +#define RW_PCI32_PCIBR_S3(mBoot, Rx, St, Rt) \ + RW_PCI32_S3(mBoot, PCIBR_BUS, PCIBR_DEV, PCIBR_FUN, Rx, St, Rt) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_EHCI_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Val) +#define SET_PCI8_EHCI_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Set) +#define RESET_PCI8_EHCI_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Rst) +#define RW_PCI8_EHCI_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Set, Rst) +#define WRITE_PCI16_EHCI_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Val) +#define SET_PCI16_EHCI_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Set) +#define RESET_PCI16_EHCI_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Rst) +#define RW_PCI16_EHCI_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Set, Rst) +#define WRITE_PCI32_EHCI_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Val) +#define SET_PCI32_EHCI_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Set) +#define RESET_PCI32_EHCI_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Rst) +#define RW_PCI32_EHCI_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, EHCI_BUS, EHCI_DEV, EHCI_DEV, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_EHCI2_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Val) +#define SET_PCI8_EHCI2_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set) +#define RESET_PCI8_EHCI2_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Rst) +#define RW_PCI8_EHCI2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set, Rst) +#define WRITE_PCI16_EHCI2_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Val) +#define SET_PCI16_EHCI2_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set) +#define RESET_PCI16_EHCI2_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Rst) +#define RW_PCI16_EHCI2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set, Rst) +#define WRITE_PCI32_EHCI2_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Val) +#define SET_PCI32_EHCI2_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set) +#define RESET_PCI32_EHCI2_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Rst) +#define RW_PCI32_EHCI2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, EHCI2_BUS, EHCI2_DEV, EHCI2_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_LAN_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Val) +#define SET_PCI8_LAN_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set) +#define RESET_PCI8_LAN_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Rst) +#define RW_PCI8_LAN_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set, Rst) +#define WRITE_PCI16_LAN_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Val) +#define SET_PCI16_LAN_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set) +#define RESET_PCI16_LAN_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Rst) +#define RW_PCI16_LAN_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set, Rst) +#define WRITE_PCI32_LAN_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Val) +#define SET_PCI32_LAN_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set) +#define RESET_PCI32_LAN_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Rst) +#define RW_PCI32_LAN_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, LAN_BUS, LAN_DEV, LAN_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_HDA_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Val) +#define SET_PCI8_HDA_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set) +#define RESET_PCI8_HDA_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Rst) +#define RW_PCI8_HDA_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set, Rst) +#define WRITE_PCI16_HDA_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Val) +#define SET_PCI16_HDA_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set) +#define RESET_PCI16_HDA_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Rst) +#define RW_PCI16_HDA_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set, Rst) +#define WRITE_PCI32_HDA_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Val) +#define SET_PCI32_HDA_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set) +#define RESET_PCI32_HDA_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Rst) +#define RW_PCI32_HDA_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, HDA_BUS, HDA_DEV, HDA_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_SMBUS_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Val) +#define SET_PCI8_SMBUS_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set) +#define RESET_PCI8_SMBUS_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Rst) +#define RW_PCI8_SMBUS_S3(mBoot, Rx, St, Rt) \ + RW_PCI8_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, St, Rt) +#define WRITE_PCI16_SMBUS_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Val) +#define SET_PCI16_SMBUS_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set) +#define RESET_PCI16_SMBUS_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Rst) +#define RW_PCI16_SMBUS_S3(mBoot, Rx, St, Rt) \ + RW_PCI16_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, St, Rt) +#define WRITE_PCI32_SMBUS_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Val) +#define SET_PCI32_SMBUS_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Set) +#define RESET_PCI32_SMBUS_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, Rst) +#define RW_PCI32_SMBUS_S3(mBoot, Rx, St, Rt) \ + RW_PCI32_S3(mBoot, SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, Rx, St, Rt) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_HECI_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Val) +#define SET_PCI8_HECI_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set) +#define RESET_PCI8_HECI_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Rst) +#define RW_PCI8_HECI_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set, Rst) +#define WRITE_PCI16_HECI_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Val) +#define SET_PCI16_HECI_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set) +#define RESET_PCI16_HECI_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Rst) +#define RW_PCI16_HECI_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set, Rst) +#define WRITE_PCI32_HECI_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Val) +#define SET_PCI32_HECI_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set) +#define RESET_PCI32_HECI_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Rst) +#define RW_PCI32_HECI_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, HECI_BUS, HECI_DEV, HECI_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_PCI8_HECI2_S3(mBoot, Rx, Val) \ + WRITE_PCI8_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Val) +#define SET_PCI8_HECI2_S3(mBoot, Rx, Set) \ + SET_PCI8_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set) +#define RESET_PCI8_HECI2_S3(mBoot, Rx, Rst) \ + RESET_PCI8_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Rst) +#define RW_PCI8_HECI2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI8_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set, Rst) +#define WRITE_PCI16_HECI2_S3(mBoot, Rx, Val) \ + WRITE_PCI16_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Val) +#define SET_PCI16_HECI2_S3(mBoot, Rx, Set) \ + SET_PCI16_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set) +#define RESET_PCI16_HECI2_S3(mBoot, Rx, Rst) \ + RESET_PCI16_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Rst) +#define RW_PCI16_HECI2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI16_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set, Rst) +#define WRITE_PCI32_HECI2_S3(mBoot, Rx, Val) \ + WRITE_PCI32_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Val) +#define SET_PCI32_HECI2_S3(mBoot, Rx, Set) \ + SET_PCI32_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set) +#define RESET_PCI32_HECI2_S3(mBoot, Rx, Rst) \ + RESET_PCI32_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Rst) +#define RW_PCI32_HECI2_S3(mBoot, Rx, Set, Rst) \ + RW_PCI32_S3(mBoot, HECI2_BUS, HECI2_DEV, HECI2_FUN, Rx, Set, Rst) + +//--------------------------------------------------------------------------- +// Chipset MMIO Macros, Porting Required. +//--------------------------------------------------------------------------- + +#define READ_MEM8_RCRB(wReg) READ_MEM8(SB_RCRB_BASE_ADDRESS | wReg) +#define WRITE_MEM8_RCRB(wReg, bVal) WRITE_MEM8(SB_RCRB_BASE_ADDRESS | wReg,bVal) +#define SET_MEM8_RCRB(wReg, Set) RW_MEM8(SB_RCRB_BASE_ADDRESS | wReg, Set, 0) +#define RESET_MEM8_RCRB(wReg, Rst) RW_MEM8(SB_RCRB_BASE_ADDRESS | wReg,0,Rst) +#define RW_MEM8_RCRB(wReg,Set,Rst) RW_MEM8(SB_RCRB_BASE_ADDRESS|wReg,Set,Rst) +#define READ_MEM16_RCRB(wReg) READ_MEM16(SB_RCRB_BASE_ADDRESS | wReg) +#define WRITE_MEM16_RCRB(wReg,Val) WRITE_MEM16(SB_RCRB_BASE_ADDRESS|wReg,Val) +#define SET_MEM16_RCRB(wReg, Set) RW_MEM16(SB_RCRB_BASE_ADDRESS|wReg, Set,0) +#define RESET_MEM16_RCRB(wReg, Rst) RW_MEM16(SB_RCRB_BASE_ADDRESS|wReg, 0,Rst) +#define RW_MEM16_RCRB(Reg,Set,Rst) RW_MEM16(SB_RCRB_BASE_ADDRESS|Reg,Set,Rst) +#define READ_MEM32_RCRB(wReg) READ_MEM32(SB_RCRB_BASE_ADDRESS | wReg) +#define WRITE_MEM32_RCRB(wReg,Val) WRITE_MEM32(SB_RCRB_BASE_ADDRESS|wReg,Val) +#define SET_MEM32_RCRB(wReg,Set) RW_MEM32(SB_RCRB_BASE_ADDRESS|wReg, Set,0) +#define RESET_MEM32_RCRB(wReg,Rst) RW_MEM32(SB_RCRB_BASE_ADDRESS|wReg,0,Rst) +#define RW_MEM32_RCRB(Reg,Set,Rst) RW_MEM32(SB_RCRB_BASE_ADDRESS|Reg,Set,Rst) + +//--------------------------------------------------------------------------- +#define WRITE_MEM8_RCRB_S3(mBoot, wReg, bVal) \ + WRITE_MEM8_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, bVal) +#define SET_MEM8_RCRB_S3(mBoot, wReg, Set) \ + SET_MEM8_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, Set) +#define RESET_MEM8_RCRB_S3(mBoot, wReg, Rst) \ + RESET_MEM8_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, Rst) +#define RW_MEM8_RCRB_S3(mBoot, wReg, Set, Rst) \ + RW_MEM8_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, Set,Rst) +#define WRITE_MEM16_RCRB_S3(mBoot, wReg, wVal) \ + WRITE_MEM16_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg,wVal) +#define SET_MEM16_RCRB_S3(mBoot, wReg, Set) \ + SET_MEM16_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, Set) +#define RESET_MEM16_RCRB_S3(mBoot, wReg, Rst) \ + RESET_MEM16_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, Rst) +#define RW_MEM16_RCRB_S3(mBoot, wReg, Set, Rst) \ + RW_MEM16_S3(mBoot,SB_RCRB_BASE_ADDRESS|wReg, Set,Rst) +#define WRITE_MEM32_RCRB_S3(mBoot, wReg, dVal) \ + WRITE_MEM32_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg,dVal) +#define SET_MEM32_RCRB_S3(mBoot, wReg, Set) \ + SET_MEM32_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, Set) +#define RESET_MEM32_RCRB_S3(mBoot, wReg, Rst) \ + RESET_MEM32_S3(mBoot, SB_RCRB_BASE_ADDRESS|wReg, Rst) +#define RW_MEM32_RCRB_S3(mBoot, wReg, Set, Rst) \ + RW_MEM32_S3(mBoot,SB_RCRB_BASE_ADDRESS|wReg, Set,Rst) + +//--------------------------------------------------------------------------- +// SPI MMIO Macros, Porting Required. +//--------------------------------------------------------------------------- + +#define READ_MEM8_SPI(wReg) READ_MEM8(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS| wReg) +#define WRITE_MEM8_SPI(wReg, bVal) WRITE_MEM8(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS | wReg,bVal) +#define SET_MEM8_SPI(wReg, Set) RW_MEM8(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS | wReg, Set, 0) +#define RESET_MEM8_SPI(wReg, Rst) RW_MEM8(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS | wReg,0,Rst) +#define RW_MEM8_SPI(wReg,Set,Rst) RW_MEM8(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|wReg,Set,Rst) +#define READ_MEM16_SPI(wReg) READ_MEM16(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS | wReg) +#define WRITE_MEM16_SPI(wReg,Val) WRITE_MEM16(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|wReg,Val) +#define SET_MEM16_SPI(wReg, Set) RW_MEM16(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|wReg, Set,0) +#define RESET_MEM16_SPI(wReg, Rst) RW_MEM16(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|wReg, 0,Rst) +#define RW_MEM16_SPI(Reg,Set,Rst) RW_MEM16(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|Reg,Set,Rst) +#define READ_MEM32_SPI(wReg) READ_MEM32(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS | wReg) +#define WRITE_MEM32_SPI(wReg,Val) WRITE_MEM32(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|wReg,Val) +#define SET_MEM32_SPI(wReg,Set) RW_MEM32(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|wReg, Set,0) +#define RESET_MEM32_SPI(wReg,Rst) RW_MEM32(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|wReg,0,Rst) +#define RW_MEM32_SPI(Reg,Set,Rst) RW_MEM32(SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS|Reg,Set,Rst) + +//--------------------------------------------------------------------------- +// Chipset I/O Macros, Porting Required. +//--------------------------------------------------------------------------- + +#define READ_IO8_PM(bReg) READ_IO8(PM_BASE_ADDRESS+bReg) +#define WRITE_IO8_PM(bReg, bVal) WRITE_IO8(PM_BASE_ADDRESS+bReg, bVal) +#define SET_IO8_PM(bReg, Set) SET_IO8(PM_BASE_ADDRESS+bReg, Set) +#define RESET_IO8_PM(bReg, Reset) RESET_IO8(PM_BASE_ADDRESS+bReg, Reset) +#define RW_IO8_PM(bReg, Set, Rst) RW_IO8(PM_BASE_ADDRESS+bReg, Set, Rst) +#define READ_IO16_PM(bReg) READ_IO16(PM_BASE_ADDRESS+bReg) +#define WRITE_IO16_PM(bReg, wVal) WRITE_IO16(PM_BASE_ADDRESS+bReg, wVal) +#define SET_IO16_PM(bReg, Set) SET_IO16(PM_BASE_ADDRESS+bReg, Set) +#define RESET_IO16_PM(bReg, Reset) RESET_IO16(PM_BASE_ADDRESS+bReg, Reset) +#define RW_IO16_PM(bReg, Set, Rst) RW_IO16(PM_BASE_ADDRESS+bReg, Set, Rst) +#define READ_IO32_PM(bReg) READ_IO32(PM_BASE_ADDRESS+bReg) +#define WRITE_IO32_PM(bReg, dVal) WRITE_IO32(PM_BASE_ADDRESS+bReg, dVal) +#define SET_IO32_PM(bReg, Set) SET_IO32(PM_BASE_ADDRESS+bReg, Set) +#define RESET_IO32_PM(bReg, Reset) RESET_IO32(PM_BASE_ADDRESS+bReg, Reset) +#define RW_IO32_PM(bReg, Set, Rst) RW_IO32(PM_BASE_ADDRESS+bReg, Set, Rst) + +//--------------------------------------------------------------------------- + +#define READ_IO8_TCO(bReg) READ_IO8(TCO_BASE_ADDRESS+bReg) +#define WRITE_IO8_TCO(bReg, bVal) WRITE_IO8(TCO_BASE_ADDRESS+bReg, bVal) +#define SET_IO8_TCO(bReg, Set) SET_IO8(TCO_BASE_ADDRESS+bReg, Set) +#define RESET_IO8_TCO(bReg, Reset) RESET_IO8(TCO_BASE_ADDRESS+bReg, Reset) +#define RW_IO8_TCO(bReg, Set, Rst) RW_IO8(TCO_BASE_ADDRESS+bReg, Set, Rst) +#define READ_IO16_TCO(bReg) READ_IO16(TCO_BASE_ADDRESS+bReg) +#define WRITE_IO16_TCO(bReg, wVal) WRITE_IO16(TCO_BASE_ADDRESS+bReg, wVal) +#define SET_IO16_TCO(bReg, Set) SET_IO16(TCO_BASE_ADDRESS+bReg, Set) +#define RESET_IO16_TCO(bReg, Reset) RESET_IO16(TCO_BASE_ADDRESS+bReg, Reset) +#define RW_IO16_TCO(bReg, Set, Rst) RW_IO16(TCO_BASE_ADDRESS+bReg, Set, Rst) +#define READ_IO32_TCO(bReg) READ_IO32(TCO_BASE_ADDRESS+bReg) +#define WRITE_IO32_TCO(bReg, dVal) WRITE_IO32(TCO_BASE_ADDRESS+bReg, dVal) +#define SET_IO32_TCO(bReg, Set) SET_IO32(TCO_BASE_ADDRESS+bReg, Set) +#define RESET_IO32_TCO(bReg, Reset) RESET_IO32(TCO_BASE_ADDRESS+bReg, Reset) +#define RW_IO32_TCO(bReg, Set, Rst) RW_IO32(TCO_BASE_ADDRESS+bReg, Set, Rst) + +//--------------------------------------------------------------------------- + +#define WRITE_IO8_PM_S3(mBoot, bReg, bVal) \ + WRITE_IO8_S3(mBoot, PM_BASE_ADDRESS+bReg, bVal) +#define RW_IO8_PM_S3(mBoot, bReg, Set, Reset) \ + RW_IO8_S3(mBoot, PM_BASE_ADDRESS+bReg, Set, Reset) +#define SET_IO8_PM_S3(mBoot, bReg, Set) \ + RW_IO8_S3(mBoot, PM_BASE_ADDRESS+bReg, Set, 0) +#define RESET_IO8_PM_S3(mBoot, bReg, Reset) \ + RW_IO8_S3(mBoot, PM_BASE_ADDRESS+bReg, 0, Reset) + +#define WRITE_IO16_PM_S3(mBoot, bReg, bVal) \ + WRITE_IO16_S3(mBoot, PM_BASE_ADDRESS+bReg, bVal) +#define RW_IO16_PM_S3(mBoot, bReg, Set, Rst) \ + RW_IO16_S3(mBoot, PM_BASE_ADDRESS+bReg, Set, Rst) +#define SET_IO16_PM_S3(mBoot, bReg, Set) \ + RW_IO16_S3(mBoot, PM_BASE_ADDRESS+bReg, Set, 0) +#define RESET_IO16_PM_S3(mBoot, bReg, Reset) \ + RW_IO16_S3(mBoot, PM_BASE_ADDRESS+bReg, 0, Reset) + +#define WRITE_IO32_PM_S3(mBoot, bReg, bVal) \ + WRITE_IO32_S3(mBoot, PM_BASE_ADDRESS+bReg, bVal) +#define RW_IO32_PM_S3(mBoot, bReg, Set, Rst) \ + RW_IO32_S3(mBoot, PM_BASE_ADDRESS+bReg, Set, Rst) +#define SET_IO32_PM_S3(mBoot, bReg, Set) \ + RW_IO32_S3(mBoot, PM_BASE_ADDRESS+bReg, Set, 0) +#define RESET_IO32_PM_S3(mBoot, bReg, Reset) \ + RW_IO32_S3(mBoot, PM_BASE_ADDRESS+bReg, 0, Reset) + +//--------------------------------------------------------------------------- + +#define WRITE_IO8_TCO_S3(mBoot, bReg, bVal) \ + WRITE_IO8_S3(mBoot, TCO_BASE_ADDRESS+bReg, bVal) +#define RW_IO8_TCO_S3(mBoot, bReg, Set, Rst) \ + RW_IO8_S3(mBoot, TCO_BASE_ADDRESS+bReg, Set, Rst) +#define SET_IO8_TCO_S3(mBoot, bReg, Set) \ + RW_IO8_S3(mBoot, TCO_BASE_ADDRESS+bReg, Set, 0) +#define RESET_IO8_TCO_S3(mBoot, bReg, Reset) \ + RW_IO8_S3(mBoot, TCO_BASE_ADDRESS+bReg, 0, Reset) + +#define WRITE_IO16_TCO_S3(mBoot, bReg, bVal) \ + WRITE_IO16_S3(mBoot, TCO_BASE_ADDRESS+bReg, bVal) +#define RW_IO16_TCO_S3(mBoot, bReg, Set, Rst) \ + RW_IO16_S3(mBoot, TCO_BASE_ADDRESS+bReg, Set, Rst) +#define SET_IO16_TCO_S3(mBoot, bReg, Set) \ + RW_IO16_S3(mBoot, TCO_BASE_ADDRESS+bReg, Set, 0) +#define RESET_IO16_TCO_S3(mBoot, bReg, Reset) \ + RW_IO16_S3(mBoot, TCO_BASE_ADDRESS+bReg, 0, Reset) + +#define WRITE_IO32_TCO_S3(mBoot, bReg, bVal) \ + WRITE_IO32_S3(mBoot, TCO_BASE_ADDRESS+bReg, bVal) +#define RW_IO32_TCO_S3(mBoot, bReg, Set, Rst) \ + RW_IO32_S3(mBoot, TCO_BASE_ADDRESS+bReg, Set, Rst) +#define SET_IO32_TCO_S3(mBoot, bReg, Set) \ + RW_IO32_S3(mBoot, TCO_BASE_ADDRESS+bReg, Set, 0) +#define RESET_IO32_TCO_S3(mBoot, bReg, Reset) \ + RW_IO32_S3(mBoot, TCO_BASE_ADDRESS+bReg, 0, Reset) + +//--------------------------------------------------------------------------- + +#define READ_IO8_RTC(bReg) ReadIo8IdxData(CMOS_ADDR_PORT, bReg) +#define WRITE_IO8_RTC(bReg, bVal) WriteIo8IdxData(CMOS_ADDR_PORT, bReg, bVal) +#define RW_IO8_RTC(bReg, Set, Rst) RwIo8IdxData(CMOS_ADDR_PORT, bReg, Set, Rst) +#define SET_IO8_RTC(bReg, Set) RwIo8IdxData(CMOS_ADDR_PORT, bReg, Set, 0) +#define RESET_IO8_RTC(bReg, Reset) RwIo8IdxData(CMOS_ADDR_PORT, bReg, 0, Reset) + +//--------------------------------------------------------------------------- + +#define WRITE_IO8_RTC_S3(mBoot, bReg, bVal) \ + WriteIo8IdxDataS3(mBoot, CMOS_ADDR_PORT, bReg, bVal) +#define RW_IO8_RTC_S3(mBoot, bReg, Set, Rst) \ + RwIo8IdxDataS3(mBoot, CMOS_ADDR_PORT, bReg, Set,Rst) +#define SET_IO8_RTC_S3(mBoot, bReg, Set) \ + RwIo8IdxDataS3(mBoot, CMOS_ADDR_PORT, bReg, Set, 0) +#define RESET_IO8_RTC_S3(mBoot, bReg, Rst) \ + RwIo8IdxDataS3(mBoot, CMOS_ADDR_PORT, bReg, 0, Rst) + +//--------------------------------------------------------------------------- + +//----------------------------------------------------------------------- +#ifndef _EFI_MMIO_ACCESS_H_ +#define _EFI_MMIO_ACCESS_H_ + +#define MmioAddress(BaseAddr, Register) \ + ( (UINTN)BaseAddr + (UINTN)(Register) ) + +// 32-bit +#define Mmio32Ptr(BaseAddr, Register) \ + ( (volatile UINT32 *)MmioAddress(BaseAddr, Register) ) + +#define Mmio32(BaseAddr, Register) \ + *Mmio32Ptr(BaseAddr, Register) + +#define MmioRead32(Addr) \ + Mmio32(Addr, 0) + +#define MmioWrite32(Addr, Value) \ + (Mmio32(Addr, 0) = (UINT32)Value) + +#define MmioRW32(Addr, set, reset) \ + (Mmio32(Addr, 0) = ((Mmio32(Addr, 0) & (UINT32)~(reset)) | (UINT32)set)) + +// 16-bit +#define Mmio16Ptr(BaseAddr, Register) \ + ( (volatile UINT16 *)MmioAddress(BaseAddr, Register) ) + +#define Mmio16(BaseAddr, Register) \ + *Mmio16Ptr(BaseAddr, Register) + +#define MmioRead16(Addr) \ + Mmio16(Addr, 0) + +#define MmioWrite16(Addr, Value) \ + (Mmio16(Addr, 0) = (UINT16)Value) + +#define MmioRW16(Addr, set, reset) \ + (Mmio16(Addr, 0) = ((Mmio16(Addr, 0) & (UINT16)~(reset)) | (UINT16)set)) + +// 8-bit +#define Mmio8Ptr(BaseAddr, Register) \ + ( (volatile UINT8 *)MmioAddress(BaseAddr, Register) ) + +#define Mmio8(BaseAddr, Register) \ + *Mmio8Ptr(BaseAddr, Register) + +#define MmioRead8(Addr) \ + Mmio8(Addr, 0) + +#define MmioWrite8(Addr, Value) \ + (Mmio8(Addr, 0) = (UINT8)Value) + +#define MmioRW8(Addr, set, reset) \ + (Mmio8(Addr, 0) = ((Mmio8(Addr, 0) & (UINT8)~(reset)) | (UINT8)set)) + +#endif +//----------------------------------------------------------------------- + + +//----------------------------------------------------------------------- +// +//----------------------------------------------------------------------- +#ifndef _EFI_PCI_ACCESS_H_ +#define _EFI_PCI_ACCESS_H_ + +#ifndef MmPciAddress +#define MmPciAddress(Base, Bus, Device, Function, Register) \ + ( (UINTN)(Base) + \ + (UINTN)(Bus << 20) + \ + (UINTN)(Device << 15) + \ + (UINTN)(Function << 12) + \ + (UINTN)(Register) ) +#endif + +// 32-bit +#define MmPci32Ptr(Bus, Device, Function, Register) \ + ( (volatile UINT32 *)MmPciAddress(PCIEX_BASE_ADDRESS, Bus, Device, Function, Register) ) + +#define MmPci32(Bus, Device, Function, Register) \ + *MmPci32Ptr(Bus, Device, Function, Register) + +#define MmPciRead32(Bus, Device, Function, Register) \ + MmPci32(Bus, Device, Function, Register) + +#define MmPciWrite32(Bus, Device, Function, Register, Value) \ + (MmPci32(Bus, Device, Function, Register) = (UINT32)Value) + +#define MmPciRW32(Bus, Device, Function, Register, set, reset) \ + (MmPci32(Bus, Device, Function, Register) = ((MmPci32(Bus, Device, Function, Register) & (UINT32)~(reset)) | (UINT32)set)) + +// 16-bit +#define MmPci16Ptr(Bus, Device, Function, Register) \ + ( (volatile UINT16 *)MmPciAddress(PCIEX_BASE_ADDRESS, Bus, Device, Function, Register) ) + +#define MmPci16(Bus, Device, Function, Register) \ + *MmPci16Ptr(Bus, Device, Function, Register) + +#define MmPciRead16(Bus, Device, Function, Register) \ + MmPci16(Bus, Device, Function, Register) + +#define MmPciWrite16(Bus, Device, Function, Register, Value) \ + (MmPci16(Bus, Device, Function, Register) = (UINT16)Value) + +#define MmPciRW16(Bus, Device, Function, Register, set, reset) \ + (MmPci16(Bus, Device, Function, Register) = ((MmPci16(Bus, Device, Function, Register) & (UINT16)~(reset)) | (UINT16)set)) + +// 8-bit +#define MmPci8Ptr(Bus, Device, Function, Register) \ + ( (volatile UINT8 *)MmPciAddress(PCIEX_BASE_ADDRESS, Bus, Device, Function, Register) ) + +#define MmPci8(Bus, Device, Function, Register) \ + *MmPci8Ptr(Bus, Device, Function, Register) + +#define MmPciRead8(Bus, Device, Function, Register) \ + MmPci8(Bus, Device, Function, Register) + +#define MmPciWrite8(Bus, Device, Function, Register, Value) \ + (MmPci8(Bus, Device, Function, Register) = (UINT8)Value) + +#define MmPciRW8(Bus, Device, Function, Register, set, reset) \ + (MmPci8(Bus, Device, Function, Register) = ((MmPci8(Bus, Device, Function, Register) & (UINT8)~(reset)) | (UINT8)set)) + +#endif +//----------------------------------------------------------------------- + +UINT32 DummyVerbTable[]; + +#ifdef __cplusplus +} +#endif +#endif + + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBDxe.c b/Chipset/SB/SBDxe.c new file mode 100644 index 0000000..91f2cfb --- /dev/null +++ b/Chipset/SB/SBDxe.c @@ -0,0 +1,7266 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Chipset/SB/SBDxe.c 1 11/02/17 1:48a Chienhsieh $ +// +// $Revision: 1 $ +// +// $Date: 11/02/17 1:48a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Chipset/SB/SBDxe.c $ +// +// 1 11/02/17 1:48a Chienhsieh +// [TAG] EIP357393 +// [Category] Improvement +// [Description] [SAx0039] SPI opcode Security Vulnerability +// [Files] Chipset\SB\SBDxe.c +// ReferenceCode\Chipset\LynxPoint\PchInit\Dxe\PchInit.c +// +// 100 1/29/15 4:09a Mirayang +// [TAG] EIP200269 +// [Category] New Feature +// [Description] For add FlashSmi : Label 4.6.5.5_FlashSmi_00 +// ($/Alaska/SOURCE/Modules/FlashSmi) +// +// 99 9/05/14 3:30a Mirayang +// [TAG] EIP182598 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Missing ULT differentiation in +// InstallDxePchPlatformPolicy() for GbE slot number detection +// [RootCause] In InstallDxePchPlatformPolicy(), there is a ULT +// differentiation missing. +// [Solution] The strap readout, is not the same for LynxPoint LP. Add +// determine to set value. +// +// 98 5/20/14 2:15a Barretlin +// [TAG] EIP N/A +// [Category] Improvement +// [Description] remove unnecessary source code +// [Files] SBDxe.c +// +// 97 5/16/14 6:16a Barretlin +// [TAG] EIP167087 +// [Category] Improvement +// [Description] BIOS security improvement on Haswell CRB project +// [Files] SBGeneric.c SBDxe.c SBCspLib.h Sb.sdl Sb.sd +// +// 96 5/14/14 1:08p Barretlin +// [TAG] EIP167028 +// [Category] Improvement +// [Description] Variable attribute improment +// [Files] SB.sd SBDxe.c WdtAppDxe.c +// +// 95 3/21/14 4:44a Barretlin +// +// 94 3/20/14 8:41a Barretlin +// [TAG] EIP158783 +// [Category] Improvement +// [Description] Fix programming error +// [Files] SbDxe.c +// +// 93 3/13/14 11:30a Barretlin +// [TAG] EIP153695 +// [Category] Improvement +// [Description] USB Per port control is not reasonable when +// OEM_USBPREPORT_DISABLE_SUPPORT token is Enabled and USB devices are +// behind hubs +// [Files] Sb.sdl Sb.sd Sb.uni GetSetupData.c SbDxe.c PchUsbCommon.c +// PchRegsUsb.h +// +// 92 3/13/14 10:13a Barretlin +// [TAG] EIP N/A +// [Category] Improvement +// [Description] Fix build error when remove or disable CSM module +// [Files] SbDxe.c +// +// 91 11/19/13 7:32a Barretlin +// [TAG] EIP141917 +// [Category] New Feature +// [Description] Support SetTimer() with HPET Timer on Lynx Point +// [Files] SB.sdl SBGeneric.c SBDxe.c SbHpet.h sbProtocal.cif +// SamrtTimer.sdl +// +// 90 11/11/13 6:26a Barretlin +// [TAG] EIP N/A +// [Category] Improvement +// [Description] Fix build error +// [Files] SBDxe.c +// +// 89 10/28/13 10:58p Barretlin +// [TAG] EIP141266 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] CPU exception error after apply "Save/Restore Bit25 of +// PxCMD" solution +// [RootCause] PciIO point is NULL +// [Solution] if PciIO point is NULL, skip this Option ROM, because it +// must not be SATA Option Rom +// [Files] SBDxe.c +// +// 88 10/06/13 2:22a Barretlin +// +// 86 9/17/13 2:00p Barretlin +// [TAG] EIP N/A +// [Category] Improvement +// [Description] set a token to enable/disable SATA DLAE bit +// [Files] SB.sdl SBDxe.c +// +// 85 9/17/13 9:31a Barretlin +// [TAG] EIP134850 +// [Category] New Feature +// [Description] Save/Restore Bit25 of PxCMD in Aptio Chipset Module +// [Files] SBDxe.c +// +// 84 9/17/13 8:51a Barretlin +// [TAG] EIP N/A +// [Category] Improvement +// [Description] update AhciPlatformPolicy default value for AHCI module +// rev.24 +// [Files] SBDxe.c +// +// 83 8/13/13 7:46a Scottyang +// [TAG] EIP132701 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Coding error. +// [RootCause] Incorrect offset of IO APIC data register. +// [Solution] Correct the offset. +// [Files] SBDxe.c +// +// 82 8/01/13 4:26a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add PCIE LTR setup items. +// [Files] SB.sd, SB.uni, SBDxe.c, GetSetupData.c, SbSetupData.c +// +// 81 7/15/13 10:13p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Fixed build error at SharkBay DT. +// [Files] SBDxe.c +// +// 80 7/15/13 3:19a Scottyang +// [TAG] EIP129089 +// [Category] Improvement +// [Description] Update PCH RC 1.6.1. +// [Files] SBDxe.c, SB.asl, ..\ReferenceCode\Chipset\LynxPoint\*.* +// +// 79 7/12/13 1:51a Scottyang +// [TAG] EIP126943 +// [Category] Improvement +// [Description] Create S3 boot script tabel for SATA2 controller even +// SATA1 hiden. +// [Files] SBDxe.c +// +// 78 7/09/13 5:15a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Create "PCH Cross Throttling" setup item.(Only ULT +// support) +// [Files] SBDxe.c, SB.sd, SB.uni, GetSetupData.c, SB.sd +// +// 77 7/07/13 10:14p Scottyang +// [TAG] EIP127410 +// [Category] Improvement +// [Description] Update DSDT taable when PCIE port swap function enable. +// [Files] SBDxe.c +// +// 76 7/03/13 8:00a Scottyang +// [TAG] EIP124410 +// [Category] Improvement +// [Description] Implement SMBIOS type 88h for CRID. +// [Files] SBDxe.c, SB.sdl, SB.sd, SBSetup.c, SBSetup.sdl +// +// 75 6/24/13 7:04a Scottyang +// [TAG] EIP127217 +// [Category] Improvement +// [Description] Only update RC's ASL code for L event. +// [Files] SBDxe.c, GPE.asl +// +// 74 6/24/13 6:29a Scottyang +// [TAG] EIP127297 +// [Category] Improvement +// [Description] Update PCH RC 1.6.0. +// [Files] SB.sd, SBDxe.c, ..\ReferenceCode\Chipset\LynxPoint\*.* +// +// 73 6/14/13 12:00a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Make sure the USB preport disable call back function +// processing is performed only once. +// [Files] SBDxe.c +// +// 72 6/13/13 11:53p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Update RC 150 GNVS. +// [Files] SBDxe.c, SB.uni, SB.sd +// +// 71 6/06/13 10:25p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Remove XHCB at Dsdt table update. +// [Files] SBDxe.c +// +// 70 6/03/13 3:40a Scottyang +// [TAG] EIP125453 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Build field when enable "FORCE_USER_TO_SETUP_IF_CMOS_BAD" +// [RootCause] Miss the header file. +// [Files] SBDxe.c +// +// 69 5/23/13 1:56a Scottyang +// [TAG] EIP120623 +// [Category] Improvement +// [Description] LCD turn on automatically when resume from S3. +// [Files] SBPEI.c, SBDxe.c, AcpiModeEnable.c +// +// 68 5/21/13 8:49a Scottyang +// [TAG] EIP121740 +// [Category] Bug Fix +// [Severity] Critical +// [Symptom] Event log has HAL error after resume from S3. +// [RootCause] Coding error for S3 script type. +// [Solution] Correct the S3 script type. +// [Files] SBDxe.c +// +// 67 5/20/13 6:21a Scottyang +// [TAG] EIP124245 +// [Category] Improvement +// [Description] On S3 resume under Raid mode System may gets hangs. +// [Files] SBDxe.c +// +// 66 5/13/13 8:56a Scottyang +// [TAG] EIP123496 +// [Category] Improvement +// [Description] Update PCH RC 1.5.0. +// [Files] ..\ReferenceCode\Chipset\LynxPoint\*.* , SBDxe.C, SBPEI.c, +// SB.sd, SB.uni, SbSetupData.h, GetSetupData.c +// +// 65 5/03/13 4:39a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Make sure Clear the Start and FIS Receive Enable bit +// [Files] SBDxe.c +// +// 64 4/24/13 6:48a Scottyang +// [TAG] EIP82149 +// [Category] Improvement +// [Description] Intel(R) 8 Series Chipset Family Deep Sx and CPU +// Soft-Strap BIOS Override Co-Existence Issue. If the soft-strap override +// feature is required and enabled, BIOS must disable Deep Sx +// functionality. +// [Files] SBDxe.c, SB.sd, SBPlatformData.h +// +// 63 4/15/13 10:50p Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Hide HPET device if it is disabled. +// [Files] SBDXE.c +// +// 62 4/15/13 10:47p Wesleychen +// [TAG] EIP120857 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] TCO S3 Boot Script in wrong order. +// After S3 resume, TCO_EN bit din't be +// restored. +// [RootCause] Lockdown TCO bit is set before TCO_EN +// restore. +// [Solution] Relocate PM_BASE+ALTGP_SMI_EN & SMI_EN +// save/restore to SbExitPmAuthProtocolCallback(). +// [Files] SBDxe.c +// +// 61 4/09/13 11:35p Wesleychen +// [TAG] EIP120480 +// [Category] Improvement +// [Description] Always disabling PCH platform policy "ExternalObffEn". +// [Files] SB.SDL, SBDXE.c +// +// 59 4/08/13 2:47a Wesleychen +// [TAG] EIP120159 +// [Category] Improvement +// [Description] Update for Intel PCH LPT RC140. +// Added new tokens: +// 1. "PCH_RESET_CYCLE_DURATION" +// 2. "LEGACY_DMA_DISABLE" +// [Files] SB.SDL, SBDXE.c +// +// 58 4/08/13 2:37a Wesleychen +// [TAG] EIP116939 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] The available memory size is less than +// 2GB in Windowss 7 32 bit. +// [RootCause] The "SB_TEMP_MMIO_BASE" is too low. +// [Solution] Rearrange "SB_TEMP_MMIO_BASE" to +// 4GB - 16M(ROM) - 64KB (Intel Required). +// [Files] SB.SDL; SBDxe.c +// +// 57 3/26/13 5:54a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Update the address of operation region "XHCB" for +// Intel ACPI RC 1.3.1 compatible. +// [Files] SBDxe.c +// +// 56 3/22/13 5:15a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Wireless LAN PHY use SLP_WLAN# pin +// [Files] SB.sdl, SBDxe.c +// +// 55 3/19/13 8:19a Scottyang +// [TAG] EIP118158 +// [Category] Improvement +// [Description] Correct SBLib_CmosRead () offset. +// [Files] SmiHandlerPorting2.c, SBDxe.c, SBGeneric.c, SBSmm.c, +// SmiHandlerPorting.c +// +// 54 3/19/13 4:56a Scottyang +// [TAG] EIP118480 +// [Category] Improvement +// [Description] Use another array for +// ULT_USB_OVER_CURRENT_MAPPING_SETTINGS. +// [Files] SBDxe.c +// +// 53 3/15/13 3:33a Scottyang +// [TAG] EIP118121 +// [Category] Improvement +// [Description] Update PCH RC 1.3.0. +// [Files] ..\ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SB.uni, GetSetupData.c, SbSetupData.h +// +// 51 3/14/13 2:50a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Fixed coding error for OEM USB preport disable after +// setup menu. +// [Files] SBDxe.c +// +// 49 2/26/13 1:21a Scottyang +// [TAG] EIP116154 +// [Category] Improvement +// [Description] Update PCH RC 1.2.0. +// [Files] .\ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c +// +// 48 2/25/13 5:12a Scottyang +// [TAG] EIP113678 +// [Category] Improvement +// [Description] Disable BIOS lock when recovery and capsule BIOS flash. +// [Files] SBDxe.c +// +// 47 2/19/13 10:35p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Correct UsbOverCurrentMapping array size fot LPT-LP +// [Files] SBDxe.c +// +// 46 2/09/13 12:12a Scottyang +// [TAG] EIP114922 +// [Category] Improvement +// [Description] Update PCH RC 1.1.0. +// [Files] ..\ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SB.uni, GetSetupData.c, SbSetupDara.h +// +// 45 1/31/13 10:54a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add Serial IO GNVS setup option. +// [Files] SBDxe.c, SB.sd, SB.uni, SbSetupData.h, GetSetupData.c +// +// 44 1/28/13 4:16a Scottyang +// [TAG] EIP108803 +// [Category] Improvement +// [Description] Disable usb port after setup. +// [Files] SB.sdl, SBDxe.c, PchUsbCommon.c +// +// 43 1/27/13 11:01p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Capsule 2.0 crash dump link function. +// [Files] SBPEI.c +// SBDxe.c +// SBRun.c +// +// 42 1/11/13 2:34a Scottyang +// [TAG] EIP92011 +// [Category] Improvement +// [Description] EC SMI inactive when system resume from iRST sleep +// [Files] SBDxe.c +// +// 41 1/11/13 1:51a Scottyang +// [TAG] EIP88358 +// [Category] Improvement +// [Description] Add FORCE_USER_TO_SETUP_IF_CMOS_BAD token +// [Files] SBDex.c, SBPei.c, RTC.h, SB.sdl +// +// 40 1/10/13 4:53a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Create DTIO value and DM value option +// [Files] SB.sd, SB.uni, SbSetupData.h, GetSetupData.c, SBDxe.c +// +// 39 1/04/13 4:47a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] ADSP Interrupt Mode should same with LPSS Interrupt +// Mode +// [Files] SBDxe.c +// +// 38 12/24/12 5:51a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add option for XHCI Idel L1 workaroung. +// [Files] GetSetupData.c, SbSetupData.h, SB.sd, SB.uni, SBDxe.c, +// SBPEI.c +// +// 37 12/22/12 2:07a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add PCIE "L1 Substates"setup option. +// [Files] GetSetupData.c, SbSetupData.h, SB.sd, SB.uni, SBDxe.c +// +// 36 12/18/12 6:10a Scottyang +// [TAG] EIP109697 +// [Category] Improvement +// [Description] Update PCH RC 0.8.1 +// [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd, +// SbSetupData.c, GetSetupDate.c +// +// 35 12/17/12 6:45a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add setup menu for LPSS and ECTG. +// [Files] GetSetupData.c +// SbSetupData.h +// SB.sd +// SB.uni +// SBDxe.c +// +// 34 11/20/12 9:47a Scottyang +// [TAG] EIP107014 +// [Category] Improvement +// [Description] Update RC 0.8.0 +// [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SbSetupData.c, GetSetupDate.c +// +// 33 11/19/12 9:57p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Support RAID mode device ID for WS and server. +// [Files] SBDxe.c, PchSata.c +// +// 32 11/08/12 9:46a Scottyang +// [TAG] Initialize8259 +// +// [Category] Improvement +// +// [Description] To prevent the unexpected interrupt asserted in 8259 +// initialization. +// +// [Files] SBDxe.c +// +// 31 11/08/12 8:44a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add device item that connect LPSS. +// [Files] GetSetupData.c, SbSetupData.h, SBDxe.c, SB.sd, SB.uni +// +// 30 11/06/12 8:12a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Reduce function "GetPchSeries()". +// [Files] SBPEI.c, SBDxe.c, SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 29 11/05/12 6:24a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Change memory type for RTC. +// [Files] SBDxe.c +// +// 28 11/01/12 4:57a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Remove token "SOLUTION_FOR_EIP95440". +// [Files] SBDxe.c, SB.sdl +// +// 27 10/30/12 8:40a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] ULT do not need. +// +// 26 10/26/12 3:05a Scottyang +// [TAG] None +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] After S3 resime R_PCH_SPI_VSCC1 cannot restore. +// [RootCause] R_PCH_SPI_VSCC0 set first than R_PCH_SPI_VSCC1 cannot +// restore. +// [Solution] change order for R_PCH_SPI_VSCC1 restore first. +// [Files] SBDxe.c +// +// 25 10/26/12 3:00a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Change all L event, GPRW and pcidock at DSDT for ULT. +// [Files] SBDxe.c +// +// 24 10/23/12 10:30p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] After S3 resume EC can not use GPI to trigger SMI +// [Files] SBDxe.c +// +// 23 10/23/12 8:28a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Create Device Sleep at setup menu +// [Files] SB.sd, SB.uni, SBDxe.c, GetSetupData.c, SbSetupData.h +// +// 22 10/23/12 8:17a Scottyang +// [TAG] EIP73607 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Intruder Detect state is cleaned by BIOS POST. +// [Files] SBDXE.c; SBSECInit.asm +// +// 21 10/23/12 2:09a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Already program at SBPEI.c +// +// 20 10/18/12 5:56a Scottyang +// [TAG] EIP101204 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Azalia PME bit doesn't been set when Enabled "Azalia PME" +// [RootCause] PME bit will be cleared by AMI PCI bus driver. +// [Solution] Reprogram PME bit in SbInitAfterDeviceInstall(). +// [Files] SBDXE.c +// +// 19 10/16/12 3:56a Scottyang +// [TAG] EIP103924 +// +// [Category] Improvement +// +// [Description] Update RC 0.7.1 +// +// [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd, +// SbSetupData.c, GetSetupDate.c +// + + +// 17 10/15/12 8:42a Scottyang +// [TAG] ULTDsdtTableUpdate +// [Category] Improvement +// [Description] Update DSDT when ULT. +// +// 16 10/14/12 8:33a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] One rom for two chip and one chip. +// [Files] SPPEIBoard.c, SB.sd, SBDxe.c, SBPEI.c, PCH.asl +// +// 15 10/12/12 7:46a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Clear all SB warm reset flag +// +// 14 10/12/12 2:04a Scottyang +// [TAG] EIP76432 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] It will BSOD ,while system boot to OS at "starting windows" +// press the KB in succession. +// [RootCause] System BSOD is caused by a large number of SMI generated. +// [Solution] Disable legacy USB SMI in ACPI enable stage. +// [Files] AcpiModeEnable.c; SBDXE.c +// +// 13 10/12/12 2:02a Scottyang +// [TAG] ULT_SUBID +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Win8 BSOD for ULT A0 CPU +// [RootCause] The Sub-device ID not match LPT-LP A0 stepping. +// [Solution] Use old Sub-device ID +// [Files] SBDxe.c +// +// 12 10/01/12 5:53a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Create new token "SOLUTION_FOR_EIP95440" for EIP#95440 +// changed. +// [Files] SB.sdl, SBDXE.c +// +// 11 9/26/12 3:53a Victortu +// [TAG] None +// [Category] Improvement +// [Description] If SPI Flash module support VSCC updated, skip +// programming VSCC. +// [Files] SB.sdl, SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update from EIP#95440 to resolve the RAID driver +// compatibility issue. +// [Files] SB.mak, SB.sdl, SBDXE.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update for Intel PCH LPT RC070. +// [Files] SB.sdl, SBDXE.c, SBPEI.c, Pch.sdl, SB.sd, SB.uni +// +// [TAG] None +// [Category] Improvement +// [Description] Update EIP#101515. +// [Files] SBDXE.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// [TAG] None +// [Category] Improvement +// [Description] Implement ULT platform LPSS and ADSP setup option. +// [Files] GetSetupData.c, SB.sd, SB.uni, SbSetupData.h, SBDxe.c, +// SB.sdl +// +// 10 9/12/12 5:18a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove useless HdmiVerbTable. +// [Files] SB.sdl, SBCspLib.h, SBDxe.c, SBGeneric.c +// +// [TAG] None +// [Category] Improvement +// [Description] Support OEM update VSCC table. +// [Files] SB.H, SB.mak, SB.sdl, SBDXE.c +// +// 9 8/30/12 9:49a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Fixed building error when disable RC_PORT_0. +// [Files] SBDxe.c +// +// 8 8/24/12 6:50a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update RC_PORT_x for PCIe. +// [Files] SB.sdl, SB.sd, SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Report HPET Function Number to zero for VTD. +// [Files] SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Implement USB Skip MASS Storage function. +// [Files] SBDxe.c +// +// 7 8/15/12 12:53a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove ME_SERVER_SUPPORT. +// [Files] SBDxe.c, SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update "SB_TEMP_MMIO_BASE" and +// "EHCI_MMIO_BASE_ADDRESS". +// [Files] SB.sdl, SBDxe.c, SBPEI.c +// +// 6 8/13/12 10:27a Victortu +// [TAG] EIP96150 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] USB Device still can be detected even set USB controllers as +// "Disabled" in BIOS Setup. +// [Solution] Set XHCI disable bit of FD Reg. +// [Files] SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Implement BIOS Lock function. +// [Files] SBCspLib.h, SBDxe.c, SBSMI.c, SBSMI.dxs, SBSMI.sdl +// +// [TAG] None +// [Category] Improvement +// [Description] Create the token "USB30_OVER_CURRENT_MAPPING_SETTINGS" +// for the policy "Usb30OverCurrentPins". +// [Files] SB.sdl, SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Improve CheckDisableUsbControllers function. +// [Files] SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Remove PCH_A0PWRON_SAFEMODE. +// [Files] SBDxe.c, Pch.sdl +// +// [TAG] None +// [Category] Improvement +// [Description] Remove useless Dppm items. +// [Files] GetSetupData.c, SB.sd, SbSetupData.h, SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update PCH Policy. +// [Files] SB.sdl, SBDxe.c, SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Implement USB Precondition option for policy +// "UsbPrecondition". +// [Files] GetSetupData.c, SB.sd, SB.uni, SbSetupData.h, SBDxe.c, +// SBPEI.c +// +// 5 7/27/12 6:13a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update setup items and policies. +// [Files] GetSetupData.c, SB.sdl, SB.sd, SB.uni, SbSetupData.h, +// SBPEI.c, SBDXE.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 4 7/02/12 10:18a Victortu +// [TAG] None +// [Category] Improvement +// [Description] SETUP.MassStorageOpRom will instead of SETUP.SataRaidRom +// to decide the launching policy of RAID UEFI driver/Legacy OpRom if +// CsmOptOut_SUPPORT enabled. +// [Files] SBDex.c, SB.sd +// +// [TAG] None +// [Category] Improvement +// [Description] Updated and modified for PCH RC 0.6.0. +// [Files] SBGeneric.c, SB.sdl, SBCspLib.h, SBDxe.c, SBPEI.c +// +// 3 6/13/12 11:34p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement Warm Boot function for Secure Flash feature. +// [Files] SB.H, SB.mak, SB.sdl, SBDxe.c, SBGeneric.c, SBPEI.c, +// SBSMI.c +// +// 2 4/25/12 9:10a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Relayout PCH USB Setup. +// [Files] GetSetupData.c; SB.sd; SB.uni; SbSetupData.h; SBDxe.c +// +// [TAG] None +// [Category] Improvement +// [Description] Fixed GenericSio use 0x0 ~ 0xfff issue. +// [Files] SBDxe.c +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBDxe.C +// +// Description: This file contains code for Template Southbridge +// initialization in the DXE stage +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Efi.h> +#include <token.h> +#include <AmiLib.h> +#include <AmiDxeLib.h> +#include <Setup.h> +#include <Dxe.h> +#include <PCI.h> +#include <AmiHobs.h> +#include <AmiCspLib.h> +#include "HDAVBTBL.h" +#include <AcpiRes.h> +#include <Protocol\BusSpecificDriverOverride.h> +#include <Protocol\LoadedImage.h> +#include <protocol\DriverBinding.h> + +// Consumed Protocols +#include <Protocol\PciIo.h> +#include <Protocol\Cpu.h> +#include <Protocol\PciRootBridgeIo.h> +#include <Protocol\DevicePath.h> +#if SB_PCIE_ERROR_LOG_SUPPORT +#include <Protocol\GenericElog.h> +#endif + +#if ACPI_SUPPORT + #if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014) + #include <Protocol\AcpiSystemDescriptionTable.h> + #else + #include <Protocol\AcpiSupport.h> + #endif +#endif + +#if defined(CsmOptOut_SUPPORT) && (CsmOptOut_SUPPORT == 1) +#include <AmiLoadCsmPolicy.h> +#endif + +#if CSM_SUPPORT +#include <Protocol\CsmPlatform.h> +#include <Protocol\LegacyBiosExt.h> +#endif + +// Produced Protocols +#include <Protocol\RealTimeClock.h> +#include <Protocol\WatchdogTimer.h> +#include <Protocol\Timer.h> +#include <Protocol\Legacy8259.h> + +#if defined HPET_PROTOCOL_SUPPORT && HPET_PROTOCOL_SUPPORT == 1 +#include <Protocol\SbHpet.h> +#endif + +#if defined(IntelPchInclude_SUPPORT) && IntelPchInclude_SUPPORT +#include <PchAccess.h> +#endif +#include <Protocol\PchPlatformPolicy\PchPlatformPolicy.h> + +#if defined iME_SUPPORT && iME_SUPPORT +#include <Guid\MeBiosExtensionSetup\MeBiosExtensionSetup.h> +#endif + +#include <Protocol\SBPlatformData.h> +#include <Board\EM\Platform\PlatformSetup.h> + +#if defined INTEL_CRB_DXE_KSC_LIB_SUPPORT && INTEL_CRB_DXE_KSC_LIB_SUPPORT +#if defined CRB_EC_SUPPORT && CRB_EC_SUPPORT +#include <KscLib.h> +#include <Protocol\ECACCESS.h> +#endif +#endif + +#if SecureMod_SUPPORT +#include <Flash.h> +#endif +#if defined (SPI_INITIALIZE_WITH_VSCC) && (SPI_INITIALIZE_WITH_VSCC == 1) +#include <Protocol\FlashProtocol.h> +#endif +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 +#include <Protocol\AmiUsbController.h> +#endif + +#if defined OEM_USB_PER_PORT_DISABLE_SUPPORT && OEM_USB_PER_PORT_DISABLE_SUPPORT == 1 +#include <Protocol\UsbIo.h> +#endif + +#include <Protocol\GlobalNvsArea\GlobalNvsArea.h> +#include <RTC.h> +#include "protocol\BlockIo.h" +#include "Protocol\PDiskInfo.h" +#include "Protocol\PIDEController.h" +#include "Protocol\PIDEBus.h" +#include "Protocol\PAhciBus.h" +#include <Protocol\SMBios.h> //(EIP124410) + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Build flag adjustments +#ifndef SMM_SUPPORT +#define SMM_SUPPORT 0 +#endif + +// Timer Constants +#define SYSTEM_TIMER_IRQ 0 + +// Timer Period +#define TIMER_TICK 838 // ns + +// default duration is 0xffff ticks +#define DEFAULT_TICK_DURATION ((65535 * 838 + 50) / 100) +#define MAX_TICK_DURATION DEFAULT_TICK_DURATION + +//8259 PIC defines +#define ICW1 0x11 // Slave exists and ICW4 required. +#define ICW3_M 1 << 2 // IRQ 2 connects to slave +#define ICW3_S 2 // IRQ 2 connects to master +#define ICW4 1 // Bit 4 Normal Nested Mode + // Bit 3 Non-buffered Mode + // Bit 2 Unused with non-buffered mode + // Bit 1 Set manual EOI instead of automatic + // Bit 0 8086/8088 mode + +#define OCW1_M 0xff // Master Mask +#define OCW1_S 0xff // Slave Mask + +#define EOI_COMMAND 0x20 // EOI Command + +#define FLASH_DEVICE_BASE_ADDRESS (0xffffffff - FLASH_SIZE + 1) + +#define PCI_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x00 +#define PCI_CLASS_NETWORK_OTHER 0x80 + +#define SPI_OPCODE_READ_ID_INDEX 0x4 + +#if defined HPET_PROTOCOL_SUPPORT && HPET_PROTOCOL_SUPPORT == 1 +#define LEGACY_TIMER_0_COUNT 0x40 +#define LEGACY_TIMER_1_COUNT 0x41 +#define LEGACY_TIMER_CTRL 0x43 +#define TIMER_1_COUNT LEGACY_TIMER_1_COUNT +#endif + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +EFI_STATUS WatchdogInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +); + +EFI_STATUS Initialize8259( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +); + +EFI_STATUS PciPlatformInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +); + +EFI_STATUS +SBDXE_BoardInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +); + +VOID SbInitAfterDeviceInstall ( + IN EFI_EVENT Event, + IN VOID *Context +); + +VOID EFIAPI WatchdogHandler ( + IN EFI_EVENT Event, + IN VOID *Context +); + +EFI_STATUS EFIAPI RegisterHandler ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction +); + +EFI_STATUS EFIAPI WatchdogSetTimerPeriod ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod +); + +EFI_STATUS EFIAPI WatchdogGetTimerPeriod ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN UINT64 *TimerPeriod +); + +EFI_STATUS EFIAPI TimerInit ( + IN EFI_EVENT Event, + IN VOID *Context +); + +EFI_STATUS TimerRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction +); + +EFI_STATUS SetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod +); + +EFI_STATUS GetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 *TimerPeriod +); + +EFI_STATUS GenerateSoftIntr ( + IN EFI_TIMER_ARCH_PROTOCOL *This +); + +VOID SaveRestoreRegisters ( + IN BOOLEAN Save +); + +VOID CreateSbAcpiComponent ( VOID ); + +EFI_STATUS ReserveSbResources ( + IN EFI_HANDLE ImgHandle, + IN EFI_HANDLE CntrHandle +); + +EFI_STATUS AddLpcStdIoSpace ( VOID ); + //(EIP124410)>> +VOID UpdateSmbios136Table( + IN EFI_EVENT Event, + IN VOID *Context +); + //(EIP124410)<< + // [EIP134850] >> +#if defined CSM_SUPPORT && CSM_SUPPORT == 1 +VOID SBSataRegSaveRestore( + IN EFI_EVENT Event, + IN VOID *Context +); +#endif + // [EIP134850] << + +VOID InitSbRegsBeforeBoot ( + IN EFI_EVENT Event, + IN VOID *Context +); + +VOID InitSbRegsBeforeLagecyBoot ( + IN EFI_EVENT Event, + IN VOID *Context +); + +#if defined OEM_USB_PER_PORT_DISABLE_SUPPORT && OEM_USB_PER_PORT_DISABLE_SUPPORT == 1 +VOID USBPrePortDisableCallback ( + IN EFI_EVENT Event, + IN VOID *Context +); +#endif + +VOID EHCIWorkAround ( + IN UINT8 EhciDev +); + +VOID ConfigPciDevices ( + IN EFI_SYSTEM_TABLE *SystemTable +); + +VOID ReportSBDxeError ( + IN EFI_STATUS Status +); + +#ifdef CSM_OPRROM_POLICY_GUID +VOID SbCheckOprom ( + IN EFI_EVENT Event, + IN VOID *Context +); +#endif + +VOID SbSetupNvramUpdatedCallback ( + IN EFI_EVENT Event, + IN VOID *Context +); + +VOID SbExitPmAuthProtocolCallback ( + IN EFI_EVENT Event, + IN VOID *Context +); + +EFI_STATUS +InstallDxePchPlatformPolicy (VOID); + +VOID SBSpiProgramVSCC(VOID); +VOID SBS3SaveSpi(VOID); // [ EIP357393 ] + +VOID SBClearRTC_AlarmFlag(VOID); + +VOID LocatePublishIdeSataAcpiTables(VOID); + +EFI_STATUS SbSmmInit( + IN EFI_EVENT Event, + IN VOID *Context +); + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) +typedef struct { + UINT16 Address; + UINT16 Length; +} LPC_IO_STD_DECODE; + +typedef struct { + UINT8 Bus; + UINT8 Dev; + UINT8 Fun; + VOID *Process; +} DEVICES_AFTER_PCIIO; + +typedef struct { + UINT32 Signature; + UINT32 Length; +} EFI_ACPI_COMMON_HEADER; + +DEVICES_AFTER_PCIIO gDevicesTable[] = { + { PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, NULL }, + { PCIEBRS2_BUS, PCIEBRS2_DEV, PCIEBRS2_FUN, NULL }, + { PCIEBRS3_BUS, PCIEBRS3_DEV, PCIEBRS3_FUN, NULL }, + { PCIEBRS4_BUS, PCIEBRS4_DEV, PCIEBRS4_FUN, NULL }, + { PCIEBRS5_BUS, PCIEBRS5_DEV, PCIEBRS5_FUN, NULL }, + { PCIEBRS6_BUS, PCIEBRS6_DEV, PCIEBRS6_FUN, NULL }, + { PCIEBRS7_BUS, PCIEBRS7_DEV, PCIEBRS7_FUN, NULL }, + { PCIEBRS8_BUS, PCIEBRS8_DEV, PCIEBRS8_FUN, NULL }, + { HDA_BUS, HDA_DEV, HDA_FUN, NULL }, //(EIP101204) + { SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, NULL }, + { SATA_BUS, SATA_DEV, SATA_FUN, NULL }, + { 0xFF, 0xFF, 0xFF, NULL } +}; +UINTN gEventCount = sizeof(gDevicesTable) / sizeof(DEVICES_AFTER_PCIIO); + +typedef struct { + UINT32 VidDid; + UINT32 Vscc; +} SPI_VSCC_TABLE; + //(EIP124410)>> +#pragma pack (1) +typedef struct { + SMBIOS_STRUCTURE_HEADER Header; + UINT16 OemInfo; + UINT16 Zero; //terminator +} EFI_MISC_OEM_TYPE_0x88; +#pragma pack () + //(EIP124410)<< +EFI_HANDLE mTimerProtocolHandle = NULL; +EFI_HANDLE mWatchdogHandle = NULL; +EFI_EVENT mWatchdogEvent; + +// Save daylight when set. +UINT8 gDaylight = 0; +UINT8 gMasterBase; +UINT8 gSlaveBase; + +// Initially in protected mode. (0 = Real, 1 = 32 bit protected) +UINT8 gMode = 1; + +// Initially all Real IRQs masked, protected masked +UINT16 gIrqMask[2] = {0xffff, 0xffff}; + +// Initially all Real IRQs Edge, protected Edge. +UINT16 gIrqTrigger[2] = {0, 0}; +UINT64 mWatchdogPeriod = 0; +UINT64 mProgrammedTimerValue; + +BOOLEAN gErrorLoggingFlag = FALSE; + +EFI_TIMER_NOTIFY mNotifyFunction; +EFI_LEGACY_8259_PROTOCOL *mLegacy8259 = NULL; +EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotifyFunction = NULL; +EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *gPciRootBridgeIo = NULL; +AMI_S3_SAVE_PROTOCOL *gBootScript = NULL; +VOID *gSbInitNotifyReg = NULL; +VOID *gCsmOpromReg = NULL; +VOID *gSbSetupNvramUpdatedReg = NULL; +VOID *gSbExitPmAuthProtocolReg = NULL; +VOID *gSbSataIdeProtocolReg = NULL; +EFI_STATUS LocateSBSATAIDESupportProtocol (IN EFI_GUID *Protocol,OUT VOID **Instance,IN BOOLEAN Type ); + + +SB_SETUP_DATA *gSbSetupData = NULL; +SB_PLATFORM_DATA SbPlatformData; +#if defined(CsmOptOut_SUPPORT) && (CsmOptOut_SUPPORT == 1) +VOID *gInterface = NULL; +#endif +#if defined CSM_SUPPORT && CSM_SUPPORT == 1 // [EIP134850] >> +VOID *SataOpRomRegistration; +static EFI_GUID OpRomStartEndProtocolGuid = OPROM_START_END_PROTOCOL_GUID; +UINT8 SaveSataReg = 0; +UINT8 IsSataOpROM = 0; +UINT8 DLAE = 0; +#endif // [EIP134850] << +BOOLEAN gDisableAllUsbControllers = FALSE; +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 +EFI_EVENT gEvtUsbProtocol = NULL; +VOID *gRegUsbProtocol = NULL; +EFI_USB_PROTOCOL *gUsbProtocol = NULL; +#endif + //(EIP124410)>> +EFI_SMBIOS_PROTOCOL *gSmbiosProtocol = NULL; +EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID; + //(EIP124410)<< +#if SB_PCIE_ERROR_LOG_SUPPORT +EFI_GUID gElogProtocolGuid = EFI_SM_ELOG_PROTOCOL_GUID; +#endif +#define IDE_SATA_ACPI_TABLE_STORAGE_GUID \ + { 0x22046D50,0xF390,0x498c,0x92,0xE5,0x5B,0xA4,0xF8,0xE7,0xF8,0xB6} +EFI_GUID IdeSataAcpiTableStorageGuid = IDE_SATA_ACPI_TABLE_STORAGE_GUID; +#if defined(CsmOptOut_SUPPORT) && (CsmOptOut_SUPPORT == 1) +EFI_GUID gAmiLoadCsmGuid = AMI_LOAD_CSM_GUID; +#endif +#if SecureMod_SUPPORT +EFI_GUID gBiosLockEnableEventGuid = AMI_EVENT_FLASH_WRITE_LOCK; +#endif + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) +extern UINT8 gBspLocalApicID; +#endif + +CSP_RES_ITEM gSbResTable[] = { +//---------------------------------------------------------------------------- +// ResBase ResLength ResType Attributes +//---------------------------------------------------------------------------- +// Always reserve 16MB for ROM image. +{ RESERVED_ROM_BASE, RESERVED_ROM_LENGTH, EfiGcdMemoryTypeMemoryMappedIo ,\ + (EFI_MEMORY_UC | EFI_MEMORY_RUNTIME)}, +// IOAPICs dedicated Space +{ APCB, APCL, EfiGcdMemoryTypeMemoryMappedIo , \ + (EFI_MEMORY_UC|EFI_MEMORY_RUNTIME)}, +#if FEC00000_APIC_AUTODETECT +{ APCB + APCL, 0x00100000 - APCL, EfiGcdMemoryTypeMemoryMappedIo , \ + EFI_MEMORY_UC}, +#endif + +#if HPET_SUPPORT +// HPET dedicated Space +{ HPET_BASE_ADDRESS, 0x00004000, EfiGcdMemoryTypeMemoryMappedIo , \ + (EFI_MEMORY_UC|EFI_MEMORY_RUNTIME)}, +#endif +// Reserve for RCRB Base, the attributes of this region should be defined to +// RUNTIME because it includes the SPI_BASE_ADDRESS. +{ SB_RCRB_BASE_ADDRESS, SB_RCRB_LENGTH, EfiGcdMemoryTypeMemoryMappedIo , \ + (EFI_MEMORY_UC|EFI_MEMORY_RUNTIME)}, +// SB Temp Memory Mapped Space +{ SB_TEMP_MMIO_BASE, SB_TEMP_MMIO_BASE_LENGTH, EfiGcdMemoryTypeMemoryMappedIo, (EFI_MEMORY_UC) }, +// HECI Memory Mapped Space +{ HECI_BASE_ADDRESS, 0x10000, EfiGcdMemoryTypeMemoryMappedIo, (EFI_MEMORY_UC) }, +// HECI2 Memory Mapped Space +{ HECI2_BASE_ADDRESS, 0x10000, EfiGcdMemoryTypeMemoryMappedIo, (EFI_MEMORY_UC) }, +// IO Used by PM register block +{ PM_BASE_ADDRESS, PMLN ,EfiGcdIoTypeIo , -1 }, +// IO Used by SMBus register block +{ SMBUS_BASE_ADDRESS, SMBL ,EfiGcdIoTypeIo , -1 }, +// IO Used by GPIO register block +{ GPIO_BASE_ADDRESS, GPLN ,EfiGcdIoTypeIo , -1 }, +}; + +UINTN gSbResTableCount = sizeof(gSbResTable) / sizeof(CSP_RES_ITEM); + +#define ONBOARD_RAID_GUID \ + { 0x5d206dd3, 0x516a, 0x47dc, 0xa1, 0xbc, 0x6d, 0xa2, 0x4, 0xaa, 0xbe, 0x8 }; + +#define EXIT_PM_AUTH_PROTOCOL_GUID \ + { 0xd088a413, 0xa70, 0x4217, 0xba, 0x55, 0x9a, 0x3c, 0xb6, 0x5c, 0x41, 0xb3 }; + +#if SataDriver_SUPPORT +#define PCH_EFI_RAID_DRIVER_EXECUTION_GUID \ + { 0x99D5757C, 0xD906, 0x11E0, 0x8D, 0x78, 0x8D, 0xE4, 0x48, 0x24, 0x01, 0x9B }; +#endif + +// GUID Definition(s) +EFI_GUID gOnboardRaidGuid = ONBOARD_RAID_GUID; +EFI_GUID gEfiTimerArchProtocolGuid = EFI_TIMER_ARCH_PROTOCOL_GUID; +EFI_GUID gEfiLegacy8259ProtocolGuid = EFI_LEGACY_8259_PROTOCOL_GUID; +EFI_GUID gEfiPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID; +EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; +EFI_GUID gEfiPciPlatformProtocolGuid = EFI_PCI_PLATFORM_PROTOCOL_GUID; +EFI_GUID gDxeSvcTblGuid = DXE_SERVICES_TABLE_GUID; +EFI_GUID gSetupNvramUpdatedGuid = AMITSE_NVRAM_UPDATE_GUID; +EFI_GUID gDxePchPlatformPolicyProtocolGuid = DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID; +EFI_GUID gWatchdogGuid = EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID; +EFI_GUID gEfiPciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; +EFI_GUID gExitPmAuthProtocolGuid = EXIT_PM_AUTH_PROTOCOL_GUID; +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 +EFI_GUID gEfiUsbProtocolGuid = EFI_USB_PROTOCOL_GUID; +#endif + +EFI_GUID BeforeBootProtocolGuid = AMITSE_EVENT_BEFORE_BOOT_GUID; +#if CSM_SUPPORT +EFI_GUID BeforeLegacyBootProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID; +#endif + +#ifdef CSM_OPRROM_POLICY_GUID +EFI_GUID gCsmOpromPolicyGuid = CSM_OPRROM_POLICY_GUID; +#endif + +extern EFI_GUID gEfiSmmControlProtocolGuid; + +EFI_GUID GuidListCheckForRaid[] = { BUS_OVERRIDE_GUIDS_FOR_RAID NULL }; +EFI_HANDLE ImageHandleArray[5] = {NULL}; +BOOLEAN LoadedImageDone = FALSE; + +EFI_STATUS RaidGetDriver( + IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, + IN OUT EFI_HANDLE *DriverImageHandle +); + +static EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL RaidBusSpecificDriverOverride = { + RaidGetDriver +}; + +static AHCI_PLATFORM_POLICY_PROTOCOL AhciPlatformPolicy= { +#ifndef DiPM_SUPPORT + FALSE, // Legacy Raid option selected + TRUE // Ahcibus driver handles the ATAPI devices +#else + FALSE, // Legacy Raid option selected + TRUE, // Ahcibus driver handles the ATAPI devices +#if !defined SB_SATA_DLAE || SB_SATA_DLAE == 0 + FALSE, // Drive LED on ATAPI Enable (DLAE) +#else + TRUE, +#endif +#ifdef POWERUP_IN_STANDBY_SUPPORT + POWERUP_IN_STANDBY_SUPPORT, // PowerUpInStandby feature is supported or not +#else + FALSE, +#endif +#ifdef POWERUP_IN_STANDBY_MODE + POWERUP_IN_STANDBY_MODE, // PowerUpInStandby mode +#else + FALSE, +#endif + DiPM_SUPPORT // Device Initiated power management +#endif +}; + +// Protocol Definition(s) + +// Architectural Protocol Definitions +EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdog = { + RegisterHandler, + WatchdogSetTimerPeriod, + WatchdogGetTimerPeriod +}; + +EFI_TIMER_ARCH_PROTOCOL mTimerProtocol = { + TimerRegisterHandler, + SetTimerPeriod, + GetTimerPeriod, + GenerateSoftIntr +}; + +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 +VOID SbUsbProtocolCallback ( + IN EFI_EVENT Event, + IN VOID *Context +); +#endif + +#if SecureMod_SUPPORT +VOID BiosLockEnableCallback ( + IN EFI_EVENT Event, + IN VOID *Context +); +#endif + +VOID ULTDsdtTableUpdate ( + IN ACPI_HDR *DsdtTable +); + +VOID DsdtTableUpdate ( + IN ACPI_HDR *DsdtTable +); +// External Declaration(s) + +extern EFI_STATUS CountTime ( + IN UINTN DelayTime, + IN UINT16 BaseAddr +); + +VOID ClearWarmResetFlag (VOID); + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RetrainLink +// +// Description: Retrain PCIE Device Link +// +// Input: IN UINT32 Address +// +// Output: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID RetrainLink(IN UINT32 Address) +{ + SET_MEM8(Address + R_PCH_PCIE_LCTL, BIT05); // 0x50 + CountTime(10, PM_BASE_ADDRESS); + while (READ_MEM16(Address + R_PCH_PCIE_LSTS) & BIT11); // 0x52 +} + +#if SataDriver_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InstallPchSataUefiDriver +// +// Description: Install SATA UEFI RAID driver GUID for PCH SataDriver. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID InstallPchSataUefiDriver ( VOID ) +{ +#if defined(CsmOptOut_SUPPORT) && (CsmOptOut_SUPPORT == 1) + SETUP_DATA SetupData; + EFI_GUID SetupGuid = SETUP_GUID; + UINTN Size = sizeof(SETUP_DATA); +#endif // CsmOptOut_SUPPORT + BOOLEAN InstallRaidDriver = TRUE; + EFI_HANDLE Handle = NULL; + EFI_STATUS Status; + EFI_HANDLE RaidDriverHandle=NULL; + EFI_GUID PchEfiRaidDriverExecutionGuid = \ + PCH_EFI_RAID_DRIVER_EXECUTION_GUID; + + if (gSbSetupData->SataInterfaceMode == SATA_MODE_RAID) { + +#if defined(CsmOptOut_SUPPORT) && (CsmOptOut_SUPPORT == 1) + Status = pBS->LocateProtocol( &gAmiLoadCsmGuid, \ + NULL, \ + &gInterface ); + if(!EFI_ERROR(Status)) { + + Status = pRS->GetVariable ( L"Setup", \ + &SetupGuid, \ + NULL,\ + &Size, \ + &SetupData ); + if (!EFI_ERROR(Status)) { + if ((SetupData.MassStorageOpRom == 0) || \ + (SetupData.MassStorageOpRom == 2)) + InstallRaidDriver = FALSE; + } + } +#else + if (gSbSetupData->SataRaidRom == 0) InstallRaidDriver = FALSE; +#endif // CsmOptOut_SUPPORT + + // + // By default Legacy Raid option settings initilized + // + AhciPlatformPolicy.RaidDriverMode= FALSE; + AhciPlatformPolicy.AhciBusAtapiSupport= TRUE; + + if (InstallRaidDriver) { + Status = pBS->InstallProtocolInterface( \ + &Handle, \ + &PchEfiRaidDriverExecutionGuid, \ + EFI_NATIVE_INTERFACE, \ + NULL); + ASSERT_EFI_ERROR(Status); + + // + // UEFI Raid driver enabled + // + AhciPlatformPolicy.RaidDriverMode= TRUE; + // + // Uefi Raid driver supports the ATAPI device. So Ahcibus doesn't need to handle the ATAPI devices + // + AhciPlatformPolicy.AhciBusAtapiSupport= FALSE; + } + + Status = pBS->InstallProtocolInterface( &RaidDriverHandle, + &gAciPlatformPolicyProtocolGuid, + EFI_NATIVE_INTERFACE, + &AhciPlatformPolicy); + } +} +#endif + +#if FORCE_USER_TO_SETUP_IF_CMOS_BAD // [EIP88358] >> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ForceSetupIfCmosBad +// +// Description: BIOS force to enter setup if CMOS was bad. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ForceSetupIfCmosBad (VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + CMOS_BAD_HOB *CmosBadHob; + UINT32 BootFlow = BOOT_FLOW_CONDITION_FIRST_BOOT; + EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID; + EFI_GUID ghoblistguid = HOB_LIST_GUID; + EFI_GUID CmosBadHobGuid = CMOS_BAD_HOB_GUID; + + CmosBadHob = GetEfiConfigurationTable( //get hob list + pST, + &ghoblistguid); + + if(CmosBadHob == NULL) return; + + Status = FindNextHobByGuid( //the hob exit when cmos is bad and creat hob success. + &CmosBadHobGuid, + &CmosBadHob); + + if(!EFI_ERROR(Status)) { + TRACE((-1, "SB: Force to Setup.\n")); + pRS->SetVariable( + L"BootFlow", + &guidBootFlow, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(BootFlow), + &BootFlow); + } +} +#endif // [EIP88358] << + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBDXE_Init +// +// Description: This function is the entry point for this DXE. This function +// initializes the chipset SB +// +// Input: ImageHandle - Image handle +// SystemTable - Pointer to the system table +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBDXE_Init ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + + EFI_STATUS Status = EFI_SUCCESS; + EFI_EVENT Event; + CPUINFO_HOB *CpuInfoHob; + EFI_GUID HobListGuid = HOB_LIST_GUID; + EFI_GUID AmiCpuinfoHobGuid = AMI_CPUINFO_HOB_GUID; + EFI_GUID SetupGuid = SETUP_GUID; + UINTN VariableSize = sizeof(SB_SETUP_DATA); + EFI_EVENT BeforeBootEvent; + EFI_EVENT LegacyBootEvent; + EFI_EVENT CRIDSmbiosEvent; //(EIP124410) +#if defined CSM_SUPPORT && CSM_SUPPORT == 1 + EFI_EVENT SbSataOptEvent; // [EIP134850] +#endif + VOID *Protocol = NULL; + VOID *NotifyReg = NULL; +#if SecureMod_SUPPORT + EFI_EVENT BleEvtProtocol = NULL; + VOID *BleProtocolReg = NULL; +#endif + VOID *Registration = NULL; + + InitAmiLib(ImageHandle, SystemTable); + + PROGRESS_CODE (DXE_SB_INIT); + + ClearWarmResetFlag(); + + Status = pBS->LocateProtocol( &gEfiPciRootBridgeIoProtocolGuid, \ + NULL, \ + &gPciRootBridgeIo ); + ReportSBDxeError(Status); + + Status = pBS->LocateProtocol( AMI_S3_SAVE_PROTOCOL_GUID, \ + NULL, \ + &gBootScript ); + ReportSBDxeError(Status); + + //Find APIC ID Hob. + CpuInfoHob = (CPUINFO_HOB*)GetEfiConfigurationTable( SystemTable, \ + &HobListGuid ); + if (CpuInfoHob == NULL) Status = EFI_UNSUPPORTED; + else Status = FindNextHobByGuid( &AmiCpuinfoHobGuid, (VOID**)&CpuInfoHob); + ASSERT_EFI_ERROR(Status); + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + gBspLocalApicID = CpuInfoHob->Cpuinfo[0].ApicId; +#endif + + // Put the I/O APIC in Virtual wire mode + // CHIPSET PROGRAMMING TO ENABLE IOAPIC GOES HERE + + WRITE_MEM8_S3(gBootScript, APCB, 0); // IO APIC index (0) + WRITE_MEM32_S3(gBootScript, APCB + 0x10, (NCPU << 24)); // APIC ID // [EIP132701] + WRITE_MEM8_S3(gBootScript, APCB, 0x10); // Index 0x10 + // INT0 - EXT INT unmasked + WRITE_MEM32_S3(gBootScript, APCB + 0x10, 0x700); // [EIP132701] + + // Install 8259 services + Initialize8259(ImageHandle, SystemTable); + + // Install watchdog timer services + WatchdogInit(ImageHandle, SystemTable); + +#if SmartTimer_SUPPORT == 0 + // Install Legacy timer services + TimerInit(ImageHandle, SystemTable); +#endif + + + Status = pBS->AllocatePool( EfiBootServicesData, \ + VariableSize, \ + &gSbSetupData ); + ASSERT_EFI_ERROR(Status); + + GetSbSetupData( pRS, gSbSetupData, FALSE ); + + // + // Enable or Disable the Devices depending upon the Setup. + // + + PROGRESS_CODE (DXE_SB_DEVICES_INIT); + + ConfigPciDevices(SystemTable); + + CreateSbAcpiComponent(); + + // Clear RTC Reg C Alarm Flag + SBClearRTC_AlarmFlag(); + + Status = SBDXE_BoardInit(ImageHandle, SystemTable); + + Status = RegisterProtocolCallback( &gEfiPciIoProtocolGuid, \ + SbInitAfterDeviceInstall, \ + NULL, \ + &Event, \ + &gSbInitNotifyReg ); + ReportSBDxeError( Status ); + +#ifdef CSM_OPRROM_POLICY_GUID + Status = RegisterProtocolCallback( &gCsmOpromPolicyGuid, \ + SbCheckOprom, \ + NULL, \ + &Event, \ + &gCsmOpromReg ); + + ReportSBDxeError( Status ); +#endif + + Status = RegisterProtocolCallback( &gSetupNvramUpdatedGuid, \ + SbSetupNvramUpdatedCallback, \ + NULL, \ + &Event, \ + &gSbSetupNvramUpdatedReg ); + ReportSBDxeError( Status ); + + + Status = ReserveSbResources(ImageHandle, SystemTable); + + ReportSBDxeError(Status); + + Status = RegisterProtocolCallback( &gExitPmAuthProtocolGuid, \ + SbExitPmAuthProtocolCallback, \ + NULL, \ + &Event, \ + &gSbExitPmAuthProtocolReg ); + ReportSBDxeError( Status ); + +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 + Status = RegisterProtocolCallback( &gEfiUsbProtocolGuid,\ + SbUsbProtocolCallback,\ + NULL,\ + &gEvtUsbProtocol,\ + &gRegUsbProtocol ); +#endif + +#if SecureMod_SUPPORT + Status = RegisterProtocolCallback( &gBiosLockEnableEventGuid,\ + BiosLockEnableCallback,\ + NULL,\ + &BleEvtProtocol,\ + &BleProtocolReg ); +#endif + + Status = CreateReadyToBootEvent( TPL_NOTIFY, InitSbRegsBeforeBoot, \ + NULL, &BeforeBootEvent ); + ReportSBDxeError(Status); + //(EIP124410)>> + Status = CreateReadyToBootEvent( TPL_NOTIFY, UpdateSmbios136Table, \ + NULL, &CRIDSmbiosEvent ); + ReportSBDxeError(Status); + //(EIP124410)<< + Status = CreateLegacyBootEvent( TPL_CALLBACK, \ + InitSbRegsBeforeLagecyBoot, \ + NULL, \ + &LegacyBootEvent ); + ReportSBDxeError(Status); + +#if defined OEM_USB_PER_PORT_DISABLE_SUPPORT && OEM_USB_PER_PORT_DISABLE_SUPPORT == 1 + RegisterProtocolCallback( + &BeforeBootProtocolGuid, + USBPrePortDisableCallback, + NULL, &Event, &Registration + ); + +#if CSM_SUPPORT + RegisterProtocolCallback( + &BeforeLegacyBootProtocolGuid, + USBPrePortDisableCallback, + NULL, &Event, &Registration + ); + + CreateLegacyBootEvent(TPL_CALLBACK, &USBPrePortDisableCallback, NULL, &LegacyBootEvent); +#endif + + pBS->CreateEvent( + EVT_SIGNAL_EXIT_BOOT_SERVICES,TPL_CALLBACK, + &USBPrePortDisableCallback, NULL, &Event + ); +#endif + + Status = InstallDxePchPlatformPolicy(); + ReportSBDxeError(Status); + + //Program SPI base VSCC + SBSpiProgramVSCC(); + //Restore SPI register for S3 resume // [ EIP357393 ] + SBS3SaveSpi(); // [ EIp357393 ] + +//- Status = AddLpcStdIoSpace(); + +#if SataDriver_SUPPORT + InstallPchSataUefiDriver(); +#endif +#if defined CSM_SUPPORT && CSM_SUPPORT == 1 // [EIP134850] >> + if(gSbSetupData->SataInterfaceMode == SATA_MODE_RAID){ + Status = RegisterProtocolCallback(&OpRomStartEndProtocolGuid, + SBSataRegSaveRestore, + NULL, + &SbSataOptEvent, + &SataOpRomRegistration); + TRACE((TRACE_ALWAYS, "Register OpRomStartEndProtocol callback() = %r\n", Status)); + } +#endif // [EIP134850] << + +#if FORCE_USER_TO_SETUP_IF_CMOS_BAD // [EIP88358] >> + ForceSetupIfCmosBad(); +#endif // [EIP88358] << + +#if defined SMM_SUPPORT && SMM_SUPPORT == 1 + Status = pBS->LocateProtocol(&gEfiSmmControlProtocolGuid, NULL, &Protocol); + if (EFI_ERROR(Status)) + { + Status = RegisterProtocolCallback( + &gEfiSmmControlProtocolGuid, + SbSmmInit, + NULL, + &Event, + &NotifyReg); + ASSERT_EFI_ERROR(Status); + } + else + { + Status = SbSmmInit(NULL, NULL); + if (Status != EFI_SUCCESS) + { + TRACE((TRACE_ALWAYS, "SbSmmInit() = %r\n", Status)); + ASSERT_EFI_ERROR(Status); + } + } +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBClearRTC_AlarmFlag +// +// Description: Clear RTC Reg C Alarm Flag +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBClearRTC_AlarmFlag(VOID) +{ + + // Clear all SMI status here. + // Must read RTC Reg C to be able to clear SMM RTC alarm flag. + SBLib_CmosRead(0x0C); + + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0xcd31); // 0x00 + if (GetPchSeries() == PchLp) { + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_STS + 0x0c, 0xffffffff); // 0x8C + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_STS, 0xffffffff); // 0x50 + } else { + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS, 0xffffffff); // 0x20 + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS + 4, 0xffffffff); // 0x24 + WRITE_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS, 0xffff); // 0x3A + } + WRITE_IO16_PM(ACPI_IOREG_DEVACT_STS, 0xffff); // 0x44 + WRITE_IO16_TCO(TCO_IOREG_STS1, 0xffff); // 0x04 + WRITE_IO16_TCO(TCO_IOREG_STS2, 0xfffe); // 0x06, Skip Intrusion [EIP73607] + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0xffffffff); // 0x34 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSpiProgramVSCC +// +// Description: Program SPI VSCC. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBSpiProgramVSCC(VOID) +{ + EFI_STATUS Status; + UINT32 Data32 = 0; + UINT32 dUVSCC = 0; + UINT32 Mask = 0xFFFFFFFF; + UINT8 Data8 = 0; +#if defined (SPI_INITIALIZE_WITH_VSCC) && (SPI_INITIALIZE_WITH_VSCC == 1) + static FLASH_PROTOCOL *Flash = NULL; +#endif +#if defined (OEM_UPDATE_VSCC_TABLE_SUPPORT) && (OEM_UPDATE_VSCC_TABLE_SUPPORT == 1) + SPI_VSCC_TABLE SpiVsccTbl[] = { OEM_SPI_VSCC_TABLE }; + UINTN VsccTableCount = sizeof (SpiVsccTbl) / sizeof (SPI_VSCC_TABLE); + UINT16 SpiCmd =0; + UINT32 Timeout; + UINTN i; +#endif + + TRACE((TRACE_ALWAYS, "[[ SBSpiProgramVSCC() Start. ]]\n")); + + // If Flash module support VSCC updated, skip programming VSCC. + // If enable OEM_UPDATE_VSCC_TABLE_SUPPORT, override VSCC value by ELINK. + if (((0 == READ_MEM32_SPI(R_RCRB_SPI_UVSCC)) && + (0 == READ_MEM32_SPI(R_RCRB_SPI_LVSCC))) || + (OEM_UPDATE_VSCC_TABLE_SUPPORT == 1)) { +#if defined (SPI_INITIALIZE_WITH_VSCC) && (SPI_INITIALIZE_WITH_VSCC == 1) + Status = pBS->LocateProtocol(&gFlashProtocolGuid, NULL, &Flash); + if (!EFI_ERROR(Status)) { + // Identify Flash through FlashWriteEnable Hook. + Flash->DeviceWriteEnable(); + Flash->DeviceWriteDisable(); + } + if (((0 == READ_MEM32_SPI(R_RCRB_SPI_UVSCC)) && + (0 == READ_MEM32_SPI(R_RCRB_SPI_LVSCC))) || + (OEM_UPDATE_VSCC_TABLE_SUPPORT == 1)) +#endif + { + dUVSCC = ((UINT32)(READ_MEM8_SPI(R_RCRB_SPI_OPMENU + 2)) << 8); + + Data8 = READ_MEM8_SPI(R_RCRB_SPI_PREOP + 1); + if ((Data8 == 0x50) || (Data8 == 0x39)) + dUVSCC |= BIT03; + + if (Data8 == 0x39 ) { + dUVSCC |= (BIT04 + BIT02); + } else if(Data8 != 0x50) { + dUVSCC |= BIT02; + } + + if (READ_MEM8_SPI(R_RCRB_SPI_OPMENU + 2) == 0xD8) + dUVSCC |= (BIT00 + BIT01); + else + dUVSCC |= (BIT00); + +#if defined (OEM_UPDATE_VSCC_TABLE_SUPPORT) && (OEM_UPDATE_VSCC_TABLE_SUPPORT == 1) + // Set SPI read-address = 0 + WRITE_MEM32_SPI(R_RCRB_SPI_FADDR, 0); + SpiCmd = SPI_OPCODE_READ_ID_INDEX << 4; + SpiCmd += ( ( 3 - 1 ) << 8 ); + SpiCmd += ( 1 << 14 ); + // Go (BIT1) + WRITE_MEM16_SPI(R_RCRB_SPI_SSFCTL, SpiCmd | BIT01); + + // WaitForSpiCycleDone + for ( Timeout = 0, i = 0; Timeout < 0x4000000; Timeout++ ) { + i = READ_MEM8_SPI(R_RCRB_SPI_SSFSTS); + if ( i & BIT02 ) break; + } + // IoDelay + for ( Timeout = 0; Timeout < 33; Timeout++ ) { + IoWrite8( 0xEB, 0x55 ); + IoWrite8( 0xEB, 0xAA ); + } + // write BIT2 to clear CycleDone status + WRITE_MEM8_SPI(R_RCRB_SPI_SSFSTS, BIT02); + // Get Flash ID + Data32 = READ_MEM32_SPI(R_RCRB_SPI_FDATA0) & 0x00FFFFFF; + // Swap MSB/LSB + Data32 = (((Data32 & 0xff) << 16) | ((Data32 & 0xff0000) >>16) | ((Data32 & 0xff00))); + + for ( i =0; i < VsccTableCount; i++ ) { + if (SpiVsccTbl[i].VidDid == Data32) { + dUVSCC = SpiVsccTbl[i].Vscc; + } + } +#endif + WRITE_MEM32_SPI(R_RCRB_SPI_UVSCC, dUVSCC); + WRITE_MEM32_SPI(R_RCRB_SPI_LVSCC, dUVSCC); + } + } +//#### } + + Status = ReadSPIDescriptor(0x01, 0x00, &Data32); + if (!EFI_ERROR(Status)) + { + Data8 = (UINT8)((Data32 & (BIT27 | BIT28 | BIT29)) >> 27); + SET_MEM8_SPI(R_RCRB_SPI_SSFCTL + 2, Data8); + } + TRACE((TRACE_ALWAYS, "[[ SBSpiProgramVSCC() Done. ]]\n")); +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsMobileSku +// +// Description: This function will check the South Bridge whether it is +// mobile SKU. +// +// Input: None +// +// Output: BOOLEAN +// TRUE - The South Bridge is mobile SKU. +// FALSE - The South Bridge is not mobile SKU. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsMobileSku (VOID) +{ + return TRUE; // TODO +} + +//---------------------------------------------------------------------------- +#if (ACPI_SUPPORT) + +#include <Acpi20.h> +#include <Protocol\AcpiSupport.h> + +EFI_EVENT mAcpiEvent; +VOID *mAcpiReg; +UINT64 gHpetBase = HPET_BASE_ADDRESS; +UINTN mHpetTblHandle; +SB_ASL_BUFFER *gSbAslBufPtr = NULL; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: CreateSbAcpiCallback +// +// Description: This function will create all ACPI components for SB when +// ACPI support protocol is available. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID CreateSbAcpiCallback ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID SbAslBufPtrGuid = SB_ASL_BUFFER_PTR_GUID; + CHAR16 SbAslBufPtrVar[] = SB_ASL_BUFFER_PTR_VARIABLE; + HPET_20 *Hpet; + EFI_ACPI_SUPPORT_PROTOCOL *As; + ACPI_HDR *DsdtPtr = NULL; + FACP_20 *Table = NULL; + UINT8 *OtRegDataPtr = NULL; + ASL_OBJ_INFO AslObj; + EFI_ACPI_TABLE_VERSION Version; + UINTN Handle; + UINTN Index; + UINT32 SbAslBufVarPtr; + UINT32 OldSbAslBufVarPtr = 0; + UINT32 Attributes = 0; + UINTN VarSize; + UINT8 OemId[6] = CONVERT_TO_STRING(T_ACPI_OEM_ID); + UINT8 OemTblId[8] = \ + CONVERT_TO_STRING(T_ACPI_OEM_TBL_ID); + + // It must be only one instance of such protocol + Status = pBS->LocateProtocol(&gEfiAcpiSupportGuid, NULL, &As); + if(EFI_ERROR(Status)) { + TRACE((-1, "ACPI Support Protocol is not ready for SB components\n")); + return; + } + TRACE((-1,"SB Locate Protocol(ACPISupport)- %r Success\n", Status)); + + if (gSbSetupData->Hpet) { + + Hpet = MallocZ(sizeof(HPET_20)); + ASSERT(Hpet); + if (Hpet) { + // Fill Table header; + Hpet->Header.Signature = HPET_SIG; + Hpet->Header.Length = sizeof(HPET_20); + Hpet->Header.Revision = 1; + Hpet->Header.Checksum = 0; + MemCpy(&(Hpet->Header.OemId[0]), OemId, 6); + MemCpy(&(Hpet->Header.OemTblId[0]), OemTblId, 8); + Hpet->Header.OemRev = ACPI_OEM_REV; + Hpet->Header.CreatorId = 0x2e494d41;//"AMI." + Hpet->Header.CreatorRev = CORE_REVISION; + + // Fill HPET Fields + // The GAS structure + Hpet->BaseAddress.AddrSpcID = GAS_SYS_MEM; + Hpet->BaseAddress.RegBitWidth = 64; + Hpet->BaseAddress.RegBitOffs = 0; + // Base address of 1K HPET RegBlock space + Hpet->BaseAddress.Address = gHpetBase; + + Hpet->EvtTmrBlockId.TMR_BLK_ID = *(UINT32*)(UINTN)gHpetBase; + + Hpet->MinTickPeriod = 14318; // Approx 1ms + + // Add table + Status = As->SetAcpiTable( As, \ + Hpet, \ + TRUE, \ + EFI_ACPI_TABLE_VERSION_ALL, \ + &mHpetTblHandle ); + TRACE((-1,"ACPISupport.SetAcpiTable() = %r \n", Status)); + ASSERT_EFI_ERROR(Status); + + // Free memory used for table image + pBS->FreePool(Hpet); + } + } + + // Find DSDT ACPI Table + for (Index = 0; Index < ACPI_RSDT_TABLE_NUM; Index++) { + Status = As->GetAcpiTable(As, Index, &Table, &Version, &Handle); + if (EFI_ERROR(Status)) break;//no more tables left + + if ((Table->Header.Signature == FACP_SIG) && (DsdtPtr == NULL)) { + DsdtPtr = (ACPI_HDR*)Table->DSDT; + TRACE((-1, "SBDXE: Found DSDT Table at 0x%08X\n", DsdtPtr)); + break; + } + } + + Status = pBS->AllocatePool( EfiReservedMemoryType, \ + sizeof(SB_ASL_BUFFER), \ + (VOID**)&gSbAslBufPtr ); + if (!EFI_ERROR(Status)) { + MemSet(gSbAslBufPtr, sizeof(SB_ASL_BUFFER), 0); + Status = GetAslObj( (UINT8*)(DsdtPtr + 1), \ + DsdtPtr->Length - sizeof(ACPI_HDR)-1, \ + "CPSB", \ + otOpReg, \ + &AslObj ); + if (!EFI_ERROR(Status)) { + OtRegDataPtr = (UINT8*)AslObj.DataStart; + SbAslBufVarPtr = (UINT32)gSbAslBufPtr; + *(UINT32*)(OtRegDataPtr + 2) = SbAslBufVarPtr; + + VarSize = sizeof(SbAslBufVarPtr); + Status = pRS->GetVariable( SbAslBufPtrVar, \ + &SbAslBufPtrGuid, \ + &Attributes, \ + &VarSize, \ + &OldSbAslBufVarPtr ); + if ((EFI_ERROR(Status)) || (SbAslBufVarPtr != OldSbAslBufVarPtr)) + if (EFI_ERROR(Status)) Attributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS); + Status = pRS->SetVariable( SbAslBufPtrVar, \ + &SbAslBufPtrGuid, \ + Attributes, + sizeof(SbAslBufVarPtr), \ + &SbAslBufVarPtr ); + } + } + + LocatePublishIdeSataAcpiTables(); + + // Kill the Event + pBS->CloseEvent(Event); +} + +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ConfigPciDevices +// +// Description: This function will Enable/Disable onchip PCI device in SB +// depend on SETUP questions. +// +// Input: SystemTable - Pointer to the system table +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ConfigPciDevices ( + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: CreateSbAcpiComponent +// +// Description: This function creates all ACPI components supported by SB. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID CreateSbAcpiComponent (VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT8 Buffer8 = 0; + +//HPET Support +#if (HPET_SUPPORT) + if (gSbSetupData->Hpet) { + Buffer8 = (UINT8)((HPET_BASE_ADDRESS >> 12) & 3) | 0x80; + // Enable HPET (0x3404) + WRITE_MEM32_RCRB_S3(gBootScript, RCRB_MMIO_HPTC, Buffer8); + } else { + RESET_MEM32_RCRB_S3(gBootScript, RCRB_MMIO_HPTC, 0x80); + } +#endif + +#if (ACPI_SUPPORT) + Status = RegisterProtocolCallback( &gEfiAcpiSupportGuid, \ + CreateSbAcpiCallback, \ + NULL, \ + &mAcpiEvent, \ + &mAcpiReg ); + // If AcpiSupport protocol has been installed we can use it rigth on + // the way + pBS->SignalEvent( mAcpiEvent ); +#endif + + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetExtCapStrucAddr +// +// Description: This function tries to find the specific PCI Express extended +// capabilities ID structure address. +// +// Input: Bus - The PCI Bus number. +// Dev - The PCI Device number. +// Fun - The PCI Function number. +// FindCapId - the specific extended capabilities ID will be +// found. +// +// Output: EFI_STATUS +// EFI_SUCCESS - Found the extended capabilities structure +// successfully, the input CapPtr16 will +// have the structure address. +// EFI_NOT_FOUND - Not found the extended capabilities +// structure. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS GetExtCapStrucAddr ( + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Fun, + IN UINT16 FindCapId, + IN UINT16 *CapPtr16 ) +{ + UINT32 Buffer32; + + *CapPtr16 = 0x100; + + Buffer32 = READ_PCI32(Bus, Dev, Fun, *CapPtr16); + while (Buffer32 != 0xffffffff) { + if ((UINT16)Buffer32 == FindCapId) return EFI_SUCCESS; + *CapPtr16 = (UINT16)((Buffer32 >> 20) & 0xfffc); + if (*CapPtr16 == 0) break; + Buffer32 = READ_PCI32(Bus, Dev, Fun, *CapPtr16); + } + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetLegCapStrucAddr +// +// Description: This function tries to find the specific capabilities +// ID structure address. +// +// Input: Bus - The PCI Bus number. +// Dev - The PCI Device number. +// Fun - The PCI Function number. +// FindCapId - the specific legacy capabilities ID will be +// found. +// +// Output: EFI_STATUS +// EFI_SUCCESS - Found the legacy capabilities structure +// successfully, the input CapPtr16 will +// have the structure address. +// EFI_NOT_FOUND - Not found the extended capabilities +// structure. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS GetLegCapStrucAddr ( + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Fun, + IN UINT8 FindCapId, + IN UINT16 *CapPtr16 ) +{ + UINT8 Buffer8; + + if (READ_PCI32(Bus, Dev, Fun, PCI_VID) != 0xffffffff) { + if (READ_PCI16(Bus, Dev, Fun, PCI_STS) & 0x10) { + *CapPtr16 = ((READ_PCI8(Bus, Dev, Fun, PCI_HDR) & 0x7f) == 2) ? \ + 0x14:0x34; + *CapPtr16 = (UINT16)READ_PCI8(Bus, Dev, Fun, *CapPtr16); + if (*CapPtr16 == 0) return EFI_NOT_FOUND; + Buffer8 = READ_PCI8(Bus, Dev, Fun, *CapPtr16); + while (Buffer8 != 0) { + if (Buffer8 == FindCapId) return EFI_SUCCESS; + Buffer8 = (UINT8)(*CapPtr16) + 1; + *CapPtr16 = (UINT16)(READ_PCI8(Bus, Dev, Fun, Buffer8)); + if (*CapPtr16 == 0) break; + Buffer8 = READ_PCI8(Bus, Dev, Fun, *CapPtr16); + } + } + } + + return EFI_NOT_FOUND; +} + +#if SB_PCIE_ERROR_LOG_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbEnablePciDevErr +// +// Description: Enable the error register of PCI-Express Device. +// +// Input: Address - PCI Express Config MMIO of device. +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SbEnablePciDevErr(IN UINT64 Address) +{ + UINT32 DevBaseAddr = (UINT32)Address; + UINT8 CapPtr; + + CapPtr = SbFindCapPtr(DevBaseAddr, 0x10); + if(CapPtr != 0) + { + // Clear Error Status + WRITE_MEM8_S3(gBootScript, DevBaseAddr + CapPtr + 0x0A, (BIT0 | BIT1 | BIT2)); + + // Enable CEE/NFE/FEE + // Root? + if ((READ_MEM8(DevBaseAddr + CapPtr + 0x02) & 0xF0) == 0x40) + WRITE_MEM8_S3(gBootScript, DevBaseAddr + CapPtr + 0x1C, (BIT0 | BIT1 | BIT2)); + + // End-Device? + else if ((READ_MEM8(DevBaseAddr + CapPtr + 0x02) & 0xF0) == 0x00) + WRITE_MEM8_S3(gBootScript, DevBaseAddr + CapPtr + 0x08, (BIT0 | BIT1 | BIT2)); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SbPciExpressDeviceInitialize +// +// Description: Initialize PCI Express Device Error Handle. +// +// Input: Address - PCI Express Config MMIO of device. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SbPciExpressDeviceInitialize(IN UINT64 Address) +{ + UINT8 Dev; + UINT8 Func; + UINT8 CurrentBus; + UINT16 Buffer16; + UINT64 DevAddress; + UINT8 PciFun = (Address >> 12) & 0x07; + UINT8 CapPtr; + UINT8 Buffer8; + + CapPtr = SbFindCapPtr(Address, 0x10); + Buffer8 = READ_MEM8(Address + CapPtr + 0x08); + Buffer8 &= 0xF0; + if (gSbSetupData->PcieRootPortURE[PciFun]) + Buffer8 |= BIT03; + + if (gSbSetupData->PcieRootPortFEE[PciFun]) + Buffer8 |= BIT02; + + if (gSbSetupData->PcieRootPortNFE[PciFun]) + Buffer8 |= BIT01; + + if (gSbSetupData->PcieRootPortCEE[PciFun]) + Buffer8 |= BIT00; + + WRITE_MEM8_S3( gBootScript, \ + Address + CapPtr + 0x08, \ + Buffer8 ); + + CurrentBus = READ_MEM8((UINT32)Address + PCIBR_REG_SBUSN); + + for (Dev = 0; Dev < 32; Dev++) + { + for (Func = 0; Func < 8; Func++) + { + DevAddress = (UINT64)SB_PCIE_CFG_ADDRESS(CurrentBus, Dev, Func, 0); + + if (READ_MEM16(DevAddress) == 0xFFFF) + continue; + + SbEnablePciDevErr(DevAddress); + + Buffer16 = READ_MEM16((UINT32)SB_PCIE_CFG_ADDRESS(CurrentBus, Dev, 0, 0) + PCI_SCC); + if (Buffer16 == 0x0604) + { + DevAddress = (UINT64)SB_PCIE_CFG_ADDRESS(CurrentBus, Dev, 0, 0); + SbPciExpressDeviceInitialize(DevAddress); + } + } + } +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbInitAfterDeviceInstall +// +// Description: This callback function is called when a PCI I/O Protocol is +// installed. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbInitAfterDeviceInstall ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status; + UINTN BufferSize = 20 * sizeof(EFI_HANDLE); + EFI_HANDLE Handle; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_STD_DEVICE Pci; + UINTN i = 0; + UINTN PciSeg; + UINTN PciBus; + UINTN PciDev; + UINTN PciFun; +#if SB_PCIE_ERROR_LOG_SUPPORT + UINT64 Address = 0; + EFI_SM_ELOG_PROTOCOL *GenericElogProtocol = NULL; +#endif + + Status = pBS->LocateHandle( ByRegisterNotify, \ + NULL, \ + gSbInitNotifyReg, \ + &BufferSize, \ + &Handle ); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) return; + // + // Locate PciIo protocol installed on Handle + // + + Status = pBS->HandleProtocol( Handle, &gEfiPciIoProtocolGuid, &PciIo ); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) return; + + // Get PCI Device Bus/Device/Function Numbers + Status = PciIo->GetLocation( PciIo, &PciSeg, &PciBus, &PciDev, &PciFun ); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) return; + + TRACE((TRACE_ALWAYS, "PCI Bus, Device, function = %X, %X,%X\n", PciBus, PciDev, PciFun )); + + if (((UINT8)PciBus == SMBUS_BUS) && \ + ((UINT8)PciDev == SMBUS_DEV) && \ + ((UINT8)PciFun == SMBUS_FUN)) { + if ((READ_PCI32_SMBUS(SMBUS_REG_MBASE0_ADDR) & 0xFFFFFFF0) && \ + ((READ_PCI8_SMBUS(SMBUS_REG_PCICMD) & B_PCH_SMBUS_PCICMD_MSE) == 0)) + SET_PCI8_SMBUS(SMBUS_REG_PCICMD, B_PCH_SMBUS_PCICMD_MSE); + + if ((READ_PCI16_SMBUS(SMBUS_REG_BASE_ADDR) & 0xFFC0) && \ + ((READ_PCI8_SMBUS(SMBUS_REG_PCICMD) & B_PCH_SMBUS_PCICMD_IOSE) == 0)) + SET_PCI8_SMBUS(SMBUS_REG_PCICMD, B_PCH_SMBUS_PCICMD_IOSE); + + gEventCount -= 1; + } + //(EIP101204)>> + if (((UINT8)PciBus == HDA_BUS) && \ + ((UINT8)PciDev == HDA_DEV) && \ + ((UINT8)PciFun == HDA_FUN)) { + if(gSbSetupData->AzaliaPme){ + SET_PCI16_HDA(R_PCH_HDA_PCS, B_PCH_HDA_PCS_PMEE); + } + gEventCount -= 1; + } //<<(EIP101204) + + if (((UINT8)PciBus == SATA_BUS) && \ + ((UINT8)PciDev == SATA_DEV) && \ + ((UINT8)PciFun == SATA_FUN)) { + Status = PciIo->Pci.Read (PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci); + + //Check for Onboard Raid controller and if's it's onboard install the Guid on that Handle. + if (!EFI_ERROR (Status)) + { + if ( Pci.Header.ClassCode[1] == PCI_CL_MASS_STOR_SCL_RAID && \ + Pci.Header.VendorId == 0x8086 && \ + (Pci.Header.DeviceId == 0x282A || Pci.Header.DeviceId == 0x2822 || Pci.Header.DeviceId == 0x2826) ) { // for mobile, Desktop, WS and Server + + pBS->InstallProtocolInterface(&Handle, \ + &gOnboardRaidGuid, \ + EFI_NATIVE_INTERFACE, \ + NULL); + + // + // Install the Bus Specific Override Protocol on the Raid Controller Handle + // + Status = pBS->InstallMultipleProtocolInterfaces(&Handle, + &gEfiBusSpecificDriverOverrideProtocolGuid, + &RaidBusSpecificDriverOverride, + NULL); + + ASSERT_EFI_ERROR(Status); + } + } + gEventCount -= 1; + } + + if (((UINT8)PciBus == PCIEBRS_BUS) && \ + ((UINT8)PciDev == PCIEBRS_DEV) && \ + (((UINT8)PciFun >= PCIEBRS_FUN) || ((UINT8)PciFun >= PCIEBRS8_FUN))) { +#if SB_PCIE_ERROR_LOG_SUPPORT + Status = pBS->LocateProtocol( &gElogProtocolGuid, + NULL, + &GenericElogProtocol ); + if (!EFI_ERROR (Status)) { + gErrorLoggingFlag = TRUE; + Address = SB_PCIE_CFG_ADDRESS((UINT8)PciBus, (UINT8)PciDev, (UINT8)PciFun, 0); + SbPciExpressDeviceInitialize(Address); + } +#endif + gEventCount -= 1; + } + + // Kill the Event + if (gEventCount == 1) + pBS->CloseEvent(Event); +} + +#ifdef CSM_OPRROM_POLICY_GUID +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbCheckOprom +// +// Description: This callback function is called before/after processing all +// PCI optonal ROM. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbCheckOprom ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status; + UINTN BufferSize = sizeof(EFI_HANDLE); + EFI_HANDLE Handle; + CSM_PLATFORM_POLICY_DATA *Data; + UINTN Seg; + UINTN Bus; + UINTN Dev; + UINTN Fun; + + Status = pBS->LocateHandle( ByRegisterNotify, \ + NULL, \ + gCsmOpromReg, \ + &BufferSize, \ + &Handle ); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) return; + + // Locate CSM Platform Policy data + Status = pBS->HandleProtocol( Handle, &gCsmOpromPolicyGuid, &Data ); + + if ( EFI_ERROR(Status) ) return; + if (Data == NULL) return; + if (Data->ExecuteThisRom == FALSE) return; + if(Data->PciIo == NULL) return; + + Status = Data->PciIo->GetLocation( Data->PciIo, &Seg, &Bus, &Dev, &Fun ); + +#if SataDriver_SUPPORT +#if !defined(CsmOptOut_SUPPORT) || (CsmOptOut_SUPPORT == 0) + if ((Bus == SATA_BUS) && (Dev == SATA_DEV) && (Fun == SATA_FUN)) { + if (gSbSetupData->SataInterfaceMode == SATA_MODE_RAID) { + if (gSbSetupData->SataRaidRom != 1) + Data->ExecuteThisRom = TRUE; + else + Data->ExecuteThisRom = FALSE; + } + } +#endif +#endif + + // Close the event if needed. + // pBS->CloseEvent(Event); +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReserveSbResources +// +// Description: This function reserves system resources for SB internal +// device(s). +// +// Input: ImgHandle - Image handle +// CntrHandle - Control handle +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ReserveSbResources ( + IN EFI_HANDLE ImgHandle, + IN EFI_HANDLE CntrHandle ) +{ + EFI_STATUS Status; + +#if (CORE_VERSION >= 4600) + Status = LibAllocCspResource( gSbResTable, \ + gSbResTableCount, \ + ImgHandle, \ + CntrHandle ); +#else + DXE_SERVICES *gDxeSvcTbl; + UINTN i; + + gDxeSvcTbl = (DXE_SERVICES*)GetEfiConfigurationTable(pST,&gDxeSvcTblGuid); + if(gDxeSvcTbl == NULL) return EFI_NOT_AVAILABLE_YET; + + for (i = 0; i < gSbResTableCount; i++) { + // Remove gSbResTable existant IO to non-existant IO + if (gSbResTable[i].Attributes == 0xffffffffffffffff) { + Status = gDxeSvcTbl->RemoveIoSpace( gSbResTable[i].ResBase, \ + gSbResTable[i].ResLength ); + } else { + Status = gDxeSvcTbl->RemoveMemorySpace( gSbResTable[i].ResBase, \ + gSbResTable[i].ResLength); + } + if (EFI_ERROR(Status)) { + TRACE((-1, "RemoveSpace B=%lX, L=%X, i=%d, S=%r\n", \ + gSbResTable[i].ResBase, gSbResTable[i].ResLength, i, Status)); + ASSERT_EFI_ERROR(Status); + break; + } + } + + // Convert gSbResTable non-existant IO to existant IO + Status = AllocCspResource( gDxeSvcTbl, gSbResTable, gSbResTableCount, \ + ImgHandle, CntrHandle, TRUE ); + if(EFI_ERROR(Status)) return Status; +#endif + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AddLpcStdIoSpace +// +// Description: This function adds LPC I/O or I/O resources to the global +// coherency domain of the processor. +// +// Input: None +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS AddLpcStdIoSpace ( VOID ) +{ + EFI_STATUS Status; + DXE_SERVICES *DxeSvcTbl; + LPC_IO_STD_DECODE LpcIoStdDecode[] = { + {0x3F8, 8}, {0x2F8, 8}, {0x220, 8}, {0x228, 8},\ + {0x238, 8}, {0x2E8, 8}, {0x338, 8}, {0x3E8, 8},\ + {0x378, 8}, {0x778, 8}, {0x278, 8}, {0x678, 8},\ + {0x3BC, 4}, {0x7BC, 4}, {0x3F0, 6}, {0x3F7, 1},\ + {0x370, 6}, {0x377, 1}, {0x200, 8}, {0x208, 8},\ + {0x060, 1}, {0x064, 1}, {0x062, 1}, {0x066, 1},\ + {0x02E, 1}, {0x02F, 1}, {0x04E, 1}, {0x04F, 1} + }; + UINT8 TableLength = sizeof(LpcIoStdDecode) / sizeof(LPC_IO_STD_DECODE); + UINT8 i; + UINT8 j; + UINT8 AddressMask; + UINT16 GenDecodeBase; + UINT16 GenDecodeLength = 0; + + DxeSvcTbl = (DXE_SERVICES*)GetEfiConfigurationTable(pST,&gDxeSvcTblGuid); + if(DxeSvcTbl == NULL) return EFI_NOT_AVAILABLE_YET; + + for (i = 0; i < TableLength; i++) { + + Status = DxeSvcTbl->AddIoSpace ( EfiGcdIoTypeIo,\ + LpcIoStdDecode[i].Address, \ + LpcIoStdDecode[i].Length ); + } + + for (i = 0; i < 4; i++) { + GenDecodeBase = READ_PCI16_SB(SB_REG_GEN1_DEC + i * 4) & 0xFFFC; + AddressMask = READ_PCI8_SB((SB_REG_GEN1_DEC + 2) + i * 4) & 0x00FC; + + if (GenDecodeBase == 0) continue; + + for (j = 2; j < 8; j++) { + if (AddressMask & (BIT00 << j)) GenDecodeLength += (BIT00 << j); + } + GenDecodeLength += 4; + + Status = DxeSvcTbl->AddIoSpace ( EfiGcdIoTypeIo,\ + GenDecodeBase, \ + GenDecodeLength ); + } + + return Status; +} + +//********************************************************************** + +BOOT_SCRIPT_SB_PCI_REG_SAVE gPciRegistersSave[] = { + SB_REG(SB_REG_PIRQ_A) , EfiBootScriptWidthUint32, 0xffffffff, // 0x60 The register will be filled in later. + SB_REG(SB_REG_PIRQ_E) , EfiBootScriptWidthUint32, 0xffffffff, // 0x68 The register will be filled in later. + SB_REG(SB_REG_LPC_IO_DEC) , EfiBootScriptWidthUint16, 0xffff, // 0x80 + SB_REG(SB_REG_LPC_EN) , EfiBootScriptWidthUint16, 0xffff, // 0x82 + SB_REG(SB_REG_GEN1_DEC) , EfiBootScriptWidthUint32, 0xffffffff, // 0x84 + SB_REG(SB_REG_GEN2_DEC) , EfiBootScriptWidthUint32, 0xffffffff, // 0x88 + SB_REG(SB_REG_GEN3_DEC) , EfiBootScriptWidthUint32, 0xffffffff, // 0x8C + SB_REG(SB_REG_GEN4_DEC) , EfiBootScriptWidthUint32, 0xffffffff, // 0x90 + SB_REG(SB_REG_GEN_PMCON_1) , EfiBootScriptWidthUint16, 0xffffffff, // 0xA0 + SB_REG(SB_REG_BIOS_CNTL) , EfiBootScriptWidthUint8, 0xffffffff, // 0xDC, + + PCIBR_REG(PCIBR_REG_PBUSN) , EfiBootScriptWidthUint32, 0xffffffff, // 0x18 + PCIBR_REG(PCIBR_REG_IOBASE) , EfiBootScriptWidthUint16, 0xffffffff, // 0x1C + PCIBR_REG(PCIBR_REG_MBASE) , EfiBootScriptWidthUint32, 0xffffffff, // 0x20 + PCIBR_REG(PCIBR_REG_PMBASE) , EfiBootScriptWidthUint32, 0xffffffff, // 0x24 + PCIBR_REG(PCIBR_REG_PMBASEU) , EfiBootScriptWidthUint32, 0xffffffff, // 0x28 + PCIBR_REG(PCIBR_REG_INTR_LN) , EfiBootScriptWidthUint8, 0xffffffff, // 0x3C + PCIBR_REG(PCIBR_REG_SPDH) , EfiBootScriptWidthUint16, 0xffffffff, // 0x40 + PCIBR_REG(PCIBR_REG_DTC) , EfiBootScriptWidthUint32, 0xffffffff, // 0x44 + PCIBR_REG(PCIBR_REG_BPC) , EfiBootScriptWidthUint32, 0xffffffff, // 0x4C + PCIBR_REG(PCIBR_REG_PCICMD) , EfiBootScriptWidthUint8, 0xffffffff, // 0x04 + + HDA_REG(R_PCH_HDA_HDBARL) , EfiBootScriptWidthUint32, 0xffffffff, // 0x10 + HDA_REG(R_PCH_HDA_HDBARU) , EfiBootScriptWidthUint32, 0xffffffff, // 0x14 + + SMBUS_REG(SMBUS_REG_MBASE0_ADDR), EfiBootScriptWidthUint32, 0xffffffff, // 0x10 + SMBUS_REG(SMBUS_REG_MBASE1_ADDR), EfiBootScriptWidthUint32, 0xffffffff, // 0x14 + SMBUS_REG(SMBUS_REG_BASE_ADDR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x20 + SMBUS_REG(SMBUS_REG_INTR_LN) , EfiBootScriptWidthUint16, 0xffffffff, // 0x3C + SMBUS_REG(SMBUS_REG_PCICMD) , EfiBootScriptWidthUint16, 0xffffffff, // 0x04 + + THERMAL_REG(THERMAL_REG_TBAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x10 Thermal device is not getting restored, don't know why + THERMAL_REG(THERMAL_REG_PCICMD), EfiBootScriptWidthUint16, 0xffffffff, // 0x04 Thermal device is not getting restored, don't know why + THERMAL_REG(THERMAL_REG_INTR_LN), EfiBootScriptWidthUint32, 0xffffffff, // 0x3C Thermal device is not getting restored, don't know why +}; + +BOOT_SCRIPT_SB_PCI_REG_SAVE gSata1RegistersSave[] = { + SATA_REG(SATA_REG_MAP) , EfiBootScriptWidthUint8, 0xffffffff, // 0x90 + SATA_REG(SATA_REG_PCIPI) , EfiBootScriptWidthUint8, 0xffffffff, // 0x09 + SATA_REG(SATA_REG_INTR_LN) , EfiBootScriptWidthUint8, 0xffffffff, // 0x3c + SATA_REG(SATA_REG_IDETIM) , EfiBootScriptWidthUint32, 0xffffffff, // 0x40 + SATA_REG(SATA_REG_SIDETIM) , EfiBootScriptWidthUint8, 0xffffffff, // 0x44 + SATA_REG(SATA_REG_SDMACTL) , EfiBootScriptWidthUint8, 0xffffffff, // 0x48 + SATA_REG(SATA_REG_SDMATIM) , EfiBootScriptWidthUint16, 0xffffffff, // 0x4a + SATA_REG(SATA_REG_IDE_CONFIG), EfiBootScriptWidthUint32, 0xffffffff, // 0x54 + SATA_REG(SATA_REG_PMCS) , EfiBootScriptWidthUint16, 0xffffffff, // 0x74 + SATA_REG(SATA_REG_PCS) , EfiBootScriptWidthUint16, 0xffffffff, // 0x92 + SATA_REG(SATA_REG_PCMD_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x10 + SATA_REG(SATA_REG_PCNL_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x14 + SATA_REG(SATA_REG_SCMD_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x18 + SATA_REG(SATA_REG_SCNL_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x1c + SATA_REG(SATA_REG_BM_BASE) , EfiBootScriptWidthUint32, 0xffffffff, // 0x20 + SATA_REG(SATA_REG_ABAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x24 + SATA_REG(SATA_REG_PCICMD) , EfiBootScriptWidthUint8, 0xffffffff, // 0x04 +}; + +BOOT_SCRIPT_SB_PCI_REG_SAVE gSata2RegistersSave[] = { + SATA2_REG(SATA_REG_MAP) , EfiBootScriptWidthUint8, 0xffffffff, // 0x90 + SATA2_REG(SATA_REG_PCIPI) , EfiBootScriptWidthUint8, 0xffffffff, // 0x09 + SATA2_REG(SATA_REG_INTR_LN) , EfiBootScriptWidthUint8, 0xffffffff, // 0x3c + SATA2_REG(SATA_REG_IDETIM) , EfiBootScriptWidthUint32, 0xffffffff, // 0x40 + SATA2_REG(SATA_REG_SIDETIM) , EfiBootScriptWidthUint8, 0xffffffff, // 0x44 + SATA2_REG(SATA_REG_SDMACTL) , EfiBootScriptWidthUint8, 0xffffffff, // 0x48 + SATA2_REG(SATA_REG_SDMATIM) , EfiBootScriptWidthUint16, 0xffffffff, // 0x4a + SATA2_REG(SATA_REG_IDE_CONFIG), EfiBootScriptWidthUint32, 0xffffffff, // 0x54 + SATA2_REG(SATA_REG_PMCS) , EfiBootScriptWidthUint16, 0xffffffff, // 0x74 + SATA2_REG(SATA_REG_PCS) , EfiBootScriptWidthUint16, 0xffffffff, // 0x92 + SATA2_REG(SATA_REG_PCMD_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x10 + SATA2_REG(SATA_REG_PCNL_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x14 + SATA2_REG(SATA_REG_SCMD_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x18 + SATA2_REG(SATA_REG_SCNL_BAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x1c + SATA2_REG(SATA_REG_BM_BASE) , EfiBootScriptWidthUint32, 0xffffffff, // 0x20 + SATA2_REG(SATA_REG_ABAR) , EfiBootScriptWidthUint32, 0xffffffff, // 0x24 + SATA2_REG(SATA_REG_PCICMD) , EfiBootScriptWidthUint8, 0xffffffff, // 0x04 +}; + +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 +VOID CheckDisableUsbControllers(VOID) +{ + UINT32 FunctionDisable; + EFI_STATUS Status; + EFI_GUID EfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE; + UINTN BootOrderSize = 0; + UINT16 *BootOrder = NULL; + PCH_SERIES PchSeries = GetPchSeries(); + + Status = pBS->LocateProtocol( &gEfiUsbProtocolGuid, + NULL, + &gUsbProtocol ); + if (EFI_ERROR(Status)) return; + + if (gDisableAllUsbControllers) { + + Status = pRS->GetVariable( L"BootOrder", \ + &EfiGlobalVariableGuid, \ + NULL, \ + &BootOrderSize, \ + &BootOrder ); + if (Status == EFI_NOT_FOUND) return; + + // Shutdown legacy + gUsbProtocol->UsbRtShutDownLegacy(); + + WRITE_PCI16_EHCI(EHCI_REG_PCICMD, 0); + if (PchSeries != PchLp) { + WRITE_PCI16_EHCI2(EHCI_REG_PCICMD, 0); + } + WRITE_PCI16(XHCI_BUS, XHCI_DEV, XHCI_FUN, XHCI_REG_PCICMD, 0); + + FunctionDisable = (READ_MEM32_RCRB(RCRB_MMIO_FD) | BIT13 | BIT15 | BIT27); + WRITE_MEM32_RCRB_S3(gBootScript, RCRB_MMIO_FD, FunctionDisable); + }/* else if ((gSbSetupData->PchUsb20[0] == 0) && (gSbSetupData->PchUsb20[1] == 0)) { + WRITE_PCI16_EHCI(EHCI_REG_PCICMD, 0); + if (PchSeries != PchLp) { + WRITE_PCI16_EHCI2(EHCI_REG_PCICMD, 0); + } + FunctionDisable = (READ_MEM32_RCRB(RCRB_MMIO_FD) | BIT13 | BIT15); + WRITE_MEM32_RCRB_S3(gBootScript, RCRB_MMIO_FD, FunctionDisable); + }*/ +} +#endif + //(EIP124410)>> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: UpdateSmbios136Table +// +// Description: Build and fill SmBios type 0x88 for CRID. +// +// Input: EFI_EVENT - Event, +// VOID - *Context +// +// Output: EFI_STATUS - EFI_SUCCESS. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +UpdateSmbios136Table( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_MISC_OEM_TYPE_0x88 Data88; + DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy; + + Status = pBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, &gSmbiosProtocol); + if (EFI_ERROR(Status)) return; + + //Clear all data + pBS->SetMem (&Data88, sizeof(EFI_MISC_OEM_TYPE_0x88), 0); + + Data88.Header.Type = 0x88; + Data88.Header.Length = 6; + Data88.Header.Handle = 0; + + Status = pBS->LocateProtocol ( &gDxePchPlatformPolicyProtocolGuid, \ + NULL, \ + &PchPlatformPolicy); + if (!EFI_ERROR (Status)) { + if (PchPlatformPolicy->DeviceEnabling->Crid == 1){ + Data88.OemInfo = 0x5a5a; + } + } + + Status = gSmbiosProtocol->SmbiosAddStructure((UINT8 *)&Data88, sizeof(EFI_MISC_OEM_TYPE_0x88)); + + pBS->CloseEvent(Event); +} + //(EIP124410)<< +#if defined CSM_SUPPORT && CSM_SUPPORT == 1 // [EIP134850] >> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSataRegSaveRestore +// +// Description: This callback will be called before and after installing legacy OpROM +// +// Input: +// IN EFI_EVENT Event - Callback event +// IN VOID *Context - pointer to calling context +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SBSataRegSaveRestore( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + UINTN Size = sizeof(EFI_HANDLE); + UINTN Seg, Bus, Dev, Fun; + UINT32 ABar, RegVal; + UINT8 Index = 0; + CSM_PLATFORM_POLICY_DATA *OpRomStartEndProtocol; + EFI_PCI_IO_PROTOCOL *PciIo; + PCH_SERIES PchSeries = GetPchSeries(); + + TRACE((TRACE_ALWAYS, "SBSataRegSaveRestore() !!!\n")); + Status = pBS->LocateHandle(ByRegisterNotify, NULL, SataOpRomRegistration, &Size, &Handle); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) return; + + Status = pBS->HandleProtocol(Handle, &OpRomStartEndProtocolGuid, &OpRomStartEndProtocol); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) return; + + if(OpRomStartEndProtocol != NULL) { + //pre-process OpROM callback + PciIo = OpRomStartEndProtocol->PciIo; + + if (PciIo == NULL){ + // this OpROM is not Intel SATA RAID OpROM + IsSataOpROM = 0; + return; + } + + PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Fun); + TRACE((TRACE_ALWAYS, "OpRom Location: Seg:%x, Bus:%x, Dev:%x, Fun:%x\n", Seg, Bus, Dev, Fun)); + if((Bus == SATA_BUS) && (Dev == SATA_DEV) && (Fun == SATA_FUN)){ + // This OpROM is Intel SATA RAID OpROM + TRACE((TRACE_ALWAYS, "Before execute SATA OpROM... save sata regs...\n")); + if (SaveSataReg != 0) return; + SaveSataReg = 1; + IsSataOpROM = 1; + DLAE = 0; + // Save PxCMD bit 25 of each Sata ports + ABar = READ_MMIO32(SATA_PCIE_REG(SATA_REG_ABAR)); + TRACE((TRACE_ALWAYS, "ABar = %x Index = %x MaxPortNumber = %x\n", ABar, Index, GetPchMaxSataPortNum())); + while(Index < GetPchMaxSataPortNum()){ + RegVal = READ_MMIO32((UINT64)(ABar + 0x118 + (0x80 * Index))); // R_PCH_SATA_AHCI_P0CMD + TRACE((TRACE_ALWAYS, "Index = %x, RegVal = %x\n", Index, RegVal)); + if ((RegVal != 0xFFFFFFFF) && (RegVal & BIT24)){ + DLAE |= (UINT8)((RegVal & BIT25) >> (25 - Index)); + } + Index++; + } + TRACE((TRACE_ALWAYS, "DLAE = %x\n", DLAE)); + } else { + // this OpROM is not Intel SATA RAID OpROM + IsSataOpROM = 0; + } + } else { + //post-process OpROM callback + if ((SaveSataReg == 1) && (IsSataOpROM == 1)){ + TRACE((TRACE_ALWAYS, "After execute SATA OpROM... restore sata regs...\n")); + // Restore PxCMD bit 25 of each Sata ports + ABar = READ_MMIO32(SATA_PCIE_REG(SATA_REG_ABAR)); + while(Index < GetPchMaxSataPortNum()){ + RegVal = READ_MMIO32((UINT64)(ABar + 0x118 + (0x80 * Index))); // R_PCH_SATA_AHCI_P0CMD + if(RegVal != 0xFFFFFFFF){ + if(DLAE & (BIT0 << Index)){ + RegVal |= BIT25; + WRITE_MMIO32((UINT64)(ABar + 0x118 + (0x80 * Index)), RegVal); + TRACE((TRACE_ALWAYS, "Sata Port %x restore done\n", Index)); + } + } + Index++; + } + } + } +} +#endif // [EIP134850] << + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSbRegsBeforeBoot +// +// Description: This function can initialize any SB registers before DXE +// stage exiting. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitSbRegsBeforeBoot ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + UINT32 i, j; + UINT8 *SbRcba = (UINT8*)(UINTN)SB_RCRB_BASE_ADDRESS; + UINT32 Data32; + UINT32 PortImplemented = 0x0f; + UINT32 GlobalPchControl; + UINT64 AHCIBar = 0; +// UINT16 Offset; //[EIP124245] + UINT8 Data8; + UINT32 Index; + EFI_ACPI_SUPPORT_PROTOCOL *As; + FACP_20 *Table = NULL; + EFI_ACPI_TABLE_VERSION Version; + UINTN Handle; + ACPI_HDR *DsdtPtr = NULL; + EFI_STATUS Status; + PCH_SERIES PchSeries = GetPchSeries(); + + for (i = 0; i < sizeof(gPciRegistersSave)/ sizeof(BOOT_SCRIPT_SB_PCI_REG_SAVE); ++i) { + gPciRootBridgeIo->Pci.Read( \ + gPciRootBridgeIo, \ + gPciRegistersSave[i].Width, \ + gPciRegistersSave[i].Address, \ + 1, \ + &Data32); + + Data32 &= gPciRegistersSave[i].Mask; + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( \ + gBootScript, \ + gPciRegistersSave[i].Width, \ + gPciRegistersSave[i].Address, \ + 1, \ + &Data32); + } + if (PchSeries != PchLp) { + gPciRootBridgeIo->Pci.Read( \ + gPciRootBridgeIo, \ + EfiBootScriptWidthUint32, \ + SB_REG(SB_REG_GPI_ROUT) , \ + 1, \ + &Data32); + + Data32 &= 0xffffffff; + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( \ + gBootScript, \ + EfiBootScriptWidthUint32, \ + SB_REG(SB_REG_GPI_ROUT) , \ + 1, \ + &Data32); + }else{ + Data32 = IoRead32(GPIO_BASE_ADDRESS + GP_IOREG_GPI_ROUT2); + Data32 &= 0xffffffff; + BOOT_SCRIPT_S3_IO_WRITE_MACRO( \ + gBootScript, \ + EfiBootScriptWidthUint32, \ + GPIO_BASE_ADDRESS + GP_IOREG_GPI_ROUT2, \ + 1, \ + &Data32); + } + +#if defined (HOST_WLAN_PP_EN) && HOST_WLAN_PP_EN == 1 + + Data32 = READ_MEM32_RCRB(ICH_RCRB_PMCFG) | BIT04; // 0x3318 + WRITE_MEM32_RCRB (ICH_RCRB_PMCFG , Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO( \ + gBootScript, \ + EfiBootScriptWidthUint32, \ + SbRcba + ICH_RCRB_PMCFG, \ + 1, \ + &Data32); + +#endif + + Data32 = READ_MEM32_RCRB(RCRB_MMIO_FD); // 0x3418 + BOOT_SCRIPT_S3_MEM_WRITE_MACRO( \ + gBootScript, \ + EfiBootScriptWidthUint32, \ + SbRcba + R_PCH_RCRB_FUNC_DIS, \ + 1, \ + &Data32); + + // Trap Configuration + for (i = RCRB_MMIO_IO_TRAP_0; i < (RCRB_MMIO_IO_TRAP_3 + 8); i += 4) { + Data32 = *(UINT32 *)(SbRcba + i); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO( \ + gBootScript, \ + EfiBootScriptWidthUint32, \ + SbRcba + i, \ + 1, \ + &Data32); + } + + //RootPort register save + for(i = 0; i <= 7; i++) + { + gPciRootBridgeIo->Pci.Read ( + gPciRootBridgeIo, \ + EfiPciWidthUint32, \ + SB_PCI_CFG_ADDRESS(PCIEBRS_BUS, PCIEBRS_DEV, i, 0x00), \ + 1, \ + &Data32); + if(Data32 != 0xffffffff) + { + for(j = 0x18; j < 0x34; j += 4) + { + gPciRootBridgeIo->Pci.Read ( \ + gPciRootBridgeIo, \ + EfiPciWidthUint32, \ + SB_PCI_CFG_ADDRESS(PCIEBRS_BUS, PCIEBRS_DEV, i, j), \ + 1, \ + &Data32); + + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( \ + gBootScript, \ + EfiBootScriptWidthUint32, \ + SB_PCI_CFG_ADDRESS(PCIEBRS_BUS, PCIEBRS_DEV, i, j), \ + 1, \ + &Data32); + } + } + } + //End + +//Save Onboard LAN BAR- Efi aware Vista GBE bar is not restored by OS if network driver is not installed. + + gPciRootBridgeIo->Pci.Read ( \ + gPciRootBridgeIo, \ + EfiPciWidthUint32, \ + LAN_REG(0x00), \ + 1, \ + &Data32); + if(Data32 != 0xffffffff) + { + for(j = 0x10; j < 0x1B; j += 4) + { + gPciRootBridgeIo->Pci.Read ( \ + gPciRootBridgeIo, \ + EfiPciWidthUint32, \ + LAN_REG(j), \ + 1, \ + &Data32); + + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( + gBootScript, \ + EfiBootScriptWidthUint32, \ + LAN_REG(j), \ + 1, \ + &Data32); + } + } + +//Save Sata and ABAR S3 reg. + gPciRootBridgeIo->Pci.Read( \ + gPciRootBridgeIo, \ + EfiBootScriptWidthUint32, \ + SATA_REG(PCI_VID), \ + 1, \ + &Data32); + if (Data32 != 0xffffffff) { + for (i = 0; i < sizeof(gSata1RegistersSave)/ sizeof(BOOT_SCRIPT_SB_PCI_REG_SAVE); ++i) { + gPciRootBridgeIo->Pci.Read( \ + gPciRootBridgeIo, \ + gSata1RegistersSave[i].Width, \ + gSata1RegistersSave[i].Address, \ + 1, \ + &Data32); + Data32 &= gSata1RegistersSave[i].Mask; + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( + gBootScript, \ + gSata1RegistersSave[i].Width, \ + gSata1RegistersSave[i].Address, \ + 1, \ + &Data32); + } + + //If SATA is in AHCI or RAID Mode Save/Restore additional registers. + gPciRootBridgeIo->Pci.Read(gPciRootBridgeIo, EfiBootScriptWidthUint8, SATA_REG(SATA_REG_MAP), 1, &Data8); // 0x90 + if ( Data8 & 0xC0 ) { // AHCI or RAID + + gPciRootBridgeIo->Pci.Read(gPciRootBridgeIo, EfiBootScriptWidthUint32, SATA_REG(SATA_REG_ABAR), 1, &(UINT32)AHCIBar); // 0x24 + AHCIBar &= 0xFFFFFFF0; + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + 0x04, 1, &GlobalPchControl); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + 0x04, 1, &GlobalPchControl); + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + 0x0c, 1, &PortImplemented); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + 0xc, 1, &PortImplemented); + + + //[EIP124245]>> +/* for (i = 0, Offset = 0x100; i < 6 ; i++, Offset += 0x80) { + if ( PortImplemented & (BIT00 << i) ) { + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + Offset, 1, &Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + Offset, 1, &Data32); + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + Offset + 0x04, 1, &Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + Offset + 0x04, 1, &Data32); + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + Offset + 0x04, 1, &Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + Offset + 0x04, 1, &Data32); + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + Offset + 0x08, 1, &Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + Offset + 0x08, 1, &Data32); + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + Offset + 0x0c, 1, &Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + Offset + 0x0c, 1, &Data32); + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + Offset + 0x18, 1, &Data32); + Data32 &= 0xFFFFFFEE; //Make sure Clear the Start and FIS Receive Enable bit + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + Offset + 0x18, 1, &Data32); + + gPciRootBridgeIo->Mem.Read(gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar + Offset + 0x2c, 1, &Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar + Offset + 0x2c, 1, &Data32); + } + }*/ //[EIP124245]<< + + gPciRootBridgeIo->Mem.Read (gPciRootBridgeIo, EfiPciIoWidthUint32, AHCIBar, 1, &Data32); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint32, AHCIBar,1,&Data32); + } + } // if SATA 1 = ffffffff + //(EIP126943)>> + //Controller in IDE Mode. Save/Restore Secondary SataController (B0:D1F:F5) Registers also. + + gPciRootBridgeIo->Pci.Read( + gPciRootBridgeIo, + EfiBootScriptWidthUint32, + SATA2_REG(0), + 1, + &Data32 + ); + if (Data32 != 0xFFFFFFFF) { + for (i = 0; i < sizeof(gSata2RegistersSave)/ sizeof(BOOT_SCRIPT_SB_PCI_REG_SAVE); ++i) { + gPciRootBridgeIo->Pci.Read( + gPciRootBridgeIo, + gSata2RegistersSave[i].Width, + gSata2RegistersSave[i].Address, + 1, + &Data32 + ); + Data32 &= gSata2RegistersSave[i].Mask; + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( + gBootScript, + gSata2RegistersSave[i].Width, + gSata2RegistersSave[i].Address, + 1, + &Data32 + ); + } + }// if SATA 2 = ffffffff //(EIP126943)<< + + + if (gErrorLoggingFlag == TRUE) { + Data8 = SW_SMI_SB_EL_S3; + WRITE_IO8(SW_SMI_IO_ADDRESS, Data8 ); + BOOT_SCRIPT_S3_IO_WRITE_MACRO( gBootScript, \ + EfiBootScriptWidthUint8, \ + SW_SMI_IO_ADDRESS, \ + 1, \ + &Data8); + } + +#if SB_SWSMI_WRITE_TO_BOOTSCRIPT + SBSwSmiWriteToBootScript(gBootScript); +#endif + +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 + CheckDisableUsbControllers(); +#endif + //(EIP127410)>> + if (PchSeries == PchLp) { + WRITE_PCI16_SB(SB_REG_GEN_PMCON_1, (READ_PCI16_SB(SB_REG_GEN_PMCON_1) | 0x800)); + TRACE((TRACE_ALWAYS, "SB_REG_GEN_PMCON_1= %x\n", READ_PCI16_SB(SB_REG_GEN_PMCON_1))); + } + + Status = pBS->LocateProtocol(&gEfiAcpiSupportGuid, NULL, &As); + + // Find DSDT ACPI Table + for (Index = 0; Index < ACPI_RSDT_TABLE_NUM; Index++) { + Status = As->GetAcpiTable(As, Index, &Table, &Version, &Handle); + if (EFI_ERROR(Status)) break;//no more tables left + + if ((Table->Header.Signature == FACP_SIG) && (DsdtPtr == NULL)) { + DsdtPtr = (ACPI_HDR*)Table->DSDT; + TRACE((-1, "SBDxe: Found DSDT Table at 0x%08X\n", DsdtPtr)); + if (PchSeries == PchLp) { + ULTDsdtTableUpdate (DsdtPtr); + } else { + DsdtTableUpdate (DsdtPtr); + } + break; + } + } //(EIP127410)<< + + // + //Kill the Event + // + pBS->CloseEvent(Event); + +} + +#if defined AMIUSB_SUPPORT && AMIUSB_SUPPORT == 1 +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbUsbProtocolCallback +// +// Description: This callback function is called after USB Protocol is +// installed. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbUsbProtocolCallback ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status = EFI_SUCCESS; + USB_SKIP_LIST SkipMassTable[] = { {1, 0, 0xff, 0, 0, 0x8}, + {0, 0, 0, 0, 0, 0 } + }; + + if (gDisableAllUsbControllers) + { + Status = pBS->LocateProtocol( &gEfiUsbProtocolGuid, + NULL, + &gUsbProtocol ); + if (EFI_ERROR(Status)) return; + gUsbProtocol->UsbCopySkipTable(SkipMassTable, sizeof(SkipMassTable)/sizeof (USB_SKIP_LIST)); + } + + pBS->CloseEvent(Event); +} +#endif + +#if SecureMod_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BiosLockEnableCallback +// +// Description: This callback function is called after AMI_EVENT_FLASH_WRITE_LOCK is +// installed. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID BiosLockEnableCallback ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status; + DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy; + + Status = pBS->LocateProtocol ( &gDxePchPlatformPolicyProtocolGuid, \ + NULL, \ + &PchPlatformPolicy); + if (!EFI_ERROR (Status)) { + if ((gSbSetupData->BiosLock == PCH_DEVICE_ENABLE) && + (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != 0)) { + IoWrite32 (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress, PCH_BWP_SIGNATURE); + } + } + + pBS->CloseEvent(Event); +} +#endif + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure : LocatePublishIdeSataAcpiTables +// +// Description : This function will locate and publish the IDE.asl or SATA.asl +// depending upon the mode IDE/AHCI. +// +// Input :None +// +// Output :None +// +//<AMI_PHDR_END> +//********************************************************************** +VOID LocatePublishIdeSataAcpiTables(VOID) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN k; + EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol = NULL; + INTN Instance; + EFI_ACPI_TABLE_VERSION Version; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINTN AcpiTableHandle; + ACPI_HDR *AcpiTable = NULL; + ACPI_HDR *TableHeader; + UINT8 Data; + EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport =0; + BOOLEAN AhciFlag = FALSE; + + //Locate the PcirootbridgeIoprotocol + Status = pBS->LocateProtocol(&gEfiPciRootBridgeIoProtocolGuid, NULL, &gPciRootBridgeIo); + ASSERT_EFI_ERROR(Status); + + //Read the Sub class code register to check for ide/Ahci mode. + Data = READ_PCI8_SATA(R_PCH_SATA_SUB_CLASS_CODE); + + if (Data == V_PCH_SATA_SUB_CLASS_CODE_AHCI || \ + Data == V_PCH_SATA_SUB_CLASS_CODE_RAID) + AhciFlag = TRUE; + // + // Locate protocol. + // There is little chance we can't find an FV protocol + // + Status = pBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + ASSERT_EFI_ERROR (Status); + + // + // Looking for FV with ACPI storage file + // + for (k = 0; k < NumberOfHandles; k++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = pBS->HandleProtocol ( + HandleBuffer[k], + &gEfiFirmwareVolumeProtocolGuid, + &FwVol + ); + ASSERT_EFI_ERROR (Status); + + // + // See if it has the ACPI storage file + // + Size = 0; + FvStatus = 0; + Status = FwVol->ReadFile ( + FwVol, + &IdeSataAcpiTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + // + // If we found it, then we are done + // + if (Status == EFI_SUCCESS) { + break; + } + } + + // + // Our exit status is determined by the success of the previous operations + // If the protocol was found, Instance already points to it. + // + // + // Free any allocated buffers + // + pBS->FreePool (HandleBuffer); + + // + // Sanity check that we found our data file + // + ASSERT (FwVol); + + // + // By default, a table belongs in all ACPI table versions published. + // + Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0; + + // + // Find the AcpiSupport protocol + // + Status = LocateSBSATAIDESupportProtocol ( + &gEfiAcpiSupportGuid, + &AcpiSupport, + FALSE + ); + ASSERT_EFI_ERROR (Status); + // + // Read tables from the storage file. + // + Instance = 0; + CurrentTable = NULL; + + while (Status == EFI_SUCCESS) { + Status = FwVol->ReadSection ( + FwVol, + &IdeSataAcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + // + // Check the table ID to modify the table + // + TableHeader = (ACPI_HDR *) CurrentTable; + + if(AhciFlag) { + //AHCI mode is Enabled + //Locate and publish ACPItable for SATA.asl + + if (MemCmp (&TableHeader->OemTblId, "SataTabl", 8) == 0) { + AcpiTable = (ACPI_HDR*) CurrentTable; + } + } else { + //AHCI mode is Disabled + //Locate and publish ACPItable for Ide.asl + if (MemCmp (&TableHeader->OemTblId, "IdeTable", 8) == 0) { + AcpiTable = (ACPI_HDR*) CurrentTable; + } + } + // + // Increment the instance + // + Instance++; + CurrentTable = NULL; + } + } + + // + // Update the SSDT table in the ACPI tables. + // + AcpiTableHandle = 0; + + Status = AcpiSupport->SetAcpiTable (AcpiSupport, AcpiTable, TRUE, Version, &AcpiTableHandle); + ASSERT_EFI_ERROR (Status); + pBS->FreePool (AcpiTable); + + // + // Publish all ACPI Tables + // + Status = AcpiSupport->PublishTables (AcpiSupport, Version); + ASSERT_EFI_ERROR (Status); + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: LocateSBSATAIDESupportProtocol +// +// Description: Locate the first instance of a protocol. If the protocol requested is an +// FV protocol, then it will return the first FV that contains the ACPI table +// storage file. +// +// Input: Protocol The protocol to find. +// Instance Return pointer to the first instance of the protocol +// Type TRUE if the desired protocol is a FV protocol +// +// Output: EFI_SUCCESS The function completed successfully. +// EFI_NOT_FOUND The protocol could not be located. +// EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +LocateSBSATAIDESupportProtocol ( + IN EFI_GUID *Protocol, + OUT VOID **Instance, + IN BOOLEAN Type + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN i; + + FvStatus = 0; + // + // Locate protocol. + // + Status = pBS->LocateHandleBuffer ( + ByProtocol, + Protocol, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + // + // Defined errors at this time are not found and out of resources. + // + return Status; + } + // + // Looking for FV with ACPI storage file + // + for (i = 0; i < NumberOfHandles; i++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = pBS->HandleProtocol ( + HandleBuffer[i], + Protocol, + Instance + ); + ASSERT (!EFI_ERROR (Status)); + + if (!Type) { + // + // Not looking for the FV protocol, so find the first instance of the + // protocol. There should not be any errors because our handle buffer + // should always contain at least one or LocateHandleBuffer would have + // returned not found. + // + break; + } + + // + // See if it has the ACPI storage file + // + Status = ((EFI_FIRMWARE_VOLUME_PROTOCOL *) (*Instance))->ReadFile ( + *Instance, + &IdeSataAcpiTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + // + // If we found it, then we are done + // + if (Status == EFI_SUCCESS) { + break; + } + } + + // + // Our exit status is determined by the success of the previous operations + // If the protocol was found, Instance already points to it. + // + + // + // Free any allocated buffers + // + pBS->FreePool (HandleBuffer); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSbRegsBeforeLagecyBoot +// +// Description: This function can initialize any SB registers before legacy +// OS booting. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitSbRegsBeforeLagecyBoot ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + pBS->CloseEvent(Event); +} + +#if defined OEM_USB_PER_PORT_DISABLE_SUPPORT && OEM_USB_PER_PORT_DISABLE_SUPPORT == 1 +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DisableRmhDownPort +// +// Description: +// +// Input: EFI_USB_IO_PROTOCOL - *UsbIo +// UINT8 - Port +// +// Output: EFI_STATUS Status +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DisableRmhDownPort ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN UINT8 Port +) +{ + EFI_STATUS Status; + EFI_USB_DEVICE_REQUEST DevReq; + UINT32 Timeout; + UINT32 UsbStatus; + + DevReq.RequestType = 0x23; + DevReq.Request = 0x01; + DevReq.Value = 0x1; + DevReq.Index = Port; + DevReq.Length = 0; + Timeout = 3000; + Status = UsbIo->UsbControlTransfer(UsbIo, &DevReq, + EfiUsbNoData, Timeout, NULL, 0, &UsbStatus); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: USBPrePortDisableCallback +// +// Description: This function can disable USB preport before OS booting. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID USBPrePortDisableCallback ( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + EFI_GUID EfiUsbIoProtocolGuid = EFI_USB_IO_PROTOCOL_GUID; + UINTN HandleCount = 0; + PCH_SERIES PchSeries = GetPchSeries(); + EFI_USB_IO_PROTOCOL *UsbIo; + EFI_USB_IO_PROTOCOL *Ehci1RmhUsbIo = NULL; + EFI_USB_IO_PROTOCOL *Ehci2RmhUsbIo = NULL; + EFI_USB_DEVICE_DESCRIPTOR DevDesc = {0}; + UINT32 Index; + UINT8 EHCIPort1 = 0; + UINT8 EHCIPort2 = 0; + UINT8 XhciPortDisableFlage[21]; + UINT32 XhciUsb2Pdo = 0; + UINT32 XhciUsb3Pdo = 0; + UINT32 XhciIndex; + UINT16 RegData16; + UINT32 XhciUsb2InternalPortNumberLookUpTable[] = {0,1,2,3,8,9,12,13,4,5,6,7,10,11,12,13}; + static BOOLEAN USBPrePortDisableDone = FALSE; + + /// + /// Table: USB2 Pins Mapping between XHCI/EHCI Port + /// ------------------------------------------- + /// | USB2 Pin | EHCI Port | XHCI Port | + /// |--------------+----------------+-----------| + /// | USB[P,N][0] | EHCI 1 Port 0 | Port 0 | + /// | USB[P,N][1] | EHCI 1 Port 1 | Port 1 | + /// | USB[P,N][2] | EHCI 1 Port 2 | Port 2 | + /// | USB[P,N][3] | EHCI 1 Port 3 | Port 3 | + /// | USB[P,N][4] | EHCI 1 Port 4 | Port 8 | + /// | USB[P,N][5] | EHCI 1 Port 5 | Port 9 | + /// | USB[P,N][6] | EHCI 1 Port 6 | Port 12 | + /// | USB[P,N][7] | EHCI 1 Port 7 | Port 13 | + /// | USB[P,N][8] | EHCI 2 Port 8 | Port 4 | + /// | USB[P,N][9] | EHCI 2 Port 9 | Port 5 | + /// | USB[P,N][10] | EHCI 2 Port 10 | Port 6 | + /// | USB[P,N][11] | EHCI 2 Port 11 | Port 7 | + /// | USB[P,N][12] | EHCI 2 Port 12 | Port 10 | + /// | USB[P,N][13] | EHCI 2 Port 13 | Port 11 | + /// ------------------------------------------- + /// + + //Make sure the processing is performed only once. + if (USBPrePortDisableDone){ + pBS->CloseEvent(Event); + return; + } + + TRACE((-1, "OEM_USB_PER_PORT_DISABLE_SUPPORT - Start\n")); + + // Locate handle buffer for USB Io Protocol + Status = pBS->LocateHandleBuffer( ByProtocol, + &EfiUsbIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer); + if (EFI_ERROR(Status)){ + TRACE((-1, "ERROR: Cannot Locate handle buffer for USB Io Protocol !!!\n")); + } else { + TRACE((-1, "USB Io Protocol user are %d Handles!!!\n", HandleCount)); + } + + // Initial Xhci Port Disable Flage + // for PCH-LP + // Index: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 + // SS/HS: HS HS HS HS HS HS HS HS HS xx SS SS SS SS + // for PCH-H + // SS/HS: HS HS HS HS HS HS HS HS HS HS HS HS HS HS xx SS SS SS SS SS SS + for (Index=0;Index<21;Index++) XhciPortDisableFlage[Index] = 0; + + for ( Index=0; Index < HandleCount; Index++ ) { + pBS->HandleProtocol(HandleBuffer[Index], &gEfiUsbIoProtocolGuid, &UsbIo); + Status = UsbIo->UsbGetDeviceDescriptor(UsbIo, &DevDesc); + if (EFI_ERROR(Status)) { + continue; + } + if (DevDesc.IdVendor != 0x8087) { + continue; + } + switch (DevDesc.IdProduct) { + case 0x8000: + Ehci1RmhUsbIo = UsbIo; + break; + case 0x8008: + Ehci2RmhUsbIo = UsbIo; + break; + default: + break; + } // switch + } // for loop + +// Intel_RC >>> + if (gSbSetupData->PchUsbPerPortCtl == PCH_DEVICE_ENABLE){ + /// + /// Open the Per-Port Disable Control Override + /// + + RegData16 = IoRead16 ((UINTN) ((UINT64) (PM_BASE_ADDRESS + R_PCH_UPRWC))); + RegData16 |= B_PCH_UPRWC_WR_EN; + IoWrite16 ((UINTN) ((UINT64) (PM_BASE_ADDRESS + R_PCH_UPRWC)), RegData16); + + /// + /// To support RapidStart resume from G3 state, all resume well registers need to be saved + /// into S3 Script table. + /// + BOOT_SCRIPT_S3_IO_WRITE_MACRO ( gBootScript, + EfiBootScriptWidthUint16, + (PM_BASE_ADDRESS + R_PCH_UPRWC), + 1, + &RegData16); + + for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) { + if ((Index < 8) && (gSbSetupData->PchUsb20[0] == PCH_DEVICE_ENABLE) && (gSbSetupData->PchUsb30Mode != 1)) { + /// + /// EHCI1 PDO for Port 0 to 7 + /// + if (gSbSetupData->PchUsbPort[Index] == PCH_DEVICE_DISABLE) { + EHCIPort1 |= B_PCH_EHCI_PDO_DIS_PORT0 << Index; + if (Ehci1RmhUsbIo != NULL) { + DisableRmhDownPort(Ehci1RmhUsbIo, (Index + 1)); + } + } else { + EHCIPort1 &= ~(B_PCH_EHCI_PDO_DIS_PORT0 << Index); + } + } // EHCI1 PDO + if (PchSeries == PchH) { + if ((Index >= 8) && (Index < 14) && (gSbSetupData->PchUsb20[1] == PCH_DEVICE_ENABLE) && (gSbSetupData->PchUsb30Mode != 1)) { + /// + /// EHCI2 PDO for Port 8 to 13 + /// + if (gSbSetupData->PchUsbPort[Index] == PCH_DEVICE_DISABLE) { + EHCIPort2 |= B_PCH_EHCI_PDO_DIS_PORT0 << (Index - 8); + if (Ehci1RmhUsbIo != NULL) { + DisableRmhDownPort(Ehci2RmhUsbIo, (Index - 7)); + } + } else { + EHCIPort2 &= ~(B_PCH_EHCI_PDO_DIS_PORT0 << (Index - 8)); + } + } // EHCI2 PDO + } // PchSeries == PchH + } // for loop + + if((gSbSetupData->PchUsb20[0] == PCH_DEVICE_ENABLE) && (gSbSetupData->PchUsb30Mode != 1)){ + /// + /// To support RapidStart resume from G3 state, all resume well registers need to be saved + /// into S3 Script table. + /// + TRACE((-1, "Write back Ehci1 PDO value: %x to PDO register\n", EHCIPort1)); + WRITE_PCI8 (0, 29, 0, R_PCH_EHCI_PDO, EHCIPort1); + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( gBootScript, + EfiBootScriptWidthUint32, + SB_PCI_CFG_ADDRESS(0, 29, 0, R_PCH_EHCI_PDO), + 1, + &EHCIPort1); + + if (PchSeries == PchH && (gSbSetupData->PchUsb20[1] == PCH_DEVICE_ENABLE)) { + TRACE((-1, "Write back Ehci2 PDO value: %x to PDO register\n", EHCIPort2)); + WRITE_PCI8 (0, 26, 0, R_PCH_EHCI_PDO, EHCIPort2); + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( gBootScript, + EfiBootScriptWidthUint32, + SB_PCI_CFG_ADDRESS(0, 26, 0, R_PCH_EHCI_PDO), + 1, + &EHCIPort2); + } // PchSeries == PchH && Echi2 enable + } // Echi1 enable + + if (gSbSetupData->PchUsb30Mode != 0){ + for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) { + XhciIndex = Index; + if (PchSeries == PchH) { + /// + /// Translate physical pins to internal ports numbering + /// + XhciIndex = XhciUsb2InternalPortNumberLookUpTable[Index]; + } + if (gSbSetupData->PchUsbPort[Index] == PCH_DEVICE_DISABLE) { + XhciUsb2Pdo |= (UINT32) (B_PCH_XHCI_USB2PDO_DIS_PORT0 << XhciIndex); + XhciPortDisableFlage[XhciIndex] |= 1; + } else { + XhciUsb2Pdo &= (UINT32)~(B_PCH_XHCI_USB2PDO_DIS_PORT0 << XhciIndex); + } // XCHI PDO + } // for loop + + /// + /// XHCI PDO for SS + /// + for (Index = 0; Index < GetPchXhciMaxUsb3PortNum (); Index++) { + if (gSbSetupData->PchUsb30Port[Index] == PCH_DEVICE_DISABLE) { + XhciUsb3Pdo |= (UINT32) (B_PCH_XHCI_USB3PDO_DIS_PORT0 << Index); + if (PchSeries == PchH){ + XhciPortDisableFlage[Index + 15] |= 1; + } else { + XhciPortDisableFlage[Index + 10] |= 1; + } // PCH sku + } else { + XhciUsb3Pdo &= (UINT32)~(B_PCH_XHCI_USB3PDO_DIS_PORT0 << Index); + } // XHCI PDO + } // for loop + /// + /// USB2PDO and USB3PDO are Write-Once registers and bits in them are in the SUS Well. + /// + TRACE((-1, "Write back Xhci HS PDO value: %x to HS PDO register\n", XhciUsb2Pdo)); + WRITE_PCI32(0, 20, 0, R_PCH_XHCI_USB2PDO, XhciUsb2Pdo); + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( gBootScript, + EfiBootScriptWidthUint32, + SB_PCI_CFG_ADDRESS(0, 20, 0, R_PCH_XHCI_USB2PDO), + 1, + &XhciUsb2Pdo); + + TRACE((-1, "Write back Xhci SS PDO value: %x to SS PDO register\n", XhciUsb3Pdo)); + WRITE_PCI32(0, 20, 0, R_PCH_XHCI_USB3PDO, XhciUsb3Pdo); + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( gBootScript, + EfiBootScriptWidthUint32, + SB_PCI_CFG_ADDRESS(0, 20, 0, R_PCH_XHCI_USB3PDO), + 1, + &XhciUsb3Pdo); + + /// + /// Close the Per-Port Disable Control Override + /// + + RegData16 &= (~B_PCH_UPRWC_WR_EN); + IoWrite16 ((UINTN) ((UINT64) (PM_BASE_ADDRESS + R_PCH_UPRWC)), RegData16); + + /// + /// To support RapidStart resume from G3 state, all resume well registers need to be saved + /// into S3 Script table. + /// + + BOOT_SCRIPT_S3_IO_WRITE_MACRO ( gBootScript, + EfiBootScriptWidthUint16, + (PM_BASE_ADDRESS + R_PCH_UPRWC), + 1, + &RegData16); + } // gSbSetupData->PchUsb30Mode != 0 + } // gSbSetupData->PchUsbPerPortCtl == PCH_DEVICE_ENABLE +// Intel_RC <<< +// Disable usb port under Xhci controller >>> +{ + UINT8 counter; + UINT32 RegVal; + UINT64 XhciBar; + + // Read back Xhci MMIO addrss + if ((MmPciRead32(XHCI_BUS, XHCI_DEV, XHCI_FUN, R_PCH_XHCI_MEM_BASE) & 0x6) == 0x4){ + XhciBar = (((UINT64) MmPciRead32(XHCI_BUS, XHCI_DEV, XHCI_FUN, R_PCH_XHCI_MEM_BASE + 4) << 32) | + ((UINT64) MmPciRead32(XHCI_BUS, XHCI_DEV, XHCI_FUN, R_PCH_XHCI_MEM_BASE) & (~0x0F))); + } else { + XhciBar = MmPciRead32(XHCI_BUS, XHCI_DEV, XHCI_FUN, R_PCH_XHCI_MEM_BASE) & (~0x0F); + } + TRACE((-1, "Xhci Bar = %x\n", XhciBar)); + + // Disable Xhci port which are disconnected + for(Index=0;Index<21;Index++){ + if (XhciPortDisableFlage[Index] != 0){ + TRACE((-1, "Disable port%d under Xhci controller(start number:1)\n", (Index + 1))); + if (PchSeries ==PchLp){ + // for PCH-LP + // Index: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 + // SS/HS: HS HS HS HS HS HS HS HS HS xx SS SS SS SS + TRACE((-1, "this PCH is ULT sku\n")); + if (Index > 13) break; + + if (Index < 9){ + //HS port + RegVal = MmioRead32(XhciBar + R_PCH_XHCI_PORTSC01USB2 + 0x10 * Index); + if (RegVal & B_PCH_XHCI_PORTSCXUSB2_PED){ + RegVal = (B_PCH_XHCI_PORTSCXUSB2_PED | B_PCH_XHCI_PORTSCXUSB2_PP); + MmioWrite32((XhciBar + R_PCH_XHCI_PORTSC01USB2 + 0x10 * Index), RegVal); + for(counter=0;counter<200;counter++){ + RegVal = MmioRead32(XhciBar + R_PCH_XHCI_PORTSC01USB2 + 0x10 * Index); + if(!(RegVal & B_PCH_XHCI_PORTSCXUSB2_PED)) break; + pBS->Stall(100); + } // for loop + } // PED bit is enable + } else { + //SS port + RegVal = MmioRead32(XhciBar + R_PCH_LP_XHCI_PORTSC1USB3 + 0x10 * Index); + if (RegVal & B_PCH_XHCI_PORTSCXUSB3_PED){ + RegVal = (B_PCH_XHCI_PORTSCXUSB3_PR | B_PCH_XHCI_PORTSCXUSB3_PP); + MmioWrite32((XhciBar + R_PCH_LP_XHCI_PORTSC1USB3 + 0x10 * Index), RegVal); + for(counter=0;counter<3000;counter++){ + RegVal = MmioRead32(XhciBar + R_PCH_LP_XHCI_PORTSC1USB3 + 0x10 * Index); + if(RegVal & B_PCH_XHCI_PORTSCXUSB3_PRC) break; + pBS->Stall(100); + } // for loop + + // Clear Warm Port Reset Change and Port Reset Change bits + //RegVal = (B_PCH_XHCI_PORTSCXUSB3_WRC | B_PCH_XHCI_PORTSCXUSB3_PRC | B_PCH_XHCI_PORTSCXUSB3_PP); + //MmioWrite32((XhciBar + R_PCH_LP_XHCI_PORTSC1USB3 + 0x10 * Index), RegVal); + } // PED bit is enable + }// SS/HS port + } else { + // for PCH-H + // Index: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 + // SS/HS: HS HS HS HS HS HS HS HS HS HS HS HS HS HS xx SS SS SS SS SS SS + TRACE((-1, "this PCH is MB/DT sku\n")); + if (Index < 14){ + //HS port + RegVal = MmioRead32(XhciBar + R_PCH_XHCI_PORTSC01USB2 + 0x10 * Index); + if (RegVal & B_PCH_XHCI_PORTSCXUSB2_PED){ + RegVal = (B_PCH_XHCI_PORTSCXUSB2_PED | B_PCH_XHCI_PORTSCXUSB2_PP); + MmioWrite32((XhciBar + R_PCH_XHCI_PORTSC01USB2 + 0x10 * Index), RegVal); + for(counter=0;counter<200;counter++){ + RegVal = MmioRead32(XhciBar + R_PCH_XHCI_PORTSC01USB2 + 0x10 * Index); + if(!(RegVal & B_PCH_XHCI_PORTSCXUSB2_PED)) break; + pBS->Stall(100); + } // for loop + } // PED bit is enable + } else { + //SS port + RegVal = MmioRead32(XhciBar + R_PCH_H_XHCI_PORTSC1USB3 + 0x10 * Index); + if (RegVal & B_PCH_XHCI_PORTSCXUSB3_PED){ + RegVal = (B_PCH_XHCI_PORTSCXUSB3_PR | B_PCH_XHCI_PORTSCXUSB3_PP); + MmioWrite32((XhciBar + R_PCH_H_XHCI_PORTSC1USB3 + 0x10 * Index), RegVal); + for(counter=0;counter<3000;counter++){ + RegVal = MmioRead32(XhciBar + R_PCH_H_XHCI_PORTSC1USB3 + 0x10 * Index); + if(RegVal & B_PCH_XHCI_PORTSCXUSB3_PRC) break; + pBS->Stall(100); + } // for loop + + // Clear Warm Port Reset Change and Port Reset Change bits + //RegVal = (B_PCH_XHCI_PORTSCXUSB3_WRC | B_PCH_XHCI_PORTSCXUSB3_PRC | B_PCH_XHCI_PORTSCXUSB3_PP); + //MmioWrite32((XhciBar + R_PCH_H_XHCI_PORTSC1USB3 + 0x10 * Index), RegVal); + } // PED bit is enable + } // SS/HS port + } // PCH sku + } // XhciPortDisableFlage[counter] != 0 + } // for loop + + pBS->FreePool(HandleBuffer); +} +// Disable usb port under Xhci controller <<< + + USBPrePortDisableDone = TRUE; + TRACE((-1, "OEM_USB_PER_PORT_DISABLE_SUPPORT - End\n")); + pBS->CloseEvent(Event); +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbSetupNvramUpdatedCallback +// +// Description: This callback function is called after Setup NVRAM variable +// being updated. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbSetupNvramUpdatedCallback ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status; + SB_SETUP_DATA *SetupData = NULL; + UINTN VariableSize = sizeof(SB_SETUP_DATA); + + Status = pBS->AllocatePool( EfiBootServicesData, \ + VariableSize, \ + &SetupData ); + ASSERT_EFI_ERROR(Status); + + GetSbSetupData( pRS, SetupData, FALSE ); + + // Free memory used for setup data + pBS->FreePool( SetupData ); + + pBS->CloseEvent(Event); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbExitPmAuthProtocolCallback +// +// Description: This callback function is called after Setup NVRAM variable +// being updated. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbExitPmAuthProtocolCallback ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status; + // [EIP120623]> + UINT8 Data8; + // <[EIP120623] +// [ EIP357393 ]->>> +// UINT32 Data32; +// UINT32 i; +// UINT32 SpiRegister[] = { +// R_PCH_SPI_SSFS, +// R_PCH_SPI_PREOP, +// R_PCH_SPI_OPMENU, +// R_PCH_SPI_OPMENU + 4, +// R_PCH_SPI_VSCC1, +// R_PCH_SPI_VSCC0 +// }; +// [ EIP357393 ]-<<< + VOID *ProtocolPointer; + UINT32 SmiEn; + UINT16 Pm1Sts; + PCH_SERIES PchSeries = GetPchSeries(); + + // + // Check whether this is real ExitPmAuth notification, or just a SignalEvent + // + Status = pBS->LocateProtocol (&gExitPmAuthProtocolGuid, NULL, &ProtocolPointer); + if (EFI_ERROR (Status)) return; + + // + // Save SPI Registers for S3 resume usage + // +// [ EIP357393 ]->>> +// for (i = 0; i < sizeof (SpiRegister) / sizeof (UINT32); i++) { +// Data32 = READ_MEM32_RCRB (SpiRegister[i]); +// BOOT_SCRIPT_S3_MEM_WRITE_MACRO( gBootScript, \ +// EfiBootScriptWidthUint32, \ +// SB_RCRB_BASE_ADDRESS + SpiRegister[i], \ +// 1, \ +// &Data32 +// ); +// } +// [ EIP357393 ]-<<< + + // [EIP120623]> + Data8 = IoRead8 (PM_BASE_ADDRESS + ACPI_IOREG_PM1_CNTL); //0x04 + Data8 |= B_PCH_ACPI_PM1_CNT_SCI_EN; + + BOOT_SCRIPT_S3_IO_WRITE_MACRO ( \ + gBootScript, \ + EfiBootScriptWidthUint8, \ + PM_BASE_ADDRESS + ACPI_IOREG_PM1_CNTL, \ + 1, \ + &Data8); + // <[EIP120623] + + SmiEn = IoRead32 (PM_BASE_ADDRESS + ACPI_IOREG_SMI_EN); //0x30 + SmiEn &= ~B_PCH_SMI_EN_SWSMI_TMR; + // [EIP76432]>> +#if defined EMUL6064_SUPPORT && EMUL6064_SUPPORT == 1 + SmiEn &= ~B_PCH_SMI_EN_LEGACY_USB; +#endif + // <<[EIP76432] + BOOT_SCRIPT_S3_IO_WRITE_MACRO ( \ + gBootScript, \ + EfiBootScriptWidthUint32, \ + PM_BASE_ADDRESS + ACPI_IOREG_SMI_EN, \ + 1, \ + &SmiEn); + // [EIP92011] >> + if (PchSeries != PchLp) { + SmiEn = IoRead16 (PM_BASE_ADDRESS + ACPI_IOREG_ALTGP_SMI_EN); // Alternate GPI SMI Enable Reg. + //0x38 + BOOT_SCRIPT_S3_IO_WRITE_MACRO ( \ + gBootScript, \ + EfiBootScriptWidthUint16, \ + PM_BASE_ADDRESS + ACPI_IOREG_ALTGP_SMI_EN, \ + 1, \ + &SmiEn); + }else{ + SmiEn = IoRead16 (GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN); // Alternate GPI SMI Enable Reg. + //0x54 + BOOT_SCRIPT_S3_IO_WRITE_MACRO ( \ + gBootScript, \ + EfiBootScriptWidthUint16, \ + GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN, \ + 1, \ + &SmiEn); + } + //[EIP92011] << + + // Clear bus master status bit on S3 resume + Pm1Sts = B_PCH_ACPI_PM1_STS_BM; + //0x00 + BOOT_SCRIPT_S3_IO_WRITE_MACRO ( \ + gBootScript, \ + EfiBootScriptWidthUint16, \ + PM_BASE_ADDRESS + ACPI_IOREG_PM1_STS, \ + 1, \ + &Pm1Sts); +/* // [ EIP357393 ]->>> + // EIP167087 >>> + TRACE((-1, "Programming SPI Protected Range registers")); + Status = SbFlashProtectedRange(); + TRACE((-1, " %r !!!\n", Status)); + ASSERT_EFI_ERROR(Status); + + // Write SPI Protected Range registers to S3 script + for(i=0;i<5;i++){ + Data32 = READ_MEM32_RCRB(SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (i * 4))); + TRACE((-1, "PR%d value @ %x: %x\n", i, (SB_RCBA + SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (i * 4))), Data32)); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO( gBootScript, \ + EfiBootScriptWidthUint32, \ + SB_RCBA + SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (i * 4)), \ + 1, \ + &Data32 + ); + } + // EIP167087 <<< +*/ // [ EIP357393 ]-<<< + + pBS->CloseEvent(Event); +} + + +// [ EIP357393 ]+>>> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBS3SaveSpi +// +// Description: Restore SPI register for S3 resume +// +// Input: NoneE +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBS3SaveSpi(VOID) +{ + EFI_STATUS Status; + UINT32 Data32; + UINT32 i; + UINT32 SpiRegister[] = { + R_PCH_SPI_SSFS, + R_PCH_SPI_PREOP, + R_PCH_SPI_OPMENU, + R_PCH_SPI_OPMENU + 4, + R_PCH_SPI_VSCC1, + R_PCH_SPI_VSCC0 + }; + + // + // Save SPI Registers for S3 resume usage + // + for (i = 0; i < sizeof (SpiRegister) / sizeof (UINT32); i++) { + Data32 = READ_MEM32_RCRB (SpiRegister[i]); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO( gBootScript, \ + EfiBootScriptWidthUint32, \ + SB_RCRB_BASE_ADDRESS + SpiRegister[i], \ + 1, \ + &Data32 + ); + } + + // EIP167087 >>> + TRACE((-1, "Programming SPI Protected Range registers")); + Status = SbFlashProtectedRange(); + TRACE((-1, " %r !!!\n", Status)); + ASSERT_EFI_ERROR(Status); + + // Write SPI Protected Range registers to S3 script + for(i=0;i<5;i++){ + Data32 = READ_MEM32_RCRB(SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (i * 4))); + TRACE((-1, "PR%d value @ %x: %x\n", i, (SB_RCBA + SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (i * 4))), Data32)); + BOOT_SCRIPT_S3_MEM_WRITE_MACRO( gBootScript, \ + EfiBootScriptWidthUint32, \ + SB_RCBA + SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (i * 4)), \ + 1, \ + &Data32 + ); + } + // EIP167087 <<< +} +// [ EIP357393 ]+<<< + + +//---------------------------------------------------------------------------- +// USUALLY NO PORTING REQUIRED FOR THE FOLLOWING ROUTINES +//---------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ClearWarmResetFlag +// +// Description: This function resets warm reset variable. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ClearWarmResetFlag (VOID) +{ + EFI_STATUS Status; + EFI_GUID SbWarmResetGuid = SB_WARM_RESET_GUID; + CHAR16 SbWarmResetVar[] = SB_WARM_RESET_VARIABLE; + UINT32 SbWarmResetFlag = 0; + UINT32 Attributes = 0; + UINTN VarSize = sizeof(SbWarmResetFlag); + static EFI_GUID guidHob = HOB_LIST_GUID; + EFI_HOB_HANDOFF_INFO_TABLE *pHit; + + Status = pRS->GetVariable( SbWarmResetVar, \ + &SbWarmResetGuid, \ + &Attributes, \ + &VarSize, \ + &SbWarmResetFlag ); + if ((!EFI_ERROR(Status)) && (SbWarmResetFlag == SB_WARM_RESET_TAG)) { + SbWarmResetFlag ^= 0xffffffff; + Status = pRS->SetVariable( SbWarmResetVar, \ + &SbWarmResetGuid, \ + Attributes, \ + 0, \ + &SbWarmResetFlag ); + + //Get Boot Mode + pHit = GetEfiConfigurationTable(pST, &guidHob); + if (pHit && (pHit->BootMode == BOOT_WITH_FULL_CONFIGURATION)) { + // Update Boot mode for ME. + pHit->BootMode = BOOT_ASSUMING_NO_CONFIGURATION_CHANGES; + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReportSBDxeError +// +// Description: This function reports DXE_SB_ERROR code to system during SB +// DXE initialzation if needed. +// +// Input: Status - EFI status. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ReportSBDxeError ( + IN EFI_STATUS Status ) +{ + if (Status != EFI_SUCCESS) { + // Report Error code + ERROR_CODE (DXE_SB_ERROR, EFI_ERROR_MAJOR); + ASSERT_EFI_ERROR(Status); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WatchdogHandler +// +// Description: This function is called when the watchdog timer event is +// signalled. It calls the registered handler and then +// resets the system +// +// Inout: Event - Watchdog event +// Context - Context pointer +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID EFIAPI WatchdogHandler ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + // Call the registered handler if there is one + if (mWatchdogNotifyFunction != NULL) { + mWatchdogNotifyFunction (mWatchdogPeriod); + } + + // Reset the system + pRS->ResetSystem( EfiResetCold, EFI_TIMEOUT, 0, NULL ); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RegisterHandler +// +// Description: This function registers a handler that is called when the +// Timer event has been signalled +// +// Input: *This - Pointer to the instance of the Architectural +// Protocol +// NotifyFunction - The function to call when the interrupt fires +// +// Output: EFI_STATUS +// EFI_SUCCESS - When new handle is registered +// EFI_ALREADY_STARTED - If notify function is already +// defined +// EFI_INVALID_PARAMETER - If notify function is NULL +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EFIAPI RegisterHandler ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction ) +{ + // Only register the handler if it is still NULL + if (NotifyFunction && mWatchdogNotifyFunction) + return EFI_ALREADY_STARTED; + if (!NotifyFunction && !mWatchdogNotifyFunction) + return EFI_INVALID_PARAMETER; + + mWatchdogNotifyFunction = NotifyFunction; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WatchdogSetTimerPeriod +// +// Description: This function sets the timer period before the watchdog goes +// off every TimerPeriod number of 100ns intervals, if the +// period is set to 0 the timer event is cancelled +// +// Input: *This - Pointer to the instance of the Architectural +// Protocol +// TimerPeriod - The number of 100ns intervals to which the +// watchdog will be programmed. +// +// Output: EFI_STATUS +// EFI_SUCCESS - The event has been set to be +// signaled at the requested time. +// EFI_INVALID_PARAMETER - WatchdogEvent or TimerDelayType +// is not valid. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EFIAPI WatchdogSetTimerPeriod ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod ) +{ + EFI_TIMER_DELAY TimerDelayType; + + // Store new timer length + mWatchdogPeriod = TimerPeriod; + + // Cancel timer event if Timer Period is 0 + TimerDelayType = (TimerPeriod) ? TimerRelative : TimerCancel; + + // Set the timer for the event + return pBS->SetTimer( mWatchdogEvent, TimerDelayType, mWatchdogPeriod ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WatchdogGetTimerPeriod +// +// Description: This function returns the current watchdog timer period +// +// Input: *This - Pointer to the instance of the Architectural +// Protocol +// *TimerPeriod - Pointer to a memory location to load the +// current Timer period into +// +// Output: *TimerPeriod - Current Timer Period if function returns +// EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EFIAPI WatchdogGetTimerPeriod ( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN UINT64 *TimerPeriod ) +{ + // return the current Watchdog period + *TimerPeriod = mWatchdogPeriod; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WatchdogInit +// +// Description: This function installs the the Watchdog Timer protocol on its +// handle, and initializes the Watchdog timer. +// +// Input: ImageHandle - ImageHandle of the loaded driver +// SystemTable - Pointer to the System Table +// +// Output: EFI_STATUS +// EFI_SUCCESS - The Watchdog Timer protocol was +// installed. +// EFI_OUT_OF_RESOURCES - Space for a new handle could not +// be allocated. +// EFI_INVALID_PARAMETER - One of the parameters has an +// invalid value. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WatchdogInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + + // Use the Timer event to trigger the Watchdog. No specific hardware + // exists for this + Status = pBS->CreateEvent( EVT_TIMER | EVT_NOTIFY_SIGNAL, \ + TPL_NOTIFY, \ + WatchdogHandler, \ + NULL, \ + &mWatchdogEvent ); + + // Create a handle for the ArchProtocol and install Watchdog Arch + // Protocol on the handle + Status = pBS->InstallProtocolInterface( &mWatchdogHandle, \ + &gWatchdogGuid, \ + EFI_NATIVE_INTERFACE, \ + &mWatchdog ); + + return Status; +} + +#if defined(HPET_PROTOCOL_SUPPORT) && (HPET_PROTOCOL_SUPPORT != 0) +// Mask used for counter and comparator calculations to adjust for a 32-bit or 64-bit counter. +UINT64 gCounterMask; +// Cached state of the HPET General Capabilities register managed by this driver. +// Caching the state reduces the number of times the configuration register is read. +volatile HPET_GENERAL_CAPABILITIES_ID_REGISTER gHpetGeneralCapabilities; +// Cached state of the HPET General Configuration register managed by this driver. +// Caching the state reduces the number of times the configuration register is read. +volatile HPET_GENERAL_CONFIGURATION_REGISTER gHpetGeneralConfiguration; +// Cached state of the Configuration register for the HPET Timer managed by +// this driver. Caching the state reduces the number of times the configuration +// register is read. +volatile HPET_TIMER_CONFIGURATION_REGISTER gTimerConfiguration; + +EFI_EVENT gHpetLegacyBootEvent; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EnableHpetInChipset +// +// Description: This function enables HPET register decode. +// +// Input: None +// +// Output: None +// +// Notes: Porting required. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID EnableHpetInChipset( VOID ) +{ + // Porting required. +// WRITE_MEM32_RCRB_S3(gBootScriptSave, RCRB_MMIO_HPTC, ((HPET_BASE_ADDRESS >> 12) & 3) | 0x80); +WRITE_MEM32_RCRB_S3(gBootScript, RCRB_MMIO_HPTC, ((HPET_BASE_ADDRESS >> 12) & 3) | 0x80); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: HpetRead +// +// Description: This function reads a 64-bit register from the HPET register. +// +// Input: Offset - Specifies the offset of the HPET register to read. +// +// Output: The 64-bit value read from the HPET register specified by +// Offset. +// +// Notes: No porting required. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT64 HpetRead ( + IN UINTN Offset ) +{ + return MMIO_READ64( HPET_BASE_ADDRESS + Offset ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: HpetWrite +// +// Description: This function writes a 64-bit HPET register. +// +// Input: Offset - Specifies the ofsfert of the HPET register to write. +// Value - Specifies the value to write to the HPET register +// specified by Offset. +// +// Output: The 64-bit value written to HPET register specified by Offset. +// +// Notes: No porting required. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT64 HpetWrite ( + IN UINTN Offset, + IN UINT64 Value ) +{ + MMIO_WRITE64( HPET_BASE_ADDRESS + Offset, Value ); + return HpetRead( Offset ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: HpetEnable +// +// Description: This function enables or disables the main counter in the +// HPET Timer. +// +// Input: Enable TRUE - Enable the main counter in the HPET Timer. +// FALSE - Disable the main counter in the HPET Timer. +// Output: None +// +// Notes: No porting required. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID HpetEnable ( + IN BOOLEAN Enable ) +{ + gHpetGeneralConfiguration.Bits.MainCounterEnable = Enable ? 1 : 0; + HpetWrite( HPET_GENERAL_CONFIGURATION_OFFSET, + gHpetGeneralConfiguration.Uint64); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: StopHpetBeforeLagecyBoot +// +// Description: This function stops HPET counter & interrupt. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID StopHpetBeforeLagecyBoot ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + // Disable HPET and Legacy Replacement Support. + HpetEnable (FALSE); + CountTime ((HPET_DEFAULT_TICK_DURATION / 10) * 2, PM_BASE_ADDRESS); + HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE, 0); + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + IoApicDisableIrq(HPET_APIC_INTERRUPT_PIN); +#else + gHpetGeneralConfiguration.Bits.LegacyRouteEnable = 0; + + HpetEnable (FALSE); +#endif + + pBS->CloseEvent(Event); +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerRegisterHandler +// +// Description: This function registers a handler that is called every time +// the timer interrupt fires +// +// Input: *This - Pointer to the instance of the Architectural +// Protocol +// NotifyFunction - The function to call when the interrupt fires +// +// Output: EFI_STATUS +// EFI_SUCCESS - New handle registered +// EFI_ALREADY_STARTED - if Notify function is already +// defined +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS TimerRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction ) +{ + // Check to see if the handler has already been installed + if ((NotifyFunction != NULL) && (mNotifyFunction != NULL)) { + return EFI_ALREADY_STARTED; + } + + // If not install it + mNotifyFunction = NotifyFunction; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SetTimerPeriod +// +// Description: This function sets the timer to create an Intr on IRQ0 +// every TimerPeriod number of 100ns intervals +// +// Input: *This - Pointer to the instance of the Architectural +// Protocol +// TimerPeriod - The number of 100ns intervals to which the +// timer will be programmed. This value will +// be rounded up to the nearest timer interval. +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod ) +{ +#if defined(HPET_PROTOCOL_SUPPORT) && (HPET_PROTOCOL_SUPPORT != 0) + UINTN Remainder; + UINT64 TimerCount; + + // Disable HPET timer when adjusting the timer period + HpetEnable (FALSE); +#else +// EFI_STATUS Status; + UINT32 NumberOfTicks; + UINT8 Value8; +#endif + + // Find the CPU Architectural Protocol + //Status = pBS->LocateProtocol( &gEfiCpuArchProtocolGuid, NULL, &CpuArch ); + + // If timer period is 0 then disable the Timer interrupt + if (TimerPeriod == 0) { +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + IoApicDisableIrq(HPET_APIC_INTERRUPT_PIN); +#endif + // DisableIrq(SYSTEM_TIMER_IRQ); + mLegacy8259->DisableIrq( mLegacy8259, SYSTEM_TIMER_IRQ ); + } else { +#if defined(HPET_PROTOCOL_SUPPORT) && (HPET_PROTOCOL_SUPPORT != 0) + // Convert TimerPeriod to femtoseconds and divide by the number if + // femtoseconds per tick of the HPET counter to determine the number + // of HPET counter ticks in TimerPeriod 100 ns units. + TimerCount = Div64( Mul64( TimerPeriod, 100000000 ), + gHpetGeneralCapabilities.Bits.CounterClockPeriod, + &Remainder ); + + // Reset Main Counter + HpetWrite (HPET_MAIN_COUNTER_OFFSET, 0); + // ValueSetEnable must be set if the timer is set to periodic mode. + gTimerConfiguration.Bits.ValueSetEnable = 1; + HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE, gTimerConfiguration.Uint64); + // Clear ValueSetEnable bit. + gTimerConfiguration.Bits.ValueSetEnable = 0; + HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE, TimerCount); + +#else + // otherwise change the timer period into number of ticks and set + // the timer + if (TimerPeriod > MAX_TICK_DURATION) TimerPeriod = MAX_TICK_DURATION; + // NumberOfTicks = TimerPeriod * 100 /TIMER_TICK; + // Since TimerPeriod in 100ns units and TIMER_TICK in ns + // We have to multiple TimerPeriod by 100 + // To round up result: + // NumberOfTicks = TimerPeriod * 100/TIMER_TICK + 0.5 = + // (TimerPeriod*100+TIMER_TICK/2)/TIMER_TICK + NumberOfTicks = ((UINT32)TimerPeriod * 100 + TIMER_TICK / 2) \ + / TIMER_TICK; + // Write to port 0x43 to setup the timer + IoWrite8 ( LEGACY_TIMER_CTRL, 0x36 ); + // Write to port 0x40 to set the time + IoWrite8 ( LEGACY_TIMER_0_COUNT, (UINT8)NumberOfTicks ); + IoWrite8 ( LEGACY_TIMER_0_COUNT, *(((UINT8*)&NumberOfTicks) + 1) ); + + Value8 = 0x36; + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_CTRL, 1, &Value8); + Value8 = (UINT8)NumberOfTicks; + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_0_COUNT, 1, &Value8); + Value8 = *(((UINT8*)&NumberOfTicks)+1); + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_0_COUNT, 1, &Value8); + +#endif + + // Now enable the interrupt +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + IoApicEnableIrq(HPET_APIC_INTERRUPT_PIN, HPET_INTERRUPT_TRIGGER, (HPET_INTERRUPT_POLARITY == 0) ? TRUE : FALSE); +#endif + // EnableIrq(SYSTEM_TIMER_IRQ); + mLegacy8259->EnableIrq( mLegacy8259, SYSTEM_TIMER_IRQ, FALSE ); + +#if defined(HPET_PROTOCOL_SUPPORT) && (HPET_PROTOCOL_SUPPORT != 0) + // Enable HPET Interrupt Generation + gTimerConfiguration.Bits.InterruptEnable = 1; + HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE, gTimerConfiguration.Uint64); + + // Enable the HPET counter once new timer period has been established + // The HPET counter should run even if the HPET Timer interrupts are + // disabled. This is used to account for time passed while the interrupt + // is disabled. + HpetEnable (TRUE); +#endif + } + + mProgrammedTimerValue = TimerPeriod; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetTimerPeriod +// +// Description: This function returns the current timer period +// +// Input: *This - Pointer to the instance of the Architectural +// Protocol +// *TimerPeriod - pointer to a memory location to load the +// current Timer period into +// +// Output: EFI_SUCCESS - *TimerPeriod - Current Timer Period +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS GetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN OUT UINT64 *TimerPeriod ) +{ + *TimerPeriod = mProgrammedTimerValue; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GenerateSoftIntr + +// +// Description: This function generates a soft timer interrupt +// +// Input: *This - Pointer to the instance of the Architectural Protocol +// +// Output: EFI_UNSUPPORTED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS GenerateSoftIntr ( + IN EFI_TIMER_ARCH_PROTOCOL *This ) +{ + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerInterruptHandler +// +// Description: This function is called when the Timer reaches 0. It raises +// the TPL and then calls the registered notify function +// +// Input: InterruptType - Interrupt type +// SystemContext - System context +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext ) +{ + EFI_TPL OldTpl; + static volatile UINT32 StoreCF8; +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) && defined(HPET_INTERRUPT_TRIGGER) && (HPET_INTERRUPT_TRIGGER == 1) + static volatile UINT64 HpetGenIntSts; +#endif + + OldTpl = pBS->RaiseTPL (TPL_HIGH_LEVEL); + + SaveRestoreRegisters( TRUE ); + + StoreCF8 = IoRead32(0xcf8); // Store CF8 (PCI index) + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + IoApicEoi(GetHpetApicPin()); + +#if defined(HPET_INTERRUPT_TRIGGER) && (HPET_INTERRUPT_TRIGGER == 1) + HpetGenIntSts = HpetRead(HPET_GENERAL_INTERRUPT_STATUS_OFFSET); + HpetWrite (HPET_GENERAL_INTERRUPT_STATUS_OFFSET, Shl64(BIT0, HPET_OFFSET)); +#endif +#else + // Clear the interrupt flag + mLegacy8259->EndOfInterrupt(mLegacy8259,SYSTEM_TIMER_IRQ); +#endif + + // This checks for the existance of a registered notify function and + // if it exists it calls the function with the current programmed Timer + // Period + if (mNotifyFunction) + { +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) && defined(HPET_INTERRUPT_TRIGGER) && (HPET_INTERRUPT_TRIGGER == 1) + if (HpetGenIntSts & Shl64(BIT0, HPET_OFFSET)) + { + mNotifyFunction (mProgrammedTimerValue); + } +#else + mNotifyFunction (mProgrammedTimerValue); +#endif + } + + IoWrite32(0xcf8, StoreCF8); // Restore 0xCF8 (PCI index) + + SaveRestoreRegisters( FALSE ); + + pBS->RestoreTPL (OldTpl); +} + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: Irq0InterruptHandler +// +// Description: This function is called when the 8254 Timer 0 reaches 0. +// It raises the TPL and then calls the registered notify +// function. +// +// Input: InterruptType - Interrupt type +// SystemContext - System context +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID Irq0InterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext ) +{ + EFI_TPL OldTpl; + + + OldTpl = pBS->RaiseTPL (TPL_HIGH_LEVEL); + + // Clear the interrupt flag + mLegacy8259->EndOfInterrupt(mLegacy8259, SYSTEM_TIMER_IRQ); + + pBS->RestoreTPL (OldTpl); +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerInit +// +// Description: This function installs the the timer protocol on its handle, +// and initializes the timer. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: EFI_STATUS +// EFI_SUCCESS - The Timer protocol was installed +// EFI_OUT_OF_RESOURCES - Space for a new handle could not +// be allocated. +// EFI_INVALID_PARAMETER - One of the parameters has an +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EFIAPI TimerInit ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + EFI_STATUS Status; + EFI_CPU_ARCH_PROTOCOL *CpuArch; + // TimerVector must be initialized to 0, since GetVector only modifies + // the lowest byte, and RegisterInterruptHandler requires TimerVector + // to be 4 bytes. + UINT32 TimerVector = 0; + UINT32 Irq0TimerVector = 0; + UINT8 Value; + + Status = pBS->LocateProtocol ( &gEfiLegacy8259ProtocolGuid, \ + NULL, \ + &mLegacy8259 ); + ASSERT_EFI_ERROR(Status); + +#if defined(HPET_PROTOCOL_SUPPORT) && (HPET_PROTOCOL_SUPPORT != 0) + // Enable HPET (0x3404) + EnableHpetInChipset(); + + // Retrieve HPET Capabilities and Configuration Information + gHpetGeneralCapabilities.Uint64 = HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET); + gHpetGeneralConfiguration.Uint64 = HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET); + + // If Revision is not valid, then ASSERT() and unload the driver because the HPET + // device is not present. + if (gHpetGeneralCapabilities.Uint64 == 0 || gHpetGeneralCapabilities.Uint64 == 0xFFFFFFFFFFFFFFFF) { + TRACE((-1, "HPET device is not present. Unload HPET driver.\n")); + return EFI_DEVICE_ERROR; + } + + // Force the HPET timer to be disabled while setting everything up + HpetEnable (FALSE); +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE == 0) + // Enable Legacy Interrupt + gHpetGeneralConfiguration.Bits.LegacyRouteEnable = 1; +#endif +#endif + + // Disable timer, make sure no interrupt will be created + Status = SetTimerPeriod ( &mTimerProtocol, 0 ); + ASSERT_EFI_ERROR(Status); + +#if defined(HPET_PROTOCOL_SUPPORT) && (HPET_PROTOCOL_SUPPORT != 0) + // Configure the selected HPET Timer (Timer#0), clear InterruptEnable to keep + // interrupts disabled until full init is complete + // Enable PeriodicInterruptEnable to use perioidic mode + // Configure as a 32-bit counter + gTimerConfiguration.Uint64 = HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE); + gTimerConfiguration.Bits.InterruptEnable = 0; + gTimerConfiguration.Bits.PeriodicInterruptEnable = 1; + gTimerConfiguration.Bits.CounterSizeEnable = 1; // 32bit + gTimerConfiguration.Bits.LevelTriggeredInterrupt = HPET_INTERRUPT_TRIGGER; +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + gTimerConfiguration.Bits.InterruptRoute = HPET_APIC_INTERRUPT_PIN; +#endif + HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE, gTimerConfiguration.Uint64); + + // Read the HPET Timer Capabilities and Configuration register back again. + // CounterSizeEnable will be read back as a 0 if it is a 32-bit only timer + gTimerConfiguration.Uint64 = HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE); +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + // If the interrupt pin isn't supported by the particular timer, then the value read back won't match that is written. + if (gTimerConfiguration.Bits.InterruptRoute != HPET_APIC_INTERRUPT_PIN) { + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); + return EFI_UNSUPPORTED; + } +#endif + if ((gTimerConfiguration.Bits.CounterSizeEnable == 1) && (sizeof (UINTN) == sizeof (UINT64))) { + // 64-bit BIOS can use 64-bit HPET timer + gCounterMask = 0xffffffffffffffff; + // Set timer back to 64-bit + gTimerConfiguration.Bits.CounterSizeEnable = 0; + HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE, gTimerConfiguration.Uint64); + } else { + gCounterMask = 0x00000000ffffffff; + } +#endif + + // Find the CPU Arch Protocol + Status = pBS->LocateProtocol ( &gEfiCpuArchProtocolGuid, \ + NULL, \ + &CpuArch ); + ASSERT_EFI_ERROR(Status); + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + TimerVector = MASTER_INTERRUPT_BASE + HPET_APIC_INTERRUPT_PIN; + + Status = mLegacy8259->GetVector ( mLegacy8259, \ + Efi8259Irq0, \ + (UINT8 *)&Irq0TimerVector ); + ASSERT_EFI_ERROR(Status); + + Status = CpuArch->RegisterInterruptHandler ( CpuArch, \ + Irq0TimerVector, \ + Irq0InterruptHandler ); + ASSERT_EFI_ERROR(Status); +#else + Status = mLegacy8259->GetVector ( mLegacy8259, \ + Efi8259Irq0, \ + (UINT8 *)&TimerVector ); + ASSERT_EFI_ERROR(Status); +#endif + + Status = CpuArch->RegisterInterruptHandler ( CpuArch, \ + TimerVector, \ + TimerInterruptHandler ); + ASSERT_EFI_ERROR(Status); + + // Initialize the handle pointer + mNotifyFunction = NULL; + +#if defined(HPET_PROTOCOL_SUPPORT) && (HPET_PROTOCOL_SUPPORT != 0) + // Init default for Timer 1 + IoWrite8( LEGACY_TIMER_CTRL, 0x36 ); + IoWrite8( LEGACY_TIMER_0_COUNT, 0 ); + IoWrite8( LEGACY_TIMER_0_COUNT, 0 ); + // Add boot script programming + Value = 0x36; + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_CTRL, 1, &Value); + Value = 0x0; + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_0_COUNT, 1, &Value); + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_0_COUNT, 1, &Value); + + // The default value of 10000 100 ns units is the same as 1 ms. + Status = SetTimerPeriod ( &mTimerProtocol, HPET_DEFAULT_TICK_DURATION ); + + + + Status = CreateLegacyBootEvent( TPL_CALLBACK, + StopHpetBeforeLagecyBoot, + NULL, + &gHpetLegacyBootEvent ); +#else + // Force the timer to be enabled at its default period + Status = SetTimerPeriod ( &mTimerProtocol, DEFAULT_TICK_DURATION ); +#endif + ASSERT_EFI_ERROR (Status); + + //Program Timer1 to pass certain customer's test + IoWrite8( LEGACY_TIMER_CTRL, 0x54 ); + IoWrite8( LEGACY_TIMER_1_COUNT, 0x12 ); + //add boot script programming + Value = 0x54; + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_CTRL, 1, &Value); + Value = 0x12; + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScript, EfiBootScriptWidthUint8, LEGACY_TIMER_1_COUNT, 1, &Value); + + + // Install the Timer Architectural Protocol onto a new handle + Status = pBS->InstallProtocolInterface ( &mTimerProtocolHandle, \ + &gEfiTimerArchProtocolGuid, \ + EFI_NATIVE_INTERFACE, \ + &mTimerProtocol ); + ASSERT_EFI_ERROR(Status); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramIrqMaskTrigger +// +// Description: Program the Irq Mask and Trigger. +// +// Input: None +// +// Output: None +// +// Notes: Here is the control flow of this function: +// 1. Program Master Irq Mask. +// 2. Program Slave Irq Mask. +// 3. Program Trigger Level. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ProgramIrqMaskTrigger (VOID) +{ + IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, (UINT8)gIrqMask[gMode]); + IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8)(gIrqMask[gMode] >> 8)); + + // 4d0 can not be accessed as by IoWrite16, we have to split + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, \ + (UINT8)gIrqTrigger[gMode]); + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, \ + (UINT8)(gIrqTrigger[gMode] >> 8)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SetVectorBase +// +// Description: Initializes the interrupt controller and program the Irq +// Master and Slave Vector Base. +// +// Input: *This - Pointer to this object +// MasterBase - IRQ base for the master 8259 controller +// SlaveBase - IRQ base for the slave 8259 controller +// +// Output: EFI_SUCCESS - Interrupt on the interrupt controllers was +// enabled. +// +// Notes: Here is the control flow of this function: +// 1. If Master base is changed, initialize master 8259 setting +// the interrupt offset. +// 2. If Slave base is changed, initialize slave 8259 setting +// the interrupt offset. +// 3. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SetVectorBase ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT8 MasterBase, + IN UINT8 SlaveBase ) +{ + // 8259 Master + if (MasterBase != gMasterBase) { + // Start 8259 Master Initialization. + IoWrite8(LEGACY_8259_CONTROL_REGISTER_MASTER, ICW1); // 0x20 + // Set Interrupt Offset + IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, MasterBase); // 0x21 + // Set Slave IRQ. + IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, ICW3_M); // 0x21 + // Set 8259 mode. See ICW4 comments with #define. + IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, ICW4); // 0x21 + gMasterBase = MasterBase; + } + + // 8259 Slave + if (SlaveBase != gSlaveBase) { + // Start 8259 Slave Initialization. + IoWrite8(LEGACY_8259_CONTROL_REGISTER_SLAVE, ICW1); // 0xA0 + // Set Interrupt Offset + IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, SlaveBase); // 0xA1 + // Set Slave IRQ. + IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, ICW3_S); // 0xA1 + // Set 8259 mode. See ICW4 comments with #define. + IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, ICW4); // 0xA1 + gSlaveBase = SlaveBase; + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetMask +// +// Description: Get the Master/Slave Irq Mask, Irq Level for Legacy real +// mode and protected mode. +// +// Input: *This - Pointer to this object +// *LegacyMask - Legacy mode interrupt mask +// *LegacyEdgeLevel - Legacy mode edge/level trigger value +// *ProtectedMask - Protected mode interrupt mask +// *ProtectedEdgeLevel - Protected mode edge/level trigger value +// +// Output: EFI_SUCCESS - Returned irq mask/level. +// +// Notes: Here is the control flow of this function: +// 1. If *LegacyMask not NULL, get legacy Mask. +// 2. If *LegacyEdgeLevel not NULL, get legacy Trigger Level. +// 3. If *ProtectedMask not NULL, get protected Mask. +// 4. If *ProtectedEdgeLevel not NULL, get protected trigger +// level. +// 5. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS GetMask ( + IN EFI_LEGACY_8259_PROTOCOL *This, + OUT UINT16 *LegacyMask OPTIONAL, + OUT UINT16 *LegacyEdgeLevel OPTIONAL, + OUT UINT16 *ProtectedMask OPTIONAL, + OUT UINT16 *ProtectedEdgeLevel OPTIONAL ) +{ + if (LegacyMask) *LegacyMask = gIrqMask[0]; + if (LegacyEdgeLevel) *LegacyEdgeLevel = gIrqTrigger[0]; + if (ProtectedMask) *ProtectedMask = gIrqMask[1]; + if (ProtectedEdgeLevel) *ProtectedEdgeLevel = gIrqTrigger[1]; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SetMask +// +// Description: Set the Master/Slave Irq Mask, Irq Level for Legacy real mode +// and protected mode. +// +// Input: *This - Pointer to this object +// *LegacyMask - Legacy mode interrupt mask +// *LegacyEdgeLevel - Legacy mode edge/level trigger value +// *ProtectedMask - Protected mode interrupt mask +// *ProtectedEdgeLevel - Protected mode edge/level trigger value +// +// Output: EFI_SUCCESS - Set irq mask/level. +// +// Notes: Here is the control flow of this function: +// 1. If *LegacyMask not NULL, set legacy mask variable. +// 2. If *LegacyEdgeLevel not NULL, set legacy Trigger Level +// variable. +// 3. If *ProtectedMask not NULL, set protected mask variable. +// 4. If *ProtectedEdgeLevel not NULL, set protected trigger +// level variable. +// 5. Call function to program 8259 with mask/trigger of +// current mode. +// 6. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SetMask ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT16 *LegacyMask OPTIONAL, + IN UINT16 *LegacyEdgeLevel OPTIONAL, + IN UINT16 *ProtectedMask OPTIONAL, + IN UINT16 *ProtectedEdgeLevel OPTIONAL ) +{ + if (LegacyMask) gIrqMask[0] = *LegacyMask; + if (LegacyEdgeLevel) gIrqTrigger[0] = *LegacyEdgeLevel; + if (ProtectedMask) gIrqMask[1] = *ProtectedMask; + if (ProtectedEdgeLevel) gIrqTrigger[1] = *ProtectedEdgeLevel; + + ProgramIrqMaskTrigger(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SetMode +// +// Description: Sets the interrupt mode operation to legacy or protected. +// New mask and edge/level status can be provided as input +// +// Input: *This - Pointer to this object +// Mode - Interrupt mode setting +// *Mask - New interrupt mask for this mode +// *EdgeLevel - New edge/level trigger value for this mode +// +// Output: EFI_SUCCESS - Set mode was successful +// +// Notes: Here is the control flow of this function: +// 1. If invalid mode, return EFI_INVALID_PARAMETER. +// 2. If *Mask not NULL, set mode mask variable. +// 3. If *EdgeLevel not NULL, set mode trigger level variable. +// 4. Call function to program 8259 with mask/trigger of +// current mode. +// 5. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SetMode ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_MODE Mode, + IN UINT16 *Mask OPTIONAL, + IN UINT16 *EdgeLevel OPTIONAL ) +{ + if (Mode >= Efi8259MaxMode) return EFI_INVALID_PARAMETER; +#if defined (HPET_INTERRUPT_TRIGGER) && (HPET_INTERRUPT_TRIGGER == 1) + if (Mode == Efi8259LegacyMode) + gTimerConfiguration.Bits.InterruptEnable = 0; + else // Efi8259ProtectedMode + gTimerConfiguration.Bits.InterruptEnable = 1; + + HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE, gTimerConfiguration.Uint64); +#endif + + gMode = Mode; + if (Mask) gIrqMask[Mode] = *Mask; + if (EdgeLevel) gIrqTrigger[Mode] = *EdgeLevel; + + ProgramIrqMaskTrigger(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetVector +// +// Description: Returns the vector number for the requested IRQ +// +// Input: This - Legacy8259 protocol object +// Irq - IRQ number for which vector is needed +// Vector - Vector value is returned in this pointer +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Invalid IRQ. +// EFI_SUCCESS - Get Irq Vector for IRQ. +// +// Notes: Here is the control flow of this function: +// 1. If invalid IRQ, return EFI_INVALID_PARAMETER. +// 2. If Set *Vector to Irq base + interrupt offset. +// 3. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS GetVector ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + OUT UINT8 *Vector ) +{ + if ((UINT8)Irq >= (UINT8)Efi8259IrqMax) return EFI_INVALID_PARAMETER; + *Vector = (Irq <= Efi8259Irq7) ? gMasterBase + Irq : gSlaveBase + Irq - 8; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EnableIrq +// +// Description: Enable the Interrupt controllers to respond in a specific IRQ. +// +// Input: This - Legacy8259 protocol object +// Irq - IRQ that has to be enabled +// LevelTriggered - Trigger mechanism (level or edge) for this +// IRQ +// +// Output: EFI_STATUS +// EFI_SUCCESS - Interrupt on the interrupt +// controllers was enabled. +// EFI_INVALID_PARAMETER - Interrupt not existent. +// The 8259 master/slave supports +// IRQ 0-15. +// +// Notes: Here is the control flow of this function: +// 1. Check if IRQ is valid. If not, return EFI_INVALID_PARAMETER +// 2. Clear interrupt mask bit in variable of current mode. +// 3. Set/Clear bit of trigger level variable of current mode. +// 4. Program mask/trigger. +// 5. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EnableIrq ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + IN BOOLEAN LevelTriggered ) +{ + if ((UINT8)Irq > (UINT8)15) return EFI_INVALID_PARAMETER; + + gIrqMask[gMode] &= (UINT16)(~(1 << Irq)); // Clear mask for the Irq. + + gIrqTrigger[gMode] &= (UINT16)(~(1 << Irq)); // Mask Irq to change. + + // Change irq bit, 0 = edge, 1 = level. + if (LevelTriggered) gIrqTrigger[gMode] |= (1 << Irq); + + ProgramIrqMaskTrigger(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DisableIrq +// +// Description: Disable the Interrupt controllers to stop responding to +// a specific IRQ. +// +// Input: This - Legacy8259 protocol object +// Irq - IRQ that has to be disabled +// +// Output: EFI_STATUS +// EFI_SUCCESS - Interrupt on the interrupt +// controllers was enabled. +// EFI_INVALID_PARAMETER - Interrupt not existent. +// The 8259 master/slave supports +// IRQ 0-15. +// +// Notes: Here is the control flow of this function: +// 1. Check if IRQ is valid. If not, return EFI_INVALID_PARAMETER +// 2. Set interrupt mask bit in variable of current mode. +// 3. Program mask/trigger. +// 4. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS DisableIrq ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq ) +{ + if ((UINT8)Irq > (UINT8)15) return EFI_INVALID_PARAMETER; + + gIrqMask[gMode] |= (1 << Irq); // Set mask for the IRQ. + + ProgramIrqMaskTrigger(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetInterruptLine +// +// Description: Get IRQ vector asigned to PCI card. +// +// Input: This - Pointer to this object +// PciHandle - PCI handle for this device +// Vector - Interrupt vector this device +// +// Output: EFI_STATUS +// EFI_SUCCESS - Vector returned. +// EFI_INVALID_PARAMETER - Invalid PciHandle. +// +// Notes: Here is the control flow of this function: +// 1. Get Handle of PciIo installed on PciHandle. +// 2. If PciIo not installed, return EFI_INVALID_DEVICE. +// 3. Set *vector to Irq vector programmed into card. +// 4. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS GetInterruptLine ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_HANDLE PciHandle, + OUT UINT8 *Vector ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + + Status = pBS->HandleProtocol( PciHandle, \ + &gEfiPciIoProtocolGuid, \ + &PciIo ); + if (EFI_ERROR(Status)) return EFI_INVALID_PARAMETER; + + // Read vector from card. + PciIo->Pci.Read( PciIo, \ + EfiPciIoWidthUint8, \ + PCI_INTLINE, \ + 1, \ + Vector ); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EndOfInterrupt +// +// Description: Send end of interrupt command to interrupt controller(s). +// +// Input: This - Pointer to this object +// Irq - IRQ number for this EOI has to be sent +// +// Output: EFI_STATUS +// EFI_SUCCESS - EOI command sent to controller(s) +// EFI_INVALID_PARAMETER - Interrupt not existent. The 8259 +// master/slave supports IRQ 0-15. +// +// Notes: Here is the control flow of this function: +// 1. Check if IRQ is valid. If not, return EFI_INVALID_PARAMETER +// 2. If Irq >= 8, then Send EOI to slave controller. +// 3. Send EOI to master controller. (This is for both master / +// slave IRQs) +// 4. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EndOfInterrupt ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq ) +{ + if (Irq > 15) return EFI_INVALID_PARAMETER; + + if (Irq >= 8) { // If Slave, send EOI to slave first. + // Send Slave EOI + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, EOI_COMMAND); + } + // Send Master EOI + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, EOI_COMMAND); + + return EFI_SUCCESS; +} + +EFI_LEGACY_8259_PROTOCOL gLegacy8259Protocol = { + SetVectorBase, + GetMask, SetMask, + SetMode, + GetVector, + EnableIrq, DisableIrq, + GetInterruptLine, + EndOfInterrupt +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: Initialize8259 +// +// Description: Initialize 8259 Interrupt Controller. +// +// Input: ImageHandle - Image handle for this driver +// SystemTable - Pointer to the sytem table +// +// Output: EFI_STATUS +// EFI_SUCCESS - The legacy 8259 Protocols were +// installed. +// EFI_ALREADY_STARTED - The legacy 8259 Protocol was passed +// in that is already present in the +// handle database. +// EFI_OUT_OF_RESOURCES - There was not enought memory in +// pool to install all the protocols. +// +// Notes: Here is the control flow of this function: +// 1. Initialize the Cpu setting vector bases. +// 2. Set Cpu Mode, mask, and trigger level. +// 3. Install Legacy 8259 Interface. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS Initialize8259 ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + UINT16 Mask = 0xffff; // Mask all interrupts. + UINT16 EdgeLevel = 0x00; // Set all edge. + BOOLEAN IntState = CPULib_GetInterruptState(); + + CPULib_DisableInterrupt(); + + // Set the protected mode vectors for MASTER and SLAVE PICs + SetVectorBase(0, MASTER_INTERRUPT_BASE, SLAVE_INTERRUPT_BASE); + SetMode(0, Efi8259ProtectedMode, &Mask, &EdgeLevel); + + // Install the Legacy8259Protocol + Status = pBS->InstallMultipleProtocolInterfaces( \ + &ImageHandle, \ + &gEfiLegacy8259ProtocolGuid, \ + &gLegacy8259Protocol, \ + NULL ); + if (EFI_ERROR(Status)) return Status; + + if(IntState)CPULib_EnableInterrupt(); + + return EFI_SUCCESS; +} + + +// Protocols that are installed +DXE_PCH_PLATFORM_POLICY_PROTOCOL mPchPolicyData = { 0 }; +PCH_DEVICE_ENABLING mPchDeviceEnabling = { 0 }; +PCH_USB_CONFIG mPchUsbConfig = { 0 }; +PCH_PCI_EXPRESS_CONFIG mPchPciExpressConfig = { 0 }; +PCH_SATA_CONFIG mPchSataConfig = { 0 }; +PCH_AZALIA_CONFIG mPchAzaliaConfig = { 0 }; +PCH_SMBUS_CONFIG mPchSmbusConfig = { 0 }; +PCH_MISC_PM_CONFIG mPchMiscPmConfig = { 0 }; +PCH_IO_APIC_CONFIG mPchIoApicConfig = { 0 }; +PCH_DEFAULT_SVID_SID mPchDefaultSvidSid = { 0 }; +PCH_LOCK_DOWN_CONFIG mPchLockDownConfig = { 0 }; +PCH_THERMAL_CONFIG mPchThermalConfig = { 0 }; +PCH_LPC_HPET_CONFIG mPchHpetConfig = { 0 }; +PCH_LPC_SIRQ_CONFIG mSerialIrqConfig = { 0 }; +PCH_DMI_CONFIG mPchDmiConfig = { 0 }; +PCH_PWR_OPT_CONFIG mPchPwrOptConfig = { 0 }; +PCH_MISC_CONFIG mPchMiscConfig = { 0 }; +PCH_AUDIO_DSP_CONFIG mPchAudioDspConfig = { 0 }; +PCH_SERIAL_IO_CONFIG mSerialIoConfig = { 0 }; + +UINT8 mSmbusRsvdAddresses[DIMM_SLOT_NUM] = { + DIMM1_SMBUS_ADDRESS, + DIMM2_SMBUS_ADDRESS, + DIMM3_SMBUS_ADDRESS, + DIMM4_SMBUS_ADDRESS +}; + +PCH_PCIE_DEVICE_ASPM_OVERRIDE mDevAspmOverride[] = { + // + // Intel PRO/Wireless + // + {0x8086, 0x422b, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x422c, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x4238, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x4239, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel WiMAX/WiFi Link + // + {0x8086, 0x0082, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0085, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0083, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0084, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0086, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0087, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0088, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0089, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x008F, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0090, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Crane Peak WLAN NIC + // + {0x8086, 0x08AE, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x08AF, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Crane Peak w/BT WLAN NIC + // + {0x8086, 0x0896, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0897, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Kelsey Peak WiFi, WiMax + // + {0x8086, 0x0885, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0886, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Centrino Wireless-N 105 + // + {0x8086, 0x0894, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0895, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Centrino Wireless-N 135 + // + {0x8086, 0x0892, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0893, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Centrino Wireless-N 2200 + // + {0x8086, 0x0890, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0891, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Centrino Wireless-N 2230 + // + {0x8086, 0x0887, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x0888, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel Centrino Wireless-N 6235 + // + {0x8086, 0x088E, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x088F, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel CampPeak 2 Wifi + // + {0x8086, 0x08B5, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + {0x8086, 0x08B6, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}, + // + // Intel WilkinsPeak 1 Wifi + // + {0x8086, 0x08B3, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003}, + {0x8086, 0x08B3, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003}, + {0x8086, 0x08B4, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003}, + {0x8086, 0x08B4, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003}, + // + // Intel Wilkins Peak 2 Wifi + // + {0x8086, 0x08B1, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003}, + {0x8086, 0x08B1, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003}, + {0x8086, 0x08B2, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003}, + {0x8086, 0x08B2, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003}, + // + // Intel Wilkins Peak PF Wifi + // + {0x8086, 0x08B0, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF} + +#if defined OEM_SB_PCIE_ASPM_OVERRIDE_TABLE + OEM_SB_PCIE_ASPM_OVERRIDE_TABLE, +#endif +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InstallDxePchPlatformPolicy +// +// Description: Install Dxe Pch Platform Policy. +// +// Input: ImageHandle - Image handle +// SystemTable - Pointer to the system table +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +InstallDxePchPlatformPolicy (VOID) +{ + EFI_HANDLE Handle; + EFI_STATUS Status; + UINT8 PortIndex; + UINT8 PortDataOut = 0; + UINTN VariableSize; + EFI_GUID SetupGuid = SETUP_GUID; + SETUP_DATA SetupData; + UINT32 SetupDataAttributes = 0; + UINT32 PchSpiStrp9; +#if defined iME_SUPPORT && iME_SUPPORT + ME_BIOS_EXTENSION_SETUP MeBiosExtensionSetupData; + EFI_GUID EfiMeBiosExtensionSetupGuid = EFI_ME_BIOS_EXTENSION_SETUP_GUID; + CHAR16 EfiMeBiosExtensionSetupName[] = EFI_ME_BIOS_EXTENSION_SETUP_VARIABLE_NAME; +#endif + UINT16 GpioBase = 0; + UINT16 UsbPortLength[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_PORTS_LENGTH}; + UINT8 UsbPortLocation[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_PORT_LOCATION_CONFIG}; + UINT8 UsbOverCurrentMapping[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_OVER_CURRENT_MAPPING_SETTINGS}; + UINT8 ULTUsbOverCurrentMapping[LPTLP_USB_MAX_PHYSICAL_PORTS]= {ULT_USB_OVER_CURRENT_MAPPING_SETTINGS}; //[EIP118480] + UINT8 Usb30OverCurrentMapping[LPTH_XHCI_MAX_USB3_PORTS] = {USB30_OVER_CURRENT_MAPPING_SETTINGS}; + UINT16 LpcDeviceId; + EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; + EFI_GUID gEfiGlobalNvsAreaProtocolGuid = EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID; + PCH_SERIES PchSeries = GetPchSeries(); + UINT32 GbePortSel; +#if defined(RC_PORT_0) && (RC_PORT_0 == 1) + BOOLEAN PcieRPMap[] = { RC_PORT_0, RC_PORT_1, RC_PORT_2, RC_PORT_3, + RC_PORT_4, RC_PORT_5, RC_PORT_6, RC_PORT_7 }; +#endif + static EFI_GUID guidHob = HOB_LIST_GUID; + EFI_HOB_HANDOFF_INFO_TABLE *pHit; + + // + // Locate the Global NVS Protocol. + // + Status = pBS->LocateProtocol ( + &gEfiGlobalNvsAreaProtocolGuid, + NULL, + &GlobalNvsArea + ); + ASSERT_EFI_ERROR (Status); + + LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID); + + // Read the SB Platform Data + VariableSize = sizeof (SB_PLATFORM_DATA); + Status = pRS->GetVariable ( + L"SbPlatformData", + &SetupGuid, + NULL, + &VariableSize, + &SbPlatformData + ); + + VariableSize = sizeof (SETUP_DATA); + Status = pRS->GetVariable ( + L"Setup", + &SetupGuid, + &SetupDataAttributes, + &VariableSize, + &SetupData + ); + ASSERT_EFI_ERROR (Status); + + if ((READ_MEM16_RCRB(R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) { + RESET_MEM32_RCRB(R_PCH_SPI_FDOC, (UINT32) (B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)); + SET_MEM32_RCRB(R_PCH_SPI_FDOC, (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP9)); + PchSpiStrp9 = READ_MEM32_RCRB(R_PCH_SPI_FDOD); + + // Get GbePortSel + GbePortSel = (UINT8)(( PchSpiStrp9 & B_PCH_SPI_STRP9_GBE_PCIE_PSC) >> N_PCH_SPI_STRP9_GBE_PCIE_PSC); + + // Get GbE slot number (zero based value) from descriptor and Get Subtractive decode enable bit from descriptor + if ( PchSeries == PchLp ) { + switch(GbePortSel) { + case 0: + SbPlatformData.GbePciePortNum = 2; // Root Port 3 + break; + case 1: + SbPlatformData.GbePciePortNum = 3; // Root Port 4 + break; + case 2: // Root Port 5, lane 0 + case 3: // Root Port 5, lane 1 + case 4: // Root Port 5, lane 2 + case 5: // Root Port 5, lane 3 + SbPlatformData.GbePciePortNum = 4; + break; + default: + SbPlatformData.GbePciePortNum = GbePortSel; + break; + } + } else { + SbPlatformData.GbePciePortNum = GbePortSel; + } + + SbPlatformData.PcieSBDE = (UINT8)(( PchSpiStrp9 & + B_PCH_SPI_STRP9_PCIE_SBDE_EN) >> + N_PCH_SPI_STRP9_PCIE_SBDE_EN); + } else { + SbPlatformData.GbePciePortNum = 5; + SbPlatformData.PcieSBDE = 0; + } + + // General intialization + mPchPolicyData.Revision = DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7; + mPchPolicyData.BusNumber = 0; + mPchPolicyData.DeviceEnabling = &mPchDeviceEnabling; + mPchPolicyData.UsbConfig = &mPchUsbConfig; + mPchPolicyData.PciExpressConfig = &mPchPciExpressConfig; + mPchPolicyData.SataConfig = &mPchSataConfig; + mPchPolicyData.AzaliaConfig = &mPchAzaliaConfig; + mPchPolicyData.SmbusConfig = &mPchSmbusConfig; + mPchPolicyData.MiscPmConfig = &mPchMiscPmConfig; + mPchPolicyData.IoApicConfig = &mPchIoApicConfig; + mPchPolicyData.DefaultSvidSid = &mPchDefaultSvidSid; + mPchPolicyData.LockDownConfig = &mPchLockDownConfig; + mPchPolicyData.ThermalConfig = &mPchThermalConfig; + mPchPolicyData.HpetConfig = &mPchHpetConfig; + mPchPolicyData.SerialIrqConfig = &mSerialIrqConfig; + mPchPolicyData.DmiConfig = &mPchDmiConfig; + mPchPolicyData.PwrOptConfig = &mPchPwrOptConfig; + mPchPolicyData.MiscConfig = &mPchMiscConfig; + mPchPolicyData.AudioDspConfig = &mPchAudioDspConfig; + mPchPolicyData.SerialIoConfig = &mSerialIoConfig; + + // PCH BIOS Spec Section 5.1.1 security recommendations, + // Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit. Enabling this bit + // will mitigate malicious software attempts to replace the system BIOS option ROM with its own code. + // We always enable this as a platform policy. + mPchPolicyData.LockDownConfig->BiosInterface = gSbSetupData->BiosInterfaceLock; + + // Intel strongly recommends that BIOS enables SMI_LOCK (B0:D31:F0:Offset A0h [4]=1) + // which prevent writes to the Global SMI Enable bit (GLB_SMI_EN PMBASE + 30h Bit + // [0]). Enabling this bit will mitigate malicious software attempts to gain system management + // mode privileges. + // We always enable this as a platform policy. + mPchPolicyData.LockDownConfig->GlobalSmi = gSbSetupData->SmiLock; + + mPchPolicyData.LockDownConfig->GpioLockDown = gSbSetupData->GpioLock; + mPchPolicyData.LockDownConfig->RtcLock = gSbSetupData->RtcLock; + + // + // While BiosLock is enabled, BIOS can only be modified from SMM after ExitPmAuth. + // + mPchPolicyData.LockDownConfig->BiosLock = gSbSetupData->BiosLock; + // [EIP113678] >> + pHit = GetEfiConfigurationTable(pST, &guidHob); +// if (pHit && ((pHit->BootMode == BOOT_IN_RECOVERY_MODE) || \ +// (pHit->BootMode == BOOT_ON_FLASH_UPDATE))) { +// mPchPolicyData.LockDownConfig->BiosLock = 0; +// } + // <<[EIP113678] +// mPchPolicyData.LockDownConfig->PchBiosLockSwSmiNumber = SW_SMI_BIOS_LOCK; // Deprecated from Revision 2 !!! DO NOT USE !!! + mPchPolicyData.LockDownConfig->PchBiosLockIoTrapAddress = 0; // Dynamic updated by IoTrap driver. + + // DeviceEnables + mPchPolicyData.DeviceEnabling->Lan = gSbSetupData->PchLan; + if ((READ_MEM16_RCRB(R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) { + if ((PchSpiStrp9 & B_PCH_SPI_STRP9_GBE_PCIE_EN) == 0) { + mPchPolicyData.DeviceEnabling->Lan = PCH_DEVICE_DISABLE; + } + } + mPchPolicyData.DeviceEnabling->Azalia = gSbSetupData->PchAzalia; + mPchPolicyData.DeviceEnabling->Sata = gSbSetupData->PchSata; + mPchPolicyData.DeviceEnabling->Smbus = PCH_DEVICE_ENABLE; + mPchPolicyData.DeviceEnabling->PciClockRun = gSbSetupData->PchPciClockRun; + mPchPolicyData.DeviceEnabling->Display = gSbSetupData->PchDisplay; + mPchPolicyData.DeviceEnabling->Crid = gSbSetupData->PchEnableCrid; + if (PchSeries == PchLp) { + SbPlatformData.LPTType = 1; + mPchPolicyData.DeviceEnabling->SerialIoDma = gSbSetupData->LpssDmaEnable; + mPchPolicyData.DeviceEnabling->SerialIoI2c0 = gSbSetupData->LpssI2c0Enable; + mPchPolicyData.DeviceEnabling->SerialIoI2c1 = gSbSetupData->LpssI2c1Enable; + mPchPolicyData.DeviceEnabling->SerialIoSpi0 = gSbSetupData->LpssSpi0Enable; + mPchPolicyData.DeviceEnabling->SerialIoSpi1 = gSbSetupData->LpssSpi1Enable; + mPchPolicyData.DeviceEnabling->SerialIoUart0 = gSbSetupData->LpssUart0Enable; + mPchPolicyData.DeviceEnabling->SerialIoUart1 = gSbSetupData->LpssUart1Enable; + mPchPolicyData.DeviceEnabling->SerialIoSdio = gSbSetupData->LpssSdioEnable; + mPchPolicyData.DeviceEnabling->AudioDsp = gSbSetupData->ADspEnable; + if( mPchPolicyData.DeviceEnabling->AudioDsp == PCH_DEVICE_ENABLE) + mPchPolicyData.DeviceEnabling->Azalia = PCH_DEVICE_DISABLE; + } else { + SbPlatformData.LPTType = 0; + mPchPolicyData.DeviceEnabling->SerialIoDma = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->SerialIoI2c0 = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->SerialIoI2c1 = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->SerialIoSpi0 = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->SerialIoSpi1 = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->SerialIoUart0 = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->SerialIoUart1 = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->SerialIoSdio = PCH_DEVICE_DISABLE; + mPchPolicyData.DeviceEnabling->AudioDsp = PCH_DEVICE_DISABLE; + } +#if defined iAMT_SUPPORT && iAMT_SUPPORT + mPchPolicyData.UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE; //gSbSetupData->KvmEnabled; + mPchPolicyData.UsbConfig->Ehci2Usbr = PCH_DEVICE_DISABLE; //gSbSetupData->KvmEnabled; +#else + mPchPolicyData.UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE; + mPchPolicyData.UsbConfig->Ehci2Usbr = PCH_DEVICE_DISABLE; +#endif + +#if defined iME_SUPPORT && iME_SUPPORT + VariableSize = sizeof (MeBiosExtensionSetupData); + Status = pRS->GetVariable ( + EfiMeBiosExtensionSetupName, + &EfiMeBiosExtensionSetupGuid, + NULL, + &VariableSize, + &MeBiosExtensionSetupData ); + if (!EFI_ERROR (Status)) { + mPchPolicyData.UsbConfig->Ehci1Usbr |= (MeBiosExtensionSetupData.KvmEnable & KVM_ENABLE); + mPchPolicyData.UsbConfig->Ehci2Usbr |= (MeBiosExtensionSetupData.KvmEnable & KVM_ENABLE); + } +#endif + + if (PchSeries == PchLp) { + if ((gSbSetupData->PchUsb20[0] == 0) && + (gSbSetupData->PchUsb30Mode == 0)) { + gDisableAllUsbControllers = TRUE; + } + } else { + if ((gSbSetupData->PchUsb20[0] == 0) && + (gSbSetupData->PchUsb20[1] == 0) && + (gSbSetupData->PchUsb30Mode == 0)) { + gDisableAllUsbControllers = TRUE; + } + } + + mPchPolicyData.UsbConfig->Usb20Settings[0].Enable = gSbSetupData->PchUsb20[0]; + if (PchSeries == PchLp) { + mPchPolicyData.UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_DISABLE; + } else { + mPchPolicyData.UsbConfig->Usb20Settings[1].Enable = gSbSetupData->PchUsb20[1]; + } + + if ((mPchPolicyData.UsbConfig->Usb20Settings[0].Enable == PCH_DEVICE_DISABLE) && + (mPchPolicyData.UsbConfig->Usb20Settings[1].Enable == PCH_DEVICE_DISABLE)) { + // Force enable EHCI#1 & 2 then disable them in InitSbRegsBeforeBoot() + // if all USB controllers are disabled. + // USB Device 29 configuration + mPchPolicyData.UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_ENABLE; + if (PchSeries != PchLp) { + // USB Device 26 configuration + mPchPolicyData.UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_ENABLE; + } + } + + mPchPolicyData.UsbConfig->UsbPerPortCtl = gSbSetupData->PchUsbPerPortCtl; + + for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) { + + if (gSbSetupData->PchUsbPerPortCtl != PCH_DEVICE_DISABLE) { + mPchPolicyData.UsbConfig->Port30Settings[PortIndex].Enable = gSbSetupData->PchUsb30Port[PortIndex]; + } else { + mPchPolicyData.UsbConfig->Port30Settings[PortIndex].Enable = PCH_DEVICE_ENABLE; + } + } + for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) { + + if (gSbSetupData->PchUsbPerPortCtl != PCH_DEVICE_DISABLE) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Enable = gSbSetupData->PchUsbPort[PortIndex]; + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Enable = PCH_DEVICE_ENABLE; + } + + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength = UsbPortLength[PortIndex]; + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location = UsbPortLocation[PortIndex]; + + if (PchSeries == PchH) { + mPchPolicyData.UsbConfig->Usb20OverCurrentPins[PortIndex] = UsbOverCurrentMapping[PortIndex]; //[EIP118480] + if (IS_PCH_LPT_LPC_DEVICE_ID_DESKTOP (LpcDeviceId)) { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; //Back Panel + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 3; //Front Panel + } + + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x80) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 7.9" + } else if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x130) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 8"-12.9" + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 4; //Back Panel, 13" onward + } + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Front Panel + } + } else if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology + } else if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock + } else { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7" + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward + } + } + + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology + } else if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5" + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward + } + } else { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10" + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward + } + } + } + } else if (PchSeries == PchLp) { + mPchPolicyData.UsbConfig->Usb20OverCurrentPins[PortIndex] = ULTUsbOverCurrentMapping[PortIndex]; //[EIP118480] + if ((mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) || + (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7" + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward + } + } else if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology + } + + if ((mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) || + (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10" + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward + } + } else if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + if (mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5" + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward + } + } else { + mPchPolicyData.UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology + } + } + } + + // + // PCH BIOS Spec Section 13.1 xHCI controller options in Reference Code + // Please refer to Table 13-1 in PCH BIOS Spec for USB Port Operation with no xHCI + // pre-boot software. + // Please refer to Table 13-2 in PCH BIOS Spec for USB Port Operation with xHCI + // pre-boot software. + // + // The xHCI modes that available in BIOS are: + // Disabled - forces only USB 2.0 to be supported in the OS. The xHCI controller is turned off + // and hidden from the PCI space. + // Enabled - allows USB 3.0 to be supported in the OS. The xHCI controller is turned on. The + // shareable ports are routed to the xHCI controller. OS needs to provide drivers + // to support USB 3.0. + // Auto - This mode uses ACPI protocol to provide an option that enables the xHCI controller + // and reroute USB ports via the _OSC ACPI method call. Note, this mode switch requires + // special OS driver support for USB 3.0. + // Smart Auto - This mode is similar to Auto, but it adds the capability to route the ports to xHCI + // or EHCI according to setting used in previous boots (for non-G3 boot) in the pre-boot + // environment. This allows the use of USB 3.0 devices prior to OS boot. Note, this mode + // switch requires special OS driver support for USB 3.0 and USB 3.0 software available + // in the pre-boot enviroment. + // Recommendations: + // - If BIOS supports xHCI pre-boot driver then use Smart Auto mode as default + // - If BIOS does not support xHCI pre-boot driver then use AUTO mode as default + // + mPchPolicyData.UsbConfig->Usb30Settings.Mode = gSbSetupData->PchUsb30Mode; + + // + // Automatically disable EHCI when XHCI Mode is Enabled to save power. + // + if (mPchPolicyData.UsbConfig->Usb30Settings.Mode == 1) { + mPchPolicyData.UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_DISABLE; + if (PchSeries == PchH) { + mPchPolicyData.UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_DISABLE; + } + } + + if (gSbSetupData->PchUsb30Mode == 3) { + mPchPolicyData.UsbConfig->Usb30Settings.PreBootSupport = 1; + } else { + mPchPolicyData.UsbConfig->Usb30Settings.PreBootSupport = gSbSetupData->PchUsb30PreBootSupport; + } +// mPchPolicyData.UsbConfig->Usb30Settings.XhciStreams = gSbSetupData->XhciStreams; + + if (gSbSetupData->PchUsb30Mode == 4) { + mPchPolicyData.UsbConfig->Usb30Settings.Mode = 2; + mPchPolicyData.UsbConfig->Usb30Settings.ManualMode = PCH_DEVICE_ENABLE; + } else { + mPchPolicyData.UsbConfig->Usb30Settings.ManualMode = PCH_DEVICE_DISABLE; + } + + // + // XhciIdleL1 can be set to disable for LPT-LP Ax stepping to workaround USB3 hot plug will fail after 1 hot plug removal. + // + mPchPolicyData.UsbConfig->Usb30Settings.XhciIdleL1 = gSbSetupData->PchUsb30IdleL1; + + // + // Btcg is for enabling/disabling trunk clock gating. + // + mPchPolicyData.UsbConfig->Usb30Settings.Btcg = gSbSetupData->PchUsb30Btcg; + + for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) { + if (gSbSetupData->PchUsb20PinRoute == 1){ + mPchPolicyData.UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = 0; + } else if (gSbSetupData->PchUsb20PinRoute == 2){ + mPchPolicyData.UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = 1; + } else { + mPchPolicyData.UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = gSbSetupData->ManualModeUsb20PerPinRoute[PortIndex]; + } + } + + for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) { + if (gSbSetupData->PchUsb30PinEnable == 1){ + mPchPolicyData.UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = 0; + } else if (gSbSetupData->PchUsb30PinEnable == 2){ + mPchPolicyData.UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = 1; + } else { + mPchPolicyData.UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = gSbSetupData->ManualModeUsb30PerPinEnable[PortIndex]; + } + mPchPolicyData.UsbConfig->Usb30OverCurrentPins[PortIndex] = Usb30OverCurrentMapping[PortIndex]; + } + mPchPolicyData.UsbConfig->UsbPrecondition = gSbSetupData->UsbPrecondition; + +#ifdef USB_PRECONDITION_ENABLE_FLAG + /// + /// Update Precondition option for S4 resume. + /// Skip Precondition for S4 resume in case this boot may not connect BIOS USB driver. + /// If BIOS USB driver will be connected always for S4, then disable below update. + /// To keep consistency during boot, must enabled or disabled below function in both PEI and DXE + /// PlatformPolicyInit driver. + /// + if (mPchUsbConfig.UsbPrecondition == TRUE) { + if (pHit && (pHit->BootMode == BOOT_ON_S4_RESUME)) { + mPchUsbConfig.UsbPrecondition = FALSE; + TRACE((-1, "BootMode is BOOT_ON_S4_RESUME, disable Precondition\n")); + } + } +#endif // USB_PRECONDITION_ENABLE_FLAG + + GlobalNvsArea->Area->XhciMode = (UINT8)gSbSetupData->PchUsb30Mode; + + // PCI Express related settings from setup variable + mPchPolicyData.PciExpressConfig->RootPortClockGating = gSbSetupData->PcieClockGating; + mPchPolicyData.PciExpressConfig->DevAspmOverride = mDevAspmOverride; + mPchPolicyData.PciExpressConfig->NumOfDevAspmOverride = sizeof (mDevAspmOverride) / sizeof (PCH_PCIE_DEVICE_ASPM_OVERRIDE); + mPchPolicyData.PciExpressConfig->RootPortFunctionSwapping = gSbSetupData->RootPortFunctionSwapping; + + mPchPolicyData.PciExpressConfig->TempRootPortBusNumMin = PCH_PCIE_TEMP_RP_BUS_NUM_MIN; + mPchPolicyData.PciExpressConfig->TempRootPortBusNumMax = PCH_PCIE_TEMP_RP_BUS_NUM_MAX; + + for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) { +#if defined(RC_PORT_0) && (RC_PORT_0 == 1) + if (PcieRPMap[PortIndex]) + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].Enable = gSbSetupData->PcieRootPortEn[PortIndex]; + else +#endif + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].Enable = PCH_DEVICE_DISABLE; + + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].SlotImplemented = gSbSetupData->PcieRootPortEn[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].FunctionNumber = PortIndex; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].PhysicalSlotNumber = PortIndex; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].Aspm = gSbSetupData->PcieRootPortAspm[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].PmSci = gSbSetupData->PcieRootPortPMCE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].HotPlug = gSbSetupData->PcieRootPortHPE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].AdvancedErrorReporting = PCH_PCIE_ADVANCED_ERROR_REPORTING; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].UnsupportedRequestReport = gSbSetupData->PcieRootPortURE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].FatalErrorReport = gSbSetupData->PcieRootPortFEE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].NoFatalErrorReport = gSbSetupData->PcieRootPortNFE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].CorrectableErrorReport = gSbSetupData->PcieRootPortCEE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].PmeInterrupt = PCH_PCIE_PME_INTERRUPT; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].SystemErrorOnFatalError = gSbSetupData->PcieRootPortSFE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].SystemErrorOnNonFatalError = gSbSetupData->PcieRootPortSNE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].SystemErrorOnCorrectableError = gSbSetupData->PcieRootPortSCE[PortIndex]; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].CompletionTimeout = PCH_PCIE_COMPLETION_TIME_OUT; + mPchPolicyData.PciExpressConfig->RootPort[PortIndex].L1Substates = gSbSetupData->PcieRootPortL1S[PortIndex]; + } + + if (SbPlatformData.PcieSBDE) { + mPchPolicyData.PciExpressConfig->EnableSubDecode = gSbSetupData->PcieRootPortSBDE; + mPchPolicyData.PciExpressConfig->PchPcieSbdePort = gSbSetupData->PcieSBDEPort; + } else { + mPchPolicyData.PciExpressConfig->EnableSubDecode = PCH_DEVICE_DISABLE; + mPchPolicyData.PciExpressConfig->PchPcieSbdePort = 0; + } + + // SATA configuration + for (PortIndex = 0; PortIndex < GetPchMaxSataPortNum (); PortIndex++) { + if ((gSbSetupData->SataInterfaceMode) == 0) { // for IDE + mPchPolicyData.SataConfig->PortSettings[PortIndex].Enable = PCH_DEVICE_ENABLE; + } else { + mPchPolicyData.SataConfig->PortSettings[PortIndex].Enable = gSbSetupData->SataPort[PortIndex]; + } + + mPchPolicyData.SataConfig->PortSettings[PortIndex].HotPlug = gSbSetupData->SataHotPlug[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].InterlockSw = gSbSetupData->SataMechanicalSw[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].External = gSbSetupData->ExternalSata[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].SolidStateDrive = gSbSetupData->SolidStateDrive[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].SpinUp = gSbSetupData->SataSpinUp[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].DevSlp = gSbSetupData->SataDevSlp[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].EnableDitoConfig = gSbSetupData->EnableDitoConfig[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].DmVal = gSbSetupData->DmVal[PortIndex]; + mPchPolicyData.SataConfig->PortSettings[PortIndex].DitoVal = gSbSetupData->DitoVal[PortIndex]; + } + GlobalNvsArea->Area->DVS0 = gSbSetupData->SataDevSlp[0]; + GlobalNvsArea->Area->DVS1 = gSbSetupData->SataDevSlp[1]; + GlobalNvsArea->Area->DVS2 = gSbSetupData->SataDevSlp[2]; + GlobalNvsArea->Area->DVS3 = gSbSetupData->SataDevSlp[3]; + + mPchPolicyData.SataConfig->RaidAlternateId = gSbSetupData->SataAlternateId; + mPchPolicyData.SataConfig->Raid0 = gSbSetupData->SataRaidR0; + mPchPolicyData.SataConfig->Raid1 = gSbSetupData->SataRaidR1; + mPchPolicyData.SataConfig->Raid10 = gSbSetupData->SataRaidR10; + mPchPolicyData.SataConfig->Raid5 = gSbSetupData->SataRaidR5; + mPchPolicyData.SataConfig->Irrt = gSbSetupData->SataRaidIrrt; + mPchPolicyData.SataConfig->OromUiBanner = gSbSetupData->SataRaidOub; + mPchPolicyData.SataConfig->HddUnlock = gSbSetupData->SataHddlk; + mPchPolicyData.SataConfig->LedLocate = gSbSetupData->SataLedl; + mPchPolicyData.SataConfig->IrrtOnly = gSbSetupData->SataRaidIooe; + mPchPolicyData.SataConfig->SmartStorage = gSbSetupData->SmartStorage; + mPchPolicyData.SataConfig->OromUiDelay = gSbSetupData->OromUiDelay; + mPchPolicyData.SataConfig->TestMode = gSbSetupData->SataTestMode; + mPchPolicyData.SataConfig->SalpSupport = gSbSetupData->SalpSupport; + mPchPolicyData.SataConfig->LegacyMode = PCH_DEVICE_DISABLE; + mPchPolicyData.SataConfig->SpeedSupport = gSbSetupData->SataControllerSpeed; + + // AzaliaConfig + mPchPolicyData.AzaliaConfig->Pme = gSbSetupData->AzaliaPme; + mPchPolicyData.AzaliaConfig->DS = gSbSetupData->AzaliaDs; + + if (!IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + // These boards do not have KSC - set Azalia as "Not Docked" + mPchPolicyData.AzaliaConfig->DA = 0; + } else { + // Call KSC lib to get dock status +#if defined INTEL_CRB_DXE_KSC_LIB_SUPPORT && INTEL_CRB_DXE_KSC_LIB_SUPPORT +#if defined CRB_EC_SUPPORT && CRB_EC_SUPPORT + if (mPchPolicyData.AzaliaConfig->DS == PCH_DEVICE_ENABLE) { + InitializeKscLib (); + Status = SendKscCommand (KSC_C_DOCK_STATUS); + if (Status == EFI_SUCCESS) { + Status = ReceiveKscData ((UINT8 *) &PortDataOut); + if (PortDataOut & KSC_B_DOCK_STATUS_ATTACH) { + + // Bit 0 is dock status: 1 = docked + mPchPolicyData.AzaliaConfig->DA = 1; + } else { + mPchPolicyData.AzaliaConfig->DA = 0; + } + } + } +#endif +#endif + } + + mPchPolicyData.AzaliaConfig->AzaliaVerbTableNum = sizeof (HdaVerbTbl) / sizeof (PCH_AZALIA_VERB_TABLE); + mPchPolicyData.AzaliaConfig->AzaliaVerbTable = (PCH_AZALIA_VERB_TABLE*)HdaVerbTbl; + mPchPolicyData.AzaliaConfig->ResetWaitTimer = HDA_RESET_WAIT_TIMER; + + // Reserved SMBus Address + mPchPolicyData.SmbusConfig->NumRsvdSmbusAddresses = DIMM_SLOT_NUM; + mPchPolicyData.SmbusConfig->RsvdSmbusAddressTable = mSmbusRsvdAddresses; + + // MiscPm Configuration + if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + mPchPolicyData.MiscPmConfig->PchDeepSxPol = gSbSetupData->DeepSxBattMode; + if (gSbSetupData->BoardCapability == 0) + mPchPolicyData.MiscPmConfig->PchDeepSxPol = PchDeepSxPolDisable; + } else { + mPchPolicyData.MiscPmConfig->PchDeepSxPol = gSbSetupData->DeepSxMode; + } + + // [EIP82149]> + // Intel(R) 8 Series Chipset Family Deep Sx and CPU Soft-Strap BIOS Override Co-Existence Issue. + // If the soft-strap override feature is required and enabled, BIOS must disable Deep Sx functionality. + if (READ_MEM32_RCRB(R_PCH_SPI_SRD) & B_PCH_SPI_SRD_SSD) { + mPchPolicyData.MiscPmConfig->PchDeepSxPol = PchDeepSxPolDisable; + SbPlatformData.HideDeepSx = 1; + } + // <[EIP82149] + + mPchPolicyData.MiscPmConfig->WakeConfig.PmeB0S5Dis = PCH_DEVICE_DISABLE; + mPchPolicyData.MiscPmConfig->WakeConfig.WolEnableOverride = gSbSetupData->PchWakeOnLan; + mPchPolicyData.MiscPmConfig->WakeConfig.Gp27WakeFromDeepSx = gSbSetupData->Gp27Wake; + mPchPolicyData.MiscPmConfig->WakeConfig.PcieWakeFromDeepSx = gSbSetupData->PcieWake; + mPchPolicyData.MiscPmConfig->PowerResetStatusClear.MeWakeSts = ME_WAKE_STS; + mPchPolicyData.MiscPmConfig->PowerResetStatusClear.MeHrstColdSts = ME_HRST_COLD_STS; + mPchPolicyData.MiscPmConfig->PowerResetStatusClear.MeHrstWarmSts = ME_HRST_WARM_STS; + mPchPolicyData.MiscPmConfig->PchSlpS3MinAssert = PCH_SLP_S3_MIN_ASSERT_VALUE; + mPchPolicyData.MiscPmConfig->PchSlpS4MinAssert = gSbSetupData->SlpS4AssW; + mPchPolicyData.MiscPmConfig->PchSlpSusMinAssert = PCH_SLP_SUS_MIN_ASSERT_VALUE; + mPchPolicyData.MiscPmConfig->PchSlpAMinAssert = PCH_SLPA_MIN_ASSERT_VALUE; + mPchPolicyData.MiscPmConfig->PchPwrCycDur = PCH_RESET_CYCLE_DURATION; // 4-5 seconds (PCH default setting) + mPchPolicyData.MiscPmConfig->SlpStrchSusUp = SLP_STRCH_SUS_UP; + mPchPolicyData.MiscPmConfig->SlpLanLowDc = gSbSetupData->SlpLanLow; + + // Thermal configuration - Initialize policy to SETUP values. + mPchPolicyData.ThermalConfig->ThermalAlertEnable.TselLock = PCH_DEVICE_ENABLE; +// mPchPolicyData.ThermalConfig->ThermalAlertEnable.TspcLock = gSbSetupData->TSPCLock; // Deprecated from Revision 2 !!! DO NOT USE !!! + mPchPolicyData.ThermalConfig->ThermalAlertEnable.TscLock = PCH_DEVICE_ENABLE; + mPchPolicyData.ThermalConfig->ThermalAlertEnable.TsmicLock = PCH_DEVICE_ENABLE; + mPchPolicyData.ThermalConfig->ThermalAlertEnable.PhlcLock = PCH_DEVICE_ENABLE; + + mPchPolicyData.ThermalConfig->ThermalThrottling.TTLevels.SuggestedSetting = TTLEVELS_SUGGEST; + mPchPolicyData.ThermalConfig->ThermalThrottling.TTLevels.PchCrossThrottling = gSbSetupData->PchCrossThrottling; + mPchPolicyData.ThermalConfig->ThermalThrottling.DmiHaAWC.SuggestedSetting = DMIHAAWC_SUGGEST; + mPchPolicyData.ThermalConfig->ThermalThrottling.SataTT.SuggestedSetting = SATATT_SUGGEST; + mPchPolicyData.ThermalConfig->PchHotLevel = gSbSetupData->PchHotLevel;; + + // PCH thermal device D31:F6 needs to be enabled for DPPM or validation. + mPchPolicyData.ThermalConfig->ThermalDeviceEnable = gSbSetupData->ThermalDeviceEnable; + + if (mPchPolicyData.DeviceEnabling->Lan != PCH_DEVICE_ENABLE) + SbPlatformData.GbePciePortNum = 0xff; + + // Set IOAPIC BDF + mPchPolicyData.IoApicConfig->BdfValid = 1; + mPchPolicyData.IoApicConfig->BusNumber = 0xF0; + mPchPolicyData.IoApicConfig->DeviceNumber = 0x1F; + mPchPolicyData.IoApicConfig->FunctionNumber = 0; + mPchPolicyData.IoApicConfig->IoApicEntry24_39 = PCH_DEVICE_ENABLE; + + // Set HPET BDF + mPchPolicyData.HpetConfig->BdfValid = 1; + for (PortIndex=0; PortIndex<PCH_HPET_BDF_MAX; PortIndex++) { + mPchPolicyData.HpetConfig->Hpet[PortIndex].BusNumber = 0xF0; + mPchPolicyData.HpetConfig->Hpet[PortIndex].DeviceNumber = 0x0F; + mPchPolicyData.HpetConfig->Hpet[PortIndex].FunctionNumber = 0; + } + + // Initialize Serial IRQ Config + mPchPolicyData.SerialIrqConfig->SirqEnable = SIRQ_ENABLE; + mPchPolicyData.SerialIrqConfig->StartFramePulse = SIRQ_START_FRAME_PULSE; + mPchPolicyData.SerialIrqConfig->SirqMode = gSbSetupData->SirqMode; + + // Set these two policies to 0 for skip ProgramSvidSid(). (PchInit.c) + // ULT_SUBID>> + // SB SSID programming has done in ProgramSBSubId(). (SBPEI.c) + + mPchPolicyData.DefaultSvidSid->SubSystemVendorId = 0; + mPchPolicyData.DefaultSvidSid->SubSystemId = 0; + // <<ULT_SUBID + + // + // DMI related settings + // + mPchPolicyData.DmiConfig->DmiAspm = gSbSetupData->PchDmiAspm; + mPchPolicyData.DmiConfig->DmiExtSync = gSbSetupData->PchDmiExtSync; + mPchPolicyData.DmiConfig->DmiIot = PCH_DEVICE_DISABLE; + /// + /// Power Optimizer related settings + /// + mPchPolicyData.PwrOptConfig->PchPwrOptDmi = PCH_PWR_OPT_DMI; + mPchPolicyData.PwrOptConfig->PchPwrOptGbe = PCH_PWR_OPT_GBE; + mPchPolicyData.PwrOptConfig->PchPwrOptXhci = PCH_PWR_OPT_XHCI; + mPchPolicyData.PwrOptConfig->PchPwrOptEhci = PCH_PWR_OPT_EHCI; + mPchPolicyData.PwrOptConfig->PchPwrOptSata = PCH_PWR_OPT_SATA; + mPchPolicyData.PwrOptConfig->MemCloseStateEn = MEM_CLOSE_STATE_EN; + mPchPolicyData.PwrOptConfig->InternalObffEn = INTERNAL_OBFF_EN; + mPchPolicyData.PwrOptConfig->ExternalObffEn = PCH_DEVICE_DISABLE; // De-feature OBFF from LPT-H/LPT-LP.(RC v1.2.0) + mPchPolicyData.PwrOptConfig->NumOfDevLtrOverride = NUM_OF_DEVLTR_OVERRID; +#if defined DEVLTR_OVERRID && DEVLTR_OVERRID == 1 + mPchPolicyData.PwrOptConfig->DevLtrOverride = 1; +#else + mPchPolicyData.PwrOptConfig->DevLtrOverride = NULL; +#endif + for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) { + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].LtrEnable = gSbSetupData->PcieLtrEnable[PortIndex]; + // + // De-feature OBFF from LPT-H/LPT-LP. + // Doesn't enable Obff policy anymore. + // + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].ObffEnable = PCH_DEVICE_DISABLE; + } + + GlobalNvsArea->Area->LTRE1 = gSbSetupData->PcieLtrEnable[0]; + GlobalNvsArea->Area->LTRE2 = gSbSetupData->PcieLtrEnable[1]; + GlobalNvsArea->Area->LTRE3 = gSbSetupData->PcieLtrEnable[2]; + GlobalNvsArea->Area->LTRE4 = gSbSetupData->PcieLtrEnable[3]; + GlobalNvsArea->Area->LTRE5 = gSbSetupData->PcieLtrEnable[4]; + GlobalNvsArea->Area->LTRE6 = gSbSetupData->PcieLtrEnable[5]; + GlobalNvsArea->Area->LTRE7 = gSbSetupData->PcieLtrEnable[6]; + GlobalNvsArea->Area->LTRE8 = gSbSetupData->PcieLtrEnable[7]; + + mPchPolicyData.PwrOptConfig->LegacyDmaDisable = LEGACY_DMA_DISABLE; + for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) { + if (PchSeries == PchLp) { + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxSnoopLatency = 0x1003; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxNoSnoopLatency = 0x1003; + } + if (PchSeries == PchH) { + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxSnoopLatency = 0x0846; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxNoSnoopLatency = 0x0846; + } + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].LtrConfigLock = gSbSetupData->PcieLtrConfigLock[PortIndex]; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].SnoopLatencyOverrideMode = gSbSetupData->PcieSnoopLatencyOverrideMode[PortIndex]; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].SnoopLatencyOverrideMultiplier = gSbSetupData->PcieSnoopLatencyOverrideMultiplier[PortIndex]; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].SnoopLatencyOverrideValue = gSbSetupData->PcieSnoopLatencyOverrideValue[PortIndex]; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].NonSnoopLatencyOverrideMode = gSbSetupData->PcieNonSnoopLatencyOverrideMode[PortIndex]; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].NonSnoopLatencyOverrideMultiplier = gSbSetupData->PcieNonSnoopLatencyOverrideMultiplier[PortIndex]; + mPchPolicyData.PwrOptConfig->PchPwrOptPcie[PortIndex].NonSnoopLatencyOverrideValue = gSbSetupData->PcieNonSnoopLatencyOverrideValue[PortIndex]; + } + /// + /// Interrupt Settings + /// + mPchPolicyData.IoApicConfig->IoApicEntry24_39 = PCH_DEVICE_ENABLE; + + /// + /// Misc. Config + /// + /// FviSmbiosType is the SMBIOS OEM type (0x80 to 0xFF) defined in SMBIOS Type 14 - Group + /// Associations structure - item type. FVI structure uses it as SMBIOS OEM type to provide + /// version information. The default value is type 221. + /// + mPchPolicyData.MiscConfig->FviSmbiosType = 0xDD; + + /// + /// DCI (Direct Connect Interface) Configuration + /// + mPchPolicyData.MiscConfig->DciEn = PCH_DEVICE_DISABLE; + + mPchPolicyData.AudioDspConfig->AudioDspD3PowerGating = gSbSetupData->ADspD3PG; + GlobalNvsArea->Area->AudioDspCodec = (UINT8)gSbSetupData->ADspCodecSelect; + mPchPolicyData.AudioDspConfig->AudioDspBluetoothSupport = gSbSetupData->ADspBluetooth; + mPchPolicyData.AudioDspConfig->AudioDspAcpiMode = gSbSetupData->ADspMode; //1: ACPI mode, 0: PCI mode + mPchPolicyData.AudioDspConfig->AudioDspAcpiInterruptMode = !(gSbSetupData->LpssIntMode); //1: ACPI mode, 0: PCI mode + mPchPolicyData.AudioDspConfig->AudioDspBluetoothSupport = PCH_DEVICE_DISABLE; // Bluetooth SCO disabled + + mPchPolicyData.SerialIoConfig->SerialIoMode = gSbSetupData->LpssMode; + mPchPolicyData.SerialIoConfig->SerialIoInterruptMode = gSbSetupData->LpssIntMode; + mPchPolicyData.SerialIoConfig->Ddr50Support = PCH_DEVICE_DISABLE; + mPchPolicyData.SerialIoConfig->I2c0VoltageSelect = gSbSetupData->I2C0VoltageSelect; + mPchPolicyData.SerialIoConfig->I2c1VoltageSelect = gSbSetupData->I2C1VoltageSelect; + if(gSbSetupData->SensorHub){ + GlobalNvsArea->Area->SDS0 = GlobalNvsArea->Area->SDS0 | BIT0; + } + if(gSbSetupData->TPD4){ + GlobalNvsArea->Area->SDS0 = GlobalNvsArea->Area->SDS0 | BIT2; + } + if(gSbSetupData->AtmelTPL){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT0; + } + if(gSbSetupData->ElanTPL){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT1; + } + if(gSbSetupData->ElanTPD){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT2; + } + if(gSbSetupData->SynaTPD){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT3; + } + if(gSbSetupData->NtriTPL){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT5; + } + if(gSbSetupData->EetiTPL){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT6; + } + if(gSbSetupData->AlpsTPD){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT7; + } + if(gSbSetupData->CyprTPD){ + GlobalNvsArea->Area->SDS1 = GlobalNvsArea->Area->SDS1 | BIT8; + } + if(gSbSetupData->LpssI2c0Enable){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT5; + } + if(gSbSetupData->LpssI2c1Enable){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT6; + } + if(gSbSetupData->LpssUart0Enable){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT2; + } + if(gSbSetupData->LpssUart1Enable){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT3; + } + if(gSbSetupData->LpssSdioEnable){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT4; + } + if(gSbSetupData->ADspEnable){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT9; + } + if(gSbSetupData->PchAzalia){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT8; + } + if(gSbSetupData->PchUsb30Mode != 0){ + GlobalNvsArea->Area->PEPC = GlobalNvsArea->Area->PEPC | BIT7; + } + GlobalNvsArea->Area->DOSD = gSbSetupData->LpssDmaEnable; + GlobalNvsArea->Area->SDS4 = gSbSetupData->Bluetooth0; + GlobalNvsArea->Area->SDS5 = gSbSetupData->Bluetooth1; + + GlobalNvsArea->Area->SSH0 = gSbSetupData->I2C0SSH; + GlobalNvsArea->Area->SSL0 = gSbSetupData->I2C0SSL; + GlobalNvsArea->Area->SSD0 = gSbSetupData->I2C0SSD; + GlobalNvsArea->Area->FMH0 = gSbSetupData->I2C0FMH; + GlobalNvsArea->Area->FML0 = gSbSetupData->I2C0FML; + GlobalNvsArea->Area->FMD0 = gSbSetupData->I2C0FMD; + GlobalNvsArea->Area->FPH0 = gSbSetupData->I2C0FPH; + GlobalNvsArea->Area->FPL0 = gSbSetupData->I2C0FPL; + GlobalNvsArea->Area->FPD0 = gSbSetupData->I2C0FPD; + GlobalNvsArea->Area->M0C0 = gSbSetupData->I2C0M0C0; + GlobalNvsArea->Area->M1C0 = gSbSetupData->I2C0M1C0; + GlobalNvsArea->Area->M2C0 = gSbSetupData->I2C0M2C0; + + GlobalNvsArea->Area->SSH1 = gSbSetupData->I2C1SSH; + GlobalNvsArea->Area->SSL1 = gSbSetupData->I2C1SSL; + GlobalNvsArea->Area->SSD1 = gSbSetupData->I2C1SSD; + GlobalNvsArea->Area->FMH1 = gSbSetupData->I2C1FMH; + GlobalNvsArea->Area->FML1 = gSbSetupData->I2C1FML; + GlobalNvsArea->Area->FMD1 = gSbSetupData->I2C1FMD; + GlobalNvsArea->Area->FPH1 = gSbSetupData->I2C1FPH; + GlobalNvsArea->Area->FPL1 = gSbSetupData->I2C1FPL; + GlobalNvsArea->Area->FPD1 = gSbSetupData->I2C1FPD; + GlobalNvsArea->Area->M0C1 = gSbSetupData->I2C1M0C1; + GlobalNvsArea->Area->M1C1 = gSbSetupData->I2C1M1C1; + GlobalNvsArea->Area->M2C1 = gSbSetupData->I2C1M2C1; + + GlobalNvsArea->Area->M0C2 = gSbSetupData->SPI0M0C2; + GlobalNvsArea->Area->M1C2 = gSbSetupData->SPI0M1C2; + + GlobalNvsArea->Area->M0C3 = gSbSetupData->SPI1M0C3; + GlobalNvsArea->Area->M1C3 = gSbSetupData->SPI1M1C3; + + GlobalNvsArea->Area->M0C4 = gSbSetupData->UAR0M0C4; + GlobalNvsArea->Area->M1C4 = gSbSetupData->UAR0M1C4; + + GlobalNvsArea->Area->M0C5 = gSbSetupData->UAR1M0C5; + GlobalNvsArea->Area->M1C5 = gSbSetupData->UAR1M1C5; + + GlobalNvsArea->Area->ECTG = gSbSetupData->ECTG; + + SbPlatformData.PchRid = READ_PCI8_SB(R_PCH_LPC_RID); + + // Save SB PLATFORM DATA variables. + Status = pRS->SetVariable ( + L"SbPlatformData", + &SetupGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (SB_PLATFORM_DATA), + &SbPlatformData + ); + ASSERT_EFI_ERROR (Status); + +#if (defined SB_SETUP_SUPPORT && SB_SETUP_SUPPORT) || \ + (defined OEM_SB_SETUP_SUPPORT && OEM_SB_SETUP_SUPPORT) + SetupData.TrEnabled = gSbSetupData->TrEnabled; +#endif + + Status = pRS->SetVariable ( + L"Setup", + &SetupGuid, + SetupDataAttributes, + sizeof (SETUP_DATA), + &SetupData + ); + ASSERT_EFI_ERROR (Status); + + Handle = NULL; + Status = pBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gDxePchPlatformPolicyProtocolGuid, + &mPchPolicyData, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RaidGetDriver +// +// Description: Get the the DriverImage Handle order to Start the +// Raid Controller handle +// +// Input: This - EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL +// DriverImageHandle - Driver Image Handle +// +// Output: DriverImageHandle - Returns the Driver Image handle +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RaidGetDriver( + IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, + IN OUT EFI_HANDLE *DriverImageHandle +) +{ + UINTN HandleCount; + EFI_HANDLE *HandleBuffer=NULL; + UINTN Index; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DRIVER_BINDING_PROTOCOL *DriverBindingProtocol=NULL; + EFI_GUID gEfiLoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + static UINT8 GuidCount=0; + EFI_STATUS Status; + + + // + // Validate the the Input parameters + // + if (DriverImageHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // If already Found all the images,proceed to return the data + // + if( !LoadedImageDone ) { + + LoadedImageDone = TRUE; + + // + // Locate all the driver binding protocols + // + Status = pBS->LocateHandleBuffer ( + ByProtocol, + &gEfiDriverBindingProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + + if (EFI_ERROR(Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + + // + // Get the Driver Binding Protocol Interface + // + Status = pBS->HandleProtocol(HandleBuffer[Index], + &gEfiDriverBindingProtocolGuid, + &DriverBindingProtocol); + + if(EFI_ERROR(Status) || DriverBindingProtocol == NULL){ + continue; + } + + // + // Get the LoadedImage Protocol from ImageHandle + // + Status = pBS->HandleProtocol(DriverBindingProtocol->ImageHandle, + &gEfiLoadedImageGuid, + &LoadedImage); + + if(EFI_ERROR(Status)){ + continue; + } + + // + //Compare the File guid with driver's needs to launched first + // + if(guidcmp(&(((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(LoadedImage->FilePath))->NameGuid) + , &GuidListCheckForRaid[GuidCount]) != 0) { + continue; + } + + // + // Driver Image handle found. Add it in the Array + // + ImageHandleArray[GuidCount] = DriverBindingProtocol->ImageHandle; + GuidCount++; + + // + // Start from the begining + // + Index = -1; + + // + // Check All the Guid's are found. If found break the loop + // + if(GuidCount >= (sizeof(GuidListCheckForRaid)/sizeof(EFI_GUID) -1 )) { + break; + } + + } + + // + // Free the HandleBuffer Memory. + // + if (HandleBuffer) { + pBS->FreePool (HandleBuffer); + } + + } + + if(GuidCount == 0) { + // + // Image handle not found + // + return EFI_NOT_FOUND; + } + + // + //If the *DriverImageHandle is NULL , return the first Imagehandle + // + if( *DriverImageHandle == NULL ) { + if(ImageHandleArray[0] != NULL) { + *DriverImageHandle = ImageHandleArray[0]; + return EFI_SUCCESS; + } + } else { + // + // If *DriverImageHandle not NULL , return the next Imagehandle + // from the avilable image handle list + // + for (Index = 0; Index < 4; Index++) { + if( *DriverImageHandle == ImageHandleArray[Index] && (ImageHandleArray[Index+1] != NULL) ) { + *DriverImageHandle = ImageHandleArray[Index+1]; + return EFI_SUCCESS; + } + } + } + + // + // No more Image handle found to handle the controller. + // + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ULTDsdtTableUpdate +// +// Description: Update the ULT DSDT table +// +// Input: DsdtTable - The table points to DSDT table. +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +ULTDsdtTableUpdate ( + IN ACPI_HDR *DsdtTable + ) +{ + UINT8 *CurrPtr; + UINT8 *DsdtPointer; + UINT32 *Signature; + UINT8 HexStr[36] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H',\ + 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; + UINT8 ReturnVaule = 0; + UINT32 *SignaturePcieAdrs; //(EIP127410)>> + UINT8 RPFN[6]; //Root Port Function Number + UINT8 i; //(EIP127410)<< + UINT8 RP06Done = 0; +#if LOW_POWER_S0_IDLE_CAPABLE == 1 + SETUP_DATA *SetupData = NULL; + EFI_GUID SetupGuid = SETUP_GUID; + UINTN VariableSize = sizeof(SETUP_DATA); + EFI_STATUS Status; + UINT8 S0ID; + + Status = pBS->AllocatePool( EfiBootServicesData, + VariableSize, + &SetupData ); + ASSERT_EFI_ERROR(Status); + + Status = pRS->GetVariable( L"Setup", + &SetupGuid, + NULL, + &VariableSize, + SetupData ); + + S0ID = SetupData->AcpiLowPowerS0Idle; + + if (SetupData != NULL) { + pBS->FreePool(SetupData); + } +#endif + //(EIP127410)>> + for(i = 0 ; i < 6; i++){ + RPFN[i] = ((UINT8)(MmioRead32(SB_RCRB_BASE_ADDRESS + R_PCH_RCRB_RPFN) >> 4*i)) & 0x07; + TRACE((-1, "\nRCBA RPFN%x = %x\n", i, RPFN[i])); + } + //(EIP127410)<< + CurrPtr = (UINT8 *) DsdtTable; + for (DsdtPointer = CurrPtr; + DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); + DsdtPointer++ ) + { + Signature = (UINT32 *) DsdtPointer; + switch(*Signature){ + //************** GPE event case ************** + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'B')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '3')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '4')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'C')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'E')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '5')): + //************************************************* + case (EFI_SIGNATURE_32 ('X', 'L', '0', '9')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'D')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '1')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '2')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '6')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '7')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '8')): + *DsdtPointer = '_'; + *(DsdtPointer + 2) = HexStr[6]; //6 + DsdtPointer = DsdtPointer + 3; + break; + case (EFI_SIGNATURE_32 ('X', 'L', '1', 'E')): + *DsdtPointer = '_'; + *(DsdtPointer + 3) = HexStr[11]; //B + DsdtPointer = DsdtPointer + 3; + break; + //************** Return vaule case ************** + case (EFI_SIGNATURE_32 ('G', 'P', 'R', 'W')): + ReturnVaule = *(DsdtPointer + 5); + switch (ReturnVaule){ + case 0x03: + case 0x04: + case 0x05: + case 0x08: + case 0x09: + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + *(DsdtPointer + 5) = ReturnVaule + 0x60; + break; + default: + break; + } + + DsdtPointer = DsdtPointer + 7; + break; + #if LOW_POWER_S0_IDLE_CAPABLE == 1 + //************** Change Dock case ************** + case (EFI_SIGNATURE_32 ('_', 'D', 'C', 'K')): + if (S0ID == 1){ + *DsdtPointer = HexStr[33]; //X + DsdtPointer = DsdtPointer + 3; + } + break; + #endif + //************** PCIE Adress **************** //(EIP127410)>> + case (EFI_SIGNATURE_32 ('R', 'P', '0', '1')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[0]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '2')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[1]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '3')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[2]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '4')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[3]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '5')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[4]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '6')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[5]; + break; + default: + break; + } + } + while(RP06Done != 1){ + DsdtPointer++; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('A', 'R', '0', '9')): + *(DsdtPointer + 3) = HexStr[8]; //8 + DsdtPointer = DsdtPointer + 3; + break; + + case (EFI_SIGNATURE_32 ('P', 'R', '0', '9')): + *(DsdtPointer + 3) = HexStr[8]; //8 + DsdtPointer = DsdtPointer + 3; + RP06Done = 1; + break; + + default: + break; + } + } + break; //(EIP127410)<< + default: + break; + }// end switch + }// end of for loop +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DsdtTableUpdate +// +// Description: Update the DSDT table +// +// Input: DsdtTable - The table points to DSDT table. +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +DsdtTableUpdate ( + IN ACPI_HDR *DsdtTable + ) +{ + UINT8 *CurrPtr; + UINT8 *DsdtPointer; + UINT32 *Signature; + UINT8 HexStr[36] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H',\ + 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; + UINT8 ReturnVaule = 0; + UINT32 *SignaturePcieAdrs; //(EIP127410)>> + UINT8 RPFN[8]; //Root Port Function Number + UINT8 i; //(EIP127410)<< + + CurrPtr = (UINT8 *) DsdtTable; + //(EIP127410)>> + for(i = 0 ; i < 8; i++){ + RPFN[i] = ((UINT8)(MmioRead32(SB_RCRB_BASE_ADDRESS + R_PCH_RCRB_RPFN) >> 4*i)) & 0x07; + TRACE((-1, "\nRCBA RPFN%x = %x\n", i, RPFN[i])); + } + //(EIP127410)<< + for (DsdtPointer = CurrPtr; + DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); + DsdtPointer++ ) + { + Signature = (UINT32 *) DsdtPointer; + switch(*Signature){ + //************** GPE event case ************** + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'B')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '3')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '4')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'C')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'E')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '5')): + //************************************************* + case (EFI_SIGNATURE_32 ('X', 'L', '0', '9')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', 'D')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '1')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '2')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '6')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '7')): + case (EFI_SIGNATURE_32 ('X', 'L', '0', '8')): + *DsdtPointer = '_'; + DsdtPointer = DsdtPointer + 3; + break; + case (EFI_SIGNATURE_32 ('X', 'L', '1', 'E')): + *DsdtPointer = '_'; + DsdtPointer = DsdtPointer + 3; + break; + //************** PCIE Adress **************** //(EIP127410)>> + case (EFI_SIGNATURE_32 ('R', 'P', '0', '1')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[0]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '2')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[1]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '3')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[2]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '4')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[3]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '5')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[4]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '6')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[5]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '7')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[6]; + break; + default: + break; + } + } + break; + case (EFI_SIGNATURE_32 ('R', 'P', '0', '8')): + if (gSbSetupData->RootPortFunctionSwapping){ + DsdtPointer = DsdtPointer + 5; + SignaturePcieAdrs = (UINT32 *) DsdtPointer; + switch(*SignaturePcieAdrs){ + case (EFI_SIGNATURE_32 ('_', 'A', 'D', 'R')): + DsdtPointer = DsdtPointer + 5; + *DsdtPointer = RPFN[7]; + break; + default: + break; + } + } + break; //(EIP127410)<< + default: + break; + }// end switch + }// end of for loop +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBGeneric.c b/Chipset/SB/SBGeneric.c new file mode 100644 index 0000000..efdedd4 --- /dev/null +++ b/Chipset/SB/SBGeneric.c @@ -0,0 +1,3717 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBGeneric.c 27 1/29/15 4:14a Mirayang $ +// +// $Revision: 27 $ +// +// $Date: 1/29/15 4:14a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBGeneric.c $ +// +// 27 1/29/15 4:14a Mirayang +// [TAG] EIP200269 +// [Category] New Feature +// [Description] For add FlashSmi : Label 4.6.5.5_FlashSmi_00 +// ($/Alaska/SOURCE/Modules/FlashSmi) +// +// 26 5/16/14 6:16a Barretlin +// [TAG] EIP167087 +// [Category] Improvement +// [Description] BIOS security improvement on Haswell CRB project +// [Files] SBGeneric.c SBDxe.c SBCspLib.h Sb.sdl Sb.sd +// +// 25 1/24/14 2:49a Barretlin +// [TAG] EIP136638 +// [Category] Improvement +// [Description] fix programming error +// [Files] SBGeneric.c PchResetCommon.c +// +// 24 12/30/13 6:01a Barretlin +// [TAG] EIP144559 +// [Category] Improvement +// [Description] S3 can't resume via USB KB & MS under usb3.0 port in +// special case +// [Files] SBSMI.c SBSMI.h SBGeneric.c +// +// 23 11/19/13 7:32a Barretlin +// [TAG] EIP141917 +// [Category] New Feature +// [Description] Support SetTimer() with HPET Timer on Lynx Point +// [Files] SB.sdl SBGeneric.c SBDxe.c SbHpet.h sbProtocal.cif +// SamrtTimer.sdl +// +// 22 4/29/13 1:58a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] THe NMI read port should before index update. +// [Files] SBGeneric.c +// +// 21 4/19/13 6:35a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Update GbES02SxWorkaround() and add +// UsbS02SxWorkaround() for SBPwrBtnHandler(). +// [Files] SBSMI.c; SBSMI.h; SBGeneric.c; SBCspLib.h +// +// 20 4/01/13 6:43a Scottyang +// [TAG] EIP119703 +// [Category] Improvement +// [Description] Clear RTC before BIOS flash capsule function enter S3. +// [Files] SBGeneric.c +// +// 19 3/19/13 8:33a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Improve alternate access mode enable/disable routine. +// [Files] SBGeneric.c, SBCspLib.h, SBSMI.c +// +// 18 3/19/13 8:19a Scottyang +// [TAG] EIP118158 +// [Category] Improvement +// [Description] Correct SBLib_CmosRead () offset. +// [Files] SmiHandlerPorting2.c, SBDxe.c, SBGeneric.c, SBSmm.c, +// SmiHandlerPorting.c +// +// 17 3/12/13 7:44a Scottyang +// [TAG] EIP106722 +// [Category] Improvement +// [Description] Clear RTC before capsule function enter S3. +// [Files] SBGeneric.c +// +// 16 1/11/13 4:36a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add ReadCmos() / WriteCmos() from SB template. +// [Files] SBGeneric.c +// +// 15 1/11/13 12:46a Scottyang +// [TAG] EIP81593 +// [Category] Improvement +// [Description] Added new SDL token "COLD_RESET_WITH_POWER_CYCLE". +// [Files] SB.sdl, SBGeneric.c, PchResetCommon.c, +// PchResetCommonLib.sdl +// +// 14 1/10/13 8:20a Scottyang +// [TAG] EIP111666 +// [Category] New Feature +// [Description] Support OEM reset callback function Elink. +// [Files] SB.mak, SBCspLib.h, SBGeneric.c, SB.sdl, PchReset.c +// +// 13 11/21/12 3:07a Scottyang +// +// 11 11/19/12 3:52a Scottyang +// [TAG] EIP106353 +// [Category] Bug Fix +// [Severity] Critical +// [Symptom] The system has assert error when PFAT is Disabled and Debug +// Mode is Enabled. +// [RootCause] Use build time PFAT flag that make some code not run whrn +// PFAT disable. +// [Solution] Detect PFAT flag useing MSR. +// [Files] SBGeneric, SB.mak +// +// 10 10/30/12 10:02p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Remove clear SMI state and Y2K roller for PFAT +// function. +// [Files] SBSMI.c, SBGeneric.c +// +// 9 10/25/12 11:57p Scottyang +// [TAG] EIP100108 +// [Category] Improvement +// [Description] Support Capsule 2.0. +// [Files] SBGeneric.c +// +// 8 10/19/12 2:46a Scottyang +// [TAG] EIP93461 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System halt when AFUDOS is running with /N /ME command. +// [RootCause] An unexpected BIOSWR_STS is set, it causes BIOS stuck +// at SMM dispatcher. +// [Solution] Clear BIOSWR_STS if BIOS Lock Enable is not set. +// [Files] SmiHandlerPorting2.c; SmmChildDispatch2Main.c +// SmmChildDispatcher2.sdl; SmmChildDispatch2.h +// SB\SBGeneric.c +// +// 7 10/01/12 5:53a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for PFTA support. +// [Files] SBGeneric.c +// +// 6 9/26/12 3:54a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 5 9/12/12 5:19a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove useless HdmiVerbTable. +// [Files] SB.sdl, SBCspLib.h, SBDxe.c, SBGeneric.c +// +// 4 8/24/12 6:50a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove useless SB_SHADOW_CONTROL. +// [Files] SB.sdl, SBCspLib.h, SBGeneric.c +// +// 3 7/02/12 10:17a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Updated and modified for PCH RC 0.6.0. +// [Files] SBGeneric.c, SB.sdl, SBCspLib.h, SBDxe.c, SBPEI.c +// +// 2 6/13/12 11:34p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement Warm Boot function for Secure Flash feature. +// [Files] SB.H, SB.mak, SB.sdl, SBDxe.c, SBGeneric.c, SBPEI.c, +// SBSMI.c +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBGeneric.C +// +// Description: This file contains south bridge related code that is needed +// for both PEI & DXE stage. +// To avoid code duplication this file is made as a library and +// linked both in PEI & DXE south bridge FFS. +// +// Notes: MAKE SURE NO PEI OR DXE SPECIFIC CODE IS NEEDED +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Efi.h> +#include <Token.h> +#include <AmiPeiLib.h> +#include <AmiDxeLib.h> +#include <Protocol\PciRootBridgeIo.h> +#include <AmiCspLib.h> +#include "PchAccess.h" +#include "RTC.h" +#if Capsule2_0_SUPPORT +#include <capsule.h> //CAPSULE20 +#endif +#include <Include\PchRegs.h> +#include <Include\PchRegs\PchRegsLpc.h> + +#if CSM_SUPPORT +#include <Protocol\LegacyInterrupt.h> +#endif + +#include "CpuRegs.h" // EIP106353 + +#if defined HPET_PROTOCOL_SUPPORT && HPET_PROTOCOL_SUPPORT == 1 +#include <Protocol\SbHpet.h> +#endif + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +#ifndef BIT35 // EIP106353 >> +#define BIT35 0x0000000800000000ULL +#endif // EIP106353 << + +#if CSM_SUPPORT + +#define MAX_PIRQS 8 // Porting Required. + +#endif + +#ifndef CAPSULE_SUPPORT + +#if defined Capsule2_0_SUPPORT && Capsule2_0_SUPPORT +#define CAPSULE_SUPPORT 1 +#else +#define CAPSULE_SUPPORT 0 +#endif + +#endif + +// Macro Definition(s) + +// Type Definition(s) + +typedef VOID (SB_OEM_S3_WARMRESET_CALLBACK) (VOID); + +typedef EFI_STATUS (SB_RUN_RESET_CALLBACK) ( + IN EFI_RESET_TYPE ResetType +); + +typedef struct { + UINT8 Device; + UINT8 Function; +} USB_CONTROLLER; + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) +#if defined CAPSULE_SUPPORT && CAPSULE_SUPPORT == 1 +extern SB_OEM_S3_WARMRESET_CALLBACK \ + SB_OEM_S3_WARMRESET_CALLBACK_LIST EndOfList; +SB_OEM_S3_WARMRESET_CALLBACK* SbS3InsteadOfWarmResetCallBackList[] = \ + {SB_OEM_S3_WARMRESET_CALLBACK_LIST NULL}; +#endif + +extern SB_RUN_RESET_CALLBACK SB_RUN_RESET_CALLBACK_LIST EndOfList1; +SB_RUN_RESET_CALLBACK* SbRunResetCallbackList[] = {SB_RUN_RESET_CALLBACK_LIST NULL}; + +//--------------------------------------------------------------------------- +// The following table contains the information regarding the PIRQ routing +// registers and other South Bridge registers that need to be restored +// during the S3 wakeup. +// Mention all register address (bus, device, function , register), specify +// the size of the register ans the mask also. +//--------------------------------------------------------------------------- + +BOOT_SCRIPT_SB_PCI_REG_SAVE gSBRegsSaveTbl[] = { + {SB_REG(SB_REG_PIRQ_A), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_PIRQ_B), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_PIRQ_C), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_PIRQ_D), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_PIRQ_E), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_PIRQ_F), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_PIRQ_G), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_PIRQ_H), EfiBootScriptWidthUint8, 0xff}, + {SB_REG(SB_REG_GEN_PMCON_1),EfiBootScriptWidthUint16, 0xffff},// SMI Timer + {SB_REG(SB_REG_GEN_PMCON_3),EfiBootScriptWidthUint16, 0xffff},// SMI Timer + {SB_REG(SB_REG_LPC_IO_DEC), EfiBootScriptWidthUint16, 0xffff}, + {SB_REG(SB_REG_LPC_EN), EfiBootScriptWidthUint16, 0xffff}, + {SB_REG(SB_REG_GEN1_DEC), EfiBootScriptWidthUint32, 0xffffffff}, + {SB_REG(SB_REG_GEN2_DEC), EfiBootScriptWidthUint32, 0xffffffff}, + {SB_REG(SB_REG_GEN3_DEC), EfiBootScriptWidthUint32, 0xffffffff}, + {SB_REG(SB_REG_GEN4_DEC), EfiBootScriptWidthUint32, 0xffffffff}, +}; + +#define NUM_SB_PCI_REG_SAVE \ + sizeof(gSBRegsSaveTbl)/ sizeof(BOOT_SCRIPT_SB_PCI_REG_SAVE) + +#if CSM_SUPPORT + +UINT8 bMaxPIRQ = MAX_PIRQS; // For CSM +UINT8 bRouterBus = SB_BUS; // PORTING REQUIRED (Use appropriate Equate) +UINT8 bRouterDevice = SB_DEV; // PORTING REQUIRED (Use appropriate Equate) +UINT8 bRouterFunction = SB_FUN; // PORTING REQUIRED (Use appropriate Equate) +UINT8 RRegs[MAX_PIRQS] = { SB_REG_PIRQ_A, \ + SB_REG_PIRQ_B, \ + SB_REG_PIRQ_C, \ + SB_REG_PIRQ_D, \ + SB_REG_PIRQ_E, \ + SB_REG_PIRQ_F, \ + SB_REG_PIRQ_G, \ + SB_REG_PIRQ_H }; // Porting required + +#endif +// Local variable +static EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *gPciRootBridgeIo; + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +// Function Definition(s) +BOOLEAN CheckOff20hBit28(IN UINT32 GbEBase); +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// Start OF CSM Related Porting Hooks +//--------------------------------------------------------------------------- + +#if CSM_SUPPORT + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBGen_InitializeRouterRegisters +// +// Description: This function is clears the routing registers to default +// values +// +// Input: PciRBIo - Root bridge IO protocol pointer +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBGen_InitializeRouterRegisters ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRBIo ) +{ + UINT8 RegIdx; + + gPciRootBridgeIo = PciRBIo; // Save RB IO value for later use + + for (RegIdx = 0; RegIdx < MAX_PIRQS; RegIdx++) + WRITE_PCI8_SB(RRegs[RegIdx], 0x80); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBGen_GetPIRQIndex +// +// Description: This function returns the 0 based PIRQ index (PIRQ0, 1 etc) +// based on the PIRQ register number specified in the routing +// table. +// +// Input: PIRQRegister - Register number of the PIR +// +// Output: An 8Bit Index for RRegs table, its range is 0 - (MAX_PIRQ -1) +// if PIRQRegister is invalid, then 0xff will be returned. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 SBGen_GetPIRQIndex ( + IN UINT8 PIRQRegister ) +{ + UINT8 rrIndx = 0; + + while ((rrIndx < MAX_PIRQS) && (RRegs[rrIndx] != PIRQRegister)) rrIndx++; + + if (rrIndx == MAX_PIRQS) return 0xff; + + return rrIndx; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBGen_ReadPirq +// +// Description: This function reads the IRQ associated with the PIRQ from +// the chipset register +// +// Input: This - Pointer to Legacy interrupt protocol +// PirqNumber - PIRQ number to read +// PirqData - IRQ programmed for this PIRQ (BIT7 will be +// set if the PIRQ is not programmed) +// +// Output: EFI_STATUS +// EFI_SUCCESS - On successfull IRQ value return +// EFI_INVALID_PARAMETER - If PirqNumber is greater than max +// PIRQs +// +// Notes: Here is the control flow of this function: +// 1. If Invalid PirqNumber, return EFI_INVALID_PARAMETER. +// 2. Read into *PriqData from PIRQ register for Pirq requested +// 3. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBGen_ReadPirq ( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + IN UINT8 PirqNumber, + OUT UINT8 *PirqData ) +{ + if (PirqNumber > MAX_PIRQS) return EFI_INVALID_PARAMETER; + + // If Pirq is not routed, bit 7 is set, however specification does not + // specify a return error for this condition. + *PirqData = READ_PCI8_SB(RRegs[PirqNumber]); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBGen_WritePirq +// +// Description: This function writes an IRQ value allocated for the PIRQ by +// programming the chipset register +// +// Input: This - Pointer to Legacy interrupt protocol +// PirqNumber - PIRQ number to read +// PirqData - IRQ to be programmed +// +// Output: EFI_STATUS +// EFI_SUCCESS - On successfull IRQ value return +// EFI_INVALID_PARAMETER - If PirqNumber is greater than +// max PIRQs or PirqData is greater +// than 15 (MAX IRQ) +// +// Notes: Here is the control flow of this function: +// 1. If Invalid PirqNumber or PirqData is greater than 15, +// return EFI_INVALID_PARAMETER. +// 2. Write PirqData to PIRQ register for Pirq requested. +// 3. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBGen_WritePirq ( + IN EFI_LEGACY_INTERRUPT_PROTOCOL *This, + IN UINT8 PirqNumber, + IN UINT8 PirqData ) +{ + UINT8 PirqValue = PirqData & 0x0f; + + if (PirqNumber > MAX_PIRQS) return EFI_INVALID_PARAMETER; + if (PirqData > 15) return EFI_INVALID_PARAMETER; + + WRITE_PCI8_SB(RRegs[PirqNumber], PirqValue); + + return EFI_SUCCESS; +} + +//--------------------------------------------------------------------------- +#endif // END OF CSM Related Porting Hooks +//--------------------------------------------------------------------------- +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SbFindCapPtr +// +// Description: This function searches the PCI address space for the PCI +// device specified for a particular capability ID and returns +// the offset in the PCI address space if one found +// +// Input: UINT64 PciAddress, +// UINT8 CapId +// +// Output: Capability ID Address if one found +// Otherwise returns 0 +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT32 SbFindCapPtr( + IN UINT64 PciAddress, + IN UINT8 CapId +) +{ + UINT8 Value; + UINT32 Address = (UINT32)PciAddress; + + Address = (Address & 0xffffff00) | 6; //PCI Status Register. + Value = READ_MEM8(Address + 0); + + if (Value == 0xff) return 0; // No device. + if (!(Value & (1 << 4))) return 0; // Check if capabilities list. + + *(UINT8*)&Address = 0x34; // Register to First capabilities pointer + // if 0, then capabilities + for(;;) + { + Value = READ_MEM8(Address + 0); + if (Value == 0) return 0; + + *(UINT8*)&Address = Value; // PciAddress = ptr to CapID + Value = READ_MEM8(Address + 0); // New cap ptr. + + //If capablity ID, return register that points to it. + if (Value == CapId) return Address; + + ++Address; // Equals to next capability pointer. + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBSwSmiWriteToBootScript +// +// Description: Write SB necessary SW SMIs to boot script. +// +// Input: *BootScriptSave - Pointer to Boot Scrpit Save Protocol. +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SBSwSmiWriteToBootScript ( + IN AMI_S3_SAVE_PROTOCOL *BootScriptSave ) +{ + + UINT8 Value8; + + // Generate an ACPI Enable SMI when S3 resuming. + Value8 = SW_SMI_ACPI_ENABLE; + BOOT_SCRIPT_S3_IO_WRITE_MACRO( BootScriptSave, \ + EfiBootScriptWidthUint8, \ + SW_SMI_IO_ADDRESS, \ + 1, \ + &Value8 ); + + // Generate a Software SMI to enable SB patched codes when S3 resuming. + Value8 = SW_SMI_SB_ACPI_S3; + BOOT_SCRIPT_S3_IO_WRITE_MACRO( BootScriptSave, \ + EfiBootScriptWidthUint8, \ + SW_SMI_IO_ADDRESS, \ + 1, \ + &Value8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBGen_WriteBootScript +// +// Description: This writes the PIRQ to boot script before booting. +// +// Input: *BootScriptSave - Pointer to Boot Scrpit Save Protocol. +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SBGen_WriteBootScript ( + IN AMI_S3_SAVE_PROTOCOL *BootScriptSave ) +{ + UINTN i; + UINT32 Value32; + + //Porting required: Write Boot Script + for (i = 0; i < NUM_SB_PCI_REG_SAVE; ++i) { + gPciRootBridgeIo->Pci.Read( gPciRootBridgeIo, \ + gSBRegsSaveTbl[i].Width, + gSBRegsSaveTbl[i].Address, + 1, + &Value32 ); + Value32 &= gSBRegsSaveTbl[i].Mask; + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( BootScriptSave, \ + gSBRegsSaveTbl[i].Width, \ + gSBRegsSaveTbl[i].Address, \ + 1, \ + &Value32 ); + } + + SBSwSmiWriteToBootScript(BootScriptSave); + + return EFI_SUCCESS; +} + +#if SB_RESET_PPI_SUPPORT +#if defined CAPSULE_SUPPORT && CAPSULE_SUPPORT == 1 +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_S3InsteadOfWarmResetCallBack +// +// Description: This function calls registered callbacks for S3 RTC/Timer +// (WarmBoot) eLink. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBLib_S3InsteadOfWarmResetCallBack (VOID) +{ + UINTN i; + + for (i = 0; SbS3InsteadOfWarmResetCallBackList[i] != NULL; i++) + SbS3InsteadOfWarmResetCallBackList[i](); +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_S3InsteadOfWarmReset +// +// Description: This function puts system into ACPI S3 State. +// if token ENABLE_RTC_ONE_SECOND_WAKEUP = 1, then it setups RTC +// 1 second alarm as well. +// +// Input: None +// +// Output: None, system will enter ACPI S3 State. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBLib_S3InsteadOfWarmReset (VOID) +{ +#if ENABLE_RTC_ONE_SECOND_WAKEUP + UINT8 Hour; + UINT8 Minute; + UINT8 Second; + BOOLEAN InBCD = TRUE; + + // Determine if RTC is in BCD mode + if ( READ_IO8_RTC(0x0b) & 0x4 ) InBCD = FALSE; // Bit 2 + + // Wait for time update to complete before reading the values, + // while bit 7 is set the time update is in progress. + while( READ_IO8_RTC(0x0a) & 0x80 ); + + // Read current hour, minute, second + Hour = READ_IO8_RTC(0x04); // Hours + Minute = READ_IO8_RTC(0x02); // Minutes + Second = READ_IO8_RTC(0x00); // Seconds + + // Convert second to decimal from BCD and increment by 1 + if (InBCD) Second = (Second >> 4) * 10 + (Second & 0x0F); + Second += 2; + + if (Second > 59) { + Second -= 60; + if (InBCD) Minute = (Minute >> 4) * 10 + (Minute & 0x0F); + Minute++; + if (Minute > 59){ + Minute = 0; + if (InBCD) Hour = (Hour >> 4) * 10 + (Hour & 0x0F); + Hour++; + // Check 24 hour mode/12 hour mode, Bit1 1=24hour else 12 hour + if ( READ_IO8_RTC(0x0b) & 0x2 ) { + if(Hour > 23) Hour = 0; + } else { + if(Hour > 11) Hour = 0; + } + + if (InBCD) Hour = Hour % 10 + ( (Hour / 10) << 4 ) ; + } + + if (InBCD) Minute = Minute % 10 + ( (Minute / 10) << 4 ) ; + } + + // Convert from decimal to BCD + if (InBCD) Second = Second % 10 + ( (Second / 10) << 4 ) ; + + // Set the alarm + WRITE_IO8_RTC(0x05, Hour); // Hours Alarm + WRITE_IO8_RTC(0x03, Minute); // Minutes Alarm + WRITE_IO8_RTC(0x01, Second); // Seconds Alarm + + // [EIP119703]> + // Clear date alarm. + WRITE_IO8_RTC(0x0D, READ_IO8_RTC(0x0D) & BIT07); + // <[EIP119703] + + // Enable the alarm + SET_IO8_RTC(0x0b, 0x20); // Bit 5 + + if (READ_IO16_PM(ACPI_IOREG_PM1_STS) & 0x400) { + READ_IO8_RTC(0x8C); + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0x400); // 0x00 + } + + // Set RTC_EN bit in PM1_EN to wake up from the alarm + SET_IO16_PM(ACPI_IOREG_PM1_EN, 0x400 ); // 0x02 +#endif + + // Do any specific porting if needed. + SBLib_S3InsteadOfWarmResetCallBack(); + + // Enable Sleep SMI for all S3 sleep SMI callback functions. + SET_IO32_PM(ACPI_IOREG_SMI_EN, BIT04); // 0x30 + // Triger S3 sleep callback functions. + RW_IO32_PM(ACPI_IOREG_PM1_CNTL, 0x1400, 0x1c00 ); // 0x04 + SET_IO32_PM(ACPI_IOREG_PM1_CNTL, 0x2000 ); // 0x04 +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------------------- +// Procedure: SB_Shutdown +// Description: This function Shuts the system down (S5) +// +// Input: VOID +// +// Output: VOID +// +//----------------------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SB_Shutdown(VOID) +{ + //Check if Sleep SMI is enabled we will disable it. + RESET_IO16_PM(R_PCH_SMI_EN, BIT04); // 0x30 + + //Clear All PM Statuses + WRITE_IO16_PM(R_PCH_ACPI_PM1_STS, \ + READ_IO16_PM(R_PCH_ACPI_PM1_STS)); // 0x00 + + //Go to S5 + SET_IO16_PM(R_PCH_ACPI_PM1_CNT, 0x0f << 10); // 0x04 + + EFI_DEADLOOP() +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ClearGPIOResetSelect +// +// Description: Intel PCH Specification update rev 1.02, +// Document Changes 24. Update sec 19.5 +// 19.5 Addttional Consideration, Step 2 +// System BIOS is recommended to clear "GPIO Reset Select" +// registers [GP_RST_SEL1(GPIOBASE + offset 60h), GP_RST_SEL2 +// (GPIOBASE + offset 64h), GP_RST_SEL3(GPIOBASE + offset 68h) +// before issuing a hard or global reset unless specially +// requested by the platform designer. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ClearGPIOResetSelect(VOID) +{ + WRITE_IO32 (GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1, BIT30); // 0x60 + WRITE_IO32 (GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL2, BIT30); // 0x64 + WRITE_IO32 (GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL3, BIT30); // 0x68 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SbLib_RunTimeResetCallback +// +// Description: Dispatch E-Link SbRuntimeResetElinkList. +// +// Input: IN EFI_RESET_TYPE ResetType +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +SbLib_RunTimeResetCallback( + IN EFI_RESET_TYPE ResetType + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN i; + + for (i = 0; SbRunResetCallbackList[i] != NULL; i++) + Status = SbRunResetCallbackList[i](ResetType); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_ResetSystem +// +// Description: This function is the reset call interface function published +// by the reset PPI +// +// Input: ResetType - Type of reset to be generated +// +// Output: SYSTEM RESET +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBLib_ResetSystem ( + IN EFI_RESET_TYPE ResetType ) +{ + UINT8 OutputData; + UINT32 Data32; + UINT16 Data16; +#if defined CAPSULE_SUPPORT && CAPSULE_SUPPORT == 1 + EFI_GUID SbWarmResetGuid = SB_WARM_RESET_GUID; + CHAR16 SbWarmResetVar[] = SB_WARM_RESET_VARIABLE; + UINT32 SbWarmResetFlag = SB_WARM_RESET_TAG; + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID gCapsuleVendorGuid = EFI_CAPSULE_AMI_GUID; + EFI_PHYSICAL_ADDRESS IoData; + UINTN Size = sizeof(EFI_PHYSICAL_ADDRESS); +#endif + + SbLib_RunTimeResetCallback(ResetType); + + switch (ResetType) { + case EfiResetWarm: +#if defined CAPSULE_SUPPORT && CAPSULE_SUPPORT == 1 + if (pRS->GetVariable(CAPSULE_UPDATE_VAR,&gCapsuleVendorGuid, NULL, &Size, &IoData) == EFI_SUCCESS) { + Status = pRS->SetVariable( SbWarmResetVar, \ + &SbWarmResetGuid, \ + EFI_VARIABLE_NON_VOLATILE | \ + EFI_VARIABLE_BOOTSERVICE_ACCESS | \ + EFI_VARIABLE_RUNTIME_ACCESS, \ + sizeof(SbWarmResetFlag), \ + &SbWarmResetFlag ); + + SBLib_S3InsteadOfWarmReset(); + return; + } +#endif + WRITE_IO8 (R_PCH_RST_CNT, V_PCH_RST_CNT_SOFTSTARTSTATE); + OutputData = V_PCH_RST_CNT_SOFTRESET; + break; + + case EfiResetCold: + WRITE_IO8 (R_PCH_RST_CNT, V_PCH_RST_CNT_HARDSTARTSTATE); + // [EIP81593]> +#if defined COLD_RESET_WITH_POWER_CYCLE && \ + COLD_RESET_WITH_POWER_CYCLE == 1 + OutputData = V_PCH_RST_CNT_FULLRESET; +#else + OutputData = V_PCH_RST_CNT_HARDRESET; +#endif + // <[EIP81593] + break; + + case EfiResetShutdown: + // + // Firstly, ACPI decode must be enabled + // + SET_PCI8_SB(R_PCH_LPC_ACPI_CNT, B_PCH_LPC_ACPI_CNT_ACPI_EN); + + // + // Then, GPE0_EN should be disabled to avoid any GPI waking up the system from S5 + // + Data16 = 0; + + WRITE_IO32_PM(R_PCH_ACPI_GPE0a_EN, Data16); + WRITE_IO16_PM(R_PCH_ACPI_GPE0b_EN, Data16); + + // + // Secondly, PwrSts register must be cleared + // + // Write a "1" to bit[8] of power button status register at + // (PM_BASE + PM1_STS_OFFSET) to clear this bit + // + Data16 = B_PCH_SMI_STS_PM1_STS_REG; + WRITE_IO16_PM(R_PCH_ACPI_PM1_STS, Data16); + + // + // Finally, transform system into S5 sleep state + // + Data32 = READ_IO32_PM(R_PCH_ACPI_PM1_CNT); + Data32 &= ~(B_PCH_ACPI_PM1_CNT_SLP_TYP + B_PCH_ACPI_PM1_CNT_SLP_EN); + Data32 |= V_PCH_ACPI_PM1_CNT_S5; + WRITE_IO32_PM(R_PCH_ACPI_PM1_CNT, Data32); + Data32 = Data32 | B_PCH_ACPI_PM1_CNT_SLP_EN; + WRITE_IO32_PM(R_PCH_ACPI_PM1_CNT, Data32); + + EFI_DEADLOOP () + + default: + return; + } + + WRITE_IO8 (R_PCH_RST_CNT, OutputData); + // + // Waiting for system reset + // + EFI_DEADLOOP () +} + +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_ExtResetSystem +// +// Description: This function is the extended reset call interface function +// provided by SB. +// +// Input: ResetType - The extended type of reset to be generated +// +// Output: SYSTEM RESET +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBLib_ExtResetSystem ( + IN SB_EXT_RESET_TYPE ResetType ) +{ + UINT16 GpioBase; + UINT8 OutputData; + EFI_STATUS Status = EFI_SUCCESS; + + GpioBase = READ_PCI16_SB (R_PCH_LPC_GPIO_BASE) & B_PCH_LPC_GPIO_BASE_BAR; + + // Issue some delay before system reset. +#if SB_STALL_PPI_SUPPORT + Status = CountTime(4000, PM_BASE_ADDRESS); // 1ms +#endif + + // Disable All SMI Enables, include the Global SMI. + WRITE_IO32_PM(ACPI_IOREG_SMI_EN, 0); // 0x30 + + switch (ResetType) { + case SbResetFull: + case SbResetGlobal: + WRITE_IO32 ((GpioBase + R_PCH_GP_RST_SEL), 0); + WRITE_IO32 ((GpioBase + R_PCH_GP_RST_SEL2), 0); + WRITE_IO32 ((GpioBase + R_PCH_GP_RST_SEL3), 0); + + if (ResetType == SbResetGlobal) + SET_PCI32_SB(R_PCH_LPC_PMIR, B_PCH_LPC_PMIR_CF9GR); + + OutputData = V_PCH_RST_CNT_FULLRESET; + break; + + default: + return; + } + + WRITE_IO8 (R_PCH_RST_CNT, OutputData); + + // We should never get this far + EFI_DEADLOOP(); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: StopUsb +// +// Description: This routine stops all USB controller action. +// +// Input: Bus - The PCI bus number for the USB controller +// Dev - The PCI device number for the USB controller +// Fun - The PCI function number for the USB controller +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID StopUsb ( + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Fun ) +{ +//#### UINT32 MmioBase; +//#### UINT16 IoBase; +//#### UINT16 TimeOut = 0x1000; + +//#### if (READ_PCI32(Bus, Dev, Fun, 0) != 0xffffffff) { +//#### if ((READ_PCI32(Bus, Dev, Fun, 4) & 0x3) == 0) return; +//#### if (READ_PCI8(Bus, Dev, Fun, USB_REG_PI) == 0x20) { // USB 2.0 +//#### WRITE_PCI8(Bus, Dev, Fun, USB20_REG_LEGSUP_EXTCS, 0); // 0x6C +//#### MmioBase = READ_PCI32(Bus, Dev, Fun, USB20_REG_MEM_BASE_ADDR); +//#### RESET_MEM32(MmioBase | 0x20, 1); +//#### while (READ_MEM32(MmioBase | 0x20) & 1) { +//#### TimeOut--; +//#### if (TimeOut == 0) break; +//#### } +//#### } else { // USB 1.1 +//#### WRITE_PCI8(Bus, Dev, Fun, USB_REG_LEGSUP, 0); // 0xC0 +//#### IoBase = READ_PCI32(Bus, Dev, Fun, USB_REG_BASE_ADDR) & 0xfffe; +//#### RESET_IO16(IoBase, 1); +//#### while (IoRead16(IoBase) & 1) { +//#### TimeOut--; +//#### if (TimeOut == 0) break; +//#### } +//#### } +//#### } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UsbS02SxWorkaround +// +// Description: PCH BIOS Spec Rev 0.5.0, Section 12.10.1 +// Additional Programming Requirements prior to enter S4/S5 +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +UsbS02SxWorkaround ( + VOID + ) +{ + UINT8 Index; + UINTN EhciPciRegBase; + UINT32 UsbBar; + UINT16 CmdReg; + UINT16 PowerState; + USB_CONTROLLER EhciControllersMap[PchEhciControllerMax] = { + { + PCI_DEVICE_NUMBER_PCH_USB, + PCI_FUNCTION_NUMBER_PCH_EHCI + }, + { + PCI_DEVICE_NUMBER_PCH_USB_EXT, + PCI_FUNCTION_NUMBER_PCH_EHCI2 + } + }; + + /// + /// System BIOS must execute the following steps prior to enter S4/S5. + /// + for (Index = 0; Index < GetPchEhciMaxControllerNum (); Index++) { + /// + /// Step 1 + /// Read "Memory Base Address (MEM_BASE) Register" of D26/D29:F0 + /// + EhciPciRegBase = MmPciAddress (PCIEX_BASE_ADDRESS, 0, EhciControllersMap[Index].Device, EhciControllersMap[Index].Function, 0); + UsbBar = MmioRead32 (EhciPciRegBase + R_PCH_EHCI_MEM_BASE); + CmdReg = MmioRead16 (EhciPciRegBase + R_PCH_EHCI_COMMAND_REGISTER); + PowerState = MmioRead16 (EhciPciRegBase + R_PCH_EHCI_PWR_CNTL_STS); + + if (UsbBar != 0xFFFFFFFF) { + /// + /// Check if the Ehci device is in D3 power state + /// + if ((PowerState & B_PCH_EHCI_PWR_CNTL_STS_PWR_STS) == V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D3) { + /// + /// Step 2 + /// Set "Power State" bit of PWR_CNTL_STS register, D26/D29:F0:54h [1:0] = 0h + /// + MmioWrite16 (EhciPciRegBase + R_PCH_EHCI_PWR_CNTL_STS, (PowerState &~B_PCH_EHCI_PWR_CNTL_STS_PWR_STS)); + /// + /// Step 3 + /// Write back the value from step 1 to the "Memory Base Address (MEM_BASE) Register" of D26/D29:F0 + /// + MmioWrite32 (EhciPciRegBase + R_PCH_EHCI_MEM_BASE, UsbBar); + /// + /// Step 4 + /// Enable "Memory Space Enable (MSE)" bit, set D26/D29:F0:04h [1] = 1b. + /// + SET_MEM16 ( + EhciPciRegBase + R_PCH_EHCI_COMMAND_REGISTER, + (UINT16) (B_PCH_EHCI_COMMAND_MSE) + ); + } + /// + /// Step 5 + /// Clear "Asynchronous Schedule Enable" and "Periodic Schedule Enable" bits, if "Run/Stop (RS)" bit, MEM_BASE + offset 20h [0] = 1b. + /// Proceed to steps below if "Run/Stop (RS)" bit, MEM_BASE + offset 20h [0] = 0b. + /// + if (!(MmioRead32 (UsbBar + R_PCH_EHCI_USB2CMD) & B_PCH_EHCI_USB2CMD_RS)) { + RESET_MEM32 (UsbBar + R_PCH_EHCI_USB2CMD, (UINT32)(B_PCH_EHCI_USB2CMD_ASE | B_PCH_EHCI_USB2CMD_PSE)); + SET_MEM32 (UsbBar + R_PCH_EHCI_USB2CMD, B_PCH_EHCI_USB2CMD_RS); + } + /// + /// Step 6 + /// If "Port Enabled/Disabled" bit of Port N Status and Control (PORTSC) Register is set, MEM_BASE + 64h [2] = 1b, + /// proceed steps below else continue with S4/S5. + /// + if ((MmioRead32 (UsbBar + R_PCH_EHCI_PORTSC0) & R_PCH_EHCI_PORTSC0_PORT_EN_DIS)) { + /// + /// Step 7 + /// Ensure that "Suspend" bit of Port N Status and Control (PORTSC) Register is set, MEM_BASE + 64h [7] = 1b. + /// + if (!(MmioRead32 (UsbBar + R_PCH_EHCI_PORTSC0) & R_PCH_EHCI_PORTSC0_SUSPEND)) { + SET_MEM32 (UsbBar + R_PCH_EHCI_PORTSC0, R_PCH_EHCI_PORTSC0_SUSPEND); + } + /// + /// Step 8 + /// Set delay of 25ms + /// + CountTime((25 * 1000), PM_BASE_ADDRESS); + /// + /// Step 9 + /// Clear "Run/Stop (RS)" bit, MEM_BASE + offset 20h [0] = 0b. + /// + RESET_MEM32 (UsbBar + R_PCH_EHCI_USB2CMD, (UINT32)(B_PCH_EHCI_USB2CMD_RS)); + } + /// + /// If the EHCI device is in D3 power state before executing this WA + /// + if ((PowerState & B_PCH_EHCI_PWR_CNTL_STS_PWR_STS) == V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D3) { + /// + /// Restore PCI Command Register + /// + MmioWrite16 (EhciPciRegBase + R_PCH_EHCI_COMMAND_REGISTER, CmdReg); + /// + /// Set "Power State" bit of PWR_CNTL_STS register to D3 state, D26/D29:F0:54h [1:0] = 3h + /// + MmioWrite16 (EhciPciRegBase + R_PCH_EHCI_PWR_CNTL_STS, PowerState); + } + /// + /// Step 10 + /// Continue with S4/S5 + /// + } + } +} + // [EIP83075]> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: XhciS5Workaround +// +// Description: PCH BIOS Spec Rev 0.7.0, Section 13.5 +// Additional xHCI Controller Configurations Prior to Entering S5 +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID XhciS5Workaround ( VOID ) +{ + UINT32 XhciMmioBase; + // + // Check if XHCI controller is enabled + // + if ((READ_MEM32_RCRB(R_PCH_RCRB_FUNC_DIS) & B_PCH_RCRB_FUNC_DIS_XHCI) != 0) { + return ; + } + // + // System BIOS must execute the following steps for all steppings prior to S5 + // + // + XhciMmioBase = READ_PCI32( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_MEM_BASE + ) & ~(0x0F); + + if (XhciMmioBase != 0) { + //Clear "Run/Stop (RS)" bit, + RESET_MEM32(XhciMmioBase + R_PCH_XHCI_USBCMD, B_PCH_XHCI_USBCMD_RS); + } + // Step 1 + // Set D3hot state - 11b + // + SET_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_PWR_CNTL_STS, \ + (BIT00 | BIT01) + ); + + // + // Step 2 + // Set "PME Enable" bit of PWR_CNTL_STS register, D20:F0:74h[8] = 1h + // + SET_PCI16( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_PWR_CNTL_STS, \ + BIT08 + ); +} + // <[EIP83075] + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_BeforeShutdown +// +// Description: This routine will be called before shutdown or ACPI S5,(If +// S5 Sleep SMI is enabled. +// +// Input: None +// +// Output: None +// +// Notes: Porting required if any workaround is needed. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBLib_BeforeShutdown (VOID) +{ + UINT8 DevNo; + UINT8 FunNo; + +//#### StopUsb( EUSB_BUS, EUSB_DEV, EUSB_FUN ); + + for (DevNo = 0; DevNo < 0x20 ; DevNo++) { + if (READ_PCI32(0, DevNo, 0, PCI_VID) != 0xffffffff) { + FunNo = (READ_PCI8(0, DevNo, 0, PCI_HDR) & 0x80) ? 8 : 1; + do { + FunNo--; + if (READ_PCI32(0, DevNo, FunNo, PCI_VID) != 0xffffffff) { + RESET_PCI16(0, DevNo, FunNo, PCI_CMD, 4); + } + } while (FunNo); + } + } +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_Shutdown +// +// Description: Shutdown the system (Enter soft-off/S5) +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBLib_Shutdown (VOID) +{ + UINT16 Buffer16; + + // Clear ME wake status + ClearMeWakeSts(); + + UsbS02SxWorkaround(); + XhciS5Workaround(); // [EIP83075] + + // Disable Sleep SMI + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x10); // 0x30 + + SBLib_BeforeShutdown(); + + // Clear power button status + Buffer16 = READ_IO16(PM_BASE_ADDRESS) | (UINT16)(1 << 8); + do { + WRITE_IO16(PM_BASE_ADDRESS, Buffer16); + for (Buffer16 = 0; Buffer16 < 0x100; Buffer16++) + WRITE_IO8(IO_DELAY_PORT, (UINT8)Buffer16); + Buffer16 = READ_IO16(PM_BASE_ADDRESS); + } while (Buffer16 & 0x100); + + // Enter soft-off/S5 + RW_IO16(PM_BASE_ADDRESS + ACPI_IOREG_PM1_CNTL, \ + (SLP_S5 | 8 ) << 10, 15 << 10); + + // We should never get this far + EFI_DEADLOOP(); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure:ClearMeWakeSts +// +// Description: Clear the ME wake up status. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ClearMeWakeSts(VOID) +{ +// Mmio32(SB_RCBA, ICH_RCRB_PRSTS) |= BIT00; + SET_MEM8_RCRB(R_PCH_RCRB_PRSTS, BIT00); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: Enable_GbE_PME +// +// Description: Enable the Gigabit Ethernet Controller PME +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID Enable_GbE_PME(VOID) +{ + if (READ_PCI16_LAN(R_PCH_LAN_VENDOR_ID) != 0xffff) + { + if (GetPchSeries() == PchLp) { + WRITE_IO16_PM(ACPI_PCHLP_IOREG_GPE0_STS+0x0c, BIT13); + SET_IO16_PM(ACPI_PCHLP_IOREG_GPE0_EN+0x0c, BIT13); + } else { + WRITE_IO16_PM(ACPI_IOREG_GPE0_STS, BIT13); + SET_IO16_PM(ACPI_IOREG_GPE0_EN, BIT13); + } + SET_PCI16_LAN(R_PCH_LAN_PMCS, BIT08); + } +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: HighBitSet32 +// +// Description: Returns the bit position of the highest bit set in a 32-bit value. Equivalent +// to log2(x). +// +// Input: Operand - Operand The 32-bit operand to evaluate. +// +// Output: Position of the highest bit set in Operand if found. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +INTN +EFIAPI +HighBitSet32 ( + IN UINT32 Operand + ) +{ + INTN BitIndex; + + for (BitIndex = -1; Operand != 0; BitIndex++, Operand >>= 1); + return BitIndex; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetPowerOfTwo32 +// +// Description: Returns the value of the highest bit set in a 32-bit value. Equivalent to +// 1 << HighBitSet32(x). +// +// Input: Operand - Operand The 32-bit operand to evaluate. +// +// Output: Return 1 << HighBitSet32(Operand) +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT32 +EFIAPI +GetPowerOfTwo32 ( + IN UINT32 Operand + ) +{ + if (Operand == 0) { + return 0; + } + + return 1ul << HighBitSet32 (Operand); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ChipsetFlashDeviceWriteEnable +// +// Description: This function is invoked to do any chipset specific +// operations, that are necessary when enabling the Flash Part +// for writing. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ChipsetFlashDeviceWriteEnable (VOID) +{ +// UINT32 Data32; + + // + // Set BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 1b + // + RW_PCI8_SB(SB_REG_BIOS_CNTL, BIT00, BIT05); + + // + // PCH BIOS Spec Section 3.7 BIOS Region SMM Protection Enabling + // If the following steps are implemented: + // - Set the SMM_BWP bit (B0:D31:F0 Offset DCh [5]) = 1b + // - Follow the 1st recommendation in section 3.6 + // the BIOS Region can only be updated by following the steps bellow: + // - Once all threads enter SMM + // - Read memory location FED30880h OR with 00000001h, place the result in EAX, + // and write data to lower 32 bits of MSR 1FEh (sample code available) + // - Set BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 1b + // - Modify BIOS Region + // - Clear BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 0b + // - Read memory location FED30880h AND with FFFFFFFEh, place the result in EAX, + // and write data to lower 32 bits of MSR 1FEh (sample code available) + // + + // + // Check if SMM_BWP bit and BLE bit are both set + // + if ((READ_PCI8_SB(SB_REG_BIOS_CNTL) & 0x22) == 0x22) { + // + // Read memory location FED30880h OR with 00000001h, place the result in EAX, + // and write data to lower 32 bits of MSR 1FEh (sample code available) + // + // EIP106353 >> + if ( !((ReadMsr (MSR_PLATFORM_INFO) & B_MSR_PLATFORM_INFO_PFAT_AVAIL) && + (ReadMsr (MSR_PLAT_FRMW_PROT_CTRL) & B_MSR_PLAT_FRMW_PROT_CTRL_EN)) ) { +// Data32 = MmioRead32 ((UINTN) (0xFED30880)) | (UINT32) (BIT0); +// WriteMsr(0x1FE, Data32); + } + // EIP106353 << + } + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ChipsetFlashDeviceWriteDisable +// +// Description: This function is invoked to do any chipset specific +// operations, that are necessary when disabling the Flash Part +// for writing. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ChipsetFlashDeviceWriteDisable (VOID) +{ +// UINT32 Data32; + + // + // Clear BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 0b + // + RESET_PCI8_SB(SB_REG_BIOS_CNTL, BIT00); + // + // Check if SMM_BWP bit and BLE bit are both set + // + if ((READ_PCI8_SB(SB_REG_BIOS_CNTL) & 0x22) == 0x22) { + // + // Read memory location FED30880h AND with FFFFFFFEh, place the result in EAX, + // and write data to lower 32 bits of MSR 1FEh (sample code available) + // + // EIP106353 >> + if ( !((ReadMsr (MSR_PLATFORM_INFO) & B_MSR_PLATFORM_INFO_PFAT_AVAIL) && + (ReadMsr (MSR_PLAT_FRMW_PROT_CTRL) & B_MSR_PLAT_FRMW_PROT_CTRL_EN)) ) { +// Data32 = MmioRead32 ((UINTN) (0xFED30880)) & (UINT32) (~BIT0); +// WriteMsr (0x1FE, Data32); + } + // EIP106353 << + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: BiosLockEnableSMIFlashHook +// +// Description: The procedure clears BIOSWR_STS after Enable Flash SWSMI, +// for prevent that AFU write operation fail when BIOS Lock +// is enabled. +// +// Input: UINT8 SwSmiNum +// UINT64 Buffer +// +// Output: UINT64 Buffer +// +// Returns: NONE +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +BiosLockEnableSMIFlashHook ( + IN UINT8 SwSmiNum, + IN OUT UINT64 Buffer +) +{ + if ((SwSmiNum != 0x20) || \ + ((READ_PCI8_SB(R_PCH_LPC_BIOS_CNTL) & B_PCH_LPC_BIOS_CNTL_BLE) == 0)) + return; + + // Clear BIOSWR_STS + SET_IO16_TCO(R_PCH_TCO1_STS, B_PCH_TCO1_STS_BIOSWR); + + // Clear TCO_STS + SET_IO16_PM(R_PCH_SMI_STS, B_PCH_SMI_STS_TCO); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBIsDefaultConfigMode +// +// Description: This function determines if the system should boot with the +// default configuration. +// +// Input: EFI_PEI_SERVICES - Pointer to the PEI services table +// EFI_PEI_READ_ONLY_VARIABLE2_PPI - Pointer to the Read +// Variable#2 PPI +// (The pointer can be used to read and enumerate existing NVRAM +// variables) +// +// Output: TRUE - Firmware will boot with default configuration. +// +// Notes: 1. If boot with default configuration is detected, default +// values for NVRAM variables are used. +// 2. Normally we have to check RTC power status or CMOS clear +// jumper status to determine whether the system should boot +// with the default configuration. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SBIsDefaultConfigMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadVariablePpi ) +{ + UINT8 Buffer8; + + Buffer8 = READ_PCI8_SB(SB_REG_GEN_PMCON_3); // 0xA4 + return (Buffer8 & 4) ? TRUE : FALSE; +} + +#if SB_STALL_PPI_SUPPORT + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: CountTime +// +// Description: This function delays for the number of micro seconds passed in +// +// Input: DelayTime - Number of microseconds(us) to delay +// BaseAddr - The I/O base address of the ACPI registers +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS CountTime ( + IN UINTN DelayTime, + IN UINT16 BaseAddr ) // Only needs to be 16 bit for I/O address +{ +// The following code is to generate delay for specified amount of micro +// seconds using ACPI timer. + UINTN TicksNeeded; + UINT32 TimerValue; + UINT32 NewTimerValue; + UINTN OverFlow; + UINTN TheRest; + UINTN EndValue; + + // Set up timer to point to the ACPI Timer register + BaseAddr += ACPI_IOREG_PM1_TMR; // *** PORTING NEEDED + + // There are 3.58 ticks per us, so we have to convert the number of us + // passed in to the number of ticks that need to pass before the timer has + // expired convert us to Ticks, don't loose significant figures or as few + // as possible do integer math in ticks/tens of ns and then divide by 100 + // to get ticks per us + OverFlow = 0; + +//#### TheRest = TicksNeeded = (DelayTime * 358) /100; + TicksNeeded = DelayTime * 3; //(DelayTime * 3) + TicksNeeded += (DelayTime) / 2; //(DelayTime * 5)/10 + TicksNeeded += (DelayTime * 2) / 25; //(DelayTime * 8)/100 + TheRest = TicksNeeded; + + // 32 bits corresponds to approz 71 mins no delay should be that long + // otherwise get the number of times the counter will have to overflow + // to delay as long as needed + if (NUM_BITS_IN_ACPI_TIMER < MAX_ACPI_TIMER_BITS) { + OverFlow = TicksNeeded / (1 << NUM_BITS_IN_ACPI_TIMER); + TheRest = TicksNeeded % (1 << NUM_BITS_IN_ACPI_TIMER); + } + + // Read ACPI Timer + TimerValue = IoRead32( BaseAddr ); + + // Need to adjust the values based off of the start time + EndValue = TheRest + TimerValue; + + // Check for overflow on addition. possibly a problem + if (EndValue < TimerValue) { + OverFlow++; + } else { + if (NUM_BITS_IN_ACPI_TIMER < MAX_ACPI_TIMER_BITS) { + // Here make sure that EndValue is less than the max value + // of the counter + OverFlow += EndValue / (1 << NUM_BITS_IN_ACPI_TIMER); + EndValue = EndValue % (1 << NUM_BITS_IN_ACPI_TIMER); + } + } + + // Let the timer wrap around as many times as calculated + while (OverFlow) { + // read timer amd look to see if the new value read is less than + // the current timer value. if this happens the timer overflowed + NewTimerValue = IoRead32(BaseAddr); + + if (NewTimerValue < TimerValue) OverFlow--; + + TimerValue = NewTimerValue; + } + + // Now wait for the correct number of ticks that need to occur after + // all the needed overflows + while (EndValue > TimerValue) { + NewTimerValue = IoRead32(BaseAddr); + + // check to see if the timer overflowed. if it did then + // the time has elapsed. Because EndValue should be greater than + // TimerValue + if (NewTimerValue < TimerValue) break; + + TimerValue = NewTimerValue; + } + + return EFI_SUCCESS; +} + + +#endif + +//--------------------------------------------------------------------------- + +#if CMOS_MANAGER_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReadWriteCmosBank2 +// +// Description: This function is used to access addresses in the CMOS +// register range (0x80-0xff), for PEI and DXE boot phases. +// +// Input: **PeiServices - PEI Services table pointer +// (NULL in DXE phase) +// AccessType - ReadType or WriteType to specify the +// type of access +// CmosRegister - The CMOS register to access +// *CmosParameterValue - Pointer to the data variable to be +// accessed +// +// Output: EFI_STATUS (return value) +// EFI_SUCCESS - The access operation was successfull. +// Otherwise - A valid EFI error code is returned. +// +// Modified: None +// +// Referrals: IoRead8, IoWrite8 +// +// Notes: This function is used when a translation from logical address +// to index port value is required. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ReadWriteCmosBank2 ( + IN EFI_PEI_SERVICES **PeiServices, // NULL in DXE phase + IN CMOS_ACCESS_TYPE AccessType, + IN UINT16 CmosRegister, + IN OUT UINT8 *CmosParameterValue ) +{ + if ((CmosRegister < 0x80) || (CmosRegister > 0xff)) + return EFI_INVALID_PARAMETER; + + // Some chipsets require tranlation from the logical CMOS address to a + // physical CMOS index port value. However, other chipsets do not require + // a translation and the index/data port can be directly used for + // accessing the second bank. + + IoWrite8( CMOS_IO_EXT_INDEX, (UINT8)CmosRegister ); + + if (AccessType == ReadType) { + *CmosParameterValue = IoRead8( CMOS_IO_EXT_DATA ); + } else { + IoWrite8( CMOS_IO_EXT_DATA, *CmosParameterValue ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbGetRtcPowerStatus +// +// Description: This function is checked CMOS battery is good or not. +// +// Input: **PeiServices - PEI Services table pointer (NULL in DXE phase) +// +// Output: BOOLEAN +// TRUE - The CMOS is battery is good. +// FALSE - The CMOS is battery is bad. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SbGetRtcPowerStatus ( + IN EFI_PEI_SERVICES **PeiServices ) +{ + return (READ_PCI8_SB(SB_REG_GEN_PMCON_3) & 4) ? FALSE : TRUE; // 0xA4 +} + +#endif // #if CMOS_MANAGER_SUPPORT + //Improve alternate access mode >> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwitchAlternateAccessMode +// +// Description: Enable or disable Alternate Access Mode. +// +// Input: TRUE: Enable Alternate Access Mode +// FALSE: Disable Alternate Access Mode +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SwitchAlternateAccessMode +( + BOOLEAN Switch +) +{ + if (Switch) { + do { + // Enable Alternate Access Mode + SET_MEM32_RCRB(R_PCH_RCRB_GCS, B_PCH_RCRB_GCS_AME); + } while((READ_MEM32_RCRB(R_PCH_RCRB_GCS) & B_PCH_RCRB_GCS_AME) == 0); + } else { + do { + // Disable Alternate Access Mode + RESET_MEM32_RCRB(R_PCH_RCRB_GCS, B_PCH_RCRB_GCS_AME); + } while(READ_MEM32_RCRB(R_PCH_RCRB_GCS) & B_PCH_RCRB_GCS_AME); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReadPort70h +// +// Description: Read port 70h. +// +// Input: None +// +// Output: Data of port 70h. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 ReadPort70h ( VOID ) +{ + UINT8 Port70h; + + SwitchAlternateAccessMode (TRUE); + + Port70h = IoRead8(RTC_INDEX_REG); + + SwitchAlternateAccessMode (FALSE); + + return Port70h; +} //Improve alternate access mode << + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReadCmos +// +// Description: This function reads one byte from CMOS register addressed by Index +// +// Input: UINT8 Index +// +// Output: UINT8 - read value +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 ReadCmos( + IN UINT8 Index +) +{ + // Read bit 7 (NMI setting). + UINT8 NMI = 0; + volatile UINT8 Value; + BOOLEAN IntState = CPULib_GetInterruptState(); + UINT8 RtcIndexPort; + UINT8 RtcDataPort; + + CPULib_DisableInterrupt(); + + if (Index < 0x80) { + // Standard CMOS + RtcIndexPort = RTC_INDEX_REG; + RtcDataPort = RTC_DATA_REG; + + if (Index < 0x80) //Improve alternate access mode >> + // Save current NMI_EN. + NMI = ReadPort70h() & RTC_NMI_MASK; //Improve alternate access mode << + + } else { + // Upper CMOS + RtcIndexPort = CMOS_IO_EXT_INDEX; + RtcDataPort = CMOS_IO_EXT_DATA; + } + + Index &= ~RTC_NMI_MASK; + + IoWrite8(RtcIndexPort, Index | NMI); + Value = IoRead8(RtcDataPort); // Read register. + + if (IntState) CPULib_EnableInterrupt(); + + return (UINT8)Value; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: WriteCmos +// +// Description: This function writes value to CMOS register addressed by Index +// +// Input: UINT8 Index - CMOS register index +// UINT8 Value - value to write +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID WriteCmos( + IN UINT8 Index, + IN UINT8 Value +) +{ + // Read bit 7 (NMI setting). + UINT8 NMI = 0; + BOOLEAN IntState = CPULib_GetInterruptState(); + UINT8 RtcIndexPort; + UINT8 RtcDataPort; + + CPULib_DisableInterrupt(); + + if (Index < 0x80) { + // Standard CMOS + RtcIndexPort = RTC_INDEX_REG; + RtcDataPort = RTC_DATA_REG; + + //Improve alternate access mode >> + // Save current NMI_EN. + NMI = ReadPort70h() & RTC_NMI_MASK; + //Improve alternate access mode << + } else { + // Upper CMOS + RtcIndexPort = CMOS_IO_EXT_INDEX; + RtcDataPort = CMOS_IO_EXT_DATA; + } + + Index &= ~RTC_NMI_MASK; + + IoWrite8(RtcIndexPort, Index | NMI); + IoWrite8(RtcDataPort, Value); // Write Register. + + if (IntState) CPULib_EnableInterrupt(); +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbLib_GetSmiState +// +// Description: This function returns SMI state +// +// Input: None +// +// Output: TRUE - SMI enabled, FALSE - SMI disabled +// +// Note: This function must work at runtime. Do not use boot time +// services/protocols. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SbLib_GetSmiState (VOID) +{ +#if SMM_SUPPORT + static BOOLEAN OriginalSmiState = FALSE; + static BOOLEAN HadBeenCame = FALSE; + volatile BOOLEAN SmiState = (READ_IO32_PM(ACPI_IOREG_SMI_EN) & 1) ? \ + TRUE : FALSE; + + if (HadBeenCame && SmiState) HadBeenCame = FALSE; + + if (HadBeenCame) { + SmiState = OriginalSmiState; + } else { + OriginalSmiState = SmiState; + HadBeenCame = TRUE; + } + + return SmiState; +#else + return FALSE; +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbLib_SmiDisable +// +// Description: This function disables SMI +// +// Input: None +// +// Output: None +// +// Note: This function should be used ONLY in critical parts of code. +// This function must work at runtime. Do not use boot time +// services/protocols +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbLib_SmiDisable (VOID) +{ +#if SMM_SUPPORT + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 3); // 0x30 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbLib_SmiEnable +// +// Description: This function enables SMI +// +// Input: None +// +// Output: None +// +// Note: This function should be used ONLY in critical parts of code. +// This function must work at runtime. Do not use boot time +// services/protocols +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbLib_SmiEnable (VOID) +{ + +#if SMM_SUPPORT + SET_IO32_PM(ACPI_IOREG_SMI_EN, 2); // 0x30 + SET_IO32_PM(ACPI_IOREG_SMI_EN, 1); // 0x30 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: CspLibCheckPowerLoss +// +// Description: This function is PM Specific function to check and Report to +// the System Status Code - CMOS Battary and Power Supply Power +// loss/failure. Also it responcibe of clearing PM Power Loss +// Statuses +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID CspLibCheckPowerLoss (VOID) +{ + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbLib_SetLpcDeviceDecoding +// +// Description: This function sets LPC Bridge Device Decoding +// +// Input: *LpcPciIo - Pointer to LPC PCI IO Protocol +// Base - I/O base address, if Base is 0 means disabled the +// decode of the device +// DevUid - The device Unique ID +// Type - Device Type, please refer to AMISIO.h +// +// Output: EFI_STATUS +// EFI_SUCCESS - Set successfully. +// EFI_UNSUPPORTED - There is not proper Device Decoding +// register for the device UID. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SbLib_SetLpcDeviceDecoding ( + IN EFI_PCI_IO_PROTOCOL *LpcPciIo, + IN UINT16 Base, + IN UINT8 DevUid, + IN SIO_DEV_TYPE Type ) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + + // Porting Required + UINT16 ComRng[] = { 0x3f8, 0x2f8, 0x220, 0x228, \ + 0x238, 0x2e8, 0x338, 0x3e8, 0}; + UINT16 LptRange[] = { 0x378, 0x278, 0x3bc, 0}; + UINT16 FpcRange[] = { 0x3f0, 0x370, 0}; + UINT16 IoRangeMask16 = 0xffff; + UINT16 IoRangeSet16 = 0; + UINT16 IoEnMask16 = 0xffff; + UINT16 IoEnSet16 = 0; + UINT8 i; + + switch (Type) { + // FDC Address Range + case (dsFDC) : + if (Base == 0) IoEnMask16 &= ~BIT03; + else { + for (i = 0; (FpcRange[i] != 0) && (FpcRange[i] != Base); i++); + if (FpcRange[i]) { + IoEnSet16 |= BIT03; + IoRangeMask16 &= ~BIT12; + IoRangeSet16 |= (i << 12); + } + else return EFI_UNSUPPORTED; + } + break; + + // LPT Address Range + case (dsLPT) : + if (Base == 0) IoEnMask16 &= ~BIT02; + else { + for (i = 0; (LptRange[i] != 0) && (LptRange[i] != Base); i++); + if (LptRange[i]) { + IoEnSet16 |= BIT02; + IoRangeMask16 &= ~(BIT09 | BIT08); + IoRangeSet16 |= (i << 8); + } else return EFI_UNSUPPORTED; + } + break; + + // COM x Address Range + case (dsUART) : + if (Base == 0) { + switch (DevUid) { + case 0 : + IoEnMask16 &= ~BIT00; + break; + case 1 : + IoEnMask16 &= ~BIT01; + break; + case 2 : + break; + case 3 : + break; + default: + break; + } + } else { + if (DevUid < 2) { + for (i = 0; (ComRng[i] != 0) && (ComRng[i] != Base); i++); + if (ComRng[i]) { + if (DevUid) { + IoEnSet16 |= BIT01; + IoRangeMask16 &= ~(BIT06 | BIT05 | BIT04); + IoRangeSet16 |= (i << 4); + } else { + IoEnSet16 |= BIT00; + IoRangeMask16 &= ~(BIT02 | BIT01 | BIT00); + IoRangeSet16 |= i; + } + } else return EFI_UNSUPPORTED; + } else { + SbLib_SetLpcGenericDecoding( LpcPciIo, \ + Base , \ + 8, \ + TRUE ); + } + } + break; + + // KBC Address Enable + case (dsPS2K) : + case (dsPS2M) : + case (dsPS2CK) : + case (dsPS2CM) : + if (Base == 0) IoEnMask16 &= ~BIT10; + else IoEnSet16 |= BIT10; + break; + + // Game Port Address Enable + case (dsGAME) : + if (Base == 0) IoEnMask16 &= ~(BIT09 | BIT08); + else { + if (Base == 0x200) { + IoEnSet16 |= BIT08; + } else { + if (Base == 0x208) IoEnSet16 |= BIT09; + else return EFI_UNSUPPORTED; + } + } + break; + + // Other Address Enable + case (0xff) : + switch (Base) { + case (0x2e) : + IoEnSet16 |= BIT12; + break; + case (0x4e) : + IoEnSet16 |= BIT13; + break; + case (0x62) : + case (0x63) : + case (0x64) : + case (0x65) : + case (0x66) : + IoEnSet16 |= BIT11; + break; + case (0) : + return EFI_UNSUPPORTED; + break; + default : + SbLib_SetLpcGenericDecoding( LpcPciIo, \ + Base , \ + 4, \ + TRUE ); + break; + } + +//#### if (Base == 0x2e) IoEnSet16 |= BIT12; +//#### else { +//#### if (Base == 0x4e) IoEnSet16 |= BIT13; +//#### else { +//#### if (Base) SbLib_SetLpcGenericDecoding( LpcPciIo, \ +//#### Base , \ +//#### 4, \ +//#### TRUE ); +//#### else return EFI_UNSUPPORTED; +//#### } +//#### } + + break; + + default : + return EFI_UNSUPPORTED; + } + + RW_PCI16_SB(SB_REG_LPC_IO_DEC, IoRangeSet16, ~IoRangeMask16); // 0x80 + RW_PCI16_SB(SB_REG_LPC_EN, IoEnSet16, ~IoEnMask16); // 0x82 + // Porting End + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbLib_SetLpcGenericDecoding +// +// Description: This function sets LPC Bridge Generic Decoding +// +// Input: *LpcPciIo - Pointer to LPC PCI IO Protocol +// Base - I/O base address +// Length - I/O Length +// Enabled - Enable/Disable the generic decode range register +// +// Output: EFI_STATUS +// EFI_SUCCESS - Set successfully. +// EFI_UNSUPPORTED - This function is not implemented or the +// Length more than the maximum supported +// size of generic range decoding. +// EFI_INVALID_PARAMETER - the Input parameter is invalid. +// EFI_OUT_OF_RESOURCES - There is not available Generic +// Decoding Register. +// EFI_NOT_FOUND - the generic decode range will be disabled +// is not found. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SbLib_SetLpcGenericDecoding ( + IN EFI_PCI_IO_PROTOCOL *LpcPciIo, + IN UINT16 Base, + IN UINT16 Length, + IN BOOLEAN Enable ) +{ + // Porting Required + UINT32 IoGenDecode32; + UINT16 IoGenDecIndex; + UINT16 Buffer16; + UINT8 Bsf8 = 0; + UINT8 Bsr8 = 0; + + if (Length > 0x100) return EFI_UNSUPPORTED; + + if (Length == 0) return EFI_INVALID_PARAMETER; + + if (Length < 4) Length = 4; + + // Read I/O Generic Decodes Register. + for (IoGenDecIndex = 0; IoGenDecIndex < 4; IoGenDecIndex++) { + IoGenDecode32 = READ_PCI32_SB(SB_REG_GEN1_DEC + IoGenDecIndex * 4); + if (Enable) { + if ((IoGenDecode32 & 1) == 0) break; + } else { + if (((IoGenDecode32 & 0xfffc) == Base) && (IoGenDecode32 & 1)) { + IoGenDecode32 = 0; // Disable & clear the base/mask fields + break; + } + } + } + + if (Enable) { + if (IoGenDecIndex == 4) return EFI_OUT_OF_RESOURCES; + + Buffer16 = Length; + while ((Buffer16 % 2) == 0) { + Buffer16 /= 2; + Bsf8++; + } + + while (Length) { + Length >>= 1; + Bsr8++; + } + + if (Bsf8 == (Bsr8 - 1)) Bsr8--; + + Length = (1 << Bsr8) - 1 ; + + Base &= (~Length); + + IoGenDecode32 = Base | (UINT32)((Length >> 2) << 18) | 1; + + } else { + if (IoGenDecIndex == 4) return EFI_NOT_FOUND; + } + + WRITE_PCI32_SB(SB_REG_GEN1_DEC + IoGenDecIndex * 4, IoGenDecode32); + // Porting End + + return EFI_SUCCESS; + +} + +//--------------------------------------------------------------------------- +#if SMM_SUPPORT +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBSmmSaveRestoreStates +// +// Description: This hook is called in the very SMI entry and exit. +// Save/Restore chipset data if needed. +// +// Input: Save - TRUE = Save / FALSE = Restore +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBSmmSaveRestoreStates ( + IN BOOLEAN Save ) +{ + static volatile UINT8 StoreCMOS; + static volatile UINT8 StoreExtCMOS; + static volatile UINT32 StoreCF8; + static volatile UINT32 AltAcc; + static volatile UINT8 RtcRegA; + UINT8 SbCmosMiscFlag = 0; +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + static volatile BOOLEAN IsHpetApicEn = FALSE; + static volatile UINT8 StoreIoApicIndex; + volatile UINT8 Irq; +#endif + UINT32 Data32 =0; + + if (Save) { + StoreCF8 = IoRead32(0xcf8); // Store CF8 (PCI index) + + // Save Alternate access bit. + AltAcc = READ_MEM32_RCRB(RCRB_MMIO_GCS) & 0x10; + + StoreCMOS = ReadPort70h(); // Save 0x70 + + StoreExtCMOS = IoRead8(CMOS_IO_EXT_INDEX); // Save 0x72 + +#if defined CMOS_MANAGER_SUPPORT && CMOS_MANAGER_SUPPORT + IoWrite8(CMOS_IO_EXT_INDEX, SB_CMOS_MISC_FLAG_REG); + IoWrite8(CMOS_IO_EXT_DATA, 0); +#endif +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + StoreIoApicIndex = MMIO_READ8(APCB); + IsHpetApicEn = IsHpetApicEnable(); + if (IsHpetApicEn) { + Irq = GetHpetApicPin(); + IoApicMaskIrq(Irq); + } +#endif + + Data32 = MmioRead32 ((UINTN) (0xFED30880)) | (UINT32) (BIT0); + WriteMsr(0x1FE, Data32); + + } else { + do { + RtcRegA = SBLib_CmosRead(RTC_REG_A_INDEX); + } while (RtcRegA & 0x80); + +#if defined CMOS_MANAGER_SUPPORT && CMOS_MANAGER_SUPPORT + IoWrite8(CMOS_IO_EXT_INDEX, SB_CMOS_MISC_FLAG_REG); + SbCmosMiscFlag = IoRead8(CMOS_IO_EXT_DATA); + + if (SbCmosMiscFlag & ENABLE_NMI_BEFORE_SMI_EXIT) + StoreCMOS &= ~BIT07; // Enable NMI_EN + + if (SbCmosMiscFlag & DISABLE_NMI_BEFORE_SMI_EXIT) + StoreCMOS |= BIT07; // Disable NMI_EN +#endif + + IoWrite8(CMOS_ADDR_PORT, StoreCMOS); // Restore 0x70 + IoWrite8(CMOS_IO_EXT_INDEX, StoreExtCMOS); // Restore 0x72 + + // Restore Alternate access bit. + do { //Improve alternate access mode >> + RW_MEM32_RCRB(RCRB_MMIO_GCS, AltAcc, 0x10); + } while ((READ_MEM32_RCRB(RCRB_MMIO_GCS) & 0x10) != AltAcc); //Improve alternate access mode << + + IoWrite32(0xcf8, StoreCF8); // Restore 0xCF8 (PCI index) + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) + if (IsHpetApicEn) { + Irq = GetHpetApicPin(); + IoApicUnmaskIrq(Irq); + IoApicEoi(Irq); + } + + MMIO_WRITE8(APCB, StoreIoApicIndex); + StoreIoApicIndex = MMIO_READ8(APCB); +#endif + + Data32 = MmioRead32 ((UINTN) (0xFED30880)) & (UINT32) (~BIT0); + WriteMsr(0x1FE, Data32); + + } + + return EFI_SUCCESS; +} + +//--------------------------------------------------------------------------- +#endif // END OF SMM Related Porting Hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBProtectedPciDevice +// +// Description: This function is called by PCI Bus Driver before configuring +// or disabling any PCI device. This function should examine the +// Vendor/Device ID or PCI Bus, Device and Function numbers to +// make sure it is not a south bridge device or any other device +// which should no be configured by PCI Bus Driver. +// +// Input: *PciDevice - Pointer to PCI Device Info structure. +// +// Output: EFI_STATUS +// EFI_SUCCESS - SKIP this device, do not touch +// PCI Command register. +// EFI_UNSUPPORTED - DON'T SKIP this device do complete +// enumeration as usual. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SBProtectedPciDevice ( + IN PCI_DEV_INFO *PciDevice ) +{ + +//####if ((PciDevice->Address.Addr.Bus == SMBUS_BUS) && \ +//#### (PciDevice->Address.Addr.Device == SMBUS_DEV) && \ +//#### (PciDevice->Address.Addr.Function == SMBUS_FUN)) { +//#### +//#### return EFI_SUCCESS; +//####} + + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBProgramPciDevice +// +// Description: This function is called by PCI Bus Driver before installing +// Protocol Interface for the input device. +// +// Input: *PciDevice - Pointer to PCI Device Info structure. +// +// Output: EFI_SUCCESS +// +// Notes: All resource in the device had been assigned, but the command +// register is disabled. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SBProgramPciDevice ( + IN PCI_DEV_INFO *PciDevice ) +{ + +//####if ((PciDevice->Address.Addr.Bus == EUSB_BUS) && \ +//#### (PciDevice->Address.Addr.Device == EUSB_DEV) && \ +//#### (PciDevice->Address.Addr.Function == EUSB_FUN)) { +//#### // Do any porting if needed. +//####} + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBUpdatePciDeviceAttributes +// +// Description: This function is called by PCI Bus Driver, can be used to +// the attributes of the PCI device. +// +// Input: *PciDevice - Pointer to PCI Device Info structure. +// *Attributes - Attributes bitmask which caller whants to +// change. +// Capabilities - The PCI device supports Capabilityes +// Set - Specifies weathere to set or reset given +// "Attributes". +// +// Output: EFI_SUCCESS +// +// Notes: This routine may be invoked twice depend on the device type, +// the first time is at BDS phase, the second is before +// legacy boot. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SBUpdatePciDeviceAttributes ( + IN PCI_DEV_INFO *PciDevice, + IN OUT UINT64 *Attributes, + IN UINT64 Capabilities, + IN BOOLEAN Set ) +{ + +//####if ((PciDevice->Address.Addr.Bus == EUSB_BUS) && \ +//#### (PciDevice->Address.Addr.Device == EUSB_DEV) && \ +//#### (PciDevice->Address.Addr.Function == EUSB_FUN)) { +//#### // Do any porting if needed. +//####} + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReadSPIDescriptor +// +// Description: Read SPI Descriptor. +// +// Input: FDSS - Flash Descriptor Section Select. +// FDSI - Flash Descriptor Section Index. +// FDOD - Flash Descriptor Observability Data +// +// Output:EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReadSPIDescriptor( + IN UINT8 FDSS, + IN UINT8 FDSI, + OUT UINT32 *FDOD +) +{ + UINT32 Buffer32; + + WRITE_MEM32_SPI(R_RCRB_SPI_FDOC, 0); + + Buffer32 = READ_MEM32_SPI(R_RCRB_SPI_FDOD); + + if (Buffer32 != 0x0ff0a55a) //Improve alternate access mode + return EFI_NOT_FOUND; + + Buffer32 = ((UINT32)FDSS << 12) | ((UINT32)FDSI << 2); + WRITE_MEM32_SPI(R_RCRB_SPI_FDOC, Buffer32); + *FDOD = READ_MEM32_SPI(R_RCRB_SPI_FDOD); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetTotalFlashRomSize +// +// Description: Read SPI Descriptor to get Total Flash size. +// +// Input: None +// +// Output: UINT32 - Flash Rom Size +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT32 GetTotalFlashRomSize ( VOID ) +{ + UINT32 TotalRomSize = 0; + UINT32 CtrlData; + UINT8 NumSpi = 0; + + // Select to Flash Map 0 Register to get the number of flash Component + CtrlData = MmioRead32((SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_RCRB_SPI_FDOC)); + CtrlData &= (UINT32)(~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)); + CtrlData |= (UINT32)(V_PCH_SPI_FDOC_FDSS_FSDM | R_PCH_SPI_FDBAR_FLASH_MAP0); + MmioWrite32((SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_RCRB_SPI_FDOC), CtrlData); + + switch ( MmioRead16 (SB_RCBA + R_PCH_SPI_FDOD) & B_PCH_SPI_FDBAR_NC ) { + case V_PCH_SPI_FDBAR_NC_1: + NumSpi = 1; + break; + case V_PCH_SPI_FDBAR_NC_2: + NumSpi = 2; + break; + default: + break; + } + //if (NumSpi == 0) ASSERT_EFI_ERROR(EFI_DEVICE_ERROR); + + // Select to Flash Components Register to get the Component 1 Density + CtrlData = MmioRead32((SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_RCRB_SPI_FDOC)); + CtrlData &= (UINT32)(~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)); + CtrlData |= (UINT32)(V_PCH_SPI_FDOC_FDSS_COMP | R_PCH_SPI_FCBA_FLCOMP); + MmioWrite32((SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_RCRB_SPI_FDOC), CtrlData); + + /// Copy Component 1 Density + switch ( (UINT8) MmioRead32 (SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_RCRB_SPI_FDOD) & B_PCH_SPI_FLCOMP_COMP1_MASK ) { + case V_PCH_SPI_FLCOMP_COMP1_512KB: + TotalRomSize += (UINT32) (512 << KBShift); + break; + case V_PCH_SPI_FLCOMP_COMP1_1MB: + TotalRomSize += (UINT32) (1 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP1_2MB: + TotalRomSize += (UINT32) (2 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP1_4MB: + TotalRomSize += (UINT32) (4 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP1_8MB: + TotalRomSize += (UINT32) (8 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP1_16MB: + TotalRomSize += (UINT32) (16 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP1_32MB: + TotalRomSize += (UINT32) (32 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP1_64MB: + TotalRomSize += (UINT32) (64 << MBShift); + break; + default: + break; + } // end of switch + + // Copy Component 2 Density + if(NumSpi == 2){ + switch ( (UINT8) MmioRead32 (SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_RCRB_SPI_FDOD) & B_PCH_SPI_FLCOMP_COMP2_MASK ) { + case V_PCH_SPI_FLCOMP_COMP2_512KB: + TotalRomSize += (UINT32) (512 << KBShift); + break; + case V_PCH_SPI_FLCOMP_COMP2_1MB: + TotalRomSize += (UINT32) (1 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP2_2MB: + TotalRomSize += (UINT32) (2 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP2_4MB: + TotalRomSize += (UINT32) (4 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP2_8MB: + TotalRomSize += (UINT32) (8 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP2_16MB: + TotalRomSize += (UINT32) (16 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP2_32MB: + TotalRomSize += (UINT32) (32 << MBShift); + break; + case V_PCH_SPI_FLCOMP_COMP2_64MB: + TotalRomSize += (UINT32) (64 << MBShift); + break; + default: + break; + } // end of switch + }// end of if + //if (TotalRomSize == 0) ASSERT_EFI_ERROR(EFI_DEVICE_ERROR); + + return TotalRomSize; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SbGetSpiRegionAddresses +// +// Description: Read SPI Descriptor to get flash rom base address and length +// of one region +// +// Input: AMI_SB_SPI_RANGE_TYPE - Region Type +// +// Output: UINT32 - BaseAddress +// UINT32 - EndAddress +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SbGetSpiRangeAddresses( + IN AMI_SB_SPI_RANGE_TYPE RangeType, + OUT UINT32 *BaseAddress, + OUT UINT32 *EndAddress ) +{ + UINT32 ReadValue = 0; + + if (!((RangeType > AnyType) && (RangeType < PchSpiRangeTypeMax))) { + return EFI_INVALID_PARAMETER; + } + + if (RangeType <= SecondaryBiosType) { + ReadValue = MmioRead32 (SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_SB_RCRB_SPI_FREG0_FLASHD + (S_SB_SPI_FREGX * ((UINTN) (RangeType - 1)))); + *BaseAddress = (ReadValue & B_SB_SPI_FREGX_BASE_MASK) << 12; + *EndAddress = ((ReadValue & B_SB_SPI_FREGX_LIMIT_MASK) >> 4) | 0x00000FFF; + } else if (RangeType == BfpregType) { + ReadValue = MmioRead32 (SB_RCRB_BASE_ADDRESS + SPI_BASE_ADDRESS + R_SB_RCRB_SPI_BFPR); + *BaseAddress = (ReadValue & B_SB_SPI_BFPR_PRB) << 12; + *EndAddress = ((ReadValue & B_SB_SPI_BFPR_PRL) >> 4) | 0x00000FFF; + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbFlashProtectedRegion +// +// Description: This routine provides H/W read/write-protection of the BIOS +// region. If chipset supports "SPI Flash Protected Range +// registers", then program them to protect BIOS region in SPI +// Flash. +// +// Input: None +// +// Output: EFI_STATUS +// EFI_SUCCESS - Set successfully. +// EFI_OUT_OF_RESOURCES - There is no available register +// for this call. +// EFI_INVALID_PARAMETER - The parameter of input is +// invalid +// EFI_UNSUPPORTED - Chipset or H/W is not supported. +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SbFlashProtectedRange( VOID ) +{ + // + // Porting required if chipset is able to support H/W protection of + // BIOS region. + // + EFI_STATUS Status = EFI_SUCCESS; + UINT32 RegIndex; + UINT32 TotalFlashRomSize; + UINT32 FlashRangeBaseAddr = 0; + UINT32 FlashRangeEndAddr = 0; + volatile UINT32 Value32, AddrCheck; + SPI_PROTECTED_RANGE_CONIFG SpiProtectedRange[] = {SPI_PROTECTED_RANGE_0, + SPI_PROTECTED_RANGE_1, + SPI_PROTECTED_RANGE_2, + SPI_PROTECTED_RANGE_3, + SPI_PROTECTED_RANGE_4}; + + // Get Total ROM size first + TotalFlashRomSize = GetTotalFlashRomSize(); + + for (RegIndex = 0; RegIndex < 5; RegIndex++) { + // Check Read or Write protected is enable or not + if (!(SpiProtectedRange[RegIndex].ReadProtectEnable || \ + SpiProtectedRange[RegIndex].WriteProtectEnable)) + continue; + + // Check Protected Range Length should not be 0 + if(SpiProtectedRange[RegIndex].ProtectedRangeLength == 0) + continue; + + switch (SpiProtectedRange[RegIndex].ProtectedRangeType){ + case BiosType: + case MeType: + case GbeType: + Status = SbGetSpiRangeAddresses(SpiProtectedRange[RegIndex].ProtectedRangeType, &FlashRangeBaseAddr, &FlashRangeEndAddr); + if(!EFI_ERROR(Status)){ + AddrCheck = (UINT32)(SpiProtectedRange[RegIndex].ProtectedRangeBase) + FlashRangeBaseAddr; + if (AddrCheck > FlashRangeEndAddr) + return EFI_INVALID_PARAMETER; + AddrCheck += (UINT32)(SpiProtectedRange[RegIndex].ProtectedRangeLength - 1); + if (AddrCheck > FlashRangeEndAddr) + return EFI_INVALID_PARAMETER; + + Value32 = *(UINT32 *)(SB_RCBA + SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (RegIndex * 4))); + Value32 = (((UINT32)(SpiProtectedRange[RegIndex].ProtectedRangeBase) + FlashRangeBaseAddr) & 0x1FFF000) >> 12; + Value32 |= ((((UINT32)(SpiProtectedRange[RegIndex].ProtectedRangeBase + SpiProtectedRange[RegIndex].ProtectedRangeLength - 1) + FlashRangeBaseAddr) & 0x1FFF000) << 4); + } else return Status; + + break; + case AnyType: + // Exceed the address of protected range base. + if (SpiProtectedRange[RegIndex].ProtectedRangeBase >= (UINTN)TotalFlashRomSize) + return EFI_INVALID_PARAMETER; + + Value32 = *(UINT32 *)(SB_RCBA + SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (RegIndex * 4))); + Value32 = (UINT32)(SpiProtectedRange[RegIndex].ProtectedRangeBase & 0x1FFF000) >> 12; + Value32 |= (((UINT32)(SpiProtectedRange[RegIndex].ProtectedRangeBase + SpiProtectedRange[RegIndex].ProtectedRangeLength - 1) & 0x1FFF000) << 4); + break; + } // end of switch + + if (SpiProtectedRange[RegIndex].ReadProtectEnable) Value32 |= B_SB_SPI_PRx_RPE; + if (SpiProtectedRange[RegIndex].WriteProtectEnable) Value32 |= B_SB_SPI_PRx_WPE; + *(UINT32 *)(SB_RCBA + SPI_BASE_ADDRESS + (R_SB_RCRB_SPI_PR0 + (RegIndex * 4))) = Value32; + } // for loop + + return Status; +} + +//--------------------------------------------------------------------------- +// Standard I/O Access Routines, No Porting Required. +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RtcRead +// +// Description: Read specific RTC/CMOS RAM +// +// Input: Location Point to RTC/CMOS RAM offset for read +// +// Output: nONE +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 RtcRead ( IN UINT8 Location ) +{ + return ReadCmos(Location); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RtcWrite +// +// Description: Write specific RTC/CMOS RAM +// +// Parameters: Location Point to RTC/CMOS RAM offset for write +// Value The data that will be written to RTC/CMOS RAM +// +// Returns: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +RtcWrite ( + IN UINT8 Location, + IN UINT8 Value + ) +{ + WriteCmos(Location, Value); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReadIo8IdxData +// +// Description: This function reads an 8bit value from a specific I/O +// Index/Data port. +// +// Input: IoBase16 - A 16 Bit I/O Address for Index I/O Port +// RegIdx8 - An 8 Bit Register offset +// +// Output: An 8Bit data read from the specific Index/Data I/O port. +// +// Notes: The default Data I/O Port is the Index I/O Port plus 1, if +// your Data I/O Port is not that, please modify below +// "++IoBase16". +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 ReadIo8IdxData ( + IN UINT16 IoBase16, + IN UINT8 RegIdx8 ) +{ + IoWrite8( IoBase16, RegIdx8 ); + return IoRead8( ++IoBase16 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteIo8IdxData +// +// Description: This function writes an 8bit value to a specific I/O +// Index/Data port. +// +// Input: IoBase16 - A 16 Bit I/O Address for Index I/O Port +// RegIdx8 - An 8 Bit Register Index +// Value8 - An 8 Bit Value to write. +// +// Output: None +// +// Notes: The default Data I/O Port is the Index I/O Port plus 1, if +// your Data I/O Port is not that, please modify below +// "++IoBase16". +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteIo8IdxData ( + IN UINT16 IoBase16, + IN UINT8 RegIdx8, + IN UINT8 Value8 ) +{ + IoWrite8( IoBase16, RegIdx8 ); + IoWrite8( ++IoBase16, Value8 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RwIo8IdxData +// +// Description: This function reads an 8bit value from a specific I/O +// Index/Data port, then applies Set/Reset masks and writes +// it back. +// +// Input: IoBase16 - A 16 Bit I/O Address for Index I/O Port +// RegIdx8 - An 8 Bit Register Index +// SetBit8 - Mask of 8bits to set (1 = Set) +// ResetBit8 - Mask of 8bits to reset (1 = Reset) +// +// Output: None +// +// Notes: The default Data I/O Port is the Index I/O Port plus 1, if +// your Data I/O Port is not that, please modify IoRead8IdxData +// and IoWrite8IdxData's "++IoBase16". +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID RwIo8IdxData ( + IN UINT16 IoBase16, + IN UINT8 RegIdx8, + IN UINT8 SetBit8, + IN UINT8 ResetBit8 ) +{ + UINT8 Buffer8 ; + + Buffer8 = ReadIo8IdxData( IoBase16, RegIdx8 ) & ~ResetBit8 | SetBit8; + WriteIo8IdxData( IoBase16, RegIdx8, Buffer8 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteIo8S3 +// +// Description: This function writes an 8bit value to a specific I/O port +// and writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBaseReg16 - A 16 Bit I/O Port Address +// Value8 - An 8 Bit Value to write. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteIo8S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT8 Value8 ) +{ + IoWrite8( IoBaseReg16, Value8 ); + + BOOT_SCRIPT_S3_IO_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint8, \ + IoBaseReg16, \ + 1, \ + &Value8 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteIo16S3 +// +// Description: This function writes a 16bit value to a specific I/O port +// and writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBaseReg16 - A 16 Bit I/O Port Address +// Value16 - A 16 Bit Value to write. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteIo16S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT16 Value16 ) +{ + IoWrite16( IoBaseReg16, Value16 ); + + BOOT_SCRIPT_S3_IO_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint16,\ + IoBaseReg16, \ + 1, \ + &Value16 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteIo32S3 +// +// Description: This function writes a 32bit value to a specific I/O port +// and writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBaseReg16 - A 16 Bit I/O Port Address +// Value32 - a 32 Bit Value to write. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteIo32S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT32 Value32 ) +{ + IoWrite32( IoBaseReg16, Value32 ); + + BOOT_SCRIPT_S3_IO_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint32,\ + IoBaseReg16, \ + 1, \ + &Value32 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RwIo8S3 +// +// Description: This function reads an 8bit value from a specific I/O port, +// then applies Set/Reset masks, and writes it back, then +// writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBaseReg16 - A 16 Bit I/O Port Address +// SetBit8 - Mask of 8bits to set (1 = Set) +// ResetBit8 - Mask of 8bits to reset (1 = Reset) +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID RwIo8S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT8 SetBit8, + IN UINT8 ResetBit8 ) +{ + + RW_IO8( IoBaseReg16, SetBit8, ResetBit8 ); + + ResetBit8 = ~ResetBit8; + + BOOT_SCRIPT_S3_IO_READ_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint8, \ + IoBaseReg16, \ + &SetBit8, \ + &ResetBit8 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RwIo16S3 +// +// Description: This function reads a 16bit value from a specific I/O port, +// then applies Set/Reset masks, and writes it back, then +// writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBaseReg16 - A 16 Bit I/O Port Address +// SetBit16 - Mask of 16bits to set (1 = Set) +// ResetBit16 - Mask of 16bits to reset (1 = Reset) +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID RwIo16S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT16 SetBit16, + IN UINT16 ResetBit16 ) +{ + RW_IO16( IoBaseReg16, SetBit16, ResetBit16 ); + + ResetBit16 = ~ResetBit16; + + BOOT_SCRIPT_S3_IO_READ_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint16, \ + IoBaseReg16, \ + &SetBit16, \ + &ResetBit16 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RwIo32S3 +// +// Description: This function reads a 32bit value from a specific I/O port, +// then applies Set/Reset masks, and writes it back, then +// writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBaseReg16 - A 16 Bit I/O Port Address +// SetBit32 - Mask of 32bits to set (1 = Set) +// ResetBit32 - Mask of 32bits to reset (1 = Reset) +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID RwIo32S3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBaseReg16, + IN UINT32 SetBit32, + IN UINT32 ResetBit32 ) +{ + RW_IO32( IoBaseReg16, SetBit32, ResetBit32 ); + + ResetBit32 = ~ResetBit32; + + BOOT_SCRIPT_S3_IO_READ_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint32, \ + IoBaseReg16, \ + &SetBit32, \ + &ResetBit32 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteIo8IdxDataS3 +// +// Description: This function writes an 8bit value to a specific I/O +// Index/Data ports and writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBase16 - A 16 Bit I/O Address for Index I/O Port +// RegIdx8 - An 8 Bit Register Index +// Value8 - An 8 Bit Value to write. +// +// Output: None +// +// Notes: The default Data I/O Port is the Index I/O Port plus 1, if +// your Data I/O Port is not that, please modify below +// "IoBase16+1". +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteIo8IdxDataS3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBase16, + IN UINT8 IoReg8, + IN UINT8 Value8 ) +{ + WriteIo8S3(mBootScriptSave, IoBase16, IoReg8); + WriteIo8S3(mBootScriptSave, IoBase16 + 1, Value8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RwIo8IdxDataS3 +// +// Description: This function reads an 8bit value from a specific I/O +// Index/Data ports, then applies Set/Reset masks, and writes +// it back. Also writes a copy to Boot Script Table. +// +// Input: *mBootScriptSave - Pointer to Boot Script Save Protocal +// IoBase16 - A 16 Bit I/O Address for Index I/O Port +// RegIdx8 - An 8 Bit Register Index +// SetBit8 - Mask of 8bits to set (1 = Set) +// ResetBit8 - Mask of 8bits to reset (1 = Reset) +// +// Output: An 8Bit data read from the specific Index/Data I/O port +// after appling Set/Reset masks. +// +// Notes: The default Data I/O Port is the Index I/O Port plus 1, if +// your Data I/O Port is not that, please modify below +// "IoBase16+1" and IoWrite8IdxData's "++IoBase16". +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID RwIo8IdxDataS3 ( + IN AMI_S3_SAVE_PROTOCOL *mBootScriptSave, + IN UINT16 IoBase16, + IN UINT8 IoReg8, + IN UINT8 SetBit8, + IN UINT8 ResetBit8 ) +{ + RwIo8IdxData(IoBase16, IoReg8, SetBit8, ResetBit8); + + BOOT_SCRIPT_S3_IO_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint8,\ + IoBase16, \ + 1, \ + &IoReg8 ); + ResetBit8 = ~ResetBit8; + BOOT_SCRIPT_S3_IO_READ_WRITE_MACRO( mBootScriptSave, \ + EfiBootScriptWidthUint8, \ + IoBase16 + 1, \ + &SetBit8, \ + &ResetBit8 ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_CmosRead +// +// Description: Read the RTC value at the given Index. +// +// Input: Index - RTC Index +// +// Output: RTC Value read from the provided Index +// +// Notes: Here is the control flow of this function: +// 1. Read port 0x70 (RTC Index Register) to get bit 7. +// Bit 7 is the NMI bit-it should not be changed. +// 2. Set Index with the NMI bit setting. +// 3. Output 0x70 with the Index and NMI bit setting. +// 4. Read 0x71 for Data. Getting Dec when appropriate. +// 5. Return the Data. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 SBLib_CmosRead ( + IN UINT8 Index ) +{ + return ReadCmos(Index); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBLib_CmosWrite +// +// Description: Write the RTC value at the given Index. +// +// Input: Index - RTC Index +// Value - Value to write +// +// Output: None +// +// Notes: Here is the control flow of this function: +// 1. Read port 0x70 (RTC Index Register) to get bit 7. +// Bit 7 is the NMI bit-it should not be changed. +// 2. Set Index with the NMI bit setting. +// 3. Output 0x70 with the Index. Switch to BCD when needed. +// 4. Write the data to 0x71. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SBLib_CmosWrite ( + IN UINT8 Index, + IN UINT8 Value ) +{ + WriteCmos(Index, Value); +} + +PCH_SERIES +EFIAPI +GetPchSeries ( + VOID + ) +/** + + Return Pch Series + + @param[in] None + + @retval PCH_SERIES Pch Series + +**/ +{ + UINT16 LpcDeviceId; + UINT32 PchSeries; + + LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID); + + if (IS_PCH_LPTH_LPC_DEVICE_ID (LpcDeviceId)) { + PchSeries = PchH; + } else if (IS_PCH_LPTLP_LPC_DEVICE_ID (LpcDeviceId)) { + PchSeries = PchLp; + } else { + PchSeries = PchUnknownSeries; + } + + return PchSeries; +} + +UINT8 +EFIAPI +GetPchMaxPciePortNum ( + VOID + ) +/** + + Get Pch Maximum Pcie Root Port Number + + @param[in] None + + @retval Pch Maximum Pcie Root Port Number + +**/ +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_PCIE_MAX_ROOT_PORTS; + + case PchH: + return LPTH_PCIE_MAX_ROOT_PORTS; + + default: + return 0; + } +} + +UINT8 +EFIAPI +GetPchMaxSataPortNum ( + VOID + ) +/** + + Get Pch Maximum Sata Port Number + + @param[in] None + + @retval Pch Maximum Sata Port Number + +**/ +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_AHCI_MAX_PORTS; + + case PchH: + return LPTH_AHCI_MAX_PORTS; + + default: + return 0; + } +} + +UINT8 +EFIAPI +GetPchUsbMaxPhysicalPortNum ( + VOID + ) +/** + + Get Pch Usb Maximum Physical Port Number + + @param[in] None + + @retval Pch Usb Maximum Physical Port Number + +**/ +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_USB_MAX_PHYSICAL_PORTS; + + case PchH: + return LPTH_USB_MAX_PHYSICAL_PORTS; + + default: + return 0; + } +} + +UINT8 +EFIAPI +GetPchXhciMaxUsb3PortNum ( + VOID + ) +/** + + Get Pch Maximum Usb3 Port Number of XHCI Controller + + @param[in] None + + @retval Pch Maximum Usb3 Port Number of XHCI Controller + +**/ +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_XHCI_MAX_USB3_PORTS; + + case PchH: + return LPTH_XHCI_MAX_USB3_PORTS; + + default: + return 0; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetPchEhciMaxControllerNum +// +// Description: Get Pch Maximum EHCI Controller Number +// +// Input: None +// +// Output: Pch Maximum EHCI Controller Number +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 +EFIAPI +GetPchEhciMaxControllerNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_EHCI_MAX_CONTROLLERS; + + case PchH: + return LPTH_EHCI_MAX_CONTROLLERS; + + default: + return 0; + } +} + +UINT32 DummyVerbTable[] = { + // + // Dummy Verb Table + // + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF +}; + +#if defined(HPET_APIC_INTERRUPT_MODE) && (HPET_APIC_INTERRUPT_MODE != 0) +//---------------------------------------------------------------------------- +// Generic IO APIC routine. +//---------------------------------------------------------------------------- +UINT8 gBspLocalApicID = 0; +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicBase +// +// Description: This routine returns a structure pointer to the I/O APIC. +// +// Input: None +// +// Output: IO_APIC structure. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +struct IO_APIC* IoApicBase( VOID ) +{ + static UINT32 IoApicAddr = 0; + if (IoApicAddr == 0 || IoApicAddr == -1) { + // This value may need to read from chipset registers. + IoApicAddr = APCB; + } + + return (struct IO_APIC*)IoApicAddr; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicWrite +// +// Description: This function writes a 32bits data to the register of +// I/O APIC. +// +// Input: UINT8 Reg - The register offset to be written. +// UINT32 Value - A 32bits data will be written to the register +// of I/O APIC. +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS IoApicWrite ( + IN UINT8 Reg, + IN UINT32 Value ) +{ + struct IO_APIC *IoApicStruct = IoApicBase(); + + MMIO_WRITE8((UINT64)&IoApicStruct->Index, Reg); + MMIO_WRITE32((UINT64)&IoApicStruct->Data, Value); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicRead +// +// Description: This function reads a 32bits data from the register of +// I/O APIC. +// +// Input: UINT8 Reg - the register offset to be read. +// +// Output: UINT32 - A 32bits data read from the register of I/O APIC. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT32 IoApicRead ( + IN UINT8 Reg ) +{ + struct IO_APIC *IoApicStruct = IoApicBase(); + + MMIO_WRITE8((UINT64)&IoApicStruct->Index, Reg); + return MMIO_READ32((UINT64)&IoApicStruct->Data); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicEnableIrq +// +// Description: This function enables the specific interrupt pin of I/O APIC. +// +// Input: UINT8 Irq - The pin number of I/O APIC +// BOOLEAN LevelTriggered - Trigger mechanism (level or edge) +// for this INT pin. +// BOOLEAN Polarity - Specifies the polarity of the INT pin. +// (Active High or Active Low) +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS IoApicEnableIrq ( + IN UINT8 Irq, + IN BOOLEAN LevelTriggered, + IN BOOLEAN Polarity ) +{ + IO_APIC_ROUTE_ENTRY ApicEntry; + union ENTRY_UNION Eu = {{0, 0}}; + + ApicEntry.DestMode = 0; // 0: physical + ApicEntry.Mask = 0; // 0 : enable + ApicEntry.Dest = gBspLocalApicID; // suppose the BSP handle interrupt. + ApicEntry.DeliveryMode = 0; // 000: FIXED + ApicEntry.Polarity = (Polarity) ? 1 : 0; + ApicEntry.Trigger = (LevelTriggered) ? 1 : 0; + ApicEntry.Vector = MASTER_INTERRUPT_BASE + Irq; + + Eu.Entry = ApicEntry; + IoApicWrite(IO_APIC_REDIR_TABLE_HIGH + 2 * Irq, Eu.W2); + IoApicWrite(IO_APIC_REDIR_TABLE_LOW + 2 * Irq, Eu.W1); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicDisableIrq +// +// Description: This function disables the specific interrupt pin of I/O APIC. +// +// Input: UINT8 Irq - The pin number of I/O APIC +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS IoApicDisableIrq ( + IN UINT8 Irq ) +{ + union ENTRY_UNION Eu = {{0, 0}}; + + Eu.W1 = IoApicRead(IO_APIC_REDIR_TABLE_LOW + 2 * Irq); + Eu.W2 = IoApicRead(IO_APIC_REDIR_TABLE_HIGH + 2 * Irq); + Eu.Entry.Mask = 1; + IoApicWrite(IO_APIC_REDIR_TABLE_LOW + 2 * Irq, Eu.W1); + IoApicWrite(IO_APIC_REDIR_TABLE_HIGH + 2 * Irq, Eu.W2); + IoApicEoi(Irq); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicMaskIrq +// +// Description: This routine masks the specific interrupt pin of I/O APIC. +// +// Input: UINT8 Irq - The pin number of I/O APIC +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS IoApicMaskIrq ( + IN UINT8 Irq ) +{ + union ENTRY_UNION Eu = {{0, 0}}; + + Eu.W1 = IoApicRead(IO_APIC_REDIR_TABLE_LOW + 2 * Irq); + Eu.Entry.Mask = 1; + IoApicWrite(IO_APIC_REDIR_TABLE_LOW + 2 * Irq, Eu.W1); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicUnmaskIrq +// +// Description: This routine unmasks the specific interrupt pin of I/O APIC. +// +// Input: UINT8 Irq - The pin number of I/O APIC +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS IoApicUnmaskIrq ( + IN UINT8 Irq ) +{ + union ENTRY_UNION Eu = {{0, 0}}; + + Eu.W1 = IoApicRead(IO_APIC_REDIR_TABLE_LOW + 2 * Irq); + Eu.Entry.Mask = 0; + IoApicWrite(IO_APIC_REDIR_TABLE_LOW + 2 * Irq, Eu.W1); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoApicEoi +// +// Description: This routine issues an EOI to the specific pin of I/O APIC. +// +// Input: UINT8 Irq - The pin number of I/O APIC +// +// Output: EFI_SUCCESS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS IoApicEoi ( + IN UINT8 Irq ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Vector = MASTER_INTERRUPT_BASE + Irq; + struct IO_APIC *IoApicStruct = IoApicBase(); + UINT32 Isr = 0; + union ENTRY_UNION Eu = {{0, 0}}; + + do { + MMIO_WRITE32((UINT64)&IoApicStruct->Eoi, Vector); + Eu.W1 = IoApicRead(IO_APIC_REDIR_TABLE_LOW + 2 * Irq); + } while (Eu.Entry.Irr); + + do { + MMIO_WRITE32(LOCAL_APIC_BASE + APIC_EOI_REGISTER, Vector); + Isr = MMIO_READ32(LOCAL_APIC_BASE + ISR_REG (Vector)); + } while (Isr & ISR_BIT(Vector)); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetHpetApicPin +// +// Description: This routine gets the pin number of I/O APIC for HPET. +// +// Input: None +// +// Output: UINT8 Irq - The pin number of I/O APIC for HPET. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 GetHpetApicPin (VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT8 Irq = 0; + + volatile HPET_TIMER_CONFIGURATION_REGISTER TimerConfiguration; + + TimerConfiguration.Uint64 = MMIO_READ64( HPET_BASE_ADDRESS + HPET_TIMER_CONFIGURATION_OFFSET + HPET_OFFSET * HPET_TIMER_STRIDE ); + Irq = TimerConfiguration.Bits.InterruptRoute; + + return Irq; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsHpetApicEnable +// +// Description: This routine checks the pin of I/O APIC for HPET is enabled or +// not. +// +// Input: None +// +// Output: TRUE - The pin of I/O APIC for HPET is enabled +// FALSE - The pin of I/O APIC for HPET is disabled +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsHpetApicEnable (VOID) +{ + union ENTRY_UNION Eu = {{0, 0}}; + UINT8 Irq; + + Irq = GetHpetApicPin(); + + Eu.W1 = IoApicRead(IO_APIC_REDIR_TABLE_LOW + 2 * Irq); + + return (Eu.Entry.Mask) ? FALSE : TRUE; +} +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBPEI.c b/Chipset/SB/SBPEI.c new file mode 100644 index 0000000..918f226 --- /dev/null +++ b/Chipset/SB/SBPEI.c @@ -0,0 +1,3430 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBPEI.c 57 5/27/15 2:26a Dennisliu $ +// +// $Revision: 57 $ +// +// $Date: 5/27/15 2:26a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBPEI.c $ +// +// 57 5/27/15 2:26a Dennisliu +// [TAG] EIP219399 +// [Category] Improvement +// [Description] Static code analysis issue found in Aptio4 Intel +// LynxPoint PCH module +// [Files] Chipset\SB\SBPEI.c +// +// 56 11/17/14 7:24a Mirayang +// [TAG] EIP190402 +// [Category] New Feature +// [Description] Support BootScriptHide eModule on Sharkbay CRB project +// +// 55 9/23/14 6:12a Mirayang +// [TAG] EIP183246 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] BIOS capsule update usb issue +// [RootCause] Boot mode conditions miss "BOOT_ON_FLASH_UPDATE" in +// InitUsbMisc(). +// [Solution] Add "BOOT_ON_FLASH_UPDATE" this boot mode conditions . +// +// 54 7/21/14 10:42p Mirayang +// [TAG] EIP176923 +// [Category] Improvement +// [Description] Program BUC.SDO to 1 on normal boot in PCH component. +// +// 53 4/01/14 10:18p Barretlin +// [TAG] EIP156783 +// [Category] Improvement +// [Description] fix build error when removing usb recovery module +// [Files] SbPei.c +// +// 52 1/14/14 1:37a Barretlin +// [TAG] EIP150529 +// [Category] Improvement +// [Description] System hang due to dysfunctional MRC delay routine +// [Files] SBPei.c +// +// 51 1/08/14 11:18p Barretlin +// [TAG] EIP149596 +// [Category] Improvement +// [Description] system cannot enter to recovery mode when CMOS is bad +// [Files] SBPEI.c +// +// 50 10/29/13 12:38a Barretlin +// [TAG] EIP136997 +// [Category] Improvement +// [Description] fix build error when SUPPORT_RAID_DRIVER token is 0 +// [Files] SBPei.c +// +// 49 10/06/13 2:31a Barretlin +// [TAG] EIP138340 +// [Category] Improvement +// [Description] SATA drive detection issue in PCH Platform BIOS +// reference code revision 1.6.2 +// [Files] SB.sdl SBPEI.c +// +// 48 9/17/13 2:48p Barretlin +// [TAG] EIP N/A +// [Category] Improvement +// [Description] use token to decide SATA RxEq policy vaule +// [Files] SB.sdl SBPei.c +// +// 47 9/17/13 8:43a Barretlin +// [TAG] EIP136354 +// [Category] Improvement +// [Description] remove setting RCBA Coprocessor Error Enable bit +// [Files] SB.sdl SbPei.c +// +// 46 8/23/13 4:34a Barretlin +// [TAG] EIP133819 +// [Category] Improvement +// [Description] change platform policy revision to 4 +// [Files] SBPEI.c +// +// 45 8/23/13 3:42a Barretlin +// [TAG] EIP133819 +// [Category] Improvement +// [Description] update for Intel PCH RC 1.6.2.0 +// [Files] SB.sdl SBPEI.c +// +// 44 7/17/13 8:01a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Let's GPIO GPINDIS bit setting by custom define except +// GPO. +// [Files] SBPEI.c +// +// 43 5/23/13 1:56a Scottyang +// [TAG] EIP120623 +// [Category] Improvement +// [Description] LCD turn on automatically when resume from S3. +// [Files] SBPEI.c, SBDxe.c, AcpiModeEnable.c +// +// 42 5/13/13 9:14a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Set time to default when clear cmos by jumper or +// remove battery. +// [Files] SBPEI.c +// +// 40 5/08/13 4:37a Scottyang +// [TAG] EIP123117 +// [Category] Improvement +// [Description] Fixed enable USB precondition, and do power off, power +// on, it will hang 9C. +// [Files] SBPEI.c +// +// 39 5/08/13 3:09a Scottyang +// [TAG] None +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Enable bit set at wrong place. +// [RootCause] The offset error. +// [Solution] Make offset correct. +// [Files] SBPEI.c +// +// 37 5/03/13 1:42a Scottyang +// [TAG] EIP115528 +// [Category] Improvement +// [Description] Support XHCI port recovery when reset after boot to OS +// with XHCI driver. +// [Files] SBPEI.c +// +// 36 4/24/13 6:42a Scottyang +// [TAG] EIP114861 +// [Category] Improvement +// [Description] For PTT(Fast boot) 15 can reduce post for CD-ROM. +// [Files] SBPEI.c +// +// 35 4/24/13 4:20a Scottyang +// [TAG] EIP118667 +// [Category] Improvement +// [Description] For ULT when GPIO is GPO will also set GPI_DIS_DISABLE. +// [Files] SBPEI.c +// +// 34 4/24/13 2:15a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Porting GPI interrupt by LPT-LP EDS 1.5. +// [Files] SB.sdl, SB.H, SBPPI.h, SBPEI.c +// +// 33 4/23/13 4:51a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Add token "ONLY_CLEAR_RTC_EN_IN_PEI" for improve +// "EIP120623". +// [Files] AcpiModeEnable.c; SB.SDL; SBPEI.c +// +// 31 4/18/13 12:18a Wesleychen +// [TAG] EIP120623 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] LCD doesn't turn on automatically when resume from S3. +// [RootCause] PM1_STS (PMBASE+00h) are cleared in EnableAcpiMode(). +// [Solution] Avoid PM1_STS clearing behavior is occurring in S3 +// resuming. +// *AcpiModeEnable.c Rev#8~11(EIP101628 & EIP118531) are are +// no need be existence. +// [Files] SBPEI.c; AcpiModeEnable.c +// +// 29 3/15/13 3:33a Scottyang +// [TAG] EIP118121 +// [Category] Improvement +// [Description] Update PCH RC 1.3.0. +// [Files] ..\ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SB.uni, GetSetupData.c, SbSetupData.h +// +// 28 3/12/13 7:40a Scottyang +// [TAG] EIP115528 +// [Category] Improvement +// [Description] USB ports are connected to EHCI not XHCI When recovery. +// [Files] SBPEI.c +// +// 27 2/26/13 1:02a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Follow intel BIOS V112 to change IRQ rout. +// [Files] SB.sdl, SBPEI.c +// +// 26 2/09/13 12:12a Scottyang +// [TAG] EIP114922 +// [Category] Improvement +// [Description] Update PCH RC 1.1.0. +// [Files] ..\ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SB.uni, GetSetupData.c, SbSetupDara.h +// +// 25 1/31/13 10:51a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add delay for HDD recovery. +// [Files] SBPEI.c +// +// 24 1/30/13 1:15a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Fix build error at 4653. +// [Files] SBPEI.c +// +// 23 1/27/13 11:01p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Capsule 2.0 crash dump link function. +// [Files] SBPEI.c +// SBDxe.c +// SBRun.c +// +// 22 1/11/13 1:51a Scottyang +// [TAG] EIP88358 +// [Category] Improvement +// [Description] Add FORCE_USER_TO_SETUP_IF_CMOS_BAD token +// [Files] SBDex.c, SBPei.c, RTC.h, SB.sdl +// +// 21 12/24/12 5:51a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add option for XHCI Idel L1 workaroung. +// [Files] GetSetupData.c, SbSetupData.h, SB.sd, SB.uni, SBDxe.c, +// SBPEI.c +// +// 20 12/18/12 6:10a Scottyang +// [TAG] EIP109697 +// [Category] Improvement +// [Description] Update PCH RC 0.8.1 +// [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd, +// SbSetupData.c, GetSetupDate.c +// +// 19 12/13/12 10:31a Scottyang +// [TAG] EIP106687 +// [Category] Improvement +// [Description] Add option for delay to detect PCIE card. +// [Files] SBPEI.c, SB.sd, SB.uni, GetSetupData.c, SbSetupData.h, +// PciBus.c +// +// 18 12/13/12 10:17a Scottyang +// [TAG] EIP107424 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System stops at CKP 0x9C when system performs a cool boot +// and AMI debugger is enabled. +// [RootCause] Unexpected USB EHCI Legacy Support Extended status is +// rised, it is out of USB module control. +// [Solution] Clear unexpected USB EHCI Legacy Support Extended +// status. +// [Files] SBPEI.c +// +// 17 11/20/12 9:47a Scottyang +// [TAG] EIP107014 +// [Category] Improvement +// [Description] Update RC 0.8.0 +// [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, +// SB.sd, SbSetupData.c, GetSetupDate.c +// +// 16 11/06/12 8:12a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Reduce function "GetPchSeries()". +// [Files] SBPEI.c, SBDxe.c, SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 15 10/25/12 8:16a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Add new device and remove device which no use +// [Files] SBPEI.c, SB.sdl +// +// 14 10/16/12 4:16a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Assign IRQ for device 21 +// +// 13 10/14/12 8:33a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] One rom for two chip and one chip. +// [Files] SPPEIBoard.c, SB.sd, SBDxe.c, SBPEI.c, PCH.asl +// +// 12 10/12/12 4:55a Scottyang +// [TAG] EIP87695 +// [Category] Improvement +// [Description] System should reboot successfully next time if S3 +// resume fail +// [Files] SB.sdl, SBPei.c +// +// 11 10/11/12 11:15p Scottyang +// [TAG] EIP86096 +// [Category] Improvement +// [Description] Fix SATA AHCI port4 & 5 can't loading recovery image. +// [Files] SBPei.c +// +// 10 9/26/12 3:55a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for Intel PCH LPT RC070. +// [Files] SB.sdl, SBDXE.c, SBPEI.c, Pch.sdl, SB.sd, SB.uni +// +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 9 9/12/12 5:20a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Force HPET enabled for MRC initialization. +// [Files] SB.sd, SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Modify for ULT GPIO changed by PCH LPT-LP EDS 1.0. +// [Files] SB.H, SB.sdl, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBPEI.c +// +// 8 8/24/12 6:51a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Sync USB policy for UsbPrecondition function. +// [Files] SBPEI.c +// +// 7 8/14/12 11:26p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update "SB_TEMP_MMIO_BASE" and +// "EHCI_MMIO_BASE_ADDRESS". +// [Files] SB.sdl, SBDxe.c, SBPEI.c +// +// 6 8/13/12 10:29a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update correct MMIO BASE for TempMemBaseAddr policy. +// [Files] SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update PCH Policy. +// [Files] SB.sdl, SBDxe.c, SBPEI.c +// +// [TAG] None +// [Category] Improvement +// [Description] Implement USB Precondition option for policy +// "UsbPrecondition". +// [Files] GetSetupData.c, SB.sd, SB.uni, SbSetupData.h, SBDxe.c, +// SBPEI.c +// +// 5 7/27/12 6:14a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update setup items and policies. +// [Files] GetSetupData.c, SB.sdl, SB.sd, SB.uni, SbSetupData.h, +// SBPEI.c, SBDXE.c +// +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 4 7/02/12 10:17a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Updated and modified for PCH RC 0.6.0. +// [Files] SBGeneric.c, SB.sdl, SBCspLib.h, SBDxe.c, SBPEI.c +// +// 3 6/13/12 11:34p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement Warm Boot function for Secure Flash feature. +// [Files] SB.H, SB.mak, SB.sdl, SBDxe.c, SBGeneric.c, SBPEI.c, +// SBSMI.c +// +// 2 2/24/12 2:35a Victortu +// Support RapidStart_SUPPORT. +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBPEI.C +// +// Description: This file contains code for South Bridge initialization +// in the PEI stage +// +//<AMI_FHDR_END> +//************************************************************************* + +//---------------------------------------------------------------------------- +// Include(s) +//---------------------------------------------------------------------------- + +#include <Efi.h> +#include <Pei.h> +#include <Token.h> +#include <AmiPeiLib.h> +#include <Hob.h> +#include <Setup.h> +#include <AmiCspLib.h> +// Produced/used PPI interfaces +#include <ppi\PciCfg2.h> +#include <ppi\SBPPI.h> +#include <ppi\CpuIo.h> +#include <ppi\CspLibPpi.h> +#include <RTC.h> +#include <PchAccess.h> +#include <Ppi\PchUsbPolicy\PchUsbPolicy.h> +#include <Ppi\PchInit\PchInit.h> + +#include <Ppi\SmbusPolicy\SmbusPolicy.h> +#include <Ppi\PchPlatformPolicy\PchPlatformPolicy.h> + +#if defined iME_SUPPORT && iME_SUPPORT +#include <Guid\MeBiosExtensionSetup\MeBiosExtensionSetup.h> +#endif + +#if SB_RESET_PPI_SUPPORT +#include <Ppi\Reset.h> +#endif + +#if ATAPI_RECOVERY_SUPPORT +#include <Ppi\AtaController.h> +#endif + +#if SB_STALL_PPI_SUPPORT +#include <Ppi\Stall.h> +#endif + +#if WdtPei_SUPPORT +#include "ppi\Wdt\Wdt.h" +#endif +#include <ppi\NBPPI.h> + +#if Capsule2_0_SUPPORT +#include <ppi\capsule.h> //CAPSULE20 +#endif + +#if defined(SUPPORT_RAID_DRIVER) && SUPPORT_RAID_DRIVER && (PTT_VER > 15) +#include <FastBoot.h> + +#define SATA1_BDF (0x1f << 3 | 0x02) +#define SATA2_BDF (0x1f << 3 | 0x05) +#endif +//---------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//---------------------------------------------------------------------------- +// Constant Definition(s) +#define EHCI_MEMORY_SPACE 0x400 +#define TIMER_RESOLUTION 1 +#define S3_SLP_TYP 0x05 + +#ifndef SMM_SUPPORT + #define SMM_SUPPORT 0 +#endif + +#define RETRAIN_DELAY 50 // [EIP106687] + +// Macro Definition(s) + +// Type Definition(s) +#if defined iME_SUPPORT && iME_SUPPORT +// TS on DIMM defines +#define TS_ON_CHANNEL0_SLOT_0_DIMM 0x1 +#define TS_ON_CHANNEL1_SLOT_0_DIMM 0x2 +#define TS_ON_C0_S0_AND_C1_S0_DIMM 0x3 +#endif + +#ifndef CAPSULE_SUPPORT + +#if defined Capsule2_0_SUPPORT && Capsule2_0_SUPPORT +#define CAPSULE_SUPPORT 1 +#else +#define CAPSULE_SUPPORT 0 +#endif + +#endif + +typedef struct _SATA_LENGTH_CONFIG { + UINT8 SataGen1RxEqEnable; + UINT8 SataGen1RxEqValue; + UINT8 SataGen2RxEqEnable; + UINT8 SataGen2RxEqValue; + UINT8 SataGen3RxEqEnable; + UINT8 SataGen3RxEqValue; +} SATA_LENGTH_CONFIG; +// Function Prototype(s) + +BOOLEAN IsRecovery ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +#if SB_RESET_PPI_SUPPORT +EFI_STATUS SBPEI_ResetSystem ( + IN EFI_PEI_SERVICES **PeiServices +); +#endif + +#if SB_STALL_PPI_SUPPORT +EFI_STATUS SBPEI_Stall ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_STALL_PPI *This, + IN UINTN Microseconds +); +#endif + +#if ATAPI_RECOVERY_SUPPORT +EFI_STATUS EFIAPI EnableAtaChannel ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_ATA_CONTROLLER_PPI *This, + IN UINT8 ChannelIndex +); +#endif + +BOOLEAN IsS3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +VOID ProgramGPIO ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData, + IN AMI_GPIO_INIT_TABLE_STRUCT *pTable +); + +VOID ProgramSBSubId( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN AMI_PEI_SB_CUSTOM_PPI *SBPeiOemPpi +); + +VOID InitPCIe ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +VOID InitSMBus ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +VOID InitUsbMisc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN EFI_BOOT_MODE BootMode +); + +EFI_STATUS UpdateBootMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS ProgramSBRegAfterMemInstalled ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +EFI_STATUS ProgramSBRegBeforeEndofPei ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +EFI_STATUS ProgramSBRegAfterMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +EFI_STATUS ProgramSBRegEndOfMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi +); + +VOID InitPMRegs( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData +); + +VOID InitRTC( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +VOID WriteSBDefaultSubId ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +VOID ProgramRCRBMmio ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo +); + +EFI_STATUS +ProgramSBIoDecodeRegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS +ProgramPchDeviceBase ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS +GeneralPowerFailureHandler ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +); + +EFI_STATUS +SetTheStateToGoAfterG3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN SB_SETUP_DATA *SbSetupData +); + +EFI_STATUS InstallPchPlatformPolicyPpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN SB_SETUP_DATA *SbSetupData +); + +EFI_STATUS +InstallAmtPlatformPolicyPpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN SB_SETUP_DATA *SbSetupData +); + +EFI_STATUS +CreateAmtForcePushPetPolicyHob( + IN EFI_PEI_SERVICES **PeiServices +); + +//---------------------------------------------------------------------------- +// Variable and External Declaration(s) +//---------------------------------------------------------------------------- +// Variable Declaration(s) + +// GUID Definition(s) +EFI_GUID gAmiPEISBInitPolicyGuid = AMI_PEI_SBINIT_POLICY_PPI_GUID; +EFI_GUID gAmiPEIPCITableInitPpiGuid = AMI_PEI_PCI_TABLE_INIT_PPI_GUID; +EFI_GUID gMasterBootModeGuid = EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI; +EFI_GUID gRecoveryBootModeGuid = EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI; +EFI_GUID gEfiPeiPermMemInstalledGuid = EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI; +EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID; +EFI_GUID gPeiSmbusPolicyPpiGuid = PEI_SMBUS_POLICY_PPI_GUID; +EFI_GUID gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID; +EFI_GUID gSetupGuid = SETUP_GUID; +EFI_GUID gPchUsbPolicyPpiGuid = PCH_USB_POLICY_PPI_GUID; +EFI_GUID gPchInitPpiGuid = PCH_INIT_PPI_GUID; + +EFI_GUID gPeiCompleteMRCGuid = AMI_PEI_AFTER_MRC_GUID; + +#if SB_STALL_PPI_SUPPORT +EFI_GUID gStallPpiGuid = EFI_PEI_STALL_PPI_GUID; +#endif + +#if SB_RESET_PPI_SUPPORT +EFI_GUID gPeiResetPpiGuid = EFI_PEI_RESET_PPI_GUID; +#endif + +#if ATAPI_RECOVERY_SUPPORT +EFI_GUID gPeiAtaControllerPpiGuid = PEI_ATA_CONTROLLER_PPI_GUID; +#endif + +#if WdtPei_SUPPORT +EFI_GUID gWdtPpiGuid = WDT_PPI_GUID; +#endif + +EFI_GUID gOemPchPlatformPolicyOverridePpiGuid = AMI_PEI_SB_OEM_PLATFORM_POLICY_OVERRIDE_PPI_GUID; + +// PPI Definition(s) + +static AMI_PEI_SBINIT_POLICY_PPI mAMIPEISBInitPolicyPpi = { + TRUE +}; + +#if ATAPI_RECOVERY_SUPPORT +static PEI_ATA_CONTROLLER_PPI mAtaControllerPpi = { + EnableAtaChannel +}; +#endif + +#if SB_STALL_PPI_SUPPORT +static EFI_PEI_STALL_PPI mStallPpi = { + TIMER_RESOLUTION, + SBPEI_Stall +}; +#endif + +#if SB_RESET_PPI_SUPPORT +static EFI_PEI_RESET_PPI mResetPpi = { + SBPEI_ResetSystem +}; +#endif + +// PPI that are installed + +#if SB_STALL_PPI_SUPPORT +static EFI_PEI_PPI_DESCRIPTOR mBeforeBootModePpiList[] = { + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gStallPpiGuid, &mStallPpi }, +}; +#endif + +static EFI_PEI_PPI_DESCRIPTOR mBootModePpi[] = { + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gMasterBootModeGuid, NULL }, +}; + +static EFI_PEI_PPI_DESCRIPTOR mRecoveryModePpi[] = { + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gRecoveryBootModeGuid, NULL }, +}; + +static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { +#if ATAPI_RECOVERY_SUPPORT + { EFI_PEI_PPI_DESCRIPTOR_PPI, \ + &gPeiAtaControllerPpiGuid, &mAtaControllerPpi }, +#endif +#if SB_RESET_PPI_SUPPORT + { EFI_PEI_PPI_DESCRIPTOR_PPI, &gPeiResetPpiGuid, &mResetPpi }, +#endif + { EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gAmiPEISBInitPolicyGuid, &mAMIPEISBInitPolicyPpi } +}; + +// PPI that are notified + +static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gEfiPeiEndOfPeiPhasePpiGuid, ProgramSBRegBeforeEndofPei }, +}; + +static EFI_PEI_NOTIFY_DESCRIPTOR mMemoryReadyNotify[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiPermMemInstalledGuid, ProgramSBRegAfterMemInstalled } +}; + +static EFI_PEI_NOTIFY_DESCRIPTOR AfterMrcNotifyList[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gAmiPeiAfterMrcGuid, ProgramSBRegAfterMrc }, +}; +static EFI_PEI_NOTIFY_DESCRIPTOR EndOfMrcNotifyList[] = { + { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \ + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \ + &gAmiPeiEndOfMemDetectGuid, ProgramSBRegEndOfMrc }, +}; + +static EFI_PEI_PPI_DESCRIPTOR StallPpiDescriptor_InMemory[] = +{ + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gStallPpiGuid, + &mStallPpi + } +}; + +// External Declaration(s) + +extern AMI_GPIO_INIT_TABLE_STRUCT stSB_GPIODefaultInitTable[]; +extern AMI_GPIO_INIT_TABLE_STRUCT stSB_GPIODefaultULTInitTable[]; + +extern EFI_STATUS CountTime ( + IN UINTN DelayTime, + IN UINT16 BaseAddr +); + +#if SB_RESET_PPI_SUPPORT +extern VOID SBLib_ResetSystem ( + IN EFI_RESET_TYPE ResetType +); +#endif + +// Function Definition(s) + +#ifdef RAPID_START_FLAG + +#define RAPID_START_FLAG_ENTRY_DONE BIT0 + +EFI_STATUS +RapidStartGetFlag ( + OUT UINT8 *Value + ) +{ + *Value = RtcRead (FFS_NV_FLAG_REG); + return EFI_SUCCESS; +} + +BOOLEAN +RapidStartResumeCheck ( + VOID +) +{ + EFI_STATUS Status; + BOOLEAN RapidStartFlag; + + Status = RapidStartGetFlag (&RapidStartFlag); + if ( !EFI_ERROR (Status) && ((RapidStartFlag & RAPID_START_FLAG_ENTRY_DONE) != 0)) { + return TRUE; + } + + return FALSE; +} +#endif + +//---------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsS3 +// +// Description: This function determines if the system is resuming from an S3 +// sleep state. +// +// Input: PeiServices - Pointer to the Pei Services function and data +// structure. +// +// Output: TRUE - It is an S3 Resume +// FALSE - It is not an S3 Resume +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsS3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + // Check PWR_FLR Bit + if ((READ_PCI8_SB(R_PCH_LPC_GEN_PMCON_3) & B_PCH_LPC_GEN_PMCON_PWR_FLR) == 0) // 0xA4 + // Check PWRBTN override + if ((READ_IO16_PM(R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_PRBTNOR) == 0) // 0x00 + // Check WAK_STS bit + if ((READ_IO16_PM(R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_WAK)) // 0x00 + // Check the sleep type + if ((READ_IO16_PM(R_PCH_ACPI_PM1_CNT) & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) //0x04 + return TRUE; + + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsS4 +// +// Description: This function determines if the system is resuming from an S4 +// sleep state. +// +// Input: PeiServices - Pointer to the Pei Services function and data +// structure. +// +// Output: TRUE - It is an S4 Resume +// FALSE - It is not an S4 Resume +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsS4 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + if ((READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 0x1c00) == 0x1800) //0x04 + return TRUE; + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsCmosBad +// +// Description: This function determines CMOS data is available. +// +// Input: PeiServices - Pointer to the Pei Services function and data +// structure. +// +// Output: TRUE - CMOS data is bad +// FALSE - CMOS DATA is available +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsCmosBad ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + return (READ_IO8_RTC(CMOS_BAD_REG | RTC_NMI_MASK) & 0xc0) ? TRUE : FALSE; +} + +#if KBC_SUPPORT && Recovery_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ResetKbc +// +// Description: This function resets Keyboard controller for Ctrl-Home +// recovery function. +// +// Input: PeiServices - Pointer to the Pei Services function and +// data structure +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +// +// Notes: No porting required. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ResetKbc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + volatile UINT8 KbcSts = 0; + volatile UINT8 Buffer8; + UINT32 TimeOut = 0x100; + + // Reset KBC + if (CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ) != 0xff) { + // Clear KBC buffer + do { + Buffer8 = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_DATA ); + KbcSts = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 + TimeOut--; + } while ((KbcSts & 3) && (TimeOut != 0)); + + + // Send BAT command + CpuIo->IoWrite8( PeiServices, CpuIo, KBC_IO_STS, 0xaa ); // 0x64 + + // IBFree + for (TimeOut = 0; TimeOut < 0x1000; TimeOut++) { + CpuIo->IoWrite8( PeiServices, CpuIo, IO_DELAY_PORT, KbcSts ); + KbcSts = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 + if ((KbcSts & 2) == 0) break; + } + + // OBFree + for (TimeOut = 0; TimeOut < 0x500; TimeOut++) { + CpuIo->IoWrite8( PeiServices, CpuIo, IO_DELAY_PORT, KbcSts ); + KbcSts = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 + if (KbcSts & 1) break; + } + + // Get result if needed + if (KbcSts & 1) + Buffer8 = CpuIo->IoRead8( PeiServices, CpuIo, KBC_IO_DATA ); + } + + // Clear KBC status buffer. + KbcSts = CpuIo->IoRead8 ( PeiServices, CpuIo, KBC_IO_STS ); // 0x64 +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UpdateBootMode +// +// Description: This function determines the boot mode of the system. +// After the correct boot mode has been determined, the PEI +// Service function SetBootMode is called and then +// the MasterBootModePpi is installed +// +// Input: PeiServices - Pointer to the Pei Services function and +// data structure +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: Always returns EFI_SUCCESS +// Also defines the boot mode for the system +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS UpdateBootMode ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + // Check for changes in the possible boot modes. This should be made in + // prioritized order. At the end of this function the boot mode is + // determined. The EFI_BOOT_MODE is defined in the PEI Spec + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if (EFI_ERROR(Status) || (BootMode != BOOT_IN_RECOVERY_MODE)) + BootMode = BOOT_WITH_FULL_CONFIGURATION; + + // Returns 0 if no S3 resume detected returns -1 if this is an S3 boot + if (IsS3(PeiServices, CpuIo)) { + BootMode = BOOT_ON_S3_RESUME; + PEI_TRACE((-1,PeiServices, "Boot mode = BOOT_ON_S3_RESUME\n")); + } else { + // Check for S4 resume + if (IsS4(PeiServices, CpuIo)) { + BootMode = BOOT_ON_S4_RESUME; + PEI_TRACE((-1, PeiServices, "Boot mode = BOOT_ON_S4_RESUME\n")); + } + // Check for recovery mode + #if KBC_SUPPORT && Recovery_SUPPORT && PERFORM_KBC_RESET + ResetKbc(PeiServices, CpuIo, PciCfg); + #endif + + if (IsRecovery(PeiServices, PciCfg, CpuIo)) + BootMode = BOOT_IN_RECOVERY_MODE; + } + + if (IsCmosBad(PeiServices, CpuIo)) { + if (BootMode != BOOT_IN_RECOVERY_MODE){ + BootMode = BOOT_WITH_DEFAULT_SETTINGS; + PEI_TRACE((-1,PeiServices,"Boot mode = BOOT_WITH_DEFAULT_SETTING\n")); + } + +#if FORCE_USER_TO_SETUP_IF_CMOS_BAD // [EIP88358] >> +{ + EFI_STATUS Status; + UINT16 HobSize = sizeof(CMOS_BAD_HOB); + EFI_GUID CmosBadHobGuid = CMOS_BAD_HOB_GUID; + CMOS_BAD_HOB *CmosBadHob; + + Status = (*PeiServices)->CreateHob( PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + HobSize, + &CmosBadHob); + if(!EFI_ERROR(Status)) { + CmosBadHob->Header.Name = CmosBadHobGuid; + } +} +#endif // [EIP88358] << + } +#if Capsule2_0_SUPPORT + +#else + #if CAPSULE_SUPPORT + if (!EFI_ERROR(CheckIfCapsuleAvailable())) + BootMode = BOOT_ON_FLASH_UPDATE; + #endif +#endif + // Set the system BootMode + (*PeiServices)->SetBootMode(PeiServices, BootMode); + + // Let everyone know that boot mode has been determined by installing the + // MasterBootMode PPI + (*PeiServices)->InstallPpi(PeiServices, mBootModePpi ); + + (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + if (BootMode == BOOT_IN_RECOVERY_MODE) // Recovery Boot Mode PPI + (*PeiServices)->InstallPpi( PeiServices, mRecoveryModePpi ); + + // [EIP87695]> +#if SYSTEM_REBOOT_NORMALLY_IF_S3_IS_FAILED + if (BootMode == BOOT_ON_S3_RESUME) //S3 Boot Mode PPI + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 0xe3ff ); // Clear S3 for avoiding S3 resume twice +#endif + // <[EIP87695] + + return EFI_SUCCESS; +} + +#if defined(SUPPORT_RAID_DRIVER) && SUPPORT_RAID_DRIVER && (PTT_VER > 15) +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DetectSataPortInfo +// +// Description: This function provides SATA Port Information +// +// Input: PeiServices - Pointer to the PEI services table +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID DetectSataPortInfo ( + IN EFI_PEI_SERVICES **PeiServices) +{ + EFI_STATUS Status; + UINT16 HobSize = sizeof(SATA_PRESENT_HOB); + EFI_GUID SataPresentHobGuid = AMI_SATA_PRESENT_HOB_GUID; + SATA_PRESENT_HOB *SataPresentHob; + UINT16 SataClassCode; + UINT8 SataPortStatus; + UINT8 SataPortEnable = 0; + SB_SETUP_DATA SbSetupData; + UINT8 i; + + Status = (*PeiServices)->CreateHob (PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + HobSize, + &SataPresentHob); + if(EFI_ERROR(Status)) return; + + SataPresentHob->EfiHobGuidType.Name = SataPresentHobGuid; + + for (i = 0; i < 4; i++) { + SataPresentHob->SataInfo[i].ClassCode = 0; + SataPresentHob->SataInfo[i].PresentPortBitMap = 0; + } + + // The SATA Mode Select should be configured in PchInitPeim. + SataClassCode = READ_PCI16_SATA(R_PCH_SATA_SUB_CLASS_CODE); + SataPresentHob->SataInfo[0].ClassCode = SataClassCode; + + if ((SataClassCode & 0xFF) == V_PCH_SATA_SUB_CLASS_CODE_IDE) { + // Lynx Point-LP didn't support IDE mode, so code should not enter here. + SataPortStatus = READ_PCI16_SATA(R_PCH_SATA_PCS) >> 8; + SataPresentHob->SataInfo[0].PresentPortBitMap = (SATA1_BDF << 16) | (SataPortStatus & 0xF); // Port 0~3 + SataPortStatus = READ_PCI16_SATA2(R_PCH_SATA_PCS) >> 8; + SataPresentHob->SataInfo[1].PresentPortBitMap = (SATA2_BDF << 16) | (SataPortStatus & 0x3); // Port 4~5 + SataPresentHob->SataInfo[1].ClassCode = SataClassCode; + SataPresentHob->ControllerCount = 2; + } else { // AHCI or Raid + GetSbSetupData (PeiServices, &SbSetupData, TRUE); + SataPortStatus = READ_PCI16_SATA(R_PCH_SATA_PCS) >> 8; + for (i = 0; i < GetPchMaxSataPortNum(); i++) { + // SataPort controll is done in DXE, so check Setup value here. + SataPortEnable |= (SbSetupData.SataPort[i] << i); + } + SataPortStatus &= SataPortEnable; + SataPresentHob->SataInfo[0].PresentPortBitMap = (SATA1_BDF << 16) | (SataPortStatus & 0x3F); // Port 0~5 + SataPresentHob->ControllerCount = 1; + } +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBPEI_Init +// +// Description: This function is the entry point for this PEI. This function +// initializes the chipset SB +// +// Input: FfsHeader - Pointer to the FFS file header +// PeiServices - Pointer to the PEI services table +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +// +// Notes: This function should initialize South Bridge for memory +// detection. +// Install AMI_PEI_SBINIT_POLICY_PPI to indicate that SB Init +// PEIM is installed +// Following things can be done at this point: +// - Enabling top of 4GB decode for full flash ROM +// - Programming South Bridge ports to enable access to +// South Bridge and other I/O bridge access +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EFIAPI SBPEI_Init ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices ) +{ + EFI_STATUS Status; + IN EFI_PEI_PCI_CFG2_PPI *PciCfg; + EFI_PEI_CPU_IO_PPI *CpuIo; + AMI_PEI_PCI_TABLE_INIT_PPI *AMIPCITableInit; + SB_SETUP_DATA SbSetupData; + AMI_GPIO_INIT_TABLE_STRUCT *pTable; + AMI_PEI_SB_CUSTOM_PPI *SBPeiOemPpi = NULL; + PCH_SERIES PchSeries = GetPchSeries(); + + // Get pointer to the PCI config PPI + PciCfg = (*PeiServices)->PciCfg; + CpuIo = (*PeiServices)->CpuIo; + + PEI_PROGRESS_CODE (PeiServices, PEI_CAR_SB_INIT); + WRITE_IO8(PORTB_IO_CNTL, 0x0c); // Disable IOCHK NMI #, PCI SERR#. (0x61) + + // Locate AMI PCI Table Init PPI + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gAmiPEIPCITableInitPpiGuid, \ + 0, \ + NULL, \ + &AMIPCITableInit ); + + // Assert if not found - the AMI PCI Table Init PPI should exist + ASSERT_PEI_ERROR( PeiServices, Status ); + + GetSbSetupData( PeiServices, &SbSetupData, TRUE ); + +#if WdtPei_SUPPORT +{ + WDT_PPI *WdtPpi; + + // Locate WDT PPI for access to Wdt->Disable() + // + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gWdtPpiGuid, + 0, + NULL, + &WdtPpi + ); + if (!EFI_ERROR (Status)) { + WdtPpi->Disable(); + } +} +#endif + // Program Pch devices bar base + ProgramPchDeviceBase(PeiServices, PciCfg); + +#if SB_STALL_PPI_SUPPORT + // Install the SB Stall PPI + Status = (*PeiServices)->InstallPpi( PeiServices, \ + &mBeforeBootModePpiList[0] ); + ASSERT_PEI_ERROR( PeiServices, Status ); +#endif + + // Program Pch RCBA base + ProgramRCRBMmio(PeiServices, CpuIo); + + UpdateBootMode( PeiServices, CpuIo, PciCfg ); + + // Install PchPlatformPolicyPpi, it will notify to PchInitialize. + InstallPchPlatformPolicyPpi( PeiServices, &SbSetupData); + + //DeCode LPC IO + ProgramSBIoDecodeRegs( PeiServices, PciCfg); + + //Program GPIOs. + //Program the default GPIO Setting for chipset. +#if defined PROGRAM_DEFAULT_GPIO && PROGRAM_DEFAULT_GPIO == 1 + if (PchSeries == PchLp) { + pTable = stSB_GPIODefaultULTInitTable; + }else{ + pTable = stSB_GPIODefaultInitTable; + } + + ProgramGPIO( PeiServices, \ + CpuIo, \ + &SbSetupData, \ + pTable); +#endif + + //Program the OEM GPIO Setting for board. + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gAmiPeiSBCustomPpiGuid, \ + 0, \ + NULL, \ + &SBPeiOemPpi ); + + if (Status == EFI_SUCCESS) { + if (SBPeiOemPpi->GpioInit != NULL) { + pTable = SBPeiOemPpi->GpioInit->GpioTable; + ProgramGPIO( PeiServices, \ + CpuIo, \ + &SbSetupData, \ + pTable); + } + } else { + SBPeiOemPpi = NULL; + } + + // Program SB Devices' Subsystem Vendor ID & Subsystem ID + ProgramSBSubId( PeiServices, PciCfg, SBPeiOemPpi ); + + //Program PM Regs. + InitPMRegs(PeiServices, CpuIo, &SbSetupData); + + // General power failure handling + GeneralPowerFailureHandler(PeiServices, CpuIo, PciCfg); + + InitRTC( PeiServices, CpuIo ); + + // Set what state (S0/S5) to go to when power is re-applied after a power failure (G3 state) + SetTheStateToGoAfterG3(PeiServices, CpuIo, PciCfg, &SbSetupData); + + InitPCIe( PeiServices, CpuIo, PciCfg ); + + InitSMBus( PeiServices, CpuIo, PciCfg ); + + + // Install the SB Init Policy PPI + Status = (*PeiServices)->InstallPpi( PeiServices, &mPpiList[0] ); + ASSERT_PEI_ERROR( PeiServices, Status ); + + // Setup a SBPEI entry after PEI permantent memory be installed + + Status = (*PeiServices)->NotifyPpi( PeiServices, AfterMrcNotifyList ); + + Status = (*PeiServices)->NotifyPpi ( PeiServices, mMemoryReadyNotify ); + ASSERT_PEI_ERROR( PeiServices, Status ); + +#if defined iME_SUPPORT && iME_SUPPORT == 0 + if (!IsS3(PeiServices, CpuIo)) { + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, 0x20); // Clear Sleep Type + } +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramGPIO +// +// Description: This function initializes SB GPIOs +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ProgramGPIO ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData, + IN AMI_GPIO_INIT_TABLE_STRUCT *pTable +) +{ + UINT16 i; + UINT32 OWN1; + UINT32 OWN2; + UINT32 OWN3; + UINT32 GPN_CFG1[96]; + UINT32 GPN_CFG2[96]; + UINT32 USE1_SEL; + UINT32 USE2_SEL; + UINT32 USE3_SEL; + UINT32 IO1_SEL; + UINT32 IO2_SEL; + UINT32 IO3_SEL; + UINT32 LVL1_SEL; + UINT32 LVL2_SEL; + UINT32 LVL3_SEL; + UINT32 INV1_SEL; + UINT32 RST1_SEL; + UINT32 RST2_SEL; + UINT32 RST3_SEL; + UINT32 BLNK_SEL; + UINT32 INT1_SEL; + UINT32 INT2_SEL; + UINT32 INT3_SEL; + UINT16 Offset; + UINT16 LpcDeviceId; + PCH_SERIES PchSeries = GetPchSeries(); + + LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID); + + if (pTable[0].GpioNo != 0xffff) { + if (PchSeries == PchLp) { + OWN1 = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN1); // 0x00 + OWN2 = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN2); // 0x04 + OWN3 = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN3); // 0x08 + INT1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL1); // 0x90 + INT2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL2); // 0x94 + INT3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL3); // 0x98 + } else { + USE1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL); // 0x00 + IO1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL); // 0x04 + LVL1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL); // 0x0C + INV1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPI_INV); // 0x2C + + USE2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL2); // 0x30 + IO2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL2); // 0x34 + LVL2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL2); // 0x38 + + USE3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL3); // 0x40 + IO3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL3); // 0x44 + LVL3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL3); // 0x48 + } + BLNK_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPO_BLINK); // 0x18 + RST1_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1); // 0x60 + RST2_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL2); // 0x64 + RST3_SEL = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL3); // 0x68 + + for (i = 0; pTable[i].GpioNo != 0xffff; i++) { + + Offset = pTable[i].GpioNo; + if (PchSeries == PchLp) { + GPN_CFG1[Offset] = READ_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG1 + GP_GPIO_CONFIG_SIZE*Offset)); // 0x100 + n*8h + GPN_CFG2[Offset] = READ_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG2 + GP_GPIO_CONFIG_SIZE*Offset)); // 0x104 + n*8h + + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT31)) | (pTable[i].GpioCfg.Fileds.LVL << 31); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT4)) | (pTable[i].GpioCfg.Fileds.LEB << 4); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT3)) | (pTable[i].GpioCfg.Fileds.INV << 3); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(BIT2)) | (pTable[i].GpioCfg.Fileds.IO << 2); + GPN_CFG1[Offset] = (GPN_CFG1[Offset] & ~(1)) | (pTable[i].GpioCfg.Fileds.USE); + GPN_CFG2[Offset] = (GPN_CFG2[Offset] & ~(BIT2)) | (pTable[i].GpioCfg.Fileds.DIS << 2); + //(EIP118667)>> + if(pTable[i].GpioCfg.Fileds.IO == 0 && pTable[i].GpioCfg.Fileds.USE == 1){ + GPN_CFG2[Offset] = (GPN_CFG2[Offset] & ~(BIT2)) | (BIT2); + } + //(EIP118667)<< + GPN_CFG2[Offset] = (GPN_CFG2[Offset] & ~(3)) | (pTable[i].GpioCfg.Fileds.WP); + } + + if (Offset < 32) { + if (PchSeries == PchLp) { + OWN1 = (OWN1 & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.OWN << Offset); + INT1_SEL = (INT1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.INT << Offset); + } else { + USE1_SEL = (USE1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.USE << Offset); + IO1_SEL = (IO1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.IO << Offset); + LVL1_SEL = (LVL1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.LVL << Offset); + INV1_SEL = (INV1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.INV << Offset); + } + RST1_SEL = (RST1_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.RST << Offset); + BLNK_SEL = (BLNK_SEL & ~(1 << Offset)) | (pTable[i].GpioCfg.Fileds.BLK << Offset); + } else if ((Offset >= 32) && (Offset < 64)) { + if (PchSeries == PchLp) { + OWN2 = (OWN2 & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.OWN << (Offset - 32)); + INT2_SEL = (INT2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.INT << (Offset - 32)); + } else { + USE2_SEL = (USE2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.USE << (Offset - 32)); + IO2_SEL = (IO2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.IO << (Offset - 32)); + LVL2_SEL = (LVL2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.LVL << (Offset - 32)); + } + RST2_SEL = (RST2_SEL & ~(1 << (Offset - 32))) | (pTable[i].GpioCfg.Fileds.RST << (Offset - 32)); + } else { + if (PchSeries == PchLp) { + OWN3 = (OWN3 & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.OWN << (Offset - 64)); + INT3_SEL = (INT3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.INT << (Offset - 64)); + } else { + USE3_SEL = (USE3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.USE << (Offset - 64)); + IO3_SEL = (IO3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.IO << (Offset - 64)); + LVL3_SEL = (LVL3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.LVL << (Offset - 64)); + } + RST3_SEL = (RST3_SEL & ~(1 << (Offset - 64))) | (pTable[i].GpioCfg.Fileds.RST << (Offset - 64)); + } + if (PchSeries == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG1 + GP_GPIO_CONFIG_SIZE*Offset), GPN_CFG1[Offset]); // 0x100 + n*8h + WRITE_IO32(GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG2 + GP_GPIO_CONFIG_SIZE*Offset), GPN_CFG2[Offset]); // 0x104 + n*8h + } + } + + if (PchSeries == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN1, OWN1); // 0x00 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN2, OWN2); // 0x04 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_OWN3, OWN3); // 0x08 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL1, INT1_SEL); // 0x90 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL2, INT2_SEL); // 0x94 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_INT_SEL3, INT3_SEL); // 0x98 + WRITE_IO32(GPIO_BASE_ADDRESS + GPI_IRQ_2_IOAPIC, GPI_IRQ_2_IOXAPIC); // 0x10 + } else { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL, USE1_SEL); // 0x00 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL, IO1_SEL); // 0x04 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL, LVL1_SEL); // 0x0C + + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPI_INV, INV1_SEL); // 0x2C + + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL2, USE2_SEL); // 0x30 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL2, IO2_SEL); // 0x34 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL2, LVL2_SEL); // 0x38 + + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL3, USE3_SEL); // 0x40 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_IO_SEL3, IO3_SEL); // 0x44 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL3, LVL3_SEL); // 0x48 + } + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GPO_BLINK, BLNK_SEL); // 0x18 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1, RST1_SEL); // 0x60 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL2, RST2_SEL); // 0x64 + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL3, RST3_SEL); // 0x68 + } + + // BIOS implementation for SUS_PWR_DN_ACK + // As soon as platform BARs are initialized, BIOS must ensure that the following things + // are set high on all boot flows: + // (1) GPIO_BASE_ADDRESS + 0x60[30] + // (2) GPIO[30] pin (GPIO_BASE_ADDRESS + GP_LVL) (Done in GPIO.SDL) + if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + SET_IO32 (GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1, BIT30); // 0x60 + } + // + // Now enable LANPHY_PC GPIO if LAN is enabled in the setup. + // Enabling this GPIO for all the boards. Both Red Fort and Buffalo Trail uses GPIO12 for this. + // Electric Peak does not use GPIO12, so changing the value for all boards should not effect + if (SbSetupData->PchLan) { + if (PchSeries == PchLp) { + SET_IO32 (GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG1 + GP_GPIO_CONFIG_SIZE*22), BIT31); // 0x190 + } else { + SET_IO32 (GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL, BIT12); // 0x0C + } + } + + // Clear GPI Status + if (PchSeries == PchLp) { + WRITE_IO16_PM(ACPI_PCHLP_IOREG_GPE0_STS, 0xffff); // 0x80 + WRITE_IO16_PM(ACPI_PCHLP_IOREG_GPE0_STS + 4, 0xffff); // 0x84 + WRITE_IO16_PM(ACPI_PCHLP_IOREG_GPE0_STS + 8, 0xffff); // 0x88 + } else { + WRITE_IO16_PM(ACPI_IOREG_GPE0_STS + 2, 0xffff); // 0x22 + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsSBDevice +// +// Description: This function detimines SB PCI devices +// +// Input: UINT64 PciAddress +// UINT8 *PciSidReg +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS IsSBDevice( + IN UINT64 PciAddress, + IN OUT UINT8 *PciSidReg +) +{ + UINT8 i; + AMI_SB_PCI_DEVICES_TABLE_STRUCT PchDeviceTable[] = { HECI_BUS_DEV_FUN, ME_REG_SVID, + HECI2_BUS_DEV_FUN, ME_REG_SVID, + IDER_BUS_DEV_FUN, ME_REG_SVID, + KT_BUS_DEV_FUN, ME_REG_SVID, + XHCI_BUS_DEV_FUN, XHCI_REG_SVID, + LAN_BUS_DEV_FUN, LAN_REG_SVID, + EHCI2_BUS_DEV_FUN, EHCI_REG_SVID, + HDA_BUS_DEV_FUN, HDA_REG_SVID, + PCIEBRS_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS2_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS3_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS4_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS5_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS6_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS7_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIEBRS8_BUS_DEV_FUN, PCIEBRS_REG_SVID, + PCIBR_BUS_DEV_FUN, PCIBR_REG_SVID, + EHCI_BUS_DEV_FUN, EHCI_REG_SVID, + SB_BUS_DEV_FUN, R_PCH_LPC_SS, + SATA_BUS_DEV_FUN, SATA_REG_SVID, + SMBUS_BUS_DEV_FUN, SMBUS_REG_SVID, + SATA2_BUS_DEV_FUN, SATA_REG_SVID, + THERMAL_BUS_DEV_FUN, R_PCH_LPC_SS + }; + UINT32 TableSize = sizeof(PchDeviceTable) / sizeof(AMI_SB_PCI_DEVICES_TABLE_STRUCT); + + for (i = 0; i < TableSize; i++) { + + if (PciAddress != PchDeviceTable[i].PciAddr) { + continue; + } else { + if (READ_PCI32((UINT8)(Shr64(PchDeviceTable[i].PciAddr, 24) & 0xff), \ + (UINT8)(Shr64(PchDeviceTable[i].PciAddr, 16) & 0xff), \ + (UINT8)(Shr64(PchDeviceTable[i].PciAddr, 8) & 0xff), \ + 0) == 0xffffffff) + return EFI_UNSUPPORTED; + + *PciSidReg = PchDeviceTable[i].PciSidReg; + return EFI_SUCCESS; + } + } + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBSubId +// +// Description: This function programs SB PCI devices sub-vendor ID and +// sub-system ID. +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: VOID +// +// Notes: 1. This routine only programs the PCI device in SB, hence, we +// have to check the bus/device/function numbers whether they +// are a SB PCI device or not. +// 2. This routine is invoked by PEI phase.(After PEI permantent +// memory be installed) +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ProgramSBSubId ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN AMI_PEI_SB_CUSTOM_PPI *SBPeiOemPpi +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN i = 0; + UINT32 PciSid = 0xffffffff; + UINT8 PciSidReg = 0xff; + AMI_SB_PCI_SSID_TABLE_STRUCT DefaultSIdTbl[] = {SB_PCI_DEVICES_SSID_TABLE}; + AMI_SB_PCI_SSID_TABLE_STRUCT *SsidTblPtr = DefaultSIdTbl; + + if ((SBPeiOemPpi != NULL) && (SBPeiOemPpi->SsidTable != NULL)) + SsidTblPtr = SBPeiOemPpi->SsidTable; + + while (SsidTblPtr[i].PciAddr != 0xffffffffffffffff) { + if (IsSBDevice(SsidTblPtr[i].PciAddr, &PciSidReg) == EFI_SUCCESS) { + if (SsidTblPtr[i].Sid == 0xffffffff) { + Status = PciCfg->Read( PeiServices, + PciCfg, + EfiPeiPciCfgWidthUint32, + SsidTblPtr[i].PciAddr, + &PciSid); + } else { + PciSid = SsidTblPtr[i].Sid; + } + + if (SsidTblPtr[i].PciAddr == EHCI_BUS_DEV_FUN) + SET_PCI8_EHCI(R_PCH_EHCI_ACCESS_CNTL, 1); + else if (SsidTblPtr[i].PciAddr == EHCI2_BUS_DEV_FUN) + SET_PCI8_EHCI2(R_PCH_EHCI_ACCESS_CNTL, 1); + + Status = PciCfg->Write( PeiServices, + PciCfg, + EfiPeiPciCfgWidthUint32, + SsidTblPtr[i].PciAddr | PciSidReg, + &PciSid); + + if (SsidTblPtr[i].PciAddr == EHCI_BUS_DEV_FUN) + RESET_PCI8_EHCI(R_PCH_EHCI_ACCESS_CNTL, 1); + else if (SsidTblPtr[i].PciAddr == EHCI2_BUS_DEV_FUN) + RESET_PCI8_EHCI2(R_PCH_EHCI_ACCESS_CNTL, 1); + } + i++; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitPCIe +// +// Description: This function initializes SB PCI Express controller(s) +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitPCIe ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + // TODO +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSMBus +// +// Description: This function initializes SB SMBUS controller(s) +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitSMBus ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + // TODO +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitUsbMisc +// +// Description: Miscellaneous USB initialization. +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// BootMode - Boot Mode +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitUsbMisc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN EFI_BOOT_MODE BootMode +) +{ + PCH_SERIES PchSeries = GetPchSeries(); +#ifndef PEI_XHCI_MMIOBASE + UINT32 XhciMmioBase = 0xFE400000; //[EIP156783] +#else + UINT32 XhciMmioBase = PEI_XHCI_MMIOBASE; //[EIP115528] >> +#endif + UINT8 XhciCapLength; + UINT8 XhciMaxPorts; + UINT32 XhciPort; + EFI_PEI_STALL_PPI *StallPpi; + StallPpi = &mStallPpi; + +if ((BootMode == BOOT_IN_RECOVERY_MODE) || (BootMode == BOOT_ON_FLASH_UPDATE)) { + WRITE_PCI32( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x10, \ + XhciMmioBase); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x04, \ + 0x06); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_USB3PR, \ + 0x3F); + + //Add some delay to wait that device links are stable + StallPpi->Stall(PeiServices, StallPpi, 500 * 1000); + + XhciCapLength = READ_MEM8(XhciMmioBase); + if (PchSeries == PchH) { + switch ((READ_MEM8(XhciMmioBase + R_PCH_XHCI_FUS)) & B_PCH_XHCI_FUS_SSPRTCNT) { + case V_PCH_XHCI_FUS_SSPRTCNT_11B: + XhciMaxPorts = 0x0F; + break; + + case V_PCH_XHCI_FUS_SSPRTCNT_10B: + XhciMaxPorts = 0x11; + break; + + case V_PCH_XHCI_FUS_SSPRTCNT_01B: + XhciMaxPorts = 0x13; + break; + + case V_PCH_XHCI_FUS_SSPRTCNT_00B: + default: + XhciMaxPorts = 0x15; + break; + } + } else { + XhciMaxPorts = READ_MEM8(XhciMmioBase + 0x7); + } + //Clear each xHCI port power + for (XhciPort = 0; XhciPort < XhciMaxPorts; XhciPort++) { + RESET_MEM32(XhciMmioBase + XhciCapLength + 0x400 + (0x10 * XhciPort), BIT9); + } + // Set xHCI D0h & D8h as power-on default value. + WRITE_PCI16( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_USB2PR, \ + 0 ); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + R_PCH_XHCI_USB3PR, \ + 0 ); + WRITE_PCI8( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x04, \ + 0); + WRITE_PCI32( DEFAULT_PCI_BUS_NUMBER_PCH, \ + PCI_DEVICE_NUMBER_PCH_XHCI, \ + PCI_FUNCTION_NUMBER_PCH_XHCI, \ + 0x10, \ + 0); + } + + + // [EIP107424] [EIP123117]> + if (BootMode != BOOT_ON_S3_RESUME) { + // + // Clear unexpected USB EHCI Legacy Support Extended status. + // Set B0:D1A/1D:F0 Reg#6Ch[31:29] = '111b'. + // + WRITE_PCI32_EHCI ( R_PCH_EHCI_LEGEXT_CS, \ + B_PCH_EHCI_LEGEXT_CS_SMIBAR | \ + B_PCH_EHCI_LEGEXT_CS_SMIPCI | \ + B_PCH_EHCI_LEGEXT_CS_SMIOS); + if (PchSeries == PchH) { + WRITE_PCI32_EHCI ( R_PCH_EHCI_LEGEXT_CS, \ + B_PCH_EHCI_LEGEXT_CS_SMIBAR | \ + B_PCH_EHCI_LEGEXT_CS_SMIPCI | \ + B_PCH_EHCI_LEGEXT_CS_SMIOS); + } + } + // <[EIP107424] [EIP123117] + //[EIP115528]<< +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegAfterMemInstalled +// +// Description: This function can be used to program any SB regisater after +// PEI permantent memory be installed. +// +// Input: FfsHeader - Pointer to the desired FFS header. +// PeiServices - Pointer to the PEI services table. +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegAfterMemInstalled ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PEI_CPU_IO_PPI *CpuIo; + IN EFI_PEI_PCI_CFG2_PPI *PciCfg; + EFI_BOOT_MODE BootMode; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + UINTN VariableSize; + UINT32 SbAslBufVarPtr; + EFI_GUID SbAslBufPtrGuid = SB_ASL_BUFFER_PTR_GUID; + CHAR16 SbAslBufPtrVar[] = SB_ASL_BUFFER_PTR_VARIABLE; + + CpuIo = (*PeiServices)->CpuIo; + PciCfg = (*PeiServices)->PciCfg; + + PEI_PROGRESS_CODE (PeiServices, PEI_MEM_SB_INIT); + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + InitUsbMisc( PeiServices, CpuIo, PciCfg, BootMode ); + +#if (ACPI_SUPPORT) + if (BootMode == BOOT_ON_S3_RESUME) { + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gEfiPeiReadOnlyVariable2PpiGuid, \ + 0, \ + NULL, \ + &ReadOnlyVariable ); + ASSERT_PEI_ERROR( PeiServices, Status ); + VariableSize = sizeof(SbAslBufVarPtr); + Status = ReadOnlyVariable->GetVariable( ReadOnlyVariable, \ + SbAslBufPtrVar, \ + &SbAslBufPtrGuid, \ + NULL, \ + &VariableSize, \ + &SbAslBufVarPtr ); + if (!EFI_ERROR(Status)) { + // Update ACPI RTC status + RESET_MEM8(SbAslBufVarPtr, 1); // Clear ACPI RTC status + if (READ_IO16_PM(ACPI_IOREG_PM1_STS) & 0x400) + SET_MEM8(SbAslBufVarPtr, 1); // Set ACPI RTC status + } +#if defined BootScriptHide_SUPPORT && BootScriptHide_SUPPORT + //SCI_EN = 1 + SET_IO8_PM(ACPI_IOREG_PM1_CNTL, B_PCH_ACPI_PM1_CNT_SCI_EN); //PM1_CNT +#endif + } +#endif + // Clear Global Reset Bit + RESET_PCI32_SB(SB_REG_LPC_PMIR, B_ICH_LPC_PMIR_CF9GR); + + // Set up necessary PPI notifications after PEI permantent memory + // be installed + Status = (*PeiServices)->NotifyPpi( PeiServices, &mNotifyList[0] ); + ASSERT_PEI_ERROR ( PeiServices, Status ); + +#if defined RapidStart_SUPPORT && RapidStart_SUPPORT + if (BootMode == BOOT_ON_S4_RESUME) + if (RtcRead(FFS_NV_FLAG_REG) & BIT0) + return EFI_SUCCESS; +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegBeforeEndofPei +// +// Description: This function can be used to program any SB regisater before +// end of PEI phase. +// +// Input: PeiServices - Pointer to the PEI services table +// NotifyDescriptor - Pointer to the descriptor for the +// notification event. +// InvokePpi - Pointer to the PPI that was installed +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegBeforeEndofPei ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PEI_CPU_IO_PPI *CpuIo; + IN EFI_PEI_PCI_CFG2_PPI *PciCfg; + EFI_BOOT_MODE BootMode; + + CpuIo = (*PeiServices)->CpuIo; + PciCfg = (*PeiServices)->PciCfg; + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + if (BootMode == BOOT_ON_S3_RESUME) { + // [EIP87695]> +#if SYSTEM_REBOOT_NORMALLY_IF_S3_IS_FAILED + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 0xe3ff | (S3_SLP_TYP << 10)); // Clear S3 for avoiding S3 resume twice +#endif + // <[EIP87695] + // Porting if needed. + } else { + // Porting if needed. + } + + // Setting 8254 + // program timer 1 as refresh timer + IoWrite8(LEGACY_TIMER_CTRL,0x54); + IoWrite8(LEGACY_TIMER_1_COUNT,0x12); + +#if defined(SUPPORT_RAID_DRIVER) && SUPPORT_RAID_DRIVER && (PTT_VER > 15) + DetectSataPortInfo(PeiServices); +#endif + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsRtcUipAlwaysSet +// +// Description: Check RTC Time Update In Progress. +// +// Input: PeiServices - Pointer to the PEI services table +// +// Output: Boolean +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN IsRtcUipAlwaysSet( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + + EFI_PEI_STALL_PPI *StallPpi; + UINTN Count; + + StallPpi = &mStallPpi; + + for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500) + if ((READ_IO8_RTC(RTC_NMI_MASK | RTC_REG_A_INDEX) & BIT07) == 0) { + return FALSE; + } + StallPpi->Stall (PeiServices, StallPpi, 3000); + } + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitRTC +// +// Description: This function initializes SB RTC related registers +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitRTC ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + UINT8 Buffer8; + UINT16 Buffer16; + BOOLEAN RtcUipIsAlwaysSet; + + // + // PCH BIOS Specification 0.6.0 - Section 19.2, "Power Failure Consideration" + // + // When the RTC_PWR_STS bit is set, it indicates that the RTCRST# signal went low. + // Software should clear this bit. For example, changing the RTC battery sets this bit. + // System BIOS should reset CMOS to default values if the RTC_PWR_STS is set. + // + // The System BIOS should execute the sequence below if the RTC_PWR_STS bit is set before memory initialization. + // This will ensure that the RTC state machine has been initialized. + // 1. If the RTC_PWR_STS bit is set, which indicates a new coin-cell batttery + // insertion or a battery failure, steps 2 through 5 should be executed. + // 2. Set RTC Register 0Ah[6:4] to '110b' or '111b'. + // 3. Set RTC Register 0Bh[7]. + // 4. Set RTC Register 0Ah[6:4] to '010b'. + // 5. Clear RTC Register 0Bh[7]. + Buffer16 = READ_PCI16_SB(R_PCH_LPC_GEN_PMCON_3); // 0xA4 + RtcUipIsAlwaysSet = IsRtcUipAlwaysSet(PeiServices); + if ((Buffer16 & B_PCH_LPC_GEN_PMCON_RTC_PWR_STS) || RtcUipIsAlwaysSet) { + + // + // Step 1. + // BIOS clears this bit by writing a '0' to it. + // + if (Buffer16 & B_PCH_LPC_GEN_PMCON_RTC_PWR_STS) { + Buffer16 &= ~B_PCH_LPC_GEN_PMCON_RTC_PWR_STS; + WRITE_PCI16_SB(R_PCH_LPC_GEN_PMCON_3, Buffer16); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_DAY_OF_MONTH_REG), 0xFF); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_HOURS_REG), 0xFF); + } + + // + // Step 2. + // Set RTC Register 0Ah[6:4] to '110' or '111'. + // + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_A_INDEX), 0x66); + + // + // Step 3. + // Set RTC Register 0Bh[7]. + // + Buffer8 = (READ_IO8_RTC(RTC_NMI_MASK | RTC_REG_B_INDEX) | 0x80); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_B_INDEX), Buffer8); + + // + // Step 4. + // Set RTC Register 0Ah[6:4] to '010'. + // + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_A_INDEX), 0x26); + + // + // Step 5. + // Clear RTC Register 0Bh[7]. + // + Buffer8 = (READ_IO8_RTC(RTC_NMI_MASK | RTC_REG_B_INDEX) & ~0x80); + WRITE_IO8_RTC((RTC_NMI_MASK | RTC_REG_B_INDEX), Buffer8); + } + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitPMRegs +// +// Description: This function initializes SB Power Management registers. +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitPMRegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN SB_SETUP_DATA *SbSetupData) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_BOOT_MODE BootMode = 0; + PCH_SERIES PchSeries = GetPchSeries(); + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if (BootMode != BOOT_ON_S3_RESUME) { + WRITE_IO16_PM(ACPI_IOREG_PM1_EN, 0); + } + if (PchSeries == PchLp) { + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_EN+0x0c, 0); + } else { + WRITE_IO32_PM(ACPI_IOREG_GPE0_EN, 0); + WRITE_IO32_PM(ACPI_IOREG_GPE0_EN + 4, 0); + } + + // Clear Alternate GPI SMI Status Reg. + if (PchSeries == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_STS, 0xFFFFFFFF); + } else { + WRITE_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS, 0xFFFF); + } + +#if EHCI_CON_DISCON_WAKE_UP_SUPPORT + if (SbSetupData->EhciConDisConWakeUp) + RESET_MEM8_RCRB(RCRB_MMIO_RMHWKCTL , 0xFF); + else + SET_MEM8_RCRB(RCRB_MMIO_RMHWKCTL , (BIT00 | BIT01 | BIT04 | BIT05)); +#endif + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramRCRBMmio +// +// Description: This function initializes SB Root Complex registers +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ProgramRCRBMmio ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo ) +{ + PCH_SERIES PchSeries = GetPchSeries(); + + //Enable IOAPIC Decoding and FERR# + if(PchSeries == PchLp){ + SET_MEM16_RCRB(R_PCH_RCRB_OIC, B_PCH_RCRB_OIC_AEN); + } else { + SET_MEM16_RCRB(R_PCH_RCRB_OIC, (B_PCH_RCRB_OIC_AEN | (PCH_RCRB_OIC_CEN << 9))); + } + + // Enable No Reboot, Boot BIOS Destination + SET_MEM32_RCRB(R_PCH_RCRB_GCS, (BIT06 | B_PCH_RCRB_GCS_NR)); + + SET_MEM32_RCRB (R_PCH_RCRB_FD2, BIT00); //0x3428 + + // PIRQ routing Info + // Device 31 Interrupt Pin, reg#3100h + WRITE_MEM32_RCRB(R_PCH_RCRB_D31IP, (RCRB_IRQB << 8) + + (RCRB_IRQC << 12) + + (RCRB_IRQD << 16) + + (RCRB_IRQB << 20) + + (RCRB_IRQC << 24)); + + // Device 30 Interrupt Pin, reg#3104h - Read Only + + // Device 29 Interrupt Pin, reg#3108h + WRITE_MEM32_RCRB(R_PCH_RCRB_D29IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQD << 12) + + (RCRB_IRQA << 16)); + + // Device 28 Interrupt Pin, reg#310Ch + WRITE_MEM32_RCRB(R_PCH_RCRB_D28IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQD << 12) + + (RCRB_IRQA << 16) + + (RCRB_IRQB << 20) + + (RCRB_IRQC << 24) + + (RCRB_IRQD << 28)); + + // Device 27 Interrupt Pin, reg#3110h + WRITE_MEM32_RCRB(R_PCH_RCRB_D27IP, (RCRB_IRQA << 0)); + + // Device 26 Interrupt Pin, reg#3114h + WRITE_MEM32_RCRB(R_PCH_RCRB_D26IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQD << 12)); + + // Device 25 Interrupt Pin, reg#3118h + WRITE_MEM32_RCRB(R_PCH_RCRB_D25IP, (RCRB_IRQA << 0)); + + // Device 22 Interrupt Pin, reg#3124h + WRITE_MEM16_RCRB(R_PCH_RCRB_D22IP, (RCRB_IRQA << 0) + + (RCRB_IRQB << 4) + + (RCRB_IRQC << 8) + + (RCRB_IRQB << 12)); + + // Device 20 Interrupt Pin, reg#3128h + WRITE_MEM32_RCRB(R_PCH_RCRB_D20IP, (RCRB_IRQA << 0)); + + // Device 31 Interrupt Route, reg#3140h + WRITE_MEM16_RCRB(R_PCH_RCRB_D31IR, (RCRB_PIRQD << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQA << 12)); + + // Device 29 Interrupt Route, reg#3144h + WRITE_MEM16_RCRB(R_PCH_RCRB_D29IR, (RCRB_PIRQH << 0) + + (RCRB_PIRQD << 4) + + (RCRB_PIRQA << 8) + + (RCRB_PIRQC << 12)); + + // Device 28 Interrupt Route, reg#3146h + WRITE_MEM16_RCRB(R_PCH_RCRB_D28IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQB << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + // Device 27 Interrupt Route, reg#3148h + WRITE_MEM16_RCRB(R_PCH_RCRB_D27IR, (RCRB_PIRQG << 0) + + (RCRB_PIRQB << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + // Device 26 Interrupt Route, reg#314Ch + WRITE_MEM16_RCRB(R_PCH_RCRB_D26IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQF << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + // Device 25 Interrupt Route, reg#3150h + WRITE_MEM16_RCRB(R_PCH_RCRB_D25IR, (RCRB_PIRQE << 0) + + (RCRB_PIRQF << 4) + + (RCRB_PIRQG << 8) + + (RCRB_PIRQH << 12)); + + if (PchSeries == PchLp) { + // Device 23 Interrupt Route, reg#3158h + WRITE_MEM16_RCRB(R_PCH_RCRB_D23IR, (RCRB_PIRQG << 0)); + } + + // Device 22 Interrupt Route, reg#315Ch + WRITE_MEM16_RCRB(R_PCH_RCRB_D22IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQD << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQB << 12)); + + if (PchSeries == PchLp) { + // Device 21 Interrupt Route, reg#3164h + WRITE_MEM16_RCRB(R_PCH_RCRB_D21IR, (RCRB_PIRQE << 0) + + (RCRB_PIRQE << 4) + + (RCRB_PIRQF << 8) + + (RCRB_PIRQF << 12)); + } + + // Device 20 Interrupt Route, reg#3160h + WRITE_MEM16_RCRB(R_PCH_RCRB_D20IR, (RCRB_PIRQA << 0) + + (RCRB_PIRQB << 4) + + (RCRB_PIRQC << 8) + + (RCRB_PIRQD << 12)); + + if (PchSeries == PchLp) { + // Device 19 Interrupt Route, reg#3168h + WRITE_MEM16_RCRB(R_PCH_RCRB_D19IR, (RCRB_PIRQH << 0)); + } + + // EIP176923 + #if defined DISABLE_DAYLIGHT_SAVINGS && DISABLE_DAYLIGHT_SAVINGS == 1 + SET_MEM16_RCRB(R_PCH_RCRB_BUC, B_PCH_RCRB_BUC_SDO); + #endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBIoDecodeRegs +// +// Description: This function initializes SB IO Decide Registers. +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +ProgramSBIoDecodeRegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + +#if defined EMUL6064_SUPPORT && EMUL6064_SUPPORT == 1 + // Force KBC_LPC_EN bit (B0:D31:F0 Reg 82h[10]) = 1 if EMUL6064_SUPPORT = 1. + SbLib_SetLpcDeviceDecoding(NULL, 0x60, 0, dsPS2K); +#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramPchDeviceBase +// +// Description: This function initializes SB Devices Base +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +ProgramPchDeviceBase ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + + // Program RCBA Base + WRITE_PCI32_SB(SB_REG_RCBA, SB_RCRB_BASE_ADDRESS | 1);//0xF0 + + // Write Heci Base Address and enable Heci device + WRITE_PCI32_HECI(ME_REG_HECI_MBAR, HECI_BASE_ADDRESS); + WRITE_PCI16_HECI(ME_REG_PCICMD, 0x06); + + // Write Heci Base Address and enable Heci device + WRITE_PCI32_HECI2(ME_REG_HECI_MBAR, HECI2_BASE_ADDRESS); + WRITE_PCI16_HECI2(ME_REG_PCICMD, 0x06); + + // Program PM Base + WRITE_PCI16_SB(SB_REG_PMBASE, PM_BASE_ADDRESS); + WRITE_PCI8_SB(SB_REG_ACPI_CNTL, 0x80); + + // Program GPIO Base + WRITE_PCI16_SB(SB_REG_GPIOBASE, GPIO_BASE_ADDRESS); + WRITE_PCI8_SB(SB_REG_GC, 0x10); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GeneralPowerFailureHandler +// +// Description: When the PWR_FLR bit is set, it indicates the trickle power +// from the main battery or tricle supply failed while in suspend +// or since last boot. This bit us ub the RTC well and is cleared +// only by RTCRST#. Software writes a "1" to clear this bit. +// System BIUOS should follow cold boot path if PWR_FLR, GEN_RST_STS +// or PWRBTNOR_STS is set to 1 regardless of the value in the SLP_TYP +// field. +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +GeneralPowerFailureHandler ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + + UINT16 DataUint16; + UINT8 DataUint8; + + // + // PCH BIOS Specification 0.6.0 - Section 19.2, "Power Failure Considerations" + // + // When the PWR_FLR bit is set, it indicates the trickle power from the main + // battery or tricle supply failed while in suspend or since last boot. + // System BIOS should follow cold boot path if PWR_FLR, GEN_RST_STS or + // PWRBTNOR_STS is set to 1 regardless of the value in the SLP_TYP field. + // + DataUint16 = READ_PCI16_SB(R_PCH_LPC_GEN_PMCON_3); + if ((DataUint16 & (B_PCH_LPC_GEN_PMCON_GEN_RST_STS | B_PCH_LPC_GEN_PMCON_PWR_FLR)) || \ + (READ_IO16_PM(R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_PRBTNOR)) { + // + // BIOS clears these bits by writing a '1' to them. + // + WRITE_PCI16_SB(R_PCH_LPC_GEN_PMCON_3, DataUint16); + WRITE_IO16_PM(R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PRBTNOR); + + // + // Clear Wake Status (WAK_STS) and Sleep Type (SLP_TYP) + // + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, B_PCH_ACPI_PM1_STS_WAK); + DataUint16 = (READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & ~B_PCH_ACPI_PM1_CNT_SLP_TYP); + WRITE_IO16_PM(ACPI_IOREG_PM1_CNTL, DataUint16); + } + + // + // When the CPUPWR_FLR bit is set, it indicates VRMPWRGD signal from + // the CPU VRM went low. This bit is now set if VRMPWRGD goes low + // during Intel (R) SpeedStep Technology transition. + // Software must clear this bit if set. + // + DataUint8 = READ_PCI8_SB(R_PCH_LPC_GEN_PMCON_2); + if (DataUint8 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) { + // + // BIOS clears this bit by writing a '0' to it. + // + DataUint8 &= ~B_PCH_LPC_GEN_PMCON_SYSPWR_FLR; + WRITE_PCI8_SB(R_PCH_LPC_GEN_PMCON_2, DataUint8); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SetTheStateToGoAfterG3 +// +// Description: Set what state (S0/S5) to go to when power is re-applied +// after a power failure (G3 state) +// +// Input: PeiServices - Pointer to the PEI services table +// CpuIo - Pointer to the CPU I/O PPI +// PciCfg - Pointer to the PCI Configuration PPI +// SbSetupData - Pointer to the SbSetupData +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +SetTheStateToGoAfterG3 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_CPU_IO_PPI *CpuIo, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg, + IN SB_SETUP_DATA *SbSetupData +) +{ + UINT16 DataUint16; + // + // Make sure we have a setup data, if not, just return. + // + if (SbSetupData == NULL) { + return EFI_UNSUPPORTED; + } + + DataUint16 = READ_PCI16_SB(R_PCH_LPC_GEN_PMCON_3); + if(SbSetupData->LastState == 0) { + DataUint16 |= B_PCH_LPC_GEN_PMCON_AFTERG3_EN; + } else { + DataUint16 &= ~B_PCH_LPC_GEN_PMCON_AFTERG3_EN; + } + +// Done in PchMisc.c +//#### DataUint16 |= (SbSetupData->SlpS4AssW << 4); + + WRITE_PCI16_SB(R_PCH_LPC_GEN_PMCON_3, DataUint16); + + return EFI_SUCCESS; +} + +static UINT8 mSmbusRsvdAddresses[DIMM_SLOT_NUM] = { + DIMM1_SMBUS_ADDRESS, + DIMM2_SMBUS_ADDRESS, + DIMM3_SMBUS_ADDRESS, + DIMM4_SMBUS_ADDRESS +}; + +static PEI_SMBUS_POLICY_PPI mSmbusPolicyPpi = { + SMBUS_BASE_ADDRESS, + SMBUS_BUS_DEV_FUN, + DIMM_SLOT_NUM, + mSmbusRsvdAddresses +}; + +EFI_PEI_PPI_DESCRIPTOR SmbusPolicy_PpiDescriptor = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiSmbusPolicyPpiGuid, + &mSmbusPolicyPpi +}; + // [EIP106687]> +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbPcieDetectNonComplaintPcieDevice +// +// Description: +// +// Input: IN UINT8 Index, +// IN PCH_PCIE_CONFIG *PcieConfig +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID +SbPcieDetectNonComplaintPcieDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT8 Index, + IN PCH_PCIE_CONFIG *PcieConfig, + IN SB_SETUP_DATA *SbSetupData +) +{ + if ((PcieConfig->PcieSpeed[Index] == PchPcieAuto) && \ + (SbSetupData->PcieRootPortEn[Index]!= 0)) + { + PEI_TRACE((-1,PeiServices, "Enhance Detect Non-Compliance PCIE Device @B:0|D:1C|F:%x Start .\n", Index)); + // Assign temp bus + PEI_TRACE((-1,PeiServices, "Assign temp bus ...\n")); + WRITE_PCI16(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_BNUM+1, 0x0101); + // Do a dummy Write + WRITE_PCI32(1, 0, 0, PCI_VID, 0x12345678); + + if (READ_PCI16(1, 0, 0, PCI_VID) == 0xFFFF) { + PEI_TRACE((-1,PeiServices, "Can't find Device... Retrain device first.\n")); + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_LD); + CountTime((RETRAIN_DELAY * 10), PM_BASE_ADDRESS); //delay 500us + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_RL); + CountTime((RETRAIN_DELAY * 8000), PM_BASE_ADDRESS); //delay 400ms + if (READ_PCI16(1, 0, 0, PCI_VID) == 0xFFFF) { + PEI_TRACE((-1,PeiServices, "Still can't find Device in Gen2 Speed... Speed is setted in Gen1 and delay 200 ms.\n")); + // Set Speed to Gen1 + RW_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL2, 0x01, 0x03); + CountTime((RETRAIN_DELAY * 4000), PM_BASE_ADDRESS); //delay 200ms + + if (READ_PCI16(1, 0, 0, PCI_VID) == 0xFFFF) { + PEI_TRACE((-1,PeiServices, "Still can't find Device in Gen1 Speed... Retrain device again !!!\n")); + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_LD); + CountTime((RETRAIN_DELAY * 10), PM_BASE_ADDRESS); //delay 500us + WRITE_PCI8(PCIEBRS_BUS, PCIEBRS_DEV, Index, R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_RL); + CountTime((RETRAIN_DELAY * 8000), PM_BASE_ADDRESS); //delay 400ms + + if (READ_PCI16(1, 0, 0, PCI_VID) != 0xFFFF) PcieConfig->PcieSpeed[Index] = PchPcieGen1; + } + else PcieConfig->PcieSpeed[Index] = PchPcieGen1; + } + } + + // Remove temp bus + PEI_TRACE((-1,PeiServices, "Remove temp bus.\n")); + WRITE_PCI32(PCIEBRS_BUS, PCIEBRS_DEV, Index, PCI_PBUS, 0xFF000000); + + PEI_TRACE((-1,PeiServices, "Enhance Detect Non-Compliance PCIE Device end.\n")); + } +} + // <[EIP106687] +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InstallPchPlatformPolicyPpi +// +// Description: Install Pch Platform Policy Ppi +// +// Input: IN EFI_PEI_SERVICES **PeiServices, +// IN SB_SETUP_DATA *SbSetupData +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +InstallPchPlatformPolicyPpi ( + IN EFI_PEI_SERVICES **PeiServices, + IN SB_SETUP_DATA *SbSetupData +) +{ + + UINT8 *SbRcba = (UINT8*)(UINTN)SB_RCRB_BASE_ADDRESS; + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PchPlatformPolicyPpiDesc; + PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi; + PCH_THERMAL_MANAGEMENT *ThermalMgmt; + PCH_MEMORY_THROTTLING *MemoryThrottling; + PCH_HPET_CONFIG *HpetConfig; + PCH_IOAPIC_CONFIG *IoApicConfig; + PCH_SATA_CONTROL *SataConfig; + PCH_SATA_TRACE_CONFIG *SataTraceConfig; + PCH_GBE_CONFIG *GbeConfig; + PCH_PCIE_CONFIG *PcieConfig; + PCH_USB_CONFIG *UsbConfig; + EFI_BOOT_MODE BootMode; + UINT8 Index; + PCH_PLATFORM_DATA *PlatformData; + UINT16 LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID); + UINT16 Data16; + UINT8 PortIndex; + UINT16 UsbPortLength[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_PORTS_LENGTH}; + UINT8 UsbPortLocation[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_PORT_LOCATION_CONFIG}; + UINT8 UsbOverCurrentMapping[LPTH_USB_MAX_PHYSICAL_PORTS] = {USB_OVER_CURRENT_MAPPING_SETTINGS}; + UINT8 Usb30OverCurrentMapping[LPTH_XHCI_MAX_USB3_PORTS] = {USB30_OVER_CURRENT_MAPPING_SETTINGS}; + PCH_SERIES PchSeries = GetPchSeries(); + SATA_LENGTH_CONFIG SataLengthConfigTable[] = {SATA_PORT1_LENGTH_CONFIG, + SATA_PORT2_LENGTH_CONFIG, + SATA_PORT3_LENGTH_CONFIG, + SATA_PORT4_LENGTH_CONFIG, + SATA_PORT5_LENGTH_CONFIG, + SATA_PORT6_LENGTH_CONFIG}; +#if defined iME_SUPPORT && iME_SUPPORT + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + UINTN VariableSize; + ME_BIOS_EXTENSION_SETUP MeBiosExtensionSetupData; + EFI_GUID EfiMeBiosExtensionSetupGuid = EFI_ME_BIOS_EXTENSION_SETUP_GUID; + CHAR16 EfiMeBiosExtensionSetupName[] = EFI_ME_BIOS_EXTENSION_SETUP_VARIABLE_NAME; +#endif + + BootMode = BOOT_WITH_FULL_CONFIGURATION; + + // Install SmbusPolicy PPI + Status = (**PeiServices).InstallPpi (PeiServices, &SmbusPolicy_PpiDescriptor); + ASSERT_PEI_ERROR (PeiServices, Status); + + // Allocate descriptor and PPI structures. Since these are dynamically updated + // we cannot do a global variable PPI. + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), &PchPlatformPolicyPpiDesc); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PchPlatformPolicyPpiDesc, sizeof (EFI_PEI_PPI_DESCRIPTOR), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_POLICY_PPI), &PchPlatformPolicyPpi); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PchPlatformPolicyPpi, sizeof (PCH_PLATFORM_POLICY_PPI), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_HPET_CONFIG), &HpetConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) HpetConfig, sizeof (PCH_HPET_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_THERMAL_MANAGEMENT), &ThermalMgmt); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) ThermalMgmt, sizeof (PCH_THERMAL_MANAGEMENT), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_IOAPIC_CONFIG), &IoApicConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) IoApicConfig, sizeof (PCH_IOAPIC_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_MEMORY_THROTTLING), &MemoryThrottling); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) MemoryThrottling, sizeof (PCH_MEMORY_THROTTLING), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_SATA_CONTROL), &SataConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) SataConfig, sizeof (PCH_SATA_CONTROL), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_SATA_TRACE_CONFIG), &SataTraceConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) SataTraceConfig, sizeof (PCH_SATA_TRACE_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_GBE_CONFIG), &GbeConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) GbeConfig, sizeof (PCH_GBE_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PCIE_CONFIG), &PcieConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PcieConfig, sizeof (PCH_PCIE_CONFIG), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_DATA), &PlatformData); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) PlatformData, sizeof (PCH_PLATFORM_DATA), 0); + + Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_CONFIG), &UsbConfig); + ASSERT_PEI_ERROR (PeiServices, Status); + (*PeiServices)->SetMem ((VOID*) UsbConfig, sizeof (PCH_USB_CONFIG), 0); + + PchPlatformPolicyPpi->Revision = PCH_PLATFORM_POLICY_PPI_REVISION_4; + PchPlatformPolicyPpi->BusNumber = 0; + PchPlatformPolicyPpi->Rcba = SB_RCRB_BASE_ADDRESS; + PchPlatformPolicyPpi->PmBase = PM_BASE_ADDRESS; + PchPlatformPolicyPpi->GpioBase = GPIO_BASE_ADDRESS; + PchPlatformPolicyPpi->Port80Route = RESERVED_PAGE_ROUTE; + + PchPlatformPolicyPpi->GbeConfig = GbeConfig; + PchPlatformPolicyPpi->ThermalMgmt = ThermalMgmt; + PchPlatformPolicyPpi->HpetConfig = HpetConfig; + PchPlatformPolicyPpi->SataConfig = SataConfig; + PchPlatformPolicyPpi->PcieConfig = PcieConfig; + PchPlatformPolicyPpi->IoApicConfig = IoApicConfig; + PchPlatformPolicyPpi->PlatformData = PlatformData; + PchPlatformPolicyPpi->UsbConfig = UsbConfig; + +//- ThermalMgmt->ThermalBaseB = SB_THERMAL_BASE_ADDRESS; + ThermalMgmt->MemoryThrottling = MemoryThrottling; + + GbeConfig->EnableGbe = 1; +//- GbeConfig->GbeMemBaseAddr = 0xFFFF8000; //PCH_LAN_MBARB_BASE_ADDRESS; + + for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) + PcieConfig->PcieSpeed[Index] = PchPcieAuto; + + HpetConfig->Enable = PCH_DEVICE_ENABLE; + HpetConfig->Base = HPET_BASE_ADDRESS; + + + IoApicConfig->IoApicId = PCH_IO_APIC_ID; + IoApicConfig->ApicRangeSelect = PCH_APIC_RANGE_SELECT; + IoApicConfig->IoApicEntry24_39 = PCH_DEVICE_ENABLE; + + if(SbSetupData != NULL) { + GbeConfig->EnableGbe = SbSetupData->PchLan; + + if ((READ_MEM16_RCRB(R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) { + RESET_MEM32_RCRB(R_PCH_SPI_FDOC, (UINT32) (B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)); + SET_MEM32_RCRB(R_PCH_SPI_FDOC, (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP9)); + if ((READ_MEM32_RCRB (R_PCH_SPI_FDOD) & B_PCH_SPI_STRP9_GBE_PCIE_EN) == 0) { + GbeConfig->EnableGbe = PCH_DEVICE_DISABLE; + } + } + + PchPlatformPolicyPpi->Port80Route = SbSetupData->Port80Route; // 0 - Forward to LPC. 1 - Forward to PCI. + SataConfig->SataMode = SbSetupData->SataInterfaceMode; + SataConfig->SataTraceConfig = SataTraceConfig; +// HpetConfig->Enable = SbSetupData->Hpet; // Force HPET enabled for MRC initialization. + // [EIP106687]> + for (Index = 0; Index < GetPchMaxPciePortNum (); Index++){ + PcieConfig->PcieSpeed[Index] = SbSetupData->PcieRootPortSpeed[Index]; + + //Enhance Detect Non-Compliance PCIE Device + if ((SbSetupData->PcieRPDetectNonComplaint[Index] == 1) && (SbSetupData->PcieRootPortEn[0]!= 0)) + SbPcieDetectNonComplaintPcieDevice(PeiServices, Index, PcieConfig, SbSetupData); + } + // <[EIP106687] + //In case of recovery change the SATA mode to IDE + (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if(BootMode == BOOT_IN_RECOVERY_MODE) { + SataConfig->SataMode = PchSataModeIde; + } + + SataTraceConfig->TestMode = PCH_DEVICE_DISABLE; + PEI_TRACE((-1,PeiServices, "SBPei SATA RxEq Policy setting:\n")); + for( PortIndex = 0; PortIndex < GetPchMaxSataPortNum(); PortIndex++ ) { + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[0].Enable = SataLengthConfigTable[PortIndex].SataGen1RxEqEnable; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[1].Enable = SataLengthConfigTable[PortIndex].SataGen2RxEqEnable; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[2].Enable = SataLengthConfigTable[PortIndex].SataGen3RxEqEnable; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[0].RxEq = SataLengthConfigTable[PortIndex].SataGen1RxEqValue; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[1].RxEq = SataLengthConfigTable[PortIndex].SataGen2RxEqValue; + SataTraceConfig->PortRxEq[PortIndex].GenSpeed[2].RxEq = SataLengthConfigTable[PortIndex].SataGen3RxEqValue; + PEI_TRACE((-1,PeiServices, "SATA Port%x: %x %x %x %x %x %x\n", PortIndex,\ + SataLengthConfigTable[PortIndex].SataGen1RxEqEnable, SataLengthConfigTable[PortIndex].SataGen1RxEqValue,\ + SataLengthConfigTable[PortIndex].SataGen2RxEqEnable, SataLengthConfigTable[PortIndex].SataGen2RxEqValue,\ + SataLengthConfigTable[PortIndex].SataGen3RxEqEnable, SataLengthConfigTable[PortIndex].SataGen3RxEqValue)); + } + // + // Thermal configuration - Initialize policy to SETUP values. + // +#if defined iME_SUPPORT && iME_SUPPORT + MemoryThrottling->Enable = SbSetupData->TrEnabled; +#else + MemoryThrottling->Enable = PCH_DEVICE_DISABLE; +#endif + MemoryThrottling->TsGpioPinSetting[TsGpioC].PmsyncEnable = TSGPIO_C_PMSYN; + MemoryThrottling->TsGpioPinSetting[TsGpioD].PmsyncEnable = TSGPIO_D_PMSYN; + MemoryThrottling->TsGpioPinSetting[TsGpioC].C0TransmitEnable = TSGPIO_C_C0_TRANSMIT; + MemoryThrottling->TsGpioPinSetting[TsGpioD].C0TransmitEnable = TSGPIO_D_C0_TRANSMIT; + MemoryThrottling->TsGpioPinSetting[TsGpioC].PinSelection = TSGPIO_C_PIN_SEL; + MemoryThrottling->TsGpioPinSetting[TsGpioD].PinSelection = TSGPIO_D_PIN_SEL; + /// + /// UsbConfig should be initialized based on platform configuration if UsbPrecondition feature is + /// enabled. Otherwise, the remaining data of UsbConfig can stay in zero. + /// + UsbConfig->UsbPrecondition = SbSetupData->UsbPrecondition; +#ifdef RAPID_START_FLAG + if (RapidStartResumeCheck () == TRUE) { + /// + /// This is RapidStart resume, skip the UsbPrecondition feature in PEI phase + /// + UsbConfig->UsbPrecondition = 0; + } +#endif + +#ifdef USB_PRECONDITION_ENABLE_FLAG + /// + /// Update Precondition option for S4 resume. + /// Skip Precondition for S4 resume in case this boot may not connect BIOS USB driver. + /// If BIOS USB driver will be connected always for S4, then disable below update. + /// To keep consistency during boot, must enabled or disabled below function in both PEI and DXE + /// PlatformPolicyInit driver. + /// + if (UsbConfig->UsbPrecondition == TRUE) { + (*PeiServices)->GetBootMode (PeiServices, &BootMode); + if ((BootMode == BOOT_ON_S4_RESUME) || (BootMode == BOOT_IN_RECOVERY_MODE)){ + UsbConfig->UsbPrecondition = FALSE; + PEI_TRACE((-1,PeiServices, "BootMode is BOOT_ON_S4_RESUME or BOOT_IN_RECOVERY_MODE, disable Precondition")); + } + } +#endif // USB_PRECONDITION_ENABLE_FLAG + + if (UsbConfig->UsbPrecondition) { +#if defined iAMT_SUPPORT && iAMT_SUPPORT + UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE; + UsbConfig->Ehci2Usbr = PCH_DEVICE_DISABLE; +#else + UsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE; + UsbConfig->Ehci2Usbr = PCH_DEVICE_DISABLE; +#endif + +#if defined iME_SUPPORT && iME_SUPPORT + Status = (*PeiServices)->LocatePpi( PeiServices, + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + &ReadOnlyVariable ); + if (ReadOnlyVariable != NULL) { + VariableSize = sizeof (MeBiosExtensionSetupData); + Status = ReadOnlyVariable->GetVariable( ReadOnlyVariable, + EfiMeBiosExtensionSetupName, + &EfiMeBiosExtensionSetupGuid, + NULL, + &VariableSize, + &MeBiosExtensionSetupData ); + if (!EFI_ERROR (Status)) { + UsbConfig->Ehci1Usbr |= (MeBiosExtensionSetupData.KvmEnable & KVM_ENABLE); + UsbConfig->Ehci2Usbr |= (MeBiosExtensionSetupData.KvmEnable & KVM_ENABLE); + } + } +#endif + + UsbConfig->Usb20Settings[0].Enable = SbSetupData->PchUsb20[0]; + if (PchSeries == PchLp) { + // [ EIP219399 ] + //UsbOverCurrentMapping[LPTH_USB_MAX_PHYSICAL_PORTS]=ULT_USB_OVER_CURRENT_MAPPING_SETTINGS; + UINT8 UltUsbOverCurrentMapping[LPTH_USB_MAX_PHYSICAL_PORTS] = {ULT_USB_OVER_CURRENT_MAPPING_SETTINGS}; + (*PeiServices)->CopyMem(UsbOverCurrentMapping, UltUsbOverCurrentMapping, LPTH_USB_MAX_PHYSICAL_PORTS); + + UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_DISABLE; + } else { + UsbConfig->Usb20Settings[1].Enable = SbSetupData->PchUsb20[1]; + } + + if ((UsbConfig->Usb20Settings[0].Enable == PCH_DEVICE_DISABLE) && + (UsbConfig->Usb20Settings[1].Enable == PCH_DEVICE_DISABLE)) { + UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_ENABLE; + if (PchSeries == PchLp) { + UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_ENABLE; + } + } + + UsbConfig->UsbPerPortCtl = SbSetupData->PchUsbPerPortCtl; + + for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) { + if (SbSetupData->PchUsbPerPortCtl != PCH_DEVICE_DISABLE) { + UsbConfig->PortSettings[PortIndex].Enable = SbSetupData->PchUsbPort[PortIndex]; + } else { + UsbConfig->PortSettings[PortIndex].Enable = PCH_DEVICE_ENABLE; + } + + UsbConfig->Usb20OverCurrentPins[PortIndex] = UsbOverCurrentMapping[PortIndex]; + UsbConfig->PortSettings[PortIndex].Usb20PortLength = UsbPortLength[PortIndex]; + UsbConfig->PortSettings[PortIndex].Location = UsbPortLocation[PortIndex]; + + if (PchSeries == PchH) { + if (IS_PCH_LPT_LPC_DEVICE_ID_DESKTOP (LpcDeviceId)) { + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; //Back Panel + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 3; //Front Panel + } + + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x80) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 7.9" + } else if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x130) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 8"-12.9" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 4; //Back Panel, 13" onward + } + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Front Panel + } + } else if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock + } else { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward + } + } + + if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward + } + } else { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward + } + } + } + } else if (PchSeries == PchLp) { + if ((UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) || + (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward + } + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology + } + + if ((UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) || + (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward + } + } else if (UsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) { + if (UsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5" + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward + } + } else { + UsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology + } + } + } + + UsbConfig->Usb30Settings.Mode = SbSetupData->PchUsb30Mode; + + // + // Automatically disable EHCI when XHCI Mode is Enabled to save power. + // + if (UsbConfig->Usb30Settings.Mode == 1) { + UsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_DISABLE; + if (PchSeries == PchH) { + UsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_DISABLE; + } + } + + if (SbSetupData->PchUsb30Mode == 3) { + UsbConfig->Usb30Settings.PreBootSupport = 1; + } else { + UsbConfig->Usb30Settings.PreBootSupport = SbSetupData->PchUsb30PreBootSupport; + } + + if (SbSetupData->PchUsb30Mode == 4) { + UsbConfig->Usb30Settings.Mode = 2; + UsbConfig->Usb30Settings.ManualMode = PCH_DEVICE_ENABLE; + } else { + UsbConfig->Usb30Settings.ManualMode = PCH_DEVICE_DISABLE; + } + + // + // XhciIdleL1 can be set to disable for LPT-LP Ax stepping to workaround USB3 hot plug will fail after 1 hot plug removal. + // + UsbConfig->Usb30Settings.XhciIdleL1 = SbSetupData->PchUsb30IdleL1; + + // + // Btcg is for enabling/disabling trunk clock gating. + // + UsbConfig->Usb30Settings.Btcg = SbSetupData->PchUsb30Btcg; + + for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) { + if (SbSetupData->PchUsb20PinRoute == 1){ + UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = 0; + } else if (SbSetupData->PchUsb20PinRoute == 2){ + UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = 1; + } else { + UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = SbSetupData->ManualModeUsb20PerPinRoute[PortIndex]; + } + } + + for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) { + if (SbSetupData->PchUsb30PinEnable == 1){ + UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = 0; + } else if (SbSetupData->PchUsb30PinEnable == 2){ + UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = 1; + } else { + UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = SbSetupData->ManualModeUsb30PerPinEnable[PortIndex]; + } + UsbConfig->Usb30OverCurrentPins[PortIndex] = Usb30OverCurrentMapping[PortIndex]; + } + } // if (UsbConfig->UsbPrecondition) + + if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + // Save R_PCH_LPC_ENABLES in Data16. + Data16 = READ_PCI16_SB(R_PCH_LPC_ENABLES); + + if (!(Data16 & B_PCH_LPC_ENABLES_MC_EN)) + SET_PCI16_SB(R_PCH_LPC_ENABLES, B_PCH_LPC_ENABLES_MC_EN); + + if (READ_IO8(0x66) != 0xFF) PlatformData->EcPresent = 1; + + // Restore R_PCH_LPC_ENABLES. + WRITE_PCI16_SB(R_PCH_LPC_ENABLES, Data16); + } + + } // (SbSetupData != NULL) + + /// + /// PlatformData->SmmBwp value directly depends on the value of CpuConfig->Pfat + /// (found in CpuPolicyInitPei.c file) + /// If CpuConfig->Pfat is set to 1 (enabled) then + /// PlatformData->SmmBwp has to be set to 1 (enabled) + /// This is a PFAT Security requirement that needs to be addressed + /// If CpuConfig->Pfat is set to 0 (disabled) then + /// PlatformData->SmmBwp value don't care, it can be set to either + /// 1 (enabled) or 0 (disabled) based on customer implementation + /// + PlatformData->SmmBwp = 0; + + /// + /// Temporary Memory Base Address for PCI devices to be used to initialize MMIO registers. + /// Minimum size is 64KB bytes. + /// + PlatformData->TempMemBaseAddr = SB_TEMP_MMIO_BASE; + + PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi; + + // + // Install OEM PCH Platform Policy Override PPI + // + PchPlatformPolicyPpiDesc->Guid = &gOemPchPlatformPolicyOverridePpiGuid; + Status = (**PeiServices).InstallPpi (PeiServices, PchPlatformPolicyPpiDesc); + ASSERT_PEI_ERROR (PeiServices, Status); + + // + // Install PCH Platform Policy PPI + // + PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid; + Status = (**PeiServices).InstallPpi (PeiServices, PchPlatformPolicyPpiDesc); + ASSERT_PEI_ERROR (PeiServices, Status); + + // [EIP120438]> + if ((HpetConfig->Enable) && (HpetConfig->Base != 0)) { + WRITE_MEM32(HpetConfig->Base + 0xF0, 0); + } + // <[EIP120438] + + return EFI_SUCCESS; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegAfterMrc +// +// Description: This function can be used to program any SB regisater after +// memory is detected. +// +// Input: PeiServices - Pointer to the PEI services table +// NotifyDescriptor - Pointer to the descriptor for the +// notification event. +// InvokePpi - Pointer to the PPI that was installed +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegAfterMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + EFI_STATUS Status = EFI_SUCCESS; + IN EFI_BOOT_MODE BootMode; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable; + UINTN VariableSize; + EFI_GUID WarmResetGuid = SB_WARM_RESET_GUID; + CHAR16 WarmResetVar[] = SB_WARM_RESET_VARIABLE; + UINT32 WarmResetFlag = 0; +#if Capsule2_0_SUPPORT + PEI_CAPSULE_PPI *Capsule; +#endif + + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): Start.\n")); + + Status = (*PeiServices)->GetBootMode( PeiServices, &BootMode ); + + if (BootMode == BOOT_ON_S3_RESUME) { + + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): S3 Resume.\n")); + + Status = (*PeiServices)->LocatePpi( PeiServices, \ + &gEfiPeiReadOnlyVariable2PpiGuid, \ + 0, \ + NULL, \ + &ReadOnlyVariable ); + if (!EFI_ERROR(Status)) { + VariableSize = sizeof(WarmResetFlag); + Status = ReadOnlyVariable->GetVariable( ReadOnlyVariable, \ + WarmResetVar, \ + &WarmResetGuid, \ + NULL, \ + &VariableSize, \ + &WarmResetFlag ); + if (WarmResetFlag == SB_WARM_RESET_TAG) { + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): Update BootMode.\n")); + BootMode = BOOT_WITH_FULL_CONFIGURATION; + +#if Capsule2_0_SUPPORT + // + // Update BootMode, if Capsule 2.0 PPI is available. + // + Status = (*PeiServices)->LocatePpi ( PeiServices, \ + &gPeiCapsulePpiGuid, \ + 0, \ + NULL, \ + &Capsule); + + if (!EFI_ERROR(Status)) { + BootMode = BOOT_ON_FLASH_UPDATE; + Status = (*PeiServices)->NotifyPpi( PeiServices, EndOfMrcNotifyList ); + + } else { + // Clear ACPI Sleep Type + RESET_IO32_PM(ACPI_IOREG_PM1_CNTL, 0x1c00 ); // 0x04 + } + + (*PeiServices)->SetBootMode(PeiServices, BootMode); +#else + (*PeiServices)->SetBootMode(PeiServices, BootMode); + // Clear ACPI Sleep Type + RESET_IO32_PM(ACPI_IOREG_PM1_CNTL, 0x1c00 ); // 0x04 +#endif + } + } + } + + PEI_TRACE((-1,PeiServices, "ProgramSBRegAfterMrc(): End.\n")); + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramSBRegEndOfMrc +// +// Description: This function can be used to program any SB regisater at +// end of MRC. +// +// Input: PeiServices - Pointer to the PEI services table +// NotifyDescriptor - Pointer to the descriptor for the +// notification event. +// InvokePpi - Pointer to the PPI that was installed +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ProgramSBRegEndOfMrc ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *InvokePpi ) +{ + IN EFI_BOOT_MODE BootMode; + EFI_STATUS Status; + VOID *RecoveryModePpi; + + PEI_TRACE((-1,PeiServices, "ProgramSBRegEndOfMrc(): Start.\n")); + + Status = (*PeiServices)->LocatePpi (PeiServices, \ + &gRecoveryBootModeGuid, \ + 0, \ + NULL, \ + &RecoveryModePpi); + + if (EFI_ERROR(Status)) { + // Update Bootmode + (*PeiServices)->GetBootMode( PeiServices, &BootMode ); + PEI_TRACE((-1,PeiServices, "Before change BootMode = %X\n", BootMode)); + BootMode = BOOT_WITH_FULL_CONFIGURATION; + (*PeiServices)->SetBootMode(PeiServices, BootMode); + } + PEI_TRACE((-1,PeiServices, "ProgramSBRegEndOfMrc(): End.\n")); + + return EFI_SUCCESS; +} + +#if SB_RESET_PPI_SUPPORT + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBPEI_ResetSystem +// +// Description: This function is the reset call interface function published +// by the reset PPI +// +// Input: PeiServices Pointer to the PEI services table +// +// Output: SYSTEM RESET +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBPEI_ResetSystem ( + IN EFI_PEI_SERVICES **PeiServices ) +{ +#if WdtPei_SUPPORT + WDT_PPI *Wdt; + EFI_STATUS Status; + + Status = (*PeiServices)->LocatePpi ( PeiServices, \ + &gWdtPpiGuid, \ + 0, \ + NULL, \ + &Wdt ); + + ASSERT_PEI_ERROR (PeiServices, Status); + + Wdt->AllowKnownReset(); +#endif + + SBLib_ResetSystem(EfiResetCold); + + // We should never get this far + return EFI_SUCCESS; +} + +#endif + +#if SB_STALL_PPI_SUPPORT + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBPEI_Stall +// +// Description: This function provides a blocking stall at least number +// of microseconds by SB ACPI timer +// +// Input: PeiServices - Pointer to the PEI services table +// This - Pointer to the Stall PPI +// MicroSeconds - Number of microseconds for which to stall +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBPEI_Stall ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_STALL_PPI *This, + IN UINTN MicroSeconds ) +{ + EFI_STATUS Status; + EFI_PEI_PCI_CFG2_PPI *PciCfg; + + // Locate PciCfg PPI + PciCfg = (*PeiServices)->PciCfg; + + // At this time no manipulation needed. The value passed in is in + // MicroSeconds(us) and that is what the library function uses + + // Call Library function that is shared with Metronome + // Architecture Protocol + + + Status = CountTime(MicroSeconds, PM_BASE_ADDRESS); + + return Status; +} + +#endif + +#if ATAPI_RECOVERY_SUPPORT + +EFI_GUID gIdeRecoveryNativeModePpiGuid = \ + PEI_IDE_RECOVERY_NATIVE_MODE_PPI_GUID; + +PEI_IDE_RECOVERY_NATIVE_MODE_PPI IdeRecoveryNativeModePpi = { + SB_TEMP_IO_BASE+0x200, + SB_TEMP_IO_BASE+0x282, + SB_TEMP_IO_BASE+0x300, + SB_TEMP_IO_BASE+0x382 +}; + +EFI_PEI_PPI_DESCRIPTOR IdeRecoveryNativeModePpiDescriptor = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), \ + &gIdeRecoveryNativeModePpiGuid, &IdeRecoveryNativeModePpi +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSATARegs +// +// Description: This function initializes SATA controller registers +// for ATA/ATAPI recovery support. +// +// Input: PeiServices - Pointer to the PEI services table +// PciCfg - Pointer to the PCI Configuration PPI +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitSATARegs ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_PCI_CFG2_PPI *PciCfg +) +{ + // TODO +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EnableAtaChannel +// +// Description: This function enables the specific channel of ATA/SATA +// controller(s) depend on input ChannelMask +// +// Input: PeiServices - Pointer to the PEI services table +// This - Pointer to the ATA Controller PPI +// ChannelMask - Mask for the specific channel. +// +// Output: EFI_STATUS +// +// Notes: Normally we have to enables all chennels on ATA/SATA +// controller(s) regardless of ChannelMask. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EnableAtaChannel ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_ATA_CONTROLLER_PPI *This, + IN UINT8 ChannelMask ) +{ + EFI_STATUS Status; + + // SATA 0 (B0:D31:F2) + // Initialize the controller to IDE mode + RW_PCI8_SATA(R_PCH_SATA_MAP, 0, B_PCH_SATA_MAP_SMS_MASK | B_PCH_SATA_PORT_TO_CONTROLLER_CFG); // [EIP86096]>> + + //Enable the SATA2 for setting IDE mode to recovery + RESET_MEM32_RCRB (R_PCH_RCRB_FUNC_DIS ,BIT25); // <<[EIP86096] + + // Initialize Primary/Secondary IDE controller to operate in Legacy mode + RW_PCI8_SATA(R_PCH_SATA_PI_REGISTER, 0, B_PCH_SATA_PI_REGISTER_PNE | B_PCH_SATA_PI_REGISTER_SNE); + + // Enable IO space decode + RW_PCI16_SATA(R_PCH_SATA_COMMAND, B_PCH_SATA_COMMAND_IOSE, 0); + + if ((ChannelMask & PEI_ICH_IDE_PRIMARY) == PEI_ICH_IDE_PRIMARY) + // Enable Primary IDE Controller decode + RW_PCI16_SATA(R_PCH_SATA_TIMP, B_PCH_SATA_TIM_IDE, 0); + + if ((ChannelMask & PEI_ICH_IDE_SECONDARY) == PEI_ICH_IDE_SECONDARY) + // Enable Secondary IDE Controller decode + RW_PCI16_SATA(R_PCH_SATA_TIMS, B_PCH_SATA_TIM_IDE, 0); + + // Enable SATA ports 0, 1, 2 and 3. + RW_PCI16_SATA(R_PCH_SATA_PCS, (B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN | B_PCH_SATA_PCS_PORT2_EN | B_PCH_SATA_PCS_PORT3_EN), 0); + + // SATA 1 (B0:D31:F5) + RW_PCI16_SATA2(R_PCH_SATA_PCMD_BAR, SB_TEMP_IO_BASE + 0x200, 0); + RW_PCI16_SATA2(R_PCH_SATA_PCNL_BAR, SB_TEMP_IO_BASE + 0x282, 0); + RW_PCI16_SATA2(R_PCH_SATA_SCMD_BAR, SB_TEMP_IO_BASE + 0x300, 0); + RW_PCI16_SATA2(R_PCH_SATA_SCNL_BAR, SB_TEMP_IO_BASE + 0x382, 0); + + // Enable IO space decode + RW_PCI16_SATA2(R_PCH_SATA_COMMAND, B_PCH_SATA_COMMAND_IOSE, 0); + + if ((ChannelMask & PEI_ICH_IDE_PRIMARY) == PEI_ICH_IDE_PRIMARY) + // Enable Primary IDE Controller decode + RW_PCI16_SATA2(R_PCH_SATA_TIMP, B_PCH_SATA_TIM_IDE, 0); + + if ((ChannelMask & PEI_ICH_IDE_SECONDARY) == PEI_ICH_IDE_SECONDARY) + // Enable Secondary IDE Controller decode + RW_PCI16_SATA2(R_PCH_SATA_TIMS, B_PCH_SATA_TIM_IDE, 0); + + // Enable SATA1 ports 0(4) and 1(5). + RW_PCI16_SATA2(R_PCH_SATA_PCS, (B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN), 0); + + // Delay 1ms for HDD devices ready. + CountTime(1000, PM_BASE_ADDRESS); + + Status = (**PeiServices).InstallPpi( PeiServices, \ + &IdeRecoveryNativeModePpiDescriptor); + if (EFI_ERROR (Status)) return Status; + + return EFI_SUCCESS; +} +#endif // ATAPI_RECOVERY_SUPPORT + + + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBRun.c b/Chipset/SB/SBRun.c new file mode 100644 index 0000000..a5f9430 --- /dev/null +++ b/Chipset/SB/SBRun.c @@ -0,0 +1,1144 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Chipset/SB/SBRun.c 1 4/19/16 7:42a Chienhsieh $ +// +// $Revision: 1 $ +// +// $Date: 4/19/16 7:42a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Chipset/SB/SBRun.c $ +// +// 1 4/19/16 7:42a Chienhsieh +// +// 5 7/17/13 1:54a Scottyang +// [TAG] EIP128233 +// [Category] Improvement +// [Description] Improving UEFI PXE image downloading proformance. +// [Files] RTC.h +// SBRun.c +// +// 4 3/19/13 8:24a Scottyang +// [TAG] EIP106509 +// [Category] Improvement +// [Description] 3. Improve the Intel UEFI GbE driver performance in +// IPv4 connection. +// [Files] SBRun.c +// +// 3 1/27/13 11:01p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Capsule 2.0 crash dump link function. +// [Files] SBPEI.c +// SBDxe.c +// SBRun.c +// +// 2 12/20/12 9:59p Scottyang +// [TAG] EIP77459 +// [Category] Improvement +// [Description] Update for Intel flash utility "FPT.efi" support. +// [Files] SBRun.c +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBRUN.C +// +// Description: This file contains code for general Southbridge runtime +// protocol +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Efi.h> +#include <Token.h> +#include <AmiLib.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include "RTC.h" + +// Produced Protocols +#include <Protocol\Metronome.h> +#include <Protocol\Reset.h> +#include <Protocol\RealTimeClock.h> +#include <Protocol\Timer.h> + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +EFI_STATUS WaitForTick ( + IN EFI_METRONOME_ARCH_PROTOCOL *This, + IN UINT32 TickNumber +); + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +EFI_HANDLE mResetProtocolHandle = NULL; +static BOOLEAN gTimeOut = FALSE; + // [EIP77459]> +UINT16 gTimeZone; +UINT8 gDaylight; + // <[EIP77459] + +EFI_RESET_SYSTEM gCallSavedIntelPointer; + +// This the number of days in a month - 1. (0 Based) +UINT8 DaysInMonth[] = { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }; + // (EIP128233)>> +#pragma pack(push, 1) +typedef struct { + INT16 TimeZone; + UINT8 Daylight; + } TIME_VARIABLE; +#pragma pack(pop) + +static TIME_VARIABLE CachedTimeVariable; +static BOOLEAN CachedTimeVariableValid = FALSE; + // <<(EIP128233) +// GUID Definition(s) + +EFI_GUID gEfiMetronomeArchProtocolGuid = EFI_METRONOME_ARCH_PROTOCOL_GUID; +EFI_GUID guidReset = EFI_RESET_ARCH_PROTOCOL_GUID; +EFI_GUID gEfiRtcArchProtocolGuid = EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID; +EFI_GUID gEfiTimeVariableGuid = EFI_TIME_VARIABLE_GUID; + +// Protocol Definition(s) + +EFI_METRONOME_ARCH_PROTOCOL mMetronomeProtocol = { + WaitForTick, + 1 +}; + +// External Declaration(s) + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiResetSystem +// +// Description: This function is the interface for the reset function. +// In the future, this may allow for a shared library for DXE +// and PEI. +// +// Input: ResetType - Type of reset to perform +// ResetStatus - System status that caused the reset. if part +// of normal operation then this should be +// EFI_SUCCESS, Otherwise it should reflect the +// state of the system that caused it +// DataSize - Size in bytes of the data to be logged +// *ResetData - Pointer to the data buffer that is to be +// logged +// +// Output: None, Even though it should never get that far +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN CHAR16 *ResetData OPTIONAL +) +{ + // Add logging messages here + // do a cold reset of the system + if (ResetType == EfiResetWarm) + { + SBLib_ResetSystem (ResetType); + } + else + { + if (gCallSavedIntelPointer == NULL) + SBLib_ResetSystem (ResetType); + + gCallSavedIntelPointer( ResetType, \ + ResetStatus, \ + DataSize, \ + ResetData ); + } + + // This should not get here + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WaitForTick +// +// Description: This function calculates the time needed to delay and then +// calls a library function to delay that amount of time +// +// Input: *This - Pointer to the instance of the Metronome Arch +// Protocol +// TickNumber - Number of ticks needed based off of tick period +// defined in Protocol Definiton +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WaitForTick ( + IN EFI_METRONOME_ARCH_PROTOCOL *This, + IN UINT32 TickNumber ) +{ + EFI_STATUS Status; + UINT32 TotalTime; + + // Manipulate TickNumber into a valid value for the library function call + // the Current Resolution is 10us. + // The Library uses Microseconds to count delayed time. + TotalTime = (TickNumber * This->TickPeriod) / 10; + + // Make Library Function call here + Status = CountTime( TotalTime, PM_BASE_ADDRESS ); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DecToBCD +// +// Description: This function converts data from DEC to BCD format +// +// Input: UINT8 Dec - Value to be converted +// +// Output: UINT8 - Result of conversion +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 DecToBCD ( + IN UINT8 Dec ) +{ + UINT8 FirstDigit = Dec % 10; + UINT8 SecondDigit = Dec / 10; + + // Only for 2 digit BCD. + return (SecondDigit << 4) + FirstDigit; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BCDToDec +// +// Description: This function converts data from BCD to DEC format +// +// Input: UINT8 Bcd - Value to be converted +// +// Output: UINT8 - Result of conversion +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 BCDToDec ( + IN UINT8 Bcd ) +{ + UINT8 FirstDigit = Bcd & 0xf; + UINT8 SecondDigit = Bcd >> 4;; + + // Only for 2 digit BCD. + return SecondDigit * 10 + FirstDigit; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReadRtcIndex +// +// Description: Read the RTC value at the given Index. +// +// Input: Index - RTC Index +// +// Output: RTC Value read from the provided Index +// +// Notes: Here is the control flow of this function: +// 1. Read port 0x70 (RTC Index Register) to get bit 7. +// Bit 7 is the NMI bit-it should not be changed. +// 2. Set Index with the NMI bit setting. +// 3. Output 0x70 with the Index and NMI bit setting. +// 4. Read 0x71 for Data. Getting Dec when appropriate. +// 5. Return the Data. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 ReadRtcIndex ( + IN UINT8 Index ) +{ + volatile UINT8 Value; + BOOLEAN IntState = CPULib_GetInterruptState(); + + CPULib_DisableInterrupt(); + + IoWrite8(CMOS_IO_INDEX_BACKDOOR, Index); + Value = IoRead8(CMOS_IO_DATA_BACKDOOR); // Read register. + + if (IntState) CPULib_EnableInterrupt(); + + if ((Index <= RTC_YEAR_REG) || (Index == ACPI_CENTURY_CMOS)) + Value = BCDToDec(Value); + + return (UINT8)Value; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteRtcIndex +// +// Description: Write the RTC value at the given Index. +// +// Input: Index - RTC Index +// Value - Value to write +// +// Output: None +// +// Notes: Here is the control flow of this function: +// 1. Read port 0x70 (RTC Index Register) to get bit 7. +// Bit 7 is the NMI bit-it should not be changed. +// 2. Set Index with the NMI bit setting. +// 3. Output 0x70 with the Index. Switch to BCD when needed. +// 4. Write the data to 0x71. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteRtcIndex ( + IN UINT8 Index, + IN UINT8 Value ) +{ + BOOLEAN IntState = CPULib_GetInterruptState(); + + if ((Index <= RTC_YEAR_REG) || (Index == ACPI_CENTURY_CMOS)) + Value = DecToBCD(Value); + + CPULib_DisableInterrupt(); + + IoWrite8(CMOS_IO_INDEX_BACKDOOR, Index); + IoWrite8(CMOS_IO_DATA_BACKDOOR, Value); // Write Register. + + if (IntState) CPULib_EnableInterrupt(); + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitRtc +// +// Description: This function initializes RTC +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID InitRtc (VOID) +{ + WriteRtcIndex(RTC_REG_B_INDEX, 0x82); + WriteRtcIndex(RTC_REG_A_INDEX, 0x26); + ReadRtcIndex(RTC_REG_C_INDEX); + ReadRtcIndex(RTC_REG_D_INDEX); + WriteRtcIndex(RTC_REG_B_INDEX, 0x02); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SetUpdate +// +// Description: Enables Disables RTC Date and Time update cicles. +// +// Input: Enable - TRUE or FALSE to Enable\Disabe RTC Update. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SetUpdate ( + IN BOOLEAN Enable ) +{ + RTC_REG_B RegB; + UINT8 Set = (Enable) ? 0 : 1; + + RegB.REG_B = ReadRtcIndex(RTC_REG_B_INDEX); + if (RegB.Set != Set) { + RegB.Set = Set; + WriteRtcIndex(RTC_REG_B_INDEX, RegB.REG_B); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckUpdateCmplete +// +// Description: Check if RTC Date and Time update in progress and waits till +// it's over. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID CheckUpdateCmplete (VOID) +{ + volatile RTC_REG_A RegA; + UINTN TimeOut = 0; + + RegA.REG_A = ReadRtcIndex(RTC_REG_A_INDEX); + while (RegA.UpdInProgr) { + RegA.REG_A = ReadRtcIndex(RTC_REG_A_INDEX); + TimeOut++; + if (TimeOut >= 0x0fffff) { + gTimeOut = TRUE; + return; + } + } + + gTimeOut = FALSE; +} + +BOOLEAN IsLeapYear ( + IN EFI_TIME *Time ) +{ + if (Time->Year % 4 == 0) { + if (Time->Year % 100 == 0) { + if (Time->Year % 400 == 0) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } + } else { + return FALSE; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: VerifyTime +// +// Description: This routine verifies if time and data if needed, before +// setting the RTC +// +// Input: *Time - Time to verify with +// +// Output: TRUE if valid time and date +// +// Notes: Here is the control flow of this function: +// 1. Decrease month and date to change to 0-base +// 2. Validate Year, Month and Day. If invalid, return FALSE. +// 3. Validate Hour, Minute and Second. If invalid, return FALSE. +// 4. Return True. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN VerifyTime ( + IN EFI_TIME *Time ) +{ + // Always check these to satisfy EFI compliancy test even for setting + // wake-up time. + UINT8 Month = Time->Month - 1; + UINT8 Day = Time->Day - 1; + + if ((Time->Year < EARLIEST_YEAR) || (Time->Year > 9999)) return FALSE; + if (Month > 11) return FALSE; // 0 based month + if ((Month != 1) || (!IsLeapYear(Time))) { // Not leap year or not February. + // All values already adjusted for 0 based. + if (Day > DaysInMonth[Month]) return FALSE; + } else { + if (Day > 28) return FALSE; // February + } + + if (Time->Hour > 23) return FALSE; + if (Time->Minute > 59) return FALSE; + if (Time->Second > 59) return FALSE; + + // Check these to satisfy EFI compliancy test. + if (Time->Nanosecond > 999999999) return FALSE; // 999,999,999 + if (Time->TimeZone < -1440) return FALSE; + if (Time->TimeZone > 1440 && Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) + return FALSE; + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetDayOfTheWeek +// +// Description: Returns an index that represents the day of the week of the +// date passed in +// +// Input: *Time - Pointer to EFI_TIME structure +// +// Output: Returns the index to the day of the week. 0 = Sunday, +// 1 = Monday ... 6 = Saturday +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT8 GetDayOfTheWeek ( + IN EFI_TIME *Time ) +{ + UINT16 a; + UINT16 m; + UINT16 d; + UINT16 y; + + a = (14 - Time->Month) / 12; + y = Time->Year - a; + m = Time->Month + 12 * a - 2; + d = (Time->Day + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12) % 7; + + return (UINT8)d; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckRtc +// +// Description: Check if RTC Mode and Format have appropriate values and sets +// them if necessary +// +// Input: Set - if true, force Rtc to 24 hour mode and binary format. +// +// Output: EFI_STATUS +// EFI_SUCCESS - RTC mode and format have appropriate values. +// EFI_DEVICE_ERROR - RTC mode and/or format are invalid. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS CheckRtc ( + IN BOOLEAN Set ) +{ + RTC_REG_B RegB; + + // Check RTC Conditions and stuff + RegB.REG_B = ReadRtcIndex(RTC_REG_B_INDEX); + if((RegB.Mode == 0) || (RegB.Format == 1)) { + if (Set) { + RegB.Mode = 1; // 1 - 24 hour mode + RegB.Format = 0; // 0 - BCD Format + WriteRtcIndex(RTC_REG_B_INDEX, RegB.REG_B); + } else { + return EFI_DEVICE_ERROR; + } + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiGetTime +// +// Description: Return the current date and time +// +// Input: *Time - Current time filled in EFI_TIME structure +// *Capabilities - Time capabilities (OPTIONAL) +// +// Output: EFI_SUCCESS +// EFI_INVALID_PARAMETER - A NULL Time. +// EFI_DEVICE_ERROR - RTC mode and/or format are invalid +// EFI_SUCCESS - Read the current date and time successfully. +// +// +// Notes: Here is the control flow of this function: +// 1. Read the original time format 12/24 hours and BCD/binary. +// 2. Set the format to 24 hrs and binary. +// 3. Read the 2 digit year. +// 4. Add either 1900 or 2000, so the year is between 1998 - 2097 +// 5. Read the month, day, hour, minute, second. +// 6. Set the nanosecond to 0. +// 7. Set the time to zone to unspecified. +// 8. Set daylight savings value to 0. +// 9. Restore the original time format. +// 10.Set Capabilities with 1 sec Resolution, 0 Accuracy +// (Unknown), and False SetsToZero. +// 11.Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL ) +{ + EFI_STATUS Status; + UINT8 Year; + BOOLEAN IntState; + BOOLEAN SmiState; + UINTN TimeVarSize = sizeof(TIME_VARIABLE); + UINT8 Buffer8; // [EIP77459] + + if (Time == NULL) return EFI_INVALID_PARAMETER; + + // Check RTC Conditions (24h Mode and BCD is ON) + Status = CheckRtc(FALSE); + if (EFI_ERROR(Status)) return Status; + + // Get SMI State and disable it + SmiState = SbLib_GetSmiState(); + SbLib_SmiDisable(); + // Get INTERRUPT State and disable it + IntState = CPULib_GetInterruptState(); + CPULib_DisableInterrupt(); + + // Wait till RTC is safe to read, + CheckUpdateCmplete(); + if (gTimeOut) InitRtc(); + + // After control comes back, we will have 488 u's to read data. + Year = ReadRtcIndex(RTC_YEAR_REG); + Time->Month = ReadRtcIndex(RTC_MONTH_REG); + Time->Day = ReadRtcIndex(RTC_DAY_OF_MONTH_REG); + Time->Hour = ReadRtcIndex(RTC_HOURS_REG); + Time->Minute = ReadRtcIndex(RTC_MINUTES_REG); + Time->Second = ReadRtcIndex(RTC_SECONDS_REG); + + // Restore SMIs and INTERRUPT State + if(IntState) CPULib_EnableInterrupt(); + if(SmiState) SbLib_SmiEnable(); + + // This Register is not affected by UIP bit so read it very last. + // If RTC Year only 1 digit, EFI spec says years rang is 1998 - 2097 + Time->Year = ReadRtcIndex(ACPI_CENTURY_CMOS) * 100 + Year; + + Time->Nanosecond= 0; + + // [EIP77459]> + // Save BIOSWE bit (B0:D31:F0 Reg#DCh[0]) + Buffer8 = READ_PCI8_SB(SB_REG_BIOS_CNTL); + // (EIP128233)>> + if(CachedTimeVariableValid && (Buffer8 & BIT00) != 0) { + Time->TimeZone = CachedTimeVariable.TimeZone; + Time->Daylight = CachedTimeVariable.Daylight; + } else { + Status = pRS->GetVariable( L"EfiTime", \ + &gEfiTimeVariableGuid, \ + NULL, \ + &TimeVarSize, \ + &CachedTimeVariable ); + if (EFI_ERROR(Status)) { + CachedTimeVariable.TimeZone = EFI_UNSPECIFIED_TIMEZONE; + CachedTimeVariable.Daylight = 0; + } + + Time->TimeZone = CachedTimeVariable.TimeZone; + Time->Daylight = CachedTimeVariable.Daylight; + CachedTimeVariableValid = TRUE; + } + + // Restore BIOSWE bit (B0:D31:F0 Reg#DCh[0]) + WRITE_PCI8_SB(SB_REG_BIOS_CNTL, Buffer8); + // <[EIP77459] + // <<(EIP128233) + if (Capabilities != NULL) { + Capabilities->Resolution = 1; + Capabilities->Accuracy = 0; + Capabilities->SetsToZero = 0; + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSetTime +// +// Description: Sets the RTC time +// +// Input: *Time - Time to set +// +// Output: EFI_STATUS +// EFI_SUCCESS - Time is Set +// EFI_INVALID_PARAMETER - Time to Set is not valid. +// +// Notes: Here is the control flow of this function: +// 1. Read the original time format 12/24 hours and BCD/binary. +// 2. Set the format to 24 hrs and binary. +// 3. Verify the time to set. If it is an invalid time, +// restore the time format and return EFI_INVALID_PARAMETER. +// 4. Change the 4 digit year to a 2 digit year. +// 5. Stop the RTC time. +// 6. Store time and data on the RTC. +// 7. Read the month, day, hour, minute, second. +// 8. Start the RTC time. +// 9. Restore the original time format. +// 10.Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSetTime ( + IN EFI_TIME *Time ) +{ + + EFI_STATUS Status = EFI_SUCCESS; + UINTN TimeVarSize = sizeof(TIME_VARIABLE); + + // Check RTC Conditions and stuff + CheckRtc(TRUE); + + if (Time == NULL) return EFI_INVALID_PARAMETER; + if (!VerifyTime(Time)) return EFI_INVALID_PARAMETER; + + SetUpdate(FALSE); + WriteRtcIndex(ACPI_CENTURY_CMOS, Time->Year / 100); + WriteRtcIndex(RTC_YEAR_REG, Time->Year % 100); + WriteRtcIndex(RTC_MONTH_REG, Time->Month); + WriteRtcIndex(RTC_DAY_OF_MONTH_REG, Time->Day); + WriteRtcIndex(RTC_DAY_OF_WEEK_REG, GetDayOfTheWeek(Time) + 1); + + WriteRtcIndex(RTC_HOURS_REG, Time->Hour); + WriteRtcIndex(RTC_MINUTES_REG, Time->Minute); + WriteRtcIndex(RTC_SECONDS_REG, Time->Second); + SetUpdate(TRUE); + + // (EIP128233)>> + if(CachedTimeVariableValid && + CachedTimeVariable.TimeZone == Time->TimeZone && + CachedTimeVariable.Daylight == Time->Daylight) + return EFI_SUCCESS; + + CachedTimeVariable.TimeZone = Time->TimeZone; + CachedTimeVariable.Daylight = Time->Daylight; + + Status = pRS->SetVariable( + L"EfiTime", + &gEfiTimeVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(TIME_VARIABLE), + &CachedTimeVariable + ); + if(!EFI_ERROR(Status)) + CachedTimeVariableValid = TRUE; + // <<(EIP128233) + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiGetWakeupTime +// +// Description: Read the wake time. Read the status if it is enabled or +// if the system has woken up. +// +// Input: *Enabled - Flag indicating the validity of wakeup time +// *Pending - Check if wake up time has expired. +// *Time - Current wake up time setting +// +// Output: EF_STATUS +// EFI_SUCCESS - Read the wake time successfully. +// EFI_INVALID_PARAMETER - Invalid input parameters +// EFI_DEVICE_ERROR - RTC mode and/or format are invalid +// +// Notes: Here is the control flow of this function: +// 1. Read the original time format 12/24 hours and BCD/binary. +// 2. Set the format to 24 hrs and binary. +// 3. Read the status if the wake up time is enabled or if it has expired. +// 4. Set the wakeup time. +// 5. Restore the original time format. +// 6. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time ) +{ + EFI_STATUS Status; + BOOLEAN IntState; + BOOLEAN SmiState; + RTC_REG_B RegB; + RTC_REG_C RegC; +#if ACPI_ALARM_DAY_CMOS + RTC_DATE_ALARM_REG RegDateAlarm; +#endif +#if ACPI_ALARM_MONTH_CMOS + RTC_MONTH_ALARM_REG RegMonthAlarm; +#endif + + if (!Enabled || !Pending || !Time) return EFI_INVALID_PARAMETER; + + // Check RTC Conditions (24h Mode and BCD is ON) + Status = CheckRtc(FALSE); + if (EFI_ERROR(Status)) return Status; + + // Get SMI State and disable it + SmiState = SbLib_GetSmiState(); + SbLib_SmiDisable(); + // Get INTERRUPT State and disable it + IntState = CPULib_GetInterruptState(); + CPULib_DisableInterrupt(); + + // Wait till RTC is safe to read, + CheckUpdateCmplete(); + if (gTimeOut) InitRtc(); + + Time->Hour = ReadRtcIndex(RTC_HOURS_ALARM_REG); + Time->Minute = ReadRtcIndex(RTC_MINUTES_ALARM_REG); + Time->Second = ReadRtcIndex(RTC_SECONDS_ALARM_REG); + + // Restore SMIs and INTERRUPT State + if (IntState) CPULib_EnableInterrupt(); + if (SmiState) SbLib_SmiEnable(); + +#if ACPI_ALARM_DAY_CMOS + RegDateAlarm.REG_DATE_ALARM = ReadRtcIndex(ACPI_ALARM_DAY_CMOS); + Time->Day = BCDToDec(RegDateAlarm.DateAlarm); +#else + Time->Day = 0; +#endif + +#if ACPI_ALARM_MONTH_CMOS + RegMonthAlarm.REG_MONTH_ALARM = ReadRtcIndex(ACPI_ALARM_MONTH_CMOS); + Time->Month = BCDToDec(RegMonthAlarm.MonthAlarm); +#else + Time->Month = 0; +#endif + + RegB.REG_B = ReadRtcIndex(RTC_REG_B_INDEX); + RegC.REG_C = ReadRtcIndex(RTC_REG_C_INDEX); + + + *Enabled = (RegB.AlarmInt == 1) ? TRUE : FALSE; + *Pending = (RegC.AlarmFlag == 1) ? TRUE : FALSE; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSetWakeupTime +// +// Description: Enable/disable and set wakeup time +// +// Input: Enable - Flag indicating whether to enable/disble the time +// *Time - Time to set +// +// Output: EFI_STATUS +// EFI_SUCCESS - Wakeup time is Set and/or Enabled/Disabled. +// EFI_DEVICE_ERROR - RTC mode and/or format are invalid +// EFI_INVALID_PARAMETER - Invalid time or enabling with a +// NULL Time. +// +// Notes: Here is the control flow of this function: +// 1. Read the original time format 12/24 hours and BCD/binary. +// 2. If Time is not NULL, +// a. Verify the wakeup time to set. If it is an invalid +// time, restore the time format and +// return EFI_INVALID_PARAMETER. +// b. Set the wakeup time. +// 3. If Time is NULL and Enable is true, restore original +// time format and return EFI_INVALID_PARAMETER. +// 4. Enable/Disable wakeup. +// 5. Restore the original time format. +// 6. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSetWakeupTime ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL ) +{ + + EFI_STATUS Status; + RTC_REG_B RegB; + RTC_REG_C RegC; +#if ACPI_ALARM_DAY_CMOS + RTC_DATE_ALARM_REG RegDateAlarm; +#endif +#if ACPI_ALARM_MONTH_CMOS + RTC_MONTH_ALARM_REG RegMonthAlarm; +#endif + + // Check RTC Conditions (24h Mode and BCD is ON) + Status = CheckRtc(FALSE); + if(EFI_ERROR(Status)) return Status; + + if (Time != NULL) { + if (!VerifyTime(Time)) return EFI_INVALID_PARAMETER; + } else { + if (Enable) return EFI_INVALID_PARAMETER; + } + + RegB.REG_B = ReadRtcIndex(RTC_REG_B_INDEX); + + SetUpdate(FALSE); + if (Time != NULL) { + WriteRtcIndex(RTC_HOURS_ALARM_REG, Time->Hour); + WriteRtcIndex(RTC_MINUTES_ALARM_REG, Time->Minute); + WriteRtcIndex(RTC_SECONDS_ALARM_REG, Time->Second); +#if ACPI_ALARM_DAY_CMOS + // Day == 0 means don't care + RegDateAlarm.DateAlarm = DecToBCD(Time->Day); + WriteRtcIndex(ACPI_ALARM_DAY_CMOS, RegDateAlarm.REG_DATE_ALARM); +#endif +#if ACPI_ALARM_MONTH_CMOS + // Month == 0 means don't care + RegMonthAlarm.MonthAlarm = DecToBCD(Time->Month); + WriteRtcIndex(ACPI_ALARM_MONTH_CMOS, RegMonthAlarm.REG_MONTH_ALARM); +#endif + } + + // Clear Alarm Flag + RegC.REG_C = ReadRtcIndex(RTC_REG_C_INDEX); + + // Set Enable/Disable + RegB.AlarmInt = (Enable) ? 1 : 0; + WriteRtcIndex(RTC_REG_B_INDEX, RegB.REG_B); + + SetUpdate(TRUE); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SaveIntelResetPointer +// +// Description: +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SaveIntelResetPointer ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + gCallSavedIntelPointer = pRS->ResetSystem; + pRS->ResetSystem = EfiResetSystem; + + pBS->CloseEvent(Event); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBRun_Init +// +// Description: This function is the entry point for this DXE. This function +// installs the runtime services related to SB +// +// Input: ImageHandle - Image handle +// SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// EFI_SUCCESS - All the protocol interfaces were installed. +// EFI_ALREADY_STARTED - A Device Path instance was passed +// in that is already present in the +// handle database. +// EFI_OUT_OF_RESOURCES - There was not enough memory in +// pool to install all the protocols. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBRun_Init ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_TIME Time; + EFI_TIME NewTime; + EFI_HANDLE Handle = NULL; + UINT8 PM2 = READ_PCI8_SB(SB_REG_GEN_PMCON_2); + UINT8 PM3 = READ_PCI8_SB(SB_REG_GEN_PMCON_3); + RTC_REG_D RegD; + BOOLEAN RtcLostPower = FALSE; + + InitAmiRuntimeLib(ImageHandle, SystemTable, NULL, NULL); + + PROGRESS_CODE(DXE_SBRUN_INIT); + + // CspLib PM Specific function to check and Report + // CMOS Battary and Power Supply Power loss/failure + CspLibCheckPowerLoss(); + + if(PM3 & BIT02) { + // Clear RTC_PWR_STS. + PM3 &= ~BIT02; + RtcLostPower = TRUE; + } + //Write back Cleared Statuses + WRITE_PCI8_SB(SB_REG_GEN_PMCON_2, PM2); + WRITE_PCI8_SB(SB_REG_GEN_PMCON_3, PM3); + + RegD.REG_D = ReadRtcIndex(RTC_REG_D_INDEX); + if (RegD.DataValid == 0) + RtcLostPower = TRUE; + + if (RtcLostPower) { + ERROR_CODE(DXE_SB_BAD_BATTERY, EFI_ERROR_MAJOR); + InitRtc(); + } + + + // MakeSure Mode, Format and REG_A is OK + CheckRtc(TRUE); + + Status = EfiGetTime(&Time, NULL); + if (EFI_ERROR(Status) || !VerifyTime(&Time)) { + ERROR_CODE(GENERIC_BAD_DATE_TIME_ERROR, EFI_ERROR_MINOR); + + TRACE((TRACE_ALWAYS, "\n\nTime: %d/%d/%d %d:%d:%d\n", + Time.Month, + Time.Day, + Time.Year, + Time.Hour, + Time.Minute, + Time.Second + )); + + TRACE((TRACE_ALWAYS, "Nanosecond: %d TimeZone: %d\n\n\n", + Time.Nanosecond, + Time.TimeZone + )); + + // if Time is invalid the battery probably has been removed + // Let's setup RTC_REG_A just in case... + WriteRtcIndex(RTC_REG_A_INDEX, 0x26); + + // Check to see what part of EFI_TIME was wrong. + // reset unrelated to RTC fields. + Time.TimeZone = EFI_UNSPECIFIED_TIMEZONE; + Time.Daylight = 0; + Time.Nanosecond = 0; + + NewTime = Time; + + NewTime.Hour = 0; + NewTime.Minute = 0; + NewTime.Second = 0; + + if (VerifyTime(&NewTime)) { + // if we here that means Time was wrong + Time.Hour = 0; + Time.Minute = 0; + Time.Second = 0; + } else { + // if we here that means Date was wrong + Time.Month = DEFAULT_MONTH; + Time.Day = DEFAULT_DAY; + Time.Year = DEFAULT_YEAR; + } + + // Here is the situation when both Time and Date is Incorrect. + if (!VerifyTime(&Time)) { + Time.Hour = 0; + Time.Minute = 0; + Time.Second = 0; + Time.Month=DEFAULT_MONTH; + Time.Day=DEFAULT_DAY; + Time.Year=DEFAULT_YEAR; + } + + TRACE((TRACE_ALWAYS, "Reseting Date and Time to: %d/%d/%d %d:%d:%d\n", + Time.Month, + Time.Day, + Time.Year, + Time.Hour, + Time.Minute, + Time.Second + )); + EfiSetTime(&Time); + } + + // Install runtime services + pRS->ResetSystem = EfiResetSystem; + + gCallSavedIntelPointer = NULL; + + pRS->GetTime = EfiGetTime; + pRS->SetTime = EfiSetTime; + pRS->GetWakeupTime = EfiGetWakeupTime; + pRS->SetWakeupTime = EfiSetWakeupTime; + + Status = pBS->InstallProtocolInterface( &ImageHandle, \ + &gEfiMetronomeArchProtocolGuid, \ + EFI_NATIVE_INTERFACE, \ + &mMetronomeProtocol ); + ASSERT_EFI_ERROR(Status); +{ + EFI_EVENT Event = NULL; + VOID *Registration = NULL; + + Status = RegisterProtocolCallback( &gEfiResetArchProtocolGuid,\ + SaveIntelResetPointer,\ + NULL,\ + &Event,\ + &Registration ); + ASSERT_EFI_ERROR(Status); +} + + // This protocol is to notify core that the Runtime Table has been + // updated, so it can update the runtime table CRC. + return pBS->InstallMultipleProtocolInterfaces( &Handle, \ + &gEfiRtcArchProtocolGuid, \ + NULL, \ + NULL ); +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBSMI.c b/Chipset/SB/SBSMI.c new file mode 100644 index 0000000..a6cae4d --- /dev/null +++ b/Chipset/SB/SBSMI.c @@ -0,0 +1,1744 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.c 19 7/12/15 11:08p Dennisliu $ +// +// $Revision: 19 $ +// +// $Date: 7/12/15 11:08p $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.c $ +// +// 19 7/12/15 11:08p Dennisliu +// [TAG] None +// [Category] Improvement +// [Description] Coding error in ElogGenerateNmiNow() +// [Files] Chipset\SB\SBSMI.c +// +// 17 12/30/13 5:59a Barretlin +// [TAG] EIP144559 +// [Category] Improvement +// [Description] S3 can't resume via USB KB & MS under usb3.0 port in +// special case +// [Files] SBSMI.c SBSMI.h SBGeneric.c +// +// 16 10/01/13 7:53a Barretlin +// [TAG] EIP137385 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System hang if power button pushed on BSU, after windows +// shutdown / reboot +// [RootCause] Push power button key on RF keyboard will triger xhci hw +// smi, but xhci is set D3hot state in power button handler, then we can't +// service it +// [Solution] Stop xhci before we set D3hot state and check if +// hciversion is valid +// [Files] SBSMI.c +// +// 15 5/28/13 11:45p Scottyang +// [TAG] None +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] GbE cannot wake form S5 under DOS. +// [RootCause] The base address is incorrect. +// [Solution] Correct base address. +// [Files] SBSMI.c +// +// 14 4/19/13 6:34a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Update GbES02SxWorkaround() and add +// UsbS02SxWorkaround() for SBPwrBtnHandler(). +// [Files] SBSMI.c; SBSMI.h; SBGeneric.c; SBCspLib.h +// +// 12 3/21/13 3:39a Scottyang +// [TAG] EIP83075 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] USB3.0 mouse can not resume form S3 if shot down at POST +// before. +// [Solution] Additional xHCI Controller Configurations Prior to Enter +// S5. +// [Files] SBSMI.c +// +// 11 3/19/13 8:37a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Improve alternate access mode enable/disable routine. +// [Files] SBGeneric.c, SBCspLib.h, SBSMI.c +// +// 10 1/11/13 4:46a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Fixed coding error. +// [Files] SBSMI.c +// +// 9 1/04/13 2:45a Scottyang +// [TAG] EIP104199 +// [Category] Improvement +// [Description] Register dummy Handler for all Tco Smi +// [Files] SBSMI.c; +// +// 8 10/30/12 10:04p Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Remove clear SMI state and Y2K roller for PFAT +// function. +// [Files] SBSMI.c, SBGeneric.c +// +// 7 10/26/12 1:11a Scottyang +// [TAG] CHECK_BS_VARIABLE +// [Category] Improvement +// [Description] If project has module NVRamSMI then don't need to check +// this. +// [Files] SBSMI.c +// +// 6 10/12/12 8:06a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Fixed the system hang when Y2K roll over is occur with +// TCO SMI enabled. +// +// 5 9/26/12 3:58a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 4 8/13/12 10:31a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement BIOS Lock function. +// [Files] SBCspLib.h, SBDxe.c, SBSMI.c, SBSMI.dxs, SBSMI.sdl +// +// 3 7/27/12 6:17a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 2 6/13/12 11:36p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement Warm Boot function for Secure Flash feature. +// [Files] SB.H, SB.mak, SB.sdl, SBDxe.c, SBGeneric.c, SBPEI.c, +// SBSMI.c +// +// 1 2/08/12 8:31a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBSMI.c +// +// Description: This file contains code for all North Bridge SMI events +// +//<AMI_FHDR_END> +//************************************************************************* + +//---------------------------------------------------------------------------- +// Include(s) +//---------------------------------------------------------------------------- + +#include <Token.h> +#include <Setup.h> +#include <AmiDxeLib.h> +#include <AMICSPLIBInc.h> +#include <AmiCspLib.h> +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +#include <Protocol\SmmPowerButtonDispatch2.h> +#include <Protocol\SmmBase2.h> +#include <Protocol\S3SaveState.h> +#include <Protocol\SmmSwDispatch2.h> +#else +#include <Protocol\SmmPowerButtonDispatch.h> +#include <Protocol\SmmBase.h> +#include <Protocol\BootScriptSave.h> +#include <Protocol\SmmSwDispatch.h> +#endif +#if SB_PCIE_ERROR_LOG_SUPPORT +#include <Protocol\GenericElog.h> +#endif +#include <Protocol\SBSmiProtocol.h> +#include <Edk\Foundation\Framework\Protocol\SmmIchnDispatch\SmmIchnDispatch.h> +#include <Protocol\PchPlatformPolicy\PchPlatformPolicy.h> +#include <ReferenceCode\Chipset\LynxPoint\Protocol\SmmIchnDispatchEx\SmmIchnDispatchEx.h> +#include <ReferenceCode\Chipset\LynxPoint\Protocol\SmmIoTrapDispatch\SmmIoTrapDispatch.h> +#include <Protocol\SBPlatformData.h> +#include <SBSMI.h> + +//---------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//---------------------------------------------------------------------------- +// Constant Definition(s) +#define GBE_MAX_LOOP_TIME 4000 + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +#define AMI_SMM_SW_DISPATCH_PROTOCOL EFI_SMM_SW_DISPATCH2_PROTOCOL +#define AMI_SMM_SW_DISPATCH_CONTEXT EFI_SMM_SW_REGISTER_CONTEXT +#define AMI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL +#define AMI_SMM_POWER_BUTTON_DISPATCH_CONTEXT EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT +#define SMM_CHILD_DISPATCH_SUCCESS EFI_SUCCESS +#else +#define AMI_SMM_SW_DISPATCH_PROTOCOL EFI_SMM_SW_DISPATCH_PROTOCOL +#define AMI_SMM_SW_DISPATCH_CONTEXT EFI_SMM_SW_DISPATCH_CONTEXT +#define AMI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL +#define AMI_SMM_POWER_BUTTON_DISPATCH_CONTEXT EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT +#define SMM_CHILD_DISPATCH_SUCCESS +#endif + +#ifndef NvramSmiSupport +#define CHECK_BS_VARIABLE 1 +#endif + +#if defined NvramSmiSupport && NvramSmiSupport +#define CHECK_BS_VARIABLE 0 +#else +#define CHECK_BS_VARIABLE 1 +#endif + + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//---------------------------------------------------------------------------- +// Variable and External Declaration(s) +//---------------------------------------------------------------------------- +// Variable Declaration(s) +#if SB_PCIE_ERROR_LOG_SUPPORT + +SB_PCIE_ERROR_LOG_DISPATCH_LINK *gSbPcieErrorLogDispatchHead = 0, *gSbPcieErrorLogDispatchTail = 0; + +UINT32 SBPcieBridge[] = +{ + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS_BUS, PCIEBRS_DEV, PCIEBRS_FUN, PCI_VID)}, + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS2_BUS, PCIEBRS2_DEV, PCIEBRS2_FUN, PCI_VID)}, + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS3_BUS, PCIEBRS3_DEV, PCIEBRS3_FUN, PCI_VID)}, + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS4_BUS, PCIEBRS4_DEV, PCIEBRS4_FUN, PCI_VID)}, + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS5_BUS, PCIEBRS5_DEV, PCIEBRS5_FUN, PCI_VID)}, + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS6_BUS, PCIEBRS6_DEV, PCIEBRS6_FUN, PCI_VID)}, + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS7_BUS, PCIEBRS7_DEV, PCIEBRS7_FUN, PCI_VID)}, + {(UINT32)SB_PCIE_CFG_ADDRESS(PCIEBRS8_BUS, PCIEBRS8_DEV, PCIEBRS8_FUN, PCI_VID)}, + {0xFFFFFFFF} +}; +#endif + +BOOLEAN gIsLastState = FALSE; +BOOLEAN gPchWakeOnLan = FALSE; +EFI_SMM_ICHN_DISPATCH_PROTOCOL *gIchnDispatch; +EFI_RESET_SYSTEM gSmmResetSystem = NULL; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_SMM_BASE2_PROTOCOL *gSmmBase2; +#endif + +// GUID Definition(s) +#if SB_PCIE_ERROR_LOG_SUPPORT +EFI_GUID gSbPcieErrorLogDispatchProtocolGuid = EFI_SB_PCIE_ERROR_LOG_DISPATCH_PROTOCOL_GUID; +EFI_GUID gElogProtocolGuid = EFI_SM_ELOG_PROTOCOL_GUID; +#endif +EFI_GUID gAmiSbSmiProtocolGuid = AMI_SB_SMI_PROTOCOL_GUID; +EFI_GUID gEfiSmmIchnExDispatchProtocolGuid = EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID; +EFI_GUID gIchnDispatchProtocolGuid = EFI_SMM_ICHN_DISPATCH_PROTOCOL_GUID; +EFI_GUID gDxePchPlatformPolicyProtocolGuid = DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID; +EFI_GUID gEfiSmmIoTrapDispatchProtocolGuid = EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID; + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION<0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_GUID gSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID; +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AddLink +// +// Description: Create and add link to specified list. +// +// Parameters: Size - +// Head - +// Tail - +// +// Returns: VOID Pointer +// +// Modified: +// +// Referrals: SmmAllocatePool +// +// Notes: Here is the control flow of this function: +// 1. Allocate Link in Smm Pool. +// 2. Add Link to end. +// 3. Return Link address. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID * AddLink ( + IN UINT32 Size, + IN VOID **Head, + IN VOID **Tail ) +{ + VOID *Link; + + if (pSmst->SmmAllocatePool(0, Size, &Link) != EFI_SUCCESS) return 0; + + ((GENERIC_LINK*)Link)->Link = 0; + if (!*Head) { + *Head = *Tail = Link; + } else { + ((GENERIC_LINK*)*Tail)->Link = Link; + *Tail = Link; + } + + return Link; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RemoveLink +// +// Description: Remove link from specified list. +// +// Parameters: Handle - EFI Handle +// Head - +// Tail - +// +// Returns: BOOLEAN +// TRUE if link was removed. FALSE if link not in the list. +// +// Modified: +// +// Referrals: SmmFreePool +// +// Notes: Here is the control flow of this function: +// 1. Search link list for Link. +// 2. Remove link from list. +// 3. Free link. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN RemoveLink ( + IN EFI_HANDLE Handle, + IN VOID **Head, + IN VOID **Tail ) +{ + GENERIC_LINK *PrevLink,*Link; + + PrevLink = *Head; + + // Is link first. Link address is the same as the Handle. + if (((GENERIC_LINK*)*Head) == Handle) { + if (PrevLink == *Tail) *Tail = 0; // If Tail = Head, then 0. + *Head = PrevLink->Link; + pSmst->SmmFreePool(PrevLink); + return TRUE; + } + + // Find Link. + for (Link=PrevLink->Link; Link; PrevLink=Link, Link=Link->Link) { + if (Link == Handle) { // Link address is the same as the Handle. + if (Link == *Tail) *Tail = PrevLink; + PrevLink->Link = Link->Link; + pSmst->SmmFreePool(Link); + return TRUE; + } + } + + return FALSE; +} + +#if SB_PCIE_ERROR_LOG_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSbPcieErrorLogEnRegister +// +// Description: Register a Link on SbPcieErrorLog enable SMI. +// +// Parameters: This - +// Function - +// Context - +// +// +// Returns: Handle - +// EFI_STATUS +// +// Modified: gSbPcieErrorLogDispatchHead, gSbPcieErrorLogDispatchTail +// +// Referrals: AddLink +// +// Notes: Here is the control flow of this function: +// 1. Verify if Context if valid. If invalid, +// return EFI_INVALID_PARAMETER. +// 2. Allocate structure and add to link list. +// 3. Fill link. +// 4. Enable Smi Source. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SbPcieErrorLogRegister ( + IN EFI_SB_PCIE_ERROR_LOG_DISPATCH_PROTOCOL *This, + IN EFI_SB_PCIE_ERROR_LOG_DISPATCH Function, + OUT EFI_HANDLE *Handle ) +{ + SB_PCIE_ERROR_LOG_DISPATCH_LINK *NewLink; + + NewLink = AddLink( sizeof(SB_PCIE_ERROR_LOG_DISPATCH_LINK), \ + &gSbPcieErrorLogDispatchHead, \ + &gSbPcieErrorLogDispatchTail ); + if (!NewLink) return EFI_OUT_OF_RESOURCES; + + NewLink->Function = Function; + *Handle = NewLink; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbPcieErrorLogUnregister +// +// Description: Unregister a Link on SbPcieErrorLog enable SMI. +// +// Parameters: This - +// Handle - +// +// Returns: EFI_STATUS +// +// Modified: gSbPcieErrorLogDispatchHead, gSbPcieErrorLogDispatchTail +// +// Referrals: RemoveLink +// +// Notes: Here is the control flow of this function: +// 1. Remove link. If no link, return EFI_INVALID_PARAMETER. +// 2. Disable SMI Source if no other handlers using source. +// 3. Return EFI_SUCCESS. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SbPcieErrorLogUnregister ( + IN EFI_SB_PCIE_ERROR_LOG_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + if (!RemoveLink(Handle, &gSbPcieErrorLogDispatchHead, &gSbPcieErrorLogDispatchTail)) + return EFI_INVALID_PARAMETER; + return EFI_SUCCESS; +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: CheckReadyFlag +// +// Description: Check ready flag to see if writing to MDIC is done. +// +// Parameters: GbEBar - GbE Memory Base Address Register +// +// Returns: EFI_SUCCESS - Successfully completed. +// EFI_TIMEOUT - Checking flag time out. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS CheckReadyFlag ( IN UINT32 GbEBar ) +{ + UINT32 ReadyFlag; + UINT32 LoopTime; + + ReadyFlag = 0; + + for (LoopTime = 0; LoopTime < GBE_MAX_LOOP_TIME; LoopTime++) { + ReadyFlag = READ_MEM32 (GbEBar + R_PCH_MBARA_GBECSR3) & B_PCH_MBARA_GBECSR3_RB; + + if (ReadyFlag) { + break; + } + + CountTime((10), PM_BASE_ADDRESS); + } + + if (LoopTime >= GBE_MAX_LOOP_TIME) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GbES02SxWorkaround +// +// Description: PCH BIOS Spec Rev 0.7.0 Section 10.6 +// Additional Internal GbE Controller special cases WOL Support +// +// Parameters: None +// +// Returns: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID GbES02SxWorkaround ( VOID ) +{ + UINTN PciD25F0RegBase; + UINTN PciD31F0RegBase; + UINT32 GbEBar; + UINT32 GbEBarB; + UINT16 CmdReg; + UINT32 RAL0; + UINT32 RAH0; + UINT32 PhyCtrl; + UINT32 ExtCnfCtrl; + UINT32 Buffer; + UINT32 LoopTime; + UINT32 RootComplexBar; + UINT32 PchGpioBase; + EFI_STATUS Status; + + PciD25F0RegBase = MmPciAddress ( + PCIEX_BASE_ADDRESS, + PCI_BUS_NUMBER_PCH_LAN, + PCI_DEVICE_NUMBER_PCH_LAN, + PCI_FUNCTION_NUMBER_PCH_LAN, + 0 + ); + PciD31F0RegBase = MmPciAddress ( + PCIEX_BASE_ADDRESS, + 0, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + 0 + ); + RootComplexBar = (READ_MEM32 (PciD31F0RegBase + SB_REG_RCBA)) & ~BIT0; + PchGpioBase = (MmioRead32 (PciD31F0RegBase + R_PCH_LPC_GPIO_BASE)) &~BIT0; + GbEBar = 0; + GbEBarB = 0; + CmdReg = 0; + Buffer = 0; + + if (((MmioRead16 (RootComplexBar + R_PCH_RCRB_BUC)) & BIT5) == 0) { + /// + /// System BIOS requires to program the registers listed below for internal GbE to function upon S0 to S3,4,5 transition + /// (When ME off and GbE device in D0) + /// + /// Note: Time out should be applied for MBARA + Offset 20h[28] verification to avoid non respond loop. Upon time out, + /// system BIOS is required to clear MBARA + Offset F00h [5] = 0b before exiting the WA. + /// + /// Check if GbE device is in D0 state + /// + if ((MmioRead16 (PciD25F0RegBase + R_PCH_LAN_PMCS) & (UINT16) B_PCH_LAN_PMCS_PS) == (UINT16) V_PCH_LAN_PMCS_PS0) { + GbEBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A); + /// + /// Step 1 + /// If MBARA + Offset 5800h [0] = 1b then proceed the steps below + /// + if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR9) & B_PCH_MBARA_GBECSR9_APME) { + /// + /// Step 2 + /// System BIOS perform read to MBARA + Offset 5400h [31:0], MBARA + Offset 5404h [31:0] + /// and MBARA + Offset F00h [31:0] + /// + RAL0 = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR7); + RAH0 = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR8); + ExtCnfCtrl = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR5); + /// + /// Step 3 + /// Ensure that MBARA + Offset F00h [5] = 1b + /// a. Set MBARA + Offset F00h [31:0] value with the value read in step 2 or with 0x20 (set bit 5) + /// b. Read MBARA + Offset F00h + /// c. If MBARA + Offset F00h [5] = 1b (true) continue else wait X Sec and go back to step 3.b for Y times + /// (X*Y totals to ~200mSec) if false - exit flow by jumping to step 32. + /// + MmioWrite32 (GbEBar + R_PCH_MBARA_GBECSR5, ExtCnfCtrl | B_PCH_MBARA_GBECSR5_SWFLAG); + + for (LoopTime = 0; LoopTime < GBE_MAX_LOOP_TIME; LoopTime++) { + ExtCnfCtrl = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR5); + + if (ExtCnfCtrl & B_PCH_MBARA_GBECSR5_SWFLAG) { + break; + } + + CountTime((50), PM_BASE_ADDRESS); + } + + if (LoopTime >= GBE_MAX_LOOP_TIME) { + goto ExitGbEWa; + } + /// + /// Step 4 + /// If MBARA + Offset 5B54h [15] = 1b then jump to Step 10 + /// + if ((MmioRead32 (GbEBar + 0x5B54) & BIT15) != BIT15) { + /// + /// Step 5 + /// If MBARA + Offset F10h [2] = 1b, then set MBARA + Offset F10h[1] = 1b. Else clear MBARA + Offset F10h[1] = 0b + /// + if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6) & B_PCH_MBARA_GBECSR6_LPLUND) { + SET_MEM32(GbEBar + R_PCH_MBARA_GBECSR6, (UINT32) B_PCH_MBARA_GBECSR6_LPLUD); + } else { + RESET_MEM32 (GbEBar + R_PCH_MBARA_GBECSR6, (UINT32)B_PCH_MBARA_GBECSR6_LPLUD); + } + /// + /// Step 6 + /// Set MBARA + Offset 20h = 0x043f0000. Verify MBARA + Offset 20h[28] = 1b + /// + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x043f0000); + + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + /// + /// Step 7 + /// Wait 4 mSec + /// + CountTime((4 * 1000), PM_BASE_ADDRESS); + /// + /// Step 8 + /// Set MBARA + Offset 20h = 0x04390000 or with 0x400 or with 0x40 if MBARA + Offset F10h [3] = 1b + /// or with 0x04 if MBARA + Offset F10h [2] = 1b + /// + Buffer = 0x04390000 | 0x400; + if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6) & B_PCH_MBARA_GBECSR6_GbE_DIS) { + Buffer |= 0x40; + } + + if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6) & B_PCH_MBARA_GBECSR6_LPLUND) { + Buffer |= 0x04; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), Buffer); + /// + /// Step 9 + /// Verify MBARA + Offset 20h[28] = 1b + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + } + /// + /// Step 10 + /// Set MBARA + Offset 20h = 0x043f6400 + /// + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x043f6400); + /// + /// Step 11 + /// Wait 4 mSec + /// + CountTime((4 * 1000), PM_BASE_ADDRESS); + /// + /// Step 12 + /// Set MBARA + Offset F10h [6] = 1b (read modify write) + /// + PhyCtrl = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6); + MmioWrite32 (GbEBar + R_PCH_MBARA_GBECSR6, PhyCtrl | B_PCH_MBARA_GBECSR6_GGD); + /// + /// Step 13 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310010 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310010); + /// + /// Step 14 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4320000 or with + /// the least significant word of MBARA + offset 5400 that read in step 2 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), (0x4320000 | (RAL0 & 0x0000FFFF))); + /// + /// Step 15 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310011 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310011); + /// + /// Step 16 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4320000 or with + /// the most significant word of MBARA + offset 5400 that read in step 2 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), (0x4320000 | (RAL0 >> 16))); + /// + /// Step 17 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310012 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310012); + /// + /// Step 18 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4320000 or with + /// the least significant word of MBARA + offset 5404 that read in step 2 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), (0x4320000 | (RAH0 & B_PCH_MBARA_GBECSR8_RAH))); + /// + /// Step 19 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310013 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310013); + /// + /// Step 20 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4328000 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4328000); + /// + /// Step 21 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310001 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310001); + /// + /// Step 22 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x8320000 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x8320000); + /// + /// Step 23 + /// Verify MBARA + Offset 20h[28] = 1b, TEMP[15:0] = MBARA + Offset 20h [15:0] + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + Buffer = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR3) & B_PCH_MBARA_GBECSR3_DATA; + /// + /// Step 24 + /// Set MBARA + Offset 20h = 0x4320000 or TEMP[15:0] or 0x0001 + /// + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4320000 | Buffer | 0x0001); + /// + /// Step 25 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x43f6460 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x43f6460); + /// + /// Step 26 + /// Wait 4 mSec + /// + CountTime((4 * 1000), PM_BASE_ADDRESS); + /// + /// Step 27 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310042 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310042); + /// + /// Step 28 + /// Verify MBARA + Offset 20h[28] = 1b. + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x43F6020); + + /// + /// Step 29 + /// Wait 4 mSec + /// + CountTime((4 * 1000), PM_BASE_ADDRESS); + + /// + /// Step 30 + /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x8310000 + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x8310000); + /// + /// Step 31 + /// Verify MBARA + Offset 20h[28] = 1b, TEMP[15:0] = MBARA + 20[15:0] + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + + Buffer = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR3) & 0x0000FFFF; + + /// + /// Step 32 + /// Verify MBARA + 20h[28] = 1b, set MBARA + 20h = 4310000h or with the TEMP[15:0] or with 10h + /// + Status = CheckReadyFlag (GbEBar); + if (EFI_ERROR (Status)) { + goto ExitGbEWa; + } + +ExitGbEWa: + + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310000 | Buffer | 0x10); + /// + /// Step 33 + /// Verify MBARA + Offset 20h[28] = 1b + /// + Status = CheckReadyFlag (GbEBar); + + /// + /// Step 34 + /// Clear MBARA + Offset F00h [5] = 0b (read modify write) + /// + MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR5), (ExtCnfCtrl & (UINT32) (~BIT5))); + + } + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBPwrBtnHandler +// +// Description: If the power button is pressed, then this function is called. +// +// Input: DispatchHandle - Handle of dispatch function, for when interfacing +// with the parent SMM driver, will be the address of linked +// list link in the call back record. +// DispatchContext - Pointer to the dispatch function's context. +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS SBPwrBtnHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID SBPwrBtnHandler( + IN EFI_HANDLE DispatchHandle, + IN AMI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext) +#endif +{ + +// Usage sample code shows that user how to decide NMI_EN bit is diabled or enabled in SMI. +//#### EFI_CMOS_ACCESS_INTERFACE *CmosInterface; +//#### EFI_STATUS Status; +//#### +//#### LOCATE_CMOS_ACCESS_SMM_PROTOCOL(Status, CmosInterface); +//#### if( !EFI_ERROR(Status) ) { +//#### // Example1:Disable NMI +//#### CmosInterface->Write( CmosInterface, +//#### SB_SSP_NMI_CONTROL_BITS, +//#### DISABLE_NMI_BEFORE_SMI_EXIT ); +//#### // Example2:Enable NMI +//####// CmosInterface->Write( CmosInterface, +//####// SB_SSP_NMI_CONTROL_BITS, +//####// ENABLE_NMI_BEFORE_SMI_EXIT ); +//#### } + + // Program AfterG3 bit depend the setup question. + if (gIsLastState) SET_PCI8_SB(SB_REG_GEN_PMCON_3, 1); // 0xA4 + + if (gPchWakeOnLan) GbES02SxWorkaround(); + + return SMM_CHILD_DISPATCH_SUCCESS; +} + +#if SB_PCIE_ERROR_LOG_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ElogGenerateNmiNow +// +// Description: Generate NmiNow. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ElogGenerateNmiNow (VOID) +{ + UINT16 PmBase; + UINT8 SaveNmi2SmiEn; + UINT8 SavePort70; + + // + // Get the PM Base Address + // + PmBase = READ_PCI16_SB (SB_REG_PMBASE) & 0xFF80; + + // Read the NMI2SMI_EN bit, save it for future restore + SaveNmi2SmiEn = READ_IO8(PmBase + TCO1_CNT_OFFSET + 1); + + // Set the NMI2SMI_EN bit to 0 + RESET_IO8(PmBase + TCO1_CNT_OFFSET + 1, BIT01); + + SavePort70 = ReadPort70h(); //Improve alternate access mode + + // Enable NMI_EN + WRITE_IO8(CMOS_ADDR_PORT, (SavePort70 & ~BIT07)); //Improve alternate access mode + + // Set NMI_NOW = 1 + SET_IO8(PmBase + TCO1_CNT_OFFSET + 1, BIT00); + + // Clear NMI_NOW = 0 by writing 1 to NMI_NOW bit + RESET_IO8(PmBase + TCO1_CNT_OFFSET + 1, BIT00); + + // Restore NMI2SMI_EN + WRITE_IO8(PmBase + TCO1_CNT_OFFSET + 1, SaveNmi2SmiEn); + + // Clear the DMISERR_STS bit, bit 12 + WRITE_IO16(PmBase + TCO1_STS_OFFSET, BIT12); + + // Clear the NMI2SMI_STS bit if set + if ((READ_IO16(PmBase + TCO1_STS_OFFSET)) & 0x0001) { + // check port 0x61 + if (READ_IO8(NMI_SC_PORT) & 0x80) { + SET_IO8(NMI_SC_PORT, BIT02); + RESET_IO8(NMI_SC_PORT, BIT02); + } + } + + // Restore NMI_EN + WRITE_IO8(CMOS_ADDR_PORT, SavePort70); + + return; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SBErrLogHandler +// +// Description: South bridge error logging handler. +// +// Input: DispatchHandle - Handle of dispatch function, for when interfacing +// with the parent SMM driver, will be the address of linked +// list link in the call back record. +// DispatchContext - Pointer to the dispatch function's context. +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SBErrLogHandler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext +) +{ + EFI_STATUS Status = EFI_SUCCESS; + SB_PCIE_ERROR_LOG_DISPATCH_LINK *Link; + SB_PCIE_ERR ErrorInfo; + UINT8 i; + UINT8 CapPtr; + UINT16 PciStatus; + UINT16 PcieStatus; + UINT16 DeviceStatus; + UINT32 DevBaseAddr; + + if (READ_IO8(NMI_SC_PORT) & BIT7) // SERR#_NMI_STS? + { + // Clear SERR#_NMI_STS & NMI2SMI_STS by set Port 61h[2] = 1 then set it to 0. + SET_IO8(NMI_SC_PORT, BIT02); + RESET_IO8(NMI_SC_PORT, BIT02); + + for (i = 0; SBPcieBridge[i] != 0xFFFFFFFF; i++) + { + DevBaseAddr = SBPcieBridge[i]; + if (READ_MEM32(DevBaseAddr) == 0xFFFFFFFF) + continue; + + PciStatus = READ_MEM16(DevBaseAddr + 0x06); + PcieStatus = READ_MEM16(DevBaseAddr + 0x1E); + + CapPtr = SbFindCapPtr(DevBaseAddr, 0x10); + if (CapPtr != 0) + DeviceStatus = READ_MEM16(DevBaseAddr + CapPtr + 0x0A); + + if ((PciStatus & (BIT8 | BIT15)) || (PcieStatus & (BIT8 | BIT15))) + ErrorInfo.ParityError = TRUE; + else + ErrorInfo.ParityError = FALSE; + + if ((PciStatus & BIT14) || (PcieStatus & BIT14)) + ErrorInfo.SystemError = TRUE; + else + ErrorInfo.SystemError = FALSE; + + if ((ErrorInfo.ParityError) || (ErrorInfo.SystemError)) { + ErrorInfo.PcieAddress = DevBaseAddr; + ErrorInfo.Bus = (DevBaseAddr >> 20) & ((UINT8)((PCIEX_LENGTH >> 20) - 1)); + ErrorInfo.Dev = (DevBaseAddr >> 15) & 0x1F; + ErrorInfo.Fun = (DevBaseAddr >> 12) & 0x07; + ErrorInfo.VendorId = READ_MEM16(DevBaseAddr + 0x00); + ErrorInfo.DeviceId = READ_MEM16(DevBaseAddr + 0x02); + ErrorInfo.PciCommand = READ_MEM16(DevBaseAddr + 0x04); + ErrorInfo.PciCCode = READ_MEM16(DevBaseAddr + 0x0A); + ErrorInfo.BridgeControl = READ_MEM16(DevBaseAddr + 0x3E); + ErrorInfo.Version = READ_MEM8(DevBaseAddr + CapPtr + 0x02) & 0x0F; + ErrorInfo.PortType = (UINT32)((READ_MEM8(DevBaseAddr + CapPtr + 0x02) & 0xF0) >> 4); + + if (CapPtr != 0) { + ErrorInfo.Correctable = (DeviceStatus & BIT0)? TRUE : FALSE; + ErrorInfo.NonFatal = (DeviceStatus & BIT1)? TRUE : FALSE; + ErrorInfo.Fatal = (DeviceStatus & BIT2)? TRUE : FALSE; + } + + // Clear Error status + WRITE_MEM16(DevBaseAddr + 0x06, PciStatus); + WRITE_MEM16(DevBaseAddr + 0x1E, PcieStatus); + + if (CapPtr != 0) + // Clear Error Status + WRITE_MEM16(DevBaseAddr + CapPtr + 0x0A, DeviceStatus); + +//#### if (!ErrorInfo.Correctable) +//#### ElogGenerateNmiNow(); + + for(Link = gSbPcieErrorLogDispatchHead; Link; Link = Link->Link) { + Link->Function(Link, ErrorInfo); + } + } // if ((ErrorInfo.ParityError) || (ErrorInfo.SystemError)) + } + } +} + + +//---------------------------------------------------------------------------- +VOID InitSbSmiLogic(VOID) +{ +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSbSmiLogicHandler +// +// Description: Initialize SB SMI Logic Handler. +// This handler should be performed in ready to boot +// and S3 rerume. +// +// Input: DispatchHandle - Handle of dispatch function, for when interfacing +// with the parent SMM driver, will be the address of linked +// list link in the call back record. +// DispatchContext - Pointer to the dispatch function's context. +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS InitSbSmiLogicHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID InitSbSmiLogicHandler ( + IN EFI_HANDLE DispatchHandle, + IN AMI_SMM_SW_DISPATCH_CONTEXT *DispatchContext) +#endif +{ + UINT32 PmBase; + UINT32 Buffer32; + + PmBase = READ_PCI16_SB (SB_REG_PMBASE) & 0xFF80; + + // + //Every SERR (System Erors) will generate NMI. So route NMI as a SMI to handle Errors + //Steps to route NMI as a SMI + //Enable NMI2SMI_EN bit in TCO1 Control Register + //UnMask NMI Enable bit in NMI Enable (and Real Time Clock Index) Register + // + + // Set NMI2SMI_EN = '1b', TCO_BASE + 08h[9] + SET_IO16_PM(TCO1_CNT_OFFSET, BIT09); + + // Enable NMI by set Port 70h[7] = '0b' + SwitchAlternateAccessMode (TRUE); //Improve alternate access mode + RESET_IO8(CMOS_ADDR_PORT, BIT07); + SwitchAlternateAccessMode (FALSE); //Improve alternate access mode + + // + //Clear all Spurious Sources of the SMI. + // + Buffer32 = READ_IO32_PM(SMI_STS_OFFSET); + WRITE_IO32_PM(SMI_STS_OFFSET, Buffer32); + + Buffer32 = READ_IO32_PM(TCO1_STS_OFFSET); + WRITE_IO32_PM(TCO1_STS_OFFSET, Buffer32); + + SET_IO8(NMI_SC_PORT, BIT02); + RESET_IO8(NMI_SC_PORT, BIT02); + + return SMM_CHILD_DISPATCH_SUCCESS; +} + +EFI_SB_PCIE_ERROR_LOG_DISPATCH_PROTOCOL gEfiSbPcieErrorLogDispatchProtocol = \ + {SbPcieErrorLogRegister, SbPcieErrorLogUnregister}; +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetSbSmiContext +// +// Description: This is a template SB SMI GetContext for Porting. +// +// Input: None +// +// Output: BOOLEAN +// +// Notes: Here is the control flow of this function: +// 1. Check if NB Smi source. +// 2. If yes, return TRUE. +// 3. If not, return FALSE. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN GetSbSmiContext (VOID) +{ + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbSmiHandler +// +// Description: This is a template SB SMI Handler for Porting. +// +// Input: None +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbSmiHandler (VOID) +{ + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbIchnExGpioUnlockSmiHandler +// +// Description: If the GPIO Lockdown Enable(GLE, B0:D31:F0 R4Ch[0]) bit is +// changed from 1 to 0, then this function is called. +// +// Input: DispatchHandle - EFI Handle +// DispatchContext - Pointer to the EFI_SMM_ICHN_DISPATCH_EX_CONTEXT +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SbIchnExGpioUnlockSmiHandler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_ICHN_DISPATCH_EX_CONTEXT *DispatchContext ) +{ + // Set GPIO Lockdown Enable(GLE) bit. + SET_PCI8_SB(SB_REG_GC, BIT00); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PchBiosWpCallback +// +// Description: This hardware SMI handler will be run every time the BIOS Write Enable bit is set. +// +// Input: DispatchHandle Not used +// DispatchContext Not used +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static +VOID +PchBiosWpCallback ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext + ) +{ +#if CHECK_BS_VARIABLE + // Do not need to check the BS attribute variable + // if NvramSmi is enabled. + EFI_STATUS Status; + SB_PLATFORM_DATA SbPlatformData; + EFI_GUID SetupGuid = SETUP_GUID; + UINTN VarSize; + + VarSize = sizeof(SB_PLATFORM_DATA); + Status = pRS->GetVariable( + L"SbPlatformData", + &SetupGuid, + NULL, + &VarSize, + &SbPlatformData ); + if(!EFI_ERROR(Status) || (Status == EFI_ACCESS_DENIED)) return; +#endif + // + // Disable BIOSWE bit to protect BIOS + // + RESET_PCI8_SB(R_PCH_LPC_BIOS_CNTL, B_PCH_LPC_BIOS_CNTL_BIOSWE); + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PchBiosLockIoTrapCallback +// +// Description: Register an IchnBiosWp callback function to handle TCO BIOSWR SMI +// SMM_BWP and BLE bits will be set here +// +// Input: DispatchHandle Not used +// DispatchContext Not used +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID PchBiosLockIoTrapCallback ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *DispatchContext ) +{ + EFI_STATUS Status; + EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext; + EFI_HANDLE IchnHandle = NULL; + + if (READ_PCI8_SB(R_PCH_LPC_BIOS_CNTL) & B_PCH_LPC_BIOS_CNTL_BLE) { + return; + } + + if ((DispatchContext->Type != WriteTrap) || (DispatchContext->WriteData != PCH_BWP_SIGNATURE)) { + return; + } + + if (gIchnDispatch == NULL) { + return; + } + +#if defined NvramSmiSupport && NvramSmiSupport +#if SMM_BIOS_WRITE_PROTECT_DISABLE + // + // Set SMM_BWP bit before registering IchnBiosWp + // + SET_PCI8_SB(R_PCH_LPC_BIOS_CNTL, B_PCH_LPC_BIOS_CNTL_SMM_BWP); +#endif +#endif + // + // Register an IchnBiosWp callback function to handle TCO BIOSWR SMI + // + IchnContext.Type = IchnBiosWp; + Status = gIchnDispatch->Register ( + gIchnDispatch, + PchBiosWpCallback, + &IchnContext, + &IchnHandle + ); + ASSERT_EFI_ERROR (Status); + + return; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbChildDispatcher +// +// Description: South Bridge SMM Child Dispatcher Handler. +// +// Input: SmmImageHandle - +// *CommunicationBuffer - OPTIONAL +// *SourceSize - OPTIONAL +// +// Output: EFI_STATUS +// +// Modified: +// +// Referrals: EfiSmmSwDispatch EfiSmmSxDispatch +// +// Notes: Here is the control flow of this function: +// 1. Read SMI source status registers. +// 2. If source, call handler. +// 3. Repeat #2 for all sources registered. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SbChildDispatcher ( +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else + IN EFI_HANDLE SmmImageHandle, + IN OUT VOID *CommunicationBuffer OPTIONAL, + IN OUT UINTN *SourceSize OPTIONAL ) +#endif +{ + if (GetSbSmiContext()) SbSmiHandler(); + + return EFI_HANDLER_SUCCESS; +} + +//<AMI_PHDR_START> //EIP104199 >> +//---------------------------------------------------------------------------- +// +// Procedure: DummyTcoSmiCallback +// +// Description: +// +// Input: +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +static VOID DummyTcoSmiCallback ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext + ) +{ + // Dummy routine for clear any unexpected TCO SMIs status. +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RegisterAllTcoSmiDummyHandler +// +// Description: +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID RegisterAllTcoSmiDummyHandler ( VOID ) +{ + EFI_STATUS Status; + EFI_HANDLE IchnHandle[12]; + EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext[12]; + UINT8 Index=0; + + IchnContext[0].Type = IchnMch; + IchnContext[1].Type = IchnPme; + IchnContext[2].Type = IchnRtcAlarm; + IchnContext[3].Type = IchnRingIndicate; + IchnContext[4].Type = IchnAc97Wake; + IchnContext[5].Type = IchnSerialIrq; + IchnContext[6].Type = IchnY2KRollover; + IchnContext[7].Type = IchnTcoTimeout; + IchnContext[8].Type = IchnOsTco; + IchnContext[9].Type = IchnNmi; + IchnContext[10].Type = IchnIntruderDetect; + IchnContext[11].Type = IchnBiosWp; + + for(Index = 0; Index<12; Index++){ + Status = gIchnDispatch->Register ( + gIchnDispatch, + DummyTcoSmiCallback, + &IchnContext[Index], + &IchnHandle[Index] + ); + ASSERT_EFI_ERROR (Status); + } +} + //EIP104199 << +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InSmmFunction +// +// Description: Installs North Bridge SMM Child Dispatcher Handler. +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InSmmFunction ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + AMI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *PowerButton; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + AMI_SMM_POWER_BUTTON_DISPATCH_CONTEXT DispatchContext = {EfiPowerButtonEntry}; + EFI_HANDLE RootHandle; +#else + AMI_SMM_POWER_BUTTON_DISPATCH_CONTEXT DispatchContext = {PowerButtonEntry}; + EFI_SMM_BASE_PROTOCOL *SmmBaseProtocol; +#endif + EFI_HANDLE Handle = NULL; + EFI_STATUS Status; + AMI_S3_SAVE_PROTOCOL *BootScriptSave; + + EFI_HANDLE DummyHandle = NULL; +#if SB_PCIE_ERROR_LOG_SUPPORT + EFI_SM_ELOG_PROTOCOL *GenericElogProtocol = NULL; + AMI_SMM_SW_DISPATCH_CONTEXT SbErrorLogS3PatchContext = {SW_SMI_SB_EL_S3}; + EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext; +#endif + EFI_SMM_ICHN_DISPATCH_EX_CONTEXT IchnExContext; + EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL *pIchnExDispatch; + + SB_SETUP_DATA *SbSetupData = NULL; + UINTN VariableSize = sizeof(SB_SETUP_DATA); + DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy; + EFI_HANDLE SwHandle = NULL; + AMI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch; +// AMI_SMM_SW_DISPATCH_CONTEXT SwContext; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + EFI_SMM_SYSTEM_TABLE2 *pSmst2; +#endif + EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *PchIoTrap; + EFI_HANDLE PchIoTrapHandle; + EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext; + // + // Locate PCH Platform Policy protocol + // + Status = pBS->LocateProtocol ( &gDxePchPlatformPolicyProtocolGuid, \ + NULL, \ + &PchPlatformPolicy); + if (EFI_ERROR (Status)) return Status; + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = InitAmiSmmLib( ImageHandle, SystemTable ); + + // We are in SMM, retrieve the pointer to SMM System Table + Status = gSmmBase2->GetSmstLocation( gSmmBase2, &pSmst2); + if (EFI_ERROR(Status)) return EFI_UNSUPPORTED; + +#else + Status = pBS->LocateProtocol( &gEfiSmmBaseProtocolGuid, \ + NULL, \ + &SmmBaseProtocol ); +#endif + if (EFI_ERROR(Status)) return Status; + + + Status = pBS->LocateProtocol( AMI_S3_SAVE_PROTOCOL_GUID, \ + NULL, \ + &BootScriptSave ); + + Status = pBS->AllocatePool( EfiBootServicesData, \ + VariableSize, \ + &SbSetupData ); + + GetSbSetupData( pRS, SbSetupData, FALSE ); + + gPchWakeOnLan = (SbSetupData->PchWakeOnLan == 1) ? TRUE : FALSE; + gIsLastState = (SbSetupData->LastState == 2) ? TRUE : FALSE; + + Status = pBS->FreePool( SbSetupData ); + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = pSmst2->SmmLocateProtocol( &gEfiSmmPowerButtonDispatch2ProtocolGuid, \ + NULL, \ + &PowerButton ); +#else + Status = pBS->LocateProtocol( + &gEfiSmmPowerButtonDispatchProtocolGuid, + NULL, + &PowerButton + ); +#endif + + if (EFI_ERROR(Status)) return Status; + + Status = PowerButton->Register( PowerButton, + SBPwrBtnHandler, + &DispatchContext, + &Handle ); + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = pSmst2->SmmLocateProtocol( &gEfiSmmSwDispatch2ProtocolGuid, \ + NULL, \ + &SwDispatch ); +#else + Status = pBS->LocateProtocol( &gSwDispatchProtocolGuid, \ + NULL, \ + &SwDispatch ); +#endif + + if (EFI_ERROR(Status)) return Status; + + Status = pBS->LocateProtocol ( &gIchnDispatchProtocolGuid, \ + NULL, \ + &gIchnDispatch ); + if (EFI_ERROR(Status)) return Status; + +#if REGISTER_ALL_TCO_SMI_IN_DUMMY //EIP104199 >> +//Please define this token if need support this function. + RegisterAllTcoSmiDummyHandler(); +#endif //EIP104199 << + +#if SB_PCIE_ERROR_LOG_SUPPORT + Status = pBS->LocateProtocol( &gElogProtocolGuid, + NULL, + &GenericElogProtocol ); + if (!EFI_ERROR (Status)) { + + Status = SwDispatch->Register( SwDispatch, \ + InitSbSmiLogicHandler, \ + &SbErrorLogS3PatchContext, \ + &Handle ); + if (EFI_ERROR(Status)) return Status; + + ASSERT_EFI_ERROR (Status); + + IchnContext.Type = IchnNmi; + Status = gIchnDispatch->Register( gIchnDispatch, \ + SBErrLogHandler, \ + &IchnContext, \ + &Handle ); + ASSERT_EFI_ERROR (Status); + + Status = pBS->InstallProtocolInterface( &DummyHandle, \ + &gSbPcieErrorLogDispatchProtocolGuid, \ + EFI_NATIVE_INTERFACE, \ + &gEfiSbPcieErrorLogDispatchProtocol ); + } + +#endif + + if (PchPlatformPolicy->LockDownConfig->GpioLockDown == PCH_DEVICE_ENABLE) { + Status = pBS->LocateProtocol( &gEfiSmmIchnExDispatchProtocolGuid, \ + NULL, \ + &pIchnExDispatch ); + if (!EFI_ERROR(Status)) { + IchnExContext.Type = IchnExGpioUnlock; + Status = pIchnExDispatch->Register( pIchnExDispatch, \ + SbIchnExGpioUnlockSmiHandler, \ + &IchnExContext, \ + &Handle ); + } + } + + if (PchPlatformPolicy->LockDownConfig->BiosLock == PCH_DEVICE_ENABLE) { + /// + /// Locate the PCH IO TRAP Dispatch protocol + /// + PchIoTrapHandle = NULL; + Status = pBS->LocateProtocol (&gEfiSmmIoTrapDispatchProtocolGuid, NULL, &PchIoTrap); + ASSERT_EFI_ERROR (Status); + + if (!EFI_ERROR(Status)) { + /// + /// Register BIOS Lock IO Trap SMI handler + /// + PchIoTrapContext.Type = WriteTrap; + PchIoTrapContext.Length = 4; + PchIoTrapContext.Address = PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress; + PchIoTrapContext.Context = NULL; + PchIoTrapContext.MergeDisable = FALSE; + Status = PchIoTrap->Register ( + PchIoTrap, + PchBiosLockIoTrapCallback, + &PchIoTrapContext, + &PchIoTrapHandle ); + if (EFI_ERROR(Status)) return Status; + + if ((PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress == 0) && + (PchIoTrapContext.Address == 0)) { + TRACE((TRACE_ALWAYS, "Invalid PchIoTrapContext.Address!!!\n")); + } else { + if ((PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != 0) && + (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != PchIoTrapContext.Address)) { + TRACE((TRACE_ALWAYS, "Invalid PchIoTrapContext.Address!!!\n")); + } else { + PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress = PchIoTrapContext.Address; + } + } + } + + } + + Status = pBS->InstallProtocolInterface( &DummyHandle, \ + &gAmiSbSmiProtocolGuid, \ + EFI_NATIVE_INTERFACE, \ + NULL ); + + // Register Callbacks +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = pSmst2->SmiHandlerRegister( SbChildDispatcher, \ + NULL, \ + &RootHandle ); +#else + Status = SmmBaseProtocol->RegisterCallback( SmmBaseProtocol, \ + ImageHandle, \ + SbChildDispatcher, \ + FALSE, \ + FALSE ); +#endif + + // Update SMM Runtime Service Table + pRS->ResetSystem = gSmmResetSystem; + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: NotInSmmFunction +// +// Description: This function is called from outside of SMM during SMM registration. +// +// Input: IN EFI_HANDLE ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS NotInSmmFunction( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) +{ + UINT16 Value = 0; + +#if defined PowerButton_SUPPORT && PowerButton_SUPPORT == 0 + //Clear All PM Statuses + Value = IoRead16(PM_BASE_ADDRESS); + IoWrite16(PM_BASE_ADDRESS,Value); + + //Enable PowerButton and Global Enable + IoWrite16(PM_BASE_ADDRESS + 0x02, BIT05 + BIT08); +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitializeSBSmm +// +// Description: Installs North Bridge SMM Child Dispatcher Handler. +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InitializeSBSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + InitAmiLib(ImageHandle, SystemTable); + + gSmmResetSystem = pRS->ResetSystem; + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = SystemTable->BootServices->LocateProtocol( \ + &gEfiSmmBase2ProtocolGuid, \ + NULL, \ + &gSmmBase2 ); + ASSERT_EFI_ERROR(Status); +#endif + + return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction); +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBSMI.cif b/Chipset/SB/SBSMI.cif new file mode 100644 index 0000000..45f5dbb --- /dev/null +++ b/Chipset/SB/SBSMI.cif @@ -0,0 +1,12 @@ +<component> + name = "SB SMI" + category = ModulePart + LocalRoot = "Chipset\SB" + RefName = "SBSMI" +[files] +"SBSMI.sdl" +"SBSMI.c" +"SBSMI.h" +"SBSMI.mak" +"SBSMI.dxs" +<endComponent> diff --git a/Chipset/SB/SBSMI.dxs b/Chipset/SB/SBSMI.dxs new file mode 100644 index 0000000..eeaa9c4 --- /dev/null +++ b/Chipset/SB/SBSMI.dxs @@ -0,0 +1,84 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.dxs 3 8/13/12 10:31a Victortu $ +// +// $Revision: 3 $ +// +// $Date: 8/13/12 10:31a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.dxs $ +// +// 3 8/13/12 10:31a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement BIOS Lock function. +// [Files] SBCspLib.h, SBDxe.c, SBSMI.c, SBSMI.dxs, SBSMI.sdl +// +// 2 4/25/12 9:27a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove unnecessary dependence. +// [Files] AcpiModeEnable.dxs; SBSMI.dxs; SleepSmi.dxs +// +// 1 2/08/12 8:31a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SBSmi.dxs +// +// Description: This file is the dependency file for the South Bridge SMI +// handler. +// +//<AMI_FHDR_END> +//************************************************************************* +#include <token.h> + +#include <Protocol\SmmSwDispatch.h> + +#include <Edk\Foundation\Framework\Protocol\SmmIchnDispatch\SmmIchnDispatch.h> +#include <ReferenceCode\Chipset\LynxPoint\Protocol\SmmIchnDispatchEx\SmmIchnDispatchEx.h> +#include <ReferenceCode\Chipset\LynxPoint\Protocol\SmmIoTrapDispatch\SmmIoTrapDispatch.h> +#if SB_PCIE_ERROR_LOG_SUPPORT +#include <Protocol\GenericElog.h> +#endif + +DEPENDENCY_START +#if SB_PCIE_ERROR_LOG_SUPPORT + EFI_SM_ELOG_PROTOCOL_GUID AND +#endif + EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND + EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID AND + EFI_SMM_ICHN_DISPATCH_PROTOCOL_GUID AND + EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBSMI.h b/Chipset/SB/SBSMI.h new file mode 100644 index 0000000..d6e8542 --- /dev/null +++ b/Chipset/SB/SBSMI.h @@ -0,0 +1,77 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.h 4 12/30/13 5:59a Barretlin $ +// +// $Revision: 4 $ +// +// $Date: 12/30/13 5:59a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.h $ +// +// 4 12/30/13 5:59a Barretlin +// [TAG] EIP144559 +// [Category] Improvement +// [Description] S3 can't resume via USB KB & MS under usb3.0 port in +// special case +// [Files] SBSMI.c SBSMI.h SBGeneric.c +// +// 3 4/19/13 6:35a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Update GbES02SxWorkaround() and add +// UsbS02SxWorkaround() for SBPwrBtnHandler(). +// [Files] SBSMI.c; SBSMI.h; SBGeneric.c; SBCspLib.h +// +// 1 2/08/12 8:31a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +//************************************************************************* +// +// Name: SBSMI.h +// +// Description: This file contains all definitions for South Bridge SMI +// driver +// +//************************************************************************* +//<AMI_FHDR_END> + +#ifndef _SBSMI_H_ +#define _SBSMI_H_ + +// Type Definition(s) + +// Prototypes +VOID SbSmiHandler ( VOID ); + +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SBSMI.mak b/Chipset/SB/SBSMI.mak new file mode 100644 index 0000000..912df89 --- /dev/null +++ b/Chipset/SB/SBSMI.mak @@ -0,0 +1,80 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.mak 1 2/08/12 8:31a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:31a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.mak $ +# +# 1 2/08/12 8:31a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: SBSMI.MAK +# +# Description: Make file for the SB SMI handler code +# +#<AMI_FHDR_END> +#************************************************************************* +!IFNDEF PI_SPECIFICATION_VERSION +PI_SPECIFICATION_VERSION = 0 +!ENDIF + +all : SBSMI + +SBSMI: $(BUILD_DIR)\SBSMI.mak SBSMIBin + +$(BUILD_DIR)\SBSMI.mak : $(SB_SMI_PATH)\SBSMI.cif $(SB_SMI_PATH)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SB_SMI_PATH)\SBSMI.cif $(CIF2MAK_DEFAULTS) + +SBSMIBin : $(AMIDXELIB) $(AMICSPLib) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SBSMI.mak all\ + "CFLAGS=$(CFLAGS) $(SB_INCLUDES) $(INTEL_PCH_INCLUDES)"\ + OBJECTS="$(SB_SMI_OBJECTS)" \ + GUID=7B8DB049-C7C7-4d3b-809F-926DEE47CCA2\ + ENTRY_POINT=InitializeSBSmm\ +!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A && $(CORE_COMBINED_VERSION) >= 0x4028B + TYPE=BS_DRIVER \ + DEPEX1=$(SB_SMI_PATH)\SBSmi.DXS \ +!ELSE + TYPE=BS_DRIVER \ + DEPEX1=$(SB_SMI_PATH)\SBSmi.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ +!ENDIF + COMPRESS=1 + +# {7B8DB049-C7C7-4d3b-809F-926DEE47CCA2} +# {0x7b8db049, 0xc7c7, 0x4d3b, 0x80, 0x9f, 0x92, 0x6d, 0xee, 0x47, 0xcc, 0xa2} + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/SBSMI.sdl b/Chipset/SB/SBSMI.sdl new file mode 100644 index 0000000..5d97b3c --- /dev/null +++ b/Chipset/SB/SBSMI.sdl @@ -0,0 +1,114 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.sdl 2 8/13/12 10:31a Victortu $ +# +# $Revision: 2 $ +# +# $Date: 8/13/12 10:31a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SB SMI/SBSMI.sdl $ +# +# 2 8/13/12 10:31a Victortu +# [TAG] None +# [Category] Improvement +# [Description] Implement BIOS Lock function. +# [Files] SBCspLib.h, SBDxe.c, SBSMI.c, SBSMI.dxs, SBSMI.sdl +# +# 1 2/08/12 8:31a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "SBSMI_SUPPORT" + Value = "1" + Help = "Main switch to enable SB SMI support in Project" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Master = Yes +End + +TOKEN + Name = "SW_SMI_SB_EL_S3" + Value = "0xb9" + Help = "Value to be written into SMI command register \to enable S3 patched codes" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "SB_PCIE_ERROR_LOG_SUPPORT" + Value = "1" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Token = "ErrorLogging_SUPPORT" "=" "1" + Token = "IpmiLib_SUPPORT" "=" "1" + Token = "SmmRuntime_SUPPORT" "=" "1" +End + +TOKEN + Name = "SMM_BIOS_WRITE_PROTECT_DISABLE" + Value = "1" + Help = "SMM BIOS Write Protect Disable(SMM_BWP, B0:D31:F0 Reg#DCh[5]).\0 = BIOS region SMM protection is disabled.\1 = BIOS region SMM protection is enabled." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes + Token = "NvramSmiSupport" "=" "1" +End + +PATH + Name = "SB_SMI_PATH" + Path = "Chipset\SB" +End + +MODULE + Help = "Includes SBSMI.mak to Project" + File = "SBSMI.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SBSMI.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +ELINK + Name = "SB_SMI_OBJECTS" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\$(SB_CHIPSET_DIR)\SBSMI.obj" + Parent = "SB_SMI_OBJECTS" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/SBSmm.c b/Chipset/SB/SBSmm.c new file mode 100644 index 0000000..1c1337a --- /dev/null +++ b/Chipset/SB/SBSmm.c @@ -0,0 +1,648 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBSmm.c 2 3/19/13 8:20a Scottyang $ +// +// $Revision: 2 $ +// +// $Date: 3/19/13 8:20a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SBSmm.c $ +// +// 2 3/19/13 8:20a Scottyang +// [TAG] EIP118158 +// [Category] Improvement +// [Description] Correct SBLib_CmosRead () offset. +// [Files] SmiHandlerPorting2.c, SBDxe.c, SBGeneric.c, SBSmm.c, +// SmiHandlerPorting.c +// +// 1 2/08/12 8:24a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: SBSMM.C +// +// Description: This file contains code for SMM control - the +// protocol defined by Framework +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + + +// Module specific Includes +#include <Efi.h> +#include <token.h> +#include <HOB.h> +#include <DXE.h> +#include <AmiLib.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> + +// Used Protocols +#include <Protocol\PciRootBridgeIo.h> +#include <Protocol\BootScriptSave.h> +#include <Protocol\SmmAccess.h> +// Produced Protocols +#include <Protocol\SmmControl.h> +#if PI_SPECIFICATION_VERSION >= 0x0001000A +#include <Protocol\SmmControl2.h> +#endif + +// Function Prototypes +typedef struct { + UINT8 IoReg8; + UINT32 Value32; +} PMIO_BOOT_SCRIPT_STRUCT; + +EFI_STATUS +SBSMM_ClearSMI( + IN EFI_SMM_CONTROL_PROTOCOL *This, + IN BOOLEAN Periodic OPTIONAL +); + +VOID SBSMM_BootScript(); + +EFI_STATUS +SBSMM_TriggerSMI( + IN EFI_SMM_CONTROL_PROTOCOL *This, + IN OUT INT8 *ArgumentBuffer OPTIONAL, + IN OUT UINTN *ArgumentBufferSize OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL +); + +EFI_STATUS +SBSMM_GetRegisterInfo( + IN EFI_SMM_CONTROL_PROTOCOL *This, + IN OUT EFI_SMM_CONTROL_REGISTER *SmiRegister +); + +VOID SaveSmiEnBeforeBoot ( + IN EFI_EVENT Event, + IN VOID *Context +); + +#if PI_SPECIFICATION_VERSION >= 0x0001000A +EFI_STATUS SBSMM_TriggerSMI2( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN OUT UINT8 *CommandPort OPTIONAL, + IN OUT UINT8 *DataPort OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL +); + +EFI_STATUS SBSMM_ClearSMI2( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN BOOLEAN Periodic OPTIONAL +); +#endif + +// GUID Definitions +EFI_GUID gEfiSmmAccessProtocolGuid = EFI_SMM_ACCESS_PROTOCOL_GUID; +EFI_GUID gEfiSmmControlProtocolGuid = EFI_SMM_CONTROL_PROTOCOL_GUID; + + +// Global variable declarations +//-extern EFI_BOOT_SCRIPT_SAVE_PROTOCOL *gBootScriptSave; +EFI_SMM_ACCESS_PROTOCOL *gSmmAccess; +EFI_SMM_CONTROL_PROTOCOL mEfiSmmControlProtocol = +{ + SBSMM_TriggerSMI, + SBSMM_ClearSMI, + SBSMM_GetRegisterInfo, + 0 +}; + +EFI_SMM_CONTROL_PROTOCOL *gEfiSmmControlProtocol = NULL; + +#if PI_SPECIFICATION_VERSION >= 0x0001000A +EFI_SMM_CONTROL2_PROTOCOL gEfiSmmControl2Protocol = +{ + SBSMM_TriggerSMI2, + SBSMM_ClearSMI2, + 0 +}; +#endif + +// Portable Constants + +// Function Definition + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSMM_EnableSWSmi +// +// Description: This function programs the SB chipset registers to enable +// S/W SMI generation +// +// Input: None +// +// Output: EFI_SUCCESS Always +// +// Notes: CHIPSET AND/OR BOARD PORTING NEEDED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +SBSMM_EnableSWSmi(VOID) +{ +/* + UINT32 Value32; + + SBSMM_ClearSMI(&mEfiSmmControlProtocol, FALSE); + SBSMM_BootScript(); + +//Porting Required. Include code to enable S/W SMI generation + Value32 = IoRead32(PM_BASE_ADDRESS + ICH_IOREG_SMI_EN) | (BIT05 | BIT00); + IoWrite32(PM_BASE_ADDRESS + ICH_IOREG_SMI_EN, Value32); //Enable global SMIs. + + Value32 = 0x00002002B; + BOOT_SCRIPT_S3_IO_WRITE_MACRO(gBootScriptSave, + EfiBootScriptWidthUint32, + PM_BASE_ADDRESS + ICH_IOREG_SMI_EN, + 1, + &Value32); +//End Porting +*/ + + return EFI_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSMM_TriggerSMI +// +// Description: This function generates a software SMI by writing the provided +// byte value into the software SMI generation register +// +// Input: *This Pointer to the SMM control protocol +// *ArgumentBuffer Contains the value to be written to the +// S/W SMI port. Currently supports byte only +// and this is a optional pointer +// *ArgumentBufferSize Optional. Valid value is 1 +// Periodic Boolean indicating the nature of generation +// TRUE means periodic generation depending on +// timing value provided in the next variable +// CURRENTLY NOT SUPPORTED. EXPECTS FALSE +// ActivationInterval Optional. NOT SUPPORTED +// +// Output: EFI_STATUS +// EFI_SUCCESS S/W SMI triggered successfully +// EFI_INVALID_PARAMETER If Periodic is TRUE or when +// (ArgumentBuffer is not NULL and +// ArgumentBufferSize is not 1) +// +// Notes: CHIPSET AND/OR BOARD PORTING NEEDED +// Here is the control flow of this function: +// 1. If Periodic was TRUE, return EFI_INVALID_PARAMETER. +// 2. If ArgumentBuffer == NULL, use 0xFF as data. +// 3. If not NULL, if valid byte, use it as data. Otherwise +// return EFI_INVALID_PARAMETER. +// 4. Deactive any active SMI status. +// 5. Write the data to the SMI trigger port. +// 6. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SBSMM_TriggerSMI( + IN EFI_SMM_CONTROL_PROTOCOL *This, + IN OUT INT8 *ArgumentBuffer OPTIONAL, + IN OUT UINTN *ArgumentBufferSize OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL +) +{ + UINT8 Data; + EFI_STATUS Status = EFI_SUCCESS; + + if (Periodic) + return EFI_INVALID_PARAMETER; + + if (ArgumentBuffer == NULL) + { + Data = 0xFF; // If no data given, use 0xFF to trigger SMI. + } + else + { + if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) + return EFI_INVALID_PARAMETER; // Only able to send 1 byte. + Data = *ArgumentBuffer; + } + + // Porting Required. Include code to generate S/W SMI + WRITE_IO32_PM(ICH_IOREG_SMI_EN, (READ_IO32_PM(ICH_IOREG_SMI_EN) | (BIT5 | BIT0))); + WRITE_IO8(SW_SMI_IO_ADDRESS, Data); // This triggers SMI + // Porting End + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSMM_ClearSMI +// +// Description: This function clears all SMI status registers and generates +// End-of-SMI (EOS) +// +// Input: *This Pointer to the SMM control protocol +// Periodic Boolean indicating the nature of clearing +// TRUE means periodic SMI clearing +// CURRENTLY NOT SUPPORTED. EXPECTS FALSE +// +// Output: EFI_STATUS +// EFI_SUCCESS SMI status successfully cleared +// EFI_INVALID_PARAMETER If Periodic is TRUE +// +// Notes: CHIPSET AND/OR BOARD PORTING NEEDED +// Here is the control flow of this function: +// 1. If Periodic was TRUE, return EFI_INVALID_PARAMETER. +// 2. Clear SMI Status on all appropriate SMI status registers +// 3. Set EOS. +// 4. Return EFI_SUCCESS. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +SBSMM_ClearSMI( + IN EFI_SMM_CONTROL_PROTOCOL *This, + IN BOOLEAN Periodic OPTIONAL +) +{ + + if (Periodic) return EFI_INVALID_PARAMETER; + + // Porting Required. Include code to clear software SMI status only + WRITE_IO8_PM(ICH_IOREG_SMI_STS, 0x20); // 0x34 + + + //Set EOS + SET_IO8_PM(ICH_IOREG_SMI_EN, BIT01); + + // Porting end + + return EFI_SUCCESS; +} + +#if PI_SPECIFICATION_VERSION >= 0x0001000A +EFI_STATUS SBSMM_TriggerSMI2( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN OUT UINT8 *CommandPort OPTIONAL, + IN OUT UINT8 *DataPort OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN DataSize = 1; + UINT8 Data; + + if (Periodic) + return EFI_INVALID_PARAMETER; + + if (CommandPort == NULL) + { + Data = 0xFF; // If no data given, use 0xFF to trigger SMI. + } + else + { + Data = *CommandPort; + } + + Status = gEfiSmmControlProtocol->Trigger(gEfiSmmControlProtocol, &Data, &DataSize, FALSE, 0); + + return Status; +} + +EFI_STATUS SBSMM_ClearSMI2( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN BOOLEAN Periodic OPTIONAL +) +{ + if (Periodic) + return EFI_INVALID_PARAMETER; + + gEfiSmmControlProtocol->Clear(gEfiSmmControlProtocol, FALSE); + + return EFI_SUCCESS; +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSMM_BootScript +// +// Description: This function clears all SMI enables registers and generates +// End-of-SMI (EOS) in Boot Script +// +// Input: None +// +// Output: None +// +// Notes: CHIPSET AND/OR BOARD PORTING NEEDED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SBSMM_BootScript(VOID) +{ +/* + UINT16 i; + UINT16 j; + +// 0x00-0x03 +// 0x28-0x2B +// 0x2C-0x2F +// 0x20-0x23 +// 0x24-0x27 +// 0x38-0x3B +// 0x34-0x37 + PMIO_BOOT_SCRIPT_STRUCT PMIoBootScriptTbl[] = { \ + {ICH_IOREG_PM1_STS, 0x01000831},\ + {ICH_IOREG_GPE0_EN, 0},\ + {ICH_IOREG_GPE0_EN + 4, 0},\ + {ICH_IOREG_GPE0_STS, 0xFFFFFFFF},\ + {ICH_IOREG_GPE0_STS + 4, 0xFFFFFFFF},\ + {ICH_IOREG_ALT_GP_SMI_EN + 4, 0xFFFF0000},\ + {ICH_IOREG_SMI_STS, 0xFFFFFFF}}; + + // Use boot script to do : + // 1. Clear PM1 statuses except power button & RTC statuses and + // enable power button, OS will setup it as a wake event anyway. + // 2. disable GPE enables. + // 3. disable SMI enables and clear SMI statuses. + // 4. Enable SCI (SCI_EN). + + j = sizeof(PMIoBootScriptTbl) / sizeof(PMIO_BOOT_SCRIPT_STRUCT); + for (i = 0; i < j; i++) + BOOT_SCRIPT_S3_IO_WRITE_MACRO( \ + gBootScriptSave, \ + EfiBootScriptWidthUint32, \ + PM_BASE_ADDRESS + PMIoBootScriptTbl[i].IoReg8,\ + 1, \ + &PMIoBootScriptTbl[i].Value32 ); + + + // Enable SCI. + i = 1; + j = 0xffff; + BOOT_SCRIPT_S3_IO_READ_WRITE_MACRO( \ + gBootScriptSave, \ + EfiBootScriptWidthUint16, \ + PM_BASE_ADDRESS + ICH_IOREG_PM1_CNT, + &i, \ + &j ); +*/ +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SaveSmiEnBeforeBoot +// +// Description: This function uses boot script to all SMI enables before boot +// to OS. +// +// Input: Event - Event of callback +// Context - Context of callback. +// +// Output: None +// +// Notes: CHIPSET AND/OR BOARD PORTING NEEDED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SaveSmiEnBeforeBoot ( + IN EFI_EVENT Event, + IN VOID *Context ) +{ +/* + // Porting Required. + UINT32 Buffer32; + UINT32 PCIAdd; + UINT8 Data8; + + // Remove SLP_SMI from boot script if needed. + Buffer32 = READ_IO32_PM(ICH_IOREG_SMI_EN) & ~(BIT04 | BIT06); + + BOOT_SCRIPT_S3_IO_WRITE_MACRO( \ + gBootScriptSave, \ + EfiBootScriptWidthUint32, \ + PM_BASE_ADDRESS + ICH_IOREG_SMI_EN, \ + 1, \ + &Buffer32 ); + + + // Save NMI2SMI_EN, TCO_TMR_HLT and TCO_LOCK + Data8 = READ_IO8_TCO(ICH_IOREG_TCO1_CNT + 1) & (BIT01 | BIT03 | BIT04); + BOOT_SCRIPT_S3_IO_WRITE_MACRO( \ + gBootScriptSave, \ + EfiBootScriptWidthUint8, \ + TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1, \ + 1, \ + &Data8 ); + + + PCIAdd = EFI_SB_PCI_CFG_ADDRESS(LPC_BUS, LPC_DEVICE, LPC_FUNC, ICH_REG_LPC_VID); + + Data8 = READ_PCI8_SB(ICH_REG_GEN_PMCON_1); + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( \ + gBootScriptSave, \ + EfiPciIoWidthUint8, \ + EFI_SB_PCI_CFG_ADDRESS(LPC_BUS, LPC_DEVICE, LPC_FUNC, ICH_REG_GEN_PMCON_1), \ + 1, \ + &Data8 + ); + + Data8 = READ_PCI8_SB(ICH_REG_GEN_PMCON_3); + Data8 &= ~(BIT01); + BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO( \ + gBootScriptSave, \ + EfiPciIoWidthUint8, \ + EFI_SB_PCI_CFG_ADDRESS(LPC_BUS, LPC_DEVICE, LPC_FUNC, ICH_REG_GEN_PMCON_3), \ + 1, \ + &Data8 + ); +*/ + + // Porting End + pBS->CloseEvent(Event); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSMM_GetRegisterInfo +// +// Description: This function returns the S/W SMI generation register and +// its status register values +// +// Input: *This Pointer to the SMM control protocol +// SmiRegister Pointer to the SMM control register structure +// +// Output: EFI_UNSUPPORTED +// +// Notes: CHIPSET AND/OR BOARD PORTING NEEDED +// 1. Return EFI_UNSUPPORTED. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +SBSMM_GetRegisterInfo( + IN EFI_SMM_CONTROL_PROTOCOL *This, + IN OUT EFI_SMM_CONTROL_REGISTER *SmiRegister +) +{ + + // Porting Required. Include code to return I/O port to generate S/W SMI + SmiRegister->SmiTriggerRegister = SW_SMI_IO_ADDRESS; + SmiRegister->SmiDataRegister = SW_SMI_IO_ADDRESS + 1; + // Porting End + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: DisableAllSmi +// +// Description: This function disables all SMI's which can be caused by +// SouthBridge, include global SMI. +// +// Input: None +// +// Output: None +// +// Notes: CHIPSET AND/OR BOARD PORTING NEEDED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID DisableAllSmi(VOID) +{ + //--WRITE_IO16_PM(ICH_IOREG_PM1_EN, 0x0000); // 0x02 + //--WRITE_IO32_PM(ICH_IOREG_GPE0_EN, 0x00000000); // 0x2C + //--WRITE_IO32_PM(ICH_IOREG_SMI_EN, 0x00000000); // 0x30 + //--WRITE_IO32_PM(ICH_IOREG_ALT_GP_SMI_EN, 0x00000000); // 0x38 +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SBSMM_Init +// +// Description: This function is invoked from SB DXE to initialize SMM +// related stuff in NorthBridge and install appropriate +// SMM protocols such as SMM Access & SMM Control +// +// Input: ImageHandle Image handle +// SystemTable Pointer to the system table +// +// Output: Return Status based on errors that occurred while waiting for +// time to expire. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +SbSmmInit( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_EVENT mEvent; + UINT8 Value; + + PROGRESS_CODE(DXE_SB_SMM_INIT); + + Status = pBS->LocateProtocol(&gEfiSmmControlProtocolGuid, NULL, &gEfiSmmControlProtocol); + if (EFI_ERROR(Status)) + { + Status = pBS->LocateProtocol(&gEfiSmmAccessProtocolGuid, NULL, &gSmmAccess); + ASSERT_EFI_ERROR(Status); + + // Disable all SMI enables here + DisableAllSmi(); + + //Must read RTC Reg C to be able to clear SMM RTC alarm flag. + Value = SBLib_CmosRead(0x0C); + + // Clear all SMI status here. + //--WRITE_IO16_PM(ICH_IOREG_PM1_STS, 0xCF31); // 0x00 + //--WRITE_IO32_PM(ICH_IOREG_GPE0_STS, 0xFFFFFFFF); // 0x20 + //--WRITE_IO32_PM(ICH_IOREG_GPE0_STS + 4, 0xffffffff); // 0x24 + //--WRITE_IO16_PM(ICH_IOREG_ALT_GP_SMI_STS, 0xFFFF); // 0x3A + //--WRITE_IO16_PM(ICH_IOREG_DEVACT_STS, 0xFFFF); // 0x44 + //--WRITE_IO16_TCO(ICH_IOREG_TCO1_STS, 0xFFFF); // 0x04 + //--WRITE_IO16_TCO(ICH_IOREG_TCO2_STS, (0xFFFF)); // 0x06 + //--WRITE_IO32_PM(ICH_IOREG_SMI_STS, 0xFFFFFFFF); // 0x34 + + // Enable S/W SMI Generation + SBSMM_EnableSWSmi(); + + Status = CreateReadyToBootEvent( TPL_NOTIFY, \ + SaveSmiEnBeforeBoot, \ + NULL, \ + &mEvent ); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallMultipleProtocolInterfaces( + &TheImageHandle, + &gEfiSmmControlProtocolGuid, + &mEfiSmmControlProtocol, +#if PI_SPECIFICATION_VERSION >= 0x0001000A + &gEfiSmmControl2ProtocolGuid, + &gEfiSmmControl2Protocol, +#endif + NULL, + NULL + ); + ASSERT_EFI_ERROR(Status); + } + else + { +#if PI_SPECIFICATION_VERSION >= 0x0001000A + Status = pBS->InstallMultipleProtocolInterfaces( + &TheImageHandle, + &gEfiSmmControl2ProtocolGuid, + &gEfiSmmControl2Protocol, + NULL, + NULL + ); + ASSERT_EFI_ERROR(Status); +#endif + } + + return Status; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SataDriver/SataDriver.cif b/Chipset/SB/SataDriver/SataDriver.cif new file mode 100644 index 0000000..d0e9cac --- /dev/null +++ b/Chipset/SB/SataDriver/SataDriver.cif @@ -0,0 +1,11 @@ +<component> + name = "PchSataDriver" + category = ModulePart + LocalRoot = "Chipset\SB\SataDriver\" + RefName = "SataDriver" +[files] +"SataDriver.sdl" +"SataDriver.mak" +"SataDriver.dxs" +"SataDriver.efi" +<endComponent> diff --git a/Chipset/SB/SataDriver/SataDriver.dxs b/Chipset/SB/SataDriver/SataDriver.dxs new file mode 100644 index 0000000..a53fc90 --- /dev/null +++ b/Chipset/SB/SataDriver/SataDriver.dxs @@ -0,0 +1,64 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SataDriver/SataDriver.dxs 1 2/08/12 8:37a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:37a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SataDriver/SataDriver.dxs $ +// +// 1 2/08/12 8:37a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: SataDriver.dxs +// +// Description: Sata UEFI Driver. +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> +#include "AutoGen.h" +#include "DxeDepex.h" +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#endif + +#define PCH_EFI_RAID_DRIVER_EXECUTION_GUID \ + { 0x99D5757C, 0xD906, 0x11E0, 0x8D, 0x78, 0x8D, 0xE4, 0x48, 0x24, 0x01, 0x9B } + +DEPENDENCY_START + PCH_EFI_RAID_DRIVER_EXECUTION_GUID +DEPENDENCY_END +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, 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/Chipset/SB/SataDriver/SataDriver.efi b/Chipset/SB/SataDriver/SataDriver.efi Binary files differnew file mode 100644 index 0000000..f8925f1 --- /dev/null +++ b/Chipset/SB/SataDriver/SataDriver.efi diff --git a/Chipset/SB/SataDriver/SataDriver.mak b/Chipset/SB/SataDriver/SataDriver.mak new file mode 100644 index 0000000..8270404 --- /dev/null +++ b/Chipset/SB/SataDriver/SataDriver.mak @@ -0,0 +1,73 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SataDriver/SataDriver.mak 2 1/10/13 8:28a Scottyang $ +# +# $Revision: 2 $ +# +# $Date: 1/10/13 8:28a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SataDriver/SataDriver.mak $ +# +# 2 1/10/13 8:28a Scottyang +# [TAG] None +# [Category] Improvement +# [Description] Create token for SataDriver path. +# [Files] SataDriver.sdl, SataDriver.mak +# +# 1 2/08/12 8:37a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: SatsDriver.mak +# +# Description: Make file for the Sata Uefi Driver. +# +#<AMI_FHDR_END> +#************************************************************************* +all : $(BUILD_DIR)\SataDriver.ffs + +SataDriver_INCLUDES=\ + $(INTEL_PCH_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(EDK_INCLUDES) + +$(BUILD_DIR)\SataDriver.ffs : $(OEM_SATA_EFI_DRIVER_FILE) $(SataDriver_DIR)\$(@B).mak Core\FFS.mak + $(MAKE) /$(MAKEFLAGS) /f Core\FFS.mak \ + CPFLAGS="$(GLOBAL_DEFINES) /D TIANO_RELEASE_VERSION=0x00080006 $(EXTRA_DEFINES) $(SataDriver_INCLUDES)" \ + BUILD_DIR=$(BUILD_DIR) SOURCE_DIR=$(SataDriver_DIR) \ + GUID=91B4D9C1-141C-4824-8D02-3C298E36EB3F\ + NAME=$(@B)\ + TYPE=EFI_FV_FILETYPE_DRIVER \ + DEPEX1=$(SataDriver_DIR)\SataDriver.dxs\ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ + PEFILE=$(OEM_SATA_EFI_DRIVER_FILE) FFSFILE=$@ COMPRESS=1 \ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, 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/Chipset/SB/SataDriver/SataDriver.sdl b/Chipset/SB/SataDriver/SataDriver.sdl new file mode 100644 index 0000000..ba1dd02 --- /dev/null +++ b/Chipset/SB/SataDriver/SataDriver.sdl @@ -0,0 +1,88 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SataDriver/SataDriver.sdl 3 1/10/13 8:28a Scottyang $ +# +# $Revision: 3 $ +# +# $Date: 1/10/13 8:28a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SataDriver/SataDriver.sdl $ +# +# 3 1/10/13 8:28a Scottyang +# [TAG] None +# [Category] Improvement +# [Description] Create token for SataDriver path. +# [Files] SataDriver.sdl, SataDriver.mak +# +# 2 7/02/12 10:15a Victortu +# [TAG] None +# [Category] Improvement +# [Description] Set SataDriver_SUPPORT enabled by default. +# [Files] SataDriver.sdl +# +# 1 2/08/12 8:37a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = SataDriver_SUPPORT + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Help = "Main switch to enable SataDriver support in Project" +End + +MODULE + Help = "Includes SataDriver.mak to Project" + File = "SataDriver.mak" +End + +PATH + Name = "SataDriver_DIR" + Help = "Sata Uefi Raid Driver." +End + +TOKEN + Name = "OEM_SATA_EFI_DRIVER_FILE" + Value = "$(SataDriver_DIR)\SataDriver.efi" + TokenType = Expression + TargetMAK = Yes +End + +ELINK + Name = "$(BUILD_DIR)\SataDriver.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, 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/Chipset/SB/SataOrom125.bin b/Chipset/SB/SataOrom125.bin Binary files differnew file mode 100644 index 0000000..3da7af5 --- /dev/null +++ b/Chipset/SB/SataOrom125.bin diff --git a/Chipset/SB/SleepSmi.c b/Chipset/SB/SleepSmi.c new file mode 100644 index 0000000..20408a1 --- /dev/null +++ b/Chipset/SB/SleepSmi.c @@ -0,0 +1,457 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.c 4 9/26/12 3:59a Victortu $ +// +// $Revision: 4 $ +// +// $Date: 9/26/12 3:59a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.c $ +// +// 4 9/26/12 3:59a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 3 7/27/12 6:17a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 2 6/13/12 11:29p Victortu +// [TAG] None +// [Category] Improvement +// [Description] Program AfterG3 bit depend the setup question in +// S3/S4/S5. +// [Files] SleepSmi.c +// +// 1 2/08/12 8:30a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SleepSmi.C +// +// Description: Provide functions to register and handle Sleep SMI +// functionality. +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Token.h> +#include <Setup.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +#include <Protocol\SmmBase2.h> +#include <Protocol\SmmSxDispatch2.h> +#else +#include <Protocol\SmmBase.h> +#include <Protocol\SmmSxDispatch.h> +#endif +#include <PchAccess.h> + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +#define AMI_SMM_SX_DISPATCH_PROTOCOL EFI_SMM_SX_DISPATCH2_PROTOCOL +#define AMI_SMM_SX_DISPATCH_CONTEXT EFI_SMM_SX_REGISTER_CONTEXT +#define SMM_CHILD_DISPATCH_SUCCESS EFI_SUCCESS +#else +#define AMI_SMM_SX_DISPATCH_PROTOCOL EFI_SMM_SX_DISPATCH_PROTOCOL +#define AMI_SMM_SX_DISPATCH_CONTEXT EFI_SMM_SX_DISPATCH_CONTEXT +#define SMM_CHILD_DISPATCH_SUCCESS +#endif + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +BOOLEAN gIsLastState = FALSE; +BOOLEAN gPchWakeOnLan = FALSE; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_SMM_BASE2_PROTOCOL *gSmmBase2; +#endif + +// GUID Definition(s) + +EFI_GUID gThisFileGuid = \ + {0x6298fe18, 0xd5ef, 0x42b7, 0xbb, 0xc, 0x29, 0x53, 0x28, 0x3f, 0x57, 0x4}; + // {6298FE18-D5EF-42b7-BB0C-2953283F5704} + +// Protocol Definition(s) + +// External Declaration(s) + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ProgramAfterG3Bit +// +// Description: This function will set AfterG3 bit depend the setup question. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ProgramAfterG3Bit(VOID) +{ + if (gIsLastState) SET_PCI8_SB(SB_REG_GEN_PMCON_3, 1); // 0xA4 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: S1SleepSmiOccurred +// +// Description: This function will be called by EfiSmmSxDispatch when a Sleep +// SMI occurs and the sleep state is S1. +// +// Input: DispatchHandle - SMI dispatcher handle +// *DispatchContext - Pointer to the dispatch context +// +// Output: Nothing +// +// Notes: This function does not need to put the system to sleep. This is +// handled by PutToSleep. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS S1SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID S1SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext ) +#endif +{ + // Porting required if any workaround is needed. + return SMM_CHILD_DISPATCH_SUCCESS; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: S3SleepSmiOccurred +// +// Description: This function will be called by EfiSmmSxDispatch when a Sleep +// SMI occurs and the sleep state is S3. +// +// Input: DispatchHandle - SMI dispatcher handle +// *DispatchContext - Pointer to the dispatch context +// +// Output: Nothing +// +// Notes: This function does not need to put the system to sleep. This is +// handled by PutToSleep. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS S3SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID S3SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext ) +#endif +{ + BOOLEAN IsGpioLocked; + UINT16 LpcDeviceId; + + LpcDeviceId = READ_PCI16_SB(R_PCH_LPC_DEVICE_ID); + + IsGpioLocked = (READ_PCI8_SB(SB_REG_GC) & BIT00)? TRUE:FALSE; + + if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) { + + // Reset GPIO Lockdown Enable (GLE) + if (IsGpioLocked) + RESET_PCI8_SB(SB_REG_GC, BIT00); + + // Set GPIO 60 to low (S3 power) + if (GetPchSeries() == PchLp) { + RESET_IO32( GPIO_BASE_ADDRESS + (GP_IOREG_GP_GPN_CFG1 + GP_GPIO_CONFIG_SIZE*60), ~BIT31); // 0x38 + } else { + RESET_IO32( GPIO_BASE_ADDRESS + GP_IOREG_GP_LVL2, ~0xEFFFFFFF); // 0x38 + } + + // Set GPIO Lockdown Enable (GLE) + if (IsGpioLocked) + SET_PCI8_SB(SB_REG_GC, BIT00); + } + + ProgramAfterG3Bit(); + + return SMM_CHILD_DISPATCH_SUCCESS; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: S4SleepSmiOccurred +// +// Description: This function will be called by EfiSmmSxDispatch when a Sleep +// SMI occurs and the sleep state is S4. +// +// Input: DispatchHandle - SMI dispatcher handle +// *DispatchContext - Pointer to the dispatch context +// +// Output: Nothing +// +// Notes: This function does not need to put the system to sleep. This is +// handled by PutToSleep. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS S4SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID S4SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext ) +#endif +{ + ClearMeWakeSts(); + + ProgramAfterG3Bit(); + + return SMM_CHILD_DISPATCH_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: S5SleepSmiOccurred +// +// Description: This function will be called by EfiSmmSxDispatch when a Sleep +// SMI occurs and the sleep state is S1. +// +// Input: DispatchHandle - SMI dispatcher handle +// *DispatchContext - Pointer to the dispatch context +// +// Output: Nothing +// +// Notes: This function does not need to put the system to sleep. This is +// handled by PutToSleep. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) +EFI_STATUS S5SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +#else +VOID S5SleepSmiOccurred ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext ) +#endif +{ + + ClearMeWakeSts(); + SBLib_BeforeShutdown(); + + if (gPchWakeOnLan) Enable_GbE_PME(); + + // Program AfterG3 bit depend the setup question. + ProgramAfterG3Bit(); + + return SMM_CHILD_DISPATCH_SUCCESS; +} + +//---------------------------------------------------------------------------- +// +// Procedure: InSmmFunction +// +// Description: Install Sleep SMI Handlers for south bridge. +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InSmmFunction ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + EFI_HANDLE hS1Smi; + EFI_HANDLE hS3Smi; + EFI_HANDLE hS4Smi; + EFI_HANDLE hS5Smi; + AMI_SMM_SX_DISPATCH_PROTOCOL *SxDispatch; + AMI_SMM_SX_DISPATCH_CONTEXT S1DispatchContext = {SxS1, SxEntry}; + AMI_SMM_SX_DISPATCH_CONTEXT S3DispatchContext = {SxS3, SxEntry}; + AMI_SMM_SX_DISPATCH_CONTEXT S4DispatchContext = {SxS4, SxEntry}; + AMI_SMM_SX_DISPATCH_CONTEXT S5DispatchContext = {SxS5, SxEntry}; +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + EFI_SMM_SYSTEM_TABLE2 *pSmst2; +#endif + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = InitAmiSmmLib( ImageHandle, SystemTable ); + if (EFI_ERROR(Status)) return Status; + + // We are in SMM, retrieve the pointer to SMM System Table + Status = gSmmBase2->GetSmstLocation( gSmmBase2, &pSmst2); + if (EFI_ERROR(Status)) return EFI_UNSUPPORTED; + + Status = pSmst2->SmmLocateProtocol( &gEfiSmmSxDispatch2ProtocolGuid , \ + NULL, \ + &SxDispatch ); + TRACE((TRACE_ALWAYS, "Smm Locate Protocol gEfiSmmSxDispatch2ProtocolGuid, Status = %r\n",Status)); + +#else + Status = pBS->LocateProtocol( &gEfiSmmSxDispatchProtocolGuid , \ + NULL, \ + &SxDispatch ); +#endif + if (EFI_ERROR(Status)) return Status; + + // Register Sleep SMI Handlers + Status = SxDispatch->Register( SxDispatch, \ + S1SleepSmiOccurred, \ + &S1DispatchContext, \ + &hS1Smi ); + if (EFI_ERROR(Status)) return Status; + + Status = SxDispatch->Register( SxDispatch, \ + S3SleepSmiOccurred, \ + &S3DispatchContext, \ + &hS3Smi ); + if (EFI_ERROR(Status)) return Status; + + Status = SxDispatch->Register( SxDispatch, \ + S4SleepSmiOccurred, \ + &S4DispatchContext, \ + &hS4Smi ); + if (EFI_ERROR(Status)) return Status; + + Status = SxDispatch->Register( SxDispatch, \ + S5SleepSmiOccurred, \ + &S5DispatchContext, \ + &hS5Smi ); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InitSleepSmi +// +// Description: This function Registers Sleep SMI functionality. +// +// Input: ImageHandle - Handle for this FFS image +// *SystemTable- Pointer to the system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InitSleepSmi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + SB_SETUP_DATA *SbSetupData = NULL; + UINTN VariableSize = sizeof(SB_SETUP_DATA); + + InitAmiLib( ImageHandle, SystemTable ); + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = SystemTable->BootServices->LocateProtocol( \ + &gEfiSmmBase2ProtocolGuid, \ + NULL, \ + &gSmmBase2 ); + ASSERT_EFI_ERROR(Status); +#endif + + // Porting Required + // Put the Setup Vairable to SMM if needed. + Status = pBS->AllocatePool( EfiBootServicesData, \ + VariableSize, \ + &SbSetupData ); + ASSERT_EFI_ERROR(Status); + + GetSbSetupData( pRS, SbSetupData, FALSE ); + + gIsLastState = (SbSetupData->LastState == 2) ? TRUE : FALSE; + gPchWakeOnLan = (SbSetupData->PchWakeOnLan == 1) ? TRUE : FALSE; + Status = pBS->FreePool( SbSetupData ); + + // Porting End + + return InitSmmHandler( ImageHandle, SystemTable, InSmmFunction, NULL ); +} + + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SleepSmi.cif b/Chipset/SB/SleepSmi.cif new file mode 100644 index 0000000..98f82e7 --- /dev/null +++ b/Chipset/SB/SleepSmi.cif @@ -0,0 +1,11 @@ +<component> + name = "SleepSmi" + category = ModulePart + LocalRoot = "Chipset\SB" + RefName = "SleepSmi" +[files] +"SleepSmi.sdl" +"SleepSmi.mak" +"SleepSmi.c" +"SleepSmi.dxs" +<endComponent> diff --git a/Chipset/SB/SleepSmi.dxs b/Chipset/SB/SleepSmi.dxs new file mode 100644 index 0000000..d6cf554 --- /dev/null +++ b/Chipset/SB/SleepSmi.dxs @@ -0,0 +1,62 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.dxs 2 4/25/12 9:28a Victortu $ +// +// $Revision: 2 $ +// +// $Date: 4/25/12 9:28a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.dxs $ +// +// 2 4/25/12 9:28a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Remove unnecessary dependence. +// [Files] AcpiModeEnable.dxs; SBSMI.dxs; SleepSmi.dxs +// +// 1 2/08/12 8:30a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SleepSmi.DXS +// +// Description: Dependency file for the sleep SMI handler driver +// +//<AMI_FHDR_END> +//************************************************************************* +#include <Protocol\SmmSxDispatch.h> + +DEPENDENCY_START + EFI_SMM_SX_DISPATCH_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SleepSmi.mak b/Chipset/SB/SleepSmi.mak new file mode 100644 index 0000000..845d783 --- /dev/null +++ b/Chipset/SB/SleepSmi.mak @@ -0,0 +1,77 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.mak 1 2/08/12 8:30a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:30a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.mak $ +# +# 1 2/08/12 8:30a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: SleepSmi.MAK +# +# Description: Make file for the SMM Sleep SMI handler code +# +#<AMI_FHDR_END> +#************************************************************************* +!IFNDEF PI_SPECIFICATION_VERSION +PI_SPECIFICATION_VERSION = 0 +!ENDIF + +all : SleepSmi + +SleepSmi : $(BUILD_DIR)\SleepSmi.mak SleepSmiBin + +$(BUILD_DIR)\SleepSmi.mak : $(SLEEP_SMI_DIR)\SleepSmi.cif $(SLEEP_SMI_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SLEEP_SMI_DIR)\SleepSmi.cif $(CIF2MAK_DEFAULTS) + +SleepSmiBin : $(AMICSPLib) $(AMIDXELIB) + @set INCLUDE=%%INCLUDE%% + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SleepSmi.mak all\ + GUID=6298FE18-D5EF-42b7-BB0C-2953283F5704\ + ENTRY_POINT=InitSleepSmi\ + "MY_INCLUDES=$(INTEL_PCH_INCLUDES)" \ +!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A + TYPE=BS_DRIVER \ + DEPEX1=$(SLEEP_SMI_DIR)\SleepSmi.DXS \ +!ELSE + TYPE=BS_DRIVER \ + DEPEX1=$(SLEEP_SMI_DIR)\SleepSmi.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ +!ENDIF + COMPRESS=1 + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/SleepSmi.sdl b/Chipset/SB/SleepSmi.sdl new file mode 100644 index 0000000..12e2bff --- /dev/null +++ b/Chipset/SB/SleepSmi.sdl @@ -0,0 +1,68 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.sdl 1 2/08/12 8:30a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:30a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SleepSmi/SleepSmi.sdl $ +# +# 1 2/08/12 8:30a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "SleepSmi_SUPPORT" + Value = "1" + Help = "Main switch to enable SleepSmi support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "SmmChildDispatcher_SUPPORT" "=" "1" +End + +PATH + Name = "SLEEP_SMI_DIR" +End + +MODULE + Help = "Includes SleepSmi.mak to Project" + File = "SleepSmi.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SleepSmi.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, 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/Chipset/SB/SmBus/SmBus.cif b/Chipset/SB/SmBus/SmBus.cif new file mode 100644 index 0000000..5f3dee2 --- /dev/null +++ b/Chipset/SB/SmBus/SmBus.cif @@ -0,0 +1,20 @@ +<component> + name = "SmBus" + category = ModulePart + LocalRoot = "Chipset\SB\SmBus\" + RefName = "SmBus" +[files] +"SmBus.sdl" +"SmBus.mak" +"SmBusCommon.h" +"SmBusPei.h" +"SmBusDxe.h" +"SmBusCommon.c" +"SmBusPorting.c" +"SmBusPei.c" +"SmBusDxe.c" +"SmBusPciHooks.c" +"SmBusPei.dxs" +"SmBusDxe.dxs" +"SmBusSmm.dxs" +<endComponent> diff --git a/Chipset/SB/SmBus/SmBus.mak b/Chipset/SB/SmBus/SmBus.mak new file mode 100644 index 0000000..7a5148e --- /dev/null +++ b/Chipset/SB/SmBus/SmBus.mak @@ -0,0 +1,146 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#********************************************************************** +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBus.mak 1 6/06/12 8:00a Victortu $ +# +# $Revision: 1 $ +# +# $Date: 6/06/12 8:00a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBus.mak $ +# +# 1 6/06/12 8:00a Victortu +# Implement EFI_PEI_SMBUS2_PPI Support. +# +# 6 7/19/11 8:28a Abelwu +# [TAG] EIP63768 +# [Category] Improvement +# [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +# [Files] SmBus.mak +# +# 5 6/17/11 5:52p Artems +# EIP 53378: Replaced tabs with spaces, formatted to follow coding +# standard +# +# 4 5/18/11 11:50a Artems +# +# 3 1/27/11 9:48p Abelwu +# Supports SMBUS Protocol in early DXE phase. (EIP#40778) +# +# 2 10/16/09 7:06p Artems +# Updated copyright header +# +# 1 1/09/09 6:53p Artems +# New implementation of SMBus EIP 16730 +# +# 1 3/18/07 5:23p Felixp +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: SmBus.mak +# +# Description: This make file builds SMBus PEI and DXE components +# and link them to respective binary. +# +#<AMI_FHDR_END> +#********************************************************************** +!IFNDEF PI_SPECIFICATION_VERSION +PI_SPECIFICATION_VERSION = 0 +!ENDIF + +all : SmBusPei #SmBusDxe + +SMBUS_PEI_OBJECTS=\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusCommon.obj\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPorting.obj\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPei.obj + +#SMBUS_DXE_OBJECTS=\ +#$$(BUILD_DIR)\$(SmBus_DIR)\SmBusCommon.obj\ +#$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPorting.obj\ +#$$(BUILD_DIR)\$(SmBus_DIR)\SmBusDxe.obj + +SMBUS_PCI_OBJECTS=\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPciHooks.obj\ + +$(BUILD_DIR)\SmBus.mak : $(SmBus_DIR)\$(@B).cif $(SmBus_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SmBus_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +#SmBusDxe : $(BUILD_DIR)\SmBus.mak SmBusDxeBin +SmBusPei : $(BUILD_DIR)\SmBus.mak SmBusPeiBin +#PciBusSrc : $(BUILD_DIR)\SmBus.mak SmBusPciHooksBin +$(BUILD_DIR)\AMISmBusLib.lib : $(BUILD_DIR)\SmBus.mak SmBusPciHooksBin + +#SmBusDxeBin : $(AMIDXELIB) +# $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ +# /f $(BUILD_DIR)\SmBus.mak all\ +# NAME=SmBusDxe\ +# MAKEFILE=$(BUILD_DIR)\SmBus.mak \ +# "OBJECTS=$(SMBUS_DXE_OBJECTS)" \ +# GUID=4B680E2D-0D63-4f62-B930-7AE995B9B3A3\ +# ENTRY_POINT=SmBusDxeEntryPoint\ +#!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A +# TYPE=DXESMM_DRIVER \ +# DEPEX1=$(SmBus_DIR)\SmBusSmm.DXS DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \ +# DEPEX2=$(SmBus_DIR)\SmBusDxe.DXS DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \ +#!ELSE +# TYPE=BS_DRIVER \ +# DEPEX1=$(SmBus_DIR)\SmBusDxe.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ +#!ENDIF +# COMPRESS=1\ + +SmBusPeiBin : $(AMICSPLib) $(AMIPEILIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SmBus.mak all\ + NAME=SmBusPei\ + MAKEFILE=$(BUILD_DIR)\SmBus.mak \ +!IF "$(x64_BUILD)"=="1" + BUILD_DIR=$(BUILD_DIR)\IA32\ +!ELSE + BUILD_DIR=$(BUILD_DIR)\ +!ENDIF + "OBJECTS=$(SMBUS_PEI_OBJECTS)" \ + GUID=9EA28D33-0175-4788-BEA8-6950516030A5 \ + ENTRY_POINT=SmBusPeiEntryPoint \ + TYPE=PEIM \ + "MY_INCLUDES=$(INTEL_PCH_INCLUDES)" \ + DEPEX1=$(SmBus_DIR)\SmBusPei.DXS DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 + +SmBusPciHooksBin : + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SmBus.mak all\ + NAME=AMISmBusLib\ + MAKEFILE=$(BUILD_DIR)\SmBus.mak\ + OBJECTS="$(SMBUS_PCI_OBJECTS)"\ + TYPE=LIBRARY\ + "CFLAGS=$(CFLAGS)" + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#********************************************************************** diff --git a/Chipset/SB/SmBus/SmBus.sdl b/Chipset/SB/SmBus/SmBus.sdl new file mode 100644 index 0000000..e7e6dcb --- /dev/null +++ b/Chipset/SB/SmBus/SmBus.sdl @@ -0,0 +1,61 @@ +TOKEN + Name = "SmBus_SUPPORT" + Value = "1" + Help = "Main switch to enable SmBus support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "PI_SPECIFICATION_VERSION" ">=" "0x10000" +End + +TOKEN + Name = "SMBUS_BLINDING_PROTOCOL_SUPPORT" + Value = "1" + Help = "On - SMBus EFI 1.1 driver support." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "PCH_SPD_WRITE_DISABLE" + Value = "1" + Help = "0: Turn off SPD Write Disable.\1: Turn on SPD Write Disable." + TokenType = Integer + TargetH = Yes +End + +PATH + Name = "SmBus_DIR" +End + +MODULE + Help = "Includes SmBus.mak to Project" + File = "SmBus.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SmBusPei.ffs" + Parent = "FV_BB" + Help = "Template Smbus PEI component" + InvokeOrder = AfterParent +End + +#ELINK +# Name = "$(BUILD_DIR)\SmBusDxe.ffs" +# Parent = "FV_MAIN" +# Help = "Template Smbus DXE component" +# InvokeOrder = AfterParent +#End + +ELINK + Name = "OEM_PCI_DEVICE_CALLBACK(0, 0, SmBusProtectedPciDevice)," + Parent = "OEM_SKIP_PCI_DEVICE" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\AMISmBusLib.lib" + Parent = "PCIBUSSRCLIB" + InvokeOrder = AfterParent +End diff --git a/Chipset/SB/SmBus/SmBusCommon.c b/Chipset/SB/SmBus/SmBusCommon.c new file mode 100644 index 0000000..e4fbae7 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusCommon.c @@ -0,0 +1,559 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusCommon.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusCommon.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 5 6/27/11 2:26p Artems +// Updated year in file header +// +// 4 6/17/11 5:53p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 3 10/16/09 7:21p Artems +// Updated copyright header +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusCommon.c +// +// Description: SMBUS driver common functions implementation +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <AmiLib.h> +#include "SmBusCommon.h" + +UINT8 SmBusSpecReservedAddress[SMBUS_SPEC_RESERVED_ADDRESS] = { + 0x00, // 0000 000 0 General Call Address + // 0000 000 1 START byte + 0x01, // 0000 001 X CBUS address + 0x02, // 0000 010 X Address reserved for different bus format + 0x03, // 0000 011 X Reserved for future use + 0x04, // 0000 1XX X Reserved for future use + 0x05, + 0x06, + 0x07, + 0x28, // 0101 000 X Reserved for ACCESS.bus host + 0x37, // 0110 111 X Reserved for ACCESS.bus default address + 0x78, // 1111 0XX X 10-bit slave addressing + 0x79, + 0x7a, + 0x7b, + 0x7c, // 1111 1XX X Reserved for future use + 0x7d, + 0x7e, + 0x7f, + 0x08, // 0001 000 X SMBus Host + 0x0c, // 0001 100 X SMBus Alert Response Address + 0x61 // 1100 001 X SMBus Device Default Address +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusRead +// +// Description: This function reads given number of bytes from SMBUS device +// +// Input: IN UINT16 SmBusBase - SMBUS device IO address base +// IN UINT16 Offset - SMBUS device IO address offset +// IN UINTN ByteCount - number of bytes to read +// OUT UINT8 *Buffer - pointer to buffer to store data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusRead ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + OUT UINT8 *Buffer +) +{ + UINTN i; + + for(i = 0; i < ByteCount; i++) + Buffer[i] = IoRead8(SmBusBase + Offset); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusWrite +// +// Description: This function writes given number of bytes to SMBUS device +// +// Input: IN UINT16 SmBusBase - SMBUS device IO address base +// IN UINT16 Offset - SMBUS device IO address offset +// IN UINTN ByteCount - number of bytes to write +// IN UINT8 *Buffer - pointer to buffer to get data from +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusWrite ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + IN UINT8 *Buffer +) +{ + UINTN i; + + for(i = 0; i < ByteCount; i++) + IoWrite8(SmBusBase + Offset, Buffer[i]); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ArpDevice +// +// Description: This function assign address to specific or all devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN BOOLEAN ArpAll - Enumerate all devices flag +// IN EFI_SMBUS_UDID *SmbusUdid - pointer to device ID to assign new address +// IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return assigned address +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ArpDevice ( + IN SMBUS_PRIVATE *Context, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +) +{ + if(ArpAll) + return ArpDeviceFull(Context); + else + return ArpDeviceDirected(Context, SmbusUdid, SlaveAddress); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetArpMap +// +// Description: This function returns list of enumerated devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN OUT UINTN *Length - pointer to store size of address map +// IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap - pointer to store pointer to address map +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS GetArpMap ( + IN SMBUS_PRIVATE *Context, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +) +{ + *Length = Context->ArpDeviceCount; + *SmbusDeviceMap = Context->ArpDeviceList; + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PrepareToArp +// +// Description: This function sends PREPARE_TO_ARP command to devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS PrepareToArp ( + IN SMBUS_PRIVATE *Context +) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer; + + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + Length = 1; + Buffer = SMBUS_DATA_PREPARE_TO_ARP; + + Status = Execute ( + Context, + SlaveAddress, + SMBUS_DATA_PREPARE_TO_ARP, + EfiSmbusSendByte, + TRUE, + &Length, + &Buffer ); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IsAddressAvailable +// +// Description: This function checks if given address is available +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN UINT8 Address - address to check +// +// Output: TRUE - address is available +// FALSE - address is not available +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN IsAddressAvailable ( + IN SMBUS_PRIVATE *Context, + IN UINT8 Address +) +{ + UINTN Index; + + for(Index = 0; Index < Context->ArpDeviceCount; Index++) + if(Address == Context->ArpDeviceList[Index].SmbusDeviceAddress.SmbusDeviceAddress) + return FALSE; + + for(Index = 0; Index < Context->BoardReservedAddressCount; Index++) + if(Address == Context->BoardReservedAddressList[Index]) + return FALSE; + + for(Index = 0; Index < SMBUS_SPEC_RESERVED_ADDRESS; Index++) + if(Address == SmBusSpecReservedAddress[Index]) + return FALSE; + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetAvailableAddress +// +// Description: This function returns available address +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// +// Output: UINT8 - address +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 GetAvailableAddress ( + IN SMBUS_PRIVATE *Context +) +{ + UINT8 Address; + + for(Address = SMBUS_LOWEST_AVAILABLE_ADDRESS; + Address <= SMBUS_HIGHEST_AVAILABLE_ADDRESS; + Address++) + if(IsAddressAvailable(Context, Address)) + return Address; + + return 0xff; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ArpDeviceFull +// +// Description: This function enumerates all devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ArpDeviceFull ( + IN SMBUS_PRIVATE *Context +) +{ + EFI_SMBUS_DEVICE_MAP DeviceMap; + EFI_STATUS Status; + + Status = PrepareToArp(Context); + if(EFI_ERROR(Status)) + return (Status == EFI_DEVICE_ERROR) ? EFI_SUCCESS : Status; + + do + { + Status = GetUdidGeneral(Context, &DeviceMap); + if(EFI_ERROR(Status)) + break; + + if(DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress == 0x7f) //0xff >> 1 + { + DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress = GetAvailableAddress(Context); + if(DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress == 0xff) + return EFI_OUT_OF_RESOURCES; + } + else + { + if((DeviceMap.SmbusDeviceUdid.DeviceCapabilities & 0xC0) != 0 && + !IsAddressAvailable(Context, (UINT8)DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress)) + { + DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress = GetAvailableAddress(Context); + if(DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress == 0xff) + return EFI_OUT_OF_RESOURCES; + } + } + + Status = AssignAddress(Context, &DeviceMap); + if(EFI_ERROR(Status)) + return Status; + + //save assigned address to our database + Context->ArpDeviceList[Context->ArpDeviceCount] = DeviceMap; + Context->ArpDeviceCount++; + } while(Context->ArpDeviceCount < Context->MaxDevices); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ArpDeviceDirected +// +// Description: This function assign given address to given device +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN EFI_SMBUS_UDID *SmbusUdid - pointer to device ID +// IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return assigned address +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ArpDeviceDirected ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_UDID *SmbusUdid, + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress +) +{ + UINT8 AssignedAddress; + EFI_SMBUS_DEVICE_MAP DeviceMap; + EFI_STATUS Status; + + if(Context->ArpDeviceCount > Context->MaxDevices) + return EFI_OUT_OF_RESOURCES; + + AssignedAddress = GetAvailableAddress(Context); + if(AssignedAddress == 0xff) + return EFI_OUT_OF_RESOURCES; + + DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress = AssignedAddress; + DeviceMap.SmbusDeviceUdid = *SmbusUdid; + + Status = AssignAddress(Context, &DeviceMap); + if(EFI_ERROR(Status)) + return Status; + +//save assigned address to our database + Context->ArpDeviceList[Context->ArpDeviceCount] = DeviceMap; + Context->ArpDeviceCount++; + + *SlaveAddress = DeviceMap.SmbusDeviceAddress; + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: AssignAddress +// +// Description: This function sends ASSIGN_ADDRESS command via SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to device Udid/Address pair +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS AssignAddress ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_DEVICE_MAP *DeviceMap + ) +{ + UINT8 Buffer[GET_UDID_BUFFER_SIZE]; + UINTN Length; + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + + ConvertMapToBuffer(DeviceMap, Buffer); + + Length = GET_UDID_BUFFER_SIZE; + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + + Status = Execute ( + Context, + SlaveAddress, + SMBUS_DATA_ASSIGN_ADDRESS, + EfiSmbusWriteBlock, + TRUE, + &Length, + Buffer ); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetUdidGeneral +// +// Description: This function sends GET_UDID_GENERAL command via SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// OUT EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to store device Udid/Address pair +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS GetUdidGeneral ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap +) +{ + UINT8 Buffer[GET_UDID_BUFFER_SIZE]; + UINTN Length; + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + + Length = GET_UDID_BUFFER_SIZE; + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + + Status = Execute ( + Context, + SlaveAddress, + SMBUS_DATA_GET_UDID_GENERAL, + EfiSmbusReadBlock, + TRUE, + &Length, + Buffer ); + + if(EFI_ERROR(Status) || Length != GET_UDID_BUFFER_SIZE) + return EFI_DEVICE_ERROR; + + ConvertBufferToMap(DeviceMap, Buffer); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConvertMapToBuffer +// +// Description: This function converts EFI_SMBUS_DEVICE_MAP structure into UINT8[] buffer +// +// Input: IN EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to structure to convert from +// OUT UINT8 *Buffer - pointer buffer to convert to +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ConvertMapToBuffer ( + IN EFI_SMBUS_DEVICE_MAP *DeviceMap, + OUT UINT8 *Buffer +) +{ + Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities; + Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision; + Buffer[2] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorId >> 8); + Buffer[3] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorId); + Buffer[4] = (UINT8)(DeviceMap->SmbusDeviceUdid.DeviceId >> 8); + Buffer[5] = (UINT8)(DeviceMap->SmbusDeviceUdid.DeviceId); + Buffer[6] = (UINT8)(DeviceMap->SmbusDeviceUdid.Interface >> 8); + Buffer[7] = (UINT8)(DeviceMap->SmbusDeviceUdid.Interface); + Buffer[8] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8); + Buffer[9] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemVendorId); + Buffer[10] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8); + Buffer[11] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemDeviceId); + Buffer[12] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24); + Buffer[13] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16); + Buffer[14] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8); + Buffer[15] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId); + Buffer[16] = (UINT8)(DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConvertBufferToMap +// +// Description: This function converts UINT8[] buffer into EFI_SMBUS_DEVICE_MAP structure +// +// Input: OUT EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to structure to convert to +// IN UINT8 *Buffer - pointer buffer to convert from +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ConvertBufferToMap ( + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap, + IN UINT8 *Buffer + ) +{ + DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0]; + DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1]; + DeviceMap->SmbusDeviceUdid.VendorId = (UINT16)((Buffer[2] << 8) + Buffer[3]); + DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16)((Buffer[4] << 8) + Buffer[5]); + DeviceMap->SmbusDeviceUdid.Interface = (UINT16)((Buffer[6] << 8) + Buffer[7]); + DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16)((Buffer[8] << 8) + Buffer[9]); + DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16)((Buffer[10] << 8) + Buffer[11]); + DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32)((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]); + DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8)(Buffer[16] >> 1); +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusCommon.h b/Chipset/SB/SmBus/SmBusCommon.h new file mode 100644 index 0000000..0dda40d --- /dev/null +++ b/Chipset/SB/SmBus/SmBusCommon.h @@ -0,0 +1,226 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusCommon.h 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusCommon.h $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 5 6/27/11 2:26p Artems +// Updated year in file header +// +// 4 6/17/11 5:52p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 3 10/16/09 7:08p Artems +// Updated copyright header +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusCommon.h +// +// Description: This file contains shared PEI and DXE Smbus functions and +// data structures definitions +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> +#ifndef __SMBUS_COMMON__H__ +#define __SMBUS_COMMON__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <Efi.h> +#include <AmiCspLib.h> +#include <SmBus.h> + +#define SMBUS_ADDRESS_ARP 0x61 // 1100 001 X SMBus Device Default Address + +#define SMBUS_DATA_PREPARE_TO_ARP 0x01 +#define SMBUS_DATA_RESET_DEVICE 0x02 +#define SMBUS_DATA_GET_UDID_GENERAL 0x03 +#define SMBUS_DATA_ASSIGN_ADDRESS 0x04 + +#define SMBUS_SPEC_RESERVED_ADDRESS 21 +#define GET_UDID_BUFFER_SIZE 17 + +#define SMBUS_LOWEST_AVAILABLE_ADDRESS 0x08 +#define SMBUS_HIGHEST_AVAILABLE_ADDRESS 0x77 + +typedef VOID (* SMBUS_WAIT ) ( + IN UINTN Microseconds + ); + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: SMBUS_PRIVATE +// +// Description: AMI SMBUS driver private data structure +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// SmBusBase UINT16 SMBUS device base IO address +// SmBusWait SMBUS_WAIT Pointer to Wait function +// MaxDevices UINT8 Maximum number of supported devices +// BoardReservedAddressCount UINT8 Number of board reserved addesses +// BoardReservedAddressList UINT8* Pointer to board reserved addresses list +// ArpDeviceCount UINT8 Number of current devices +// ArpDeviceList EFI_SMBUS_DEVICE_MAP* Pointer to list of current devices +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct _SMBUS_PRIVATE +{ + UINT16 SmBusBase; + SMBUS_WAIT SmBusWait; + UINT8 MaxDevices; + UINT8 BoardReservedAddressCount; + UINT8 *BoardReservedAddressList; + UINT8 ArpDeviceCount; + EFI_SMBUS_DEVICE_MAP *ArpDeviceList; + +} SMBUS_PRIVATE; + + +//******************************************************* +// Shared functions prototypes +//******************************************************* + +VOID SmBusRead ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + OUT UINT8 *Buffer +); + +VOID SmBusWrite ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + IN UINT8 *Buffer +); + +EFI_STATUS Execute ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +); + +EFI_STATUS CheckNotify ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress, + OUT UINTN *Data +); + +EFI_STATUS ArpDevice ( + IN SMBUS_PRIVATE *Context, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +); + +EFI_STATUS GetArpMap ( + IN SMBUS_PRIVATE *Context, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +); + +EFI_STATUS PrepareToArp ( + IN SMBUS_PRIVATE *Context +); + +EFI_STATUS ArpDeviceDirected ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_UDID *SmbusUdid, + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress +); + +EFI_STATUS ArpDeviceFull ( + IN SMBUS_PRIVATE *Context +); + +EFI_STATUS AssignAddress ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_DEVICE_MAP *DeviceMap +); + +EFI_STATUS GetUdidGeneral ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap +); + +BOOLEAN IsAddressAvailable ( + IN SMBUS_PRIVATE *Context, + IN UINT8 Address +); + +UINT8 GetAvailableAddress ( + IN SMBUS_PRIVATE *Context +); + +VOID ConvertMapToBuffer ( + IN EFI_SMBUS_DEVICE_MAP *DeviceMap, + OUT UINT8 *Buffer +); + +VOID ConvertBufferToMap ( + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap, + IN UINT8 *Buffer +); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + diff --git a/Chipset/SB/SmBus/SmBusDxe.c b/Chipset/SB/SmBus/SmBusDxe.c new file mode 100644 index 0000000..2aee2ff --- /dev/null +++ b/Chipset/SB/SmBus/SmBusDxe.c @@ -0,0 +1,940 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 11 7/21/11 7:32a Abelwu +// [TAG] None +// [Category] New Feature +// [Description] Added SMBus SMM protocol support. +// [Files] SmBusDxe.c +// +// 10 7/19/11 8:28a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] 1. Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 +// compliance +// 2. Added SMBus SMM protocol support. +// +// 9 6/17/11 5:54p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 8 5/18/11 11:51a Artems +// +// 7 1/27/11 9:48p Abelwu +// Supports SMBUS Protocol in early DXE phase. (EIP#40778) +// +// 6 10/13/10 4:16p Artems +// EIP 45184 - fixed pointer size to be same in IA32 and X64 mode +// +// 5 10/16/09 7:32p Artems +// Updated copyright header +// +// 4 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 3 1/29/09 4:20p Artems +// Change "Note" to "Notes" for HelpBuilder +// +// 2 1/28/09 6:51p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusDxe.c +// +// Description: SMBUS DXE functions implementation +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <AmiHobs.h> +#include "SmBusDxe.h" +#include <Protocol\PciRootBridgeIo.h> + +#define MICROSECOND 10 +#define MILLISECOND (1000 * MICROSECOND) +#define ONESECOND (1000 * MILLISECOND) + +extern EFI_GUID SmBusIdentifierGuid; + +EFI_DRIVER_BINDING_PROTOCOL SmBusDriverBindingProtocol = { + DriverBindingSupported, + DriverBindingStart, + DriverBindingStop, + 0x10, + NULL, + NULL + }; + +SMBUS_DXE_PRIVATE *gPrivate; +EFI_HANDLE gControllerHandle = NULL; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusEarlyDxeDriver +// +// Description: This function configures and installs SMBUS protocol before +// SMBus EFI 1.1 drvier is installed. +// +// Input: None +// +// Output: EFI_STATUS +// EFI_SUCCESS - SMBUS protocol has been installed. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusEarlyDxeDriver ( VOID ) +{ + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo = NULL; + EFI_GUID EfiPciRootBridgeIoProtocolGuid = \ + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; +/* Porting Required + UINT32 IoBase32; + UINT16 Cmd16; +Porting End */ + + Status = pBS->AllocatePool( EfiBootServicesData, \ + sizeof(SMBUS_DXE_PRIVATE), \ + &gPrivate ); + if (EFI_ERROR(Status)) return Status; + + Status = pBS->AllocatePool( \ + EfiBootServicesData, \ + sizeof(EFI_SMBUS_DEVICE_MAP) * MAX_DXE_ARP_DEVICES, \ + &(gPrivate->SmBusContext.ArpDeviceList) ); + if (EFI_ERROR(Status)) { + pBS->FreePool( gPrivate ); + return Status; + } + + gPrivate->SmBusProtocol.Execute = SmBusDxeExecute; + gPrivate->SmBusProtocol.ArpDevice = SmBusDxeArpDevice; + gPrivate->SmBusProtocol.GetArpMap = SmBusDxeGetArpMap; + gPrivate->SmBusProtocol.Notify = SmBusDxeNotify; + + gPrivate->NotifyEvent = NULL; + gPrivate->Identifier = SmBusIdentifierGuid; + + gPrivate->SmBusContext.SmBusWait = SmBusDxeWait; + gPrivate->SmBusContext.MaxDevices = MAX_DXE_ARP_DEVICES; + RetrieveHobData( gPrivate ); + +/* Porting Required + Status = pBS->LocateProtocol( &EfiPciRootBridgeIoProtocolGuid, \ + NULL, \ + &PciRootBridgeIo ); + // Update SMBus I/O Base Address + PciRootBridgeIo->Pci.Read( PciRootBridgeIo, \ + EfiPciWidthUint32, \ + SMBUS_REG(SMBUS_REG_BASE_ADDR), \ + 1, \ + &IoBase32 ); + IoBase32 &= 0xfffffffe; + gPrivate->SmBusContext.SmBusBase = (UINT16)IoBase32; + + // Enable SMBus controller I/O decode. + PciRootBridgeIo->Pci.Read( PciRootBridgeIo, \ + EfiPciWidthUint16, \ + SMBUS_REG(SMBUS_REG_PCICMD), \ + 1, \ + &Cmd16 ); + Cmd16 |= 1; + PciRootBridgeIo->Pci.Write( PciRootBridgeIo, \ + EfiPciWidthUint16, \ + SMBUS_REG(SMBUS_REG_PCICMD), \ + 1, \ + &Cmd16 ); +Porting End */ + + Status = pBS->InstallProtocolInterface( &gControllerHandle, \ + &gEfiSmbusProtocolGuid, \ + EFI_NATIVE_INTERFACE, + &gPrivate->SmBusProtocol ); + + if (EFI_ERROR(Status)) { + TRACE((-1, "SBSmbusDxe: Install Protocol Interface Failed.\n")); + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusSmmExecute +// +// Description: This Protocol Function can be used to execute SMBus command +// on a particular SMBus controller in SMM. +// +// Input: *This - Pointer to the SMBus Protocol structure +// SlaveAddress - Address of the SMBus device +// Command - Command to be sent to the device +// Operation - SMBus operation to be performed +// PecCheck - Flag indicating the usage of PEC +// *Length - Length of the data in the Buffer (IN or OUT) +// *Buffer - Pointer to the buffer with the data (IN or OUT) +// +// Output: EFI_STATUS +// +// Notes: PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusSmmExecute ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer ) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; +/* + // Porting Required + UINT16 SmBusBase = READ_PCI16_SMBUS(SMBUS_REG_BASE_ADDR) & 0xfff0; + UINT16 SmBusCmd = READ_PCI16_SMBUS(SMBUS_REG_PCICMD); + + if (SmBusBase == 0) { // Assign a new I/O if the original address is 0 + WRITE_PCI16_SMBUS(SMBUS_REG_BASE_ADDR, SMBUS_BASE_ADDRESS); + SmBusBase = SMBUS_BASE_ADDRESS; + } + + gPrivate->SmBusContext.SmBusBase = SmBusBase; + + if ((SmBusCmd & 1) == 0) { // Enable I/O command if needed. + WRITE_PCI16_SMBUS(SMBUS_REG_PCICMD, 1); + } + // Porting End + + Status = Execute( &(((SMBUS_DXE_PRIVATE *)This)->SmBusContext), \ + SlaveAddress, \ + Command, \ + Operation, \ + PecCheck, \ + Length, \ + Buffer ); + + // Porting Required + // Restore the SMBus PCI Command Register + WRITE_PCI16_SMBUS(SMBUS_REG_PCICMD, SmBusCmd); + // Porting End +*/ + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SMBusInSmmInit +// +// Description: This function installs SMBus SMM protocol for the SMBus +// controller present in the SB. +// +// Input: ImageHandle - Image handle for the SB component +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SMBusInSmmInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_HANDLE Handle = NULL; + EFI_GUID SmmSmbusProtocolGuid = \ + AMI_SMBUS_SMM_PROTOCOL_GUID; + static SMBUS_DXE_PRIVATE SmbusSmmPrivate; + + gPrivate = &SmbusSmmPrivate; + gPrivate->SmBusProtocol.Execute = SmBusSmmExecute; + gPrivate->SmBusProtocol.ArpDevice = SmBusDxeArpDevice; + gPrivate->SmBusProtocol.GetArpMap = SmBusDxeGetArpMap; + gPrivate->SmBusProtocol.Notify = SmBusDxeNotify; + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + Status = InitAmiSmmLib( ImageHandle, SystemTable ); + if (EFI_ERROR(Status)) return Status; + + return pSmst->SmmInstallProtocolInterface( &Handle, \ + &SmmSmbusProtocolGuid, \ + EFI_NATIVE_INTERFACE, \ + &gPrivate->SmBusProtocol ); +#else + return pBS->InstallProtocolInterface( &Handle, + &SmmSmbusProtocolGuid, + EFI_NATIVE_INTERFACE, + &gPrivate->SmBusProtocol ); +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SMBusNotInSmmInit +// +// Description: This function installs SMBus DXE protocol for the SMBus +// controller present in the SB. +// +// Input: ImageHandle - Image handle for the SB component +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SMBusNotInSmmInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + + Status = SmBusEarlyDxeDriver(); + +#if SMBUS_BLINDING_PROTOCOL_SUPPORT + SmBusDriverBindingProtocol.ImageHandle = ImageHandle; + SmBusDriverBindingProtocol.DriverBindingHandle = ImageHandle; + Status = pBS->InstallMultipleProtocolInterfaces( \ + &ImageHandle, \ + &gEfiDriverBindingProtocolGuid, \ + &SmBusDriverBindingProtocol, \ + NULL ); +#endif + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusDxeEntryPoint +// +// Description: This function installs SMBus DXE/SMM protocols for the SMBus +// controller present in the SB. +// +// Input: ImageHandle - Image handle for the SB component +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + InitAmiLib(ImageHandle, SystemTable); + + return InitSmmHandlerEx( ImageHandle, \ + SystemTable, \ + SMBusInSmmInit, \ + SMBusNotInSmmInit ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverBindingSupported +// +// Description: SMBUS DXE Driver binding protocol Supported function +// +// Input: IN EFI_DRIVER_BINDING_PROTOCOL* This - pointer to EFI_DRIVER_BINDING_PROTOCOL structure +// IN EFI_HANDLE ControllerHandle - handle of controller to serve +// IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath - pointer to EFI_DEVICE_PATH_PROTOCOL structure +// +// Output: EFI_SUCCESS - driver supports given controller +// EFI_UNSUPPORTED - given controller not supported +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 PciData[4]; + + Status = pBS->OpenProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR (Status)) + return EFI_UNSUPPORTED; + + // + // See if this is a PCI Smbus Controller by looking at the Class Code Register + // + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0x8, + 1, + (VOID *)PciData ); + if (EFI_ERROR (Status)) + return EFI_UNSUPPORTED; + + pBS->CloseProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + + return (PciData[3] == 0x0c && PciData[2] == 0x05) ? EFI_SUCCESS : EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverBindingStart +// +// Description: SMBUS DXE Driver binding protocol Start function +// +// Input: IN EFI_DRIVER_BINDING_PROTOCOL* This - pointer to EFI_DRIVER_BINDING_PROTOCOL structure +// IN EFI_HANDLE ControllerHandle - handle of controller to serve +// IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath - pointer to EFI_DEVICE_PATH_PROTOCOL structure +// +// Output: EFI_SUCCESS - driver supports given controller +// EFI_UNSUPPORTED - given controller not supported +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +) +{ + EFI_STATUS Status; + SMBUS_DXE_PRIVATE *Private; + static BOOLEAN EarlyDxeProtocol = TRUE; + + if (EarlyDxeProtocol) { + Status = pBS->UninstallProtocolInterface( gControllerHandle, \ + &gEfiSmbusProtocolGuid, \ + &gPrivate->SmBusProtocol ); + if (Status == EFI_SUCCESS) { + pBS->FreePool( gPrivate->SmBusContext.ArpDeviceList ); + pBS->FreePool( gPrivate ); + } + EarlyDxeProtocol = FALSE; + } + + Status = pBS->AllocatePool(EfiBootServicesData, + sizeof(SMBUS_DXE_PRIVATE), + &Private); + if(EFI_ERROR(Status)) + return Status; + + Status = pBS->AllocatePool(EfiBootServicesData, + sizeof(EFI_SMBUS_DEVICE_MAP) * MAX_DXE_ARP_DEVICES, + &(Private->SmBusContext.ArpDeviceList)); + if(EFI_ERROR(Status)) + return Status; + + Status = pBS->OpenProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &(Private->PciIo), + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR (Status)) + { + pBS->FreePool(Private->SmBusContext.ArpDeviceList); + pBS->FreePool(Private); + return Status; + } + + Private->SmBusProtocol.Execute = SmBusDxeExecute; + Private->SmBusProtocol.ArpDevice = SmBusDxeArpDevice; + Private->SmBusProtocol.GetArpMap = SmBusDxeGetArpMap; + Private->SmBusProtocol.Notify = SmBusDxeNotify; + + Private->NotifyEvent = NULL; + Private->Identifier = SmBusIdentifierGuid; + + Private->SmBusContext.SmBusWait = SmBusDxeWait; + Private->SmBusContext.MaxDevices = MAX_DXE_ARP_DEVICES; + RetrieveHobData(Private); + +//TODO Fill Private->SmBusContext.SmBusBase with value read from PCI device + + DListInit(&(Private->NotifyList)); + + Status = pBS->InstallMultipleProtocolInterfaces( + &ControllerHandle, + &gEfiSmbusProtocolGuid, &Private->SmBusProtocol, + NULL); + if (EFI_ERROR (Status)) + { + pBS->CloseProtocol( + ControllerHandle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + pBS->FreePool(Private->SmBusContext.ArpDeviceList); + pBS->FreePool(Private); + } + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverBindingStop +// +// Description: SMBUS DXE Driver binding protocol Stop function +// +// Input: IN EFI_DRIVER_BINDING_PROTOCOL* This - pointer to EFI_DRIVER_BINDING_PROTOCOL structure +// IN EFI_HANDLE ControllerHandle - handle of controller to serve +// IN UINTN NumberOfChildren - number of child devices of controller +// IN EFI_HANDLE* ChildHandleBuffer - pointer to child devices handles array +// +// Output: EFI_SUCCESS - driver was successfully uninstalled from controller +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer +) +{ + EFI_STATUS Status; + SMBUS_DXE_PRIVATE *Private; + EFI_SMBUS_HC_PROTOCOL *SmBusProtocol; + + Status = pBS->OpenProtocol ( + ControllerHandle, + &gEfiSmbusProtocolGuid, + &SmBusProtocol, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL ); + if (EFI_ERROR (Status)) + return EFI_NOT_STARTED; + + pBS->CloseProtocol ( + ControllerHandle, + &gEfiSmbusProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + + Private = (SMBUS_DXE_PRIVATE *) SmBusProtocol; + + // uninstall the protocol + Status = pBS->UninstallMultipleProtocolInterfaces ( + ControllerHandle, + &gEfiSmbusProtocolGuid, &Private->SmBusProtocol, + NULL ); + if (EFI_ERROR (Status)) + return Status; + + if(Private->NotifyEvent != 0) + { + SMBUS_NOTIFY_LINK *NotifyLink = (SMBUS_NOTIFY_LINK *)(Private->NotifyList.pHead); + SMBUS_NOTIFY_LINK *DeleteLink; + + pBS->CloseEvent(Private->NotifyEvent); + while(NotifyLink != 0) + { + DeleteLink = NotifyLink; + NotifyLink = (SMBUS_NOTIFY_LINK *)NotifyLink->Link.pNext; + pBS->FreePool(DeleteLink); + } + } + + pBS->CloseProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + pBS->FreePool(Private->SmBusContext.ArpDeviceList); + pBS->FreePool(Private); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiExecute +// +// Description: EFI_SMBUS_HC_PROTOCOL Execute function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - slave address +// IN EFI_SMBUS_DEVICE_COMMAND Command - command +// IN EFI_SMBUS_OPERATION Operation - operation +// IN BOOLEAN PecCheck - parity check flag +// IN OUT UINTN *Length - pointer to size of data buffer +// IN OUT VOID *Buffer - pointer to data buffer +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeExecute ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +) +{ + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + + return Execute( + &(Private->SmBusContext), + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeArpDevice +// +// Description: EFI_SMBUS_HC_PROTOCOL ArpDevice function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN EFI_PEI_SMBUS_PPI *This - pointer to PPI +// IN BOOLEAN ArpAll - Enumerate all devices flag +// IN EFI_SMBUS_UDID *SmbusUdid - pointer to device ID to assign new address +// IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return assigned address +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeArpDevice ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +) +{ + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + + return ArpDevice( + &(Private->SmBusContext), + ArpAll, + SmbusUdid, + SlaveAddress); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeGetArpMap +// +// Description: EFI_SMBUS_HC_PROTOCOL GetArpMap function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN OUT UINTN *Length - pointer to store size of address map +// IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap - pointer to store pointer to address map +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeGetArpMap ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +) +{ + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + + return GetArpMap( + &(Private->SmBusContext), + Length, + SmbusDeviceMap); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeNotify +// +// Description: EFI_SMBUS_HC_PROTOCOL Notify function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - address of notification device +// IN UINTN Data - notification data +// IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction - pointer to callback function +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeNotify ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction +) +{ + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + SMBUS_NOTIFY_LINK *NewLink; + EFI_STATUS Status; + + if(NotifyFunction == NULL) + return EFI_INVALID_PARAMETER; + + Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SMBUS_NOTIFY_LINK), &NewLink); + if(EFI_ERROR(Status)) + return Status; + + NewLink->SlaveAddress = SlaveAddress; + NewLink->Data = Data; + NewLink->NotifyFunction = NotifyFunction; + + DListAdd(&(Private->NotifyList), (DLINK *)NewLink); + if(Private->NotifyList.Size == 1) + Status = InitializeNotifyPolling(Private); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitializeNotifyPolling +// +// Description: Function initializes host notify polling periodic event +// +// Input: IN SMBUS_DXE_PRIVATE *Context - pointer to SMBUS device private data +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS InitializeNotifyPolling ( + IN SMBUS_DXE_PRIVATE *Context +) +{ + EFI_STATUS Status; + + Status = pBS->CreateEvent ( + (EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL), + TPL_CALLBACK, + PollSmbusNotify, + Context, + &Context->NotifyEvent ); + if (EFI_ERROR(Status)) + return Status; + + Status = pBS->SetTimer ( + Context->NotifyEvent, + TimerPeriodic, + ONESECOND ); + if (EFI_ERROR(Status)) + return Status; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PollSmbusNotify +// +// Description: Function performs periodic check of host notifications +// +// Input: IN EFI_EVENT Event - periodic check event +// IN VOID *Context - event calling context +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID PollSmbusNotify ( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS Address; + UINTN Data; + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)Context; + SMBUS_NOTIFY_LINK *NotifyLink = (SMBUS_NOTIFY_LINK *)(Private->NotifyList.pHead); + + Status = CheckNotify(&(Private->SmBusContext), &Address, &Data); + if (EFI_ERROR(Status)) + return; + + while(NotifyLink != NULL) + { + if(Address.SmbusDeviceAddress == NotifyLink->SlaveAddress.SmbusDeviceAddress && + Data == NotifyLink->Data) + NotifyLink->NotifyFunction(Address, Data); + + NotifyLink = (SMBUS_NOTIFY_LINK *)NotifyLink->Link.pNext; + } +} + +//------------------------------------------------------------------- +// Struct EFI_SMBUS_DEVICE_MAP has one member, that declared as UINTN +// Due to this declaration this struct may have different size if +// compiled in x64 mode - 4 bytes in PEI and 8 bytes in DXE +// So we need mediator structure, to convert from PEI to DXE map, that +// was saved in Hob in PEI phase +//------------------------------------------------------------------- + +#pragma pack(1) +typedef struct { + UINT32 Address; + EFI_SMBUS_UDID Udid; +} PEI_EFI_SMBUS_DEVICE_MAP; +#pragma pack() + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RetrieveHobData +// +// Description: Function reads device map created in PEI phase +// +// Input: IN OUT SMBUS_DXE_PRIVATE *Context - pointer to device private data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID RetrieveHobData ( + IN OUT SMBUS_DXE_PRIVATE *Private +) +{ + AMI_SMBUS_HOB *Hob; + EFI_GUID HobListGuid = HOB_LIST_GUID; + EFI_STATUS Status; + SMBUS_PRIVATE *Context = &(Private->SmBusContext); + + PEI_EFI_SMBUS_DEVICE_MAP *PeiMap; + UINT32 i; + + Context->BoardReservedAddressCount = 0; + Context->BoardReservedAddressList = 0; + Context->ArpDeviceCount = 0; + + Hob = (AMI_SMBUS_HOB *)GetEfiConfigurationTable(pST, &HobListGuid); + + if(Hob == NULL) + return; + + Status = FindNextHobByGuid(&(Private->Identifier), &Hob); + if(EFI_ERROR(Status)) + return; + + Context->BoardReservedAddressCount = Hob->BoardReservedAddressCount; + Context->BoardReservedAddressList = (UINT8 *)(UINTN)Hob->BoardReservedAddressList; + Context->ArpDeviceCount = Hob->ArpDeviceCount; + + PeiMap = (PEI_EFI_SMBUS_DEVICE_MAP *)Hob->ArpDeviceList; + for(i = 0; i < Hob->ArpDeviceCount; i++) + { + Context->ArpDeviceList[i].SmbusDeviceAddress.SmbusDeviceAddress = PeiMap[i].Address; + Context->ArpDeviceList[i].SmbusDeviceUdid = PeiMap[i].Udid; + } +/* + MemCpy(Context->ArpDeviceList, + Hob->ArpDeviceList, + Context->ArpDeviceCount * sizeof(EFI_SMBUS_DEVICE_MAP)); +*/ +} + +//********************************************************************** +// Porting functions +//********************************************************************** + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeWait +// +// Description: This function waits given number of microseconds +// +// Input: IN UINTN Microseconds - number of microseconds to wait +// +// Output: None +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusDxeWait( + IN UINTN Microseconds +) +{ +//Porting required - implement wait function for pei phase +} + +/* +VOID SmBusDxeInitialize( + IN SMBUS_PRIVATE *Context + ) +{ +//Porting required - initialize PCI device and fill SmBusBase + +} +*/ + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusDxe.dxs b/Chipset/SB/SmBus/SmBusDxe.dxs new file mode 100644 index 0000000..7de1921 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusDxe.dxs @@ -0,0 +1,82 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.dxs 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +// +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.dxs $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 4 6/17/11 5:55p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 3 1/27/11 9:48p Abelwu +// Supports SMBUS Protocol in early DXE phase. (EIP#40778) +// +// 2 10/16/09 7:25p Artems +// Updated copyright header +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 4 7/24/07 12:33p Sivagarn +// Copyright year update +// +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: SmBusDxe.DXS +// +// Description: This file is the dependency file for the Smbus DXE +// driver +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + + +#include <Protocol\PciRootBridgeIo.h> + +DEPENDENCY_START + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID +DEPENDENCY_END + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + diff --git a/Chipset/SB/SmBus/SmBusDxe.h b/Chipset/SB/SmBus/SmBusDxe.h new file mode 100644 index 0000000..955ea21 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusDxe.h @@ -0,0 +1,219 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.h 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.h $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 9 8/03/11 8:18a Abelwu +// Updated AMI_SMBUS_SMM_PROTOCOL_GUID for following INTEL RC. +// +// 8 7/19/11 8:27a Abelwu +// [TAG] NONE +// [Category] New Feature +// [Description] Added SMBus SMM Protocol support. +// [Files] SmBusDxe.h +// +// 7 6/27/11 2:26p Artems +// Updated year in file header +// +// 6 6/17/11 5:52p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 5 5/18/11 11:50a Artems +// +// 4 10/16/09 7:11p Artems +// Updated copyright header +// +// 3 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusDxe.h +// +// Description: This file contains DXE SMBUS Driver functions and data +// structures definition. +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> +#ifndef __SMBUS_DXE__H__ +#define __SMBUS_DXE__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <AmiDxeLib.h> +#include <Protocol/Smbus.h> +#include <Protocol/DriverBinding.h> +#include <Protocol/PciIo.h> +#include <Protocol/PciRootBridgeIo.h> +#include "SmBusCommon.h" + +#define AMI_SMBUS_SMM_PROTOCOL_GUID \ + {0x72e40094, 0x2ee1, 0x497a, 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0xc} + +#define MAX_DXE_ARP_DEVICES 0x30 + +#pragma pack(1) + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: SMBUS_DXE_PRIVATE +// +// Description: AMI SMBUS driver PEI private data structure +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// SmBusProtocol EFI_SMBUS_HC_PROTOCOL SMBUS host controller protocol structure +// Identifier EFI_GUID SMBUS host controller identifier +// SmBusContext SMBUS_PRIVATE SMBUS private data structure +// PciIo EFI_PCI_IO_PROTOCOL* Pointer to PCI IO protocol of SMBUS device +// NotifyList DLIST Linked list of notify callbacks +// NotifyEvent EFI_EVENT EFI_EVENT structure +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct _SMBUS_DXE_PRIVATE +{ + EFI_SMBUS_HC_PROTOCOL SmBusProtocol; + EFI_GUID Identifier; + SMBUS_PRIVATE SmBusContext; + EFI_PCI_IO_PROTOCOL *PciIo; + DLIST NotifyList; + EFI_EVENT NotifyEvent; +} SMBUS_DXE_PRIVATE; + +#pragma pack() + +typedef struct { + DLINK Link; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + UINTN Data; + EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction; +} SMBUS_NOTIFY_LINK; + +EFI_STATUS SmBusDxeExecute ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +); + +EFI_STATUS SmBusDxeArpDevice ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +); + +EFI_STATUS SmBusDxeGetArpMap ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +); + +EFI_STATUS SmBusDxeNotify ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction +); + +EFI_STATUS DriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +); + +EFI_STATUS DriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +); + +EFI_STATUS DriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer +); + +EFI_STATUS InitializeNotifyPolling ( + IN SMBUS_DXE_PRIVATE *Context +); + +VOID PollSmbusNotify ( + IN EFI_EVENT Event, + IN VOID *Context +); + +VOID RetrieveHobData ( + IN OUT SMBUS_DXE_PRIVATE *Context +); + +VOID SmBusDxeWait( + IN UINTN Microseconds + ); + +/* +VOID SmBusDxeInitialize( + IN SMBUS_PRIVATE *Context + ); +*/ + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusPciHooks.c b/Chipset/SB/SmBus/SmBusPciHooks.c new file mode 100644 index 0000000..7362140 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPciHooks.c @@ -0,0 +1,129 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPciHooks.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPciHooks.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 2 1/27/11 9:44p Abelwu +// Supports SMBUS Protocol in early DXE phase. (EIP#40778) +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmbusPciHooks.c +// +// Description: This file contains PCI initialized hooks for SMBus porting. +// +// Notes: Porting required if SMBus early DXE supported +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Efi.h> +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include <PciBus.h> + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +// Local variable + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusProtectedPciDevice +// +// Description: This function is called by PCI Bus Driver before configuring +// or disabling any PCI device. This function should examine the +// Vendor/Device ID or PCI Bus, Device and Function numbers to +// make sure it is not a south bridge device or any other device +// which should no be configured by PCI Bus Driver. +// +// Input: *PciDevice - Pointer to PCI Device Info structure. +// +// Output: EFI_STATUS +// EFI_SUCCESS - SKIP this device, do not touch +// PCI Command register. +// EFI_UNSUPPORTED - DON'T SKIP this device do complete +// enumeration as usual. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusProtectedPciDevice ( + IN PCI_DEV_INFO *PciDevice ) +{ +/* +if ((PciDevice->Address.Addr.Bus == SMBUS_BUS) && \ + (PciDevice->Address.Addr.Device == SMBUS_DEV) && \ + (PciDevice->Address.Addr.Function == SMBUS_FUN)) { + + return EFI_SUCCESS; +} +*/ + return EFI_UNSUPPORTED; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmBus/SmBusPei.c b/Chipset/SB/SmBus/SmBusPei.c new file mode 100644 index 0000000..f9c5665 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPei.c @@ -0,0 +1,527 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.c 3 3/27/13 10:29p Wesleychen $ +// +// $Revision: 3 $ +// +// $Date: 3/27/13 10:29p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.c $ +// +// 3 3/27/13 10:29p Wesleychen +// Fix coding error. +// +// 2 11/25/12 10:40p Scottyang +// [TAG] EIP107376 +// [Category] Improvement +// [Description] Add token "PCH_SPD_WRITE_DISABLE" for SMBus reg 40h bit +// 4. +// [Files] SmBus.sdl +// SmBusPei.c +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 10 7/21/11 7:31a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.c +// +// 9 7/19/11 8:03a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.c +// +// 8 6/27/11 2:26p Artems +// Updated year in file header +// +// 7 6/17/11 5:53p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 6 10/13/10 4:15p Artems +// EIP 45184 - fixed pointer size to be same in IA32 and X64 mode +// +// 5 10/19/09 12:48p Artems +// Updated copyright header +// +// 4 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 3 1/29/09 4:20p Artems +// Change "Note" to "Notes" for HelpBuilder +// +// 2 1/28/09 6:51p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusPei.c +// +// Description: SMBUS driver PEI functions implementation +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <AmiLib.h> +#include <AmiHobs.h> +#include "SmBusPei.h" + // [EIP82310]> +#include <Ppi\SmbusPolicy\SmbusPolicy.h> +#include <PchAccess.h> + +static EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID; +EFI_GUID mPeiSmbusPolicyPpiGuid = PEI_SMBUS_POLICY_PPI_GUID; + +extern EFI_GUID SmBusIdentifierGuid; +extern UINT8 SmBusPlatformReservedAddress[]; +extern UINT8 SmBusPlatformReservedAddressSize; + // <[EIP82310] + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiEntryPoint +// +// Description: SMBUS driver PEI entry point +// +// Input: EFI_FFS_FILE_HEADER *FfsHeader - pointer to file header +// EFI_PEI_SERVICES **PeiServices - pointer to PEI services table +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +) +{ + EFI_STATUS Status; + SMBUS_PEI_PRIVATE *Private; + + Status = (*PeiServices)->AllocatePool( + PeiServices, + sizeof(SMBUS_PEI_PRIVATE), + &Private); + if(EFI_ERROR(Status)) + return Status; + + Status = (*PeiServices)->AllocatePool( + PeiServices, + sizeof(EFI_SMBUS_DEVICE_MAP) * MAX_PEI_ARP_DEVICES, + &(Private->SmBusContext.ArpDeviceList)); + if(EFI_ERROR(Status)) + return Status; + + Private->SmBusPpi.Execute = SmBusPeiExecute; + Private->SmBusPpi.ArpDevice = SmBusPeiArpDevice; + Private->SmBusPpi.GetArpMap = SmBusPeiGetArpMap; + Private->SmBusPpi.Notify = SmBusPeiNotify; + + Private->SmBusPpiDesc.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + Private->SmBusPpiDesc.Guid = &gEfiPeiSmbus2PpiGuid; + Private->SmBusPpiDesc.Ppi = &Private->SmBusPpi; + + Private->NotifyDesc.Flags = EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + Private->NotifyDesc.Guid = &gEfiPeiEndOfPeiPhasePpiGuid; + Private->NotifyDesc.Notify = SmBusEndOfPeiCallback; + + Private->SmBusContext.ArpDeviceCount = 0; + Private->SmBusContext.MaxDevices = MAX_PEI_ARP_DEVICES; + Private->SmBusContext.SmBusWait = SmBusPeiWait; + + Private->SmBusPpi.Identifier = SmBusIdentifierGuid; + + SmBusPeiInitialize(PeiServices, &Private->SmBusContext); + + Status = (*PeiServices)->NotifyPpi(PeiServices, &Private->NotifyDesc); + if(EFI_ERROR(Status)) + return Status; + + return (*PeiServices)->InstallPpi(PeiServices, &Private->SmBusPpiDesc); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiExecute +// +// Description: SMBUS driver PPI Execute function +// +// Input: PI 0.91 +// **PeiServices - Pointer to the PEI services table +// *This - Pointer to the SMBus PPI structure +// +// PI 1.X +// *This - Pointer to the SMBus2 PPI structure +// +// SlaveAddress - Address of the SMBus device to be used to +// send this command +// Command - Command to be sent to the device +// Operation - SMBus operation to be performed +// PecCheck - Flag indicating the usage of PEC +// *Length - Length of the data in the Buffer (IN/OUT) +// *Buffer - Pointer to the buffer with the data (IN/OUT) +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiExecute ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +) +{ + SMBUS_PEI_PRIVATE *Private = (SMBUS_PEI_PRIVATE *)This; + + return Execute( + &(Private->SmBusContext), + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiArpDevice +// +// Description: SMBUS driver PPI ArpDevice function +// +// Input: PI 0.91 +// **PeiServices - Pointer to the PEI services table +// *This - Pointer to the SMBus PPI structure +// +// PI 1.X +// *This - Pointer to the SMBus2 PPI structure +// +// ArpAll - Flag indicating ARP type - ALL or specific +// *SmbusUdid - SMBus UDID for the device whose Address has +// to be resolved +// *SlaveAddress - Slave address to be assigned to the device +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiArpDevice ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +) +{ + SMBUS_PEI_PRIVATE *Private = (SMBUS_PEI_PRIVATE *)This; + + return ArpDevice( + &(Private->SmBusContext), + ArpAll, + SmbusUdid, + SlaveAddress); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiGetArpMap +// +// Description: SMBUS driver PPI GetArpMap function +// +// Input: PI 0.91 +// **PeiServices - Pointer to the PEI services table +// *This - Pointer to the SMBus PPI structure +// +// PI 1.X +// *This - Pointer to the SMBus2 PPI structure +// +// *Length - Length of the Device map structure(IN & OUT) +// *SmBusDeviceMap - Pointer to the buffer where the SMBus +// device map will be filled in +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiGetArpMap ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +) +{ + SMBUS_PEI_PRIVATE *Private = (SMBUS_PEI_PRIVATE *)This; + + return GetArpMap( + &(Private->SmBusContext), + Length, + SmbusDeviceMap); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiNotify +// +// Description: SMBUS driver PPI Notify function +// +// Input: EFI_PEI_SERVICES **PeiServices - pointer to PEI services table +// EFI_PEI_SMBUS_PPI *This - pointer to PPI +// EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - address of notification device +// UINTN Data - notification data +// EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction - pointer to callback function +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiNotify ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_PEI_SMBUS_NOTIFY2_FUNCTION NotifyFunction +) +{ + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusEndOfPeiCallback +// +// Description: This function creates map of devices connected to SMBUS at the end of PEI phase +// +// Input: EFI_PEI_SERVICES **PeiServices - pointer to PEI services table +// EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor - pointer to notify descriptor +// VOID *Ppi - pointer to notify PPI +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi +) +{ + SMBUS_PEI_PRIVATE *Private = OUTTER(NotifyDescriptor, NotifyDesc, SMBUS_PEI_PRIVATE); + UINTN HobSize; + AMI_SMBUS_HOB *Hob; + EFI_STATUS Status; + + HobSize = sizeof(AMI_SMBUS_HOB) + Private->SmBusContext.ArpDeviceCount * sizeof(EFI_SMBUS_DEVICE_MAP); + Status = (*PeiServices)->CreateHob(PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, HobSize, &Hob); + if(!EFI_ERROR(Status)) + { + Hob->Header.Name = Private->SmBusPpi.Identifier; + Hob->BoardReservedAddressCount = Private->SmBusContext.BoardReservedAddressCount; + Hob->BoardReservedAddressList = (UINT32) (Private->SmBusContext.BoardReservedAddressList); + Hob->ArpDeviceCount = Private->SmBusContext.ArpDeviceCount; + MemCpy(Hob->ArpDeviceList, + Private->SmBusContext.ArpDeviceList, + Private->SmBusContext.ArpDeviceCount * sizeof(EFI_SMBUS_DEVICE_MAP)); + } + return Status; +} + +//********************************************************************** +// Porting functions +//********************************************************************** + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiWait +// +// Description: This function waits given number of microseconds +// +// Input: UINTN Microseconds - number of microseconds to wait +// +// Output: None +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusPeiWait( + IN UINTN Microseconds +) +{ + // The following code is to generate delay for specified amount of micro + // seconds using ACPI timer. + UINT16 AcpiTmrReg = PM_BASE_ADDRESS + ACPI_IOREG_PM1_TMR; + UINTN TicksNeeded; + UINT32 TimerValue; + UINT32 NewTimerValue; + UINTN OverFlow = 0; + UINTN TheRest; + UINTN EndValue; + + // There are 3.58 ticks per us, so we have to convert the number of us + // passed in to the number of ticks that need to pass before the timer has + // expired convert us to Ticks, don't loose significant figures or as few + // as possible do integer math in ticks/tens of ns and then divide by 100 + // to get ticks per us + + TicksNeeded = Microseconds * 3; // (Microseconds * 3) + TicksNeeded += (Microseconds) / 2; // (Microseconds * 5)/10 + TicksNeeded += (Microseconds * 2) / 25; // (Microseconds * 8)/100 + TheRest = TicksNeeded; + + // 32 bits corresponds to approz 71 mins no delay should be that long + // otherwise get the number of times the counter will have to overflow + // to delay as long as needed + if (NUM_BITS_IN_ACPI_TIMER < MAX_ACPI_TIMER_BITS) { + OverFlow = TicksNeeded / (1 << NUM_BITS_IN_ACPI_TIMER); + TheRest = TicksNeeded % (1 << NUM_BITS_IN_ACPI_TIMER); + } + + // Read ACPI Timer + TimerValue = IoRead32( AcpiTmrReg ); + + // Need to adjust the values based off of the start time + EndValue = TheRest + TimerValue; + + // Check for overflow on addition. possibly a problem + if (EndValue < TimerValue) { + OverFlow++; + } else { + if (NUM_BITS_IN_ACPI_TIMER < MAX_ACPI_TIMER_BITS) { + // Here make sure that EndValue is less than the max value + // of the counter + OverFlow += EndValue / (1 << NUM_BITS_IN_ACPI_TIMER); + EndValue = EndValue % (1 << NUM_BITS_IN_ACPI_TIMER); + } + } + + // Let the timer wrap around as many times as calculated + while (OverFlow) { + // read timer amd look to see if the new value read is less than + // the current timer value. if this happens the timer overflowed + NewTimerValue = IoRead32( AcpiTmrReg ); + + if (NewTimerValue < TimerValue) OverFlow--; + + TimerValue = NewTimerValue; + } + + // Now wait for the correct number of ticks that need to occur after + // all the needed overflows + while (EndValue > TimerValue) { + NewTimerValue = IoRead32( AcpiTmrReg ); + + // check to see if the timer overflowed. if it did then + // the time has elapsed. Because EndValue should be greater than + // TimerValue + if (NewTimerValue < TimerValue) break; + + TimerValue = NewTimerValue; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiInitialize +// +// Description: This function initializes SMBUS PCI device and fills device context +// +// Input: **PeiServices - Pointer to the PEI Services table +// *Context - Pointer to the SMBus private structure. +// +// Output: None +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusPeiInitialize( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT SMBUS_PRIVATE *Context ) +{ + // [EIP82310]> + EFI_STATUS Status; + PEI_SMBUS_POLICY_PPI *SmbusPolicy; + UINTN SmbusRegBase; + + Context->BoardReservedAddressCount = SmBusPlatformReservedAddressSize; + Context->BoardReservedAddressList = SmBusPlatformReservedAddress; + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &mPeiSmbusPolicyPpiGuid, + 0, + NULL, + &SmbusPolicy + ); + if (EFI_ERROR(Status)) return; + + SmbusRegBase = SB_PCIE_CFG_ADDRESS (SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, 0); + + if (MEM_READ16(SmbusRegBase + R_PCH_SMBUS_VENDOR_ID) != 0xFFFF) { + Context->SmBusBase = MEM_READ16(SmbusRegBase + R_PCH_SMBUS_BASE) & (UINT16) B_PCH_SMBUS_BASE_BAR; + if (Context->SmBusBase == SmbusPolicy->BaseAddress) { + return; + } else if (Context->SmBusBase == 0) { + Context->SmBusBase = SmbusPolicy->BaseAddress; + + // Set the BAR & I/O space enable ourselves + MEM_WRITE16(SmbusRegBase + SMBUS_REG_BASE_ADDR, Context->SmBusBase); + MEM_SET8(SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE); + + // Reset the SMBus host controller + MEM_SET8(SmbusRegBase + R_PCH_SMBUS_HOSTC, (PCH_SPD_WRITE_DISABLE << 4) | B_PCH_SMBUS_HOSTC_SSRESET); + + // Enable the SMBus host controller + MEM_RW8(SmbusRegBase + R_PCH_SMBUS_HOSTC, \ + B_PCH_SMBUS_HOSTC_HST_EN, \ + B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN); + + // Clear Status Register before anyone uses the interfaces + IoWrite8 (Context->SmBusBase + R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); + } + } + // <[EIP82310] +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + diff --git a/Chipset/SB/SmBus/SmBusPei.dxs b/Chipset/SB/SmBus/SmBusPei.dxs new file mode 100644 index 0000000..79abc58 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPei.dxs @@ -0,0 +1,73 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.dxs 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.dxs $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 3 6/27/11 2:26p Artems +// Updated year in file header +// +// 2 10/16/09 7:25p Artems +// Updated copyright header +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 7/30/07 6:19p Sivagarn +// Initial check-in for the template +// +//********************************************************************** + +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: SmBusPei.DXS +// +// Description: Dependency file for the Smbus PEI driver +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> + + // [EIP82310]> +#include <Ppi\SmbusPolicy\SmbusPolicy.h> + +DEPENDENCY_START + PEI_SMBUS_POLICY_PPI_GUID +DEPENDENCY_END + // <[EIP82310] + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusPei.h b/Chipset/SB/SmBus/SmBusPei.h new file mode 100644 index 0000000..6857196 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPei.h @@ -0,0 +1,182 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.h 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.h $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 8 7/21/11 7:31a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.h +// +// 7 7/19/11 8:02a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.h +// +// 6 6/27/11 2:26p Artems +// Updated year in file header +// +// 5 6/17/11 5:52p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 4 10/16/09 7:10p Artems +// Updated copyright header +// +// 3 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusPei.h +// +// Description: This file contains PEI SMBUS Driver functions and data structures definition +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#ifndef __SMBUS_PEI__H__ +#define __SMBUS_PEI__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <Ppi/Smbus2.h> + +#include "SmBusCommon.h" + +#define MAX_PEI_ARP_DEVICES 8 + +#pragma pack(1) + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: SMBUS_PEI_PRIVATE +// +// Description: AMI SMBUS driver PEI private data structure +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// SmBusPpi EFI_PEI_SMBUS/2_PPI SMBUS (2) PPI structure +// Identifier EFI_GUID SMBUS controller identifier +// SmBusContext SMBUS_PRIVATE SMBUS private data structure +// NotifyDesc EFI_PEI_NOTIFY_DESCRIPTOR Notify descriptor structure +// SmBusPpiDesc EFI_PEI_PPI_DESCRIPTOR PPI descriptor structure +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct _SMBUS_PEI_PRIVATE +{ + EFI_PEI_SMBUS2_PPI SmBusPpi; + SMBUS_PRIVATE SmBusContext; + EFI_PEI_NOTIFY_DESCRIPTOR NotifyDesc; + EFI_PEI_PPI_DESCRIPTOR SmBusPpiDesc; +} SMBUS_PEI_PRIVATE; + +#pragma pack() + +EFI_STATUS SmBusPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +); + +EFI_STATUS SmBusPeiExecute ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +); + +EFI_STATUS SmBusPeiArpDevice ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +); + +EFI_STATUS SmBusPeiGetArpMap ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +); + +EFI_STATUS SmBusPeiNotify ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_PEI_SMBUS_NOTIFY2_FUNCTION NotifyFunction +); + +EFI_STATUS SmBusEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi +); + +VOID SmBusPeiWait( + IN UINTN Microseconds +); + +VOID SmBusPeiInitialize( + IN EFI_PEI_SERVICES **PeiServices, + IN SMBUS_PRIVATE *Context +); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusPorting.c b/Chipset/SB/SmBus/SmBusPorting.c new file mode 100644 index 0000000..eb4ad69 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPorting.c @@ -0,0 +1,705 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPorting.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPorting.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 7 6/27/11 2:26p Artems +// Updated year in file header +// +// 6 6/17/11 5:53p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 5 10/16/09 7:24p Artems +// Updated copyright header +// +// 4 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 3 1/29/09 4:20p Artems +// Change "Note" to "Notes" for HelpBuilder +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusPorting.c +// +// Description: SMBUS driver porting functions +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include "SmBusCommon.h" + +//Porting Required - Put unique GUID for given SMBUS controller +#define SM_BUS_CONTROLLER_IDENTIFIER_GUID \ + {0x882f2546, 0xef1f, 0x4090, 0x9f, 0x9c, 0x93, 0x84, 0x5a, 0xd7, 0x84, 0x1c} + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + + // [EIP82310]> +UINT8 SmBusPlatformReservedAddress[] = { + DIMM1_SMBUS_ADDRESS, + DIMM2_SMBUS_ADDRESS, + DIMM3_SMBUS_ADDRESS, + DIMM4_SMBUS_ADDRESS +}; + // <[EIP82310] + +UINT8 SmBusPlatformReservedAddressSize = \ + sizeof(SmBusPlatformReservedAddress) / sizeof(UINT8); + +// GUID Definition(s) + +EFI_GUID SmBusIdentifierGuid = SM_BUS_CONTROLLER_IDENTIFIER_GUID; + +// Protocol/PPI Definition(s) + +// External Declaration(s) + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BeforeSMBusTransfer +// +// Description: Set an enviornment for SMBus transfering. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// +// Output: EFI_STATUS +// EFI_TIMEOUT - The caller can't obtain ownership of SMBus. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS BeforeSMBusTransfer ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8 ) +{ + UINT16 Timeout = 0xffff; + + // Waiting for other software's usage. + while (IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS) & HST_STS_INUSE_STS) { + IoRead8(0xed); // I/O Delay + Timeout--; + if (Timeout == 0) return EFI_TIMEOUT; + } + + // BIOS obtains ownership of SMBus & Waiting for transmission completed. + while (IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS) & HST_STS_HOST_BUSY) { + Timeout--; + if (Timeout == 0) break; + } + + // Clears all statues + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_ALL); + + if (Protocol8 == SMB_CMD_BLOCK) { +//#### SET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_E32B); // 0x0D +//#### // Reset Buffer Pointer +//#### IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_CNT); // 0x02 + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteCommand +// +// Description: This support function writes command field to SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Command8 - SMBus command to be performed +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteCommand ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Command8 ) +{ + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CMD, Command8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteSlAddr +// +// Description: This support function writes slave address to SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// SlAddr8 - Address of the SMBus device +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteSlAddr ( + IN UINT16 SmBusIoAddr16, + IN UINT8 SlAddr8 ) +{ + IoWrite8(SmBusIoAddr16 + SMB_IOREG_XMIT_SLVA, SlAddr8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteSMBusData +// +// Description: This support function writes data(s) to SMBus Controller for +// SMBus write operation. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// Length8 - Size of data buffer in bytes +// *Data8 - Buffer to be written +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteSMBusData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8, + IN UINT8 Length8, + IN UINT8 *Data8 ) +{ + UINT8 i; + + for (i = 0; i < Length8; i++) { + if (Protocol8 == SMB_CMD_BLOCK) { + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_D0, Length8); + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HOST_BLOCK_DB, *Data8++); + break; + } else { + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_D0 + i, *Data8++); + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WaitForHostByteDoneStatus +// +// Description: This support function waits the Byte Done bit to be set for +// SMBus Block operation. +// +// Input: SmBusStsReg - 16 Bit I/O address for SMBus status register +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - The Byte Done bit had been set. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WaitForHostByteDoneStatus ( + IN UINT16 SmBusStsReg ) +{ + UINT8 HostSts; + + while (1) { + HostSts = IoRead8( SmBusStsReg ); + IoWrite8( IO_DELAY_PORT, HostSts ); + if ( HostSts & HST_STS_ERROR ) return EFI_DEVICE_ERROR; + if ( HostSts & HST_STS_BDS ) return EFI_SUCCESS; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteSmBusBlockData +// +// Description: This support function writes to SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Length8 - Size of data buffer in bytes +// *Data8 - Buffer to be written +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - Write SMBus Block data successfully. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WriteSmBusBlockData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Length8, + IN UINT8 *Data8 ) +{ + EFI_STATUS Status; + UINT8 i; + UINT16 StatusReg = SmBusIoAddr16 + SMB_IOREG_HST_STS; + + for (i = 1; i < Length8; i++) { + if (WaitForHostByteDoneStatus(StatusReg)) return EFI_DEVICE_ERROR; + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HOST_BLOCK_DB, *Data8++); + IoWrite8(StatusReg, HST_STS_BDS); + } + Status = WaitForHostByteDoneStatus(StatusReg); + IoWrite8(StatusReg, HST_STS_BDS); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReadSmBusData +// +// Description: This support function reads from SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// Length8 - Size of data buffer in bytes +// *Data8 - Buffer for the read data +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - Read SMBus data successfully. +// +// Modified: *Data8 - The Pointer will store data(s) read from the SMBus +// device if EFI_SUCCESS is returned. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ReadSmBusData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8, + IN UINT8 Length8, + OUT UINT8 *Data8 ) +{ + UINT8 i; + + if (Protocol8 == SMB_CMD_BLOCK) + Length8 = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_D0); + + for (i = 0; i < Length8; i++) { + if (Protocol8 == SMB_CMD_BLOCK) { + if (WaitForHostByteDoneStatus(SmBusIoAddr16 + SMB_IOREG_HST_STS)) + return EFI_DEVICE_ERROR; + *Data8++ = IoRead8(SmBusIoAddr16 + SMB_IOREG_HOST_BLOCK_DB); + if (i == (Length8 - 1)) { + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CNT, \ + HST_CNT_LAST_BYTE | SMB_CMD_BLOCK); + } + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_BDS); + } else { + *Data8++ = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_D0 + i); + } + } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: StartSmBusTransition +// +// Description: This support function starts SMBus operation. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// PecCheck - TRUE will set PecCheck bit. +// +// Ouput: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID StartSmBusTransition ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8, + IN BOOLEAN PecCheck ) +{ + UINT8 Buffer8; + + Buffer8 = Protocol8; + if (PecCheck) { + Buffer8 |= HST_CNT_PEC_EN; + SET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_AAC); // 0x0D + } + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CNT, Buffer8); + + Buffer8 |= HST_CNT_START; + + if (Protocol8 == SMB_CMD_BLOCK) + // Clear SECOND_TO_STS status before SMBus block read/write. + WRITE_IO8_TCO(TCO_IOREG_STS2, 2); // 0x06 + + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CNT, Buffer8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WaitForSmBusComplete +// +// Description: This support function waits for the operation complete +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - SMBus transaction is successfully +// completed. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WaitForSmBusComplete ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8 ) +{ + volatile UINT8 Buffer8; + UINT8 StsChkBit; + UINT16 TimeoutCounter; + + for (TimeoutCounter = 0; TimeoutCounter < 0x6000; TimeoutCounter++) { + Buffer8 = IoRead8(IO_DELAY_PORT); // I/O Delay + Buffer8 = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS); + if (Buffer8 & (HST_STS_BDS | HST_STS_ERROR | HST_STS_INTR)) break; + } + + StsChkBit = (Protocol8 == SMB_CMD_BLOCK) ? HST_STS_BDS : HST_STS_INTR; + if (Buffer8 & StsChkBit) + return (Buffer8 & HST_STS_ERROR) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + return EFI_DEVICE_ERROR; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ClearSmBusStatusAndDelay +// +// Description: This support function clears all statues of the SMBus +// controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// +// Ouptut: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ClearSmBusStatusAndDelay ( + IN UINT16 SmBusIoAddr16 ) +{ + UINT16 Timeout = 0x4000; + volatile UINT8 HstSts; + + // Waiting for transmission completed. + do { + Timeout--; + if (Timeout == 0) break; + HstSts = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS); + if (HstSts & HST_STS_HOST_BUSY) continue; + } while ((HstSts & (HST_STS_ERROR | HST_STS_INTR | HST_STS_BDS)) == 0); + + // Clears all statues. + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_ALL); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AfterSMBusTransfer +// +// Description: Restore the enviornment. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID AfterSMBusTransfer ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8 ) +{ +//#### if (Protocol8 == SMB_CMD_BLOCK) +//#### RESET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_E32B); // 0x0D + RESET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_AAC); // 0x0D + + // BIOS releases the ownership of SMBus. + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_INUSE_STS); + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RwSmBusData +// +// Description: This support function reads/writes from/to SMBus Controller. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// SlAddr8 - Address of the SMBus device +// Command8 - SMBus command to be performed +// Protocol8 - SMBus operation to be performed +// PecCheck - TRUE will set PecCheck bit. +// Length8 - Size of data buffer in bytes +// Data8 - Buffer for the read/write data(s) +// +// Output: Return Status based on errors that occurred while SMBus +// transaction. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS RwSmBusData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 SlAddr8, + IN UINT8 Command8, + IN UINT8 Protocol8, + IN BOOLEAN PecCheck, + IN UINT8 Length8, + IN OUT UINT8 *Data8 ) +{ + EFI_STATUS Status; + BOOLEAN IsWriteOperation = (!(SlAddr8 & XMIT_SLVA_RW)); + + Status = BeforeSMBusTransfer(SmBusIoAddr16, Protocol8); + if (Status != EFI_SUCCESS) return Status; + WriteCommand(SmBusIoAddr16, Command8); + WriteSlAddr(SmBusIoAddr16, SlAddr8); + if (IsWriteOperation) + WriteSMBusData(SmBusIoAddr16, Protocol8, Length8, Data8); + StartSmBusTransition(SmBusIoAddr16, Protocol8, PecCheck); + Status = WaitForSmBusComplete(SmBusIoAddr16, Protocol8); + if (Status == EFI_SUCCESS) { + if (IsWriteOperation) { + if (Protocol8 == SMB_CMD_BLOCK) + WriteSmBusBlockData(SmBusIoAddr16, Length8, &Data8[1]); + } else { + Status = ReadSmBusData(SmBusIoAddr16, Protocol8, Length8, Data8); + } + } + + ClearSmBusStatusAndDelay(SmBusIoAddr16); + AfterSMBusTransfer(SmBusIoAddr16, Protocol8); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Execute +// +// Description: This function sends commands via SMBUS interface +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - slave address value +// IN EFI_SMBUS_DEVICE_COMMAND Command - command +// IN EFI_SMBUS_OPERATION Operation - operation +// IN BOOLEAN PecCheck - parity check flag +// IN OUT UINTN *Length - pointer to size of data buffer +// IN OUT VOID *Buffer - pointer to data buffer +// +// Output: EFI_STATUS +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS Execute ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +) +{ + // Porting required - implement internal Smbus protocols here + EFI_STATUS Status = EFI_UNSUPPORTED; + UINT8 *bData = (UINT8 *)Buffer; + UINT8 bSlAddr = (UINT8)(SlaveAddress.SmbusDeviceAddress << 1); + UINT8 bCommand = (UINT8)Command; + UINT8 bLength = (UINT8)(*Length); + + // Wait for SMBus transaction to finish if needed. +//#### while (IoRead8(Context->SmBusBase + SMB_IOREG_CNTL) & 3); + + if (bLength > 32) bLength = 32; + if (bLength == 0) return EFI_INVALID_PARAMETER; + + switch (Operation) { + case EfiSmbusQuickRead: + case EfiSmbusQuickWrite: + break; + + case EfiSmbusReceiveByte: + break; + + case EfiSmbusSendByte: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_BYTE, \ + PecCheck, \ + 1, \ + bData ); + break; + + case EfiSmbusReadByte: + Status = RwSmBusData( Context->SmBusBase , \ + (bSlAddr | XMIT_SLVA_RW), \ + bCommand, \ + SMB_CMD_BYTE_DATA, \ + PecCheck, \ + 1, \ + bData ); + break; + case EfiSmbusReadWord: + Status = RwSmBusData( Context->SmBusBase , \ + (bSlAddr | XMIT_SLVA_RW), \ + bCommand, \ + SMB_CMD_WORD_DATA, \ + PecCheck, \ + 2, \ + bData ); + break; + + case EfiSmbusWriteByte: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_BYTE_DATA, \ + PecCheck, \ + 1, \ + bData ); + break; + case EfiSmbusWriteWord: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_WORD_DATA, \ + PecCheck, \ + 2, \ + bData ); + break; + + case EfiSmbusReadBlock: + Status = RwSmBusData( Context->SmBusBase , \ + (bSlAddr | XMIT_SLVA_RW), \ + bCommand, \ + SMB_CMD_BLOCK, \ + PecCheck, \ + bLength, \ + bData ); + *Length = IoRead8( Context->SmBusBase + SMB_IOREG_HST_D0 ); + break; + + case EfiSmbusWriteBlock: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_BLOCK, \ + PecCheck, \ + bLength, \ + bData ); + *Length = IoRead8( Context->SmBusBase + SMB_IOREG_HST_D0 ); + break; + + case EfiSmbusProcessCall: + break; + + case EfiSmbusBWBRProcessCall: + break; + + default: + break; + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckNotify +// +// Description: This function checks if SMBUS host received any notifications +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return address of notificaion device +// OUT UINTN *Data - pointer to notification data +// +// Output: EFI_STATUS +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS CheckNotify ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress, + OUT UINTN *Data +) +{ +//Porting required + return EFI_UNSUPPORTED; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusSmm.dxs b/Chipset/SB/SmBus/SmBusSmm.dxs new file mode 100644 index 0000000..dc90908 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusSmm.dxs @@ -0,0 +1,65 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusSmm.dxs 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusSmm.dxs $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 1 7/19/11 8:09a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusSmm.dxs +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmBusSmm.DXS +// +// Description: This file is the dependency file for the Smbus SMM +// driver +// +//<AMI_FHDR_END> +//************************************************************************* + +#include <Protocol\SmmBase2.h> +#include <Protocol\SmBus.h> +DEPENDENCY_START + EFI_SMM_BASE2_PROTOCOL_GUID AND + EFI_SMBUS_HC_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmiHandlerGeneric.c b/Chipset/SB/SmiHandlerGeneric.c new file mode 100644 index 0000000..112cc29 --- /dev/null +++ b/Chipset/SB/SmiHandlerGeneric.c @@ -0,0 +1,1796 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmiHandlerGeneric.c 2 4/25/12 9:35a Victortu $ +// +// $Revision: 2 $ +// +// $Date: 4/25/12 9:35a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmiHandlerGeneric.c $ +// +// 2 4/25/12 9:35a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// 1 2/08/12 8:27a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmiHandlerGeneric.c +// +// Description: This file contains implementation of generic SMI handler +// functions +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include "SmmChildDispatch.h" +#include <DXE.h> +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +static UINT64 gCurrentInterval = 0xffffffffffffffff; +static UINT16 gEnabledUsbSmi = 0; +static UINT16 gActiveUsbSmi = 0; +static UINT32 gEnabledGpiSmi = 0; +static UINT32 gEnabledTcoSmi = 0; +static UINT32 gEnabledIoTrapSmi = 0; +static UINT32 gIoTrapWriteData = 0; + +BOOLEAN gIsLastState = FALSE; + +// GUID Definition(s) +EFI_GUID gDxeGuid = DXE_SERVICES_TABLE_GUID; + +// Protocol Definition(s) + +// External Declaration(s) + +extern EFI_SMM_SYSTEM_TABLE *pSmst; +extern SMM_CHILD_DISPATCHER SmmHandler[]; +extern EFI_SMM_SMI_CONTEXT SmiContext; + +extern UINT64 gSupportedIntervals[]; + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// Software SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwAddHandler +// +// Description: This function adds SW SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSwAddHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC if (SmmHandler[EfiSmmSwSmi].RegisteredCallbacks.Size == 1) SwSmiEnable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwRemoveHandler +// +// Description: This function removes SW SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSwRemoveHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC if (SmmHandler[EfiSmmSwSmi].RegisteredCallbacks.Size == 1) SwSmiDisable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwVerifyContext +// +// Description: This function verifies SW SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSwVerifyContext ( + IN VOID *Context ) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmSwSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_SW_DISPATCH_CONTEXT *SwContext; +//#### Use Intel RC EFI_SMM_SW_DISPATCH_CONTEXT *RegisteredSwContext; + +//#### Use Intel RC SwContext = (EFI_SMM_SW_DISPATCH_CONTEXT *)Context; +//#### Use Intel RC // First check if we already registered handler for this value +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC RegisteredSwContext = (EFI_SMM_SW_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC if(SwContext->SwSmiInputValue == RegisteredSwContext->SwSmiInputValue) +//#### Use Intel RC // Handler with this value already registered +//#### Use Intel RC return EFI_INVALID_PARAMETER; + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC // Second check if given value is extended SMI value, +//#### Use Intel RC // check the lowest byte +//#### Use Intel RC if ((SwContext->SwSmiInputValue & 0xff) == EXTENDED_SMI) +//#### Use Intel RC return EFI_SUCCESS; // Accept value of UINTN size + +//#### Use Intel RC // Third check if given value is in default range +//#### Use Intel RC return (SwContext->SwSmiInputValue > MAX_SW_SMI_INPUT_VALUE) ? \ +//#### Use Intel RC EFI_INVALID_PARAMETER : EFI_SUCCESS; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwGetContext +// +// Description: This function verifies SW SMI event and sets SW SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - SW SMI occured, context saved +// FALSE - There was no SW SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmSwGetContext (VOID) +{ + UINT16 SwSmiNumber; + BOOLEAN SwSmiDetected; + + // use intel ref code + return FALSE; + + SwSmiDetected = SwSmiDetect( &SwSmiNumber ); + + if (SwSmiDetected) { + if(SwSmiNumber == EXTENDED_SMI) { + // Get the actual number from EAX register + SmiContext.SwContext.SwSmiInputValue = GetEAX(); + } else { + SmiContext.SwContext.SwSmiInputValue = SwSmiNumber; + } + } + + return SwSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwDispatchSmi +// +// Description: This function dispatches SW SMI event based on context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmSwDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler; +//#### Use Intel RC EFI_SMM_SW_DISPATCH_CONTEXT *SwContext; + +//#### Use Intel RC Handler = \ +//#### Use Intel RC (HANDLER_LINK *)SmmHandler[EfiSmmSwSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC SwContext = (EFI_SMM_SW_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC if(SwContext->SwSmiInputValue == SmiContext.SwContext.SwSmiInputValue) +//#### Use Intel RC Handler->Callback(Handler, SwContext); + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC SwSmiClear(); +} + +//--------------------------------------------------------------------------- +// Sleep SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxAddHandler +// +// Description: This function adds Sx SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSxAddHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC#if SLP_SMI_ENABLE_ON_REGISTER +//#### Use Intel RC if (SmmHandler[EfiSmmSxSmi].RegisteredCallbacks.Size == 1) SxSmiEnable(); +//#### Use Intel RC#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxRemoveHandler +// +// Description: This function removes Sx SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSxRemoveHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC if (SmmHandler[EfiSmmSxSmi].RegisteredCallbacks.Size == 1) SxSmiDisable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxVerifyContext +// +// Description: This function verifies Sx SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_SUCCESS - Context verified +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSxVerifyContext ( + IN VOID *Context ) +{ + EFI_SMM_SX_DISPATCH_CONTEXT *SxContext; + + SxContext = (EFI_SMM_SX_DISPATCH_CONTEXT *)Context; + if ((SxContext->Type >= EfiMaximumSleepType) || \ + (SxContext->Phase >= EfiMaximumPhase)) + return EFI_INVALID_PARAMETER; + + return ((SxContext->Phase) != SxExit) ? EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxGetContext +// +// Description: This function verifies Sx SMI event and sets SX SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Sx SMI occured, context saved +// FALSE - There was no SX SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmSxGetContext (VOID) +{ + UINT16 SxSleepState; + BOOLEAN SxSmiDetected; + // use intel ref code + return FALSE; + + SxSmiDetected = SxSmiDetect( &SxSleepState ); + + SmiContext.SxContext.Type = SxSleepState; + SmiContext.SxContext.Phase = SxEntry; + + return SxSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxDispatchSmi +// +// Description: This function dispatches Sx SMI event based on context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmSxDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler; +//#### Use Intel RC EFI_SMM_SX_DISPATCH_CONTEXT *SxContext; + +//#### Use Intel RC Handler = \ +//#### Use Intel RC (HANDLER_LINK *)SmmHandler[EfiSmmSxSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC SxContext = (EFI_SMM_SX_DISPATCH_CONTEXT *)Handler->Context; + +//#### Use Intel RC if ((SxContext->Type == SmiContext.SxContext.Type) && \ +//#### Use Intel RC (SxContext->Phase == SmiContext.SxContext.Phase)) +//#### Use Intel RC Handler->Callback(Handler, SxContext); + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC SxSmiClear(); + +//#### Use Intel RC if (SmiContext.SxContext.Type == SxS0) return; + +//#### Use Intel RC PutToSleep( &(SmiContext.SxContext) ); + + // Control returns here on S1. + +//#### Use Intel RC SxSmiClear(); +} + +//--------------------------------------------------------------------------- +// Periodic timer SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerAddHandler +// +// Description: This function adds Periodic timer SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTimerAddHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *TimerContext; + +//#### Use Intel RC TimerContext = (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Context; + +//#### Use Intel RC TimerContext->TimerEnabled = TRUE; + +//#### Use Intel RC if (SmmHandler[EfiSmmPeriodicTimerSmi].RegisteredCallbacks.Size == 1) { +//#### Use Intel RC gCurrentInterval = TimerContext->SmiTickInterval; +//#### Use Intel RC TimerSetInterval( TimerContext->SmiTickInterval ); +//#### Use Intel RC TimerSmiClear(); +//#### Use Intel RC TimerSmiEnable(); +//#### Use Intel RC return EFI_SUCCESS; +//#### Use Intel RC } + +//#### Use Intel RC if (gCurrentInterval > TimerContext->SmiTickInterval) { +//#### Use Intel RC gCurrentInterval = TimerContext->SmiTickInterval; +//#### Use Intel RC TimerSetInterval( TimerContext->SmiTickInterval ); +//#### Use Intel RC } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerRemoveHandler +// +// Description: This function removes Periodic timer SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTimerRemoveHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmPeriodicTimerSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *TimerContext; +//#### Use Intel RC EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *CurrentTimerContext; +//#### Use Intel RC UINT64 Interval = 0xffffffffffffffff; + +//#### Use Intel RC UINT16 CurrentIntervalCounter = 0; +//#### Use Intel RC UINT64 *SupportedIntervals = gSupportedIntervals; + +//#### Use Intel RC ((EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Context)->TimerEnabled = \ +//#### Use Intel RC FALSE; + +//#### Use Intel RC if (SmmHandler[EfiSmmPeriodicTimerSmi].RegisteredCallbacks.Size == 1) { +//#### Use Intel RC gCurrentInterval = 0xffffffffffffffff; +//#### Use Intel RC TimerSmiDisable(); +//#### Use Intel RC return EFI_SUCCESS; +//#### Use Intel RC } + +//#### Use Intel RC CurrentTimerContext = (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Context; +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC TimerContext = \ +//#### Use Intel RC (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC if (Interval > TimerContext->SmiTickInterval) +//#### Use Intel RC Interval = TimerContext->SmiTickInterval; +//#### Use Intel RC if (TimerContext->SmiTickInterval == \ +//#### Use Intel RC CurrentTimerContext->SmiTickInterval) +//#### Use Intel RC CurrentIntervalCounter++; +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC if ((Interval == CurrentTimerContext->SmiTickInterval) && \ +//#### Use Intel RC (CurrentIntervalCounter == 1)) { +//#### Use Intel RC Interval = 0xffffffffffffffff; +//#### Use Intel RC while (*SupportedIntervals != 0) { +//#### Use Intel RC if (*SupportedIntervals != CurrentTimerContext->SmiTickInterval) +//#### Use Intel RC if (*SupportedIntervals < Interval) +//#### Use Intel RC Interval = *SupportedIntervals; +//#### Use Intel RC SupportedIntervals++; +//#### Use Intel RC } +//#### Use Intel RC } + +//#### Use Intel RC // This means lowest rate timer no longer active +//#### Use Intel RC if (gCurrentInterval < Interval) { +//#### Use Intel RC gCurrentInterval = Interval; +//#### Use Intel RC TimerSetInterval( Interval ); +//#### Use Intel RC } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerVerifyContext +// +// Description: This function verifies Periodic timer SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTimerVerifyContext ( + IN VOID *Context ) +{ + EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *TimerContext; + UINT64 *Interval = gSupportedIntervals; + + TimerContext = (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Context; + while (*Interval != 0) { + if (*Interval == TimerContext->SmiTickInterval) return EFI_SUCCESS; + Interval++; + } + + return EFI_INVALID_PARAMETER; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerGetContext +// +// Description: This function verifies Periodic timer SMI event and sets +// Periodic timer SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Periodic timer SMI occured, context saved +// FALSE - There was no Periodic timer SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmTimerGetContext (VOID) +{ + UINT16 TimerType; + BOOLEAN TimerSmiDetected; + + // use intel ref code + return FALSE; + + TimerSmiDetected = TimerSmiDetect( &TimerType ); + SmiContext.TimerContext.SmiTickInterval = gCurrentInterval; + + return TimerSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerDispatchSmi +// +// Description: This function dispatches Periodic timer SMI event based on +// context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmTimerDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmPeriodicTimerSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *TimerContext; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC TimerContext = \ +//#### Use Intel RC (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Handler->Context; + +//#### Use Intel RC if (TimerContext->TimerEnabled) { +//#### Use Intel RC TimerContext->ElapsedTime += \ +//#### Use Intel RC SmiContext.TimerContext.SmiTickInterval; +//#### Use Intel RC if ((TimerContext->ElapsedTime) >= (TimerContext->Period)) { +//#### Use Intel RC Handler->Callback(Handler, TimerContext); +//#### Use Intel RC TimerContext->ElapsedTime = 0; +//#### Use Intel RC } +//#### Use Intel RC } +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC TimerSmiClear(); +} + +//--------------------------------------------------------------------------- +// USB SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbAddHandler +// +// Description: This function adds USB SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmUsbAddHandler ( + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_SMM_USB_DISPATCH_CONTEXT *UsbContext; + UINT16 ControllerType; + VOID *NewDp; + UINTN Length; + + UsbContext = (EFI_SMM_USB_DISPATCH_CONTEXT *)Context; + + // Save USB device path protocol into SMM memory + Length = DPLength( UsbContext->Device ); + Status = pSmst->SmmAllocatePool( 0, Length, &NewDp ); + if (EFI_ERROR(Status)) return Status; + MemCpy( NewDp, UsbContext->Device, Length ); + UsbContext->Device = (EFI_DEVICE_PATH_PROTOCOL *)NewDp; + + ControllerType = GetControllerType( UsbContext->Device ); + if((ControllerType & gEnabledUsbSmi) == 0) { + gEnabledUsbSmi |= ControllerType; + UsbSmiSet( gEnabledUsbSmi ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbRemoveHandler +// +// Description: This function removes USB SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmUsbRemoveHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmUsbSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_USB_DISPATCH_CONTEXT *UsbContext; +//#### Use Intel RC UINT16 ControllerType = 0; + +//#### Use Intel RC UsbContext = (EFI_SMM_USB_DISPATCH_CONTEXT *)Context; + +//#### Use Intel RC pSmst->SmmFreePool( UsbContext->Device ); + +//#### Use Intel RC if (SmmHandler[EfiSmmUsbSmi].RegisteredCallbacks.Size == 1) { +//#### Use Intel RC gEnabledUsbSmi = 0; +//#### Use Intel RC UsbSmiSet( gEnabledUsbSmi ); +//#### Use Intel RC return EFI_SUCCESS; +//#### Use Intel RC } + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC UsbContext = (EFI_SMM_USB_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC ControllerType |= GetControllerType( UsbContext->Device ); +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC if (ControllerType != gEnabledUsbSmi) { +//#### Use Intel RC gEnabledUsbSmi = ControllerType; +//#### Use Intel RC UsbSmiSet( gEnabledUsbSmi ); +//#### Use Intel RC } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbVerifyContext +// +// Description: This function verifies USB SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmUsbVerifyContext ( + IN VOID *Context ) +{ + EFI_SMM_USB_DISPATCH_CONTEXT *UsbContext; + UINT16 ControllerType; + + UsbContext = (EFI_SMM_USB_DISPATCH_CONTEXT *)Context; + ControllerType = GetControllerType( UsbContext->Device ); + if (((ControllerType & 3) == 0) || (UsbContext->Type > UsbWake)) + return EFI_INVALID_PARAMETER; + + return ((UsbContext->Type) > UsbLegacy) ? EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbGetContext +// +// Description: This function verifies USB SMI event and sets USB SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - USB SMI occured, context saved +// FALSE - There was no USB SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmUsbGetContext (VOID) +{ + BOOLEAN UsbSmiDetected; + // use intel ref code + return FALSE; + + UsbSmiDetected = UsbSmiDetect( &gActiveUsbSmi ); + SmiContext.UsbContext.Type = UsbLegacy; + + return UsbSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbDispatchSmi +// +// Description: This function dispatches USB SMI event based on context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmUsbDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmUsbSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_USB_DISPATCH_CONTEXT *UsbContext; +//#### Use Intel RC UINT16 ControllerType; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC UsbContext = (EFI_SMM_USB_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC ControllerType = GetControllerType( UsbContext->Device ); + +//#### Use Intel RC if (((ControllerType & gActiveUsbSmi) != 0) && \ +//#### Use Intel RC (UsbContext->Type == SmiContext.UsbContext.Type)) +//#### Use Intel RC Handler->Callback(Handler, UsbContext); + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC UsbSmiClear( gActiveUsbSmi ); + +//#### Use Intel RC gActiveUsbSmi = 0; +} + +//--------------------------------------------------------------------------- +// GPI SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiAddHandler +// +// Description: This function adds GPI SMI handler +// +// Input: VOID *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmGpiAddHandler ( + IN VOID *Context ) +{ + EFI_SMM_GPI_DISPATCH_CONTEXT *GpiContext; + + GpiContext = (EFI_SMM_GPI_DISPATCH_CONTEXT *)Context; + if (((UINT32)(GpiContext->GpiNum) & gEnabledGpiSmi) == 0) { + gEnabledGpiSmi |= (UINT32)(GpiContext->GpiNum); + GpiSmiSet( (UINT32)(GpiContext->GpiNum) ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiRemoveHandler +// +// Description: This function removes GPI SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmGpiRemoveHandler ( + IN VOID *Context ) +{ + UINTN RemoveGpiSmi = ((EFI_SMM_GPI_DISPATCH_CONTEXT *)Context)->GpiNum; + + gEnabledGpiSmi &= ~((UINT32)RemoveGpiSmi); + + GpiSmiReset( (UINT32)RemoveGpiSmi ); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiVerifyContext +// +// Description: This function verifies GPI SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmGpiVerifyContext ( + IN VOID *Context ) +{ + EFI_SMM_GPI_DISPATCH_CONTEXT *GpiContext; + + GpiContext = (EFI_SMM_GPI_DISPATCH_CONTEXT *)Context; + if ((GpiContext->GpiNum & (UINT32)SUPPORTED_GPIS) == 0) + return EFI_INVALID_PARAMETER; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiGetContext +// +// Description: This function verifies GPI SMI event and sets GPI SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - GPI SMI occured, context saved +// FALSE - There was no GPI SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmGpiGetContext (VOID) +{ +//#### Use Intel RC BOOLEAN GpiSmiDetected; +//#### Use Intel RC UINT32 GpiSmiNum; + + // use intel ref code +//#### Use Intel RC GpiSmiDetected = GpiSmiDetect( &GpiSmiNum ); +//#### Use Intel RC SmiContext.GpiContext.GpiNum = GpiSmiNum; +//#### Use Intel RC return GpiSmiDetected; + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiDispatchSmi +// +// Description: This function dispatches GPI SMI event based on context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmGpiDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmGpiSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_GPI_DISPATCH_CONTEXT *GpiContext; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC GpiContext = (EFI_SMM_GPI_DISPATCH_CONTEXT *)Handler->Context; + +//#### Use Intel RC if ((SmiContext.GpiContext.GpiNum & GpiContext->GpiNum) != 0) +//#### Use Intel RC Handler->Callback( Handler, GpiContext ); + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC GpiSmiClear( (UINT16)SmiContext.GpiContext.GpiNum ); +} + +//--------------------------------------------------------------------------- +// Standby button SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonAddHandler +// +// Description: This function adds Standby button SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSButtonAddHandler ( + IN VOID *Context ) +{ + if (SmmHandler[EfiSmmStandbyButtonSmi].RegisteredCallbacks.Size == 1) + SButtonSmiEnable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonRemoveHandler +// +// Description: This function removes Standby button SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSButtonRemoveHandler ( + IN VOID *Context ) +{ + if (SmmHandler[EfiSmmStandbyButtonSmi].RegisteredCallbacks.Size == 1) + SButtonSmiDisable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonVerifyContext +// +// Description: This function verifies Standby button SMI context +// +// Input: VOID *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSButtonVerifyContext ( + IN VOID *Context ) +{ + EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT *SButtonContext; + + SButtonContext = (EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT *)Context; + if (SButtonContext->Phase > Exit) + return EFI_INVALID_PARAMETER; + + return (SButtonContext->Phase > Entry) ? EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonGetContext +// +// Description: This function verifies Standby button SMI event and sets +// Standby button SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Standby button SMI occured, context saved +// FALSE - There was no Standby button SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmSButtonGetContext (VOID) +{ + UINT16 Dummy = 0; + BOOLEAN SButtonSmiDetected; + + SButtonSmiDetected = SButtonSmiDetect( &Dummy ); + + SmiContext.SBtnContext.Phase = Entry; + + return SButtonSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonDispatchSmi +// +// Description: This function dispatches Standby button SMI event based on +// context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmSButtonDispatchSmi (VOID) +{ + HANDLER_LINK *Handler = (HANDLER_LINK *)\ + SmmHandler[EfiSmmStandbyButtonSmi].RegisteredCallbacks.pHead; + EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT *SButtonContext; + + while (Handler != NULL) { + SButtonContext = \ + (EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT *)Handler->Context; + + if (SButtonContext->Phase == SmiContext.SBtnContext.Phase) + Handler->Callback( Handler, SButtonContext ); + + Handler = (HANDLER_LINK *)Handler->Link.pNext; + } + + SButtonSmiClear(); +} + +//--------------------------------------------------------------------------- +// Power button SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonAddHandler +// +// Description: This function adds Power button SMI handler +// +// Input: *Context - pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmPButtonAddHandler ( + IN VOID *Context ) +{ +#if 0 + if (SmmHandler[EfiSmmPowerButtonSmi].RegisteredCallbacks.Size == 1) + PButtonSmiEnable(); +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonRemoveHandler +// +// Description: This function removes Power button SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS; +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmPButtonRemoveHandler ( + IN VOID *Context ) +{ +#if 0 + if (SmmHandler[EfiSmmPowerButtonSmi].RegisteredCallbacks.Size == 1) + PButtonSmiDisable(); +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonVerifyContext +// +// Description: This function verifies Power button SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmPButtonVerifyContext ( + IN VOID *Context ) +{ + EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *PButtonContext; + + PButtonContext = (EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *)Context; + if (PButtonContext->Phase > PowerButtonExit) + return EFI_INVALID_PARAMETER; + + return (PButtonContext->Phase > PowerButtonEntry) ? \ + EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonGetContext +// +// Description: This function verifies Power button SMI event and sets Power +// button SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Power button SMI occured, context saved +// FALSE - There was no Power button SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmPButtonGetContext (VOID) +{ + UINT16 Dummy = 0; + BOOLEAN PButtonSmiDetected; + + PButtonSmiDetected = PButtonSmiDetect( &Dummy ); + + SmiContext.PBtnContext.Phase = PowerButtonEntry; + + return PButtonSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonDispatchSmi +// +// Description: This function dispatches Power button SMI event based on +// context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmPButtonDispatchSmi (VOID) +{ +#if 0 + HANDLER_LINK *Handler = (HANDLER_LINK *)\ + SmmHandler[EfiSmmPowerButtonSmi].RegisteredCallbacks.pHead; + EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *PButtonContext; + + while (Handler != NULL) { + PButtonContext = \ + (EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *)Handler->Context; + + if (PButtonContext->Phase == SmiContext.PBtnContext.Phase) + Handler->Callback( Handler, PButtonContext ); + + Handler = (HANDLER_LINK *)Handler->Link.pNext; + } + + PButtonSmiClear(); + + SBLib_Shutdown(); +#endif +} +//--------------------------------------------------------------------------- +// TCO SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTcoAddHandler +// +// Description: This function adds TCO SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTcoAddHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC EFI_SMM_TCO_DISPATCH_CONTEXT *TcoContext; + +//#### Use Intel RC TcoContext = (EFI_SMM_TCO_DISPATCH_CONTEXT *)Context; + +//#### Use Intel RC gEnabledTcoSmi |= (1 << (UINT32)(TcoContext->TcoBitOffset)); +//#### Use Intel RC TcoSmiSet( (UINT32)(TcoContext->TcoBitOffset) ); + +//#### Use Intel RC if (SmmHandler[EfiSmmTcoSmi].RegisteredCallbacks.Size == 1) +//#### Use Intel RC TcoSmiEnable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTcoRemoveHandler +// +// Description: This function removes TCO SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTcoRemoveHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC UINT32 RemoveTcoSmiOffset = (UINT32) \ +//#### Use Intel RC (((EFI_SMM_TCO_DISPATCH_CONTEXT *)Context)->TcoBitOffset); + +//#### Use Intel RC TcoSmiReset( RemoveTcoSmiOffset ); + +//#### Use Intel RC gEnabledTcoSmi &= ~(1 << RemoveTcoSmiOffset); + +//#### Use Intel RC if (gEnabledTcoSmi == 0) TcoSmiDisable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTcoVerifyContext +// +// Description: This function verifies TCO SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_SUCCESS - Context verified +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTcoVerifyContext ( + IN VOID *Context ) +{ +//#### Use Intel RC EFI_SMM_TCO_DISPATCH_CONTEXT *TcoContext; + +//#### Use Intel RC TcoContext = (EFI_SMM_TCO_DISPATCH_CONTEXT *)Context; + +//#### Use Intel RC if (((1 << TcoContext->TcoBitOffset) & SUPPORTED_TCOS) == 0) +//#### Use Intel RC return EFI_UNSUPPORTED; + +//#### Use Intel RC if ( TcoContext->TcoBitOffset > 32) return EFI_INVALID_PARAMETER; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTcoGetContext +// +// Description: This function verifies TCO SMI event and sets TCO SMI context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - TCO SMI occured, context saved +// FALSE - There was no TCO SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmTcoGetContext (VOID) +{ +//#### Use Intel RC UINT32 TcoStatus; +//#### Use Intel RC BOOLEAN TcoSmiDetected; + +//#### Use Intel RC TcoSmiDetected = TcoSmiDetect( &TcoStatus ); +//#### Use Intel RC SmiContext.TcoContext.TcoBitOffset = (UINTN)(TcoStatus & gEnabledTcoSmi); +//#### Use Intel RC if (SmiContext.TcoContext.TcoBitOffset == 0) TcoSmiDetected = FALSE; + +//#### Use Intel RC return TcoSmiDetected; + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTcoDispatchSmi +// +// Description: This function dispatches TCO SMI event based on context +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmTcoDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler; +//#### Use Intel RC EFI_SMM_TCO_DISPATCH_CONTEXT *TcoContext; + +//#### Use Intel RC Handler = \ +//#### Use Intel RC (HANDLER_LINK *)SmmHandler[EfiSmmTcoSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC TcoContext = (EFI_SMM_TCO_DISPATCH_CONTEXT *)Handler->Context; + +//#### Use Intel RC if ((Shl64( 1 , (UINT8)TcoContext->TcoBitOffset)) & \ +//#### Use Intel RC SmiContext.TcoContext.TcoBitOffset) +//#### Use Intel RC Handler->Callback(Handler, TcoContext); + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC TcoSmiClear(); +} + +//--------------------------------------------------------------------------- +// I/O Trap SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapAddHandler +// +// Description: This function adds I/O Trap SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmIoTrapAddHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC HANDLER_LINK *Handler; +//#### Use Intel RC EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *RegedContext; +//#### Use Intel RC EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *IoTrapContext; +//#### Use Intel RC UINTN i = 0; +//#### Use Intel RC UINT32 TrapRegIndex = 0; + +//#### Use Intel RC IoTrapContext = (EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *)Context; + +//#### Use Intel RC Handler = \ +//#### Use Intel RC (HANDLER_LINK *)SmmHandler[EfiSmmIoTrapSmi].RegisteredCallbacks.pHead; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC RegedContext = (EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC if (RegedContext->Address == IoTrapContext->Address) { +//#### Use Intel RC TrapRegIndex = RegedContext->TrapRegIndex; +//#### Use Intel RC i++; +//#### Use Intel RC } +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC if (i > 1) { +//#### Use Intel RC IoTrapContext->TrapRegIndex = TrapRegIndex; +//#### Use Intel RC return EFI_SUCCESS; +//#### Use Intel RC } + +//#### Use Intel RC IoTrapSmiSet( IoTrapContext ); + +//#### Use Intel RC gEnabledIoTrapSmi |= (1 << (UINT32)(IoTrapContext->TrapRegIndex)); + +//#### Use Intel RC if (SmmHandler[EfiSmmIoTrapSmi].RegisteredCallbacks.Size == 1) +//#### Use Intel RC IoTrapSmiEnable(); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapRemoveHandler +// +// Description: This function removes I/O Trap SMI handler +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmIoTrapRemoveHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC HANDLER_LINK *Handler; +//#### Use Intel RC EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *RegedContext; +//#### Use Intel RC UINTN i = 0; +//#### Use Intel RC UINTN RemoveIoTrapRegIndex = \ +//#### Use Intel RC (((EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *)Context)->TrapRegIndex); + +//#### Use Intel RC Handler = \ +//#### Use Intel RC (HANDLER_LINK *)SmmHandler[EfiSmmIoTrapSmi].RegisteredCallbacks.pHead; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC RegedContext = (EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC if (RegedContext->TrapRegIndex == RemoveIoTrapRegIndex) i++; +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC if (i > 1) return EFI_SUCCESS; + +//#### Use Intel RC IoTrapSmiReset( Context ); + +//#### Use Intel RC gEnabledIoTrapSmi &= ~(1 << RemoveIoTrapRegIndex); + +//#### Use Intel RC if (gEnabledIoTrapSmi == 0) IoTrapSmiDisable(); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapVerifyContext +// +// Description: This function verifies I/O Trap SMI context +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_SUCCESS - Context verified +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_UNSUPPORTED - Context is not supported +// EFI_OUT_OF_RESOURCES - There is no I/O Trap register +// available +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmIoTrapVerifyContext ( + IN VOID *Context ) +{ +//#### Use Intel RC HANDLER_LINK *Handler; +//#### Use Intel RC EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *RegedContext; +//#### Use Intel RC EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *IoTrapContext; + +//#### Use Intel RC Handler = \ +//#### Use Intel RC (HANDLER_LINK *)SmmHandler[EfiSmmIoTrapSmi].RegisteredCallbacks.pHead; + +//#### Use Intel RC IoTrapContext = (EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *)Context; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC RegedContext = (EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC if (RegedContext->Address == IoTrapContext->Address) { +//#### Use Intel RC if ( IoTrapContext->Length > MAX_SUPPORTED_IOTRAP_LENGTH) +//#### Use Intel RC return EFI_INVALID_PARAMETER; +//#### Use Intel RC return EFI_SUCCESS; +//#### Use Intel RC } +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC if (gEnabledIoTrapSmi >= ((1 << MAX_SUPPORTED_IOTRAP_REGS) - 1)) +//#### Use Intel RC return EFI_OUT_OF_RESOURCES; + +//#### Use Intel RC if ( IoTrapContext->Length > MAX_SUPPORTED_IOTRAP_LENGTH) +//#### Use Intel RC return EFI_INVALID_PARAMETER; + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapGetContext +// +// Description: This function verifies I/O Trap SMI event and sets +// I/O Trap SMI context. +// +// Input: None +// +// Output: BOOLEAN +// TRUE - I/O Trap SMI occured, context saved +// FALSE - There was no I/O Trap SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmIoTrapGetContext (VOID) +{ + return IoTrapSmiDetect( &SmiContext.IoTrapContext ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapDispatchSmi +// +// Description: This function dispatches I/O Trap SMI event based on context. +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmIoTrapDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler; +//#### Use Intel RC EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *IoTrapContext; + +//#### Use Intel RC Handler = \ +//#### Use Intel RC (HANDLER_LINK *)SmmHandler[EfiSmmIoTrapSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC IoTrapContext = (EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *)Handler->Context; + +//#### Use Intel RC if ( IoTrapContext->TrapRegIndex == \ +//#### Use Intel RC SmiContext.IoTrapContext.TrapRegIndex) +//#### Use Intel RC if ( gEnabledIoTrapSmi & (1 << IoTrapContext->TrapRegIndex)) +//#### Use Intel RC Handler->Callback(Handler, &SmiContext.IoTrapContext); + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC IoTrapSmiClear(); +} + +//--------------------------------------------------------------------------- +// BIOS Write SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmBiosWriteAddHandler +// +// Description: This function adds BIOS Write SMI handler. +// +// Input: *Context - pointer to SMI context +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmBiosWriteAddHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC if (SmmHandler[EfiSmmBiosWriteSmi].RegisteredCallbacks.Size == 1) +//#### Use Intel RC BiosWriteSmiEnable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmBiosWriteRemoveHandler +// +// Description: This function removes BIOS Write SMI handler. +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_SUCCESS; +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmBiosWriteRemoveHandler ( + IN VOID *Context ) +{ +//#### Use Intel RC if (SmmHandler[EfiSmmBiosWriteSmi].RegisteredCallbacks.Size == 1) +//#### Use Intel RC BiosWriteSmiDisable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmBiosWriteVerifyContext +// +// Description: This function verifies BIOS Write SMI context. +// +// Input: *Context - Pointer to SMI context +// +// Output: EFI_STATUS +// EFI_SUCCESS - Context verified +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmBiosWriteVerifyContext ( + IN VOID *Context ) +{ + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmBiosWriteGetContext +// +// Description: This function verifies BIOS Write SMI event. +// +// Input: None +// +// Output: BOOLEAN +// TRUE - BIOS Write SMI occured. +// FALSE - There was no BIOS Write SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmBiosWriteGetContext (VOID) +{ + return BiosWriteSmiDetect(); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmBiosWriteDispatchSmi +// +// Description: This function dispatches BIOW Write SMI event based on +// context. +// +// Input: None +// +// Output: None +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SmmBiosWriteDispatchSmi (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmBiosWriteSmi].RegisteredCallbacks.pHead; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC Handler->Callback( Handler, NULL ); +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + +//#### Use Intel RC BiosWriteSmiClear(); +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmiHandlerPorting.c b/Chipset/SB/SmiHandlerPorting.c new file mode 100644 index 0000000..d0e55e1 --- /dev/null +++ b/Chipset/SB/SmiHandlerPorting.c @@ -0,0 +1,1699 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmiHandlerPorting.c 6 3/19/13 8:21a Scottyang $ +// +// $Revision: 6 $ +// +// $Date: 3/19/13 8:21a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmiHandlerPorting.c $ +// +// 6 3/19/13 8:21a Scottyang +// [TAG] EIP118158 +// [Category] Improvement +// [Description] Correct SBLib_CmosRead () offset. +// [Files] SmiHandlerPorting2.c, SBDxe.c, SBGeneric.c, SBSmm.c, +// SmiHandlerPorting.c +// +// 5 11/06/12 8:10a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Reduce function "GetPchSeries()". +// [Files] SBPEI.c, SBDxe.c, SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 4 9/26/12 4:00a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 3 7/27/12 6:15a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 2 4/25/12 9:33a Victortu +// +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// [TAG] EIP73033 +// [Category] Improvement +// [Description] 'PciDevicePath' used in GetControllerType(), +// conditionally not set. +// [Files] SmiHandlerPorting.c; SmiHandlerPorting2.c +// +// 1 2/08/12 8:27a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmiHandlerPorting.c +// +// Description: This file contains SMM Child Dispatcher porting functions +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include <AmiSmm.h> +#include "SmmChildDispatch.h" + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +UINT64 gSupportedIntervals[] = { + // Porting required - put all available intervals here (in Nanoseconds) +#if SWSMI_TIMER_INSTEAD + 15000, // 1.5ms + 160000, // 16 ms + 320000, // 32 ms + 640000, // 64 ms +#else + 600000000, // 60 Seconds + 320000000, // 32 Seconds + 160000000, // 16 Seconds + 80000000, // 8 Seconds +#endif + + // Terminator record + 0 +}; + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +extern EFI_SMM_SYSTEM_TABLE *pSmst; + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// All purpose SMI Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsAcpi +// +// Description: This function determines if the system is in ACPI mode. +// +// Input: None +// +// Output: BOOLEAN +// TRUE - It is in ACPI mode +// FALSE - It is not in ACPI mode +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsAcpi (VOID) +{ + return (READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 1) ? TRUE : FALSE; // 0x04 +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsMe +// +// Description: This function checks whether the specific SMI event is raised +// +// Input: CheckBitNo - The bit number for the specific SMI. +// +// Output: BOOLEAN +// TRUE - It is the specific SMI event +// FALSE - It is not the specific SMI event +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsMe ( + IN UINT8 CheckBitNo ) +{ + volatile UINT32 Buffer32 = READ_IO32_PM(ACPI_IOREG_SMI_EN); // 0x30 + + Buffer32 &= READ_IO32_PM(ACPI_IOREG_SMI_STS); // 0x34 + return (Buffer32 & (UINT32)(1 << CheckBitNo)) ? TRUE : FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ClearAllSmi +// +// Description: This function clears all SMI's and issues an EOS (End of SMI). +// +// Input: None +// +// Output: None +// +// Notes: If you are porting INTEL chipset and have to support SWSMI +// Timer SMI, you must be unable to clear the SWSMI status in +// this routine. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ClearAllSmi (VOID) +{ + // Porting Required. Program to clear ALL SMI status bit + if ( !IsAcpi() ) { + if (READ_IO16_PM(ACPI_IOREG_PM1_EN) & 0x400) + if (READ_IO16_PM(ACPI_IOREG_PM1_STS) & 0x400) + SBLib_CmosRead(0x0C); + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0xcc31); // 0x00 + if (GetPchSeries() == PchLp) { + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_STS+0x0c, 0xffffffff); // 0x8C + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_STS, 0xffffffff); // 0x50 + } else { + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS, 0xffffffff); // 0x20 + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS+4, 0xffffffff); // 0x24 + WRITE_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS, 0xffff); // 0x3A + } + WRITE_IO16_PM(ACPI_IOREG_DEVACT_STS, 0xffff); // 0x44 + WRITE_IO16_TCO(TCO_IOREG_STS1, 0xffff); // 0x04 + WRITE_IO16_TCO(TCO_IOREG_STS2, 0xfffe); // 0x06 (Except Intruder Det) + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0xffffffbf); // 0x34 (Except SWSMI) + if ((READ_IO16_TCO(TCO_IOREG_CNT1) & 0x300) == 0x300) { // 0x08 + SET_IO16_TCO(TCO_IOREG_CNT1, 0x100); // Clear NMI_NOW if needed. + } + } + // EOS + SET_IO8_PM(ACPI_IOREG_SMI_EN, 0x02); // 0x30 + if ((READ_IO8_PM(ACPI_IOREG_SMI_EN) & 0x02) == 0) { + // Reset GBL_SMI_EN + RESET_IO8_PM(ACPI_IOREG_SMI_EN, 0x01); // 0x30 + // Set EOS Again + SET_IO8_PM(ACPI_IOREG_SMI_EN, 0x02); // 0x30 + // Set GBL_SMI_EN + SET_IO8_PM(ACPI_IOREG_SMI_EN, 0x01); // 0x30 + } +} + +//--------------------------------------------------------------------------- +// SW SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiEnable +// +// Description: This function enables SW SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SwSmiEnable (VOID) +{ + // Porting required + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x20); // 0x30 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiDisable +// +// Description: This function disables SW SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SwSmiDisable (VOID) +{ + // Porting required + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x20); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiClear +// +// Description: This function clears SW SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SwSmiClear (VOID) +{ + // Porting required + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x20); // 0x34 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiDetect +// +// Description: This function detects SW SMI event +// +// Input: *Type - Pointer to store SW SMI number +// +// Output: TRUE - SW SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SwSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + if ( IsMe(5) ) { // SW_SMI + *Type = IoRead8(SW_SMI_IO_ADDRESS); + return TRUE; + } + + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetEAX +// +// Description: This function returns EAX saved value from CPU that caused +// SW SMI. +// +// Input: None +// +// Output: EAX saved value +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINTN GetEAX (VOID) +{ + // Porting required for different CPU + EFI_GUID SwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID; + SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger; + UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1; // CPU # + EFI_SMM_CPU_SAVE_STATE *CpuSaveState; + UINT16 i; + + for (i = 0; i < pSmst->NumberOfTableEntries; i++) { + if (guidcmp(&(pSmst->SmmConfigurationTable[i].VendorGuid), \ + &SwSmiCpuTriggerGuid) == 0) + break; + } + + // If found table, check for the CPU that caused the software Smi. + if (i != pSmst->NumberOfTableEntries) + { + SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable; + Cpu = SwSmiCpuTrigger->Cpu; + } + CpuSaveState = pSmst->CpuSaveState; + + return CpuSaveState[Cpu].Ia32SaveState.EAX; +} + +//--------------------------------------------------------------------------- +// SX SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiEnable +// +// Description: This function enables SX SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SxSmiEnable (VOID) +{ + // Porting required + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x10); // 0x30 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiDisable +// +// Description: This function disables SX SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SxSmiDisable (VOID) +{ + // Porting required + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x10); // 0x30 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiClear +// +// Description: This function clears SX SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SxSmiClear (VOID) +{ + // Porting required + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x10); // 0x34 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiDetect +// +// Description: This function detects SX SMI event +// +// Input: *Type - Pointer to store value of Sleep type +// +// Output: TRUE - SX SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SxSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + if (IsMe(4)) { // SLP_SMI + switch (READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & (7 << 10)) { // SLP_TYP + case (0 << 10): + *Type = SxS0; + break; + case (1 << 10): + *Type = SxS1; + break; + case (5 << 10): + *Type = SxS3; + break; + case (6 << 10): + *Type = SxS4; + break; + case (7 << 10): + *Type = SxS5; + break; + default: + return FALSE; // Unknown Error. + } + return TRUE; + } + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PutToSleep +// +// Description: Disable Smi sleep and put to sleep. +// +// Input: *Context - Pointer to Sleep SMI context +// +// Output: None +// +// Referrals: SxSmiDisable +// +// Notes: Here is the control flow of this function: +// 1. Disable Smi sleep. +// 2. Set to go to sleep if you want to sleep in SMI. otherwise +// set IORestart to 0xFF in CPU SMM dump area. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PutToSleep ( + IN VOID *SxContext ) +{ + EFI_SMM_CPU_SAVE_STATE *pCpuSaveState = pSmst->CpuSaveState; + UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1; + UINT32 CacheFlush = 0; + + SxSmiDisable(); // Disable sleep SMI. + +//#### if (SxContext->Type == SxS5) +//#### SBLib_BeforeShutdown(); + +#if ACPI_SLEEP_IN_SMM + SET_IO16_PM(ACPI_IOREG_PM1_CNTL, 0x2000); // Set to sleep. +#else + CacheFlush = pCpuSaveState[Cpu].Ia32SaveState.IORestart; + pCpuSaveState[Cpu].Ia32SaveState.IORestart = 0xff; +#endif + +} + +//--------------------------------------------------------------------------- +// Periodic timer SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiEnable +// +// Description: This function enables Periodic timer SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSmiEnable (VOID) +{ + // Porting required +#if SWSMI_TIMER_INSTEAD + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x40); // 0x30 +#else + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x4000); // 0x30 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiDisable +// +// Description: This function disables Periodic timer SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSmiDisable (VOID) +{ + // Porting required +#if SWSMI_TIMER_INSTEAD + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x40); // 0x30 +#else + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x4000); // 0x30 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiClear +// +// Description: This function clears Periodic timer SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSmiClear (VOID) +{ + // Porting required +#if SWSMI_TIMER_INSTEAD + // SWSMI has to be disabled before clear the status + volatile UINT32 Buffer32 = READ_IO32_PM(ACPI_IOREG_SMI_EN); // 0x30 + WRITE_IO32_PM(ACPI_IOREG_SMI_EN, Buffer32 & (UINT32)(~0x40)); // 0x30 + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x40); // 0x34 + WRITE_IO32_PM(ACPI_IOREG_SMI_EN, Buffer32); // 0x30 +#else + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x4000); // 0x34 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiDetect +// +// Description: This function detects Periodic timer SMI event +// +// Input: *Type - Added for compatibility, not used +// +// Output: TRUE - Periodic timer SMI occured, FALSE otherwise +// +// Notes: Return TRUE if Timer SMI detected, Type ignored +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN TimerSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + *Type = 0; +#if SWSMI_TIMER_INSTEAD + return (IsMe(6)) ? TRUE : FALSE; +#else + return (IsMe(14)) ? TRUE : FALSE; +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSetInterval +// +// Description: This function programs Periodic timer to given interval +// +// Input: Interval - Interval to program +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSetInterval ( + IN UINT64 Interval ) +{ + // Porting required + UINT16 RateIndex; + UINT16 AvailTimer = sizeof(gSupportedIntervals) / sizeof(UINT64) - 1; + + TimerSmiDisable(); + TimerSmiClear(); + + for (RateIndex = 0; RateIndex < AvailTimer ; RateIndex++) + if (Interval == gSupportedIntervals[RateIndex]) break; +#if SWSMI_TIMER_INSTEAD + RW_PCI16_SB(SB_REG_GEN_PMCON_3, RateIndex << 6, 0xc0); // 0xA4 +#else + RW_PCI16_SB(SB_REG_GEN_PMCON_1, RateIndex, 3); // 0xA0 +#endif + + TimerSmiEnable(); +} + +//--------------------------------------------------------------------------- +// Usb SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UsbSmiSet +// +// Description: This function enables/disables USB SMI based on given +// Controller type +// +// Input: ControllerType - USB controller type variable +// +// Output: None +// +// Notes: This function implements logic as follows: +// Two lowest bits of ControllerType: +// 00 - both USB controllers smi are disabled +// 01 - UHCI/OHCI enabled, EHCI - disabled +// 10 - UHCI/OHCI disabled, EHCI - enabled +// 11 - both USB controllers smi are enabled +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID UsbSmiSet( + IN UINT16 ControllerType ) +{ + // Porting required + switch (ControllerType & 3) { + case 0 : + RESET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + RESET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x60008); // 0x30 + break; + case 1 : + RESET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + RESET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x08, 0x60008); // 0x30 + break; + case 2 : + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x60000, 0x60008); // 0x30 + SET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + SET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + break; + default: + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x60008); // 0x30 + SET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + SET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + break; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: UsbSmiClear +// +// Description: This function clears USB SMI based on given Controller type +// +// Input: UINT16 ControllerType - USB controller type variable +// +// Output: None +// +// Notes: This function implements logic as follows: +// Two lowest bits of ControllerType: +// 00 - Nothing to do +// 01 - Clear UHCI/OHCI USB SMI status +// 10 - Clear EHCI USB SMI status +// 11 - Clear UHCI/OHCI & EHCI USB SMI statuses +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID UsbSmiClear ( + IN UINT16 ControllerType ) +{ + // Porting required + switch (ControllerType & 3) { + case 0 : + break; + case 1 : + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x08); // 0x34 + break; + case 2 : + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x20000); // 0x34 + break; + default: + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x20008); // 0x34 + break; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UsbSmiDetect +// +// Description: This function detects USB SMI event +// +// Input: *Type - Pointer to store USB controller type, source of event +// +// Output: TRUE - USB SMI occured, FALSE otherwise +// +// Notes: This function implements logic as follows: +// *Type will be set to +// 01 - If UHCI/OHCI USB SMI is occured +// 02 - If EHCI USB SMI is occured +// 03 - If UHCI/OHCI & EHCI USB SMI is occured +// 00 - Nothing is occured and return FALSE +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN UsbSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + *Type = 0; + if (IsMe(3)) *Type |= 1; // USB_SMI (USB 1.1) + if (IsMe(17)) *Type |= 2; // USB_SMI (USB 2.0) + + return (*Type) ? TRUE : FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetControllerType +// +// Description: This function returns USB controller type, based on given +// device path +// +// Input: *Device - Pointer USB device path protocol +// +// Output: UINT16 - USB controller type +// +// Notes: The USB controller type will be retuened by the follow value: +// 0 - If there is no matche. +// 1 - It is an UHCI/OHCI (USB 1.1) controller +// 2 - It is an EHCI (USB 2.0) controller +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT16 GetControllerType ( + IN EFI_DEVICE_PATH_PROTOCOL *Device) +{ + + // Porting required + EFI_DEVICE_PATH_PROTOCOL *DevicePath = Device; + PCI_DEVICE_PATH *PciDevicePath = NULL; // [EIP73033] + UINT16 ControllerType = 0; + + while (!isEndNode( DevicePath )) { + if ((DevicePath->Type == HARDWARE_DEVICE_PATH) && \ + (DevicePath->SubType == HW_PCI_DP)) { + PciDevicePath = (PCI_DEVICE_PATH *) DevicePath; + break; + } + DevicePath = NEXT_NODE (DevicePath); + } + + if ((PciDevicePath->Device == EHCI_DEV) || \ + (PciDevicePath->Device == EHCI2_DEV)) { + if ((READ_MEM32_RCRB(0x3598) & 1) == 0) return 2; // RMH Enabled + ControllerType = 1; + if (PciDevicePath->Function == 0x07) ControllerType = 2; + } + + return ControllerType; +} + +//--------------------------------------------------------------------------- +// GPI SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GpiSmiSet +// +// Description: This function enables GPI SMI based on given bit field. +// +// Input: GpiEnableBit - GPI enabled bit field +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID GpiSmiSet ( + IN UINT32 GpiEnableBit ) +{ + // Porting required + + UINT8 GpiNum = 0; + PCH_SERIES PchSeries = GetPchSeries(); + + if (PchSeries == PchLp) { + SET_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN, GpiEnableBit); + } else { + SET_IO16_PM(ACPI_IOREG_ALTGP_SMI_EN, (UINT16)GpiEnableBit); + } + + while ((GpiEnableBit % 2) == 0) { + GpiEnableBit /= 2; + GpiNum++; + } + + if (PchSeries == PchLp) { + //Only GPI[47:32] are capable of SMI# generation. + SET_IO16(GPIO_BASE_ADDRESS+GP_IOREG_GPI_ROUT2, (UINT16)GpiEnableBit); + } else { + RW_PCI32_SB(SB_REG_GPI_ROUT, 1 << (GpiNum * 2), 3 << (GpiNum * 2)); // 0xB8, + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GpiSmiReset +// +// Description: This function disables GPI SMI based on given bit field. +// +// Input: GpiDisableBit - GPI disabled bit field +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID GpiSmiReset ( + IN UINT32 GpiDisableBit ) +{ + // Porting required + + UINT8 GpiNum = 0; + PCH_SERIES PchSeries = GetPchSeries(); + + if (PchSeries == PchLp) { + RESET_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN, GpiDisableBit); + } else { + RESET_IO16_PM(ACPI_IOREG_ALTGP_SMI_EN, (UINT16)GpiDisableBit); + } + + while ((GpiDisableBit % 2) == 0) { + GpiDisableBit /= 2; + GpiNum++; + } + + if (PchSeries == PchLp) { + //Only GPI[47:32] are capable of SMI# generation. + RESET_IO16(GPIO_BASE_ADDRESS+GP_IOREG_GPI_ROUT2, (UINT16)GpiDisableBit); + } else { + RESET_PCI32_SB(SB_REG_GPI_ROUT, 3 << (GpiNum * 2)); // 0xB8, + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GpiSmiClear +// +// Description: This function clears GPI SMI status based on given bit field +// +// Input: Type - GPI Disabled bit field +// +// Output: None +// +// Notes: All GPIs which correspondent bit in Type set to 1 should +// be cleared +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID GpiSmiClear ( + IN UINT32 GpiClearBit ) +{ + // Porting required + if (GetPchSeries() == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN, GpiClearBit); + } else { + WRITE_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS, (UINT16)GpiClearBit); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GpiSmiDetect +// +// Description: This function detects GPI SMI event +// +// Input: *Gpi - Pointer to store source of GPI SMI +// +// Output: TRUE - GPI SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN GpiSmiDetect ( + OUT UINT32 *Gpi ) +{ + // Porting required + if (GetPchSeries() == PchLp) { + *Gpi = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN) & READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_STS); + } else { + *Gpi = READ_IO16_PM(ACPI_IOREG_ALTGP_SMI_EN) & READ_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS); + } + + return (*Gpi) ? TRUE : FALSE; +} + +//--------------------------------------------------------------------------- +// Standby button SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiEnable +// +// Description: This function enables Standby button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SButtonSmiEnable (VOID) +{ + // Porting required +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiDisable +// +// Description: This function disables Standby button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SButtonSmiDisable (VOID) +{ + // Porting required +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiClear +// +// Description: This function clears Standby button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SButtonSmiClear (VOID) +{ + // Porting required +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiDetect +// +// Description: This function detects Standby button SMI event +// +// Input: *Type - Pointer to store value of Standby button phase, +// not used. +// +// Output: TRUE - Standby button SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SButtonSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + return FALSE; +} + +//--------------------------------------------------------------------------- +// Power button SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiEnable +// +// Description: This function enables Power button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PButtonSmiEnable (VOID) +{ + // Porting required + SET_IO16_PM(ACPI_IOREG_PM1_EN, 0x100); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiDisable +// +// Description: This function disables Power button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PButtonSmiDisable (VOID) +{ + // Porting required + RESET_IO16_PM(ACPI_IOREG_PM1_EN, 0x100); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiClear +// +// Description: This function clears Power button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PButtonSmiClear (VOID) +{ + // Porting required + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0x100); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiDetect +// +// Description: This function detects Power button SMI event +// +// Input: *Type - pointer to store value of Power button phase +// not used. +// +// Output: TRUE - Power button SMI occured, FALSE - otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN PButtonSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting Required + UINT16 Buffer16; + + if ( IsAcpi() ) { + return FALSE; + } else { + Buffer16 = READ_IO16_PM(ACPI_IOREG_PM1_STS) & \ + READ_IO16_PM(ACPI_IOREG_PM1_EN) & 0x100; + return (Buffer16) ? TRUE : FALSE; + } +} + +//--------------------------------------------------------------------------- +// TCO SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TcoSmiSet +// +// Description: This function sets TCO functon based on given bit field . +// +// Input: TcoBitOffset - The offset of TCO bit will be set. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TcoSmiSet ( + IN UINT32 TcoBitOffset ) +{ + UINT32 PchRcba = READ_PCI32_SB(SB_REG_RCBA); + + // NMI2SMI_STS (TCOBASE+04h[0]) + if (TcoBitOffset == 0) { + // Enable NMI by set Port 70h[7] = '0b' + SwitchAlternateAccessMode (TRUE); + RESET_IO8(CMOS_ADDR_PORT, BIT07); + SwitchAlternateAccessMode (FALSE); + + // GBL_SMI_EN = 1 + SET_IO8_PM(ACPI_IOREG_SMI_EN, BIT00); + // Set NMI2SMI_EN = '1b', TCO_BASE + 08h[9] + SET_IO16_TCO(TCO_IOREG_CNT1, BIT09); + } + + // INTRD_DET (TCOBASE+06h[0]) + if (TcoBitOffset == 16) { + // INTRD_SEL + RW_IO16_TCO(TCO_IOREG_STS2, BIT02, (BIT01 | BIT02)); + } + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TcoSmiReset +// +// Description: This function resets TCO functon based on given bit field . +// +// Input: TcoBitOffset - The offset of TCO bit will be reset. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TcoSmiReset ( + IN UINT32 TcoBitOffset ) +{ + // NMI2SMI_STS (TCOBASE+04h[0]) + if (TcoBitOffset & BIT00) { + // Set NMI2SMI_EN = 0 + RESET_IO16_TCO(TCO_IOREG_CNT1, BIT09); + } + + // INTRD_DET (TCOBASE+06h[0]) + if (TcoBitOffset & BIT16) { + // INTRD_SEL + RESET_IO16_TCO(TCO_IOREG_CNT2, (BIT01 | BIT02)); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TcoSmiEnable +// +// Description: This function enables TCO SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TcoSmiEnable (VOID) +{ + // Porting required + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x2000); // 0x30 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TcoSmiDisable +// +// Description: This function disables TCO SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TcoSmiDisable (VOID) +{ + // Porting required + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x2000); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TcoSmiClear +// +// Description: This function clears TCO SMI and TCO statuses +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TcoSmiClear (VOID) +{ + // Porting required + WRITE_IO32_TCO(TCO_IOREG_STS1, (UINT32)SUPPORTED_TCOS); // 0x04 + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x2000); // 0x34 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TcoSmiDetect +// +// Description: This function detects TCO SMI event +// +// Input: *TcoStatus - Pointer to store TCO SMI status +// +// Output: TRUE - TCO SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN TcoSmiDetect ( + OUT UINT32 *TcoStatus ) +{ + // Porting required + if ( (IsMe(13)) || (READ_IO8_TCO(TCO_IOREG_STS1) & BIT00)) { // TCO_SMI + *TcoStatus = READ_IO32_TCO(TCO_IOREG_STS1); // 0x04 + return TRUE; + } + + return FALSE; +} + +//--------------------------------------------------------------------------- +// I/O Trap SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiSet +// +// Description: This function sets I/O Trap functon based on given the +// context +// +// Input: IoTrapContext - Pointer to the context that I/O trap register +// will be enabled. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiSet ( + IN EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *IoTrapContext ) +{ + // Porting required if needed. + UINT32 IoTrapAddr = RCRB_MMIO_IO_TRAP_0; // 0x1E80 + UINT32 i; + UINT32 Buffer32 = 0; + + // Find an available I/O trap register + for (i = 0; i < MAX_SUPPORTED_IOTRAP_REGS; i++) { + if ((READ_MEM32_RCRB(IoTrapAddr) & 1) == 0) break; + IoTrapAddr += 8; + } + + IoTrapContext->TrapRegIndex = i; + + if (IoTrapContext->Length < 4) IoTrapContext->Length = 4; + Buffer32 = IoTrapContext->Length; + for (i = 0; Buffer32 != 1; Buffer32 >>= 1, i++); + if (IoTrapContext->Length > (1 << i)) i++; + + IoTrapContext->Length = 1 << i; // Length is always 2^n + + Buffer32 = IoTrapContext->Address & 0xfffc; + Buffer32 |= ((IoTrapContext->Length - 1) & 0xfffc) << 16; + WRITE_MEM32_RCRB(IoTrapAddr, Buffer32); + + Buffer32 = 0xf0; + if (IoTrapContext->TrapWidth == AccessWord) Buffer32 = 0x03; + if (IoTrapContext->TrapWidth == AccessDWord) Buffer32 = 0x0f; + + if (IoTrapContext->TrapOpType == ReadWriteIoCycle) { + Buffer32 |= (1 << 17); // Both Read/Write Cycles. + } else { + if (IoTrapContext->TrapOpType == ReadIoCycle) + Buffer32 |= (1 << 16); // Read Cycle Only + } + + WRITE_MEM32_RCRB(IoTrapAddr + 4, Buffer32); + SET_MEM32_RCRB(IoTrapAddr, 1); // Enable Trap and SMI. +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiReset +// +// Description: This function resets I/O Trap functon based on given the +// context +// +// Input: IoTrapContext - Pointer to the context that I/O trap register +// will be disabled. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiReset ( + IN EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *IoTrapContext ) +{ + // Porting required if needed. + UINT32 IoTrapAddr = RCRB_MMIO_IO_TRAP_0 + IoTrapContext->TrapRegIndex * 8; + + WRITE_MEM32_RCRB(IoTrapAddr, 0); + WRITE_MEM32_RCRB(IoTrapAddr + 4, 0); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiEnable +// +// Description: This function enables I/O Trap SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiEnable (VOID) +{ + // Porting required if needed. +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiDisable +// +// Description: This function disables I/O Trap SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiDisable (VOID) +{ + // Porting required if needed. +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiClear +// +// Description: This function clears all I/O Trap SMI status. +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiClear (VOID) +{ + // Porting required + SET_MEM32_RCRB(RCRB_MMIO_TRSR, 0); // 0x1E00 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiDetect +// +// Description: This function detects I/O Trap SMI event. +// +// Input: *IoTrapContext - Pointer to EFI_SMM_IO_TRAP_DISPATCH_CONTEXT +// +// Output: TRUE - I/O Trap SMI occured, the SMI context IoTrapContext +// should be updated according to the traped H/W +// information. +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IoTrapSmiDetect ( + OUT EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *IoTrapContext ) +{ + UINT32 IoTrapStatus; + UINT32 Buffer32; + + // Porting required + IoTrapStatus = READ_MEM32_RCRB(RCRB_MMIO_TRSR) & 15; // 0x1E00 + + if (IoTrapStatus) { + + IoTrapContext->TrapRegIndex = 0; + + while (IoTrapStatus != 1) { + IoTrapStatus >>= 1; + IoTrapContext->TrapRegIndex++; + } + + Buffer32 = READ_MEM32_RCRB(RCRB_MMIO_TRCR); // 0x1E10 + IoTrapContext->TrapAddress = Buffer32 & 0xfffc; + IoTrapContext->TrapOpType = (Buffer32 & 0x1000000) ? WriteIoCycle : + ReadIoCycle; + if (IoTrapContext->TrapOpType == WriteIoCycle) + IoTrapContext->TrapData = READ_MEM32_RCRB(RCRB_MMIO_TWDR); + + return TRUE; + } + + return FALSE; +} + +//--------------------------------------------------------------------------- +// BIOS Write SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BiosWriteSmiEnable +// +// Description: This function enables BIOS write SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID BiosWriteSmiEnable (VOID) +{ + // Enable BIOSWE SMI if needed +//#### SET_PCI8_SB(SB_REG_BIOS_CNTL, 2); // 0xDC +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BiosWriteSmiDisable +// +// Description: This function disables BIOS write SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID BiosWriteSmiDisable (VOID) +{ + // Disable BIOSWE SMI if possible. +//#### RESET_PCI8_SB(SB_REG_BIOS_CNTL, 2); // 0xDC +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BiosWriteSmiClear +// +// Description: This function clears BIOS write SMI status and disables +// BIOS write function. +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID BiosWriteSmiClear (VOID) +{ + // Only clear BIOSWR_STS + WRITE_IO16_TCO(TCO_IOREG_STS1, 0x100); // 0x04 + // Disable BIOS Write + RESET_PCI8_SB(SB_REG_BIOS_CNTL, 1); // 0xDC +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BiosWriteSmiDetect +// +// Description: This function detects BIOS write SMI event +// +// Input: None +// +// Output: TRUE - BIOS Write SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN BiosWriteSmiDetect (VOID) +{ + // Check BIOS Lock Enable first. + if ((READ_PCI8_SB(SB_REG_BIOS_CNTL) & 2) == 0) return FALSE; // 0xDC + + return (READ_IO16_TCO(TCO_IOREG_STS1) & 0x100) ? TRUE : FALSE; // 0x04 +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbSmiWorkaround +// +// Description: This hook is used for all south bridge workaround in SMI. +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbSmiWorkaround (VOID) +{ + UINT8 DevNum8 = 0; + UINT32 BaseAddress; + UINT8 Offset; + UINT8 EndPort; + + // Sighting #3306438 + if ((READ_IO32_PM(ACPI_IOREG_SMI_EN) & 0x40000) == 0) return; + if ((READ_IO32_PM(ACPI_IOREG_SMI_STS) & 0x40000) == 0) return; + + // Clear the SMI status + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x40000); + + if (READ_PCI32_EHCI(EHCI_REG_VID) != 0xffffffff) + if ((READ_PCI32_EHCI(EHCI_REG_SPECIAL_SMI) & 0x10001) == 0x10001) + DevNum8 = EHCI_DEV; + + if (READ_PCI32_EHCI2(EHCI_REG_VID) != 0xffffffff) + if ((READ_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI) & 0x10001) == 0x10001) + DevNum8 = EHCI2_DEV; + + if (DevNum8) { + // Clear HCReset SMI status + WRITE_PCI16(0, DevNum8, 0, EHCI_REG_SPECIAL_SMI + 2, 1); + + BaseAddress = READ_PCI32(0, DevNum8, 0, EHCI_REG_MBASE_ADDR); + BaseAddress &= 0xfffffff0; + EndPort = (DevNum8 == EHCI2_DEV) ? 0x78 : 0x80; + + for (Offset = 0x68; Offset <= EndPort; Offset += 4) { + // Ensure port ownerchip is not been claimed. + // Clear "Port Owner" bit, Port N Status and Control(PORTSC) [13], + // if it was set. + RESET_MEM8(BaseAddress + Offset + 1, 0x20); + + // Set "Port Test Control" bit, PORTSC[19:16], to '1h'. + RW_MEM8(BaseAddress + Offset + 2, 0x01, 0x0f); + + // Clear "Port Test Control" bit, PORTSC[19:16], to '0h'. + RESET_MEM8(BaseAddress + Offset + 2, 0x0f); + } + // Clear FC[5]; + RESET_PCI16(0, DevNum8, 0, EHCI_REG_IR2, 0x20); + } +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmiHandlerGeneric2.c b/Chipset/SB/Smm2/SmiHandlerGeneric2.c new file mode 100644 index 0000000..d476784 --- /dev/null +++ b/Chipset/SB/Smm2/SmiHandlerGeneric2.c @@ -0,0 +1,1644 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmiHandlerGeneric2.c 7 8/17/14 11:55p Mirayang $ +// +// $Revision: 7 $ +// +// $Date: 8/17/14 11:55p $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmiHandlerGeneric2.c $ +// +// 7 8/17/14 11:55p Mirayang +// Fix Build Error when token "PI_0_9_CHILD_DISPATCHER_SUPPORT" = 0 +// +// 6 3/25/13 4:59a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Refine GPI SMM2 related routines. +// [Files] SmiHandlerGeneric2.c; SmiHandlerPorting2.c; +// SmmChildDispatch2.h +// +// 5 3/15/13 2:25a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Support ULT GPISMI. +// [Files] SmiHandlerGeneric2.c +// +// 4 1/03/13 7:00a Scottyang +// [TAG] None +// [Category] Bug Fix +// [Severity] Important +// [Symptom] GPISMI cannot use. +// [RootCause] GPISMI2 will clear status before GPISMI. +// [Solution] GPISMI2 do not clear status when GPISMI has register. +// [Files] SmmChildDispatcher2.sdl; SmiHandlerGeneric2.c +// +// 3 8/30/12 9:50a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement EIP#73211 and EIP#79156 for OA 3.0 function. +// [Files] SmiHandlerGeneric2.c, SmmChildDispatch2Main.c +// +// 2 4/25/12 9:32a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// 1 2/08/12 8:28a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmiHandlerGeneric2.c +// +// Description: This file contains implementation of generic SMI handler II +// functions +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include "SmmChildDispatch2.h" +#include <AmiSmm.h> + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +static UINT64 gCurrentInterval = 0xffffffffffffffff; +static UINT16 gEnabledUsbSmi = 0; +static UINT16 gActiveUsbSmi = 0; +static UINT32 gEnabledGpiSmi = 0; +static UINT32 gEnabledTcoSmi = 0; +static UINT32 gEnabledIoTrapSmi = 0; +static UINT32 gIoTrapWriteData = 0; + +BOOLEAN gIsLastState = FALSE; + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +extern EFI_SMM_SYSTEM_TABLE2 *gSmst2; +extern SMM_CHILD_DISPATCHER2 Smm2Handler[]; +extern EFI_SMM_SMI_CONTEXT2 SmiContext; + +extern UINT64 gSupportedIntervals[]; + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// Software SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwAddHandler2 +// +// Description: This function adds SW SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_SW_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSwAddHandler2 ( + IN VOID *Context ) +{ + if (Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.Size == 1) SwSmiEnable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwRemoveHandler2 +// +// Description: This function removes SW SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_SW_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSwRemoveHandler2 ( + IN VOID *Context ) +{ +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + if (Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.Size == 1) SwSmiDisable(); +#endif + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwVerifyContext2 +// +// Description: This function verifies SW SMI II context +// +// Input: *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSwVerifyContext2 ( + IN VOID *Context ) +{ + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.pHead; + EFI_SMM_SW_REGISTER_CONTEXT *SwContext; + EFI_SMM_SW_REGISTER_CONTEXT *RegisteredSwContext; + + SwContext = (EFI_SMM_SW_REGISTER_CONTEXT *)Context; + // First check if we already registered handler for this value + while (Handler != NULL) { + RegisteredSwContext = (EFI_SMM_SW_REGISTER_CONTEXT *)Handler->Context; + if(SwContext->SwSmiInputValue == RegisteredSwContext->SwSmiInputValue) + // Handler with this value already registered + return EFI_INVALID_PARAMETER; + + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + + // Second check if given value is extended SMI value, + // check the lowest byte + if ((SwContext->SwSmiInputValue & 0xff) == EXTENDED_SMI) + return EFI_SUCCESS; // Accept value of UINTN size + + // Third check if given value is in default range + return (SwContext->SwSmiInputValue > MAX_SW_SMI_INPUT_VALUE) ? \ + EFI_INVALID_PARAMETER : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwGetContext2 +// +// Description: This function verifies SW SMI II event and sets SW SMI II +// context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - SW SMI occured, context saved +// FALSE - There was no SW SMI II +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmSwGetContext2 (VOID) +{ + UINT16 SwSmiNumber; + BOOLEAN SwSmiDetected; + + SwSmiDetected = SwSmiDetect( &SwSmiNumber ); + + if (SwSmiDetected) { + if(SwSmiNumber == EXTENDED_SMI) { + // Get the actual number from EAX register + SmiContext.SwContext.SwSmiInputValue = GetEAX(); + } else { + SmiContext.SwContext.SwSmiInputValue = SwSmiNumber; + } + } + + return SwSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSwDispatchSmi2 +// +// Description: This function dispatches SW SMI II event based on context +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSwDispatchSmi2 ( VOID ) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler; + EFI_SMM_SW_REGISTER_CONTEXT *SwRegisterContext; + + EFI_SMM_SW_CONTEXT SwContext; + UINTN SwContextSize; + UINT16 i; + EFI_GUID SwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID; + SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger; + UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1; //default cpu # + + for (i = 0; i < pSmst->NumberOfTableEntries; i++) + { + if (guidcmp(&(pSmst->SmmConfigurationTable[i].VendorGuid), &SwSmiCpuTriggerGuid) == 0) + break; + } + + //If found table, check for the CPU that caused the software Smi. + if (i != pSmst->NumberOfTableEntries) + { + SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable; + Cpu = SwSmiCpuTrigger->Cpu; + } + + SwContext.SwSmiCpuIndex = Cpu; + SwContext.CommandPort = IoRead8(SW_SMI_IO_ADDRESS); + SwContext.DataPort = IoRead8(SW_SMI_IO_ADDRESS + 1); + SwContextSize = sizeof(SwContext); + + Handler = \ + (HANDLER_LINK2 *)Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.pHead; + while (Handler != NULL) { + SwRegisterContext = (EFI_SMM_SW_REGISTER_CONTEXT *)Handler->Context; + if(SwRegisterContext->SwSmiInputValue == SmiContext.SwContext.SwSmiInputValue) + Status = Handler->Callback(Handler, SwRegisterContext, &SwContext, &SwContextSize); + + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + +/*#if (CHILD_DISPATCHER_SUPPORT != 0) + if (!EFI_ERROR(Status)) +#endif*/ +if (Status != EFI_WARN_INTERRUPT_SOURCE_QUIESCED) + SwSmiClear(); + + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +} + +//--------------------------------------------------------------------------- +// Sleep SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxAddHandler2 +// +// Description: This function adds Sx SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_SX_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSxAddHandler2 ( + IN VOID *Context ) +{ +#if SLP_SMI_ENABLE_ON_REGISTER + if (Smm2Handler[EfiSmmSxSmi2].RegisteredCallbacks.Size == 1) SxSmiEnable(); +#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxRemoveHandler2 +// +// Description: This function removes Sx SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_SX_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSxRemoveHandler2 ( + IN VOID *Context ) +{ +#if SLP_SMI_ENABLE_ON_REGISTER && (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + if (Smm2Handler[EfiSmmSxSmi2].RegisteredCallbacks.Size == 1) SxSmiDisable(); +#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxVerifyContext2 +// +// Description: This function verifies Sx SMI II context +// +// Input: *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_SUCCESS - Context verified +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSxVerifyContext2 ( + IN VOID *Context ) +{ + EFI_SMM_SX_REGISTER_CONTEXT *SxContext; + + SxContext = (EFI_SMM_SX_REGISTER_CONTEXT *)Context; + if ((SxContext->Type >= EfiMaximumSleepType) || \ + (SxContext->Phase >= EfiMaximumPhase)) + return EFI_INVALID_PARAMETER; + + return ((SxContext->Phase) != SxEntry) ? EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxGetContext2 +// +// Description: This function verifies Sx SMI II event and sets SX SMI II +// context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Sx SMI occured, context saved +// FALSE - There was no SX SMI II +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmSxGetContext2 (VOID) +{ + UINT16 SxSleepState; + BOOLEAN SxSmiDetected; + + SxSmiDetected = SxSmiDetect( &SxSleepState ); + + SmiContext.SxContext.Type = SxSleepState; + SmiContext.SxContext.Phase = SxEntry; + + return SxSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSxDispatchSmi2 +// +// Description: This function dispatches Sx SMI II event based on context +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSxDispatchSmi2 (VOID) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler; + EFI_SMM_SX_REGISTER_CONTEXT *SxContext; + + Handler = \ + (HANDLER_LINK2 *)Smm2Handler[EfiSmmSxSmi2].RegisteredCallbacks.pHead; + while (Handler != NULL) { + SxContext = (EFI_SMM_SX_REGISTER_CONTEXT *)Handler->Context; + + if ((SxContext->Type == SmiContext.SxContext.Type) && \ + (SxContext->Phase == SmiContext.SxContext.Phase)) + Status = Handler->Callback(Handler, SxContext, NULL, NULL); + + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + SxSmiClear(); + + if (SmiContext.SxContext.Type == SxS0) return Status; + + PutToSleep( &(SmiContext.SxContext) ); + + // Control returns here on S1. + + SxSmiClear(); + + return Status; +#else + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +#endif +} + +//--------------------------------------------------------------------------- +// Periodic timer SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerAddHandler2 +// +// Description: This function adds Periodic timer SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTimerAddHandler2 ( + IN VOID *Context ) +{ + EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext; + + TimerContext = (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Context; + + if (Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.Size == 1) { + gCurrentInterval = TimerContext->OrgContext.SmiTickInterval; + TimerSetInterval2( TimerContext->OrgContext.SmiTickInterval ); + TimerSmiClear2(); + TimerSmiEnable2(); + return EFI_SUCCESS; + } + + if (gCurrentInterval > TimerContext->OrgContext.SmiTickInterval) { + gCurrentInterval = TimerContext->OrgContext.SmiTickInterval; + TimerSetInterval2( TimerContext->OrgContext.SmiTickInterval ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerRemoveHandler2 +// +// Description: This function removes Periodic timer SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTimerRemoveHandler2 ( + IN VOID *Context ) +{ + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.pHead; + EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext; + EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *CurrentTimerContext; + UINT64 Interval = 0xffffffffffffffff; + + UINT16 CurrentIntervalCounter = 0; + UINT64 *SupportedIntervals = gSupportedIntervals; + + if (Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.Size == 1) { + gCurrentInterval = 0xffffffffffffffff; + TimerSmiDisable2(); + return EFI_SUCCESS; + } + + CurrentTimerContext = \ + (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Context; + while (Handler != NULL) { + TimerContext = \ + (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Handler->Context; + if (Interval > TimerContext->OrgContext.SmiTickInterval) + Interval = TimerContext->OrgContext.SmiTickInterval; + if (TimerContext->OrgContext.SmiTickInterval == \ + CurrentTimerContext->OrgContext.SmiTickInterval) + CurrentIntervalCounter++; + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + + if ((Interval == CurrentTimerContext->OrgContext.SmiTickInterval) && \ + (CurrentIntervalCounter == 1)) { + Interval = 0xffffffffffffffff; + while (*SupportedIntervals != 0) { + if (*SupportedIntervals != \ + CurrentTimerContext->OrgContext.SmiTickInterval) + if (*SupportedIntervals < Interval) + Interval = *SupportedIntervals; + SupportedIntervals++; + } + } + + // This means lowest rate timer no longer active + if (gCurrentInterval < Interval) { + gCurrentInterval = Interval; + TimerSetInterval2( Interval ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerVerifyContext2 +// +// Description: This function verifies Periodic timer SMI II context +// +// Input: *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTimerVerifyContext2 ( + IN VOID *Context ) +{ + EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext; + UINT64 *Interval = gSupportedIntervals; + + TimerContext = (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Context; + while (*Interval != 0) { + if (*Interval == TimerContext->OrgContext.SmiTickInterval) + return EFI_SUCCESS; + Interval++; + } + + return EFI_INVALID_PARAMETER; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerGetContext2 +// +// Description: This function verifies Periodic timer SMI II event and sets +// Periodic timer SMI II context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Periodic timer SMI occured, context saved +// FALSE - There was no Periodic timer SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmTimerGetContext2 (VOID) +{ + UINT16 TimerType; + BOOLEAN TimerSmiDetected; + + TimerSmiDetected = TimerSmiDetect2( &TimerType ); + SmiContext.TimerContext.OrgContext.SmiTickInterval = gCurrentInterval; + + return TimerSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmTimerDispatchSmi2 +// +// Description: This function dispatches Periodic timer SMI event based on +// context +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmTimerDispatchSmi2 (VOID) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.pHead; + EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext; + + while (Handler != NULL) { + TimerContext = \ + (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Handler->Context; + + TimerContext->ElapsedTime += \ + SmiContext.TimerContext.OrgContext.SmiTickInterval; + if (TimerContext->ElapsedTime >= TimerContext->OrgContext.Period){ + Status = Handler->Callback(Handler, TimerContext, NULL, NULL); + TimerContext->ElapsedTime = 0; + } + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + TimerSmiClear2(); + return Status; +#else + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +#endif + +} + +//--------------------------------------------------------------------------- +// USB SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbAddHandler2 +// +// Description: This function adds USB SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_USB_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmUsbAddHandler2 ( + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_SMM_USB_REGISTER_CONTEXT *UsbContext; + UINT16 ControllerType; + VOID *NewDp; + UINTN Length; + + UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Context; + + // Save USB device path protocol into SMM memory + Length = DPLength( UsbContext->Device ); + Status = gSmst2->SmmAllocatePool( 0, Length, &NewDp ); + if (EFI_ERROR(Status)) return Status; + MemCpy( NewDp, UsbContext->Device, Length ); + UsbContext->Device = (EFI_DEVICE_PATH_PROTOCOL *)NewDp; + + ControllerType = GetControllerType( UsbContext->Device ); + if((ControllerType & gEnabledUsbSmi) == 0) { + gEnabledUsbSmi |= ControllerType; + UsbSmiSet( gEnabledUsbSmi ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbRemoveHandler2 +// +// Description: This function removes USB SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_USB_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmUsbRemoveHandler2 ( + IN VOID *Context ) +{ + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmUsbSmi2].RegisteredCallbacks.pHead; + EFI_SMM_USB_REGISTER_CONTEXT *UsbContext; + UINT16 ControllerType = 0; + + UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Context; + + gSmst2->SmmFreePool( UsbContext->Device ); + + if (Smm2Handler[EfiSmmUsbSmi2].RegisteredCallbacks.Size == 1) { + gEnabledUsbSmi = 0; + UsbSmiSet( gEnabledUsbSmi ); + return EFI_SUCCESS; + } + + while (Handler != NULL) { + UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Handler->Context; + ControllerType |= GetControllerType( UsbContext->Device ); + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + + if (ControllerType != gEnabledUsbSmi) { + gEnabledUsbSmi = ControllerType; + UsbSmiSet( gEnabledUsbSmi ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbVerifyContext2 +// +// Description: This function verifies USB SMI II context +// +// Input: *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmUsbVerifyContext2 ( + IN VOID *Context ) +{ + EFI_SMM_USB_REGISTER_CONTEXT *UsbContext; + UINT16 ControllerType; + + UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Context; + ControllerType = GetControllerType( UsbContext->Device ); + if (((ControllerType & 7) == 0) || (UsbContext->Type > UsbWake)) + return EFI_INVALID_PARAMETER; + + return ((UsbContext->Type) > UsbLegacy) ? EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbGetContext2 +// +// Description: This function verifies USB SMI II event and sets USB SMI II +// context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - USB SMI occured, context saved +// FALSE - There was no USB SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmUsbGetContext2 (VOID) +{ + BOOLEAN UsbSmiDetected; + + UsbSmiDetected = UsbSmiDetect( &gActiveUsbSmi ); + SmiContext.UsbContext.Type = UsbLegacy; + + return UsbSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmUsbDispatchSmi2 +// +// Description: This function dispatches USB SMI II event based on context +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmUsbDispatchSmi2 (VOID) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmUsbSmi2].RegisteredCallbacks.pHead; + EFI_SMM_USB_REGISTER_CONTEXT *UsbContext; + UINT16 ControllerType; + + while (Handler != NULL) { + UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Handler->Context; + ControllerType = GetControllerType( UsbContext->Device ); + + if (((ControllerType & gActiveUsbSmi) != 0) && \ + (UsbContext->Type == SmiContext.UsbContext.Type)) + Status = Handler->Callback(Handler, UsbContext, NULL, NULL); + + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + UsbSmiClear( gActiveUsbSmi ); + gActiveUsbSmi = 0; + return Status; +#else + gActiveUsbSmi = 0; + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +#endif + +} + +//--------------------------------------------------------------------------- +// GPI SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiAddHandler2 +// +// Description: This function adds GPI SMI II handler +// +// Input: VOID *Context - Pointer to EFI_SMM_GPI_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmGpiAddHandler2 ( + IN VOID *Context ) +{ + EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext; + UINT32 GpiBitMap = 0; + + GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Context; + + GpiBitMap = ConvertGpi (GpiContext->GpiNum); + + if ((GpiBitMap & gEnabledGpiSmi) == 0) { + gEnabledGpiSmi |= GpiBitMap; + GpiSmiSet( GpiBitMap ); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiRemoveHandler2 +// +// Description: This function removes GPI SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_GPI_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmGpiRemoveHandler2 ( + IN VOID *Context ) +{ + EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext; + UINT32 GpiBitMap = 0; + + GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Context; + + GpiBitMap = ConvertGpi (GpiContext->GpiNum); + + gEnabledGpiSmi &= ~(GpiBitMap); + + GpiSmiReset( GpiBitMap ); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiVerifyContext2 +// +// Description: This function verifies GPI SMI II context +// +// Input: *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmGpiVerifyContext2 ( + IN VOID *Context ) +{ + EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext; + UINT32 GpiBitMap = 0; + + GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Context; + + GpiBitMap = ConvertGpi (GpiContext->GpiNum); + + if ((GpiBitMap & SUPPORTED_GPIS2) == 0) + return EFI_INVALID_PARAMETER; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiGetContext2 +// +// Description: This function verifies GPI SMI II event and sets GPI SMI II +// context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - GPI SMI occured, context saved +// FALSE - There was no GPI SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmGpiGetContext2 (VOID) +{ + BOOLEAN GpiSmiDetected; + UINT32 GpiSmiNum; + + GpiSmiDetected = GpiSmiDetect( &GpiSmiNum ); + SmiContext.GpiContext.GpiNum = GpiSmiNum; + + return GpiSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmGpiDispatchSmi2 +// +// Description: This function dispatches GPI SMI event based on context +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmGpiDispatchSmi2 (VOID) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmGpiSmi2].RegisteredCallbacks.pHead; + EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext; + UINT32 GpiBitMap = 0; + BOOLEAN GpiSmiServiced = FALSE; + + while (Handler != NULL) { + GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Handler->Context; + + GpiBitMap = ConvertGpi (GpiContext->GpiNum); + + GpiSmiServiced = FALSE; + if ((SmiContext.GpiContext.GpiNum & GpiBitMap) != 0) { + Status = Handler->Callback( Handler, GpiContext, NULL, NULL ); + GpiSmiServiced = TRUE; + } + + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + + if (GpiSmiServiced) + GpiSmiClear( (UINT16)SmiContext.GpiContext.GpiNum ); + +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + return Status; +#else + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +#endif + +} + +//--------------------------------------------------------------------------- +// Standby button SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonAddHandler2 +// +// Description: This function adds Standby button SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSButtonAddHandler2 ( + IN VOID *Context ) +{ + if (Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.Size == 1) + SButtonSmiEnable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonRemoveHandler2 +// +// Description: This function removes Standby button SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSButtonRemoveHandler2 ( + IN VOID *Context ) +{ + if (Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.Size == 1) + SButtonSmiDisable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonVerifyContext2 +// +// Description: This function verifies Standby button SMI II context +// +// Input: VOID *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSButtonVerifyContext2 ( + IN VOID *Context ) +{ + EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *SButtonContext; + + SButtonContext = (EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context; + if (SButtonContext->Phase >= EfiStandbyButtonMax) + return EFI_INVALID_PARAMETER; + + return (SButtonContext->Phase > EfiStandbyButtonEntry) \ + ? EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonGetContext2 +// +// Description: This function verifies Standby button SMI II event and sets +// Standby button SMI II context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Standby button SMI occured, context saved +// FALSE - There was no Standby button SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmSButtonGetContext2 (VOID) +{ + UINT16 Dummy = 0; + BOOLEAN SButtonSmiDetected; + + SButtonSmiDetected = SButtonSmiDetect( &Dummy ); + + SmiContext.SBtnContext.Phase = EfiStandbyButtonEntry; + + return SButtonSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmSButtonDispatchSmi2 +// +// Description: This function dispatches Standby button SMI II event based on +// context +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmSButtonDispatchSmi2 (VOID) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.pHead; + EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *SButtonContext; + + while (Handler != NULL) { + SButtonContext = \ + (EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Handler->Context; + + if (SButtonContext->Phase == SmiContext.SBtnContext.Phase) + Status = Handler->Callback( Handler, SButtonContext, NULL, NULL ); + + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + SButtonSmiClear(); + + return Status; +#else + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +#endif +} + +//--------------------------------------------------------------------------- +// Power button SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonAddHandler2 +// +// Description: This function adds Power button SMI II handler +// +// Input: *Context - pointer to EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmPButtonAddHandler2 ( + IN VOID *Context ) +{ + if (Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.Size == 1) + PButtonSmiEnable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonRemoveHandler2 +// +// Description: This function removes Power button SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS; +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmPButtonRemoveHandler2 ( + IN VOID *Context ) +{ + if (Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.Size == 1) + PButtonSmiDisable(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonVerifyContext2 +// +// Description: This function verifies Power button SMI II context +// +// Input: *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_SUCCESS - Context verified +// EFI_UNSUPPORTED - Context is not supported +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmPButtonVerifyContext2 ( + IN VOID *Context ) +{ + EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *PButtonContext; + + PButtonContext = (EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context; + if (PButtonContext->Phase >= EfiPowerButtonMax) + return EFI_INVALID_PARAMETER; + + return (PButtonContext->Phase > EfiPowerButtonEntry) ? \ + EFI_UNSUPPORTED : EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonGetContext2 +// +// Description: This function verifies Power button SMI II event and sets +// Power button SMI II context +// +// Input: None +// +// Output: BOOLEAN +// TRUE - Power button SMI occured, context saved +// FALSE - There was no Power button SMI +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmPButtonGetContext2 (VOID) +{ + UINT16 Dummy = 0; + BOOLEAN PButtonSmiDetected; + + PButtonSmiDetected = PButtonSmiDetect( &Dummy ); + + SmiContext.PBtnContext.Phase = EfiPowerButtonEntry; + + return PButtonSmiDetected; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmPButtonDispatchSmi2 +// +// Description: This function dispatches Power button SMI II event based on +// context +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmPButtonDispatchSmi2 (VOID) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\ + Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.pHead; + EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *PButtonContext; + + while (Handler != NULL) { + PButtonContext = \ + (EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Handler->Context; + + if (PButtonContext->Phase == SmiContext.PBtnContext.Phase) + Status = Handler->Callback( Handler, PButtonContext, NULL, NULL ); + + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + PButtonSmiClear(); + SBLib_Shutdown(); + + return Status; +#else + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +#endif +} + +//--------------------------------------------------------------------------- +// I/O Trap SMI II Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapAddHandler2 +// +// Description: This function adds I/O Trap SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_IO_TRAP_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS - The context has been registerd successfully. +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmIoTrapAddHandler2 ( + IN VOID *Context ) +{ + HANDLER_LINK2 *Handler; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RegedContext; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext; + UINT32 TrapRegIndex = 0; + UINT32 i = 0; + + IoTrapContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context; + + Handler = \ + (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead; + + while (Handler != NULL) { + RegedContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context; + if ((RegedContext->Address == IoTrapContext->Address) && \ + (RegedContext->Type == IoTrapContext->Type) && \ + (RegedContext->Length == IoTrapContext->Length)) { + i++; + } + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + + if (i > 1) return EFI_SUCCESS; + + IoTrapSmiSet2( IoTrapContext, &TrapRegIndex ); + + gEnabledIoTrapSmi |= (UINT32)(1 << TrapRegIndex); + + if (Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.Size == 1) + IoTrapSmiEnable2(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapRemoveHandler2 +// +// Description: This function removes I/O Trap SMI II handler +// +// Input: *Context - Pointer to EFI_SMM_IO_TRAP_REGISTER_CONTEXT +// +// Output: EFI_SUCCESS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmIoTrapRemoveHandler2 ( + IN VOID *Context ) +{ + HANDLER_LINK2 *Handler; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RegedContext; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RemoveContext; + UINT32 i = 0; + UINT32 TrapRegIndex = 0; + + RemoveContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context; + + Handler = \ + (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead; + + while (Handler != NULL) { + RegedContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context; + if ((RegedContext->Address == RemoveContext->Address) && \ + (RegedContext->Type == RemoveContext->Type) && \ + (RegedContext->Length == RemoveContext->Length)) i++; + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + + if (i > 1) return EFI_SUCCESS; + + IoTrapSmiReset2( Context, &TrapRegIndex ); + + gEnabledIoTrapSmi &= ~(1 << TrapRegIndex); + + if (gEnabledIoTrapSmi == 0) IoTrapSmiDisable2(); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapVerifyContext2 +// +// Description: This function verifies I/O Trap SMI II context +// +// Input: *Context - Pointer to SMI II context +// +// Output: EFI_STATUS +// EFI_SUCCESS - Context verified +// EFI_INVALID_PARAMETER - Given context is invalid +// EFI_UNSUPPORTED - Context is not supported +// EFI_OUT_OF_RESOURCES - There is no I/O Trap register +// available +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmIoTrapVerifyContext2 ( + IN VOID *Context ) +{ + HANDLER_LINK2 *Handler; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RegedContext; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext; + + Handler = \ + (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead; + + IoTrapContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context; + + while (Handler != NULL) { + RegedContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context; + if ((RegedContext->Address == IoTrapContext->Address) && \ + (RegedContext->Type == IoTrapContext->Type)) { + if ( IoTrapContext->Length > MAX_SUPPORTED_IOTRAP_LENGTH) + return EFI_INVALID_PARAMETER; + return EFI_SUCCESS; + } + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } + + if (gEnabledIoTrapSmi >= ((1 << MAX_SUPPORTED_IOTRAP_REGS) - 1)) + return EFI_OUT_OF_RESOURCES; + + if (IoTrapContext->Length > MAX_SUPPORTED_IOTRAP_LENGTH) + return EFI_INVALID_PARAMETER; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapGetContext2 +// +// Description: This function verifies I/O Trap SMI II event and sets +// I/O Trap SMI II context. +// +// Input: None +// +// Output: BOOLEAN +// TRUE - I/O Trap SMI occured, context saved +// FALSE - There was no I/O Trap SMI +// The global variable gIoTrapWriteData will save the data from +// I/O write cycle. +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SmmIoTrapGetContext2 (VOID) +{ + return IoTrapSmiDetect2( &SmiContext.IoTrapContext, &gIoTrapWriteData ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmIoTrapDispatchSmi2 +// +// Description: This function dispatches I/O Trap SMI II event based on +// context. +// +// Input: None +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmIoTrapDispatchSmi2 (VOID) +{ + EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; + HANDLER_LINK2 *Handler; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext; + volatile UINT16 MaxAddress; + + Handler = \ + (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead; + while (Handler != NULL) { + IoTrapContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context; + MaxAddress = IoTrapContext->Address + IoTrapContext->Length; + if ((IoTrapContext->Address <= SmiContext.IoTrapContext.Address) && \ + (MaxAddress > SmiContext.IoTrapContext.Address)) { + if ((IoTrapContext->Type == ReadWriteTrap) || \ + (IoTrapContext->Type == SmiContext.IoTrapContext.Type)) { + Status = Handler->Callback( \ + Handler, \ + (EFI_SMM_IO_TRAP_CONTEXT*)&gIoTrapWriteData, \ + NULL, \ + NULL ); + } + } + Handler = (HANDLER_LINK2 *)Handler->Link.pNext; + } +#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0) + if (Status != EFI_WARN_INTERRUPT_SOURCE_QUIESCED) IoTrapSmiClear2(); + return Status; +#else + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; +#endif +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmiHandlerPorting2.c b/Chipset/SB/Smm2/SmiHandlerPorting2.c new file mode 100644 index 0000000..12fb095 --- /dev/null +++ b/Chipset/SB/Smm2/SmiHandlerPorting2.c @@ -0,0 +1,1565 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmiHandlerPorting2.c 9 5/22/15 9:13a Dennisliu $ +// +// $Revision: 9 $ +// +// $Date: 5/22/15 9:13a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmiHandlerPorting2.c $ +// +// 9 5/22/15 9:13a Dennisliu +// [TAG] EIP215945 +// [Category] Improvement +// [Description] [SharkBay][PCH] Executing code outside TSEG check in +// SMM +// +// 8 3/25/13 5:00a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Refine GPI SMM2 related routines. +// [Files] SmiHandlerGeneric2.c; SmiHandlerPorting2.c; +// SmmChildDispatch2.h +// +// 7 3/19/13 8:21a Scottyang +// [TAG] EIP118158 +// [Category] Improvement +// [Description] Correct SBLib_CmosRead () offset. +// [Files] SmiHandlerPorting2.c, SBDxe.c, SBGeneric.c, SBSmm.c, +// SmiHandlerPorting.c +// +// 6 11/06/12 8:11a Scottyang +// [TAG] None +// [Category] Improvement +// [Description] Reduce function "GetPchSeries()". +// [Files] SBPEI.c, SBDxe.c, SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 5 10/19/12 2:52a Scottyang +// [TAG] EIP93461 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System halt when AFUDOS is running with /N /ME command. +// [RootCause] An unexpected BIOSWR_STS is set, it causes BIOS stuck +// at SMM dispatcher. +// [Solution] Clear BIOSWR_STS if BIOS Lock Enable is not set. +// [Files] SmiHandlerPorting2.c; SmmChildDispatch2Main.c +// SmmChildDispatcher2.sdl; SmmChildDispatch2.h +// SB\SBGeneric.c +// +// 4 9/26/12 3:56a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update for PCH LP GPIO compatible. +// [Files] SB.sdl, SB.H, AcpiModeEnable.c, AcpiModeEnable.sdl, +// SBDxe.c, SBGeneric.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c +// +// 3 7/27/12 6:16a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Update to support ULT Platform. +// [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c, +// AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c, +// SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl +// +// 2 4/25/12 9:30a Victortu +// [TAG] EIP73033 +// [Category] Improvement +// [Description] 'PciDevicePath' used in GetControllerType(), +// conditionally not set. +// [Files] SmiHandlerPorting.c; SmiHandlerPorting2.c +// +// 1 2/08/12 8:28a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmiHandlerPorting2.c +// +// Description: This file contains SMM Child Dispatcher II porting +// functions +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include <AmiSmm.h> +#include <Protocol\SmmCpu.h> +#include "SmmChildDispatch2.h" + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +UINT64 gSupportedIntervals[] = { + // Porting required - put all available intervals here (in 100Nanoseconds) +#if SWSMI_TIMER_INSTEAD +// [ EIP215677 ] +// 15000, // 1.5ms +// 160000, // 16 ms +// 320000, // 32 ms +// 640000, // 64 ms + 640000, // 64 ms + 320000, // 32 ms + 160000, // 16 ms + 15000, // 1.5ms +#else + 600000000, // 60 Seconds + 320000000, // 32 Seconds + 160000000, // 16 Seconds + 80000000, // 8 Seconds +#endif + + // Terminator record + 0 +}; + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +extern EFI_SMM_SYSTEM_TABLE2 *gSmst2; +extern EFI_SMM_CPU_PROTOCOL *gEfiSmmCpuProtocol; + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// All purpose SMI Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsAcpi +// +// Description: This function determines if the system is in ACPI mode. +// +// Input: None +// +// Output: BOOLEAN +// TRUE - It is in ACPI mode +// FALSE - It is not in ACPI mode +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsAcpi (VOID) +{ + return (READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & 1) ? TRUE : FALSE; // 0x04 +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IsMe +// +// Description: This function checks whether the specific SMI event is raised +// +// Input: CheckBitNo - The bit number for the specific SMI. +// +// Output: BOOLEAN +// TRUE - It is the specific SMI event +// FALSE - It is not the specific SMI event +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IsMe ( + IN UINT8 CheckBitNo ) +{ + volatile UINT32 Buffer32 = READ_IO32_PM(ACPI_IOREG_SMI_EN); // 0x30 + + Buffer32 &= READ_IO32_PM(ACPI_IOREG_SMI_STS); // 0x34 + return (Buffer32 & (UINT32)(1 << CheckBitNo)) ? TRUE : FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ClearAllSmi +// +// Description: This function clears all SMI's and issues an EOS (End of SMI). +// +// Input: None +// +// Output: None +// +// Notes: If you are porting INTEL chipset and have to support SWSMI +// Timer SMI, you must be unable to clear the SWSMI status in +// this routine. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ClearAllSmi (VOID) +{ + // Porting Required. Program to clear ALL SMI status bit + if ( !IsAcpi() ) { + if (READ_IO16_PM(ACPI_IOREG_PM1_EN) & 0x400) + if (READ_IO16_PM(ACPI_IOREG_PM1_STS) & 0x400) + SBLib_CmosRead(0x0C); + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0xcc31); // 0x00 + if (GetPchSeries() == PchLp) { + WRITE_IO32_PM(ACPI_PCHLP_IOREG_GPE0_STS+0x0c, 0xffffffff); // 0x8C + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_STS, 0xffffffff); // 0x50 + } else { + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS, 0xffffffff); // 0x20 + WRITE_IO32_PM(ACPI_IOREG_GPE0_STS+4, 0xffffffff); // 0x24 + WRITE_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS, 0xffff); // 0x3A + } + WRITE_IO16_PM(ACPI_IOREG_DEVACT_STS, 0xffff); // 0x44 + WRITE_IO16_TCO(TCO_IOREG_STS1, 0xffff); // 0x04 + WRITE_IO16_TCO(TCO_IOREG_STS2, 0xfffe); // 0x06 (Except Intruder Det) + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0xffffffbf); // 0x34 (Except SWSMI) + if ((READ_IO16_TCO(TCO_IOREG_CNT1) & 0x300) == 0x300) { // 0x08 + SET_IO16_TCO(TCO_IOREG_CNT1, 0x100); // Clear NMI_NOW if needed. + } + } + // EOS + SET_IO8_PM(ACPI_IOREG_SMI_EN, 0x02); // 0x30 + if ((READ_IO8_PM(ACPI_IOREG_SMI_EN) & 0x02) == 0) { + // Reset GBL_SMI_EN + RESET_IO8_PM(ACPI_IOREG_SMI_EN, 0x01); // 0x30 + // Set EOS Again + SET_IO8_PM(ACPI_IOREG_SMI_EN, 0x02); // 0x30 + // Set GBL_SMI_EN + SET_IO8_PM(ACPI_IOREG_SMI_EN, 0x01); // 0x30 + } +} + +//--------------------------------------------------------------------------- +// SW SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiEnable +// +// Description: This function enables SW SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SwSmiEnable (VOID) +{ + // Porting required + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x20); // 0x30 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiDisable +// +// Description: This function disables SW SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SwSmiDisable (VOID) +{ + // Porting required + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x20); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiClear +// +// Description: This function clears SW SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SwSmiClear (VOID) +{ + // Porting required + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x20); // 0x34 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SwSmiDetect +// +// Description: This function detects SW SMI event +// +// Input: *Type - Pointer to store SW SMI number +// +// Output: TRUE - SW SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SwSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + if ( IsMe(5) ) { // SW_SMI + *Type = IoRead8(SW_SMI_IO_ADDRESS); + return TRUE; + } + + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetEAX +// +// Description: This function returns EAX saved value from CPU that caused +// SW SMI. +// +// Input: None +// +// Output: EAX saved value +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINTN GetEAX (VOID) +{ + // Porting required for different CPU + EFI_STATUS Status; + EFI_GUID SwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID; + SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger; + UINTN Cpu = gSmst2->CurrentlyExecutingCpu - 1; // CPU # + UINT16 i; + UINT32 RegEAX; + + for (i = 0; i < gSmst2->NumberOfTableEntries; i++) { + if (guidcmp(&(gSmst2->SmmConfigurationTable[i].VendorGuid), \ + &SwSmiCpuTriggerGuid) == 0) + break; + } + + // If found table, check for the CPU that caused the software Smi. + if (i != gSmst2->NumberOfTableEntries) { + SwSmiCpuTrigger = gSmst2->SmmConfigurationTable[i].VendorTable; + Cpu = SwSmiCpuTrigger->Cpu; + } + + Status = gEfiSmmCpuProtocol->ReadSaveState ( \ + gEfiSmmCpuProtocol, \ + 4, \ + EFI_SMM_SAVE_STATE_REGISTER_RAX, \ + Cpu, \ + &RegEAX ); + return RegEAX; +} + +//--------------------------------------------------------------------------- +// SX SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiEnable +// +// Description: This function enables SX SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SxSmiEnable (VOID) +{ + // Porting required + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x10); // 0x30 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiDisable +// +// Description: This function disables SX SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SxSmiDisable (VOID) +{ + // Porting required + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x10); // 0x30 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiClear +// +// Description: This function clears SX SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SxSmiClear (VOID) +{ + // Porting required + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x10); // 0x34 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SxSmiDetect +// +// Description: This function detects SX SMI event +// +// Input: *Type - Pointer to store value of Sleep type +// +// Output: TRUE - SX SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SxSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + if (IsMe(4)) { // SLP_SMI + switch (READ_IO16_PM(ACPI_IOREG_PM1_CNTL) & (7 << 10)) { // SLP_TYP + case (0 << 10): + *Type = SxS0; + break; + case (1 << 10): + *Type = SxS1; + break; + case (5 << 10): + *Type = SxS3; + break; + case (6 << 10): + *Type = SxS4; + break; + case (7 << 10): + *Type = SxS5; + break; + default: + return FALSE; // Unknown Error. + } + return TRUE; + } + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PutToSleep +// +// Description: Disable Smi sleep and put to sleep. +// +// Input: *Context - Pointer to Sleep SMI context +// +// Output: None +// +// Referrals: SxSmiDisable +// +// Notes: Here is the control flow of this function: +// 1. Disable Smi sleep. +// 2. Set to go to sleep if you want to sleep in SMI. otherwise +// set IORestart to 0xFF in CPU SMM dump area. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PutToSleep ( + IN EFI_SMM_SX_REGISTER_CONTEXT *SxContext ) +{ +// TODO YODO TODO +//#### EFI_SMM_CPU_SAVE_STATE *pCpuSaveState = gSmst2->CpuSaveState; +//#### UINTN Cpu = gSmst2->CurrentlyExecutingCpu - 1; +//#### UINT32 CacheFlush = 0; + + SxSmiDisable(); // Disable sleep SMI. + +//#### if (SxContext->Type == SxS5) +//#### SBLib_BeforeShutdown(); + +//#####if ACPI_SLEEP_IN_SMM + SET_IO16_PM(ACPI_IOREG_PM1_CNTL, 0x2000); // Set to sleep. +//#####else +//#### CacheFlush = pCpuSaveState[Cpu].Ia32SaveState.IORestart; +//#### pCpuSaveState[Cpu].Ia32SaveState.IORestart = 0xff; +//#####endif + +} + +//--------------------------------------------------------------------------- +// Periodic timer SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiEnable2 +// +// Description: This function enables Periodic timer SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSmiEnable2 (VOID) +{ + // Porting required +#if SWSMI_TIMER_INSTEAD + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x40); // 0x30 +#else + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x4000); // 0x30 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiDisable2 +// +// Description: This function disables Periodic timer SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSmiDisable2 (VOID) +{ + // Porting required +#if SWSMI_TIMER_INSTEAD + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x40); // 0x30 +#else + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x4000); // 0x30 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiClear2 +// +// Description: This function clears Periodic timer SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSmiClear2 (VOID) +{ + + // Porting required +#if SWSMI_TIMER_INSTEAD + // SWSMI has to be disabled before clear the status + volatile UINT32 Buffer32 = READ_IO32_PM(ACPI_IOREG_SMI_EN); // 0x30 + WRITE_IO32_PM(ACPI_IOREG_SMI_EN, Buffer32 & (UINT32)(~0x40)); // 0x30 + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x40); // 0x34 + WRITE_IO32_PM(ACPI_IOREG_SMI_EN, Buffer32); // 0x30 +#else + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x4000); // 0x34 +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSmiDetect2 +// +// Description: This function detects Periodic timer SMI event +// +// Input: *Type - Added for compatibility, not used +// +// Output: TRUE - Periodic timer SMI occured, FALSE otherwise +// +// Notes: Return TRUE if Timer SMI detected, Type ignored +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN TimerSmiDetect2 ( + OUT UINT16 *Type ) +{ + // Porting required + *Type = 0; +#if SWSMI_TIMER_INSTEAD + return (IsMe(6)) ? TRUE : FALSE; +#else + return (IsMe(14)) ? TRUE : FALSE; +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: TimerSetInterval2 +// +// Description: This function programs Periodic timer to given interval +// +// Input: Interval - Interval to program +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID TimerSetInterval2 ( + IN UINT64 Interval ) +{ + + // Porting required + UINT16 RateIndex; + UINT16 AvailTimer = sizeof(gSupportedIntervals) / sizeof(UINT64) - 1; + + TimerSmiDisable2(); + TimerSmiClear2(); + + for (RateIndex = 0; RateIndex < AvailTimer ; RateIndex++) + if (Interval == gSupportedIntervals[RateIndex]) break; +#if SWSMI_TIMER_INSTEAD + RW_PCI16_SB(SB_REG_GEN_PMCON_3, RateIndex << 6, 0xc0); // 0xA4 +#else + RW_PCI16_SB(SB_REG_GEN_PMCON_1, RateIndex, 3); // 0xA0 +#endif + + TimerSmiEnable2(); +} + +//--------------------------------------------------------------------------- +// Usb SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UsbSmiSet +// +// Description: This function enables/disables USB SMI based on given +// Controller type +// +// Input: ControllerType - USB controller type variable +// +// Output: None +// +// Notes: This function implements logic as follows: +// Three lowest bits of ControllerType: +// 000 - All USB controllers SMI are disabled +// 001 - UHCI/OHCI enabled, EHCI/XHCI - disabled +// 010 - EHCI enabled, UHCI/OHCI/XHCI - disabled +// 011 - UHCI/OHCI/EHCI enabled, XHCI - disabled +// 100 - XHCI enabled, UHCI/OHCI/EHCI - disabled +// 101 - UHCI/OHCI/XHCI enabled, EHCI - disabled +// 110 - EHCI/XHCI enabled, UHCI/OHCI - disabled +// 111 - All USB controllers SMI are enabled +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID UsbSmiSet( + IN UINT16 ControllerType ) +{ + // Porting required + switch (ControllerType & 7) { + + case 0 : // All USB controllers SMI are disabled + RESET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + RESET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + RESET_IO32_PM(ACPI_IOREG_SMI_EN, 0x80060008); // 0x30 + break; + + case 1 : // UHCI/OHCI enabled, EHCI/XHCI - disabled + RESET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + RESET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x08, 0x80060008); // 0x30 + break; + + case 2 : // EHCI enabled, UHCI/OHCI/XHCI - disabled + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x60000, 0x80060008); // 0x30 + SET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + SET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + break; + + case 3 : // UHCI/OHCI/EHCI enabled, XHCI - disabled + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x60008, 0x80060008); // 0x30 + SET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + SET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + break; + + case 4 : // XHCI enabled, UHCI/OHCI/EHCI - disabled + RESET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + RESET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x80000000, 0x80060008); // 0x30 + break; + + case 5 : // UHCI/OHCI/XHCI enabled, EHCI - disabled + RESET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + RESET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x80000008, 0x80060008); // 0x30 + break; + + case 6 : // EHCI/XHCI enabled, UHCI/OHCI - disabled + RW_IO32_PM(ACPI_IOREG_SMI_EN, 0x80060000, 0x80060008); // 0x30 + SET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + SET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + break; + + default: // All USB controllers SMI are enabled + SET_IO32_PM(ACPI_IOREG_SMI_EN, 0x80060008); // 0x30 + SET_PCI32_EHCI(EHCI_REG_SPECIAL_SMI, 1); + SET_PCI32_EHCI2(EHCI_REG_SPECIAL_SMI, 1); + break; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: UsbSmiClear +// +// Description: This function clears USB SMI status based on given Controller +// type. +// +// Input: UINT16 ControllerType - USB controller type variable +// +// Output: None +// +// Notes: This function implements logic as follows: +// Three lowest bits of ControllerType: +// Bit 0 - Clear UHCI/OHCI USB SMI status +// Bit 1 - Clear EHCI USB SMI status +// Bit 2 - Clear XHCI USB SMI status +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID UsbSmiClear ( + IN UINT16 ControllerType ) +{ + // Porting required + + if (ControllerType & 1) // Clear UHCI/OHCI USB SMI status + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x08); // 0x34 + + if (ControllerType & 2) // Clear EHCI USB SMI status + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x20000); // 0x34 + if (ControllerType & 4) // Clear XHCI USB SMI status + WRITE_IO32_PM(ACPI_IOREG_SMI_STS, 0x80000000); // 0x34 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UsbSmiDetect +// +// Description: This function detects USB SMI event +// +// Input: *Type - Pointer to store USB controller type, source of event +// +// Output: TRUE - USB SMI occured, FALSE otherwise +// +// Notes: This function implements logic as follows: +// *Type will be set to +// 000 - There is no SMI occured +// Bit 0 - If UHCI/OHCI USB SMI is occured +// Bit 1 - If EHCI USB SMI is occured +// Bit 2 - If XHCI USB SMI is occured +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN UsbSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + *Type = 0; + if (IsMe(03)) *Type |= 1; // USB_SMI (USB 1.1) + if (IsMe(17)) *Type |= 2; // USB_SMI (USB 2.0) + if (IsMe(31)) *Type |= 4; // USB_SMI (USB 3.0) + + return (*Type) ? TRUE : FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GetControllerType +// +// Description: This function returns USB controller type, based on given +// device path +// +// Input: *Device - Pointer USB device path protocol +// +// Output: UINT16 - USB controller type +// +// Notes: The USB controller type will be retuened by the follow value: +// 0 - If there is no matche. +// 1 - It is an UHCI/OHCI (USB 1.1) controller +// 2 - It is an EHCI (USB 2.0) controller +// 4 - It is a XHCI (USB 3.0) controller +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINT16 GetControllerType ( + IN EFI_DEVICE_PATH_PROTOCOL *Device) +{ + // Porting required + EFI_DEVICE_PATH_PROTOCOL *DevicePath = Device; + PCI_DEVICE_PATH *PciDevicePath = NULL; // [EIP73033] + UINT16 ControllerType = 0; + + while (!isEndNode( DevicePath )) { + if ((DevicePath->Type == HARDWARE_DEVICE_PATH) && \ + (DevicePath->SubType == HW_PCI_DP)) { + PciDevicePath = (PCI_DEVICE_PATH *) DevicePath; + break; + } + DevicePath = NEXT_NODE (DevicePath); + } + +// [ EIP215945 ] +// if (PciDevicePath->Device == EHCI_DEV) { +// ControllerType = 1; +// if (PciDevicePath->Function == 0x07) ControllerType = 2; +// + if ((PciDevicePath->Device == EHCI_DEV) || (PciDevicePath->Device == EHCI2_DEV)) + { + ControllerType = 2; + } else { + if (PciDevicePath->Device == XHCI_DEV) + if (PciDevicePath->Function == XHCI_FUN) ControllerType = 4; + } + + return ControllerType; +} + +//--------------------------------------------------------------------------- +// GPI SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GpiSmiSet +// +// Description: This function enables GPI SMI based on given bit field. +// +// Input: GpiEnableBit - GPI enabled bit field +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID GpiSmiSet ( + IN UINT32 GpiEnableBit ) +{ + // Porting required + + UINT8 GpiNum = 0; + PCH_SERIES PchSeries = GetPchSeries(); + + if (PchSeries == PchLp) { + SET_IO16(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN, (UINT16)GpiEnableBit); + } else { + SET_IO16_PM(ACPI_IOREG_ALTGP_SMI_EN, (UINT16)GpiEnableBit); + } + + while ((GpiEnableBit % 2) == 0) { + GpiEnableBit /= 2; + GpiNum++; + } + GpiNum *= 2; + + if (PchSeries == PchLp) { + //Only GPI[47:32] are capable of SMI# generation. + SET_IO16(GPIO_BASE_ADDRESS + GP_IOREG_GPI_ROUT2, (UINT16)GpiEnableBit); + } else { + RW_PCI32_SB(SB_REG_GPI_ROUT, 1 << GpiNum, 3 << GpiNum); // 0xB8 + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GpiSmiReset +// +// Description: This function disables GPI SMI based on given bit field. +// +// Input: GpiDisableBit - GPI disabled bit field +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID GpiSmiReset ( + IN UINT32 GpiDisableBit ) +{ + // Porting required + + UINT8 GpiNum = 0; + PCH_SERIES PchSeries = GetPchSeries(); + + if (PchSeries == PchLp) { + RESET_IO16(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN, (UINT16)GpiDisableBit); + } else { + RESET_IO16_PM(ACPI_IOREG_ALTGP_SMI_EN, (UINT16)GpiDisableBit); + } + + while ((GpiDisableBit % 2) == 0) { + GpiDisableBit /= 2; + GpiNum++; + } + GpiNum *= 2; + + if (PchSeries == PchLp) { + //Only GPI[47:32] are capable of SMI# generation. + RESET_IO16(GPIO_BASE_ADDRESS+GP_IOREG_GPI_ROUT2, (UINT16)GpiDisableBit); + } else { + RESET_PCI32_SB(SB_REG_GPI_ROUT, 3 << GpiNum); // 0xB8 + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GpiSmiClear +// +// Description: This function clears GPI SMI status based on given bit field +// +// Input: Type - GPI Disabled bit field +// +// Output: None +// +// Notes: All GPIs which correspondent bit in Type set to 1 should +// be cleared +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID GpiSmiClear ( + IN UINT32 GpiClearBit ) +{ + // Porting required + if (GetPchSeries() == PchLp) { + WRITE_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN, GpiClearBit); + } else { + WRITE_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS, (UINT16)GpiClearBit); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: GpiSmiDetect +// +// Description: This function detects GPI SMI event +// +// Input: *Gpi - Pointer to store source of GPI SMI +// +// Output: TRUE - GPI SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN GpiSmiDetect ( + OUT UINT32 *Gpi ) +{ + // Porting required + if (GetPchSeries() == PchLp) { + *Gpi = READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_EN) & READ_IO32(GPIO_BASE_ADDRESS + GP_IOREG_ALTGP_SMI_STS); + } else { + *Gpi = READ_IO16_PM(ACPI_IOREG_ALTGP_SMI_EN) & READ_IO16_PM(ACPI_IOREG_ALTGP_SMI_STS); + } + + return (*Gpi) ? TRUE : FALSE; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConvertGpi +// +// Description: This function converts GPI to bitmap in 32 bit. +// +// Input: Gpi - GPI Pin number or bitmap +// +// Output: Converted GPI bitmap in 32 bit. +// GpiBitMap[16:0] = ALT_GPI_SMI_EN[15:0] = LPT-H GPI[15:0] +// GpiBitMap[16:0] = ALT_GPI_SMI_EN[15:0] = LPT-LP GPI[47:32] +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT32 ConvertGpi ( + IN UINTN Gpi +) +{ + UINT32 GpiBitMap = 0; + PCH_SERIES PchSeries = GetPchSeries(); + + if (GPI_DISPATCH2_BY_BITMAP) { + if (PchSeries == PchLp) + GpiBitMap = (UINT32)(Shr64((UINT64)Gpi, 32)); + else + GpiBitMap = (UINT32)Gpi; + } else { + if (PchSeries == PchLp) + GpiBitMap |= Shl64(1, (UINT8)(Gpi - 32)); + else + GpiBitMap |= Shl64(1, (UINT8)Gpi); + } + return GpiBitMap; +} + +//--------------------------------------------------------------------------- +// Standby button SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiEnable +// +// Description: This function enables Standby button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SButtonSmiEnable (VOID) +{ + // Porting required +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiDisable +// +// Description: This function disables Standby button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SButtonSmiDisable (VOID) +{ + // Porting required +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiClear +// +// Description: This function clears Standby button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SButtonSmiClear (VOID) +{ + // Porting required +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SButtonSmiDetect +// +// Description: This function detects Standby button SMI event +// +// Input: *Type - Pointer to store value of Standby button phase, +// not used. +// +// Output: TRUE - Standby button SMI occured, FALSE otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN SButtonSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting required + return FALSE; +} + +//--------------------------------------------------------------------------- +// Power button SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiEnable +// +// Description: This function enables Power button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PButtonSmiEnable (VOID) +{ + // Porting required + SET_IO16_PM(ACPI_IOREG_PM1_EN, 0x100); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiDisable +// +// Description: This function disables Power button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PButtonSmiDisable (VOID) +{ + // Porting required + RESET_IO16_PM(ACPI_IOREG_PM1_EN, 0x100); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiClear +// +// Description: This function clears Power button SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID PButtonSmiClear (VOID) +{ + // Porting required + WRITE_IO16_PM(ACPI_IOREG_PM1_STS, 0x100); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PButtonSmiDetect +// +// Description: This function detects Power button SMI event +// +// Input: *Type - pointer to store value of Power button phase +// not used. +// +// Output: TRUE - Power button SMI occured, FALSE - otherwise +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN PButtonSmiDetect ( + OUT UINT16 *Type ) +{ + // Porting Required + UINT16 Buffer16; + + if ( IsAcpi() ) { + return FALSE; + } else { + Buffer16 = READ_IO16_PM(ACPI_IOREG_PM1_STS) & \ + READ_IO16_PM(ACPI_IOREG_PM1_EN) & 0x100; + return (Buffer16) ? TRUE : FALSE; + } +} + +//--------------------------------------------------------------------------- +// I/O Trap SMI Handler Porting hooks +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiSet +// +// Description: This function sets I/O Trap functon based on given the +// context +// +// Input: IoTrapContext - Pointer to the context +// EFI_SMM_IO_TRAP_REGISTER_CONTEXT +// +// Output: TrapRegIndex - Pointer to the index of I/O Trap register +// that I/O Trap register will be enabled. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiSet2 ( + IN EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext, + OUT UINT32 *TrapRegIndex ) +{ + // Porting required if needed. + UINT32 IoTrapAddr = RCRB_MMIO_IO_TRAP_0; // 0x1E80 + UINT32 i; + UINT32 Buffer32 = 0; + UINT16 Length = IoTrapContext->Length; + + // Find an available I/O trap register + for (i = 0; i < MAX_SUPPORTED_IOTRAP_REGS; i++) { + if ((READ_MEM32_RCRB(IoTrapAddr) & 1) == 0) break; + IoTrapAddr += 8; + } + + *TrapRegIndex = i; + + if (*TrapRegIndex == MAX_SUPPORTED_IOTRAP_REGS) return; + + if (Length < 4) Length = 4; + Buffer32 = Length; + for (i = 0; Buffer32 != 1; Buffer32 >>= 1, i++); + if (Length > (1 << i)) i++; + + Length = 1 << i; // Length is always 2^n + + Buffer32 = IoTrapContext->Address & 0xfffc; + Buffer32 |= ((Length - 1) & 0xfffc) << 16; + WRITE_MEM32_RCRB(IoTrapAddr, Buffer32); + + Buffer32 = 0xf0; // Byte Access +// if (IoTrapContext->TrapWidth == AccessWord) Buffer32 = 0x03; +// if (IoTrapContext->TrapWidth == AccessDWord) Buffer32 = 0x0f; + + if (IoTrapContext->Type == ReadWriteTrap) { + Buffer32 |= (1 << 17); // Both Read/Write Cycles. + } else { + if (IoTrapContext->Type == ReadTrap) + Buffer32 |= (1 << 16); // Read Cycle Only + } + + WRITE_MEM32_RCRB(IoTrapAddr + 4, Buffer32); + SET_MEM32_RCRB(IoTrapAddr, 1); // Enable Trap and SMI. +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiReset +// +// Description: This function resets I/O Trap functon based on given the +// context +// +// Input: IoTrapContext - Pointer to the context that I/O trap register +// will be disabled. +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiReset2 ( + IN EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext, + OUT UINT32 *TrapRegIndex ) +{ + // Porting required if needed. + + UINT32 IoTrapAddr = RCRB_MMIO_IO_TRAP_0; // 0x1E80 + UINT32 i; + UINT32 TrapContext32 = 0; + + for (i = 0; i < MAX_SUPPORTED_IOTRAP_REGS; i++) { + TrapContext32 = READ_MEM32_RCRB(IoTrapAddr); + if (TrapContext32 & 1) + if ((UINT16)(TrapContext32 & 0xfffc) == IoTrapContext->Address) { + TrapContext32 = READ_MEM32_RCRB(IoTrapAddr + 4); + if (TrapContext32 & 0x20000) { + if (IoTrapContext->Type == ReadWriteTrap) break; + } else { + if (TrapContext32 & 0x10000) { + if (IoTrapContext->Type == ReadTrap) break; + } else { + if (IoTrapContext->Type == WriteTrap) break; + } + } + } + IoTrapAddr += 8; + } + + WRITE_MEM32_RCRB(IoTrapAddr, 0); + WRITE_MEM32_RCRB(IoTrapAddr + 4, 0); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiEnable +// +// Description: This function enables I/O Trap SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiEnable2 (VOID) +{ + // Porting required if needed. +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiDisable +// +// Description: This function disables I/O Trap SMI +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiDisable2 (VOID) +{ + // Porting required if needed. +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiClear +// +// Description: This function clears all I/O Trap SMI status. +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID IoTrapSmiClear2 (VOID) +{ + // Porting required + SET_MEM32_RCRB(RCRB_MMIO_TRSR, 0); // 0x1E00 +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: IoTrapSmiDetect2 +// +// Description: This function detects I/O Trap SMI event. +// +// Input: *IoTrapContext - Pointer to EFI_SMM_IO_TRAP_REGISTER_CONTEXT +// +// Output: TRUE - I/O Trap SMI occured, the SMI context IoTrapContext +// should be updated according to the traped H/W +// information. +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN IoTrapSmiDetect2 ( + OUT EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext, + OUT UINT32 *IoTrapWriteData ) +{ + // Porting required + + UINT32 Buffer32; + UINT16 Offset = 0; + UINT16 i; + + if (READ_MEM32_RCRB(RCRB_MMIO_TRSR) & 15) { // 0x1E00 + + Buffer32 = READ_MEM32_RCRB(RCRB_MMIO_TRCR); // 0x1E10 + IoTrapContext->Address = Buffer32 & 0xfffc; + for (i = 0; i < 4; i++) { + if (Buffer32 & (1 << (16 + i))) break; + Offset++; + } + IoTrapContext->Address += Offset; + if (Buffer32 & (1 << 24)) { + IoTrapContext->Type = ReadTrap; + } else { + IoTrapContext->Type = WriteTrap; + *IoTrapWriteData = READ_MEM32_RCRB(RCRB_MMIO_TWDR); // 0x1E18 + } + return TRUE; + } + + return FALSE; +} + // [EIP93461]> +#if BIOS_WRITE_SMI_PATCH_ENABLE +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: PchBiosWritePatch +// +// Description: This function clears unexpected BIOSWR_STS. +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID BiosWriteSmiPatch ( VOID ) +{ + // Clear BIOSWR_STS(TCO_BASE + 04h[8]) if BIOS Lock Enable + // (B0:D31:F0 Reg#DCh[1]) is not set. + if (((READ_PCI8_SB(SB_REG_BIOS_CNTL) & BIT01) == 0) && \ + (READ_IO16_TCO(TCO_IOREG_STS1) & BIT08)) { + + // Clear BIOSWR_STS + WRITE_IO16_TCO(TCO_IOREG_STS1, BIT08); + // Clear TCO_STS + WRITE_IO16_PM(ACPI_IOREG_SMI_STS, BIT13); + + } +} +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SbSmiWorkaround2 +// +// Description: This hook is used for all south bridge workaround in SMI. +// +// Input: None +// +// Output: None +// +// Notes: Porting required +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID SbSmiWorkaround2 (VOID) +{ + +#if BIOS_WRITE_SMI_PATCH_ENABLE + BiosWriteSmiPatch(); +#endif + +} + // <[EIP93461] +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmmChildDispatch2.h b/Chipset/SB/Smm2/SmmChildDispatch2.h new file mode 100644 index 0000000..7e557f2 --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatch2.h @@ -0,0 +1,333 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2.h 3 3/25/13 5:00a Wesleychen $ +// +// $Revision: 3 $ +// +// $Date: 3/25/13 5:00a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2.h $ +// +// 3 3/25/13 5:00a Wesleychen +// [TAG] None +// [Category] Improvement +// [Description] Refine GPI SMM2 related routines. +// [Files] SmiHandlerGeneric2.c; SmiHandlerPorting2.c; +// SmmChildDispatch2.h +// +// 2 10/19/12 2:52a Scottyang +// [TAG] EIP93461 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System halt when AFUDOS is running with /N /ME command. +// [RootCause] An unexpected BIOSWR_STS is set, it causes BIOS stuck +// at SMM dispatcher. +// [Solution] Clear BIOSWR_STS if BIOS Lock Enable is not set. +// [Files] SmiHandlerPorting2.c; SmmChildDispatch2Main.c +// SmmChildDispatcher2.sdl; SmmChildDispatch2.h +// SB\SBGeneric.c +// +// 1 2/08/12 8:28a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatch2.h +// +// Description: SMM Child dispatcher II functions and data structures +// definition. +// +//<AMI_FHDR_END> +//************************************************************************* + +#ifndef __SMM_CHILD_DISPATCH2__H__ +#define __SMM_CHILD_DISPATCH2__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <AmiDxeLib.h> + +#include <Protocol\SmmSwDispatch2.h> +#include <Protocol\SmmSxDispatch2.h> +#include <Protocol\SmmPeriodicTimerDispatch2.h> +#include <Protocol\SmmUsbDispatch2.h> +#include <Protocol\SmmGpiDispatch2.h> +#include <Protocol\SmmStandbyButtonDispatch2.h> +#include <Protocol\SmmPowerButtonDispatch2.h> +#include <Protocol\SmmIoTrapDispatch2.h> + +#define SMM_CHILD_DISPATCHER2_GUID \ + {0x950c3a26, 0xe0c2, 0x491c, 0xb6, 0xb2, 0x3, 0x74, 0xf5, 0xc7, 0x3b, 0x96} + +#pragma pack(push, 1) + +typedef enum { + EfiSmmSwSmi2, + EfiSmmSxSmi2, + EfiSmmPeriodicTimerSmi2, + EfiSmmUsbSmi2, + EfiSmmGpiSmi2, + EfiSmmStandbyButtonSmi2, + EfiSmmPowerButtonSmi2, + EfiSmmIoTrapSmi2, + EfiSmmMaxSmi2 +} EFI_SMM_SMI2; + +typedef struct { + EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT OrgContext; + UINT64 ElapsedTime; +} EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT; + +typedef union { + EFI_SMM_SW_REGISTER_CONTEXT SwContext; + EFI_SMM_SX_REGISTER_CONTEXT SxContext; + EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT TimerContext; + EFI_SMM_USB_REGISTER_CONTEXT UsbContext; + EFI_SMM_GPI_REGISTER_CONTEXT GpiContext; + EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT SBtnContext; + EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT PBtnContext; + EFI_SMM_IO_TRAP_REGISTER_CONTEXT IoTrapContext; +} EFI_SMM_SMI_CONTEXT2; + +typedef EFI_STATUS ( *SMI_GENERIC_CALLBACK2 ) ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL +); + +typedef struct { + DLINK Link; + UINT32 Signature; + SMI_GENERIC_CALLBACK2 Callback; + UINT8 Context[1]; +} HANDLER_LINK2; + +//--------------------------------------------------------------------------- +// SMI Handler protocol functions prototypes +//--------------------------------------------------------------------------- + +typedef EFI_STATUS ( *ADD_HANDLER2 ) ( + IN VOID *Context +); + +typedef EFI_STATUS ( *REMOVE_HANDLER2 ) ( + IN VOID *Context +); + +typedef EFI_STATUS ( *VERIFY_CONTEXT2) ( + IN VOID *Context +); + +typedef BOOLEAN ( *GET_CONTEXT2 ) ( + VOID +); + +typedef EFI_STATUS ( *DISPATCH_SMI2 ) ( + VOID +); + +typedef struct { + ADD_HANDLER2 AddHandler; + REMOVE_HANDLER2 RemoveHandler; + VERIFY_CONTEXT2 VerifyContext; + GET_CONTEXT2 GetContext; + DISPATCH_SMI2 DispatchSmi; +} SMI_HANDLER_PROTOCOL2; + +typedef struct { + EFI_SMM_SMI2 SmiType; + SMI_HANDLER_PROTOCOL2 HandlerProtocol; + DLIST RegisteredCallbacks; +} SMM_CHILD_DISPATCHER2; + +#pragma pack(pop) + +//--------------------------------------------------------------------------- +// SW SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmSwAddHandler2( IN VOID *Context ); +EFI_STATUS SmmSwRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmSwVerifyContext2( IN VOID *Context ); +BOOLEAN SmmSwGetContext2( VOID ); +EFI_STATUS SmmSwDispatchSmi2( VOID ); + +//---------------------- SW SMI Handler Porting hooks ----------------------- + +VOID SwSmiEnable( VOID ); +VOID SwSmiDisable( VOID ); +VOID SwSmiClear( VOID ); +BOOLEAN SwSmiDetect( OUT UINT16 *Type ); +UINTN GetEAX( VOID ); + +//--------------------------------------------------------------------------- +// SX SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmSxAddHandler2( IN VOID *Context ); +EFI_STATUS SmmSxRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmSxVerifyContext2( IN VOID *Context ); +BOOLEAN SmmSxGetContext2( VOID ); +EFI_STATUS SmmSxDispatchSmi2( VOID ); + +//---------------------- SX SMI Handler Porting hooks ----------------------- + +VOID SxSmiEnable( VOID ); +VOID SxSmiDisable( VOID ); +VOID SxSmiClear( VOID ); +VOID PutToSleep( IN VOID *Context ); +BOOLEAN SxSmiDetect( OUT UINT16 *Type ); + +//--------------------------------------------------------------------------- +// Periodic timer SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmTimerAddHandler2( IN VOID *Context ); +EFI_STATUS SmmTimerRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmTimerVerifyContext2( IN VOID *Context ); +BOOLEAN SmmTimerGetContext2( VOID ); +EFI_STATUS SmmTimerDispatchSmi2( VOID ); + +//---------------- Periodic timer SMI Handler Porting hooks ----------------- + +VOID TimerSmiEnable2( VOID ); +VOID TimerSmiDisable2( VOID ); +VOID TimerSmiClear2( VOID ); +BOOLEAN TimerSmiDetect2( OUT UINT16 *Type ); +VOID TimerSetInterval2( IN UINT64 Interval); + +//--------------------------------------------------------------------------- +// USB SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmUsbAddHandler2( IN VOID *Context ); +EFI_STATUS SmmUsbRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmUsbVerifyContext2( IN VOID *Context ); +BOOLEAN SmmUsbGetContext2( VOID ); +EFI_STATUS SmmUsbDispatchSmi2( VOID ); + +//---------------------- USB SMI Handler Porting hooks ---------------------- + +VOID UsbSmiSet( IN UINT16 ControllerType ); +VOID UsbSmiClear( IN UINT16 ControllerType ); +BOOLEAN UsbSmiDetect( OUT UINT16 *Type ); +UINT16 GetControllerType( OUT EFI_DEVICE_PATH_PROTOCOL *Device ); + +//--------------------------------------------------------------------------- +// GPI SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmGpiAddHandler2( IN VOID *Context ); +EFI_STATUS SmmGpiRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmGpiVerifyContext2( IN VOID *Context ); +BOOLEAN SmmGpiGetContext2( VOID ); +EFI_STATUS SmmGpiDispatchSmi2( VOID ); + +//---------------------- GPI SMI Handler Porting hooks ---------------------- + +VOID GpiSmiSet( IN UINT32 GpiEnableBit ); +VOID GpiSmiReset( IN UINT32 GpiDisableBit ); +VOID GpiSmiClear( IN UINT32 GpiClearBit ); +BOOLEAN GpiSmiDetect( OUT UINT32 *Gpi ); +UINT32 ConvertGpi ( IN UINTN Gpi ); + +//--------------------------------------------------------------------------- +// Standby button SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmSButtonAddHandler2( IN VOID *Context ); +EFI_STATUS SmmSButtonRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmSButtonVerifyContext2( IN VOID *Context ); +BOOLEAN SmmSButtonGetContext2( VOID ); +EFI_STATUS SmmSButtonDispatchSmi2( VOID ); + +//---------------- Standby button SMI Handler Porting hooks ----------------- + +VOID SButtonSmiEnable( VOID ); +VOID SButtonSmiDisable( VOID ); +VOID SButtonSmiClear( VOID ); +BOOLEAN SButtonSmiDetect( OUT UINT16 *Type ); + +//--------------------------------------------------------------------------- +// Power button SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmPButtonAddHandler2( IN VOID *Context ); +EFI_STATUS SmmPButtonRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmPButtonVerifyContext2( IN VOID *Context ); +BOOLEAN SmmPButtonGetContext2( VOID ); +EFI_STATUS SmmPButtonDispatchSmi2( VOID ); + +//---------------- Power button SMI Handler Porting hooks ------------------- + +VOID PButtonSmiEnable( VOID ); +VOID PButtonSmiDisable( VOID ); +VOID PButtonSmiClear( VOID ); +BOOLEAN PButtonSmiDetect( OUT UINT16 *Type ); + +//--------------------------------------------------------------------------- +// I/O Trap SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmIoTrapAddHandler2( IN VOID *Context ); +EFI_STATUS SmmIoTrapRemoveHandler2( IN VOID *Context ); +EFI_STATUS SmmIoTrapVerifyContext2( IN VOID *Context ); +BOOLEAN SmmIoTrapGetContext2( VOID ); +EFI_STATUS SmmIoTrapDispatchSmi2( VOID ); + +//------------------ I/O Trap SMI Handler Porting hooks --------------------- + +VOID IoTrapSmiSet2( IN EFI_SMM_IO_TRAP_REGISTER_CONTEXT *Context, \ + OUT UINT32 *TrapRegIndex ); +VOID IoTrapSmiReset2( IN EFI_SMM_IO_TRAP_REGISTER_CONTEXT *Context, \ + OUT UINT32 *TrapRegIndex ); +VOID IoTrapSmiEnable2( VOID ); +VOID IoTrapSmiDisable2( VOID ); +VOID IoTrapSmiClear2( VOID ); +BOOLEAN IoTrapSmiDetect2( OUT EFI_SMM_IO_TRAP_REGISTER_CONTEXT *Context, \ + OUT UINT32 *IoTrapWriteDara ); + +//--------------------------------------------------------------------------- +// All purpose SMI Porting hooks +//--------------------------------------------------------------------------- +VOID ClearAllSmi( VOID ); + // [EIP93461]> +VOID SbSmiWorkaround2( VOID ); + // <[EIP93461] +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmmChildDispatch2Main.c b/Chipset/SB/Smm2/SmmChildDispatch2Main.c new file mode 100644 index 0000000..bae5efc --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatch2Main.c @@ -0,0 +1,510 @@ +#pragma optimize ("", off) +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2Main.c 4 10/19/12 2:52a Scottyang $ +// +// $Revision: 4 $ +// +// $Date: 10/19/12 2:52a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2Main.c $ +// +// 4 10/19/12 2:52a Scottyang +// [TAG] EIP93461 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System halt when AFUDOS is running with /N /ME command. +// [RootCause] An unexpected BIOSWR_STS is set, it causes BIOS stuck +// at SMM dispatcher. +// [Solution] Clear BIOSWR_STS if BIOS Lock Enable is not set. +// [Files] SmiHandlerPorting2.c; SmmChildDispatch2Main.c +// SmmChildDispatcher2.sdl; SmmChildDispatch2.h +// SB\SBGeneric.c +// +// 3 8/30/12 9:50a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Implement EIP#73211 and EIP#79156 for OA 3.0 function. +// [Files] SmiHandlerGeneric2.c, SmmChildDispatch2Main.c +// +// 2 4/25/12 9:32a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// 1 2/08/12 8:28a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatch2Main.c +// +// Description: This file contains implementation of module entry point, +// generic RegisterHandler and UnregisterHandler routines +// and main dispatcher loop. +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <AmiCspLib.h> +#include <Smm.h> +#include <Protocol\SmmBase2.h> +#include <Protocol\SmmCpu.h> +#include "SmmChildDispatch2.h" +#include "SmmChildDispatch2Protocol.h" + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +#define SMI_HANDLER_SIGNATURE 0x48494d53 //SMIH + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +EFI_SMM_SMI_CONTEXT2 SmiContext; +EFI_SMM_BASE2_PROTOCOL *gSmmBase2; +EFI_SMM_SYSTEM_TABLE2 *gSmst2; +EFI_SMM_CPU_PROTOCOL *gEfiSmmCpuProtocol; + +// GUID Definition(s) + +EFI_GUID gEfiSmmChildDispatcher2Guid = SMM_CHILD_DISPATCHER2_GUID; + +// Protocol Definition(s) + +// External Declaration(s) + +extern SMM_CHILD_DISPATCHER2 Smm2Handler[]; + +extern EFI_SMM_SW_DISPATCH2_PROTOCOL gEfiSmmSwDispatch2Protocol; +extern EFI_SMM_SX_DISPATCH2_PROTOCOL gEfiSmmSxDispatch2Protocol; +extern EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL gEfiSmmPeriodicTimerDispatch2Protocol; +extern EFI_SMM_USB_DISPATCH2_PROTOCOL gEfiSmmUsbDispatch2Protocol; +extern EFI_SMM_GPI_DISPATCH2_PROTOCOL gEfiSmmGpiDispatch2Protocol; +extern EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL gEfiSmmStandbyButtonDispatch2Protocol; +extern EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL gEfiSmmPowerButonDispatch2Protocol; +extern EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL gEfiSmmIoTrapDispatch2Protocol; + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RegisterHandler2 +// +// Description: This function registers SMI II handler and returns registered +// handle +// +// Input: Type - Type of SMI handler +// Function - Pointer to callback function +// *Context - Pointer to callback context +// ContextSize - Callback context size +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS RegisterHandler2 ( + IN EFI_SMM_SMI2 Type, + IN SMI_GENERIC_CALLBACK2 Function, + IN VOID *Context, + IN UINTN ContextSize, + OUT EFI_HANDLE *Handle ) +{ + EFI_STATUS Status; + HANDLER_LINK2 *HandlerLink; + + Status = Smm2Handler[Type].HandlerProtocol.VerifyContext( Context ); + if(EFI_ERROR(Status)) return Status; + + Status = gSmst2->SmmAllocatePool( 0, + sizeof(HANDLER_LINK2) + ContextSize - 1, + &HandlerLink ); + if(EFI_ERROR(Status)) return Status; + + HandlerLink->Callback = Function; + HandlerLink->Signature = SMI_HANDLER_SIGNATURE; + MemCpy( HandlerLink->Context, Context, ContextSize ); + + DListAdd(&(Smm2Handler[Type].RegisteredCallbacks), (DLINK *)HandlerLink); + + Smm2Handler[Type].HandlerProtocol.AddHandler( HandlerLink->Context ); + *Handle = HandlerLink; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: FindHandler +// +// Description: This function find the handle in the Type of SMI hander list. +// +// Input: Type - Type of SMI handler +// Handle - Handle of found handler +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS FindHandler( + IN EFI_SMM_SMI2 Type, + IN EFI_HANDLE Handle) +{ + HANDLER_LINK2 *HandlerLink = (HANDLER_LINK2 *)Handle; + HANDLER_LINK2 *NodeLink = NULL; + + if (HandlerLink->Signature != SMI_HANDLER_SIGNATURE) + return EFI_INVALID_PARAMETER; + + if (Smm2Handler[Type].RegisteredCallbacks.Size <= 0) + return EFI_UNSUPPORTED; + + NodeLink = (HANDLER_LINK2 *)Smm2Handler[Type].RegisteredCallbacks.pHead; + for (; NodeLink != NULL; NodeLink = (HANDLER_LINK2 *)NodeLink->Link.pNext) + { + if (NodeLink == HandlerLink) + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UnregisterHandler2 +// +// Description: This function unregisters SMI II handler with given handle +// +// Input: Type - Type of SMI handler +// Handle - Handle of registered handler +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS UnregisterHandler2 ( + IN EFI_SMM_SMI2 Type, + IN EFI_HANDLE Handle ) +{ + EFI_STATUS Status; + HANDLER_LINK2 *HandlerLink = (HANDLER_LINK2 *)Handle; + + Status = FindHandler(Type, Handle); + if (Status == EFI_SUCCESS) + { + Smm2Handler[Type].HandlerProtocol.RemoveHandler( HandlerLink->Context ); + DListDelete( &(Smm2Handler[Type].RegisteredCallbacks), (DLINK *)HandlerLink ); + gSmst2->SmmFreePool( HandlerLink ); + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ChildDispatcher2 +// +// Description: This function implements main SMI II dispatcher. +// +// Input: DispatchHandle - SMM dispatch handle +// *Context - Pointer to the dispatched context +// CommBuffer - Pointer to a collection of data in memory +// that will be conveyed from a non-SMM +// environment into an SMM environment. +// CommBufferSize - Pointer to the size of the CommBuffer +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ChildDispatcher2 ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL ) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + UINT32 Index; + BOOLEAN HandledSmi; + + do + { + HandledSmi = FALSE; + for (Index = EfiSmmSwSmi2; Index < EfiSmmMaxSmi2; Index++) + { + if (Smm2Handler[Index].HandlerProtocol.GetContext != 0 && + Smm2Handler[Index].HandlerProtocol.GetContext()) + { + Status = Smm2Handler[Index].HandlerProtocol.DispatchSmi(); + if (Status != EFI_WARN_INTERRUPT_SOURCE_QUIESCED) + { + HandledSmi = TRUE; + } + } + } + } while (HandledSmi); + // [EIP93461]> + SbSmiWorkaround2(); + // <[EIP93461] + return EFI_HANDLER_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InSmmFunction +// +// Description: This function initializes Child dispatcher in SMM mode +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InSmmFunction ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle = NULL; + EFI_HANDLE BsHandle = NULL; + EFI_HANDLE RootHandle; + +#if (CHILD_DISPATCHER_SUPPORT == 0) + ClearAllSmi(); +#endif + + // Locate SMM CPU Protocols + Status = gSmst2->SmmLocateProtocol( &gEfiCpuProtocolGuid, + NULL, + &gEfiSmmCpuProtocol); + + // Install Protocols + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmSwDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmSwDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmSwDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmSxDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmSxDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmSxDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmPeriodicTimerDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmPeriodicTimerDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmPeriodicTimerDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmUsbDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmUsbDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmUsbDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmGpiDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmGpiDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmGpiDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmStandbyButtonDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmStandbyButtonDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmStandbyButtonDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmPowerButtonDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmPowerButonDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmPowerButtonDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmmInstallProtocolInterface( + &Handle, + &gEfiSmmIoTrapDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &gEfiSmmIoTrapDispatch2Protocol); + ASSERT_EFI_ERROR(Status); + + Status = pBS->InstallProtocolInterface( + &BsHandle, + &gEfiSmmIoTrapDispatch2ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + Status = gSmst2->SmiHandlerRegister(ChildDispatcher2, NULL, &RootHandle); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmChildDispatch2EntryPoint +// +// Description: SMM Child Dispatcher II module entry point +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmChildDispatch2EntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + BOOLEAN InSmram = FALSE; + + InitAmiLib( ImageHandle, SystemTable ); + + Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2); + if (!EFI_ERROR(Status)) + { + Status = gSmmBase2->InSmm(gSmmBase2, &InSmram); + if ((!EFI_ERROR(Status)) && + (InSmram)) + { + Status = InitAmiSmmLib( ImageHandle, SystemTable ); + if (EFI_ERROR(Status)) + return Status; + + Status = gSmmBase2->GetSmstLocation(gSmmBase2, &gSmst2); + if (!EFI_ERROR(Status)) + { + Status = InSmmFunction(ImageHandle, SystemTable); + return Status; + } + else + { + gSmst2 = NULL; + } + } + else + { + // DXE initialize. + } + } + + return EFI_SUCCESS; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmmChildDispatch2Protocol.c b/Chipset/SB/Smm2/SmmChildDispatch2Protocol.c new file mode 100644 index 0000000..2fc7edc --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatch2Protocol.c @@ -0,0 +1,679 @@ +#pragma optimize ("", off) +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2Protocol.c 1 2/08/12 8:28a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:28a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2Protocol.c $ +// +// 1 2/08/12 8:28a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatch2Protocol.c +// +// Description: This file contains SMM Child dispatcher II Protocols +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Token.h> +#include <AmiDxeLib.h> +#include "SmmChildDispatch2.h" +#include "SmmChildDispatch2Protocol.h" + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +SMM_CHILD_DISPATCHER2 Smm2Handler[] = { + // SwSmmHandler + EfiSmmSwSmi2, + { SmmSwAddHandler2, \ + SmmSwRemoveHandler2, \ + SmmSwVerifyContext2, \ + SmmSwGetContext2, \ + SmmSwDispatchSmi2 }, + { 0, NULL, NULL }, + + // SxSmmHandler + EfiSmmSxSmi2, + { SmmSxAddHandler2, \ + SmmSxRemoveHandler2, \ + SmmSxVerifyContext2, \ + SmmSxGetContext2, \ + SmmSxDispatchSmi2 }, + { 0, NULL, NULL }, + + // PeriodicTimerSmmHandler + EfiSmmPeriodicTimerSmi2, + { SmmTimerAddHandler2, \ + SmmTimerRemoveHandler2, \ + SmmTimerVerifyContext2, \ + SmmTimerGetContext2, \ + SmmTimerDispatchSmi2 }, + { 0, NULL, NULL }, + + // UsbSmmHandler + EfiSmmUsbSmi2, + { SmmUsbAddHandler2, \ + SmmUsbRemoveHandler2, \ + SmmUsbVerifyContext2, \ + SmmUsbGetContext2, \ + SmmUsbDispatchSmi2 }, + { 0, NULL, NULL }, + + // GpiSmmHandler + EfiSmmGpiSmi2, + { SmmGpiAddHandler2, \ + SmmGpiRemoveHandler2, \ + SmmGpiVerifyContext2, \ + SmmGpiGetContext2, \ + SmmGpiDispatchSmi2 }, + { 0, NULL, NULL }, + + // SButtonSmmHandler + EfiSmmStandbyButtonSmi2, + { SmmSButtonAddHandler2, \ + SmmSButtonRemoveHandler2, \ + SmmSButtonVerifyContext2, \ + SmmSButtonGetContext2, \ + SmmSButtonDispatchSmi2 }, + { 0, NULL, NULL }, + + // PButtonSmmHandler + EfiSmmPowerButtonSmi2, + { SmmPButtonAddHandler2, \ + SmmPButtonRemoveHandler2, \ + SmmPButtonVerifyContext2, \ + SmmPButtonGetContext2, \ + SmmPButtonDispatchSmi2 }, + { 0, NULL, NULL }, + + // IoTrapSmmHandler + EfiSmmIoTrapSmi2, + { SmmIoTrapAddHandler2, \ + SmmIoTrapRemoveHandler2, \ + SmmIoTrapVerifyContext2, \ + SmmIoTrapGetContext2, \ + SmmIoTrapDispatchSmi2 }, + { 0, NULL, NULL }, + +//********************** PUT ADDITIONAL HANDLERS HERE *********************** +//********************** PUT ADDITIONAL HANDLERS HERE *********************** +//********************** PUT ADDITIONAL HANDLERS HERE *********************** + + // Terminator record + EfiSmmMaxSmi2, + { NULL, NULL, NULL, NULL, NULL }, + { 0, NULL, NULL } +}; + +EFI_SMM_SW_DISPATCH2_PROTOCOL gEfiSmmSwDispatch2Protocol = \ + { EfiSmmSwRegister2, \ + EfiSmmSwUnregister2, \ + MAX_SW_SMI_INPUT_VALUE }; + +EFI_SMM_SX_DISPATCH2_PROTOCOL gEfiSmmSxDispatch2Protocol = \ + { EfiSmmSxRegister2, EfiSmmSxUnregister2 }; + +EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL \ + gEfiSmmPeriodicTimerDispatch2Protocol = \ + { EfiSmmTimerRegister2, \ + EfiSmmTimerUnregister2, \ + EfiSmmTimerGetNextShorterInterval2 }; + +EFI_SMM_USB_DISPATCH2_PROTOCOL gEfiSmmUsbDispatch2Protocol = \ + { EfiSmmUsbRegister2, EfiSmmUsbUnregister2 }; + +EFI_SMM_GPI_DISPATCH2_PROTOCOL gEfiSmmGpiDispatch2Protocol = \ + { EfiSmmGpiRegister2, \ + EfiSmmGpiUnregister2, \ + SUPPORTED_GPIS }; + +EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL \ + gEfiSmmStandbyButtonDispatch2Protocol = \ + { EfiSmmSButtonRegister2, EfiSmmSButtonUnregister2 }; + +EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL gEfiSmmPowerButonDispatch2Protocol = \ + { EfiSmmPButtonRegister2, EfiSmmPButtonUnregister2 }; + + +EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL gEfiSmmIoTrapDispatch2Protocol = \ + { EfiSmmIoTrapRegister2, EfiSmmIoTrapUnregister2 }; + + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +extern UINT64 gSupportedIntervals[]; + +// Function Definition(s) + +//--------------------------------------------------------------------------- +// S/W SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSwRegister2 +// +// Description: EFI_SMM_SW_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_SW_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSwRegister2 ( + IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_SW_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + return RegisterHandler2( EfiSmmSwSmi2, \ + Function, \ + Context, \ + sizeof(EFI_SMM_SW_REGISTER_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSwUnregister2 +// +// Description: EFI_SMM_SW_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSwUnregister2 ( + IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler2( EfiSmmSwSmi2, Handle ); +} + +//--------------------------------------------------------------------------- +// Sleep SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSxRegister2 +// +// Description: EFI_SMM_SX_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_SX_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSxRegister2 ( + IN CONST EFI_SMM_SX_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_SX_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + return RegisterHandler2( EfiSmmSxSmi2, \ + Function, \ + Context, \ + sizeof(EFI_SMM_SX_REGISTER_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSxUnregister2 +// +// Description: EFI_SMM_SW_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_SX_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSxUnregister2 ( + IN CONST EFI_SMM_SX_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler2( EfiSmmSxSmi2, Handle ); +} + +//--------------------------------------------------------------------------- +// Periodic timer SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTimerRegister2 +// +// Description: EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to +// EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTimerRegister2 ( + IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT ExContext; + TRACE ((TRACE_ALWAYS, "EfiSmmTimerRegister2 \n")); + ExContext.OrgContext = *Context; + ExContext.ElapsedTime = 0; + + return RegisterHandler2( EfiSmmPeriodicTimerSmi2, \ + Function, \ + &ExContext, \ + sizeof(EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTimerUnregister2 +// +// Description: EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the +// EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTimerUnregister2 ( + IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + TRACE ((TRACE_ALWAYS, "EfiSmmTimerUnregister2 \n")); + return UnregisterHandler2( EfiSmmPeriodicTimerSmi2, Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTimerGetNextShorterInterval2 +// +// Description: EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL +// GetNextShorterInterval function. +// +// Input: *This - Pointer to the +// EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL +// **SmiTickInterval - Pointer to store pointer to next interval +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTimerGetNextShorterInterval2 ( + IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *This, + IN OUT UINT64 **SmiTickInterval ) +{ + UINT64 *Result = *SmiTickInterval; + TRACE ((TRACE_ALWAYS, "EfiSmmTimerGetNextShorterInterval2 \n")); + if (Result == NULL) { + Result = gSupportedIntervals; + } else { + Result++; + } + *SmiTickInterval = (*Result == 0) ? NULL : Result; + + return EFI_SUCCESS; +} + +//--------------------------------------------------------------------------- +// USB SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmUsbRegister2 +// +// Description: EFI_SMM_USB_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_USB_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmUsbRegister2 ( + IN CONST EFI_SMM_USB_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_USB_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + return RegisterHandler2( EfiSmmUsbSmi2, \ + Function, \ + Context, \ + sizeof(EFI_SMM_USB_REGISTER_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmUsbUnregister2 +// +// Description: EFI_SMM_USB_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_USB_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmUsbUnregister2 ( + IN CONST EFI_SMM_USB_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler2( EfiSmmUsbSmi2, Handle ); +} + +//--------------------------------------------------------------------------- +// GPI SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmGpiRegister2 +// +// Description: EFI_SMM_GPI_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_GPI_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmGpiRegister2 ( + IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_GPI_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + return RegisterHandler2( EfiSmmGpiSmi2, \ + Function, \ + Context, \ + sizeof(EFI_SMM_GPI_REGISTER_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmGpiUnregister2 +// +// Description: EFI_SMM_GPI_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_GPI_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmGpiUnregister2 ( + IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler2( EfiSmmGpiSmi2, Handle ); +} + +//--------------------------------------------------------------------------- +// Standby button SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSButtonRegister2 +// +// Description: EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to +// EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSButtonRegister2 ( + IN CONST EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + return RegisterHandler2( EfiSmmStandbyButtonSmi2, \ + Function, \ + Context, \ + sizeof(EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT),\ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSButtonUnregister2 +// +// Description: EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the +// EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSButtonUnregister2 ( + IN CONST EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler2( EfiSmmStandbyButtonSmi2, Handle ); +} + +//--------------------------------------------------------------------------- +// Power button SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmPButtonRegister2 +// +// Description: EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmPButtonRegister2 ( + IN CONST EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + return RegisterHandler2( EfiSmmPowerButtonSmi2, \ + Function, \ + Context, \ + sizeof(EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmPButtonUnregister2 +// +// Description: EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the +// EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmPButtonUnregister2 ( + IN CONST EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler2( EfiSmmPowerButtonSmi2, Handle ); +} + +//--------------------------------------------------------------------------- +// I/O Trap SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmIoTrapRegister2 +// +// Description: EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to register context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmIoTrapRegister2 ( + IN CONST EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN OUT EFI_SMM_IO_TRAP_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle) +{ + return RegisterHandler2( EfiSmmIoTrapSmi2, \ + Function, \ + Context, \ + sizeof(EFI_SMM_IO_TRAP_REGISTER_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmIoTrapUnregister2 +// +// Description: EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmIoTrapUnregister2 ( + IN CONST EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler2( EfiSmmIoTrapSmi2, Handle ); +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmmChildDispatch2Protocol.h b/Chipset/SB/Smm2/SmmChildDispatch2Protocol.h new file mode 100644 index 0000000..39d7bd4 --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatch2Protocol.h @@ -0,0 +1,204 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2Protocol.h 1 2/08/12 8:28a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:28a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatch2Protocol.h $ +// +// 1 2/08/12 8:28a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatch2Protocol.h +// +// Description: SMM Child dispatcher II protocols functions definition +// +//<AMI_FHDR_END> +//************************************************************************* + +#ifndef __SMM_CHILD_DISPATCH2_PROTOCOL__H__ +#define __SMM_CHILD_DISPATCH2_PROTOCOL__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <Protocol\SmmSwDispatch2.h> +#include <Protocol\SmmSxDispatch2.h> +#include <Protocol\SmmPeriodicTimerDispatch2.h> +#include <Protocol\SmmUsbDispatch2.h> +#include <Protocol\SmmGpiDispatch2.h> +#include <Protocol\SmmStandbyButtonDispatch2.h> +#include <Protocol\SmmPowerButtonDispatch2.h> +#include <Protocol\SmmIoTrapDispatch2.h> + +//-------------- Generic register/unregister handler functions -------------- + +EFI_STATUS RegisterHandler2( + IN EFI_SMM_SMI2 Type, + IN SMI_GENERIC_CALLBACK2 Function, + IN CONST VOID *Context, + IN UINTN ContextSize, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS UnregisterHandler2 ( + IN EFI_SMM_SMI2 Type, + IN EFI_HANDLE Handle +); + +//------------------------ Sw SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmSwRegister2 ( + IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_SW_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmSwUnregister2 ( + IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------------ Sx SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmSxRegister2 ( + IN CONST EFI_SMM_SX_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_SX_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmSxUnregister2 ( + IN CONST EFI_SMM_SX_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------ Periodic timer SMI protocol functions ------------------ + +EFI_STATUS EfiSmmTimerRegister2 ( + IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmTimerUnregister2 ( + IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +EFI_STATUS EfiSmmTimerGetNextShorterInterval2 ( + IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *This, + IN OUT UINT64 **SmiTickInterval +); + +//----------------------- Usb SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmUsbRegister2 ( + IN CONST EFI_SMM_USB_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_USB_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmUsbUnregister2 ( + IN CONST EFI_SMM_USB_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//----------------------- Gpi SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmGpiRegister2 ( + IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_GPI_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmGpiUnregister2 ( + IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------ Standby button SMI protocol functions ------------------ + +EFI_STATUS EfiSmmSButtonRegister2 ( + IN CONST EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmSButtonUnregister2 ( + IN CONST EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------- Power button SMI protocol functions ------------------- + +EFI_STATUS EfiSmmPButtonRegister2 ( + IN CONST EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN CONST EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmPButtonUnregister2 ( + IN CONST EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//--------------------- I/O Trap SMI protocol functions --------------------- + +EFI_STATUS EfiSmmIoTrapRegister2 ( + IN CONST EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN OUT EFI_SMM_IO_TRAP_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmIoTrapUnregister2 ( + IN CONST EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmmChildDispatcher2.cif b/Chipset/SB/Smm2/SmmChildDispatcher2.cif new file mode 100644 index 0000000..c02d46b --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatcher2.cif @@ -0,0 +1,16 @@ +<component> + name = "SmmChildDispatcher2" + category = ModulePart + LocalRoot = "Chipset\SB\Smm2" + RefName = "SmmChildDispatcher2" +[files] +"SmmChildDispatcher2.mak" +"SmmChildDispatcher2.sdl" +"SmmChildDispatcher2.dxs" +"SmiHandlerGeneric2.c" +"SmiHandlerPorting2.c" +"SmmChildDispatch2.h" +"SmmChildDispatch2Main.c" +"SmmChildDispatch2Protocol.c" +"SmmChildDispatch2Protocol.h" +<endComponent> diff --git a/Chipset/SB/Smm2/SmmChildDispatcher2.dxs b/Chipset/SB/Smm2/SmmChildDispatcher2.dxs new file mode 100644 index 0000000..2d6cd56 --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatcher2.dxs @@ -0,0 +1,58 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatcher2.dxs 1 2/08/12 8:28a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:28a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatcher2.dxs $ +// +// 1 2/08/12 8:28a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatcher2.DXS +// +// Description: This file contains the dependency expression for the SMM +// Child Dispatcher II driver +// +//<AMI_FHDR_END> +//************************************************************************* + +#include <Protocol\SmmBase2.h> + +DEPENDENCY_START + EFI_SMM_BASE2_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/Smm2/SmmChildDispatcher2.mak b/Chipset/SB/Smm2/SmmChildDispatcher2.mak new file mode 100644 index 0000000..18e5cd7 --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatcher2.mak @@ -0,0 +1,85 @@ +# MAK file for the ModulePart:SmmChildDispatcher II +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatcher2.mak 2 4/25/12 9:32a Victortu $ +# +# $Revision: 2 $ +# +# $Date: 4/25/12 9:32a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatcher2.mak $ +# +# 2 4/25/12 9:32a Victortu +# [TAG] None +# [Category] Improvement +# [Description] Reprogram SMM ChildDispatcher drivers. +# [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +# SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +# SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +# SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +# PchSmiDispatcher.sdl +# +# 1 2/08/12 8:28a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: SmmChildDispatcher2.mak +# +# Description: Make file for the SMM Child Dispatcher II driver. +# +#<AMI_FHDR_END> +#************************************************************************* +!IFNDEF BACKWARD_COMPATIBLE_MODE +BACKWARD_COMPATIBLE_MODE = 1 +!ENDIF + +all : SmmChildDispatcher2 + +SmmChildDispatcher2 : $(BUILD_DIR)\SmmChildDispatcher2.mak SmmChildDispatcher2Bin + +$(BUILD_DIR)\SmmChildDispatcher2.mak : $(SMM_CHILD_DISP2_DIR)\SmmChildDispatcher2.cif $(SMM_CHILD_DISP2_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SMM_CHILD_DISP2_DIR)\SmmChildDispatcher2.cif $(CIF2MAK_DEFAULTS) + +SmmChildDispatcher2Bin : $(AMICSPLib) $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SmmChildDispatcher2.mak all\ + "CFLAGS=$(CFLAGS) /I$(SB_BOARD_DIR)"\ + GUID=E53734A3-E594-4c25-B1A2-081445650F7F\ + ENTRY_POINT=SmmChildDispatch2EntryPoint\ + TYPE=DXESMM_DRIVER \ + DEPEX1=$(SMM_CHILD_DISP2_DIR)\SmmChildDispatcher2.dxs \ + DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \ + DEPEX2=$(SMM_CHILD_DISP2_DIR)\SmmChildDispatcher2.dxs \ + DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \ + COMPRESS=1 + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/Smm2/SmmChildDispatcher2.sdl b/Chipset/SB/Smm2/SmmChildDispatcher2.sdl new file mode 100644 index 0000000..5540394 --- /dev/null +++ b/Chipset/SB/Smm2/SmmChildDispatcher2.sdl @@ -0,0 +1,135 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatcher2.sdl 4 1/03/13 7:00a Scottyang $ +# +# $Revision: 4 $ +# +# $Date: 1/03/13 7:00a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmmChildDispatcher2.sdl $ +# +# 4 1/03/13 7:00a Scottyang +# [TAG] None +# [Category] Bug Fix +# [Severity] Important +# [Symptom] GPISMI cannot use. +# [RootCause] GPISMI2 will clear status before GPISMI. +# [Solution] GPISMI2 do not clear status when GPISMI has register. +# [Files] SmmChildDispatcher2.sdl +# SmiHandlerGeneric2.c +# +# 3 10/19/12 2:52a Scottyang +# [TAG] EIP93461 +# [Category] Bug Fix +# [Severity] Normal +# [Symptom] System halt when AFUDOS is running with /N /ME command. +# [RootCause] An unexpected BIOSWR_STS is set, it causes BIOS stuck +# at SMM dispatcher. +# [Solution] Clear BIOSWR_STS if BIOS Lock Enable is not set. +# [Files] SmiHandlerPorting2.c; SmmChildDispatch2Main.c +# SmmChildDispatcher2.sdl; SmmChildDispatch2.h +# SB\SBGeneric.c +# +# 2 4/25/12 9:32a Victortu +# [TAG] None +# [Category] Improvement +# [Description] Reprogram SMM ChildDispatcher drivers. +# [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +# SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +# SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +# SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +# PchSmiDispatcher.sdl +# +# 1 2/08/12 8:28a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "SmmChildDispatcher2_SUPPORT" + Value = "1" + Help = "Main switch to enable SmmChildDispatcher II support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "PI_SPECIFICATION_VERSION" ">" "0x10000" +End + +TOKEN + Name = "PI_0_9_CHILD_DISPATCHER_SUPPORT" + Value = "1" + Help = "Enable SmmChildDispatcher I support" + TokenType = Boolean + TargetH = Yes +End + + # [EIP93461]> +TOKEN + Name = "BIOS_WRITE_SMI_PATCH_ENABLE" + Value = "1" + Help = "Clear unexpected BIOSWR_STS." + TokenType = Boolean + TargetH = Yes +End + # <[EIP93461] + +TOKEN + Name = "GPI_DISPATCH2_BY_BITMAP" + Value = "0" + Help = "ON = The registered parameter of SMM GPI dispatcher II is using bitmapped.\OFF = The registered parameter of SMM GPI disatcher is using index based" + TokenType = Boolean + TargetH = Yes + Lock = Yes +End + +TOKEN + Name = "SUPPORTED_GPIS2" + Value = "0xFFFF" + Help = "This is a supported GPI SMI mask, 1 = supported, 16 bits maximum" + TokenType = Integer + TargetH = Yes +End + +PATH + Name = "SMM_CHILD_DISP2_DIR" +End + +MODULE + Help = "Includes SmmChildDispatcher2.mak to Project" + File = "SmmChildDispatcher2.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SmmChildDispatcher2.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, 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/Chipset/SB/SmmChildDispatch.h b/Chipset/SB/SmmChildDispatch.h new file mode 100644 index 0000000..01458d0 --- /dev/null +++ b/Chipset/SB/SmmChildDispatch.h @@ -0,0 +1,369 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatch.h 2 4/25/12 9:35a Victortu $ +// +// $Revision: 2 $ +// +// $Date: 4/25/12 9:35a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatch.h $ +// +// 2 4/25/12 9:35a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// 1 2/08/12 8:27a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatch.h +// +// Description: SMM Child dispatcher functions and data structures +// definition. +// +//<AMI_FHDR_END> +//************************************************************************* + +#ifndef __SMM_CHILD_DISPATCH__H__ +#define __SMM_CHILD_DISPATCH__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <AmiDxeLib.h> +#include <Protocol\SmmSwDispatch.h> +#include <Protocol\SmmSxDispatch.h> +#include <Protocol\SmmPeriodicTimerDispatch.h> +#include <Protocol\SmmUsbDispatch.h> +#include <Protocol\SmmGpiDispatch.h> +#include <Protocol\SmmStandbyButtonDispatch.h> +#include <Protocol\SmmPowerButtonDispatch.h> +#include <Protocol\SmmTcoDispatch.h> +#include <Protocol\SmmIoTrapDispatch.h> + +#include <Protocol\SmmBiosWriteDispatch.h> + +#ifndef INTEL_RC_SMI_DISPATCHER_SUPPORT +#define INTEL_RC_SMI_DISPATCHER_SUPPORT 0 +#endif + +#pragma pack(push, 1) + +typedef enum { + EfiSmmSwSmi, + EfiSmmSxSmi, + EfiSmmPeriodicTimerSmi, + EfiSmmUsbSmi, + EfiSmmGpiSmi, + EfiSmmStandbyButtonSmi, + EfiSmmPowerButtonSmi, + EfiSmmTcoSmi, + EfiSmmIoTrapSmi, + EfiSmmMaxSmi +} EFI_SMM_SMI; + +typedef union { + EFI_SMM_SW_DISPATCH_CONTEXT SwContext; + EFI_SMM_SX_DISPATCH_CONTEXT SxContext; + EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT TimerContext; + EFI_SMM_USB_DISPATCH_CONTEXT UsbContext; + EFI_SMM_GPI_DISPATCH_CONTEXT GpiContext; + EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT SBtnContext; + EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT PBtnContext; + EFI_SMM_TCO_DISPATCH_CONTEXT TcoContext; + EFI_SMM_IO_TRAP_DISPATCH_CONTEXT IoTrapContext; +} EFI_SMM_SMI_CONTEXT; + +typedef VOID ( *SMI_GENERIC_CALLBACK ) ( + IN EFI_HANDLE DispatchHandle, + IN VOID *DispatchContext +); + +typedef struct { + DLINK Link; + UINT32 Signature; + SMI_GENERIC_CALLBACK Callback; + UINT8 Context[1]; +} HANDLER_LINK; + +typedef VOID ( *SMI_GENERIC_NEW_CALLBACK ) ( + IN EFI_HANDLE DispatchHandle, + IN VOID *DispatchContext, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize +); + + +typedef struct { + DLINK Link; + UINT32 Signature; + SMI_GENERIC_NEW_CALLBACK Callback; + UINT8 Context[1]; +} HANDLER_NEW_LINK; + +//--------------------------------------------------------------------------- +// SMI Handler protocol functions prototypes +//--------------------------------------------------------------------------- + +typedef EFI_STATUS ( *ADD_HANDLER ) ( + IN VOID *Context +); + +typedef EFI_STATUS ( *REMOVE_HANDLER ) ( + IN VOID *Context +); + +typedef EFI_STATUS ( *VERIFY_CONTEXT) ( + IN VOID *Context +); + +typedef BOOLEAN ( *GET_CONTEXT ) ( + VOID +); + +typedef VOID ( *DISPATCH_SMI ) ( + VOID +); + +typedef struct { + ADD_HANDLER AddHandler; + REMOVE_HANDLER RemoveHandler; + VERIFY_CONTEXT VerifyContext; + GET_CONTEXT GetContext; + DISPATCH_SMI DispatchSmi; +} SMI_HANDLER_PROTOCOL; + +typedef struct { + EFI_SMM_SMI SmiType; + SMI_HANDLER_PROTOCOL HandlerProtocol; + DLIST RegisteredCallbacks; +} SMM_CHILD_DISPATCHER; + +#pragma pack(pop) + +//--------------------------------------------------------------------------- +// SW SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmSwAddHandler( IN VOID *Context ); +EFI_STATUS SmmSwRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmSwVerifyContext( IN VOID *Context ); +BOOLEAN SmmSwGetContext( VOID ); +VOID SmmSwDispatchSmi( VOID ); + +//---------------------- SW SMI Handler Porting hooks ----------------------- + +VOID SwSmiEnable( VOID ); +VOID SwSmiDisable( VOID ); +VOID SwSmiClear( VOID ); +BOOLEAN SwSmiDetect( OUT UINT16 *Type ); +UINTN GetEAX( VOID ); + +//--------------------------------------------------------------------------- +// SX SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmSxAddHandler( IN VOID *Context ); +EFI_STATUS SmmSxRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmSxVerifyContext( IN VOID *Context ); +BOOLEAN SmmSxGetContext( VOID ); +VOID SmmSxDispatchSmi( VOID ); + +//---------------------- SX SMI Handler Porting hooks ----------------------- + +VOID SxSmiEnable( VOID ); +VOID SxSmiDisable( VOID ); +VOID SxSmiClear( VOID ); +VOID PutToSleep( IN VOID *Context ); +BOOLEAN SxSmiDetect( OUT UINT16 *Type ); + +//--------------------------------------------------------------------------- +// Periodic timer SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmTimerAddHandler( IN VOID *Context ); +EFI_STATUS SmmTimerRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmTimerVerifyContext( IN VOID *Context ); +BOOLEAN SmmTimerGetContext( VOID ); +VOID SmmTimerDispatchSmi( VOID ); + +//---------------- Periodic timer SMI Handler Porting hooks ----------------- + +VOID TimerSmiEnable( VOID ); +VOID TimerSmiDisable( VOID ); +VOID TimerSmiClear( VOID ); +BOOLEAN TimerSmiDetect( OUT UINT16 *Type ); +VOID TimerSetInterval( IN UINT64 Interval); + +//--------------------------------------------------------------------------- +// USB SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmUsbAddHandler( IN VOID *Context ); +EFI_STATUS SmmUsbRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmUsbVerifyContext( IN VOID *Context ); +BOOLEAN SmmUsbGetContext( VOID ); +VOID SmmUsbDispatchSmi( VOID ); + +//---------------------- USB SMI Handler Porting hooks ---------------------- + +VOID UsbSmiSet( IN UINT16 ControllerType ); +VOID UsbSmiClear( IN UINT16 ControllerType ); +BOOLEAN UsbSmiDetect( OUT UINT16 *Type ); +UINT16 GetControllerType( OUT EFI_DEVICE_PATH_PROTOCOL *Device ); + +//--------------------------------------------------------------------------- +// GPI SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmGpiAddHandler( IN VOID *Context ); +EFI_STATUS SmmGpiRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmGpiVerifyContext( IN VOID *Context ); +BOOLEAN SmmGpiGetContext( VOID ); +VOID SmmGpiDispatchSmi( VOID ); + +//---------------------- GPI SMI Handler Porting hooks ---------------------- + +VOID GpiSmiSet( IN UINT32 GpiEnableBit ); +VOID GpiSmiReset( IN UINT32 GpiDisableBit ); +VOID GpiSmiClear( IN UINT32 GpiClearBit ); +BOOLEAN GpiSmiDetect( OUT UINT32 *Gpi ); + +//--------------------------------------------------------------------------- +// Standby button SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmSButtonAddHandler( IN VOID *Context ); +EFI_STATUS SmmSButtonRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmSButtonVerifyContext( IN VOID *Context ); +BOOLEAN SmmSButtonGetContext( VOID ); +VOID SmmSButtonDispatchSmi( VOID ); + +//---------------- Standby button SMI Handler Porting hooks ----------------- + +VOID SButtonSmiEnable( VOID ); +VOID SButtonSmiDisable( VOID ); +VOID SButtonSmiClear( VOID ); +BOOLEAN SButtonSmiDetect( OUT UINT16 *Type ); + +//--------------------------------------------------------------------------- +// Power button SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmPButtonAddHandler( IN VOID *Context ); +EFI_STATUS SmmPButtonRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmPButtonVerifyContext( IN VOID *Context ); +BOOLEAN SmmPButtonGetContext( VOID ); +VOID SmmPButtonDispatchSmi( VOID ); + +//---------------- Power button SMI Handler Porting hooks ------------------- + +VOID PButtonSmiEnable( VOID ); +VOID PButtonSmiDisable( VOID ); +VOID PButtonSmiClear( VOID ); +BOOLEAN PButtonSmiDetect( OUT UINT16 *Type ); + +//--------------------------------------------------------------------------- +// TCO SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmTcoAddHandler( IN VOID *Context ); +EFI_STATUS SmmTcoRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmTcoVerifyContext( IN VOID *Context ); +BOOLEAN SmmTcoGetContext( VOID ); +VOID SmmTcoDispatchSmi( VOID ); + +//--------------------- TCO SMI Handler Porting hooks ----------------------- + +VOID TcoSmiSet( IN UINT32 TcoBitOffset ); +VOID TcoSmiReset( IN UINT32 TcoBitOffset ); +VOID TcoSmiEnable( VOID ); +VOID TcoSmiDisable( VOID ); +VOID TcoSmiClear( VOID ); +BOOLEAN TcoSmiDetect( OUT UINT32 *TcoStatus ); + +//--------------------------------------------------------------------------- +// I/O Trap SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmIoTrapAddHandler( IN VOID *Context ); +EFI_STATUS SmmIoTrapRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmIoTrapVerifyContext( IN VOID *Context ); +BOOLEAN SmmIoTrapGetContext( VOID ); +VOID SmmIoTrapDispatchSmi( VOID ); + +//------------------ I/O Trap SMI Handler Porting hooks --------------------- + +VOID IoTrapSmiSet( IN EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *Context ); +VOID IoTrapSmiReset( IN EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *Context ); +VOID IoTrapSmiEnable( VOID ); +VOID IoTrapSmiDisable( VOID ); +VOID IoTrapSmiClear( VOID ); +BOOLEAN IoTrapSmiDetect( OUT EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *Context ); + +//--------------------------------------------------------------------------- +// BIOS Write SMI Handler functions +//--------------------------------------------------------------------------- + +EFI_STATUS SmmBiosWriteAddHandler( IN VOID *Context ); +EFI_STATUS SmmBiosWriteRemoveHandler( IN VOID *Context ); +EFI_STATUS SmmBiosWriteVerifyContext( IN VOID *Context ); +BOOLEAN SmmBiosWriteGetContext( VOID ); +VOID SmmBiosWriteDispatchSmi( VOID ); + +//----------------- BIOS Write SMI Handler Porting hooks -------------------- + +VOID BiosWriteSmiEnable( VOID ); +VOID BiosWriteSmiDisable( VOID ); +VOID BiosWriteSmiClear( VOID ); +BOOLEAN BiosWriteSmiDetect( VOID ); + +//--------------------------------------------------------------------------- +// All purpose SMI Porting hooks +//--------------------------------------------------------------------------- +VOID ClearAllSmi( VOID ); + +VOID SbSmiWorkaround( VOID ); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmmChildDispatchMain.c b/Chipset/SB/SmmChildDispatchMain.c new file mode 100644 index 0000000..650c5fa --- /dev/null +++ b/Chipset/SB/SmmChildDispatchMain.c @@ -0,0 +1,437 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatchMain.c 2 4/25/12 9:35a Victortu $ +// +// $Revision: 2 $ +// +// $Date: 4/25/12 9:35a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatchMain.c $ +// +// 2 4/25/12 9:35a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// 1 2/08/12 8:27a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatchMain.c +// +// Description: This file contains implementation of module entry point, +// generic RegisterHandler and UnregisterHandler routines +// and main dispatcher loop. +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <AmiCspLib.h> +#include <Smm.h> +#include "SmmChildDispatch.h" +#include "SmmChildDispatchProtocol.h" + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) +#define SMI_HANDLER_SIGNATURE 0x48494d53 //SMIH + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +EFI_SMM_SMI_CONTEXT SmiContext; +SB_ASL_BUFFER *gSbAslBufPtr = NULL; + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +extern EFI_SMM_SYSTEM_TABLE *pSmst; +extern SMM_CHILD_DISPATCHER SmmHandler[]; + +#if INTEL_RC_SMI_DISPATCHER_SUPPORT == 0 +extern EFI_SMM_SW_DISPATCH_PROTOCOL gEfiSmmSwDispatchProtocol; +extern EFI_SMM_SX_DISPATCH_PROTOCOL gEfiSmmSxDispatchProtocol; +extern EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL gEfiSmmPeriodicTimerDispatchProtocol; +extern EFI_SMM_USB_DISPATCH_PROTOCOL gEfiSmmUsbDispatchProtocol; +extern EFI_SMM_GPI_DISPATCH_PROTOCOL gEfiSmmGpiDispatchProtocol; +#endif +extern EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL gEfiSmmStandbyButtonDispatchProtocol; +#if INTEL_RC_SMI_DISPATCHER_SUPPORT == 0 +extern EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL gEfiSmmPowerButonDispatchProtocol; +extern EFI_SMM_TCO_DISPATCH_PROTOCOL gEfiSmmTcoDispatchProtocol; +extern EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL gEfiSmmIoTrapDispatchProtocol; +#endif + +// Function Definition(s) + +#if (INTEL_RC_SMI_DISPATCHER_SUPPORT == 1) && (PI_0_9_CHILD_DISPATCHER_SUPPORT == 1) +static BOOLEAN PowerBtnSmi = FALSE; + +VOID PowerButtonActivated( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext + ) +{ + PowerBtnSmi = TRUE; +} + +VOID AfterChildDispatcher(VOID) +{ + if (PowerBtnSmi) + { + PButtonSmiClear(); + SBLib_Shutdown(); + PowerBtnSmi = FALSE; + } +} + +VOID InstallAfterChildDispatcher(VOID) +{ + EFI_STATUS Status; + EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *PowerButton; + EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT DispatchContext = {PowerButtonEntry}; + EFI_HANDLE hPowerButton; + + Status = pBS->LocateProtocol( + &gEfiSmmPowerButtonDispatchProtocolGuid, + NULL, + &PowerButton); + if (!EFI_ERROR(Status)) + { + Status = PowerButton->Register( + PowerButton, + PowerButtonActivated, + &DispatchContext, + &hPowerButton); + ASSERT_EFI_ERROR(Status); + } +} +#endif + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RegisterHandler +// +// Description: This function registers SMI handler and returns registered +// handle +// +// Input: Type - Type of SMI handler +// Function - Pointer to callback function +// *Context - Pointer to callback context +// ContextSize - Callback context size +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS RegisterHandler ( + IN EFI_SMM_SMI Type, + IN VOID *Function, + IN VOID *Context, + IN UINTN ContextSize, + OUT EFI_HANDLE *Handle ) +{ + EFI_STATUS Status; + HANDLER_LINK *HandlerLink; + Status = SmmHandler[Type].HandlerProtocol.VerifyContext( Context ); + if(EFI_ERROR(Status)) return Status; + + Status = pSmst->SmmAllocatePool( 0, + sizeof(HANDLER_LINK) + ContextSize - 1, + &HandlerLink ); + if(EFI_ERROR(Status)) return Status; + + HandlerLink->Callback = Function; + HandlerLink->Signature = SMI_HANDLER_SIGNATURE; + MemCpy( HandlerLink->Context, Context, ContextSize ); + + DListAdd(&(SmmHandler[Type].RegisteredCallbacks), (DLINK *)HandlerLink); + SmmHandler[Type].HandlerProtocol.AddHandler( HandlerLink->Context ); + *Handle = HandlerLink; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: FindHandler +// +// Description: This function find the handle in the Type of SMI hander list. +// +// Input: Type - Type of SMI handler +// Handle - Handle of found handler +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS FindHandler( + IN EFI_SMM_SMI Type, + IN EFI_HANDLE Handle) +{ + HANDLER_LINK *HandlerLink = (HANDLER_LINK *)Handle; + HANDLER_LINK *NodeLink = NULL; + + if (HandlerLink->Signature != SMI_HANDLER_SIGNATURE) + return EFI_INVALID_PARAMETER; + + if (SmmHandler[Type].RegisteredCallbacks.Size <= 0) + return EFI_UNSUPPORTED; + + NodeLink = (HANDLER_LINK *)SmmHandler[Type].RegisteredCallbacks.pHead; + for (; NodeLink != NULL; NodeLink = (HANDLER_LINK *)NodeLink->Link.pNext) + { + if (NodeLink == HandlerLink) + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: UnregisterHandler +// +// Description: This function unregisters SMI handler with given handle +// +// Input: Type - Type of SMI handler +// Handle - Handle of registered handler +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS UnregisterHandler ( + IN EFI_SMM_SMI Type, + IN EFI_HANDLE Handle ) +{ + EFI_STATUS Status; + HANDLER_LINK *HandlerLink = (HANDLER_LINK *)Handle; + + Status = FindHandler(Type, Handle); + if (Status == EFI_SUCCESS) + { + SmmHandler[Type].HandlerProtocol.RemoveHandler( HandlerLink->Context ); + DListDelete( &(SmmHandler[Type].RegisteredCallbacks), (DLINK *)HandlerLink ); + pSmst->SmmFreePool( HandlerLink ); + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ChildDispatcher +// +// Description: This function implements main SMI dispatcher loop +// +// Input: SmmImageHandle - SMM Image handle +// *CommunicationBuffer - Pointer to optional communication +// buffer +// *SourceSize - Pointer to size of communication +// buffer +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ChildDispatcher ( + IN EFI_HANDLE SmmImageHandle, + IN OUT VOID *CommunicationBuffer OPTIONAL, + IN OUT UINTN *SourceSize OPTIONAL ) +{ + UINT32 Index; + BOOLEAN HandledSmi; + + do { + HandledSmi = FALSE; + for (Index = EfiSmmStandbyButtonSmi; Index < EfiSmmMaxSmi; Index++) + { + if (SmmHandler[Index].HandlerProtocol.GetContext != NULL && + SmmHandler[Index].HandlerProtocol.GetContext()) + { + SmmHandler[Index].HandlerProtocol.DispatchSmi(); + HandledSmi = TRUE; + } + } + } while (HandledSmi); + + SbSmiWorkaround(); + +#if (INTEL_RC_SMI_DISPATCHER_SUPPORT == 1) && (PI_0_9_CHILD_DISPATCHER_SUPPORT == 1) + AfterChildDispatcher(); +#endif + + return EFI_HANDLER_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: InSmmFunction +// +// Description: This function initializes Child dispatcher in SMM mode +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS InSmmFunction( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + EFI_GUID SbAslBufPtrGuid = SB_ASL_BUFFER_PTR_GUID; + CHAR16 SbAslBufPtrVar[] = SB_ASL_BUFFER_PTR_VARIABLE; + EFI_HANDLE Handle = NULL; + UINTN VarSize = sizeof(UINT32); + UINT32 SbAslBufPtr; + + ClearAllSmi(); + + Status = pRS->GetVariable( SbAslBufPtrVar, + &SbAslBufPtrGuid, + NULL, + &VarSize, + &SbAslBufPtr ); + if (!EFI_ERROR(Status)) gSbAslBufPtr = (SB_ASL_BUFFER *)SbAslBufPtr; + + // Install Protocols + Status = pBS->InstallMultipleProtocolInterfaces( + &Handle, + +#if INTEL_RC_SMI_DISPATCHER_SUPPORT == 0 + &gEfiSmmSwDispatchProtocolGuid, + &gEfiSmmSwDispatchProtocol, + + &gEfiSmmSxDispatchProtocolGuid, + &gEfiSmmSxDispatchProtocol, + + &gEfiSmmPeriodicTimerDispatchProtocolGuid, + &gEfiSmmPeriodicTimerDispatchProtocol, + + &gEfiSmmUsbDispatchProtocolGuid, + &gEfiSmmUsbDispatchProtocol, + + &gEfiSmmGpiDispatchProtocolGuid, + &gEfiSmmGpiDispatchProtocol, +#endif + + &gEfiSmmStandbyButtonDispatchProtocolGuid, + &gEfiSmmStandbyButtonDispatchProtocol, + +#if INTEL_RC_SMI_DISPATCHER_SUPPORT == 0 + &gEfiSmmPowerButtonDispatchProtocolGuid, + &gEfiSmmPowerButonDispatchProtocol, + + &gEfiSmmTcoDispatchProtocolGuid, + &gEfiSmmTcoDispatchProtocol, + + &gEfiSmmIoTrapDispatchProtocolGuid, + &gEfiSmmIoTrapDispatchProtocol, + + &gEfiSmmBiosWriteDispatchProtocolGuid, + &gEfiSmmBiosWriteDispatchProtocol, +#endif + + NULL ); + ASSERT_EFI_ERROR(Status); + + Status = pSmmBase->RegisterCallback( pSmmBase, + ImageHandle, + ChildDispatcher, + TRUE, + FALSE ); + ASSERT_EFI_ERROR(Status); + +#if (INTEL_RC_SMI_DISPATCHER_SUPPORT == 1) && (PI_0_9_CHILD_DISPATCHER_SUPPORT == 1) + InstallAfterChildDispatcher(); +#endif + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmmChildDispatchEntryPoint +// +// Description: SMM Child Dispatcher module entry point +// +// Input: ImageHandle - Image handle +// *SystemTable - Pointer to system table +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmmChildDispatchEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + InitAmiLib( ImageHandle,SystemTable ); + + return InitSmmHandler( ImageHandle, SystemTable, InSmmFunction, NULL ); +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmmChildDispatchProtocol.c b/Chipset/SB/SmmChildDispatchProtocol.c new file mode 100644 index 0000000..b56d925 --- /dev/null +++ b/Chipset/SB/SmmChildDispatchProtocol.c @@ -0,0 +1,961 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatchProtocol.c 2 4/25/12 9:35a Victortu $ +// +// $Revision: 2 $ +// +// $Date: 4/25/12 9:35a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatchProtocol.c $ +// +// 2 4/25/12 9:35a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// 1 2/08/12 8:27a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatchProtocol.c +// +// Description: This file contains SMM Child dispatcher Protocols +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Token.h> +#include <AmiDxeLib.h> +#include "SmmChildDispatch.h" +#include "SmmChildDispatchProtocol.h" + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +#if INTEL_RC_SMI_DISPATCHER_SUPPORT == 0 +SMM_CHILD_DISPATCHER SmmHandler[] = { + // SwSmmHandler + EfiSmmSwSmi, + { SmmSwAddHandler, + SmmSwRemoveHandler, + SmmSwVerifyContext, + SmmSwGetContext, + SmmSwDispatchSmi }, + { 0, NULL, NULL }, + + // SxSmmHandler + EfiSmmSxSmi, + { SmmSxAddHandler, + SmmSxRemoveHandler, + SmmSxVerifyContext, + SmmSxGetContext, + SmmSxDispatchSmi }, + { 0, NULL, NULL }, + + // PeriodicTimerSmmHandler + EfiSmmPeriodicTimerSmi, + { SmmTimerAddHandler, + SmmTimerRemoveHandler, + SmmTimerVerifyContext, + SmmTimerGetContext, + SmmTimerDispatchSmi }, + { 0, NULL, NULL }, + + // UsbSmmHandler + EfiSmmUsbSmi, + { SmmUsbAddHandler, + SmmUsbRemoveHandler, + SmmUsbVerifyContext, + SmmUsbGetContext, + SmmUsbDispatchSmi }, + { 0, NULL, NULL }, + + // GpiSmmHandler + EfiSmmGpiSmi, + { SmmGpiAddHandler, + SmmGpiRemoveHandler, + SmmGpiVerifyContext, + SmmGpiGetContext, + SmmGpiDispatchSmi }, + { 0, NULL, NULL }, + + // SButtonSmmHandler + EfiSmmStandbyButtonSmi, + { SmmSButtonAddHandler, + SmmSButtonRemoveHandler, + SmmSButtonVerifyContext, + SmmSButtonGetContext, + SmmSButtonDispatchSmi }, + { 0, NULL, NULL }, + + // PButtonSmmHandler + EfiSmmPowerButtonSmi, + { SmmPButtonAddHandler, + SmmPButtonRemoveHandler, + SmmPButtonVerifyContext, + SmmPButtonGetContext, + SmmPButtonDispatchSmi }, + { 0, NULL, NULL }, + + // TcoSmmHandler + EfiSmmTcoSmi, + { SmmTcoAddHandler, + SmmTcoRemoveHandler, + SmmTcoVerifyContext, + SmmTcoGetContext, + SmmTcoDispatchSmi }, + { 0, NULL, NULL }, + + // IoTrapSmmHandler + EfiSmmIoTrapSmi, + { SmmIoTrapAddHandler, + SmmIoTrapRemoveHandler, + SmmIoTrapVerifyContext, + SmmIoTrapGetContext, + SmmIoTrapDispatchSmi }, + { 0, NULL, NULL }, + +//********************** PUT ADDITIONAL HANDLERS HERE *********************** +//********************** PUT ADDITIONAL HANDLERS HERE *********************** +//********************** PUT ADDITIONAL HANDLERS HERE *********************** + + // Terminator record + EfiSmmMaxSmi, + { NULL, NULL, NULL, NULL, NULL }, + { 0, NULL, NULL } +}; +#else +SMM_CHILD_DISPATCHER SmmHandler[] = { + // SwSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + + // SxSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + + // PeriodicTimerSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + + // UsbSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + + // GpiSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + + // SButtonSmmHandler + EfiSmmStandbyButtonSmi, + { SmmSButtonAddHandler, + SmmSButtonRemoveHandler, + SmmSButtonVerifyContext, + SmmSButtonGetContext, + SmmSButtonDispatchSmi }, + { 0, NULL, NULL }, + + // PButtonSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + + // TcoSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + + // IoTrapSmmHandler + (EfiSmmMaxSmi + 1), + { NULL, + NULL, + NULL, + NULL, + NULL }, + { 0, NULL, NULL }, + +//********************** PUT ADDITIONAL HANDLERS HERE *********************** +//********************** PUT ADDITIONAL HANDLERS HERE *********************** +//********************** PUT ADDITIONAL HANDLERS HERE *********************** + + // Terminator record + EfiSmmMaxSmi, + { NULL, NULL, NULL, NULL, NULL }, + { 0, NULL, NULL } +}; +#endif + +EFI_SMM_SW_DISPATCH_PROTOCOL gEfiSmmSwDispatchProtocol = \ + { EfiSmmSwRegister, \ + EfiSmmSwUnregister, \ + MAX_SW_SMI_INPUT_VALUE }; + +EFI_SMM_SX_DISPATCH_PROTOCOL gEfiSmmSxDispatchProtocol = \ + { EfiSmmSxRegister, EfiSmmSxUnregister }; + +EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL gEfiSmmPeriodicTimerDispatchProtocol= + { EfiSmmTimerRegister, \ + EfiSmmTimerUnregister, \ + EfiSmmTimerGetNextShorterInterval }; + +EFI_SMM_USB_DISPATCH_PROTOCOL gEfiSmmUsbDispatchProtocol = \ + { EfiSmmUsbRegister, EfiSmmUsbUnregister }; + +EFI_SMM_GPI_DISPATCH_PROTOCOL gEfiSmmGpiDispatchProtocol = \ + { EfiSmmGpiRegister, \ + EfiSmmGpiUnregister, \ + SUPPORTED_GPIS }; + +EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL gEfiSmmStandbyButtonDispatchProtocol= + { EfiSmmSButtonRegister, EfiSmmSButtonUnregister }; + +EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL gEfiSmmPowerButonDispatchProtocol = \ + { EfiSmmPButtonRegister, EfiSmmPButtonUnregister }; + +EFI_SMM_TCO_DISPATCH_PROTOCOL gEfiSmmTcoDispatchProtocol = \ + { EfiSmmTcoRegister, EfiSmmTcoUnregister }; + +EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL gEfiSmmIoTrapDispatchProtocol = \ + { EfiSmmIoTrapRegister, EfiSmmIoTrapUnregister }; + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +extern UINT64 gSupportedIntervals[]; + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSwRegister +// +// Description: EFI_SMM_SW_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_SW_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSwRegister ( + IN EFI_SMM_SW_DISPATCH_PROTOCOL *This, + IN EFI_SMM_SW_DISPATCH Function, + IN EFI_SMM_SW_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +//#### Use Intel RC return RegisterHandler( EfiSmmSwSmi, \ +//#### Use Intel RC Function, \ +//#### Use Intel RC Context, \ +//#### Use Intel RC sizeof(EFI_SMM_SW_DISPATCH_CONTEXT), \ +//#### Use Intel RC Handle ); + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSwUnregister +// +// Description: EFI_SMM_SW_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_SW_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSwUnregister ( + IN EFI_SMM_SW_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC return UnregisterHandler( EfiSmmSwSmi, Handle ); + return EFI_NOT_FOUND; +} + +//--------------------------------------------------------------------------- +// Sleep SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSxRegister +// +// Description: EFI_SMM_SX_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_SX_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSxRegister ( + IN EFI_SMM_SX_DISPATCH_PROTOCOL *This, + IN EFI_SMM_SX_DISPATCH Function, + IN EFI_SMM_SX_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +//#### Use Intel RC return RegisterHandler( EfiSmmSxSmi, \ +//#### Use Intel RC Function, \ +//#### Use Intel RC Context, \ +//#### Use Intel RC sizeof(EFI_SMM_SX_DISPATCH_CONTEXT), \ +//#### Use Intel RC Handle ); + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSxUnregister +// +// Description: EFI_SMM_SW_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_SX_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSxUnregister ( + IN EFI_SMM_SX_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC return UnregisterHandler( EfiSmmSxSmi, Handle ); + return EFI_NOT_FOUND; +} + +//--------------------------------------------------------------------------- +// Periodic timer SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTimerRegister +// +// Description: EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTimerRegister ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_SMM_PERIODIC_TIMER_DISPATCH Function, + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +//#### Use Intel RC return RegisterHandler( EfiSmmPeriodicTimerSmi, \ +//#### Use Intel RC Function, \ +//#### Use Intel RC Context, \ +//#### Use Intel RC sizeof(EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT), \ +//#### Use Intel RC Handle ); + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTimerUnregister +// +// Description: EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the +// EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTimerUnregister ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC return UnregisterHandler( EfiSmmPeriodicTimerSmi, Handle ); + return EFI_NOT_FOUND;; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTimerGetNextShorterInterval +// +// Description: EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL +// GetNextShorterInterval function. +// +// Input: *This - Pointer to the +// EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL +// **SmiTickInterval - Pointer to store pointer to next interval +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTimerGetNextShorterInterval ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN OUT UINT64 **SmiTickInterval ) +{ + UINT64 *Result = *SmiTickInterval; + + if (Result == NULL) { + Result = gSupportedIntervals; + } else { + Result++; + } + *SmiTickInterval = (*Result == 0) ? NULL : Result; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmGetPeriodicTimerSourcesStatus +// +// Description: Gets Periodic Timer sources status. +// +// Input: None +// +// Output: BOOLEAN +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +BOOLEAN EfiSmmGetPeriodicTimerSourcesStatus (VOID) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmPeriodicTimerSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *TimerContext; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC TimerContext = \ +//#### Use Intel RC (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC if (TimerContext->TimerEnabled) return TRUE; + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + return FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmPeriodicTimerEnable +// +// Description: Enables Periodic Timer SMI. +// +// Input: *This - Pointer to the +// EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL +// Handle - Handle to enable +// +// Output: EFI_STATUS +// EFI_NOT_FOUND - The specific handle is not found. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmPeriodicTimerEnable ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmPeriodicTimerSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *TimerContext; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC if (Handler == Handle) { +//#### Use Intel RC TimerContext = \ +//#### Use Intel RC (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC TimerContext->TimerEnabled = TRUE; +//#### Use Intel RC TimerSmiClear(); +//#### Use Intel RC TimerSmiEnable(); +//#### Use Intel RC return EFI_SUCCESS; +//#### Use Intel RC } + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmPeriodicTimerDisable +// +// Description: Disables Periodic Timer SMI. +// +// Input: *This - Pointer to the +// EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL +// Handle - Handle to disable +// +// Output: EFI_STATUS +// EFI_NOT_FOUND - The specific handle is not found. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmPeriodicTimerDisable ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC HANDLER_LINK *Handler = (HANDLER_LINK *)\ +//#### Use Intel RC SmmHandler[EfiSmmPeriodicTimerSmi].RegisteredCallbacks.pHead; +//#### Use Intel RC EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *TimerContext; + +//#### Use Intel RC while (Handler != NULL) { +//#### Use Intel RC if (Handler == Handle) { +//#### Use Intel RC TimerContext = \ +//#### Use Intel RC (EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *)Handler->Context; +//#### Use Intel RC TimerContext->TimerEnabled = FALSE; +//#### Use Intel RC if (!EfiSmmGetPeriodicTimerSourcesStatus()) +//#### Use Intel RC TimerSmiDisable(); +//#### Use Intel RC return EFI_SUCCESS; +//#### Use Intel RC } + +//#### Use Intel RC Handler = (HANDLER_LINK *)Handler->Link.pNext; +//#### Use Intel RC } + return EFI_NOT_FOUND; +} + +//--------------------------------------------------------------------------- +// USB SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmUsbRegister +// +// Description: EFI_SMM_USB_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_USB_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmUsbRegister ( + IN EFI_SMM_USB_DISPATCH_PROTOCOL *This, + IN EFI_SMM_USB_DISPATCH Function, + IN EFI_SMM_USB_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +//#### Use Intel RC return RegisterHandler( EfiSmmUsbSmi, \ +//#### Use Intel RC Function, \ +//#### Use Intel RC Context, \ +//#### Use Intel RC sizeof(EFI_SMM_USB_DISPATCH_CONTEXT), \ +//#### Use Intel RC Handle ); + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmUsbUnregister +// +// Description: EFI_SMM_USB_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_USB_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmUsbUnregister ( + IN EFI_SMM_USB_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC return UnregisterHandler( EfiSmmUsbSmi, Handle ); + return EFI_SUCCESS; +} + +//--------------------------------------------------------------------------- +// GPI SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmGpiRegister +// +// Description: EFI_SMM_GPI_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_GPI_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmGpiRegister ( + IN EFI_SMM_GPI_DISPATCH_PROTOCOL *This, + IN EFI_SMM_GPI_DISPATCH Function, + IN EFI_SMM_GPI_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +//#### Use Intel RC return RegisterHandler( EfiSmmGpiSmi, \ +//#### Use Intel RC Function, \ +//#### Use Intel RC Context, \ +//#### Use Intel RC sizeof(EFI_SMM_GPI_DISPATCH_CONTEXT), \ +//#### Use Intel RC Handle ); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmGpiUnregister +// +// Description: EFI_SMM_GPI_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_GPI_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmGpiUnregister ( + IN EFI_SMM_GPI_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC return UnregisterHandler( EfiSmmGpiSmi, Handle ); + return EFI_SUCCESS; +} + +//--------------------------------------------------------------------------- +// Standby button SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSButtonRegister +// +// Description: EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSButtonRegister ( + IN EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_SMM_STANDBY_BUTTON_DISPATCH Function, + IN EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ + return RegisterHandler( EfiSmmStandbyButtonSmi, \ + Function, \ + Context, \ + sizeof(EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT), \ + Handle ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmSButtonUnregister +// +// Description: EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the +// EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmSButtonUnregister ( + IN EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ + return UnregisterHandler( EfiSmmStandbyButtonSmi, Handle ); +} + +//--------------------------------------------------------------------------- +// Power button SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmPButtonRegister +// +// Description: EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmPButtonRegister ( + IN EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_SMM_POWER_BUTTON_DISPATCH Function, + IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +#if INTEL_RC_SMI_DISPATCHER_SUPPORT == 0 + return RegisterHandler( EfiSmmPowerButtonSmi, + Function, + Context, + sizeof(EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT), + Handle ); +#else + return EFI_UNSUPPORTED; +#endif +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmPButtonUnregister +// +// Description: EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmPButtonUnregister ( + IN EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +#if INTEL_RC_SMI_DISPATCHER_SUPPORT == 0 + return UnregisterHandler( EfiSmmPowerButtonSmi, Handle ); +#else + return EFI_UNSUPPORTED; +#endif +} + +//--------------------------------------------------------------------------- +// TCO SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTcoRegister +// +// Description: EFI_SMM_TCO_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_TCO_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTcoRegister ( + IN EFI_SMM_TCO_DISPATCH_PROTOCOL *This, + IN EFI_SMM_TCO_DISPATCH Function, + IN EFI_SMM_TCO_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +//#### Use Intel RC return RegisterHandler( EfiSmmTcoSmi, \ +//#### Use Intel RC Function, \ +//#### Use Intel RC Context, \ +//#### Use Intel RC sizeof(EFI_SMM_TCO_DISPATCH_CONTEXT), \ +//#### Use Intel RC Handle ); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmTcoUnregister +// +// Description: EFI_SMM_TCO_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_TCO_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmTcoUnregister ( + IN EFI_SMM_TCO_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC return UnregisterHandler( EfiSmmTcoSmi, Handle ); + return EFI_SUCCESS; +} + +//--------------------------------------------------------------------------- +// I/O Trap SMI Handler functions +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmIoTrapRegister +// +// Description: EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL Register function. +// +// Input: *This - Pointer to EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL +// Function - Pointer to callback function +// *Context - Pointer to callback context +// *Handle - Pointer to store registered handle +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmIoTrapRegister ( + IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This, + IN EFI_SMM_IO_TRAP_DISPATCH Function, + IN EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle ) +{ +//#### Use Intel RC return RegisterHandler( EfiSmmIoTrapSmi, \ +//#### Use Intel RC Function, \ +//#### Use Intel RC Context, \ +//#### Use Intel RC sizeof(EFI_SMM_IO_TRAP_DISPATCH_CONTEXT), \ +//#### Use Intel RC Handle ); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: EfiSmmIoTrapUnregister +// +// Description: EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL Unregister function. +// +// Input: *This - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL +// Handle - Handle to unregister +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS EfiSmmIoTrapUnregister ( + IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle ) +{ +//#### Use Intel RC return UnregisterHandler( EfiSmmIoTrapSmi, Handle ); + return EFI_SUCCESS; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmmChildDispatchProtocol.h b/Chipset/SB/SmmChildDispatchProtocol.h new file mode 100644 index 0000000..39bca9a --- /dev/null +++ b/Chipset/SB/SmmChildDispatchProtocol.h @@ -0,0 +1,279 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatchProtocol.h 1 2/08/12 8:27a Yurenlai $ +// +// $Revision: 1 $ +// +// $Date: 2/08/12 8:27a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatchProtocol.h $ +// +// 1 2/08/12 8:27a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatchProtocol.h +// +// Description: SMM Child dispatcher protocols functions definition +// +//<AMI_FHDR_END> +//************************************************************************* + +#ifndef __SMM_CHILD_DISPATCH_PROTOCOL__H__ +#define __SMM_CHILD_DISPATCH_PROTOCOL__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <Protocol\SmmSwDispatch.h> +#include <Protocol\SmmSxDispatch.h> +#include <Protocol\SmmPeriodicTimerDispatch.h> +#include <Protocol\SmmUsbDispatch.h> +#include <Protocol\SmmGpiDispatch.h> +#include <Protocol\SmmStandbyButtonDispatch.h> +#include <Protocol\SmmPowerButtonDispatch.h> +#include <Protocol\SmmTcoDispatch.h> +#include <Protocol\SmmIoTrapDispatch.h> +#if defined PI_SPECIFICATION_VERSION && (PI_SPECIFICATION_VERSION >= 0x0001000A) +#include <Protocol\SmmIoTrapDispatch2.h> +#else +#include <Protocol\SmmPchIoTrapDispatch2.h> +#endif + +#include <Protocol\SmmBiosWriteDispatch.h> +#include <Token.h> +//-------------- Generic register/unregister handler functions -------------- + +EFI_STATUS RegisterHandler( + IN EFI_SMM_SMI Type, + IN VOID *Function, + IN VOID *Context, + IN UINTN ContextSize, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS UnregisterHandler ( + IN EFI_SMM_SMI Type, + IN EFI_HANDLE Handle +); + +//------------------------ Sw SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmSwRegister ( + IN EFI_SMM_SW_DISPATCH_PROTOCOL *This, + IN EFI_SMM_SW_DISPATCH Function, + IN EFI_SMM_SW_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmSwUnregister ( + IN EFI_SMM_SW_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------------ Sx SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmSxRegister ( + IN EFI_SMM_SX_DISPATCH_PROTOCOL *This, + IN EFI_SMM_SX_DISPATCH Function, + IN EFI_SMM_SX_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmSxUnregister ( + IN EFI_SMM_SX_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------ Periodic timer SMI protocol functions ------------------ + +EFI_STATUS EfiSmmTimerRegister ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_SMM_PERIODIC_TIMER_DISPATCH Function, + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmTimerUnregister ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +EFI_STATUS EfiSmmTimerGetNextShorterInterval ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN OUT UINT64 **SmiTickInterval +); + +EFI_STATUS EfiSmmPeriodicTimerEnable ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +EFI_STATUS EfiSmmPeriodicTimerDisable ( + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//----------------------- Usb SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmUsbRegister ( + IN EFI_SMM_USB_DISPATCH_PROTOCOL *This, + IN EFI_SMM_USB_DISPATCH Function, + IN EFI_SMM_USB_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmUsbUnregister ( + IN EFI_SMM_USB_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//----------------------- Gpi SMI protocol functions ------------------------ + +EFI_STATUS EfiSmmGpiRegister ( + IN EFI_SMM_GPI_DISPATCH_PROTOCOL *This, + IN EFI_SMM_GPI_DISPATCH Function, + IN EFI_SMM_GPI_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmGpiUnregister ( + IN EFI_SMM_GPI_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------ Standby button SMI protocol functions ------------------ + +EFI_STATUS EfiSmmSButtonRegister ( + IN EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_SMM_STANDBY_BUTTON_DISPATCH Function, + IN EFI_SMM_STANDBY_BUTTON_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmSButtonUnregister ( + IN EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------- Power button SMI protocol functions ------------------- + +EFI_STATUS EfiSmmPButtonRegister ( + IN EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_SMM_POWER_BUTTON_DISPATCH Function, + IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmPButtonUnregister ( + IN EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//----------- Total Cost of Ownership (TCO) SMI protocol functions ---------- + +EFI_STATUS EfiSmmTcoRegister ( + IN EFI_SMM_TCO_DISPATCH_PROTOCOL *This, + IN EFI_SMM_TCO_DISPATCH Function, + IN EFI_SMM_TCO_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmTcoUnregister ( + IN EFI_SMM_TCO_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//--------------------- I/O Trap SMI protocol functions --------------------- + +EFI_STATUS EfiSmmIoTrapRegister ( + IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This, + IN EFI_SMM_IO_TRAP_DISPATCH Function, + IN EFI_SMM_IO_TRAP_DISPATCH_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmIoTrapUnregister ( + IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +//------------------- I/O Trap #2 SMI protocol functions ------------------- + +#if defined PI_SPECIFICATION_VERSION && (PI_SPECIFICATION_VERSION >= 0x0001000A) +EFI_STATUS EfiSmmIoTrap2Register ( + IN CONST EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_HANDLER_ENTRY_POINT2 Function, + IN EFI_SMM_IO_TRAP_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); +#else +EFI_STATUS EfiSmmIoTrap2Register ( + IN EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_SMM_IO_TRAP_DISPATCH2 Function, + IN EFI_SMM_IO_TRAP_REGISTER_CONTEXT *Context, + OUT EFI_HANDLE *Handle +); +#endif + +#if defined PI_SPECIFICATION_VERSION && (PI_SPECIFICATION_VERSION >= 0x0001000A) +EFI_STATUS EfiSmmIoTrap2Unregister ( + IN CONST EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); +#else +EFI_STATUS EfiSmmIoTrap2Unregister ( + IN EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *This, + IN EFI_HANDLE Handle +); +#endif + +//-------------------- BIOS Write SMI protocol functions -------------------- + +EFI_STATUS EfiSmmBiosWriteRegister ( + IN EFI_SMM_BIOS_WRITE_DISPATCH_PROTOCOL *This, + IN EFI_SMM_BIOS_WRITE_DISPATCH Function, + OUT EFI_HANDLE *Handle +); + +EFI_STATUS EfiSmmBiosWriteUnregister ( + IN EFI_SMM_BIOS_WRITE_DISPATCH_PROTOCOL *This, + IN EFI_HANDLE Handle +); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmmChildDispatcher.cif b/Chipset/SB/SmmChildDispatcher.cif new file mode 100644 index 0000000..9649c65 --- /dev/null +++ b/Chipset/SB/SmmChildDispatcher.cif @@ -0,0 +1,16 @@ +<component> + name = "SmmChildDispatcher" + category = ModulePart + LocalRoot = "Chipset\SB" + RefName = "SmmChildDispatcher" +[files] +"SmmChildDispatcher.mak" +"SmmChildDispatcher.sdl" +"SmmChildDispatcher.dxs" +"SmiHandlerGeneric.c" +"SmiHandlerPorting.c" +"SmmChildDispatch.h" +"SmmChildDispatchMain.c" +"SmmChildDispatchProtocol.c" +"SmmChildDispatchProtocol.h" +<endComponent> diff --git a/Chipset/SB/SmmChildDispatcher.dxs b/Chipset/SB/SmmChildDispatcher.dxs new file mode 100644 index 0000000..aa66571 --- /dev/null +++ b/Chipset/SB/SmmChildDispatcher.dxs @@ -0,0 +1,76 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatcher.dxs 2 4/25/12 9:35a Victortu $ +// +// $Revision: 2 $ +// +// $Date: 4/25/12 9:35a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatcher.dxs $ +// +// 2 4/25/12 9:35a Victortu +// [TAG] None +// [Category] Improvement +// [Description] Reprogram SMM ChildDispatcher drivers. +// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c; +// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak; +// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c; +// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs; +// PchSmiDispatcher.sdl +// +// 1 2/08/12 8:27a Yurenlai +// Intel Lynx Point/SB eChipset initially releases. +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmmChildDispatcher.DXS +// +// Description: This file contains the dependency expression for the SMM +// Child Dispatcher driver +// +//<AMI_FHDR_END> +//************************************************************************* + +#include <token.h> + +#include <Protocol\SmmBase.h> +#if INTEL_RC_SMI_DISPATCHER_SUPPORT +#include <Protocol\SmmSwDispatch.h> +#endif + +DEPENDENCY_START +#if INTEL_RC_SMI_DISPATCHER_SUPPORT + EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND +#endif + EFI_SMM_BASE_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* diff --git a/Chipset/SB/SmmChildDispatcher.mak b/Chipset/SB/SmmChildDispatcher.mak new file mode 100644 index 0000000..5825886 --- /dev/null +++ b/Chipset/SB/SmmChildDispatcher.mak @@ -0,0 +1,78 @@ +# MAK file for the ModulePart:SmmChildDispatcher +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatcher.mak 1 2/08/12 8:27a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:27a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatcher.mak $ +# +# 1 2/08/12 8:27a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +#<AMI_FHDR_START> +# +# Name: SmmChildDispatcher.mak +# +# Description: Make file for the SMM Child Dispatcher driver. +# +#<AMI_FHDR_END> +#************************************************************************* +!IFNDEF BACKWARD_COMPATIBLE_MODE +BACKWARD_COMPATIBLE_MODE = 1 +!ENDIF + +all : SmmChildDispatcher + +SmmChildDispatcher : $(BUILD_DIR)\SmmChildDispatcher.mak SmmChildDispatcherBin + +$(BUILD_DIR)\SmmChildDispatcher.mak : $(SMM_CHILD_DISP_DIR)\SmmChildDispatcher.cif $(SMM_CHILD_DISP_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SMM_CHILD_DISP_DIR)\SmmChildDispatcher.cif $(CIF2MAK_DEFAULTS) + +SmmChildDispatcherBin : $(AMICSPLib) $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SmmChildDispatcher.mak all\ + "CFLAGS=$(CFLAGS) /I$(SB_BOARD_DIR)"\ + GUID=753630C9-FAE5-47a9-BBBF-88D621CD7282\ + ENTRY_POINT=SmmChildDispatchEntryPoint\ +!IF $(BACKWARD_COMPATIBLE_MODE) + TYPE=BS_DRIVER \ + DEPEX1=$(SMM_CHILD_DISP_DIR)\SmmChildDispatcher.DXS \ + DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ +!ELSE + TYPE=RT_DRIVER \ + DEPEX1=$(SMM_CHILD_DISP_DIR)\SmmChildDispatcher.DXS \ +!ENDIF + COMPRESS=1 + +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/Chipset/SB/SmmChildDispatcher.sdl b/Chipset/SB/SmmChildDispatcher.sdl new file mode 100644 index 0000000..6630274 --- /dev/null +++ b/Chipset/SB/SmmChildDispatcher.sdl @@ -0,0 +1,141 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatcher.sdl 1 2/08/12 8:27a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:27a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher/SmmChildDispatcher.sdl $ +# +# 1 2/08/12 8:27a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "SmmChildDispatcher_SUPPORT" + Value = "1" + Help = "Main switch to enable SmmChildDispatcher support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "EXTENDED_SMI" + Value = "0xF0" + Help = "SMI number for DWORD SMI value handlers" + TokenType = Integer + TargetH = Yes + Range = "00-FF" +End + +TOKEN + Name = "MAX_SW_SMI_INPUT_VALUE" + Value = "0xEF" + Help = "This is the maximum value supported by the SW SMI child dispatcher" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "SUPPORTED_GPIS" + Value = "0xFFFF" + Help = "This is a supported GPI SMI mask, 1 = supported, 32 bits maximum" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "GPI_DISPATCH_BY_BITMAP" + Value = "0" + Help = "ON = The registered parameter of SMM GPI dispatcher is using bitmapped.\OFF = The registered parameter of SMM GPI disatcher is using index based" + TokenType = Boolean + TargetH = Yes + Lock = Yes +End + +TOKEN + Name = "SUPPORTED_TCOS" + Value = "0x168F" + Help = "This is a supported TCO SMI status mask, 1 = supported, 32 bits maximum\This value should not include BIOSWE bit, because it had been supported by another SMM dispatch" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "MAX_SUPPORTED_IOTRAP_REGS" + Value = "0x04" + Help = "This is the maximum register number in SB can be used for I/O Trap" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "MAX_SUPPORTED_IOTRAP_LENGTH" + Value = "0x100" + Help = "This is the maximum length (BYTE) supported by I/O Trap register" + TokenType = Integer + TargetH = Yes +End + +TOKEN + Name = "ACPI_SLEEP_IN_SMM" + Value = "1" + Help = "If ON = The function of ACPI Sleep will enable in SMM by BIOS.\If OFF = The function of ACPI Sleep will enable by OS." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "SWSMI_TIMER_INSTEAD" + Value = "1" + Help = "ON = Select the SWSMI Timer for SMI Periodic Timer event.\OFF = Select the Periodic Timer for SMI Periodic Timer event." + TokenType = Boolean + TargetH = Yes +End + +PATH + Name = "SMM_CHILD_DISP_DIR" +End + +MODULE + Help = "Includes SmmChildDispatcher.mak to Project" + File = "SmmChildDispatcher.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SmmChildDispatcher.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + diff --git a/Chipset/SB/sb.cif b/Chipset/SB/sb.cif new file mode 100644 index 0000000..3bc20aa --- /dev/null +++ b/Chipset/SB/sb.cif @@ -0,0 +1,12 @@ +<component> + name = "Intel PCH" + category = eChipset + LocalRoot = "Chipset\SB\" + RefName = "Intel Pch" +[files] +"ReleaseNotes.chm" +[parts] +"Intel Pch SB Board" +"Intel Pch SB Chipset" +"Intel Pch SB Refcode" +<endComponent> diff --git a/Chipset/SB/sbCSP.CIF b/Chipset/SB/sbCSP.CIF new file mode 100644 index 0000000..0031bf6 --- /dev/null +++ b/Chipset/SB/sbCSP.CIF @@ -0,0 +1,31 @@ +<component> + name = "Intel Pch SB Chipset" + category = ModulePart + LocalRoot = "Chipset\SB\" + RefName = "Intel Pch SB Chipset" +[files] +"SBGeneric.c" +"SBPEI.c" +"SBDxe.c" +"SBCspLib.h" +"RTC.h" +"SBRun.c" +"SBSmm.c" +"RRIORDMA.asl" +"GbE_OR.BIN" +"SB.ASL" +"IDE.ASL" +"SATA.ASL" +"SataOrom125.bin" +[parts] +"SB PPI" +"SB Protocols" +"SmBus" +"SmmChildDispatcher" +"SmmChildDispatcher2" +"AcpiModeEnable" +"SleepSmi" +"SBSMI" +"PchWrap" +"SataDriver" +<endComponent> diff --git a/Chipset/SB/usb/usbsb.c b/Chipset/SB/usb/usbsb.c new file mode 100644 index 0000000..2d0a21f --- /dev/null +++ b/Chipset/SB/usb/usbsb.c @@ -0,0 +1,891 @@ +//**************************************************************************** +//**************************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone (770)-246-8600 ** +//** ** +//**************************************************************************** +//**************************************************************************** + +//**************************************************************************** +// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/chipset/sb/usb/usbsb.c 2 2/10/17 1:48a Chienhsieh $ +// +// $Revision: 2 $ +// +// $Date: 2/10/17 1:48a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/chipset/sb/usb/usbsb.c $ +// +// 2 2/10/17 1:48a Chienhsieh +// [TAG] EIP316430 +// [Description] [Haswell Series] Modules Update/Function +// implementation/Bug fixed on 'SharkBay DT' CRB049 project label. +// Sync with 4.6.5.1_USB_08.10.36 +// +// 1 8/08/16 4:02a Chienhsieh +// Sync with 4.6.3_USB_08.10.35. +// +// 29 6/11/14 2:26a Littleyan +// Update USBSB Template to 4.6.3_USB_08.10.30. +// +// 28 1/17/14 4:20a Littleyan +// Update USBSB Template to 4.6.3_USB_08.10.29. +// +// 27 12/10/13 6:04a Littleyan +// Add WPT Sku +// +// 26 5/13/13 12:17a Wesleychen +// Update address of GPE0_STS and GPE0_EN for Intel PCH LPT-LP. +// +// 25 4/02/13 5:31a Wesleychen +// Update USBSB Template to 4.6.3_USB_08.10.26. +// +// 23 1/22/13 5:00a Wesleychen +// Fix USB keyboard cannot work in DOS if LPT xHCI Mode = Enabled. +// +// 22 1/14/13 10:05p Wesleychen +// Improve IsAllEhciDisabled(). +// +// 21 1/11/13 5:47a Wesleychen +// Fixed coding error. +// +// 19 1/06/13 9:55p Wesleychen +// Update for Intel LPT RC 0.8.1. Turen on the SWSMI Timer when all EHCI +// controllers are disabled. +// +// 18 12/20/12 8:11a Wesleychen +// [TAG] EIP108635 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Lynx Point USB ports have no function in DOS when +// all EHCIs are disabled and only xHCI exists. +// [RootCause] Legacy keyboard support is rely on EHCI H/W SMI to +// trigger it, that is why the USB KB couldn't working +// under DOS if you issue a warm boot from Windows 8 or +// set "xHCI Mode" = "Enabled". +// [Solution] Use SW Timer SMI to instead of EHCI H/W SMI. +// [Files] usbsb.c +// +// 15 10/31/12 2:11a Wesleychen +// Update for Intel PCH Lynx Point-LP support. +// +// 13 6/05/12 2:13a Wesleychen +// Update USBSB Template to 4.6.3_USB_08.10.22. +// +// 30 5/22/12 10:02a Ryanchou +// [TAG] EIP90154 +// [Category] Improvement +// [Description] Remove the USBSB_EnableSmmPeriodicSmi and +// USBSB_DisableSmmPeriodicSmi hooks. +// [Files] amidef.h, amiusb.c, usb.c, usbsb.c +// +// 29 5/04/12 6:36a Ryanchou +// [TAG] EIP82875 +// [Category] Improvement +// [Description] Support start/stop individual USB host to avoid +// reconnect issues. +// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c, +// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h, +// usbbus.c, usbmisc.c +// +// 28 5/03/12 6:31a Roberthsu +// [TAG] EIP84455 +// [Category] Improvement +// [Description] Implement usb hid device gencric. +// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc +// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c +// ,usbsrc.sdl +// +// 27 1/16/12 6:02a Ryanchou +// [TAG] EIP81132 +// [Description] Add core version check for EIP80609 solution. +// [Files] amiusb.c, usbrt.mak, usbsb.c +// +// 26 1/14/12 4:11a Ryanchou +// [TAG] EIP80609 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] If to enable debug mode and set launch CSM is "Never" in +// setup, system will hang at 0xB1 +// [RootCause] The pointer AmiUsb is invalid if CSM is not launched, +// that may cause CPU exception. +// [Solution] Added USB smm protocol, and use SmmLocateProtocol to get +// the pointer. +// [Files] amiusb.c, AmiUsbController.h, usbrt.mak, usbsb.c +// +// 25 11/08/11 2:02a Ryanchou +// [TAG] EIP63188 +// [Category] Improvement +// [Description] External USB controller support. +// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c, +// usbdef.h, usbmisc.c, usbsb.c, xhci.c +// +// 24 10/17/11 2:25a Ryanchou +// [TAG] EIP69136 +// [Category] Improvement +// [Description] Remove the dependency of EBDA in USB module for CSM +// disabling. +// [Files] amiusb.c, uhcd.c, usbport.c, usbsb.c +// +// 23 8/08/11 7:03a Ryanchou +// [TAG] EIP54018 +// [Category] New Feature +// [Description] Added USB S5 wake up support. +// [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h, +// usbsb.c xhci.c +// +// 22 7/15/11 6:33a Ryanchou +// [TAG] EIP38434 +// [Category] New Feature +// [Description] Added USB HID report protocol support. +// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c, +// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, +// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c, +// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c +// +// 21 6/22/11 4:48a Ryanchou +// [TAG] EIP61556 +// [Category] Improvement +// [Description] Add both bitmapped and index based GPI number for +// better compatibility. +// [Files] usbsb.c +// +// 20 4/06/11 3:29a Ryanchou +// [TAG] EIP55275 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] EBDA:108 conflict +// [RootCause] The EIP48064 save EFI_USB_PROTOCOL pointer in EBDA:108, +// but Keymon filter driver used the same location. +// [Solution] Use the EBDA:32 to save EFI_USB_PROTOCOL pointer and add a +// signature in EFI_USB_PROTOCOL. +// [Files] amidef.h, AmiUsbController.h, uhcd.c, usbsb.c +// +// 19 3/29/11 10:23a Ryanchou +// [TAG] EIP53518 +// [Category] Improvement +// [Description] Added chipset xHCI chip support. +// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c, +// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c +// +// 18 12/29/10 1:51a Ryanchou +// [TAG] EIP50358 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] System hang at "Starting Windows". +// [RootCause] The EIP48064 modification save EFI_USB_PROTOCOL pointer +// to EBDA, if disable USB Support, the pointer will be 0. +// [Solution] Check the pointer in EBDA before use it. +// [Files] usbsb.c +// +// 17 12/29/10 1:29a Ryanchou +// [TAG] EIP50943 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] USB Keyboard abnormal +// [RootCause] We only check the aUSBKBDeviceTable entry 0, if the value +// is 0, we will not send the characters to KBC. +// [Solution] The solution is search all the aUSBKBDeviceTable. +// [Files] usbsb.c +// +// 16 11/22/10 8:48a Ryanchou +// [TAG] EIP48064 +// [Category] Improvement +// [Description] The SB template implemented elink +// AcpiEnableCallbackList, the XHCI/EHCI hand off function should be +// invoked via the elink AcpiEnableCallbackList. +// [Files] amidef.h, amiusb.c, amiusb.dxs, amiusb.h, +// AmiUsbController.h, usb.sdl, usbrt.mak, usbsb.c +// +// 15 11/02/10 12:04a Tonylo +// EIP45564 - System hang when resume from S3. +// +// 13 10/21/10 8:58a Ryanchou +// EIP44570: Added multiple xHCI SMI pin support. +// +// 12 10/07/10 10:12a Ryanchou +// EIP41379: Move the code that install xHCI hardware SMI handler in +// XHCI_Start function. +// +// 11 8/31/10 11:32p Tonylo +// EIP43380 - BIOS build failed with WDK 7600.16385.1. +// +// 10 7/13/10 7:09a Ryanchou +// EIP38356: Implement shutdown USB legacy support in ACPI enable call. +// +// 9 7/13/10 5:32a Ryanchou +// EIP40732: Implement xHCI periodic timer handler to replace the XHCI HW +// SMI functionality. +// +// 8 6/15/10 1:23a Ryanchou +// Implement xHCI USB Legacy Capability. +// +// 7 4/29/10 10:07a Olegi +// +// 6 4/14/10 5:42p Olegi +// Unnecessary code commented out, left for reference only. +// +// 4 1/29/10 4:55p Olegi +// +// 3 11/20/09 6:17p Olegi +// Sample implementation added. +// +// 2 11/18/09 4:25p Olegi +// Copyright message update. +// +// 1 2/19/08 2:32p Olegi +// +//**************************************************************************** +// +//<AMI_FHDR_START> +//----------------------------------------------------------------------------- +// +// Name: USBSB.C +// +// Description: USB South Bridge Porting Hooks +// +//----------------------------------------------------------------------------- +//<AMI_FHDR_END> + +//**************************************************************************** + +#include "Efi.h" +#include "token.h" +#include "amidef.h" +#include "usbdef.h" +#include "amiusb.h" +#include "usbkbd.h" +#include "AmiCspLib.h" +#include <Setup.h> + +#ifndef USB_ACPI_ENABLE_CALLBACK + +#include <Edk\Foundation\Framework\Protocol\SmmPeriodicTimerDispatch\SmmPeriodicTimerDispatch.h> +#include <Protocol\SmmGpiDispatch.h> + +#ifdef USB_ACPI_ENABLE_DISPATCH +#include <Chipset\SB\AcpiModeEnable.h> + +EFI_GUID gEfiAcpiEnDispatchProtocolGuid = EFI_ACPI_EN_DISPATCH_PROTOCOL_GUID; +#endif + +#include <AmiBufferValidationLib.h> +#include <AmiUsbSmmGlobalDataValidationLib.h> + +// Timer service +EFI_GUID gEfiSmmPeriodicTimerDispatchProtocolGuid = EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL_GUID; +EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *gPeriodicTimerDispatch = NULL; +EFI_HANDLE gPeriodicTimerHandle = NULL; +EFI_HANDLE gUsbIntTimerHandle = NULL; + +EFI_STATUS USBPort_PeriodicTimerCallBack ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *DispatchContext + ); + +extern USB_GLOBAL_DATA *gUsbData; +extern BOOLEAN gLockSmiHandler; +extern BOOLEAN gLockHwSmiHandler; + +UINT8 ByteReadIO (UINT16); +VOID ByteWriteIO (UINT16, UINT8); +UINT32 ReadPCIConfig(UINT16, UINT8); + +extern UINT32 DwordReadMem(UINT32, UINT16); +extern void DwordWriteMem(UINT32, UINT16, UINT32); + +#ifndef GP_IOREG_GPI_ROUT2 +#define GP_IOREG_GPI_ROUT2 0x34 +#endif + +#ifndef ICH_LP_IOREG_GPE0_STS +#define ICH_LP_IOREG_GPE0_STS ACPI_PCHLP_IOREG_GPE0_STS + 0x0c +#endif + +#ifndef ICH_LP_IOREG_GPE0_EN +#define ICH_LP_IOREG_GPE0_EN ACPI_PCHLP_IOREG_GPE0_EN + 0x0c +#endif + +#define PCH_NON_LPT 0x00 // Non Lynx Point Series +#define PCH_LPT_H 0x01 // Lynx Point 2 Chip +#define PCH_LPT_LP 0x02 // Lynx Point LP + +UINT8 IsLynxPoint ( VOID ) +{ + UINT32 LpcId; + UINT16 LpcBusDevFunc = (0 << 8) + (0x1F << 3) + 0; + + LpcId = ReadPCIConfig(LpcBusDevFunc, 0); + + if (((UINT16)(LpcId >> 16) & 0xFF00) == 0x8C00) + return PCH_LPT_H; + + if (((UINT16)(LpcId >> 16) & 0xFF00) == 0x9C00) + return PCH_LPT_LP; + + return PCH_NON_LPT; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Function: USBSB_PeriodicTimerCallBack +// +// Description: +// This function is registers periodic timer callbacks. +// +// Input: +// Pointer to the EFI System Table +// +// Output: +// - EFI_SUCCESS if timers are initialized or function is not implemented +// - timer initialization error +// +// Note: +// If function is not implemented (timers are not needed for this chipset), +// function must return EFI_SUCCESS +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +USBSB_PeriodicTimerCallBack ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *DispatchContext + ) +{ + DEV_INFO* fpDevInfo; + int i; + DEV_INFO* pDev = gUsbData->aDevInfoTable; + EFI_STATUS Status = EFI_SUCCESS; + + if (gLockSmiHandler == TRUE) { + return EFI_SUCCESS; + } +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = AmiUsbSmmGlobalDataValidation(gUsbData); + + ASSERT_EFI_ERROR(Status); + + if (EFI_ERROR(Status)) { + gLockHwSmiHandler = TRUE; + gLockSmiHandler = TRUE; + return EFI_SUCCESS; + } +#endif + + for (i = 0; i < USB_DEV_HID_COUNT; i++) { + fpDevInfo = gUsbData->aUSBKBDeviceTable[i]; + if (fpDevInfo != NULL) break; + } + if(fpDevInfo == NULL){ + for (i = 1; i < MAX_DEVICES; ++i, ++pDev ){ +#if USB_DRIVER_BUILD_VER > 29 + if ( (pDev->Flag & DEV_INFO_VALID_STRUC) != 0 && +#else + if ( (pDev->bFlag & DEV_INFO_VALID_STRUC) != 0 && +#endif + pDev->bDeviceType == BIOS_DEV_TYPE_HID && +#if USB_DRIVER_BUILD_VER > 28 + (pDev->HidDevType & HID_DEV_TYPE_MOUSE) ) { //(EIP84455) +#else + (pDev->bSubDeviceType & SUB_DEV_TYPE_MOUSE) ) { //(EIP84455) +#endif + fpDevInfo= pDev; + break; + } + } + } + + if (fpDevInfo != NULL){ + USBKBDPeriodicInterruptHandler(gUsbData->HcTable[fpDevInfo->bHCNumber - 1]); + } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: USBSB_InstallXhciHwSmiHandler +// +// Description: +// This function registers XHCI hardware SMI callback function. +// +// Note: +// Currently EHCI, UHCI and OHCI drivers install their SMI handlers in the +// corresponding Start functions. In the future all code related to SMI +// registration can be moved here. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +USBSB_InstallXhciHwSmiHandler() +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_HANDLE Handle = NULL; + +#if XHCI_SUPPORT +#if XHCI_EVENT_SERVICE_MODE != 0 +//GPI service + EFI_SMM_GPI_DISPATCH_PROTOCOL *GpiDispatch = NULL; + EFI_SMM_GPI_DISPATCH_CONTEXT Context; + + UINT8 HwSmiPinTable[] = {USB_XHCI_EXT_HW_SMI_PINS}; + UINT8 i; + UINT32 Buffer32; + + Status = pBS->LocateProtocol (&gEfiSmmGpiDispatchProtocolGuid, NULL, &GpiDispatch); + ASSERT_EFI_ERROR(Status); // driver dependencies? + + if (!EFI_ERROR(Status)) { + for (i = 0; i < sizeof(HwSmiPinTable)/sizeof(UINT8); i++) { + if(HwSmiPinTable[i] == 0xFF) continue; + //(EIP61556)> + Context.GpiNum = HwSmiPinTable[i]; + //<(EIP61556) + GpiDispatch->Register(GpiDispatch, XhciHwSmiHandler, &Context, &Handle); + if (IsLynxPoint() == PCH_LPT_LP) { + Buffer32 = IoRead32(GPIO_BASE_ADDRESS + GP_IOREG_GPI_ROUT2); + Buffer32 &= ~(3 << (Context.GpiNum * 2)); + Buffer32 |= (1 << (Context.GpiNum * 2)); + IoWrite32(GPIO_BASE_ADDRESS + GP_IOREG_GPI_ROUT2, Buffer32); + } else { + // Set GPIO_ROUTx = SMI# (B0:D31:F0 B8h[31:0]) + Buffer32 = DwordReadMem(SB_PCIE_CFG_ADDRESS(SB_BUS, SB_DEV, SB_FUN, 0), SB_REG_GPI_ROUT); + Buffer32 &= ~(3 << (Context.GpiNum * 2)); + Buffer32 |= (1 << (Context.GpiNum * 2)); + DwordWriteMem(SB_PCIE_CFG_ADDRESS(SB_BUS, SB_DEV, SB_FUN, 0), SB_REG_GPI_ROUT, Buffer32); + } + } + } +#endif + +#if XHCI_EVENT_SERVICE_MODE != 1 + Status = USBSB_InstallUsbIntTimerHandler(); +#endif +#endif + + return Status; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: UsbIntTimerCallBack +// +// Description: +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID +UsbIntTimerCallBack ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT *DispatchContext +) +{ + HC_STRUC* HcStruc; + UINT8 i; + EFI_STATUS Status; + + if (gLockSmiHandler == TRUE) { + return; + } +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B) + Status = AmiUsbSmmGlobalDataValidation(gUsbData); + + ASSERT_EFI_ERROR(Status); + + if (EFI_ERROR(Status)) { + gLockHwSmiHandler = TRUE; + gLockSmiHandler = TRUE; + return; + } +#endif + + for (i = 0; i < gUsbData->HcTableCount; i++) { + HcStruc = gUsbData->HcTable[i]; + if (HcStruc == NULL) { + continue; + } + if((HcStruc->dHCFlag & (HC_STATE_EXTERNAL | HC_STATE_RUNNING)) == + (HC_STATE_EXTERNAL | HC_STATE_RUNNING)) { + (*gUsbData->aHCDriverTable[ + GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDProcessInterrupt)(HcStruc); + } + } +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: USBSB_InstallUsbIntTimerHandler +// +// Description: +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +USBSB_InstallUsbIntTimerHandler() +{ + EFI_STATUS Status; + EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT TimerContext; + UINT64 *SmiTickInterval; + + if (gUsbIntTimerHandle != NULL) { + return EFI_SUCCESS; + } + + Status = pBS->LocateProtocol ( + &gEfiSmmPeriodicTimerDispatchProtocolGuid, + NULL, + &gPeriodicTimerDispatch); + ASSERT_EFI_ERROR(Status); // driver dependencies? + + if (!EFI_ERROR(Status)) { + TimerContext.Period = 160000; //16ms + TimerContext.SmiTickInterval = 160000; + TimerContext.ElapsedTime = 0; + SmiTickInterval = NULL; + //Check SmiTickInterval that are supported by the chipset. + do { + Status = gPeriodicTimerDispatch->GetNextShorterInterval( + gPeriodicTimerDispatch, + &SmiTickInterval + ); + if (EFI_ERROR(Status)) { + break; + } + if (SmiTickInterval != NULL) { + if (*SmiTickInterval <= TimerContext.SmiTickInterval) { + TimerContext.SmiTickInterval = *SmiTickInterval; + break; + } + } + } while (SmiTickInterval != NULL); + + Status = gPeriodicTimerDispatch->Register ( + gPeriodicTimerDispatch, + UsbIntTimerCallBack, + &TimerContext, + &gUsbIntTimerHandle); + ASSERT_EFI_ERROR(Status); + } + + return Status; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: USBSB_UninstallTimerHandlers +// +// Description: This function unregisters all the periodic timer handles. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +USBSB_UninstallTimerHandlers() +{ + EFI_STATUS Status = EFI_SUCCESS; + + if (gPeriodicTimerDispatch == NULL) { + return Status; + } + + if (gUsbIntTimerHandle) { + Status = gPeriodicTimerDispatch->UnRegister ( + gPeriodicTimerDispatch, + gUsbIntTimerHandle); + ASSERT_EFI_ERROR(Status); + + gUsbIntTimerHandle = NULL; + } + + if (gPeriodicTimerHandle) { + Status = gPeriodicTimerDispatch->UnRegister ( + gPeriodicTimerDispatch, + gPeriodicTimerHandle); + ASSERT_EFI_ERROR(Status); + + gPeriodicTimerHandle = NULL; + } + + return Status; +} + +#ifdef USB_ACPI_ENABLE_DISPATCH +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: AcpiEnableCallBack +// +// Description: +// This is ACPI mode enable callback function. It is a workaround for non +// XHCI/EHCI aware OSes. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID +AcpiEnableCallBack( + IN EFI_HANDLE DispatchHandle +) +{ + USB_StopUnsupportedHc(); + gUsbData->dUSBStateFlag |= USB_FLAG_RUNNING_UNDER_OS; + gLockSmiHandler = TRUE; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: RegisterAcpiEnableCallBack +// +// Description: +// This function registers ACPI enable callback function. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +RegisterAcpiEnableCallBack( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + EFI_ACPI_DISPATCH_PROTOCOL *AcpiEnDispatch; + + Status = pBS->LocateProtocol(&gEfiAcpiEnDispatchProtocolGuid, NULL, &AcpiEnDispatch); + if (EFI_ERROR(Status)) return Status; + + Status = AcpiEnDispatch->Register(AcpiEnDispatch, AcpiEnableCallBack, &Handle); + ASSERT_EFI_ERROR(Status); + + return Status; +} +#endif + +BOOLEAN IsAllEhciDisabled ( VOID ) +{ + UINT32 XhciDID; + UINT16 XhciBusDevFunc = (0 << 8) + (0x14 << 3) + 0; + EFI_STATUS Status; + SETUP_DATA SetupData; + EFI_GUID SetupGuid = SETUP_GUID; + UINTN VarSize; + + XhciDID = ReadPCIConfig(XhciBusDevFunc, 0); + + if (((UINT16)(XhciDID >> 16) == 0x8C31) || \ + ((UINT16)(XhciDID >> 16) == 0x8CB1) || \ + ((UINT16)(XhciDID >> 16) == 0x9CB1) || \ + ((UINT16)(XhciDID >> 16) == 0x9C31)) { + + VarSize = sizeof(SETUP_DATA); + Status = pRS->GetVariable( + L"Setup", + &SetupGuid, + NULL, + &VarSize, + &SetupData ); + if (!EFI_ERROR(Status)) { + if ((SetupData.PchUsb30Mode == 1) || \ + ((SetupData.PchUsb20[0] == 0) && \ + (SetupData.PchUsb20[1] == 0))) + return TRUE; + } + } + + return FALSE; +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: USBSB_InstallSmiEventHandlers +// +// Description: +// This function is called from USBRT entry point inside SMM. Any SMI handlers +// registration related to USB driver can be done here. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +USBSB_InstallSmiEventHandlers(VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + + +#if USB_HID_KEYREPEAT_USE_SETIDLE == 0 + EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT PeriodicTimerContext; + + if (IsLynxPoint() != PCH_NON_LPT) { + + // [Lynx point] Register Timer SMI if all EHCI controllers are disabled. + if (!IsAllEhciDisabled()) return Status; + + Status = pBS->LocateProtocol ( + &gEfiSmmPeriodicTimerDispatchProtocolGuid, + NULL, + &gPeriodicTimerDispatch); + ASSERT_EFI_ERROR(Status); // driver dependencies? + + if (!EFI_ERROR(Status)) { + PeriodicTimerContext.Period = 160000; //16ms + PeriodicTimerContext.SmiTickInterval = 160000; + PeriodicTimerContext.ElapsedTime = 0; + + Status = gPeriodicTimerDispatch->Register ( + gPeriodicTimerDispatch, + USBSB_PeriodicTimerCallBack, + &PeriodicTimerContext, + &gPeriodicTimerHandle); + ASSERT_EFI_ERROR(Status); + } + if (EFI_ERROR(Status)) { + gPeriodicTimerDispatch = NULL; + } + } + +#endif + +#ifdef USB_ACPI_ENABLE_DISPATCH + { + EFI_ACPI_DISPATCH_PROTOCOL *AcpiEnDispatch; + EFI_EVENT Event; + VOID *Reg; + + Status = pBS->LocateProtocol(&gEfiAcpiEnDispatchProtocolGuid, NULL, &AcpiEnDispatch); + if(!EFI_ERROR(Status)) { + RegisterAcpiEnableCallBack(NULL, NULL); + } else { + Status = RegisterProtocolCallback( + &gEfiAcpiEnDispatchProtocolGuid, + RegisterAcpiEnableCallBack, + NULL, + &Event, + &Reg); + ASSERT_EFI_ERROR(Status); + } + } +#endif + return Status; +} + //(EIP54018+)> +#if USB_S5_WAKEUP_SUPPORT +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Name: UsbSbEnablePme +// +// Description: +// The funciton enable usb PME +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID +UsbSbEnablePme(VOID) +{ + // Disable USB Wake on Device Connect/Disconnect + *(UINT32*)(SB_RCBA + RCRB_MMIO_RMHWKCTL)= 0x33; + + // Clear PM1_STS + IoWrite16(PM_BASE_ADDRESS, IoRead16(PM_BASE_ADDRESS)); + if (IsLynxPoint() == PCH_LPT_LP) { + // Clear GPE0_STS + IoWrite32(PM_BASE_ADDRESS + ICH_LP_IOREG_GPE0_STS, 0xFFFFFFFF); // PMBASE + 8Ch + IoWrite32(PM_BASE_ADDRESS + ICH_LP_IOREG_GPE0_STS - 0x04, 0xFFFFFFFF); // PMBASE + 88h + IoWrite32(PM_BASE_ADDRESS + ICH_LP_IOREG_GPE0_STS - 0x08, 0xFFFFFFFF); // PMBASE + 84h + IoWrite32(PM_BASE_ADDRESS + ICH_LP_IOREG_GPE0_STS - 0x0C, 0xFFFFFFFF); // PMBASE + 80h + // Set PME_B0_EN and PME_EN + IoWrite16(PM_BASE_ADDRESS + ICH_LP_IOREG_GPE0_EN, BIT13 + BIT11); // PMBASE + 9Ch + } else { + // Clear GPE0_STS + IoWrite32(PM_BASE_ADDRESS + ICH_IOREG_GPE0_STS, 0xFFFFFFFF); // PMBASE + 20h + IoWrite32(PM_BASE_ADDRESS + ICH_IOREG_GPE0_STS + 0x04, 0xFFFFFFFF); // PMBASE + 24h + // Set PME_B0_EN and PME_EN (PMBASE + 28h) + IoWrite16(PM_BASE_ADDRESS + ICH_IOREG_GPE0_EN, BIT13 + BIT11); // PMBASE + 28h + } + // Clear PCI Express Wake Disable + IoWrite16(PM_BASE_ADDRESS + ACPI_IOREG_PM1_EN, + IoRead16(PM_BASE_ADDRESS + ACPI_IOREG_PM1_EN & ~BIT14)); +} + +#endif + //<(EIP54018+) +#else + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: UsbAcpiEnableCallBack +// +// Description: +// This is ACPI mode enable callback function. It is a workaround for non +// XHCI/EHCI aware OSes. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID +UsbAcpiEnableCallBack( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext +) +{ +#if (defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION>=0x0001000A)) && defined(SMM_BUILD) + EFI_STATUS Status; + AMI_USB_SMM_PROTOCOL *UsbSmmProtocol = NULL; + + Status = pSmst->SmmLocateProtocol(&gAmiUsbSmmProtocolGuid, NULL, &UsbSmmProtocol); + if (EFI_ERROR(Status)) { + return; + } + + UsbSmmProtocol->UsbStopUnsupportedHc(); + +#else + EFI_USB_PROTOCOL *AmiUsb = NULL; + UINT16 EbdaSeg = *((UINT16*)0x40E); + + AmiUsb = *(EFI_USB_PROTOCOL **)(UINTN)(((UINT32)EbdaSeg << 4) + USB_PROTOCOL_EBDA_OFFSET); + //(EIP50358)> + if (AmiUsb && AmiUsb->Signature == 0x50425355) { //USBP //(EIP55275) + AmiUsb->UsbStopUnsupportedHc(); + } + //<(EIP50358) +#endif +} + +#endif + +//**************************************************************************** +//**************************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone (770)-246-8600 ** +//** ** +//**************************************************************************** +//**************************************************************************** diff --git a/Chipset/SB/usb/usbsb.cif b/Chipset/SB/usb/usbsb.cif new file mode 100644 index 0000000..9134fda --- /dev/null +++ b/Chipset/SB/usb/usbsb.cif @@ -0,0 +1,8 @@ +<component> + name = "SouthBridge - Intel PCH" + category = ModulePart + LocalRoot = "chipset\sb\usb\" + RefName = "USB_SB" +[files] +"usbsb.c" +<endComponent> |