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_store.c,v 1.22 2000/08/09 14:47:44 iwasaki Exp
30 * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_store.c,v 1.3 2000/11/09 06:24:45 iwasaki Exp $
32 #include <sys/cdefs.h>
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_region.h>
45 #include <aml/aml_status.h>
46 #include <aml/aml_store.h>
55 #include <sys/systm.h>
59 aml_store_to_fieldname(struct aml_environ
*env
, union aml_object
*obj
,
60 struct aml_name
*name
)
63 struct aml_name
*wname
, *oname
, *iname
;
64 struct aml_field
*field
;
65 struct aml_opregion
*or;
66 union aml_object tobj
, iobj
, *tmpobj
;
68 field
= &name
->property
->field
;
71 env
->curname
= name
->parent
;
72 if (field
->f
.ftype
== f_t_field
) {
73 wname
= aml_search_name(env
, field
->f
.fld
.regname
);
75 wname
->property
== NULL
||
76 wname
->property
->type
!= aml_t_opregion
) {
77 AML_DEBUGPRINT("Inappropreate Type\n");
78 env
->stat
= aml_stat_panic
;
82 or = &wname
->property
->opregion
;
85 aml_region_write(env
, or->space
, field
->flags
,
86 obj
->num
.number
, or->offset
,
87 field
->bitoffset
, field
->bitlen
);
88 AML_DEBUGPRINT("[write(%d, 0x%x, 0x%x)]",
89 or->space
, obj
->num
.number
,
90 or->offset
+ field
->bitoffset
/ 8);
93 case aml_t_bufferfield
:
94 if (obj
->type
== aml_t_buffer
) {
95 buffer
= obj
->buffer
.data
;
97 buffer
= obj
->bfld
.origin
;
98 buffer
+= obj
->bfld
.bitoffset
/ 8;
100 aml_region_write_from_buffer(env
, or->space
,
101 field
->flags
, buffer
, or->offset
, field
->bitoffset
,
105 if (or->space
!= obj
->regfield
.space
) {
106 AML_DEBUGPRINT("aml_store_to_fieldname: "
107 "Different type of space\n");
110 aml_region_bcopy(env
, obj
->regfield
.space
,
111 obj
->regfield
.flags
, obj
->regfield
.offset
,
112 obj
->regfield
.bitoffset
, obj
->regfield
.bitlen
,
113 field
->flags
, or->offset
, field
->bitoffset
,
117 AML_DEBUGPRINT("aml_store_to_fieldname: "
118 "Inappropreate Type of src object\n");
121 } else if (field
->f
.ftype
== f_t_index
) {
122 iname
= aml_search_name(env
, field
->f
.ifld
.indexname
);
123 wname
= aml_search_name(env
, field
->f
.ifld
.dataname
);
124 iobj
.type
= aml_t_num
;
125 iobj
.num
.number
= field
->bitoffset
/ 8; /* AccessType Boundary */
127 /* read whole values of IndexField */
128 aml_store_to_name(env
, &iobj
, iname
);
129 tmpobj
= aml_eval_name(env
, wname
);
131 /* make the values to be written */
133 tobj
.num
.number
= aml_adjust_updatevalue(field
->flags
,
134 field
->bitoffset
& 7, field
->bitlen
,
135 tmpobj
->num
.number
, obj
->num
.number
);
137 /* write the values to IndexField */
138 aml_store_to_name(env
, &iobj
, iname
);
139 aml_store_to_name(env
, &tobj
, wname
);
141 env
->curname
= oname
;
145 aml_store_to_buffer(struct aml_environ
*env
, union aml_object
*obj
,
146 union aml_object
*buf
, int offset
)
153 if (offset
> buf
->buffer
.size
) {
154 aml_realloc_object(buf
, offset
);
156 buf
->buffer
.data
[offset
] = obj
->num
.number
& 0xff;
157 AML_DEBUGPRINT("[Store number 0x%x to buffer]",
158 obj
->num
.number
& 0xff);
161 size
= strlen((const char *)obj
->str
.string
);
162 if (buf
->buffer
.size
- offset
< size
) {
163 aml_realloc_object(buf
, offset
+ size
+ 1);
165 strcpy((char *)&buf
->buffer
.data
[offset
],
166 (const char *)obj
->str
.string
);
167 AML_DEBUGPRINT("[Store string to buffer]");
170 bzero(buf
->buffer
.data
, buf
->buffer
.size
);
171 if (obj
->buffer
.size
> buf
->buffer
.size
) {
172 size
= buf
->buffer
.size
;
174 size
= obj
->buffer
.size
;
176 bcopy(obj
->buffer
.data
, buf
->buffer
.data
, size
);
179 bitlen
= (buf
->buffer
.size
- offset
) * 8;
180 if (bitlen
> obj
->regfield
.bitlen
) {
181 bitlen
= obj
->regfield
.bitlen
;
183 aml_region_read_into_buffer(env
, obj
->regfield
.space
,
184 obj
->regfield
.flags
, obj
->regfield
.offset
,
185 obj
->regfield
.bitoffset
, bitlen
,
186 buf
->buffer
.data
+ offset
);
193 AML_DEBUGPRINT("[XXX not supported yet]");
198 aml_store_to_object(struct aml_environ
*env
, union aml_object
*src
,
199 union aml_object
* dest
)
201 u_int8_t
*buffer
, *srcbuf
;
204 switch (dest
->type
) {
206 if (src
->type
== aml_t_num
) {
207 dest
->num
= src
->num
;
208 AML_DEBUGPRINT("[Store number 0x%x]", src
->num
.number
);
210 env
->stat
= aml_stat_panic
;
217 aml_store_to_buffer(env
, src
, dest
, 0);
219 case aml_t_bufferfield
:
220 buffer
= dest
->bfld
.origin
;
221 offset
= dest
->bfld
.bitoffset
;
222 bitlen
= dest
->bfld
.bitlen
;
226 if (aml_bufferfield_write(src
->num
.number
, buffer
, offset
, bitlen
)) {
227 AML_DEBUGPRINT("aml_bufferfield_write() failed\n");
231 case aml_t_bufferfield
:
232 if (src
->type
== aml_t_buffer
) {
233 srcbuf
= src
->buffer
.data
;
235 srcbuf
= src
->bfld
.origin
;
236 srcbuf
+= src
->bfld
.bitoffset
/ 8;
238 bcopy(srcbuf
, buffer
, bitlen
/ 8);
241 aml_region_read_into_buffer(env
, src
->regfield
.space
,
242 src
->regfield
.flags
, src
->regfield
.offset
,
243 src
->regfield
.bitoffset
, src
->regfield
.bitlen
,
247 AML_DEBUGPRINT("not implemented yet");
255 AML_DEBUGPRINT("[Unimplemented %d]", dest
->type
);
261 aml_store_to_objref(struct aml_environ
*env
, union aml_object
*obj
,
265 union aml_object
*ref
;
267 if (r
->objref
.ref
== NULL
) {
268 r
->objref
.ref
= aml_alloc_object(obj
->type
, NULL
); /* XXX */
269 r
->objref
.nameref
->property
= r
->objref
.ref
;
275 offset
= r
->objref
.offset
;
276 aml_store_to_buffer(env
, obj
, ref
, r
->objref
.offset
);
279 offset
= r
->objref
.offset
;
280 if (r
->objref
.ref
->package
.elements
< offset
) {
281 aml_realloc_object(ref
, offset
);
283 if (ref
->package
.objects
[offset
] == NULL
) {
284 ref
->package
.objects
[offset
] = aml_copy_object(env
, obj
);
286 aml_store_to_object(env
, obj
, ref
->package
.objects
[offset
]);
290 aml_store_to_object(env
, obj
, ref
);
296 * Store to Named object
299 aml_store_to_name(struct aml_environ
*env
, union aml_object
*obj
,
300 struct aml_name
*name
)
302 struct aml_name
*wname
;
304 if (env
->stat
== aml_stat_panic
) {
307 if (name
== NULL
|| obj
== NULL
) {
308 AML_DEBUGPRINT("[Try to store no existant name ]");
311 if (name
->property
== NULL
) {
312 name
->property
= aml_copy_object(env
, obj
);
313 AML_DEBUGPRINT("[Copy number 0x%x]", obj
->num
.number
);
316 if (name
->property
->type
== aml_t_namestr
) {
317 wname
= aml_search_name(env
, name
->property
->nstr
.dp
);
321 env
->stat
= aml_stat_panic
;
324 if (name
->property
== NULL
|| name
->property
->type
== aml_t_null
) {
325 name
->property
= aml_copy_object(env
, obj
);
326 AML_DEBUGPRINT("[Copy number 0x%x]", obj
->num
.number
);
329 /* Writes to constant object are not allowed */
330 if (name
->property
!= NULL
&& name
->property
->type
== aml_t_num
&&
331 name
->property
->num
.constant
== 1) {
334 /* try to dereference */
335 if (obj
->type
== aml_t_objref
&& obj
->objref
.deref
== 0) {
336 AML_DEBUGPRINT("Source object isn't dereferenced yet, "
337 "try to dereference anyway\n");
338 obj
->objref
.deref
= 1;
339 obj
= aml_eval_objref(env
, obj
);
341 switch (name
->property
->type
) {
343 aml_store_to_fieldname(env
, obj
, name
);
346 aml_store_to_objref(env
, obj
, name
->property
);
349 if (name
== &env
->tempname
)
352 aml_store_to_object(env
, obj
, name
->property
);