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