1*e7dd2c75Slukem /* $NetBSD: aml_obj.c,v 1.2 2009/01/18 09:46:59 lukem Exp $ */
253e202c1Schristos
353e202c1Schristos /*-
453e202c1Schristos * Copyright (c) 1999 Takanori Watanabe
553e202c1Schristos * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
653e202c1Schristos * All rights reserved.
753e202c1Schristos *
853e202c1Schristos * Redistribution and use in source and binary forms, with or without
953e202c1Schristos * modification, are permitted provided that the following conditions
1053e202c1Schristos * are met:
1153e202c1Schristos * 1. Redistributions of source code must retain the above copyright
1253e202c1Schristos * notice, this list of conditions and the following disclaimer.
1353e202c1Schristos * 2. Redistributions in binary form must reproduce the above copyright
1453e202c1Schristos * notice, this list of conditions and the following disclaimer in the
1553e202c1Schristos * documentation and/or other materials provided with the distribution.
1653e202c1Schristos *
1753e202c1Schristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1853e202c1Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1953e202c1Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2053e202c1Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2153e202c1Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2253e202c1Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2353e202c1Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2453e202c1Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2553e202c1Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2653e202c1Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2753e202c1Schristos * SUCH DAMAGE.
2853e202c1Schristos *
2953e202c1Schristos * Id: aml_obj.c,v 1.17 2000/08/12 15:20:45 iwasaki Exp
3053e202c1Schristos * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_obj.c,v 1.3 2000/11/09 06:24:45 iwasaki Exp $
3153e202c1Schristos */
3253e202c1Schristos #include <sys/cdefs.h>
33*e7dd2c75Slukem __RCSID("$NetBSD: aml_obj.c,v 1.2 2009/01/18 09:46:59 lukem Exp $");
3453e202c1Schristos
3553e202c1Schristos #include <sys/param.h>
3653e202c1Schristos
3753e202c1Schristos #include <acpi_common.h>
3853e202c1Schristos #include <aml/aml_amlmem.h>
3953e202c1Schristos #include <aml/aml_env.h>
4053e202c1Schristos #include <aml/aml_name.h>
4153e202c1Schristos #include <aml/aml_obj.h>
4253e202c1Schristos #include <aml/aml_status.h>
4353e202c1Schristos #include <aml/aml_store.h>
4453e202c1Schristos
4553e202c1Schristos #ifndef _KERNEL
4653e202c1Schristos #include <sys/stat.h>
4753e202c1Schristos #include <sys/mman.h>
4853e202c1Schristos
4953e202c1Schristos #include <assert.h>
5053e202c1Schristos #include <err.h>
5153e202c1Schristos #include <fcntl.h>
5253e202c1Schristos #include <stdio.h>
5353e202c1Schristos #include <stdlib.h>
5453e202c1Schristos #include <string.h>
5553e202c1Schristos #else /* _KERNEL */
5653e202c1Schristos #include <sys/systm.h>
5753e202c1Schristos #endif /* !_KERNEL */
5853e202c1Schristos
5953e202c1Schristos union aml_object *
aml_copy_object(struct aml_environ * env,union aml_object * orig)6053e202c1Schristos aml_copy_object(struct aml_environ *env, union aml_object *orig)
6153e202c1Schristos {
6253e202c1Schristos int i;
6353e202c1Schristos union aml_object *ret;
6453e202c1Schristos
6553e202c1Schristos if (orig == NULL)
6653e202c1Schristos return (NULL);
6753e202c1Schristos switch (orig->type) {
6853e202c1Schristos case aml_t_regfield:
6953e202c1Schristos ret = aml_alloc_object(aml_t_buffer, 0);
7053e202c1Schristos ret->buffer.size = (orig->regfield.bitlen / 8) +
7153e202c1Schristos ((orig->regfield.bitlen % 8) ? 1 : 0);
7253e202c1Schristos if (ret->buffer.size == 0) {
7353e202c1Schristos goto out;
7453e202c1Schristos }
7553e202c1Schristos ret->buffer.data = memman_alloc_flexsize(aml_memman, ret->buffer.size);
7653e202c1Schristos aml_store_to_object(env, orig, ret);
7753e202c1Schristos break;
7853e202c1Schristos
7953e202c1Schristos default:
8053e202c1Schristos ret = aml_alloc_object(0, orig);
8153e202c1Schristos break;
8253e202c1Schristos }
8353e202c1Schristos
8453e202c1Schristos if (1 || orig != &env->tempobject) { /* XXX */
8553e202c1Schristos if (orig->type == aml_t_buffer) {
8653e202c1Schristos if (orig->buffer.size == 0) {
8753e202c1Schristos goto out;
8853e202c1Schristos }
8953e202c1Schristos ret->buffer.data = memman_alloc_flexsize(aml_memman,
9053e202c1Schristos orig->buffer.size);
9153e202c1Schristos bcopy(orig->buffer.data, ret->buffer.data, orig->buffer.size);
9253e202c1Schristos } else if (orig->type == aml_t_package) {
9353e202c1Schristos if (ret->package.elements == 0) {
9453e202c1Schristos goto out;
9553e202c1Schristos }
9653e202c1Schristos ret->package.objects = memman_alloc_flexsize(aml_memman,
9753e202c1Schristos ret->package.elements * sizeof(union aml_object *));
9853e202c1Schristos for (i = 0; i < ret->package.elements; i++) {
9953e202c1Schristos ret->package.objects[i] = aml_copy_object(env, orig->package.objects[i]);
10053e202c1Schristos }
10153e202c1Schristos } else if (orig->type == aml_t_string && orig->str.needfree != 0) {
10253e202c1Schristos ret->str.string = memman_alloc_flexsize(aml_memman,
10353e202c1Schristos strlen((const char *)orig->str.string) + 1);
10453e202c1Schristos strcpy((char *)orig->str.string,
10553e202c1Schristos (const char *)ret->str.string);
10653e202c1Schristos } else if (orig->type == aml_t_num) {
10753e202c1Schristos ret->num.constant = 0;
10853e202c1Schristos }
10953e202c1Schristos } else {
11053e202c1Schristos printf("%s:%d\n", __FILE__, __LINE__);
11153e202c1Schristos env->tempobject.type = aml_t_null;
11253e202c1Schristos }
11353e202c1Schristos out:
11453e202c1Schristos return ret;
11553e202c1Schristos }
11653e202c1Schristos
11753e202c1Schristos /*
11853e202c1Schristos * This function have two function: copy or allocate. if orig != NULL,
11953e202c1Schristos * orig is duplicated.
12053e202c1Schristos */
12153e202c1Schristos
12253e202c1Schristos union aml_object *
aml_alloc_object(enum aml_objtype type,union aml_object * orig)12353e202c1Schristos aml_alloc_object(enum aml_objtype type, union aml_object *orig)
12453e202c1Schristos {
12553e202c1Schristos unsigned int memid;
12653e202c1Schristos union aml_object *ret;
12753e202c1Schristos
12853e202c1Schristos if (orig != NULL) {
12953e202c1Schristos type = orig->type;
13053e202c1Schristos }
13153e202c1Schristos switch (type) {
13253e202c1Schristos case aml_t_namestr:
13353e202c1Schristos memid = memid_aml_namestr;
13453e202c1Schristos break;
13553e202c1Schristos case aml_t_buffer:
13653e202c1Schristos memid = memid_aml_buffer;
13753e202c1Schristos break;
13853e202c1Schristos case aml_t_string:
13953e202c1Schristos memid = memid_aml_string;
14053e202c1Schristos break;
14153e202c1Schristos case aml_t_bufferfield:
14253e202c1Schristos memid = memid_aml_bufferfield;
14353e202c1Schristos break;
14453e202c1Schristos case aml_t_package:
14553e202c1Schristos memid = memid_aml_package;
14653e202c1Schristos break;
14753e202c1Schristos case aml_t_num:
14853e202c1Schristos memid = memid_aml_num;
14953e202c1Schristos break;
15053e202c1Schristos case aml_t_powerres:
15153e202c1Schristos memid = memid_aml_powerres;
15253e202c1Schristos break;
15353e202c1Schristos case aml_t_opregion:
15453e202c1Schristos memid = memid_aml_opregion;
15553e202c1Schristos break;
15653e202c1Schristos case aml_t_method:
15753e202c1Schristos memid = memid_aml_method;
15853e202c1Schristos break;
15953e202c1Schristos case aml_t_processor:
16053e202c1Schristos memid = memid_aml_processor;
16153e202c1Schristos break;
16253e202c1Schristos case aml_t_field:
16353e202c1Schristos memid = memid_aml_field;
16453e202c1Schristos break;
16553e202c1Schristos case aml_t_mutex:
16653e202c1Schristos memid = memid_aml_mutex;
16753e202c1Schristos break;
16853e202c1Schristos case aml_t_device:
16953e202c1Schristos memid = memid_aml_objtype;
17053e202c1Schristos break;
17153e202c1Schristos case aml_t_objref:
17253e202c1Schristos memid = memid_aml_objref;
17353e202c1Schristos break;
17453e202c1Schristos default:
17553e202c1Schristos memid = memid_aml_objtype;
17653e202c1Schristos break;
17753e202c1Schristos }
17853e202c1Schristos ret = memman_alloc(aml_memman, memid);
17953e202c1Schristos ret->type = type;
18053e202c1Schristos
18153e202c1Schristos if (orig != NULL) {
18253e202c1Schristos bcopy(orig, ret, memman_memid2size(aml_memman, memid));
18353e202c1Schristos }
18453e202c1Schristos return (ret);
18553e202c1Schristos }
18653e202c1Schristos
18753e202c1Schristos void
aml_free_objectcontent(union aml_object * obj)18853e202c1Schristos aml_free_objectcontent(union aml_object *obj)
18953e202c1Schristos {
19053e202c1Schristos int i;
19153e202c1Schristos
19253e202c1Schristos if (obj->type == aml_t_buffer && obj->buffer.data != NULL) {
19353e202c1Schristos memman_free_flexsize(aml_memman, obj->buffer.data);
19453e202c1Schristos obj->buffer.data = NULL;
19553e202c1Schristos }
19653e202c1Schristos if (obj->type == aml_t_string && obj->str.string != NULL) {
19753e202c1Schristos if (obj->str.needfree != 0) {
19853e202c1Schristos memman_free_flexsize(aml_memman, obj->str.string);
19953e202c1Schristos obj->str.string = NULL;
20053e202c1Schristos }
20153e202c1Schristos }
20253e202c1Schristos if (obj->type == aml_t_package && obj->package.objects != NULL) {
20353e202c1Schristos for (i = 0; i < obj->package.elements; i++) {
20453e202c1Schristos aml_free_object(&obj->package.objects[i]);
20553e202c1Schristos }
20653e202c1Schristos memman_free_flexsize(aml_memman, obj->package.objects);
20753e202c1Schristos obj->package.objects = NULL;
20853e202c1Schristos }
20953e202c1Schristos }
21053e202c1Schristos
21153e202c1Schristos void
aml_free_object(union aml_object ** obj)21253e202c1Schristos aml_free_object(union aml_object **obj)
21353e202c1Schristos {
21453e202c1Schristos union aml_object *body;
21553e202c1Schristos
21653e202c1Schristos body = *obj;
21753e202c1Schristos if (body == NULL) {
21853e202c1Schristos return;
21953e202c1Schristos }
22053e202c1Schristos aml_free_objectcontent(*obj);
22153e202c1Schristos memman_free(aml_memman, memid_unkown, *obj);
22253e202c1Schristos *obj = NULL;
22353e202c1Schristos }
22453e202c1Schristos
22553e202c1Schristos void
aml_realloc_object(union aml_object * obj,int size)22653e202c1Schristos aml_realloc_object(union aml_object *obj, int size)
22753e202c1Schristos {
22853e202c1Schristos int i;
22953e202c1Schristos enum aml_objtype type;
23053e202c1Schristos union aml_object tmp;
23153e202c1Schristos
23253e202c1Schristos type = obj->type;
23353e202c1Schristos switch (type) {
23453e202c1Schristos case aml_t_buffer:
23553e202c1Schristos if (obj->buffer.size >= size) {
23653e202c1Schristos return;
23753e202c1Schristos }
23853e202c1Schristos tmp.buffer.size = size;
23953e202c1Schristos tmp.buffer.data = memman_alloc_flexsize(aml_memman, size);
24053e202c1Schristos bzero(tmp.buffer.data, size);
24153e202c1Schristos bcopy(obj->buffer.data, tmp.buffer.data, obj->buffer.size);
24253e202c1Schristos aml_free_objectcontent(obj);
24353e202c1Schristos *obj = tmp;
24453e202c1Schristos break;
24553e202c1Schristos case aml_t_string:
246*e7dd2c75Slukem if ((int)strlen((const char *)obj->str.string) >= size) {
24753e202c1Schristos return;
24853e202c1Schristos }
24953e202c1Schristos tmp.str.string = memman_alloc_flexsize(aml_memman, size + 1);
25053e202c1Schristos strcpy((char *)tmp.str.string, (const char *)obj->str.string);
25153e202c1Schristos aml_free_objectcontent(obj);
25253e202c1Schristos *obj = tmp;
25353e202c1Schristos break;
25453e202c1Schristos case aml_t_package:
25553e202c1Schristos if (obj->package.elements >= size) {
25653e202c1Schristos return;
25753e202c1Schristos }
25853e202c1Schristos tmp.package.objects = memman_alloc_flexsize(aml_memman,
25953e202c1Schristos size * sizeof(union aml_object *));
26053e202c1Schristos bzero(tmp.package.objects, size * sizeof(union aml_object *));
26153e202c1Schristos for (i = 0; i < obj->package.elements; i++) {
26253e202c1Schristos tmp.package.objects[i] = obj->package.objects[i];
26353e202c1Schristos }
26453e202c1Schristos memman_free_flexsize(aml_memman, obj->package.objects);
26553e202c1Schristos obj->package.objects = tmp.package.objects;
26653e202c1Schristos break;
26753e202c1Schristos default:
26853e202c1Schristos break;
26953e202c1Schristos }
27053e202c1Schristos }
271