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