Files
system76-edk2/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c
2019-04-09 10:58:22 -07:00

368 lines
7.1 KiB
C

/** @file
Copyright (c) 2013-2015 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include "QNCSmm.h"
#include "QNCSmmHelpers.h"
//
// #define BIT_ZERO 0x00000001
//
CONST UINT32 BIT_ZERO = 0x00000001;
//
// /////////////////////////////////////////////////////////////////////////////
// SUPPORT / HELPER FUNCTIONS (QNC version-independent)
//
BOOLEAN
CompareEnables (
CONST IN QNC_SMM_SOURCE_DESC *Src1,
CONST IN QNC_SMM_SOURCE_DESC *Src2
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Src1 - GC_TODO: add argument description
Src2 - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
BOOLEAN IsEqual;
UINTN loopvar;
IsEqual = TRUE;
for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
//
// It's okay to compare a NULL bit description to a non-NULL bit description.
// They are unequal and these tests will generate the correct result.
//
if (Src1->En[loopvar].Bit != Src2->En[loopvar].Bit ||
Src1->En[loopvar].Reg.Type != Src2->En[loopvar].Reg.Type ||
Src1->En[loopvar].Reg.Data.raw != Src2->En[loopvar].Reg.Data.raw
) {
IsEqual = FALSE;
break;
//
// out of for loop
//
}
}
return IsEqual;
}
BOOLEAN
CompareStatuses (
CONST IN QNC_SMM_SOURCE_DESC *Src1,
CONST IN QNC_SMM_SOURCE_DESC *Src2
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Src1 - GC_TODO: add argument description
Src2 - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
BOOLEAN IsEqual;
UINTN loopvar;
IsEqual = TRUE;
for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
//
// It's okay to compare a NULL bit description to a non-NULL bit description.
// They are unequal and these tests will generate the correct result.
//
if (Src1->Sts[loopvar].Bit != Src2->Sts[loopvar].Bit ||
Src1->Sts[loopvar].Reg.Type != Src2->Sts[loopvar].Reg.Type ||
Src1->Sts[loopvar].Reg.Data.raw != Src2->Sts[loopvar].Reg.Data.raw
) {
IsEqual = FALSE;
break;
//
// out of for loop
//
}
}
return IsEqual;
}
BOOLEAN
CompareSources (
CONST IN QNC_SMM_SOURCE_DESC *Src1,
CONST IN QNC_SMM_SOURCE_DESC *Src2
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Src1 - GC_TODO: add argument description
Src2 - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
return (BOOLEAN) (CompareEnables (Src1, Src2) && CompareStatuses (Src1, Src2));
}
BOOLEAN
SourceIsActive (
CONST IN QNC_SMM_SOURCE_DESC *Src
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Src - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
BOOLEAN IsActive;
UINTN loopvar;
BOOLEAN SciEn;
IsActive = TRUE;
SciEn = QNCSmmGetSciEn ();
if ((Src->Flags & QNC_SMM_SCI_EN_DEPENDENT) && (SciEn)) {
//
// This source is dependent on SciEn, and SciEn == 1. An ACPI OS is present,
// so we shouldn't do anything w/ this source until SciEn == 0.
//
IsActive = FALSE;
} else {
//
// Read each bit desc from hardware and make sure it's a one
//
for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
if (!IS_BIT_DESC_NULL (Src->En[loopvar])) {
if (ReadBitDesc (&Src->En[loopvar]) == 0) {
IsActive = FALSE;
break;
//
// out of for loop
//
}
}
}
if (IsActive) {
//
// Read each bit desc from hardware and make sure it's a one
//
for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
if (!IS_BIT_DESC_NULL (Src->Sts[loopvar])) {
if (ReadBitDesc (&Src->Sts[loopvar]) == 0) {
IsActive = FALSE;
break;
//
// out of for loop
//
}
}
}
}
}
return IsActive;
}
VOID
QNCSmmEnableSource (
CONST QNC_SMM_SOURCE_DESC *SrcDesc
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
SrcDesc - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
UINTN loopvar;
//
// Set enables to 1 by writing a 1
//
for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
WriteBitDesc (&SrcDesc->En[loopvar], 1);
}
}
QNCSmmClearSource (SrcDesc);
}
VOID
QNCSmmDisableSource (
CONST QNC_SMM_SOURCE_DESC *SrcDesc
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
SrcDesc - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
UINTN loopvar;
for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
WriteBitDesc (&SrcDesc->En[loopvar], 0);
}
}
}
VOID
QNCSmmClearSource (
CONST QNC_SMM_SOURCE_DESC *SrcDesc
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
SrcDesc - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
UINTN loopvar;
BOOLEAN ValueToWrite;
ValueToWrite =
((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;
for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);
}
}
}
VOID
QNCSmmClearSourceAndBlock (
CONST QNC_SMM_SOURCE_DESC *SrcDesc
)
// GC_TODO: function comment should start with '/*++'
/*
Sets the source to a 1 or 0 and then waits for it to clear.
Be very careful when calling this function -- it will not
ASSERT. An acceptable case to call the function is when
waiting for the NEWCENTURY_STS bit to clear (which takes
3 RTCCLKs).
*/
// GC_TODO: function comment should end with '--*/'
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: SrcDesc - add argument and description to function comment
{
UINTN loopvar;
BOOLEAN IsSet;
BOOLEAN ValueToWrite;
ValueToWrite =
((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;
for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
//
// Write the bit
//
WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);
//
// Don't return until the bit actually clears.
//
IsSet = TRUE;
while (IsSet) {
IsSet = ReadBitDesc (&SrcDesc->Sts[loopvar]);
//
// IsSet will eventually clear -- or else we'll have
// an infinite loop.
//
}
}
}
}