/** Initialize the state information for the CPU Architectural Protocol @param ImageHandle of the loaded driver @param SystemTable Pointer to the System Table @retval EFI_SUCCESS Protocol registered @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure @retval EFI_DEVICE_ERROR Hardware problems **/ EFI_STATUS GicV3DxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Index; UINT32 RegOffset; UINTN RegShift; UINT64 CpuTarget; UINT64 MpId; // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); mGicDistributorBase = PcdGet32 (PcdGicDistributorBase); mGicRedistributorsBase = PcdGet32 (PcdGicRedistributorsBase); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); // // We will be driving this GIC in native v3 mode, i.e., with Affinity // Routing enabled. So ensure that the ARE bit is set. // if (!FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { MmioOr32 (mGicDistributorBase + ARM_GIC_ICDDCR, ARM_GIC_ICDDCR_ARE); } for (Index = 0; Index < mGicNumInterrupts; Index++) { GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index); // Set Priority RegOffset = Index / 4; RegShift = (Index % 4) * 8; MmioAndThenOr32 ( mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset), ~(0xff << RegShift), ARM_GIC_DEFAULT_PRIORITY << RegShift ); } // // Targets the interrupts to the Primary Cpu // if (FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { // Only Primary CPU will run this code. We can identify our GIC CPU ID by reading // the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each // connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31. // More Info in the GIC Specification about "Interrupt Processor Targets Registers" // // Read the first Interrupt Processor Targets Register (that corresponds to the 4 // first SGIs) CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR); // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value // is 0 when we run on a uniprocessor platform. if (CpuTarget != 0) { // The 8 first Interrupt Processor Targets Registers are read-only for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) { MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget); } } } else { MpId = ArmReadMpidr (); CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3); if ((MmioRead32 (mGicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_DS) != 0) { // // If the Disable Security (DS) control bit is set, we are dealing with a // GIC that has only one security state. In this case, let's assume we are // executing in non-secure state (which is appropriate for DXE modules) // and that no other firmware has performed any configuration on the GIC. // This means we need to reconfigure all interrupts to non-secure Group 1 // first. // MmioWrite32 (mGicRedistributorsBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDISR, 0xffffffff); for (Index = 32; Index < mGicNumInterrupts; Index += 32) { MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDISR + Index / 8, 0xffffffff); } } // Route the SPIs to the primary CPU. SPIs start at the INTID 32 for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) { MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM); } } // Set binary point reg to 0x7 (no preemption) ArmGicV3SetBinaryPointer (0x7); // Set priority mask reg to 0xff to allow all priorities through ArmGicV3SetPriorityMask (0xff); // Enable gic cpu interface ArmGicV3EnableInterruptInterface (); // Enable gic distributor ArmGicEnableDistributor (mGicDistributorBase); Status = InstallAndRegisterInterruptService ( &gHardwareInterruptV3Protocol, GicV3IrqInterruptHandler, GicV3ExitBootServicesEvent); return Status; }
/** Returns if the capsule can be supported via UpdateCapsule(). @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules being passed into update capsule. @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in CaspuleHeaderArray. @param MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can support as an argument to UpdateCapsule() via CapsuleHeaderArray and ScatterGatherList. @param ResetType Returns the type of reset required for the capsule update. @retval EFI_SUCCESS Valid answer returned. @retval EFI_UNSUPPORTED The capsule image is not supported on this platform, and MaximumCapsuleSize and ResetType are undefined. @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL, or ResetTyep is NULL, Or CapsuleCount is Zero, or CapsuleImage is not valid. **/ EFI_STATUS EFIAPI QueryCapsuleCapabilities ( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, OUT UINT64 *MaxiumCapsuleSize, OUT EFI_RESET_TYPE *ResetType ) { EFI_STATUS Status; UINTN ArrayNumber; EFI_CAPSULE_HEADER *CapsuleHeader; BOOLEAN NeedReset; // // Capsule Count can't be less than one. // if (CapsuleCount < 1) { return EFI_INVALID_PARAMETER; } // // Check whether input parameter is valid // if ((MaxiumCapsuleSize == NULL) ||(ResetType == NULL)) { return EFI_INVALID_PARAMETER; } CapsuleHeader = NULL; NeedReset = FALSE; for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { CapsuleHeader = CapsuleHeaderArray[ArrayNumber]; // // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well. // if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) { return EFI_INVALID_PARAMETER; } // // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must have // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well. // if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) { return EFI_INVALID_PARAMETER; } // // Check FMP capsule flag // if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid) && (CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 ) { return EFI_INVALID_PARAMETER; } // // Check Capsule image without populate flag is supported by firmware // if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) { Status = SupportCapsuleImage (CapsuleHeader); if (EFI_ERROR(Status)) { return Status; } } } // // Find out whether there is any capsule defined to persist across system reset. // for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) { CapsuleHeader = CapsuleHeaderArray[ArrayNumber]; if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) { NeedReset = TRUE; break; } } if (NeedReset) { // //Check if the platform supports update capsule across a system reset // if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) { return EFI_UNSUPPORTED; } *ResetType = EfiResetWarm; *MaxiumCapsuleSize = (UINT64) mMaxSizePopulateCapsule; } else { // // For non-reset capsule image. // *ResetType = EfiResetCold; *MaxiumCapsuleSize = (UINT64) mMaxSizeNonPopulateCapsule; } return EFI_SUCCESS; }
/** Allocates and fills in the Page Directory and Page Table Entries to establish a 1:1 Virtual to Physical mapping. If BootScriptExector driver will run in 64-bit mode, this function will establish the 1:1 virtual to physical mapping page table. If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. @return the 1:1 Virtual to Physical identity mapping page table base address. **/ EFI_PHYSICAL_ADDRESS S3CreateIdentityMappingPageTables ( VOID ) { if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { UINT32 RegEax; UINT32 RegEdx; UINT8 PhysicalAddressBits; UINT32 NumberOfPml4EntriesNeeded; UINT32 NumberOfPdpEntriesNeeded; EFI_PHYSICAL_ADDRESS S3NvsPageTableAddress; UINTN TotalPageTableSize; VOID *Hob; BOOLEAN Page1GSupport; Page1GSupport = FALSE; if (PcdGetBool(PcdUse1GPageTable)) { AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax >= 0x80000001) { AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); if ((RegEdx & BIT26) != 0) { Page1GSupport = TRUE; } } } // // Get physical address bits supported. // Hob = GetFirstHob (EFI_HOB_TYPE_CPU); if (Hob != NULL) { PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace; } else { AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax >= 0x80000008) { AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); PhysicalAddressBits = (UINT8) RegEax; } else { PhysicalAddressBits = 36; } } // // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses. // ASSERT (PhysicalAddressBits <= 52); if (PhysicalAddressBits > 48) { PhysicalAddressBits = 48; } // // Calculate the table entries needed. // if (PhysicalAddressBits <= 39 ) { NumberOfPml4EntriesNeeded = 1; NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30)); } else { NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39)); NumberOfPdpEntriesNeeded = 512; } // // We need calculate whole page size then allocate once, because S3 restore page table does not know each page in Nvs. // if (!Page1GSupport) { TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded + NumberOfPml4EntriesNeeded * NumberOfPdpEntriesNeeded); } else { TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded); } DEBUG ((EFI_D_ERROR, "TotalPageTableSize - %x pages\n", TotalPageTableSize)); // // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. // S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize)); ASSERT (S3NvsPageTableAddress != 0); return S3NvsPageTableAddress; } else { // // If DXE is running 32-bit mode, no need to establish page table. // return (EFI_PHYSICAL_ADDRESS) 0; } }
/** Function show progress bar to wait for user input. @param TimeoutDefault The fault time out value before the system continue to boot. @retval EFI_SUCCESS User pressed some key except "Enter" @retval EFI_TIME_OUT Timeout expired or user press "Enter" **/ EFI_STATUS ShowProgress ( IN UINT16 TimeoutDefault ) { CHAR16 *TmpStr; UINT16 TimeoutRemain; EFI_STATUS Status; EFI_INPUT_KEY Key; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; if (TimeoutDefault != 0) { DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n")); SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION)); if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { // // Clear the progress status bar first // if (TmpStr != NULL) { PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0); } } TimeoutRemain = TimeoutDefault; while (TimeoutRemain != 0) { DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain)); Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND); if (Status != EFI_TIMEOUT) { break; } TimeoutRemain--; if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { // // Show progress // if (TmpStr != NULL) { PlatformBdsShowProgress ( Foreground, Background, TmpStr, Color, ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault), 0 ); } } } if (TmpStr != NULL) { gBS->FreePool (TmpStr); } // // Timeout expired // if (TimeoutRemain == 0) { return EFI_TIMEOUT; } } // // User pressed some key // if (!PcdGetBool (PcdConInConnectOnDemand)) { Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); if (EFI_ERROR (Status)) { return Status; } if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { // // User pressed enter, equivalent to select "continue" // return EFI_TIMEOUT; } } return EFI_SUCCESS; }
/** Set value for an PCD entry @param TokenNumber Pcd token number autogenerated by build tools. @param Data Value want to be set for PCD entry @param Size Size of value. @param PtrType If TRUE, the type of PCD entry's value is Pointer. If False, the type of PCD entry's value is not Pointer. @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set. @retval EFI_INVALID_PARAMETER If Size can not be set to size table. @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database. @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in range of UINT8, UINT16, UINT32, UINT64 @retval EFI_NOT_FOUND Can not find the PCD type according to token number. **/ EFI_STATUS SetWorker ( IN UINTN TokenNumber, IN VOID *Data, IN OUT UINTN *Size, IN BOOLEAN PtrType ) { UINT32 LocalTokenNumber; UINTN PeiNexTokenNumber; PEI_PCD_DATABASE *PeiPcdDb; STRING_HEAD StringTableIdx; UINTN Offset; VOID *InternalData; UINTN MaxSize; UINT32 LocalTokenCount; if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) { return EFI_UNSUPPORTED; } // // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. // We have to decrement TokenNumber by 1 to make it usable // as the array index. // TokenNumber--; PeiPcdDb = GetPcdDatabase (); LocalTokenCount = PeiPcdDb->LocalTokenCount; // EBC compiler is very choosy. It may report warning about comparison // between UINTN and 0 . So we add 1 in each size of the // comparison. ASSERT (TokenNumber + 1 < (LocalTokenCount + 1)); if (PtrType) { // // Get MaxSize first, then check new size with max buffer size. // GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); if (*Size > MaxSize) { *Size = MaxSize; return EFI_INVALID_PARAMETER; } } else { if (*Size != PeiPcdGetSize (TokenNumber + 1)) { return EFI_INVALID_PARAMETER; } } // // We only invoke the callback function for Dynamic Type PCD Entry. // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX // type PCD entry in ExSetWorker. // PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount; if (TokenNumber + 1 < PeiNexTokenNumber + 1) { InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size); } LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1); Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset); switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: case PCD_TYPE_HII: case PCD_TYPE_HII|PCD_TYPE_STRING: { ASSERT (FALSE); return EFI_INVALID_PARAMETER; } case PCD_TYPE_STRING: if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) { StringTableIdx = *((STRING_HEAD *)InternalData); CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + StringTableIdx, Data, *Size); return EFI_SUCCESS; } else { return EFI_INVALID_PARAMETER; } case PCD_TYPE_DATA: { if (PtrType) { if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) { CopyMem (InternalData, Data, *Size); return EFI_SUCCESS; } else { return EFI_INVALID_PARAMETER; } } switch (*Size) { case sizeof(UINT8): *((UINT8 *) InternalData) = *((UINT8 *) Data); return EFI_SUCCESS; case sizeof(UINT16): *((UINT16 *) InternalData) = *((UINT16 *) Data); return EFI_SUCCESS; case sizeof(UINT32): *((UINT32 *) InternalData) = *((UINT32 *) Data); return EFI_SUCCESS; case sizeof(UINT64): *((UINT64 *) InternalData) = *((UINT64 *) Data); return EFI_SUCCESS; default: ASSERT (FALSE); return EFI_NOT_FOUND; } } } ASSERT (FALSE); return EFI_NOT_FOUND; }
EFI_STATUS EFIAPI MemoryPeim ( IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, IN UINT64 UefiMemorySize ) { EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINT64 SystemMemoryTop; // Ensure PcdSystemMemorySize has been set ASSERT (PcdGet64 (PcdSystemMemorySize) != 0); // // Now, the permanent memory has been installed, we can call AllocatePages() // ResourceAttributes = ( 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_RESOURCE_ATTRIBUTE_TESTED ); SystemMemoryTop = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); if (SystemMemoryTop - 1 > MAX_ADDRESS) { BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, PcdGet64 (PcdSystemMemoryBase), (UINT64)MAX_ADDRESS - PcdGet64 (PcdSystemMemoryBase) + 1 ); BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, (UINT64)MAX_ADDRESS + 1, SystemMemoryTop - MAX_ADDRESS - 1 ); } else { BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, PcdGet64 (PcdSystemMemoryBase), PcdGet64 (PcdSystemMemorySize) ); } // // When running under virtualization, the PI/UEFI memory region may be // clean but not invalidated in system caches or in lower level caches // on other CPUs. So invalidate the region by virtual address, to ensure // that the contents we put there with the caches and MMU off will still // be visible after turning them on. // InvalidateDataCacheRange ((VOID*)(UINTN)UefiMemoryBase, UefiMemorySize); // Build Memory Allocation Hob InitMmu (); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } return EFI_SUCCESS; }
/** Decompresses a section to the output buffer. This function looks up the compression type field in the input section and applies the appropriate compression algorithm to compress the section to a callee allocated buffer. @param This Points to this instance of the EFI_PEI_DECOMPRESS_PEI PPI. @param CompressionSection Points to the compressed section. @param OutputBuffer Holds the returned pointer to the decompressed sections. @param OutputSize Holds the returned size of the decompress section streams. @retval EFI_SUCCESS The section was decompressed successfully. OutputBuffer contains the resulting data and OutputSize contains the resulting size. **/ EFI_STATUS EFIAPI Decompress ( IN CONST EFI_PEI_DECOMPRESS_PPI *This, IN CONST EFI_COMPRESSION_SECTION *CompressionSection, OUT VOID **OutputBuffer, OUT UINTN *OutputSize ) { EFI_STATUS Status; UINT8 *DstBuffer; UINT8 *ScratchBuffer; UINT32 DstBufferSize; UINT32 ScratchBufferSize; VOID *CompressionSource; UINT32 CompressionSourceSize; UINT32 UncompressedLength; UINT8 CompressionType; if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) { ASSERT (FALSE); return EFI_INVALID_PARAMETER; } if (IS_SECTION2 (CompressionSection)) { CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2)); CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2)); UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength; CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType; } else { CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION)); CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION)); UncompressedLength = CompressionSection->UncompressedLength; CompressionType = CompressionSection->CompressionType; } // // This is a compression set, expand it // switch (CompressionType) { case EFI_STANDARD_COMPRESSION: if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) { // // Load EFI standard compression. // For compressed data, decompress them to destination buffer. // Status = UefiDecompressGetInfo ( CompressionSource, CompressionSourceSize, &DstBufferSize, &ScratchBufferSize ); if (EFI_ERROR (Status)) { // // GetInfo failed // DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status)); return EFI_NOT_FOUND; } // // Allocate scratch buffer // ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize)); if (ScratchBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Allocate destination buffer // DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize)); if (DstBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Call decompress function // Status = UefiDecompress ( CompressionSource, DstBuffer, ScratchBuffer ); if (EFI_ERROR (Status)) { // // Decompress failed // DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status)); return EFI_NOT_FOUND; } break; } else { // // PcdDxeIplSupportUefiDecompress is FALSE // Don't support UEFI decompression algorithm. // ASSERT (FALSE); return EFI_NOT_FOUND; } case EFI_NOT_COMPRESSED: // // Allocate destination buffer // DstBufferSize = UncompressedLength; DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize)); if (DstBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // stream is not actually compressed, just encapsulated. So just copy it. // CopyMem (DstBuffer, CompressionSource, DstBufferSize); break; default: // // Don't support other unknown compression type. // ASSERT (FALSE); return EFI_NOT_FOUND; } *OutputSize = DstBufferSize; *OutputBuffer = DstBuffer; return EFI_SUCCESS; }
/** Return the Virtual Memory Map of your platform This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- Virtual Memory mapping. This array must be ended by a zero-filled entry **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; UINTN Index = 0; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; ASSERT (VirtualMemoryMap != NULL); VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } if (FeaturePcdGet(PcdCacheEnable) == TRUE) { CacheAttributes = DDR_ATTRIBUTES_CACHED; } else { CacheAttributes = DDR_ATTRIBUTES_UNCACHED; } #ifdef ARM_BIGLITTLE_TC2 // Secure NOR0 Flash VirtualMemoryTable[Index].PhysicalBase = ARM_VE_SEC_NOR0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SEC_NOR0_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SEC_NOR0_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Secure RAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SEC_RAM0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SEC_RAM0_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SEC_RAM0_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; #endif // SMB CS0 - NOR0 Flash VirtualMemoryTable[Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].Length = SIZE_256KB * 255; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Environment Variables region VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].Length = SIZE_64KB * 4; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS1 or CS4 - NOR1 Flash VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR1_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR1_BASE; VirtualMemoryTable[Index].Length = SIZE_256KB * 255; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Environment Variables region VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255); VirtualMemoryTable[Index].Length = SIZE_64KB * 4; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS3 or CS1 - PSRAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // Motherboard peripherals VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; #ifdef ARM_BIGLITTLE_TC2 // Non-secure ROM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_TC2_NON_SECURE_ROM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_TC2_NON_SECURE_ROM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_TC2_NON_SECURE_ROM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; #endif // OnChip peripherals VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ONCHIP_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_ONCHIP_PERIPH_BASE; VirtualMemoryTable[Index].Length = ARM_VE_ONCHIP_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SCC Region VirtualMemoryTable[++Index].PhysicalBase = ARM_CTA15A7_SCC_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_CTA15A7_SCC_BASE; VirtualMemoryTable[Index].Length = SIZE_64KB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; #ifdef ARM_BIGLITTLE_TC2 // TC2 OnChip non-secure SRAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_TC2_NON_SECURE_SRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_TC2_NON_SECURE_SRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_TC2_NON_SECURE_SRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; #endif #ifndef ARM_BIGLITTLE_TC2 // Workaround for SRAM bug in RTSM if (PcdGet64 (PcdSystemMemoryBase) != 0x80000000) { VirtualMemoryTable[++Index].PhysicalBase = 0x80000000; VirtualMemoryTable[Index].VirtualBase = 0x80000000; VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemoryBase) - 0x80000000; VirtualMemoryTable[Index].Attributes = CacheAttributes; } #endif // DDR VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].Attributes = CacheAttributes; // Detect if it is a 1GB or 2GB Test Chip // [16:19]: 0=1GB TC2, 1=2GB TC2 if (MmioRead32(ARM_VE_SYS_PROCID0_REG) & (0xF << 16)) { DEBUG((EFI_D_ERROR,"Info: 2GB Test Chip 2 detected.\n")); 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_RESOURCE_ATTRIBUTE_TESTED, PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize), SIZE_1GB ); // Map the additional 1GB into the MMU VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].Length = SIZE_1GB; VirtualMemoryTable[Index].Attributes = CacheAttributes; } // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); *VirtualMemoryMap = VirtualMemoryTable; }
/** The module Entry Point of the CPU SMM driver. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval Other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI PiCpuSmmEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_MP_SERVICES_PROTOCOL *MpServices; UINTN NumberOfEnabledProcessors; UINTN Index; VOID *Buffer; UINTN BufferPages; UINTN TileCodeSize; UINTN TileDataSize; UINTN TileSize; UINT8 *Stacks; VOID *Registration; UINT32 RegEax; UINT32 RegEdx; UINTN FamilyId; UINTN ModelId; UINT32 Cr3; // // Initialize Debug Agent to support source level debug in SMM code // InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, NULL, NULL); // // Report the start of CPU SMM initialization. // REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT ); // // Fix segment address of the long-mode-switch jump // if (sizeof (UINTN) == sizeof (UINT64)) { gSmmJmpAddr.Segment = LONG_MODE_CODE_SEGMENT; } // // Find out SMRR Base and SMRR Size // FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize); // // Get MP Services Protocol // Status = SystemTable->BootServices->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices); ASSERT_EFI_ERROR (Status); // // Use MP Services Protocol to retrieve the number of processors and number of enabled processors // Status = MpServices->GetNumberOfProcessors (MpServices, &mNumberOfCpus, &NumberOfEnabledProcessors); ASSERT_EFI_ERROR (Status); ASSERT (mNumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); // // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE. // A constant BSP index makes no sense because it may be hot removed. // DEBUG_CODE ( if (FeaturePcdGet (PcdCpuHotPlugSupport)) { ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection)); } );
/** Retrieve the PCI Card device BAR information via PciIo interface. @param PciIoDevice PCI Card device instance. **/ VOID GetBackPcCardBar ( IN PCI_IO_DEVICE *PciIoDevice ) { UINT32 Address; if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { return; } // // Read PciBar information from the bar register // if (!gFullEnumeration) { Address = 0; PciIoDevice->PciIo.Pci.Read ( &(PciIoDevice->PciIo), EfiPciIoWidthUint32, PCI_CARD_MEMORY_BASE_0, 1, &Address ); (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address); (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000; (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32; Address = 0; PciIoDevice->PciIo.Pci.Read ( &(PciIoDevice->PciIo), EfiPciIoWidthUint32, PCI_CARD_MEMORY_BASE_1, 1, &Address ); (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address); (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000; (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32; Address = 0; PciIoDevice->PciIo.Pci.Read ( &(PciIoDevice->PciIo), EfiPciIoWidthUint32, PCI_CARD_IO_BASE_0_LOWER, 1, &Address ); (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address); (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100; (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16; Address = 0; PciIoDevice->PciIo.Pci.Read ( &(PciIoDevice->PciIo), EfiPciIoWidthUint32, PCI_CARD_IO_BASE_1_LOWER, 1, &Address ); (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address); (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100; (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16; } if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { GetResourcePaddingForHpb (PciIoDevice); } }
/** Submits the I/O and memory resource requirements for the specified PCI Host Bridge. @param PciResAlloc Point to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. @retval EFI_SUCCESS Successfully finished resource allocation. @retval EFI_NOT_FOUND Cannot get root bridge instance. @retval EFI_OUT_OF_RESOURCES Platform failed to program the resources if no hot plug supported. @retval other Some error occurred when allocating resources for the PCI Host Bridge. @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug. **/ EFI_STATUS PciHostBridgeResourceAllocator ( IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc ) { PCI_IO_DEVICE *RootBridgeDev; EFI_HANDLE RootBridgeHandle; VOID *AcpiConfig; EFI_STATUS Status; UINT64 IoBase; UINT64 Mem32Base; UINT64 PMem32Base; UINT64 Mem64Base; UINT64 PMem64Base; UINT64 IoResStatus; UINT64 Mem32ResStatus; UINT64 PMem32ResStatus; UINT64 Mem64ResStatus; UINT64 PMem64ResStatus; UINT64 MaxOptionRomSize; PCI_RESOURCE_NODE *IoBridge; PCI_RESOURCE_NODE *Mem32Bridge; PCI_RESOURCE_NODE *PMem32Bridge; PCI_RESOURCE_NODE *Mem64Bridge; PCI_RESOURCE_NODE *PMem64Bridge; PCI_RESOURCE_NODE IoPool; PCI_RESOURCE_NODE Mem32Pool; PCI_RESOURCE_NODE PMem32Pool; PCI_RESOURCE_NODE Mem64Pool; PCI_RESOURCE_NODE PMem64Pool; BOOLEAN ReAllocate; EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData; EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData; // // Reallocate flag // ReAllocate = FALSE; // // It may try several times if the resource allocation fails // while (TRUE) { // // Initialize resource pool // InitializeResourcePool (&IoPool, PciBarTypeIo16); InitializeResourcePool (&Mem32Pool, PciBarTypeMem32); InitializeResourcePool (&PMem32Pool, PciBarTypePMem32); InitializeResourcePool (&Mem64Pool, PciBarTypeMem64); InitializeResourcePool (&PMem64Pool, PciBarTypePMem64); RootBridgeDev = NULL; RootBridgeHandle = 0; while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { // // Get Root Bridge Device by handle // RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); if (RootBridgeDev == NULL) { return EFI_NOT_FOUND; } // // Create the entire system resource map from the information collected by // enumerator. Several resource tree was created // // // If non-stardard PCI Bridge I/O window alignment is supported, // set I/O aligment to minimum possible alignment for root bridge. // IoBridge = CreateResourceNode ( RootBridgeDev, 0, FeaturePcdGet (PcdPciBridgeIoAlignmentProbe) ? 0x1FF: 0xFFF, RB_IO_RANGE, PciBarTypeIo16, PciResUsageTypical ); Mem32Bridge = CreateResourceNode ( RootBridgeDev, 0, 0xFFFFF, RB_MEM32_RANGE, PciBarTypeMem32, PciResUsageTypical ); PMem32Bridge = CreateResourceNode ( RootBridgeDev, 0, 0xFFFFF, RB_PMEM32_RANGE, PciBarTypePMem32, PciResUsageTypical ); Mem64Bridge = CreateResourceNode ( RootBridgeDev, 0, 0xFFFFF, RB_MEM64_RANGE, PciBarTypeMem64, PciResUsageTypical ); PMem64Bridge = CreateResourceNode ( RootBridgeDev, 0, 0xFFFFF, RB_PMEM64_RANGE, PciBarTypePMem64, PciResUsageTypical ); // // Create resourcemap by going through all the devices subject to this root bridge // CreateResourceMap ( RootBridgeDev, IoBridge, Mem32Bridge, PMem32Bridge, Mem64Bridge, PMem64Bridge ); // // Get the max ROM size that the root bridge can process // RootBridgeDev->RomSize = Mem32Bridge->Length; // // Skip to enlarge the resource request during realloction // if (!ReAllocate) { // // Get Max Option Rom size for current root bridge // MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev); // // Enlarger the mem32 resource to accomdate the option rom // if the mem32 resource is not enough to hold the rom // if (MaxOptionRomSize > Mem32Bridge->Length) { Mem32Bridge->Length = MaxOptionRomSize; RootBridgeDev->RomSize = MaxOptionRomSize; // // Alignment should be adjusted as well // if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) { Mem32Bridge->Alignment = MaxOptionRomSize - 1; } } } // // Based on the all the resource tree, contruct ACPI resource node to // submit the resource aperture to pci host bridge protocol // Status = ConstructAcpiResourceRequestor ( RootBridgeDev, IoBridge, Mem32Bridge, PMem32Bridge, Mem64Bridge, PMem64Bridge, &AcpiConfig ); // // Insert these resource nodes into the database // InsertResourceNode (&IoPool, IoBridge); InsertResourceNode (&Mem32Pool, Mem32Bridge); InsertResourceNode (&PMem32Pool, PMem32Bridge); InsertResourceNode (&Mem64Pool, Mem64Bridge); InsertResourceNode (&PMem64Pool, PMem64Bridge); if (Status == EFI_SUCCESS) { // // Submit the resource requirement // Status = PciResAlloc->SubmitResources ( PciResAlloc, RootBridgeDev->Handle, AcpiConfig ); // // If SubmitResources returns error, PciBus isn't able to start. // It's a fatal error so assertion is added. // DEBUG ((EFI_D_INFO, "PciBus: HostBridge->SubmitResources() - %r\n", Status)); ASSERT_EFI_ERROR (Status); } // // Free acpi resource node // if (AcpiConfig != NULL) { FreePool (AcpiConfig); } if (EFI_ERROR (Status)) { // // Destroy all the resource tree // DestroyResourceTree (&IoPool); DestroyResourceTree (&Mem32Pool); DestroyResourceTree (&PMem32Pool); DestroyResourceTree (&Mem64Pool); DestroyResourceTree (&PMem64Pool); return Status; } } // // End while, at least one Root Bridge should be found. // ASSERT (RootBridgeDev != NULL); // // Notify platform to start to program the resource // Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources); DEBUG ((EFI_D_INFO, "PciBus: HostBridge->NotifyPhase(AllocateResources) - %r\n", Status)); if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { // // If Hot Plug is not supported // if (EFI_ERROR (Status)) { // // Allocation failed, then return // return EFI_OUT_OF_RESOURCES; } // // Allocation succeed. // Get host bridge handle for status report, and then skip the main while // HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; break; } else { // // If Hot Plug is supported // if (!EFI_ERROR (Status)) { // // Allocation succeed, then continue the following // break; } // // If the resource allocation is unsuccessful, free resources on bridge // RootBridgeDev = NULL; RootBridgeHandle = 0; IoResStatus = EFI_RESOURCE_SATISFIED; Mem32ResStatus = EFI_RESOURCE_SATISFIED; PMem32ResStatus = EFI_RESOURCE_SATISFIED; Mem64ResStatus = EFI_RESOURCE_SATISFIED; PMem64ResStatus = EFI_RESOURCE_SATISFIED; while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { // // Get RootBridg Device by handle // RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); if (RootBridgeDev == NULL) { return EFI_NOT_FOUND; } // // Get host bridge handle for status report // HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; // // Get acpi resource node for all the resource types // AcpiConfig = NULL; Status = PciResAlloc->GetProposedResources ( PciResAlloc, RootBridgeDev->Handle, &AcpiConfig ); if (EFI_ERROR (Status)) { return Status; } if (AcpiConfig != NULL) { // // Adjust resource allocation policy for each RB // GetResourceAllocationStatus ( AcpiConfig, &IoResStatus, &Mem32ResStatus, &PMem32ResStatus, &Mem64ResStatus, &PMem64ResStatus ); FreePool (AcpiConfig); } } // // End while // // // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code // // // It is very difficult to follow the spec here // Device path , Bar index can not be get here // ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData)); REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( EFI_PROGRESS_CODE, EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT, (VOID *) &AllocFailExtendedData, sizeof (AllocFailExtendedData) ); Status = PciHostBridgeAdjustAllocation ( &IoPool, &Mem32Pool, &PMem32Pool, &Mem64Pool, &PMem64Pool, IoResStatus, Mem32ResStatus, PMem32ResStatus, Mem64ResStatus, PMem64ResStatus ); // // Destroy all the resource tree // DestroyResourceTree (&IoPool); DestroyResourceTree (&Mem32Pool); DestroyResourceTree (&PMem32Pool); DestroyResourceTree (&Mem64Pool); DestroyResourceTree (&PMem64Pool); NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources); if (EFI_ERROR (Status)) { return Status; } ReAllocate = TRUE; } } // // End main while // // // Raise the EFI_IOB_PCI_RES_ALLOC status code // REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( EFI_PROGRESS_CODE, EFI_IO_BUS_PCI | EFI_IOB_PCI_RES_ALLOC, (VOID *) &HandleExtendedData, sizeof (HandleExtendedData) ); // // Notify pci bus driver starts to program the resource // Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources); if (EFI_ERROR (Status)) { return Status; } RootBridgeDev = NULL; RootBridgeHandle = 0; while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { // // Get RootBridg Device by handle // RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); if (RootBridgeDev == NULL) { return EFI_NOT_FOUND; } // // Get acpi resource node for all the resource types // AcpiConfig = NULL; Status = PciResAlloc->GetProposedResources ( PciResAlloc, RootBridgeDev->Handle, &AcpiConfig ); if (EFI_ERROR (Status)) { return Status; } // // Get the resource base by interpreting acpi resource node // // GetResourceBase ( AcpiConfig, &IoBase, &Mem32Base, &PMem32Base, &Mem64Base, &PMem64Base ); // // Process option rom for this root bridge // ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize); // // Create the entire system resource map from the information collected by // enumerator. Several resource tree was created // IoBridge = FindResourceNode (RootBridgeDev, &IoPool); Mem32Bridge = FindResourceNode (RootBridgeDev, &Mem32Pool); PMem32Bridge = FindResourceNode (RootBridgeDev, &PMem32Pool); Mem64Bridge = FindResourceNode (RootBridgeDev, &Mem64Pool); PMem64Bridge = FindResourceNode (RootBridgeDev, &PMem64Pool); ASSERT (IoBridge != NULL); ASSERT (Mem32Bridge != NULL); ASSERT (PMem32Bridge != NULL); ASSERT (Mem64Bridge != NULL); ASSERT (PMem64Bridge != NULL); // // Program IO resources // ProgramResource ( IoBase, IoBridge ); // // Program Mem32 resources // ProgramResource ( Mem32Base, Mem32Bridge ); // // Program PMem32 resources // ProgramResource ( PMem32Base, PMem32Bridge ); // // Program Mem64 resources // ProgramResource ( Mem64Base, Mem64Bridge ); // // Program PMem64 resources // ProgramResource ( PMem64Base, PMem64Bridge ); IoBridge ->PciDev->PciBar[IoBridge ->Bar].BaseAddress = IoBase; Mem32Bridge ->PciDev->PciBar[Mem32Bridge ->Bar].BaseAddress = Mem32Base; PMem32Bridge->PciDev->PciBar[PMem32Bridge->Bar].BaseAddress = PMem32Base; Mem64Bridge ->PciDev->PciBar[Mem64Bridge ->Bar].BaseAddress = Mem64Base; PMem64Bridge->PciDev->PciBar[PMem64Bridge->Bar].BaseAddress = PMem64Base; // // Dump the resource map for current root bridge // DEBUG_CODE ( DumpResourceMap ( RootBridgeDev, IoBridge, Mem32Bridge, PMem32Bridge, Mem64Bridge, PMem64Bridge ); ); FreePool (AcpiConfig); }
/** Return the Virtual Memory Map of your platform This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- Virtual Memory mapping. This array must be ended by a zero-filled entry **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; UINTN Index = 0; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; ASSERT(VirtualMemoryMap != NULL); VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } if (FeaturePcdGet(PcdCacheEnable) == TRUE) { CacheAttributes = DDR_ATTRIBUTES_CACHED; } else { CacheAttributes = DDR_ATTRIBUTES_UNCACHED; } // ReMap (Either NOR Flash or DRAM) VirtualMemoryTable[Index].PhysicalBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].Length = ARM_VE_REMAP_SZ; if (FeaturePcdGet(PcdNorFlashRemapping) == FALSE) { // Map the NOR Flash as Secure Memory if (FeaturePcdGet(PcdCacheEnable) == TRUE) { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; } else { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_UNCACHED; } } else { // DRAM mapping VirtualMemoryTable[Index].Attributes = CacheAttributes; } // DDR VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_DRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_DRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_DRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // SMC CS7 VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ON_CHIP_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_ON_CHIP_PERIPH_BASE; VirtualMemoryTable[Index].Length = ARM_VE_ON_CHIP_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS0-CS1 - NOR Flash 1 & 2 VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_NOR0_SZ + ARM_VE_SMB_NOR1_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS2 - SRAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // SMB CS3-CS6 - Motherboard Peripherals VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].Length = 2 * ARM_VE_SMB_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // If a Logic Tile is connected to The ARM Versatile Express Motherboard if (MmioRead32(ARM_VE_SYS_PROCID1_REG) != 0) { VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_EXT_AXI_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_EXT_AXI_BASE; VirtualMemoryTable[Index].Length = ARM_VE_EXT_AXI_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; ASSERT((Index + 1) == (MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS + 1)); } else { ASSERT((Index + 1) == MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); } // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; *VirtualMemoryMap = VirtualMemoryTable; }
/** Main entry for Firmware Performance Data Table PEIM. This routine is to register report status code listener for FPDT. @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Pointer to PEI Services table. @retval EFI_SUCCESS Report status code listener is registered successfully. **/ EFI_STATUS EFIAPI FirmwarePerformancePeiEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; EFI_PEI_RSC_HANDLER_PPI *RscHandler; PEI_SEC_PERFORMANCE_PPI *SecPerf; FIRMWARE_SEC_PERFORMANCE Performance; Status = PeiServicesGetBootMode(&BootMode); ASSERT_EFI_ERROR (Status); if (BootMode == BOOT_ON_S3_RESUME) { if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) { // // S3 resume - register status code listener for OS wake vector. // Status = PeiServicesLocatePpi ( &gEfiPeiRscHandlerPpiGuid, 0, NULL, (VOID **) &RscHandler ); ASSERT_EFI_ERROR (Status); Status = RscHandler->Register (FpdtStatusCodeListenerPei); ASSERT_EFI_ERROR (Status); } } else { // // Normal boot - build Hob for SEC performance data. // Status = PeiServicesLocatePpi ( &gPeiSecPerformancePpiGuid, 0, NULL, (VOID **) &SecPerf ); if (!EFI_ERROR (Status)) { Status = SecPerf->GetPerformance (PeiServices, SecPerf, &Performance); } if (!EFI_ERROR (Status)) { BuildGuidDataHob ( &gEfiFirmwarePerformanceGuid, &Performance, sizeof (FIRMWARE_SEC_PERFORMANCE) ); DEBUG ((EFI_D_INFO, "FPDT: SEC Performance Hob ResetEnd = %ld\n", Performance.ResetEnd)); } else { // // SEC performance PPI is not installed or fail to get performance data // from SEC Performance PPI. // DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance PPI not installed or failed!\n")); } } return EFI_SUCCESS; }
/** Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE. Spare block is accessed by FTW working FVB protocol interface. LBA is 1. Target block is accessed by FvbBlock protocol interface. LBA is Lba. FTW will do extra work on boot block update. FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL, which is produced by a chipset driver. FTW updating boot block steps may be: 1. GetRangeLocation(), if the Range is inside the boot block, FTW know that boot block will be update. It shall add a FLAG in the working block. 2. When spare block is ready, 3. SetSwapState(EFI_SWAPPED) 4. erasing boot block, 5. programming boot block until the boot block is ok. 6. SetSwapState(UNSWAPPED) FTW shall not allow to update boot block when battery state is error. @param FtwDevice The private data of FTW driver @retval EFI_SUCCESS Spare block content is copied to boot block @retval EFI_INVALID_PARAMETER Input parameter error @retval EFI_OUT_OF_RESOURCES Allocate memory error @retval EFI_ABORTED The function could not complete successfully **/ EFI_STATUS FlushSpareBlockToBootBlock ( EFI_FTW_DEVICE *FtwDevice ) { EFI_STATUS Status; UINTN Length; UINT8 *Buffer; UINTN Count; UINT8 *Ptr; UINTN Index; BOOLEAN TopSwap; EFI_SWAP_ADDRESS_RANGE_PROTOCOL *SarProtocol; EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *BootFvb; EFI_LBA BootLba; if (!FeaturePcdGet(PcdFullFtwServiceEnable)) { return EFI_UNSUPPORTED; } // // Locate swap address range protocol // Status = FtwGetSarProtocol ((VOID **) &SarProtocol); if (EFI_ERROR (Status)) { return Status; } // // Allocate a memory buffer // Length = FtwDevice->SpareAreaLength; Buffer = AllocatePool (Length); if (Buffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Get TopSwap bit state // Status = SarProtocol->GetSwapState (SarProtocol, &TopSwap); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Ftw: Get Top Swapped status - %r\n", Status)); FreePool (Buffer); return EFI_ABORTED; } if (TopSwap) { // // Get FVB of current boot block // if (GetFvbByAddress (FtwDevice->SpareAreaAddress + FtwDevice->SpareAreaLength, &BootFvb) == NULL) { FreePool (Buffer); return EFI_ABORTED; } // // Read data from current boot block // BootLba = 0; Ptr = Buffer; for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) { Count = FtwDevice->BlockSize; Status = BootFvb->Read ( BootFvb, BootLba + Index, 0, &Count, Ptr ); if (EFI_ERROR (Status)) { FreePool (Buffer); return Status; } Ptr += Count; } } else { // // Read data from spare block // Ptr = Buffer; for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) { Count = FtwDevice->BlockSize; Status = FtwDevice->FtwBackupFvb->Read ( FtwDevice->FtwBackupFvb, FtwDevice->FtwSpareLba + Index, 0, &Count, Ptr ); if (EFI_ERROR (Status)) { FreePool (Buffer); return Status; } Ptr += Count; } // // Set TopSwap bit // Status = SarProtocol->SetSwapState (SarProtocol, TRUE); if (EFI_ERROR (Status)) { FreePool (Buffer); return Status; } } // // Erase current spare block // Because TopSwap is set, this actually erase the top block (boot block)! // Status = FtwEraseSpareBlock (FtwDevice); if (EFI_ERROR (Status)) { FreePool (Buffer); return EFI_ABORTED; } // // Write memory buffer to current spare block. Still top block. // Ptr = Buffer; for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) { Count = FtwDevice->BlockSize; Status = FtwDevice->FtwBackupFvb->Write ( FtwDevice->FtwBackupFvb, FtwDevice->FtwSpareLba + Index, 0, &Count, Ptr ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Ftw: FVB Write boot block - %r\n", Status)); FreePool (Buffer); return Status; } Ptr += Count; } FreePool (Buffer); // // Clear TopSwap bit // Status = SarProtocol->SetSwapState (SarProtocol, FALSE); return Status; }
/** Show progress bar with title above it. It only works in Graphics mode. @param TitleForeground Foreground color for Title. @param TitleBackground Background color for Title. @param Title Title above progress bar. @param ProgressColor Progress bar color. @param Progress Progress (0-100) @param PreviousValue The previous value of the progress. @retval EFI_STATUS Success update the progress bar **/ EFI_STATUS PlatformBdsShowProgress ( IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground, IN CHAR16 *Title, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor, IN UINTN Progress, IN UINTN PreviousValue ) { EFI_STATUS Status; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_UGA_DRAW_PROTOCOL *UgaDraw; UINT32 SizeOfX; UINT32 SizeOfY; UINT32 ColorDepth; UINT32 RefreshRate; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; UINTN BlockHeight; UINTN BlockWidth; UINTN BlockNum; UINTN PosX; UINTN PosY; UINTN Index; if (Progress > 100) { return EFI_INVALID_PARAMETER; } UgaDraw = NULL; Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput ); if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { GraphicsOutput = NULL; Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw ); } if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } SizeOfX = 0; SizeOfY = 0; if (GraphicsOutput != NULL) { SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; } else if (UgaDraw != NULL) { Status = UgaDraw->GetMode ( UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } } else { return EFI_UNSUPPORTED; } BlockWidth = SizeOfX / 100; BlockHeight = SizeOfY / 50; BlockNum = Progress; PosX = 0; PosY = SizeOfY * 48 / 50; if (BlockNum == 0) { // // Clear progress area // SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, &Color, EfiBltVideoFill, 0, 0, 0, PosY - EFI_GLYPH_HEIGHT - 1, SizeOfX, SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) &Color, EfiUgaVideoFill, 0, 0, 0, PosY - EFI_GLYPH_HEIGHT - 1, SizeOfX, SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), SizeOfX * sizeof (EFI_UGA_PIXEL) ); } else { return EFI_UNSUPPORTED; } } // // Show progress by drawing blocks // for (Index = PreviousValue; Index < BlockNum; Index++) { PosX = Index * BlockWidth; if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, &ProgressColor, EfiBltVideoFill, 0, 0, PosX, PosY, BlockWidth - 1, BlockHeight, (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) &ProgressColor, EfiUgaVideoFill, 0, 0, PosX, PosY, BlockWidth - 1, BlockHeight, (BlockWidth) * sizeof (EFI_UGA_PIXEL) ); } else { return EFI_UNSUPPORTED; } } PrintXY ( (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2, PosY - EFI_GLYPH_HEIGHT - 1, &TitleForeground, &TitleBackground, Title ); return EFI_SUCCESS; }
/** Use SystemTable Conout to stop video based Simple Text Out consoles from going to the video device. Put up LogoFile on every video device that is a console. @param[in] LogoFile File name of logo to display on the center of the screen. @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed. @retval EFI_UNSUPPORTED Logo not found **/ EFI_STATUS EFIAPI EnableQuietBoot ( IN EFI_GUID *LogoFile ) { EFI_STATUS Status; EFI_OEM_BADGING_PROTOCOL *Badging; UINT32 SizeOfX; UINT32 SizeOfY; INTN DestX; INTN DestY; UINT8 *ImageData; UINTN ImageSize; UINTN BltSize; UINT32 Instance; EFI_BADGING_FORMAT Format; EFI_BADGING_DISPLAY_ATTRIBUTE Attribute; UINTN CoordinateX; UINTN CoordinateY; UINTN Height; UINTN Width; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; EFI_UGA_DRAW_PROTOCOL *UgaDraw; UINT32 ColorDepth; UINT32 RefreshRate; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_BOOT_LOGO_PROTOCOL *BootLogo; UINTN NumberOfLogos; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt; UINTN LogoDestX; UINTN LogoDestY; UINTN LogoHeight; UINTN LogoWidth; UINTN NewDestX; UINTN NewDestY; UINTN NewHeight; UINTN NewWidth; UINT64 BufferSize; UgaDraw = NULL; // // Try to open GOP first // Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { GraphicsOutput = NULL; // // Open GOP failed, try to open UGA // Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw); } if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } // // Try to open Boot Logo Protocol. // BootLogo = NULL; gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); // // Erase Cursor from screen // gST->ConOut->EnableCursor (gST->ConOut, FALSE); Badging = NULL; Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging); if (GraphicsOutput != NULL) { SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } } else { return EFI_UNSUPPORTED; } Blt = NULL; NumberOfLogos = 0; LogoDestX = 0; LogoDestY = 0; LogoHeight = 0; LogoWidth = 0; NewDestX = 0; NewDestY = 0; NewHeight = 0; NewWidth = 0; Instance = 0; while (1) { ImageData = NULL; ImageSize = 0; if (Badging != NULL) { // // Get image from OEMBadging protocol. // Status = Badging->GetImage ( Badging, &Instance, &Format, &ImageData, &ImageSize, &Attribute, &CoordinateX, &CoordinateY ); if (EFI_ERROR (Status)) { goto Done; } // // Currently only support BMP format. // if (Format != EfiBadgingFormatBMP) { if (ImageData != NULL) { FreePool (ImageData); } continue; } } else { // // Get the specified image from FV. // Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } CoordinateX = 0; CoordinateY = 0; if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { Attribute = EfiBadgingDisplayAttributeCenter; } else { Attribute = EfiBadgingDisplayAttributeCustomized; } } if (Blt != NULL) { FreePool (Blt); } Blt = NULL; Status = TranslateBmpToGopBlt ( ImageData, ImageSize, &Blt, &BltSize, &Height, &Width ); if (EFI_ERROR (Status)) { FreePool (ImageData); if (Badging == NULL) { return Status; } else { continue; } } // // Calculate the display position according to Attribute. // switch (Attribute) { case EfiBadgingDisplayAttributeLeftTop: DestX = CoordinateX; DestY = CoordinateY; break; case EfiBadgingDisplayAttributeCenterTop: DestX = (SizeOfX - Width) / 2; DestY = CoordinateY; break; case EfiBadgingDisplayAttributeRightTop: DestX = (SizeOfX - Width - CoordinateX); DestY = CoordinateY;; break; case EfiBadgingDisplayAttributeCenterRight: DestX = (SizeOfX - Width - CoordinateX); DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeRightBottom: DestX = (SizeOfX - Width - CoordinateX); DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeCenterBottom: DestX = (SizeOfX - Width) / 2; DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeLeftBottom: DestX = CoordinateX; DestY = (SizeOfY - Height - CoordinateY); break; case EfiBadgingDisplayAttributeCenterLeft: DestX = CoordinateX; DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeCenter: DestX = (SizeOfX - Width) / 2; DestY = (SizeOfY - Height) / 2; break; case EfiBadgingDisplayAttributeCustomized: DestX = (SizeOfX - Width) / 2; DestY = ((SizeOfY * 382) / 1000) - Height / 2; break; default: DestX = CoordinateX; DestY = CoordinateY; break; } if ((DestX >= 0) && (DestY >= 0)) { if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, Blt, EfiBltBufferToVideo, 0, 0, (UINTN) DestX, (UINTN) DestY, Width, Height, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) Blt, EfiUgaBltBufferToVideo, 0, 0, (UINTN) DestX, (UINTN) DestY, Width, Height, Width * sizeof (EFI_UGA_PIXEL) ); } else { Status = EFI_UNSUPPORTED; } // // Report displayed Logo information. // if (!EFI_ERROR (Status)) { NumberOfLogos++; if (LogoWidth == 0) { // // The first Logo. // LogoDestX = (UINTN) DestX; LogoDestY = (UINTN) DestY; LogoWidth = Width; LogoHeight = Height; } else { // // Merge new logo with old one. // NewDestX = MIN ((UINTN) DestX, LogoDestX); NewDestY = MIN ((UINTN) DestY, LogoDestY); NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX; NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY; LogoDestX = NewDestX; LogoDestY = NewDestY; LogoWidth = NewWidth; LogoHeight = NewHeight; } } } FreePool (ImageData); if (Badging == NULL) { break; } } Done: if (BootLogo == NULL || NumberOfLogos == 0) { // // No logo displayed. // if (Blt != NULL) { FreePool (Blt); } return Status; } // // Advertise displayed Logo information. // if (NumberOfLogos == 1) { // // Only one logo displayed, use its Blt buffer directly for BootLogo protocol. // LogoBlt = Blt; Status = EFI_SUCCESS; } else { // // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. // if (Blt != NULL) { FreePool (Blt); } // // Ensure the LogoHeight * LogoWidth doesn't overflow // if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) { return EFI_UNSUPPORTED; } BufferSize = MultU64x64 (LogoWidth, LogoHeight); // // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow // if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { return EFI_UNSUPPORTED; } LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); if (LogoBlt == NULL) { return EFI_OUT_OF_RESOURCES; } if (GraphicsOutput != NULL) { Status = GraphicsOutput->Blt ( GraphicsOutput, LogoBlt, EfiBltVideoToBltBuffer, LogoDestX, LogoDestY, 0, 0, LogoWidth, LogoHeight, LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) ); } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { Status = UgaDraw->Blt ( UgaDraw, (EFI_UGA_PIXEL *) LogoBlt, EfiUgaVideoToBltBuffer, LogoDestX, LogoDestY, 0, 0, LogoWidth, LogoHeight, LogoWidth * sizeof (EFI_UGA_PIXEL) ); } else { Status = EFI_UNSUPPORTED; } } if (!EFI_ERROR (Status)) { BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight); } FreePool (LogoBlt); return Status; }
/** Returns the size and type of the requested recovery capsule. This function gets the size and type of the capsule specified by CapsuleInstance. @param[in] PeiServices General-purpose services that are available to every PEIM @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance. @param[in] CapsuleInstance Specifies for which capsule instance to retrieve the information. This parameter must be between one and the value returned by GetNumberRecoveryCapsules() in NumberRecoveryCapsules. @param[out] Size A pointer to a caller-allocated UINTN in which the size of the requested recovery module is returned. @param[out] CapsuleType A pointer to a caller-allocated EFI_GUID in which the type of the requested recovery capsule is returned. The semantic meaning of the value returned is defined by the implementation. @retval EFI_SUCCESS One or more capsules were discovered. @retval EFI_DEVICE_ERROR A device error occurred. @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found. **/ EFI_STATUS EFIAPI GetRecoveryCapsuleInfo ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This, IN UINTN CapsuleInstance, OUT UINTN *Size, OUT EFI_GUID *CapsuleType ) { EFI_STATUS Status; PEI_FAT_PRIVATE_DATA *PrivateData; UINTN Index; UINTN BlockDeviceNo; UINTN RecoveryCapsuleCount; PEI_FILE_HANDLE Handle; UINTN NumberRecoveryCapsules; Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules); if (EFI_ERROR (Status)) { return Status; } if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { CapsuleInstance = CapsuleInstance + 1; } if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) { return EFI_NOT_FOUND; } PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This); // // Search each volume in the root directory for the Recovery capsule // RecoveryCapsuleCount = 0; for (Index = 0; Index < PrivateData->VolumeCount; Index++) { Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle); if (EFI_ERROR (Status)) { continue; } if (CapsuleInstance - 1 == RecoveryCapsuleCount) { // // Get file size // *Size = (UINTN) (((PEI_FAT_FILE *) Handle)->FileSize); // // Find corresponding physical block device // BlockDeviceNo = PrivateData->Volume[Index].BlockDeviceNo; while (PrivateData->BlockDevice[BlockDeviceNo].Logical && BlockDeviceNo < PrivateData->BlockDeviceCount) { BlockDeviceNo = PrivateData->BlockDevice[BlockDeviceNo].ParentDevNo; } // // Fill in the Capsule Type GUID according to the block device type // if (BlockDeviceNo < PrivateData->BlockDeviceCount) { if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo2 != NULL) { switch (PrivateData->BlockDevice[BlockDeviceNo].InterfaceType) { case MSG_ATAPI_DP: CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid); break; case MSG_USB_DP: CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid); break; default: break; } } if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo != NULL) { switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) { case LegacyFloppy: CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid); break; case IdeCDROM: case IdeLS120: CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid); break; case UsbMassStorage: CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid); break; default: break; } } } return EFI_SUCCESS; } RecoveryCapsuleCount++; } return EFI_NOT_FOUND; }
VOID EFIAPI PlatformConfigOnSmmConfigurationProtocol ( IN EFI_EVENT Event, IN VOID *Context ) /*++ Routine Description: Function runs in PI-DXE to perform platform specific config when SmmConfigurationProtocol is installed. Arguments: Event - The event that occured. Context - For EFI compatiblity. Not used. Returns: None. --*/ { EFI_STATUS Status; UINT32 NewValue; UINT64 BaseAddress; UINT64 SmramLength; EFI_CPU_ARCH_PROTOCOL *CpuArchProtocol; // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE VOID *SmmCfgProt; Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, &SmmCfgProt); if (Status != EFI_SUCCESS){ DEBUG ((DEBUG_INFO, "gEfiSmmConfigurationProtocolGuid triggered but not valid.\n")); return; } if (mMemCfgDone) { DEBUG ((DEBUG_INFO, "Platform DXE Mem config already done.\n")); return; } // // Disable eSram block (this will also clear/zero eSRAM) // We only use eSRAM in the PEI phase. Disable now that we are in the DXE phase // NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK); NewValue |= BLOCK_DISABLE_PG; QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue); // // Update HMBOUND to top of DDR3 memory and LOCK // We disabled eSRAM so now we move HMBOUND down to top of DDR3 // QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength); NewValue = (UINT32)(BaseAddress + SmramLength); DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue)); QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK)); if(FeaturePcdGet (PcdEnableSecureLock)) { // // Lock IMR5 now that HMBOUND is locked (legacy S3 region) // NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL); NewValue |= IMR_LOCK; QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue); // // Lock IMR6 now that HMBOUND is locked (ACPI Reclaim/ACPI/Runtime services/Reserved) // NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL); NewValue |= IMR_LOCK; QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue); // // Disable IMR2 memory protection (RMU Main Binary) // QncImrWrite ( QUARK_NC_MEMORY_MANAGER_IMR2, (UINT32)(IMRL_RESET & ~IMR_EN), (UINT32)IMRH_RESET, (UINT32)IMRX_ALL_ACCESS, (UINT32)IMRX_ALL_ACCESS ); // // Disable IMR3 memory protection (Default SMRAM) // QncImrWrite ( QUARK_NC_MEMORY_MANAGER_IMR3, (UINT32)(IMRL_RESET & ~IMR_EN), (UINT32)IMRH_RESET, (UINT32)IMRX_ALL_ACCESS, (UINT32)IMRX_ALL_ACCESS ); // // Disable IMR4 memory protection (eSRAM). // QncImrWrite ( QUARK_NC_MEMORY_MANAGER_IMR4, (UINT32)(IMRL_RESET & ~IMR_EN), (UINT32)IMRH_RESET, (UINT32)IMRX_ALL_ACCESS, (UINT32)IMRX_ALL_ACCESS ); } // // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE // Workaround to make default SMRAM UnCachable // Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &CpuArchProtocol); ASSERT_EFI_ERROR (Status); CpuArchProtocol->SetMemoryAttributes ( CpuArchProtocol, (EFI_PHYSICAL_ADDRESS) SMM_DEFAULT_SMBASE, SMM_DEFAULT_SMBASE_SIZE_BYTES, EFI_MEMORY_WB ); mMemCfgDone = TRUE; }
/** Starts a target block update. This records information about the write in fault tolerant storage and will complete the write in a recoverable manner, ensuring at all times that either the original contents or the modified contents are available. @param This The pointer to this protocol instance. @param CallerId The GUID identifying the last write. @param Lba The logical block address of the last write. @param Offset The offset within the block of the last write. @param Length The length of the last write. @param PrivateDataSize bytes from the private data stored for this write. @param PrivateData A pointer to a buffer. The function will copy @param Complete A Boolean value with TRUE indicating that the write was completed. @retval EFI_SUCCESS The function completed successfully @retval EFI_ABORTED The function could not complete successfully @retval EFI_NOT_FOUND No allocated writes exist @retval EFI_BUFFER_TOO_SMALL Input buffer is not larget enough **/ EFI_STATUS EFIAPI FtwGetLastWrite ( IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, OUT EFI_GUID *CallerId, OUT EFI_LBA *Lba, OUT UINTN *Offset, OUT UINTN *Length, IN OUT UINTN *PrivateDataSize, OUT VOID *PrivateData, OUT BOOLEAN *Complete ) { EFI_STATUS Status; EFI_FTW_DEVICE *FtwDevice; EFI_FAULT_TOLERANT_WRITE_HEADER *Header; EFI_FAULT_TOLERANT_WRITE_RECORD *Record; if (!FeaturePcdGet(PcdFullFtwServiceEnable)) { return EFI_UNSUPPORTED; } FtwDevice = FTW_CONTEXT_FROM_THIS (This); Status = WorkSpaceRefresh (FtwDevice); if (EFI_ERROR (Status)) { return EFI_ABORTED; } Header = FtwDevice->FtwLastWriteHeader; Record = FtwDevice->FtwLastWriteRecord; // // If Header is incompleted and the last record has completed, then // call Abort() to set the Header->Complete FLAG. // if ((Header->Complete != FTW_VALID_STATE) && (Record->DestinationComplete == FTW_VALID_STATE) && IsLastRecordOfWrites (Header, Record) ) { Status = FtwAbort (This); *Complete = TRUE; return EFI_NOT_FOUND; } // // If there is no write header/record, return not found. // if (Header->HeaderAllocated != FTW_VALID_STATE) { *Complete = TRUE; return EFI_NOT_FOUND; } // // If this record SpareComplete has not set, then it can not restart. // if (Record->SpareComplete != FTW_VALID_STATE) { Status = GetPreviousRecordOfWrites (Header, &Record); if (EFI_ERROR (Status)) { FtwAbort (This); *Complete = TRUE; return EFI_NOT_FOUND; } ASSERT (Record != NULL); } // // Fill all the requested values // CopyMem (CallerId, &Header->CallerId, sizeof (EFI_GUID)); *Lba = Record->Lba; *Offset = Record->Offset; *Length = Record->Length; *Complete = (BOOLEAN) (Record->DestinationComplete == FTW_VALID_STATE); if (*PrivateDataSize < Header->PrivateDataSize) { *PrivateDataSize = Header->PrivateDataSize; PrivateData = NULL; Status = EFI_BUFFER_TOO_SMALL; } else { *PrivateDataSize = Header->PrivateDataSize; CopyMem (PrivateData, Record + 1, *PrivateDataSize); Status = EFI_SUCCESS; } DEBUG ((EFI_D_ERROR, "Ftw: GetLasetWrite() success\n")); return Status; }
/*++ 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 MemoryPeim ( IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, IN UINT64 UefiMemorySize ) { EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINT64 ResourceLength; EFI_PEI_HOB_POINTERS NextHob; EFI_PHYSICAL_ADDRESS FdTop; EFI_PHYSICAL_ADDRESS SystemMemoryTop; EFI_PHYSICAL_ADDRESS ResourceTop; BOOLEAN Found; // Ensure PcdSystemMemorySize has been set ASSERT (PcdGet32 (PcdSystemMemorySize) != 0); // // Now, the permanent memory has been installed, we can call AllocatePages() // ResourceAttributes = ( 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_RESOURCE_ATTRIBUTE_TESTED ); // Reserved the memory space occupied by the firmware volume BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, PcdGet32 (PcdSystemMemoryBase), PcdGet32 (PcdSystemMemorySize) ); SystemMemoryTop = PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemorySize); FdTop = PcdGet32(PcdFdBaseAddress) + PcdGet32(PcdFdSize); // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE // core to overwrite this area we must mark the region with the attribute non-present if ((PcdGet32 (PcdFdBaseAddress) >= PcdGet32 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) { Found = FALSE; // Search for System Memory Hob that contains the firmware NextHob.Raw = GetHobList (); while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) { if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) && (PcdGet32(PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) && (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength)) { ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute; ResourceLength = NextHob.ResourceDescriptor->ResourceLength; ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength; if (PcdGet32(PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) { if (SystemMemoryTop == FdTop) { NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT; } else { // Create the System Memory HOB for the firmware with the non-present attribute BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT, PcdGet32(PcdFdBaseAddress), PcdGet32(PcdFdSize)); // Top of the FD is system memory available for UEFI NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize); NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize); } } else { // Create the System Memory HOB for the firmware with the non-present attribute BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT, PcdGet32(PcdFdBaseAddress), PcdGet32(PcdFdSize)); // Update the HOB NextHob.ResourceDescriptor->ResourceLength = PcdGet32(PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart; // If there is some memory available on the top of the FD then create a HOB if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) { // Create the System Memory HOB for the remaining region (top of the FD) BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, FdTop, ResourceTop - FdTop); } } Found = TRUE; break; } NextHob.Raw = GET_NEXT_HOB (NextHob); } ASSERT(Found); } // Build Memory Allocation Hob InitMmu (); if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { // Optional feature that helps prevent EFI memory map fragmentation. BuildMemoryTypeInformationHob (); } return EFI_SUCCESS; }
/** Worker function that locates the Node in the List. By searching the List, finds the location of the Node in List. At the same time, verifies the validity of this list. If List is NULL, then ASSERT(). If List->ForwardLink is NULL, then ASSERT(). If List->backLink is NULL, then ASSERT(). If Node is NULL, then ASSERT(). If PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE and Node is in not a member of List, then return FALSE If PcdMaximumLinkedListLength is not zero, and List contains more than PcdMaximumLinkedListLength nodes, then ASSERT(). @param List A pointer to a node in a linked list. @param Node A pointer to a node in a linked list. @param VerifyNodeInList TRUE if a check should be made to see if Node is a member of List. FALSE if no membership test should be performed. @retval TRUE if PcdVerifyNodeInList is FALSE @retval TRUE if DoMembershipCheck is FALSE @retval TRUE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE and Node is a member of List. @retval FALSE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE and Node is in not a member of List. **/ BOOLEAN EFIAPI InternalBaseLibIsNodeInList ( IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node, IN BOOLEAN VerifyNodeInList ) { UINTN Count; CONST LIST_ENTRY *Ptr; // // Test the validity of List and Node // ASSERT (List != NULL); ASSERT (List->ForwardLink != NULL); ASSERT (List->BackLink != NULL); ASSERT (Node != NULL); Count = 0; Ptr = List; if (FeaturePcdGet (PcdVerifyNodeInList) && VerifyNodeInList) { // // Check to see if Node is a member of List. // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength // do { Ptr = Ptr->ForwardLink; if (PcdGet32 (PcdMaximumLinkedListLength) > 0) { Count++; // // ASSERT() if the linked list is too long // ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength)); // // Return if the linked list is too long // if (Count >= PcdGet32 (PcdMaximumLinkedListLength)) { return (BOOLEAN)(Ptr == Node); } } } while ((Ptr != List) && (Ptr != Node)); if (Ptr != Node) { return FALSE; } } if (PcdGet32 (PcdMaximumLinkedListLength) > 0) { // // Count the total number of nodes in List. // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength // do { Ptr = Ptr->ForwardLink; Count++; } while ((Ptr != List) && (Count < PcdGet32 (PcdMaximumLinkedListLength))); // // ASSERT() if the linked list is too long // ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength)); } return TRUE; }
/** The module Entry Point of the Firmware Performance Data Table DXE driver. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval Other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI FirmwarePerformanceDxeEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HOB_GUID_TYPE *GuidHob; FIRMWARE_SEC_PERFORMANCE *Performance; VOID *Registration; // // Get Report Status Code Handler Protocol. // Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol); ASSERT_EFI_ERROR (Status); // // Register report status code listener for OS Loader load and start. // Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL); ASSERT_EFI_ERROR (Status); // // Register the notify function to update FPDT on ExitBootServices Event. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FpdtExitBootServicesEventNotify, NULL, &gEfiEventExitBootServicesGuid, &mExitBootServicesEvent ); ASSERT_EFI_ERROR (Status); // // Create ready to boot event to install ACPI FPDT table. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FpdtReadyToBootEventNotify, NULL, &gEfiEventReadyToBootGuid, &mReadyToBootEvent ); ASSERT_EFI_ERROR (Status); // // Create legacy boot event to log OsLoaderStartImageStart for legacy boot. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FpdtLegacyBootEventNotify, NULL, &gEfiEventLegacyBootGuid, &mLegacyBootEvent ); ASSERT_EFI_ERROR (Status); // // Retrieve GUID HOB data that contains the ResetEnd. // GuidHob = GetFirstGuidHob (&gEfiFirmwarePerformanceGuid); if (GuidHob != NULL) { Performance = (FIRMWARE_SEC_PERFORMANCE *) GET_GUID_HOB_DATA (GuidHob); mBootPerformanceTableTemplate.BasicBoot.ResetEnd = Performance->ResetEnd; } else { // // SEC Performance Data Hob not found, ResetEnd in ACPI FPDT table will be 0. // DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n")); } if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) { // // Register callback function upon VariableArchProtocol and LockBoxProtocol // to allocate S3 performance table memory and save the pointer to LockBox. // EfiCreateProtocolNotifyEvent ( &gEfiVariableArchProtocolGuid, TPL_CALLBACK, FpdtAllocateS3PerformanceTableMemory, NULL, &Registration ); EfiCreateProtocolNotifyEvent ( &gEfiLockBoxProtocolGuid, TPL_CALLBACK, FpdtAllocateS3PerformanceTableMemory, NULL, &Registration ); } else { // // Exclude S3 Performance Table Pointer from FPDT table template. // mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD); } return EFI_SUCCESS; }
/** This function is the main entry of the platform setup entry. The function will present the main menu of the system setup, this is the platform reference part and can be customize. @param TimeoutDefault The fault time out value before the system continue to boot. @param ConnectAllHappened The indicater to check if the connect all have already happened. **/ VOID PlatformBdsEnterFrontPage ( IN UINT16 TimeoutDefault, IN BOOLEAN ConnectAllHappened ) { EFI_STATUS Status; EFI_STATUS StatusHotkey; EFI_BOOT_LOGO_PROTOCOL *BootLogo; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; UINTN BootTextColumn; UINTN BootTextRow; UINT64 OsIndication; UINTN DataSize; EFI_INPUT_KEY Key; GraphicsOutput = NULL; SimpleTextOut = NULL; PERF_START (NULL, "BdsTimeOut", "BDS", 0); // // Indicate if we need connect all in the platform setup // if (ConnectAllHappened) { gConnectAllHappened = TRUE; } if (!mModeInitialized) { // // After the console is ready, get current video resolution // and text mode before launching setup at first time. // Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID**)&GraphicsOutput ); if (EFI_ERROR (Status)) { GraphicsOutput = NULL; } Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiSimpleTextOutProtocolGuid, (VOID**)&SimpleTextOut ); if (EFI_ERROR (Status)) { SimpleTextOut = NULL; } if (GraphicsOutput != NULL) { // // Get current video resolution and text mode. // mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution; mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution; } if (SimpleTextOut != NULL) { Status = SimpleTextOut->QueryMode ( SimpleTextOut, SimpleTextOut->Mode->Mode, &BootTextColumn, &BootTextRow ); mBootTextModeColumn = (UINT32)BootTextColumn; mBootTextModeRow = (UINT32)BootTextRow; } // // Get user defined text mode for setup. // mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution); mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn); mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow); mModeInitialized = TRUE; } // // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set // OsIndication = 0; DataSize = sizeof(UINT64); Status = gRT->GetVariable ( L"OsIndications", &gEfiGlobalVariableGuid, NULL, &DataSize, &OsIndication ); // // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot // if (!EFI_ERROR(Status) && ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0)) { // // Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS // OsIndication &= ~((UINT64)EFI_OS_INDICATIONS_BOOT_TO_FW_UI); Status = gRT->SetVariable ( L"OsIndications", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, sizeof(UINT64), &OsIndication ); // // Changing the content without increasing its size with current variable implementation shouldn't fail. // ASSERT_EFI_ERROR (Status); // // Follow generic rule, Call ReadKeyStroke to connect ConIn before enter UI // if (PcdGetBool (PcdConInConnectOnDemand)) { gST->ConIn->ReadKeyStroke(gST->ConIn, &Key); } // // Ensure screen is clear when switch Console from Graphics mode to Text mode // gST->ConOut->EnableCursor (gST->ConOut, TRUE); gST->ConOut->ClearScreen (gST->ConOut); } else { HotkeyBoot (); if (TimeoutDefault != 0xffff) { Status = ShowProgress (TimeoutDefault); StatusHotkey = HotkeyBoot (); if (!FeaturePcdGet(PcdBootlogoOnlyEnable) || !EFI_ERROR(Status) || !EFI_ERROR(StatusHotkey)){ // // Ensure screen is clear when switch Console from Graphics mode to Text mode // Skip it in normal boot // gST->ConOut->EnableCursor (gST->ConOut, TRUE); gST->ConOut->ClearScreen (gST->ConOut); } if (EFI_ERROR (Status)) { // // Timeout or user press enter to continue // goto Exit; } } } // // Boot Logo is corrupted, report it using Boot Logo protocol. // Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); if (!EFI_ERROR (Status) && (BootLogo != NULL)) { BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0); } // // Install BM HiiPackages. // Keep BootMaint HiiPackage, so that it can be covered by global setting. // InitBMPackage (); Status = EFI_SUCCESS; do { // // Set proper video resolution and text mode for setup // BdsSetConsoleMode (TRUE); InitializeFrontPage (FALSE); // // Update Front Page strings // UpdateFrontPageStrings (); gCallbackKey = 0; CallFrontPage (); // // If gCallbackKey is greater than 1 and less or equal to 5, // it will launch configuration utilities. // 2 = set language // 3 = boot manager // 4 = device manager // 5 = boot maintenance manager // if (gCallbackKey != 0) { REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP) ); } // // Based on the key that was set, we can determine what to do // switch (gCallbackKey) { // // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can // describe to their customers in documentation how to find their setup information (namely // under the device manager and specific buckets) // // These entries consist of the Continue, Select language, Boot Manager, and Device Manager // case FRONT_PAGE_KEY_CONTINUE: // // User hit continue // break; case FRONT_PAGE_KEY_LANGUAGE: // // User made a language setting change - display front page again // break; case FRONT_PAGE_KEY_BOOT_MANAGER: // // Remove the installed BootMaint HiiPackages when exit. // FreeBMPackage (); // // User chose to run the Boot Manager // CallBootManager (); // // Reinstall BootMaint HiiPackages after exiting from Boot Manager. // InitBMPackage (); break; case FRONT_PAGE_KEY_DEVICE_MANAGER: // // Display the Device Manager // do { CallDeviceManager (); } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER); break; case FRONT_PAGE_KEY_BOOT_MAINTAIN: // // Display the Boot Maintenance Manager // BdsStartBootMaint (); break; } } while ((Status == EFI_SUCCESS) && (gCallbackKey != FRONT_PAGE_KEY_CONTINUE)); if (mLanguageString != NULL) { FreePool (mLanguageString); mLanguageString = NULL; } // //Will leave browser, check any reset required change is applied? if yes, reset system // SetupResetReminder (); // // Remove the installed BootMaint HiiPackages when exit. // FreeBMPackage (); Exit: // // Automatically load current entry // Note: The following lines of code only execute when Auto boot // takes affect // PERF_END (NULL, "BdsTimeOut", "BDS", 0); }
/** Return the Virtual Memory Map of your platform This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- Virtual Memory mapping. This array must be ended by a zero-filled entry **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINTN Index = 0; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; UINT32 SysId; BOOLEAN HasSparseMemory; EFI_VIRTUAL_ADDRESS SparseMemoryBase; UINT64 SparseMemorySize; ASSERT (VirtualMemoryMap != NULL); // The FVP model has Sparse memory SysId = MmioRead32 (ARM_VE_SYS_ID_REG); if (SysId != ARM_RTSM_SYS_ID) { HasSparseMemory = TRUE; ResourceAttributes = 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_RESOURCE_ATTRIBUTE_TESTED; // Declared the additional DRAM from 2GB to 4GB SparseMemoryBase = 0x0880000000; SparseMemorySize = SIZE_2GB; BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, SparseMemoryBase, SparseMemorySize); } else { HasSparseMemory = FALSE; SparseMemoryBase = 0x0; SparseMemorySize = 0x0; } VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } if (FeaturePcdGet(PcdCacheEnable) == TRUE) { CacheAttributes = DDR_ATTRIBUTES_CACHED; } else { CacheAttributes = DDR_ATTRIBUTES_UNCACHED; } // ReMap (Either NOR Flash or DRAM) VirtualMemoryTable[Index].PhysicalBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].Length = ARM_VE_REMAP_SZ; if (FeaturePcdGet(PcdNorFlashRemapping) == FALSE) { // Map the NOR Flash as Secure Memory if (FeaturePcdGet(PcdCacheEnable) == TRUE) { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; } else { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_UNCACHED; } } else { // DRAM mapping VirtualMemoryTable[Index].Attributes = CacheAttributes; } // DDR VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_DRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_DRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_DRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // CPU peripherals. TRM. Manual says not all of them are implemented. VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ON_CHIP_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_ON_CHIP_PERIPH_BASE; VirtualMemoryTable[Index].Length = ARM_VE_ON_CHIP_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // SMB CS0-CS1 - NOR Flash 1 & 2 VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_NOR0_SZ + ARM_VE_SMB_NOR1_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // SMB CS2 - SRAM VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE; VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ; VirtualMemoryTable[Index].Attributes = CacheAttributes; // Peripheral CS2 and CS3 VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE; VirtualMemoryTable[Index].Length = 2 * ARM_VE_SMB_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Map sparse memory region if present if (HasSparseMemory) { VirtualMemoryTable[++Index].PhysicalBase = SparseMemoryBase; VirtualMemoryTable[Index].VirtualBase = SparseMemoryBase; VirtualMemoryTable[Index].Length = SparseMemorySize; VirtualMemoryTable[Index].Attributes = CacheAttributes; } // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; *VirtualMemoryMap = VirtualMemoryTable; }
/** Create KEYBOARD_CONSOLE_IN_DEV instance on controller. @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL @param Controller driver controller handle @param RemainingDevicePath Children's device path @retval whether success to create floppy control instance. **/ EFI_STATUS EFIAPI KbdControllerDriverStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_STATUS Status1; EFI_ISA_IO_PROTOCOL *IsaIo; KEYBOARD_CONSOLE_IN_DEV *ConsoleIn; UINT8 Data; EFI_STATUS_CODE_VALUE StatusCode; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; StatusCode = 0; Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid, (VOID **) &ParentDevicePath, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // Report that the keyboard is being enabled // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE, ParentDevicePath ); // // Get the ISA I/O Protocol on Controller's handle // Status = gBS->OpenProtocol ( Controller, &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); return EFI_INVALID_PARAMETER; } // // Allocate private data // ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV)); if (ConsoleIn == NULL) { Status = EFI_OUT_OF_RESOURCES; StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } // // Setup the device instance // ConsoleIn->Signature = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE; ConsoleIn->Handle = Controller; (ConsoleIn->ConIn).Reset = KeyboardEfiReset; (ConsoleIn->ConIn).ReadKeyStroke = KeyboardReadKeyStroke; ConsoleIn->DataRegisterAddress = KEYBOARD_8042_DATA_REGISTER; ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER; ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER; ConsoleIn->IsaIo = IsaIo; ConsoleIn->DevicePath = ParentDevicePath; ConsoleIn->ConInEx.Reset = KeyboardEfiResetEx; ConsoleIn->ConInEx.ReadKeyStrokeEx = KeyboardReadKeyStrokeEx; ConsoleIn->ConInEx.SetState = KeyboardSetState; ConsoleIn->ConInEx.RegisterKeyNotify = KeyboardRegisterKeyNotify; ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify; InitializeListHead (&ConsoleIn->NotifyList); // // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS. // When KBC decode (IO port 0x60/0x64 decode) is not enabled, // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS. // So instead we read status register to detect after read if KBC decode is enabled. // // // Return code is ignored on purpose. // if (!PcdGetBool (PcdFastPS2Detection)) { KeyboardRead (ConsoleIn, &Data); if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) { // // If nobody decodes KBC I/O port, it will read back as 0xFF. // Check the Time-Out and Parity bit to see if it has an active KBC in system // Status = EFI_DEVICE_ERROR; StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED; goto ErrorExit; } } // // Setup the WaitForKey event // Status = gBS->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY, KeyboardWaitForKey, ConsoleIn, &((ConsoleIn->ConIn).WaitForKey) ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } // // Setup the WaitForKeyEx event // Status = gBS->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY, KeyboardWaitForKeyEx, ConsoleIn, &(ConsoleIn->ConInEx.WaitForKeyEx) ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } // Setup a periodic timer, used for reading keystrokes at a fixed interval // Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, KeyboardTimerHandler, ConsoleIn, &ConsoleIn->TimerEvent ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } Status = gBS->SetTimer ( ConsoleIn->TimerEvent, TimerPeriodic, KEYBOARD_TIMER_INTERVAL ); if (EFI_ERROR (Status)) { Status = EFI_OUT_OF_RESOURCES; StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT, ParentDevicePath ); // // Reset the keyboard device // Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification)); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED; goto ErrorExit; } REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED, ParentDevicePath ); ConsoleIn->ControllerNameTable = NULL; AddUnicodeString2 ( "eng", gPs2KeyboardComponentName.SupportedLanguages, &ConsoleIn->ControllerNameTable, L"PS/2 Keyboard Device", TRUE ); AddUnicodeString2 ( "en", gPs2KeyboardComponentName2.SupportedLanguages, &ConsoleIn->ControllerNameTable, L"PS/2 Keyboard Device", FALSE ); // // Install protocol interfaces for the keyboard device. // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiSimpleTextInProtocolGuid, &ConsoleIn->ConIn, &gEfiSimpleTextInputExProtocolGuid, &ConsoleIn->ConInEx, NULL ); if (EFI_ERROR (Status)) { StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR; goto ErrorExit; } return Status; ErrorExit: // // Report error code // if (StatusCode != 0) { REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE | EFI_ERROR_MINOR, StatusCode, ParentDevicePath ); } if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) { gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey); } if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) { gBS->CloseEvent (ConsoleIn->TimerEvent); } if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) { gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx); } KbdFreeNotifyList (&ConsoleIn->NotifyList); if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) { FreeUnicodeStringTable (ConsoleIn->ControllerNameTable); } // // Since there will be no timer handler for keyboard input any more, // exhaust input data just in case there is still keyboard data left // if (ConsoleIn != NULL) { Status1 = EFI_SUCCESS; while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) { Status1 = KeyboardRead (ConsoleIn, &Data);; } } if (ConsoleIn != NULL) { gBS->FreePool (ConsoleIn); } gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); gBS->CloseProtocol ( Controller, &gEfiIsaIoProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
/** Return the Virtual Memory Map of your platform This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- Virtual Memory mapping. This array must be ended by a zero-filled entry **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; //EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; UINTN Index; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; //UINT32 SysId; //BOOLEAN HasSparseMemory; //EFI_VIRTUAL_ADDRESS SparseMemoryBase; //UINT64 SparseMemorySize; EFI_PEI_HOB_POINTERS NextHob; ASSERT (VirtualMemoryMap != NULL); VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } if (FeaturePcdGet(PcdCacheEnable) == TRUE) { CacheAttributes = DDR_ATTRIBUTES_CACHED; } else { CacheAttributes = DDR_ATTRIBUTES_UNCACHED; } /* // ReMap (Either NOR Flash or DRAM) VirtualMemoryTable[Index].PhysicalBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].VirtualBase = ARM_VE_REMAP_BASE; VirtualMemoryTable[Index].Length = ARM_VE_REMAP_SZ; if (FeaturePcdGet(PcdNorFlashRemapping) == FALSE) { // Map the NOR Flash as Secure Memory if (FeaturePcdGet(PcdCacheEnable) == TRUE) { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; } else { VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_UNCACHED; } } else { // DRAM mapping VirtualMemoryTable[Index].Attributes = CacheAttributes; } */ Index = OemSetVirtualMapDesc(VirtualMemoryTable, CacheAttributes); // Search for System Memory Hob that contains the EFI resource system memory s00296804 NextHob.Raw = GetHobList (); while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) { if (NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { if (NextHob.ResourceDescriptor->PhysicalStart > BASE_4GB) { VirtualMemoryTable[++Index].PhysicalBase = NextHob.ResourceDescriptor->PhysicalStart; VirtualMemoryTable[Index].VirtualBase = NextHob.ResourceDescriptor->PhysicalStart; VirtualMemoryTable[Index].Length =NextHob.ResourceDescriptor->ResourceLength; VirtualMemoryTable[Index].Attributes = CacheAttributes; } } NextHob.Raw = GET_NEXT_HOB (NextHob); } // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); DEBUG((EFI_D_ERROR, "[%a]:[%dL] discriptor count=%d\n", __FUNCTION__, __LINE__, Index+1)); *VirtualMemoryMap = VirtualMemoryTable; }
/** Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended consumption, the firmware may process the capsule immediately. If the payload should persist across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must be passed into ResetSystem() and will cause the capsule to be processed by the firmware as part of the reset process. @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules being passed into update capsule. @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in CaspuleHeaderArray. @param ScatterGatherList Physical pointer to a set of EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the location in physical memory of a set of capsules. @retval EFI_SUCCESS Valid capsule was passed. If CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the capsule has been successfully processed by the firmware. @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were set in the capsule header. @retval EFI_INVALID_PARAMETER CapsuleCount is Zero. @retval EFI_INVALID_PARAMETER For across reset capsule image, ScatterGatherList is NULL. @retval EFI_UNSUPPORTED CapsuleImage is not recognized by the firmware. @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule is compatible with this platform but is not capable of being submitted or processed in runtime. The caller may resubmit the capsule prior to ExitBootServices(). @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates the capsule is compatible with this platform but there are insufficient resources to process. **/ EFI_STATUS EFIAPI UpdateCapsule ( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL ) { UINTN ArrayNumber; EFI_STATUS Status; EFI_CAPSULE_HEADER *CapsuleHeader; BOOLEAN NeedReset; BOOLEAN InitiateReset; CHAR16 CapsuleVarName[30]; CHAR16 *TempVarName; // // Capsule Count can't be less than one. // if (CapsuleCount < 1) { return EFI_INVALID_PARAMETER; } NeedReset = FALSE; InitiateReset = FALSE; CapsuleHeader = NULL; CapsuleVarName[0] = 0; for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { // // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well. // CapsuleHeader = CapsuleHeaderArray[ArrayNumber]; if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) { return EFI_INVALID_PARAMETER; } // // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must have // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well. // if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) { return EFI_INVALID_PARAMETER; } // // Check FMP capsule flag // if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid) && (CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 ) { return EFI_INVALID_PARAMETER; } // // Check Capsule image without populate flag by firmware support capsule function // if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) { Status = SupportCapsuleImage (CapsuleHeader); if (EFI_ERROR(Status)) { return Status; } } } // // Walk through all capsules, record whether there is a capsule needs reset // or initiate reset. And then process capsules which has no reset flag directly. // for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) { CapsuleHeader = CapsuleHeaderArray[ArrayNumber]; // // Here should be in the boot-time for non-reset capsule image // Platform specific update for the non-reset capsule image. // if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) { if (EfiAtRuntime ()) { Status = EFI_OUT_OF_RESOURCES; } else { Status = ProcessCapsuleImage(CapsuleHeader); } if (EFI_ERROR(Status)) { return Status; } } else { NeedReset = TRUE; if ((CapsuleHeader->Flags & CAPSULE_FLAGS_INITIATE_RESET) != 0) { InitiateReset = TRUE; } } } // // After launching all capsules who has no reset flag, if no more capsules claims // for a system reset just return. // if (!NeedReset) { return EFI_SUCCESS; } // // ScatterGatherList is only referenced if the capsules are defined to persist across // system reset. // if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) { return EFI_INVALID_PARAMETER; } // // Check if the platform supports update capsule across a system reset // if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) { return EFI_UNSUPPORTED; } // // Construct variable name CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2... // if user calls UpdateCapsule multiple times. // StrCpy (CapsuleVarName, EFI_CAPSULE_VARIABLE_NAME); TempVarName = CapsuleVarName + StrLen (CapsuleVarName); if (mTimes > 0) { UnicodeValueToString (TempVarName, 0, mTimes, 0); } // // ScatterGatherList is only referenced if the capsules are defined to persist across // system reset. Set its value into NV storage to let pre-boot driver to pick it up // after coming through a system reset. // Status = EfiSetVariable ( CapsuleVarName, &gEfiCapsuleVendorGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof (UINTN), (VOID *) &ScatterGatherList ); if (!EFI_ERROR (Status)) { // // Variable has been set successfully, increase variable index. // mTimes++; if(InitiateReset) { // // Firmware that encounters a capsule which has the CAPSULE_FLAGS_INITIATE_RESET Flag set in its header // will initiate a reset of the platform which is compatible with the passed-in capsule request and will // not return back to the caller. // EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); } } return Status; }
/** Perform the memory test base on the memory test intensive level, and update the memory resource. @param Level The memory test intensive level. @retval EFI_STATUS Success test all the system memory and update the memory resource **/ EFI_STATUS EFIAPI BdsMemoryTest ( IN EXTENDMEM_COVERAGE_LEVEL Level ) { EFI_STATUS Status; EFI_STATUS KeyStatus; EFI_STATUS InitStatus; EFI_STATUS ReturnStatus; BOOLEAN RequireSoftECCInit; EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest; UINT64 TestedMemorySize; UINT64 TotalMemorySize; UINTN TestPercent; UINT64 PreviousValue; BOOLEAN ErrorOut; BOOLEAN TestAbort; EFI_INPUT_KEY Key; CHAR16 StrPercent[80]; CHAR16 *StrTotalMemory; CHAR16 *Pos; CHAR16 *TmpStr; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; BOOLEAN IsFirstBoot; UINT32 TempData; UINTN StrTotalMemorySize; ReturnStatus = EFI_SUCCESS; ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); StrTotalMemorySize = 128; Pos = AllocateZeroPool (StrTotalMemorySize); if (Pos == NULL) { return ReturnStatus; } StrTotalMemory = Pos; TestedMemorySize = 0; TotalMemorySize = 0; PreviousValue = 0; ErrorOut = FALSE; TestAbort = FALSE; SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); RequireSoftECCInit = FALSE; Status = gBS->LocateProtocol ( &gEfiGenericMemTestProtocolGuid, NULL, (VOID **) &GenMemoryTest ); if (EFI_ERROR (Status)) { FreePool (Pos); return EFI_SUCCESS; } InitStatus = GenMemoryTest->MemoryTestInit ( GenMemoryTest, Level, &RequireSoftECCInit ); if (InitStatus == EFI_NO_MEDIA) { // // The PEI codes also have the relevant memory test code to check the memory, // it can select to test some range of the memory or all of them. If PEI code // checks all the memory, this BDS memory test will has no not-test memory to // do the test, and then the status of EFI_NO_MEDIA will be returned by // "MemoryTestInit". So it does not need to test memory again, just return. // FreePool (Pos); return EFI_SUCCESS; } if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST)); if (TmpStr != NULL) { PrintXY (10, 10, NULL, NULL, TmpStr); FreePool (TmpStr); } } else { DEBUG ((EFI_D_INFO, "Enter memory test.\n")); } do { Status = GenMemoryTest->PerformMemoryTest ( GenMemoryTest, &TestedMemorySize, &TotalMemorySize, &ErrorOut, TestAbort ); if (ErrorOut && (Status == EFI_DEVICE_ERROR)) { TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR)); if (TmpStr != NULL) { PrintXY (10, 10, NULL, NULL, TmpStr); FreePool (TmpStr); } ASSERT (0); } if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { TempData = (UINT32) DivU64x32 (TotalMemorySize, 16); TestPercent = (UINTN) DivU64x32 ( DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16), TempData ); if (TestPercent != PreviousValue) { UnicodeValueToStringS (StrPercent, sizeof (StrPercent), 0, TestPercent, 0); TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT)); if (TmpStr != NULL) { // // TmpStr size is 64, StrPercent is reserved to 16. // StrnCatS ( StrPercent, sizeof (StrPercent) / sizeof (CHAR16), TmpStr, sizeof (StrPercent) / sizeof (CHAR16) - StrLen (StrPercent) - 1 ); PrintXY (10, 10, NULL, NULL, StrPercent); FreePool (TmpStr); } TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST)); if (TmpStr != NULL) { PlatformBdsShowProgress ( Foreground, Background, TmpStr, Color, TestPercent, (UINTN) PreviousValue ); FreePool (TmpStr); } } PreviousValue = TestPercent; } else { DEBUG ((EFI_D_INFO, "Perform memory test (ESC to skip).\n")); } if (!PcdGetBool (PcdConInConnectOnDemand)) { KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) { if (!RequireSoftECCInit) { if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST)); if (TmpStr != NULL) { PlatformBdsShowProgress ( Foreground, Background, TmpStr, Color, 100, (UINTN) PreviousValue ); FreePool (TmpStr); } PrintXY (10, 10, NULL, NULL, L"100"); } Status = GenMemoryTest->Finished (GenMemoryTest); goto Done; } TestAbort = TRUE; } } } while (Status != EFI_NOT_FOUND); Status = GenMemoryTest->Finished (GenMemoryTest); Done: if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { UnicodeValueToStringS (StrTotalMemory, StrTotalMemorySize, COMMA_TYPE, TotalMemorySize, 0); if (StrTotalMemory[0] == L',') { StrTotalMemory++; StrTotalMemorySize -= sizeof (CHAR16); } TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED)); if (TmpStr != NULL) { StrnCatS ( StrTotalMemory, StrTotalMemorySize / sizeof (CHAR16), TmpStr, StrTotalMemorySize / sizeof (CHAR16) - StrLen (StrTotalMemory) - 1 ); FreePool (TmpStr); } PrintXY (10, 10, NULL, NULL, StrTotalMemory); PlatformBdsShowProgress ( Foreground, Background, StrTotalMemory, Color, 100, (UINTN) PreviousValue ); } else { DEBUG ((EFI_D_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize)); } FreePool (Pos); // // Use a DynamicHii type pcd to save the boot status, which is used to // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration. // IsFirstBoot = PcdGetBool(PcdBootState); if (IsFirstBoot) { Status = PcdSetBoolS(PcdBootState, FALSE); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Set PcdBootState to FALSE failed.\n")); } } return ReturnStatus; }
/** Prepares all information that is needed in the S3 resume boot path. Allocate the resources or prepare informations and save in ACPI variable set for S3 resume boot path @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance. @param LegacyMemoryAddress The base address of legacy memory. @retval EFI_NOT_FOUND Some necessary information cannot be found. @retval EFI_SUCCESS All information was saved successfully. @retval EFI_OUT_OF_RESOURCES Resources were insufficient to save all the information. @retval EFI_INVALID_PARAMETER The memory range is not located below 1 MB. **/ EFI_STATUS EFIAPI S3Ready ( IN EFI_ACPI_S3_SAVE_PROTOCOL *This, IN VOID *LegacyMemoryAddress ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS AcpiS3ContextBuffer; ACPI_S3_CONTEXT *AcpiS3Context; STATIC BOOLEAN AlreadyEntered; IA32_DESCRIPTOR *Idtr; IA32_IDT_GATE_DESCRIPTOR *IdtGate; DEBUG ((EFI_D_INFO, "S3Ready!\n")); // // Platform may invoke AcpiS3Save->S3Save() before ExitPmAuth, because we need save S3 information there, while BDS ReadyToBoot may invoke it again. // So if 2nd S3Save() is triggered later, we need ignore it. // if (AlreadyEntered) { return EFI_SUCCESS; } AlreadyEntered = TRUE; AcpiS3Context = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(*AcpiS3Context)); ASSERT (AcpiS3Context != NULL); AcpiS3ContextBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context; // // Get ACPI Table because we will save its position to variable // AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiFacsTable (); ASSERT (AcpiS3Context->AcpiFacsTable != 0); IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR)); Idtr = (IA32_DESCRIPTOR *)(IdtGate + 0x100); Idtr->Base = (UINTN)IdtGate; Idtr->Limit = (UINT16)(sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 - 1); AcpiS3Context->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)Idtr; Status = SaveLockBox ( &mAcpiS3IdtrProfileGuid, (VOID *)(UINTN)Idtr, (UINTN)sizeof(IA32_DESCRIPTOR) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&mAcpiS3IdtrProfileGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); // // Allocate page table // AcpiS3Context->S3NvsPageTableAddress = S3CreateIdentityMappingPageTables (); // // Allocate stack // AcpiS3Context->BootScriptStackSize = PcdGet32 (PcdS3BootScriptStackSize); AcpiS3Context->BootScriptStackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3BootScriptStackSize)); ASSERT (AcpiS3Context->BootScriptStackBase != 0); // // Allocate a code buffer < 4G for S3 debug to load external code // AcpiS3Context->S3DebugBufferAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGE_SIZE); DEBUG((EFI_D_INFO, "AcpiS3Context: AcpiFacsTable is 0x%8x\n", AcpiS3Context->AcpiFacsTable)); DEBUG((EFI_D_INFO, "AcpiS3Context: IdtrProfile is 0x%8x\n", AcpiS3Context->IdtrProfile)); DEBUG((EFI_D_INFO, "AcpiS3Context: S3NvsPageTableAddress is 0x%8x\n", AcpiS3Context->S3NvsPageTableAddress)); DEBUG((EFI_D_INFO, "AcpiS3Context: S3DebugBufferAddress is 0x%8x\n", AcpiS3Context->S3DebugBufferAddress)); Status = SaveLockBox ( &gEfiAcpiVariableGuid, &AcpiS3ContextBuffer, sizeof(AcpiS3ContextBuffer) ); ASSERT_EFI_ERROR (Status); Status = SaveLockBox ( &gEfiAcpiS3ContextGuid, (VOID *)(UINTN)AcpiS3Context, (UINTN)sizeof(*AcpiS3Context) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&gEfiAcpiS3ContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); if (FeaturePcdGet(PcdFrameworkCompatibilitySupport)) { S3ReadyThunkPlatform (AcpiS3Context); } return EFI_SUCCESS; }
/** The user Entry Point for English module. This function initializes unicode character mapping and then installs Unicode Collation & Unicode Collation 2 Protocols based on the feature flags. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI InitializeUnicodeCollationEng ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Index; UINTN Index2; // // Initialize mapping tables for the supported languages // for (Index = 0; Index < MAP_TABLE_SIZE; Index++) { mEngUpperMap[Index] = (CHAR8) Index; mEngLowerMap[Index] = (CHAR8) Index; mEngInfoMap[Index] = 0; if ((Index >= 'a' && Index <= 'z') || (Index >= 0xe0 && Index <= 0xf6) || (Index >= 0xf8 && Index <= 0xfe)) { Index2 = Index - 0x20; mEngUpperMap[Index] = (CHAR8) Index2; mEngLowerMap[Index2] = (CHAR8) Index; mEngInfoMap[Index] |= CHAR_FAT_VALID; mEngInfoMap[Index2] |= CHAR_FAT_VALID; } } for (Index = 0; mOtherChars[Index] != 0; Index++) { Index2 = mOtherChars[Index]; mEngInfoMap[Index2] |= CHAR_FAT_VALID; } if (FeaturePcdGet (PcdUnicodeCollation2Support)) { if (FeaturePcdGet (PcdUnicodeCollationSupport)) { Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiUnicodeCollationProtocolGuid, &UnicodeEng, &gEfiUnicodeCollation2ProtocolGuid, &Unicode2Eng, NULL ); ASSERT_EFI_ERROR (Status); } else { Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiUnicodeCollation2ProtocolGuid, &Unicode2Eng, NULL ); ASSERT_EFI_ERROR (Status); } } else { if (FeaturePcdGet (PcdUnicodeCollationSupport)) { Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiUnicodeCollationProtocolGuid, &UnicodeEng, NULL ); ASSERT_EFI_ERROR (Status); } else { // // This module must support to produce at least one of Unicode Collation Protocol // and Unicode Collation 2 Protocol. // ASSERT (FALSE); Status = EFI_UNSUPPORTED; } } return Status; }