1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright (c) 2000 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate * All rights reserved.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate #include <stdio.h>
30*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
31*7c478bd9Sstevel@tonic-gate #include <string.h>
32*7c478bd9Sstevel@tonic-gate
33*7c478bd9Sstevel@tonic-gate #include <fcode/private.h>
34*7c478bd9Sstevel@tonic-gate #include <fcode/log.h>
35*7c478bd9Sstevel@tonic-gate
36*7c478bd9Sstevel@tonic-gate void
create_prop(fcode_env_t * env,char * name)37*7c478bd9Sstevel@tonic-gate create_prop(fcode_env_t *env, char *name)
38*7c478bd9Sstevel@tonic-gate {
39*7c478bd9Sstevel@tonic-gate push_a_string(env, name);
40*7c478bd9Sstevel@tonic-gate property(env);
41*7c478bd9Sstevel@tonic-gate }
42*7c478bd9Sstevel@tonic-gate
43*7c478bd9Sstevel@tonic-gate void
create_int_prop(fcode_env_t * env,char * name,int val)44*7c478bd9Sstevel@tonic-gate create_int_prop(fcode_env_t *env, char *name, int val)
45*7c478bd9Sstevel@tonic-gate {
46*7c478bd9Sstevel@tonic-gate PUSH(DS, val);
47*7c478bd9Sstevel@tonic-gate encode_int(env);
48*7c478bd9Sstevel@tonic-gate create_prop(env, name);
49*7c478bd9Sstevel@tonic-gate }
50*7c478bd9Sstevel@tonic-gate
51*7c478bd9Sstevel@tonic-gate void
create_string_prop(fcode_env_t * env,char * name,char * val)52*7c478bd9Sstevel@tonic-gate create_string_prop(fcode_env_t *env, char *name, char *val)
53*7c478bd9Sstevel@tonic-gate {
54*7c478bd9Sstevel@tonic-gate push_a_string(env, val);
55*7c478bd9Sstevel@tonic-gate encode_string(env);
56*7c478bd9Sstevel@tonic-gate create_prop(env, name);
57*7c478bd9Sstevel@tonic-gate }
58*7c478bd9Sstevel@tonic-gate
59*7c478bd9Sstevel@tonic-gate static int
addr_cmp(void * a,void * b)60*7c478bd9Sstevel@tonic-gate addr_cmp(void *a, void *b)
61*7c478bd9Sstevel@tonic-gate {
62*7c478bd9Sstevel@tonic-gate return ((uchar_t *)a == (uchar_t *)b);
63*7c478bd9Sstevel@tonic-gate }
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate static void *
add_property_buffer(fcode_env_t * env,int len)66*7c478bd9Sstevel@tonic-gate add_property_buffer(fcode_env_t *env, int len)
67*7c478bd9Sstevel@tonic-gate {
68*7c478bd9Sstevel@tonic-gate void *data = MALLOC(len+1);
69*7c478bd9Sstevel@tonic-gate return (add_resource(&env->propbufs, data, addr_cmp));
70*7c478bd9Sstevel@tonic-gate }
71*7c478bd9Sstevel@tonic-gate
72*7c478bd9Sstevel@tonic-gate static void
free_property_buffer(fcode_env_t * env,void * buffer)73*7c478bd9Sstevel@tonic-gate free_property_buffer(fcode_env_t *env, void *buffer)
74*7c478bd9Sstevel@tonic-gate {
75*7c478bd9Sstevel@tonic-gate free_resource(&env->propbufs, buffer, addr_cmp);
76*7c478bd9Sstevel@tonic-gate FREE(buffer);
77*7c478bd9Sstevel@tonic-gate }
78*7c478bd9Sstevel@tonic-gate
79*7c478bd9Sstevel@tonic-gate /*
80*7c478bd9Sstevel@tonic-gate * Golden Rule:
81*7c478bd9Sstevel@tonic-gate * DO NOT cache the value of the head of the property list *before*
82*7c478bd9Sstevel@tonic-gate * looking up a property.
83*7c478bd9Sstevel@tonic-gate * This routine is also responsible for purging dead properties
84*7c478bd9Sstevel@tonic-gate * and that *can* affect the head pointer.
85*7c478bd9Sstevel@tonic-gate * you have been warned!
86*7c478bd9Sstevel@tonic-gate */
87*7c478bd9Sstevel@tonic-gate prop_t *
find_property(device_t * d,char * name)88*7c478bd9Sstevel@tonic-gate find_property(device_t *d, char *name)
89*7c478bd9Sstevel@tonic-gate {
90*7c478bd9Sstevel@tonic-gate prop_t *p = d->properties, *prev;
91*7c478bd9Sstevel@tonic-gate prop_t *found = NULL;
92*7c478bd9Sstevel@tonic-gate
93*7c478bd9Sstevel@tonic-gate prev = NULL;
94*7c478bd9Sstevel@tonic-gate while (p && !found) {
95*7c478bd9Sstevel@tonic-gate if (p->name) {
96*7c478bd9Sstevel@tonic-gate if (strcmp(name, p->name) == 0) {
97*7c478bd9Sstevel@tonic-gate found = p;
98*7c478bd9Sstevel@tonic-gate }
99*7c478bd9Sstevel@tonic-gate prev = p;
100*7c478bd9Sstevel@tonic-gate p = p->next;
101*7c478bd9Sstevel@tonic-gate } else {
102*7c478bd9Sstevel@tonic-gate prop_t *dead;
103*7c478bd9Sstevel@tonic-gate
104*7c478bd9Sstevel@tonic-gate if (prev)
105*7c478bd9Sstevel@tonic-gate prev->next = p->next;
106*7c478bd9Sstevel@tonic-gate else {
107*7c478bd9Sstevel@tonic-gate /* last prop in chain */
108*7c478bd9Sstevel@tonic-gate d->properties = p->next;
109*7c478bd9Sstevel@tonic-gate }
110*7c478bd9Sstevel@tonic-gate dead = p;
111*7c478bd9Sstevel@tonic-gate p = p->next;
112*7c478bd9Sstevel@tonic-gate FREE(dead->name);
113*7c478bd9Sstevel@tonic-gate FREE(dead->data);
114*7c478bd9Sstevel@tonic-gate FREE(dead);
115*7c478bd9Sstevel@tonic-gate }
116*7c478bd9Sstevel@tonic-gate }
117*7c478bd9Sstevel@tonic-gate return (found);
118*7c478bd9Sstevel@tonic-gate }
119*7c478bd9Sstevel@tonic-gate
120*7c478bd9Sstevel@tonic-gate static prop_t *
stack_find_property(fcode_env_t * env,device_t * d)121*7c478bd9Sstevel@tonic-gate stack_find_property(fcode_env_t *env, device_t *d)
122*7c478bd9Sstevel@tonic-gate {
123*7c478bd9Sstevel@tonic-gate char *propname;
124*7c478bd9Sstevel@tonic-gate
125*7c478bd9Sstevel@tonic-gate propname = pop_a_string(env, NULL);
126*7c478bd9Sstevel@tonic-gate return (find_property(d, propname));
127*7c478bd9Sstevel@tonic-gate }
128*7c478bd9Sstevel@tonic-gate
129*7c478bd9Sstevel@tonic-gate void
property(fcode_env_t * env)130*7c478bd9Sstevel@tonic-gate property(fcode_env_t *env)
131*7c478bd9Sstevel@tonic-gate {
132*7c478bd9Sstevel@tonic-gate int datalen;
133*7c478bd9Sstevel@tonic-gate char *propname, *srcptr;
134*7c478bd9Sstevel@tonic-gate prop_t *p;
135*7c478bd9Sstevel@tonic-gate device_t *d;
136*7c478bd9Sstevel@tonic-gate
137*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 4, "property");
138*7c478bd9Sstevel@tonic-gate if (MYSELF) {
139*7c478bd9Sstevel@tonic-gate d = MYSELF->device;
140*7c478bd9Sstevel@tonic-gate } else {
141*7c478bd9Sstevel@tonic-gate d = env->current_device;
142*7c478bd9Sstevel@tonic-gate if (!d) {
143*7c478bd9Sstevel@tonic-gate void *buffer;
144*7c478bd9Sstevel@tonic-gate
145*7c478bd9Sstevel@tonic-gate two_drop(env);
146*7c478bd9Sstevel@tonic-gate if ((buffer = pop_a_string(env, NULL)) != NULL)
147*7c478bd9Sstevel@tonic-gate free_property_buffer(env, buffer);
148*7c478bd9Sstevel@tonic-gate return;
149*7c478bd9Sstevel@tonic-gate }
150*7c478bd9Sstevel@tonic-gate }
151*7c478bd9Sstevel@tonic-gate propname = pop_a_string(env, NULL);
152*7c478bd9Sstevel@tonic-gate p = find_property(d, propname);
153*7c478bd9Sstevel@tonic-gate if (p == NULL) {
154*7c478bd9Sstevel@tonic-gate p = MALLOC(sizeof (prop_t));
155*7c478bd9Sstevel@tonic-gate p->next = d->properties;
156*7c478bd9Sstevel@tonic-gate d->properties = p;
157*7c478bd9Sstevel@tonic-gate p->name = STRDUP(propname);
158*7c478bd9Sstevel@tonic-gate } else if (p->data)
159*7c478bd9Sstevel@tonic-gate FREE(p->data); /* release old resources */
160*7c478bd9Sstevel@tonic-gate srcptr = pop_a_string(env, &datalen);
161*7c478bd9Sstevel@tonic-gate p->data = MALLOC(datalen+1);
162*7c478bd9Sstevel@tonic-gate p->size = datalen;
163*7c478bd9Sstevel@tonic-gate memcpy(p->data, srcptr, datalen);
164*7c478bd9Sstevel@tonic-gate p->data[datalen] = 0;
165*7c478bd9Sstevel@tonic-gate if (srcptr)
166*7c478bd9Sstevel@tonic-gate free_property_buffer(env, srcptr);
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate
169*7c478bd9Sstevel@tonic-gate prop_t *
lookup_package_property(fcode_env_t * env,char * propname,device_t * d)170*7c478bd9Sstevel@tonic-gate lookup_package_property(fcode_env_t *env, char *propname, device_t *d)
171*7c478bd9Sstevel@tonic-gate {
172*7c478bd9Sstevel@tonic-gate prop_t *p;
173*7c478bd9Sstevel@tonic-gate
174*7c478bd9Sstevel@tonic-gate p = find_property(d, propname);
175*7c478bd9Sstevel@tonic-gate if (p) {
176*7c478bd9Sstevel@tonic-gate return (p);
177*7c478bd9Sstevel@tonic-gate }
178*7c478bd9Sstevel@tonic-gate if (d->vectors.get_package_prop) {
179*7c478bd9Sstevel@tonic-gate static prop_t sp;
180*7c478bd9Sstevel@tonic-gate fstack_t fail, n;
181*7c478bd9Sstevel@tonic-gate
182*7c478bd9Sstevel@tonic-gate /* recreate the FORTH environment for the remote call */
183*7c478bd9Sstevel@tonic-gate push_a_string(env, propname);
184*7c478bd9Sstevel@tonic-gate REVERT_PHANDLE(env, n, d);
185*7c478bd9Sstevel@tonic-gate PUSH(DS, n);
186*7c478bd9Sstevel@tonic-gate d->vectors.get_package_prop(env);
187*7c478bd9Sstevel@tonic-gate fail = POP(DS);
188*7c478bd9Sstevel@tonic-gate if (fail)
189*7c478bd9Sstevel@tonic-gate return (NULL);
190*7c478bd9Sstevel@tonic-gate sp.size = POP(DS);
191*7c478bd9Sstevel@tonic-gate sp.data = (uchar_t *)POP(DS);
192*7c478bd9Sstevel@tonic-gate sp.name = propname;
193*7c478bd9Sstevel@tonic-gate sp.next = NULL;
194*7c478bd9Sstevel@tonic-gate return (&sp);
195*7c478bd9Sstevel@tonic-gate }
196*7c478bd9Sstevel@tonic-gate return (NULL);
197*7c478bd9Sstevel@tonic-gate }
198*7c478bd9Sstevel@tonic-gate
199*7c478bd9Sstevel@tonic-gate void
get_package_property(fcode_env_t * env)200*7c478bd9Sstevel@tonic-gate get_package_property(fcode_env_t *env)
201*7c478bd9Sstevel@tonic-gate {
202*7c478bd9Sstevel@tonic-gate prop_t *p;
203*7c478bd9Sstevel@tonic-gate device_t *d;
204*7c478bd9Sstevel@tonic-gate char *propname;
205*7c478bd9Sstevel@tonic-gate
206*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 3, "get-package-property");
207*7c478bd9Sstevel@tonic-gate CONVERT_PHANDLE(env, d, POP(DS));
208*7c478bd9Sstevel@tonic-gate propname = pop_a_string(env, NULL);
209*7c478bd9Sstevel@tonic-gate p = lookup_package_property(env, propname, d);
210*7c478bd9Sstevel@tonic-gate if (p) {
211*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)p->data);
212*7c478bd9Sstevel@tonic-gate PUSH(DS, p->size);
213*7c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
214*7c478bd9Sstevel@tonic-gate } else
215*7c478bd9Sstevel@tonic-gate PUSH(DS, TRUE);
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate
218*7c478bd9Sstevel@tonic-gate void
get_inherited_prop(fcode_env_t * env)219*7c478bd9Sstevel@tonic-gate get_inherited_prop(fcode_env_t *env)
220*7c478bd9Sstevel@tonic-gate {
221*7c478bd9Sstevel@tonic-gate instance_t *ih;
222*7c478bd9Sstevel@tonic-gate device_t *dev;
223*7c478bd9Sstevel@tonic-gate prop_t *prop;
224*7c478bd9Sstevel@tonic-gate char *pname;
225*7c478bd9Sstevel@tonic-gate int plen;
226*7c478bd9Sstevel@tonic-gate
227*7c478bd9Sstevel@tonic-gate /*
228*7c478bd9Sstevel@tonic-gate * First, we look thru the in-memory device tree for the property.
229*7c478bd9Sstevel@tonic-gate * If we don't find it, we call get_inherited_prop, which "knows" it's
230*7c478bd9Sstevel@tonic-gate * not going to find the property below the attachment point.
231*7c478bd9Sstevel@tonic-gate */
232*7c478bd9Sstevel@tonic-gate
233*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "get-inherited-property");
234*7c478bd9Sstevel@tonic-gate pname = pop_a_string(env, &plen);
235*7c478bd9Sstevel@tonic-gate ih = MYSELF;
236*7c478bd9Sstevel@tonic-gate if (ih) {
237*7c478bd9Sstevel@tonic-gate for (; ih; ih = ih->parent) {
238*7c478bd9Sstevel@tonic-gate dev = ih->device;
239*7c478bd9Sstevel@tonic-gate prop = find_property(dev, pname);
240*7c478bd9Sstevel@tonic-gate if (prop) {
241*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)prop->data);
242*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)prop->size);
243*7c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
244*7c478bd9Sstevel@tonic-gate return;
245*7c478bd9Sstevel@tonic-gate }
246*7c478bd9Sstevel@tonic-gate }
247*7c478bd9Sstevel@tonic-gate if (dev->vectors.get_inherited_prop) {
248*7c478bd9Sstevel@tonic-gate push_a_string(env, pname);
249*7c478bd9Sstevel@tonic-gate dev->vectors.get_inherited_prop(env);
250*7c478bd9Sstevel@tonic-gate return;
251*7c478bd9Sstevel@tonic-gate }
252*7c478bd9Sstevel@tonic-gate }
253*7c478bd9Sstevel@tonic-gate PUSH(DS, TRUE);
254*7c478bd9Sstevel@tonic-gate }
255*7c478bd9Sstevel@tonic-gate
256*7c478bd9Sstevel@tonic-gate void
delete_property(fcode_env_t * env)257*7c478bd9Sstevel@tonic-gate delete_property(fcode_env_t *env)
258*7c478bd9Sstevel@tonic-gate {
259*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "delete-property");
260*7c478bd9Sstevel@tonic-gate if (MYSELF) {
261*7c478bd9Sstevel@tonic-gate prop_t *p;
262*7c478bd9Sstevel@tonic-gate
263*7c478bd9Sstevel@tonic-gate p = stack_find_property(env, MYSELF->device);
264*7c478bd9Sstevel@tonic-gate if (p) {
265*7c478bd9Sstevel@tonic-gate /*
266*7c478bd9Sstevel@tonic-gate * write the name as NULL; the space will be free'd
267*7c478bd9Sstevel@tonic-gate * the next time a property lookup passes this node
268*7c478bd9Sstevel@tonic-gate */
269*7c478bd9Sstevel@tonic-gate p->name = NULL;
270*7c478bd9Sstevel@tonic-gate }
271*7c478bd9Sstevel@tonic-gate } else {
272*7c478bd9Sstevel@tonic-gate two_drop(env);
273*7c478bd9Sstevel@tonic-gate }
274*7c478bd9Sstevel@tonic-gate }
275*7c478bd9Sstevel@tonic-gate
276*7c478bd9Sstevel@tonic-gate void
get_my_property(fcode_env_t * env)277*7c478bd9Sstevel@tonic-gate get_my_property(fcode_env_t *env)
278*7c478bd9Sstevel@tonic-gate {
279*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "get-my-property");
280*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)MYSELF);
281*7c478bd9Sstevel@tonic-gate ihandle_to_phandle(env);
282*7c478bd9Sstevel@tonic-gate get_package_property(env);
283*7c478bd9Sstevel@tonic-gate }
284*7c478bd9Sstevel@tonic-gate
285*7c478bd9Sstevel@tonic-gate void
encode_string(fcode_env_t * env)286*7c478bd9Sstevel@tonic-gate encode_string(fcode_env_t *env)
287*7c478bd9Sstevel@tonic-gate {
288*7c478bd9Sstevel@tonic-gate char *str;
289*7c478bd9Sstevel@tonic-gate char *prop;
290*7c478bd9Sstevel@tonic-gate int len;
291*7c478bd9Sstevel@tonic-gate
292*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "encode-string");
293*7c478bd9Sstevel@tonic-gate str = pop_a_string(env, &len);
294*7c478bd9Sstevel@tonic-gate
295*7c478bd9Sstevel@tonic-gate prop = add_property_buffer(env, len);
296*7c478bd9Sstevel@tonic-gate memcpy(prop, str, len);
297*7c478bd9Sstevel@tonic-gate prop[len] = 0;
298*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)prop);
299*7c478bd9Sstevel@tonic-gate PUSH(DS, len + 1);
300*7c478bd9Sstevel@tonic-gate }
301*7c478bd9Sstevel@tonic-gate
302*7c478bd9Sstevel@tonic-gate void
encode_int(fcode_env_t * env)303*7c478bd9Sstevel@tonic-gate encode_int(fcode_env_t *env)
304*7c478bd9Sstevel@tonic-gate {
305*7c478bd9Sstevel@tonic-gate uchar_t *ptr;
306*7c478bd9Sstevel@tonic-gate uint32_t p;
307*7c478bd9Sstevel@tonic-gate
308*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "encode-int");
309*7c478bd9Sstevel@tonic-gate p = POP(DS);
310*7c478bd9Sstevel@tonic-gate ptr = add_property_buffer(env, sizeof (uint32_t));
311*7c478bd9Sstevel@tonic-gate
312*7c478bd9Sstevel@tonic-gate memcpy(ptr, (char *)&p, sizeof (uint32_t));
313*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)ptr);
314*7c478bd9Sstevel@tonic-gate PUSH(DS, sizeof (uint32_t));
315*7c478bd9Sstevel@tonic-gate }
316*7c478bd9Sstevel@tonic-gate
317*7c478bd9Sstevel@tonic-gate void
encode_phys(fcode_env_t * env)318*7c478bd9Sstevel@tonic-gate encode_phys(fcode_env_t *env)
319*7c478bd9Sstevel@tonic-gate {
320*7c478bd9Sstevel@tonic-gate uint_t ncells;
321*7c478bd9Sstevel@tonic-gate
322*7c478bd9Sstevel@tonic-gate ncells = get_number_of_parent_address_cells(env);
323*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, ncells, "encode-phys");
324*7c478bd9Sstevel@tonic-gate encode_int(env);
325*7c478bd9Sstevel@tonic-gate while (--ncells) {
326*7c478bd9Sstevel@tonic-gate rot(env);
327*7c478bd9Sstevel@tonic-gate encode_int(env);
328*7c478bd9Sstevel@tonic-gate encode_plus(env);
329*7c478bd9Sstevel@tonic-gate }
330*7c478bd9Sstevel@tonic-gate }
331*7c478bd9Sstevel@tonic-gate
332*7c478bd9Sstevel@tonic-gate static fstack_t
get_decoded_int(uchar_t * dp)333*7c478bd9Sstevel@tonic-gate get_decoded_int(uchar_t *dp)
334*7c478bd9Sstevel@tonic-gate {
335*7c478bd9Sstevel@tonic-gate uint32_t d;
336*7c478bd9Sstevel@tonic-gate
337*7c478bd9Sstevel@tonic-gate memcpy((char *)&d, dp, sizeof (uint32_t));
338*7c478bd9Sstevel@tonic-gate return (d);
339*7c478bd9Sstevel@tonic-gate }
340*7c478bd9Sstevel@tonic-gate
341*7c478bd9Sstevel@tonic-gate int
get_default_intprop(fcode_env_t * env,char * name,device_t * d,int def)342*7c478bd9Sstevel@tonic-gate get_default_intprop(fcode_env_t *env, char *name, device_t *d, int def)
343*7c478bd9Sstevel@tonic-gate {
344*7c478bd9Sstevel@tonic-gate prop_t *p;
345*7c478bd9Sstevel@tonic-gate
346*7c478bd9Sstevel@tonic-gate if (!d) /* Kludge for testing */
347*7c478bd9Sstevel@tonic-gate return (def);
348*7c478bd9Sstevel@tonic-gate p = lookup_package_property(env, name, d);
349*7c478bd9Sstevel@tonic-gate if (p == NULL)
350*7c478bd9Sstevel@tonic-gate return (def);
351*7c478bd9Sstevel@tonic-gate return (get_decoded_int(p->data));
352*7c478bd9Sstevel@tonic-gate }
353*7c478bd9Sstevel@tonic-gate
354*7c478bd9Sstevel@tonic-gate int
get_num_addr_cells(fcode_env_t * env,device_t * d)355*7c478bd9Sstevel@tonic-gate get_num_addr_cells(fcode_env_t *env, device_t *d)
356*7c478bd9Sstevel@tonic-gate {
357*7c478bd9Sstevel@tonic-gate return (get_default_intprop(env, "#address-cells", d, 2));
358*7c478bd9Sstevel@tonic-gate }
359*7c478bd9Sstevel@tonic-gate
360*7c478bd9Sstevel@tonic-gate int
get_num_size_cells(fcode_env_t * env,device_t * d)361*7c478bd9Sstevel@tonic-gate get_num_size_cells(fcode_env_t *env, device_t *d)
362*7c478bd9Sstevel@tonic-gate {
363*7c478bd9Sstevel@tonic-gate return (get_default_intprop(env, "#size-cells", d, 1));
364*7c478bd9Sstevel@tonic-gate }
365*7c478bd9Sstevel@tonic-gate
366*7c478bd9Sstevel@tonic-gate void
decode_phys(fcode_env_t * env)367*7c478bd9Sstevel@tonic-gate decode_phys(fcode_env_t *env)
368*7c478bd9Sstevel@tonic-gate {
369*7c478bd9Sstevel@tonic-gate char *ptr;
370*7c478bd9Sstevel@tonic-gate int len;
371*7c478bd9Sstevel@tonic-gate int adr_cells;
372*7c478bd9Sstevel@tonic-gate int offset;
373*7c478bd9Sstevel@tonic-gate
374*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "decode-phys");
375*7c478bd9Sstevel@tonic-gate ptr = pop_a_string(env, &len);
376*7c478bd9Sstevel@tonic-gate
377*7c478bd9Sstevel@tonic-gate adr_cells = get_num_addr_cells(env, env->current_device->parent);
378*7c478bd9Sstevel@tonic-gate
379*7c478bd9Sstevel@tonic-gate offset = sizeof (uint32_t) * adr_cells;
380*7c478bd9Sstevel@tonic-gate
381*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)(ptr + offset));
382*7c478bd9Sstevel@tonic-gate PUSH(DS, len + offset);
383*7c478bd9Sstevel@tonic-gate
384*7c478bd9Sstevel@tonic-gate while (adr_cells--) {
385*7c478bd9Sstevel@tonic-gate fstack_t d;
386*7c478bd9Sstevel@tonic-gate offset -= sizeof (uint32_t);
387*7c478bd9Sstevel@tonic-gate d = get_decoded_int((uchar_t *)(ptr + offset));
388*7c478bd9Sstevel@tonic-gate PUSH(DS, d);
389*7c478bd9Sstevel@tonic-gate }
390*7c478bd9Sstevel@tonic-gate }
391*7c478bd9Sstevel@tonic-gate
392*7c478bd9Sstevel@tonic-gate /*
393*7c478bd9Sstevel@tonic-gate * 'reg' Fcode 0x116
394*7c478bd9Sstevel@tonic-gate */
395*7c478bd9Sstevel@tonic-gate void
reg_prop(fcode_env_t * env)396*7c478bd9Sstevel@tonic-gate reg_prop(fcode_env_t *env)
397*7c478bd9Sstevel@tonic-gate {
398*7c478bd9Sstevel@tonic-gate fstack_t size;
399*7c478bd9Sstevel@tonic-gate
400*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "reg");
401*7c478bd9Sstevel@tonic-gate size = POP(DS);
402*7c478bd9Sstevel@tonic-gate encode_phys(env);
403*7c478bd9Sstevel@tonic-gate PUSH(DS, size);
404*7c478bd9Sstevel@tonic-gate encode_int(env);
405*7c478bd9Sstevel@tonic-gate encode_plus(env);
406*7c478bd9Sstevel@tonic-gate create_prop(env, "reg");
407*7c478bd9Sstevel@tonic-gate }
408*7c478bd9Sstevel@tonic-gate
409*7c478bd9Sstevel@tonic-gate void
encode_bytes(fcode_env_t * env)410*7c478bd9Sstevel@tonic-gate encode_bytes(fcode_env_t *env)
411*7c478bd9Sstevel@tonic-gate {
412*7c478bd9Sstevel@tonic-gate char *str;
413*7c478bd9Sstevel@tonic-gate char *prop;
414*7c478bd9Sstevel@tonic-gate int len;
415*7c478bd9Sstevel@tonic-gate
416*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "encode-bytes");
417*7c478bd9Sstevel@tonic-gate str = pop_a_string(env, &len);
418*7c478bd9Sstevel@tonic-gate prop = add_property_buffer(env, len);
419*7c478bd9Sstevel@tonic-gate memcpy(prop, str, len);
420*7c478bd9Sstevel@tonic-gate prop[len] = 0;
421*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)prop);
422*7c478bd9Sstevel@tonic-gate PUSH(DS, len);
423*7c478bd9Sstevel@tonic-gate }
424*7c478bd9Sstevel@tonic-gate
425*7c478bd9Sstevel@tonic-gate void
decode_int(fcode_env_t * env)426*7c478bd9Sstevel@tonic-gate decode_int(fcode_env_t *env)
427*7c478bd9Sstevel@tonic-gate {
428*7c478bd9Sstevel@tonic-gate char *dp;
429*7c478bd9Sstevel@tonic-gate fstack_t d;
430*7c478bd9Sstevel@tonic-gate int len;
431*7c478bd9Sstevel@tonic-gate
432*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "decode-int");
433*7c478bd9Sstevel@tonic-gate dp = pop_a_string(env, &len);
434*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)(dp + sizeof (uint32_t)));
435*7c478bd9Sstevel@tonic-gate PUSH(DS, len - sizeof (uint32_t));
436*7c478bd9Sstevel@tonic-gate d = get_decoded_int((uchar_t *)dp);
437*7c478bd9Sstevel@tonic-gate PUSH(DS, d);
438*7c478bd9Sstevel@tonic-gate }
439*7c478bd9Sstevel@tonic-gate
440*7c478bd9Sstevel@tonic-gate void
decode_string(fcode_env_t * env)441*7c478bd9Sstevel@tonic-gate decode_string(fcode_env_t *env)
442*7c478bd9Sstevel@tonic-gate {
443*7c478bd9Sstevel@tonic-gate int plen, len;
444*7c478bd9Sstevel@tonic-gate char *dp;
445*7c478bd9Sstevel@tonic-gate
446*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "decode-string");
447*7c478bd9Sstevel@tonic-gate dp = pop_a_string(env, &plen);
448*7c478bd9Sstevel@tonic-gate len = strlen(dp) + 1;
449*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)(dp + len));
450*7c478bd9Sstevel@tonic-gate PUSH(DS, plen - len);
451*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)dp);
452*7c478bd9Sstevel@tonic-gate PUSH(DS, len - 1);
453*7c478bd9Sstevel@tonic-gate }
454*7c478bd9Sstevel@tonic-gate
455*7c478bd9Sstevel@tonic-gate void
encode_plus(fcode_env_t * env)456*7c478bd9Sstevel@tonic-gate encode_plus(fcode_env_t *env)
457*7c478bd9Sstevel@tonic-gate {
458*7c478bd9Sstevel@tonic-gate int len1, len2;
459*7c478bd9Sstevel@tonic-gate char *src1, *src2;
460*7c478bd9Sstevel@tonic-gate uchar_t *new;
461*7c478bd9Sstevel@tonic-gate
462*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 4, "encode+");
463*7c478bd9Sstevel@tonic-gate src1 = pop_a_string(env, &len1);
464*7c478bd9Sstevel@tonic-gate src2 = pop_a_string(env, &len2);
465*7c478bd9Sstevel@tonic-gate new = add_property_buffer(env, len1 + len2);
466*7c478bd9Sstevel@tonic-gate if (src2) {
467*7c478bd9Sstevel@tonic-gate memcpy(new, src2, len2);
468*7c478bd9Sstevel@tonic-gate free_property_buffer(env, src2);
469*7c478bd9Sstevel@tonic-gate }
470*7c478bd9Sstevel@tonic-gate if (src1) {
471*7c478bd9Sstevel@tonic-gate memcpy(new + len2, src1, len1);
472*7c478bd9Sstevel@tonic-gate free_property_buffer(env, src1);
473*7c478bd9Sstevel@tonic-gate }
474*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)new);
475*7c478bd9Sstevel@tonic-gate PUSH(DS, len1 + len2);
476*7c478bd9Sstevel@tonic-gate }
477*7c478bd9Sstevel@tonic-gate
478*7c478bd9Sstevel@tonic-gate static void
make_special_property(fcode_env_t * env,char * name)479*7c478bd9Sstevel@tonic-gate make_special_property(fcode_env_t *env, char *name)
480*7c478bd9Sstevel@tonic-gate {
481*7c478bd9Sstevel@tonic-gate push_a_string(env, name);
482*7c478bd9Sstevel@tonic-gate property(env);
483*7c478bd9Sstevel@tonic-gate }
484*7c478bd9Sstevel@tonic-gate
485*7c478bd9Sstevel@tonic-gate void
device_name(fcode_env_t * env)486*7c478bd9Sstevel@tonic-gate device_name(fcode_env_t *env)
487*7c478bd9Sstevel@tonic-gate {
488*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "device-name");
489*7c478bd9Sstevel@tonic-gate encode_string(env);
490*7c478bd9Sstevel@tonic-gate make_special_property(env, "name");
491*7c478bd9Sstevel@tonic-gate }
492*7c478bd9Sstevel@tonic-gate
493*7c478bd9Sstevel@tonic-gate void
model_prop(fcode_env_t * env)494*7c478bd9Sstevel@tonic-gate model_prop(fcode_env_t *env)
495*7c478bd9Sstevel@tonic-gate {
496*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "model");
497*7c478bd9Sstevel@tonic-gate encode_string(env);
498*7c478bd9Sstevel@tonic-gate make_special_property(env, "model");
499*7c478bd9Sstevel@tonic-gate }
500*7c478bd9Sstevel@tonic-gate
501*7c478bd9Sstevel@tonic-gate void
device_type(fcode_env_t * env)502*7c478bd9Sstevel@tonic-gate device_type(fcode_env_t *env)
503*7c478bd9Sstevel@tonic-gate {
504*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "device-type");
505*7c478bd9Sstevel@tonic-gate encode_string(env);
506*7c478bd9Sstevel@tonic-gate make_special_property(env, "device_type");
507*7c478bd9Sstevel@tonic-gate }
508*7c478bd9Sstevel@tonic-gate
509*7c478bd9Sstevel@tonic-gate /*
510*7c478bd9Sstevel@tonic-gate * 'next-property' Fcode implementation.
511*7c478bd9Sstevel@tonic-gate */
512*7c478bd9Sstevel@tonic-gate void
next_property(fcode_env_t * env)513*7c478bd9Sstevel@tonic-gate next_property(fcode_env_t *env)
514*7c478bd9Sstevel@tonic-gate {
515*7c478bd9Sstevel@tonic-gate device_t *phandle;
516*7c478bd9Sstevel@tonic-gate char *previous;
517*7c478bd9Sstevel@tonic-gate prop_t *p;
518*7c478bd9Sstevel@tonic-gate
519*7c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 3, "next-property");
520*7c478bd9Sstevel@tonic-gate phandle = (device_t *)POP(DS);
521*7c478bd9Sstevel@tonic-gate previous = pop_a_string(env, NULL);
522*7c478bd9Sstevel@tonic-gate p = phandle->properties;
523*7c478bd9Sstevel@tonic-gate if (previous == NULL)
524*7c478bd9Sstevel@tonic-gate p = phandle->properties;
525*7c478bd9Sstevel@tonic-gate else if (p = find_property(phandle, previous))
526*7c478bd9Sstevel@tonic-gate p = p->next;
527*7c478bd9Sstevel@tonic-gate
528*7c478bd9Sstevel@tonic-gate for (; p != NULL && p->name == NULL; p = p->next)
529*7c478bd9Sstevel@tonic-gate ;
530*7c478bd9Sstevel@tonic-gate
531*7c478bd9Sstevel@tonic-gate if (p)
532*7c478bd9Sstevel@tonic-gate push_a_string(env, p->name);
533*7c478bd9Sstevel@tonic-gate else
534*7c478bd9Sstevel@tonic-gate push_a_string(env, "");
535*7c478bd9Sstevel@tonic-gate PUSH(DS, TRUE);
536*7c478bd9Sstevel@tonic-gate }
537*7c478bd9Sstevel@tonic-gate
538*7c478bd9Sstevel@tonic-gate void
get_property(fcode_env_t * env)539*7c478bd9Sstevel@tonic-gate get_property(fcode_env_t *env)
540*7c478bd9Sstevel@tonic-gate {
541*7c478bd9Sstevel@tonic-gate if (MYSELF)
542*7c478bd9Sstevel@tonic-gate get_my_property(env);
543*7c478bd9Sstevel@tonic-gate else if (env->current_device) {
544*7c478bd9Sstevel@tonic-gate fstack_t d;
545*7c478bd9Sstevel@tonic-gate
546*7c478bd9Sstevel@tonic-gate REVERT_PHANDLE(env, d, env->current_device);
547*7c478bd9Sstevel@tonic-gate PUSH(DS, d);
548*7c478bd9Sstevel@tonic-gate get_package_property(env);
549*7c478bd9Sstevel@tonic-gate } else {
550*7c478bd9Sstevel@tonic-gate two_drop(env);
551*7c478bd9Sstevel@tonic-gate log_message(MSG_WARN, "No device context\n");
552*7c478bd9Sstevel@tonic-gate }
553*7c478bd9Sstevel@tonic-gate }
554*7c478bd9Sstevel@tonic-gate
555*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
556*7c478bd9Sstevel@tonic-gate
557*7c478bd9Sstevel@tonic-gate static void
print_indented(char * name)558*7c478bd9Sstevel@tonic-gate print_indented(char *name)
559*7c478bd9Sstevel@tonic-gate {
560*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%-28s", name);
561*7c478bd9Sstevel@tonic-gate }
562*7c478bd9Sstevel@tonic-gate
563*7c478bd9Sstevel@tonic-gate static void
print_string(fcode_env_t * env,uchar_t * data,int len)564*7c478bd9Sstevel@tonic-gate print_string(fcode_env_t *env, uchar_t *data, int len)
565*7c478bd9Sstevel@tonic-gate {
566*7c478bd9Sstevel@tonic-gate while (len > 0) {
567*7c478bd9Sstevel@tonic-gate int nlen = (strlen((char *)data)+1);
568*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s\n", data);
569*7c478bd9Sstevel@tonic-gate len -= nlen;
570*7c478bd9Sstevel@tonic-gate data += nlen;
571*7c478bd9Sstevel@tonic-gate if (len > 0)
572*7c478bd9Sstevel@tonic-gate print_indented("");
573*7c478bd9Sstevel@tonic-gate }
574*7c478bd9Sstevel@tonic-gate }
575*7c478bd9Sstevel@tonic-gate
576*7c478bd9Sstevel@tonic-gate static void
print_ints(uchar_t * data,int len,int crlf)577*7c478bd9Sstevel@tonic-gate print_ints(uchar_t *data, int len, int crlf)
578*7c478bd9Sstevel@tonic-gate {
579*7c478bd9Sstevel@tonic-gate uint32_t d;
580*7c478bd9Sstevel@tonic-gate
581*7c478bd9Sstevel@tonic-gate while (len--) {
582*7c478bd9Sstevel@tonic-gate d = get_decoded_int(data);
583*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%8.8lx ", d);
584*7c478bd9Sstevel@tonic-gate data += sizeof (uint32_t);
585*7c478bd9Sstevel@tonic-gate }
586*7c478bd9Sstevel@tonic-gate if (crlf)
587*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n");
588*7c478bd9Sstevel@tonic-gate }
589*7c478bd9Sstevel@tonic-gate
590*7c478bd9Sstevel@tonic-gate static void
print_integer(fcode_env_t * env,uchar_t * data,int len)591*7c478bd9Sstevel@tonic-gate print_integer(fcode_env_t *env, uchar_t *data, int len)
592*7c478bd9Sstevel@tonic-gate {
593*7c478bd9Sstevel@tonic-gate print_ints(data, len/sizeof (uint32_t), 1);
594*7c478bd9Sstevel@tonic-gate }
595*7c478bd9Sstevel@tonic-gate
596*7c478bd9Sstevel@tonic-gate static void
print_bytes(fcode_env_t * env,uchar_t * data,int len)597*7c478bd9Sstevel@tonic-gate print_bytes(fcode_env_t *env, uchar_t *data, int len)
598*7c478bd9Sstevel@tonic-gate {
599*7c478bd9Sstevel@tonic-gate while (len--) {
600*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%2.2x ", *data++);
601*7c478bd9Sstevel@tonic-gate }
602*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n");
603*7c478bd9Sstevel@tonic-gate }
604*7c478bd9Sstevel@tonic-gate
605*7c478bd9Sstevel@tonic-gate static void
print_bytes_indented(fcode_env_t * env,uchar_t * data,int len)606*7c478bd9Sstevel@tonic-gate print_bytes_indented(fcode_env_t *env, uchar_t *data, int len)
607*7c478bd9Sstevel@tonic-gate {
608*7c478bd9Sstevel@tonic-gate int nbytes;
609*7c478bd9Sstevel@tonic-gate
610*7c478bd9Sstevel@tonic-gate for (; ; ) {
611*7c478bd9Sstevel@tonic-gate nbytes = min(len, 16);
612*7c478bd9Sstevel@tonic-gate print_bytes(env, data, nbytes);
613*7c478bd9Sstevel@tonic-gate len -= nbytes;
614*7c478bd9Sstevel@tonic-gate data += nbytes;
615*7c478bd9Sstevel@tonic-gate if (len == 0)
616*7c478bd9Sstevel@tonic-gate break;
617*7c478bd9Sstevel@tonic-gate print_indented("");
618*7c478bd9Sstevel@tonic-gate }
619*7c478bd9Sstevel@tonic-gate }
620*7c478bd9Sstevel@tonic-gate
621*7c478bd9Sstevel@tonic-gate static void
print_reg(fcode_env_t * env,uchar_t * data,int len)622*7c478bd9Sstevel@tonic-gate print_reg(fcode_env_t *env, uchar_t *data, int len)
623*7c478bd9Sstevel@tonic-gate {
624*7c478bd9Sstevel@tonic-gate int pcells, nlen;
625*7c478bd9Sstevel@tonic-gate
626*7c478bd9Sstevel@tonic-gate if (env->current_device != NULL &&
627*7c478bd9Sstevel@tonic-gate env->current_device->parent != NULL) {
628*7c478bd9Sstevel@tonic-gate pcells = get_num_size_cells(env, env->current_device->parent);
629*7c478bd9Sstevel@tonic-gate pcells += get_num_addr_cells(env, env->current_device->parent);
630*7c478bd9Sstevel@tonic-gate nlen = pcells*sizeof (uint32_t);
631*7c478bd9Sstevel@tonic-gate while (len > 0) {
632*7c478bd9Sstevel@tonic-gate print_ints(data, pcells, 1);
633*7c478bd9Sstevel@tonic-gate len -= nlen;
634*7c478bd9Sstevel@tonic-gate data += nlen;
635*7c478bd9Sstevel@tonic-gate if (len > 0)
636*7c478bd9Sstevel@tonic-gate print_indented("");
637*7c478bd9Sstevel@tonic-gate }
638*7c478bd9Sstevel@tonic-gate } else
639*7c478bd9Sstevel@tonic-gate print_bytes_indented(env, data, len);
640*7c478bd9Sstevel@tonic-gate }
641*7c478bd9Sstevel@tonic-gate
642*7c478bd9Sstevel@tonic-gate static void
print_imap(fcode_env_t * env,uchar_t * dp,int len)643*7c478bd9Sstevel@tonic-gate print_imap(fcode_env_t *env, uchar_t *dp, int len)
644*7c478bd9Sstevel@tonic-gate {
645*7c478bd9Sstevel@tonic-gate int n, icells;
646*7c478bd9Sstevel@tonic-gate
647*7c478bd9Sstevel@tonic-gate if (env->current_device == NULL) {
648*7c478bd9Sstevel@tonic-gate print_bytes_indented(env, dp, len);
649*7c478bd9Sstevel@tonic-gate return;
650*7c478bd9Sstevel@tonic-gate }
651*7c478bd9Sstevel@tonic-gate n = get_num_addr_cells(env, env->current_device);
652*7c478bd9Sstevel@tonic-gate
653*7c478bd9Sstevel@tonic-gate while (len) {
654*7c478bd9Sstevel@tonic-gate int offset;
655*7c478bd9Sstevel@tonic-gate fstack_t data;
656*7c478bd9Sstevel@tonic-gate device_t *node;
657*7c478bd9Sstevel@tonic-gate
658*7c478bd9Sstevel@tonic-gate offset = 0;
659*7c478bd9Sstevel@tonic-gate data = get_decoded_int(dp+((n+1)*sizeof (uint32_t)));
660*7c478bd9Sstevel@tonic-gate CONVERT_PHANDLE(env, node, data);
661*7c478bd9Sstevel@tonic-gate offset += (n+2)*sizeof (uint32_t);
662*7c478bd9Sstevel@tonic-gate print_ints(dp, (n+2), 0);
663*7c478bd9Sstevel@tonic-gate icells = get_default_intprop(env, "#interrupt-cells", node, 1);
664*7c478bd9Sstevel@tonic-gate print_ints(dp+offset, icells, 1);
665*7c478bd9Sstevel@tonic-gate offset += icells*sizeof (uint32_t);
666*7c478bd9Sstevel@tonic-gate dp += offset;
667*7c478bd9Sstevel@tonic-gate len -= offset;
668*7c478bd9Sstevel@tonic-gate if (len)
669*7c478bd9Sstevel@tonic-gate print_indented("");
670*7c478bd9Sstevel@tonic-gate }
671*7c478bd9Sstevel@tonic-gate }
672*7c478bd9Sstevel@tonic-gate
673*7c478bd9Sstevel@tonic-gate static void
print_ranges(fcode_env_t * env,uchar_t * data,int len)674*7c478bd9Sstevel@tonic-gate print_ranges(fcode_env_t *env, uchar_t *data, int len)
675*7c478bd9Sstevel@tonic-gate {
676*7c478bd9Sstevel@tonic-gate int pcells, nlen;
677*7c478bd9Sstevel@tonic-gate
678*7c478bd9Sstevel@tonic-gate if (env->current_device != NULL &&
679*7c478bd9Sstevel@tonic-gate env->current_device->parent != NULL) {
680*7c478bd9Sstevel@tonic-gate pcells = get_num_addr_cells(env, env->current_device);
681*7c478bd9Sstevel@tonic-gate pcells += get_num_addr_cells(env, env->current_device->parent);
682*7c478bd9Sstevel@tonic-gate pcells += get_num_size_cells(env, env->current_device);
683*7c478bd9Sstevel@tonic-gate nlen = pcells*sizeof (uint32_t);
684*7c478bd9Sstevel@tonic-gate while (len > 0) {
685*7c478bd9Sstevel@tonic-gate print_ints(data, pcells, 1);
686*7c478bd9Sstevel@tonic-gate len -= nlen;
687*7c478bd9Sstevel@tonic-gate data += nlen;
688*7c478bd9Sstevel@tonic-gate if (len > 0)
689*7c478bd9Sstevel@tonic-gate print_indented("");
690*7c478bd9Sstevel@tonic-gate }
691*7c478bd9Sstevel@tonic-gate } else
692*7c478bd9Sstevel@tonic-gate print_bytes_indented(env, data, len);
693*7c478bd9Sstevel@tonic-gate }
694*7c478bd9Sstevel@tonic-gate
695*7c478bd9Sstevel@tonic-gate typedef struct MAGIC_PROP {
696*7c478bd9Sstevel@tonic-gate char *name;
697*7c478bd9Sstevel@tonic-gate void (*fn)(fcode_env_t *env, uchar_t *data, int len);
698*7c478bd9Sstevel@tonic-gate } magic_prop_t;
699*7c478bd9Sstevel@tonic-gate
700*7c478bd9Sstevel@tonic-gate static magic_prop_t magic_props[] = {
701*7c478bd9Sstevel@tonic-gate { "name", print_string },
702*7c478bd9Sstevel@tonic-gate { "device_type", print_string },
703*7c478bd9Sstevel@tonic-gate { "model", print_string },
704*7c478bd9Sstevel@tonic-gate { "reg", print_reg },
705*7c478bd9Sstevel@tonic-gate { "assigned-addresses", print_reg },
706*7c478bd9Sstevel@tonic-gate { "interrupt-map", print_imap },
707*7c478bd9Sstevel@tonic-gate { "#interrupt-cells", print_integer },
708*7c478bd9Sstevel@tonic-gate { "interrupt-map-mask", print_integer },
709*7c478bd9Sstevel@tonic-gate { "#size-cells", print_integer },
710*7c478bd9Sstevel@tonic-gate { "#address-cells", print_integer },
711*7c478bd9Sstevel@tonic-gate { "ranges", print_ranges },
712*7c478bd9Sstevel@tonic-gate { "device-id", print_integer },
713*7c478bd9Sstevel@tonic-gate { "vendor-id", print_integer },
714*7c478bd9Sstevel@tonic-gate { "class-code", print_integer },
715*7c478bd9Sstevel@tonic-gate { "compatible", print_string },
716*7c478bd9Sstevel@tonic-gate { "version", print_string },
717*7c478bd9Sstevel@tonic-gate { "manufacturer", print_string },
718*7c478bd9Sstevel@tonic-gate { NULL, NULL }
719*7c478bd9Sstevel@tonic-gate };
720*7c478bd9Sstevel@tonic-gate
721*7c478bd9Sstevel@tonic-gate static void
print_content(fcode_env_t * env,char * prop,uchar_t * data,int len)722*7c478bd9Sstevel@tonic-gate print_content(fcode_env_t *env, char *prop, uchar_t *data, int len)
723*7c478bd9Sstevel@tonic-gate {
724*7c478bd9Sstevel@tonic-gate magic_prop_t *p;
725*7c478bd9Sstevel@tonic-gate
726*7c478bd9Sstevel@tonic-gate for (p = magic_props; p->name; p++)
727*7c478bd9Sstevel@tonic-gate if (strcmp(prop, p->name) == 0) {
728*7c478bd9Sstevel@tonic-gate (*p->fn)(env, data, len);
729*7c478bd9Sstevel@tonic-gate return;
730*7c478bd9Sstevel@tonic-gate }
731*7c478bd9Sstevel@tonic-gate print_bytes_indented(env, data, len);
732*7c478bd9Sstevel@tonic-gate }
733*7c478bd9Sstevel@tonic-gate
734*7c478bd9Sstevel@tonic-gate void
print_property(fcode_env_t * env,prop_t * p,char * prepend)735*7c478bd9Sstevel@tonic-gate print_property(fcode_env_t *env, prop_t *p, char *prepend)
736*7c478bd9Sstevel@tonic-gate {
737*7c478bd9Sstevel@tonic-gate char buf[40];
738*7c478bd9Sstevel@tonic-gate char *name = (p->name ? p->name : "<noname>");
739*7c478bd9Sstevel@tonic-gate
740*7c478bd9Sstevel@tonic-gate if (prepend) {
741*7c478bd9Sstevel@tonic-gate sprintf(buf, "%s %s", prepend, name);
742*7c478bd9Sstevel@tonic-gate name = buf;
743*7c478bd9Sstevel@tonic-gate }
744*7c478bd9Sstevel@tonic-gate print_indented(name);
745*7c478bd9Sstevel@tonic-gate if (p->name)
746*7c478bd9Sstevel@tonic-gate print_content(env, p->name, p->data, p->size);
747*7c478bd9Sstevel@tonic-gate else
748*7c478bd9Sstevel@tonic-gate print_bytes_indented(env, p->data, p->size);
749*7c478bd9Sstevel@tonic-gate }
750*7c478bd9Sstevel@tonic-gate
751*7c478bd9Sstevel@tonic-gate void
dot_properties(fcode_env_t * env)752*7c478bd9Sstevel@tonic-gate dot_properties(fcode_env_t *env)
753*7c478bd9Sstevel@tonic-gate {
754*7c478bd9Sstevel@tonic-gate prop_t *p;
755*7c478bd9Sstevel@tonic-gate instance_t *omyself;
756*7c478bd9Sstevel@tonic-gate
757*7c478bd9Sstevel@tonic-gate omyself = MYSELF;
758*7c478bd9Sstevel@tonic-gate MYSELF = NULL;
759*7c478bd9Sstevel@tonic-gate
760*7c478bd9Sstevel@tonic-gate if (env->current_device) {
761*7c478bd9Sstevel@tonic-gate for (p = env->current_device->properties; p; p = p->next)
762*7c478bd9Sstevel@tonic-gate print_property(env, p, NULL);
763*7c478bd9Sstevel@tonic-gate } else {
764*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "No device context\n");
765*7c478bd9Sstevel@tonic-gate }
766*7c478bd9Sstevel@tonic-gate MYSELF = omyself;
767*7c478bd9Sstevel@tonic-gate }
768*7c478bd9Sstevel@tonic-gate
769*7c478bd9Sstevel@tonic-gate #endif
770*7c478bd9Sstevel@tonic-gate
771*7c478bd9Sstevel@tonic-gate #pragma init(_init)
772*7c478bd9Sstevel@tonic-gate
773*7c478bd9Sstevel@tonic-gate static void
_init(void)774*7c478bd9Sstevel@tonic-gate _init(void)
775*7c478bd9Sstevel@tonic-gate {
776*7c478bd9Sstevel@tonic-gate fcode_env_t *env = initial_env;
777*7c478bd9Sstevel@tonic-gate
778*7c478bd9Sstevel@tonic-gate ASSERT(env);
779*7c478bd9Sstevel@tonic-gate NOTICE;
780*7c478bd9Sstevel@tonic-gate
781*7c478bd9Sstevel@tonic-gate P1275(0x110, 0, "property", property);
782*7c478bd9Sstevel@tonic-gate P1275(0x111, 0, "encode-int", encode_int);
783*7c478bd9Sstevel@tonic-gate P1275(0x112, 0, "encode+", encode_plus);
784*7c478bd9Sstevel@tonic-gate P1275(0x113, 0, "encode-phys", encode_phys);
785*7c478bd9Sstevel@tonic-gate P1275(0x114, 0, "encode-string", encode_string);
786*7c478bd9Sstevel@tonic-gate P1275(0x115, 0, "encode-bytes", encode_bytes);
787*7c478bd9Sstevel@tonic-gate P1275(0x116, 0, "reg", reg_prop);
788*7c478bd9Sstevel@tonic-gate FCODE(0x117, 0, "intr", fc_obsolete);
789*7c478bd9Sstevel@tonic-gate FCODE(0x118, 0, "driver", fc_historical);
790*7c478bd9Sstevel@tonic-gate P1275(0x119, 0, "model", model_prop);
791*7c478bd9Sstevel@tonic-gate P1275(0x11a, 0, "device-type", device_type);
792*7c478bd9Sstevel@tonic-gate
793*7c478bd9Sstevel@tonic-gate P1275(0x128, 0, "decode-phys", decode_phys);
794*7c478bd9Sstevel@tonic-gate
795*7c478bd9Sstevel@tonic-gate P1275(0x201, 0, "device-name", device_name);
796*7c478bd9Sstevel@tonic-gate
797*7c478bd9Sstevel@tonic-gate P1275(0x21a, 0, "get-my-property", get_my_property);
798*7c478bd9Sstevel@tonic-gate P1275(0x21b, 0, "decode-int", decode_int);
799*7c478bd9Sstevel@tonic-gate P1275(0x21c, 0, "decode-string", decode_string);
800*7c478bd9Sstevel@tonic-gate P1275(0x21d, 0, "get-inherited-property", get_inherited_prop);
801*7c478bd9Sstevel@tonic-gate P1275(0x21e, 0, "delete-property", delete_property);
802*7c478bd9Sstevel@tonic-gate P1275(0x21f, 0, "get-package-property", get_package_property);
803*7c478bd9Sstevel@tonic-gate
804*7c478bd9Sstevel@tonic-gate P1275(0x23d, 0, "next-property", next_property);
805*7c478bd9Sstevel@tonic-gate
806*7c478bd9Sstevel@tonic-gate FORTH(0, "get-property", get_property);
807*7c478bd9Sstevel@tonic-gate FORTH(0, ".properties", dot_properties);
808*7c478bd9Sstevel@tonic-gate }
809