AcpiPlatform.c revision 620f289162b08d319fe1e73b3c7e2baff6b388e4
1/** @file
2
3  Copyright (c) 2004  - 2014, 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
25Module Name:
26
27  AcpiPlatform.c
28
29Abstract:
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
63CHAR16    EfiPlatformCpuInfoVariable[] = L"PlatformCpuInfo";
64CHAR16    gACPIOSFRModelStringVariableName[] = ACPI_OSFR_MODEL_STRING_VARIABLE_NAME;
65CHAR16    gACPIOSFRRefDataBlockVariableName[] = ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME;
66CHAR16    gACPIOSFRMfgStringVariableName[] = ACPI_OSFR_MFG_STRING_VARIABLE_NAME;
67
68EFI_CPU_IO_PROTOCOL                    *mCpuIo;
69#ifndef __GNUC__
70#pragma optimize("", off)
71#endif
72BOOLEAN                   mFirstNotify;
73EFI_PLATFORM_INFO_HOB     *mPlatformInfo;
74EFI_GUID                  mSystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
75SYSTEM_CONFIGURATION      mSystemConfiguration;
76SYSTEM_CONFIGURATION      mSystemConfig;
77
78UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;
79UINT8 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**/
95EFI_STATUS
96LocateSupportProtocol (
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**/
199EFI_STATUS
200PlatformUpdateTables (
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
620Routine Description:
621
622  GC_TODO: Add function description.
623
624Arguments:
625
626  Event   - GC_TODO: add argument description
627  Context - GC_TODO: add argument description
628
629Returns:
630
631  GC_TODO: add return values
632
633**/
634STATIC
635VOID
636EFIAPI
637OnReadyToBoot (
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
740VOID
741PR1FSASetting (
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**/
770EFI_STATUS
771EFIAPI
772AcpiPlatformEntryPoint (
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
972
973
974
975
976  //
977  // Update BootMode: 0:ACPI mode; 1:PCI mode
978  //
979  mGlobalNvsArea.Area->LpssSccMode = mSystemConfiguration.LpssPciModeEnabled;
980  if (mSystemConfiguration.LpssMipiHsi == 0) {
981    mGlobalNvsArea.Area->MipiHsiAddr  = 0;
982    mGlobalNvsArea.Area->MipiHsiLen   = 0;
983    mGlobalNvsArea.Area->MipiHsi1Addr = 0;
984    mGlobalNvsArea.Area->MipiHsi1Len  = 0;
985  }
986
987  //
988  // Platform Flavor
989  //
990  mGlobalNvsArea.Area->PlatformFlavor = mPlatformInfo->PlatformFlavor;
991
992  //
993  // Update the Platform id
994  //
995  mGlobalNvsArea.Area->BoardID = mPlatformInfo->BoardId;
996
997  //
998  // Update the  Board Revision
999  //
1000  mGlobalNvsArea.Area->FabID = mPlatformInfo->BoardRev;
1001
1002  //
1003  // Update SOC Stepping
1004  //
1005  mGlobalNvsArea.Area->SocStepping = (UINT8)(PchStepping());
1006
1007  mGlobalNvsArea.Area->OtgMode = mSystemConfiguration.PchUsbOtg;
1008
1009  pchStepping = PchStepping();
1010  if (mSystemConfiguration.UsbAutoMode == 1) {
1011    //
1012    // Auto mode is enabled.
1013    //
1014    if (PchA0 == pchStepping) {
1015      //
1016      //  For A0, EHCI is enabled as default.
1017      //
1018      mSystemConfiguration.PchUsb20       = 1;
1019      mSystemConfiguration.PchUsb30Mode   = 0;
1020      mSystemConfiguration.UsbXhciSupport = 0;
1021      DEBUG ((EFI_D_INFO, "EHCI is enabled as default. SOC 0x%x\n", pchStepping));
1022    } else {
1023      //
1024      //  For A1 and later, XHCI is enabled as default.
1025      //
1026      mSystemConfiguration.PchUsb20       = 0;
1027      mSystemConfiguration.PchUsb30Mode   = 1;
1028      mSystemConfiguration.UsbXhciSupport = 1;
1029      DEBUG ((EFI_D_INFO, "XHCI is enabled as default. SOC 0x%x\n", pchStepping));
1030    }
1031  }
1032
1033  mGlobalNvsArea.Area->XhciMode = mSystemConfiguration.PchUsb30Mode;
1034
1035  mGlobalNvsArea.Area->Stepping = mPlatformInfo->IchRevision;
1036
1037  //
1038  // Override invalid Pre-Boot Driver and XhciMode combination.
1039  //
1040  if ((mSystemConfiguration.UsbXhciSupport == 0) && (mSystemConfiguration.PchUsb30Mode == 3)) {
1041    mGlobalNvsArea.Area->XhciMode = 2;
1042  }
1043  if ((mSystemConfiguration.UsbXhciSupport == 1) && (mSystemConfiguration.PchUsb30Mode == 2)) {
1044    mGlobalNvsArea.Area->XhciMode = 3;
1045  }
1046
1047  DEBUG ((EFI_D_ERROR, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea.Area->XhciMode));
1048
1049  mGlobalNvsArea.Area->PmicEnable                       = GLOBAL_NVS_DEVICE_DISABLE;
1050  mGlobalNvsArea.Area->BatteryChargingSolution          = GLOBAL_NVS_DEVICE_DISABLE;
1051  mGlobalNvsArea.Area->ISPDevSel                        = mSystemConfiguration.ISPDevSel;
1052  mGlobalNvsArea.Area->LpeEnable                        = mSystemConfiguration.Lpe;
1053
1054  if (mSystemConfiguration.ISPEn == 0) {
1055    mGlobalNvsArea.Area->ISPDevSel                      = GLOBAL_NVS_DEVICE_DISABLE;
1056  }
1057
1058  mGlobalNvsArea.Area->WittEnable                       = mSystemConfiguration.WittEnable;
1059  mGlobalNvsArea.Area->UtsEnable                        = mSystemConfiguration.UtsEnable;
1060  mGlobalNvsArea.Area->SarEnable                        = mSystemConfiguration.SAR1;
1061
1062
1063  mGlobalNvsArea.Area->ReservedO                        = 1;
1064
1065  SettingI2CTouchAddress();
1066  mGlobalNvsArea.Area->IdleReserve= mSystemConfiguration.IdleReserve;
1067  //
1068  // Read BMBOUND and store it in GlobalNVS to pass into ASL.
1069  //
1070  // BUGBUG: code was moved into silicon reference code.
1071  //
1072  if (mSystemConfiguration.eMMCBootMode== 1) {
1073    //
1074    // Auto detect mode.
1075    //
1076    DEBUG ((EFI_D_ERROR, "Auto detect mode------------start\n"));
1077
1078    //
1079    // Silicon Steppings.
1080    //
1081    switch (PchStepping()) {
1082      case PchA0: // A0/A1
1083      case PchA1:
1084        DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 Configuration\n"));
1085        mSystemConfiguration.LpsseMMCEnabled            = 1;
1086        mSystemConfiguration.LpsseMMC45Enabled          = 0;
1087        break;
1088
1089      case PchB0: // B0 and later.
1090      default:
1091        DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 Configuration\n"));
1092        mSystemConfiguration.LpsseMMCEnabled            = 0;
1093        mSystemConfiguration.LpsseMMC45Enabled          = 1;
1094        break;
1095   }
1096  } else if (mSystemConfiguration.eMMCBootMode == 2) {
1097      //
1098      // eMMC 4.41
1099      //
1100      DEBUG ((EFI_D_ERROR, "Force to eMMC 4.41 Configuration\n"));
1101      mSystemConfiguration.LpsseMMCEnabled            = 1;
1102      mSystemConfiguration.LpsseMMC45Enabled          = 0;
1103  } else if (mSystemConfiguration.eMMCBootMode == 3) {
1104      //
1105      // eMMC 4.5
1106      //
1107      DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 Configuration\n"));
1108      mSystemConfiguration.LpsseMMCEnabled            = 0;
1109      mSystemConfiguration.LpsseMMC45Enabled          = 1;
1110
1111  } else {
1112      //
1113      // Disable eMMC controllers.
1114      //
1115      DEBUG ((EFI_D_ERROR, "Disable eMMC controllers\n"));
1116      mSystemConfiguration.LpsseMMCEnabled            = 0;
1117      mSystemConfiguration.LpsseMMC45Enabled          = 0;
1118  }
1119
1120  mGlobalNvsArea.Area->emmcVersion = 0;
1121  if (mSystemConfiguration.LpsseMMCEnabled) {
1122     DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 0\n"));
1123     mGlobalNvsArea.Area->emmcVersion = 0;
1124  }
1125
1126  if (mSystemConfiguration.LpsseMMC45Enabled) {
1127     DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
1128     mGlobalNvsArea.Area->emmcVersion = 1;
1129  }
1130
1131  mGlobalNvsArea.Area->SdCardRemovable = mSystemConfiguration.SdCardRemovable;
1132
1133  //
1134  // Microsoft IOT
1135  //
1136  if ((mSystemConfiguration.LpssHsuart0FlowControlEnabled == 1) && \
1137      (mSystemConfiguration.LpssPwm0Enabled == 0) && \
1138      (mSystemConfiguration.LpssPwm1Enabled == 0)) {
1139    mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_ENABLE;
1140    DEBUG ((EFI_D_ERROR, "JP1 is set to be MSFT IOT configuration.\n"));
1141  } else {
1142    mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_DISABLE;
1143    DEBUG ((EFI_D_ERROR, "JP1 is not set to be MSFT IOT configuration.\n"));
1144  }
1145
1146  //
1147  // SIO related option.
1148  //
1149  Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (void **)&mCpuIo);
1150  ASSERT_EFI_ERROR (Status);
1151
1152  mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_DISABLE;
1153
1154  mGlobalNvsArea.Area->DockedSioPresent = GLOBAL_NVS_DEVICE_DISABLE;
1155
1156  if (mGlobalNvsArea.Area->DockedSioPresent != GLOBAL_NVS_DEVICE_ENABLE) {
1157    //
1158    // Check ID for SIO WPCN381U.
1159    //
1160    Status = mCpuIo->Io.Read (
1161                          mCpuIo,
1162                          EfiCpuIoWidthUint8,
1163                          WPCN381U_CONFIG_INDEX,
1164                          1,
1165                          &PortData
1166                          );
1167    ASSERT_EFI_ERROR (Status);
1168    if (PortData != 0xFF) {
1169      PortData = 0x20;
1170      Status = mCpuIo->Io.Write (
1171                            mCpuIo,
1172                            EfiCpuIoWidthUint8,
1173                            WPCN381U_CONFIG_INDEX,
1174                            1,
1175                            &PortData
1176                            );
1177      ASSERT_EFI_ERROR (Status);
1178      Status = mCpuIo->Io.Read (
1179                            mCpuIo,
1180                            EfiCpuIoWidthUint8,
1181                            WPCN381U_CONFIG_DATA,
1182                            1,
1183                            &PortData
1184                            );
1185      ASSERT_EFI_ERROR (Status);
1186      if ((PortData == WPCN381U_CHIP_ID) || (PortData == WDCP376_CHIP_ID)) {
1187        mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_ENABLE;
1188        mGlobalNvsArea.Area->OnboardCom = GLOBAL_NVS_DEVICE_ENABLE;
1189        mGlobalNvsArea.Area->OnboardComCir = GLOBAL_NVS_DEVICE_DISABLE;
1190      }
1191    }
1192  }
1193
1194
1195
1196  //
1197  // Get Ps2 policy to set. Will be use if present.
1198  //
1199  Status =  gBS->LocateProtocol (
1200                   &gEfiPs2PolicyProtocolGuid,
1201                   NULL,
1202                   (VOID **)&Ps2Policy
1203                   );
1204  if (!EFI_ERROR (Status)) {
1205          Status = Ps2Policy->Ps2InitHardware (ImageHandle);
1206  }
1207
1208  mGlobalNvsArea.Area->SDIOMode = mSystemConfiguration.LpssSdioMode;
1209
1210  Handle = NULL;
1211  Status = gBS->InstallMultipleProtocolInterfaces (
1212                  &Handle,
1213                  &gEfiGlobalNvsAreaProtocolGuid,
1214                  &mGlobalNvsArea,
1215                  NULL
1216                  );
1217
1218  //
1219  // Read tables from the storage file.
1220  //
1221  while (!EFI_ERROR (Status)) {
1222    CurrentTable = NULL;
1223
1224    Status = FwVol->ReadSection (
1225                      FwVol,
1226                      &gEfiAcpiTableStorageGuid,
1227                      EFI_SECTION_RAW,
1228                      Instance,
1229                      (VOID **) &CurrentTable,
1230                      (UINTN *) &Size,
1231                      &FvStatus
1232                      );
1233
1234    if (!EFI_ERROR (Status)) {
1235      //
1236      // Allow platform specific code to reject the table or update it.
1237      //
1238      AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable);
1239
1240      if (!EFI_ERROR (AcpiStatus)) {
1241        //
1242        // Perform any table specific updates.
1243        //
1244        AcpiStatus = PlatformUpdateTables (CurrentTable);
1245        if (!EFI_ERROR (AcpiStatus)) {
1246          //
1247          // Add the table.
1248          //
1249          TableHandle = 0;
1250          AcpiStatus = AcpiSupport->SetAcpiTable (
1251                                      AcpiSupport,
1252                                      CurrentTable,
1253                                      TRUE,
1254                                      TableVersion,
1255                                      &TableHandle
1256                                      );
1257          ASSERT_EFI_ERROR (AcpiStatus);
1258        }
1259      }
1260
1261      //
1262      // Increment the instance.
1263      //
1264      Instance++;
1265    }
1266  }
1267
1268  Status = EfiCreateEventReadyToBootEx (
1269             TPL_NOTIFY,
1270             OnReadyToBoot,
1271             NULL,
1272             &Event
1273             );
1274
1275  //
1276  // Finished.
1277  //
1278  return EFI_SUCCESS;
1279}
1280
1281UINT8
1282ReadCmosBank1Byte (
1283  IN  UINT8                           Index
1284  )
1285{
1286  UINT8                               Data;
1287
1288  IoWrite8(0x72, Index);
1289  Data = IoRead8 (0x73);
1290  return Data;
1291}
1292
1293VOID
1294WriteCmosBank1Byte (
1295  IN  UINT8                           Index,
1296  IN  UINT8                           Data
1297  )
1298{
1299  IoWrite8 (0x72, Index);
1300  IoWrite8 (0x73, Data);
1301}
1302
1303
1304
1305VOID
1306SettingI2CTouchAddress (
1307  IN VOID
1308  )
1309{
1310  if (mSystemConfiguration.I2CTouchAd == 0) {
1311    //
1312    // If setup menu select auto set I2C Touch Address base on board id.
1313    //
1314    if (mPlatformInfo->BoardId == BOARD_ID_BL_RVP ||
1315        mPlatformInfo->BoardId == BOARD_ID_BL_STHI ||
1316        mPlatformInfo->BoardId == BOARD_ID_BL_RVP_DDR3L ) {
1317      //
1318      //RVP
1319      //
1320      mGlobalNvsArea.Area->I2CTouchAddress = 0x4B;
1321    } else if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD) {
1322      //
1323      //FFRD
1324      //
1325      mGlobalNvsArea.Area->I2CTouchAddress = 0x4A;
1326    } else if (mPlatformInfo->BoardId == BOARD_ID_BB_RVP) {
1327      mGlobalNvsArea.Area->I2CTouchAddress = 0x4C;
1328    } else if (mPlatformInfo->BoardId == BOARD_ID_CVH) {
1329      mGlobalNvsArea.Area->I2CTouchAddress = 0x4C;
1330    } else if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD8) {
1331      //
1332      //FFRD8 uses 0x4A.
1333      //
1334      mGlobalNvsArea.Area->I2CTouchAddress = 0x4A;
1335    }
1336  } else {
1337    mGlobalNvsArea.Area->I2CTouchAddress = mSystemConfiguration.I2CTouchAd;
1338  }
1339  DEBUG((EFI_D_ERROR, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea.Area->I2CTouchAddress));
1340}
1341
1342
1343