xref: /netbsd-src/usr.sbin/acpitools/aml/aml_obj.c (revision e7dd2c7514af4e72722e9e1d552190a40fd852d2)
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