public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates
@ 2016-09-15 13:30 Ard Biesheuvel
  2016-09-15 13:30 ` [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties Ard Biesheuvel
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 13:30 UTC (permalink / raw)
  To: edk2-devel, lersek; +Cc: zhaoshenglong, sakar.arora, Ard Biesheuvel

Patch #4 moves HighMemDxe to the FDT client protocol, and updates it to
handle #address-cells/#size-cells values of <1> as well as <2>, and lets
it deal with memory nodes whose 'reg' properties describe multiple disjoint
regions.

Patches #1 to #3 are somewhat preparatory in nature:
- Patch #1 is a small thinko fix
- Patch #2 drops the 'regelemsize' output parameter for 'reg' related methods
  of the FDT client protocol in favour of addresscells/sizecells.
- Patch #3 adds methods to iterate over all 'reg' properties of all memory nodes

Ard Biesheuvel (4):
  ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties
  ArmVirtPkg/FdtClientDxe: report address and size cell count directly
  ArmVirtPkg/FdtClient: add methods to iterate over memory nodes
  ArmVirtPkg/HighMemDxe: move to FDT client protocol

 ArmVirtPkg/FdtClientDxe/FdtClientDxe.c                   |  84 +++++++++++++-
 ArmVirtPkg/HighMemDxe/HighMemDxe.c                       | 120 +++++++++-----------
 ArmVirtPkg/HighMemDxe/HighMemDxe.inf                     |  16 ++-
 ArmVirtPkg/Include/Protocol/FdtClient.h                  |  29 ++++-
 ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c |   9 +-
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c           |   9 +-
 ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c       |   8 +-
 ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c                     |  10 +-
 8 files changed, 196 insertions(+), 89 deletions(-)

-- 
2.7.4



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties
  2016-09-15 13:30 [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
@ 2016-09-15 13:30 ` Ard Biesheuvel
  2016-09-15 13:38   ` Laszlo Ersek
  2016-09-15 13:30 ` [PATCH 2/4] ArmVirtPkg/FdtClientDxe: report address and size cell count directly Ard Biesheuvel
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 13:30 UTC (permalink / raw)
  To: edk2-devel, lersek; +Cc: zhaoshenglong, sakar.arora, Ard Biesheuvel

Currently, the code in FdtClientDxe assumes #address-cells and
of <base, size> tuples, this means the size of the entire property
should always be a multiple of 16 bytes (i.e, 4 * sizeof(UINT32),
not 8. So fix this.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmVirtPkg/FdtClientDxe/FdtClientDxe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
index c336e2410033..2063a597323b 100644
--- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
+++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
@@ -178,7 +178,7 @@ FindCompatibleNodeReg (
     return Status;
   }
 
-  if ((*RegSize % 8) != 0) {
+  if ((*RegSize % 16) != 0) {
     DEBUG ((EFI_D_ERROR,
       "%a: '%a' compatible node has invalid 'reg' property (size == 0x%x)\n",
       __FUNCTION__, CompatibleString, *RegSize));
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/4] ArmVirtPkg/FdtClientDxe: report address and size cell count directly
  2016-09-15 13:30 [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
  2016-09-15 13:30 ` [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties Ard Biesheuvel
@ 2016-09-15 13:30 ` Ard Biesheuvel
  2016-09-15 13:42   ` Laszlo Ersek
  2016-09-15 13:30 ` [PATCH 3/4] ArmVirtPkg/FdtClient: add methods to iterate over memory nodes Ard Biesheuvel
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 13:30 UTC (permalink / raw)
  To: edk2-devel, lersek; +Cc: zhaoshenglong, sakar.arora, Ard Biesheuvel

The FDT client protocol methods dealing with "reg" properties return
the size of a 'reg' element. Currently, we have hardcoded this as '8',
since #address-cells == #size-cells == 2 in most cases. However, for
different values, have a single 'reg' element size is not unambiguous,
since - however unlikely - if #address-cells != #size-cells, we do not
know which is which.

So before adding more methods to the protocol, fix up this oversight.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmVirtPkg/FdtClientDxe/FdtClientDxe.c                   |  6 ++++--
 ArmVirtPkg/Include/Protocol/FdtClient.h                  |  3 ++-
 ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c |  9 ++++++---
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c           |  9 ++++++---
 ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c       |  8 ++++++--
 ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c                     | 10 +++++++---
 6 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
index 2063a597323b..382e9af6bf84 100644
--- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
+++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
@@ -159,7 +159,8 @@ FindCompatibleNodeReg (
   IN  FDT_CLIENT_PROTOCOL     *This,
   IN  CONST CHAR8             *CompatibleString,
   OUT CONST VOID              **Reg,
-  OUT UINT32                  *RegElemSize,
+  OUT UINTN                   *AddressCells,
+  OUT UINTN                   *SizeCells,
   OUT UINT32                  *RegSize
   )
 {
@@ -185,7 +186,8 @@ FindCompatibleNodeReg (
     return EFI_NOT_FOUND;
   }
 
-  *RegElemSize = 8;
+  *AddressCells = 2;
+  *SizeCells = 2;
 
   return EFI_SUCCESS;
 }
diff --git a/ArmVirtPkg/Include/Protocol/FdtClient.h b/ArmVirtPkg/Include/Protocol/FdtClient.h
index 79a8f3ce1b5d..b593c7441426 100644
--- a/ArmVirtPkg/Include/Protocol/FdtClient.h
+++ b/ArmVirtPkg/Include/Protocol/FdtClient.h
@@ -80,7 +80,8 @@ EFI_STATUS
   IN  FDT_CLIENT_PROTOCOL     *This,
   IN  CONST CHAR8             *CompatibleString,
   OUT CONST VOID              **Reg,
-  OUT UINT32                  *RegElemSize,
+  OUT UINTN                   *AddressCells,
+  OUT UINTN                   *SizeCells,
   OUT UINT32                  *RegSize
   );
 
diff --git a/ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c b/ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c
index a1cd2da2d43a..64afc4de6b4d 100644
--- a/ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c
+++ b/ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c
@@ -36,7 +36,8 @@ ArmVirtGicArchLibConstructor (
   UINT32                IccSre;
   FDT_CLIENT_PROTOCOL   *FdtClient;
   CONST UINT64          *Reg;
-  UINT32                RegElemSize, RegSize;
+  UINT32                RegSize;
+  UINTN                 AddressCells, SizeCells;
   UINTN                 GicRevision;
   EFI_STATUS            Status;
   UINT64                DistBase, CpuBase, RedistBase;
@@ -47,11 +48,13 @@ ArmVirtGicArchLibConstructor (
 
   GicRevision = 2;
   Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,cortex-a15-gic",
-                        (CONST VOID **)&Reg, &RegElemSize, &RegSize);
+                        (CONST VOID **)&Reg, &AddressCells, &SizeCells,
+                        &RegSize);
   if (Status == EFI_NOT_FOUND) {
     GicRevision = 3;
     Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,gic-v3",
-                          (CONST VOID **)&Reg, &RegElemSize, &RegSize);
+                          (CONST VOID **)&Reg, &AddressCells, &SizeCells,
+                          &RegSize);
   }
   if (EFI_ERROR (Status)) {
     return Status;
diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 377262563e3e..8ecbe3fb5fe6 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -122,7 +122,8 @@ QemuFwCfgInitialize (
   EFI_STATUS                    Status;
   FDT_CLIENT_PROTOCOL           *FdtClient;
   CONST UINT64                  *Reg;
-  UINT32                        RegElemSize, RegSize;
+  UINT32                        RegSize;
+  UINTN                         AddressCells, SizeCells;
   UINT64                        FwCfgSelectorAddress;
   UINT64                        FwCfgSelectorSize;
   UINT64                        FwCfgDataAddress;
@@ -135,7 +136,8 @@ QemuFwCfgInitialize (
   ASSERT_EFI_ERROR (Status);
 
   Status = FdtClient->FindCompatibleNodeReg (FdtClient, "qemu,fw-cfg-mmio",
-                         (CONST VOID **)&Reg, &RegElemSize, &RegSize);
+                         (CONST VOID **)&Reg, &AddressCells, &SizeCells,
+                         &RegSize);
   if (EFI_ERROR (Status)) {
     DEBUG ((EFI_D_WARN,
       "%a: No 'qemu,fw-cfg-mmio' compatible DT node found (Status == %r)\n",
@@ -143,7 +145,8 @@ QemuFwCfgInitialize (
     return EFI_SUCCESS;
   }
 
-  ASSERT (RegElemSize == sizeof (UINT64));
+  ASSERT (AddressCells == 2);
+  ASSERT (SizeCells == 2);
   ASSERT (RegSize == 2 * sizeof (UINT64));
 
   FwCfgDataAddress     = SwapBytes64 (Reg[0]);
diff --git a/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
index 37aea806283e..203946f97bf8 100644
--- a/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
+++ b/ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
@@ -45,7 +45,8 @@ GetXenArmAcpiRsdp (
   EFI_STATUS                                     Status;
   FDT_CLIENT_PROTOCOL                            *FdtClient;
   CONST UINT64                                   *Reg;
-  UINT32                                         RegElemSize, RegSize;
+  UINT32                                         RegSize;
+  UINTN                                          AddressCells, SizeCells;
   UINT64                                         RegBase;
   UINT8                                          Sum;
 
@@ -59,13 +60,16 @@ GetXenArmAcpiRsdp (
   ASSERT_EFI_ERROR (Status);
 
   Status = FdtClient->FindCompatibleNodeReg (FdtClient, "xen,guest-acpi",
-                        (CONST VOID **)&Reg, &RegElemSize, &RegSize);
+                        (CONST VOID **)&Reg, &AddressCells, &SizeCells,
+                        &RegSize);
   if (EFI_ERROR (Status)) {
     DEBUG ((EFI_D_WARN, "%a: No 'xen,guest-acpi' compatible DT node found\n",
       __FUNCTION__));
     return EFI_NOT_FOUND;
   }
 
+  ASSERT (AddressCells == 2);
+  ASSERT (SizeCells == 2);
   ASSERT (RegSize == 2 * sizeof (UINT64));
 
   RegBase = SwapBytes64(Reg[0]);
diff --git a/ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c b/ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c
index 4a88db32170c..ae012a76f5e0 100644
--- a/ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c
+++ b/ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c
@@ -31,7 +31,8 @@ InitializeXenioFdtDxe (
   EFI_STATUS            Status;
   FDT_CLIENT_PROTOCOL   *FdtClient;
   CONST UINT64          *Reg;
-  UINT32                RegElemSize, RegSize;
+  UINT32                RegSize;
+  UINTN                 AddressCells, SizeCells;
   EFI_HANDLE            Handle;
   UINT64                RegBase;
 
@@ -40,14 +41,17 @@ InitializeXenioFdtDxe (
   ASSERT_EFI_ERROR (Status);
 
   Status = FdtClient->FindCompatibleNodeReg (FdtClient, "xen,xen",
-                        (CONST VOID **)&Reg, &RegElemSize, &RegSize);
+                        (CONST VOID **)&Reg, &AddressCells, &SizeCells,
+                        &RegSize);
   if (EFI_ERROR (Status)) {
     DEBUG ((EFI_D_WARN, "%a: No 'xen,xen' compatible DT node found\n",
       __FUNCTION__));
     return EFI_UNSUPPORTED;
   }
 
-  ASSERT (RegSize == 16);
+  ASSERT (AddressCells == 2);
+  ASSERT (SizeCells == 2);
+  ASSERT (RegSize == 2 * sizeof (UINT64));
 
   //
   // Retrieve the reg base from this node and wire it up to the
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/4] ArmVirtPkg/FdtClient: add methods to iterate over memory nodes
  2016-09-15 13:30 [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
  2016-09-15 13:30 ` [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties Ard Biesheuvel
  2016-09-15 13:30 ` [PATCH 2/4] ArmVirtPkg/FdtClientDxe: report address and size cell count directly Ard Biesheuvel
@ 2016-09-15 13:30 ` Ard Biesheuvel
  2016-09-15 13:57   ` Laszlo Ersek
  2016-09-15 13:30 ` [PATCH 4/4] ArmVirtPkg/HighMemDxe: move to FDT client protocol Ard Biesheuvel
  2016-09-15 13:34 ` [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
  4 siblings, 1 reply; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 13:30 UTC (permalink / raw)
  To: edk2-devel, lersek; +Cc: zhaoshenglong, sakar.arora, Ard Biesheuvel

Add high level methods to iterate over all 'reg' properties of all DT
nodes whose device_type properties have the value "memory". Since we are
modifying the FdtClient protocol, update the protocol and the only existing
implementation at the same time.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmVirtPkg/FdtClientDxe/FdtClientDxe.c  | 76 ++++++++++++++++++++
 ArmVirtPkg/Include/Protocol/FdtClient.h | 26 +++++++
 2 files changed, 102 insertions(+)

diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
index 382e9af6bf84..099cce7821d6 100644
--- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
+++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
@@ -194,6 +194,80 @@ FindCompatibleNodeReg (
 
 STATIC
 EFI_STATUS
+EFIAPI
+FindNextMemoryNodeReg (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  INT32                   PrevNode,
+  OUT INT32                   *Node,
+  OUT CONST VOID              **Reg,
+  OUT UINTN                   *AddressCells,
+  OUT UINTN                   *SizeCells,
+  OUT UINT32                  *RegSize
+  )
+{
+  INT32          Prev, Next;
+  CONST CHAR8    *DeviceType;
+  INT32          Len;
+  EFI_STATUS     Status;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  for (Prev = PrevNode;; Prev = Next) {
+    Next = fdt_next_node (mDeviceTreeBase, Prev, NULL);
+    if (Next < 0) {
+      break;
+    }
+
+    DeviceType = fdt_getprop (mDeviceTreeBase, Next, "device_type", &Len);
+    if (DeviceType != NULL && AsciiStrCmp (DeviceType, "memory") == 0) {
+
+      //
+      // Get the 'reg' property of this memory node. For now, we will assume
+      // 8 byte quantities for base and size, respectively.
+      // TODO use #cells root properties instead
+      //
+      Status = GetNodeProperty (This, Next, "reg", Reg, RegSize);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((EFI_D_WARN,
+          "%a: ignoring memory node with no 'reg' property\n",
+          __FUNCTION__));
+        continue;
+      }
+      if ((*RegSize % 16) != 0) {
+        DEBUG ((EFI_D_WARN,
+          "%a: ignoring memory node with invalid 'reg' property (size == 0x%x)\n",
+          __FUNCTION__, RegSize));
+        continue;
+      }
+
+      *Node = Next;
+      *AddressCells = 2;
+      *SizeCells = 2;
+      return EFI_SUCCESS;
+    }
+  }
+  return EFI_NOT_FOUND;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+FindMemoryNodeReg (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  OUT INT32                   *Node,
+  OUT CONST VOID              **Reg,
+  OUT UINTN                   *AddressCells,
+  OUT UINTN                   *SizeCells,
+  OUT UINT32                  *RegSize
+  )
+{
+  return FindNextMemoryNodeReg (This, 0, Node, Reg, AddressCells, SizeCells,
+           RegSize);
+}
+
+STATIC
+EFI_STATUS
 GetOrInsertChosenNode (
   IN  FDT_CLIENT_PROTOCOL     *This,
   OUT INT32                   *Node
@@ -225,6 +299,8 @@ STATIC FDT_CLIENT_PROTOCOL mFdtClientProtocol = {
   FindNextCompatibleNode,
   FindCompatibleNodeProperty,
   FindCompatibleNodeReg,
+  FindMemoryNodeReg,
+  FindNextMemoryNodeReg,
   GetOrInsertChosenNode,
 };
 
diff --git a/ArmVirtPkg/Include/Protocol/FdtClient.h b/ArmVirtPkg/Include/Protocol/FdtClient.h
index b593c7441426..aad76db388be 100644
--- a/ArmVirtPkg/Include/Protocol/FdtClient.h
+++ b/ArmVirtPkg/Include/Protocol/FdtClient.h
@@ -87,6 +87,29 @@ EFI_STATUS
 
 typedef
 EFI_STATUS
+(EFIAPI *FDT_CLIENT_FIND_NEXT_MEMORY_NODE_REG) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  INT32                   PrevNode,
+  OUT INT32                   *Node,
+  OUT CONST VOID              **Reg,
+  OUT UINTN                   *AddressCells,
+  OUT UINTN                   *SizeCells,
+  OUT UINT32                  *RegSize
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_FIND_MEMORY_NODE_REG) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  OUT INT32                   *Node,
+  OUT CONST VOID              **Reg,
+  OUT UINTN                   *AddressCells,
+  OUT UINTN                   *SizeCells,
+  OUT UINT32                  *RegSize
+  );
+
+typedef
+EFI_STATUS
 (EFIAPI *FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE) (
   IN  FDT_CLIENT_PROTOCOL     *This,
   OUT INT32                   *Node
@@ -101,6 +124,9 @@ struct _FDT_CLIENT_PROTOCOL {
   FDT_CLIENT_FIND_COMPATIBLE_NODE_PROPERTY FindCompatibleNodeProperty;
   FDT_CLIENT_FIND_COMPATIBLE_NODE_REG      FindCompatibleNodeReg;
 
+  FDT_CLIENT_FIND_MEMORY_NODE_REG          FindMemoryNodeReg;
+  FDT_CLIENT_FIND_NEXT_MEMORY_NODE_REG     FindNextMemoryNodeReg;
+
   FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE     GetOrInsertChosenNode;
 };
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/4] ArmVirtPkg/HighMemDxe: move to FDT client protocol
  2016-09-15 13:30 [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2016-09-15 13:30 ` [PATCH 3/4] ArmVirtPkg/FdtClient: add methods to iterate over memory nodes Ard Biesheuvel
@ 2016-09-15 13:30 ` Ard Biesheuvel
  2016-09-15 14:15   ` Laszlo Ersek
  2016-09-15 13:34 ` [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
  4 siblings, 1 reply; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 13:30 UTC (permalink / raw)
  To: edk2-devel, lersek; +Cc: zhaoshenglong, sakar.arora, Ard Biesheuvel

Use the FDT client protocol rather than parsing the DT directly using
fdtlib. While we're at it, update the code so it deals correctly with
memory nodes that describe multiple disjoint regions in their "reg"
properties, and make the code work with #address-cells/#size-cells
properties of <1> as well as <2>.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmVirtPkg/HighMemDxe/HighMemDxe.c   | 120 +++++++++-----------
 ArmVirtPkg/HighMemDxe/HighMemDxe.inf |  16 ++-
 2 files changed, 62 insertions(+), 74 deletions(-)

diff --git a/ArmVirtPkg/HighMemDxe/HighMemDxe.c b/ArmVirtPkg/HighMemDxe/HighMemDxe.c
index 4d56e6236b54..08de3cbb7e9c 100644
--- a/ArmVirtPkg/HighMemDxe/HighMemDxe.c
+++ b/ArmVirtPkg/HighMemDxe/HighMemDxe.c
@@ -1,7 +1,7 @@
 /** @file
 *  High memory node enumeration DXE driver for ARM Virtual Machines
 *
-*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2015-2016, 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
@@ -15,12 +15,12 @@
 **/
 
 #include <Library/BaseLib.h>
-#include <Library/UefiDriverEntryPoint.h>
 #include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-#include <Library/HobLib.h>
-#include <libfdt.h>
 #include <Library/DxeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/FdtClient.h>
 
 EFI_STATUS
 EFIAPI
@@ -29,76 +29,66 @@ InitializeHighMemDxe (
   IN EFI_SYSTEM_TABLE     *SystemTable
   )
 {
-  VOID             *Hob;
-  VOID             *DeviceTreeBase;
-  INT32            Node, Prev;
-  EFI_STATUS       Status;
-  CONST CHAR8      *Type;
-  INT32            Len;
-  CONST VOID       *RegProp;
-  UINT64           CurBase;
-  UINT64           CurSize;
-
-  Hob = GetFirstGuidHob(&gFdtHobGuid);
-  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {
-    return EFI_NOT_FOUND;
-  }
-  DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);
-
-  if (fdt_check_header (DeviceTreeBase) != 0) {
-    DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__,
-      DeviceTreeBase));
-    return EFI_NOT_FOUND;
-  }
+  FDT_CLIENT_PROTOCOL   *FdtClient;
+  EFI_STATUS            Status, FindNodeStatus;
+  INT32                 Node;
+  CONST UINT32          *Reg;
+  UINT32                RegSize;
+  UINTN                 AddressCells, SizeCells;
+  UINT64                CurBase;
+  UINT64                CurSize;
 
-  DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase));
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
+                  (VOID **)&FdtClient);
+  ASSERT_EFI_ERROR (Status);
 
   //
-  // Check for memory node and add the memory spaces expect the lowest one
+  // Check for memory node and add the memory spaces except the lowest one
   //
-  for (Prev = 0;; Prev = Node) {
-    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
-    if (Node < 0) {
-      break;
-    }
+  for (FindNodeStatus = FdtClient->FindMemoryNodeReg (FdtClient, &Node,
+                                     (CONST VOID **) &Reg, &AddressCells,
+                                     &SizeCells, &RegSize);
+       !EFI_ERROR (FindNodeStatus);
+       FindNodeStatus = FdtClient->FindNextMemoryNodeReg (FdtClient, Node,
+                                     &Node, (CONST VOID **) &Reg, &AddressCells,
+                                     &SizeCells, &RegSize)) {
+
+    ASSERT (AddressCells <= 2);
+    ASSERT (SizeCells <= 2);
 
-    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
-    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
-      //
-      // Get the 'reg' property of this node. For now, we will assume
-      // two 8 byte quantities for base and size, respectively.
-      //
-      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
-      if (RegProp != NULL && Len == (2 * sizeof (UINT64))) {
+    while (RegSize > 0) {
 
-        CurBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
-        CurSize = fdt64_to_cpu (((UINT64 *)RegProp)[1]);
+      CurBase = SwapBytes32 (*Reg++);
+      if (AddressCells > 1) {
+        CurBase |= (CurBase << 32) | SwapBytes32 (*Reg++);
+      }
+      CurSize = SwapBytes32 (*Reg++);
+      if (SizeCells > 1) {
+        CurSize |= (CurSize << 32) | SwapBytes32 (*Reg++);
+      }
+      RegSize -= (AddressCells + SizeCells) * sizeof (UINT32);
 
-        if (PcdGet64 (PcdSystemMemoryBase) != CurBase) {
-          Status = gDS->AddMemorySpace (
-                          EfiGcdMemoryTypeSystemMemory,
-                          CurBase, CurSize,
-                          EFI_MEMORY_WB);
+      if (PcdGet64 (PcdSystemMemoryBase) != CurBase) {
+        Status = gDS->AddMemorySpace (EfiGcdMemoryTypeSystemMemory, CurBase,
+                        CurSize, EFI_MEMORY_WB);
 
-          if (EFI_ERROR (Status)) {
-            DEBUG ((EFI_D_ERROR,
-              "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n",
-              __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));
-            continue;
-          }
+        if (EFI_ERROR (Status)) {
+          DEBUG ((EFI_D_ERROR,
+            "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n",
+            __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));
+          continue;
+        }
 
-          Status = gDS->SetMemorySpaceAttributes (
-                          CurBase, CurSize,
-                          EFI_MEMORY_WB);
+        Status = gDS->SetMemorySpaceAttributes (CurBase, CurSize,
+                        EFI_MEMORY_WB);
 
-          if (EFI_ERROR (Status)) {
-            DEBUG ((EFI_D_ERROR,
-              "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n",
-              __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));
-          } else {
-            DEBUG ((EFI_D_INFO, "%a: Add System RAM @ 0x%lx - 0x%lx\n",
-              __FUNCTION__, CurBase, CurBase + CurSize - 1));
-          }
+        if (EFI_ERROR (Status)) {
+          DEBUG ((EFI_D_ERROR,
+            "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n",
+            __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));
+        } else {
+          DEBUG ((EFI_D_INFO, "%a: Add System RAM @ 0x%lx - 0x%lx\n",
+            __FUNCTION__, CurBase, CurBase + CurSize - 1));
         }
       }
     }
diff --git a/ArmVirtPkg/HighMemDxe/HighMemDxe.inf b/ArmVirtPkg/HighMemDxe/HighMemDxe.inf
index ae632a8bee93..3661cfd8c80c 100644
--- a/ArmVirtPkg/HighMemDxe/HighMemDxe.inf
+++ b/ArmVirtPkg/HighMemDxe/HighMemDxe.inf
@@ -1,7 +1,7 @@
 ## @file
 #  High memory node enumeration DXE driver for ARM Virtual Machines
 #
-#  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+#  Copyright (c) 2015-2016, 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
@@ -30,23 +30,21 @@ [Packages]
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
   ArmPkg/ArmPkg.dec
-  ArmPlatformPkg/ArmPlatformPkg.dec
   ArmVirtPkg/ArmVirtPkg.dec
-  EmbeddedPkg/EmbeddedPkg.dec
 
 [LibraryClasses]
   BaseLib
+  DebugLib
+  DxeServicesTableLib
   PcdLib
+  UefiBootServicesTableLib
   UefiDriverEntryPoint
-  FdtLib
-  HobLib
-  DxeServicesTableLib
 
-[Guids]
-  gFdtHobGuid
+[Protocols]
+  gFdtClientProtocolGuid                  ## CONSUMES
 
 [Pcd]
   gArmTokenSpaceGuid.PcdSystemMemoryBase
 
 [Depex]
-  gEfiCpuArchProtocolGuid
+  gEfiCpuArchProtocolGuid AND gFdtClientProtocolGuid
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates
  2016-09-15 13:30 [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
                   ` (3 preceding siblings ...)
  2016-09-15 13:30 ` [PATCH 4/4] ArmVirtPkg/HighMemDxe: move to FDT client protocol Ard Biesheuvel
@ 2016-09-15 13:34 ` Ard Biesheuvel
  2016-09-15 14:40   ` Ard Biesheuvel
  4 siblings, 1 reply; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 13:34 UTC (permalink / raw)
  To: edk2-devel-01, Laszlo Ersek; +Cc: Shannon Zhao, Sakar Arora, Ard Biesheuvel

On 15 September 2016 at 14:30, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> Patch #4 moves HighMemDxe to the FDT client protocol, and updates it to
> handle #address-cells/#size-cells values of <1> as well as <2>, and lets
> it deal with memory nodes whose 'reg' properties describe multiple disjoint
> regions.
>
> Patches #1 to #3 are somewhat preparatory in nature:
> - Patch #1 is a small thinko fix
> - Patch #2 drops the 'regelemsize' output parameter for 'reg' related methods
>   of the FDT client protocol in favour of addresscells/sizecells.
> - Patch #3 adds methods to iterate over all 'reg' properties of all memory nodes
>

Branch here
https://git.linaro.org/people/ard.biesheuvel/uefi-next.git/shortlog/refs/heads/virt-highmem-fdt

> Ard Biesheuvel (4):
>   ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties
>   ArmVirtPkg/FdtClientDxe: report address and size cell count directly
>   ArmVirtPkg/FdtClient: add methods to iterate over memory nodes
>   ArmVirtPkg/HighMemDxe: move to FDT client protocol
>
>  ArmVirtPkg/FdtClientDxe/FdtClientDxe.c                   |  84 +++++++++++++-
>  ArmVirtPkg/HighMemDxe/HighMemDxe.c                       | 120 +++++++++-----------
>  ArmVirtPkg/HighMemDxe/HighMemDxe.inf                     |  16 ++-
>  ArmVirtPkg/Include/Protocol/FdtClient.h                  |  29 ++++-
>  ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c |   9 +-
>  ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c           |   9 +-
>  ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c       |   8 +-
>  ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c                     |  10 +-
>  8 files changed, 196 insertions(+), 89 deletions(-)
>
> --
> 2.7.4
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties
  2016-09-15 13:30 ` [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties Ard Biesheuvel
@ 2016-09-15 13:38   ` Laszlo Ersek
  2016-09-15 13:40     ` Ard Biesheuvel
  0 siblings, 1 reply; 14+ messages in thread
From: Laszlo Ersek @ 2016-09-15 13:38 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel

On 09/15/16 15:30, Ard Biesheuvel wrote:
> Currently, the code in FdtClientDxe assumes #address-cells and

s/and/are/?

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

> of <base, size> tuples, this means the size of the entire property
> should always be a multiple of 16 bytes (i.e, 4 * sizeof(UINT32),
> not 8. So fix this.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  ArmVirtPkg/FdtClientDxe/FdtClientDxe.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
> index c336e2410033..2063a597323b 100644
> --- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
> +++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
> @@ -178,7 +178,7 @@ FindCompatibleNodeReg (
>      return Status;
>    }
>  
> -  if ((*RegSize % 8) != 0) {
> +  if ((*RegSize % 16) != 0) {
>      DEBUG ((EFI_D_ERROR,
>        "%a: '%a' compatible node has invalid 'reg' property (size == 0x%x)\n",
>        __FUNCTION__, CompatibleString, *RegSize));
> 



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties
  2016-09-15 13:38   ` Laszlo Ersek
@ 2016-09-15 13:40     ` Ard Biesheuvel
  0 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 13:40 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel@lists.01.org, Shannon Zhao, Sakar Arora

On 15 September 2016 at 14:38, Laszlo Ersek <lersek@redhat.com> wrote:
> On 09/15/16 15:30, Ard Biesheuvel wrote:
>> Currently, the code in FdtClientDxe assumes #address-cells and
>
> s/and/are/?
>

No, amusingly, the second sentence started with #size-cells, and was
dropped completely by git commit due to the leading #. I will try to
remember what I put there, and fix it up when committing.

> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>

Thanks,
Ard.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] ArmVirtPkg/FdtClientDxe: report address and size cell count directly
  2016-09-15 13:30 ` [PATCH 2/4] ArmVirtPkg/FdtClientDxe: report address and size cell count directly Ard Biesheuvel
@ 2016-09-15 13:42   ` Laszlo Ersek
  0 siblings, 0 replies; 14+ messages in thread
From: Laszlo Ersek @ 2016-09-15 13:42 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel

On 09/15/16 15:30, Ard Biesheuvel wrote:
> The FDT client protocol methods dealing with "reg" properties return
> the size of a 'reg' element. Currently, we have hardcoded this as '8',
> since #address-cells == #size-cells == 2 in most cases. However, for
> different values, have a single 'reg' element size is not unambiguous,
> since - however unlikely - if #address-cells != #size-cells, we do not
> know which is which.
> 
> So before adding more methods to the protocol, fix up this oversight.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  ArmVirtPkg/FdtClientDxe/FdtClientDxe.c                   |  6 ++++--
>  ArmVirtPkg/Include/Protocol/FdtClient.h                  |  3 ++-
>  ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c |  9 ++++++---
>  ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c           |  9 ++++++---
>  ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c       |  8 ++++++--
>  ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.c                     | 10 +++++++---
>  6 files changed, 31 insertions(+), 14 deletions(-)

Reviewed-by: Laszlo Ersek <lersek@redhat.com>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] ArmVirtPkg/FdtClient: add methods to iterate over memory nodes
  2016-09-15 13:30 ` [PATCH 3/4] ArmVirtPkg/FdtClient: add methods to iterate over memory nodes Ard Biesheuvel
@ 2016-09-15 13:57   ` Laszlo Ersek
  2016-09-15 14:04     ` Ard Biesheuvel
  0 siblings, 1 reply; 14+ messages in thread
From: Laszlo Ersek @ 2016-09-15 13:57 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel

On 09/15/16 15:30, Ard Biesheuvel wrote:
> Add high level methods to iterate over all 'reg' properties of all DT
> nodes whose device_type properties have the value "memory". Since we are
> modifying the FdtClient protocol, update the protocol and the only existing
> implementation at the same time.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  ArmVirtPkg/FdtClientDxe/FdtClientDxe.c  | 76 ++++++++++++++++++++
>  ArmVirtPkg/Include/Protocol/FdtClient.h | 26 +++++++
>  2 files changed, 102 insertions(+)
> 
> diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
> index 382e9af6bf84..099cce7821d6 100644
> --- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
> +++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
> @@ -194,6 +194,80 @@ FindCompatibleNodeReg (
>  
>  STATIC
>  EFI_STATUS
> +EFIAPI
> +FindNextMemoryNodeReg (
> +  IN  FDT_CLIENT_PROTOCOL     *This,
> +  IN  INT32                   PrevNode,
> +  OUT INT32                   *Node,
> +  OUT CONST VOID              **Reg,
> +  OUT UINTN                   *AddressCells,
> +  OUT UINTN                   *SizeCells,
> +  OUT UINT32                  *RegSize
> +  )
> +{
> +  INT32          Prev, Next;
> +  CONST CHAR8    *DeviceType;
> +  INT32          Len;
> +  EFI_STATUS     Status;
> +
> +  ASSERT (mDeviceTreeBase != NULL);
> +  ASSERT (Node != NULL);
> +
> +  for (Prev = PrevNode;; Prev = Next) {
> +    Next = fdt_next_node (mDeviceTreeBase, Prev, NULL);
> +    if (Next < 0) {
> +      break;
> +    }
> +
> +    DeviceType = fdt_getprop (mDeviceTreeBase, Next, "device_type", &Len);
> +    if (DeviceType != NULL && AsciiStrCmp (DeviceType, "memory") == 0) {

HighMemDxe uses AsciiStrnCmp (Type, "memory", Len) here.

If we're sure that we're not looking "memory*" types here, then the
change is fine. Are we sure?

> +

The empty line is likely unintended.

> +      //
> +      // Get the 'reg' property of this memory node. For now, we will assume
> +      // 8 byte quantities for base and size, respectively.
> +      // TODO use #cells root properties instead
> +      //
> +      Status = GetNodeProperty (This, Next, "reg", Reg, RegSize);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((EFI_D_WARN,
> +          "%a: ignoring memory node with no 'reg' property\n",
> +          __FUNCTION__));
> +        continue;
> +      }
> +      if ((*RegSize % 16) != 0) {
> +        DEBUG ((EFI_D_WARN,
> +          "%a: ignoring memory node with invalid 'reg' property (size == 0x%x)\n",
> +          __FUNCTION__, RegSize));

This should be *RegSize.

With the above confirmed / fixed:

Reviewed-by: Laszlo Ersek <lersek@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] ArmVirtPkg/FdtClient: add methods to iterate over memory nodes
  2016-09-15 13:57   ` Laszlo Ersek
@ 2016-09-15 14:04     ` Ard Biesheuvel
  0 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 14:04 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel@lists.01.org, Shannon Zhao, Sakar Arora

On 15 September 2016 at 14:57, Laszlo Ersek <lersek@redhat.com> wrote:
> On 09/15/16 15:30, Ard Biesheuvel wrote:
>> Add high level methods to iterate over all 'reg' properties of all DT
>> nodes whose device_type properties have the value "memory". Since we are
>> modifying the FdtClient protocol, update the protocol and the only existing
>> implementation at the same time.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  ArmVirtPkg/FdtClientDxe/FdtClientDxe.c  | 76 ++++++++++++++++++++
>>  ArmVirtPkg/Include/Protocol/FdtClient.h | 26 +++++++
>>  2 files changed, 102 insertions(+)
>>
>> diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
>> index 382e9af6bf84..099cce7821d6 100644
>> --- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
>> +++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
>> @@ -194,6 +194,80 @@ FindCompatibleNodeReg (
>>
>>  STATIC
>>  EFI_STATUS
>> +EFIAPI
>> +FindNextMemoryNodeReg (
>> +  IN  FDT_CLIENT_PROTOCOL     *This,
>> +  IN  INT32                   PrevNode,
>> +  OUT INT32                   *Node,
>> +  OUT CONST VOID              **Reg,
>> +  OUT UINTN                   *AddressCells,
>> +  OUT UINTN                   *SizeCells,
>> +  OUT UINT32                  *RegSize
>> +  )
>> +{
>> +  INT32          Prev, Next;
>> +  CONST CHAR8    *DeviceType;
>> +  INT32          Len;
>> +  EFI_STATUS     Status;
>> +
>> +  ASSERT (mDeviceTreeBase != NULL);
>> +  ASSERT (Node != NULL);
>> +
>> +  for (Prev = PrevNode;; Prev = Next) {
>> +    Next = fdt_next_node (mDeviceTreeBase, Prev, NULL);
>> +    if (Next < 0) {
>> +      break;
>> +    }
>> +
>> +    DeviceType = fdt_getprop (mDeviceTreeBase, Next, "device_type", &Len);
>> +    if (DeviceType != NULL && AsciiStrCmp (DeviceType, "memory") == 0) {
>
> HighMemDxe uses AsciiStrnCmp (Type, "memory", Len) here.
>
> If we're sure that we're not looking "memory*" types here, then the
> change is fine. Are we sure?
>

Actually, that is a bug. AsciiStrCmp () is guaranteed to check the NUL
terminator, and so it will only match on "memory\0". Using
AsciiStrnCmp() with the length of the property value is guaranteed
*not* to check the NUL terminator, so it may match on prefixes of
"memory\0"




>> +
>
> The empty line is likely unintended.
>

indeed.

>> +      //
>> +      // Get the 'reg' property of this memory node. For now, we will assume
>> +      // 8 byte quantities for base and size, respectively.
>> +      // TODO use #cells root properties instead
>> +      //
>> +      Status = GetNodeProperty (This, Next, "reg", Reg, RegSize);
>> +      if (EFI_ERROR (Status)) {
>> +        DEBUG ((EFI_D_WARN,
>> +          "%a: ignoring memory node with no 'reg' property\n",
>> +          __FUNCTION__));
>> +        continue;
>> +      }
>> +      if ((*RegSize % 16) != 0) {
>> +        DEBUG ((EFI_D_WARN,
>> +          "%a: ignoring memory node with invalid 'reg' property (size == 0x%x)\n",
>> +          __FUNCTION__, RegSize));
>
> This should be *RegSize.
>

OK

> With the above confirmed / fixed:
>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] ArmVirtPkg/HighMemDxe: move to FDT client protocol
  2016-09-15 13:30 ` [PATCH 4/4] ArmVirtPkg/HighMemDxe: move to FDT client protocol Ard Biesheuvel
@ 2016-09-15 14:15   ` Laszlo Ersek
  2016-09-15 14:18     ` Ard Biesheuvel
  0 siblings, 1 reply; 14+ messages in thread
From: Laszlo Ersek @ 2016-09-15 14:15 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel

On 09/15/16 15:30, Ard Biesheuvel wrote:
> Use the FDT client protocol rather than parsing the DT directly using
> fdtlib. While we're at it, update the code so it deals correctly with
> memory nodes that describe multiple disjoint regions in their "reg"
> properties, and make the code work with #address-cells/#size-cells
> properties of <1> as well as <2>.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  ArmVirtPkg/HighMemDxe/HighMemDxe.c   | 120 +++++++++-----------
>  ArmVirtPkg/HighMemDxe/HighMemDxe.inf |  16 ++-
>  2 files changed, 62 insertions(+), 74 deletions(-)
> 
> diff --git a/ArmVirtPkg/HighMemDxe/HighMemDxe.c b/ArmVirtPkg/HighMemDxe/HighMemDxe.c
> index 4d56e6236b54..08de3cbb7e9c 100644
> --- a/ArmVirtPkg/HighMemDxe/HighMemDxe.c
> +++ b/ArmVirtPkg/HighMemDxe/HighMemDxe.c
> @@ -1,7 +1,7 @@
>  /** @file
>  *  High memory node enumeration DXE driver for ARM Virtual Machines
>  *
> -*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
> +*  Copyright (c) 2015-2016, 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
> @@ -15,12 +15,12 @@
>  **/
>  
>  #include <Library/BaseLib.h>
> -#include <Library/UefiDriverEntryPoint.h>
>  #include <Library/DebugLib.h>
> -#include <Library/PcdLib.h>
> -#include <Library/HobLib.h>
> -#include <libfdt.h>
>  #include <Library/DxeServicesTableLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <Protocol/FdtClient.h>
>  
>  EFI_STATUS
>  EFIAPI
> @@ -29,76 +29,66 @@ InitializeHighMemDxe (
>    IN EFI_SYSTEM_TABLE     *SystemTable
>    )
>  {
> -  VOID             *Hob;
> -  VOID             *DeviceTreeBase;
> -  INT32            Node, Prev;
> -  EFI_STATUS       Status;
> -  CONST CHAR8      *Type;
> -  INT32            Len;
> -  CONST VOID       *RegProp;
> -  UINT64           CurBase;
> -  UINT64           CurSize;
> -
> -  Hob = GetFirstGuidHob(&gFdtHobGuid);
> -  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {
> -    return EFI_NOT_FOUND;
> -  }
> -  DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);
> -
> -  if (fdt_check_header (DeviceTreeBase) != 0) {
> -    DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__,
> -      DeviceTreeBase));
> -    return EFI_NOT_FOUND;
> -  }
> +  FDT_CLIENT_PROTOCOL   *FdtClient;
> +  EFI_STATUS            Status, FindNodeStatus;
> +  INT32                 Node;
> +  CONST UINT32          *Reg;
> +  UINT32                RegSize;
> +  UINTN                 AddressCells, SizeCells;
> +  UINT64                CurBase;
> +  UINT64                CurSize;
>  
> -  DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase));
> +  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
> +                  (VOID **)&FdtClient);
> +  ASSERT_EFI_ERROR (Status);
>  
>    //
> -  // Check for memory node and add the memory spaces expect the lowest one
> +  // Check for memory node and add the memory spaces except the lowest one
>    //
> -  for (Prev = 0;; Prev = Node) {
> -    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
> -    if (Node < 0) {
> -      break;
> -    }
> +  for (FindNodeStatus = FdtClient->FindMemoryNodeReg (FdtClient, &Node,
> +                                     (CONST VOID **) &Reg, &AddressCells,
> +                                     &SizeCells, &RegSize);
> +       !EFI_ERROR (FindNodeStatus);
> +       FindNodeStatus = FdtClient->FindNextMemoryNodeReg (FdtClient, Node,
> +                                     &Node, (CONST VOID **) &Reg, &AddressCells,
> +                                     &SizeCells, &RegSize)) {
> +

I think we can remove this empty line. Not too important of course.

> +    ASSERT (AddressCells <= 2);
> +    ASSERT (SizeCells <= 2);
>  
> -    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
> -    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
> -      //
> -      // Get the 'reg' property of this node. For now, we will assume
> -      // two 8 byte quantities for base and size, respectively.
> -      //
> -      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
> -      if (RegProp != NULL && Len == (2 * sizeof (UINT64))) {
> +    while (RegSize > 0) {
>  

This one too. (Also just a matter of taste.)

> -        CurBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
> -        CurSize = fdt64_to_cpu (((UINT64 *)RegProp)[1]);
> +      CurBase = SwapBytes32 (*Reg++);
> +      if (AddressCells > 1) {
> +        CurBase |= (CurBase << 32) | SwapBytes32 (*Reg++);

The operator |= seems wrong; it should be just =.

(You could do { CurBase <<= 32; CurBase |= SwapBytes32 (*Reg++); }. The
above is more compact, but the operator should be fixed.)

> +      }
> +      CurSize = SwapBytes32 (*Reg++);
> +      if (SizeCells > 1) {
> +        CurSize |= (CurSize << 32) | SwapBytes32 (*Reg++);

Same here.

With these fixed:

Reviewed-by: Laszlo Ersek <lersek@redhat.com>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] ArmVirtPkg/HighMemDxe: move to FDT client protocol
  2016-09-15 14:15   ` Laszlo Ersek
@ 2016-09-15 14:18     ` Ard Biesheuvel
  0 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 14:18 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel@lists.01.org, Shannon Zhao, Sakar Arora

On 15 September 2016 at 15:15, Laszlo Ersek <lersek@redhat.com> wrote:
> On 09/15/16 15:30, Ard Biesheuvel wrote:
>> Use the FDT client protocol rather than parsing the DT directly using
>> fdtlib. While we're at it, update the code so it deals correctly with
>> memory nodes that describe multiple disjoint regions in their "reg"
>> properties, and make the code work with #address-cells/#size-cells
>> properties of <1> as well as <2>.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  ArmVirtPkg/HighMemDxe/HighMemDxe.c   | 120 +++++++++-----------
>>  ArmVirtPkg/HighMemDxe/HighMemDxe.inf |  16 ++-
>>  2 files changed, 62 insertions(+), 74 deletions(-)
>>
>> diff --git a/ArmVirtPkg/HighMemDxe/HighMemDxe.c b/ArmVirtPkg/HighMemDxe/HighMemDxe.c
>> index 4d56e6236b54..08de3cbb7e9c 100644
>> --- a/ArmVirtPkg/HighMemDxe/HighMemDxe.c
>> +++ b/ArmVirtPkg/HighMemDxe/HighMemDxe.c
>> @@ -1,7 +1,7 @@
>>  /** @file
>>  *  High memory node enumeration DXE driver for ARM Virtual Machines
>>  *
>> -*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
>> +*  Copyright (c) 2015-2016, 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
>> @@ -15,12 +15,12 @@
>>  **/
>>
>>  #include <Library/BaseLib.h>
>> -#include <Library/UefiDriverEntryPoint.h>
>>  #include <Library/DebugLib.h>
>> -#include <Library/PcdLib.h>
>> -#include <Library/HobLib.h>
>> -#include <libfdt.h>
>>  #include <Library/DxeServicesTableLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +
>> +#include <Protocol/FdtClient.h>
>>
>>  EFI_STATUS
>>  EFIAPI
>> @@ -29,76 +29,66 @@ InitializeHighMemDxe (
>>    IN EFI_SYSTEM_TABLE     *SystemTable
>>    )
>>  {
>> -  VOID             *Hob;
>> -  VOID             *DeviceTreeBase;
>> -  INT32            Node, Prev;
>> -  EFI_STATUS       Status;
>> -  CONST CHAR8      *Type;
>> -  INT32            Len;
>> -  CONST VOID       *RegProp;
>> -  UINT64           CurBase;
>> -  UINT64           CurSize;
>> -
>> -  Hob = GetFirstGuidHob(&gFdtHobGuid);
>> -  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {
>> -    return EFI_NOT_FOUND;
>> -  }
>> -  DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);
>> -
>> -  if (fdt_check_header (DeviceTreeBase) != 0) {
>> -    DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__,
>> -      DeviceTreeBase));
>> -    return EFI_NOT_FOUND;
>> -  }
>> +  FDT_CLIENT_PROTOCOL   *FdtClient;
>> +  EFI_STATUS            Status, FindNodeStatus;
>> +  INT32                 Node;
>> +  CONST UINT32          *Reg;
>> +  UINT32                RegSize;
>> +  UINTN                 AddressCells, SizeCells;
>> +  UINT64                CurBase;
>> +  UINT64                CurSize;
>>
>> -  DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase));
>> +  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
>> +                  (VOID **)&FdtClient);
>> +  ASSERT_EFI_ERROR (Status);
>>
>>    //
>> -  // Check for memory node and add the memory spaces expect the lowest one
>> +  // Check for memory node and add the memory spaces except the lowest one
>>    //
>> -  for (Prev = 0;; Prev = Node) {
>> -    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
>> -    if (Node < 0) {
>> -      break;
>> -    }
>> +  for (FindNodeStatus = FdtClient->FindMemoryNodeReg (FdtClient, &Node,
>> +                                     (CONST VOID **) &Reg, &AddressCells,
>> +                                     &SizeCells, &RegSize);
>> +       !EFI_ERROR (FindNodeStatus);
>> +       FindNodeStatus = FdtClient->FindNextMemoryNodeReg (FdtClient, Node,
>> +                                     &Node, (CONST VOID **) &Reg, &AddressCells,
>> +                                     &SizeCells, &RegSize)) {
>> +
>
> I think we can remove this empty line. Not too important of course.
>

Sure

>> +    ASSERT (AddressCells <= 2);
>> +    ASSERT (SizeCells <= 2);
>>
>> -    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
>> -    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
>> -      //
>> -      // Get the 'reg' property of this node. For now, we will assume
>> -      // two 8 byte quantities for base and size, respectively.
>> -      //
>> -      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
>> -      if (RegProp != NULL && Len == (2 * sizeof (UINT64))) {
>> +    while (RegSize > 0) {
>>
>
> This one too. (Also just a matter of taste.)
>

If you prefer, I don't care either way.

>> -        CurBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
>> -        CurSize = fdt64_to_cpu (((UINT64 *)RegProp)[1]);
>> +      CurBase = SwapBytes32 (*Reg++);
>> +      if (AddressCells > 1) {
>> +        CurBase |= (CurBase << 32) | SwapBytes32 (*Reg++);
>
> The operator |= seems wrong; it should be just =.
>
> (You could do { CurBase <<= 32; CurBase |= SwapBytes32 (*Reg++); }. The
> above is more compact, but the operator should be fixed.)
>

You are right. I got away with it due to the fact that I tested with
base/size pairs <= 4GB, and so the leading cell == 0 in all cases.
Thanks for spotting that!

>> +      }
>> +      CurSize = SwapBytes32 (*Reg++);
>> +      if (SizeCells > 1) {
>> +        CurSize |= (CurSize << 32) | SwapBytes32 (*Reg++);
>
> Same here.
>
> With these fixed:
>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>

OK, thanks.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates
  2016-09-15 13:34 ` [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
@ 2016-09-15 14:40   ` Ard Biesheuvel
  0 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2016-09-15 14:40 UTC (permalink / raw)
  To: edk2-devel-01, Laszlo Ersek; +Cc: Shannon Zhao, Sakar Arora, Ard Biesheuvel

On 15 September 2016 at 14:34, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 15 September 2016 at 14:30, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>> Patch #4 moves HighMemDxe to the FDT client protocol, and updates it to
>> handle #address-cells/#size-cells values of <1> as well as <2>, and lets
>> it deal with memory nodes whose 'reg' properties describe multiple disjoint
>> regions.
>>
>> Patches #1 to #3 are somewhat preparatory in nature:
>> - Patch #1 is a small thinko fix
>> - Patch #2 drops the 'regelemsize' output parameter for 'reg' related methods
>>   of the FDT client protocol in favour of addresscells/sizecells.
>> - Patch #3 adds methods to iterate over all 'reg' properties of all memory nodes
>>

Committed as

38ed4a9e3a65 ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties
cfc8d51c0cbf ArmVirtPkg/FdtClientDxe: report address and size cell
count directly
969d2eb3875a ArmVirtPkg/FdtClientDxe: add methods to iterate over memory nodes
490acf8908f7 ArmVirtPkg/HighMemDxe: move to FDT client protocol

with your comments addressed.

Thanks,
Ard,


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-09-15 14:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-15 13:30 [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
2016-09-15 13:30 ` [PATCH 1/4] ArmVirtPkg/FdtClientDxe: fix check for size of "reg" properties Ard Biesheuvel
2016-09-15 13:38   ` Laszlo Ersek
2016-09-15 13:40     ` Ard Biesheuvel
2016-09-15 13:30 ` [PATCH 2/4] ArmVirtPkg/FdtClientDxe: report address and size cell count directly Ard Biesheuvel
2016-09-15 13:42   ` Laszlo Ersek
2016-09-15 13:30 ` [PATCH 3/4] ArmVirtPkg/FdtClient: add methods to iterate over memory nodes Ard Biesheuvel
2016-09-15 13:57   ` Laszlo Ersek
2016-09-15 14:04     ` Ard Biesheuvel
2016-09-15 13:30 ` [PATCH 4/4] ArmVirtPkg/HighMemDxe: move to FDT client protocol Ard Biesheuvel
2016-09-15 14:15   ` Laszlo Ersek
2016-09-15 14:18     ` Ard Biesheuvel
2016-09-15 13:34 ` [PATCH 0/4] ArmVirtPkg: FdtClientDxe & HighMemDxe updates Ard Biesheuvel
2016-09-15 14:40   ` Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox