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