]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
Clean up GCC build.
[mirror_edk2.git] / Vlv2TbltDevicePkg / VlvPlatformInitDxe / IgdOpRegion.c
CommitLineData
3cbfba02
DW
1\r
2/*++\r
3\r
4Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved\r
5 \r\r
6 This program and the accompanying materials are licensed and made available under\r\r
7 the terms and conditions of the BSD License that accompanies this distribution. \r\r
8 The full text of the license may be found at \r\r
9 http://opensource.org/licenses/bsd-license.php. \r\r
10 \r\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r\r
13 \r\r
14\r
15\r
16Module Name:\r
17\r
18 IgdOpRegion.c\r
19\r
20Abstract:\r
21\r
22 This is part of the implementation of an Intel Graphics drivers OpRegion /\r
23 Software SCI interface between system BIOS, ASL code, and Graphics drivers.\r
24 The code in this file will load the driver and initialize the interface\r
25\r
26 Supporting Specifiction: OpRegion / Software SCI SPEC 0.70\r
27\r
28 Acronyms:\r
29 IGD: Internal Graphics Device\r
30 NVS: ACPI Non Volatile Storage\r
31 OpRegion: ACPI Operational Region\r
32 VBT: Video BIOS Table (OEM customizable data)\r
33\r
34--*/\r
35\r
36//\r
37// Include files\r
38//\r
39\r
40\r
41#include "IgdOpRegion.h"\r
42#include "VlvPlatformInit.h"\r
43#include <FrameworkDxe.h>\r
44#include <Uefi.h>\r
45#include <PchRegs.h>\r
46\r
47#include <Guid/DataHubRecords.h>\r
48\r
49#include <Protocol/IgdOpRegion.h>\r
50#include <Protocol/FrameworkHii.h>\r
51#include <Protocol/FirmwareVolume.h>\r
52#include <Protocol/PlatformGopPolicy.h>\r
53#include <Protocol/PciIo.h>\r
54#include <Protocol/CpuIo.h>\r
55#include <Protocol/GlobalNvsArea.h>\r
56#include <Protocol/DxeSmmReadyToLock.h>\r
57#include <Protocol/PciRootBridgeIo.h>\r
58\r
59#include <Library/MemoryAllocationLib.h>\r
60#include <Library/BaseLib.h>\r
61#include <Library/S3BootScriptLib.h>\r
62#include <Library/IoLib.h>\r
63#include <Library/DevicePathLib.h>\r
64#include <Protocol/DriverBinding.h>\r
65#include <Library/PrintLib.h>\r
66#include <Library/BaseMemoryLib.h>\r
67\r
68\r
69\r
70UINT8 gSVER[12] = "Intel";\r
71\r
72extern DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicy;\r
73\r
74//\r
75// Global variables\r
76//\r
77\r
78IGD_OPREGION_PROTOCOL mIgdOpRegion;\r
79EFI_GUID mMiscSubClass = EFI_MISC_SUBCLASS_GUID;\r
80EFI_EVENT mConOutEvent;\r
81EFI_EVENT mSetGOPverEvent;\r
82VOID *mConOutReg;\r
83\r
84#define DEFAULT_FORM_BUFFER_SIZE 0xFFFF\r
85#ifndef ECP_FLAG\r
86#if 0\r
87/**\r
88\r
89 Get the HII protocol interface\r
90\r
91 @param Hii HII protocol interface\r
92\r
93 @retval Status code\r
94\r
95**/\r
96static\r
97EFI_STATUS\r
98GetHiiInterface (\r
99 OUT EFI_HII_PROTOCOL **Hii\r
100 )\r
101{\r
102 EFI_STATUS Status;\r
103\r
104 //\r
105 // There should only be one HII protocol\r
106 //\r
107 Status = gBS->LocateProtocol (\r
108 &gEfiHiiProtocolGuid,\r
109 NULL,\r
110 (VOID **) Hii\r
111 );\r
112\r
113 return Status;;\r
114}\r
115#endif\r
116#endif\r
117\r
118/**\r
119\r
120 Get VBT data.\r
121\r
122 @param[in] VbtFileBuffer Pointer to VBT data buffer.\r
123\r
124 @retval EFI_SUCCESS VBT data was returned.\r
125 @retval EFI_NOT_FOUND VBT data not found.\r
126 @exception EFI_UNSUPPORTED Invalid signature in VBT data.\r
127\r
128**/\r
129EFI_STATUS\r
130GetIntegratedIntelVbtPtr (\r
131 OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer\r
132 )\r
133{\r
134 EFI_STATUS Status;\r
135 EFI_PHYSICAL_ADDRESS VbtAddress = 0;\r
136 UINT32 VbtSize = 0;\r
137 UINTN FvProtocolCount;\r
138 EFI_HANDLE *FvHandles;\r
139 EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;\r
140 UINTN Index;\r
141 UINT32 AuthenticationStatus;\r
142\r
143 UINT8 *Buffer;\r
144 UINTN VbtBufferSize = 0;\r
145\r
146 Buffer = 0;\r
147 FvHandles = NULL;\r
148 *VbtFileBuffer = NULL;\r
149 Status = gBS->LocateHandleBuffer (\r
150 ByProtocol,\r
151 &gEfiFirmwareVolumeProtocolGuid,\r
152 NULL,\r
153 &FvProtocolCount,\r
154 &FvHandles\r
155 );\r
156\r
157 if (!EFI_ERROR (Status)) {\r
158 for (Index = 0; Index < FvProtocolCount; Index++) {\r
159 Status = gBS->HandleProtocol (\r
160 FvHandles[Index],\r
161 &gEfiFirmwareVolumeProtocolGuid,\r
162 (VOID **) &Fv\r
163 );\r
164 VbtBufferSize = 0;\r
165 Status = Fv->ReadSection (\r
166 Fv,\r
167 &gBmpImageGuid,\r
168 EFI_SECTION_RAW,\r
169 0,\r
170 (void **)&Buffer,\r
171 &VbtBufferSize,\r
172 &AuthenticationStatus\r
173 );\r
174\r
175 if (!EFI_ERROR (Status)) {\r
176 VbtAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
177 VbtSize = (UINT32)VbtBufferSize;\r
178 Status = EFI_SUCCESS;\r
179 break;\r
180 }\r
181 }\r
182 } else {\r
183 Status = EFI_NOT_FOUND;\r
184 }\r
185\r
186 if (FvHandles != NULL) {\r
187 FreePool(FvHandles);\r
188 FvHandles = NULL;\r
189 }\r
190\r
191\r
192 //\r
193 // Check VBT signature\r
194 //\r
195 *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;\r
196 if (*VbtFileBuffer != NULL) {\r
197 if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE) {\r
198 if (*VbtFileBuffer != NULL) {\r
199 *VbtFileBuffer = NULL;\r
200 }\r
201 return EFI_UNSUPPORTED;\r
202 }\r
203 //\r
204 // Check VBT size\r
205 //\r
206 if ((*VbtFileBuffer)->HeaderVbtSize > VbtBufferSize) {\r
207 (*VbtFileBuffer)->HeaderVbtSize = (UINT16) VbtBufferSize;\r
208 }\r
209 }\r
210\r
211 return EFI_SUCCESS;\r
212}\r
213\r
214//\r
215// Function implementations.\r
216//\r
217/**\r
218\r
219 Get a pointer to an uncompressed image of the Intel video BIOS.\r
220\r
221 Note: This function would only be called if the video BIOS at 0xC000 is\r
222 missing or not an Intel video BIOS. It may not be an Intel video BIOS\r
223 if the Intel graphic contoller is considered a secondary adapter.\r
224\r
225\r
226 @param VBiosROMImage Pointer to an uncompressed Intel video BIOS. This pointer must\r
227 be set to NULL if an uncompressed image of the Intel Video BIOS\r
228 is not obtainable.\r
229\r
230\r
231 @retval EFI_SUCCESS VBiosPtr is updated.\r
232\r
233**/\r
234EFI_STATUS\r
235GetIntegratedIntelVBiosPtr (\r
236 INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage\r
237 )\r
238{\r
239 EFI_HANDLE *HandleBuffer;\r
240 UINTN HandleCount;\r
241 UINTN Index;\r
242 INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;\r
243 EFI_STATUS Status;\r
244 EFI_PCI_IO_PROTOCOL *PciIo;\r
245 INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;\r
246\r
247 //\r
248 // Set as if an umcompressed Intel video BIOS image was not obtainable.\r
249 //\r
250 VBiosRomImage = NULL;\r
251 *VBiosImage = NULL;\r
252\r
253 //\r
254 // Get all PCI IO protocols\r
255 //\r
256 Status = gBS->LocateHandleBuffer (\r
257 ByProtocol,\r
258 &gEfiPciIoProtocolGuid,\r
259 NULL,\r
260 &HandleCount,\r
261 &HandleBuffer\r
262 );\r
263 ASSERT_EFI_ERROR (Status);\r
264\r
265 //\r
266 // Find the video BIOS by checking each PCI IO handle for an Intel video\r
267 // BIOS OPROM.\r
268 //\r
269 for (Index = 0; Index < HandleCount; Index++) {\r
270 Status = gBS->HandleProtocol (\r
271 HandleBuffer[Index],\r
272 &gEfiPciIoProtocolGuid,\r
273 (void **)&PciIo\r
274 );\r
275 ASSERT_EFI_ERROR (Status);\r
276\r
277 VBiosRomImage = PciIo->RomImage;\r
278\r
279 //\r
280 // If this PCI device doesn't have a ROM image, skip to the next device.\r
281 //\r
282 if (!VBiosRomImage) {\r
283 continue;\r
284 }\r
285\r
286 //\r
287 // Get pointer to PCIR structure\r
288 //\r
289 PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *) VBiosRomImage + VBiosRomImage->PcirOffset);\r
290\r
291 //\r
292 // Check if we have an Intel video BIOS OPROM.\r
293 //\r
294 if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&\r
295 (PcirBlockPtr->VendorId == IGD_VID) &&\r
296 (PcirBlockPtr->ClassCode[0] == 0x00) &&\r
297 (PcirBlockPtr->ClassCode[1] == 0x00) &&\r
298 (PcirBlockPtr->ClassCode[2] == 0x03)\r
299 ) {\r
300 //\r
301 // Found Intel video BIOS.\r
302 //\r
303 *VBiosImage = VBiosRomImage;\r
304 return EFI_SUCCESS;\r
305 }\r
306 }\r
307\r
308 //\r
309 // No Intel video BIOS found.\r
310 //\r
311\r
312 //\r
313 // Free any allocated buffers\r
314 //\r
315 return EFI_UNSUPPORTED;\r
316}\r
317\r
318EFI_STATUS\r
319SearchChildHandle(\r
320 EFI_HANDLE Father,\r
321 EFI_HANDLE *Child\r
322 )\r
323{\r
324 EFI_STATUS Status;\r
325 UINTN HandleIndex;\r
326 EFI_GUID **ProtocolGuidArray = NULL;\r
327 UINTN ArrayCount;\r
328 UINTN ProtocolIndex;\r
329 UINTN OpenInfoCount;\r
330 UINTN OpenInfoIndex;\r
331 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL;\r
332 UINTN mHandleCount;\r
333 EFI_HANDLE *mHandleBuffer= NULL;\r
334\r
335 //\r
336 // Retrieve the list of all handles from the handle database\r
337 //\r
338 Status = gBS->LocateHandleBuffer (\r
339 AllHandles,\r
340 NULL,\r
341 NULL,\r
342 &mHandleCount,\r
343 &mHandleBuffer\r
344 );\r
345\r
346 for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {\r
347 //\r
348 // Retrieve the list of all the protocols on each handle\r
349 //\r
350 Status = gBS->ProtocolsPerHandle (\r
351 mHandleBuffer[HandleIndex],\r
352 &ProtocolGuidArray,\r
353 &ArrayCount\r
354 );\r
355 if (!EFI_ERROR (Status)) {\r
356 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
357 Status = gBS->OpenProtocolInformation (\r
358 mHandleBuffer[HandleIndex],\r
359 ProtocolGuidArray[ProtocolIndex],\r
360 &OpenInfo,\r
361 &OpenInfoCount\r
362 );\r
363 if (!EFI_ERROR (Status)) {\r
364 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
365 if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {\r
366 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
367 *Child = mHandleBuffer[HandleIndex];\r
368 Status = EFI_SUCCESS;\r
369 goto TryReturn;\r
370 }\r
371 }\r
372 }\r
373 Status = EFI_NOT_FOUND;\r
374 }\r
375 }\r
376 if(OpenInfo != NULL) {\r
377 FreePool(OpenInfo);\r
378 OpenInfo = NULL;\r
379 }\r
380 }\r
381 FreePool (ProtocolGuidArray);\r
382 ProtocolGuidArray = NULL;\r
383 }\r
384TryReturn:\r
385 if(OpenInfo != NULL) {\r
386 FreePool (OpenInfo);\r
387 OpenInfo = NULL;\r
388 }\r
389 if(ProtocolGuidArray != NULL) {\r
390 FreePool(ProtocolGuidArray);\r
391 ProtocolGuidArray = NULL;\r
392 }\r
393 if(mHandleBuffer != NULL) {\r
394 FreePool (mHandleBuffer);\r
395 mHandleBuffer = NULL;\r
396 }\r
397 return Status;\r
398}\r
399\r
400EFI_STATUS\r
401JudgeHandleIsPCIDevice(\r
402 EFI_HANDLE Handle,\r
403 UINT8 Device,\r
404 UINT8 Funs\r
405 )\r
406{\r
407 EFI_STATUS Status;\r
408 EFI_DEVICE_PATH *DPath;\r
409 EFI_DEVICE_PATH *DevicePath;\r
410\r
411 Status = gBS->HandleProtocol (\r
412 Handle,\r
413 &gEfiDevicePathProtocolGuid,\r
414 (VOID **) &DPath\r
415 );\r
416 if(!EFI_ERROR(Status)) {\r
417 DevicePath = DPath;\r
418 while(!IsDevicePathEnd(DPath)) {\r
419 if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) {\r
420 PCI_DEVICE_PATH *PCIPath;\r
421\r
422 PCIPath = (PCI_DEVICE_PATH*) DPath;\r
423 DPath = NextDevicePathNode(DPath);\r
424 if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) {\r
425 return EFI_SUCCESS;\r
426 }\r
427 } else {\r
428 DPath = NextDevicePathNode(DPath);\r
429 }\r
430 }\r
431 }\r
432 return EFI_UNSUPPORTED;\r
433}\r
434\r
435EFI_STATUS\r
436GetDriverName(\r
437 EFI_HANDLE Handle,\r
438 CHAR16 *GopVersion\r
439 )\r
440{\r
441 EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL;\r
442 EFI_STATUS Status;\r
443 UINT32 Version;\r
444 UINT16 *Ptr;\r
445\r
446 Status = gBS->OpenProtocol(\r
447 Handle,\r
448 &gEfiDriverBindingProtocolGuid,\r
449 (VOID**)&BindHandle,\r
450 NULL,\r
451 NULL,\r
452 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
453 );\r
454 if (EFI_ERROR(Status)) {\r
455 return EFI_NOT_FOUND;\r
456 }\r
457\r
458 Version = BindHandle->Version;\r
459 Ptr = (UINT16*)&Version;\r
460 UnicodeSPrint(GopVersion, 40, L"7.0.%04d", *(Ptr));\r
461 return EFI_SUCCESS;\r
462}\r
463\r
464EFI_STATUS\r
465GetGOPDriverVersion(\r
466 CHAR16 *GopVersion\r
467 )\r
468{\r
469 UINTN HandleCount;\r
470 EFI_HANDLE *Handles= NULL;\r
471 UINTN Index;\r
472 EFI_STATUS Status;\r
473 EFI_HANDLE Child = 0;\r
474\r
475 Status = gBS->LocateHandleBuffer(\r
476 ByProtocol,\r
477 &gEfiDriverBindingProtocolGuid,\r
478 NULL,\r
479 &HandleCount,\r
480 &Handles\r
481 );\r
482 for (Index = 0; Index < HandleCount ; Index++) {\r
483 Status = SearchChildHandle(Handles[Index], &Child);\r
484 if(!EFI_ERROR(Status)) {\r
485 Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);\r
486 if(!EFI_ERROR(Status)) {\r
487 return GetDriverName(Handles[Index], GopVersion);\r
488 }\r
489 }\r
490 }\r
491 return EFI_UNSUPPORTED;\r
492}\r
493\r
494\r
495/**\r
496 Get Intel GOP driver version and copy it into IGD OpRegion GVER. This version\r
497 is picked up by IGD driver and displayed in CUI.\r
498\r
499 @param Event A pointer to the Event that triggered the callback.\r
500 @param Context A pointer to private data registered with the callback function.\r
501\r
502 @retval EFI_SUCCESS Video BIOS VBT information returned.\r
503 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).\r
504\r
505**/\r
506EFI_STATUS\r
507EFIAPI\r
508SetGOPVersionCallback (\r
509 IN EFI_EVENT Event,\r
510 IN VOID *Context\r
511 )\r
512{\r
513 CHAR16 GopVersion[16] = {0};\r
514 EFI_STATUS Status;\r
515\r
516 Status = GetGOPDriverVersion(GopVersion);\r
517 if(!EFI_ERROR(Status)) {\r
518 StrCpy((CHAR16*)&(mIgdOpRegion.OpRegion->Header.GOPV[0]), GopVersion);\r
519 return Status;\r
520 }\r
521 return EFI_UNSUPPORTED;\r
522}\r
523\r
524/**\r
525 Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).\r
526 The VBT (Video BIOS Table) is a block of customizable data that is built\r
527 within the video BIOS and edited by customers.\r
528\r
529 @param Event A pointer to the Event that triggered the callback.\r
530 @param Context A pointer to private data registered with the callback function.\r
531\r
532 @retval EFI_SUCCESS Video BIOS VBT information returned.\r
533 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).\r
534\r
535**/\r
536EFI_STATUS\r
537GetVBiosVbtCallback (\r
538 IN EFI_EVENT Event,\r
539 IN VOID *Context\r
540 )\r
541{\r
542 INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;\r
543 UINT16 PciVenderId;\r
544 UINT16 PciDeviceId;\r
545 INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;\r
546 VBIOS_VBT_STRUCTURE *VBiosVbtPtr;\r
547 VBIOS_VBT_STRUCTURE *VbtFileBuffer = NULL;\r
548\r
549 VBiosPtr = (INTEL_VBIOS_OPTION_ROM_HEADER *)(UINTN)(VBIOS_LOCATION_PRIMARY);\r
550 PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr + VBiosPtr->PcirOffset);\r
551 PciVenderId = PcirBlockPtr->VendorId;\r
552 PciDeviceId = PcirBlockPtr->DeviceId;\r
553\r
554 //\r
555 // If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get\r
556 // the integrated Intel video BIOS (must be uncompressed).\r
557 //\r
558 if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != IGD_VID) || (PciDeviceId != IGD_DID_VLV)) {\r
559 GetIntegratedIntelVBiosPtr (&VBiosPtr);\r
560\r
561 if(VBiosPtr) {\r
562 //\r
563 // Video BIOS found.\r
564 //\r
565 PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr + VBiosPtr->PcirOffset);\r
566 PciVenderId = PcirBlockPtr->VendorId;\r
567 if( (VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != IGD_VID)) {\r
568 //\r
569 // Intel video BIOS not found.\r
570 //\r
571 VBiosVbtPtr = NULL;\r
572 return EFI_UNSUPPORTED;\r
573 }\r
574 } else {\r
575 //\r
576 // No Video BIOS found, try to get VBT from FV.\r
577 //\r
578 GetIntegratedIntelVbtPtr (&VbtFileBuffer);\r
579 if (VbtFileBuffer != NULL) {\r
580 //\r
581 // Video BIOS not found, use VBT from FV\r
582 //\r
583 DEBUG ((EFI_D_ERROR, "VBT data found\n"));\r
584 (gBS->CopyMem) (\r
585 mIgdOpRegion.OpRegion->VBT.GVD1,\r
586 VbtFileBuffer,\r
587 VbtFileBuffer->HeaderVbtSize\r
588 );\r
589 FreePool (VbtFileBuffer);\r
590 return EFI_SUCCESS;\r
591 }\r
592 }\r
593 if ((VBiosPtr == NULL) ) {\r
594 //\r
595 // Intel video BIOS not found.\r
596 //\r
597 VBiosVbtPtr = NULL;\r
598 return EFI_UNSUPPORTED;\r
599 }\r
600 }\r
601\r
602 DEBUG ((EFI_D_ERROR, "VBIOS found at 0x%X\n", VBiosPtr));\r
603 VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->VbtOffset);\r
604\r
605 if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {\r
606 return EFI_UNSUPPORTED;\r
607 }\r
608\r
609 //\r
610 // Initialize Video BIOS version with its build number.\r
611 //\r
612 mIgdOpRegion.OpRegion->Header.VVER[0] = VBiosVbtPtr->CoreBlockBiosBuild[0];\r
613 mIgdOpRegion.OpRegion->Header.VVER[1] = VBiosVbtPtr->CoreBlockBiosBuild[1];\r
614 mIgdOpRegion.OpRegion->Header.VVER[2] = VBiosVbtPtr->CoreBlockBiosBuild[2];\r
615 mIgdOpRegion.OpRegion->Header.VVER[3] = VBiosVbtPtr->CoreBlockBiosBuild[3];\r
616 (gBS->CopyMem) (\r
617 mIgdOpRegion.OpRegion->VBT.GVD1,\r
618 VBiosVbtPtr,\r
619 VBiosVbtPtr->HeaderVbtSize\r
620 );\r
621\r
622 //\r
623 // Return final status\r
624 //\r
625 return EFI_SUCCESS;\r
626}\r
627\r
628/**\r
629 Graphics OpRegion / Software SCI driver installation function.\r
630\r
631 @param ImageHandle Handle for this drivers loaded image protocol.\r
632 @param SystemTable EFI system table.\r
633\r
634 @retval EFI_SUCCESS The driver installed without error.\r
635 @retval EFI_ABORTED The driver encountered an error and could not complete\r
636 installation of the ACPI tables.\r
637\r
638**/\r
639EFI_STATUS\r
640IgdOpRegionInit (\r
641 void\r
642 )\r
643{\r
644 EFI_HANDLE Handle;\r
645 EFI_STATUS Status;\r
646 EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea;\r
647 UINT32 DwordData;\r
648 EFI_CPU_IO_PROTOCOL *CpuIo;\r
649 UINT16 Data16;\r
650 UINT16 AcpiBase;\r
651 VOID *gConOutNotifyReg;\r
652\r
653\r
654 //\r
655 // Locate the Global NVS Protocol.\r
656 //\r
657 Status = gBS->LocateProtocol (\r
658 &gEfiGlobalNvsAreaProtocolGuid,\r
659 NULL,\r
660 (void **)&GlobalNvsArea\r
661 );\r
662 ASSERT_EFI_ERROR (Status);\r
663\r
664 //\r
665 // Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize\r
666 // the first 1K, and set the IGD OpRegion pointer in the Global NVS\r
667 // area structure.\r
668 //\r
669 Status = (gBS->AllocatePool) (\r
670 EfiACPIMemoryNVS,\r
671 sizeof (IGD_OPREGION_STRUC),\r
672 (void **)&mIgdOpRegion.OpRegion\r
673 );\r
674 ASSERT_EFI_ERROR (Status);\r
675 (gBS->SetMem) (\r
676 mIgdOpRegion.OpRegion,\r
677 sizeof (IGD_OPREGION_STRUC),\r
678 0\r
679 );\r
680 GlobalNvsArea->Area->IgdOpRegionAddress = (UINT32)(UINTN)(mIgdOpRegion.OpRegion);\r
681\r
682 //\r
683 // If IGD is disabled return\r
684 //\r
685 if (IgdMmPci32 (0) == 0xFFFFFFFF) {\r
686 return EFI_SUCCESS;\r
687 }\r
688\r
689 //\r
690 // Initialize OpRegion Header\r
691 //\r
692\r
693 (gBS->CopyMem) (\r
694 mIgdOpRegion.OpRegion->Header.SIGN,\r
695 HEADER_SIGNATURE,\r
696 sizeof(HEADER_SIGNATURE)\r
697 );\r
698\r
699\r
700 //\r
701 // Set OpRegion Size in KBs\r
702 //\r
703 mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE/1024;\r
704\r
705 //\r
706 // FIXME: Need to check Header OVER Field and the supported version.\r
707 //\r
708 mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64 (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));\r
709#ifdef ECP_FLAG\r
710 CopyMem(mIgdOpRegion.OpRegion->Header.SVER, gSVER, sizeof(gSVER));\r
711#else\r
712 gBS->CopyMem(\r
713 mIgdOpRegion.OpRegion->Header.SVER,\r
714 gSVER,\r
715 sizeof(gSVER)\r
716 );\r
717#endif\r
718 DEBUG ((EFI_D_ERROR, "System BIOS ID is %a\n", mIgdOpRegion.OpRegion->Header.SVER));\r
719\r
720\r
721 mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;\r
722\r
723 if( 1 == DxePlatformSaPolicy->IdleReserve) {\r
724 mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion->Header.PCON & 0xFFFC) | BIT1;\r
725 } else {\r
726 mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion->Header.PCON & 0xFFFC) | (BIT1 | BIT0);\r
727 }\r
728\r
729 //\r
730 //For graphics driver to identify if LPE Audio/HD Audio is enabled on the platform\r
731 //\r
732 mIgdOpRegion.OpRegion->Header.PCON &= AUDIO_TYPE_SUPPORT_MASK;\r
733 mIgdOpRegion.OpRegion->Header.PCON &= AUDIO_TYPE_FIELD_MASK;\r
734 if ( 1 == DxePlatformSaPolicy->AudioTypeSupport ) {\r
735 mIgdOpRegion.OpRegion->Header.PCON = HD_AUDIO_SUPPORT;\r
736 mIgdOpRegion.OpRegion->Header.PCON |= AUDIO_TYPE_FIELD_VALID;\r
737 }\r
738\r
739 //\r
740 // Initialize OpRegion Mailbox 1 (Public ACPI Methods).\r
741 //\r
742 //<TODO> The initial setting of mailbox 1 fields is implementation specific.\r
743 // Adjust them as needed many even coming from user setting in setup.\r
744 //\r
745 //Workaround to solve LVDS is off after entering OS in desktop platform\r
746 //\r
747 mIgdOpRegion.OpRegion->MBox1.CLID = DxePlatformSaPolicy->IgdPanelFeatures.LidStatus;\r
748\r
749 //\r
750 // Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).\r
751 //\r
752 //<TODO> The initial setting of mailbox 3 fields is implementation specific.\r
753 // Adjust them as needed many even coming from user setting in setup.\r
754 //\r
755\r
756 //\r
757 // Do not initialize TCHE. This field is written by the graphics driver only.\r
758 //\r
759\r
760 //\r
761 // The ALSI field is generally initialized by ASL code by reading the embedded controller.\r
762 //\r
763\r
764 mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;\r
765\r
766 mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);\r
767 if ( DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 2) {\r
768 //\r
769 // Center\r
770 //\r
771 mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_CENTER);\r
772 } else if (DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 1) {\r
773 //\r
774 // Stretch\r
775 //\r
776 mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);\r
777 } else {\r
778 //\r
779 // Auto\r
780 //\r
781 mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_SETUP_AUTO);\r
782 }\r
783\r
784 //\r
785 // Set Initial current Brightness\r
786 //\r
787 mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL | FIELD_VALID_BIT);\r
788\r
789 //\r
790 // <EXAMPLE> Create a static Backlight Brightness Level Duty cycle Mapping Table\r
791 // Possible 20 entries (example used 10), each 16 bits as follows:\r
792 // [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh).\r
793 //\r
794 // % Brightness\r
795 mIgdOpRegion.OpRegion->MBox3.BCLM[0] = ( ( 0 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT);\r
796 mIgdOpRegion.OpRegion->MBox3.BCLM[1] = ( ( 1 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT);\r
797 mIgdOpRegion.OpRegion->MBox3.BCLM[2] = ( ( 10 << 8 ) + ( 0xFF - 0xE5 ) + WORD_FIELD_VALID_BIT);\r
798 mIgdOpRegion.OpRegion->MBox3.BCLM[3] = ( ( 19 << 8 ) + ( 0xFF - 0xCE ) + WORD_FIELD_VALID_BIT);\r
799 mIgdOpRegion.OpRegion->MBox3.BCLM[4] = ( ( 28 << 8 ) + ( 0xFF - 0xB7 ) + WORD_FIELD_VALID_BIT);\r
800 mIgdOpRegion.OpRegion->MBox3.BCLM[5] = ( ( 37 << 8 ) + ( 0xFF - 0xA0 ) + WORD_FIELD_VALID_BIT);\r
801 mIgdOpRegion.OpRegion->MBox3.BCLM[6] = ( ( 46 << 8 ) + ( 0xFF - 0x89 ) + WORD_FIELD_VALID_BIT);\r
802 mIgdOpRegion.OpRegion->MBox3.BCLM[7] = ( ( 55 << 8 ) + ( 0xFF - 0x72 ) + WORD_FIELD_VALID_BIT);\r
803 mIgdOpRegion.OpRegion->MBox3.BCLM[8] = ( ( 64 << 8 ) + ( 0xFF - 0x5B ) + WORD_FIELD_VALID_BIT);\r
804 mIgdOpRegion.OpRegion->MBox3.BCLM[9] = ( ( 73 << 8 ) + ( 0xFF - 0x44 ) + WORD_FIELD_VALID_BIT);\r
805 mIgdOpRegion.OpRegion->MBox3.BCLM[10] = ( ( 82 << 8 ) + ( 0xFF - 0x2D ) + WORD_FIELD_VALID_BIT);\r
806 mIgdOpRegion.OpRegion->MBox3.BCLM[11] = ( ( 91 << 8 ) + ( 0xFF - 0x16 ) + WORD_FIELD_VALID_BIT);\r
807 mIgdOpRegion.OpRegion->MBox3.BCLM[12] = ( (100 << 8 ) + ( 0xFF - 0x00 ) + WORD_FIELD_VALID_BIT);\r
808\r
809 mIgdOpRegion.OpRegion->MBox3.PCFT = ((UINT32) GlobalNvsArea->Area->IgdPowerConservation) | BIT31;\r
810 //\r
811 // Create the notification and register callback function on the PciIo installation,\r
812 //\r
813 //\r
814 Status = gBS->CreateEvent (\r
815 EVT_NOTIFY_SIGNAL,\r
816 TPL_CALLBACK,\r
817 (EFI_EVENT_NOTIFY)GetVBiosVbtCallback,\r
818 NULL,\r
819 &mConOutEvent\r
820 );\r
821\r
822 ASSERT_EFI_ERROR (Status);\r
823 if (EFI_ERROR (Status)) {\r
824 return Status;\r
825\r
826 }\r
827\r
828 Status = gBS->RegisterProtocolNotify (\r
829#ifdef ECP_FLAG\r
830 &gExitPmAuthProtocolGuid,\r
831#else\r
832 &gEfiDxeSmmReadyToLockProtocolGuid,\r
833#endif\r
834 mConOutEvent,\r
835 &gConOutNotifyReg\r
836 );\r
837\r
838 Status = gBS->CreateEvent (\r
839 EVT_NOTIFY_SIGNAL,\r
840 TPL_CALLBACK,\r
841 (EFI_EVENT_NOTIFY)SetGOPVersionCallback,\r
842 NULL,\r
843 &mSetGOPverEvent\r
844 );\r
845\r
846 ASSERT_EFI_ERROR (Status);\r
847 if (EFI_ERROR (Status)) {\r
848 return Status;\r
849 }\r
850\r
851 Status = gBS->RegisterProtocolNotify (\r
852 &gEfiGraphicsOutputProtocolGuid,\r
853 mSetGOPverEvent,\r
854 &gConOutNotifyReg\r
855 );\r
856\r
857\r
858 //\r
859 // Initialize hardware state:\r
860 // Set ASLS Register to the OpRegion physical memory address.\r
861 // Set SWSCI register bit 15 to a "1" to activate SCI interrupts.\r
862 //\r
863\r
864 IgdMmPci32 (IGD_ASLS_OFFSET) = (UINT32)(UINTN)(mIgdOpRegion.OpRegion);\r
865 IgdMmPci16AndThenOr (IGD_SWSCI_OFFSET, ~(BIT0), BIT15);\r
866\r
867 DwordData = IgdMmPci32 (IGD_ASLS_OFFSET);\r
868 S3BootScriptSavePciCfgWrite (\r
869 S3BootScriptWidthUint32,\r
870 (UINTN) (EFI_PCI_ADDRESS (IGD_BUS, IGD_DEV, IGD_FUN_0, IGD_ASLS_OFFSET)),\r
871 1,\r
872 &DwordData\r
873 );\r
874\r
875\r
876 DwordData = IgdMmPci32 (IGD_SWSCI_OFFSET);\r
877 S3BootScriptSavePciCfgWrite (\r
878 S3BootScriptWidthUint32,\r
879 (UINTN) (EFI_PCI_ADDRESS (IGD_BUS, IGD_DEV, IGD_FUN_0, IGD_SWSCI_OFFSET)),\r
880 1,\r
881 &DwordData\r
882 );\r
883\r
884 AcpiBase = MmPci16 (\r
885 0,\r
886 DEFAULT_PCI_BUS_NUMBER_PCH,\r
887 PCI_DEVICE_NUMBER_PCH_LPC,\r
888 PCI_FUNCTION_NUMBER_PCH_LPC,\r
889 R_PCH_LPC_ACPI_BASE\r
890 ) & B_PCH_LPC_ACPI_BASE_BAR;\r
891\r
892 //\r
893 // Find the CPU I/O Protocol. ASSERT if not found.\r
894 //\r
895 Status = gBS->LocateProtocol (\r
896 &gEfiCpuIoProtocolGuid,\r
897 NULL,\r
898 (void **)&CpuIo\r
899 );\r
900 ASSERT_EFI_ERROR (Status);\r
901\r
902 CpuIo->Io.Read (\r
903 CpuIo,\r
904 EfiCpuIoWidthUint16,\r
905 AcpiBase + R_PCH_ACPI_GPE0a_STS,\r
906 1,\r
907 &Data16\r
908 );\r
909 //\r
910 // Clear the B_PCH_ACPI_GPE0a_STS_GUNIT_SCI bit in R_PCH_ACPI_GPE0a_STS by writing a '1'.\r
911 //\r
912 Data16 |= B_PCH_ACPI_GPE0a_STS_GUNIT_SCI;\r
913\r
914 CpuIo->Io.Write (\r
915 CpuIo,\r
916 EfiCpuIoWidthUint16,\r
917 AcpiBase + R_PCH_ACPI_GPE0a_STS,\r
918 1,\r
919 &Data16\r
920 );\r
921\r
922 //\r
923 // Install OpRegion / Software SCI protocol\r
924 //\r
925 Handle = NULL;\r
926 Status = gBS->InstallMultipleProtocolInterfaces (\r
927 &Handle,\r
928 &gIgdOpRegionProtocolGuid,\r
929 &mIgdOpRegion,\r
930 NULL\r
931 );\r
932 ASSERT_EFI_ERROR (Status);\r
933\r
934 //\r
935 // Return final status\r
936 //\r
937 return EFI_SUCCESS;\r
938}\r