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