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