]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/PrePi/FdtParser.c
4754cba55c7bb408bd06a1881b8940fe36bf22b1
[mirror_edk2.git] / ArmVirtPkg / PrePi / FdtParser.c
1 /*
2 * Copyright (c) 2015, Linaro Ltd. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause-Patent
5 */
6
7 #include <Uefi.h>
8 #include <Include/libfdt.h>
9
10 BOOLEAN
11 FindMemnode (
12 IN VOID *DeviceTreeBlob,
13 OUT UINT64 *SystemMemoryBase,
14 OUT UINT64 *SystemMemorySize
15 )
16 {
17 INT32 MemoryNode;
18 INT32 AddressCells;
19 INT32 SizeCells;
20 INT32 Length;
21 CONST INT32 *Prop;
22
23 if (fdt_check_header (DeviceTreeBlob) != 0) {
24 return FALSE;
25 }
26
27 //
28 // Look for a node called "memory" at the lowest level of the tree
29 //
30 MemoryNode = fdt_path_offset (DeviceTreeBlob, "/memory");
31 if (MemoryNode <= 0) {
32 return FALSE;
33 }
34
35 //
36 // Retrieve the #address-cells and #size-cells properties
37 // from the root node, or use the default if not provided.
38 //
39 AddressCells = 1;
40 SizeCells = 1;
41
42 Prop = fdt_getprop (DeviceTreeBlob, 0, "#address-cells", &Length);
43 if (Length == 4) {
44 AddressCells = fdt32_to_cpu (*Prop);
45 }
46
47 Prop = fdt_getprop (DeviceTreeBlob, 0, "#size-cells", &Length);
48 if (Length == 4) {
49 SizeCells = fdt32_to_cpu (*Prop);
50 }
51
52 //
53 // Now find the 'reg' property of the /memory node, and read the first
54 // range listed.
55 //
56 Prop = fdt_getprop (DeviceTreeBlob, MemoryNode, "reg", &Length);
57
58 if (Length < (AddressCells + SizeCells) * sizeof (INT32)) {
59 return FALSE;
60 }
61
62 *SystemMemoryBase = fdt32_to_cpu (Prop[0]);
63 if (AddressCells > 1) {
64 *SystemMemoryBase = (*SystemMemoryBase << 32) | fdt32_to_cpu (Prop[1]);
65 }
66 Prop += AddressCells;
67
68 *SystemMemorySize = fdt32_to_cpu (Prop[0]);
69 if (SizeCells > 1) {
70 *SystemMemorySize = (*SystemMemorySize << 32) | fdt32_to_cpu (Prop[1]);
71 }
72
73 return TRUE;
74 }
75
76 VOID
77 CopyFdt (
78 IN VOID *FdtDest,
79 IN VOID *FdtSource
80 )
81 {
82 fdt_pack(FdtSource);
83 CopyMem (FdtDest, FdtSource, fdt_totalsize (FdtSource));
84 }