From: oliviermartin Date: Sun, 12 May 2013 23:54:16 +0000 (+0000) Subject: ArmPkg/BdsLinuxFdt.c: Split PrepareFdt() into several functions. X-Git-Tag: edk2-stable201903~12550 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=cc9f215770a96fcbb897afb7f598f02d329a5955;p=mirror_edk2.git ArmPkg/BdsLinuxFdt.c: Split PrepareFdt() into several functions. PrepareFdt() function was getting pretty fat and big functions are more complex to understand and find the information one is looking for. This patch extracts some code from PrepareFdt() function and put it in some new functions. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin AllocatePages (AllocateMaxAddress, EfiBootServicesData, + EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_WARN, "Warning: Failed to load FDT below address 0x%lX (%r). Will try again at a random address anywhere.\n", *RelocatedFdt, Status)); + } + } + + // Try anywhere there is available space. + if (EFI_ERROR (Status)) { + Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, + EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return EFI_OUT_OF_RESOURCES; + } else { + DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", *RelocatedFdt)); + } + } + + *RelocatedFdtAlloc = *RelocatedFdt; + if (FdtAlignment != 0) { + *RelocatedFdt = ALIGN (*RelocatedFdt, FdtAlignment); + } + + // Load the Original FDT tree into the new region + Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt, + (VOID*)(UINTN)(*RelocatedFdt), *RelocatedFdtSize); + if (Error) { + DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Error))); + gBS->FreePages (*RelocatedFdtAlloc, EFI_SIZE_TO_PAGES (*RelocatedFdtSize)); + return EFI_INVALID_PARAMETER; + } + + DEBUG_CODE_BEGIN(); + //DebugDumpFdt (fdt); + DEBUG_CODE_END(); + + return EFI_SUCCESS; +} + EFI_STATUS PrepareFdt ( @@ -216,7 +322,6 @@ PrepareFdt ( EFI_PHYSICAL_ADDRESS NewFdtBlobBase; EFI_PHYSICAL_ADDRESS NewFdtBlobAllocation; UINTN NewFdtBlobSize; - UINT32 FdtAlignment; VOID* fdt; INTN err; INTN node; @@ -244,35 +349,10 @@ PrepareFdt ( UINT32 DescriptorVersion; UINTN Pages; BOOLEAN PsciSmcSupported; - UINTN Rx; UINTN OriginalFdtSize; BOOLEAN CpusNodeExist; - // - // Ensure the Power State Coordination Interface (PSCI) SMCs are there if supported - // - PsciSmcSupported = FALSE; - if (FeaturePcdGet (PcdArmPsciSupport) == TRUE) { - // Check the SMC response to the Presence SMC - Rx = ARM_SMC_ID_PRESENCE; - ArmCallSmc (&Rx); - if (Rx == 1) { - // Check the SMC UID - Rx = ARM_SMC_ID_UID; - ArmCallSmc (&Rx); - if (Rx == ARM_TRUSTZONE_UID_4LETTERID) { - Rx = ARM_SMC_ID_UID + 1; - ArmCallSmc (&Rx); - if (Rx == ARM_TRUSTZONE_ARM_UID) { - PsciSmcSupported = TRUE; - } - } - if (PsciSmcSupported == FALSE) { - DEBUG((EFI_D_ERROR,"Warning: The Power State Coordination Interface (PSCI) is not supported" - "by your platform Trusted Firmware.\n")); - } - } - } + NewFdtBlobAllocation = 0; // // Sanity checks on the original FDT blob. @@ -293,63 +373,35 @@ PrepareFdt ( } // - // Allocate memory for the new FDT + // Relocate the FDT to its final location. // - NewFdtBlobSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE; - - // If FDT load address needs to be aligned, allocate more space. - FdtAlignment = PcdGet32 (PcdArmLinuxFdtAlignment); - if (FdtAlignment != 0) { - NewFdtBlobSize += FdtAlignment; + Status = RelocateFdt (*FdtBlobBase, OriginalFdtSize, + &NewFdtBlobBase, &NewFdtBlobSize, &NewFdtBlobAllocation); + if (EFI_ERROR (Status)) { + goto FAIL_RELOCATE_FDT; } - // Try below a watermark address - Status = EFI_NOT_FOUND; - if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) { - NewFdtBlobBase = LINUX_FDT_MAX_OFFSET; - Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_WARN, "Warning: Failed to load FDT below address 0x%lX (%r). Will try again at a random address anywhere.\n", NewFdtBlobBase, Status)); - } - } - - // Try anywhere there is available space - if (EFI_ERROR(Status)) { - Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase); - if (EFI_ERROR(Status)) { - ASSERT_EFI_ERROR(Status); - goto FAIL_ALLOCATE_NEW_FDT; - } else { - DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", NewFdtBlobBase)); + // + // Ensure the Power State Coordination Interface (PSCI) SMCs are there if supported + // + PsciSmcSupported = FALSE; + if (FeaturePcdGet (PcdArmPsciSupport) == TRUE) { + PsciSmcSupported = IsPsciSmcSupported(); + if (PsciSmcSupported == FALSE) { + DEBUG ((EFI_D_ERROR, "Warning: The Power State Coordination Interface (PSCI) is not supported by your platform Trusted Firmware.\n")); } } - NewFdtBlobAllocation = NewFdtBlobBase; - if (FdtAlignment != 0) { - NewFdtBlobBase = ALIGN (NewFdtBlobBase, FdtAlignment); - } - - // Load the Original FDT tree into the new region fdt = (VOID*)(UINTN)NewFdtBlobBase; - err = fdt_open_into((VOID*)(UINTN)(*FdtBlobBase), fdt, NewFdtBlobSize); - if (err) { - DEBUG((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror(err))); - Status = EFI_INVALID_PARAMETER; - goto FAIL_NEW_FDT; - } - DEBUG_CODE_BEGIN(); - //DebugDumpFdt (fdt); - DEBUG_CODE_END(); - - node = fdt_subnode_offset(fdt, 0, "chosen"); + node = fdt_subnode_offset (fdt, 0, "chosen"); if (node < 0) { // The 'chosen' node does not exist, create it node = fdt_add_subnode(fdt, 0, "chosen"); if (node < 0) { DEBUG((EFI_D_ERROR,"Error on finding 'chosen' node\n")); Status = EFI_INVALID_PARAMETER; - goto FAIL_NEW_FDT; + goto FAIL_COMPLETE_FDT; } } @@ -519,7 +571,7 @@ PrepareFdt ( if (node < 0) { DEBUG((EFI_D_ERROR,"Error on creating 'psci' node\n")); Status = EFI_INVALID_PARAMETER; - goto FAIL_NEW_FDT; + goto FAIL_COMPLETE_FDT; } else { fdt_setprop_string(fdt, node, "compatible", "arm,psci"); fdt_setprop_string(fdt, node, "method", "smc"); @@ -542,13 +594,12 @@ PrepareFdt ( *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase)); return EFI_SUCCESS; -FAIL_NEW_FDT: +FAIL_COMPLETE_FDT: gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); -FAIL_ALLOCATE_NEW_FDT: +FAIL_RELOCATE_FDT: *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase)); - // Return success even if we failed to update the FDT blob. The original one is still valid. + // Return success even if we failed to update the FDT blob. + // The original one is still valid. return EFI_SUCCESS; } - -