/** @file
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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.
Module Name:
BoardId.c
Abstract:
Initialization for the board ID.
This code should be common across a chipset family of products.
--*/
#include "PchRegs.h"
#include "PlatformDxe.h"
#include <Guid/IdccData.h>
#include <Guid/EfiVpdData.h>
#include <Protocol/DataHub.h>
extern EFI_GUID mPlatformDriverGuid;
//
// Global module data
//
UINT32 mBoardId;
UINT8 mBoardIdIndex;
EFI_BOARD_FEATURES mBoardFeatures;
UINT16 mSubsystemDeviceId;
UINT16 mSubsystemAudioDeviceId;
CHAR8 BoardAaNumber[7];
BOOLEAN mFoundAANum;
/**
Write the boardid variable if it does not already exist.
**/
VOID
InitializeBoardId (
)
{
UINT32 BoardIdBufferSize;
EFI_IDCC_BOARD_FORM_FACTOR IdccBoardFormFactor;
EFI_DATA_HUB_PROTOCOL *DataHub;
EFI_STATUS Status;
DMI_DATA DmiDataVariable;
UINTN Size;
#if defined(DUPLICATE_AA_NO_BASE_ADDR)
CHAR8 DuplicateAaNoAscii[sizeof(DmiDataVariable.BaseBoardVersion)];
UINTN iter;
#endif
#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0
UINT8 Data8;
#endif
//
// Update data from the updatable DMI data area
//
Size = sizeof (DMI_DATA);
SetMem(&DmiDataVariable, Size, 0xFF);
Status = gRT->GetVariable (
DMI_DATA_NAME,
&gDmiDataGuid,
NULL,
&Size,
&DmiDataVariable
);
#if defined(DUPLICATE_AA_NO_BASE_ADDR)
//
// Get AA# from flash descriptor region
//
EfiSetMem(DuplicateAaNoAscii, sizeof(DuplicateAaNoAscii), 0xFF);
FlashRead((UINT8 *)(UINTN)DUPLICATE_AA_NO_BASE_ADDR,
(UINT8 *)DuplicateAaNoAscii,
sizeof(DuplicateAaNoAscii));
//
// Validate AA# read from VPD
//
for (iter = 0; iter < sizeof(DuplicateAaNoAscii); iter++) {
if ((DuplicateAaNoAscii[iter] != 0xFF) &&
(DuplicateAaNoAscii[iter] != DmiDataVariable.BaseBoardVersion[iter])) {
DmiDataVariable.BaseBoardVersion[iter] = DuplicateAaNoAscii[iter];
}
}
Status = EFI_SUCCESS;
#endif
mFoundAANum = FALSE;
//
// No variable...no copy
//
if (EFI_ERROR (Status)) {
mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the first entry
} else {
//
// This is the correct method of checking for AA#.
//
CopyMem(&BoardAaNumber, ((((UINT8*)&DmiDataVariable.BaseBoardVersion)+2)), 6);
BoardAaNumber[6] = 0;
for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) {
if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber, BoardAaNumber, 6) == 0) {
mFoundAANum = TRUE;
break;
}
}
if(!mFoundAANum) {
//
// Add check for AA#'s that is programmed without the AA as leading chars.
//
CopyMem(&BoardAaNumber, (((UINT8*)&DmiDataVariable.BaseBoardVersion)), 6);
BoardAaNumber[6] = 0;
for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) {
if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber, BoardAaNumber, 6) == 0) {
mFoundAANum = TRUE;
break;
}
}
}
}
#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0
//
// If we can't find the BoardAA# in the table, find BoardId
//
if (mFoundAANum != TRUE) {
//
// BoardID BIT Location
// 0 GPIO33 (ICH)
// 1 GPIO34 (ICH)
//
Data8 = IoRead8(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2);
//
// BoardId[0]
//
mBoardId = (UINT32)((Data8 >> 1) & BIT0);
//
// BoardId[1]
//
mBoardId |= (UINT32)((Data8 >> 1) & BIT1);
for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) {
if (mBoardIdDecodeTable[mBoardIdIndex].BoardId == mBoardId) {
break;
}
}
#endif
if (mBoardIdIndex == mBoardIdDecodeTableSize) {
mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the first entry
}
#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0
}
#endif
mBoardFeatures = mBoardIdDecodeTable[mBoardIdIndex].Features;
mSubsystemDeviceId = mBoardIdDecodeTable[mBoardIdIndex].SubsystemDeviceId;
mSubsystemAudioDeviceId = mBoardIdDecodeTable[mBoardIdIndex].AudioSubsystemDeviceId;
//
// Set the BoardFeatures variable
//
BoardIdBufferSize = sizeof (mBoardFeatures);
gRT->SetVariable (
BOARD_FEATURES_NAME,
&gEfiBoardFeaturesGuid,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS,
BoardIdBufferSize,
&mBoardFeatures
);
//
// Get the Data Hub protocol
//
Status = gBS->LocateProtocol (
&gEfiDataHubProtocolGuid,
NULL,
(VOID **) &DataHub
);
if (!(EFI_ERROR(Status))) {
//
// Fill out data
//
IdccBoardFormFactor.IdccHeader.Type = EFI_IDCC_BOARD_FORM_FACTOR_TYPE;
IdccBoardFormFactor.IdccHeader.RecordLength = sizeof(EFI_IDCC_BOARD_FORM_FACTOR);
if ((mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_ATX) || (mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX)) {
IdccBoardFormFactor.BoardFormFactor = ATX_FORM_FACTOR; // ATX
} else {
IdccBoardFormFactor.BoardFormFactor = BTX_FORM_FACTOR; // BTX
}
//
// Publish the Board Form Factor value for IDCC
//
Status = DataHub->LogData (
DataHub,
&gIdccDataHubGuid,
&mPlatformDriverGuid,
EFI_DATA_RECORD_CLASS_DATA,
&IdccBoardFormFactor,
sizeof(EFI_IDCC_BOARD_FORM_FACTOR)
);
}
}