summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/IoTrap
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Chipset/LynxPoint/IoTrap
downloadzprj-master.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/IoTrap')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c884
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h221
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak118
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs43
7 files changed, 1438 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c
new file mode 100644
index 0000000..74cb450
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c
@@ -0,0 +1,884 @@
+/** @file
+ Main implementation source file for the Io Trap SMM driver
+
+@copyright
+ Copyright (c) 2006 - 2013 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.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "IoTrap.h"
+
+//
+// Module global variables
+//
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+EFI_SMM_SYSTEM_TABLE *mSmst;
+EFI_HANDLE mDriverImageHandle;
+EFI_SMM_ICHN_DISPATCH_PROTOCOL *mIchnDispatch;
+EFI_SMM_ICHN_DISPATCH_CONTEXT mIchnContext;
+EFI_HANDLE mIchnHandle;
+UINT32 mPchRootComplexBar;
+
+IO_TRAP_INSTANCE mIoTrapData;
+IO_TRAP_RECORD *mIoTrapRecord;
+
+static CONST UINT16 mLengthTable[7] = { 4, 8, 16, 32, 64, 128, 256 };
+
+/**
+ Register a new IO Trap SMI dispatch function with a parent SMM driver.
+ The caller will provide information about the IO trap characteristics via
+ the context. This includes base address, length, read vs. r/w, etc.
+ This function will autoallocate IO base address from a common pool if the base address is 0,
+ and the RegisterContext Address field will be updated.
+ The service will not perform GCD allocation if the base address is non-zero.
+ In this case, the caller is responsible for the existence and allocation of the
+ specific IO range.
+ This function looks for the suitable handler and Register a new IchnIoTrap handler
+ if the IO Trap handler is not used. It also enable the IO Trap Range to generate
+ SMI.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchFunction Pointer to dispatch function to be invoked for
+ this SMI source.
+ @param[in, out] RegisterContext Pointer to the dispatch function's context.
+ The caller fills this context in before calling
+ the register function to indicate to the register
+ function the IO trap SMI source for which the dispatch
+ function should be invoked. This may not be NULL.
+ @param[out] 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. This may not be NULL.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ registered and the SMI source has been enabled.
+ @retval EFI_DEVICE_ERROR The driver was unable to enable the SMI source.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources are available
+ @retval EFI_INVALID_PARAMETER Address requested is already in use.
+**/
+static
+EFI_STATUS
+EFIAPI
+IoTrapRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK DispatchFunction,
+ IN OUT EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT *RegisterContext,
+ OUT EFI_HANDLE *DispatchHandle
+ )
+{
+ EFI_STATUS Status;
+ static CONST UINT16 IoTrapHandlerList[IO_TRAP_HANDLER_NUM] = { IchnIoTrap0, IchnIoTrap1, IchnIoTrap2, IchnIoTrap3 };
+ EFI_PHYSICAL_ADDRESS NextBaseAddress;
+ UINT32 NextUsedLength;
+ UINT8 NextTrapHandlerNum;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+ UINT32 IoTrapRegLowDword;
+ UINT32 IoTrapRegHighDword;
+ UINT8 LengthIndex;
+
+ //
+ // Return error if the type is invalid
+ //
+ if (RegisterContext->Type >= IoTrapTypeMaximum) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch Type %0X is invalid! \n", RegisterContext->Type));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Return error if the Length is invalid
+ //
+ if (RegisterContext->Length < 1 || RegisterContext->Length > 0x100) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch Length %0X is invalid! \n", RegisterContext->Length));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Return error if the address is invalid
+ //
+ if (RegisterContext->Address % 4 != 0) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch address %0X is invalid! \n", RegisterContext->Address));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Loop through the first IO Trap handler, looking for the suitable handler
+ //
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // Get information from Io Trap handler register
+ //
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ //
+ // Check if the IO Trap handler is not used
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD) == 0) {
+ //
+ // Search available IO address and allocate it if the IO address is 0
+ //
+ BaseAddress = RegisterContext->Address;
+ if (BaseAddress == 0) {
+ //
+ // Allocate 256 byte range from GCD for common pool usage
+ //
+ Status = gDS->AllocateIoSpace (
+ EfiGcdAllocateAnySearchBottomUp,
+ EfiGcdIoTypeIo,
+ 8,
+ 0x100,
+ &BaseAddress,
+ mDriverImageHandle,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Can't find any available IO address! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RegisterContext->Address = (UINT16) BaseAddress;
+ UsedLength = 0x100;
+ mIoTrapData.TrapUsedLength[TrapHandlerNum] = RegisterContext->Length;
+ } else {
+ //
+ // PCH only support dword * power of 2 alignment
+ //
+ for (LengthIndex = 0; LengthIndex < sizeof (mLengthTable) / sizeof (UINT16); LengthIndex++) {
+ if (RegisterContext->Length == mLengthTable[LengthIndex]) {
+ break;
+ }
+ }
+ //
+ // Return error if the alignment is not dword * power of 2
+ //
+ if (LengthIndex >= sizeof (mLengthTable) / sizeof (UINT16)) {
+ DEBUG ((EFI_D_ERROR, "The PCH only support dword * power of 2 alignment! \n"));
+ DEBUG ((EFI_D_ERROR, "The Dispatch Length %0X is 0 or invalid! \n", RegisterContext->Length));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UsedLength = RegisterContext->Length;
+ }
+
+ //
+ // Register a new IchnIoTrap handler
+ //
+ mIchnContext.Type = IoTrapHandlerList[TrapHandlerNum];
+ mIchnHandle = NULL;
+ Status = mIchnDispatch->Register (
+ mIchnDispatch,
+ IoTrapCallback,
+ &mIchnContext,
+ &mIchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ mIoTrapData.IchnIoTrapHandle[TrapHandlerNum] = mIchnHandle;
+ //
+ // Fill in the Length, address and Enable the IO Trap SMI
+ //
+ IoTrapRegLowDword = (UINT32) (((UsedLength - 1) & ~(BIT1 + BIT0)) << 16) |
+ (UINT16) BaseAddress |
+ B_PCH_RCRB_IO_TRAP_TRSE;
+
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8,
+ (UINT32) (IoTrapRegLowDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+
+ IoTrapRegHighDword = 0x000000F0 | (UINT32) (RegisterContext->Type << N_PCH_RCRB_IO_TRAP_RWIO);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+
+ //
+ // Set MergeDisable flag of the registered IoTrap
+ //
+ mIoTrapData.MergeDisable[TrapHandlerNum] = RegisterContext->MergeDisable;
+ } else {
+ //
+ // Check next handler if MergeDisable is TRUE or the registered IoTrap if MergeDisable is TRUE
+ //
+ if ((RegisterContext->MergeDisable == TRUE) || (mIoTrapData.MergeDisable[TrapHandlerNum] == TRUE)) {
+ continue;
+ }
+ //
+ // The IO Trap handler is used, calculate the Length
+ //
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+ //
+ // Assign an addfress from common pool if the caller's address is 0
+ //
+ if (RegisterContext->Address == 0) {
+ //
+ // Check next handler if it's fully used
+ //
+ if (mIoTrapData.TrapUsedLength[TrapHandlerNum] >= 0x100) {
+ continue;
+ }
+ //
+ // Check next handler if it's not for a common pool
+ //
+ if (UsedLength < 0x100) {
+ continue;
+ }
+ //
+ // Check next handler if the size is too big
+ //
+ if (RegisterContext->Length >= (UINT16) 0x100 - mIoTrapData.TrapUsedLength[TrapHandlerNum]) {
+ continue;
+ }
+ //
+ // For common pool, we don't need to change the BaseAddress and UsedLength
+ //
+ RegisterContext->Address = (UINT16) (BaseAddress + mIoTrapData.TrapUsedLength[TrapHandlerNum]);
+ mIoTrapData.TrapUsedLength[TrapHandlerNum] += RegisterContext->Length;
+ } else {
+ //
+ // Check next handler if the address is smaller than the IO trap handler's start address
+ //
+ if (RegisterContext->Address < (UINT16) BaseAddress) {
+ continue;
+ }
+ //
+ // Check next handler if the max address is bigger than IO trap handler's range
+ //
+ if ((RegisterContext->Address + RegisterContext->Length) > (UINT16) (BaseAddress + 256)) {
+ continue;
+ }
+ //
+ // If this handler is used for common pool, assert if the caller's address is within the range
+ //
+ if (mIoTrapData.TrapUsedLength[TrapHandlerNum] != 0) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch address %0x is used for common pool! \n", RegisterContext->Address));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Calculate the Length which is maximum use address - start address
+ //
+ UsedLength = RegisterContext->Address + RegisterContext->Length - (UINT16) BaseAddress;
+ //
+ // Check the alignment is dword * power of 2 or not
+ //
+ for (LengthIndex = 0; LengthIndex < sizeof (mLengthTable) / sizeof (UINT16); LengthIndex++) {
+ if (UsedLength == mLengthTable[LengthIndex]) {
+ break;
+ }
+ }
+ //
+ // Check next handler if the alignment is not dword * power of 2
+ //
+ if (LengthIndex >= sizeof (mLengthTable) / sizeof (UINT16)) {
+ continue;
+ }
+ //
+ // Merge the overlap range: remove next Io Trap handler if next Io Trap handler's range is within this handler's range
+ //
+ for (NextTrapHandlerNum = TrapHandlerNum + 1; NextTrapHandlerNum != TrapHandlerNum; NextTrapHandlerNum++) {
+ //
+ // Check if NextTrapHandlerNum overflow
+ //
+ if (NextTrapHandlerNum >= IO_TRAP_HANDLER_NUM) {
+ NextTrapHandlerNum = 0;
+ }
+ //
+ // Get information from Io Trap handler register
+ //
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8);
+ //
+ // Check next handler if the IO Trap handler is not used
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD) == 0) {
+ continue;
+ }
+ //
+ // Check if next Io Trap handler's range is within this handler's range
+ //
+ NextUsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ NextBaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+ if ((BaseAddress > NextBaseAddress) || ((BaseAddress + UsedLength) < (NextBaseAddress + NextUsedLength))) {
+ continue;
+ }
+ //
+ // Unregister the IO Trap handler
+ //
+ mIchnHandle = mIoTrapData.IchnIoTrapHandle[NextTrapHandlerNum];
+ mIchnContext.Type = IoTrapHandlerList[NextTrapHandlerNum];
+ Status = mIchnDispatch->UnRegister (
+ mIchnDispatch,
+ mIchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Clear the Io Trap handler register
+ //
+ IoTrapRegLowDword = 0;
+ IoTrapRegHighDword = 0;
+ MmioWrite32 (
+ mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+
+ MmioWrite32 (
+ mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8,
+ (UINT32) (IoTrapRegLowDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+ }
+ //
+ // Update the Length
+ //
+ IoTrapRegLowDword = (UINT32) (((UsedLength - 1) & ~(BIT1 + BIT0)) << 16) |
+ (UINT16) BaseAddress |
+ B_PCH_RCRB_IO_TRAP_TRSE;
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8,
+ (UINT32) (IoTrapRegLowDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+ }
+ //
+ // Only set RWM bit when we need both read and write cycles.
+ //
+ IoTrapRegHighDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4);
+ if ((IoTrapRegHighDword & B_PCH_RCRB_IO_TRAP_RWM) == 0 &&
+ (UINT32) ((IoTrapRegHighDword & B_PCH_RCRB_IO_TRAP_RWIO) >> N_PCH_RCRB_IO_TRAP_RWIO) !=
+ (UINT32) RegisterContext->Type) {
+ IoTrapRegHighDword = ((IoTrapRegHighDword | B_PCH_RCRB_IO_TRAP_RWM) & ~B_PCH_RCRB_IO_TRAP_RWIO);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+ }
+ }
+ break;
+ }
+
+ if (TrapHandlerNum >= IO_TRAP_HANDLER_NUM) {
+ DEBUG ((EFI_D_ERROR, "All IO Trap handler is used, no available IO Trap handler! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Create database record and add to database
+ //
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (IO_TRAP_RECORD),
+ (VOID **) &mIoTrapRecord
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for mIoTrapRecord! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Gather information about the registration request
+ //
+ mIoTrapRecord->Signature = IO_TRAP_RECORD_SIGNATURE;
+ mIoTrapRecord->Context = *RegisterContext;
+ mIoTrapRecord->Callback = DispatchFunction;
+
+ InsertTailList (&mIoTrapData.CallbackDataBase, &mIoTrapRecord->Link);
+
+ //
+ // Child's handle will be the address linked list link in the record
+ //
+ *DispatchHandle = (EFI_HANDLE) (&mIoTrapRecord->Link);
+
+ DEBUG ((EFI_D_INFO, "RegisterContext->Address:%x! \n", RegisterContext->Address));
+ DEBUG ((EFI_D_INFO, "RegisterContext->Length:%x! \n", RegisterContext->Length));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of dispatch function to deregister.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered and the SMI source has been disabled
+ if there are no other registered child dispatch
+ functions for this SMI source.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapUnRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_HANDLE *DispatchHandle
+ )
+{
+ EFI_STATUS Status;
+ IO_TRAP_RECORD *RecordToDelete;
+ UINT32 IoTrapRegLowDword;
+ UINT32 IoTrapRegHighDword;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+ UINT8 LengthIndex;
+
+ if (*DispatchHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RecordToDelete = IO_TRAP_RECORD_FROM_LINK (*DispatchHandle);
+
+ //
+ // Take the entry out of the linked list
+ //
+ if (RecordToDelete->Link.ForwardLink == (LIST_ENTRY *) EFI_BAD_POINTER) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Loop through the first IO Trap handler, looking for the suitable handler
+ //
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // Get information from Io Trap handler register
+ //
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ //
+ // Check next Io Trap handler if the IO Trap handler is not used
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD) == 0) {
+ continue;
+ }
+
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+
+ //
+ // Check if it's the maximum address of the Io Trap handler
+ //
+ if (BaseAddress + UsedLength == RecordToDelete->Context.Address + RecordToDelete->Context.Length) {
+
+ if (BaseAddress == RecordToDelete->Context.Address) {
+ //
+ // Disable the IO Trap handler if it's the only child of the Trap handler
+ //
+ mIchnHandle = mIoTrapData.IchnIoTrapHandle[TrapHandlerNum];
+ mIchnContext.Type = IchnIoTrap0 + TrapHandlerNum;
+ Status = mIchnDispatch->UnRegister (
+ mIchnDispatch,
+ mIchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Clear the Io Trap handler register
+ //
+ IoTrapRegLowDword = 0;
+ IoTrapRegHighDword = 0;
+ MmioWrite32 (
+ mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+
+ } else {
+ //
+ // Calculate the new IO Trap handler Length
+ //
+ UsedLength = UsedLength - RecordToDelete->Context.Length;
+ //
+ // Check the alignment is dword * power of 2 or not
+ //
+ for (LengthIndex = 0; LengthIndex < sizeof (mLengthTable) / sizeof (UINT16); LengthIndex++) {
+ if (UsedLength == mLengthTable[LengthIndex]) {
+ break;
+ }
+ }
+ //
+ // Do not decrease the length if the alignment is not dword * power of 2
+ //
+ if (LengthIndex >= sizeof (mLengthTable) / sizeof (UINT16)) {
+ break;
+ }
+ //
+ // Decrease the length to prevent the IO trap SMI
+ //
+ IoTrapRegLowDword = (UINT32) ((((UsedLength - 1) &~(BIT1 + BIT0)) << 16) | BaseAddress | B_PCH_RCRB_IO_TRAP_TRSE);
+ }
+
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8, (UINT32) (IoTrapRegLowDword));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+ break;
+ }
+ }
+
+ RemoveEntryList (&RecordToDelete->Link);
+ Status = mSmst->SmmFreePool (RecordToDelete);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This I/O Trap SMI handler invokes the ACPI reference code to handle the SMI.
+ It currently assumes it owns all of the IO trap SMI.
+
+ @param[in] DispatchHandle Not used
+ @param[in] DispatchContext Not used
+
+ @retval None
+**/
+VOID
+EFIAPI
+IoTrapCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ IO_TRAP_RECORD *RecordInDb;
+ LIST_ENTRY *LinkInDb;
+ EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT CurrentIoTrapData;
+ UINT16 BaseAddress;
+ UINT16 StartAddress;
+ UINT16 EndAddress;
+
+ if (!IsListEmpty (&mIoTrapData.CallbackDataBase)) {
+ BaseAddress = MmioRead16 (mPchRootComplexBar + R_PCH_RCRB_TRCR) & B_PCH_RCRB_TRCR_TIOA;
+ StartAddress = (UINT16) ((MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_TRCR) & B_PCH_RCRB_TRCR_AHBE) >> 16);
+ //
+ // StartAddress and EndAddress will be equal if it's byte access
+ //
+ EndAddress = (UINT16) (HighBitSet32 ((UINT32) (StartAddress))) + BaseAddress;
+ StartAddress = (UINT16) (LowBitSet32 ((UINT32) (StartAddress))) + BaseAddress;
+
+ CurrentIoTrapData.Type = (BOOLEAN) ((MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_TRCR) & B_PCH_RCRB_TRCR_RWI) != 0);
+ CurrentIoTrapData.WriteData = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_TRWDR);
+
+ LinkInDb = GetFirstNode (&mIoTrapData.CallbackDataBase);
+
+ while (!IsNull (&mIoTrapData.CallbackDataBase, LinkInDb)) {
+ RecordInDb = IO_TRAP_RECORD_FROM_LINK (LinkInDb);
+ if ((RecordInDb->Context.Address <= StartAddress) &&
+ (RecordInDb->Context.Address + RecordInDb->Context.Length > EndAddress)) {
+ if (RecordInDb->Context.Type == ReadWriteTrap || RecordInDb->Context.Type == CurrentIoTrapData.Type) {
+ //
+ // Pass the IO trap context information
+ //
+ CurrentIoTrapData.Address = StartAddress;
+ CurrentIoTrapData.Context = RecordInDb->Context.Context;
+ RecordInDb->Callback (&RecordInDb->Link, &CurrentIoTrapData);
+ break;
+ }
+ } else {
+ LinkInDb = GetNextNode (&mIoTrapData.CallbackDataBase, &RecordInDb->Link);
+ if (IsNull (&mIoTrapData.CallbackDataBase, LinkInDb)) {
+ //
+ // An IO access was trapped that does not have a handler registered.
+ // Since this is an invalid state, we will loop here.
+ // It may be appropriate to remove this loop in production systems to avoid potential user issues.
+ // But, this indicates an error condition.
+ //
+ DEBUG_CODE (
+ EFI_DEADLOOP ();
+ );
+ }
+ }
+ }
+ }
+}
+
+/**
+ Pause IoTrap callback function.
+
+ This function disables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady PAUSED.
+**/
+EFI_STATUS
+IoTrapControlPause (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL *This,
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ IO_TRAP_RECORD *IoTrapRecord;
+ UINT32 IoTrapRegLowDword;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+
+ if (DispatchHandle == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoTrapRecord = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+
+ if ((IoTrapRecord->Signature != IO_TRAP_RECORD_SIGNATURE) ||
+ (IoTrapRecord->Context.MergeDisable != TRUE) ||
+ (IoTrapRecord->Context.Address == 0) ||
+ (IoTrapRecord->Context.Length == 0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // This IoTrap register should be merge disabled.
+ //
+ if (mIoTrapData.MergeDisable[TrapHandlerNum] != TRUE) {
+ continue;
+ }
+
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+
+ //
+ // The address and length of record matches the IoTrap register's.
+ //
+ if ((BaseAddress == IoTrapRecord->Context.Address) &&
+ (UsedLength == IoTrapRecord->Context.Length )) {
+ //
+ // Check if status matched.
+ // If this is already Paused, return warning status.
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_TRSE) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Clear IoTrap register SMI enable bit
+ //
+ IoTrapRegLowDword &= (~B_PCH_RCRB_IO_TRAP_TRSE);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8, (UINT32) (IoTrapRegLowDword));
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Resume IoTrap callback function.
+
+ This function enables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady RESUMED.
+**/
+EFI_STATUS
+IoTrapControlResume (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL *This,
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ IO_TRAP_RECORD *IoTrapRecord;
+ UINT32 IoTrapRegLowDword;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+
+ if (DispatchHandle == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoTrapRecord = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+
+ if ((IoTrapRecord->Signature != IO_TRAP_RECORD_SIGNATURE) ||
+ (IoTrapRecord->Context.MergeDisable != TRUE) ||
+ (IoTrapRecord->Context.Address == 0) ||
+ (IoTrapRecord->Context.Length == 0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // This IoTrap register should be merge disabled.
+ //
+ if (mIoTrapData.MergeDisable[TrapHandlerNum] != TRUE) {
+ continue;
+ }
+
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+
+ //
+ // The address and length of record matches the IoTrap register's.
+ //
+ if ((BaseAddress == IoTrapRecord->Context.Address) &&
+ (UsedLength == IoTrapRecord->Context.Length )) {
+ //
+ // Check if status matched.
+ // If this is already Resume, return warning status.
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_TRSE) != 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Set IoTrap register SMI enable bit
+ //
+ IoTrapRegLowDword |= (B_PCH_RCRB_IO_TRAP_TRSE);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8, (UINT32) (IoTrapRegLowDword));
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ IO Trap SMM driver entry point function.
+
+ @param[in] ImageHandle Image handle for this driver image
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallIoTrap (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Initialize the EFI SMM driver library
+ //
+ mDriverImageHandle = ImageHandle;
+
+ //
+ // Find the SMM base protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize global variables.
+ //
+ mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+
+ //
+ // Add other initialization code
+ //
+ //
+ // PCH RCBA must be initialized prior to run this driver.
+ //
+ mPchRootComplexBar = PCH_RCRB_BASE;
+ ASSERT (mPchRootComplexBar != 0);
+
+ //
+ // Locate the ICHn Dispatch protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmIchnDispatchProtocolGuid, NULL, (VOID **) &mIchnDispatch);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Locate the S3 resume scripting protocol
+ //
+ INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+
+ //
+ // Initialize the IO trap protocol we produce
+ //
+ mIoTrapData.Signature = IO_TRAP_INSTANCE_SIGNATURE;
+ mIoTrapData.EfiSmmIoTrapDispatchProtocol.Register = IoTrapRegister;
+ mIoTrapData.EfiSmmIoTrapDispatchProtocol.UnRegister = IoTrapUnRegister;
+
+ //
+ // Initialize the Io trap control protocol.
+ //
+ mIoTrapData.PchSmmIoTrapControlProtocol.Pause = IoTrapControlPause;
+ mIoTrapData.PchSmmIoTrapControlProtocol.Resume = IoTrapControlResume;
+
+ //
+ // Install protocol interface
+ //
+ mIoTrapData.Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mIoTrapData.Handle,
+ &gEfiSmmIoTrapDispatchProtocolGuid,
+ &mIoTrapData.EfiSmmIoTrapDispatchProtocol,
+ &gPchSmmIoTrapControlGuid,
+ &mIoTrapData.PchSmmIoTrapControlProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize IO TRAP Callback DataBase
+ //
+ InitializeListHead (&mIoTrapData.CallbackDataBase);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif
new file mode 100644
index 0000000..c76e3da
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "IoTrap"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\IoTrap\Smm"
+ RefName = "IoTrap"
+[files]
+"IoTrap.sdl"
+"IoTrap.mak"
+"IoTrap.c"
+"IoTrap.h"
+"IoTrapDepex.dxs"
+"IoTrap.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h
new file mode 100644
index 0000000..d449fea
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h
@@ -0,0 +1,221 @@
+/** @file
+ Defines and prototypes for the IoTrap SMM driver
+
+@copyright
+ Copyright (c) 2006 - 2013 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.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _IO_TRAP_H_
+#define _IO_TRAP_H_
+
+//
+// Include files
+//
+//
+// 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 "EfiScriptLib.h"
+
+//
+// Driver Consumed Protocol
+//
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (LoadedImage)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIchnDispatch)
+#include EFI_PROTOCOL_DEPENDENCY (BootScriptSave)
+
+//
+// Driver Produced Protocol
+//
+#include EFI_PROTOCOL_PRODUCER (SmmIoTrapDispatch)
+#include EFI_PROTOCOL_PRODUCER (PchSmmIoTrapControl)
+#include "PchAccess.h"
+#endif
+
+#define IO_TRAP_HANDLER_NUM 4
+
+//
+// Driver private data
+//
+#define IO_TRAP_INSTANCE_SIGNATURE EFI_SIGNATURE_32 ('I', 'O', 'T', 'P')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL EfiSmmIoTrapDispatchProtocol;
+ EFI_HANDLE IchnIoTrapHandle[IO_TRAP_HANDLER_NUM];
+ LIST_ENTRY CallbackDataBase;
+ UINT32 TrapUsedLength[IO_TRAP_HANDLER_NUM];
+ BOOLEAN MergeDisable[IO_TRAP_HANDLER_NUM]; ///< Determine if IoTrap can be merged with other IoTrap
+ PCH_SMM_IO_TRAP_CONTROL_PROTOCOL PchSmmIoTrapControlProtocol; ///< Protocol for runtime control the IoTrap state
+} IO_TRAP_INSTANCE;
+
+#define IO_TRAP_INSTANCE_FROM_THIS(a) CR (a, IO_TRAP_INSTANCE, EfiSmmIoTrapDispatchProtocol, IO_TRAP_INSTANCE_SIGNATURE)
+
+///
+/// "IOTRAP" RECORD
+/// Linked list data structures
+///
+#define IO_TRAP_RECORD_SIGNATURE EFI_SIGNATURE_32 ('I', 'T', 'R', 'C')
+
+typedef struct _IO_TRAP_RECORD {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT Context;
+ EFI_SMM_IO_TRAP_DISPATCH_CALLBACK Callback;
+} IO_TRAP_RECORD;
+
+#define IO_TRAP_RECORD_FROM_LINK(_record) CR (_record, IO_TRAP_RECORD, Link, IO_TRAP_RECORD_SIGNATURE)
+
+//
+// Prototypes
+//
+/**
+ IO Trap SMM driver entry point function.
+
+ @param[in] ImageHandle Image handle for this driver image
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallIoTrap (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Register a new IO Trap SMI dispatch function with a parent SMM driver.
+ The caller will provide information about the IO trap characteristics via
+ the context. This includes base address, length, read vs. r/w, etc.
+ This function will autoallocate IO base address from a common pool if the base address is 0,
+ and the RegisterContext Address field will be updated.
+ The service will not perform GCD allocation if the base address is non-zero.
+ In this case, the caller is responsible for the existence and allocation of the
+ specific IO range.
+ This function looks for the suitable handler and Register a new IchnIoTrap handler
+ if the IO Trap handler is not used. It also enable the IO Trap Range to generate
+ SMI.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchFunction Pointer to dispatch function to be invoked for
+ this SMI source.
+ @param[in, out] RegisterContext Pointer to the dispatch function's context.
+ The caller fills this context in before calling
+ the register function to indicate to the register
+ function the IO trap SMI source for which the dispatch
+ function should be invoked. This may not be NULL.
+ @param[out] 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. This may not be NULL.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ registered and the SMI source has been enabled.
+ @retval EFI_DEVICE_ERROR The driver was unable to enable the SMI source.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources are available
+ @retval EFI_INVALID_PARAMETER Address requested is already in use.
+**/
+static
+EFI_STATUS
+EFIAPI
+IoTrapRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK DispatchFunction,
+ IN OUT EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT *RegisterContext,
+ OUT EFI_HANDLE *DispatchHandle
+ );
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of dispatch function to deregister.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered and the SMI source has been disabled
+ if there are no other registered child dispatch
+ functions for this SMI source.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapUnRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_HANDLE *DispatchHandle
+ );
+
+/**
+ This I/O Trap SMI handler invokes the ACPI reference code to handle the SMI.
+ It currently assumes it owns all of the IO trap SMI.
+
+ @param[in] DispatchHandle Not used
+ @param[in] DispatchContext Not used
+
+ @retval None
+**/
+VOID
+EFIAPI
+IoTrapCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ );
+
+/**
+ Pause IoTrap callback function.
+
+ This function disables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady PAUSED.
+**/
+EFI_STATUS
+IoTrapControlPause (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL * This,
+ IN EFI_HANDLE DispatchHandle
+ );
+
+/**
+ Resume IoTrap callback function.
+
+ This function enables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady RESUMED.
+**/
+EFI_STATUS
+IoTrapControlResume (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL * This,
+ IN EFI_HANDLE DispatchHandle
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf
new file mode 100644
index 0000000..7da9522
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf
@@ -0,0 +1,92 @@
+## @file
+# Component description file for the IoTrap BS_DRIVER
+#
+#@copyright
+# Copyright (c) 2006 - 2012 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.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = IoTrap
+FILE_GUID = 2374EDDF-F203-4fc0-A20E-61BAD73089D6
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ IoTrap.c
+ IoTrap.h
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+[libraries.common]
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ EfiScriptLib
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+#
+# Typically the sample code referenced will be available in the code base already
+# So keep this include at the end to defer to the source base definition
+# and only use the sample code definition if source base does not include these files.
+#
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = IoTrapDepex.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallIoTrap
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak
new file mode 100644
index 0000000..950c31e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak
@@ -0,0 +1,118 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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 Refcode/IoTrap/IoTrap.mak 4 12/18/12 5:19a Scottyang $
+#
+# $Revision: 4 $
+#
+# $Date: 12/18/12 5:19a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IoTrap/IoTrap.mak $
+#
+# 4 12/18/12 5:19a 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
+#
+# 3 9/26/12 2:27a Victortu
+#
+# 2 2/24/12 2:10a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:44a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+#---------------------------------------------------------------------------
+# Create IoTrap Driver
+#---------------------------------------------------------------------------
+EDK : IoTrap
+IoTrap : $(BUILD_DIR)\IoTrap.mak IoTrapBin
+
+$(BUILD_DIR)\IoTrap.mak : $(IoTrap_DIR)\$(@B).cif $(IoTrap_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IoTrap_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+IoTrap_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ /I$(EDK_SOURCE)\Foundation\Efi\Include\
+
+IoTrap_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallIoTrap"\
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+
+
+IoTrap_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueBasePciExpressLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(EFISCRIPTLIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+IoTrapBin: $(IoTrap_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\IoTrap.mak all \
+ "MY_INCLUDES=$(IoTrap_INCLUDES)" \
+ "MY_DEFINES=$(IoTrap_DEFINES)" \
+ GUID=2374EDDF-F203-4fc0-A20E-61BAD73089D6\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(IoTrap_DIR)\IoTrapDepex.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/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl
new file mode 100644
index 0000000..9eee5f4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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 Refcode/IoTrap/IoTrap.sdl 1 2/08/12 8:44a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:44a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IoTrap/IoTrap.sdl $
+#
+# 1 2/08/12 8:44a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "IoTrap_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IoTrap support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "IoTrap_DIR"
+End
+
+MODULE
+ File = "IoTrap.mak"
+ Help = "Includes IoTrap to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IoTrap.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/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs
new file mode 100644
index 0000000..0c0b283
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs
@@ -0,0 +1,43 @@
+/** @file
+ Dispatch dependency expression file for the IoTrap driver.
+
+@copyright
+ Copyright (c) 2006 - 2012 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.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+
+**/
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIchnDispatch)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_ICHN_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+