Home | History | Annotate | Download | only in PlatformInit
      1 /** @file
      2 This PEIM initialize platform for MRC, following action is performed,
      3 1. Initizluize GMCH
      4 2. Detect boot mode
      5 3. Detect video adapter to determine whether we need pre allocated memory
      6 4. Calls MRC to initialize memory and install a PPI notify to do post memory initialization.
      7 This file contains the main entrypoint of the PEIM.
      8 
      9 Copyright (c) 2013 - 2016 Intel Corporation.
     10 
     11 This program and the accompanying materials
     12 are licensed and made available under the terms and conditions of the BSD License
     13 which accompanies this distribution.  The full text of the license may be found at
     14 http://opensource.org/licenses/bsd-license.php
     15 
     16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     18 
     19 **/
     20 
     21 
     22 #include "CommonHeader.h"
     23 #include "PlatformEarlyInit.h"
     24 #include "PeiFvSecurity.h"
     25 
     26 EFI_STATUS
     27 EFIAPI
     28 EndOfPeiSignalPpiNotifyCallback (
     29   IN EFI_PEI_SERVICES           **PeiServices,
     30   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
     31   IN VOID                       *Ppi
     32   );
     33 
     34 //
     35 // Function prototypes to routines implemented in other source modules
     36 // within this component.
     37 //
     38 
     39 EFI_STATUS
     40 EFIAPI
     41 PlatformErratasPostMrc (
     42   VOID
     43   );
     44 
     45 //
     46 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
     47 //
     48 BOOLEAN ImageInMemory = FALSE;
     49 
     50 BOARD_LEGACY_GPIO_CONFIG      mBoardLegacyGpioConfigTable[]  = { PLATFORM_LEGACY_GPIO_TABLE_DEFINITION };
     51 UINTN                         mBoardLegacyGpioConfigTableLen = (sizeof(mBoardLegacyGpioConfigTable) / sizeof(BOARD_LEGACY_GPIO_CONFIG));
     52 BOARD_GPIO_CONTROLLER_CONFIG  mBoardGpioControllerConfigTable[]  = { PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION };
     53 UINTN                         mBoardGpioControllerConfigTableLen = (sizeof(mBoardGpioControllerConfigTable) / sizeof(BOARD_GPIO_CONTROLLER_CONFIG));
     54 UINT8                         ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
     55 
     56 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[1] = {
     57   {
     58     (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     59     &gEfiPeiMasterBootModePpiGuid,
     60     NULL
     61   }
     62 };
     63 
     64 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
     65   {
     66     (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     67     &gEfiPeiMemoryDiscoveredPpiGuid,
     68     MemoryDiscoveredPpiNotifyCallback
     69   }
     70 };
     71 
     72 EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[1] = {
     73   {
     74     (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     75     &gEfiEndOfPeiSignalPpiGuid,
     76     EndOfPeiSignalPpiNotifyCallback
     77   }
     78 };
     79 
     80 EFI_PEI_STALL_PPI mStallPpi = {
     81   PEI_STALL_RESOLUTION,
     82   Stall
     83 };
     84 
     85 EFI_PEI_PPI_DESCRIPTOR mPpiStall[1] = {
     86   {
     87     (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     88     &gEfiPeiStallPpiGuid,
     89     &mStallPpi
     90   }
     91 };
     92 
     93 /**
     94   Set Mac address on chipset ethernet device.
     95 
     96   @param  Bus      PCI Bus number of chipset ethernet device.
     97   @param  Device   Device number of chipset ethernet device.
     98   @param  Func     PCI Function number of chipset ethernet device.
     99   @param  MacAddr  MAC Address to set.
    100 
    101 **/
    102 VOID
    103 EFIAPI
    104 SetLanControllerMacAddr (
    105   IN CONST UINT8                          Bus,
    106   IN CONST UINT8                          Device,
    107   IN CONST UINT8                          Func,
    108   IN CONST UINT8                          *MacAddr,
    109   IN CONST UINT32                         Bar0
    110   )
    111 {
    112   UINT32                            Data32;
    113   UINT16                            PciVid;
    114   UINT16                            PciDid;
    115   UINT32                            Addr;
    116   UINT32                            MacVer;
    117   volatile UINT8                    *Wrote;
    118   UINT32                            DevPcieAddr;
    119   UINT16                            SaveCmdReg;
    120   UINT32                            SaveBarReg;
    121 
    122   DevPcieAddr = PCI_LIB_ADDRESS (
    123                   Bus,
    124                   Device,
    125                   Func,
    126                   0
    127                   );
    128 
    129   //
    130   // Do nothing if not a supported device.
    131   //
    132   PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
    133   PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
    134   if((PciVid != V_IOH_MAC_VENDOR_ID) || (PciDid != V_IOH_MAC_DEVICE_ID)) {
    135     return;
    136   }
    137 
    138   //
    139   // Save current settings for PCI CMD/BAR registers
    140   //
    141   SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
    142   SaveBarReg = PciRead32 (DevPcieAddr + R_IOH_MAC_MEMBAR);
    143 
    144   //
    145   // Use predefined tempory memory resource
    146   //
    147   PciWrite32 ( DevPcieAddr + R_IOH_MAC_MEMBAR, Bar0);
    148   PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
    149 
    150   Addr =  Bar0 + R_IOH_MAC_GMAC_REG_8;
    151   MacVer = *((volatile UINT32 *) (UINTN)(Addr));
    152 
    153   DEBUG ((EFI_D_INFO, "Ioh MAC [B:%d, D:%d, F:%d] VER:%04x ADDR:",
    154     (UINTN) Bus,
    155     (UINTN) Device,
    156     (UINTN) Func,
    157     (UINTN) MacVer
    158     ));
    159 
    160   //
    161   // Set MAC Address0 Low Register (GMAC_REG_17) ADDRLO bits.
    162   //
    163   Addr =  Bar0 + R_IOH_MAC_GMAC_REG_17;
    164   Data32 = *((UINT32 *) (UINTN)(&MacAddr[0]));
    165   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
    166   Wrote = (volatile UINT8 *) (UINTN)(Addr);
    167   DEBUG ((EFI_D_INFO, "%02x-%02x-%02x-%02x-",
    168     (UINTN) Wrote[0],
    169     (UINTN) Wrote[1],
    170     (UINTN) Wrote[2],
    171     (UINTN) Wrote[3]
    172     ));
    173 
    174   //
    175   // Set MAC Address0 High Register (GMAC_REG_16) ADDRHI bits
    176   // and Address Enable (AE) bit.
    177   //
    178   Addr =  Bar0 + R_IOH_MAC_GMAC_REG_16;
    179   Data32 =
    180     ((UINT32) MacAddr[4]) |
    181     (((UINT32)MacAddr[5]) << 8) |
    182     B_IOH_MAC_AE;
    183   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
    184   Wrote = (volatile UINT8 *) (UINTN)(Addr);
    185 
    186   DEBUG ((EFI_D_INFO, "%02x-%02x\n", (UINTN) Wrote[0], (UINTN) Wrote[1]));
    187 
    188   //
    189   // Restore settings for PCI CMD/BAR registers
    190   //
    191   PciWrite32 ((DevPcieAddr + R_IOH_MAC_MEMBAR), SaveBarReg);
    192   PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
    193 }
    194 
    195 /**
    196   Initialize state of I2C GPIO expanders.
    197 
    198   @param  PlatformType  Platform type for GPIO expander init.
    199 
    200 **/
    201 EFI_STATUS
    202 EarlyPlatformConfigGpioExpanders (
    203   IN CONST EFI_PLATFORM_TYPE              PlatformType
    204   )
    205 {
    206   EFI_STATUS              Status;
    207   EFI_I2C_DEVICE_ADDRESS  I2CSlaveAddress;
    208   UINTN                   Length;
    209   UINTN                   ReadLength;
    210   UINT8                   Buffer[2];
    211 
    212   //
    213   // Configure GPIO expanders for Galileo Gen 2
    214   // Route I2C pins to Arduino header
    215   // Set all GPIO expander pins connected to the Reset Button as inputs
    216   //
    217   if (PlatformType == GalileoGen2) {
    218     //
    219     // Configure AMUX1_IN (EXP2.P1_4) as an output
    220     //
    221     PlatformPcal9555GpioSetDir (
    222       GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
    223       12,                                   // P1-4.
    224       FALSE                                 // Configure as output
    225       );
    226 
    227     //
    228     // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector
    229     //
    230     PlatformPcal9555GpioSetLevel (
    231       GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
    232       12,                                   // P1-4.
    233       FALSE                                 // Set pin low
    234       );
    235 
    236     //
    237     // Configure Reset Button(EXP1.P1_7) as an input
    238     //
    239     PlatformPcal9555GpioSetDir (
    240       GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
    241       15,                                   // P1-7.
    242       TRUE
    243       );
    244 
    245     //
    246     // Disable pullup on Reset Button(EXP1.P1_7)
    247     //
    248     PlatformPcal9555GpioDisablePull (
    249       GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
    250       15                                    // P1-7.
    251       );
    252 
    253     //
    254     // Configure Reset Button(EXP2.P1_7) as an input
    255     //
    256     PlatformPcal9555GpioSetDir (
    257       GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
    258       15,                                   // P1-7.
    259       TRUE
    260       );
    261 
    262     //
    263     // Disable pullup on Reset Button(EXP2.P1_7)
    264     //
    265     PlatformPcal9555GpioDisablePull (
    266       GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
    267       15                                    // P1-7.
    268       );
    269   }
    270 
    271   //
    272   // Configure GPIO expanders for Galileo Gen 2
    273   // Set all GPIO expander pins connected to the Reset Button as inputs
    274   // Route I2C pins to Arduino header
    275   //
    276   if (PlatformType == Galileo) {
    277     //
    278     // Detect the I2C Slave Address of the GPIO Expander
    279     //
    280     if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
    281       I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
    282     } else {
    283       I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
    284     }
    285     DEBUG ((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress));
    286 
    287     //
    288     // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector
    289     //
    290 
    291     //
    292     // Select GPIO Expander GPORT1
    293     //
    294     Length = 2;
    295     Buffer[0] = 0x18; //sub-address
    296     Buffer[1] = 0x01; //data
    297     Status = I2cWriteMultipleByte (
    298       I2CSlaveAddress,
    299       EfiI2CSevenBitAddrMode,
    300       &Length,
    301       &Buffer
    302       );
    303     ASSERT_EFI_ERROR (Status);
    304 
    305     //
    306     // Read "Pin Direction" of GPIO Expander GPORT1
    307     //
    308     Length = 1;
    309     ReadLength = 1;
    310     Buffer[1] = 0x1C;
    311     Status = I2cReadMultipleByte (
    312       I2CSlaveAddress,
    313       EfiI2CSevenBitAddrMode,
    314       &Length,
    315       &ReadLength,
    316       &Buffer[1]
    317       );
    318     ASSERT_EFI_ERROR (Status);
    319 
    320     //
    321     // Configure GPIO Expander GPORT1_BIT5 as an output
    322     //
    323     Length = 2;
    324     Buffer[0] = 0x1C; //sub-address
    325     Buffer[1] = (UINT8)(Buffer[1] & (~BIT5)); //data
    326 
    327     Status = I2cWriteMultipleByte (
    328       I2CSlaveAddress,
    329       EfiI2CSevenBitAddrMode,
    330       &Length,
    331       &Buffer
    332       );
    333     ASSERT_EFI_ERROR (Status);
    334 
    335     //
    336     // Set GPIO Expander GPORT1_BIT5 low
    337     //
    338     Length = 2;
    339     Buffer[0] = 0x09; //sub-address
    340     Buffer[1] = (UINT8)(~BIT5); //data
    341 
    342     Status = I2cWriteMultipleByte (
    343       I2CSlaveAddress,
    344       EfiI2CSevenBitAddrMode,
    345       &Length,
    346       &Buffer
    347       );
    348     ASSERT_EFI_ERROR (Status);
    349 
    350     //
    351     // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs
    352     //
    353 
    354     //
    355     // Select GPIO Expander GPORT5
    356     //
    357     Length = 2;
    358     Buffer[0] = 0x18;
    359     Buffer[1] = 0x05;
    360     Status = I2cWriteMultipleByte (
    361       I2CSlaveAddress,
    362       EfiI2CSevenBitAddrMode,
    363       &Length,
    364       &Buffer
    365       );
    366     ASSERT_EFI_ERROR (Status);
    367 
    368     //
    369     // Read "Pin Direction" of GPIO Expander GPORT5
    370     //
    371     Length = 1;
    372     ReadLength = 1;
    373     Buffer[1] = 0x1C;
    374     Status = I2cReadMultipleByte (
    375       I2CSlaveAddress,
    376       EfiI2CSevenBitAddrMode,
    377       &Length,
    378       &ReadLength,
    379       &Buffer[1]
    380       );
    381     ASSERT_EFI_ERROR (Status);
    382 
    383     //
    384     // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs
    385     //
    386     Length = 2;
    387     Buffer[0] = 0x1C;
    388     Buffer[1] = Buffer[1] | BIT0 | BIT1;
    389     Status = I2cWriteMultipleByte (
    390       I2CSlaveAddress,
    391       EfiI2CSevenBitAddrMode,
    392       &Length,
    393       &Buffer
    394       );
    395     ASSERT_EFI_ERROR (Status);
    396   }
    397 
    398   return EFI_SUCCESS;
    399 }
    400 
    401 /**
    402   This is the entrypoint of PEIM
    403 
    404   @param  FileHandle  Handle of the file being invoked.
    405   @param  PeiServices Describes the list of possible PEI Services.
    406 
    407   @retval EFI_SUCCESS if it completed successfully.
    408 **/
    409 EFI_STATUS
    410 EFIAPI
    411 PeiInitPlatform (
    412   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    413   IN CONST EFI_PEI_SERVICES     **PeiServices
    414   )
    415 {
    416   EFI_STATUS                              Status;
    417   EFI_BOOT_MODE                           BootMode;
    418   EFI_PEI_STALL_PPI                       *StallPpi;
    419   EFI_PEI_PPI_DESCRIPTOR                  *StallPeiPpiDescriptor;
    420   EFI_FV_FILE_INFO                        FileInfo;
    421   EFI_PLATFORM_TYPE                       PlatformType;
    422 
    423   PlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
    424 
    425   //
    426   // Initialize Firmware Volume security.
    427   // This must be done before any firmware volume accesses (excl. BFV)
    428   //
    429   Status = PeiInitializeFvSecurity();
    430   ASSERT_EFI_ERROR (Status);
    431 
    432   //
    433   // Do any early platform specific initialization.
    434   //
    435   EarlyPlatformInit ();
    436 
    437   //
    438   // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based
    439   // to improve recovery performance.
    440   //
    441   Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
    442   ASSERT_EFI_ERROR (Status);
    443   //
    444   // The follow conditional check only works for memory-mapped FFS,
    445   // so we ASSERT that the file is really a MM FFS.
    446   //
    447   ASSERT (FileInfo.Buffer != NULL);
    448   if (!(((UINTN) FileInfo.Buffer <= (UINTN) PeiInitPlatform) &&
    449         ((UINTN) PeiInitPlatform <= (UINTN) FileInfo.Buffer + FileInfo.BufferSize))) {
    450     //
    451     // Now that module in memory, update the
    452     // PPI that describes the Stall to other modules
    453     //
    454     Status = PeiServicesLocatePpi (
    455                &gEfiPeiStallPpiGuid,
    456                0,
    457                &StallPeiPpiDescriptor,
    458                (VOID **) &StallPpi
    459                );
    460 
    461     if (!EFI_ERROR (Status)) {
    462 
    463       Status = PeiServicesReInstallPpi (
    464                  StallPeiPpiDescriptor,
    465                  &mPpiStall[0]
    466                  );
    467     } else {
    468 
    469       Status = PeiServicesInstallPpi (&mPpiStall[0]);
    470     }
    471     return Status;
    472   }
    473 
    474   //
    475   // Initialize System Phys
    476   //
    477 
    478   // Program USB Phy
    479   InitializeUSBPhy();
    480 
    481   //
    482   // Do platform specific logic to create a boot mode
    483   //
    484   Status = UpdateBootMode ((EFI_PEI_SERVICES**)PeiServices, &BootMode);
    485   ASSERT_EFI_ERROR (Status);
    486 
    487   //
    488   // Signal possible dependent modules that there has been a
    489   // final boot mode determination
    490   //
    491   if (!EFI_ERROR(Status)) {
    492     Status = PeiServicesInstallPpi (&mPpiBootMode[0]);
    493     ASSERT_EFI_ERROR (Status);
    494   }
    495 
    496   if (BootMode != BOOT_ON_S3_RESUME) {
    497     QNCClearSmiAndWake ();
    498   }
    499 
    500   DEBUG ((EFI_D_INFO, "MRC Entry\n"));
    501   MemoryInit ((EFI_PEI_SERVICES**)PeiServices);
    502 
    503   //
    504   // Do Early PCIe init.
    505   //
    506   DEBUG ((EFI_D_INFO, "Early PCIe controller initialization\n"));
    507   PlatformPciExpressEarlyInit (PlatformType);
    508 
    509 
    510   DEBUG ((EFI_D_INFO, "Platform Erratas After MRC\n"));
    511   PlatformErratasPostMrc ();
    512 
    513   //
    514   //
    515   //
    516   DEBUG ((EFI_D_INFO, "EarlyPlatformConfigGpioExpanders ()\n"));
    517   EarlyPlatformConfigGpioExpanders (PlatformType);
    518 
    519   //
    520   // Now that all of the pre-permanent memory activities have
    521   // been taken care of, post a call-back for the permanent-memory
    522   // resident services, such as HOB construction.
    523   // PEI Core will switch stack after this PEIM exit.  After that the MTRR
    524   // can be set.
    525   //
    526   Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);
    527   ASSERT_EFI_ERROR (Status);
    528 /*
    529 
    530   if (BootMode != BOOT_ON_S3_RESUME) {
    531     Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList);
    532     ASSERT_EFI_ERROR (Status);
    533   }
    534 */
    535   if (BootMode == BOOT_IN_RECOVERY_MODE) {
    536     PeiServicesRegisterForShadow (FileHandle);
    537   }
    538 
    539   return Status;
    540 }
    541 
    542 EFI_STATUS
    543 EFIAPI
    544 EndOfPeiSignalPpiNotifyCallback (
    545   IN EFI_PEI_SERVICES           **PeiServices,
    546   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
    547   IN VOID                       *Ppi
    548   )
    549 {
    550   EFI_STATUS                            Status;
    551 
    552   DEBUG ((EFI_D_INFO, "End of PEI Signal Callback\n"));
    553 
    554     //
    555   // Restore the flash region to be UC
    556   // for both normal boot as we build a Resource Hob to
    557   // describe this region as UC to DXE core.
    558   //
    559   WriteBackInvalidateDataCacheRange (
    560     (VOID *) (UINTN) PcdGet32 (PcdFlashAreaBaseAddress),
    561     PcdGet32 (PcdFlashAreaSize)
    562   );
    563 
    564   Status = MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress), PcdGet32 (PcdFlashAreaSize), CacheUncacheable);
    565   ASSERT_EFI_ERROR (Status);
    566 
    567   return EFI_SUCCESS;
    568 }
    569 
    570 /**
    571   This function will initialize USB Phy registers associated with QuarkSouthCluster.
    572 
    573   @param  VOID                  No Argument
    574 
    575   @retval EFI_SUCCESS           All registers have been initialized
    576 **/
    577 VOID
    578 EFIAPI
    579 InitializeUSBPhy (
    580     VOID
    581    )
    582 {
    583     UINT32 RegData32;
    584 
    585     /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock
    586      *  and Port2 as a USB device port, the following sequence must be followed
    587      *
    588      **/
    589 
    590     // Sideband register write to USB AFE (Phy)
    591     RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT);
    592     RegData32 &= ~(BIT1);
    593     //
    594     // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.
    595     // For port 0 & 1 as host and port 2 as device.
    596     //
    597     RegData32 |= (BIT8 | BIT7);
    598     QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT, RegData32);
    599 
    600     //
    601     // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV.
    602     //
    603     RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG);
    604     RegData32 &= ~(BIT10 | BIT9 | BIT8 | BIT7);
    605     RegData32 |= (BIT10 | BIT7);
    606     QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG, RegData32);
    607 
    608     // Sideband register write to USB AFE (Phy)
    609     // (pllbypass) to bypass/Disable PLL before switch
    610     RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
    611     RegData32 |= BIT29;
    612     QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
    613 
    614     // Sideband register write to USB AFE (Phy)
    615     // (coreclksel) to select 120MHz (ickusbcoreclk) clk source.
    616     // (Default 0 to select 96MHz (ickusbclk96_npad/ppad))
    617     RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);
    618     RegData32 |= BIT1;
    619     QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);
    620 
    621     // Sideband register write to USB AFE (Phy)
    622     // (divide by 8) to achieve internal 480MHz clock
    623     // for 120MHz input refclk.  (Default: 4'b1000 (divide by 10) for 96MHz)
    624     RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);
    625     RegData32 &= ~(BIT5 | BIT4 | BIT3);
    626     RegData32 |= BIT6;
    627     QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);
    628 
    629     // Sideband register write to USB AFE (Phy)
    630     // Clear (pllbypass)
    631     RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
    632     RegData32 &= ~BIT29;
    633     QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
    634 
    635     // Sideband register write to USB AFE (Phy)
    636     // Set (startlock) to force the PLL FSM to restart the lock
    637     // sequence due to input clock/freq switch.
    638     RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
    639     RegData32 |= BIT24;
    640     QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
    641 
    642     // At this point the PLL FSM and COMP FSM will complete
    643 
    644 }
    645 
    646 /**
    647   This function provides early platform Thermal sensor initialisation.
    648 **/
    649 VOID
    650 EFIAPI
    651 EarlyPlatformThermalSensorInit (
    652   VOID
    653   )
    654 {
    655   DEBUG ((EFI_D_INFO, "Early Platform Thermal Sensor Init\n"));
    656 
    657   //
    658   // Set Thermal sensor mode.
    659   //
    660   QNCThermalSensorSetRatiometricMode ();
    661 
    662   //
    663   // Enable RMU Thermal sensor with a Catastrophic Trip point.
    664   //
    665   QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS);
    666 
    667   //
    668   // Lock all RMU Thermal sensor control & trip point registers.
    669   //
    670   QNCThermalSensorLockAllRegisters ();
    671 }
    672 
    673 /**
    674   Print early platform info messages includeing the Stage1 module that's
    675   running, MFH item list and platform data item list.
    676 **/
    677 VOID
    678 EFIAPI
    679 EarlyPlatformInfoMessages (
    680   VOID
    681   )
    682 {
    683   DEBUG_CODE_BEGIN ();
    684   QUARK_EDKII_STAGE1_HEADER       *Edk2ImageHeader;
    685 
    686   //
    687   // Find which 'Stage1' image we are running and print the details
    688   //
    689   Edk2ImageHeader = (QUARK_EDKII_STAGE1_HEADER *) PcdGet32 (PcdEsramStage1Base);
    690   DEBUG ((EFI_D_INFO, "\n************************************************************\n"));
    691 
    692   switch ((UINT8)Edk2ImageHeader->ImageIndex & QUARK_STAGE1_IMAGE_TYPE_MASK) {
    693     case QUARK_STAGE1_BOOT_IMAGE_TYPE:
    694       DEBUG ((EFI_D_INFO, "****  Quark EDKII Stage 1 Boot Image %d                ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));
    695       break;
    696 
    697     case QUARK_STAGE1_RECOVERY_IMAGE_TYPE:
    698       DEBUG ((EFI_D_INFO, "****  Quark EDKII Stage 1 Recovery Image %d            ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));
    699       break;
    700 
    701     default:
    702       DEBUG ((EFI_D_INFO, "****  Quark EDKII Unknown Stage 1 Image !!!!           ****\n"));
    703       break;
    704   }
    705   DEBUG (
    706     (EFI_D_INFO,
    707     "****  Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" ,
    708     (UINTN) PcdGet32 (PcdFlashFvMainBase),
    709     (UINTN) PcdGet32 (PcdFlashFvMainSize)
    710     ));
    711 
    712   DEBUG (
    713     (EFI_D_INFO,
    714     "****  Quark EDKII Payload Image 0x%08X:0x%08X ****\n" ,
    715     (UINTN) PcdGet32 (PcdFlashFvPayloadBase),
    716     (UINTN) PcdGet32 (PcdFlashFvPayloadSize)
    717     ));
    718 
    719   DEBUG ((EFI_D_INFO, "************************************************************\n\n"));
    720 
    721   DEBUG_CODE_END ();
    722 }
    723 
    724 /**
    725   Check if system reset due to error condition.
    726 
    727   @param  ClearErrorBits  If TRUE clear error flags and value bits.
    728 
    729   @retval TRUE  if system reset due to error condition.
    730   @retval FALSE if NO reset error conditions.
    731 **/
    732 BOOLEAN
    733 CheckForResetDueToErrors (
    734   IN BOOLEAN                              ClearErrorBits
    735   )
    736 {
    737   UINT32                            RegValue;
    738   BOOLEAN                           ResetDueToError;
    739 
    740   ResetDueToError = FALSE;
    741 
    742   //
    743   // Check if RMU reset system due to access violations.
    744   // RMU updates a SOC Unit register before reseting the system.
    745   //
    746   RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);
    747   if ((RegValue & B_CFG_STICKY_RW_VIOLATION) != 0) {
    748     ResetDueToError = TRUE;
    749 
    750     DEBUG (
    751       (EFI_D_ERROR,
    752       "\nReset due to access violation: %s %s %s %s\n",
    753       ((RegValue & B_CFG_STICKY_RW_IMR_VIOLATION) != 0) ? L"'IMR'" : L".",
    754       ((RegValue & B_CFG_STICKY_RW_DECC_VIOLATION) != 0) ? L"'DECC'" : L".",
    755       ((RegValue & B_CFG_STICKY_RW_SMM_VIOLATION) != 0) ? L"'SMM'" : L".",
    756       ((RegValue & B_CFG_STICKY_RW_HMB_VIOLATION) != 0) ? L"'HMB'" : L"."
    757       ));
    758 
    759     //
    760     // Clear error bits.
    761     //
    762     if (ClearErrorBits) {
    763       RegValue &= ~(B_CFG_STICKY_RW_VIOLATION);
    764       QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, RegValue);
    765     }
    766   }
    767 
    768   return ResetDueToError;
    769 }
    770 
    771 /**
    772   This function provides early platform initialization.
    773 
    774   @param  PlatformInfo  Pointer to platform Info structure.
    775 
    776 **/
    777 VOID
    778 EFIAPI
    779 EarlyPlatformInit (
    780   VOID
    781   )
    782 {
    783   EFI_PLATFORM_TYPE                 PlatformType;
    784 
    785   PlatformType = (EFI_PLATFORM_TYPE) PcdGet16 (PcdPlatformType);
    786 
    787   DEBUG ((EFI_D_INFO, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN) PlatformType));
    788 
    789   //
    790   // Check if system reset due to error condition.
    791   //
    792   if (CheckForResetDueToErrors (TRUE)) {
    793     if(FeaturePcdGet (WaitIfResetDueToError)) {
    794       DEBUG ((EFI_D_ERROR, "Press any key to continue.\n"));
    795       PlatformDebugPortGetChar8 ();
    796     }
    797   }
    798 
    799   //
    800   // Display platform info messages.
    801   //
    802   EarlyPlatformInfoMessages ();
    803 
    804   //
    805   // Early Legacy Gpio Init.
    806   //
    807   EarlyPlatformLegacyGpioInit (PlatformType);
    808 
    809   //
    810   // Early platform Legacy GPIO manipulation depending on GPIOs
    811   // setup by EarlyPlatformLegacyGpioInit.
    812   //
    813   EarlyPlatformLegacyGpioManipulation (PlatformType);
    814 
    815   //
    816   // Early platform specific GPIO Controller init & manipulation.
    817   // Combined for sharing of temp. memory bar.
    818   //
    819   EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType);
    820 
    821   //
    822   // Early Thermal Sensor Init.
    823   //
    824   EarlyPlatformThermalSensorInit ();
    825 
    826   //
    827   // Early Lan Ethernet Mac Init.
    828   //
    829   EarlyPlatformMacInit (
    830     PcdGetPtr (PcdIohEthernetMac0),
    831     PcdGetPtr (PcdIohEthernetMac1)
    832     );
    833 }
    834 
    835 /**
    836   This function provides early platform Legacy GPIO initialisation.
    837 
    838   @param  PlatformType  Platform type for GPIO init.
    839 
    840 **/
    841 VOID
    842 EFIAPI
    843 EarlyPlatformLegacyGpioInit (
    844   IN CONST EFI_PLATFORM_TYPE              PlatformType
    845   )
    846 {
    847   BOARD_LEGACY_GPIO_CONFIG          *LegacyGpioConfig;
    848   UINT32                            NewValue;
    849   UINT32                            GpioBaseAddress;
    850 
    851   //
    852   // Assert if platform type outside table range.
    853   //
    854   ASSERT ((UINTN) PlatformType < mBoardLegacyGpioConfigTableLen);
    855   LegacyGpioConfig = &mBoardLegacyGpioConfigTable[(UINTN) PlatformType];
    856 
    857   GpioBaseAddress = (UINT32)PcdGet16 (PcdGbaIoBaseAddress);
    858 
    859   NewValue     = 0x0;
    860   //
    861   // Program QNC GPIO Registers.
    862   //
    863   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellEnable;
    864   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL, NewValue );
    865   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellIoSelect;
    866   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL, NewValue);
    867   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellLvlForInputOrOutput;
    868   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL, NewValue);
    869   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerPositiveEdge;
    870   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL, NewValue );
    871   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerNegativeEdge;
    872   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL, NewValue);
    873   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellGPEEnable;
    874   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL, NewValue);
    875   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellSMIEnable;
    876   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL, NewValue );
    877   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerStatus;
    878   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL, NewValue);
    879   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellNMIEnable;
    880   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL, NewValue);
    881 
    882   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellEnable;
    883   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL, NewValue );
    884   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellIoSelect;
    885   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL, NewValue) ;
    886   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellLvlForInputOrOutput;
    887   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL, NewValue);
    888   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerPositiveEdge;
    889   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL, NewValue );
    890   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerNegativeEdge;
    891   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL, NewValue) ;
    892   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellGPEEnable;
    893   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL, NewValue);
    894   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellSMIEnable;
    895   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL, NewValue );
    896   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerStatus;
    897   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL, NewValue) ;
    898   NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellNMIEnable;
    899   IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL, NewValue);
    900 }
    901 
    902 /**
    903   Performs any early platform specific Legacy GPIO manipulation.
    904 
    905   @param  PlatformType  Platform type GPIO manipulation.
    906 
    907 **/
    908 VOID
    909 EFIAPI
    910 EarlyPlatformLegacyGpioManipulation (
    911   IN CONST EFI_PLATFORM_TYPE              PlatformType
    912   )
    913 {
    914   if (PlatformType == CrossHill) {
    915 
    916     //
    917     // Pull TPM reset low for 80us (equivalent to cold reset, Table 39
    918     // Infineon SLB9645 Databook), then pull TPM reset high and wait for
    919     // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon
    920     // SLB9645 Databook states TPM is ready to receive command after 30ms
    921     // but section 4.7 states some TPM commands may take longer to execute
    922     // upto 150ms after test).
    923     //
    924 
    925     PlatformLegacyGpioSetLevel (
    926       R_QNC_GPIO_RGLVL_RESUME_WELL,
    927       PLATFORM_RESUMEWELL_TPM_RST_GPIO,
    928       FALSE
    929       );
    930     MicroSecondDelay (80);
    931 
    932     PlatformLegacyGpioSetLevel (
    933       R_QNC_GPIO_RGLVL_RESUME_WELL,
    934       PLATFORM_RESUMEWELL_TPM_RST_GPIO,
    935       TRUE
    936       );
    937     MicroSecondDelay (150000);
    938   }
    939 
    940 }
    941 
    942 /**
    943   Performs any early platform specific GPIO Controller init & manipulation.
    944 
    945   @param  PlatformType  Platform type for GPIO init & manipulation.
    946 
    947 **/
    948 VOID
    949 EFIAPI
    950 EarlyPlatformGpioCtrlerInitAndManipulation (
    951   IN CONST EFI_PLATFORM_TYPE              PlatformType
    952   )
    953 {
    954   UINT32                            IohGpioBase;
    955   UINT32                            Data32;
    956   UINT32                            Addr;
    957   BOARD_GPIO_CONTROLLER_CONFIG      *GpioConfig;
    958   UINT32                            DevPcieAddr;
    959   UINT16                            SaveCmdReg;
    960   UINT32                            SaveBarReg;
    961   UINT16                            PciVid;
    962   UINT16                            PciDid;
    963 
    964   ASSERT ((UINTN) PlatformType < mBoardGpioControllerConfigTableLen);
    965   GpioConfig = &mBoardGpioControllerConfigTable[(UINTN) PlatformType];
    966 
    967   IohGpioBase = (UINT32) PcdGet64 (PcdIohGpioMmioBase);
    968 
    969   DevPcieAddr = PCI_LIB_ADDRESS (
    970                   PcdGet8 (PcdIohGpioBusNumber),
    971                   PcdGet8 (PcdIohGpioDevNumber),
    972                   PcdGet8 (PcdIohGpioFunctionNumber),
    973                   0
    974                   );
    975 
    976   //
    977   // Do nothing if not a supported device.
    978   //
    979   PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
    980   PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
    981   if((PciVid != V_IOH_I2C_GPIO_VENDOR_ID) || (PciDid != V_IOH_I2C_GPIO_DEVICE_ID)) {
    982     return;
    983   }
    984 
    985   //
    986   // Save current settings for PCI CMD/BAR registers.
    987   //
    988   SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
    989   SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister));
    990 
    991   //
    992   // Use predefined tempory memory resource.
    993   //
    994   PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase);
    995   PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
    996 
    997   //
    998   // Gpio Controller Init Tasks.
    999   //
   1000 
   1001   //
   1002   // IEN- Interrupt Enable Register
   1003   //
   1004   Addr =  IohGpioBase + GPIO_INTEN;
   1005   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1006   Data32 |= (GpioConfig->IntEn & 0x000FFFFF);
   1007   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1008 
   1009   //
   1010   // ISTATUS- Interrupt Status Register
   1011   //
   1012   Addr =  IohGpioBase + GPIO_INTSTATUS;
   1013   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1014   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1015 
   1016   //
   1017   // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR
   1018   //
   1019   Addr =  IohGpioBase + GPIO_SWPORTA_DR;
   1020   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1021   Data32 |= (GpioConfig->PortADR & 0x000FFFFF);
   1022   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1023 
   1024   //
   1025   // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input
   1026   //
   1027   Addr =  IohGpioBase + GPIO_SWPORTA_DDR;
   1028   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1029   Data32 |= (GpioConfig->PortADir & 0x000FFFFF);
   1030   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1031 
   1032   //
   1033   // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked
   1034   //
   1035   Addr =  IohGpioBase + GPIO_INTMASK;
   1036   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1037   Data32 |= (GpioConfig->IntMask & 0x000FFFFF);
   1038   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1039 
   1040   //
   1041   // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive
   1042   //
   1043   Addr =  IohGpioBase + GPIO_INTTYPE_LEVEL;
   1044   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1045   Data32 |= (GpioConfig->IntType & 0x000FFFFF);
   1046   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1047 
   1048   //
   1049   // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low
   1050   //
   1051   Addr =  IohGpioBase + GPIO_INT_POLARITY;
   1052   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1053   Data32 |= (GpioConfig->IntPolarity & 0x000FFFFF);
   1054   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1055 
   1056   //
   1057   // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce
   1058   //
   1059   Addr =  IohGpioBase + GPIO_DEBOUNCE;
   1060   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1061   Data32 |= (GpioConfig->Debounce & 0x000FFFFF);
   1062   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1063 
   1064   //
   1065   // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk)
   1066   //
   1067   Addr =  IohGpioBase + GPIO_LS_SYNC;
   1068   Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
   1069   Data32 |= (GpioConfig->LsSync & 0x000FFFFF);
   1070   *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1071 
   1072   //
   1073   // Gpio Controller Manipulation Tasks.
   1074   //
   1075 
   1076   if (PlatformType == (EFI_PLATFORM_TYPE) Galileo) {
   1077     //
   1078     // Reset Cypress Expander on Galileo Platform
   1079     //
   1080     Addr = IohGpioBase + GPIO_SWPORTA_DR;
   1081     Data32 = *((volatile UINT32 *) (UINTN)(Addr));
   1082     Data32 |= BIT4;                                 // Cypress Reset line controlled by GPIO<4>
   1083     *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1084 
   1085     Data32 = *((volatile UINT32 *) (UINTN)(Addr));
   1086     Data32 &= ~BIT4;                                // Cypress Reset line controlled by GPIO<4>
   1087     *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
   1088 
   1089   }
   1090 
   1091   //
   1092   // Restore settings for PCI CMD/BAR registers
   1093   //
   1094   PciWrite32 ((DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);
   1095   PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
   1096 }
   1097 
   1098 /**
   1099   Performs any early platform init of SoC Ethernet Mac devices.
   1100 
   1101   @param  IohMac0Address  Mac address to program into Mac0 device.
   1102   @param  IohMac1Address  Mac address to program into Mac1 device.
   1103 
   1104 **/
   1105 VOID
   1106 EFIAPI
   1107 EarlyPlatformMacInit (
   1108   IN CONST UINT8                          *IohMac0Address,
   1109   IN CONST UINT8                          *IohMac1Address
   1110   )
   1111 {
   1112   BOOLEAN                           SetMacAddr;
   1113 
   1114   //
   1115   // Set chipset MAC0 address if configured.
   1116   //
   1117   SetMacAddr =
   1118     (CompareMem (ChipsetDefaultMac, IohMac0Address, sizeof (ChipsetDefaultMac))) != 0;
   1119   if (SetMacAddr) {
   1120     if ((*(IohMac0Address) & BIT0) != 0) {
   1121       DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
   1122         (UINTN) IOH_MAC0_BUS_NUMBER,
   1123         (UINTN) IOH_MAC0_DEVICE_NUMBER,
   1124         (UINTN) IOH_MAC0_FUNCTION_NUMBER
   1125         ));
   1126       ASSERT (FALSE);
   1127     } else {
   1128       SetLanControllerMacAddr (
   1129         IOH_MAC0_BUS_NUMBER,
   1130         IOH_MAC0_DEVICE_NUMBER,
   1131         IOH_MAC0_FUNCTION_NUMBER,
   1132         IohMac0Address,
   1133         (UINT32) PcdGet64(PcdIohMac0MmioBase)
   1134         );
   1135     }
   1136   } else {
   1137     DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
   1138       (UINTN) IOH_MAC0_BUS_NUMBER,
   1139       (UINTN) IOH_MAC0_DEVICE_NUMBER,
   1140       (UINTN) IOH_MAC0_FUNCTION_NUMBER
   1141       ));
   1142   }
   1143 
   1144   //
   1145   // Set chipset MAC1 address if configured.
   1146   //
   1147   SetMacAddr =
   1148     (CompareMem (ChipsetDefaultMac, IohMac1Address, sizeof (ChipsetDefaultMac))) != 0;
   1149   if (SetMacAddr) {
   1150     if ((*(IohMac1Address) & BIT0) != 0) {
   1151       DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
   1152         (UINTN) IOH_MAC1_BUS_NUMBER,
   1153         (UINTN) IOH_MAC1_DEVICE_NUMBER,
   1154         (UINTN) IOH_MAC1_FUNCTION_NUMBER
   1155         ));
   1156       ASSERT (FALSE);
   1157     } else {
   1158         SetLanControllerMacAddr (
   1159           IOH_MAC1_BUS_NUMBER,
   1160           IOH_MAC1_DEVICE_NUMBER,
   1161           IOH_MAC1_FUNCTION_NUMBER,
   1162           IohMac1Address,
   1163           (UINT32) PcdGet64(PcdIohMac1MmioBase)
   1164           );
   1165     }
   1166   } else {
   1167     DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
   1168       (UINTN) IOH_MAC1_BUS_NUMBER,
   1169       (UINTN) IOH_MAC1_DEVICE_NUMBER,
   1170       (UINTN) IOH_MAC1_FUNCTION_NUMBER
   1171       ));
   1172   }
   1173 }
   1174 
   1175