1 /** @file
2 
3   Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
4 
5 
6   This program and the accompanying materials are licensed and made available under
7 
8   the terms and conditions of the BSD License that accompanies this distribution.
9 
10   The full text of the license may be found at
11 
12   http://opensource.org/licenses/bsd-license.php.
13 
14 
15 
16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 
21 
22 
23 
24 Module Name:
25 
26   PlatformEarlyInit.c
27 
28 Abstract:
29 
30   Do platform specific PEI stage initializations.
31 
32 --*/
33 
34 
35 #include "PlatformEarlyInit.h"
36 
37 #ifdef __GNUC__
38 #pragma GCC push_options
39 #pragma GCC optimize ("O0")
40 #else
41 #pragma optimize ("", off)
42 #endif
43 
44 
45 
46 static EFI_PEI_STALL_PPI  mStallPpi = {
47   PEI_STALL_RESOLUTION,
48   Stall
49 };
50 
51 static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi = {
52   EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
53   &gEfiPeiStallPpiGuid,
54   &mStallPpi
55 };
56 
57 //
58 // The reserved SMBus addresses are defined in PlatformDxe.h file.
59 //
60 static UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;
61 static PEI_SMBUS_POLICY_PPI         mSmbusPolicyPpi = {
62   SMBUS_BASE_ADDRESS,
63   SMBUS_BUS_DEV_FUNC,
64   PLATFORM_NUM_SMBUS_RSVD_ADDRESSES,
65   mSmbusRsvdAddresses
66 };
67 
68 static EFI_PEI_PPI_DESCRIPTOR       mInstallSmbusPolicyPpi = {
69   EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
70   &gPeiSmbusPolicyPpiGuid,
71   &mSmbusPolicyPpi
72 };
73 static PEI_SPEAKER_IF_PPI    mSpeakerInterfacePpi = {
74   ProgramToneFrequency,
75   GenerateBeepTone
76 };
77 
78 static EFI_PEI_PPI_DESCRIPTOR       mInstallSpeakerInterfacePpi = {
79   EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
80   &gPeiSpeakerInterfacePpiGuid,
81   &mSpeakerInterfacePpi
82 };
83 
84 static EFI_PEI_RESET_PPI            mResetPpi = { IchReset };
85 
86 
87 static EFI_PEI_FIND_FV_PPI mEfiFindFvPpi = {
88   (EFI_PEI_FIND_FV_FINDFV)FindFv
89 };
90 
91 static EFI_PEI_PPI_DESCRIPTOR       mPpiList[] = {
92   {
93     EFI_PEI_PPI_DESCRIPTOR_PPI,
94     &gEfiPeiMasterBootModePpiGuid,
95     NULL
96   },
97   {
98     EFI_PEI_PPI_DESCRIPTOR_PPI,
99     &gEfiPeiResetPpiGuid,
100     &mResetPpi
101   },
102   {
103     (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
104     &gEfiFindFvPpiGuid,
105     &mEfiFindFvPpi
106   }
107 };
108 
109 static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
110   {
111     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
112     &gEfiEndOfPeiSignalPpiGuid,
113     (EFI_PEIM_NOTIFY_ENTRY_POINT)EndOfPeiPpiNotifyCallback
114   },
115   {
116     (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
117     &gEfiPeiMemoryDiscoveredPpiGuid,
118     (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotifyCallback
119   }
120 
121 };
122 
123 
124 /**
125 
126   Parse the status registers for figuring out the wake-up event and save it into
127   an GUID HOB which will be referenced later. However, modification is required
128   to meet the chipset register definition and the practical hardware design. Thus,
129   this is just an example.
130 
131 
GetWakeupEventAndSaveToHob(IN CONST EFI_PEI_SERVICES ** PeiServices)132   @param PeiServices    pointer to the PEI Service Table
133   @param EFI_SUCCESS    Always return Success
134 
135   @retval None
136 
137 
138 **/
139 EFI_STATUS
140 EFIAPI
141 GetWakeupEventAndSaveToHob (
142   IN CONST EFI_PEI_SERVICES   **PeiServices
143   )
144 {
145   UINT16  Pm1Sts;
146   UINTN   Gpe0Sts;
147   UINTN   WakeEventData;
148 
149   //
150   // Read the ACPI registers
151   //
152   Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
153   Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);
154 
155   //
156   // Figure out the wake-up event
157   //
158   if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) != 0) {
159     WakeEventData = SMBIOS_WAKEUP_TYPE_POWER_SWITCH;
160   } else if (((Pm1Sts & B_PCH_ACPI_PM1_STS_WAK) != 0)) {
161     WakeEventData = SMBIOS_WAKEUP_TYPE_PCI_PME;
162   } else if (Gpe0Sts != 0) {
163     WakeEventData = SMBIOS_WAKEUP_TYPE_OTHERS;
164   } else {
165     WakeEventData = SMBIOS_WAKEUP_TYPE_UNKNOWN;
166   }
167 
168   DEBUG ((EFI_D_ERROR, "ACPI Wake Status Register: %04x\n", Pm1Sts));
169   DEBUG ((EFI_D_ERROR, "ACPI Wake Event Data: %02x\n", WakeEventData));
170 
171   return EFI_SUCCESS;
172 }
173 
174 EFI_STATUS
175 GetSetupVariable (
176   IN CONST EFI_PEI_SERVICES                **PeiServices,
177   IN   SYSTEM_CONFIGURATION          *SystemConfiguration
178   )
179 {
180   UINTN                        VariableSize;
181   EFI_STATUS                   Status;
182   EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
183 
184   VariableSize = sizeof (SYSTEM_CONFIGURATION);
185   ZeroMem (SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
186 
187   Status = (*PeiServices)->LocatePpi (
188                              PeiServices,
189                              &gEfiPeiReadOnlyVariable2PpiGuid,
190                              0,
191                              NULL,
192                                       (void **)&Variable
193                              );
194   ASSERT_EFI_ERROR (Status);
195 
196   //
197   // Use normal setup default from NVRAM variable,
198   // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
199   //
200   VariableSize = sizeof(SYSTEM_CONFIGURATION);
201   Status = Variable->GetVariable (
202                        Variable,
203                        L"Setup",
204                        &gEfiSetupVariableGuid,
205                        NULL,
206                        &VariableSize,
207                        SystemConfiguration
208                        );
209   if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
210     //The setup variable is corrupted
211     VariableSize = sizeof(SYSTEM_CONFIGURATION);
212     Status = Variable->GetVariable(
213               Variable,
214               L"SetupRecovery",
215               &gEfiSetupVariableGuid,
216               NULL,
VlvPolicyInit(IN CONST EFI_PEI_SERVICES ** PeiServices,IN SYSTEM_CONFIGURATION * SystemConfiguration)217               &VariableSize,
218               SystemConfiguration
219               );
220     ASSERT_EFI_ERROR (Status);
221   }
222   return Status;
223 }
224 
225 EFI_STATUS
226 VlvPolicyInit (
227   IN CONST EFI_PEI_SERVICES             **PeiServices,
228   IN SYSTEM_CONFIGURATION         *SystemConfiguration
229   )
230 {
231   EFI_STATUS                      Status;
232   EFI_PEI_PPI_DESCRIPTOR          *mVlvPolicyPpiDesc;
233   VLV_POLICY_PPI                   *mVlvPolicyPpi;
234 
235   Status = (*PeiServices)->AllocatePool(
236                              PeiServices,
237                              sizeof (EFI_PEI_PPI_DESCRIPTOR),
238                              (void **)&mVlvPolicyPpiDesc
239                              );
240   ASSERT_EFI_ERROR (Status);
241 
242   Status = (*PeiServices)->AllocatePool(
243                              PeiServices,
244                              sizeof (VLV_POLICY_PPI),
245                              (void **)&mVlvPolicyPpi
246                              );
247   ASSERT_EFI_ERROR (Status);
248 
249   //
250   // Initialize PPI
251   //
252   (*PeiServices)->SetMem ((VOID *)mVlvPolicyPpi, sizeof (VLV_POLICY_PPI), 0);
253   mVlvPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
254   mVlvPolicyPpiDesc->Guid = &gVlvPolicyPpiGuid;
255   mVlvPolicyPpiDesc->Ppi = mVlvPolicyPpi;
256   mVlvPolicyPpi->GtConfig.PrimaryDisplay = SystemConfiguration->PrimaryVideoAdaptor;
257   mVlvPolicyPpi->GtConfig.IgdDvmt50PreAlloc = SystemConfiguration->IgdDvmt50PreAlloc;
258   mVlvPolicyPpi->GtConfig.ApertureSize = SystemConfiguration->IgdApertureSize;
259   mVlvPolicyPpi->GtConfig.GttSize = SystemConfiguration->GTTSize;
260   if (SystemConfiguration->PrimaryVideoAdaptor != 2) {
261     mVlvPolicyPpi->GtConfig.InternalGraphics = SystemConfiguration->Igd;
262   } else {
263     mVlvPolicyPpi->GtConfig.InternalGraphics = 0;
264   }
265 
266 
267   mVlvPolicyPpi->GtConfig.IgdTurboEn = 1;
268 
269 
270   mVlvPolicyPpi->PlatformData.FastBoot = SystemConfiguration->FastBoot;
271   mVlvPolicyPpi->PlatformData.DynSR = 1;
272   DEBUG ((EFI_D_ERROR, "Setup Option ISPEn: 0x%x\n", SystemConfiguration->ISPEn));
273   mVlvPolicyPpi->ISPEn                      = SystemConfiguration->ISPEn;
274   DEBUG ((EFI_D_ERROR, "Setup Option ISPDevSel: 0x%x\n", SystemConfiguration->ISPDevSel));
275   mVlvPolicyPpi->ISPPciDevConfig            = SystemConfiguration->ISPDevSel;
276   if (SystemConfiguration->ISPEn == 0) {
277     mVlvPolicyPpi->ISPPciDevConfig          = 0;
278     DEBUG ((EFI_D_ERROR, "Update Setup Option ISPDevSel: 0x%x\n", mVlvPolicyPpi->ISPPciDevConfig));
279   }
280   Status = (*PeiServices)->InstallPpi(
281                              PeiServices,
ConfigureSoCGpio(IN SYSTEM_CONFIGURATION * SystemConfiguration)282                              mVlvPolicyPpiDesc
283                              );
284   ASSERT_EFI_ERROR (Status);
285 
286   return EFI_SUCCESS;
287 }
288 
289 
290 EFI_STATUS
291 ConfigureSoCGpio (
292   IN SYSTEM_CONFIGURATION  *SystemConfiguration
293   )
294 {
295 
296     DEBUG ((EFI_D_ERROR, "ConfigureSoCGpio------------start\n"));
297     if (SystemConfiguration->eMMCBootMode== 1) {// Auto detection mode
298      DEBUG ((EFI_D_ERROR, "Auto detection mode------------start\n"));
299 
300      //
301      //Silicon Steppings
302      //
303      switch (PchStepping()) {
304        case PchA0:  // SOC A0 and A1
305        case PchA1:
306          DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 GPIO Configuration\n"));
307          SystemConfiguration->LpsseMMCEnabled            = 1;
308          SystemConfiguration->LpsseMMC45Enabled          = 0;
309          break;
310        case PchB0:  // SOC B0 and later
311        default:
312          DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 GPIO Configuration\n"));
313          SystemConfiguration->LpsseMMCEnabled            = 0;
314          SystemConfiguration->LpsseMMC45Enabled          = 1;
315          break;
316      }
317     } else if (SystemConfiguration->eMMCBootMode == 2) { // eMMC 4.41
318         DEBUG ((EFI_D_ERROR, "Force to eMMC 4.41 GPIO Configuration\n"));
319         SystemConfiguration->LpsseMMCEnabled            = 1;
320         SystemConfiguration->LpsseMMC45Enabled          = 0;
321     } else if (SystemConfiguration->eMMCBootMode == 3) { // eMMC 4.5
322          DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 GPIO Configuration\n"));
323          SystemConfiguration->LpsseMMCEnabled            = 0;
324          SystemConfiguration->LpsseMMC45Enabled          = 1;
325 
326     } else { // Disable eMMC controllers
327          DEBUG ((EFI_D_ERROR, "Disable eMMC GPIO controllers\n"));
328          SystemConfiguration->LpsseMMCEnabled            = 0;
329          SystemConfiguration->LpsseMMC45Enabled          = 0;
330     }
331 
332   /*
333   20.1.1  EMMC
334   SDMMC1_CLK -         write 0x2003ED01 to IOBASE + 0x03E0
335   SDMMC1_CMD -        write 0x2003EC81 to IOBASE + 0x0390
336   SDMMC1_D0 -           write 0x2003EC81 to IOBASE + 0x03D0
337   SDMMC1_D1 -           write 0x2003EC81 to IOBASE + 0x0400
338   SDMMC1_D2 -           write 0x2003EC81 to IOBASE + 0x03B0
339   SDMMC1_D3_CD_B - write 0x2003EC81 to IOBASE + 0x0360
340   MMC1_D4_SD_WE -   write 0x2003EC81 to IOBASE + 0x0380
341   MMC1_D5 -                write 0x2003EC81 to IOBASE + 0x03C0
342   MMC1_D6 -                write 0x2003EC81 to IOBASE + 0x0370
343   MMC1_D7 -                write 0x2003EC81 to IOBASE + 0x03F0
344   MMC1_RESET_B -       write 0x2003ED01 to IOBASE + 0x0330
345   */
346   if (SystemConfiguration->LpsseMMCEnabled== 1) {
347     MmioWrite32 (IO_BASE_ADDRESS + 0x03E0, 0x2003ED01); //EMMC 4.41
348     MmioWrite32 (IO_BASE_ADDRESS + 0x0390, 0x2003EC81);
349     MmioWrite32 (IO_BASE_ADDRESS + 0x03D0, 0x2003EC81);
350     MmioWrite32 (IO_BASE_ADDRESS + 0x0400, 0x2003EC81);
351     MmioWrite32 (IO_BASE_ADDRESS + 0x03B0, 0x2003EC81);
352     MmioWrite32 (IO_BASE_ADDRESS + 0x0360, 0x2003EC81);
353     MmioWrite32 (IO_BASE_ADDRESS + 0x0380, 0x2003EC81);
354     MmioWrite32 (IO_BASE_ADDRESS + 0x03C0, 0x2003EC81);
355     MmioWrite32 (IO_BASE_ADDRESS + 0x0370, 0x2003EC81);
356     MmioWrite32 (IO_BASE_ADDRESS + 0x03F0, 0x2003EC81);
357     MmioWrite32 (IO_BASE_ADDRESS + 0x0330, 0x2003ED01);
358   }
359 
360   /*
361   eMMC 4.5 controller
362   SDMMC1_CLK -         write 0x2003ED03 to IOBASE + 0x03E0
363   SDMMC1_CMD -        write 0x2003EC83 to IOBASE + 0x0390
364   SDMMC1_D0 -           write 0x2003EC83 to IOBASE + 0x03D0
365   SDMMC1_D1 -           write 0x2003EC83 to IOBASE + 0x0400
366   SDMMC1_D2 -           write 0x2003EC83 to IOBASE + 0x03B0
367   SDMMC1_D3_CD_B -  write 0x2003EC83 to IOBASE + 0x0360
368   MMC1_D4_SD_WE -   write 0x2003EC83 to IOBASE + 0x0380
369   MMC1_D5 -                write 0x2003EC83 to IOBASE + 0x03C0
370   MMC1_D6 -                write 0x2003EC83 to IOBASE + 0x0370
371   MMC1_D7 -                write 0x2003EC83 to IOBASE + 0x03F0
372   MMC1_RESET_B -       write 0x2003ED03 to IOBASE + 0x0330
373   */
374   if (SystemConfiguration->LpsseMMC45Enabled== 1) {
375     MmioWrite32 (IO_BASE_ADDRESS + 0x03E0, 0x2003ED03); // EMMC 4.5
376     MmioWrite32 (IO_BASE_ADDRESS + 0x0390, 0x2003EC83);
377     MmioWrite32 (IO_BASE_ADDRESS + 0x03D0, 0x2003EC83);
378     MmioWrite32 (IO_BASE_ADDRESS + 0x0400, 0x2003EC83);
379     MmioWrite32 (IO_BASE_ADDRESS + 0x03B0, 0x2003EC83);
380     MmioWrite32 (IO_BASE_ADDRESS + 0x0360, 0x2003EC83);
381     MmioWrite32 (IO_BASE_ADDRESS + 0x0380, 0x2003EC83);
382     MmioWrite32 (IO_BASE_ADDRESS + 0x03C0, 0x2003EC83);
383     MmioWrite32 (IO_BASE_ADDRESS + 0x0370, 0x2003EC83);
384     MmioWrite32 (IO_BASE_ADDRESS + 0x03F0, 0x2003EC83);
385     MmioWrite32 (IO_BASE_ADDRESS + 0x0330, 0x2003ED03);
386 
387   }
388 
389 //
MeasuredBootInit(IN CONST EFI_PEI_SERVICES ** PeiServices,IN SYSTEM_CONFIGURATION * SystemConfiguration)390 // Change GPIOC_0 setting to allow MMIO access under Android.
391 //
392   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL,
393            (IoRead32(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL) & (UINT32)~BIT0));
394   DEBUG ((EFI_D_ERROR, "ConfigureSoCGpio------------end\n"));
395   return EFI_SUCCESS;
396 }
397 
398 EFI_STATUS
399 MeasuredBootInit (
400   IN CONST EFI_PEI_SERVICES        **PeiServices,
401   IN SYSTEM_CONFIGURATION           *SystemConfiguration
402   )
403 {
404   if (SystemConfiguration->MeasuredBootEnable) {
405     PcdSetBool (PcdMeasuredBootEnable, TRUE);
ConfigureLpssAndSccGpio(IN SYSTEM_CONFIGURATION * SystemConfiguration,IN EFI_PLATFORM_INFO_HOB * PlatformInfo)406   } else {
407     PcdSetBool (PcdMeasuredBootEnable, FALSE);
408   }
409 
410   return EFI_SUCCESS;
411 }
412 
413 
414 EFI_STATUS
415 ConfigureLpssAndSccGpio (
416   IN SYSTEM_CONFIGURATION        *SystemConfiguration,
417   IN EFI_PLATFORM_INFO_HOB       *PlatformInfo
418   )
419 {
420   /*One time configuration to each GPIO controller PSB_CONF register should be done before starting pad configuration:
421   GPIO SCORE -  write 0x01001002 to IOBASE + 0x0700
422   GPIO NCORE -  write 0x01001002 to IOBASE + 0x0F00
423   GPIO SSUS -    write 0x01001002 to IOBASE + 0x1700
424   */
425     DEBUG ((EFI_D_ERROR, "ConfigureLpssAndSccGpio------------start\n"));
426 
427   /*
428   19.1.1  PWM0
429   PWM0 - write 0x2003CD01 to IOBASE + 0x00A0
430   19.1.2  PWM1
431   PWM0 - write 0x2003CD01 to IOBASE + 0x00B0
432   */
433   if (SystemConfiguration->LpssPwm0Enabled== 1) {
434     MmioWrite32 (IO_BASE_ADDRESS + 0x00A0, 0x2003CD01);
435   } else if (SystemConfiguration->LpssPwm0Enabled== 0) {
436     MmioWrite32 (IO_BASE_ADDRESS + 0x00A0, 0x2003CD00);
437   }
438 
439   if (SystemConfiguration->LpssPwm1Enabled== 1) {
440     MmioWrite32 (IO_BASE_ADDRESS + 0x00B0, 0x2003CC01);
441   } else if (SystemConfiguration->LpssPwm1Enabled== 0) {
442     MmioWrite32 (IO_BASE_ADDRESS + 0x00B0, 0x2003CD00);
443   }
444 
445   /*
446   19.1.3  UART1
447   UART1_RXD-L -     write 0x2003CC81 to IOBASE + 0x0020
448   UART1_TXD-0 -     write 0x2003CC81 to IOBASE + 0x0010
449   UART1_RTS_B-1 - write 0x2003CC81 to IOBASE + 0x0000
450   UART1_CTS_B-H - write 0x2003CC81 to IOBASE + 0x0040
451   */
452   if (SystemConfiguration->LpssHsuart0Enabled== 1) {
453     MmioWrite32 (IO_BASE_ADDRESS + 0x0020, 0x2003CC81); // uart1
454     MmioWrite32 (IO_BASE_ADDRESS + 0x0010, 0x2003CC81);
455   if (SystemConfiguration->LpssHsuart0FlowControlEnabled== 0) {
456     DEBUG ((EFI_D_ERROR, "LpssHsuart0FlowControlEnabled[0]\n"));
457     MmioWrite32 (IO_BASE_ADDRESS + 0x0000, 0x2003CC80);
458     MmioWrite32 (IO_BASE_ADDRESS + 0x0040, 0x2003CC80);
459   } else {
460     DEBUG ((EFI_D_ERROR, "LpssHsuart0FlowControlEnabled[1]\n"));
461     MmioWrite32 (IO_BASE_ADDRESS + 0x0000, 0x2003CC81);
462     MmioWrite32 (IO_BASE_ADDRESS + 0x0040, 0x2003CC01);//W/A HSD 4752617 0x2003CC81
463     }
464   } else if (SystemConfiguration->LpssHsuart0Enabled== 0) {
465     MmioWrite32 (IO_BASE_ADDRESS + 0x0020, 0x2003CC80); // uart1
466     MmioWrite32 (IO_BASE_ADDRESS + 0x0010, 0x2003CC80);
467   }
468 
469 
470   /*
471   19.1.4  UART2
472   UART2_RTS_B-1 -  write 0x2003CC81 to IOBASE + 0x0090
473   UART2_CTS_B-H - write 0x2003CC81 to IOBASE + 0x0080
474   UART2_RXD-H -    write 0x2003CC81 to IOBASE + 0x0060
475   UART2_TXD-0 -     write 0x2003CC81 to IOBASE + 0x0070
476   */
477   if (SystemConfiguration->LpssHsuart1Enabled== 1) {
478     MmioWrite32 (IO_BASE_ADDRESS + 0x0060, 0x2003CC81);
479     MmioWrite32 (IO_BASE_ADDRESS + 0x0070, 0x2003CC81);
480 
481   if (SystemConfiguration->LpssHsuart1FlowControlEnabled== 0) {
482     DEBUG ((EFI_D_ERROR, "LpssHsuart1FlowControlEnabled[0]\n"));
483     MmioWrite32 (IO_BASE_ADDRESS + 0x0090, 0x2003CC80); // UART2_RTS_B
484     MmioWrite32 (IO_BASE_ADDRESS + 0x0080, 0x2003CC80); // UART2_CTS_B
485   } else {
486     DEBUG ((EFI_D_ERROR, "LpssHsuart1FlowControlEnabled[1]\n"));
487     MmioWrite32 (IO_BASE_ADDRESS + 0x0090, 0x2003CC81); // uart2
488     MmioWrite32 (IO_BASE_ADDRESS + 0x0080, 0x2003CC01); //W/A HSD 4752617 0x2003CC81
489   }
490   } else if (SystemConfiguration->LpssHsuart1Enabled== 0) {
491   MmioWrite32 (IO_BASE_ADDRESS + 0x0060, 0x2003CC80);
492   MmioWrite32 (IO_BASE_ADDRESS + 0x0070, 0x2003CC80);
493   }
494 
495   /*
496   19.1.5  SPI
497   SPI1_CS0_B - write 0x2003CC81 to IOBASE + 0x0110
498   SPI1_CLK -     write 0x2003CD01 to IOBASE + 0x0100
499   SPI1_MOSI -   write 0x2003CC81 to IOBASE + 0x0130
500   SPI1_MISO -   write 0x2003CC81 to IOBASE + 0x0120
501   */
502   if (SystemConfiguration->LpssSpiEnabled== 1) {
503     MmioWrite32 (IO_BASE_ADDRESS + 0x0110, 0x2003CC81); // SPI
504     MmioWrite32 (IO_BASE_ADDRESS + 0x0100, 0x2003CD01);
505     MmioWrite32 (IO_BASE_ADDRESS + 0x0130, 0x2003CC81);
506     MmioWrite32 (IO_BASE_ADDRESS + 0x0120, 0x2003CC81);
507   } else if (SystemConfiguration->LpssSpiEnabled== 0) {
508     MmioWrite32 (IO_BASE_ADDRESS + 0x0110, 0x2003cc80);
509     MmioWrite32 (IO_BASE_ADDRESS + 0x0100, 0x2003cc80);
510     MmioWrite32 (IO_BASE_ADDRESS + 0x0130, 0x2003cc80);
511     MmioWrite32 (IO_BASE_ADDRESS + 0x0120, 0x2003cc80);
512   }
513 
514   /*
515   19.1.6  I2C0
516   I2C0_SDA-OD-O -    write 0x2003CC81 to IOBASE + 0x0210
517   I2C0_SCL-OD-O -    write 0x2003CC81 to IOBASE + 0x0200
518   */
519   if (SystemConfiguration->LpssI2C0Enabled== 1) {
520     MmioWrite32 (IO_BASE_ADDRESS + 0x0210, 0x2003C881);
521     MmioWrite32 (IO_BASE_ADDRESS + 0x0200, 0x2003C881);
522   }
523   /*
524   19.1.7  I2C1
525   I2C1_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01F0
526   I2C1_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01E0
527   */
528 
529   if (SystemConfiguration->LpssI2C1Enabled== 1) {
530     MmioWrite32 (IO_BASE_ADDRESS + 0x01F0, 0x2003C881);
531     MmioWrite32 (IO_BASE_ADDRESS + 0x01E0, 0x2003C881);
532   }
533   /*
534   19.1.8  I2C2
535   I2C2_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01D0
536   I2C2_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01B0
537   */
538   if (SystemConfiguration->LpssI2C2Enabled== 1) {
539     MmioWrite32 (IO_BASE_ADDRESS + 0x01D0, 0x2003C881);
540     MmioWrite32 (IO_BASE_ADDRESS + 0x01B0, 0x2003C881);
541   }
542   /*
543   19.1.9  I2C3
544   I2C3_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0190
545   I2C3_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01C0
546   */
547   if (SystemConfiguration->LpssI2C3Enabled== 1) {
548     MmioWrite32 (IO_BASE_ADDRESS + 0x0190, 0x2003C881);
549     MmioWrite32 (IO_BASE_ADDRESS + 0x01C0, 0x2003C881);
550   }
551   /*
552   19.1.10 I2C4
553   I2C4_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01A0
554   I2C4_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0170
555   */
556   if (SystemConfiguration->LpssI2C4Enabled== 1) {
557     MmioWrite32 (IO_BASE_ADDRESS + 0x01A0, 0x2003C881);
558     MmioWrite32 (IO_BASE_ADDRESS + 0x0170, 0x2003C881);
559   }
560   /*
561   19.1.11 I2C5
562   I2C5_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0150
563   I2C5_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0140
564   */
565   //touch 1.7M support on i2c5(from 0) need 2k PULL-UP.
566   if (SystemConfiguration->LpssI2C5Enabled== 1) {
567     MmioWrite32 (IO_BASE_ADDRESS + 0x0150, 0x2003C881);
568     MmioWrite32 (IO_BASE_ADDRESS + 0x0140, 0x2003C881);
569   } else if(SystemConfiguration->LpssI2C5Enabled== 0) {
570     MmioWrite32 (IO_BASE_ADDRESS + 0x0150, 0x2003C880);
571     MmioWrite32 (IO_BASE_ADDRESS + 0x0140, 0x2003C880);
572   }
573   /*
574   19.1.12 I2C6
575   I2C6_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0180
576   I2C6_SCL-OD-O/I -  write 0x2003CC81 to IOBASE + 0x0160
577   */
578   if (SystemConfiguration->LpssI2C6Enabled== 1) {
579     MmioWrite32 (IO_BASE_ADDRESS + 0x0180, 0x2003C881);
580     MmioWrite32 (IO_BASE_ADDRESS + 0x0160, 0x2003C881);
581   } else if (SystemConfiguration->LpssI2C6Enabled== 0) {
582     MmioWrite32 (IO_BASE_ADDRESS + 0x0180, 0x2003C880);
583     MmioWrite32 (IO_BASE_ADDRESS + 0x0160, 0x2003C880);
584   }
585 
586 
587   /*
588   20.1.2  SDIO
589   SDMMC2_CLK -  write 0x2003ED01 to IOBASE + 0x0320
590   SDMMC2_CMD - write 0x2003EC81 to IOBASE + 0x0300
591   SDMMC2_D0 -    write 0x2003EC81 to IOBASE + 0x0350
592   SDMMC2_D1 -    write 0x2003EC81 to IOBASE + 0x02F0
593   SDMMC2_D2 -    write 0x2003EC81 to IOBASE + 0x0340
594   SDMMC2_D3_CD_B - write 0x2003EC81 to IOBASE + 0x0310
595   */
596   if (SystemConfiguration->LpssSdioEnabled== 1) {
597     MmioWrite32 (IO_BASE_ADDRESS + 0x0320, 0x2003ED01);//SDIO
598     MmioWrite32 (IO_BASE_ADDRESS + 0x0300, 0x2003EC81);
599     MmioWrite32 (IO_BASE_ADDRESS + 0x0350, 0x2003EC81);
600     MmioWrite32 (IO_BASE_ADDRESS + 0x02F0, 0x2003EC81);
601     MmioWrite32 (IO_BASE_ADDRESS + 0x0340, 0x2003EC81);
602     MmioWrite32 (IO_BASE_ADDRESS + 0x0310, 0x2003EC81);
603   }
604 
605   /*
606   20.1.3  SD Card
607   SDMMC3_1P8_EN - write 0x2003CD01 to IOBASE + 0x03F0
608   SDMMC3_CD_B -    write 0x2003CC81 to IOBASE + 0x03A0
609   SDMMC3_CLK -       write 0x2003CD01 to IOBASE + 0x02B0
610   SDMMC3_CMD -      write 0x2003CC81 to IOBASE + 0x02C0
611   SDMMC3_D0 -         write 0x2003CC81 to IOBASE + 0x02E0
612   SDMMC3_D1 -         write 0x2003CC81 to IOBASE + 0x0290
613   SDMMC3_D2 -         write 0x2003CC81 to IOBASE + 0x02D0
614   SDMMC3_D3 -         write 0x2003CC81 to IOBASE + 0x02A0
615   SDMMC3_PWR_EN_B - write 0x2003CC81 to IOBASE + 0x0690
616   SDMMC3_WP -            write 0x2003CC82 to IOBASE + 0x0160
617   */
618   if (SystemConfiguration->LpssSdcardEnabled == 1) {
619     if (!((PlatformInfo->BoardId == BOARD_ID_BL_FFRD && PlatformInfo->BoardRev== PR11) && (SystemConfiguration->CfioPnpSettings == 1))) {
620       MmioWrite32 (IO_BASE_ADDRESS + 0x05F0, 0x2003CD01);//SDCARD
621       MmioWrite32 (IO_BASE_ADDRESS + 0x02B0, 0x2003CD01);
622       MmioWrite32 (IO_BASE_ADDRESS + 0x02C0, 0x2003CC81);
623       MmioWrite32 (IO_BASE_ADDRESS + 0x02E0, 0x2003CC81);
624       MmioWrite32 (IO_BASE_ADDRESS + 0x0290, 0x2003CC81);
625       MmioWrite32 (IO_BASE_ADDRESS + 0x02D0, 0x2003CC81);
626       MmioWrite32 (IO_BASE_ADDRESS + 0x02A0, 0x2003CC81);
627       MmioWrite32 (IO_BASE_ADDRESS + 0x0690, 0x2003CC81);
628       MmioWrite32 (IO_BASE_ADDRESS + 0x0650, 0x2003CC82); //GPIOC_7 set to WP Pin
ConfigureLpeGpio(IN SYSTEM_CONFIGURATION * SystemConfiguration)629      }
630   }
631 
632 
633      DEBUG ((EFI_D_ERROR, "ConfigureLpssAndSccGpio------------end\n"));
634     return EFI_SUCCESS;
635 }
636 
637 EFI_STATUS
638 ConfigureLpeGpio (
639   IN SYSTEM_CONFIGURATION  *SystemConfiguration
640   )
641 {
642   DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------start\n"));
643 
644   if (SystemConfiguration->PchAzalia == 0) {
645     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x220, (UINT32)~(0x7), (UINT32) (0x01));
646     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x250, (UINT32)~(0x7), (UINT32) (0x01));
647     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x240, (UINT32)~(0x7), (UINT32) (0x01));
648     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x260, (UINT32)~(0x7), (UINT32) (0x01));
649     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x270, (UINT32)~(0x7), (UINT32) (0x01));
650     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x230, (UINT32)~(0x7), (UINT32) (0x01));
651     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x280, (UINT32)~(0x7), (UINT32) (0x01));
ConfigureSciSmiGpioRout(IN EFI_PLATFORM_INFO_HOB * PlatformInfo)652     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x540, (UINT32)~(0x7), (UINT32) (0x01));
653   }
654 
655   DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------end\n"));
656 
657   return EFI_SUCCESS;
658 }
659 
660 EFI_STATUS
661 ConfigureSciSmiGpioRout (
662   IN EFI_PLATFORM_INFO_HOB       *PlatformInfo)
663 {
664 	UINT32 	GPI_Routing;
665 
666 	GPI_Routing = MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_GPI_ROUT);
667 
668 	//
669 	// For FAB3, Route GPIO_CORE 0 to cause Runtime SCI, GPIO_SUS 0 to cause Wake SCI and GPIO_SUS 7 to cause EXTSMI
670 	//
671 	if(PlatformInfo->BoardRev == 3) {
672 	GPI_Routing = GPI_Routing & 0xfffc3ffc;
673 	GPI_Routing = GPI_Routing | 0x00024002;
674 	}
675 
676 	//
677 	// For FAB2/1, Route GPIO_CORE 7 to cause Runtime SCI, GPIO_SUS 0 to cause Wake SCI and GPIO_SUS 7 to cause EXTSMI
678 	//
679 	else {
ConfigureMipiCsi(VOID)680 	GPI_Routing = GPI_Routing & 0x3fff3ffc;
681 	GPI_Routing = GPI_Routing | 0x80004002;
682 	}
683 	MmioWrite32((PMC_BASE_ADDRESS + R_PCH_PMC_GPI_ROUT), GPI_Routing);
684 
685 	return EFI_SUCCESS;
686 }
687 
688 EFI_STATUS
689 ConfigureMipiCsi (
690   VOID)
691 {
692 	  //
693     //Configure the platform clock for MIPI-CSI usage
694     //PLT_CLK0
695     //
696     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x6a0, (UINT32)~(0x7), (UINT32) (0x01));
697 
698     //
699     //PLT_CLK1
700     //
701     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x570, (UINT32)~(0x7), (UINT32) (0x01));
702 
ConfigureUSBULPI(VOID)703     //
704     //PLT_CLK2
705     //
706     MmioAndThenOr32 (IO_BASE_ADDRESS + 0x5B0, (UINT32)~(0x7), (UINT32) (0x01));
707 
708     return EFI_SUCCESS;
709 }
710 
711 EFI_STATUS
712 ConfigureUSBULPI (
713   VOID)
714 {
715 	  //
716     //Configure USB ULPI
717     //USB_ULPI_0_CLK
718     //
719     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x338, (UINT32)~(0x7), (UINT32) (GPI));
720     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x330, (UINT32)~(0x187), (UINT32) (0x101));
721 
722     //
723     //USB_ULPI_0_DATA0
724     //
725     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x388, (UINT32)~(0x7), (UINT32) (GPI));
726     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x380, (UINT32)~(0x187), (UINT32) (0x101));
727 
728     //
729     //USB_ULPI_0_DATA1
730     //
731     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x368, (UINT32)~(0x7), (UINT32) (GPI));
732     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x360, (UINT32)~(0x187), (UINT32) (0x101));
733 
734     //
735     //USB_ULPI_0_DATA2
736     //
737     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x318, (UINT32)~(0x7), (UINT32) (GPI));
738     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x310, (UINT32)~(0x187), (UINT32) (0x101));
739 
740     //
741     //USB_ULPI_0_DATA3
742     //
743     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x378, (UINT32)~(0x7), (UINT32) (GPI));
744     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x370, (UINT32)~(0x187), (UINT32) (0x101));
745 
746     //
747     //USB_ULPI_0_DATA4
748     //
749     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x308, (UINT32)~(0x7), (UINT32) (GPI));
750     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x300, (UINT32)~(0x187), (UINT32) (0x101));
751 
752     //
753     //USB_ULPI_0_DATA5
754     //
755     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x398, (UINT32)~(0x7), (UINT32) (GPI));
756     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x390, (UINT32)~(0x187), (UINT32) (0x101));
757 
758     //
759     //USB_ULPI_0_DATA6
760     //
761     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x328, (UINT32)~(0x7), (UINT32) (GPI));
762     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x320, (UINT32)~(0x187), (UINT32) (0x101));
763 
764     //
765     //USB_ULPI_0_DATA7
766     //
767     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a8, (UINT32)~(0x7), (UINT32) (GPI));
768     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a0, (UINT32)~(0x187), (UINT32) (0x101));
769 
770     //
771     //USB_ULPI_0_DIR
772     //
773     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x348, (UINT32)~(0x7), (UINT32) (GPI));
774     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x340, (UINT32)~(0x187), (UINT32) (0x81));
775 
776     //
777     //USB_ULPI_0_NXT
778     //
779     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x358, (UINT32)~(0x7), (UINT32) (GPI));
780     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x350, (UINT32)~(0x187), (UINT32) (0x101));
781 
782     //
783     //USB_ULPI_0_STP
784     //
785     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b8, (UINT32)~(0x7), (UINT32) (GPI));
786     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b0, (UINT32)~(0x187), (UINT32) (0x81));
787 
788     //
DisableRTD3(VOID)789     //USB_ULPI_0_REFCLK
790     //
791     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x288, (UINT32)~(0x7), (UINT32) (GPI));
792     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x280, (UINT32)~(0x187), (UINT32) (0x101));
793 
794     return EFI_SUCCESS;
795 }
796 
797 EFI_STATUS
798 DisableRTD3 (
799   VOID)
800 {
801 	  //
802     //Disable RTD3
803     //
804     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x210, (UINT32)~(0x0f000007), (UINT32) (0x00));
805     MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x1e0, (UINT32)~(0x0f000007), (UINT32) (0x00));
806 
807     return EFI_SUCCESS;
808 }
809 
810 /**
811   Platform specific initializations in stage1.
PlatformEarlyInitEntry(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES ** PeiServices)812 
813   @param FfsHeader         Pointer to the PEIM FFS file header.
814   @param PeiServices       General purpose services available to every PEIM.
815 
816   @retval EFI_SUCCESS       Operation completed successfully.
817   @retval Otherwise         Platform initialization failed.
818 **/
819 EFI_STATUS
820 EFIAPI
821 PlatformEarlyInitEntry (
822 
823   IN       EFI_PEI_FILE_HANDLE  FileHandle,
824   IN CONST EFI_PEI_SERVICES    **PeiServices
825   )
826 {
827   EFI_STATUS                  Status;
828   SYSTEM_CONFIGURATION        SystemConfiguration;
829   EFI_PLATFORM_INFO_HOB       *PlatformInfo;
830   EFI_PEI_HOB_POINTERS        Hob;
831   EFI_PLATFORM_CPU_INFO       PlatformCpuInfo;
832   EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
833   EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *NewDescriptorBlock;
834   UINTN                           Index;
835   UINTN                           MaxIndex;
836   UINT64                          Base;
837   UINT64                          Size;
838   UINT64                          NewSize;
839 
840   //
841   // Make sure base and size of the SMRAM region is aligned
842   //
843   Hob.Raw = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
844   if (Hob.Raw != NULL) {
845     DescriptorBlock = GET_GUID_HOB_DATA (Hob.Raw);
846     DEBUG ((DEBUG_INFO, "SMM PEI SMRAM Memory Reserved HOB\n"));
847     for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
848       DEBUG((DEBUG_INFO, "  SMRAM Descriptor[%02x]: Start=%016lx  Size=%016lx  State=%02x\n",
849         Index,
850         DescriptorBlock->Descriptor[Index].PhysicalStart,
851         DescriptorBlock->Descriptor[Index].PhysicalSize,
852         DescriptorBlock->Descriptor[Index].RegionState
853         ));
854     }
855 
856     //
857     // Find the largest usable range of SMRAM between 1MB and 4GB
858     //
859     for (Index = 0, MaxIndex = 0, Size = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
860       //
861       // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
862       //
863       if ((DescriptorBlock->Descriptor[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
864         continue;
865       }
866       //
867       // Skip any SMRAM region below 1MB
868       //
869       if (DescriptorBlock->Descriptor[Index].CpuStart < BASE_1MB) {
870         continue;
871       }
872       //
873       // Skip any SMRAM region that is above 4GB or crosses the 4GB boundary
874       //
875       if ((DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock->Descriptor[Index].PhysicalSize) >= BASE_4GB) {
876         continue;
877       }
878       //
879       // Cache the largest SMRAM region index
880       //
881       if (DescriptorBlock->Descriptor[Index].PhysicalSize >= DescriptorBlock->Descriptor[MaxIndex].PhysicalSize) {
882         MaxIndex = Index;
883       }
884     }
885 
886     //
887     // Find the extent of the contiguous SMRAM region that surrounds the largest usable SMRAM range
888     //
889     Base = DescriptorBlock->Descriptor[MaxIndex].CpuStart;
890     Size = DescriptorBlock->Descriptor[MaxIndex].PhysicalSize;
891     for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
892       if (DescriptorBlock->Descriptor[Index].CpuStart < Base &&
893           Base == (DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock->Descriptor[Index].PhysicalSize)) {
894         Base  = DescriptorBlock->Descriptor[Index].CpuStart;
895         Size += DescriptorBlock->Descriptor[Index].PhysicalSize;
896       } else if ((Base + Size) == DescriptorBlock->Descriptor[Index].CpuStart) {
897         Size += DescriptorBlock->Descriptor[Index].PhysicalSize;
898       }
899     }
900 
901     //
902     // Round SMRAM region up to nearest power of 2 that is at least 4KB
903     //
904     NewSize = MAX (LShiftU64 (1, HighBitSet64 (Size - 1) + 1), SIZE_4KB);
905     if ((Base & ~(NewSize - 1)) != Base) {
906       //
907       // SMRAM region Base Address has smaller alignment than SMRAM region Size
908       // This is not compatible with SMRR settings
909       //
910       DEBUG((DEBUG_ERROR, "ERROR: SMRAM Region Size has larger alignment than SMRAM Region Base\n"));
911       DEBUG((DEBUG_ERROR, "  SMRAM Region Base=%016lx  Size=%016lx\n", Base, NewSize));
912       ASSERT (FALSE);
913     } else if (Size != NewSize) {
914       //
915       // See if the size difference can be added to an adjacent descriptor that is already allocated
916       //
917       for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
918         if ((DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock->Descriptor[Index].PhysicalSize) == (Base + Size)) {
919           if (((DescriptorBlock->Descriptor[Index].RegionState) & EFI_ALLOCATED) != 0) {
920             DescriptorBlock->Descriptor[Index].PhysicalSize += (NewSize - Size);
921             Size = NewSize;
922             break;
923           }
924         }
925       }
926 
927       if (Size != NewSize) {
928         //
929         // Add an allocated descriptor to the SMM PEI SMRAM Memory Reserved HOB to accomodate the larger size.
930         //
931         Index = DescriptorBlock->NumberOfSmmReservedRegions;
932         NewDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)BuildGuidHob (
933           &gEfiSmmPeiSmramMemoryReserveGuid,
934           sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + ((Index + 1) * sizeof (EFI_SMRAM_DESCRIPTOR))
935           );
936         ASSERT (NewDescriptorBlock != NULL);
937 
938         //
939         // Copy old EFI_SMRAM_HOB_DESCRIPTOR_BLOCK to new allocated region
940         //
941         CopyMem (
942           NewDescriptorBlock,
943           DescriptorBlock,
944           sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + (Index * sizeof (EFI_SMRAM_DESCRIPTOR))
945           );
946 
947         //
948         // Make sure last descriptor in NewDescriptorBlock contains last descriptor from DescriptorBlock
949         //
950         CopyMem (
951           &NewDescriptorBlock->Descriptor[Index],
952           &NewDescriptorBlock->Descriptor[Index - 1],
953           sizeof (EFI_SMRAM_DESCRIPTOR)
954           );
955 
956         //
957         // Fill next to last descriptor with an allocated descriptor that aligns the total size of SMRAM
958         //
959         NewDescriptorBlock->Descriptor[Index - 1].CpuStart      = Base + Size;
960         NewDescriptorBlock->Descriptor[Index - 1].PhysicalStart = Base + Size;
961         NewDescriptorBlock->Descriptor[Index - 1].PhysicalSize  = NewSize - Size;
962         NewDescriptorBlock->Descriptor[Index - 1].RegionState   = DescriptorBlock->Descriptor[MaxIndex].RegionState | EFI_ALLOCATED;
963         NewDescriptorBlock->NumberOfSmmReservedRegions++;
964 
965         //
966         // Invalidate the original gEfiSmmPeiSmramMemoryReserveGuid HOB
967         //
968         ZeroMem (&Hob.Guid->Name, sizeof (&Hob.Guid->Name));
969       }
970 
971       Hob.Raw = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
972       DescriptorBlock = GET_GUID_HOB_DATA (Hob.Raw);
973       DEBUG ((DEBUG_INFO, "SMM PEI SMRAM Memory Reserved HOB - Updated\n"));
974       for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
975         DEBUG((DEBUG_INFO, "  SMRAM Descriptor[%02x]: Start=%016lx  Size=%016lx  State=%02x\n",
976           Index,
977           DescriptorBlock->Descriptor[Index].PhysicalStart,
978           DescriptorBlock->Descriptor[Index].PhysicalSize,
979           DescriptorBlock->Descriptor[Index].RegionState
980           ));
981       }
982     }
983   }
984 
985   //
986   // Initialize SmbusPolicy PPI
987   //
988   Status = (*PeiServices)->InstallPpi(PeiServices, &mInstallSmbusPolicyPpi);
989   ASSERT_EFI_ERROR (Status);
990 
991   //
992   // Initialize Stall PPIs
993   //
994   Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi);
995   ASSERT_EFI_ERROR (Status);
996 
997   //
998   // Initialize platform PPIs
999   //
1000   Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallSpeakerInterfacePpi);
1001   ASSERT_EFI_ERROR (Status);
1002 
1003   //
1004   // Variable initialization
1005   //
1006   ZeroMem(&PlatformCpuInfo, sizeof(EFI_PLATFORM_CPU_INFO));
1007 
1008   //
1009   // Set the some PCI and chipset range as UC
1010   // And align to 1M at leaset
1011   //
1012   Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
1013   ASSERT (Hob.Raw != NULL);
1014   PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
1015 
1016   //
1017   // Initialize PlatformInfo HOB
1018   //
1019   MultiPlatformInfoInit(PeiServices, PlatformInfo);
1020 
1021   //
1022   // Do basic MCH init
1023   //
1024   MchInit (PeiServices);
1025 
1026   //
1027   // Set the new boot mode
1028   //
1029   Status = UpdateBootMode (PeiServices, PlatformInfo);
1030   ASSERT_EFI_ERROR (Status);
1031 
1032   SetPlatformBootMode (PeiServices, PlatformInfo);
1033 
1034   //
1035   // Get setup variable. This can only be done after BootMode is updated
1036   //
1037   GetSetupVariable (PeiServices, &SystemConfiguration);
1038 
1039   CheckOsSelection(PeiServices, &SystemConfiguration);
1040 
1041   //
1042   // Update PlatformInfo HOB according to setup variable
1043   //
1044   PlatformInfoUpdate(PeiServices, PlatformInfo, &SystemConfiguration);
1045 
1046   InitializePlatform (PeiServices, PlatformInfo, &SystemConfiguration);
1047 
1048   //
1049   // Initialize VlvPolicy PPI
1050   //
1051   Status = VlvPolicyInit (PeiServices, &SystemConfiguration);
1052   ASSERT_EFI_ERROR (Status);
1053 
1054   //
1055   // Soc specific GPIO setting
1056   //
1057   ConfigureSoCGpio(&SystemConfiguration);
1058 
1059   //
1060   //  Baylake Board specific.
1061   //
1062   if (PlatformInfo->BoardId == BOARD_ID_BL_RVP  ||
1063       PlatformInfo->BoardId == BOARD_ID_BL_FFRD ||
1064 	    PlatformInfo->BoardId == BOARD_ID_BL_FFRD8 ||
1065       PlatformInfo->BoardId == BOARD_ID_BL_RVP_DDR3L ||
1066       PlatformInfo->BoardId == BOARD_ID_BL_STHI ||
1067       PlatformInfo->BoardId == BOARD_ID_BB_RVP ||
1068       PlatformInfo->BoardId == BOARD_ID_BS_RVP ||
1069       PlatformInfo->BoardId == BOARD_ID_MINNOW2 ||
1070       PlatformInfo->BoardId == BOARD_ID_MINNOW2_TURBOT||
1071       PlatformInfo->BoardId == BOARD_ID_CVH) {
1072     ConfigureLpssAndSccGpio(&SystemConfiguration, PlatformInfo);
1073 
1074   }
1075 
1076 
1077   //
1078   //  Configure LPE
1079   //  Alpine Valley and Bayley Bay board specific
1080   //
1081   ConfigureLpeGpio(&SystemConfiguration);
1082 
1083   //
1084   //  Bayley Bay Board specific.
1085   //
1086   ConfigureSciSmiGpioRout(PlatformInfo);
1087   if (SystemConfiguration.LpssI2C3Enabled == 1) {
1088     ConfigureMipiCsi();
1089   }
1090 
1091 
1092   //
1093   // Do basic CPU init
1094   //
1095   Status = PlatformCpuInit (PeiServices, &SystemConfiguration, &PlatformCpuInfo);
1096 
1097   //
1098   // Perform basic SSA related platform initialization
1099   //
1100   PlatformSsaInit (&SystemConfiguration,PeiServices);
1101 
1102 
1103   //
1104   // Do basic PCH init
1105   //
1106   Status = PlatformPchInit (&SystemConfiguration, PeiServices, PlatformInfo->PlatformType);
1107   ASSERT_EFI_ERROR (Status);
1108 
1109   //
1110   // Initialize platform PPIs
1111   //
1112   Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiList[0]);
1113   ASSERT_EFI_ERROR (Status);
1114 
1115   if (PlatformInfo->BoardId != BOARD_ID_CVH) {
1116     InstallPlatformClocksNotify (PeiServices);
1117     InstallPlatformSysCtrlGPIONotify(PeiServices);
1118   }
1119 
1120   //
1121   // Initialize platform PPIs
1122   //
1123   Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
1124   ASSERT_EFI_ERROR (Status);
1125 
1126   //
1127   // Initialize Measured Boot
1128   //
1129   Status = MeasuredBootInit (PeiServices, &SystemConfiguration);
1130   ASSERT_EFI_ERROR (Status);
1131 
1132   return Status;
1133 }
1134 
1135 /**
1136 
1137   Return the mainblockcompact Fv.
1138 
1139   @param FvNumber    Our enumeration of the firmware volumes we care about.
FindFv(IN EFI_PEI_FIND_FV_PPI * This,IN CONST EFI_PEI_SERVICES ** PeiServices,IN OUT UINT8 * FvNumber,OUT EFI_FIRMWARE_VOLUME_HEADER ** FVAddress)1140 
1141   @param FvAddress  Base Address of the memory containing the firmware volume
1142 
1143   @retval EFI_SUCCESS
1144   @retval EFI_NOT_FOUND
1145 
1146 **/
1147 EFI_STATUS
1148 EFIAPI
1149 FindFv (
1150   IN EFI_PEI_FIND_FV_PPI          *This,
1151   IN CONST EFI_PEI_SERVICES             **PeiServices,
1152   IN OUT UINT8                    *FvNumber,
1153   OUT EFI_FIRMWARE_VOLUME_HEADER  **FVAddress
1154   )
1155 {
1156 	//
1157   // At present, we only have one Fv to search
1158   //
1159   if (*FvNumber == 0) {
1160     *FvNumber = 1;
1161     *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FixedPcdGet32 (PcdFlashFvMainBase);
1162     return EFI_SUCCESS;
1163   }
1164   else if (*FvNumber == 1) {
1165     *FvNumber = 2;
1166     *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FixedPcdGet32 (PcdFlashFvRecovery2Base);
1167     return EFI_SUCCESS;
1168   }
1169   else { // Not the one Fv we care about
1170     return EFI_NOT_FOUND;
1171   }
1172 }
1173 
1174 EFI_STATUS
1175 EFIAPI
1176 CpuOnlyReset (
1177   IN CONST EFI_PEI_SERVICES   **PeiServices
1178   )
1179 {
1180 //  MsgBus32Write(CDV_UNIT_PUNIT, PUNIT_CPU_RST, 0x01)
1181 #ifdef __GNUC__
1182   __asm__
1183   (
1184    "xorl %ecx, %ecx\n"
1185    "1:hlt; hlt; hlt\n"
1186    "jmp 1b\n"
1187   );
1188 #else
1189   _asm {
1190     xor   ecx, ecx
1191   HltLoop:
1192     hlt
1193     hlt
1194     hlt
1195     loop  HltLoop
1196   }
1197 #endif
1198   //
1199   // If we get here we need to mark it as a failure.
1200   //
1201   return EFI_UNSUPPORTED;
1202 }
1203 
1204 
1205 #ifdef __GNUC__
1206 #pragma GCC pop_options
1207 #else
1208 #pragma optimize ("", on)
1209 #endif
1210