audk/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c

374 lines
7.5 KiB
C

/** @file
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
//
// 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.
//
}
}
}
}