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 PciPlatform.c 27 28 Abstract: 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 52 extern PCI_OPTION_ROM_TABLE mPciOptionRomTable[]; 53 extern UINTN mSizeOptionRomTable; 54 55 EFI_PCI_PLATFORM_PROTOCOL mPciPlatform = { 56 PhaseNotify, 57 PlatformPrepController, 58 GetPlatformPolicy, 59 GetPciRom 60 }; 61 62 EFI_HANDLE mPciPlatformHandle = NULL; 63 64 65 SYSTEM_CONFIGURATION mSystemConfiguration; 66 67 EFI_STATUS 68 GetRawImage ( 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 133 EFI_STATUS 134 EFIAPI 135 PhaseNotify ( 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 146 EFI_STATUS 147 EFIAPI 148 PlatformPrepController ( 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 160 EFI_STATUS 161 EFIAPI 162 GetPlatformPolicy ( 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 **/ 184 EFI_STATUS 185 EFIAPI 186 GetPciRom ( 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 **/ 337 EFI_STATUS 338 EFIAPI 339 PciPlatformDriverEntry ( 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