--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+**/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "QNCSmm.h"\r
+#include "QNCSmmHelpers.h"\r
+\r
+//\r
+// #define BIT_ZERO 0x00000001\r
+//\r
+CONST UINT32 BIT_ZERO = 0x00000001;\r
+\r
+//\r
+// /////////////////////////////////////////////////////////////////////////////\r
+// SUPPORT / HELPER FUNCTIONS (QNC version-independent)\r
+//\r
+BOOLEAN\r
+CompareEnables (\r
+ CONST IN QNC_SMM_SOURCE_DESC *Src1,\r
+ CONST IN QNC_SMM_SOURCE_DESC *Src2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Src1 - GC_TODO: add argument description\r
+ Src2 - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+ GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+ BOOLEAN IsEqual;\r
+ UINTN loopvar;\r
+\r
+ IsEqual = TRUE;\r
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {\r
+ //\r
+ // It's okay to compare a NULL bit description to a non-NULL bit description.\r
+ // They are unequal and these tests will generate the correct result.\r
+ //\r
+ if (Src1->En[loopvar].Bit != Src2->En[loopvar].Bit ||\r
+ Src1->En[loopvar].Reg.Type != Src2->En[loopvar].Reg.Type ||\r
+ Src1->En[loopvar].Reg.Data.raw != Src2->En[loopvar].Reg.Data.raw\r
+ ) {\r
+ IsEqual = FALSE;\r
+ break;\r
+ //\r
+ // out of for loop\r
+ //\r
+ }\r
+ }\r
+\r
+ return IsEqual;\r
+}\r
+\r
+BOOLEAN\r
+CompareStatuses (\r
+ CONST IN QNC_SMM_SOURCE_DESC *Src1,\r
+ CONST IN QNC_SMM_SOURCE_DESC *Src2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Src1 - GC_TODO: add argument description\r
+ Src2 - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+ GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+ BOOLEAN IsEqual;\r
+ UINTN loopvar;\r
+\r
+ IsEqual = TRUE;\r
+\r
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {\r
+ //\r
+ // It's okay to compare a NULL bit description to a non-NULL bit description.\r
+ // They are unequal and these tests will generate the correct result.\r
+ //\r
+ if (Src1->Sts[loopvar].Bit != Src2->Sts[loopvar].Bit ||\r
+ Src1->Sts[loopvar].Reg.Type != Src2->Sts[loopvar].Reg.Type ||\r
+ Src1->Sts[loopvar].Reg.Data.raw != Src2->Sts[loopvar].Reg.Data.raw\r
+ ) {\r
+ IsEqual = FALSE;\r
+ break;\r
+ //\r
+ // out of for loop\r
+ //\r
+ }\r
+ }\r
+\r
+ return IsEqual;\r
+}\r
+\r
+BOOLEAN\r
+CompareSources (\r
+ CONST IN QNC_SMM_SOURCE_DESC *Src1,\r
+ CONST IN QNC_SMM_SOURCE_DESC *Src2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Src1 - GC_TODO: add argument description\r
+ Src2 - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+ GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+ return (BOOLEAN) (CompareEnables (Src1, Src2) && CompareStatuses (Src1, Src2));\r
+}\r
+\r
+BOOLEAN\r
+SourceIsActive (\r
+ CONST IN QNC_SMM_SOURCE_DESC *Src\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Src - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+ GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+ BOOLEAN IsActive;\r
+ UINTN loopvar;\r
+\r
+ BOOLEAN SciEn;\r
+\r
+ IsActive = TRUE;\r
+\r
+ SciEn = QNCSmmGetSciEn ();\r
+\r
+ if ((Src->Flags & QNC_SMM_SCI_EN_DEPENDENT) && (SciEn)) {\r
+ //\r
+ // This source is dependent on SciEn, and SciEn == 1. An ACPI OS is present,\r
+ // so we shouldn't do anything w/ this source until SciEn == 0.\r
+ //\r
+ IsActive = FALSE;\r
+\r
+ } else {\r
+ //\r
+ // Read each bit desc from hardware and make sure it's a one\r
+ //\r
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {\r
+\r
+ if (!IS_BIT_DESC_NULL (Src->En[loopvar])) {\r
+\r
+ if (ReadBitDesc (&Src->En[loopvar]) == 0) {\r
+ IsActive = FALSE;\r
+ break;\r
+ //\r
+ // out of for loop\r
+ //\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ if (IsActive) {\r
+ //\r
+ // Read each bit desc from hardware and make sure it's a one\r
+ //\r
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {\r
+\r
+ if (!IS_BIT_DESC_NULL (Src->Sts[loopvar])) {\r
+\r
+ if (ReadBitDesc (&Src->Sts[loopvar]) == 0) {\r
+ IsActive = FALSE;\r
+ break;\r
+ //\r
+ // out of for loop\r
+ //\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return IsActive;\r
+}\r
+\r
+VOID\r
+QNCSmmEnableSource (\r
+ CONST QNC_SMM_SOURCE_DESC *SrcDesc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ SrcDesc - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+ GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+ UINTN loopvar;\r
+\r
+ //\r
+ // Set enables to 1 by writing a 1\r
+ //\r
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {\r
+ if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {\r
+ WriteBitDesc (&SrcDesc->En[loopvar], 1);\r
+ }\r
+ }\r
+\r
+ QNCSmmClearSource (SrcDesc);\r
+\r
+}\r
+\r
+VOID\r
+QNCSmmDisableSource (\r
+ CONST QNC_SMM_SOURCE_DESC *SrcDesc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ SrcDesc - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+ GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+ UINTN loopvar;\r
+\r
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {\r
+ if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {\r
+ WriteBitDesc (&SrcDesc->En[loopvar], 0);\r
+ }\r
+ }\r
+}\r
+\r
+VOID\r
+QNCSmmClearSource (\r
+ CONST QNC_SMM_SOURCE_DESC *SrcDesc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ SrcDesc - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+ GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+ UINTN loopvar;\r
+ BOOLEAN ValueToWrite;\r
+\r
+ ValueToWrite =\r
+ ((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;\r
+\r
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {\r
+ if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {\r
+ WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);\r
+ }\r
+ }\r
+}\r
+\r
+VOID\r
+QNCSmmClearSourceAndBlock (\r
+ CONST QNC_SMM_SOURCE_DESC *SrcDesc\r
+ )\r
+// GC_TODO: function comment should start with '/*++'\r
+/*\r
+ Sets the source to a 1 or 0 and then waits for it to clear.\r
+ Be very careful when calling this function -- it will not\r
+ ASSERT. An acceptable case to call the function is when\r
+ waiting for the NEWCENTURY_STS bit to clear (which takes\r
+ 3 RTCCLKs).\r
+*/\r
+// GC_TODO: function comment should end with '--*/'\r
+// GC_TODO: function comment is missing 'Routine Description:'\r
+// GC_TODO: function comment is missing 'Arguments:'\r
+// GC_TODO: function comment is missing 'Returns:'\r
+// GC_TODO: SrcDesc - add argument and description to function comment\r
+{\r
+ UINTN loopvar;\r
+ BOOLEAN IsSet;\r
+ BOOLEAN ValueToWrite;\r
+\r
+ ValueToWrite =\r
+ ((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;\r
+\r
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {\r
+\r
+ if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {\r
+ //\r
+ // Write the bit\r
+ //\r
+ WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);\r
+\r
+ //\r
+ // Don't return until the bit actually clears.\r
+ //\r
+ IsSet = TRUE;\r
+ while (IsSet) {\r
+ IsSet = ReadBitDesc (&SrcDesc->Sts[loopvar]);\r
+ //\r
+ // IsSet will eventually clear -- or else we'll have\r
+ // an infinite loop.\r
+ //\r
+ }\r
+ }\r
+ }\r
+}\r