]> git.proxmox.com Git - mirror_edk2.git/blobdiff - QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c
QuarkSocPkg: Add new package for Quark SoC X1000
[mirror_edk2.git] / QuarkSocPkg / QuarkNorthCluster / Smm / DxeSmm / QncSmmDispatcher / QNCSmmHelpers.c
diff --git a/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c b/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c
new file mode 100644 (file)
index 0000000..db61029
--- /dev/null
@@ -0,0 +1,373 @@
+/** @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