1 /*
2 * Copyright (c) 2015, Linaro Ltd. All rights reserved.
3 *
4 * This program and the accompanying materials
5 * are licensed and made available under the terms and conditions of the BSD License
6 * which accompanies this distribution. The full text of the license may be found at
7 * http://opensource.org/licenses/bsd-license.php
8 *
9 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 */
12
13 #include <Uefi.h>
14 #include <Include/libfdt.h>
15
16 BOOLEAN
FindMemnode(IN VOID * DeviceTreeBlob,OUT UINT64 * SystemMemoryBase,OUT UINT64 * SystemMemorySize)17 FindMemnode (
18 IN VOID *DeviceTreeBlob,
19 OUT UINT64 *SystemMemoryBase,
20 OUT UINT64 *SystemMemorySize
21 )
22 {
23 INT32 MemoryNode;
24 INT32 AddressCells;
25 INT32 SizeCells;
26 INT32 Length;
27 CONST INT32 *Prop;
28
29 if (fdt_check_header (DeviceTreeBlob) != 0) {
30 return FALSE;
31 }
32
33 //
34 // Look for a node called "memory" at the lowest level of the tree
35 //
36 MemoryNode = fdt_path_offset (DeviceTreeBlob, "/memory");
37 if (MemoryNode <= 0) {
38 return FALSE;
39 }
40
41 //
42 // Retrieve the #address-cells and #size-cells properties
43 // from the root node, or use the default if not provided.
44 //
45 AddressCells = 1;
46 SizeCells = 1;
47
48 Prop = fdt_getprop (DeviceTreeBlob, 0, "#address-cells", &Length);
49 if (Length == 4) {
50 AddressCells = fdt32_to_cpu (*Prop);
51 }
52
53 Prop = fdt_getprop (DeviceTreeBlob, 0, "#size-cells", &Length);
54 if (Length == 4) {
55 SizeCells = fdt32_to_cpu (*Prop);
56 }
57
58 //
59 // Now find the 'reg' property of the /memory node, and read the first
60 // range listed.
61 //
62 Prop = fdt_getprop (DeviceTreeBlob, MemoryNode, "reg", &Length);
63
64 if (Length < (AddressCells + SizeCells) * sizeof (INT32)) {
65 return FALSE;
66 }
67
68 *SystemMemoryBase = fdt32_to_cpu (Prop[0]);
69 if (AddressCells > 1) {
70 *SystemMemoryBase = (*SystemMemoryBase << 32) | fdt32_to_cpu (Prop[1]);
71 }
72 Prop += AddressCells;
73
74 *SystemMemorySize = fdt32_to_cpu (Prop[0]);
75 if (SizeCells > 1) {
76 *SystemMemorySize = (*SystemMemorySize << 32) | fdt32_to_cpu (Prop[1]);
77 }
78
79 return TRUE;
80 }
81
82 VOID
CopyFdt(IN VOID * FdtDest,IN VOID * FdtSource)83 CopyFdt (
84 IN VOID *FdtDest,
85 IN VOID *FdtSource
86 )
87 {
88 CopyMem (FdtDest, FdtSource, fdt_totalsize (FdtSource));
89 }
90