PciPlatform.c 9.6 KB

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