• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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,
GetRawImage(IN EFI_GUID * NameGuid,IN OUT VOID ** Buffer,IN OUT UINTN * Size)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 
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)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,
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)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,
GetPlatformPolicy(IN CONST EFI_PCI_PLATFORM_PROTOCOL * This,OUT EFI_PCI_PLATFORM_POLICY * PciPolicy)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
GetPciRom(IN CONST EFI_PCI_PLATFORM_PROTOCOL * This,IN EFI_HANDLE PciHandle,OUT VOID ** RomImage,OUT UINTN * RomSize)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 
PciPlatformDriverEntry(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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