Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/sparc/prom/tree_64.c
10817 views
1
/*
2
* tree.c: Basic device tree traversal/scanning for the Linux
3
* prom library.
4
*
5
* Copyright (C) 1995 David S. Miller ([email protected])
6
* Copyright (C) 1996,1997 Jakub Jelinek ([email protected])
7
*/
8
9
#include <linux/string.h>
10
#include <linux/types.h>
11
#include <linux/kernel.h>
12
#include <linux/sched.h>
13
#include <linux/module.h>
14
15
#include <asm/openprom.h>
16
#include <asm/oplib.h>
17
#include <asm/ldc.h>
18
19
static phandle prom_node_to_node(const char *type, phandle node)
20
{
21
unsigned long args[5];
22
23
args[0] = (unsigned long) type;
24
args[1] = 1;
25
args[2] = 1;
26
args[3] = (unsigned int) node;
27
args[4] = (unsigned long) -1;
28
29
p1275_cmd_direct(args);
30
31
return (phandle) args[4];
32
}
33
34
/* Return the child of node 'node' or zero if no this node has no
35
* direct descendent.
36
*/
37
inline phandle __prom_getchild(phandle node)
38
{
39
return prom_node_to_node("child", node);
40
}
41
42
inline phandle prom_getchild(phandle node)
43
{
44
phandle cnode;
45
46
if ((s32)node == -1)
47
return 0;
48
cnode = __prom_getchild(node);
49
if ((s32)cnode == -1)
50
return 0;
51
return cnode;
52
}
53
EXPORT_SYMBOL(prom_getchild);
54
55
inline phandle prom_getparent(phandle node)
56
{
57
phandle cnode;
58
59
if ((s32)node == -1)
60
return 0;
61
cnode = prom_node_to_node("parent", node);
62
if ((s32)cnode == -1)
63
return 0;
64
return cnode;
65
}
66
67
/* Return the next sibling of node 'node' or zero if no more siblings
68
* at this level of depth in the tree.
69
*/
70
inline phandle __prom_getsibling(phandle node)
71
{
72
return prom_node_to_node(prom_peer_name, node);
73
}
74
75
inline phandle prom_getsibling(phandle node)
76
{
77
phandle sibnode;
78
79
if ((s32)node == -1)
80
return 0;
81
sibnode = __prom_getsibling(node);
82
if ((s32)sibnode == -1)
83
return 0;
84
85
return sibnode;
86
}
87
EXPORT_SYMBOL(prom_getsibling);
88
89
/* Return the length in bytes of property 'prop' at node 'node'.
90
* Return -1 on error.
91
*/
92
inline int prom_getproplen(phandle node, const char *prop)
93
{
94
unsigned long args[6];
95
96
if (!node || !prop)
97
return -1;
98
99
args[0] = (unsigned long) "getproplen";
100
args[1] = 2;
101
args[2] = 1;
102
args[3] = (unsigned int) node;
103
args[4] = (unsigned long) prop;
104
args[5] = (unsigned long) -1;
105
106
p1275_cmd_direct(args);
107
108
return (int) args[5];
109
}
110
EXPORT_SYMBOL(prom_getproplen);
111
112
/* Acquire a property 'prop' at node 'node' and place it in
113
* 'buffer' which has a size of 'bufsize'. If the acquisition
114
* was successful the length will be returned, else -1 is returned.
115
*/
116
inline int prom_getproperty(phandle node, const char *prop,
117
char *buffer, int bufsize)
118
{
119
unsigned long args[8];
120
int plen;
121
122
plen = prom_getproplen(node, prop);
123
if ((plen > bufsize) || (plen == 0) || (plen == -1))
124
return -1;
125
126
args[0] = (unsigned long) prom_getprop_name;
127
args[1] = 4;
128
args[2] = 1;
129
args[3] = (unsigned int) node;
130
args[4] = (unsigned long) prop;
131
args[5] = (unsigned long) buffer;
132
args[6] = bufsize;
133
args[7] = (unsigned long) -1;
134
135
p1275_cmd_direct(args);
136
137
return (int) args[7];
138
}
139
EXPORT_SYMBOL(prom_getproperty);
140
141
/* Acquire an integer property and return its value. Returns -1
142
* on failure.
143
*/
144
inline int prom_getint(phandle node, const char *prop)
145
{
146
int intprop;
147
148
if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
149
return intprop;
150
151
return -1;
152
}
153
EXPORT_SYMBOL(prom_getint);
154
155
/* Acquire an integer property, upon error return the passed default
156
* integer.
157
*/
158
159
int prom_getintdefault(phandle node, const char *property, int deflt)
160
{
161
int retval;
162
163
retval = prom_getint(node, property);
164
if (retval == -1)
165
return deflt;
166
167
return retval;
168
}
169
EXPORT_SYMBOL(prom_getintdefault);
170
171
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
172
int prom_getbool(phandle node, const char *prop)
173
{
174
int retval;
175
176
retval = prom_getproplen(node, prop);
177
if (retval == -1)
178
return 0;
179
return 1;
180
}
181
EXPORT_SYMBOL(prom_getbool);
182
183
/* Acquire a property whose value is a string, returns a null
184
* string on error. The char pointer is the user supplied string
185
* buffer.
186
*/
187
void prom_getstring(phandle node, const char *prop, char *user_buf,
188
int ubuf_size)
189
{
190
int len;
191
192
len = prom_getproperty(node, prop, user_buf, ubuf_size);
193
if (len != -1)
194
return;
195
user_buf[0] = 0;
196
}
197
EXPORT_SYMBOL(prom_getstring);
198
199
/* Does the device at node 'node' have name 'name'?
200
* YES = 1 NO = 0
201
*/
202
int prom_nodematch(phandle node, const char *name)
203
{
204
char namebuf[128];
205
prom_getproperty(node, "name", namebuf, sizeof(namebuf));
206
if (strcmp(namebuf, name) == 0)
207
return 1;
208
return 0;
209
}
210
211
/* Search siblings at 'node_start' for a node with name
212
* 'nodename'. Return node if successful, zero if not.
213
*/
214
phandle prom_searchsiblings(phandle node_start, const char *nodename)
215
{
216
phandle thisnode;
217
int error;
218
char promlib_buf[128];
219
220
for(thisnode = node_start; thisnode;
221
thisnode=prom_getsibling(thisnode)) {
222
error = prom_getproperty(thisnode, "name", promlib_buf,
223
sizeof(promlib_buf));
224
/* Should this ever happen? */
225
if(error == -1) continue;
226
if(strcmp(nodename, promlib_buf)==0) return thisnode;
227
}
228
229
return 0;
230
}
231
EXPORT_SYMBOL(prom_searchsiblings);
232
233
static const char *prom_nextprop_name = "nextprop";
234
235
/* Return the first property type for node 'node'.
236
* buffer should be at least 32B in length
237
*/
238
inline char *prom_firstprop(phandle node, char *buffer)
239
{
240
unsigned long args[7];
241
242
*buffer = 0;
243
if ((s32)node == -1)
244
return buffer;
245
246
args[0] = (unsigned long) prom_nextprop_name;
247
args[1] = 3;
248
args[2] = 1;
249
args[3] = (unsigned int) node;
250
args[4] = 0;
251
args[5] = (unsigned long) buffer;
252
args[6] = (unsigned long) -1;
253
254
p1275_cmd_direct(args);
255
256
return buffer;
257
}
258
EXPORT_SYMBOL(prom_firstprop);
259
260
/* Return the property type string after property type 'oprop'
261
* at node 'node' . Returns NULL string if no more
262
* property types for this node.
263
*/
264
inline char *prom_nextprop(phandle node, const char *oprop, char *buffer)
265
{
266
unsigned long args[7];
267
char buf[32];
268
269
if ((s32)node == -1) {
270
*buffer = 0;
271
return buffer;
272
}
273
if (oprop == buffer) {
274
strcpy (buf, oprop);
275
oprop = buf;
276
}
277
278
args[0] = (unsigned long) prom_nextprop_name;
279
args[1] = 3;
280
args[2] = 1;
281
args[3] = (unsigned int) node;
282
args[4] = (unsigned long) oprop;
283
args[5] = (unsigned long) buffer;
284
args[6] = (unsigned long) -1;
285
286
p1275_cmd_direct(args);
287
288
return buffer;
289
}
290
EXPORT_SYMBOL(prom_nextprop);
291
292
phandle prom_finddevice(const char *name)
293
{
294
unsigned long args[5];
295
296
if (!name)
297
return 0;
298
args[0] = (unsigned long) "finddevice";
299
args[1] = 1;
300
args[2] = 1;
301
args[3] = (unsigned long) name;
302
args[4] = (unsigned long) -1;
303
304
p1275_cmd_direct(args);
305
306
return (int) args[4];
307
}
308
EXPORT_SYMBOL(prom_finddevice);
309
310
int prom_node_has_property(phandle node, const char *prop)
311
{
312
char buf [32];
313
314
*buf = 0;
315
do {
316
prom_nextprop(node, buf, buf);
317
if (!strcmp(buf, prop))
318
return 1;
319
} while (*buf);
320
return 0;
321
}
322
EXPORT_SYMBOL(prom_node_has_property);
323
324
/* Set property 'pname' at node 'node' to value 'value' which has a length
325
* of 'size' bytes. Return the number of bytes the prom accepted.
326
*/
327
int
328
prom_setprop(phandle node, const char *pname, char *value, int size)
329
{
330
unsigned long args[8];
331
332
if (size == 0)
333
return 0;
334
if ((pname == 0) || (value == 0))
335
return 0;
336
337
#ifdef CONFIG_SUN_LDOMS
338
if (ldom_domaining_enabled) {
339
ldom_set_var(pname, value);
340
return 0;
341
}
342
#endif
343
args[0] = (unsigned long) "setprop";
344
args[1] = 4;
345
args[2] = 1;
346
args[3] = (unsigned int) node;
347
args[4] = (unsigned long) pname;
348
args[5] = (unsigned long) value;
349
args[6] = size;
350
args[7] = (unsigned long) -1;
351
352
p1275_cmd_direct(args);
353
354
return (int) args[7];
355
}
356
EXPORT_SYMBOL(prom_setprop);
357
358
inline phandle prom_inst2pkg(int inst)
359
{
360
unsigned long args[5];
361
phandle node;
362
363
args[0] = (unsigned long) "instance-to-package";
364
args[1] = 1;
365
args[2] = 1;
366
args[3] = (unsigned int) inst;
367
args[4] = (unsigned long) -1;
368
369
p1275_cmd_direct(args);
370
371
node = (int) args[4];
372
if ((s32)node == -1)
373
return 0;
374
return node;
375
}
376
377
int prom_ihandle2path(int handle, char *buffer, int bufsize)
378
{
379
unsigned long args[7];
380
381
args[0] = (unsigned long) "instance-to-path";
382
args[1] = 3;
383
args[2] = 1;
384
args[3] = (unsigned int) handle;
385
args[4] = (unsigned long) buffer;
386
args[5] = bufsize;
387
args[6] = (unsigned long) -1;
388
389
p1275_cmd_direct(args);
390
391
return (int) args[6];
392
}
393
394