Home | History | Annotate | Line # | Download | only in aml
      1 /*	$NetBSD: aml_obj.c,v 1.2 2009/01/18 09:46:59 lukem Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1999 Takanori Watanabe
      5  * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki (at) FreeBSD.org>
      6  * All rights reserved.
      7  *
      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.
     16  *
     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.
     28  *
     29  *	Id: aml_obj.c,v 1.17 2000/08/12 15:20:45 iwasaki Exp
     30  *	$FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_obj.c,v 1.3 2000/11/09 06:24:45 iwasaki Exp $
     31  */
     32 #include <sys/cdefs.h>
     33 __RCSID("$NetBSD: aml_obj.c,v 1.2 2009/01/18 09:46:59 lukem Exp $");
     34 
     35 #include <sys/param.h>
     36 
     37 #include <acpi_common.h>
     38 #include <aml/aml_amlmem.h>
     39 #include <aml/aml_env.h>
     40 #include <aml/aml_name.h>
     41 #include <aml/aml_obj.h>
     42 #include <aml/aml_status.h>
     43 #include <aml/aml_store.h>
     44 
     45 #ifndef _KERNEL
     46 #include <sys/stat.h>
     47 #include <sys/mman.h>
     48 
     49 #include <assert.h>
     50 #include <err.h>
     51 #include <fcntl.h>
     52 #include <stdio.h>
     53 #include <stdlib.h>
     54 #include <string.h>
     55 #else /* _KERNEL */
     56 #include <sys/systm.h>
     57 #endif /* !_KERNEL */
     58 
     59 union aml_object *
     60 aml_copy_object(struct aml_environ *env, union aml_object *orig)
     61 {
     62 	int	i;
     63 	union	aml_object *ret;
     64 
     65 	if (orig == NULL)
     66 		return (NULL);
     67 	switch (orig->type) {
     68 	case aml_t_regfield:
     69 		ret = aml_alloc_object(aml_t_buffer, 0);
     70 		ret->buffer.size = (orig->regfield.bitlen / 8) +
     71 		    ((orig->regfield.bitlen % 8) ? 1 : 0);
     72 		if (ret->buffer.size == 0) {
     73 			goto out;
     74 		}
     75 		ret->buffer.data = memman_alloc_flexsize(aml_memman, ret->buffer.size);
     76 		aml_store_to_object(env, orig, ret);
     77 		break;
     78 
     79 	default:
     80 		ret = aml_alloc_object(0, orig);
     81 		break;
     82 	}
     83 
     84 	if (1 || orig != &env->tempobject) {	/* XXX */
     85 		if (orig->type == aml_t_buffer) {
     86 			if (orig->buffer.size == 0) {
     87 				goto out;
     88 			}
     89 			ret->buffer.data = memman_alloc_flexsize(aml_memman,
     90 			    orig->buffer.size);
     91 			bcopy(orig->buffer.data, ret->buffer.data, orig->buffer.size);
     92 		} else if (orig->type == aml_t_package) {
     93 			if (ret->package.elements == 0) {
     94 				goto out;
     95 			}
     96 			ret->package.objects = memman_alloc_flexsize(aml_memman,
     97 			    ret->package.elements * sizeof(union aml_object *));
     98 			for (i = 0; i < ret->package.elements; i++) {
     99 				ret->package.objects[i] = aml_copy_object(env, orig->package.objects[i]);
    100 			}
    101 		} else if (orig->type == aml_t_string && orig->str.needfree != 0) {
    102 			ret->str.string = memman_alloc_flexsize(aml_memman,
    103 			    strlen((const char *)orig->str.string) + 1);
    104 			strcpy((char *)orig->str.string,
    105 			    (const char *)ret->str.string);
    106 		} else if (orig->type == aml_t_num) {
    107                         ret->num.constant = 0;
    108                 }
    109 	} else {
    110 		printf("%s:%d\n", __FILE__, __LINE__);
    111 		env->tempobject.type = aml_t_null;
    112 	}
    113 out:
    114 	return ret;
    115 }
    116 
    117 /*
    118  * This function have two function: copy or allocate.  if orig != NULL,
    119  *  orig is duplicated.
    120  */
    121 
    122 union aml_object *
    123 aml_alloc_object(enum aml_objtype type, union aml_object *orig)
    124 {
    125 	unsigned	int memid;
    126 	union	aml_object *ret;
    127 
    128 	if (orig != NULL) {
    129 		type = orig->type;
    130 	}
    131 	switch (type) {
    132 	case aml_t_namestr:
    133 		memid = memid_aml_namestr;
    134 		break;
    135 	case aml_t_buffer:
    136 		memid = memid_aml_buffer;
    137 		break;
    138 	case aml_t_string:
    139 		memid = memid_aml_string;
    140 		break;
    141 	case aml_t_bufferfield:
    142 		memid = memid_aml_bufferfield;
    143 		break;
    144 	case aml_t_package:
    145 		memid = memid_aml_package;
    146 		break;
    147 	case aml_t_num:
    148 		memid = memid_aml_num;
    149 		break;
    150 	case aml_t_powerres:
    151 		memid = memid_aml_powerres;
    152 		break;
    153 	case aml_t_opregion:
    154 		memid = memid_aml_opregion;
    155 		break;
    156 	case aml_t_method:
    157 		memid = memid_aml_method;
    158 		break;
    159 	case aml_t_processor:
    160 		memid = memid_aml_processor;
    161 		break;
    162 	case aml_t_field:
    163 		memid = memid_aml_field;
    164 		break;
    165 	case aml_t_mutex:
    166 		memid = memid_aml_mutex;
    167 		break;
    168 	case aml_t_device:
    169 		memid = memid_aml_objtype;
    170 		break;
    171 	case aml_t_objref:
    172 		memid = memid_aml_objref;
    173 		break;
    174 	default:
    175 		memid = memid_aml_objtype;
    176 		break;
    177 	}
    178 	ret = memman_alloc(aml_memman, memid);
    179 	ret->type = type;
    180 
    181 	if (orig != NULL) {
    182 		bcopy(orig, ret, memman_memid2size(aml_memman, memid));
    183 	}
    184 	return (ret);
    185 }
    186 
    187 void
    188 aml_free_objectcontent(union aml_object *obj)
    189 {
    190 	int	i;
    191 
    192 	if (obj->type == aml_t_buffer && obj->buffer.data != NULL) {
    193 		memman_free_flexsize(aml_memman, obj->buffer.data);
    194 		obj->buffer.data = NULL;
    195 	}
    196 	if (obj->type == aml_t_string && obj->str.string != NULL) {
    197 		if (obj->str.needfree != 0) {
    198 			memman_free_flexsize(aml_memman, obj->str.string);
    199 			obj->str.string = NULL;
    200 		}
    201 	}
    202 	if (obj->type == aml_t_package && obj->package.objects != NULL) {
    203 		for (i = 0; i < obj->package.elements; i++) {
    204 			aml_free_object(&obj->package.objects[i]);
    205 		}
    206 		memman_free_flexsize(aml_memman, obj->package.objects);
    207 		obj->package.objects = NULL;
    208 	}
    209 }
    210 
    211 void
    212 aml_free_object(union aml_object **obj)
    213 {
    214 	union	aml_object *body;
    215 
    216 	body = *obj;
    217 	if (body == NULL) {
    218 		return;
    219 	}
    220 	aml_free_objectcontent(*obj);
    221 	memman_free(aml_memman, memid_unkown, *obj);
    222 	*obj = NULL;
    223 }
    224 
    225 void
    226 aml_realloc_object(union aml_object *obj, int size)
    227 {
    228 	int	i;
    229 	enum	aml_objtype type;
    230 	union	aml_object tmp;
    231 
    232 	type = obj->type;
    233 	switch (type) {
    234 	case aml_t_buffer:
    235 		if (obj->buffer.size >= size) {
    236 			return;
    237 		}
    238 		tmp.buffer.size = size;
    239 		tmp.buffer.data = memman_alloc_flexsize(aml_memman, size);
    240 		bzero(tmp.buffer.data, size);
    241 		bcopy(obj->buffer.data, tmp.buffer.data, obj->buffer.size);
    242 		aml_free_objectcontent(obj);
    243 		*obj = tmp;
    244 		break;
    245 	case aml_t_string:
    246 		if ((int)strlen((const char *)obj->str.string) >= size) {
    247 			return;
    248 		}
    249 		tmp.str.string = memman_alloc_flexsize(aml_memman, size + 1);
    250 		strcpy((char *)tmp.str.string, (const char *)obj->str.string);
    251 		aml_free_objectcontent(obj);
    252 		*obj = tmp;
    253 		break;
    254 	case aml_t_package:
    255 		if (obj->package.elements >= size) {
    256 			return;
    257 		}
    258 		tmp.package.objects = memman_alloc_flexsize(aml_memman,
    259 		    size * sizeof(union aml_object *));
    260 		bzero(tmp.package.objects, size * sizeof(union aml_object *));
    261 		for (i = 0; i < obj->package.elements; i++) {
    262 			tmp.package.objects[i] = obj->package.objects[i];
    263 		}
    264 		memman_free_flexsize(aml_memman, obj->package.objects);
    265 		obj->package.objects = tmp.package.objects;
    266 		break;
    267 	default:
    268 		break;
    269 	}
    270 }
    271