1 /** @file
2
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4
5
6 This program and the accompanying materials are licensed and made available under
7
8 the terms and conditions of the BSD License that accompanies this distribution.
9
10 The full text of the license may be found at
11
12 http://opensource.org/licenses/bsd-license.php.
13
14
15
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19
20
21
22
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;
InitializeBoardId()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