public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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>


  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