aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/ArmVirtPkg/PrePi/FdtParser.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/ArmVirtPkg/PrePi/FdtParser.c')
-rw-r--r--roms/edk2/ArmVirtPkg/PrePi/FdtParser.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/roms/edk2/ArmVirtPkg/PrePi/FdtParser.c b/roms/edk2/ArmVirtPkg/PrePi/FdtParser.c
new file mode 100644
index 000000000..4754cba55
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/FdtParser.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, Linaro Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ */
+
+#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));
+}