• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Copyright (c) 2004  - 2016, 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 
24 
25 Module Name:
26 
27   AcpiPlatform.c
28 
29 Abstract:
30 
31   ACPI Platform Driver
32 
33 
34 **/
35 
36 #include <PiDxe.h>
37 #include <Protocol/TcgService.h>
38 #include <Protocol/FirmwareVolume.h>
39 #include "AcpiPlatform.h"
40 #include "AcpiPlatformHooks.h"
41 #include "AcpiPlatformHooksLib.h"
42 #include "Platform.h"
43 #include <Hpet.h>
44 #include <Mcfg.h>
45 #include "Osfr.h"
46 #include <Guid/GlobalVariable.h>
47 #include <Guid/SetupVariable.h>
48 #include <Guid/PlatformInfo.h>
49 #include <Protocol/CpuIo.h>
50 #include <Guid/BoardFeatures.h>
51 #include <Protocol/AcpiSupport.h>
52 #include <Protocol/AcpiS3Save.h>
53 #include <Protocol/Ps2Policy.h>
54 #include <Library/CpuIA32.h>
55 #include <SetupMode.h>
56 #include <Guid/AcpiTableStorage.h>
57 #include <Guid/EfiVpdData.h>
58 #include <PchAccess.h>
59 #include <Guid/Vlv2Variable.h>
60 #include <Guid/PlatformCpuInfo.h>
61 #include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
62 
63 
64 CHAR16    EfiPlatformCpuInfoVariable[] = L"PlatformCpuInfo";
65 CHAR16    gACPIOSFRModelStringVariableName[] = ACPI_OSFR_MODEL_STRING_VARIABLE_NAME;
66 CHAR16    gACPIOSFRRefDataBlockVariableName[] = ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME;
67 CHAR16    gACPIOSFRMfgStringVariableName[] = ACPI_OSFR_MFG_STRING_VARIABLE_NAME;
68 
69 EFI_CPU_IO_PROTOCOL                    *mCpuIo;
70 EFI_GLOBAL_NVS_AREA_PROTOCOL            mGlobalNvsArea;
71 #ifndef __GNUC__
72 #pragma optimize("", off)
73 #endif
74 BOOLEAN                   mFirstNotify;
75 EFI_PLATFORM_INFO_HOB     *mPlatformInfo;
76 EFI_GUID                  mSystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
77 SYSTEM_CONFIGURATION      mSystemConfiguration;
78 SYSTEM_CONFIGURATION      mSystemConfig;
79 
80 UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;
81 UINT8 mNumberSmbusAddress = sizeof( mSmbusRsvdAddresses ) / sizeof( mSmbusRsvdAddresses[0] );
82 
83 /**
84   Locate the first instance of a protocol.  If the protocol requested is an
85   FV protocol, then it will return the first FV that contains the ACPI table
86   storage file.
87 
88   @param[in]  Protocol            The protocol to find.
89   @param[in]  Instance            Return pointer to the first instance of the protocol.
90   @param[in]  Type                The type of protocol to locate.
91 
92   @retval  EFI_SUCCESS            The function completed successfully.
93   @retval  EFI_NOT_FOUND          The protocol could not be located.
94   @retval  EFI_OUT_OF_RESOURCES   There are not enough resources to find the protocol.
95 
96 **/
97 EFI_STATUS
LocateSupportProtocol(IN EFI_GUID * Protocol,OUT VOID ** Instance,IN UINT32 Type)98 LocateSupportProtocol (
99   IN   EFI_GUID       *Protocol,
100   OUT  VOID           **Instance,
101   IN   UINT32         Type
102   )
103 {
104   EFI_STATUS              Status;
105   EFI_HANDLE              *HandleBuffer;
106   UINTN                   NumberOfHandles;
107   EFI_FV_FILETYPE         FileType;
108   UINT32                  FvStatus;
109   EFI_FV_FILE_ATTRIBUTES  Attributes;
110   UINTN                   Size;
111   UINTN                   Index;
112 
113   FvStatus = 0;
114 
115   //
116   // Locate protocol.
117   //
118   Status = gBS->LocateHandleBuffer (
119                   ByProtocol,
120                   Protocol,
121                   NULL,
122                   &NumberOfHandles,
123                   &HandleBuffer
124                   );
125   if (EFI_ERROR (Status)) {
126     //
127     // Defined errors at this time are not found and out of resources.
128     //
129     return Status;
130   }
131 
132   //
133   // Looking for FV with ACPI storage file.
134   //
135   for (Index = 0; Index < NumberOfHandles; Index++) {
136     //
137     // Get the protocol on this handle.
138     // This should not fail because of LocateHandleBuffer.
139     //
140     Status = gBS->HandleProtocol (
141                     HandleBuffer[Index],
142                     Protocol,
143                     Instance
144                     );
145     ASSERT (!EFI_ERROR (Status));
146 
147     if (!Type) {
148       //
149       // Not looking for the FV protocol, so find the first instance of the
150       // protocol.  There should not be any errors because our handle buffer
151       // should always contain at least one or LocateHandleBuffer would have
152       // returned not found.
153       //
154       break;
155     }
156 
157     //
158     // See if it has the ACPI storage file.
159     //
160     Status = ((EFI_FIRMWARE_VOLUME_PROTOCOL *) (*Instance))->ReadFile (
161                                                               *Instance,
162                                                               &gEfiAcpiTableStorageGuid,
163                                                               NULL,
164                                                               &Size,
165                                                               &FileType,
166                                                               &Attributes,
167                                                               &FvStatus
168                                                               );
169 
170     //
171     // If we found it, then we are done.
172     //
173     if (!EFI_ERROR (Status)) {
174       break;
175     }
176   }
177 
178   //
179   // Our exit status is determined by the success of the previous operations.
180   // If the protocol was found, Instance already points to it.
181   //
182   //
183   // Free any allocated buffers.
184   //
185   gBS->FreePool (HandleBuffer);
186 
187   return Status;
188 }
189 
190 /**
191   This function will update any runtime platform specific information.
192   This currently includes:
193     Setting OEM table values, ID, table ID, creator ID and creator revision.
194     Enabling the proper processor entries in the APIC tables.
195 
196   @param[in]  Table       The table to update.
197 
198   @retval  EFI_SUCCESS    The function completed successfully.
199 
200 **/
201 EFI_STATUS
PlatformUpdateTables(IN OUT EFI_ACPI_COMMON_HEADER * Table)202 PlatformUpdateTables (
203   IN OUT EFI_ACPI_COMMON_HEADER  *Table
204   )
205 {
206   EFI_ACPI_DESCRIPTION_HEADER                                 *TableHeader;
207   UINT8                                                       *CurrPtr;
208   UINT8                                                       *EndPtr;
209   ACPI_APIC_STRUCTURE_PTR                                     *ApicPtr;
210   UINT8                                                       CurrProcessor;
211   EFI_STATUS                                                  Status;
212   EFI_MP_SERVICES_PROTOCOL                                    *MpService;
213   UINTN                                                       MaximumNumberOfCPUs;
214   UINTN                                                       NumberOfEnabledCPUs;
215   UINTN                                                       BspIndex;
216   EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE                          *AsfEntry;
217   EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER            *HpetTbl;
218   UINT64                                                      OemIdValue;
219   UINT8                                                       Index;
220   EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE                   *Facp;
221   EFI_ACPI_OSFR_TABLE                                         *OsfrTable;
222   EFI_ACPI_OSFR_OCUR_OBJECT                                   *pOcurObject;
223   EFI_ACPI_OSFR_OCUR_OBJECT                                   OcurObject = {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0};
224   CHAR16                                                      *OcurMfgStringBuffer = NULL;
225   CHAR16                                                      *OcurModelStringBuffer = NULL;
226   UINT8                                                       *OcurRefDataBlockBuffer = NULL;
227   UINTN                                                       OcurMfgStringBufferSize;
228   UINTN                                                       OcurModelStringBufferSize;
229   UINTN                                                       OcurRefDataBlockBufferSize;
230 #if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED
231   EFI_ACPI_ASPT_TABLE                                         *pSpttTable;
232 #endif
233   UINT16                                                      NumberOfHpets;
234   UINT16                                                      HpetCapIdValue;
235   UINT32                                                      HpetBlockID;
236   EFI_PROCESSOR_INFORMATION                                   ProcessorInfoBuffer;
237   UINT8                                                       TempVal;
238   EFI_ACPI_3_0_IO_APIC_STRUCTURE                              *IOApicType;
239   EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER         *APICTableHeader;
240   EFI_ACPI_WSMT_TABLE                                         *WsmtTable;
241 
242   CurrPtr                 = NULL;
243   EndPtr                  = NULL;
244   ApicPtr                 = NULL;
245   CurrProcessor           = 0;
246 
247 
248  if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
249     TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
250     //
251     // Update the OEMID.
252     //
253     OemIdValue = mPlatformInfo->AcpiOemId;
254 
255     *(UINT32 *)(TableHeader->OemId)     = (UINT32)OemIdValue;
256     *(UINT16 *)(TableHeader->OemId + 4) = *(UINT16*)(((UINT8 *)&OemIdValue) + 4);
257 
258     if ((Table->Signature != EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) {
259     //
260     // Update the OEM Table ID.
261     //
262       TableHeader->OemTableId = mPlatformInfo->AcpiOemTableId;
263     }
264 
265     //
266     // Update the OEM Table ID.
267     //
268     TableHeader->OemRevision = EFI_ACPI_OEM_REVISION;
269 
270     //
271     // Update the creator ID.
272     //
273     TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
274 
275     //
276     // Update the creator revision.
277     //
278     TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
279   }
280 
281   //
282   // Complete this function.
283   //
284   //
285   // Locate the MP services protocol.
286   //
287   //
288   // Find the MP Protocol. This is an MP platform, so MP protocol must be
289   // there.
290   //
291   Status = gBS->LocateProtocol (
292                   &gEfiMpServiceProtocolGuid,
293                   NULL,
294                   (VOID **) &MpService
295                   );
296   if (EFI_ERROR (Status)) {
297     return Status;
298   }
299 
300   //
301   // Determine the number of processors.
302   //
303   MpService->GetNumberOfProcessors (
304               MpService,
305               &MaximumNumberOfCPUs,
306               &NumberOfEnabledCPUs
307               );
308 
309   ASSERT (MaximumNumberOfCPUs <= MAX_CPU_NUM && NumberOfEnabledCPUs >= 1);
310 
311 
312   //
313   // Assign a invalid intial value for update.
314   //
315   //
316   // Update the processors in the APIC table.
317   //
318   switch (Table->Signature) {
319     case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE:
320       //
321       // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
322       //
323       if (mSystemConfig.Asf == 1) {
324         return  EFI_UNSUPPORTED;
325       }
326       AsfEntry = (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE *) Table;
327       TempVal = (mNumberSmbusAddress < ASF_ADDR_DEVICE_ARRAY_LENGTH)? mNumberSmbusAddress : ASF_ADDR_DEVICE_ARRAY_LENGTH;
328       for (Index = 0; Index < TempVal; Index++) {
329         AsfEntry->AsfAddr.FixedSmbusAddresses[Index] = mSmbusRsvdAddresses[Index];
330       }
331       break;
332 
333     case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
334 
335       Status = MpService->WhoAmI (
336                             MpService,
337                             &BspIndex
338                             );
339 
340       //
341       // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
342       //
343       APICTableHeader = (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;
344       APICTableHeader->Flags |= EFI_ACPI_3_0_PCAT_COMPAT;
345 
346       CurrPtr = (UINT8 *) &((EFI_ACPI_DESCRIPTION_HEADER *) Table)[1];
347       CurrPtr = CurrPtr + 8;
348 
349       //
350       // Size of Local APIC Address & Flag.
351       //
352       EndPtr  = (UINT8 *) Table;
353       EndPtr  = EndPtr + Table->Length;
354       while (CurrPtr < EndPtr) {
355         ApicPtr = (ACPI_APIC_STRUCTURE_PTR *) CurrPtr;
356         switch (ApicPtr->AcpiApicCommon.Type) {
357           case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC:
358             //
359             // ESS override
360             // Fix for Ordering of MADT to be maintained as it is in MADT table.
361             //
362             // Update processor enabled or disabled and keep the local APIC
363             // order in MADT intact.
364             //
365             // Sanity check to make sure proc-id is not arbitrary.
366             //
367             DEBUG ((EFI_D_ERROR, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \
368             ApicPtr->AcpiLocalApic.AcpiProcessorId, MaximumNumberOfCPUs));
369             if(ApicPtr->AcpiLocalApic.AcpiProcessorId > MaximumNumberOfCPUs) {
370               ApicPtr->AcpiLocalApic.AcpiProcessorId = (UINT8)MaximumNumberOfCPUs;
371             }
372 
373             ApicPtr->AcpiLocalApic.Flags  = 0;
374 
375             for (CurrProcessor = 0; CurrProcessor < MaximumNumberOfCPUs; CurrProcessor++) {
376               Status = MpService->GetProcessorInfo (
377                                     MpService,
378                                     CurrProcessor,
379                                     &ProcessorInfoBuffer
380                                     );
381 
382               if (Status == EFI_SUCCESS && ProcessorInfoBuffer.ProcessorId == ApicPtr->AcpiLocalApic.ApicId) {
383                 //
384                 // Check to see whether or not a processor (or thread) is enabled.
385                 //
386                 if ((BspIndex == CurrProcessor) || ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0)) {
387                   //
388                   // Go on and check if Hyper Threading is enabled. If HT not enabled
389                   // hide this thread from OS by not setting the flag to 1.  This is the
390                   // software way to disable Hyper Threading.  Basically we just hide it
391                   // from the OS.
392                   //
393                   ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_1_0_LOCAL_APIC_ENABLED;
394 
395 
396                   if(ProcessorInfoBuffer.Location.Thread != 0) {
397                     ApicPtr->AcpiLocalApic.Flags = 0;
398                   }
399 
400                   AppendCpuMapTableEntry (&(ApicPtr->AcpiLocalApic));
401                 }
402                 break;
403               }
404             }
405 
406             //
407             // If no APIC-ID match, the cpu may not be populated.
408             //
409             break;
410 
411           case EFI_ACPI_3_0_IO_APIC:
412 
413             IOApicType = (EFI_ACPI_3_0_IO_APIC_STRUCTURE *)CurrPtr;
414             IOApicType->IoApicId = 0x02;
415             //
416             // IO APIC entries can be patched here.
417             //
418             break;
419         }
420 
421         CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
422       }
423       break;
424 
425     case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
426 
427        Facp = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
428        Facp->Flags &= (UINT32)(~(3<<2));
429 
430       break;
431 
432     case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
433       //
434       // Patch the memory resource.
435       //
436       PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER *) Table);
437       break;
438 
439     case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
440       //
441       // Gv3 support
442       //
443       // TBD: Need re-design based on the ValleyTrail platform.
444       //
445       break;
446 
447     case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
448       //
449       // Adjust HPET Table to correct the Base Address.
450       //
451       // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
452       //
453       MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);
454 
455 
456       HpetTbl = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table;
457       HpetTbl->BaseAddressLower32Bit.Address = HPET_BASE_ADDRESS;
458       HpetTbl->EventTimerBlockId = *((UINT32*)(UINTN)HPET_BASE_ADDRESS);
459 
460       HpetCapIdValue = *(UINT16 *)(UINTN)(HPET_BASE_ADDRESS);
461       NumberOfHpets = HpetCapIdValue & B_PCH_PCH_HPET_GCID_NT;  // Bits [8:12] contains the number of Hpets
462       HpetBlockID = EFI_ACPI_EVENT_TIMER_BLOCK_ID;
463 
464       if((NumberOfHpets) && (NumberOfHpets & B_PCH_PCH_HPET_GCID_NT)) {
465         HpetBlockID |= (NumberOfHpets);
466       }
467       HpetTbl->EventTimerBlockId = HpetBlockID;
468 
469       break;
470 
471     case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
472       //
473       // Update MCFG base and end bus number.
474       //
475       ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].BaseAddress
476         = mPlatformInfo->PciData.PciExpressBase;
477       ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].EndBusNumber
478         = (UINT8)RShiftU64 (mPlatformInfo->PciData.PciExpressSize, 20) - 1;
479       break;
480 
481 
482     case EFI_ACPI_OSFR_TABLE_SIGNATURE:
483       //
484       // Get size of OSFR variable.
485       //
486       OcurMfgStringBufferSize = 0;
487       Status = gRT->GetVariable (
488                       gACPIOSFRMfgStringVariableName,
489                       &gACPIOSFRMfgStringVariableGuid,
490                       NULL,
491                       &OcurMfgStringBufferSize,
492                       NULL
493                       );
494       if (Status != EFI_BUFFER_TOO_SMALL) {
495         //
496         // Variable must not be present on the system.
497         //
498         return EFI_UNSUPPORTED;
499       }
500 
501       //
502       // Allocate memory for variable data.
503       //
504       OcurMfgStringBuffer = AllocatePool (OcurMfgStringBufferSize);
505       Status = gRT->GetVariable (
506                       gACPIOSFRMfgStringVariableName,
507                       &gACPIOSFRMfgStringVariableGuid,
508                       NULL,
509                       &OcurMfgStringBufferSize,
510                       OcurMfgStringBuffer
511                       );
512       if (!EFI_ERROR (Status)) {
513         OcurModelStringBufferSize = 0;
514         Status = gRT->GetVariable (
515                         gACPIOSFRModelStringVariableName,
516                         &gACPIOSFRModelStringVariableGuid,
517                         NULL,
518                         &OcurModelStringBufferSize,
519                         NULL
520                         );
521         if (Status != EFI_BUFFER_TOO_SMALL) {
522           //
523           // Variable must not be present on the system.
524           //
525           return EFI_UNSUPPORTED;
526         }
527 
528         //
529         // Allocate memory for variable data.
530         //
531         OcurModelStringBuffer = AllocatePool (OcurModelStringBufferSize);
532         Status = gRT->GetVariable (
533                         gACPIOSFRModelStringVariableName,
534                         &gACPIOSFRModelStringVariableGuid,
535                         NULL,
536                         &OcurModelStringBufferSize,
537                         OcurModelStringBuffer
538                         );
539         if (!EFI_ERROR (Status)) {
540           OcurRefDataBlockBufferSize = 0;
541           Status = gRT->GetVariable (
542                           gACPIOSFRRefDataBlockVariableName,
543                           &gACPIOSFRRefDataBlockVariableGuid,
544                           NULL,
545                           &OcurRefDataBlockBufferSize,
546                           NULL
547                           );
548           if (Status == EFI_BUFFER_TOO_SMALL) {
549             //
550             // Allocate memory for variable data.
551             //
552             OcurRefDataBlockBuffer = AllocatePool (OcurRefDataBlockBufferSize);
553             Status = gRT->GetVariable (
554                             gACPIOSFRRefDataBlockVariableName,
555                             &gACPIOSFRRefDataBlockVariableGuid,
556                             NULL,
557                             &OcurRefDataBlockBufferSize,
558                             OcurRefDataBlockBuffer
559                             );
560           }
561           OsfrTable = (EFI_ACPI_OSFR_TABLE *) Table;
562           //
563           // Currently only one object is defined: OCUR_OSFR_TABLE.
564           //
565           OsfrTable->ObjectCount = 1;
566           //
567           // Initialize table length to fixed portion of the ACPI OSFR table.
568           //
569           OsfrTable->Header.Length = sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION);
570           *(UINT32 *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION)) = \
571             (UINT32) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + sizeof (UINT32));
572           pOcurObject = (EFI_ACPI_OSFR_OCUR_OBJECT *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + \
573             sizeof (UINT32));
574           CopyMem (pOcurObject, &OcurObject, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));
575           pOcurObject->ManufacturerNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
576             sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));
577           pOcurObject->ModelNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
578             sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize);
579           if (OcurRefDataBlockBufferSize > 0) {
580             pOcurObject->MicrosoftReferenceOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
581               sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + OcurModelStringBufferSize);
582           }
583           CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT)), OcurMfgStringBuffer, \
584             OcurMfgStringBufferSize);
585           CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize), \
586             OcurModelStringBuffer, OcurModelStringBufferSize);
587           if (OcurRefDataBlockBufferSize > 0) {
588             CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + \
589             OcurModelStringBufferSize),OcurRefDataBlockBuffer, OcurRefDataBlockBufferSize);
590           }
591           OsfrTable->Header.Length += (UINT32)(OcurMfgStringBufferSize + OcurModelStringBufferSize + OcurRefDataBlockBufferSize);
592           OsfrTable->Header.Length += sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + sizeof (UINT32);
593         }
594       }
595       gBS->FreePool (OcurMfgStringBuffer);
596       gBS->FreePool (OcurModelStringBuffer);
597       gBS->FreePool (OcurRefDataBlockBuffer);
598       break;
599 
600 
601     case EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE:
602       WsmtTable = (EFI_ACPI_WSMT_TABLE *) Table;
603        //
604        // Update Microsoft WSMT table Protections flags.
605        //
606       WsmtTable->ProtectionFlags = ((WsmtTable->ProtectionFlags) | (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS | EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION ));
607       break;
608 
609 
610     default:
611       break;
612   }
613 
614   //
615   //
616   // Update the hardware signature in the FACS structure.
617   //
618   //
619   // Locate the SPCR table and update based on current settings.
620   // The user may change CR settings via setup or other methods.
621   // The SPCR table must match.
622   //
623   return EFI_SUCCESS;
624 }
625 
626 /**
627 
628 Routine Description:
629 
630   GC_TODO: Add function description.
631 
632 Arguments:
633 
634   Event   - GC_TODO: add argument description
635   Context - GC_TODO: add argument description
636 
637 Returns:
638 
639   GC_TODO: add return values
640 
641 **/
642 STATIC
643 VOID
644 EFIAPI
OnReadyToBoot(IN EFI_EVENT Event,IN VOID * Context)645 OnReadyToBoot (
646   IN      EFI_EVENT                 Event,
647   IN      VOID                      *Context
648   )
649 {
650   EFI_STATUS                  Status;
651   EFI_ACPI_TABLE_VERSION      TableVersion;
652   EFI_ACPI_SUPPORT_PROTOCOL   *AcpiSupport;
653   EFI_ACPI_S3_SAVE_PROTOCOL   *AcpiS3Save;
654   SYSTEM_CONFIGURATION        SetupVarBuffer;
655   UINTN                       VariableSize;
656   EFI_PLATFORM_CPU_INFO       *PlatformCpuInfoPtr = NULL;
657   EFI_PLATFORM_CPU_INFO       PlatformCpuInfo;
658   EFI_PEI_HOB_POINTERS          GuidHob;
659 
660   if (mFirstNotify) {
661     return;
662   }
663 
664   mFirstNotify = TRUE;
665 
666   //
667   // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used".
668   //
669   PlatformCpuInfo.CpuVersion.FullCpuId = 0;
670 
671   //
672   // Get Platform CPU Info HOB.
673   //
674   PlatformCpuInfoPtr = NULL;
675   ZeroMem (&PlatformCpuInfo, sizeof(EFI_PLATFORM_CPU_INFO));
676   VariableSize = sizeof(EFI_PLATFORM_CPU_INFO);
677   Status = gRT->GetVariable(
678                   EfiPlatformCpuInfoVariable,
679                   &gEfiVlv2VariableGuid,
680                   NULL,
681                   &VariableSize,
682                   PlatformCpuInfoPtr
683                   );
684   if (EFI_ERROR(Status)) {
685     GuidHob.Raw = GetHobList ();
686     if (GuidHob.Raw != NULL) {
687       if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformCpuInfoGuid, GuidHob.Raw)) != NULL) {
688         PlatformCpuInfoPtr = GET_GUID_HOB_DATA (GuidHob.Guid);
689       }
690     }
691   }
692 
693   if ((PlatformCpuInfoPtr != NULL)) {
694     CopyMem(&PlatformCpuInfo, PlatformCpuInfoPtr, sizeof(EFI_PLATFORM_CPU_INFO));
695   }
696 
697   //
698   // Update the ACPI parameter blocks finally.
699   //
700   VariableSize = sizeof (SYSTEM_CONFIGURATION);
701   Status = gRT->GetVariable (
702                   L"Setup",
703                   &mSystemConfigurationGuid,
704                   NULL,
705                   &VariableSize,
706                   &SetupVarBuffer
707                   );
708   if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
709     //The setup variable is corrupted
710     VariableSize = sizeof(SYSTEM_CONFIGURATION);
711     Status = gRT->GetVariable(
712               L"SetupRecovery",
713               &mSystemConfigurationGuid,
714               NULL,
715               &VariableSize,
716               &SetupVarBuffer
717               );
718     ASSERT_EFI_ERROR (Status);
719   }
720 
721   //
722   // Find the AcpiSupport protocol.
723   //
724   Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0);
725   ASSERT_EFI_ERROR (Status);
726 
727   TableVersion = EFI_ACPI_TABLE_VERSION_2_0;
728 
729   //
730   // Publish ACPI 1.0 or 2.0 Tables.
731   //
732   Status = AcpiSupport->PublishTables (
733                           AcpiSupport,
734                           TableVersion
735                           );
736   ASSERT_EFI_ERROR (Status);
737 
738   //
739   // S3 script save.
740   //
741   Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save);
742   if (!EFI_ERROR (Status)) {
743     AcpiS3Save->S3Save (AcpiS3Save, NULL);
744   }
745 
746 }
747 
748 VOID
PR1FSASetting(IN VOID)749 PR1FSASetting (
750   IN VOID
751   )
752 {
753   //
754   // for FSA on  PR1.
755   //
756   if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD && mPlatformInfo->BoardRev >= PR1) {
757     DEBUG((EFI_D_ERROR, "Set FSA status = 1 for FFRD PR1\n"));
758     mGlobalNvsArea.Area->FsaStatus  = mSystemConfiguration.PchFSAOn;
759   }
760   if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD8) {
761     DEBUG((EFI_D_ERROR, "Set FSA status = 1 for FFRD8\n"));
762     mGlobalNvsArea.Area->FsaStatus  = mSystemConfiguration.PchFSAOn;
763   }
764 
765 }
766 
767 /**
768   Entry point for Acpi platform driver.
769 
770   @param[in]  ImageHandle        A handle for the image that is initializing this driver.
771   @param[in]  SystemTable        A pointer to the EFI system table.
772 
773   @retval  EFI_SUCCESS           Driver initialized successfully.
774   @retval  EFI_LOAD_ERROR        Failed to Initialize or has been loaded.
775   @retval  EFI_OUT_OF_RESOURCES  Could not allocate needed resources.
776 
777 **/
778 EFI_STATUS
779 EFIAPI
AcpiPlatformEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)780 AcpiPlatformEntryPoint (
781   IN EFI_HANDLE         ImageHandle,
782   IN EFI_SYSTEM_TABLE   *SystemTable
783   )
784 {
785   EFI_STATUS                    Status;
786   EFI_STATUS                    AcpiStatus;
787   EFI_ACPI_SUPPORT_PROTOCOL     *AcpiSupport;
788   EFI_FIRMWARE_VOLUME_PROTOCOL  *FwVol;
789   INTN                          Instance;
790   EFI_ACPI_COMMON_HEADER        *CurrentTable;
791   UINTN                         TableHandle;
792   UINT32                        FvStatus;
793   UINT32                        Size;
794   EFI_EVENT                     Event;
795   EFI_ACPI_TABLE_VERSION        TableVersion;
796   UINTN                         VarSize;
797   UINTN                         SysCfgSize;
798   EFI_HANDLE                    Handle;
799   EFI_PS2_POLICY_PROTOCOL       *Ps2Policy;
800   EFI_PEI_HOB_POINTERS          GuidHob;
801   UINT8                         PortData;
802   EFI_MP_SERVICES_PROTOCOL      *MpService;
803   UINTN                         MaximumNumberOfCPUs;
804   UINTN                         NumberOfEnabledCPUs;
805   PCH_STEPPING                  pchStepping;
806 
807   mFirstNotify      = FALSE;
808 
809   TableVersion      = EFI_ACPI_TABLE_VERSION_2_0;
810   Instance          = 0;
811   CurrentTable      = NULL;
812   TableHandle       = 0;
813 
814   //
815   // Update HOB variable for PCI resource information.
816   // Get the HOB list.  If it is not present, then ASSERT.
817   //
818   GuidHob.Raw = GetHobList ();
819   if (GuidHob.Raw != NULL) {
820     if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
821       mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
822     }
823   }
824 
825   //
826   // Search for the Memory Configuration GUID HOB.  If it is not present, then
827   // there's nothing we can do. It may not exist on the update path.
828   //
829   VarSize = sizeof(SYSTEM_CONFIGURATION);
830   Status = gRT->GetVariable(
831                   L"Setup",
832                   &mSystemConfigurationGuid,
833                   NULL,
834                   &VarSize,
835                   &mSystemConfiguration
836                   );
837   if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
838     //The setup variable is corrupted
839     VarSize = sizeof(SYSTEM_CONFIGURATION);
840     Status = gRT->GetVariable(
841               L"SetupRecovery",
842               &mSystemConfigurationGuid,
843               NULL,
844               &VarSize,
845               &mSystemConfiguration
846               );
847     ASSERT_EFI_ERROR (Status);
848   }
849 
850   //
851   // Find the AcpiSupport protocol.
852   //
853   Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0);
854   ASSERT_EFI_ERROR (Status);
855 
856   //
857   // Locate the firmware volume protocol.
858   //
859   Status = LocateSupportProtocol (&gEfiFirmwareVolumeProtocolGuid, (VOID **) &FwVol, 1);
860   ASSERT_EFI_ERROR (Status);
861 
862   //
863   // Read the current system configuration variable store.
864   //
865   SysCfgSize = sizeof(SYSTEM_CONFIGURATION);
866   Status = gRT->GetVariable (
867                   L"Setup",
868                   &gEfiNormalSetupGuid,
869                   NULL,
870                   &SysCfgSize,
871                   &mSystemConfig
872                   );
873   if (EFI_ERROR (Status) || SysCfgSize != sizeof(SYSTEM_CONFIGURATION)) {
874     //The setup variable is corrupted
875     SysCfgSize = sizeof(SYSTEM_CONFIGURATION);
876     Status = gRT->GetVariable(
877               L"SetupRecovery",
878               &gEfiNormalSetupGuid,
879               NULL,
880               &SysCfgSize,
881               &mSystemConfig
882               );
883     ASSERT_EFI_ERROR (Status);
884   }
885 
886 
887   Status    = EFI_SUCCESS;
888   Instance  = 0;
889 
890   //
891   // TBD: Need re-design based on the ValleyTrail platform.
892   //
893   Status = gBS->LocateProtocol (
894                   &gEfiMpServiceProtocolGuid,
895                   NULL,
896                   (VOID **) &MpService
897                   );
898   if (EFI_ERROR (Status)) {
899     return Status;
900   }
901 
902   //
903   // Determine the number of processors.
904   //
905   MpService->GetNumberOfProcessors (
906                MpService,
907                &MaximumNumberOfCPUs,
908                &NumberOfEnabledCPUs
909                );
910 
911   //
912   // Allocate and initialize the NVS area for SMM and ASL communication.
913   //
914   Status = gBS->AllocatePool (
915                   EfiACPIMemoryNVS,
916                   sizeof (EFI_GLOBAL_NVS_AREA),
917                   (void **)&mGlobalNvsArea.Area
918                   );
919   ASSERT_EFI_ERROR (Status);
920   gBS->SetMem (
921          mGlobalNvsArea.Area,
922          sizeof (EFI_GLOBAL_NVS_AREA),
923          0
924          );
925   DEBUG((EFI_D_ERROR, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea.Area));
926 
927   //
928   // Update global NVS area for ASL and SMM init code to use.
929   //
930   mGlobalNvsArea.Area->ApicEnable                 = 1;
931   mGlobalNvsArea.Area->EmaEnable                  = 0;
932 
933   mGlobalNvsArea.Area->NumberOfBatteries          = 1;
934   mGlobalNvsArea.Area->BatteryCapacity0           = 100;
935   mGlobalNvsArea.Area->BatteryStatus0             = 84;
936   mGlobalNvsArea.Area->OnboardCom                 = 1;
937   mGlobalNvsArea.Area->IdeMode                    = 0;
938   mGlobalNvsArea.Area->PowerState                 = 0;
939 
940   mGlobalNvsArea.Area->LogicalProcessorCount    = (UINT8)NumberOfEnabledCPUs;
941 
942   mGlobalNvsArea.Area->PassiveThermalTripPoint  = mSystemConfiguration.PassiveThermalTripPoint;
943   mGlobalNvsArea.Area->PassiveTc1Value          = mSystemConfiguration.PassiveTc1Value;
944   mGlobalNvsArea.Area->PassiveTc2Value          = mSystemConfiguration.PassiveTc2Value;
945   mGlobalNvsArea.Area->PassiveTspValue          = mSystemConfiguration.PassiveTspValue;
946   mGlobalNvsArea.Area->CriticalThermalTripPoint = mSystemConfiguration.CriticalThermalTripPoint;
947 
948   mGlobalNvsArea.Area->IgdPanelType             = mSystemConfiguration.IgdFlatPanel;
949   mGlobalNvsArea.Area->IgdPanelScaling          = mSystemConfiguration.PanelScaling;
950   mGlobalNvsArea.Area->IgdSciSmiMode            = 0;
951   mGlobalNvsArea.Area->IgdTvFormat              = 0;
952   mGlobalNvsArea.Area->IgdTvMinor               = 0;
953   mGlobalNvsArea.Area->IgdSscConfig             = 1;
954   mGlobalNvsArea.Area->IgdBiaConfig             = mSystemConfiguration.IgdLcdIBia;
955   mGlobalNvsArea.Area->IgdBlcConfig             = mSystemConfiguration.IgdLcdIGmchBlc;
956   mGlobalNvsArea.Area->IgdDvmtMemSize           =  mSystemConfiguration.IgdDvmt50TotalAlloc;
957   mGlobalNvsArea.Area->IgdPAVP                  = mSystemConfiguration.PavpMode;
958 
959   mGlobalNvsArea.Area->AlsEnable                = mSystemConfiguration.AlsEnable;
960   mGlobalNvsArea.Area->BacklightControlSupport  = 2;
961   mGlobalNvsArea.Area->BrightnessPercentage    = 100;
962   mGlobalNvsArea.Area->IgdState = 1;
963   mGlobalNvsArea.Area->LidState = 1;
964 
965   mGlobalNvsArea.Area->DeviceId1 = 0x80000100 ;
966   mGlobalNvsArea.Area->DeviceId2 = 0x80000400 ;
967   mGlobalNvsArea.Area->DeviceId3 = 0x80000200 ;
968   mGlobalNvsArea.Area->DeviceId4 = 0x04;
969   mGlobalNvsArea.Area->DeviceId5 = 0x05;
970   mGlobalNvsArea.Area->NumberOfValidDeviceId = 4 ;
971   mGlobalNvsArea.Area->CurrentDeviceList = 0x0F ;
972   mGlobalNvsArea.Area->PreviousDeviceList = 0x0F ;
973 
974   mGlobalNvsArea.Area->UartSelection = mSystemConfiguration.UartInterface;
975   mGlobalNvsArea.Area->PcuUart1Enable = mSystemConfiguration.PcuUart1;
976   mGlobalNvsArea.Area->NativePCIESupport = 1;
977   mGlobalNvsArea.Area->RtcBattery = mSystemConfiguration.RtcBattery;
978 
979 
980 
981 
982 
983   //
984   // Update BootMode: 0:ACPI mode; 1:PCI mode
985   //
986   mGlobalNvsArea.Area->LpssSccMode = mSystemConfiguration.LpssPciModeEnabled;
987   if (mSystemConfiguration.LpssMipiHsi == 0) {
988     mGlobalNvsArea.Area->MipiHsiAddr  = 0;
989     mGlobalNvsArea.Area->MipiHsiLen   = 0;
990     mGlobalNvsArea.Area->MipiHsi1Addr = 0;
991     mGlobalNvsArea.Area->MipiHsi1Len  = 0;
992   }
993 
994   //
995   // Platform Flavor
996   //
997   mGlobalNvsArea.Area->PlatformFlavor = mPlatformInfo->PlatformFlavor;
998 
999   //
1000   // Update the Platform id
1001   //
1002   mGlobalNvsArea.Area->BoardID = mPlatformInfo->BoardId;
1003 
1004   //
1005   // Update the  Board Revision
1006   //
1007   mGlobalNvsArea.Area->FabID = mPlatformInfo->BoardRev;
1008 
1009   //
1010   // Update SOC Stepping
1011   //
1012   mGlobalNvsArea.Area->SocStepping = (UINT8)(PchStepping());
1013 
1014   mGlobalNvsArea.Area->OtgMode = mSystemConfiguration.PchUsbOtg;
1015 
1016   pchStepping = PchStepping();
1017   if (mSystemConfiguration.UsbAutoMode == 1) {
1018     //
1019     // Auto mode is enabled.
1020     //
1021     if (PchA0 == pchStepping) {
1022       //
1023       //  For A0, EHCI is enabled as default.
1024       //
1025       mSystemConfiguration.PchUsb20       = 1;
1026       mSystemConfiguration.PchUsb30Mode   = 0;
1027       mSystemConfiguration.UsbXhciSupport = 0;
1028       DEBUG ((EFI_D_INFO, "EHCI is enabled as default. SOC 0x%x\n", pchStepping));
1029     } else {
1030       //
1031       //  For A1 and later, XHCI is enabled as default.
1032       //
1033       mSystemConfiguration.PchUsb20       = 0;
1034       mSystemConfiguration.PchUsb30Mode   = 1;
1035       mSystemConfiguration.UsbXhciSupport = 1;
1036       DEBUG ((EFI_D_INFO, "XHCI is enabled as default. SOC 0x%x\n", pchStepping));
1037     }
1038   }
1039 
1040   mGlobalNvsArea.Area->XhciMode = mSystemConfiguration.PchUsb30Mode;
1041 
1042   mGlobalNvsArea.Area->Stepping = mPlatformInfo->IchRevision;
1043 
1044   //
1045   // Override invalid Pre-Boot Driver and XhciMode combination.
1046   //
1047   if ((mSystemConfiguration.UsbXhciSupport == 0) && (mSystemConfiguration.PchUsb30Mode == 3)) {
1048     mGlobalNvsArea.Area->XhciMode = 2;
1049   }
1050   if ((mSystemConfiguration.UsbXhciSupport == 1) && (mSystemConfiguration.PchUsb30Mode == 2)) {
1051     mGlobalNvsArea.Area->XhciMode = 3;
1052   }
1053 
1054   DEBUG ((EFI_D_ERROR, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea.Area->XhciMode));
1055 
1056   mGlobalNvsArea.Area->PmicEnable                       = GLOBAL_NVS_DEVICE_DISABLE;
1057   mGlobalNvsArea.Area->BatteryChargingSolution          = GLOBAL_NVS_DEVICE_DISABLE;
1058   mGlobalNvsArea.Area->ISPDevSel                        = mSystemConfiguration.ISPDevSel;
1059   mGlobalNvsArea.Area->LpeEnable                        = mSystemConfiguration.Lpe;
1060   mGlobalNvsArea.Area->LpeAudioReportedByDSDT           = mSystemConfiguration.LpeAudioReportedByDSDT;
1061 
1062   if (mSystemConfiguration.ISPEn == 0) {
1063     mGlobalNvsArea.Area->ISPDevSel                      = GLOBAL_NVS_DEVICE_DISABLE;
1064   }
1065 
1066   mGlobalNvsArea.Area->WittEnable                       = mSystemConfiguration.WittEnable;
1067   mGlobalNvsArea.Area->UtsEnable                        = mSystemConfiguration.UtsEnable;
1068   mGlobalNvsArea.Area->SarEnable                        = mSystemConfiguration.SAR1;
1069 
1070 
1071   mGlobalNvsArea.Area->ReservedO                        = 1;
1072 
1073   SettingI2CTouchAddress();
1074   mGlobalNvsArea.Area->IdleReserve= mSystemConfiguration.IdleReserve;
1075   //
1076   // Read BMBOUND and store it in GlobalNVS to pass into ASL.
1077   //
1078   // BUGBUG: code was moved into silicon reference code.
1079   //
1080   if (mSystemConfiguration.eMMCBootMode== 1) {
1081     //
1082     // Auto detect mode.
1083     //
1084     DEBUG ((EFI_D_ERROR, "Auto detect mode------------start\n"));
1085 
1086     //
1087     // Silicon Steppings.
1088     //
1089     switch (PchStepping()) {
1090       case PchA0: // A0/A1
1091       case PchA1:
1092         DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 Configuration\n"));
1093         mSystemConfiguration.LpsseMMCEnabled            = 1;
1094         mSystemConfiguration.LpsseMMC45Enabled          = 0;
1095         break;
1096 
1097       case PchB0: // B0 and later.
1098       default:
1099         DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 Configuration\n"));
1100         mSystemConfiguration.LpsseMMCEnabled            = 0;
1101         mSystemConfiguration.LpsseMMC45Enabled          = 1;
1102         break;
1103    }
1104   } else if (mSystemConfiguration.eMMCBootMode == 2) {
1105       //
1106       // eMMC 4.41
1107       //
1108       DEBUG ((EFI_D_ERROR, "Force to eMMC 4.41 Configuration\n"));
1109       mSystemConfiguration.LpsseMMCEnabled            = 1;
1110       mSystemConfiguration.LpsseMMC45Enabled          = 0;
1111   } else if (mSystemConfiguration.eMMCBootMode == 3) {
1112       //
1113       // eMMC 4.5
1114       //
1115       DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 Configuration\n"));
1116       mSystemConfiguration.LpsseMMCEnabled            = 0;
1117       mSystemConfiguration.LpsseMMC45Enabled          = 1;
1118 
1119   } else {
1120       //
1121       // Disable eMMC controllers.
1122       //
1123       DEBUG ((EFI_D_ERROR, "Disable eMMC controllers\n"));
1124       mSystemConfiguration.LpsseMMCEnabled            = 0;
1125       mSystemConfiguration.LpsseMMC45Enabled          = 0;
1126   }
1127 
1128   mGlobalNvsArea.Area->emmcVersion = 0;
1129   if (mSystemConfiguration.LpsseMMCEnabled) {
1130      DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 0\n"));
1131      mGlobalNvsArea.Area->emmcVersion = 0;
1132   }
1133 
1134   if (mSystemConfiguration.LpsseMMC45Enabled) {
1135      DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
1136      mGlobalNvsArea.Area->emmcVersion = 1;
1137   }
1138 
1139   mGlobalNvsArea.Area->SdCardRemovable = mSystemConfiguration.SdCardRemovable;
1140 
1141   //
1142   // Microsoft IOT
1143   //
1144   if ((mSystemConfiguration.LpssHsuart0FlowControlEnabled == 1) && \
1145       (mSystemConfiguration.LpssPwm0Enabled == 0) && \
1146       (mSystemConfiguration.LpssPwm1Enabled == 0)) {
1147     mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_ENABLE;
1148     DEBUG ((EFI_D_ERROR, "JP1 is set to be MSFT IOT configuration.\n"));
1149   } else {
1150     mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_DISABLE;
1151     DEBUG ((EFI_D_ERROR, "JP1 is not set to be MSFT IOT configuration.\n"));
1152   }
1153 
1154   //
1155   // SIO related option.
1156   //
1157   Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (void **)&mCpuIo);
1158   ASSERT_EFI_ERROR (Status);
1159 
1160   mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_DISABLE;
1161 
1162   mGlobalNvsArea.Area->DockedSioPresent = GLOBAL_NVS_DEVICE_DISABLE;
1163 
1164   if (mGlobalNvsArea.Area->DockedSioPresent != GLOBAL_NVS_DEVICE_ENABLE) {
1165     //
1166     // Check ID for SIO WPCN381U.
1167     //
1168     Status = mCpuIo->Io.Read (
1169                           mCpuIo,
1170                           EfiCpuIoWidthUint8,
1171                           WPCN381U_CONFIG_INDEX,
1172                           1,
1173                           &PortData
1174                           );
1175     ASSERT_EFI_ERROR (Status);
1176     if (PortData != 0xFF) {
1177       PortData = 0x20;
1178       Status = mCpuIo->Io.Write (
1179                             mCpuIo,
1180                             EfiCpuIoWidthUint8,
1181                             WPCN381U_CONFIG_INDEX,
1182                             1,
1183                             &PortData
1184                             );
1185       ASSERT_EFI_ERROR (Status);
1186       Status = mCpuIo->Io.Read (
1187                             mCpuIo,
1188                             EfiCpuIoWidthUint8,
1189                             WPCN381U_CONFIG_DATA,
1190                             1,
1191                             &PortData
1192                             );
1193       ASSERT_EFI_ERROR (Status);
1194       if ((PortData == WPCN381U_CHIP_ID) || (PortData == WDCP376_CHIP_ID)) {
1195         mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_ENABLE;
1196         mGlobalNvsArea.Area->OnboardCom = GLOBAL_NVS_DEVICE_ENABLE;
1197         mGlobalNvsArea.Area->OnboardComCir = GLOBAL_NVS_DEVICE_DISABLE;
1198       }
1199     }
1200   }
1201 
1202 
1203 
1204   //
1205   // Get Ps2 policy to set. Will be use if present.
1206   //
1207   Status =  gBS->LocateProtocol (
1208                    &gEfiPs2PolicyProtocolGuid,
1209                    NULL,
1210                    (VOID **)&Ps2Policy
1211                    );
1212   if (!EFI_ERROR (Status)) {
1213           Status = Ps2Policy->Ps2InitHardware (ImageHandle);
1214   }
1215 
1216   mGlobalNvsArea.Area->SDIOMode = mSystemConfiguration.LpssSdioMode;
1217 
1218   Handle = NULL;
1219   Status = gBS->InstallMultipleProtocolInterfaces (
1220                   &Handle,
1221                   &gEfiGlobalNvsAreaProtocolGuid,
1222                   &mGlobalNvsArea,
1223                   NULL
1224                   );
1225 
1226   //
1227   // Read tables from the storage file.
1228   //
1229   while (!EFI_ERROR (Status)) {
1230     CurrentTable = NULL;
1231 
1232     Status = FwVol->ReadSection (
1233                       FwVol,
1234                       &gEfiAcpiTableStorageGuid,
1235                       EFI_SECTION_RAW,
1236                       Instance,
1237                       (VOID **) &CurrentTable,
1238                       (UINTN *) &Size,
1239                       &FvStatus
1240                       );
1241 
1242     if (!EFI_ERROR (Status)) {
1243       //
1244       // Allow platform specific code to reject the table or update it.
1245       //
1246       AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable);
1247 
1248       if (!EFI_ERROR (AcpiStatus)) {
1249         //
1250         // Perform any table specific updates.
1251         //
1252         AcpiStatus = PlatformUpdateTables (CurrentTable);
1253         if (!EFI_ERROR (AcpiStatus)) {
1254           //
1255           // Add the table.
1256           //
1257           TableHandle = 0;
1258           AcpiStatus = AcpiSupport->SetAcpiTable (
1259                                       AcpiSupport,
1260                                       CurrentTable,
1261                                       TRUE,
1262                                       TableVersion,
1263                                       &TableHandle
1264                                       );
1265           ASSERT_EFI_ERROR (AcpiStatus);
1266         }
1267       }
1268 
1269       //
1270       // Increment the instance.
1271       //
1272       Instance++;
1273     }
1274   }
1275 
1276   Status = EfiCreateEventReadyToBootEx (
1277              TPL_NOTIFY,
1278              OnReadyToBoot,
1279              NULL,
1280              &Event
1281              );
1282 
1283   //
1284   // Finished.
1285   //
1286   return EFI_SUCCESS;
1287 }
1288 
1289 UINT8
ReadCmosBank1Byte(IN UINT8 Index)1290 ReadCmosBank1Byte (
1291   IN  UINT8                           Index
1292   )
1293 {
1294   UINT8                               Data;
1295 
1296   IoWrite8(0x72, Index);
1297   Data = IoRead8 (0x73);
1298   return Data;
1299 }
1300 
1301 VOID
WriteCmosBank1Byte(IN UINT8 Index,IN UINT8 Data)1302 WriteCmosBank1Byte (
1303   IN  UINT8                           Index,
1304   IN  UINT8                           Data
1305   )
1306 {
1307   IoWrite8 (0x72, Index);
1308   IoWrite8 (0x73, Data);
1309 }
1310 
1311 
1312 
1313 VOID
SettingI2CTouchAddress(IN VOID)1314 SettingI2CTouchAddress (
1315   IN VOID
1316   )
1317 {
1318   if (mSystemConfiguration.I2CTouchAd == 0) {
1319     //
1320     // If setup menu select auto set I2C Touch Address base on board id.
1321     //
1322     if (mPlatformInfo->BoardId == BOARD_ID_BL_RVP ||
1323         mPlatformInfo->BoardId == BOARD_ID_BL_STHI ||
1324         mPlatformInfo->BoardId == BOARD_ID_BL_RVP_DDR3L ) {
1325       //
1326       //RVP
1327       //
1328       mGlobalNvsArea.Area->I2CTouchAddress = 0x4B;
1329     } else if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD) {
1330       //
1331       //FFRD
1332       //
1333       mGlobalNvsArea.Area->I2CTouchAddress = 0x4A;
1334     } else if (mPlatformInfo->BoardId == BOARD_ID_BB_RVP) {
1335       mGlobalNvsArea.Area->I2CTouchAddress = 0x4C;
1336     } else if (mPlatformInfo->BoardId == BOARD_ID_CVH) {
1337       mGlobalNvsArea.Area->I2CTouchAddress = 0x4C;
1338     } else if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD8) {
1339       //
1340       //FFRD8 uses 0x4A.
1341       //
1342       mGlobalNvsArea.Area->I2CTouchAddress = 0x4A;
1343     }
1344   } else {
1345     mGlobalNvsArea.Area->I2CTouchAddress = mSystemConfiguration.I2CTouchAd;
1346   }
1347   DEBUG((EFI_D_ERROR, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea.Area->I2CTouchAddress));
1348 }
1349 
1350 
1351