From: "Ard Biesheuvel" <ard.biesheuvel@linaro.org>
To: edk2-devel-groups-io <devel@edk2.groups.io>,
Laszlo Ersek <lersek@redhat.com>
Subject: Re: [edk2-devel] [PATCH 3/4] ArmVirtPkg/PlatformPeiLib: implement Reset2 PPI based on PSCI
Date: Wed, 8 Jan 2020 10:59:47 +0100 [thread overview]
Message-ID: <CAKv+Gu9hPMsEPYcsnJcETz_T8cPAQawVQs1_vT6nyDfF36egKQ@mail.gmail.com> (raw)
In-Reply-To: <6fb4250c-b675-3562-2099-66ef9554752d@redhat.com>
On Tue, 7 Jan 2020 at 19:47, Laszlo Ersek <lersek@redhat.com> wrote:
>
> On 01/07/20 17:55, Ard Biesheuvel wrote:
> > On Tue, 7 Jan 2020 at 17:50, Laszlo Ersek <lersek@redhat.com> wrote:
> >>
> >> On 01/07/20 10:47, Ard Biesheuvel wrote:
> >>> Extend the existing DT traversal routine in PlatformPeiLib with
> >>> discovery of the PSCI method, and expose an implementation of the
> >>> Reset2 PPI based on the method found.
> >>>
> >>> This satisfies a dependency of Tcg2Pei, which needs to reset the
> >>> platform in some cases. Since there are no other uses for system
> >>> reset in PEI on ArmVirtQemu, simply expose the PPI directly rather
> >>> than using the generic ResetSystemPei and the associated plumbing.
> >>>
> >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >>> ---
> >>> ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 3 +
> >>> ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 123 ++++++++++++++++++++
> >>> 2 files changed, 126 insertions(+)
> >>
> >> Tcg2Pei uses ResetCold() from ResetSystemLib.
> >>
> >> ArmVirtPkg's existent ResetSystemLib instance
> >> (ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf) is only
> >> suitable for DXE_DRIVER and DXE_RUNTIME_DRIVER instances. It uses our
> >> FDT Client protocol for looking up (I think) more or less the same
> >> things that you parse here.
> >>
> >> As a PEI phase replacement, this patch produces gEfiPeiReset2PpiGuid,
> >> and then in patch#4, we resolve ResetSystemLib, for PEIMs, to the
> >>
> >> MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf
> >>
> >> instance, which depends on the PPI installed here.
> >>
> >> I'm not too happy about installing the gEfiPeiReset2PpiGuid from
> >> PlatformPeiLib.
> >>
> >> As replacement, it's not ResetSystemPei what I'd recommend (which
> >> depends on a PEI-phase ResetSystemLib instance anyway, which we don't
> >> have, in the first place).
> >>
> >> (1) Instead, I'd recommend implementing a PEI-phase ResetSystemLib for
> >> ArmVirtQemu. (Under ArmVirtPkg/Library/ArmVirtPsciResetSystemLib -- new
> >> INF file.)
> >>
> >> Would that be a large burden? I think we'd need a helper function in
> >> that lib instance, for returning HVC versus SMC (from the FDT), and then
> >> we'd have to call the proper interface for the actual reset. Not fast,
> >> but resets don't need to be fast I think.
> >>
> >
> > That is what I started out with. The problem is that I am not 100%
> > convinced that it is safe to dereference the initial FDT base address
> > at arbitrary times during PEI,
>
> Great point; this is one of those things that I had to think about for
> many minutes before posting my email.
>
> I think it's safe. For two reasons:
>
> (i) all of the PEIMs, and the PEI_CORE, in ArmVirtQemu, use the
>
> ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf
>
> instance for writing to the serial port. This library instance re-parses
> the initial DTB at every DEBUG call, in effect, across all the PEIMs.
>
> (See SerialPortWrite() --> SerialPortGetBaseAddress() -->
> PcdGet64(PcdDeviceTreeInitialBaseAddress)).
>
> In other words, we're already doing this, at the moment.
>
> (ii) In
>
> ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLibConstructor.c
>
> we have:
>
> //
> // We need to make sure that the machine we are running on has at least
> // 128 MB of memory configured, and is currently executing this binary from
> // NOR flash. This prevents a device tree image in DRAM from getting
> // clobbered when our caller installs permanent PEI RAM, before we have a
> // chance of marking its location as reserved or copy it to a freshly
> // allocated block in the permanent PEI RAM in the platform PEIM.
> //
> ASSERT (NewSize >= SIZE_128MB);
> ASSERT (
> (((UINT64)PcdGet64 (PcdFdBaseAddress) +
> (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||
> ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize)));
>
>
> To elaborate on this: initially we use the temporary SEC/PEI heap+stack;
> later on we use the permanent PEI RAM.
>
> (ii.1) The temp SEC/PEI heap+stack is set up in
>
> ArmPlatformPkg/PrePeiCore/MainUniCore.c
>
> and it is based on PcdCPUCoresStackBase. The value of
> PcdCPUCoresStackBase is fixed, in ArmVirtQemu.dsc:
>
> gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000
>
> whereas the initial DTB is at the base of DRAM:
>
> gArmTokenSpaceGuid.PcdSystemMemoryBase|0x40000000
> gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress|0x40000000
>
> so if the initial DTB fits in 0x7C000 bytes (496 KiB), we're good, as
> far as the temporary SEC/PEI heap+stack is concerned.
>
> (ii.2) The permanent PEI RAM is 64MB in size:
>
> # Size of the region used by UEFI in permanent memory (Reserved 64MB)
> gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
>
> Because of the *two* ASSERT()s in "QemuVirtMemInfoPeiLibConstructor.c"
> that I quoted above, we know that the lowest DRAM node is at least 128MB
> in size, and also that it does not overlap with the flash device.
> Consequently, the the InitializeMemory() function in
>
> ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.c
>
> will take the following branch:
>
> ------
> } else {
> // Check the Firmware does not overlapped with the system memory
> ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop));
> ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop));
>
> UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
> }
>
> Status = PeiServicesInstallPeiMemory (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
> ------
>
> and therefore
>
> UefiMemoryBase == (PcdSystemMemoryBase + PcdSystemMemorySize) - PcdSystemMemoryUefiRegionSize
> == 1GiB + PcdSystemMemorySize - 64MiB
>
> Given that PcdSystemMemorySize >= 128 MiB, we get
>
> UefiMemoryBase >= 1GiB + 64 MiB
>
> Which means that the permanent PEI RAM too is safely distinct from the
> initial DTB (which is at the base of DRAM: at 1 GiB).
>
> In summary: it's safe, and it's so by design. We did this intentionally.
> Originally in commit a36d531f5d56 ("ArmPlatformPkg/ArmVirtualizationPkg:
> add ArmVirtualizationPlatformLib library", 2014-09-18):
>
> commit a36d531f5d565e6cb5496ea53824e36487a227dd
> Author: Michael Casadevall <michael.casadevall@linaro.org>
> Date: Thu Sep 18 18:05:03 2014 +0000
>
> ArmPlatformPkg/ArmVirtualizationPkg: add ArmVirtualizationPlatformLib library
>
> This is an implementation of ArmPlatformLib that discovers the size of system
> DRAM from a device tree blob located at the address passed in
> gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress, which should equal the value in
> gArmTokenSpaceGuid.PcdSystemMemoryBase.
>
> As the device tree blob is passed in system DRAM, this library can only be used
> if sufficient DRAM is available (>= 128 MB) and if not using shadowed NOR. The
> reason for this is that it makes it easier to guarantee that such a device tree
> blob at base of DRAM will not be clobbered before we get a chance to preserve it.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Michael Casadevall <michael.casadevall@linaro.org>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Signed-off-By: Olivier Martin <olivier.martin@arm.com>
>
> And then we moved it to its present spot in the series that contains
> commit 048651260b66 ("ArmVirtPkg: create QemuVirtMemInfoLib version for
> ArmVirtQemu", 2017-11-23).
>
> > and so it would be better to consume
> > the FDT from the GUIDed HOB. That, however, creates another ordering
> > issue, and so we should install a PPI that signals the availability of
> > the FDT GUIDed HOB.
> >
> > At this point, I decided it would be better to just produce the PPI in
> > the PlatformPeiLib, but I agree it is not the cleanest approach.
> >
> >> BTW I think the following modules are never meant to be used together:
> >>
> >> MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf
> >> MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
> >>
> >> because they seem to depend mutually on each other's abstract interface
> >> (PPI vs. lib class). So I think a given platform should include *at most
> >> one* of these, on top of the "other" facility that it already exposes.
> >> In ArmVirtQemu's case, I'd suggest implementing the lib class for PEI,
> >> and then we can include "ResetSystemPei" whenever the need arises.
> >>
> >
> > The idea is that other PEIMs use the library, which is backed by the
> > PEIM, so that any hooks and notifications that occur at reset time can
> > be dispatched correctly. If every PEIM that needs to reset the system
> > calls into a library directly, this no longer works.
> >
>
> Good point -- now I realize my exclusivity argument above is wrong. I
> now recall why.
>
> The following is a quite common pattern in edk2:
>
> - there is a lib class offering some service, at the abstract level
> - there is a PEIM or DXE driver that exposes the same service as a PPI
> or protocol, respectively
> - this PEIM or DXE driver internally calls the lib API
> - there are two lib instances: one instance does the real thing, and the
> other instance calls out to the PPI or protocol
> - all PEIMs / DXE drivers *except* the one PEIM or DXE driver mentioned
> above get the "shim" lib instance
> - the one PEIM / DXE driver that exposes the PPI / protocol gets the
> "real deal" lib instance, via module-level lib class resolution
> override in the DSC file.
>
> We can do the same here, I think:
>
> - resolve ResetSystemLib, generally for PEIMs, to
> "MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf",
> - include "MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf" in
> the firmware binary,
> - resolve ResetSystemLib, specifically for "ResetSystemPei.inf", to our
> new (FDT-parsing) lib instance.
>
> How does it sound to you? Yes, it's more fluff, but it's clean, and
> native to edk2.
>
Yeah, I'm fine with all of that. Thanks for reminding me why it is
safe to refer to the DT at the base of memory throughout the PEI
phase.
next prev parent reply other threads:[~2020-01-08 10:00 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-07 9:47 [PATCH 0/4] ArmVirtPkg: implement measured boot for ArmVirtQemu Ard Biesheuvel
2020-01-07 9:47 ` [PATCH 1/4] OvmfPkg/Tcg2ConfigPei: introduce a signalling PPI to depex on Ard Biesheuvel
2020-01-07 11:58 ` Laszlo Ersek
2020-01-07 9:47 ` [PATCH 2/4] ArmVirtPkg/PlatformPeiLib: discover the TPM base address from the DT Ard Biesheuvel
2020-01-07 15:42 ` Laszlo Ersek
2020-01-08 14:41 ` Ard Biesheuvel
2020-01-09 13:04 ` Laszlo Ersek
2020-01-07 9:47 ` [PATCH 3/4] ArmVirtPkg/PlatformPeiLib: implement Reset2 PPI based on PSCI Ard Biesheuvel
2020-01-07 16:50 ` Laszlo Ersek
2020-01-07 16:55 ` [edk2-devel] " Ard Biesheuvel
2020-01-07 18:47 ` Laszlo Ersek
2020-01-08 9:59 ` Ard Biesheuvel [this message]
2020-01-07 9:48 ` [PATCH 4/4] ArmVirtPkg/ArmVirtQemu: add optional support for TPM2 measured boot Ard Biesheuvel
2020-01-07 17:37 ` Laszlo Ersek
2020-01-08 14:13 ` Ard Biesheuvel
2020-01-08 14:45 ` Laszlo Ersek
2020-01-09 0:51 ` Yao, Jiewen
2020-01-09 13:07 ` Laszlo Ersek
2020-01-10 0:32 ` Yao, Jiewen
2020-01-13 1:55 ` [edk2-devel] " Gary Lin
2020-01-13 15:56 ` Laszlo Ersek
2020-01-07 11:55 ` [PATCH 0/4] ArmVirtPkg: implement measured boot for ArmVirtQemu Laszlo Ersek
2020-01-07 12:04 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAKv+Gu9hPMsEPYcsnJcETz_T8cPAQawVQs1_vT6nyDfF36egKQ@mail.gmail.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox