Ejemplo n.º 1
0
VOID FspInstallPeiMemory(EFI_PHYSICAL_ADDRESS FspReservedArea,
  UINT64 ReservedBytes)
{
  EFI_STATUS Status;

  //
  // Assign physical memory to PEI
  //
  Status = PeiServicesInstallPeiMemory (FspReservedArea, ReservedBytes);
  ASSERT_EFI_ERROR (Status);
}
Ejemplo n.º 2
0
/**
  
  Declares the presence of permanent system memory in the platform.

  Declares that the system memory buffer specified by MemoryBegin and MemoryLength
  as permanent memory that may be used for general purpose use by software.
  The amount of memory available to software may be less than MemoryLength
  if published memory has alignment restrictions.  

  @param  MemoryBegin               The start address of the memory being declared.
  @param  MemoryLength              The number of bytes of memory being declared.

  @retval  RETURN_SUCCESS           The memory buffer was published.
  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources to publish the memory buffer

**/
RETURN_STATUS
EFIAPI
PublishSystemMemory (
  IN PHYSICAL_ADDRESS       MemoryBegin,
  IN UINT64                 MemoryLength
  )
{
  EFI_STATUS        Status;

  ASSERT (MemoryLength > 0);
  ASSERT (MemoryLength <= (MAX_ADDRESS - MemoryBegin + 1));

  Status      = PeiServicesInstallPeiMemory (MemoryBegin, MemoryLength);
     
  return (RETURN_STATUS) Status;
}
Ejemplo n.º 3
0
/**
  This is the entrypoint of PEIM

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCCESS if it completed successfully.
**/
EFI_STATUS
EFIAPI
CbPeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS           Status;
  UINT64               LowMemorySize;
  UINT64               PeiMemSize = SIZE_64MB;   // 64 MB
  EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
  UINT32               RegEax;
  UINT8                PhysicalAddressBits;
  VOID*                pCbHeader;
  VOID*                pAcpiTable;
  UINT32               AcpiTableSize;
  VOID*                pSmbiosTable;
  UINT32               SmbiosTableSize;
  SYSTEM_TABLE_INFO*   pSystemTableInfo;
  FRAME_BUFFER_INFO    FbInfo;
  FRAME_BUFFER_INFO*   pFbInfo;
  ACPI_BOARD_INFO*     pAcpiBoardInfo;
  UINTN                PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;
  UINTN                PmEvtBase;
  UINTN                PmGpeEnBase;
  CB_MEM_INFO          CbMemInfo;

  //
  // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED  
  // is intentionally omitted to prevent erasing of the coreboot header  
  // record before it is processed by CbParseMemoryInfo.
  //
  BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    // Lower 640KB, except for first 4KB where the lower coreboot pointer ("LBIO") resides
    (EFI_PHYSICAL_ADDRESS)(0 + 0x1000),
    (UINT64)(0xA0000 - 0x1000)
    );


  BuildResourceDescriptorHob (
    EFI_RESOURCE_MEMORY_RESERVED,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_TESTED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0xA0000),
    (UINT64)(0x60000)
    );

  ZeroMem (&CbMemInfo, sizeof(CbMemInfo));
  Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  LowMemorySize = CbMemInfo.UsableLowMemTop;
  DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize));
  DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop));

  //
  // Should be 64k aligned
  //
  PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));

  DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));
  DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));

  Status = PeiServicesInstallPeiMemory (
         PeiMemBase,
         PeiMemSize
         );
  ASSERT_EFI_ERROR (Status);

  //
  // Set cache on the physical memory
  //
  MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
  MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);

  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Create Fv hob
  //
  CbPeiReportRemainedFvs ();

  BuildMemoryAllocationHob (
    PcdGet32 (PcdPayloadFdMemBase),
    PcdGet32 (PcdPayloadFdMemSize),
    EfiBootServicesData
    );

  //
  // Build CPU memory space and IO space hob
  //
  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
  if (RegEax >= 0x80000008) {
    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
    PhysicalAddressBits = (UINT8) RegEax;
  } else {
    PhysicalAddressBits  = 36;
  }
  //
  // Create a CPU hand-off information
  //
  BuildCpuHob (PhysicalAddressBits, 16);

  //
  // Report Local APIC range
  //
  BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);

  //
  // Boot mode
  //
  Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesInstallPpi (mPpiBootMode);
  ASSERT_EFI_ERROR (Status);

   //
  // Set pcd to save the upper coreboot header in case the dxecore will
  // erase 0~4k memory
  //
  pCbHeader = NULL;
  if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
    && ((UINTN)pCbHeader > BASE_4KB)) {
    DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));
    Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Create guid hob for system tables like acpi table and smbios table
  //
  pAcpiTable = NULL;
  AcpiTableSize = 0;
  pSmbiosTable = NULL;
  SmbiosTableSize = 0;
  Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
  if (EFI_ERROR (Status)) {
    // ACPI table is oblidgible
    DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
    ASSERT (FALSE);
  }
  CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);

  pSystemTableInfo = NULL;
  pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
  ASSERT (pSystemTableInfo != NULL);
  pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
  pSystemTableInfo->AcpiTableSize = AcpiTableSize;
  pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
  pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
  DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
  DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
  DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));

  //
  // Create guid hob for acpi board information
  //
  Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);
  ASSERT_EFI_ERROR (Status);
  pAcpiBoardInfo = NULL;
  pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
  ASSERT (pAcpiBoardInfo != NULL);
  pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
  pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
  pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
  pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
  pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;
  pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;
  DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));

  //
  // Create guid hob for frame buffer information
  //
  ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
  Status = CbParseFbInfo (&FbInfo);
  if (!EFI_ERROR (Status)) {
    pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
    ASSERT (pSystemTableInfo != NULL);
    CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
    DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
  }

  //
  // Parse platform specific information from coreboot. 
  //
  Status = CbParsePlatformInfo ();
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status));
    return Status;
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 4
0
/**
  BIOS process FspBobList for Memory Resource Descriptor.

  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.

  @return If platform process the FSP hob list successfully.
**/
EFI_STATUS
EFIAPI
FspHobProcessForMemoryResource (
  IN VOID                 *FspHobList
  )
{
  EFI_PEI_HOB_POINTERS Hob;
  UINT64               LowMemorySize;
  UINT64               FspMemorySize;
  EFI_PHYSICAL_ADDRESS FspMemoryBase;
  UINT64               PeiMemSize;
  EFI_PHYSICAL_ADDRESS PeiMemBase;
  UINT64               S3PeiMemSize;
  EFI_PHYSICAL_ADDRESS S3PeiMemBase;
  BOOLEAN              FoundFspMemHob;
  EFI_STATUS           Status;
  EFI_BOOT_MODE        BootMode;
  PEI_CAPSULE_PPI      *Capsule;
  VOID                 *CapsuleBuffer;
  UINTN                CapsuleBufferLength;
  UINT64               RequiredMemSize;
  EFI_PEI_SERVICES     **PeiServices;

  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();

  PeiServicesGetBootMode (&BootMode);

  PeiMemBase = 0;
  LowMemorySize = 0;
  FspMemorySize = 0;
  FspMemoryBase = 0;
  FoundFspMemHob = FALSE;

  //
  // Parse the hob list from fsp
  // Report all the resource hob except the memory between 1M and 4G
  //
  Hob.Raw = (UINT8 *)(UINTN)FspHobList;
  DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));

  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
    DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
        (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {
      DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
      DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
      DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
      DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
    }

    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)  // Found the low memory length below 4G
        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {
        LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
      Hob.Raw = GET_NEXT_HOB (Hob);
      continue;
    }

    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)  // Found the low memory length below 4G
        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
        && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {
      FoundFspMemHob = TRUE;
      FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
      FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
      DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
    }

    //
    // Report the resource hob
    //
    BuildResourceDescriptorHob (
      Hob.ResourceDescriptor->ResourceType,
      Hob.ResourceDescriptor->ResourceAttribute,
      Hob.ResourceDescriptor->PhysicalStart,
      Hob.ResourceDescriptor->ResourceLength
      );

    Hob.Raw = GET_NEXT_HOB (Hob);
  }

  if (!FoundFspMemHob) {
    DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
    //ASSERT(FALSE);
  }

  DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
  DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
  DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));

  if (BootMode == BOOT_ON_S3_RESUME) {
    BuildResourceDescriptorHob (
      EFI_RESOURCE_SYSTEM_MEMORY,
      (
         EFI_RESOURCE_ATTRIBUTE_PRESENT |
         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
         // EFI_RESOURCE_ATTRIBUTE_TESTED |
         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
      ),
      BASE_1MB,
      LowMemorySize
      );

    S3PeiMemBase = 0;
    S3PeiMemSize = 0;
    Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize);
    ASSERT_EFI_ERROR (Status);
    DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));

    //
    // Make sure Stack and PeiMemory are not overlap
    //

    Status = PeiServicesInstallPeiMemory (
               S3PeiMemBase,
               S3PeiMemSize
               );
    ASSERT_EFI_ERROR (Status);
  } else {
    PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
    DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));

    //
    // Capsule mode
    //
    Capsule = NULL;
    CapsuleBuffer = NULL;
    CapsuleBufferLength = 0;
    if (BootMode == BOOT_ON_FLASH_UPDATE) {
      Status = PeiServicesLocatePpi (
                 &gPeiCapsulePpiGuid,
                 0,
                 NULL,
                 (VOID **) &Capsule
                 );
      ASSERT_EFI_ERROR (Status);

      if (Status == EFI_SUCCESS) {
        //
        // Make sure Stack and CapsuleBuffer are not overlap
        //
        CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
        CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
        //
        // Call the Capsule PPI Coalesce function to coalesce the capsule data.
        //
        Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
      }
    }

    RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
    DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));

    //
    // Report the main memory
    //
    BuildResourceDescriptorHob (
      EFI_RESOURCE_SYSTEM_MEMORY,
      (
         EFI_RESOURCE_ATTRIBUTE_PRESENT |
         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
         EFI_RESOURCE_ATTRIBUTE_TESTED |
         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
      ),
      BASE_1MB,
      LowMemorySize
      );

    //
    // Make sure Stack and CapsuleBuffer are not overlap
    //

    //
    // Install efi memory
    //
    PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
    Status = PeiServicesInstallPeiMemory (
               PeiMemBase,
               PeiMemSize - RequiredMemSize
               );
    ASSERT_EFI_ERROR (Status);

    if (Capsule != NULL) {
      Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
    }
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 5
0
/*++

Routine Description:

  

Arguments:

  FileHandle  - Handle of the file being invoked.
  PeiServices - Describes the list of possible PEI Services.
    
Returns:

  Status -  EFI_SUCCESS if the boot mode could be set

--*/
EFI_STATUS
EFIAPI
InitializeMemory (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                            Status;
  UINTN                                 SystemMemoryBase;
  UINTN                                 SystemMemoryTop;
  UINTN                                 FdBase;
  UINTN                                 FdTop;
  UINTN                                 UefiMemoryBase;

  DEBUG ((EFI_D_ERROR, "Memory Init PEIM Loaded\n"));

  // Ensure PcdSystemMemorySize has been set
  ASSERT (FixedPcdGet32 (PcdSystemMemorySize) != 0);

  SystemMemoryBase = (UINTN)FixedPcdGet32 (PcdSystemMemoryBase);
  SystemMemoryTop = SystemMemoryBase + (UINTN)FixedPcdGet32 (PcdSystemMemorySize);
  FdBase = (UINTN)PcdGet32 (PcdFdBaseAddress);
  FdTop = FdBase + (UINTN)PcdGet32 (PcdFdSize);

  //
  // Initialize the System Memory (DRAM)
  //
  if (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)) {
    // In case the DRAM has not been initialized by the secure firmware
    ArmPlatformInitializeSystemMemory ();
  }

  //
  // Declare the UEFI memory to PEI
  //

  // In case the firmware has been shadowed in the System Memory
  if ((FdBase >= SystemMemoryBase) && (FdTop <= SystemMemoryTop)) {
    // Check if there is enough space between the top of the system memory and the top of the
    // firmware to place the UEFI memory (for PEI & DXE phases)
    if (SystemMemoryTop - FdTop >= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
      UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
    } else {
      // Check there is enough space for the UEFI memory
      ASSERT (SystemMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) <= FdBase);

      UefiMemoryBase = FdBase - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
    }
  } else {
    // Check the Firmware does not overlapped with the system memory
    ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop));
    ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop));

    UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
  }

  Status = PeiServicesInstallPeiMemory (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
  ASSERT_EFI_ERROR (Status);

  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
  ASSERT_EFI_ERROR (Status);

  return Status;
}
Ejemplo n.º 6
0
EFI_STATUS
EFIAPI
PeimInitializeWinNtAutoScan (
  IN       EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES          **PeiServices
  )
/*++

Routine Description:
  Perform a call-back into the SEC simulator to get a memory value

Arguments:
  FfsHeader   - General purpose data available to every PEIM
  PeiServices - General purpose services available to every PEIM.
    
Returns:
  None

--*/
{
  EFI_STATUS                            Status;
  EFI_PEI_PPI_DESCRIPTOR                *PpiDescriptor;
  PEI_NT_AUTOSCAN_PPI                   *PeiNtService;
  UINT64                                MemorySize;
  EFI_PHYSICAL_ADDRESS                  MemoryBase;
  UINTN                                 Index;
  EFI_RESOURCE_ATTRIBUTE_TYPE           Attributes;
  UINT64                                PeiMemorySize;
  EFI_PHYSICAL_ADDRESS                  PeiMemoryBase;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI       *Variable;
  UINTN                                 DataSize;
  EFI_MEMORY_TYPE_INFORMATION           MemoryData [EfiMaxMemoryType + 1];
  UINT64                                SmramMemorySize;
  EFI_PHYSICAL_ADDRESS                  SmramMemoryBase;
  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK        *SmramHobDescriptorBlock;
  PEI_CAPSULE_PPI                       *Capsule;
  VOID                                  *CapsuleBuffer;
  UINTN                                 CapsuleBufferLength;
  EFI_BOOT_MODE                         BootMode;
  EFI_WIN_NT_MEMORY_LAYOUT              *MemoryLayout;
  UINTN                                 MaxSystemMemoryCount;

  DEBUG ((EFI_D_ERROR, "NT 32 Autoscan PEIM Loaded\n"));

  //
  // Get the PEI NT Autoscan PPI
  //
  Status = PeiServicesLocatePpi (
             &gPeiNtAutoScanPpiGuid, // GUID
             0,                      // INSTANCE
             &PpiDescriptor,         // EFI_PEI_PPI_DESCRIPTOR
             (VOID**)&PeiNtService           // PPI
             );
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  DEBUG ((EFI_D_ERROR, "BootMode - %x\n", BootMode));

  if (FeaturePcdGet (PcdWinNtCapsuleEnable)) {
    MaxSystemMemoryCount = GetMaxSystemMemoryCount();
    MemoryLayout = BuildGuidHob (
                     &gEfiWinNtMemoryLayoutGuid,
                     sizeof (EFI_WIN_NT_MEMORY_LAYOUT) + sizeof (EFI_WIN_NT_MEMORY_DESCRIPTOR) * (MaxSystemMemoryCount - 1)
                     );
    ASSERT (MemoryLayout != NULL);
    MemoryLayout->NumberOfRegions = 0;
  
    Capsule = NULL;
    CapsuleBuffer = NULL;
    CapsuleBufferLength = 0;
    if (BootMode == BOOT_ON_FLASH_UPDATE) {
      Status = PeiServicesLocatePpi (&gPeiCapsulePpiGuid, 0, NULL, (VOID**) &Capsule);
      ASSERT_EFI_ERROR (Status);
    }
  }

  Index = 0;
  SmramMemorySize = 0;
  SmramMemoryBase = 0;
  do {
    Status = PeiNtService->NtAutoScan (Index, &MemoryBase, &MemorySize);
    DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Status - %r\n", Index, Status));
    if (!EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Base - 0x%lx\n", Index, MemoryBase));
      DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Size - 0x%lx\n", Index, MemorySize));

      if (FeaturePcdGet (PcdWinNtCapsuleEnable)) {
        if (MemoryLayout->NumberOfRegions < MaxSystemMemoryCount) {
          MemoryLayout->Descriptor[MemoryLayout->NumberOfRegions].Base = MemoryBase;
          MemoryLayout->Descriptor[MemoryLayout->NumberOfRegions].Size = MemorySize;
          MemoryLayout->NumberOfRegions ++;
        }
      }

      Attributes =
        (
          EFI_RESOURCE_ATTRIBUTE_PRESENT |
          EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
          EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
          EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
          EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
          EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
        );

      if (Index == 0) {
        //
        // Register the memory with the PEI Core
        //

        if (FeaturePcdGet(PcdWinNtSmmEnable)) {
          //
          // SMRAM
          //
          SmramMemorySize = PcdGet64(PcdWinNtSmramSize);
          SmramMemoryBase = MemoryBase + MemorySize - SmramMemorySize;
          DEBUG ((EFI_D_ERROR, "SmramMemoryBase - 0x%lx\n", SmramMemoryBase));
          DEBUG ((EFI_D_ERROR, "SmramMemorySize - 0x%lx\n", SmramMemorySize));

          MemorySize      = MemorySize - SmramMemorySize;
        }

        PeiMemoryBase = MemoryBase;
        PeiMemorySize = MemorySize;

        if (FeaturePcdGet(PcdWinNtCapsuleEnable)) {
          //
          // Capsule
          //
          if (Capsule != NULL) {
            CapsuleBufferLength = ((UINTN) PeiMemorySize / 2);
            PeiMemorySize       = CapsuleBufferLength;
            CapsuleBuffer = (VOID*) (UINTN) (PeiMemoryBase + CapsuleBufferLength);
          }
        }

        Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED;
      }
      
      BuildResourceDescriptorHob (
        EFI_RESOURCE_SYSTEM_MEMORY,
        Attributes,
        MemoryBase,
        MemorySize
        );
      DEBUG ((EFI_D_ERROR, "ResourceHob - 0x%lx - 0x%lx\n", MemoryBase, MemorySize));
    }
    Index++;
  } while (!EFI_ERROR (Status));

  if (FeaturePcdGet(PcdWinNtCapsuleEnable)) {
    if (Capsule != NULL) {
      //
      // Call the Capsule PPI Coalesce function to coalesce the capsule data.
      //
      Status = Capsule->Coalesce (
                          (EFI_PEI_SERVICES**) PeiServices,
                          &CapsuleBuffer,
                          &CapsuleBufferLength
                          );
      DEBUG ((EFI_D_ERROR, "CoalesceStatus - %r\n", Status));
      DEBUG ((EFI_D_ERROR, "CapsuleBuffer - %x\n", CapsuleBuffer));
      DEBUG ((EFI_D_ERROR, "CapsuleBufferLength - %x\n", CapsuleBufferLength));
      
      //
      // If it failed, then NULL out our capsule PPI pointer so that the capsule
      // HOB does not get created below.
      //
      if (Status != EFI_SUCCESS) {
        Capsule = NULL;
      }
    }
  }

  Status = PeiServicesInstallPeiMemory (PeiMemoryBase, PeiMemorySize);
  ASSERT_EFI_ERROR (Status);

  if (FeaturePcdGet(PcdWinNtCapsuleEnable)) {
    //
    // If we found the capsule PPI (and we didn't have errors), then
    // call the capsule PEIM to allocate memory for the capsule.
    //
    if (Capsule != NULL) {
      Status = Capsule->CreateState((EFI_PEI_SERVICES **)PeiServices, CapsuleBuffer, CapsuleBufferLength);
    }
  }

  //
  // Build the CPU hob with 52-bit addressing and 16-bits of IO space.
  //
  BuildCpuHob (52, 16);

  //
  // Build GUIDed Hob that contains the Memory Type Information array
  //
  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
             (VOID **)&Variable
             );
  ASSERT_EFI_ERROR (Status);

  DataSize = sizeof (MemoryData);
  Status = Variable->GetVariable (
                       Variable,
                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
                       &gEfiMemoryTypeInformationGuid,
                       NULL,
                       &DataSize,
                       &MemoryData
                       );
  if (EFI_ERROR (Status) || !ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {
    //
    // Create Memory Type Information HOB
    //
    BuildGuidDataHob (
      &gEfiMemoryTypeInformationGuid,
      mDefaultMemoryTypeInformation,
      sizeof(mDefaultMemoryTypeInformation)
      );
  } else {
    //
    // Create Memory Type Information HOB
    //
    BuildGuidDataHob (
      &gEfiMemoryTypeInformationGuid,
      MemoryData,
      DataSize
      );
  }

  if (FeaturePcdGet(PcdWinNtSmmEnable)) {
    //
    // BuildSmramHob
    //
    if ((SmramMemoryBase != 0) && (SmramMemorySize != 0)) {
      SmramHobDescriptorBlock = BuildGuidHob (
                                  &gEfiSmmPeiSmramMemoryReserveGuid,
                                  sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + sizeof (EFI_SMRAM_DESCRIPTOR)
                                  );
      ASSERT (SmramHobDescriptorBlock != NULL);
      SmramHobDescriptorBlock->NumberOfSmmReservedRegions = 1;

      SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = SmramMemoryBase;
      SmramHobDescriptorBlock->Descriptor[0].CpuStart      = SmramMemoryBase;
      SmramHobDescriptorBlock->Descriptor[0].PhysicalSize  = SmramMemorySize;
      SmramHobDescriptorBlock->Descriptor[0].RegionState   = EFI_SMRAM_CLOSED;
    }
  }

  return Status;
}
Ejemplo n.º 7
0
EFI_STATUS
EFIAPI
PeimInitializeUnixAutoScan (
  IN       EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES          **PeiServices
  )
/*++

Routine Description:
  Perform a call-back into the SEC simulator to get a memory value

Arguments:
  FfsHeader   - General purpose data available to every PEIM
  PeiServices - General purpose services available to every PEIM.
    
Returns:
  None

--*/
{
  EFI_STATUS                  Status;
  EFI_PEI_PPI_DESCRIPTOR      *PpiDescriptor;
  PEI_UNIX_AUTOSCAN_PPI      *PeiUnixService;
  UINT64                      MemorySize;
  EFI_PHYSICAL_ADDRESS        MemoryBase;
  UINTN                       Index;
  EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;


  DEBUG ((EFI_D_ERROR, "Unix Autoscan PEIM Loaded\n"));

  //
  // Get the PEI UNIX Autoscan PPI
  //
  Status = PeiServicesLocatePpi (
             &gPeiUnixAutoScanPpiGuid, // GUID
             0,                      // INSTANCE
             &PpiDescriptor,         // EFI_PEI_PPI_DESCRIPTOR
             (VOID **)&PeiUnixService           // PPI
             );
  ASSERT_EFI_ERROR (Status);

  Index = 0;
  do {
    Status = PeiUnixService->UnixAutoScan (Index, &MemoryBase, &MemorySize);
    if (!EFI_ERROR (Status)) {
      Attributes =
        (
          EFI_RESOURCE_ATTRIBUTE_PRESENT |
          EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
          EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
          EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
          EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
          EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
        );

      if (Index == 0) {
        //
        // Register the memory with the PEI Core
        //
        Status = PeiServicesInstallPeiMemory (MemoryBase, MemorySize);
        ASSERT_EFI_ERROR (Status);

        Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED;
      }
      
      BuildResourceDescriptorHob (
        EFI_RESOURCE_SYSTEM_MEMORY,
        Attributes,
        MemoryBase,
        MemorySize
        );
    }
    Index++;
  } while (!EFI_ERROR (Status));

  //
  // Build the CPU hob with 36-bit addressing and 16-bits of IO space.
  //
  BuildCpuHob (36, 16);
  
  return Status;
}
Ejemplo n.º 8
0
/**
  This is the entrypoint of PEIM

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCCESS if it completed successfully.
**/
EFI_STATUS
EFIAPI
CbPeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS Status;
  UINT64 LowMemorySize, HighMemorySize;
  UINT64 PeiMemSize = SIZE_64MB;   // 64 MB
  EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
  UINT32               RegEax;
  UINT8                PhysicalAddressBits;
  VOID*                pCbHeader;
  VOID*                pAcpiTable;
  UINT32               AcpiTableSize;
  VOID*                pSmbiosTable;
  UINT32               SmbiosTableSize;
  SYSTEM_TABLE_INFO*   pSystemTableInfo;
  FRAME_BUFFER_INFO    FbInfo;
  FRAME_BUFFER_INFO*   pFbInfo;
  ACPI_BOARD_INFO*     pAcpiBoardInfo;
  UINTN                PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;

  LowMemorySize = 0;
  HighMemorySize = 0;

  Status = CbParseMemoryInfo (&LowMemorySize, &HighMemorySize);
  if (EFI_ERROR(Status))
    return Status;

  DEBUG((EFI_D_ERROR, "LowMemorySize: 0x%lx.\n", LowMemorySize));
  DEBUG((EFI_D_ERROR, "HighMemorySize: 0x%lx.\n", HighMemorySize));

  ASSERT (LowMemorySize > 0);

  BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_TESTED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0),
    (UINT64)(0xA0000)
    );


  BuildResourceDescriptorHob (
    EFI_RESOURCE_MEMORY_RESERVED,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_TESTED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0xA0000),
    (UINT64)(0x60000)
    );

   BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
       EFI_RESOURCE_ATTRIBUTE_PRESENT |
       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
       EFI_RESOURCE_ATTRIBUTE_TESTED |
       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0x100000),
    (UINT64) (LowMemorySize - 0x100000)
    );

  if (HighMemorySize > 0) {
    BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
       EFI_RESOURCE_ATTRIBUTE_PRESENT |
       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0x100000000ULL),
    HighMemorySize
    );
  }

  //
  // Should be 64k aligned
  //
  PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));

  DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));
  DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));

  Status = PeiServicesInstallPeiMemory (
         PeiMemBase,
         PeiMemSize
         );
  ASSERT_EFI_ERROR (Status);

  //
  // Set cache on the physical memory
  //
  MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
  MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);

  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Create Fv hob
  //
  CbPeiReportRemainedFvs ();

  BuildMemoryAllocationHob (
    PcdGet32 (PcdPayloadFdMemBase),
    PcdGet32 (PcdPayloadFdMemSize),
    EfiBootServicesData
    );

  //
  // Build CPU memory space and IO space hob
  //
  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
  if (RegEax >= 0x80000008) {
    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
    PhysicalAddressBits = (UINT8) RegEax;
  } else {
    PhysicalAddressBits  = 36;
  }
  //
  // Create a CPU hand-off information
  //
  BuildCpuHob (PhysicalAddressBits, 16);

  //
  // Report Local APIC range
  //
  BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);

  //
  // Boot mode
  //
  Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesInstallPpi (mPpiBootMode);
  ASSERT_EFI_ERROR (Status);

   //
  // Set pcd to save the upper coreboot header in case the dxecore will
  // erase 0~4k memory
  //
  pCbHeader = NULL;
  if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
    && ((UINTN)pCbHeader > BASE_4KB)) {
    DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));
    PcdSet32 (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
  }

  //
  // Create guid hob for system tables like acpi table and smbios table
  //
  pAcpiTable = NULL;
  AcpiTableSize = 0;
  pSmbiosTable = NULL;
  SmbiosTableSize = 0;
  Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
  if (EFI_ERROR (Status)) {
    // ACPI table is oblidgible
    DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
    ASSERT (FALSE);
  }
  CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);

  pSystemTableInfo = NULL;
  pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
  ASSERT (pSystemTableInfo != NULL);
  pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
  pSystemTableInfo->AcpiTableSize = AcpiTableSize;
  pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
  pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
  DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
  DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
  DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));

  //
  // Create guid hob for acpi board information
  //
  Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue);
  ASSERT_EFI_ERROR (Status);
  pAcpiBoardInfo = NULL;
  pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
  ASSERT (pAcpiBoardInfo != NULL);
  pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
  pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
  pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
  pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
  DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));

  //
  // Create guid hob for frame buffer information
  //
  ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
  Status = CbParseFbInfo (&FbInfo);
  if (!EFI_ERROR (Status)) {
    pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
    ASSERT (pSystemTableInfo != NULL);
    CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
    DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
  }

  //
  // Mask off all legacy 8259 interrupt sources
  //
  IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
  IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE,  0xFF);

  return EFI_SUCCESS;
}