When the payload runs under an outer UEFI (via ChainloadApp) the PL031 register range is already present in the GCD map because UefiPayloadEntry publishes every MMIO region reported by the bootloader as EfiGcdMemoryTypeMemoryMappedIo. AddMemorySpace() then returns EFI_ACCESS_DENIED and LibRtcInitialize() bails out, so the runtime clock is never installed.
Tolerate that case: query the existing descriptor and proceed only if it is already MemoryMappedIo. Since the pre-existing descriptor typically does not advertise EFI_MEMORY_RUNTIME in its Capabilities, extend the capability set before SetMemorySpaceAttributes() so the RUNTIME attribute can be applied. The check keeps the original error handling for genuine conflicts (system RAM, or a range owned by another driver). A platform where this driver legitimately owns the range still takes the AddMemorySpace() success path, and previously EFI_ACCESS_DENIED meant the RTC was simply not installed -- so no platform that works today can regress. ChainloadApp, added later in this series, is the motivating case. Cc: Ard Biesheuvel <[email protected]> Cc: Leif Lindholm <[email protected]> Cc: Sami Mujawar <[email protected]> Assisted-by: claude-opus-5 Signed-off-by: Alexander Graf <[email protected]> --- .../PL031RealTimeClockLib.c | 66 ++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c index fb353cf2df..2b4b9d0754 100644 --- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c +++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c @@ -321,7 +321,8 @@ LibRtcInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc; // Initialize RTC Base Address mPL031RtcBase = PcdGet32 (PcdPL031RtcBase); @@ -333,7 +334,68 @@ LibRtcInitialize ( SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP ); - if (EFI_ERROR (Status)) { + if (Status == EFI_ACCESS_DENIED) { + // + // The range is already present in the GCD map, e.g. because a + // preceding platform driver or the payload's own MMIO discovery + // added it. That is only acceptable if the existing descriptor + // is MMIO; refuse to touch anything else. + // + Status = gDS->GetMemorySpaceDescriptor (mPL031RtcBase, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // AddMemorySpace() reports EFI_ACCESS_DENIED if any part of the + // requested range is already present, while GetMemorySpaceDescriptor() + // only returns the descriptor that contains the base address. The + // descriptor therefore says nothing about the rest of the range: a + // request that straddles this descriptor and another one would be + // accepted on the strength of the first descriptor alone. Require the + // whole range to lie inside it. + // + if ((Desc.BaseAddress > mPL031RtcBase) || + ((Desc.BaseAddress + Desc.Length) < + ((UINT64)mPL031RtcBase + SIZE_4KB))) + { + return EFI_ACCESS_DENIED; + } + + if ((Desc.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) || + (Desc.ImageHandle != NULL)) + { + return EFI_ACCESS_DENIED; + } + + // + // A pre-existing MMIO descriptor need not carry every capability that + // the SetMemorySpaceAttributes() call below requests, and + // CoreSetMemorySpaceAttributes() rejects any attribute that is absent + // from Capabilities with EFI_UNSUPPORTED. Add the full set that is + // about to be requested, not just EFI_MEMORY_RUNTIME. + // + if ((Desc.Capabilities & + (EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP)) != + (EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP)) + { + Status = gDS->SetMemorySpaceCapabilities ( + mPL031RtcBase, + SIZE_4KB, + Desc.Capabilities | EFI_MEMORY_UC | + EFI_MEMORY_RUNTIME | EFI_MEMORY_XP + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_WARN, + "%a: SetMemorySpaceCapabilities() failed: %r\n", + __func__, + Status + )); + return Status; + } + } + } else if (EFI_ERROR (Status)) { return Status; } -- 2.47.3 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#122083): https://edk2.groups.io/g/devel/message/122083 Mute This Topic: https://groups.io/mt/120797179/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
