1 /** @file
2
3 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 Module Name:
8
9
10 PciPlatform.c
11
12 Abstract:
13 --*/
14
15
16 #include "PciPlatform.h"
17 #include "PchRegs.h"
18 #include "PchAccess.h"
19 #include "VlvCommonDefinitions.h"
20 #include "PlatformBootMode.h"
21
22 #include <Library/BaseLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Protocol/PciIo.h>
25 #include <Guid/SetupVariable.h>
26 #include <Protocol/PciRootBridgeIo.h>
27 #include "SetupMode.h"
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/UefiRuntimeServicesTableLib.h>
30 #include <Library/DebugLib.h>
31 #include <Protocol/FirmwareVolume2.h>
32 #include <Library/HobLib.h>
33 #include <IndustryStandard/Pci22.h>
34
35 extern PCI_OPTION_ROM_TABLE mPciOptionRomTable[];
36 extern UINTN mSizeOptionRomTable;
37
38 EFI_PCI_PLATFORM_PROTOCOL mPciPlatform = {
39 PhaseNotify,
40 PlatformPrepController,
41 GetPlatformPolicy,
42 GetPciRom
43 };
44
45 EFI_HANDLE mPciPlatformHandle = NULL;
46
47
48 SYSTEM_CONFIGURATION mSystemConfiguration;
49
50 EFI_STATUS
GetRawImage(IN EFI_GUID * NameGuid,IN OUT VOID ** Buffer,IN OUT UINTN * Size)51 GetRawImage (
52 IN EFI_GUID *NameGuid,
53 IN OUT VOID **Buffer,
54 IN OUT UINTN *Size
55 )
56 {
57 EFI_STATUS Status;
58 EFI_HANDLE *HandleBuffer;
59 UINTN HandleCount;
60 UINTN Index;
61 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
62 UINT32 AuthenticationStatus;
63
64 Status = gBS->LocateHandleBuffer (
65 ByProtocol,
66 &gEfiFirmwareVolume2ProtocolGuid,
67 NULL,
68 &HandleCount,
69 &HandleBuffer
70 );
71 if (EFI_ERROR (Status) || HandleCount == 0) {
72 return EFI_NOT_FOUND;
73 }
74
75 //
76 // Find desired image in all Fvs
77 //
78 for (Index = 0; Index < HandleCount; Index++) {
79 Status = gBS->HandleProtocol(
80 HandleBuffer[Index],
81 &gEfiFirmwareVolume2ProtocolGuid,
82 (VOID **) &Fv
83 );
84
85 if ( EFI_ERROR ( Status ) ) {
86 return EFI_LOAD_ERROR;
87 }
88
89 //
90 // Try a raw file
91 //
92 *Buffer = NULL;
93 *Size = 0;
94 Status = Fv->ReadSection (
95 Fv,
96 NameGuid,
97 EFI_SECTION_RAW,
98 0,
99 Buffer,
100 Size,
101 &AuthenticationStatus
102 );
103
104 if ( !EFI_ERROR ( Status )) {
105 break;
106 }
107 }
108
109 if ( Index >= HandleCount ) {
110 return EFI_NOT_FOUND;
111 }
112
113 return EFI_SUCCESS;
114 }
115
116 EFI_STATUS
117 EFIAPI
PhaseNotify(IN EFI_PCI_PLATFORM_PROTOCOL * This,IN EFI_HANDLE HostBridge,IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase)118 PhaseNotify (
119 IN EFI_PCI_PLATFORM_PROTOCOL *This,
120 IN EFI_HANDLE HostBridge,
121 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
122 IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
123 )
124 {
125 return EFI_UNSUPPORTED;
126 }
127
128
129 EFI_STATUS
130 EFIAPI
PlatformPrepController(IN EFI_PCI_PLATFORM_PROTOCOL * This,IN EFI_HANDLE HostBridge,IN EFI_HANDLE RootBridge,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase)131 PlatformPrepController (
132 IN EFI_PCI_PLATFORM_PROTOCOL *This,
133 IN EFI_HANDLE HostBridge,
134 IN EFI_HANDLE RootBridge,
135 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
136 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,
137 IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
138 )
139 {
140 return EFI_UNSUPPORTED;
141 }
142
143 EFI_STATUS
144 EFIAPI
GetPlatformPolicy(IN CONST EFI_PCI_PLATFORM_PROTOCOL * This,OUT EFI_PCI_PLATFORM_POLICY * PciPolicy)145 GetPlatformPolicy (
146 IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
147 OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
148 )
149 {
150 *PciPolicy = EFI_RESERVE_VGA_IO_ALIAS;
151 return EFI_SUCCESS;
152 }
153
154 /**
155 GetPciRom from platform specific location for specific PCI device
156
157 @param This Protocol instance
158 @param PciHandle Identify the specific PCI devic
159 @param RomImage Returns the ROM Image memory location
160 @param RomSize Returns Rom Image size
161
162 @retval EFI_SUCCESS
163 @retval EFI_NOT_FOUND
164 @retval EFI_OUT_OF_RESOURCES
165
166 **/
167 EFI_STATUS
168 EFIAPI
GetPciRom(IN CONST EFI_PCI_PLATFORM_PROTOCOL * This,IN EFI_HANDLE PciHandle,OUT VOID ** RomImage,OUT UINTN * RomSize)169 GetPciRom (
170 IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
171 IN EFI_HANDLE PciHandle,
172 OUT VOID **RomImage,
173 OUT UINTN *RomSize
174 )
175 {
176 EFI_STATUS Status;
177 EFI_PCI_IO_PROTOCOL *PciIo;
178 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
179 UINTN Segment;
180 UINTN Bus;
181 UINTN Device;
182 UINTN Function;
183 UINT16 VendorId;
184 UINT16 DeviceId;
185 UINT16 DeviceClass;
186 UINTN TableIndex;
187 UINT8 Data8;
188 BOOLEAN MfgMode;
189 EFI_PLATFORM_SETUP_ID *BootModeBuffer;
190
191 EFI_PEI_HOB_POINTERS GuidHob;
192
193 MfgMode = FALSE;
194
195 //
196 // Check if system is in manufacturing mode.
197 //
198 GuidHob.Raw = GetHobList ();
199 if (GuidHob.Raw == NULL) {
200 return EFI_NOT_FOUND;
201 }
202
203 if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformBootModeGuid, GuidHob.Raw)) != NULL) {
204 BootModeBuffer = GET_GUID_HOB_DATA (GuidHob.Guid);
205 if (!CompareMem (&BootModeBuffer->SetupName, MANUFACTURE_SETUP_NAME,
206 StrSize (MANUFACTURE_SETUP_NAME)))
207 {
208 //
209 // System is in manufacturing mode.
210 //
211 MfgMode = TRUE;
212 }
213 }
214
215 Status = gBS->HandleProtocol (
216 PciHandle,
217 &gEfiPciIoProtocolGuid,
218 (void **)&PciIo
219 );
220 if (EFI_ERROR (Status)) {
221 return EFI_NOT_FOUND;
222 }
223
224 Status = gBS->LocateProtocol (
225 &gEfiPciRootBridgeIoProtocolGuid,
226 NULL,
227 (void **)&PciRootBridgeIo
228 );
229
230 if (EFI_ERROR (Status)) {
231 return EFI_NOT_FOUND;
232 }
233
234 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0x0A, 1, &DeviceClass);
235
236 PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
237
238 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0, 1, &VendorId);
239
240 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 2, 1, &DeviceId);
241
242 //
243 // WA for PCIe SATA card (SYBA SY-PEX400-40)
244 //
245 if ((VendorId == 0x1B21) && (DeviceId == 0x0612)) {
246 Data8 = 0x07;
247 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 4, 1, &Data8);
248 }
249
250 //
251 // Do not run RAID or AHCI Option ROM if IDE
252 //
253 if (DeviceClass == ((PCI_CLASS_MASS_STORAGE << 8 ) | PCI_CLASS_MASS_STORAGE_IDE)) {
254 return EFI_NOT_FOUND;
255 }
256
257 //
258 // Run PXE ROM only if Boot network is enabled and not in MFG mode
259 //
260 if (DeviceClass == ((PCI_CLASS_NETWORK << 8 ) | PCI_CLASS_NETWORK_ETHERNET)) {
261 if (((mSystemConfiguration.BootNetwork == 0) && (MfgMode == FALSE )) || (mSystemConfiguration.FastBoot == 1)) {
262 return EFI_NOT_FOUND;
263 }
264 }
265
266 //
267 // Loop through table of Onboard option rom descriptions
268 //
269 for (TableIndex = 0; mPciOptionRomTable[TableIndex].VendorId != 0xffff; TableIndex++) {
270
271 //
272 // See if the PCI device specified by PciHandle matches at device in mPciOptionRomTable
273 //
274 if (VendorId != mPciOptionRomTable[TableIndex].VendorId ||
275 DeviceId != mPciOptionRomTable[TableIndex].DeviceId ||
276 ((DeviceClass == ((PCI_CLASS_NETWORK << 8 ) | PCI_CLASS_NETWORK_ETHERNET)) &&
277 (mPciOptionRomTable[TableIndex].Flag != mSystemConfiguration.BootNetwork)) ) {
278 continue;
279 }
280
281 Status = GetRawImage(
282 &mPciOptionRomTable[TableIndex].FileName,
283 RomImage,
284 RomSize
285 );
286
287 if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_VLV_A0)) {
288 *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_VLV_A0;
289 }
290
291 if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_II)) {
292 *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_II;
293 }
294
295 if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_0BE4)) {
296 *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_0BE4;
297 }
298
299 if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_QS)) {
300 *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_QS;
301 }
302
303
304 if (EFI_ERROR (Status)) {
305 continue;
306 }
307 return EFI_SUCCESS;
308 }
309
310 return EFI_NOT_FOUND;
311 }
312
313 /**
314
315 @param (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
316
317 @retval EFI_STATUS
318
319 **/
320 EFI_STATUS
321 EFIAPI
PciPlatformDriverEntry(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)322 PciPlatformDriverEntry (
323 IN EFI_HANDLE ImageHandle,
324 IN EFI_SYSTEM_TABLE *SystemTable
325 )
326 {
327 EFI_STATUS Status;
328 UINTN VarSize;
329
330 VarSize = sizeof(SYSTEM_CONFIGURATION);
331 Status = gRT->GetVariable(
332 L"Setup",
333 &gEfiNormalSetupGuid,
334 NULL,
335 &VarSize,
336 &mSystemConfiguration
337 );
338 if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
339 //The setup variable is corrupted
340 VarSize = sizeof(SYSTEM_CONFIGURATION);
341 Status = gRT->GetVariable(
342 L"SetupRecovery",
343 &gEfiNormalSetupGuid,
344 NULL,
345 &VarSize,
346 &mSystemConfiguration
347 );
348 ASSERT_EFI_ERROR (Status);
349 }
350
351 //
352 // Install on a new handle
353 //
354 Status = gBS->InstallProtocolInterface (
355 &mPciPlatformHandle,
356 &gEfiPciPlatformProtocolGuid,
357 EFI_NATIVE_INTERFACE,
358 &mPciPlatform
359 );
360
361 return Status;
362 }
363
364
365