1 /** @file 2 3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR> 4 5 This program and the accompanying materials are licensed and made available under 7 the terms and conditions of the BSD License that accompanies this distribution. 9 The full text of the license may be found at 11 http://opensource.org/licenses/bsd-license.php. 13 15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 21 23 Module Name: 24 25 26 BoardId.c 27 28 Abstract: 29 30 Initialization for the board ID. 31 32 This code should be common across a chipset family of products. 33 34 35 36 --*/ 37 38 #include "PchRegs.h" 39 #include "PlatformDxe.h" 40 #include <Guid/IdccData.h> 41 #include <Guid/EfiVpdData.h> 42 #include <Protocol/DataHub.h> 43 44 45 extern EFI_GUID mPlatformDriverGuid; 46 47 // 48 // Global module data 49 // 50 UINT32 mBoardId; 51 UINT8 mBoardIdIndex; 52 EFI_BOARD_FEATURES mBoardFeatures; 53 UINT16 mSubsystemDeviceId; 54 UINT16 mSubsystemAudioDeviceId; 55 CHAR8 BoardAaNumber[7]; 56 BOOLEAN mFoundAANum; 57 58 /** 59 60 Write the boardid variable if it does not already exist. 61 62 **/ 63 VOID 64 InitializeBoardId ( 65 ) 66 { 67 68 UINT32 BoardIdBufferSize; 69 EFI_IDCC_BOARD_FORM_FACTOR IdccBoardFormFactor; 70 EFI_DATA_HUB_PROTOCOL *DataHub; 71 EFI_STATUS Status; 72 DMI_DATA DmiDataVariable; 73 UINTN Size; 74 #if defined(DUPLICATE_AA_NO_BASE_ADDR) 75 CHAR8 DuplicateAaNoAscii[sizeof(DmiDataVariable.BaseBoardVersion)]; 76 UINTN iter; 77 #endif 78 #if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0 79 UINT8 Data8; 80 #endif 81 82 // 83 // Update data from the updatable DMI data area 84 // 85 Size = sizeof (DMI_DATA); 86 SetMem(&DmiDataVariable, Size, 0xFF); 87 Status = gRT->GetVariable ( 88 DMI_DATA_NAME, 89 &gDmiDataGuid, 90 NULL, 91 &Size, 92 &DmiDataVariable 93 ); 94 95 #if defined(DUPLICATE_AA_NO_BASE_ADDR) 96 // 97 // Get AA# from flash descriptor region 98 // 99 EfiSetMem(DuplicateAaNoAscii, sizeof(DuplicateAaNoAscii), 0xFF); 100 FlashRead((UINT8 *)(UINTN)DUPLICATE_AA_NO_BASE_ADDR, 101 (UINT8 *)DuplicateAaNoAscii, 102 sizeof(DuplicateAaNoAscii)); 103 104 // 105 // Validate AA# read from VPD 106 // 107 for (iter = 0; iter < sizeof(DuplicateAaNoAscii); iter++) { 108 if ((DuplicateAaNoAscii[iter] != 0xFF) && 109 (DuplicateAaNoAscii[iter] != DmiDataVariable.BaseBoardVersion[iter])) { 110 DmiDataVariable.BaseBoardVersion[iter] = DuplicateAaNoAscii[iter]; 111 } 112 } 113 114 Status = EFI_SUCCESS; 115 #endif 116 117 mFoundAANum = FALSE; 118 119 // 120 // No variable...no copy 121 // 122 if (EFI_ERROR (Status)) { 123 mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the first entry 124 } else { 125 // 126 // This is the correct method of checking for AA#. 127 // 128 CopyMem(&BoardAaNumber, ((((UINT8*)&DmiDataVariable.BaseBoardVersion)+2)), 6); 129 BoardAaNumber[6] = 0; 130 for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) { 131 if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber, BoardAaNumber, 6) == 0) { 132 mFoundAANum = TRUE; 133 break; 134 } 135 } 136 137 if(!mFoundAANum) { 138 // 139 // Add check for AA#'s that is programmed without the AA as leading chars. 140 // 141 CopyMem(&BoardAaNumber, (((UINT8*)&DmiDataVariable.BaseBoardVersion)), 6); 142 BoardAaNumber[6] = 0; 143 for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) { 144 if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber, BoardAaNumber, 6) == 0) { 145 mFoundAANum = TRUE; 146 break; 147 } 148 } 149 } 150 } 151 152 #if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0 153 // 154 // If we can't find the BoardAA# in the table, find BoardId 155 // 156 if (mFoundAANum != TRUE) { 157 // 158 // BoardID BIT Location 159 // 0 GPIO33 (ICH) 160 // 1 GPIO34 (ICH) 161 // 162 Data8 = IoRead8(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2); 163 164 // 165 // BoardId[0] 166 // 167 mBoardId = (UINT32)((Data8 >> 1) & BIT0); 168 // 169 // BoardId[1] 170 // 171 mBoardId |= (UINT32)((Data8 >> 1) & BIT1); 172 173 for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) { 174 if (mBoardIdDecodeTable[mBoardIdIndex].BoardId == mBoardId) { 175 break; 176 } 177 } 178 #endif 179 if (mBoardIdIndex == mBoardIdDecodeTableSize) { 180 mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the first entry 181 } 182 #if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0 183 } 184 #endif 185 186 mBoardFeatures = mBoardIdDecodeTable[mBoardIdIndex].Features; 187 mSubsystemDeviceId = mBoardIdDecodeTable[mBoardIdIndex].SubsystemDeviceId; 188 mSubsystemAudioDeviceId = mBoardIdDecodeTable[mBoardIdIndex].AudioSubsystemDeviceId; 189 190 // 191 // Set the BoardFeatures variable 192 // 193 BoardIdBufferSize = sizeof (mBoardFeatures); 194 gRT->SetVariable ( 195 BOARD_FEATURES_NAME, 196 &gEfiBoardFeaturesGuid, 197 EFI_VARIABLE_NON_VOLATILE | 198 EFI_VARIABLE_BOOTSERVICE_ACCESS | 199 EFI_VARIABLE_RUNTIME_ACCESS, 200 BoardIdBufferSize, 201 &mBoardFeatures 202 ); 203 204 // 205 // Get the Data Hub protocol 206 // 207 Status = gBS->LocateProtocol ( 208 &gEfiDataHubProtocolGuid, 209 NULL, 210 (VOID **) &DataHub 211 ); 212 if (!(EFI_ERROR(Status))) { 213 // 214 // Fill out data 215 // 216 IdccBoardFormFactor.IdccHeader.Type = EFI_IDCC_BOARD_FORM_FACTOR_TYPE; 217 IdccBoardFormFactor.IdccHeader.RecordLength = sizeof(EFI_IDCC_BOARD_FORM_FACTOR); 218 if ((mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_ATX) || (mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX)) { 219 IdccBoardFormFactor.BoardFormFactor = ATX_FORM_FACTOR; // ATX 220 } else { 221 IdccBoardFormFactor.BoardFormFactor = BTX_FORM_FACTOR; // BTX 222 } 223 224 // 225 // Publish the Board Form Factor value for IDCC 226 // 227 Status = DataHub->LogData ( 228 DataHub, 229 &gIdccDataHubGuid, 230 &mPlatformDriverGuid, 231 EFI_DATA_RECORD_CLASS_DATA, 232 &IdccBoardFormFactor, 233 sizeof(EFI_IDCC_BOARD_FORM_FACTOR) 234 ); 235 } 236 } 237 238