1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/devtree/devtree.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2013,2015 */
/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
/* implied. See the License for the specific language governing */
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
#include <devtree/devtreeif.H>
#ifndef _DEVTREE_H
#define _DEVTREE_H
namespace DEVTREE
{
typedef size_t dtOffset_t;
/**
* The devtree class that does the actual work of
* generating and manipulating the devtree
*
*/
class devTree
{
public:
/**
* Initialize the FDT at address and size
* @param[in] i_addr Address to place FDT at
* @param[in] i_maxSize Size of FDT
* @param[in] i_virtual Address is virtual.
*/
void initialize(uint64_t i_addr, size_t i_maxSize, bool i_virtual);
/**
* Find given node (e.g. "/lpc") in the FDT
* @param[in] nodePath NULL terminated string of the path
* @return dtOffset_t into FDT of node location
*/
dtOffset_t findNode(const char* nodePath);
/**
* Find and return a pointer to a property within a node
* @param[in] nodeOffset Offset into FDT to start looking
* @param[in] propertyName NULL terminated string of the property
to get
* @return void* pointer to dtOffset_t into FDT of node location
*/
void* findProperty(dtOffset_t nodeOffset, const char* propertyName);
/**
* Add a new node under the parent node
* @param[in] parentNode Offset to parent node
* @param[in] nodeName NULL terminated string of node to add
* @return dtOffset_t into FDT of node location
*/
dtOffset_t addNode(dtOffset_t parentNode, const char* nodeName);
/**
* Add a new node under the parent node with address
* @param[in] parentNode Offset to parent node
* @param[in] nodeName NULL terminated string of node to add
* @param[in] unitAddress Address of the node
* @return dtOffset_t into FDT of node location
*/
dtOffset_t addNode(dtOffset_t parentNode, const char* nodeName,
uint64_t unitAddress);
/**
* Add a property to a node with no data
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
*/
void addProperty(dtOffset_t parentNode, const char* propertyName);
/**
* Add a property to a node with free form bytes
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] propertyData Data to add
* @param[in] numBytes Number of data bytes
*/
void addPropertyBytes(dtOffset_t parentNode, const char* propertyName,
const uint8_t* propertyData, uint32_t numBytes);
/**
* Add a property to a node with string data
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] propertyData NULL terminated string data
*/
void addPropertyString(dtOffset_t parentNode, const char* propertyName,
const char* propertyData);
/**
* Add a property to a node with array of strings
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] propertyData NULL terminated array of strings, last
* string must be NULL
*/
void addPropertyStrings(dtOffset_t parentNode, const char* propertyName,
const char** propertyData);
/**
* Add a property to a node with a 32 bit "cell" (aka uint32_t data)
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] cell Data to add
*/
void addPropertyCell32(dtOffset_t parentNode, const char* propertyName,
const uint32_t cell);
/**
* Add a property to a node with a 64 bit "cell" (aka uint64_t data)
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] cell Data to add
*/
void addPropertyCell64(dtOffset_t parentNode, const char* propertyName,
const uint64_t cell);
/**
* Add a property to a node with a 32 bit array of "cells"
* (aka uint32_t data)
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] cells Array of uint32_t data
* @param[in] numCells Number of cells
*/
void addPropertyCells32(dtOffset_t parentNode, const char* propertyName,
uint32_t cells[], uint32_t numCells);
/**
* Add a property to a node with a 64 bit array of "cells"
* (aka uint64_t data)
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] cells Array of uint64_t data
* @param[in] numCells Number of cells
*/
void addPropertyCells64(dtOffset_t parentNode, const char* propertyName,
uint64_t cells[], uint32_t numCells);
/**
* Return the physical "blob" address to the start of the FDT
* @return uin64_t to the start of the FDT memory
*/
uint64_t getBlobPhys();
/**
* Each devtree node has a "handle" number. This function returns the
* handle number for given node.
* @param[in] nodeOffset Offset to node
* @return uin32_t Handle number for node
*/
uint32_t getPhandle(dtOffset_t nodeOffset);
/**
* Append bytes to a property
* @param[in] parentNode Offset to node to add property to
* @param[in] propertyName NULL terminated string of property name
* @param[in] propertyData Data to add
* @param[in] numBytes Number of data bytes
*/
void appendPropertyBytes(dtOffset_t parentNode,
const char* propertyName,
const uint8_t* propertyData,
uint32_t numBytes);
/**
* Populate reserved memory regions
* @param[in] i_addrs Array of addresses to set in reserved memory
* @param[in] i_sizes Array of sizes to set in reserved memory
* @param[in] i_num Number of elements in the arrays
* @return int, zero on successes otherwise non zero
*/
int populateReservedMem(uint64_t i_addrs[],
uint64_t i_sizes[],
size_t i_num);
/**
* Return the current size of the FDT (not max)
* @return uin32_t Size of the FDT
*/
uint32_t getSize();
protected:
/*Constructor*/
devTree();
/*Destructor*/
~devTree();
/**
* Get the internal struct section at node offset
* @param[in] offset Offset to node
* @return uin32_t* pointer to struct section
*/
inline uint32_t* getStructSectionAtOffset(dtOffset_t offset);
/**
* Utility function to get the length fo the tag/name words for
* given node
* @param[in] nodeOffset Offset to node
* @return int Words consumed by tag/name in FDT
*/
int getNodeTagAndNameWords(dtOffset_t nodeOffset);
/**
* Utility function to get the length fo the tag/name words for
* given node
* @param[in] nodeOffset Offset to node
* @return int Words consumed by tag/name in FDT
*/
void insertStructSpace(uint32_t offset, int numNewWords);
/**
* Utility function to shift the string section
* @param[in] shiftSize Amount to shift
*/
void shiftStringsSection(int shiftSize);
/**
* Get number of words for property
* @param[in] propertyOffset Offset of property
* @return int Words consumed by Property
*/
int getPropertyWords(int propertyOffset);
/**
* Utility function to add String to string table
* @param[in] string NULL terminated string to add
* @return dtOffset_t Offset string was added at
*/
dtOffset_t addString(const char *string);
/**
* Set the boot CPU PIR into FDT
* @param[in] pir PIR value for boot processor
*/
void setBootCpu(uint32_t pir);
/**
* Utility function to locate string in string table
* @param[in] string NULL terminated string to find
* @param[out] stringOffset Offset if found
* @return bool True if found
*/
bool locateStringOffset(const char* string, uint32_t& stringOffset);
private:
enum Constants {
DT_MAGIC =0xd00dfeed,
DT_CUR_VERSION =0x11,
DT_COMPAT_VERSION =0x10,
DT_BEGIN_NODE =0x1,
DT_END_NODE =0x2,
DT_PROP =0x3,
DT_NOP =0x4,
DT_END =0x9,
DT_INVALID_OFFSET =0xFFFFFFFF,
DT_MAX_MEM_RESERVE =16,
};
typedef struct dtHeader
{
uint32_t magicNumber;
uint32_t totalSize;
uint32_t offsetStruct;
uint32_t offsetStrings;
uint32_t offsetReservedMemMap;
uint32_t version;
uint32_t lastCompatVersion;
uint32_t bootCpuId;
uint32_t sizeStrings;
uint32_t sizeStruct;
}
dtHeader_t;
typedef struct dtReserveEntry
{
uint64_t address;
uint64_t size;
}
dtReserveEntry_t;
union
{
dtHeader_t* mHeader;
char* mSpace;
};
uint32_t mNextPhandle;
size_t mMaxSize;
uint64_t mPhysAddr;
// let my testcase poke around
friend class devTreeTest;
};
uint32_t* devTree::getStructSectionAtOffset(dtOffset_t offset)
{
return (uint32_t*) (mSpace + mHeader->offsetStruct + offset);
}
}
#endif /* _DEVTREE_H */
|