Home | History | Annotate | Line # | Download | only in aml
aml_parse.c revision 1.1
      1  1.1  christos /*	$NetBSD: aml_parse.c,v 1.1 2007/01/14 04:36:13 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /*-
      4  1.1  christos  * Copyright (c) 1999 Doug Rabson
      5  1.1  christos  * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki (at) FreeBSD.org>
      6  1.1  christos  * All rights reserved.
      7  1.1  christos  *
      8  1.1  christos  * Redistribution and use in source and binary forms, with or without
      9  1.1  christos  * modification, are permitted provided that the following conditions
     10  1.1  christos  * are met:
     11  1.1  christos  * 1. Redistributions of source code must retain the above copyright
     12  1.1  christos  *    notice, this list of conditions and the following disclaimer.
     13  1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  christos  *    documentation and/or other materials provided with the distribution.
     16  1.1  christos  *
     17  1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     18  1.1  christos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  1.1  christos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  1.1  christos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21  1.1  christos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  1.1  christos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  1.1  christos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  1.1  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  1.1  christos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  1.1  christos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  1.1  christos  * SUCH DAMAGE.
     28  1.1  christos  *
     29  1.1  christos  *	Id: aml_parse.c,v 1.32 2000/08/12 15:20:45 iwasaki Exp
     30  1.1  christos  *	$FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_parse.c,v 1.7 2001/10/23 14:54:15 takawata Exp $
     31  1.1  christos  */
     32  1.1  christos #include <sys/cdefs.h>
     33  1.1  christos __RCSID("$NetBSD: aml_parse.c,v 1.1 2007/01/14 04:36:13 christos Exp $");
     34  1.1  christos 
     35  1.1  christos #include <sys/param.h>
     36  1.1  christos 
     37  1.1  christos #include <acpi_common.h>
     38  1.1  christos #include <aml/aml_amlmem.h>
     39  1.1  christos #include <aml/aml_common.h>
     40  1.1  christos #include <aml/aml_env.h>
     41  1.1  christos #include <aml/aml_evalobj.h>
     42  1.1  christos #include <aml/aml_name.h>
     43  1.1  christos #include <aml/aml_obj.h>
     44  1.1  christos #include <aml/aml_parse.h>
     45  1.1  christos #include <aml/aml_status.h>
     46  1.1  christos #include <aml/aml_store.h>
     47  1.1  christos 
     48  1.1  christos #ifndef _KERNEL
     49  1.1  christos #include <sys/stat.h>
     50  1.1  christos #include <sys/mman.h>
     51  1.1  christos 
     52  1.1  christos #include <assert.h>
     53  1.1  christos #include <err.h>
     54  1.1  christos #include <fcntl.h>
     55  1.1  christos #include <stdio.h>
     56  1.1  christos #include <stdlib.h>
     57  1.1  christos #include <string.h>
     58  1.1  christos #include <unistd.h>
     59  1.1  christos 
     60  1.1  christos #include "debug.h"
     61  1.1  christos #else /* _KERNEL */
     62  1.1  christos #include <sys/systm.h>
     63  1.1  christos #include <sys/bus.h>
     64  1.1  christos #include <machine/bus.h>
     65  1.1  christos #include <dev/acpi/acpireg.h>
     66  1.1  christos #include <dev/acpi/acpivar.h>
     67  1.1  christos #ifndef ACPI_NO_OSDFUNC_INLINE
     68  1.1  christos #include <machine/acpica_osd.h>
     69  1.1  christos #endif
     70  1.1  christos #endif /* !_KERNEL */
     71  1.1  christos 
     72  1.1  christos static int		 findsetleftbit(int num);
     73  1.1  christos static int		 findsetrightbit(int num);
     74  1.1  christos static int		 frombcd(int num);
     75  1.1  christos static int		 tobcd(int num);
     76  1.1  christos 
     77  1.1  christos static u_int32_t	 aml_parse_pkglength(struct aml_environ *env);
     78  1.1  christos static u_int8_t		 aml_parse_bytedata(struct aml_environ *env);
     79  1.1  christos static u_int16_t	 aml_parse_worddata(struct aml_environ *env);
     80  1.1  christos static u_int32_t	 aml_parse_dworddata(struct aml_environ *env);
     81  1.1  christos static u_int8_t		*aml_parse_namestring(struct aml_environ *env);
     82  1.1  christos static void		 aml_parse_defscope(struct aml_environ *env,
     83  1.1  christos 					    int indent);
     84  1.1  christos static union aml_object	*aml_parse_defbuffer(struct aml_environ *env,
     85  1.1  christos 					     int indent);
     86  1.1  christos static struct aml_name	*aml_parse_concat_number(struct aml_environ *env,
     87  1.1  christos 						 int num1, int indent);
     88  1.1  christos static struct aml_name	*aml_parse_concat_buffer(struct aml_environ *env,
     89  1.1  christos 						 union aml_object *obj,
     90  1.1  christos 						 int indent);
     91  1.1  christos static struct aml_name	*aml_parse_concat_string(struct aml_environ *env,
     92  1.1  christos 						 union aml_object *obj,
     93  1.1  christos 						 int indent);
     94  1.1  christos static struct aml_name	*aml_parse_concatop(struct aml_environ *env,
     95  1.1  christos 					    int indent);
     96  1.1  christos static union aml_object	*aml_parse_defpackage(struct aml_environ *env,
     97  1.1  christos 					      int indent);
     98  1.1  christos static void		 aml_parse_defmethod(struct aml_environ *env,
     99  1.1  christos 					     int indent);
    100  1.1  christos static void		 aml_parse_defopregion(struct aml_environ *env,
    101  1.1  christos 					       int indent);
    102  1.1  christos static int		 aml_parse_field(struct aml_environ *env,
    103  1.1  christos 					 struct aml_field *template);
    104  1.1  christos static void		 aml_parse_fieldlist(struct aml_environ *env,
    105  1.1  christos 					     struct aml_field *template,
    106  1.1  christos 					     int indent);
    107  1.1  christos static void		 aml_parse_deffield(struct aml_environ *env,
    108  1.1  christos 					    int indent);
    109  1.1  christos static void		 aml_parse_defindexfield(struct aml_environ *env,
    110  1.1  christos 						 int indent);
    111  1.1  christos static void		 aml_parse_defbankfield(struct aml_environ *env,
    112  1.1  christos 						int indent);
    113  1.1  christos static void		 aml_parse_defdevice(struct aml_environ *env,
    114  1.1  christos 					     int indent);
    115  1.1  christos static void		 aml_parse_defprocessor(struct aml_environ *env,
    116  1.1  christos 						int indent);
    117  1.1  christos static void		 aml_parse_defpowerres(struct aml_environ *env,
    118  1.1  christos 					       int indent);
    119  1.1  christos static void		 aml_parse_defthermalzone(struct aml_environ *env,
    120  1.1  christos 						  int indent);
    121  1.1  christos static struct aml_name	*aml_parse_defelse(struct aml_environ *env,
    122  1.1  christos 					   int indent, int num);
    123  1.1  christos static struct aml_name	*aml_parse_defif(struct aml_environ *env,
    124  1.1  christos 					 int indent);
    125  1.1  christos static struct aml_name	*aml_parse_defwhile(struct aml_environ *env,
    126  1.1  christos 					    int indent);
    127  1.1  christos static void		 aml_parse_defmutex(struct aml_environ *env,
    128  1.1  christos 					    int indent);
    129  1.1  christos static void		 aml_createfield_generic(struct aml_environ *env,
    130  1.1  christos 						 union aml_object *srcbuf,
    131  1.1  christos 						 int idx, int len,
    132  1.1  christos 						 char *newname);
    133  1.1  christos static void		 aml_parse_defcreatefield(struct aml_environ *env,
    134  1.1  christos 						  int indent);
    135  1.1  christos 
    136  1.1  christos static int
    137  1.1  christos findsetleftbit(int num)
    138  1.1  christos {
    139  1.1  christos 	int	i, filter;
    140  1.1  christos 
    141  1.1  christos 	filter = 0;
    142  1.1  christos 	for (i = 0; i < 32; i++) {
    143  1.1  christos 		filter = filter >> 1;
    144  1.1  christos 		filter |= 1 << 31;
    145  1.1  christos 		if (filter & num) {
    146  1.1  christos 			break;
    147  1.1  christos 		}
    148  1.1  christos 	}
    149  1.1  christos 	i = (i == 32) ? 0 : i + 1;
    150  1.1  christos 	return (i);
    151  1.1  christos }
    152  1.1  christos 
    153  1.1  christos static int
    154  1.1  christos findsetrightbit(int num)
    155  1.1  christos {
    156  1.1  christos 	int	i, filter;
    157  1.1  christos 
    158  1.1  christos 	filter = 0;
    159  1.1  christos 	for (i = 0; i < 32; i++) {
    160  1.1  christos 		filter = filter << 1;
    161  1.1  christos 		filter |= 1;
    162  1.1  christos 		if (filter & num) {
    163  1.1  christos 			break;
    164  1.1  christos 		}
    165  1.1  christos 	}
    166  1.1  christos 	i = (i == 32) ? 0 : i + 1;
    167  1.1  christos 	return (i);
    168  1.1  christos }
    169  1.1  christos 
    170  1.1  christos static int
    171  1.1  christos frombcd(int num)
    172  1.1  christos {
    173  1.1  christos 	int	res, factor;
    174  1.1  christos 
    175  1.1  christos 	res = 0;
    176  1.1  christos 	factor = 1;
    177  1.1  christos 	while (num != 0) {
    178  1.1  christos 		res += ((num & 0xf) * factor);
    179  1.1  christos 		num = num / 16;
    180  1.1  christos 		factor *= 10;
    181  1.1  christos 	}
    182  1.1  christos 	return (res);
    183  1.1  christos }
    184  1.1  christos 
    185  1.1  christos static int
    186  1.1  christos tobcd(int num)
    187  1.1  christos {
    188  1.1  christos 	int	res, factor;
    189  1.1  christos 
    190  1.1  christos 	res = 0;
    191  1.1  christos 	factor = 1;
    192  1.1  christos 	while (num != 0) {
    193  1.1  christos 		res += ((num % 10) * factor);
    194  1.1  christos 		num = num / 10;
    195  1.1  christos 		factor *= 16;
    196  1.1  christos 	}
    197  1.1  christos 	return (res);
    198  1.1  christos }
    199  1.1  christos 
    200  1.1  christos static u_int32_t
    201  1.1  christos aml_parse_pkglength(struct aml_environ *env)
    202  1.1  christos {
    203  1.1  christos 	u_int8_t	*dp;
    204  1.1  christos 	u_int32_t	pkglength;
    205  1.1  christos 
    206  1.1  christos 	dp = env->dp;
    207  1.1  christos 	pkglength = *dp++;
    208  1.1  christos 	switch (pkglength >> 6) {
    209  1.1  christos 	case 0:
    210  1.1  christos 		break;
    211  1.1  christos 	case 1:
    212  1.1  christos 		pkglength = (pkglength & 0xf) + (dp[0] << 4);
    213  1.1  christos 		dp += 1;
    214  1.1  christos 		break;
    215  1.1  christos 	case 2:
    216  1.1  christos 		pkglength = (pkglength & 0xf) + (dp[0] << 4) + (dp[1] << 12);
    217  1.1  christos 		dp += 2;
    218  1.1  christos 		break;
    219  1.1  christos 	case 3:
    220  1.1  christos 		pkglength = (pkglength & 0xf)
    221  1.1  christos 		    + (dp[0] << 4) + (dp[1] << 12) + (dp[2] << 20);
    222  1.1  christos 		dp += 3;
    223  1.1  christos 		break;
    224  1.1  christos 	}
    225  1.1  christos 
    226  1.1  christos 	env->dp = dp;
    227  1.1  christos 	return (pkglength);
    228  1.1  christos }
    229  1.1  christos 
    230  1.1  christos static u_int8_t
    231  1.1  christos aml_parse_bytedata(struct aml_environ *env)
    232  1.1  christos {
    233  1.1  christos 	u_int8_t	data;
    234  1.1  christos 
    235  1.1  christos 	data = env->dp[0];
    236  1.1  christos 	env->dp++;
    237  1.1  christos 	return (data);
    238  1.1  christos }
    239  1.1  christos 
    240  1.1  christos static u_int16_t
    241  1.1  christos aml_parse_worddata(struct aml_environ *env)
    242  1.1  christos {
    243  1.1  christos 	u_int16_t	data;
    244  1.1  christos 
    245  1.1  christos 	data = env->dp[0] + (env->dp[1] << 8);
    246  1.1  christos 	env->dp += 2;
    247  1.1  christos 	return (data);
    248  1.1  christos }
    249  1.1  christos 
    250  1.1  christos static u_int32_t
    251  1.1  christos aml_parse_dworddata(struct aml_environ *env)
    252  1.1  christos {
    253  1.1  christos 	u_int32_t	data;
    254  1.1  christos 
    255  1.1  christos 	data = env->dp[0] + (env->dp[1] << 8) +
    256  1.1  christos 	    (env->dp[2] << 16) + (env->dp[3] << 24);
    257  1.1  christos 	env->dp += 4;
    258  1.1  christos 	return (data);
    259  1.1  christos }
    260  1.1  christos 
    261  1.1  christos static u_int8_t *
    262  1.1  christos aml_parse_namestring(struct aml_environ *env)
    263  1.1  christos {
    264  1.1  christos 	u_int8_t	*name;
    265  1.1  christos 	int		segcount;
    266  1.1  christos 
    267  1.1  christos 	name = env->dp;
    268  1.1  christos 	if (env->dp[0] == '\\')
    269  1.1  christos 		env->dp++;
    270  1.1  christos 	else if (env->dp[0] == '^')
    271  1.1  christos 		while (env->dp[0] == '^')
    272  1.1  christos 			env->dp++;
    273  1.1  christos 	if (env->dp[0] == 0x00)	/* NullName */
    274  1.1  christos 		env->dp++;
    275  1.1  christos 	else if (env->dp[0] == 0x2e)	/* DualNamePrefix */
    276  1.1  christos 		env->dp += 1 + 4 + 4;	/* NameSeg, NameSeg */
    277  1.1  christos 	else if (env->dp[0] == 0x2f) {	/* MultiNamePrefix */
    278  1.1  christos 		segcount = env->dp[1];
    279  1.1  christos 		env->dp += 1 + 1 + segcount * 4;	/* segcount * NameSeg */
    280  1.1  christos 	} else
    281  1.1  christos 		env->dp += 4;	/* NameSeg */
    282  1.1  christos 
    283  1.1  christos 	return (name);
    284  1.1  christos }
    285  1.1  christos 
    286  1.1  christos struct aml_name *
    287  1.1  christos aml_parse_objectlist(struct aml_environ *env, int indent)
    288  1.1  christos {
    289  1.1  christos 	union	aml_object *obj;
    290  1.1  christos 
    291  1.1  christos 	obj = NULL;
    292  1.1  christos 	while (env->dp < env->end) {
    293  1.1  christos 		aml_print_indent(indent);
    294  1.1  christos 		obj = aml_eval_name(env, aml_parse_termobj(env, indent));
    295  1.1  christos 		AML_DEBUGPRINT("\n");
    296  1.1  christos 		if (env->stat == aml_stat_step) {
    297  1.1  christos 			AML_DEBUGGER(env, env);
    298  1.1  christos 			continue;
    299  1.1  christos 		}
    300  1.1  christos 		if (env->stat != aml_stat_none) {
    301  1.1  christos 			env->tempname.property = obj;
    302  1.1  christos 			return (&env->tempname);
    303  1.1  christos 		}
    304  1.1  christos 	}
    305  1.1  christos 	return (NULL);
    306  1.1  christos }
    307  1.1  christos 
    308  1.1  christos #define AML_CREATE_NAME(amlname, env, namestr, ret) do {		\
    309  1.1  christos 	amlname = aml_create_name(env, namestr);			\
    310  1.1  christos 	if (env->stat == aml_stat_panic)				\
    311  1.1  christos 		return ret;						\
    312  1.1  christos } while(0)
    313  1.1  christos 
    314  1.1  christos #define AML_COPY_OBJECT(dest, env, src, ret) do {			\
    315  1.1  christos 	dest = aml_copy_object(env, src);				\
    316  1.1  christos 	if (dest == NULL) {						\
    317  1.1  christos 		env->stat = aml_stat_panic;				\
    318  1.1  christos 		return ret;						\
    319  1.1  christos 	}								\
    320  1.1  christos } while(0)
    321  1.1  christos 
    322  1.1  christos #define AML_ALLOC_OBJECT(dest, env, type, ret) do {			\
    323  1.1  christos 	dest = aml_alloc_object(type, NULL);				\
    324  1.1  christos 	if (dest == NULL) {						\
    325  1.1  christos 		env->stat= aml_stat_panic;				\
    326  1.1  christos 		return ret;						\
    327  1.1  christos 	}								\
    328  1.1  christos } while(0)
    329  1.1  christos 
    330  1.1  christos static void
    331  1.1  christos aml_parse_defscope(struct aml_environ *env, int indent)
    332  1.1  christos {
    333  1.1  christos 	u_int8_t	*start, *end, *oend;
    334  1.1  christos 	u_int8_t	*name;
    335  1.1  christos 	u_int32_t	pkglength;
    336  1.1  christos 	struct	aml_name *oname;
    337  1.1  christos 
    338  1.1  christos 	start = env->dp;
    339  1.1  christos 	pkglength = aml_parse_pkglength(env);
    340  1.1  christos 
    341  1.1  christos 	AML_DEBUGPRINT("Scope(");
    342  1.1  christos 	name = aml_parse_namestring(env);
    343  1.1  christos 	aml_print_namestring(name);
    344  1.1  christos 	AML_DEBUGPRINT(") {\n");
    345  1.1  christos 	oname = env->curname;
    346  1.1  christos 	AML_CREATE_NAME(env->curname, env, name,);
    347  1.1  christos 	oend = env->end;
    348  1.1  christos 	env->end = end = start + pkglength;
    349  1.1  christos 	aml_parse_objectlist(env, indent + 1);
    350  1.1  christos 	aml_print_indent(indent);
    351  1.1  christos 	AML_DEBUGPRINT("}");
    352  1.1  christos 	AML_SYSASSERT(env->dp == env->end);
    353  1.1  christos 	env->dp = end;
    354  1.1  christos 	env->end = oend;
    355  1.1  christos 	env->curname = oname;
    356  1.1  christos 	env->stat = aml_stat_none;
    357  1.1  christos }
    358  1.1  christos 
    359  1.1  christos static union aml_object *
    360  1.1  christos aml_parse_defbuffer(struct aml_environ *env, int indent)
    361  1.1  christos {
    362  1.1  christos 	u_int8_t	*start;
    363  1.1  christos 	u_int8_t	*end;
    364  1.1  christos 	u_int8_t	*buffer;
    365  1.1  christos 	u_int32_t	pkglength;
    366  1.1  christos 	int	size1, size2, size;
    367  1.1  christos 	union	aml_object *obj;
    368  1.1  christos 
    369  1.1  christos 	start = env->dp;
    370  1.1  christos 	pkglength = aml_parse_pkglength(env);
    371  1.1  christos 	end = start + pkglength;
    372  1.1  christos 
    373  1.1  christos 	AML_DEBUGPRINT("Buffer(");
    374  1.1  christos 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
    375  1.1  christos 	size1 = aml_objtonum(env, obj);
    376  1.1  christos 	size2 = end - env->dp;
    377  1.1  christos 	size = (size1 < size2) ? size1 : size2;
    378  1.1  christos 	if (size1 > 0) {
    379  1.1  christos 		buffer = memman_alloc_flexsize(aml_memman, size1);
    380  1.1  christos 		if (buffer == NULL) {
    381  1.1  christos 			AML_DEBUGPRINT("NO MEMORY\n");
    382  1.1  christos 			env->stat = aml_stat_panic;
    383  1.1  christos 			return (NULL);
    384  1.1  christos 		}
    385  1.1  christos 		bzero(buffer, size1);
    386  1.1  christos 		bcopy(env->dp, buffer, size);
    387  1.1  christos 	} else {
    388  1.1  christos 		buffer = NULL;
    389  1.1  christos 	}
    390  1.1  christos 
    391  1.1  christos 	obj = &env->tempobject;
    392  1.1  christos 	obj->type = aml_t_buffer;
    393  1.1  christos 	obj->buffer.size = size1;
    394  1.1  christos 	obj->buffer.data = buffer;
    395  1.1  christos 	AML_DEBUGPRINT(") ");
    396  1.1  christos 	env->dp = end;
    397  1.1  christos 
    398  1.1  christos 	return (obj);
    399  1.1  christos }
    400  1.1  christos 
    401  1.1  christos static struct aml_name *
    402  1.1  christos aml_parse_concat_number(struct aml_environ *env, int num1, int indent)
    403  1.1  christos {
    404  1.1  christos 	int	num2;
    405  1.1  christos 	struct	aml_name *destname;
    406  1.1  christos 	union	aml_object *obj;
    407  1.1  christos 
    408  1.1  christos 	num2 = aml_objtonum(env, aml_eval_name(env,
    409  1.1  christos 		aml_parse_termobj(env, indent)));
    410  1.1  christos 	AML_DEBUGPRINT(", ");
    411  1.1  christos 	destname = aml_parse_termobj(env, indent);
    412  1.1  christos 	AML_DEBUGPRINT(")");
    413  1.1  christos 	obj = &env->tempobject;
    414  1.1  christos 	obj->type = aml_t_buffer;
    415  1.1  christos 	obj->buffer.size = 2;
    416  1.1  christos 	obj->buffer.data = memman_alloc_flexsize(aml_memman, 2);
    417  1.1  christos 	if (obj->buffer.data == NULL) {
    418  1.1  christos 		env->stat = aml_stat_panic;
    419  1.1  christos 		return (NULL);
    420  1.1  christos 	}
    421  1.1  christos 	obj->buffer.data[0] = num1 & 0xff;
    422  1.1  christos 	obj->buffer.data[1] = num2 & 0xff;
    423  1.1  christos 	aml_store_to_name(env, obj, destname);
    424  1.1  christos 	return (&env->tempname);
    425  1.1  christos }
    426  1.1  christos 
    427  1.1  christos static struct aml_name *
    428  1.1  christos aml_parse_concat_buffer(struct aml_environ *env, union aml_object *obj,
    429  1.1  christos     int indent)
    430  1.1  christos {
    431  1.1  christos 	union	aml_object *tmpobj, *tmpobj2, *resobj;
    432  1.1  christos 	struct	aml_name *destname;
    433  1.1  christos 
    434  1.1  christos 	tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent));
    435  1.1  christos 	AML_DEBUGPRINT(", ");
    436  1.1  christos 	if (tmpobj->type != aml_t_buffer) {
    437  1.1  christos 		env->stat = aml_stat_panic;
    438  1.1  christos 		return (NULL);
    439  1.1  christos 	}
    440  1.1  christos 	AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL);
    441  1.1  christos 	destname = aml_parse_termobj(env, indent);
    442  1.1  christos 	AML_DEBUGPRINT(")");
    443  1.1  christos 	resobj = &env->tempobject;
    444  1.1  christos 	env->tempname.property = resobj;
    445  1.1  christos 	resobj->buffer.type = aml_t_buffer;
    446  1.1  christos 	resobj->buffer.size = tmpobj2->buffer.size + obj->buffer.size;
    447  1.1  christos 	if (resobj->buffer.size > 0) {
    448  1.1  christos 		resobj->buffer.data = memman_alloc_flexsize(aml_memman,
    449  1.1  christos 		    resobj->buffer.size);
    450  1.1  christos 		if (resobj->buffer.data == NULL) {
    451  1.1  christos 			env->stat = aml_stat_panic;
    452  1.1  christos 			return (NULL);
    453  1.1  christos 		}
    454  1.1  christos 		bcopy(obj->buffer.data, resobj->buffer.data, obj->buffer.size);
    455  1.1  christos 		bcopy(tmpobj2->buffer.data,
    456  1.1  christos 		    resobj->buffer.data + obj->buffer.size,
    457  1.1  christos 		    tmpobj2->buffer.size);
    458  1.1  christos 	} else {
    459  1.1  christos 		resobj->buffer.data = NULL;
    460  1.1  christos 	}
    461  1.1  christos 	aml_free_object(&tmpobj2);
    462  1.1  christos 	aml_store_to_name(env, resobj, destname);
    463  1.1  christos 	return (&env->tempname);
    464  1.1  christos }
    465  1.1  christos 
    466  1.1  christos static struct aml_name *
    467  1.1  christos aml_parse_concat_string(struct aml_environ *env, union aml_object *obj,
    468  1.1  christos     int indent)
    469  1.1  christos {
    470  1.1  christos 	int	len;
    471  1.1  christos 	union	aml_object *tmpobj, *tmpobj2, *resobj;
    472  1.1  christos 	struct	aml_name *destname;
    473  1.1  christos 
    474  1.1  christos 	tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent));
    475  1.1  christos 	AML_DEBUGPRINT(", ");
    476  1.1  christos 	if (tmpobj->type != aml_t_string) {
    477  1.1  christos 		env->stat = aml_stat_panic;
    478  1.1  christos 		return (NULL);
    479  1.1  christos 	}
    480  1.1  christos 	AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL);
    481  1.1  christos 	destname = aml_parse_termobj(env, indent);
    482  1.1  christos 	AML_DEBUGPRINT(")");
    483  1.1  christos 	resobj = &env->tempobject;
    484  1.1  christos 	env->tempname.property = resobj;
    485  1.1  christos 	resobj->type = aml_t_buffer;
    486  1.1  christos 	resobj->str.needfree = 1;
    487  1.1  christos 	len = strlen((const char *)obj->str.string) +
    488  1.1  christos 	    strlen((const char *)tmpobj2->str.string) + 1;
    489  1.1  christos 	if (len > 0) {
    490  1.1  christos 		resobj->str.string = memman_alloc_flexsize(aml_memman, len);
    491  1.1  christos 		if (resobj->str.string == NULL) {
    492  1.1  christos 			env->stat = aml_stat_panic;
    493  1.1  christos 			return (NULL);
    494  1.1  christos 		}
    495  1.1  christos 		strlcpy((char *)resobj->str.string, (const char *)obj->str.string, len);
    496  1.1  christos 		strlcat((char *)resobj->str.string, (const char *)tmpobj->str.string, len);
    497  1.1  christos 	} else {
    498  1.1  christos 		resobj->str.string = NULL;
    499  1.1  christos 	}
    500  1.1  christos 	aml_free_object(&tmpobj2);
    501  1.1  christos 	aml_store_to_name(env, resobj, destname);
    502  1.1  christos 	return (&env->tempname);
    503  1.1  christos }
    504  1.1  christos 
    505  1.1  christos static struct aml_name *
    506  1.1  christos aml_parse_concatop(struct aml_environ *env, int indent)
    507  1.1  christos {
    508  1.1  christos 	union	aml_object *obj, *tmpobj;
    509  1.1  christos 	struct	aml_name *aname;
    510  1.1  christos 
    511  1.1  christos 	AML_DEBUGPRINT("Concat(");
    512  1.1  christos 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
    513  1.1  christos 	AML_DEBUGPRINT(", ");
    514  1.1  christos 	switch (obj->type) {
    515  1.1  christos 	case aml_t_num:
    516  1.1  christos 		aname = aml_parse_concat_number(env, aml_objtonum(env, obj), indent);
    517  1.1  christos 		break;
    518  1.1  christos 
    519  1.1  christos 	case aml_t_buffer:
    520  1.1  christos 		/* obj may be temporal object */
    521  1.1  christos 		AML_COPY_OBJECT(tmpobj, env, obj, NULL);
    522  1.1  christos 		aname = aml_parse_concat_buffer(env, obj, indent);
    523  1.1  christos 		aml_free_object(&tmpobj);
    524  1.1  christos 		break;
    525  1.1  christos 
    526  1.1  christos 	case aml_t_string:
    527  1.1  christos 		/* obj may be temporal object */
    528  1.1  christos 		AML_COPY_OBJECT(tmpobj, env, obj, NULL);
    529  1.1  christos 		aname = aml_parse_concat_string(env, obj, indent);
    530  1.1  christos 		aml_free_object(&tmpobj);
    531  1.1  christos 		break;
    532  1.1  christos 
    533  1.1  christos 	default:
    534  1.1  christos 		env->stat = aml_stat_panic;
    535  1.1  christos 		aname = NULL;
    536  1.1  christos 		break;
    537  1.1  christos 	}
    538  1.1  christos 
    539  1.1  christos 	AML_DEBUGPRINT("\n");
    540  1.1  christos 	return (aname);
    541  1.1  christos }
    542  1.1  christos 
    543  1.1  christos static union aml_object *
    544  1.1  christos aml_parse_defpackage(struct aml_environ *env, int indent)
    545  1.1  christos {
    546  1.1  christos 	u_int8_t	numelements;
    547  1.1  christos 	u_int8_t	*start;
    548  1.1  christos 	u_int32_t	pkglength;
    549  1.1  christos 	int		i;
    550  1.1  christos 	struct	aml_environ *copy;
    551  1.1  christos 	struct	aml_name *tmpname;
    552  1.1  christos 	union	aml_object *obj, **objects;
    553  1.1  christos 
    554  1.1  christos 	start = env->dp;
    555  1.1  christos 	pkglength = aml_parse_pkglength(env);
    556  1.1  christos 	numelements = aml_parse_bytedata(env);
    557  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
    558  1.1  christos 	if (copy == NULL) {
    559  1.1  christos 		env->stat = aml_stat_panic;
    560  1.1  christos 		return (NULL);
    561  1.1  christos 	}
    562  1.1  christos 	if (numelements > 0) {
    563  1.1  christos 		objects = memman_alloc_flexsize(aml_memman,
    564  1.1  christos 		    numelements * sizeof(union aml_object *));
    565  1.1  christos 		if (objects == NULL) {
    566  1.1  christos 			env->stat = aml_stat_panic;
    567  1.1  christos 			return (NULL);
    568  1.1  christos 		} else {
    569  1.1  christos 			bzero(objects, numelements * sizeof(union aml_object *));
    570  1.1  christos 		}
    571  1.1  christos 	} else {
    572  1.1  christos 		objects = NULL;
    573  1.1  christos 	}
    574  1.1  christos 
    575  1.1  christos 	*copy = *env;
    576  1.1  christos 	env->dp = copy->end = start + pkglength;
    577  1.1  christos 	AML_DEBUGPRINT("Package() {\n");
    578  1.1  christos 	i = 0;
    579  1.1  christos 	while ((copy->dp < copy->end) && (i < numelements)) {
    580  1.1  christos 		aml_print_indent(indent + 1);
    581  1.1  christos 		tmpname = aml_parse_termobj(copy, indent + 1);
    582  1.1  christos 
    583  1.1  christos 		if (tmpname != NULL) {
    584  1.1  christos 			objects[i] = aml_copy_object(copy, tmpname->property);
    585  1.1  christos 		}
    586  1.1  christos 		AML_DEBUGPRINT(",\n");
    587  1.1  christos 		i++;
    588  1.1  christos 	}
    589  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
    590  1.1  christos 
    591  1.1  christos 	aml_print_indent(indent);
    592  1.1  christos 	AML_DEBUGPRINT("}");
    593  1.1  christos 	obj = &env->tempobject;
    594  1.1  christos 	obj->type = aml_t_package;
    595  1.1  christos 	obj->package.elements = numelements;
    596  1.1  christos 	obj->package.objects = objects;
    597  1.1  christos 
    598  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
    599  1.1  christos 	return (obj);
    600  1.1  christos }
    601  1.1  christos 
    602  1.1  christos static void
    603  1.1  christos aml_parse_defmethod(struct aml_environ *env, int indent)
    604  1.1  christos {
    605  1.1  christos 	u_int8_t	flags;
    606  1.1  christos 	u_int8_t	*start;
    607  1.1  christos 	u_int32_t	pkglength;
    608  1.1  christos 	char	*name;
    609  1.1  christos 	struct	aml_environ *copy;
    610  1.1  christos 	struct	aml_method *meth;
    611  1.1  christos 	struct	aml_name *aname;
    612  1.1  christos 	union	aml_object *aobj;
    613  1.1  christos 
    614  1.1  christos 	start = env->dp;
    615  1.1  christos 	pkglength = aml_parse_pkglength(env);
    616  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
    617  1.1  christos 	if (copy == NULL) {
    618  1.1  christos 		env->stat = aml_stat_panic;
    619  1.1  christos 		return;
    620  1.1  christos 	}
    621  1.1  christos 	AML_DEBUGPRINT("Method(");
    622  1.1  christos 	name = (char *)aml_parse_namestring(env);
    623  1.1  christos 	aml_print_namestring((unsigned char *)name);
    624  1.1  christos 	AML_CREATE_NAME(aname, env, (unsigned char *)name,);
    625  1.1  christos 	if (aname->property != NULL) {
    626  1.1  christos 		env->stat = aml_stat_panic;
    627  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
    628  1.1  christos 		goto out;
    629  1.1  christos 	}
    630  1.1  christos 	AML_ALLOC_OBJECT(aobj, env, aml_t_method,);
    631  1.1  christos 	meth = &aobj->meth;
    632  1.1  christos 	aname->property = aobj;
    633  1.1  christos 	flags = *env->dp++;
    634  1.1  christos 
    635  1.1  christos 	if (flags) {
    636  1.1  christos 		AML_DEBUGPRINT(", %d", flags);
    637  1.1  christos 	}
    638  1.1  christos 	AML_DEBUGPRINT(") {\n");
    639  1.1  christos 	*copy = *env;
    640  1.1  christos 	meth->argnum = flags;
    641  1.1  christos 	meth->from = env->dp;
    642  1.1  christos 	meth->to = env->dp = copy->end = start + pkglength;
    643  1.1  christos 	aml_print_indent(indent);
    644  1.1  christos 	AML_DEBUGPRINT("}");
    645  1.1  christos out:
    646  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
    647  1.1  christos }
    648  1.1  christos 
    649  1.1  christos static void
    650  1.1  christos aml_parse_defopregion(struct aml_environ *env, int indent)
    651  1.1  christos {
    652  1.1  christos 	u_int8_t	*name;
    653  1.1  christos 	struct	aml_name *aname;
    654  1.1  christos 	struct	aml_opregion *opregion;
    655  1.1  christos 	union	aml_object *obj;
    656  1.1  christos 	const char	*regions[] = {
    657  1.1  christos 		"SystemMemory",
    658  1.1  christos 		"SystemIO",
    659  1.1  christos 		"PCI_Config",
    660  1.1  christos 		"EmbeddedControl",
    661  1.1  christos 		"SMBus",
    662  1.1  christos 	};
    663  1.1  christos 
    664  1.1  christos 	AML_DEBUGPRINT("OperationRegion(");
    665  1.1  christos 	/* Name */
    666  1.1  christos 	name = aml_parse_namestring(env);
    667  1.1  christos 	aml_print_namestring(name);
    668  1.1  christos 	AML_CREATE_NAME(aname, env, name,);
    669  1.1  christos 	if (aname->property != NULL) {
    670  1.1  christos 		env->stat = aml_stat_panic;
    671  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
    672  1.1  christos 		return;
    673  1.1  christos 	}
    674  1.1  christos 	AML_ALLOC_OBJECT(aname->property, env, aml_t_opregion,);
    675  1.1  christos 	opregion = &aname->property->opregion;
    676  1.1  christos 	opregion->space = *env->dp;
    677  1.1  christos 	AML_DEBUGPRINT(", %s, ", regions[*env->dp]);	/* Space */
    678  1.1  christos 	env->dp++;
    679  1.1  christos 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));	/* Offset */
    680  1.1  christos 	opregion->offset = aml_objtonum(env, obj);
    681  1.1  christos 	AML_DEBUGPRINT(", ");
    682  1.1  christos 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));	/* Length */
    683  1.1  christos 	opregion->length = aml_objtonum(env, obj);
    684  1.1  christos 	AML_DEBUGPRINT(")");
    685  1.1  christos }
    686  1.1  christos 
    687  1.1  christos static const char	*accessnames[] = {
    688  1.1  christos 	"AnyAcc",
    689  1.1  christos 	"ByteAcc",
    690  1.1  christos 	"WordAcc",
    691  1.1  christos 	"DWordAcc",
    692  1.1  christos 	"BlockAcc",
    693  1.1  christos 	"SMBSendRecvAcc",
    694  1.1  christos 	"SMBQuickAcc"
    695  1.1  christos };
    696  1.1  christos 
    697  1.1  christos static int
    698  1.1  christos aml_parse_field(struct aml_environ *env, struct aml_field *template)
    699  1.1  christos {
    700  1.1  christos 	u_int8_t	*name;
    701  1.1  christos 	u_int8_t	acc, attribute;
    702  1.1  christos 	u_int32_t	width;
    703  1.1  christos 	struct	aml_name *aname;
    704  1.1  christos 	struct	aml_field *prop;
    705  1.1  christos 
    706  1.1  christos 	switch (*env->dp) {
    707  1.1  christos 	case '\\':
    708  1.1  christos 	case '^':
    709  1.1  christos 	case 'A'...'Z':
    710  1.1  christos 	case '_':
    711  1.1  christos 	case '.':
    712  1.1  christos 	case '/':
    713  1.1  christos 		name = aml_parse_namestring(env);
    714  1.1  christos 		width = aml_parse_pkglength(env);
    715  1.1  christos 		template->bitlen = width;
    716  1.1  christos 		aml_print_namestring(name);
    717  1.1  christos 		AML_CREATE_NAME(aname, env, name, 0);
    718  1.1  christos 		/* Allignment */
    719  1.1  christos 		if (width == 16) {
    720  1.1  christos 			template->bitoffset += 15;
    721  1.1  christos 			template->bitoffset &= (~15);
    722  1.1  christos 		}
    723  1.1  christos 		if (width == 32) {
    724  1.1  christos 			template->bitoffset += 31;
    725  1.1  christos 			template->bitoffset &= (~31);
    726  1.1  christos 		} else if ((width & 7) == 0) {
    727  1.1  christos 			template->bitoffset += 7;
    728  1.1  christos 			template->bitoffset &= (~7);
    729  1.1  christos 		} else if ((width > 32) && (width & 7) != 0) {
    730  1.1  christos 			AML_DEBUGPRINT("??? Can I treat it?\n");
    731  1.1  christos 		}
    732  1.1  christos 		if (aname->property != NULL) {
    733  1.1  christos 			env->stat = aml_stat_panic;
    734  1.1  christos 			AML_DEBUGPRINT("Already Defined \n");
    735  1.1  christos 			return (0);
    736  1.1  christos 		}
    737  1.1  christos 		AML_ALLOC_OBJECT(aname->property, env, aml_t_field, 0);
    738  1.1  christos 		prop = &aname->property->field;
    739  1.1  christos 		*prop = *template;
    740  1.1  christos 		template->bitoffset += width;
    741  1.1  christos 		AML_DEBUGPRINT(",\t%d", width);
    742  1.1  christos 		break;
    743  1.1  christos 	case 0x00:
    744  1.1  christos 		env->dp++;
    745  1.1  christos 		width = aml_parse_pkglength(env);
    746  1.1  christos 		template->bitoffset += width;
    747  1.1  christos 		AML_DEBUGPRINT("Offset(0x%x)", template->bitoffset);
    748  1.1  christos 		break;
    749  1.1  christos 	case 0x01:
    750  1.1  christos 		acc = env->dp[1];
    751  1.1  christos 		attribute = env->dp[2];
    752  1.1  christos 		env->dp += 3;
    753  1.1  christos 		AML_DEBUGPRINT("AccessAs(%s, %d)", accessnames[acc], attribute);
    754  1.1  christos 		template->bitoffset = attribute;
    755  1.1  christos 		template->flags = (template->flags | 0xf0) | acc;
    756  1.1  christos 		break;
    757  1.1  christos 	}
    758  1.1  christos 	return (template->bitoffset);
    759  1.1  christos }
    760  1.1  christos 
    761  1.1  christos static void
    762  1.1  christos aml_parse_fieldlist(struct aml_environ *env, struct aml_field *template,
    763  1.1  christos     int indent)
    764  1.1  christos {
    765  1.1  christos 	u_int32_t	offset;
    766  1.1  christos 
    767  1.1  christos 	offset = 0;
    768  1.1  christos 	while (env->dp < env->end) {
    769  1.1  christos 		aml_print_indent(indent);
    770  1.1  christos 		offset = aml_parse_field(env, template);
    771  1.1  christos 		if (env->dp < env->end) {
    772  1.1  christos 			AML_DEBUGPRINT(",\n");
    773  1.1  christos 		} else {
    774  1.1  christos 			AML_DEBUGPRINT("\n");
    775  1.1  christos 		}
    776  1.1  christos 	}
    777  1.1  christos }
    778  1.1  christos 
    779  1.1  christos static void
    780  1.1  christos aml_parse_deffield(struct aml_environ *env, int indent)
    781  1.1  christos {
    782  1.1  christos 	u_int8_t	flags;
    783  1.1  christos 	u_int8_t	*start, *name;
    784  1.1  christos 	u_int32_t	pkglength;
    785  1.1  christos 	struct	aml_environ *copy;
    786  1.1  christos 	struct	aml_field fieldtemplate;
    787  1.1  christos 	static	const char *lockrules[] = {"NoLock", "Lock"};
    788  1.1  christos 	static	const char *updaterules[] = {"Preserve", "WriteAsOnes",
    789  1.1  christos 					     "WriteAsZeros", "*Error*"};
    790  1.1  christos 
    791  1.1  christos 	start = env->dp;
    792  1.1  christos 	pkglength = aml_parse_pkglength(env);
    793  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
    794  1.1  christos 	if (copy == NULL) {
    795  1.1  christos 		env->stat = aml_stat_panic;
    796  1.1  christos 		return;
    797  1.1  christos 	}
    798  1.1  christos 	AML_DEBUGPRINT("Field(");
    799  1.1  christos 	aml_print_namestring(name = aml_parse_namestring(env));
    800  1.1  christos 	fieldtemplate.type = aml_t_field;
    801  1.1  christos 	flags = aml_parse_bytedata(env);
    802  1.1  christos 	fieldtemplate.flags = fieldtemplate.flags = flags;
    803  1.1  christos 
    804  1.1  christos 	*copy = *env;
    805  1.1  christos 	env->dp = copy->end = start + pkglength;
    806  1.1  christos 	fieldtemplate.bitoffset = 0;
    807  1.1  christos 	fieldtemplate.bitlen = 0;
    808  1.1  christos 	fieldtemplate.f.ftype = f_t_field;
    809  1.1  christos 	fieldtemplate.f.fld.regname = name;
    810  1.1  christos 	AML_DEBUGPRINT(", %s, %s, %s) {\n",
    811  1.1  christos 	    accessnames[flags & 0xf],
    812  1.1  christos 	    lockrules[(flags >> 4) & 1],
    813  1.1  christos 	    updaterules[(flags >> 5) & 3]);
    814  1.1  christos 	aml_parse_fieldlist(copy, &fieldtemplate, indent + 1);
    815  1.1  christos 	aml_print_indent(indent);
    816  1.1  christos 	AML_DEBUGPRINT("}");
    817  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
    818  1.1  christos 
    819  1.1  christos 	AML_SYSASSERT(copy->dp == copy->end);
    820  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
    821  1.1  christos }
    822  1.1  christos 
    823  1.1  christos static void
    824  1.1  christos aml_parse_defindexfield(struct aml_environ *env, int indent)
    825  1.1  christos {
    826  1.1  christos 	u_int8_t	flags;
    827  1.1  christos 	u_int8_t	*start, *iname, *dname;
    828  1.1  christos 	u_int32_t	pkglength;
    829  1.1  christos 	struct	aml_environ *copy;
    830  1.1  christos 	struct	aml_field template;
    831  1.1  christos 	static	const char *lockrules[] = {"NoLock", "Lock"};
    832  1.1  christos 	static	const char *updaterules[] = {"Preserve", "WriteAsOnes",
    833  1.1  christos 					     "WriteAsZeros", "*Error*"};
    834  1.1  christos 
    835  1.1  christos 	start = env->dp;
    836  1.1  christos 	pkglength = aml_parse_pkglength(env);
    837  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
    838  1.1  christos 	if (copy == NULL) {
    839  1.1  christos 		env->stat = aml_stat_panic;
    840  1.1  christos 		return;
    841  1.1  christos 	}
    842  1.1  christos 	AML_DEBUGPRINT("IndexField(");
    843  1.1  christos 	aml_print_namestring(iname = aml_parse_namestring(env));	/* Name1 */
    844  1.1  christos 	AML_DEBUGPRINT(", ");
    845  1.1  christos 	aml_print_namestring(dname = aml_parse_namestring(env));	/* Name2 */
    846  1.1  christos 	template.type = aml_t_field;
    847  1.1  christos 	template.flags = flags = aml_parse_bytedata(env);
    848  1.1  christos 	template.bitoffset = 0;
    849  1.1  christos 	template.bitlen = 0;
    850  1.1  christos 	template.f.ftype = f_t_index;
    851  1.1  christos 	template.f.ifld.indexname = iname;
    852  1.1  christos 	template.f.ifld.dataname = dname;
    853  1.1  christos 	AML_DEBUGPRINT(", %s, %s, %s) {\n",
    854  1.1  christos 	    accessnames[flags & 0xf],
    855  1.1  christos 	    lockrules[(flags >> 4) & 1],
    856  1.1  christos 	    updaterules[(flags >> 5) & 3]);
    857  1.1  christos 	*copy = *env;
    858  1.1  christos 	env->dp = copy->end = start + pkglength;
    859  1.1  christos 	aml_parse_fieldlist(copy, &template, indent + 1);
    860  1.1  christos 	aml_print_indent(indent);
    861  1.1  christos 	AML_DEBUGPRINT("}");
    862  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
    863  1.1  christos 
    864  1.1  christos 	AML_SYSASSERT(copy->dp == copy->end);
    865  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
    866  1.1  christos }
    867  1.1  christos 
    868  1.1  christos static void
    869  1.1  christos aml_parse_defbankfield(struct aml_environ *env, int indent)
    870  1.1  christos {
    871  1.1  christos 	u_int8_t	flags;
    872  1.1  christos 	u_int8_t	*start, *rname, *bname;
    873  1.1  christos 	u_int32_t	pkglength, bankvalue;
    874  1.1  christos 	struct	aml_environ *copy;
    875  1.1  christos 	struct	aml_field template;
    876  1.1  christos 	union	aml_object *obj;
    877  1.1  christos 	static	const char *lockrules[] = {"NoLock", "Lock"};
    878  1.1  christos 	static	const char *updaterules[] = {"Preserve", "WriteAsOnes",
    879  1.1  christos 					     "WriteAsZeros", "*Error*"};
    880  1.1  christos 
    881  1.1  christos 	start = env->dp;
    882  1.1  christos 	pkglength = aml_parse_pkglength(env);
    883  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
    884  1.1  christos 	if (copy == NULL) {
    885  1.1  christos 		env->stat = aml_stat_panic;
    886  1.1  christos 		return;
    887  1.1  christos 	}
    888  1.1  christos 	AML_DEBUGPRINT("BankField(");
    889  1.1  christos 	aml_print_namestring(rname = aml_parse_namestring(env));	/* Name1 */
    890  1.1  christos 	AML_DEBUGPRINT(", ");
    891  1.1  christos 	aml_print_namestring(bname = aml_parse_namestring(env));	/* Name2 */
    892  1.1  christos 	AML_DEBUGPRINT(", ");
    893  1.1  christos 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));	/* BankValue */
    894  1.1  christos 	bankvalue = aml_objtonum(env, obj);
    895  1.1  christos 	template.type = aml_t_field;
    896  1.1  christos 	template.flags = flags = aml_parse_bytedata(env);
    897  1.1  christos 	template.bitoffset = 0;
    898  1.1  christos 	template.bitlen = 0;
    899  1.1  christos 	template.f.ftype = f_t_bank;
    900  1.1  christos 	template.f.bfld.regname = rname;
    901  1.1  christos 	template.f.bfld.bankname = bname;
    902  1.1  christos 	template.f.bfld.bankvalue = bankvalue;
    903  1.1  christos 	*copy = *env;
    904  1.1  christos 	env->dp = copy->end = start + pkglength;
    905  1.1  christos 	AML_DEBUGPRINT(", %s, %s, %s) {\n",
    906  1.1  christos 	    accessnames[flags & 0xf],
    907  1.1  christos 	    lockrules[(flags >> 4) & 1],
    908  1.1  christos 	    updaterules[(flags >> 5) & 3]);
    909  1.1  christos 	aml_parse_fieldlist(copy, &template, indent + 1);
    910  1.1  christos 	aml_print_indent(indent);
    911  1.1  christos 	AML_DEBUGPRINT("}");
    912  1.1  christos 
    913  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
    914  1.1  christos 	AML_SYSASSERT(copy->dp == copy->end);
    915  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
    916  1.1  christos }
    917  1.1  christos 
    918  1.1  christos static void
    919  1.1  christos aml_parse_defdevice(struct aml_environ *env, int indent)
    920  1.1  christos {
    921  1.1  christos 	u_int8_t	*start;
    922  1.1  christos 	u_int8_t	*name;
    923  1.1  christos 	u_int32_t	pkglength;
    924  1.1  christos 	struct	aml_environ *copy;
    925  1.1  christos 
    926  1.1  christos 	start = env->dp;
    927  1.1  christos 	pkglength = aml_parse_pkglength(env);
    928  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
    929  1.1  christos 	if (copy == NULL) {
    930  1.1  christos 		env->stat = aml_stat_panic;
    931  1.1  christos 		return;
    932  1.1  christos 	}
    933  1.1  christos 	AML_DEBUGPRINT("Device(");
    934  1.1  christos 	name = aml_parse_namestring(env);
    935  1.1  christos 	aml_print_namestring(name);
    936  1.1  christos 	AML_DEBUGPRINT(") {\n");
    937  1.1  christos 	*copy = *env;
    938  1.1  christos 	AML_CREATE_NAME(copy->curname, env, name,);
    939  1.1  christos 	if (copy->curname->property != NULL) {
    940  1.1  christos 		env->stat = aml_stat_panic;
    941  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
    942  1.1  christos 		goto out;
    943  1.1  christos 	}
    944  1.1  christos 	AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_device,);
    945  1.1  christos 	env->dp = copy->end = start + pkglength;
    946  1.1  christos 	aml_parse_objectlist(copy, indent + 1);
    947  1.1  christos 	aml_print_indent(indent);
    948  1.1  christos 	AML_DEBUGPRINT("}");
    949  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
    950  1.1  christos 
    951  1.1  christos 	AML_SYSASSERT(copy->dp == copy->end);
    952  1.1  christos out:
    953  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
    954  1.1  christos }
    955  1.1  christos 
    956  1.1  christos static void
    957  1.1  christos aml_parse_defprocessor(struct aml_environ *env, int indent)
    958  1.1  christos {
    959  1.1  christos 	u_int8_t	*start;
    960  1.1  christos 	u_int8_t	*name;
    961  1.1  christos 	u_int32_t	pkglength;
    962  1.1  christos 	struct	aml_environ *copy;
    963  1.1  christos 	struct	aml_processor *proc;
    964  1.1  christos 	union	aml_object *obj;
    965  1.1  christos 
    966  1.1  christos 	start = env->dp;
    967  1.1  christos 	pkglength = aml_parse_pkglength(env);
    968  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
    969  1.1  christos 	if (copy == NULL) {
    970  1.1  christos 		env->stat = aml_stat_panic;
    971  1.1  christos 		return;
    972  1.1  christos 	}
    973  1.1  christos 	AML_ALLOC_OBJECT(obj, env, aml_t_processor,);
    974  1.1  christos 	proc = &obj->proc;
    975  1.1  christos 	AML_DEBUGPRINT("Processor(");
    976  1.1  christos 	name = aml_parse_namestring(env);
    977  1.1  christos 	aml_print_namestring(name);
    978  1.1  christos 	proc->id = aml_parse_bytedata(env);
    979  1.1  christos 	proc->addr = aml_parse_dworddata(env);
    980  1.1  christos 	proc->len = aml_parse_bytedata(env);
    981  1.1  christos 	AML_DEBUGPRINT(", %d, 0x%x, 0x%x) {\n", proc->id, proc->addr, proc->len);
    982  1.1  christos 	*copy = *env;
    983  1.1  christos 	AML_CREATE_NAME(copy->curname, env, name,);
    984  1.1  christos 	if (copy->curname->property != NULL) {
    985  1.1  christos 		env->stat = aml_stat_panic;
    986  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
    987  1.1  christos 		goto out;
    988  1.1  christos 	}
    989  1.1  christos 	copy->curname->property = obj;
    990  1.1  christos 	env->dp = copy->end = start + pkglength;
    991  1.1  christos 	aml_parse_objectlist(copy, indent + 1);
    992  1.1  christos 	aml_print_indent(indent);
    993  1.1  christos 	AML_DEBUGPRINT("}");
    994  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
    995  1.1  christos 
    996  1.1  christos 	AML_SYSASSERT(copy->dp == copy->end);
    997  1.1  christos out:
    998  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
    999  1.1  christos }
   1000  1.1  christos 
   1001  1.1  christos static void
   1002  1.1  christos aml_parse_defpowerres(struct aml_environ *env, int indent)
   1003  1.1  christos {
   1004  1.1  christos 	u_int8_t	*start;
   1005  1.1  christos 	u_int8_t	*name;
   1006  1.1  christos 	u_int32_t	pkglength;
   1007  1.1  christos 	struct	aml_environ *copy;
   1008  1.1  christos 	struct	aml_powerres *pres;
   1009  1.1  christos 	union	aml_object *obj;
   1010  1.1  christos 
   1011  1.1  christos 	start = env->dp;
   1012  1.1  christos 	pkglength = aml_parse_pkglength(env);
   1013  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
   1014  1.1  christos 	if (copy == NULL) {
   1015  1.1  christos 		env->stat = aml_stat_panic;
   1016  1.1  christos 		return;
   1017  1.1  christos 	}
   1018  1.1  christos 	AML_DEBUGPRINT("PowerResource(");
   1019  1.1  christos 	AML_ALLOC_OBJECT(obj, env, aml_t_powerres,);
   1020  1.1  christos 	name = aml_parse_namestring(env);
   1021  1.1  christos 	aml_print_namestring(name);
   1022  1.1  christos 	pres = &obj->pres;
   1023  1.1  christos 	pres->level = aml_parse_bytedata(env);
   1024  1.1  christos 	pres->order = aml_parse_worddata(env);
   1025  1.1  christos 	AML_DEBUGPRINT(", %d, %d) {\n", pres->level, pres->order);
   1026  1.1  christos 	*copy = *env;
   1027  1.1  christos 	AML_CREATE_NAME(copy->curname, env, name,);
   1028  1.1  christos 	if (copy->curname->property != NULL) {
   1029  1.1  christos 		env->stat = aml_stat_panic;
   1030  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
   1031  1.1  christos 		goto out;
   1032  1.1  christos 	}
   1033  1.1  christos 	copy->curname->property = obj;
   1034  1.1  christos 	env->dp = copy->end = start + pkglength;
   1035  1.1  christos 
   1036  1.1  christos 	aml_parse_objectlist(copy, indent + 1);
   1037  1.1  christos 	aml_print_indent(indent);
   1038  1.1  christos 	AML_DEBUGPRINT("}");
   1039  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
   1040  1.1  christos 
   1041  1.1  christos 	AML_SYSASSERT(copy->dp == copy->end);
   1042  1.1  christos out:
   1043  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
   1044  1.1  christos }
   1045  1.1  christos 
   1046  1.1  christos static void
   1047  1.1  christos aml_parse_defthermalzone(struct aml_environ *env, int indent)
   1048  1.1  christos {
   1049  1.1  christos 	u_int8_t	*start;
   1050  1.1  christos 	u_int8_t	*name;
   1051  1.1  christos 	u_int32_t	pkglength;
   1052  1.1  christos 	struct	aml_environ *copy;
   1053  1.1  christos 
   1054  1.1  christos 	start = env->dp;
   1055  1.1  christos 	pkglength = aml_parse_pkglength(env);
   1056  1.1  christos 	copy = memman_alloc(aml_memman, memid_aml_environ);
   1057  1.1  christos 	if (copy == NULL) {
   1058  1.1  christos 		env->stat = aml_stat_panic;
   1059  1.1  christos 		return;
   1060  1.1  christos 	}
   1061  1.1  christos 	AML_DEBUGPRINT("ThermalZone(");
   1062  1.1  christos 	name = aml_parse_namestring(env);
   1063  1.1  christos 	aml_print_namestring(name);
   1064  1.1  christos 	AML_DEBUGPRINT(") {\n");
   1065  1.1  christos 	*copy = *env;
   1066  1.1  christos 	AML_CREATE_NAME(copy->curname, env, name,);
   1067  1.1  christos 	if (copy->curname->property != NULL) {
   1068  1.1  christos 		env->stat = aml_stat_panic;
   1069  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
   1070  1.1  christos 		goto out;
   1071  1.1  christos 	}
   1072  1.1  christos 	AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_therm,);
   1073  1.1  christos 	env->dp = copy->end = start + pkglength;
   1074  1.1  christos 	aml_parse_objectlist(copy, indent + 1);
   1075  1.1  christos 	aml_print_indent(indent);
   1076  1.1  christos 	AML_DEBUGPRINT("}");
   1077  1.1  christos 	aml_free_objectcontent(&copy->tempobject);
   1078  1.1  christos 	AML_SYSASSERT(copy->dp == copy->end);
   1079  1.1  christos out:
   1080  1.1  christos 	memman_free(aml_memman, memid_aml_environ, copy);
   1081  1.1  christos }
   1082  1.1  christos 
   1083  1.1  christos static struct aml_name *
   1084  1.1  christos aml_parse_defelse(struct aml_environ *env, int indent, int num)
   1085  1.1  christos {
   1086  1.1  christos 	u_int8_t	*start, *end, *oend;
   1087  1.1  christos 	u_int32_t	pkglength;
   1088  1.1  christos 	struct	aml_name *aname;
   1089  1.1  christos 
   1090  1.1  christos 	start = env->dp;
   1091  1.1  christos 	pkglength = aml_parse_pkglength(env);
   1092  1.1  christos 	oend = env->end;
   1093  1.1  christos 	env->end = end = start + pkglength;
   1094  1.1  christos 	aname = NULL;
   1095  1.1  christos 
   1096  1.1  christos 	AML_DEBUGPRINT("Else {\n");
   1097  1.1  christos 	if (num == 0) {
   1098  1.1  christos 		aname = aml_parse_objectlist(env, indent + 1);
   1099  1.1  christos 		aml_print_indent(indent);
   1100  1.1  christos 	}
   1101  1.1  christos 	AML_DEBUGPRINT("}");
   1102  1.1  christos 
   1103  1.1  christos 	env->dp = end;
   1104  1.1  christos 	env->end = oend;
   1105  1.1  christos 	return (aname);
   1106  1.1  christos }
   1107  1.1  christos 
   1108  1.1  christos static struct aml_name *
   1109  1.1  christos aml_parse_defif(struct aml_environ *env, int indent)
   1110  1.1  christos {
   1111  1.1  christos 	u_int8_t	*start, *end, *oend;
   1112  1.1  christos 	u_int32_t	pkglength;
   1113  1.1  christos 	int	num;
   1114  1.1  christos 	struct	aml_name *aname, *aname1;
   1115  1.1  christos 
   1116  1.1  christos 	start = env->dp;
   1117  1.1  christos 	pkglength = aml_parse_pkglength(env);
   1118  1.1  christos 	aname = NULL;
   1119  1.1  christos 
   1120  1.1  christos 	AML_DEBUGPRINT("If(");
   1121  1.1  christos 	num = aml_objtonum(env, aml_eval_name
   1122  1.1  christos 	    (env, aml_parse_termobj(env, indent)));
   1123  1.1  christos 	oend = env->end;
   1124  1.1  christos 	end = start + pkglength;
   1125  1.1  christos 	AML_DEBUGPRINT(")");
   1126  1.1  christos 	if (num) {
   1127  1.1  christos 		AML_DEBUGPRINT("{\n");
   1128  1.1  christos 		env->end = end;
   1129  1.1  christos 		aname = aml_parse_objectlist(env, indent + 1);
   1130  1.1  christos 		aml_print_indent(indent);
   1131  1.1  christos 		AML_DEBUGPRINT("}");
   1132  1.1  christos 	}
   1133  1.1  christos 	env->dp = end;
   1134  1.1  christos 	env->end = oend;
   1135  1.1  christos 	if ((end < oend) && *(env->dp) == 0xa1) {
   1136  1.1  christos 		env->dp++;
   1137  1.1  christos 		aname1 = aml_parse_defelse(env, indent, num);
   1138  1.1  christos 		aname = (num == 0) ? aname1 : aname;
   1139  1.1  christos 	}
   1140  1.1  christos 	return (aname);
   1141  1.1  christos }
   1142  1.1  christos 
   1143  1.1  christos static struct aml_name *
   1144  1.1  christos aml_parse_defwhile(struct aml_environ *env, int indent)
   1145  1.1  christos {
   1146  1.1  christos 	u_int8_t	*start, *end, *oend;
   1147  1.1  christos 	u_int32_t	pkglength;
   1148  1.1  christos 	int	num;
   1149  1.1  christos 	struct	aml_name *aname;
   1150  1.1  christos 
   1151  1.1  christos 	start = env->dp;
   1152  1.1  christos 	pkglength = aml_parse_pkglength(env);
   1153  1.1  christos 	oend = env->end;
   1154  1.1  christos 	end = start + pkglength;
   1155  1.1  christos 	aname = NULL;
   1156  1.1  christos 	for (;;) {
   1157  1.1  christos 		env->dp = start;
   1158  1.1  christos 		aml_parse_pkglength(env);
   1159  1.1  christos 		AML_DEBUGPRINT("While(");
   1160  1.1  christos 		num = aml_objtonum(env, aml_eval_name
   1161  1.1  christos 		    (env, aml_parse_termobj(env, indent)));
   1162  1.1  christos 		AML_DEBUGPRINT(")");
   1163  1.1  christos 		if (num == 0) {
   1164  1.1  christos 			break;
   1165  1.1  christos 		}
   1166  1.1  christos 		AML_DEBUGPRINT(" {\n");
   1167  1.1  christos 		env->end = end;
   1168  1.1  christos 		aname = aml_parse_objectlist(env, indent + 1);
   1169  1.1  christos 		if (env->stat == aml_stat_step) {
   1170  1.1  christos 			AML_DEBUGGER(env, env);
   1171  1.1  christos 			continue;
   1172  1.1  christos 		}
   1173  1.1  christos 		if (env->stat != aml_stat_none)
   1174  1.1  christos 			break;
   1175  1.1  christos 		aml_print_indent(indent);
   1176  1.1  christos 		AML_DEBUGPRINT("}");
   1177  1.1  christos 	}
   1178  1.1  christos 	AML_DEBUGPRINT("\n");
   1179  1.1  christos 	env->dp = end;
   1180  1.1  christos 	env->end = oend;
   1181  1.1  christos 	if (env->stat == aml_stat_break) {
   1182  1.1  christos 		env->stat = aml_stat_none;
   1183  1.1  christos 		aname = NULL;
   1184  1.1  christos 	}
   1185  1.1  christos 	return (aname);
   1186  1.1  christos }
   1187  1.1  christos 
   1188  1.1  christos static void
   1189  1.1  christos aml_parse_defmutex(struct aml_environ *env, int indent)
   1190  1.1  christos {
   1191  1.1  christos 	char	*name;
   1192  1.1  christos 	struct	aml_name *aname;
   1193  1.1  christos 	struct	aml_mutex *mut;
   1194  1.1  christos 
   1195  1.1  christos 	/* MutexOp */
   1196  1.1  christos 	AML_DEBUGPRINT("Mutex(");
   1197  1.1  christos 	name = (char *)aml_parse_namestring(env);
   1198  1.1  christos 	aml_print_namestring((unsigned char *)name);
   1199  1.1  christos 	AML_CREATE_NAME(aname, env, (unsigned char *)name,);
   1200  1.1  christos 	if (aname->property != NULL) {
   1201  1.1  christos 		env->stat = aml_stat_panic;
   1202  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
   1203  1.1  christos 		return;
   1204  1.1  christos 	}
   1205  1.1  christos 	AML_ALLOC_OBJECT(aname->property, env, aml_t_mutex,);
   1206  1.1  christos 	mut = &aname->property->mutex;
   1207  1.1  christos 	mut->level = *env->dp++;
   1208  1.1  christos 	STAILQ_INIT(&mut->queue);
   1209  1.1  christos 	AML_DEBUGPRINT(", %d)", mut->level);
   1210  1.1  christos }
   1211  1.1  christos 
   1212  1.1  christos static void
   1213  1.1  christos aml_createfield_generic(struct aml_environ *env,
   1214  1.1  christos     union aml_object *srcbuf, int idx,
   1215  1.1  christos     int len, char *newname)
   1216  1.1  christos {
   1217  1.1  christos 	struct	aml_bufferfield *field;
   1218  1.1  christos 	struct	aml_name *aname;
   1219  1.1  christos 
   1220  1.1  christos 	if (srcbuf == NULL || srcbuf->type != aml_t_buffer) {
   1221  1.1  christos 		AML_DEBUGPRINT("Not Buffer assigned,");
   1222  1.1  christos 		env->stat = aml_stat_panic;
   1223  1.1  christos 		return;
   1224  1.1  christos 	}
   1225  1.1  christos 	AML_CREATE_NAME(aname, env, (unsigned char *)newname,);
   1226  1.1  christos 	if (aname->property != NULL) {
   1227  1.1  christos 		env->stat = aml_stat_panic;
   1228  1.1  christos 		AML_DEBUGPRINT("Already Defined \n");
   1229  1.1  christos 		return;
   1230  1.1  christos 	}
   1231  1.1  christos 	AML_ALLOC_OBJECT(aname->property, env, aml_t_bufferfield,);
   1232  1.1  christos 	field = &aname->property->bfld;
   1233  1.1  christos 	field->bitoffset = idx;
   1234  1.1  christos 	field->bitlen = len;
   1235  1.1  christos 	field->origin = srcbuf->buffer.data;
   1236  1.1  christos }
   1237  1.1  christos 
   1238  1.1  christos static void
   1239  1.1  christos aml_parse_defcreatefield(struct aml_environ *env, int indent)
   1240  1.1  christos {
   1241  1.1  christos 	int	idx, len;
   1242  1.1  christos 	char	*newname;
   1243  1.1  christos 	union	aml_object *obj, *srcbuf;
   1244  1.1  christos 
   1245  1.1  christos 	/* CreateFieldOp */
   1246  1.1  christos 	AML_DEBUGPRINT("CreateField(");
   1247  1.1  christos 	srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent));
   1248  1.1  christos 	if (srcbuf == &env->tempobject) {
   1249  1.1  christos 		AML_DEBUGPRINT("NONAMED BUFFER\n");
   1250  1.1  christos 		env->stat = aml_stat_panic;
   1251  1.1  christos 		return;
   1252  1.1  christos 	}
   1253  1.1  christos 	AML_DEBUGPRINT(", ");
   1254  1.1  christos 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
   1255  1.1  christos 	idx = aml_objtonum(env, obj);
   1256  1.1  christos 	AML_DEBUGPRINT(", ");
   1257  1.1  christos 	obj = aml_eval_name(env, aml_parse_termobj(env, indent));
   1258  1.1  christos 	len = aml_objtonum(env, obj);
   1259  1.1  christos 	AML_DEBUGPRINT(", ");
   1260  1.1  christos 	newname = (char *)aml_parse_namestring(env);
   1261  1.1  christos 	aml_print_namestring((unsigned char *)newname);
   1262  1.1  christos 	aml_createfield_generic(env, srcbuf, idx, len, newname);
   1263  1.1  christos 	AML_DEBUGPRINT(") ");
   1264  1.1  christos }
   1265  1.1  christos 
   1266  1.1  christos /*
   1267  1.1  christos  * Returns Named object or parser buffer. The object need not be free because
   1268  1.1  christos  * it returns preallocated buffer in env or Contain of named object.  If You
   1269  1.1  christos  * need to preserve object, create a copy and then store.  And The object
   1270  1.1  christos  * returned from this function is not valid after another call is
   1271  1.1  christos  * shared, tempolary buffer may be shared.
   1272  1.1  christos  */
   1273  1.1  christos struct aml_name *
   1274  1.1  christos aml_parse_termobj(struct aml_environ *env, int indent)
   1275  1.1  christos {
   1276  1.1  christos 	u_int8_t	opcode;
   1277  1.1  christos 	u_int8_t	*name;
   1278  1.1  christos 	int	value;
   1279  1.1  christos 	int	num1, num2;
   1280  1.1  christos 	int	len;
   1281  1.1  christos 	int	match1, match2, i, pkgval, start;
   1282  1.1  christos 	int	widthindex, idx;
   1283  1.1  christos 	char	*newname;
   1284  1.1  christos 	struct	aml_name *aname;
   1285  1.1  christos 	struct	aml_name *destname1, *destname2;
   1286  1.1  christos 	struct	aml_name *tmpname, *srcname;
   1287  1.1  christos 	struct	aml_name *src;
   1288  1.1  christos 	union	aml_object *ret;
   1289  1.1  christos 	union	aml_object *tmpobj;
   1290  1.1  christos 	union	aml_object anum;
   1291  1.1  christos 	union	aml_object *objref;
   1292  1.1  christos 	union	aml_object *srcobj;
   1293  1.1  christos 	union	aml_object *obj;
   1294  1.1  christos 	union	aml_object *srcbuf;
   1295  1.1  christos 	static int	widthtbl[4] = {32, 16, 8, 1};
   1296  1.1  christos 	const char	*opname[4] = {"CreateDWordField", "CreateWordField",
   1297  1.1  christos 				      "CreateByteField", "CreateBitField"};
   1298  1.1  christos 
   1299  1.1  christos 	aname = &env->tempname;
   1300  1.1  christos 	ret = &env->tempobject;
   1301  1.1  christos 	anum.type = aml_t_num;
   1302  1.1  christos 	aname->property = ret;
   1303  1.1  christos 	aml_free_objectcontent(ret);
   1304  1.1  christos 	if (env->stat == aml_stat_panic) {
   1305  1.1  christos 		/*
   1306  1.1  christos 		 * If previosuly parser panic , parsing next instruction is
   1307  1.1  christos 		 * prohibited.
   1308  1.1  christos 		 */
   1309  1.1  christos 		return (NULL);
   1310  1.1  christos 	}
   1311  1.1  christos 	aname = NULL;
   1312  1.1  christos 	opcode = *env->dp++;
   1313  1.1  christos 	switch (opcode) {
   1314  1.1  christos 	case '\\':
   1315  1.1  christos 	case '^':
   1316  1.1  christos 	case 'A' ... 'Z':
   1317  1.1  christos 	case '_':
   1318  1.1  christos 	case '.':
   1319  1.1  christos 	case '/':
   1320  1.1  christos 		env->dp--;
   1321  1.1  christos 		ret->type = aml_t_namestr;
   1322  1.1  christos 		ret->nstr.dp = aml_parse_namestring(env);
   1323  1.1  christos 		aml_print_namestring(ret->nstr.dp);
   1324  1.1  christos 		aname = &env->tempname;
   1325  1.1  christos 		break;
   1326  1.1  christos 	case 0x0a:		/* BytePrefix */
   1327  1.1  christos 		ret->type = aml_t_num;
   1328  1.1  christos 		value = aml_parse_bytedata(env);
   1329  1.1  christos 		ret->num.number = value;
   1330  1.1  christos 		AML_DEBUGPRINT("0x%x", value);
   1331  1.1  christos 		aname = &env->tempname;
   1332  1.1  christos 		break;
   1333  1.1  christos 	case 0x0b:		/* WordPrefix */
   1334  1.1  christos 		ret->type = aml_t_num;
   1335  1.1  christos 		value = aml_parse_worddata(env);
   1336  1.1  christos 		ret->num.number = value;
   1337  1.1  christos 		AML_DEBUGPRINT("0x%x", value);
   1338  1.1  christos 		aname = &env->tempname;
   1339  1.1  christos 		break;
   1340  1.1  christos 	case 0x0c:		/* DWordPrefix */
   1341  1.1  christos 		ret->type = aml_t_num;
   1342  1.1  christos 		value = aml_parse_dworddata(env);
   1343  1.1  christos 		ret->num.number = value;
   1344  1.1  christos 		AML_DEBUGPRINT("0x%x", value);
   1345  1.1  christos 		aname = &env->tempname;
   1346  1.1  christos 		break;
   1347  1.1  christos 	case 0x0d:		/* StringPrefix */
   1348  1.1  christos 		ret->type = aml_t_string;
   1349  1.1  christos 		ret->str.string = env->dp;
   1350  1.1  christos 		len = strlen((const char *)env->dp);
   1351  1.1  christos 		ret->str.needfree = 0;
   1352  1.1  christos 		AML_DEBUGPRINT("\"%s\"", (const char *)ret->str.string);
   1353  1.1  christos 		env->dp += (len + 1);
   1354  1.1  christos 		aname = &env->tempname;
   1355  1.1  christos 		break;
   1356  1.1  christos 	case 0x00:		/* ZeroOp */
   1357  1.1  christos 		ret->type = aml_t_num;
   1358  1.1  christos 		ret->num.number = 0;
   1359  1.1  christos 		ret->num.constant = 1;
   1360  1.1  christos 		AML_DEBUGPRINT("Zero");
   1361  1.1  christos 		aname = &env->tempname;
   1362  1.1  christos 		break;
   1363  1.1  christos 	case 0x01:		/* OneOp */
   1364  1.1  christos 		ret->type = aml_t_num;
   1365  1.1  christos 		ret->num.number = 1;
   1366  1.1  christos 		ret->num.constant = 1;
   1367  1.1  christos 		AML_DEBUGPRINT("One");
   1368  1.1  christos 		aname = &env->tempname;
   1369  1.1  christos 		break;
   1370  1.1  christos 	case 0xff:		/* OnesOp */
   1371  1.1  christos 		ret->type = aml_t_num;
   1372  1.1  christos 		ret->num.number = 0xffffffff;
   1373  1.1  christos 		ret->num.constant = 1;
   1374  1.1  christos 		AML_DEBUGPRINT("Ones");
   1375  1.1  christos 		aname = &env->tempname;
   1376  1.1  christos 		break;
   1377  1.1  christos 	case 0x06:		/* AliasOp */
   1378  1.1  christos 		AML_DEBUGPRINT("Alias(");
   1379  1.1  christos 		tmpname = aml_parse_termobj(env, indent);
   1380  1.1  christos 		if (env->stat == aml_stat_panic) {
   1381  1.1  christos 			return (NULL);
   1382  1.1  christos 		}
   1383  1.1  christos 		if (tmpname->property == NULL ||
   1384  1.1  christos 		    tmpname->property->type != aml_t_namestr) {
   1385  1.1  christos 			env->stat = aml_stat_panic;
   1386  1.1  christos 			return (NULL);
   1387  1.1  christos 		}
   1388  1.1  christos 		/*
   1389  1.1  christos 		 * XXX if srcname is deleted after this object, what
   1390  1.1  christos 		 * shall I do?
   1391  1.1  christos 		 */
   1392  1.1  christos 		srcname = aml_search_name(env, tmpname->property->nstr.dp);
   1393  1.1  christos 		AML_DEBUGPRINT(", ");
   1394  1.1  christos 		name = aml_parse_namestring(env);
   1395  1.1  christos 		aml_print_namestring(name);
   1396  1.1  christos 		AML_CREATE_NAME(aname, env, name, 0);
   1397  1.1  christos 		if (aname->property != NULL) {
   1398  1.1  christos 			env->stat = aml_stat_panic;
   1399  1.1  christos 			AML_DEBUGPRINT("Already Defined \n");
   1400  1.1  christos 			aml_print_curname(aname);
   1401  1.1  christos 			return (NULL);
   1402  1.1  christos 		}
   1403  1.1  christos 		AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL);
   1404  1.1  christos 		objref = aname->property;
   1405  1.1  christos 		objref->objref.nameref = srcname;
   1406  1.1  christos 		objref->objref.ref = srcname->property;
   1407  1.1  christos 		objref->objref.offset = -1;
   1408  1.1  christos 		objref->objref.alias = 1;	/* Yes, this is an alias */
   1409  1.1  christos 		AML_DEBUGPRINT(")");
   1410  1.1  christos 		/* shut the interpreter up during the namespace initializing */
   1411  1.1  christos 		return (NULL);
   1412  1.1  christos 	case 0x08:		/* NameOp */
   1413  1.1  christos 		AML_DEBUGPRINT("Name(");
   1414  1.1  christos 		name = aml_parse_namestring(env);
   1415  1.1  christos 		aml_print_namestring(name);
   1416  1.1  christos 		AML_CREATE_NAME(aname, env, name, 0);
   1417  1.1  christos 		if (env->stat == aml_stat_panic) {
   1418  1.1  christos 			AML_DEBUGPRINT("Already Defined \n");
   1419  1.1  christos 			aml_print_curname(aname);
   1420  1.1  christos 			return (NULL);
   1421  1.1  christos 		}
   1422  1.1  christos 		AML_DEBUGPRINT(", ");
   1423  1.1  christos 		AML_COPY_OBJECT(aname->property, env,
   1424  1.1  christos 		    aml_eval_name(env,
   1425  1.1  christos 			aml_parse_termobj(env, indent)),
   1426  1.1  christos 		    NULL);
   1427  1.1  christos 		AML_DEBUGPRINT(")");
   1428  1.1  christos 		break;
   1429  1.1  christos 	case 0x10:		/* ScopeOp */
   1430  1.1  christos 		aml_parse_defscope(env, indent);
   1431  1.1  christos 		break;
   1432  1.1  christos 	case 0x11:		/* BufferOp */
   1433  1.1  christos 		aname = &env->tempname;
   1434  1.1  christos 		aname->property = aml_parse_defbuffer(env, indent);
   1435  1.1  christos 		break;
   1436  1.1  christos 	case 0x12:		/* PackageOp */
   1437  1.1  christos 		aname = &env->tempname;
   1438  1.1  christos 		aname->property = aml_parse_defpackage(env, indent);
   1439  1.1  christos 		break;
   1440  1.1  christos 	case 0x14:		/* MethodOp */
   1441  1.1  christos 		aml_parse_defmethod(env, indent);
   1442  1.1  christos 		break;
   1443  1.1  christos 	case 0x5b:		/* ExtOpPrefix */
   1444  1.1  christos 		opcode = *env->dp++;
   1445  1.1  christos 		switch (opcode) {
   1446  1.1  christos 		case 0x01:
   1447  1.1  christos 			aml_parse_defmutex(env, indent);
   1448  1.1  christos 			break;
   1449  1.1  christos 		case 0x02:	/* EventOp */
   1450  1.1  christos 			AML_DEBUGPRINT("Event(");
   1451  1.1  christos 			name = aml_parse_namestring(env);
   1452  1.1  christos 			aml_print_namestring(name);
   1453  1.1  christos 			AML_CREATE_NAME(aname, env, name, 0);
   1454  1.1  christos 			if (aname->property != NULL) {
   1455  1.1  christos 				env->stat = aml_stat_panic;
   1456  1.1  christos 				AML_DEBUGPRINT("Already Defined \n");
   1457  1.1  christos 				return (NULL);
   1458  1.1  christos 			}
   1459  1.1  christos 			AML_ALLOC_OBJECT(aname->property, env, aml_t_event, NULL);
   1460  1.1  christos 			AML_DEBUGPRINT(")");
   1461  1.1  christos 			return (NULL);
   1462  1.1  christos 			break;
   1463  1.1  christos 		case 0x12:	/* CondRefOfOp */
   1464  1.1  christos 			AML_DEBUGPRINT("CondRefOf(");
   1465  1.1  christos 			src = aml_parse_termobj(env, indent);
   1466  1.1  christos 			AML_DEBUGPRINT(", ");
   1467  1.1  christos 			if (src == &env->tempname || src == NULL) {
   1468  1.1  christos 				aml_parse_termobj(env, indent);
   1469  1.1  christos 				AML_DEBUGPRINT(")");
   1470  1.1  christos 				anum.num.number = 0xffffffff;
   1471  1.1  christos 				env->tempobject.num = anum.num;
   1472  1.1  christos 				aname = &env->tempname;
   1473  1.1  christos 				break;
   1474  1.1  christos 			}
   1475  1.1  christos 			AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL);
   1476  1.1  christos 			if (src->property == NULL ||
   1477  1.1  christos 			    src->property->type != aml_t_namestr) {
   1478  1.1  christos 				objref->objref.nameref = src;
   1479  1.1  christos 			} else {
   1480  1.1  christos 				objref->objref.nameref = aml_create_local_object();
   1481  1.1  christos 			}
   1482  1.1  christos 			objref->objref.ref = src->property;
   1483  1.1  christos 			objref->objref.offset = -1;	/* different from IndexOp */
   1484  1.1  christos 
   1485  1.1  christos 			destname1 = aml_parse_termobj(env, indent);
   1486  1.1  christos 			aml_store_to_name(env, objref, destname1);
   1487  1.1  christos 			anum.num.number = 0;
   1488  1.1  christos 			env->tempobject.num = anum.num;
   1489  1.1  christos 			aname = &env->tempname;
   1490  1.1  christos 			AML_DEBUGPRINT(")");
   1491  1.1  christos 			break;
   1492  1.1  christos 		case 0x13:
   1493  1.1  christos 			aml_parse_defcreatefield(env, indent);
   1494  1.1  christos 			break;
   1495  1.1  christos 		case 0x20:	/* LoadOp *//* XXX Not Impremented */
   1496  1.1  christos 			AML_DEBUGPRINT("Load(");
   1497  1.1  christos 			aml_parse_termobj(env, indent);
   1498  1.1  christos 			AML_DEBUGPRINT(", ");
   1499  1.1  christos 			aml_parse_termobj(env, indent);
   1500  1.1  christos 			AML_DEBUGPRINT(")");
   1501  1.1  christos 			break;
   1502  1.1  christos 		case 0x21:	/* StallOp */
   1503  1.1  christos 			AML_DEBUGPRINT("Stall(");
   1504  1.1  christos 			num1 = aml_objtonum(env, aml_eval_name(env,
   1505  1.1  christos 			    aml_parse_termobj(env, indent)));
   1506  1.1  christos 			AML_DEBUGPRINT(")");
   1507  1.1  christos 			AML_STALL(num1);
   1508  1.1  christos 			break;
   1509  1.1  christos 		case 0x22:	/* SleepOp */
   1510  1.1  christos 			AML_DEBUGPRINT("Sleep(");
   1511  1.1  christos 			num1 = aml_objtonum(env, aml_eval_name(env,
   1512  1.1  christos 			    aml_parse_termobj(env, indent)));
   1513  1.1  christos 			AML_SLEEP(0, num1);
   1514  1.1  christos 			AML_DEBUGPRINT(")");
   1515  1.1  christos 			break;
   1516  1.1  christos 		case 0x23:	/* AcquireOp *//* XXX Not yet */
   1517  1.1  christos 			AML_DEBUGPRINT("Acquire(");
   1518  1.1  christos 			aml_parse_termobj(env, indent);
   1519  1.1  christos 			AML_DEBUGPRINT(", 0x%x)", aml_parse_worddata(env));
   1520  1.1  christos 			break;
   1521  1.1  christos 		case 0x24:	/* SignalOp *//* XXX Not yet */
   1522  1.1  christos 			AML_DEBUGPRINT("Signal(");
   1523  1.1  christos 			aml_parse_termobj(env, indent);
   1524  1.1  christos 			AML_DEBUGPRINT(")");
   1525  1.1  christos 			break;
   1526  1.1  christos 		case 0x25:	/* WaitOp *//* XXX Not yet impremented */
   1527  1.1  christos 			AML_DEBUGPRINT("Wait(");
   1528  1.1  christos 			aml_parse_termobj(env, indent);
   1529  1.1  christos 			AML_DEBUGPRINT(", ");
   1530  1.1  christos 			aml_parse_termobj(env, indent);
   1531  1.1  christos 			AML_DEBUGPRINT(")");
   1532  1.1  christos 			break;
   1533  1.1  christos 		case 0x26:	/* ResetOp *//* XXX Not yet impremented */
   1534  1.1  christos 			AML_DEBUGPRINT("Reset(");
   1535  1.1  christos 			aml_parse_termobj(env, indent);
   1536  1.1  christos 			AML_DEBUGPRINT(")");
   1537  1.1  christos 			break;
   1538  1.1  christos 		case 0x27:	/* ReleaseOp *//* XXX Not yet impremented */
   1539  1.1  christos 			AML_DEBUGPRINT("Release(");
   1540  1.1  christos 			aml_parse_termobj(env, indent);
   1541  1.1  christos 			AML_DEBUGPRINT(")");
   1542  1.1  christos 			break;
   1543  1.1  christos #define NUMOP2(opname, operation) do {					\
   1544  1.1  christos 	AML_DEBUGPRINT(opname);						\
   1545  1.1  christos 	AML_DEBUGPRINT("(");						\
   1546  1.1  christos 	num1 = aml_objtonum(env, aml_eval_name(env,			\
   1547  1.1  christos 	    aml_parse_termobj(env, indent)));				\
   1548  1.1  christos 	AML_DEBUGPRINT(", ");						\
   1549  1.1  christos 	anum.num.number = operation (num1);				\
   1550  1.1  christos 	destname1 = aml_parse_termobj(env, indent);			\
   1551  1.1  christos 	AML_DEBUGPRINT(")");						\
   1552  1.1  christos 	aml_store_to_name(env, &anum, destname1);			\
   1553  1.1  christos 	env->tempobject.num = anum.num;					\
   1554  1.1  christos 	env->tempname.property = &env->tempobject;			\
   1555  1.1  christos 	aname = &env->tempname;						\
   1556  1.1  christos } while(0)
   1557  1.1  christos 
   1558  1.1  christos 		case 0x28:	/* FromBCDOp */
   1559  1.1  christos 			NUMOP2("FromBCD", frombcd);
   1560  1.1  christos 			break;
   1561  1.1  christos 		case 0x29:	/* ToBCDOp */
   1562  1.1  christos 			NUMOP2("ToBCD", tobcd);
   1563  1.1  christos 			break;
   1564  1.1  christos 		case 0x2a:	/* UnloadOp *//* XXX Not yet impremented */
   1565  1.1  christos 			AML_DEBUGPRINT("Unload(");
   1566  1.1  christos 			aml_parse_termobj(env, indent);
   1567  1.1  christos 			AML_DEBUGPRINT(")");
   1568  1.1  christos 			break;
   1569  1.1  christos 		case 0x30:
   1570  1.1  christos 			env->tempobject.type = aml_t_num;
   1571  1.1  christos 			env->tempobject.num.number = 0;
   1572  1.1  christos 			env->tempobject.num.constant = 1;
   1573  1.1  christos 			AML_DEBUGPRINT("Revision");
   1574  1.1  christos 			break;
   1575  1.1  christos 		case 0x31:
   1576  1.1  christos 			env->tempobject.type = aml_t_debug;
   1577  1.1  christos 			aname = &env->tempname;
   1578  1.1  christos 			AML_DEBUGPRINT("Debug");
   1579  1.1  christos 			break;
   1580  1.1  christos 		case 0x32:	/* FatalOp */
   1581  1.1  christos 			AML_DEBUGPRINT("Fatal(");
   1582  1.1  christos 			AML_DEBUGPRINT("0x%x, ", aml_parse_bytedata(env));
   1583  1.1  christos 			AML_DEBUGPRINT("0x%x, ", aml_parse_dworddata(env));
   1584  1.1  christos 			aml_parse_termobj(env, indent);
   1585  1.1  christos 			env->stat = aml_stat_panic;
   1586  1.1  christos 			AML_DEBUGPRINT(")");
   1587  1.1  christos 			break;
   1588  1.1  christos 		case 0x80:	/* OpRegionOp */
   1589  1.1  christos 			aml_parse_defopregion(env, indent);
   1590  1.1  christos 			break;
   1591  1.1  christos 		case 0x81:	/* FieldOp */
   1592  1.1  christos 			aml_parse_deffield(env, indent);
   1593  1.1  christos 			break;
   1594  1.1  christos 		case 0x82:	/* DeviceOp */
   1595  1.1  christos 			aml_parse_defdevice(env, indent);
   1596  1.1  christos 			break;
   1597  1.1  christos 		case 0x83:	/* ProcessorOp */
   1598  1.1  christos 			aml_parse_defprocessor(env, indent);
   1599  1.1  christos 			break;
   1600  1.1  christos 		case 0x84:	/* PowerResOp */
   1601  1.1  christos 			aml_parse_defpowerres(env, indent);
   1602  1.1  christos 			break;
   1603  1.1  christos 		case 0x85:	/* ThermalZoneOp */
   1604  1.1  christos 			aml_parse_defthermalzone(env, indent);
   1605  1.1  christos 			break;
   1606  1.1  christos 		case 0x86:	/* IndexFieldOp */
   1607  1.1  christos 			aml_parse_defindexfield(env, indent);
   1608  1.1  christos 			break;
   1609  1.1  christos 		case 0x87:	/* BankFieldOp */
   1610  1.1  christos 			aml_parse_defbankfield(env, indent);
   1611  1.1  christos 			break;
   1612  1.1  christos 		default:
   1613  1.1  christos 			AML_SYSERRX(1, "strange opcode 0x5b, 0x%x\n", opcode);
   1614  1.1  christos 			AML_SYSABORT();
   1615  1.1  christos 		}
   1616  1.1  christos 		break;
   1617  1.1  christos 	case 0x68 ... 0x6e:	/* ArgN */
   1618  1.1  christos 		AML_DEBUGPRINT("Arg%d", opcode - 0x68);
   1619  1.1  christos 		return (aml_local_stack_getArgX(NULL, opcode - 0x68));
   1620  1.1  christos 		break;
   1621  1.1  christos 	case 0x60 ... 0x67:
   1622  1.1  christos 		AML_DEBUGPRINT("Local%d", opcode - 0x60);
   1623  1.1  christos 		return (aml_local_stack_getLocalX(opcode - 0x60));
   1624  1.1  christos 		break;
   1625  1.1  christos 	case 0x70:		/* StoreOp */
   1626  1.1  christos 		AML_DEBUGPRINT("Store(");
   1627  1.1  christos 		aname = aml_create_local_object();
   1628  1.1  christos 		AML_COPY_OBJECT(tmpobj, env,
   1629  1.1  christos 		    aml_eval_name(env,	aml_parse_termobj(env, indent)), NULL);
   1630  1.1  christos 		aname->property = tmpobj;
   1631  1.1  christos 		AML_DEBUGPRINT(", ");
   1632  1.1  christos 		destname1 = aml_parse_termobj(env, indent);
   1633  1.1  christos 		AML_DEBUGPRINT(")");
   1634  1.1  christos 		/* XXX
   1635  1.1  christos 		 * temporary object may change during aml_store_to_name()
   1636  1.1  christos 		 * operation, so we make a copy of it on stack.
   1637  1.1  christos 		 */
   1638  1.1  christos 		if (destname1 == &env->tempname &&
   1639  1.1  christos 		    destname1->property == &env->tempobject) {
   1640  1.1  christos 			destname1 = aml_create_local_object();
   1641  1.1  christos 			AML_COPY_OBJECT(destname1->property, env,
   1642  1.1  christos 			    &env->tempobject, NULL);
   1643  1.1  christos 		}
   1644  1.1  christos 		aml_store_to_name(env, tmpobj, destname1);
   1645  1.1  christos 		if (env->stat == aml_stat_panic) {
   1646  1.1  christos 			AML_DEBUGPRINT("StoreOp failed");
   1647  1.1  christos 			return (NULL);
   1648  1.1  christos 		}
   1649  1.1  christos 		aname = aml_create_local_object();
   1650  1.1  christos 		AML_COPY_OBJECT(tmpobj, env, destname1->property, NULL);
   1651  1.1  christos 		aname->property = tmpobj;
   1652  1.1  christos 		if (tmpobj == NULL) {
   1653  1.1  christos 			printf("???");
   1654  1.1  christos 			break;
   1655  1.1  christos 		}
   1656  1.1  christos 		break;
   1657  1.1  christos 	case 0x71:		/* RefOfOp */
   1658  1.1  christos 		AML_DEBUGPRINT("RefOf(");
   1659  1.1  christos 		src = aml_parse_termobj(env, indent);
   1660  1.1  christos 		AML_DEBUGPRINT(")");
   1661  1.1  christos 
   1662  1.1  christos 		aname = aml_create_local_object();
   1663  1.1  christos 		AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL);
   1664  1.1  christos 		objref = aname->property;
   1665  1.1  christos 		if (src->property == NULL ||
   1666  1.1  christos 		    src->property->type != aml_t_namestr) {
   1667  1.1  christos 			objref->objref.nameref = src;
   1668  1.1  christos 		} else {
   1669  1.1  christos 			objref->objref.nameref = aml_create_local_object();
   1670  1.1  christos 		}
   1671  1.1  christos 		objref->objref.ref = src->property;
   1672  1.1  christos 		objref->objref.offset = -1;	/* different from IndexOp */
   1673  1.1  christos 		break;
   1674  1.1  christos 
   1675  1.1  christos #define NUMOP3_2(opname, oparation, ope2) do {				\
   1676  1.1  christos 	AML_DEBUGPRINT(opname);						\
   1677  1.1  christos 	AML_DEBUGPRINT("(");						\
   1678  1.1  christos 	num1 = aml_objtonum(env, aml_eval_name(env,			\
   1679  1.1  christos 	    aml_parse_termobj(env, indent)));				\
   1680  1.1  christos 	AML_DEBUGPRINT(", ");						\
   1681  1.1  christos 	num2 = aml_objtonum(env, aml_eval_name(env,			\
   1682  1.1  christos 	    aml_parse_termobj(env, indent)));				\
   1683  1.1  christos 	AML_DEBUGPRINT(", ");						\
   1684  1.1  christos 	anum.num.number = ope2(num1 oparation num2);			\
   1685  1.1  christos 	destname1 = aml_parse_termobj(env, indent);			\
   1686  1.1  christos 	AML_DEBUGPRINT(")");						\
   1687  1.1  christos 	aml_store_to_name(env, &anum, destname1);			\
   1688  1.1  christos 	env->tempobject.num = anum.num;					\
   1689  1.1  christos 	env->tempname.property = &env->tempobject;			\
   1690  1.1  christos 	aname = &env->tempname;						\
   1691  1.1  christos } while(0)
   1692  1.1  christos 
   1693  1.1  christos #define NUMOP3(opname, operation)	NUMOP3_2(opname, operation, )
   1694  1.1  christos #define NUMOPN3(opname, operation)	NUMOP3_2(opname, operation, ~)
   1695  1.1  christos 
   1696  1.1  christos 	case 0x72:		/* AddOp */
   1697  1.1  christos 		NUMOP3("Add", +);
   1698  1.1  christos 		break;
   1699  1.1  christos 	case 0x73:		/* ConcatOp  */
   1700  1.1  christos 		aname = aml_parse_concatop(env, indent);
   1701  1.1  christos 		break;
   1702  1.1  christos 	case 0x74:		/* SubtractOp */
   1703  1.1  christos 		NUMOP3("Subtract", -);
   1704  1.1  christos 		break;
   1705  1.1  christos 	case 0x75:		/* IncrementOp */
   1706  1.1  christos 		AML_DEBUGPRINT("Increment(");
   1707  1.1  christos 		aname = aml_parse_termobj(env, indent);
   1708  1.1  christos 		num1 = aml_objtonum(env, aml_eval_name(env, aname));
   1709  1.1  christos 		num1++;
   1710  1.1  christos 		anum.num.number = num1;
   1711  1.1  christos 		AML_DEBUGPRINT(")");
   1712  1.1  christos 		aml_store_to_name(env, &anum, aname);
   1713  1.1  christos 		aname = &env->tempname;
   1714  1.1  christos 		env->tempobject.num = anum.num;
   1715  1.1  christos 		break;
   1716  1.1  christos 	case 0x76:		/* DecrementOp */
   1717  1.1  christos 		AML_DEBUGPRINT("Decrement(");
   1718  1.1  christos 		aname = aml_parse_termobj(env, indent);
   1719  1.1  christos 		num1 = aml_objtonum(env, aml_eval_name(env, aname));
   1720  1.1  christos 		num1--;
   1721  1.1  christos 		anum.num.number = num1;
   1722  1.1  christos 		AML_DEBUGPRINT(")");
   1723  1.1  christos 		aml_store_to_name(env, &anum, aname);
   1724  1.1  christos 		aname = &env->tempname;
   1725  1.1  christos 		env->tempobject.num = anum.num;
   1726  1.1  christos 		break;
   1727  1.1  christos 	case 0x77:		/* MultiplyOp */
   1728  1.1  christos 		NUMOP3("Multiply", *);
   1729  1.1  christos 		break;
   1730  1.1  christos 	case 0x78:		/* DivideOp */
   1731  1.1  christos 		AML_DEBUGPRINT("Divide(");
   1732  1.1  christos 		num1 = aml_objtonum(env, aml_eval_name(env,
   1733  1.1  christos 		    aml_parse_termobj(env, indent)));
   1734  1.1  christos 		AML_DEBUGPRINT(", ");
   1735  1.1  christos 		num2 = aml_objtonum(env, aml_eval_name(env,
   1736  1.1  christos 		    aml_parse_termobj(env, indent)));
   1737  1.1  christos 		AML_DEBUGPRINT(", ");
   1738  1.1  christos 		anum.num.number = num1 % num2;
   1739  1.1  christos 		destname1 = aml_parse_termobj(env, indent);
   1740  1.1  christos 		aml_store_to_name(env, &anum, destname1);
   1741  1.1  christos 		AML_DEBUGPRINT(", ");
   1742  1.1  christos 		anum.num.number = num1 / num2;
   1743  1.1  christos 		destname2 = aml_parse_termobj(env, indent);
   1744  1.1  christos 		AML_DEBUGPRINT(")");
   1745  1.1  christos 		aml_store_to_name(env, &anum, destname2);
   1746  1.1  christos 		env->tempobject.num = anum.num;
   1747  1.1  christos 		aname = &env->tempname;
   1748  1.1  christos 		break;
   1749  1.1  christos 	case 0x79:		/* ShiftLeftOp */
   1750  1.1  christos 		NUMOP3("ShiftLeft", <<);
   1751  1.1  christos 		break;
   1752  1.1  christos 	case 0x7a:		/* ShiftRightOp */
   1753  1.1  christos 		NUMOP3("ShiftRight", >>);
   1754  1.1  christos 		break;
   1755  1.1  christos 	case 0x7b:		/* AndOp */
   1756  1.1  christos 		NUMOP3("And", &);
   1757  1.1  christos 		break;
   1758  1.1  christos 	case 0x7c:		/* NAndOp */
   1759  1.1  christos 		NUMOPN3("NAnd", &);
   1760  1.1  christos 		break;
   1761  1.1  christos 	case 0x7d:		/* OrOp */
   1762  1.1  christos 		NUMOP3("Or", |);
   1763  1.1  christos 		break;
   1764  1.1  christos 	case 0x7e:		/* NOrOp */
   1765  1.1  christos 		NUMOPN3("NOr", |);
   1766  1.1  christos 		break;
   1767  1.1  christos 	case 0x7f:		/* XOrOp */
   1768  1.1  christos 		NUMOP3("XOr", ^);
   1769  1.1  christos 		break;
   1770  1.1  christos 	case 0x80:		/* NotOp */
   1771  1.1  christos 		NUMOP2("Not", ~);
   1772  1.1  christos 		break;
   1773  1.1  christos 	case 0x81:		/* FindSetLeftBitOp */
   1774  1.1  christos 		NUMOP2("FindSetLeftBit", findsetleftbit);
   1775  1.1  christos 		break;
   1776  1.1  christos 	case 0x82:		/* FindSetRightBitOp */
   1777  1.1  christos 		NUMOP2("FindSetRightBit", findsetrightbit);
   1778  1.1  christos 		break;
   1779  1.1  christos 	case 0x83:		/* DerefOp */
   1780  1.1  christos 		AML_DEBUGPRINT("DerefOf(");
   1781  1.1  christos 		objref = aml_eval_name(env, aml_parse_termobj(env, indent));
   1782  1.1  christos 		AML_DEBUGPRINT(")");
   1783  1.1  christos 
   1784  1.1  christos 		if (objref->objref.ref == NULL) {
   1785  1.1  christos 			env->tempname.property = objref->objref.ref;
   1786  1.1  christos 			aname = &env->tempname;
   1787  1.1  christos 			break;
   1788  1.1  christos 		}
   1789  1.1  christos 		switch (objref->objref.ref->type) {
   1790  1.1  christos 		case aml_t_package:
   1791  1.1  christos 		case aml_t_buffer:
   1792  1.1  christos 			if (objref->objref.offset < 0) {
   1793  1.1  christos 				env->tempname.property = objref->objref.ref;
   1794  1.1  christos 			} else {
   1795  1.1  christos 				objref->objref.deref = 1;
   1796  1.1  christos 				env->tempname.property = objref;
   1797  1.1  christos 			}
   1798  1.1  christos 			break;
   1799  1.1  christos 		default:
   1800  1.1  christos 			env->tempname.property = objref->objref.ref;
   1801  1.1  christos 			break;
   1802  1.1  christos 		}
   1803  1.1  christos 
   1804  1.1  christos 		aname = &env->tempname;
   1805  1.1  christos 		break;
   1806  1.1  christos 	case 0x86:		/* NotifyOp *//* XXX Not yet impremented */
   1807  1.1  christos 		AML_DEBUGPRINT("Notify(");
   1808  1.1  christos 		aml_parse_termobj(env, indent);
   1809  1.1  christos 		AML_DEBUGPRINT(", ");
   1810  1.1  christos 		aml_parse_termobj(env, indent);
   1811  1.1  christos 		AML_DEBUGPRINT(")");
   1812  1.1  christos 		break;
   1813  1.1  christos 	case 0x87:		/* SizeOfOp */
   1814  1.1  christos 		AML_DEBUGPRINT("SizeOf(");
   1815  1.1  christos 		aname = aml_parse_termobj(env, indent);
   1816  1.1  christos 		tmpobj = aml_eval_name(env, aname);
   1817  1.1  christos 
   1818  1.1  christos 		AML_DEBUGPRINT(")");
   1819  1.1  christos 		num1 = 0;
   1820  1.1  christos 		switch (tmpobj->type) {
   1821  1.1  christos 		case aml_t_buffer:
   1822  1.1  christos 			num1 = tmpobj->buffer.size;
   1823  1.1  christos 			break;
   1824  1.1  christos 		case aml_t_string:
   1825  1.1  christos 			num1 = strlen((const char *)tmpobj->str.string);
   1826  1.1  christos 			break;
   1827  1.1  christos 		case aml_t_package:
   1828  1.1  christos 			num1 = tmpobj->package.elements;
   1829  1.1  christos 			break;
   1830  1.1  christos 		default:
   1831  1.1  christos 			AML_DEBUGPRINT("Args of SizeOf should be "
   1832  1.1  christos 				       "buffer/string/package only\n");
   1833  1.1  christos 			break;
   1834  1.1  christos 		}
   1835  1.1  christos 
   1836  1.1  christos 		anum.num.number = num1;
   1837  1.1  christos 		env->tempobject.num = anum.num;
   1838  1.1  christos 		aname = &env->tempname;
   1839  1.1  christos 		break;
   1840  1.1  christos 	case 0x88:		/* IndexOp */
   1841  1.1  christos 		AML_DEBUGPRINT("Index(");
   1842  1.1  christos 		srcobj = aml_eval_name(env, aml_parse_termobj(env, indent));
   1843  1.1  christos 		AML_DEBUGPRINT(", ");
   1844  1.1  christos 		num1 = aml_objtonum(env, aml_eval_name(env,
   1845  1.1  christos 		    aml_parse_termobj(env, indent)));
   1846  1.1  christos 		AML_DEBUGPRINT(", ");
   1847  1.1  christos 		destname1 = aml_parse_termobj(env, indent);
   1848  1.1  christos 		AML_DEBUGPRINT(")");
   1849  1.1  christos 		aname = aml_create_local_object();
   1850  1.1  christos 		switch (srcobj->type) {
   1851  1.1  christos 		case aml_t_package:
   1852  1.1  christos 		case aml_t_buffer:
   1853  1.1  christos 			AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL);
   1854  1.1  christos 			aname->property = objref;
   1855  1.1  christos 			objref->objref.ref = srcobj;
   1856  1.1  christos 			objref->objref.offset = num1;
   1857  1.1  christos 			objref->objref.deref = 0;
   1858  1.1  christos 			break;
   1859  1.1  christos 		default:
   1860  1.1  christos 			AML_DEBUGPRINT("Arg0 of Index should be either "
   1861  1.1  christos 				       "buffer or package\n");
   1862  1.1  christos 			return (aname);
   1863  1.1  christos 		}
   1864  1.1  christos 
   1865  1.1  christos 		aml_store_to_name(env, objref, destname1);
   1866  1.1  christos 		break;
   1867  1.1  christos 	case 0x89:		/* MatchOp *//* XXX Not yet Impremented */
   1868  1.1  christos 		AML_DEBUGPRINT("Match(");
   1869  1.1  christos 		AML_COPY_OBJECT(obj, env, aml_eval_name(env,
   1870  1.1  christos 		    aml_parse_termobj(env, indent)), NULL);
   1871  1.1  christos 		if (obj->type != aml_t_package) {
   1872  1.1  christos 			env->stat = aml_stat_panic;
   1873  1.1  christos 			return (NULL);
   1874  1.1  christos 		}
   1875  1.1  christos 		anum.num.number = 0xffffffff;
   1876  1.1  christos 		match1 = *env->dp;
   1877  1.1  christos 		AML_DEBUGPRINT(", %d", *env->dp);
   1878  1.1  christos 		env->dp++;
   1879  1.1  christos 		num1 = aml_objtonum(env, aml_eval_name(env,
   1880  1.1  christos 		    aml_parse_termobj(env, indent)));
   1881  1.1  christos 		match2 = *env->dp;
   1882  1.1  christos 		AML_DEBUGPRINT(", %d", *env->dp);
   1883  1.1  christos 		env->dp++;
   1884  1.1  christos 		num2 = aml_objtonum(env, aml_eval_name(env,
   1885  1.1  christos 		    aml_parse_termobj(env, indent)));
   1886  1.1  christos 		AML_DEBUGPRINT(", ");
   1887  1.1  christos 		start = aml_objtonum(env, aml_eval_name(env,
   1888  1.1  christos 		    aml_parse_termobj(env, indent)));
   1889  1.1  christos 
   1890  1.1  christos #define MATCHOP(opnum, arg1, arg2)	((opnum == 0) ? (1) :		\
   1891  1.1  christos     (opnum == 1) ? ((arg1) == (arg2))	:				\
   1892  1.1  christos     (opnum == 2) ? ((arg1) <= (arg2))	:				\
   1893  1.1  christos     (opnum == 3) ? ((arg1) <  (arg2))	:				\
   1894  1.1  christos     (opnum == 4) ? ((arg1) >= (arg2))	:				\
   1895  1.1  christos     (opnum == 5) ? ((arg1) >  (arg2))	: 0 )
   1896  1.1  christos 
   1897  1.1  christos 		for (i = start; i < obj->package.elements; i++) {
   1898  1.1  christos 			pkgval = aml_objtonum(env, obj->package.objects[i]);
   1899  1.1  christos 			if (MATCHOP(match1, pkgval, num1) &&
   1900  1.1  christos 			    MATCHOP(match2, pkgval, num2)) {
   1901  1.1  christos 				anum.num.number = i;
   1902  1.1  christos 				break;
   1903  1.1  christos 			}
   1904  1.1  christos 		}
   1905  1.1  christos 		AML_DEBUGPRINT(")");
   1906  1.1  christos 		aml_free_object(&obj);
   1907  1.1  christos 		aname = &env->tempname;
   1908  1.1  christos 		env->tempname.property = &env->tempobject;
   1909  1.1  christos 		env->tempobject.num = anum.num;
   1910  1.1  christos 		break;
   1911  1.1  christos #undef MATCHOP
   1912  1.1  christos 	case 0x8a ... 0x8d:	/* CreateDWordFieldOp */
   1913  1.1  christos 		widthindex = *(env->dp - 1) - 0x8a;
   1914  1.1  christos 		AML_DEBUGPRINT("%s(", opname[widthindex]);
   1915  1.1  christos 		srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent));
   1916  1.1  christos 		if (srcbuf == &env->tempobject) {
   1917  1.1  christos 			AML_DEBUGPRINT("NOT NAMEDBUF\n");
   1918  1.1  christos 			env->stat = aml_stat_panic;
   1919  1.1  christos 			return (NULL);
   1920  1.1  christos 		}
   1921  1.1  christos 		AML_DEBUGPRINT(", ");
   1922  1.1  christos 		idx = aml_objtonum(env, aml_eval_name(env,
   1923  1.1  christos 		    aml_parse_termobj(env, indent)));
   1924  1.1  christos 		if (widthindex != 3) {
   1925  1.1  christos 			idx *= 8;
   1926  1.1  christos 		}
   1927  1.1  christos 		AML_DEBUGPRINT(", ");
   1928  1.1  christos 		newname = (char *)aml_parse_namestring(env);
   1929  1.1  christos 		aml_print_namestring((unsigned char *)newname);
   1930  1.1  christos 		aml_createfield_generic(env, srcbuf, idx,
   1931  1.1  christos 		    widthtbl[widthindex], newname);
   1932  1.1  christos 		AML_DEBUGPRINT(")");
   1933  1.1  christos 		break;
   1934  1.1  christos 	case 0x8e:		/* ObjectTypeOp */
   1935  1.1  christos 		AML_DEBUGPRINT("ObjectType(");
   1936  1.1  christos 		aname = aml_parse_termobj(env, indent);
   1937  1.1  christos 		if (aname == NULL) {
   1938  1.1  christos 			env->tempobject.type = aml_t_num;
   1939  1.1  christos 			env->tempobject.num.number = aml_t_null;
   1940  1.1  christos 		} else {
   1941  1.1  christos 			env->tempobject.type = aml_t_num;
   1942  1.1  christos 			env->tempobject.num.number = aname->property->type;
   1943  1.1  christos 		}
   1944  1.1  christos 		aname = &env->tempname;
   1945  1.1  christos 		AML_DEBUGPRINT(")");
   1946  1.1  christos 		break;
   1947  1.1  christos 
   1948  1.1  christos #define CMPOP(opname,operation) do {					\
   1949  1.1  christos 	AML_DEBUGPRINT(opname);						\
   1950  1.1  christos 	AML_DEBUGPRINT("(");						\
   1951  1.1  christos 	num1 = aml_objtonum(env, aml_eval_name(env,			\
   1952  1.1  christos 	    aml_parse_termobj(env, indent)));				\
   1953  1.1  christos 	AML_DEBUGPRINT(", ");						\
   1954  1.1  christos 	num2 = aml_objtonum(env, aml_eval_name(env,			\
   1955  1.1  christos 	    aml_parse_termobj(env, indent)));				\
   1956  1.1  christos 	aname = &env->tempname;						\
   1957  1.1  christos 	env->tempobject.type = aml_t_num;				\
   1958  1.1  christos 	env->tempobject.num.number = (num1 operation num2) ? 0xffffffff : 0;	\
   1959  1.1  christos 	aname->property = &env->tempobject;				\
   1960  1.1  christos 	AML_DEBUGPRINT(")");						\
   1961  1.1  christos } while(0)
   1962  1.1  christos 
   1963  1.1  christos 	case 0x90:
   1964  1.1  christos 		CMPOP("LAnd", &&);
   1965  1.1  christos 		break;
   1966  1.1  christos 	case 0x91:
   1967  1.1  christos 		CMPOP("LOr", ||);
   1968  1.1  christos 		break;
   1969  1.1  christos 	case 0x92:
   1970  1.1  christos 		AML_DEBUGPRINT("LNot(");
   1971  1.1  christos 		num1 = aml_objtonum(env, aml_eval_name(env,
   1972  1.1  christos 		    aml_parse_termobj(env, indent)));
   1973  1.1  christos 		aname = &env->tempname;
   1974  1.1  christos 		env->tempobject.type = aml_t_num;
   1975  1.1  christos 		env->tempobject.num.number = (!num1) ? 0xffffffff : 0;
   1976  1.1  christos 		aname->property = &env->tempobject;
   1977  1.1  christos 		AML_DEBUGPRINT(")");
   1978  1.1  christos 		break;
   1979  1.1  christos 	case 0x93:
   1980  1.1  christos 		CMPOP("LEqual", ==);
   1981  1.1  christos 		break;
   1982  1.1  christos 	case 0x94:
   1983  1.1  christos 		CMPOP("LGreater", >);
   1984  1.1  christos 		break;
   1985  1.1  christos 	case 0x95:
   1986  1.1  christos 		CMPOP("LLess", <);
   1987  1.1  christos 		break;
   1988  1.1  christos 	case 0xa0:		/* IfOp */
   1989  1.1  christos 		aname = aml_parse_defif(env, indent);
   1990  1.1  christos 		break;
   1991  1.1  christos #if 0
   1992  1.1  christos 
   1993  1.1  christos 	case 0xa1:		/* ElseOp should not be treated in Main parser
   1994  1.1  christos 				 * But If Op */
   1995  1.1  christos 		aml_parse_defelse(env, indent);
   1996  1.1  christos 		break;
   1997  1.1  christos #endif
   1998  1.1  christos 	case 0xa2:		/* WhileOp */
   1999  1.1  christos 		aname = aml_parse_defwhile(env, indent);
   2000  1.1  christos 		break;
   2001  1.1  christos 	case 0xa3:		/* NoopOp */
   2002  1.1  christos 		AML_DEBUGPRINT("Noop");
   2003  1.1  christos 		break;
   2004  1.1  christos 	case 0xa5:		/* BreakOp */
   2005  1.1  christos 		AML_DEBUGPRINT("Break");
   2006  1.1  christos 		env->stat = aml_stat_break;
   2007  1.1  christos 		break;
   2008  1.1  christos 	case 0xa4:		/* ReturnOp */
   2009  1.1  christos 		AML_DEBUGPRINT("Return(");
   2010  1.1  christos 		AML_COPY_OBJECT(env->tempname.property, env, aml_eval_name(env,
   2011  1.1  christos 		    aml_parse_termobj(env, indent)), NULL);
   2012  1.1  christos 		aname = &env->tempname;
   2013  1.1  christos 		env->stat = aml_stat_return;
   2014  1.1  christos 		AML_DEBUGPRINT(")");
   2015  1.1  christos 		break;
   2016  1.1  christos 	case 0xcc:		/* BreakPointOp */
   2017  1.1  christos 		/* XXX Not Yet Impremented (Not need?) */
   2018  1.1  christos 		AML_DEBUGPRINT("BreakPoint");
   2019  1.1  christos 		break;
   2020  1.1  christos 	default:
   2021  1.1  christos 		AML_SYSERRX(1, "strange opcode 0x%x\n", opcode);
   2022  1.1  christos 		AML_SYSABORT();
   2023  1.1  christos 	}
   2024  1.1  christos 
   2025  1.1  christos 	return (aname);
   2026  1.1  christos }
   2027