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; }
/********************************************************************************* * 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; }
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; }
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 }
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; }
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; }
/********************************************************************************* * 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; }
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; }