Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / arch / ppc / mol / prom.c
1 /*
2  *   Creation Date: <2002/10/03 20:55:02 samuel>
3  *   Time-stamp: <2002/10/29 13:00:23 samuel>
4  *
5  *      <prom.c>
6  *
7  *      oftree interface
8  *
9  *   Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se)
10  *
11  *   This program is free software; you can redistribute it and/or
12  *   modify it under the terms of the GNU General Public License
13  *   as published by the Free Software Foundation
14  *
15  */
16
17 #include "config.h"
18 #include "osi_calls.h"
19 #include "mol/prom.h"
20
21 /* OSI_PromClose (free linux side device tree) */
22 int
23 prom_close( void )
24 {
25         return OSI_PromIface( kPromClose, 0 );
26 }
27
28 /* ret: 0 no more peers, -1 if error */
29 mol_phandle_t
30 prom_peer( mol_phandle_t phandle )
31 {
32         return OSI_PromIface( kPromPeer, phandle );
33 }
34
35 /* ret: 0 no child, -1 if error */
36 mol_phandle_t
37 prom_child( mol_phandle_t phandle )
38 {
39         return OSI_PromIface( kPromChild, phandle );
40 }
41
42 /* ret: 0 if root node, -1 if error */
43 mol_phandle_t
44 prom_parent( mol_phandle_t phandle )
45 {
46         return OSI_PromIface( kPromParent, phandle );
47 }
48
49 /* ret: -1 error */
50 int
51 prom_package_to_path( mol_phandle_t phandle, char *buf, long buflen )
52 {
53         return OSI_PromIface2( kPromPackageToPath, phandle, (int)buf, buflen );
54 }
55
56 /* ret: -1 error */
57 int
58 prom_get_prop_len( mol_phandle_t phandle, const char *name )
59 {
60         return OSI_PromIface1( kPromGetPropLen, phandle, (int)name );
61 }
62
63 /* ret: prop len or -1 if error */
64 int
65 prom_get_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen )
66 {
67         return OSI_PromIface3( kPromGetProp, phandle, (int)name, (int)buf, buflen );
68 }
69
70 /* ret: prop len or -1 if error */
71 int
72 prom_get_prop_by_path( const char *path, const char *name, char *buf, long buflen )
73 {
74         mol_phandle_t ph = prom_find_device(path);
75         return (ph != -1)? prom_get_prop( ph, name, buf, buflen) : -1;
76 }
77
78 /* ret: -1 error, 0 last prop, 1 otherwise */
79 int
80 prom_next_prop( mol_phandle_t phandle, const char *prev, char *buf )
81 {
82         return OSI_PromIface2( kPromNextProp, phandle, (int)prev, (int)buf );
83 }
84
85 /* ret: -1 if error */
86 int
87 prom_set_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen )
88 {
89         return OSI_PromIface3( kPromSetProp, phandle, (int)name, (int)buf, buflen );
90 }
91
92 /* ret: -1 if error */
93 mol_phandle_t
94 prom_create_node( const char *path )
95 {
96         return OSI_PromPathIface( kPromCreateNode, path );
97 }
98
99 /* ret: -1 if not found */
100 mol_phandle_t
101 prom_find_device( const char *path )
102 {
103         mol_phandle_t ph;
104         char buf2[256], ch, *p;
105
106         if( !path )
107                 return -1;
108
109         if( (ph=OSI_PromPathIface( kPromFindDevice, path )) != -1 )
110                 return ph;
111         else if( path[0] == '/' )
112                 return -1;
113
114         /* might be an alias */
115         if( !(p=strpbrk(path, "@:/")) )
116                 p = (char*)path + strlen(path);
117
118         ch = *p;
119         *p = 0;
120         if( (ph=prom_get_prop(prom_find_device("/aliases"), path, buf2, sizeof(buf2))) == -1 )
121                 return -1;
122         *p = ch;
123         strncat( buf2, p, sizeof(buf2) );
124
125         if( buf2[0] != '/' ) {
126                 printk("Error: aliases must be absolute!\n");
127                 return -1;
128         }
129         ph = OSI_PromPathIface( kPromFindDevice, buf2 );
130         return ph;
131 }
132
133
134
135 /************************************************************************/
136 /*      search the tree for nodes with matching device_type             */
137 /************************************************************************/
138
139 static mol_phandle_t
140 prom_find_device_type_( mol_phandle_t ph, const char *type, int *icount, int index )
141 {
142         char buf[64];
143         int ph2;
144
145         if( ph == -1 || !ph )
146                 return -1;
147         if( prom_get_prop( ph, "device_type", buf, sizeof(buf)) > 0 )
148                 if( !strcmp(buf, type) )
149                         if( (*icount)++ == index )
150                                 return ph;
151         if( (ph2=prom_find_device_type_( prom_peer(ph), type, icount, index )) != -1 )
152                 return ph2;
153         if( (ph2=prom_find_device_type_( prom_child(ph), type, icount, index )) != -1 )
154                 return ph2;
155         return -1;
156 }
157
158 mol_phandle_t
159 prom_find_device_type( const char *type, int index )
160 {
161         int count = 0;
162         return prom_find_device_type_( prom_peer(0), type, &count, index );
163 }
164
165
166 /************************************************************************/
167 /*      device tree tweaking                                            */
168 /************************************************************************/
169
170 /* -1 if error */
171 int
172 prom_change_phandle( mol_phandle_t old_ph, mol_phandle_t new_ph )
173 {
174         return OSI_PromIface1( kPromChangePHandle, old_ph, (int)new_ph );
175 }