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