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