Home | History | Annotate | Download | only in PciPlatform
      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