Fix mdoc(7)/man(7) mix up.
[netbsd-mini2440.git] / usr.sbin / acpitools / aml / aml_store.c
blob32378a3aea0635460a000676899ae671ece9693a
1 /* $NetBSD$ */
3 /*-
4 * Copyright (c) 1999 Takanori Watanabe
5 * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
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
27 * SUCH DAMAGE.
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>
33 __RCSID("$NetBSD$");
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>
48 #ifndef _KERNEL
49 #include <assert.h>
50 #include <stdio.h>
51 #include <string.h>
53 #include "debug.h"
54 #else /* _KERNEL */
55 #include <sys/systm.h>
56 #endif /* !_KERNEL */
58 static void
59 aml_store_to_fieldname(struct aml_environ *env, union aml_object *obj,
60 struct aml_name *name)
62 u_int8_t *buffer;
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;
69 oname = env->curname;
70 iname = NULL;
71 env->curname = name->parent;
72 if (field->f.ftype == f_t_field) {
73 wname = aml_search_name(env, field->f.fld.regname);
74 if (wname == NULL ||
75 wname->property == NULL ||
76 wname->property->type != aml_t_opregion) {
77 AML_DEBUGPRINT("Inappropreate Type\n");
78 env->stat = aml_stat_panic;
79 env->curname = oname;
80 return;
82 or = &wname->property->opregion;
83 switch (obj->type) {
84 case aml_t_num:
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);
91 break;
92 case aml_t_buffer:
93 case aml_t_bufferfield:
94 if (obj->type == aml_t_buffer) {
95 buffer = obj->buffer.data;
96 } else {
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,
102 field->bitlen);
103 break;
104 case aml_t_regfield:
105 if (or->space != obj->regfield.space) {
106 AML_DEBUGPRINT("aml_store_to_fieldname: "
107 "Different type of space\n");
108 break;
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,
114 field->bitlen);
115 break;
116 default:
117 AML_DEBUGPRINT("aml_store_to_fieldname: "
118 "Inappropreate Type of src object\n");
119 break;
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 */
132 tobj.num = obj->num;
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;
144 static void
145 aml_store_to_buffer(struct aml_environ *env, union aml_object *obj,
146 union aml_object *buf, int offset)
148 int size;
149 int bitlen;
151 switch (obj->type) {
152 case aml_t_num:
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);
159 break;
160 case aml_t_string:
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]");
168 break;
169 case aml_t_buffer:
170 bzero(buf->buffer.data, buf->buffer.size);
171 if (obj->buffer.size > buf->buffer.size) {
172 size = buf->buffer.size;
173 } else {
174 size = obj->buffer.size;
176 bcopy(obj->buffer.data, buf->buffer.data, size);
177 break;
178 case aml_t_regfield:
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);
187 break;
188 default:
189 goto not_yet;
191 return;
192 not_yet:
193 AML_DEBUGPRINT("[XXX not supported yet]");
197 void
198 aml_store_to_object(struct aml_environ *env, union aml_object *src,
199 union aml_object * dest)
201 u_int8_t *buffer, *srcbuf;
202 int offset, bitlen;
204 switch (dest->type) {
205 case aml_t_num:
206 if (src->type == aml_t_num) {
207 dest->num = src->num;
208 AML_DEBUGPRINT("[Store number 0x%x]", src->num.number);
209 } else {
210 env->stat = aml_stat_panic;
212 break;
213 case aml_t_string:
214 case aml_t_package:
215 break;
216 case aml_t_buffer:
217 aml_store_to_buffer(env, src, dest, 0);
218 break;
219 case aml_t_bufferfield:
220 buffer = dest->bfld.origin;
221 offset = dest->bfld.bitoffset;
222 bitlen = dest->bfld.bitlen;
224 switch (src->type) {
225 case aml_t_num:
226 if (aml_bufferfield_write(src->num.number, buffer, offset, bitlen)) {
227 AML_DEBUGPRINT("aml_bufferfield_write() failed\n");
229 break;
230 case aml_t_buffer:
231 case aml_t_bufferfield:
232 if (src->type == aml_t_buffer) {
233 srcbuf = src->buffer.data;
234 } else {
235 srcbuf = src->bfld.origin;
236 srcbuf += src->bfld.bitoffset / 8;
238 bcopy(srcbuf, buffer, bitlen / 8);
239 break;
240 case aml_t_regfield:
241 aml_region_read_into_buffer(env, src->regfield.space,
242 src->regfield.flags, src->regfield.offset,
243 src->regfield.bitoffset, src->regfield.bitlen,
244 buffer);
245 break;
246 default:
247 AML_DEBUGPRINT("not implemented yet");
248 break;
250 break;
251 case aml_t_debug:
252 aml_showobject(src);
253 break;
254 default:
255 AML_DEBUGPRINT("[Unimplemented %d]", dest->type);
256 break;
260 static void
261 aml_store_to_objref(struct aml_environ *env, union aml_object *obj,
262 union aml_object *r)
264 int offset;
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;
271 ref = r->objref.ref;
273 switch (ref->type) {
274 case aml_t_buffer:
275 offset = r->objref.offset;
276 aml_store_to_buffer(env, obj, ref, r->objref.offset);
277 break;
278 case aml_t_package:
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);
285 } else {
286 aml_store_to_object(env, obj, ref->package.objects[offset]);
288 break;
289 default:
290 aml_store_to_object(env, obj, ref);
291 break;
296 * Store to Named object
298 void
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) {
305 return;
307 if (name == NULL || obj == NULL) {
308 AML_DEBUGPRINT("[Try to store no existant name ]");
309 return;
311 if (name->property == NULL) {
312 name->property = aml_copy_object(env, obj);
313 AML_DEBUGPRINT("[Copy number 0x%x]", obj->num.number);
314 return;
316 if (name->property->type == aml_t_namestr) {
317 wname = aml_search_name(env, name->property->nstr.dp);
318 name = wname;
320 if (name == NULL) {
321 env->stat = aml_stat_panic;
322 return;
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);
327 return;
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) {
332 return;
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) {
342 case aml_t_field:
343 aml_store_to_fieldname(env, obj, name);
344 break;
345 case aml_t_objref:
346 aml_store_to_objref(env, obj, name->property);
347 break;
348 case aml_t_num:
349 if (name == &env->tempname)
350 break;
351 default:
352 aml_store_to_object(env, obj, name->property);
353 break;