Home | History | Annotate | Download | only in PlatformInitPei
      1 /** @file
      2 
      3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      9   The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     13 
     15   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.
     19 
     21 
     23 Module Name:
     24 
     25   MemoryCallback.c
     26 
     27 Abstract:
     28 
     29   EFI 2.0 PEIM to provide the platform support functionality on the Bridgeport.
     30 
     31 --*/
     32 
     33 #include "PlatformEarlyInit.h"
     34 
     35 
     36 VOID
     37 UpdateDefaultSetupValue (
     38   IN  EFI_PLATFORM_INFO_HOB       *PlatformInfo
     39   )
     40 {
     41 return;
     42 }
     43 
     44 /**
     45   PEI termination callback.
     46 
     47   @param PeiServices         General purpose services available to every PEIM.
     48   @param NotifyDescriptor    Not uesed.
     49   @param Ppi                 Not uesed.
     50 
     51   @retval EFI_SUCCESS        If the interface could be successfully
     52                              installed.
     53 
     54 **/
     55 EFI_STATUS
     56 EFIAPI
     57 EndOfPeiPpiNotifyCallback (
     58   IN CONST EFI_PEI_SERVICES           **PeiServices,
     59   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
     60   IN VOID                       *Ppi
     61   )
     62 {
     63   EFI_STATUS                  Status;
     64   UINT64                      LowUncableBase;
     65   EFI_PLATFORM_INFO_HOB       *PlatformInfo;
     66   UINT32                      HecBaseHigh;
     67   EFI_BOOT_MODE               BootMode;
     68   EFI_PEI_HOB_POINTERS        Hob;
     69 
     70   Status = (*PeiServices)->GetBootMode(
     71                              PeiServices,
     72                              &BootMode
     73                              );
     74 
     75   ASSERT_EFI_ERROR (Status);
     76 
     77   //
     78   // Set the some PCI and chipset range as UC
     79   // And align to 1M at leaset
     80   //
     81   Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
     82   ASSERT (Hob.Raw != NULL);
     83   PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
     84 
     85   UpdateDefaultSetupValue (PlatformInfo);
     86 
     87   DEBUG ((EFI_D_ERROR, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm));
     88   DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase));
     89   DEBUG (
     90     (EFI_D_ERROR,
     91     "PCIE   BASE: %lX     Size : %X\n",
     92     PlatformInfo->PciData.PciExpressBase,
     93     PlatformInfo->PciData.PciExpressSize)
     94     );
     95   DEBUG (
     96     (EFI_D_ERROR,
     97     "PCI32  BASE: %X     Limit: %X\n",
     98     PlatformInfo->PciData.PciResourceMem32Base,
     99     PlatformInfo->PciData.PciResourceMem32Limit)
    100     );
    101   DEBUG (
    102     (EFI_D_ERROR,
    103     "PCI64  BASE: %lX     Limit: %lX\n",
    104     PlatformInfo->PciData.PciResourceMem64Base,
    105     PlatformInfo->PciData.PciResourceMem64Limit)
    106     );
    107   DEBUG ((EFI_D_ERROR, "UC    START: %lX     End  : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1));
    108 
    109   LowUncableBase = PlatformInfo->MemData.MemMaxTolm;
    110   LowUncableBase &= (0x0FFF00000);
    111 
    112   if (BootMode != BOOT_ON_S3_RESUME) {
    113     //
    114     // In BIOS, HECBASE will be always below 4GB
    115     //
    116     HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo->PciData.PciExpressBase, 28);
    117     ASSERT (HecBaseHigh < 16);
    118   }
    119 
    120   return Status;
    121 }
    122 
    123 /**
    124   Install Firmware Volume Hob's once there is main memory
    125 
    126   @param PeiServices       General purpose services available to every PEIM.
    127   @param NotifyDescriptor  Notify that this module published.
    128   @param Ppi               PPI that was installed.
    129 
    130   @retval EFI_SUCCESS     The function completed successfully.
    131 
    132 **/
    133 EFI_STATUS
    134 EFIAPI
    135 MemoryDiscoveredPpiNotifyCallback (
    136   IN CONST EFI_PEI_SERVICES           **PeiServices,
    137   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
    138   IN VOID                       *Ppi
    139   )
    140 {
    141   EFI_STATUS                  Status;
    142   EFI_BOOT_MODE               BootMode;
    143   EFI_CPUID_REGISTER          FeatureInfo;
    144   UINT8                       CpuAddressWidth;
    145   UINT16                      Pm1Cnt;
    146   EFI_PEI_HOB_POINTERS        Hob;
    147   EFI_PLATFORM_INFO_HOB       *PlatformInfo;
    148   UINT32                      RootComplexBar;
    149   UINT32                      PmcBase;
    150   UINT32                      IoBase;
    151   UINT32                      IlbBase;
    152   UINT32                      SpiBase;
    153   UINT32                      MphyBase;
    154 
    155   //
    156   // Get Platform Info HOB
    157   //
    158   Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
    159   ASSERT (Hob.Raw != NULL);
    160   PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
    161 
    162   Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
    163 
    164   //
    165   // Check if user wants to turn off in PEI phase
    166   //
    167   if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
    168     CheckPowerOffNow();
    169   } else {
    170     Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
    171     Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SLP_TYP;
    172     IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
    173   }
    174 
    175   #ifndef MINNOW2_FSP_BUILD
    176   //
    177   // Set PEI cache mode here
    178   //
    179   SetPeiCacheMode (PeiServices);
    180   #endif
    181 
    182   //
    183   //  Pulish memory tyoe info
    184   //
    185   PublishMemoryTypeInfo ();
    186 
    187   //
    188   // Work done if on a S3 resume
    189   //
    190   if (BootMode == BOOT_ON_S3_RESUME) {
    191     //
    192     //Program the side band packet register to send a sideband message to Punit
    193     //To indicate that DRAM has been initialized and PUNIT FW base address in memory.
    194     //
    195     return EFI_SUCCESS;
    196   }
    197 
    198   RootComplexBar = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA ) & B_PCH_LPC_RCBA_BAR;
    199   BuildResourceDescriptorHob (
    200     EFI_RESOURCE_MEMORY_MAPPED_IO,
    201     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    202     RootComplexBar,
    203     0x1000
    204     );
    205   DEBUG ((EFI_D_INFO, "RootComplexBar     : 0x%x\n", RootComplexBar));
    206 
    207   PmcBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMC_BASE ) & B_PCH_LPC_PMC_BASE_BAR;
    208   BuildResourceDescriptorHob (
    209     EFI_RESOURCE_MEMORY_MAPPED_IO,
    210     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    211     PmcBase,
    212     0x1000
    213     );
    214   DEBUG ((EFI_D_INFO, "PmcBase            : 0x%x\n", PmcBase));
    215 
    216   IoBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_IO_BASE ) & B_PCH_LPC_IO_BASE_BAR;
    217   BuildResourceDescriptorHob (
    218     EFI_RESOURCE_MEMORY_MAPPED_IO,
    219     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    220     IoBase,
    221     0x4000
    222     );
    223   DEBUG ((EFI_D_INFO, "IoBase             : 0x%x\n", IoBase));
    224 
    225   IlbBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ILB_BASE ) & B_PCH_LPC_ILB_BASE_BAR;
    226   BuildResourceDescriptorHob (
    227     EFI_RESOURCE_MEMORY_MAPPED_IO,
    228     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    229     IlbBase,
    230     0x1000
    231     );
    232   DEBUG ((EFI_D_INFO, "IlbBase            : 0x%x\n", IlbBase));
    233 
    234   SpiBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_SPI_BASE ) & B_PCH_LPC_SPI_BASE_BAR;
    235   BuildResourceDescriptorHob (
    236     EFI_RESOURCE_MEMORY_MAPPED_IO,
    237     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    238     SpiBase,
    239     0x1000
    240     );
    241   DEBUG ((EFI_D_INFO, "SpiBase            : 0x%x\n", SpiBase));
    242 
    243   MphyBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_MPHY_BASE ) & B_PCH_LPC_MPHY_BASE_BAR;
    244   BuildResourceDescriptorHob (
    245     EFI_RESOURCE_MEMORY_MAPPED_IO,
    246     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    247     MphyBase,
    248     0x100000
    249     );
    250   DEBUG ((EFI_D_INFO, "MphyBase           : 0x%x\n", MphyBase));
    251 
    252   //
    253   // Local APIC
    254   //
    255   BuildResourceDescriptorHob (
    256     EFI_RESOURCE_MEMORY_MAPPED_IO,
    257     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    258     LOCAL_APIC_ADDRESS,
    259     0x1000
    260   );
    261   DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n", LOCAL_APIC_ADDRESS));
    262 
    263   //
    264   // IO APIC
    265   //
    266   BuildResourceDescriptorHob (
    267     EFI_RESOURCE_MEMORY_MAPPED_IO,
    268     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    269     IO_APIC_ADDRESS,
    270     0x1000
    271   );
    272   DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS    : 0x%x\n", IO_APIC_ADDRESS));
    273 
    274   //
    275   // Adding the PCIE Express area to the E820 memory table as type 2 memory.
    276   //
    277   BuildResourceDescriptorHob (
    278     EFI_RESOURCE_MEMORY_MAPPED_IO,
    279     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    280     PlatformInfo->PciData.PciExpressBase,
    281     PlatformInfo->PciData.PciExpressSize
    282     );
    283   DEBUG ((EFI_D_INFO, "PciExpressBase     : 0x%x\n", PlatformInfo->PciData.PciExpressBase));
    284 
    285   //
    286   // Adding the Flashpart to the E820 memory table as type 2 memory.
    287   //
    288   BuildResourceDescriptorHob (
    289     EFI_RESOURCE_FIRMWARE_DEVICE,
    290     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
    291     FixedPcdGet32 (PcdFlashAreaBaseAddress),
    292     FixedPcdGet32 (PcdFlashAreaSize)
    293     );
    294   DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", FixedPcdGet32 (PcdFlashAreaBaseAddress)));
    295 
    296   //
    297   // Create a CPU hand-off information
    298   //
    299   CpuAddressWidth = 32;
    300   AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
    301   if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) {
    302     AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
    303     CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF);
    304   }
    305 
    306   BuildCpuHob(CpuAddressWidth, 16);
    307   ASSERT_EFI_ERROR (Status);
    308 
    309   return Status;
    310 
    311 }
    312 
    313 
    314 EFI_STATUS
    315 ValidateFvHeader (
    316   IN EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
    317   )
    318 {
    319   UINT16  *Ptr;
    320   UINT16  HeaderLength;
    321   UINT16  Checksum;
    322 
    323   //
    324   // Verify the header revision, header signature, length
    325   // Length of FvBlock cannot be 2**64-1
    326   // HeaderLength cannot be an odd number
    327   //
    328   if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
    329       (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
    330       (FwVolHeader->FvLength == ((UINT64) -1)) ||
    331       ((FwVolHeader->HeaderLength & 0x01) != 0)
    332       ) {
    333     return EFI_NOT_FOUND;
    334   }
    335 
    336   //
    337   // Verify the header checksum
    338   //
    339   HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);
    340   Ptr           = (UINT16 *) FwVolHeader;
    341   Checksum      = 0;
    342   while (HeaderLength > 0) {
    343     Checksum = *Ptr++;
    344     HeaderLength--;
    345   }
    346 
    347   if (Checksum != 0) {
    348     return EFI_NOT_FOUND;
    349   }
    350 
    351   return EFI_SUCCESS;
    352 }
    353