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