1 /* $NetBSD: aml_evalobj.c,v 1.1 2007/01/14 04:36:13 christos Exp $ */
4 * Copyright (c) 1999 Takanori Watanabe
5 * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * Id: aml_evalobj.c,v 1.27 2000/08/16 18:14:53 iwasaki Exp
30 * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_evalobj.c,v 1.4 2000/11/09 06:24:45 iwasaki Exp $
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: aml_evalobj.c,v 1.1 2007/01/14 04:36:13 christos Exp $");
35 #include <sys/param.h>
37 #include <acpi_common.h>
38 #include <aml/aml_amlmem.h>
39 #include <aml/aml_common.h>
40 #include <aml/aml_env.h>
41 #include <aml/aml_evalobj.h>
42 #include <aml/aml_name.h>
43 #include <aml/aml_obj.h>
44 #include <aml/aml_parse.h>
45 #include <aml/aml_region.h>
46 #include <aml/aml_status.h>
47 #include <aml/aml_store.h>
50 #include <sys/param.h>
63 #include <sys/systm.h>
66 static union aml_object
*aml_eval_fieldobject(struct aml_environ
*env
,
67 struct aml_name
*name
);
69 static union aml_object
*
70 aml_eval_fieldobject(struct aml_environ
*env
, struct aml_name
*name
)
73 struct aml_name
*oname
,*wname
;
74 struct aml_field
*field
;
75 struct aml_opregion
*or;
76 union aml_object tobj
;
80 if (name
== NULL
|| name
->property
== NULL
||
81 name
->property
->type
!= aml_t_field
) {
83 env
->stat
= aml_stat_panic
;
86 field
= &name
->property
->field
;
88 if (field
->bitlen
> 32) {
89 env
->tempobject
.type
= aml_t_regfield
;
91 env
->tempobject
.type
= aml_t_num
;
94 if (field
->f
.ftype
== f_t_field
) {
95 wname
= aml_search_name(env
, field
->f
.fld
.regname
);
96 if (wname
== NULL
|| wname
->property
== NULL
||
97 wname
->property
->type
!= aml_t_opregion
) {
98 AML_DEBUGPRINT("Inappropreate Type\n");
99 env
->stat
= aml_stat_panic
;
100 env
->curname
= oname
;
103 or = &wname
->property
->opregion
;
104 if (env
->tempobject
.type
== aml_t_regfield
) {
105 env
->tempobject
.regfield
.space
= or->space
;
106 env
->tempobject
.regfield
.flags
= field
->flags
;
107 env
->tempobject
.regfield
.offset
= or->offset
;
108 env
->tempobject
.regfield
.bitoffset
= field
->bitoffset
;
109 env
->tempobject
.regfield
.bitlen
= field
->bitlen
;
111 env
->tempobject
.type
= aml_t_num
;
112 env
->tempobject
.num
.number
= aml_region_read(env
,
113 or->space
, field
->flags
, or->offset
,
114 field
->bitoffset
, field
->bitlen
);
115 AML_DEBUGPRINT("[read(%d, 0x%x)->0x%x]",
116 or->space
, or->offset
+ field
->bitoffset
/ 8,
117 env
->tempobject
.num
.number
);
119 } else if (field
->f
.ftype
== f_t_index
) {
120 wname
= aml_search_name(env
, field
->f
.ifld
.indexname
);
121 tobj
.type
= aml_t_num
;
122 tobj
.num
.number
= field
->bitoffset
/ 8;/* AccessType Boundary */
123 aml_store_to_name(env
, &tobj
, wname
);
124 wname
= aml_search_name(env
, field
->f
.ifld
.dataname
);
125 num
= aml_objtonum(env
, aml_eval_name(env
, wname
));
126 env
->tempobject
.type
= aml_t_num
;
127 env
->tempobject
.num
.number
= (num
>> (field
->bitoffset
& 7)) &
128 ((1 << field
->bitlen
) - 1);
130 env
->curname
= oname
;
131 return (&env
->tempobject
);
135 aml_eval_objref(struct aml_environ
*env
, union aml_object
*obj
)
138 union aml_object num1
;
139 union aml_object
*ref
, *ret
;
142 if (obj
->objref
.deref
== 1) {
143 num1
.type
= aml_t_num
;
144 offset
= obj
->objref
.offset
;
145 ref
= obj
->objref
.ref
;
151 if (ref
->package
.elements
> offset
) {
152 ret
= ref
->package
.objects
[offset
];
155 env
->tempobject
= num1
;
156 ret
= &env
->tempobject
;
160 if (ref
->buffer
.size
> offset
) {
161 num1
.num
.number
= ref
->buffer
.data
[offset
] & 0xff;
165 env
->tempobject
= num1
;
166 ret
= &env
->tempobject
;
172 if (obj
->objref
.alias
== 1) {
173 ret
= aml_eval_name(env
, obj
->objref
.nameref
);
184 aml_eval_name(struct aml_environ
*env
, struct aml_name
*aname
)
188 struct aml_name
*tmp
;
189 struct aml_environ
*copy
;
190 struct aml_local_stack
*stack
;
191 union aml_object
*obj
, *ret
;
192 union aml_object
*src
;
195 if (aname
== NULL
|| aname
->property
== NULL
) {
198 if (env
->stat
== aml_stat_panic
) {
201 copy
= memman_alloc(aml_memman
, memid_aml_environ
);
205 ret
= aname
->property
;
209 env
->stat
= aml_stat_panic
;
210 printf("TOO MANY LOOP\n");
214 switch (aname
->property
->type
) {
217 aname
= aml_search_name(env
, aname
->property
->nstr
.dp
);
224 ret
= aml_eval_objref(env
, aname
->property
);
231 ret
= aname
->property
;
234 aml_free_objectcontent(&env
->tempobject
);
235 ret
= aml_eval_fieldobject(env
, aname
);
238 aml_free_objectcontent(&env
->tempobject
);
239 argnum
= aname
->property
->meth
.argnum
& 7;
241 copy
->curname
= aname
;
242 copy
->dp
= aname
->property
->meth
.from
;
243 copy
->end
= aname
->property
->meth
.to
;
244 copy
->stat
= aml_stat_none
;
245 stack
= aml_local_stack_create();
247 for (i
= 0; i
< argnum
; i
++) {
248 aml_local_stack_getArgX(stack
, i
)->property
=
251 aml_parse_termobj(env
, 0)));
253 AML_DEBUGPRINT(", ");
255 AML_DEBUGPRINT(")\n");
256 aml_local_stack_push(stack
);
257 if (env
->stat
== aml_stat_step
) {
258 AML_DEBUGGER(env
, copy
);
260 tmp
= aml_execute_method(copy
);
261 obj
= aml_eval_name(env
, tmp
);
262 if (copy
->stat
== aml_stat_panic
) {
263 AML_DEBUGPRINT("PANIC OCCURED IN METHOD");
264 env
->stat
= aml_stat_panic
;
266 aml_local_stack_delete(aml_local_stack_pop());
274 tmp
->property
= NULL
;
275 aml_local_stack_delete(aml_local_stack_pop());
277 aml_create_local_object()->property
= obj
;
280 env
->tempobject
.type
= aml_t_num
;
281 env
->tempobject
.num
.number
= 0;
285 case aml_t_bufferfield
:
286 aml_free_objectcontent(&env
->tempobject
);
287 if (aname
->property
->bfld
.bitlen
> 32) {
288 ret
= aname
->property
;
290 src
= aname
->property
;
291 num
= aml_bufferfield_read(src
->bfld
.origin
,
292 src
->bfld
.bitoffset
, src
->bfld
.bitlen
);
293 env
->tempobject
.type
= aml_t_num
;
294 env
->tempobject
.num
.number
= num
;
295 ret
= &env
->tempobject
;
299 AML_DEBUGPRINT("I eval the object that I should not eval, %s%d",
300 aname
->name
, aname
->property
->type
);
306 memman_free(aml_memman
, memid_aml_environ
, copy
);
311 * Eval named object but env variable is not required and return
312 * status of evaluation (success is zero). This function is assumed
313 * to be called by aml_apply_foreach_found_objects().
314 * Note that no arguments are passed if object is a method.
318 aml_eval_name_simple(struct aml_name
*name
, va_list ap
)
320 struct aml_environ
*env
;
321 union aml_object
*ret
;
323 if (name
== NULL
|| name
->property
== NULL
) {
327 env
= memman_alloc(aml_memman
, memid_aml_environ
);
331 bzero(env
, sizeof(struct aml_environ
));
333 aml_local_stack_push(aml_local_stack_create());
335 AML_DEBUGPRINT("Evaluating ");
336 aml_print_curname(name
);
337 ret
= aml_eval_name(env
, name
);
338 if (name
->property
->type
!= aml_t_method
) {
339 AML_DEBUGPRINT("\n");
345 aml_local_stack_delete(aml_local_stack_pop());
347 memman_free(aml_memman
, memid_aml_environ
, env
);
352 aml_objtonum(struct aml_environ
*env
, union aml_object
*obj
)
355 if (obj
!= NULL
&& obj
->type
== aml_t_num
) {
356 return (obj
->num
.number
);
358 env
->stat
= aml_stat_panic
;
364 aml_execute_method(struct aml_environ
*env
)
366 struct aml_name
*name
;
367 struct aml_name_group
*newgrp
;
369 newgrp
= aml_new_name_group((void *)AML_NAME_GROUP_IN_METHOD
);
372 aml_print_curname(env
->curname
);
373 AML_DEBUGPRINT(" START]\n");
375 name
= aml_parse_objectlist(env
, 0);
377 aml_print_curname(env
->curname
);
378 AML_DEBUGPRINT(" END]\n");
380 aml_delete_name_group(newgrp
);
385 aml_invoke_method(struct aml_name
*name
, int argc
, union aml_object
*argv
)
388 struct aml_name
*tmp
;
389 struct aml_environ
*env
;
390 struct aml_local_stack
*stack
;
391 union aml_object
*retval
;
392 union aml_object
*obj
;
395 env
= memman_alloc(aml_memman
, memid_aml_environ
);
399 bzero(env
, sizeof(struct aml_environ
));
401 if (name
!= NULL
&& name
->property
!= NULL
&&
402 name
->property
->type
== aml_t_method
) {
404 env
->dp
= name
->property
->meth
.from
;
405 env
->end
= name
->property
->meth
.to
;
406 AML_DEBUGGER(env
, env
);
407 stack
= aml_local_stack_create();
408 for (i
= 0; i
< argc
; i
++) {
409 aml_local_stack_getArgX(stack
, i
)->property
=
410 aml_alloc_object(argv
[i
].type
, &argv
[i
]);
412 aml_local_stack_push(stack
);
413 obj
= aml_eval_name(env
, tmp
= aml_execute_method(env
));
415 aml_showtree(name
, 0);
419 tmp
->property
= NULL
;
420 aml_local_stack_delete(aml_local_stack_pop());
422 aml_create_local_object()->property
= obj
;
426 memman_free(aml_memman
, memid_aml_environ
, env
);
431 aml_invoke_method_by_name(char *method
, int argc
, union aml_object
*argv
)
433 struct aml_name
*name
;
435 name
= aml_find_from_namespace(aml_get_rootname(), method
);
440 return (aml_invoke_method(name
, argc
, argv
));