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 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 
    112   DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));
    113 
    114   NumSmramRegions = 0;
    115   SmramDescriptor = NULL;
    116   RmuMainBaseAddress = 0;
    117 
    118   PERF_START (NULL, "SetCache", NULL, 0);
    119 
    120   InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);
    121   ASSERT (SmramDescriptor != NULL);
    122   ASSERT (RmuMainBaseAddress != 0);
    123 
    124   MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;
    125 
    126   Status = PeiServicesGetBootMode (&BootMode);
    127   ASSERT_EFI_ERROR (Status);
    128 
    129   //
    130   // Get current MTRR settings
    131   //
    132   MtrrGetAllMtrrs (&MtrrSettings);
    133 
    134   //
    135   // Set all DRAM cachability to CacheWriteBack
    136   //
    137   Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack);
    138   ASSERT_EFI_ERROR (Status);
    139 
    140   //
    141   // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
    142   //             Workaround to make default SMRAM UnCachable
    143   //
    144   Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable);
    145   ASSERT_EFI_ERROR (Status);
    146 
    147   //
    148   // Set new MTRR settings
    149   //
    150   MtrrSetAllMtrrs (&MtrrSettings);
    151 
    152   PERF_END (NULL, "SetCache", NULL, 0);
    153 
    154   //
    155   // Install PeiReset for PeiResetSystem service
    156   //
    157   Status = PeiServicesInstallPpi (&mPpiList[0]);
    158   ASSERT_EFI_ERROR (Status);
    159 
    160   //
    161   // Do QNC initialization after MRC
    162   //
    163   PeiQNCPostMemInit ();
    164 
    165   Status = PeiServicesInstallPpi (&mPpiStall[0]);
    166   ASSERT_EFI_ERROR (Status);
    167 
    168   //
    169   // Set E000/F000 Routing
    170   //
    171   RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
    172   RegData32 |= (BIT2|BIT1);
    173   QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);
    174 
    175   if (BootMode == BOOT_IN_RECOVERY_MODE) {
    176     Status = PeimInitializeRecovery (PeiServices);
    177     ASSERT_EFI_ERROR (Status);
    178   } else if (BootMode == BOOT_ON_S3_RESUME) {
    179     return EFI_SUCCESS;
    180   } else {
    181     PeiServicesInstallFvInfoPpi (
    182       NULL,
    183       (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase),
    184       PcdGet32 (PcdFlashFvMainSize),
    185       NULL,
    186       NULL
    187       );
    188 
    189     //
    190     // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV
    191     // and produce Load File Protocols for UEFI Applications in this FV.
    192     //
    193     BuildFvHob (
    194       PcdGet32 (PcdFlashFvMainBase),
    195       PcdGet32 (PcdFlashFvMainSize)
    196       );
    197 
    198     //
    199     // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV
    200     // and produce Load File Protocols for UEFI Applications in this FV.
    201     //
    202     BuildFvHob (
    203       PcdGet32 (PcdFlashFvPayloadBase),
    204       PcdGet32 (PcdFlashFvPayloadSize)
    205       );
    206   }
    207 
    208   //
    209   // Build flash HOB, it's going to be used by GCD and E820 building
    210   // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)
    211   //
    212   BuildResourceDescriptorHob (
    213     EFI_RESOURCE_FIRMWARE_DEVICE,
    214     (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
    215     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    216     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    217     (SIZE_4GB - SIZE_8MB),
    218     SIZE_8MB
    219     );
    220 
    221   //
    222   // Create a CPU hand-off information
    223   //
    224   CpuAddressWidth = 32;
    225   AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
    226   if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
    227     AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
    228     CpuAddressWidth = (UINT8) (RegEax & 0xFF);
    229   }
    230   DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));
    231 
    232   BuildCpuHob (CpuAddressWidth, 16);
    233 
    234   ASSERT_EFI_ERROR (Status);
    235 
    236   return Status;
    237 }
    238