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   if (AddressCells == 1) {
69     *SystemMemoryBase = fdt32_to_cpu (*Prop);
70   } else {
71     *SystemMemoryBase = fdt64_to_cpu (*(UINT64 *)Prop);
72   }
73   Prop += AddressCells;
74 
75   if (SizeCells == 1) {
76     *SystemMemorySize = fdt32_to_cpu (*Prop);
77   } else {
78     *SystemMemorySize = fdt64_to_cpu (*(UINT64 *)Prop);
79   }
80 
81   return TRUE;
82 }
83 
84 VOID
CopyFdt(IN VOID * FdtDest,IN VOID * FdtSource)85 CopyFdt (
86   IN    VOID    *FdtDest,
87   IN    VOID    *FdtSource
88   )
89 {
90   CopyMem (FdtDest, FdtSource, fdt_totalsize (FdtSource));
91 }
92