Example #1
0
EFI_STATUS
EFIAPI
PeimInitializeWinNtStuff (
  IN EFI_FFS_FILE_HEADER       *FfsHeader,
  IN EFI_PEI_SERVICES          **PeiServices
  )
/*++

Routine Description:

  Perform a call-back into the SEC simulator to get NT Stuff

Arguments:

  PeiServices - General purpose services available to every PEIM.
    
Returns:

  None

--*/
// TODO:    FfsHeader - add argument and description to function comment
{
  EFI_STATUS              Status;
  EFI_PEI_PPI_DESCRIPTOR  *PpiDescriptor;
  PEI_NT_THUNK_PPI        *PeiNtService;
  UINT64                  InterfaceSize;
  EFI_PHYSICAL_ADDRESS    InterfaceBase;

  Status = (**PeiServices).LocatePpi (
                            PeiServices,
                            &gPeiNtThunkPpiGuid,  // GUID
                            0,                    // INSTANCE
                            &PpiDescriptor,       // EFI_PEI_PPI_DESCRIPTOR
                            &PeiNtService         // PPI
                            );
  ASSERT_PEI_ERROR (PeiServices, Status);

  Status = PeiNtService->NtThunk (&InterfaceSize, &InterfaceBase);
  ASSERT_PEI_ERROR (PeiServices, Status);

  Status = PeiBuildHobGuidData (
            PeiServices,
            &mEfiPeiWinNtThunkProtocolGuid,       // Guid
            &InterfaceBase,                       // Buffer
            (UINTN) InterfaceSize                 // BufferSize
            );
  return Status;
}
Example #2
0
/*********************************************************************************
 * Name: FchPeiAux
 *
 * Description:
 *
 *
 * Input
 *   FfsHeader   : pointer to the firmware file system header
 *   PeiServices : pointer to the PEI service table
 *
 * Output
 *   EFI_SUCCESS : Module initialized successfully
 *   EFI_ERROR   : Initialization failed (see error for more details)
 *
 *********************************************************************************/
EFI_STATUS
EFIAPI
FchPeiAux (
  IN       EFI_FFS_FILE_HEADER  *FfsHeader,
  IN       EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                Status;
  FCH_PEI_AUX_PRIVATE       *FchPrivate;
  EFI_PEI_PPI_DESCRIPTOR    *PpiListFchPeiAux;

  Status = (*PeiServices)->AllocatePool (
                             PeiServices,
                             sizeof (FCH_PEI_AUX_PRIVATE),
                             &FchPrivate
                             );
  ASSERT_PEI_ERROR (PeiServices, Status);

  LibFchPeiAuxInitialization (PeiServices);

  FchPrivate->Signature                          = FCH_PEI_AUX_PRIVATE_DATA_SIGNATURE;
  FchPrivate->StdHdr.AltImageBasePtr             = (UINT32) PeiServices;
  FchPrivate->FchPeiAuxPpi.Revision              = AMD_FCH_PEI_AUX_PPI_REV;
  FchPrivate->FchPeiAuxPpi.FpFchPeiAuxGpio       = FchPeiAuxGpio;
  FchPrivate->FchPeiAuxPpi.FpFchPeiAuxReadGpio   = FchPeiGpioRead;
  FchPrivate->FchPeiAuxPpi.FpFchPeiAuxBootTimer  = FchPeiBootTimer;
  FchPrivate->FchPeiAuxPpi.FpFchPeiAuxDisUsbPort = FchPeiDisUsbPort;
  FchPrivate->FchPeiAuxPpi.FpFchPeiAuxOscOutClk  = FchPeiOscOutClockSel;

  // Allocate memory for the PPI descriptor
  Status = (*PeiServices)->AllocatePool (
                             PeiServices,
                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
                             &PpiListFchPeiAux
                             );
  ASSERT_PEI_ERROR (PeiServices, Status);

  PpiListFchPeiAux->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
  PpiListFchPeiAux->Guid  = &gAmdFchPeiAuxPpiGuid;
  PpiListFchPeiAux->Ppi   = &FchPrivate->FchPeiAuxPpi;

  Status = (*PeiServices)->InstallPpi (
                             PeiServices,
                             PpiListFchPeiAux
                             );
  return Status;
}
Example #3
0
EFI_STATUS
EFIAPI
PeimInitializeDimm (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *SmbusPpi
  )
{
  EFI_STATUS                    Status;

  Status = (**PeiServices).InstallPpi (
                             PeiServices,
                             &mPpiPlatformDimm
                             );
  ASSERT_PEI_ERROR (PeiServices, Status);

  return EFI_SUCCESS;
}
Example #4
0
VOID
MigrateIdtTable (
  IN EFI_PEI_SERVICES  **PeiServices
  )
/*++

Routine Description:

  Migrate IDT from temporary memory to real memory where preceded with 4 bytes for
  storing PeiService pointer.

Arguments:

  PeiServices   - The direct pointer to PeiServiceTable.
  
Returns:

  NONE.
  
--*/            
{
#ifndef EFI_NT_EMULATOR
  UINT16          IdtEntrySize;
  UINTN           OldIdtBase;
  UINTN           Size;
  VOID            *NewIdtBase;
  EFI_STATUS      Status;
  
  IdtEntrySize    = ReadIdtLimit();
  OldIdtBase      = ReadIdtBase();
  Size = sizeof(PEI_IDT_TABLE) + (IdtEntrySize + 1);  
  Status = (*PeiServices)->AllocatePool (PeiServices, Size, &NewIdtBase);
  ASSERT_PEI_ERROR (PeiServices, Status);
  (*PeiServices)->CopyMem ((VOID*)((UINTN)NewIdtBase + sizeof(PEI_IDT_TABLE)), (VOID*)OldIdtBase, (IdtEntrySize + 1));
  SetIdtBase(((UINTN)NewIdtBase + sizeof(PEI_IDT_TABLE)), IdtEntrySize);
  SetPeiServicesTablePointer(PeiServices);
#endif
}
Example #5
0
EFI_STATUS
EFIAPI 
PeiLibPciCfgModify (
  IN EFI_PEI_SERVICES         **PeiServices,
  IN PEI_PCI_CFG_PPI          *PciCfg,
  IN PEI_PCI_CFG_PPI_WIDTH    Width,
  IN UINT64                   Address,
  IN UINTN                    SetBits,
  IN UINTN                    ClearBits
  )
/*++

Routine Description:

  PCI read-modify-write operations.

  PIWG's PI specification replaces Inte's EFI Specification 1.10.
  EFI_PEI_PCI_CFG_PPI defined in Inte's EFI Specification 1.10 is replaced by
  EFI_PEI_PCI_CFG2_PPI in PI 1.0. "Modify" function  in these two PPI are not 
  compatibile with each other.
  

  For Framework code that make the following call:

      PciCfg->Modify (
                       PeiServices,
                       PciCfg,
                       Width,
                       Address,
                       SetBits,
                       ClearBits
                       );
   it will be updated to the following code which call this library API:
      PeiLibPciCfgModify (
          PeiServices,
          PciCfg,
          Width,
          Address,
          SetBits,
          ClearBits
          );

   The 

Arguments:
  
  PeiServices     An indirect pointer to the PEI Services Table
                          published by the PEI Foundation.
  PciCfg          A pointer to the this pointer of EFI_PEI_PCI_CFG_PPI. 
                          This parameter is unused as a place holder to make
                          the parameter list identical to PEI_PCI_CFG_PPI_RW.
  Width           The width of the access. Enumerated in bytes. Type
                          EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().

  Address         The physical address of the access.

  SetBits         Points to value to bitwise-OR with the read configuration value.

                          The size of the value is determined by Width.

  ClearBits       Points to the value to negate and bitwise-AND with the read configuration value.
                          The size of the value is determined by Width.


Returns:

  EFI_SUCCESS           The function completed successfully.

  EFI_DEVICE_ERROR      There was a problem with the transaction.

--*/
{
  EFI_STATUS            Status;
  EFI_PEI_PCI_CFG2_PPI  *PciCfg2;

  Status = (*PeiServices)->LocatePpi (
                             PeiServices,
                             &gPeiPciCfg2PpiGuid,
                             0,
                             NULL,
                             (VOID **) &PciCfg2
                             );
  ASSERT_PEI_ERROR ((CONST EFI_PEI_SERVICES **) PeiServices, Status);

  Status = PciCfg2->Modify (
                      (CONST EFI_PEI_SERVICES **) PeiServices,
                      PciCfg2,
                      (EFI_PEI_PCI_CFG_PPI_WIDTH) Width,
                      Address,
                      &SetBits,
                      &ClearBits
                      );

  return Status;
}
Example #6
0
EFI_STATUS
EFIAPI
ReadSpd (
  IN      EFI_PEI_SERVICES      **PeiServices,
  IN      PEI_PLATFORM_DIMM_PPI *This,
  IN      UINT8                 Dimm,
  IN      UINT8                 Offset,
  IN      UINTN                 Count,
  IN OUT  UINT8                 *Buffer
  )
{
  EFI_STATUS                Status;
  PEI_SMBUS_PPI             *Smbus;
  UINTN                     Index;
  UINTN                     Index1;
  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;
  EFI_SMBUS_DEVICE_COMMAND  Command;
  UINTN                     Length;

  Status = (**PeiServices).LocatePpi (
                             PeiServices,
                             &gPeiSmbusPpiGuid,   // GUID
                             0,                   // INSTANCE
                             NULL,                // EFI_PEI_PPI_DESCRIPTOR
                             &Smbus               // PPI
                             );
  ASSERT_PEI_ERROR (PeiServices, Status);

  switch (Dimm) {
  case 0:
    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_1 >> 1;
    break;
  case 1:
    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_2 >> 1;
    break;
  case 2:
    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_1 >> 1;
    break;
  case 3:
    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_2 >> 1;
    break;
  default:
    return EFI_INVALID_PARAMETER;
  }

  Index = Count % 4;
  if (Index != 0) {
    //
    // read the first serveral bytes to speed up following reading
    //
    for (Index1 = 0; Index1 < Index; Index1++) {
      Length = 1;
      Command = Offset + Index1;
      Status = Smbus->Execute (
                        PeiServices,
                        Smbus,
                        SlaveAddress,
                        Command,
                        EfiSmbusReadByte,
                        FALSE,
                        &Length,
                        &Buffer[Index1]
                        );
      if (EFI_ERROR(Status)) {
        return Status;
      }
    }
  }

  //
  // Now collect all the remaining bytes on 4 bytes block
  //
  for (; Index < Count; Index += 2) {
    Command = Index + Offset;
    Length = 2;
    Status = Smbus->Execute (
                      PeiServices,
                      Smbus,
                      SlaveAddress,
                      Command,
                      EfiSmbusReadWord,
                      FALSE,
                      &Length,
                      &Buffer[Index]
                      );
    if (EFI_ERROR(Status)) {
      return Status;
    }

    Index += 2;
    Command = Index + Offset;
    Length = 2;
    Status = Smbus->Execute (
                      PeiServices,
                      Smbus,
                      SlaveAddress,
                      Command,
                      EfiSmbusReadWord,
                      FALSE,
                      &Length,
                      &Buffer[Index]
                      );
    if (EFI_ERROR(Status)) {
      return Status;
    }
  }
  return EFI_SUCCESS;
}
Example #7
0
/*********************************************************************************
 * Name: FchPeiInit
 *
 * Description:
 *               > Update boot mode
 *               > Install Reset PPI
 *               > Install SMBUS PPI
 *               > Install Stall PPI
 *
 * Input
 *   FfsHeader   : pointer to the firmware file system header
 *   PeiServices : pointer to the PEI service table
 *
 * Output
 *   EFI_SUCCESS : Module initialized successfully
 *   EFI_ERROR   : Initialization failed (see error for more details)
 *
 *********************************************************************************/
EFI_STATUS
EFIAPI
FchPeiInit (
  IN       EFI_FFS_FILE_HEADER  *FfsHeader,
  IN       EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                Status;
  PEI_RESET_PPI             *PeiReset;
  EFI_PEI_STALL_PPI         *PeiStall;

  FCH_PEI_PRIVATE           *FchPrivate;
  EFI_PEI_PPI_DESCRIPTOR    *PpiListFchInit;


  Status = (*PeiServices)->AllocatePool (
                             PeiServices,
                             sizeof (FCH_PEI_PRIVATE),
                             &FchPrivate
                             );
  ASSERT_PEI_ERROR (PeiServices, Status);

  FchPrivate->Signature                    = FCH_PEI_PRIVATE_DATA_SIGNATURE;
  FchPrivate->StdHdr.AltImageBasePtr       = (UINT32) PeiServices;
  FchPrivate->FchInitPpi.Revision          = AMD_FCH_INIT_PPI_REV;
  FchPrivate->FchInitPpi.FpFchXhciRecovery = FchInitXhciOnRecovery;
  FchPrivate->FchInitPpi.FpFchEhciRecovery = FchInitEhciOnRecovery;
  FchPrivate->FchInitPpi.FpFchSataRecovery = FchInitSataOnRecovery;
  FchPrivate->FchInitPpi.FpFchGppRecovery  = FchInitGppOnRecovery;

  //
  // Update the boot mode
  //
  Status = FchUpdateBootMode (PeiServices);
  ASSERT_PEI_ERROR (PeiServices, Status);


  //
  // publish other PPIs
  //
  // Reset PPI
  // check to see if an instance is already installed
  Status = (*PeiServices)->LocatePpi (
                             PeiServices,
                             &gPeiResetPpiGuid,
                             0,
                             NULL,
                             &PeiReset
                             );

  if (EFI_NOT_FOUND == Status) {
    // No instance currently installed, install our own
    Status = (*PeiServices)->InstallPpi (
                               PeiServices,
                               &mPpiListReset
                               );

    ASSERT_PEI_ERROR (PeiServices, Status);
  }

  // Stall PPI
  // check to see if an instance is already installed
  Status = (*PeiServices)->LocatePpi (
                             PeiServices,
                             &gPeiStallPpiGuid,
                             0,
                             NULL,
                             &PeiStall
                             );

  if (EFI_NOT_FOUND == Status) {
    // There is no instance currently installed, install our own
    Status = (*PeiServices)->InstallPpi (
                               PeiServices,
                               &mPpiListStall
                               );

    ASSERT_PEI_ERROR (PeiServices, Status);
  }

  // Allocate memory for the PPI descriptor
  Status = (*PeiServices)->AllocatePool (
                             PeiServices,
                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
                             &PpiListFchInit
                             );
  ASSERT_PEI_ERROR (PeiServices, Status);

  PpiListFchInit->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
  PpiListFchInit->Guid  = &gAmdFchInitPpiGuid;
  PpiListFchInit->Ppi   = &FchPrivate->FchInitPpi;

  Status = (*PeiServices)->InstallPpi (
                             PeiServices,
                             PpiListFchInit
                             );
  return Status;
}
Example #8
0
EFI_PHYSICAL_ADDRESS
CreateIdentityMappingPageTables (
  IN EFI_PEI_SERVICES      **PeiServices,
  IN UINT32                NumberOfProcessorPhysicalAddressBits
  )
/*++

Routine Description:

  Allocates and fills in the Page Directory and Page Table Entries to
  establish a 1:1 Virtual to Physical mapping.

Arguments:

  NumberOfProcessorPhysicalAddressBits - Number of processor address bits to use.
                                         Limits the number of page table entries 
                                         to the physical address space.

Returns:
  EFI_OUT_OF_RESOURCES  There are not enough resources to allocate the Page Tables

  EFI_SUCCESS           The 1:1 Virtual to Physical identity mapping was created

--*/
{  
  EFI_PHYSICAL_ADDRESS                          PageAddress;
  UINTN                                         NumberOfPml4EntriesNeeded;
  UINTN                                         NumberOfPdpEntriesNeeded;
  UINTN                                         IndexOfPml4Entries;
  UINTN                                         IndexOfPdpEntries;
  UINTN                                         IndexOfPageDirectoryEntries;
  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMapLevel4Entry;
  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMap;
  PAGE_MAP_AND_DIRECTORY_POINTER                *PageDirectoryPointerEntry;
  PAGE_TABLE_ENTRY                              *PageDirectoryEntry;

  //
  //  Page Table structure 4 level 4K, 3 level 2MB.
  //
  //                   PageMapLevel4Entry        : bits 47-39
  //                   PageDirectoryPointerEntry : bits 38-30
  //  Page Table 2MB : PageDirectoryEntry2M      : bits 29-21
  //  Page Table 4K  : PageDirectoryEntry4K      : bits 29 - 21
  //                   PageTableEntry            : bits 20 - 12
  //
  // Strategy is to map every thing in the processor address space using 
  //  2MB pages.
  //

  //
  // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.
  // 
  PageMap = PageMapLevel4Entry = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)AllocateZeroedHobPages (PeiServices, 1);
  ASSERT_PEI_ERROR (PeiServices, PageMap != NULL);
  PageAddress = 0;

  //
  // The number of page-map Level-4 Offset entries is based on the number of 
  // physical address bits. Less than equal to 38 bits only takes one entry.
  // 512 entries represents 48 address bits. 
  //
  if (NumberOfProcessorPhysicalAddressBits <= 39) {
    NumberOfPml4EntriesNeeded = 1;
    NumberOfPdpEntriesNeeded  = 1 << (NumberOfProcessorPhysicalAddressBits - 30);
  } else {
    NumberOfPml4EntriesNeeded = 1 << (NumberOfProcessorPhysicalAddressBits - 39);
    NumberOfPdpEntriesNeeded  = 512;
  }

  for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
    //
    // Each PML4 entry points to a page of Page Directory Pointer entires.
    //  So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
    //  
    PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)AllocateZeroedHobPages (PeiServices, 1);
    ASSERT_PEI_ERROR (PeiServices, PageDirectoryPointerEntry != NULL);

    //
    // Make a PML4 Entry
    //
    PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
    PageMapLevel4Entry->Bits.ReadWrite = 1;
    PageMapLevel4Entry->Bits.Present = 1;

    for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
      //
      // Each Directory Pointer entries points to a page of Page Directory entires.
      //  So lets allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
      //       
      PageDirectoryEntry = (PAGE_TABLE_ENTRY *)(UINTN)AllocateZeroedHobPages (PeiServices, 1);
      ASSERT_PEI_ERROR (PeiServices, PageDirectoryEntry != NULL);

      //
      // Fill in a Page Directory Pointer Entries
      //
      PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;
      PageDirectoryPointerEntry->Bits.ReadWrite = 1;
      PageDirectoryPointerEntry->Bits.Present = 1;

      for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += 0x200000) {
        //
        // Fill in the Page Directory entries
        //
        PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
        PageDirectoryEntry->Bits.ReadWrite = 1;
        PageDirectoryEntry->Bits.Present = 1;
        PageDirectoryEntry->Bits.MustBe1 = 1;
      }
    }
  }

  return (EFI_PHYSICAL_ADDRESS)PageMap;
}