Home | History | Annotate | Download | only in PlatformInit
      1 /** @file
      2 Essential platform configuration.
      3 
      4 Copyright (c) 2013 Intel Corporation.
      5 
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 
     15 **/
     16 
     17 #include "PlatformInitDxe.h"
     18 
     19 //
     20 // The protocols, PPI and GUID defintions for this module
     21 //
     22 
     23 //
     24 // The Library classes this module consumes
     25 //
     26 
     27 //
     28 // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
     29 //             Workaround to make default SMRAM UnCachable
     30 //
     31 #define SMM_DEFAULT_SMBASE                  0x30000     // Default SMBASE address
     32 #define SMM_DEFAULT_SMBASE_SIZE_BYTES       0x10000     // Size in bytes of default SMRAM
     33 
     34 BOOLEAN                       mMemCfgDone = FALSE;
     35 UINT8                         ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
     36 
     37 VOID
     38 EFIAPI
     39 PlatformInitializeUart0MuxGalileo (
     40   VOID
     41   )
     42 /*++
     43 
     44 
     45 Routine Description:
     46 
     47   This is the routine to initialize UART0 for DBG2 support. The hardware used in this process is a
     48   Legacy Bridge (Legacy GPIO), I2C controller, a bi-directional MUX and a Cypress CY8C9540A chip.
     49 
     50 Arguments:
     51 
     52   None.
     53 
     54 Returns:
     55 
     56   None.
     57 
     58 --*/
     59 {
     60   EFI_STATUS                        Status;
     61   EFI_I2C_DEVICE_ADDRESS            I2CSlaveAddress;
     62   UINTN                             Length;
     63   UINT8                             Buffer[2];
     64 
     65   if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
     66     I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
     67   } else {
     68     I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
     69   }
     70 
     71   //
     72   // Set GPIO_SUS<2> as an output, raise voltage to Vdd.
     73   //
     74   PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, 2, TRUE);
     75 
     76   //
     77   // Select Port 3
     78   //
     79   Length = 2;
     80   Buffer[0] = 0x18; //sub-address
     81   Buffer[1] = 0x03; //data
     82 
     83   Status = I2cWriteMultipleByte (
     84               I2CSlaveAddress,
     85               EfiI2CSevenBitAddrMode,
     86               &Length,
     87               &Buffer
     88               );
     89   ASSERT_EFI_ERROR (Status);
     90 
     91   //
     92   // Set "Pin Direction" bit4 and bit5 as outputs
     93   //
     94   Length = 2;
     95   Buffer[0] = 0x1C; //sub-address
     96   Buffer[1] = 0xCF; //data
     97 
     98   Status = I2cWriteMultipleByte (
     99               I2CSlaveAddress,
    100               EfiI2CSevenBitAddrMode,
    101               &Length,
    102               &Buffer
    103               );
    104   ASSERT_EFI_ERROR (Status);
    105 
    106   //
    107   // Lower GPORT3 bit4 and bit5 to Vss
    108   //
    109   Length = 2;
    110   Buffer[0] = 0x0B; //sub-address
    111   Buffer[1] = 0xCF; //data
    112 
    113   Status = I2cWriteMultipleByte (
    114               I2CSlaveAddress,
    115               EfiI2CSevenBitAddrMode,
    116               &Length,
    117               &Buffer
    118               );
    119   ASSERT_EFI_ERROR (Status);
    120 }
    121 
    122 VOID
    123 EFIAPI
    124 PlatformInitializeUart0MuxGalileoGen2 (
    125   VOID
    126   )
    127 /*++
    128 
    129 
    130 Routine Description:
    131 
    132   This is the routine to initialize UART0 on GalileoGen2. The hardware used in this process is
    133   I2C controller and the configuring the following IO Expander signal.
    134 
    135   EXP1.P1_5 should be configured as an output & driven high.
    136   EXP1.P0_0 should be configured as an output & driven high.
    137   EXP0.P1_4 should be configured as an output, driven low.
    138   EXP1.P0_1 pullup should be disabled.
    139   EXP0.P1_5 Pullup should be disabled.
    140 
    141 Arguments:
    142 
    143   None.
    144 
    145 Returns:
    146 
    147   None.
    148 
    149 --*/
    150 
    151 {
    152   //
    153   //  EXP1.P1_5 should be configured as an output & driven high.
    154   //
    155   PlatformPcal9555GpioSetDir (
    156     GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
    157     13,                                   // P1-5.
    158     TRUE
    159     );
    160   PlatformPcal9555GpioSetLevel (
    161     GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
    162     13,                                   // P1-5.
    163     TRUE
    164     );
    165 
    166   //
    167   // EXP1.P0_0 should be configured as an output & driven high.
    168   //
    169   PlatformPcal9555GpioSetDir (
    170     GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
    171     0,                                    // P0_0.
    172     TRUE
    173     );
    174   PlatformPcal9555GpioSetLevel (
    175     GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
    176     0,                                    // P0_0.
    177     TRUE
    178     );
    179 
    180   //
    181   //  EXP0.P1_4 should be configured as an output, driven low.
    182   //
    183   PlatformPcal9555GpioSetDir (
    184     GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
    185     12,                                   // P1-4.
    186     FALSE
    187     );
    188   PlatformPcal9555GpioSetLevel (          // IO Expander 0.
    189     GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // P1-4
    190     12,
    191     FALSE
    192     );
    193 
    194   //
    195   // EXP1.P0_1 pullup should be disabled.
    196   //
    197   PlatformPcal9555GpioDisablePull (
    198     GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
    199     1                                     // P0-1.
    200     );
    201 
    202   //
    203   // EXP0.P1_5 Pullup should be disabled.
    204   //
    205   PlatformPcal9555GpioDisablePull (
    206     GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
    207     13                                    // P1-5.
    208     );
    209 }
    210 
    211 VOID
    212 EFIAPI
    213 PlatformConfigOnSmmConfigurationProtocol (
    214   IN  EFI_EVENT Event,
    215   IN  VOID      *Context
    216   )
    217 /*++
    218 
    219 Routine Description:
    220 
    221   Function runs in PI-DXE to perform platform specific config when
    222   SmmConfigurationProtocol is installed.
    223 
    224 Arguments:
    225   Event       - The event that occured.
    226   Context     - For EFI compatiblity.  Not used.
    227 
    228 Returns:
    229   None.
    230 --*/
    231 
    232 {
    233   EFI_STATUS            Status;
    234   UINT32                NewValue;
    235   UINT64                BaseAddress;
    236   UINT64                SmramLength;
    237   VOID                  *SmmCfgProt;
    238 
    239   Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, &SmmCfgProt);
    240   if (Status != EFI_SUCCESS){
    241     DEBUG ((DEBUG_INFO, "gEfiSmmConfigurationProtocolGuid triggered but not valid.\n"));
    242     return;
    243   }
    244   if (mMemCfgDone) {
    245     DEBUG ((DEBUG_INFO, "Platform DXE Mem config already done.\n"));
    246     return;
    247   }
    248 
    249   //
    250   // Disable eSram block (this will also clear/zero eSRAM)
    251   // We only use eSRAM in the PEI phase. Disable now that we are in the DXE phase
    252   //
    253   NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK);
    254   NewValue |= BLOCK_DISABLE_PG;
    255   QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue);
    256 
    257   //
    258   // Update HMBOUND to top of DDR3 memory and LOCK
    259   // We disabled eSRAM so now we move HMBOUND down to top of DDR3
    260   //
    261   QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength);
    262   NewValue = (UINT32)(BaseAddress + SmramLength);
    263   DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue));
    264   QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK));
    265 
    266   //
    267   // Lock IMR5 now that HMBOUND is locked (legacy S3 region)
    268   //
    269   NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL);
    270   NewValue |= IMR_LOCK;
    271   QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
    272 
    273   //
    274   // Lock IMR6 now that HMBOUND is locked (ACPI Reclaim/ACPI/Runtime services/Reserved)
    275   //
    276   NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL);
    277   NewValue |= IMR_LOCK;
    278   QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
    279 
    280   //
    281   // Disable IMR2 memory protection (RMU Main Binary)
    282   //
    283   QncImrWrite (
    284             QUARK_NC_MEMORY_MANAGER_IMR2,
    285             (UINT32)(IMRL_RESET & ~IMR_EN),
    286             (UINT32)IMRH_RESET,
    287             (UINT32)IMRX_ALL_ACCESS,
    288             (UINT32)IMRX_ALL_ACCESS
    289         );
    290 
    291   //
    292   // Disable IMR3 memory protection (Default SMRAM)
    293   //
    294   QncImrWrite (
    295             QUARK_NC_MEMORY_MANAGER_IMR3,
    296             (UINT32)(IMRL_RESET & ~IMR_EN),
    297             (UINT32)IMRH_RESET,
    298             (UINT32)IMRX_ALL_ACCESS,
    299             (UINT32)IMRX_ALL_ACCESS
    300         );
    301 
    302   //
    303   // Disable IMR4 memory protection (eSRAM).
    304   //
    305   QncImrWrite (
    306             QUARK_NC_MEMORY_MANAGER_IMR4,
    307             (UINT32)(IMRL_RESET & ~IMR_EN),
    308             (UINT32)IMRH_RESET,
    309             (UINT32)IMRX_ALL_ACCESS,
    310             (UINT32)IMRX_ALL_ACCESS
    311         );
    312 
    313   //
    314   // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
    315   //             Workaround to make default SMRAM UnCachable
    316   //
    317   Status = gDS->SetMemorySpaceAttributes (
    318                   (EFI_PHYSICAL_ADDRESS) SMM_DEFAULT_SMBASE,
    319                   SMM_DEFAULT_SMBASE_SIZE_BYTES,
    320                   EFI_MEMORY_WB
    321                   );
    322   ASSERT_EFI_ERROR (Status);
    323 
    324   mMemCfgDone = TRUE;
    325 }
    326 
    327 VOID
    328 EFIAPI
    329 PlatformConfigOnSpiReady (
    330   IN  EFI_EVENT Event,
    331   IN  VOID      *Context
    332   )
    333 /*++
    334 
    335 Routine Description:
    336 
    337   Function runs in PI-DXE to perform platform specific config when SPI
    338   interface is ready.
    339 
    340 Arguments:
    341   Event       - The event that occured.
    342   Context     - For EFI compatiblity.  Not used.
    343 
    344 Returns:
    345   None.
    346 
    347 --*/
    348 {
    349   EFI_STATUS                        Status;
    350   VOID                              *SpiReadyProt = NULL;
    351   EFI_PLATFORM_TYPE                 Type;
    352   EFI_BOOT_MODE                      BootMode;
    353 
    354   BootMode = GetBootModeHob ();
    355 
    356   Status = gBS->LocateProtocol (&gEfiSmmSpiReadyProtocolGuid, NULL, &SpiReadyProt);
    357   if (Status != EFI_SUCCESS){
    358     DEBUG ((DEBUG_INFO, "gEfiSmmSpiReadyProtocolGuid triggered but not valid.\n"));
    359     return;
    360   }
    361 
    362   //
    363   // Lock regions SPI flash.
    364   //
    365   PlatformFlashLockPolicy (FALSE);
    366 
    367   //
    368   // Configurations and checks to be done when DXE tracing available.
    369   //
    370 
    371   //
    372   // Platform specific Signal routing.
    373   //
    374 
    375   //
    376   // Skip any signal not needed for recovery and flash update.
    377   //
    378   if (BootMode != BOOT_ON_FLASH_UPDATE && BootMode != BOOT_IN_RECOVERY_MODE) {
    379 
    380     //
    381     // Galileo Platform UART0 support.
    382     //
    383     Type = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
    384     if (Type == Galileo) {
    385       //
    386       // Use MUX to connect out UART0 pins.
    387       //
    388       PlatformInitializeUart0MuxGalileo ();
    389     }
    390 
    391     //
    392     // GalileoGen2 Platform UART0 support.
    393     //
    394     if (Type == GalileoGen2) {
    395       //
    396       // Use route out UART0 pins.
    397       //
    398       PlatformInitializeUart0MuxGalileoGen2 ();
    399     }
    400   }
    401 }
    402 
    403 EFI_STATUS
    404 EFIAPI
    405 CreateConfigEvents (
    406   VOID
    407   )
    408 /*++
    409 
    410 Routine Description:
    411 
    412 Arguments:
    413   None
    414 
    415 Returns:
    416   EFI_STATUS
    417 
    418 --*/
    419 {
    420   EFI_EVENT   EventSmmCfg;
    421   EFI_EVENT   EventSpiReady;
    422   VOID        *RegistrationSmmCfg;
    423   VOID        *RegistrationSpiReady;
    424 
    425   //
    426   // Schedule callback for when SmmConfigurationProtocol installed.
    427   //
    428   EventSmmCfg = EfiCreateProtocolNotifyEvent (
    429                   &gEfiSmmConfigurationProtocolGuid,
    430                   TPL_CALLBACK,
    431                   PlatformConfigOnSmmConfigurationProtocol,
    432                   NULL,
    433                   &RegistrationSmmCfg
    434                   );
    435   ASSERT (EventSmmCfg != NULL);
    436 
    437   //
    438   // Schedule callback to setup SPI Flash Policy when SPI interface ready.
    439   //
    440   EventSpiReady = EfiCreateProtocolNotifyEvent (
    441                     &gEfiSmmSpiReadyProtocolGuid,
    442                     TPL_CALLBACK,
    443                     PlatformConfigOnSpiReady,
    444                     NULL,
    445                     &RegistrationSpiReady
    446                     );
    447   ASSERT (EventSpiReady != NULL);
    448   return EFI_SUCCESS;
    449 }
    450