Home | History | Annotate | Download | only in PlatformInit
      1 /** @file
      2 This file includes a memory call back function notified when MRC is done,
      3 following action is performed in this file,
      4   1. ICH initialization after MRC.
      5   2. SIO initialization.
      6   3. Install ResetSystem and FinvFv PPI.
      7   4. Set MTRR for PEI
      8   5. Create FV HOB and Flash HOB
      9 
     10 Copyright (c) 2013 - 2016, Intel Corporation.
     11 
     12 This program and the accompanying materials
     13 are licensed and made available under the terms and conditions of the BSD License
     14 which accompanies this distribution.  The full text of the license may be found at
     15 http://opensource.org/licenses/bsd-license.php
     16 
     17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     20 **/
     21 
     22 
     23 #include "CommonHeader.h"
     24 
     25 #include "PlatformEarlyInit.h"
     26 
     27 extern EFI_PEI_PPI_DESCRIPTOR mPpiStall[];
     28 
     29 EFI_PEI_RESET_PPI mResetPpi = { ResetSystem };
     30 
     31 EFI_PEI_PPI_DESCRIPTOR mPpiList[1] = {
     32   {
     33     (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     34     &gEfiPeiResetPpiGuid,
     35     &mResetPpi
     36   }
     37 };
     38 
     39 /**
     40   This function reset the entire platform, including all processor and devices, and
     41   reboots the system.
     42 
     43   @param  PeiServices General purpose services available to every PEIM.
     44 
     45   @retval EFI_SUCCESS if it completed successfully.
     46 **/
     47 EFI_STATUS
     48 EFIAPI
     49 ResetSystem (
     50   IN CONST EFI_PEI_SERVICES          **PeiServices
     51   )
     52 {
     53   ResetCold();
     54   return EFI_SUCCESS;
     55 }
     56 
     57 /**
     58   This function provides a blocking stall for reset at least the given number of microseconds
     59   stipulated in the final argument.
     60 
     61   @param  PeiServices General purpose services available to every PEIM.
     62 
     63   @param  this Pointer to the local data for the interface.
     64 
     65   @param  Microseconds number of microseconds for which to stall.
     66 
     67   @retval EFI_SUCCESS the function provided at least the required stall.
     68 **/
     69 EFI_STATUS
     70 EFIAPI
     71 Stall (
     72   IN CONST EFI_PEI_SERVICES   **PeiServices,
     73   IN CONST EFI_PEI_STALL_PPI  *This,
     74   IN UINTN                    Microseconds
     75   )
     76 {
     77   MicroSecondDelay (Microseconds);
     78   return EFI_SUCCESS;
     79 }
     80 
     81 
     82 /**
     83   This function will be called when MRC is done.
     84 
     85   @param  PeiServices General purpose services available to every PEIM.
     86 
     87   @param  NotifyDescriptor Information about the notify event..
     88 
     89   @param  Ppi The notify context.
     90 
     91   @retval EFI_SUCCESS If the function completed successfully.
     92 **/
     93 EFI_STATUS
     94 EFIAPI
     95 MemoryDiscoveredPpiNotifyCallback (
     96   IN EFI_PEI_SERVICES           **PeiServices,
     97   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
     98   IN VOID                       *Ppi
     99   )
    100 {
    101   EFI_STATUS                            Status;
    102   EFI_BOOT_MODE                         BootMode;
    103   UINT64                                MemoryLength;
    104   EFI_SMRAM_DESCRIPTOR                  *SmramDescriptor;
    105   UINTN                                 NumSmramRegions;
    106   UINT32                                RmuMainBaseAddress;
    107   UINT32                                RegData32;
    108   UINT8                                 CpuAddressWidth;
    109   UINT32                                RegEax;
    110   MTRR_SETTINGS                         MtrrSettings;
    111   EFI_PEI_READ_ONLY_VARIABLE2_PPI       *VariableServices;
    112   UINT8                                 MorControl;
    113   UINTN                                 DataSize;
    114 
    115   DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));
    116 
    117   NumSmramRegions = 0;
    118   SmramDescriptor = NULL;
    119   RmuMainBaseAddress = 0;
    120 
    121   PERF_START (NULL, "SetCache", NULL, 0);
    122 
    123   InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);
    124   ASSERT (SmramDescriptor != NULL);
    125   ASSERT (RmuMainBaseAddress != 0);
    126 
    127   MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;
    128 
    129   Status = PeiServicesGetBootMode (&BootMode);
    130   ASSERT_EFI_ERROR (Status);
    131 
    132   //
    133   // Get current MTRR settings
    134   //
    135   MtrrGetAllMtrrs (&MtrrSettings);
    136 
    137   //
    138   // Set all DRAM cachability to CacheWriteBack
    139   //
    140   Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack);
    141   ASSERT_EFI_ERROR (Status);
    142 
    143   //
    144   // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
    145   //             Workaround to make default SMRAM UnCachable
    146   //
    147   Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable);
    148   ASSERT_EFI_ERROR (Status);
    149 
    150   //
    151   // Set new MTRR settings
    152   //
    153   MtrrSetAllMtrrs (&MtrrSettings);
    154 
    155   PERF_END (NULL, "SetCache", NULL, 0);
    156 
    157   //
    158   // Get necessary PPI
    159   //
    160   Status = PeiServicesLocatePpi (
    161              &gEfiPeiReadOnlyVariable2PpiGuid,           // GUID
    162              0,                                          // INSTANCE
    163              NULL,                                       // EFI_PEI_PPI_DESCRIPTOR
    164              (VOID **)&VariableServices                  // PPI
    165              );
    166   ASSERT_EFI_ERROR (Status);
    167 
    168   //
    169   // Detect MOR request by the OS.
    170   //
    171   MorControl = 0;
    172   DataSize = sizeof (MorControl);
    173   Status = VariableServices->GetVariable (
    174                                VariableServices,
    175                                MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
    176                                &gEfiMemoryOverwriteControlDataGuid,
    177                                NULL,
    178                                &DataSize,
    179                                &MorControl
    180                                );
    181   //
    182   // If OS requested a memory overwrite perform it now for Embedded SRAM
    183   //
    184   if (MOR_CLEAR_MEMORY_VALUE (MorControl)) {
    185     DEBUG ((EFI_D_INFO, "Clear Embedded SRAM per MOR request.\n"));
    186     if (PcdGet32 (PcdESramMemorySize) > 0) {
    187       if (PcdGet32 (PcdEsramStage1Base) == 0) {
    188         //
    189         // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.
    190         // Clear byte at 0 and start clear operation at address 1.
    191         //
    192         *(UINT8 *)(0) = 0;
    193         ZeroMem ((VOID *)1, (UINTN)PcdGet32 (PcdESramMemorySize) - 1);
    194       } else {
    195         ZeroMem (
    196           (VOID *)(UINTN)PcdGet32 (PcdEsramStage1Base),
    197           (UINTN)PcdGet32 (PcdESramMemorySize)
    198           );
    199       }
    200     }
    201   }
    202 
    203   //
    204   // Install PeiReset for PeiResetSystem service
    205   //
    206   Status = PeiServicesInstallPpi (&mPpiList[0]);
    207   ASSERT_EFI_ERROR (Status);
    208 
    209   //
    210   // Do QNC initialization after MRC
    211   //
    212   PeiQNCPostMemInit ();
    213 
    214   Status = PeiServicesInstallPpi (&mPpiStall[0]);
    215   ASSERT_EFI_ERROR (Status);
    216 
    217   //
    218   // Set E000/F000 Routing
    219   //
    220   RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
    221   RegData32 |= (BIT2|BIT1);
    222   QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);
    223 
    224   if (BootMode == BOOT_IN_RECOVERY_MODE) {
    225     // Do nothing here. A generic RecoveryModule will handle it.
    226   } else if (BootMode == BOOT_ON_S3_RESUME) {
    227     return EFI_SUCCESS;
    228   } else {
    229     PeiServicesInstallFvInfoPpi (
    230       NULL,
    231       (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase),
    232       PcdGet32 (PcdFlashFvMainSize),
    233       NULL,
    234       NULL
    235       );
    236 
    237     //
    238     // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV
    239     // and produce Load File Protocols for UEFI Applications in this FV.
    240     //
    241     BuildFvHob (
    242       PcdGet32 (PcdFlashFvMainBase),
    243       PcdGet32 (PcdFlashFvMainSize)
    244       );
    245 
    246     //
    247     // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV
    248     // and produce Load File Protocols for UEFI Applications in this FV.
    249     //
    250     BuildFvHob (
    251       PcdGet32 (PcdFlashFvPayloadBase),
    252       PcdGet32 (PcdFlashFvPayloadSize)
    253       );
    254   }
    255 
    256   //
    257   // Build flash HOB, it's going to be used by GCD and E820 building
    258   // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)
    259   //
    260   BuildResourceDescriptorHob (
    261     EFI_RESOURCE_FIRMWARE_DEVICE,
    262     (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
    263     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    264     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    265     (SIZE_4GB - SIZE_8MB),
    266     SIZE_8MB
    267     );
    268 
    269   //
    270   // Create a CPU hand-off information
    271   //
    272   CpuAddressWidth = 32;
    273   AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
    274   if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
    275     AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
    276     CpuAddressWidth = (UINT8) (RegEax & 0xFF);
    277   }
    278   DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));
    279 
    280   BuildCpuHob (CpuAddressWidth, 16);
    281 
    282   ASSERT_EFI_ERROR (Status);
    283 
    284   return Status;
    285 }
    286