VOID CEntryPoint ( IN UINTN MpId, IN UINTN UefiMemoryBase, IN UINTN StacksBase ) { UINT64 StartTimeStamp; // Initialize the platform specific controllers ArmPlatformInitialize (MpId); if (PerformanceMeasurementEnabled ()) { // Initialize the Timer Library to setup the Timer HW controller TimerConstructor (); // We cannot call yet the PerformanceLib because the HOB List has not been initialized StartTimeStamp = GetPerformanceCounter (); } else { StartTimeStamp = 0; } // Data Cache enabled on Primary core when MMU is enabled. ArmDisableDataCache (); // Invalidate instruction cache ArmInvalidateInstructionCache (); // Enable Instruction Caches on all cores. ArmEnableInstructionCache (); PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp); // DXE Core should always load and never return ASSERT (FALSE); }
VOID CEntryPoint ( IN UINTN MpId, IN UINTN UefiMemoryBase, IN UINTN StacksBase, IN UINTN GlobalVariableBase ) { UINT64 StartTimeStamp; ASSERT(!ArmIsMpCore() || (PcdGet32 (PcdCoreCount) > 1)); // Initialize the platform specific controllers ArmPlatformInitialize (MpId); if (ArmPlatformIsPrimaryCore (MpId) && PerformanceMeasurementEnabled ()) { // Initialize the Timer Library to setup the Timer HW controller TimerConstructor (); // We cannot call yet the PerformanceLib because the HOB List has not been initialized StartTimeStamp = GetPerformanceCounter (); } else { StartTimeStamp = 0; } // Data Cache enabled on Primary core when MMU is enabled. ArmDisableDataCache (); // Invalidate Data cache ArmInvalidateDataCache (); // Invalidate instruction cache ArmInvalidateInstructionCache (); // Enable Instruction Caches on all cores. ArmEnableInstructionCache (); // Define the Global Variable region when we are not running in XIP if (!IS_XIP()) { if (ArmPlatformIsPrimaryCore (MpId)) { mGlobalVariableBase = GlobalVariableBase; if (ArmIsMpCore()) { // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT) ArmCallSEV (); } } else { // Wait the Primay core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT) ArmCallWFE (); } } // If not primary Jump to Secondary Main if (ArmPlatformIsPrimaryCore (MpId)) { // Goto primary Main. PrimaryMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp); } else { SecondaryMain (MpId); } // DXE Core should always load and never return ASSERT (FALSE); }
/** Check whether the specified performance measurement can be logged. This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set. @param Type - Type of the performance measurement entry. @retval TRUE The performance measurement can be logged. @retval FALSE The performance measurement can NOT be logged. **/ BOOLEAN EFIAPI LogPerformanceMeasurementEnabled ( IN CONST UINTN Type ) { // // When Performance measurement is enabled and the type is not filtered, the performance can be logged. // if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) { return TRUE; } return FALSE; }
/** The constructor function initializes Performance infrastructure for DXE phase. The constructor function publishes Performance and PerformanceEx protocol, allocates memory to log DXE performance and merges PEI performance data to DXE performance log. It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. **/ EFI_STATUS EFIAPI DxeCorePerformanceLibConstructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; if (!PerformanceMeasurementEnabled ()) { // // Do not initialize performance infrastructure if not required. // return EFI_SUCCESS; } // // Install the protocol interfaces. // Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gPerformanceProtocolGuid, &mPerformanceInterface, &gPerformanceExProtocolGuid, &mPerformanceExInterface, NULL ); ASSERT_EFI_ERROR (Status); mMaxGaugeRecords = INIT_DXE_GAUGE_DATA_ENTRIES + PcdGet8 (PcdMaxPeiPerformanceLogEntries); mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords)); ASSERT (mGaugeData != NULL); InternalGetPeiPerformance (); return Status; }
STATIC EFI_STATUS StartLinux ( IN EFI_PHYSICAL_ADDRESS LinuxImage, IN UINTN LinuxImageSize, IN EFI_PHYSICAL_ADDRESS KernelParamsAddress, IN UINTN KernelParamsSize, IN UINT32 MachineType ) { EFI_STATUS Status; LINUX_KERNEL LinuxKernel; // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event. Status = ShutdownUefiBootServices (); if(EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status)); goto Exit; } // Move the kernel parameters to any address inside the first 1MB. // This is necessary because the ARM Linux kernel requires // the FTD / ATAG List to reside entirely inside the first 1MB of // physical memory. //Note: There is no requirement on the alignment if (MachineType != ARM_FDT_MACHINE_TYPE) { if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) { KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize); } } else { if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) { KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize); } } if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) { //Note: There is no requirement on the alignment LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize); } else { LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage; } // Check if the Linux Image is a uImage if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) { // Assume the Image Entry Point is just after the uImage header (64-byte size) LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64); LinuxImageSize -= 64; } // Check there is no overlapping between kernel and its parameters // We can only assert because it is too late to fallback to UEFI (ExitBootServices has been called). ASSERT (!IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress) && !IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress + KernelParamsSize)); // // Switch off interrupts, caches, mmu, etc // Status = PreparePlatformHardware (); ASSERT_EFI_ERROR(Status); // Register and print out performance information PERF_END (NULL, "BDS", NULL, 0); if (PerformanceMeasurementEnabled ()) { PrintPerformance (); } // // Start the Linux Kernel // // Outside BootServices, so can't use Print(); DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n")); // Jump to kernel with register set LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress); // Kernel should never exit // After Life services are not provided ASSERT(FALSE); Exit: // Only be here if we fail to start Linux Print (L"ERROR : Can not start the kernel. Status=0x%X\n", Status); // Free Runtimee Memory (kernel and FDT) return Status; }