From: Laszlo Ersek <lersek@redhat.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>, edk2-devel@lists.01.org
Cc: leif.lindholm@linaro.org
Subject: Re: [PATCH 06/15] ArmVirtPkg/PrePi: move DRAM discovery code into PrePi
Date: Tue, 21 Nov 2017 16:48:43 +0100 [thread overview]
Message-ID: <83175ecf-3400-5e20-217b-7483a8eac964@redhat.com> (raw)
In-Reply-To: <20171117160913.17292-7-ard.biesheuvel@linaro.org>
On 11/17/17 17:09, Ard Biesheuvel wrote:
> ArmVirtQemuKernel and ArmVirtXen use essentially the same code to
> retrieve DRAM information from the DT /memory node at early boot,
> and invoke it via the ArmPlatformPeiBootAction () hook exposed by
> ArmPlatformLib. Let's move this code into the PrePi implementation
> these platforms share between them (and not with any other platforms)
> so we can eliminate another dependency on the messy ArmPlatformLib.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 77 ++++++++++++++++-
> ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S | 71 +++++++++++++++
> ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 2 +
> ArmVirtPkg/PrePi/FdtParser.c | 90 ++++++++++++++++++++
> 4 files changed, 238 insertions(+), 2 deletions(-)
>
> diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
> index 7a9c0c3787cc..3296aedfe9aa 100644
> --- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
> +++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
> @@ -49,8 +49,7 @@ ASM_FUNC(_ModuleEntryPoint)
> b .Lreloc_loop
> .Lreloc_done:
>
> - // Do early platform specific actions
> - bl ASM_PFX(ArmPlatformPeiBootAction)
> + bl ASM_PFX(DiscoverDramFromDt)
>
> // Get ID of this CPU in Multicore system
> bl ASM_PFX(ArmReadMpidr)
> @@ -140,3 +139,77 @@ _GetStackBase:
>
> _NeverReturn:
> b _NeverReturn
> +
> +// VOID
> +// DiscoverDramFromDt (
> +// VOID *DeviceTreeBaseAddress, // passed by loader in x0
> +// VOID *ImageBase // passed by FDF trampoline in x1
> +// );
> +ASM_PFX(DiscoverDramFromDt):
> + //
> + // If we are booting from RAM using the Linux kernel boot protocol, x0 will
> + // point to the DTB image in memory. Otherwise, use the default value defined
> + // by the platform.
> + //
> + cbnz x0, 0f
> + ldr x0, PcdGet64 (PcdDeviceTreeInitialBaseAddress)
> +
> +0:mov x29, x30 // preserve LR
> + mov x28, x0 // preserve DTB pointer
> + mov x27, x1 // preserve base of image pointer
> +
> + //
> + // The base of the runtime image has been preserved in x1. Check whether
> + // the expected magic number can be found in the header.
> + //
> + ldr w8, .LArm64LinuxMagic
> + ldr w9, [x1, #0x38]
> + cmp w8, w9
> + bne .Lout
> +
> + //
> + //
> + // OK, so far so good. We have confirmed that we likely have a DTB and are
> + // booting via the arm64 Linux boot protocol. Update the base-of-image PCD
> + // to the actual relocated value, and add the shift of PcdFdBaseAddress to
> + // PcdFvBaseAddress as well
> + //
> + adr x8, PcdGet64 (PcdFdBaseAddress)
> + adr x9, PcdGet64 (PcdFvBaseAddress)
> + ldr x6, [x8]
> + ldr x7, [x9]
> + sub x7, x7, x6
> + add x7, x7, x1
> + str x1, [x8]
> + str x7, [x9]
> +
> + //
> + // Discover the memory size and offset from the DTB, and record in the
> + // respective PCDs. This will also return false if a corrupt DTB is
> + // encountered. Since we are calling a C function, use the window at the
> + // beginning of the FD image as a temp stack.
> + //
> + adr x1, PcdGet64 (PcdSystemMemoryBase)
> + adr x2, PcdGet64 (PcdSystemMemorySize)
> + mov sp, x7
> + bl FindMemnode
> + cbz x0, .Lout
> +
> + //
> + // Copy the DTB to the slack space right after the 64 byte arm64/Linux style
> + // image header at the base of this image (defined in the FDF), and record the
> + // pointer in PcdDeviceTreeInitialBaseAddress.
> + //
> + adr x8, PcdGet64 (PcdDeviceTreeInitialBaseAddress)
> + add x27, x27, #0x40
> + str x27, [x8]
> +
> + mov x0, x27
> + mov x1, x28
> + bl CopyFdt
> +
> +.Lout:
> + ret x29
> +
> +.LArm64LinuxMagic:
> + .byte 0x41, 0x52, 0x4d, 0x64
> diff --git a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
> index eebf660acdb2..a918c191432e 100644
> --- a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
> +++ b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
> @@ -148,3 +148,74 @@ _GetStackBase:
>
> _NeverReturn:
> b _NeverReturn
> +
> +ASM_PFX(ArmPlatformPeiBootAction):
> + //
> + // If we are booting from RAM using the Linux kernel boot protocol, r0 will
> + // point to the DTB image in memory. Otherwise, use the default value defined
> + // by the platform.
> + //
> + teq r0, #0
> + bne 0f
> + LDRL (r0, PcdGet64 (PcdDeviceTreeInitialBaseAddress))
> +
> +0:mov r11, r14 // preserve LR
> + mov r10, r0 // preserve DTB pointer
> + mov r9, r1 // preserve base of image pointer
> +
> + //
> + // The base of the runtime image has been preserved in r1. Check whether
> + // the expected magic number can be found in the header.
> + //
> + ldr r8, .LArm32LinuxMagic
> + ldr r7, [r1, #0x24]
> + cmp r7, r8
> + bne .Lout
> +
> + //
> + //
> + // OK, so far so good. We have confirmed that we likely have a DTB and are
> + // booting via the ARM Linux boot protocol. Update the base-of-image PCD
> + // to the actual relocated value, and add the shift of PcdFdBaseAddress to
> + // PcdFvBaseAddress as well
> + //
> + ADRL (r8, PcdGet64 (PcdFdBaseAddress))
> + ADRL (r7, PcdGet64 (PcdFvBaseAddress))
> + ldr r6, [r8]
> + ldr r5, [r7]
> + sub r5, r5, r6
> + add r5, r5, r1
> + str r1, [r8]
> + str r5, [r7]
> +
> + //
> + // Discover the memory size and offset from the DTB, and record in the
> + // respective PCDs. This will also return false if a corrupt DTB is
> + // encountered. Since we are calling a C function, use the window at the
> + // beginning of the FD image as a temp stack.
> + //
> + ADRL (r1, PcdGet64 (PcdSystemMemoryBase))
> + ADRL (r2, PcdGet64 (PcdSystemMemorySize))
> + mov sp, r5
> + bl FindMemnode
> + teq r0, #0
> + beq .Lout
> +
> + //
> + // Copy the DTB to the slack space right after the 64 byte arm64/Linux style
> + // image header at the base of this image (defined in the FDF), and record the
> + // pointer in PcdDeviceTreeInitialBaseAddress.
> + //
> + ADRL (r8, PcdGet64 (PcdDeviceTreeInitialBaseAddress))
> + add r9, r9, #0x40
> + str r9, [r8]
> +
> + mov r0, r9
> + mov r1, r10
> + bl CopyFdt
> +
> +.Lout:
> + bx r11
> +
> +.LArm32LinuxMagic:
> + .byte 0x18, 0x28, 0x6f, 0x01
> diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
> index 1d79b1360c22..e816e9583da8 100755
> --- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
> +++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
> @@ -23,6 +23,7 @@ [Defines]
>
> [Sources]
> PrePi.c
> + FdtParser.c
>
> [Sources.AArch64]
> AArch64/ArchPrePi.c
> @@ -44,6 +45,7 @@ [Packages]
> [LibraryClasses]
> BaseLib
> DebugLib
> + FdtLib
> ArmLib
> IoLib
> TimerLib
> diff --git a/ArmVirtPkg/PrePi/FdtParser.c b/ArmVirtPkg/PrePi/FdtParser.c
> new file mode 100644
> index 000000000000..afdc81a8839d
> --- /dev/null
> +++ b/ArmVirtPkg/PrePi/FdtParser.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright (c) 2015, Linaro Ltd. All rights reserved.
> + *
> + * This program and the accompanying materials
> + * are licensed and made available under the terms and conditions of the BSD License
> + * which accompanies this distribution. The full text of the license may be found at
> + * http://opensource.org/licenses/bsd-license.php
> + *
> + * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> + */
> +
> +#include <Uefi.h>
> +#include <Include/libfdt.h>
> +
> +BOOLEAN
> +FindMemnode (
> + IN VOID *DeviceTreeBlob,
> + OUT UINT64 *SystemMemoryBase,
> + OUT UINT64 *SystemMemorySize
> + )
> +{
> + INT32 MemoryNode;
> + INT32 AddressCells;
> + INT32 SizeCells;
> + INT32 Length;
> + CONST INT32 *Prop;
> +
> + if (fdt_check_header (DeviceTreeBlob) != 0) {
> + return FALSE;
> + }
> +
> + //
> + // Look for a node called "memory" at the lowest level of the tree
> + //
> + MemoryNode = fdt_path_offset (DeviceTreeBlob, "/memory");
> + if (MemoryNode <= 0) {
> + return FALSE;
> + }
> +
> + //
> + // Retrieve the #address-cells and #size-cells properties
> + // from the root node, or use the default if not provided.
> + //
> + AddressCells = 1;
> + SizeCells = 1;
> +
> + Prop = fdt_getprop (DeviceTreeBlob, 0, "#address-cells", &Length);
> + if (Length == 4) {
> + AddressCells = fdt32_to_cpu (*Prop);
> + }
> +
> + Prop = fdt_getprop (DeviceTreeBlob, 0, "#size-cells", &Length);
> + if (Length == 4) {
> + SizeCells = fdt32_to_cpu (*Prop);
> + }
> +
> + //
> + // Now find the 'reg' property of the /memory node, and read the first
> + // range listed.
> + //
> + Prop = fdt_getprop (DeviceTreeBlob, MemoryNode, "reg", &Length);
> +
> + if (Length < (AddressCells + SizeCells) * sizeof (INT32)) {
> + return FALSE;
> + }
> +
> + *SystemMemoryBase = fdt32_to_cpu (Prop[0]);
> + if (AddressCells > 1) {
> + *SystemMemoryBase = (*SystemMemoryBase << 32) | fdt32_to_cpu (Prop[1]);
> + }
> + Prop += AddressCells;
> +
> + *SystemMemorySize = fdt32_to_cpu (Prop[0]);
> + if (SizeCells > 1) {
> + *SystemMemorySize = (*SystemMemorySize << 32) | fdt32_to_cpu (Prop[1]);
> + }
> +
> + return TRUE;
> +}
> +
> +VOID
> +CopyFdt (
> + IN VOID *FdtDest,
> + IN VOID *FdtSource
> + )
> +{
> + fdt_pack(FdtSource);
> + CopyMem (FdtDest, FdtSource, fdt_totalsize (FdtSource));
> +}
>
OK, this is where my curiosity about PrePi starts to wane :) /me checks
the diffstat.
Acked-by: Laszlo Ersek <lersek@redhat.com>
next prev parent reply other threads:[~2017-11-21 15:44 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-17 16:08 [PATCH 00/15] ArmVirtPkg: get rid of ArmPlatformLib Ard Biesheuvel
2017-11-17 16:08 ` [PATCH 01/15] ArmPlatformPkg/ArmPlatformLibNull: remove bogus PCD dependencies Ard Biesheuvel
2017-11-17 16:20 ` Leif Lindholm
2017-11-17 16:23 ` Ard Biesheuvel
2017-11-17 16:28 ` Leif Lindholm
2017-11-17 19:10 ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 02/15] ArmVirtPkg/PrePi: run all library constructors by hand Ard Biesheuvel
2017-11-21 15:32 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 03/15] ArmVirtPkg/PrePi: remove unused GetPlatformPpi() function Ard Biesheuvel
2017-11-21 15:36 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 04/15] ArmVirtPkg/PrePi: remove bogus primary core check Ard Biesheuvel
2017-11-21 15:40 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 05/15] ArmVirtPkg/PrePi: remove dependency on ArmPlatformLib Ard Biesheuvel
2017-11-21 15:46 ` Laszlo Ersek
2017-11-21 15:47 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 06/15] ArmVirtPkg/PrePi: move DRAM discovery code into PrePi Ard Biesheuvel
2017-11-21 15:48 ` Laszlo Ersek [this message]
2017-11-17 16:09 ` [PATCH 07/15] ArmVirtPkg/PrePi: remove ArmPlatformStackLib dependency Ard Biesheuvel
2017-11-21 15:51 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 08/15] ArmVirtPkg/PrePi: remove bogus IntelFrameworkModulePkg.dec dependency Ard Biesheuvel
2017-11-21 15:52 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 09/15] ArmVirtPkg/ArmVirtPlatformLib: remove support for uncached mappings Ard Biesheuvel
2017-11-21 16:15 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 10/15] ArmVirtPkg: introduce ArmVirtMemInfoLib library class Ard Biesheuvel
2017-11-21 16:23 ` Laszlo Ersek
2017-11-21 16:27 ` Laszlo Ersek
2017-11-21 16:32 ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 11/15] ArmVirtPkg/ArmVirtXen: add ArmVirtMemInfoLib implementation Ard Biesheuvel
2017-11-21 16:30 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 12/15] ArmVirtPkg/ArmVirtQemu: " Ard Biesheuvel
2017-11-21 16:47 ` Ard Biesheuvel
2017-11-21 16:56 ` Laszlo Ersek
2017-11-21 17:11 ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 13/15] ArmVirtPkg: implement ArmVirtMemInfo PPI, PEIM and library Ard Biesheuvel
2017-11-21 17:49 ` Laszlo Ersek
2017-11-21 17:57 ` Ard Biesheuvel
2017-11-21 20:17 ` Laszlo Ersek
2017-11-21 20:32 ` Ard Biesheuvel
2017-11-22 8:45 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 14/15] ArmVirtPkg/ArmVirtMemoryInitPeiLib: move to ArmVirtMemInfoLib Ard Biesheuvel
2017-11-21 17:51 ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 15/15] ArmVirtPkg: remove ArmPlatformLib implementations Ard Biesheuvel
2017-11-21 17:52 ` Laszlo Ersek
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=83175ecf-3400-5e20-217b-7483a8eac964@redhat.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