Changes for V4 ============== 1) Remove Unicode character from C source file 2) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode from QuarkPlatformPkg commit to QuarkSocPkg commit Changes for V2 ============== 1) Sync with new APIs in SmmCpuFeaturesLib class 2) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg 3) Remove PCI serial driver from QuarkSocPkg 4) Apply optimizations to MtrrLib from MtrrLib in UefiCpuPkg 5) Convert all UNI files to utf-8 6) Replace tabs with spaces and remove trailing spaces 7) Add License.txt Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19286 6f19259b-4bc3-4df7-8a09-765794883524
374 lines
7.5 KiB
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.
|
|
//
|
|
}
|
|
}
|
|
}
|
|
}
|