xref: /netbsd-src/usr.sbin/acpitools/aml/aml_obj.c (revision e7dd2c7514af4e72722e9e1d552190a40fd852d2)
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@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 *
aml_copy_object(struct aml_environ * env,union aml_object * orig)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 *
aml_alloc_object(enum aml_objtype type,union aml_object * orig)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
aml_free_objectcontent(union aml_object * obj)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
aml_free_object(union aml_object ** obj)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
aml_realloc_object(union aml_object * obj,int size)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