Bug Summary

File:dev/acpi/dsdt.c
Warning:line 4289, column 7
Access to field 'type' results in a dereference of a null pointer (loaded from variable 'rv')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dsdt.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/acpi/dsdt.c
1/* $OpenBSD: dsdt.c,v 1.265 2024/01/08 19:52:29 kettenis Exp $ */
2/*
3 * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/param.h>
19#include <sys/systm.h>
20#include <sys/kernel.h>
21#include <sys/device.h>
22#include <sys/malloc.h>
23#include <sys/time.h>
24
25#include <machine/bus.h>
26
27#ifdef DDB1
28#include <machine/db_machdep.h>
29#endif
30
31#include <dev/acpi/acpireg.h>
32#include <dev/acpi/acpivar.h>
33#include <dev/acpi/amltypes.h>
34#include <dev/acpi/dsdt.h>
35
36#include <dev/i2c/i2cvar.h>
37
38#ifdef SMALL_KERNEL
39#undef ACPI_DEBUG
40#endif
41
42#define opsize(opcode)(((opcode) & 0xFF00) ? 2 : 1) (((opcode) & 0xFF00) ? 2 : 1)
43
44#define AML_FIELD_RESERVED0x00 0x00
45#define AML_FIELD_ATTRIB0x01 0x01
46
47#define AML_REVISION0x01 0x01
48#define AML_INTSTRLEN16 16
49#define AML_NAMESEG_LEN4 4
50
51struct aml_value *aml_loadtable(struct acpi_softc *, const char *,
52 const char *, const char *, const char *,
53 const char *, struct aml_value *);
54struct aml_scope *aml_load(struct acpi_softc *, struct aml_scope *,
55 struct aml_value *, struct aml_value *);
56
57void aml_copyvalue(struct aml_value *, struct aml_value *);
58
59void aml_setvalue(struct aml_scope *, struct aml_value *,
60 struct aml_value *, int64_t);
61void aml_freevalue(struct aml_value *);
62struct aml_value *aml_allocvalue(int, int64_t, const void *);
63struct aml_value *_aml_setvalue(struct aml_value *, int, int64_t,
64 const void *);
65
66uint64_t aml_convradix(uint64_t, int, int);
67uint64_t aml_evalexpr(uint64_t, uint64_t, int);
68int aml_lsb(uint64_t);
69int aml_msb(uint64_t);
70
71int aml_tstbit(const uint8_t *, int);
72void aml_setbit(uint8_t *, int, int);
73
74void aml_addref(struct aml_value *, const char *);
75void aml_delref(struct aml_value **, const char *);
76
77void aml_bufcpy(void *, int, const void *, int, int);
78
79int aml_pc(uint8_t *);
80
81struct aml_value *aml_parseop(struct aml_scope *, struct aml_value *,int);
82struct aml_value *aml_parsetarget(struct aml_scope *, struct aml_value *,
83 struct aml_value **);
84struct aml_value *aml_parseterm(struct aml_scope *, struct aml_value *);
85
86struct aml_value *aml_evaltarget(struct aml_scope *scope,
87 struct aml_value *res);
88int aml_evalterm(struct aml_scope *scope,
89 struct aml_value *raw, struct aml_value *dst);
90
91struct aml_opcode *aml_findopcode(int);
92
93#define acpi_os_malloc(sz)_acpi_os_malloc(sz, __FUNCTION__, 93) _acpi_os_malloc(sz, __FUNCTION__, __LINE__93)
94#define acpi_os_free(ptr)_acpi_os_free(ptr, __FUNCTION__, 94) _acpi_os_free(ptr, __FUNCTION__, __LINE__94)
95
96void *_acpi_os_malloc(size_t, const char *, int);
97void _acpi_os_free(void *, const char *, int);
98void acpi_stall(int);
99
100struct aml_value *aml_callosi(struct aml_scope *, struct aml_value *);
101
102const char *aml_getname(const char *);
103int64_t aml_hextoint(const char *);
104void aml_dump(int, uint8_t *);
105__dead__attribute__((__noreturn__)) void _aml_die(const char *fn, int line, const char *fmt, ...);
106#define aml_die(x...)_aml_die(__FUNCTION__, 106, x...) _aml_die(__FUNCTION__, __LINE__106, x)
107
108void aml_notify_task(void *, int);
109void acpi_poll_notify_task(void *, int);
110
111/*
112 * @@@: Global variables
113 */
114int aml_intlen = 64;
115struct aml_node aml_root;
116struct aml_value *aml_global_lock;
117
118/* Perfect Hash key */
119#define HASH_OFF6904 6904
120#define HASH_SIZE179 179
121#define HASH_KEY(k)(((k) ^ 6904) % 179) (((k) ^ HASH_OFF6904) % HASH_SIZE179)
122
123/*
124 * XXX this array should be sorted, and then aml_findopcode() should
125 * do a binary search
126 */
127struct aml_opcode **aml_ophash;
128struct aml_opcode aml_table[] = {
129 /* Simple types */
130 { AMLOP_ZERO0x00, "Zero", "c", },
131 { AMLOP_ONE0x01, "One", "c", },
132 { AMLOP_ONES0xFF, "Ones", "c", },
133 { AMLOP_REVISION0x5B30, "Revision", "R", },
134 { AMLOP_BYTEPREFIX0x0A, ".Byte", "b", },
135 { AMLOP_WORDPREFIX0x0B, ".Word", "w", },
136 { AMLOP_DWORDPREFIX0x0C, ".DWord", "d", },
137 { AMLOP_QWORDPREFIX0x0E, ".QWord", "q", },
138 { AMLOP_STRINGPREFIX0x0D, ".String", "a", },
139 { AMLOP_DEBUG0x5B31, "DebugOp", "D", },
140 { AMLOP_BUFFER0x11, "Buffer", "piB", },
141 { AMLOP_PACKAGE0x12, "Package", "pbT", },
142 { AMLOP_VARPACKAGE0x13, "VarPackage", "piT", },
143
144 /* Simple objects */
145 { AMLOP_LOCAL00x60, "Local0", "L", },
146 { AMLOP_LOCAL10x61, "Local1", "L", },
147 { AMLOP_LOCAL20x62, "Local2", "L", },
148 { AMLOP_LOCAL30x63, "Local3", "L", },
149 { AMLOP_LOCAL40x64, "Local4", "L", },
150 { AMLOP_LOCAL50x65, "Local5", "L", },
151 { AMLOP_LOCAL60x66, "Local6", "L", },
152 { AMLOP_LOCAL70x67, "Local7", "L", },
153 { AMLOP_ARG00x68, "Arg0", "A", },
154 { AMLOP_ARG10x69, "Arg1", "A", },
155 { AMLOP_ARG20x6A, "Arg2", "A", },
156 { AMLOP_ARG30x6B, "Arg3", "A", },
157 { AMLOP_ARG40x6C, "Arg4", "A", },
158 { AMLOP_ARG50x6D, "Arg5", "A", },
159 { AMLOP_ARG60x6E, "Arg6", "A", },
160
161 /* Control flow */
162 { AMLOP_IF0xA0, "If", "piI", },
163 { AMLOP_ELSE0xA1, "Else", "pT" },
164 { AMLOP_WHILE0xA2, "While", "piT", },
165 { AMLOP_BREAK0xA5, "Break", "" },
166 { AMLOP_CONTINUE0x9F, "Continue", "" },
167 { AMLOP_RETURN0xA4, "Return", "t", },
168 { AMLOP_FATAL0x5B32, "Fatal", "bdi", },
169 { AMLOP_NOP0xA3, "Nop", "", },
170 { AMLOP_BREAKPOINT0xCC, "BreakPoint", "", },
171
172 /* Arithmetic operations */
173 { AMLOP_INCREMENT0x75, "Increment", "S", },
174 { AMLOP_DECREMENT0x76, "Decrement", "S", },
175 { AMLOP_ADD0x72, "Add", "iir", },
176 { AMLOP_SUBTRACT0x74, "Subtract", "iir", },
177 { AMLOP_MULTIPLY0x77, "Multiply", "iir", },
178 { AMLOP_DIVIDE0x78, "Divide", "iirr", },
179 { AMLOP_SHL0x79, "ShiftLeft", "iir", },
180 { AMLOP_SHR0x7A, "ShiftRight", "iir", },
181 { AMLOP_AND0x7B, "And", "iir", },
182 { AMLOP_NAND0x7C, "Nand", "iir", },
183 { AMLOP_OR0x7D, "Or", "iir", },
184 { AMLOP_NOR0x7E, "Nor", "iir", },
185 { AMLOP_XOR0x7F, "Xor", "iir", },
186 { AMLOP_NOT0x80, "Not", "ir", },
187 { AMLOP_MOD0x85, "Mod", "iir", },
188 { AMLOP_FINDSETLEFTBIT0x81, "FindSetLeftBit", "ir", },
189 { AMLOP_FINDSETRIGHTBIT0x82,"FindSetRightBit", "ir",},
190
191 /* Logical test operations */
192 { AMLOP_LAND0x90, "LAnd", "ii", },
193 { AMLOP_LOR0x91, "LOr", "ii", },
194 { AMLOP_LNOT0x92, "LNot", "i", },
195 { AMLOP_LNOTEQUAL0x9293, "LNotEqual", "tt", },
196 { AMLOP_LLESSEQUAL0x9294, "LLessEqual", "tt", },
197 { AMLOP_LGREATEREQUAL0x9295, "LGreaterEqual", "tt", },
198 { AMLOP_LEQUAL0x93, "LEqual", "tt", },
199 { AMLOP_LGREATER0x94, "LGreater", "tt", },
200 { AMLOP_LLESS0x95, "LLess", "tt", },
201
202 /* Named objects */
203 { AMLOP_NAMECHAR0x5F, ".NameRef", "n", },
204 { AMLOP_ALIAS0x06, "Alias", "nN", },
205 { AMLOP_NAME0x08, "Name", "Nt", },
206 { AMLOP_EVENT0x5B02, "Event", "N", },
207 { AMLOP_MUTEX0x5B01, "Mutex", "Nb", },
208 { AMLOP_DATAREGION0x5B88, "DataRegion", "Nttt", },
209 { AMLOP_OPREGION0x5B80, "OpRegion", "Nbii", },
210 { AMLOP_SCOPE0x10, "Scope", "pnT", },
211 { AMLOP_DEVICE0x5B82, "Device", "pNT", },
212 { AMLOP_POWERRSRC0x5B84, "Power Resource", "pNbwT",},
213 { AMLOP_THERMALZONE0x5B85, "ThermalZone", "pNT", },
214 { AMLOP_PROCESSOR0x5B83, "Processor", "pNbdbT", },
215 { AMLOP_METHOD0x14, "Method", "pNbM", },
216
217 /* Field operations */
218 { AMLOP_FIELD0x5B81, "Field", "pnbF", },
219 { AMLOP_INDEXFIELD0x5B86, "IndexField", "pnnbF",},
220 { AMLOP_BANKFIELD0x5B87, "BankField", "pnnibF",},
221 { AMLOP_CREATEFIELD0x5B13, "CreateField", "tiiN", },
222 { AMLOP_CREATEQWORDFIELD0x8F, "CreateQWordField","tiN",},
223 { AMLOP_CREATEDWORDFIELD0x8A, "CreateDWordField","tiN",},
224 { AMLOP_CREATEWORDFIELD0x8B, "CreateWordField", "tiN",},
225 { AMLOP_CREATEBYTEFIELD0x8C, "CreateByteField", "tiN",},
226 { AMLOP_CREATEBITFIELD0x8D, "CreateBitField", "tiN", },
227
228 /* Conversion operations */
229 { AMLOP_TOINTEGER0x99, "ToInteger", "tr", },
230 { AMLOP_TOBUFFER0x96, "ToBuffer", "tr", },
231 { AMLOP_TODECSTRING0x97, "ToDecString", "tr", },
232 { AMLOP_TOHEXSTRING0x98, "ToHexString", "tr", },
233 { AMLOP_TOSTRING0x9C, "ToString", "tir", },
234 { AMLOP_MID0x9E, "Mid", "tiir", },
235 { AMLOP_FROMBCD0x5B28, "FromBCD", "ir", },
236 { AMLOP_TOBCD0x5B29, "ToBCD", "ir", },
237
238 /* Mutex/Signal operations */
239 { AMLOP_ACQUIRE0x5B23, "Acquire", "Sw", },
240 { AMLOP_RELEASE0x5B27, "Release", "S", },
241 { AMLOP_SIGNAL0x5B24, "Signal", "S", },
242 { AMLOP_WAIT0x5B25, "Wait", "Si", },
243 { AMLOP_RESET0x5B26, "Reset", "S", },
244
245 { AMLOP_INDEX0x88, "Index", "tir", },
246 { AMLOP_DEREFOF0x83, "DerefOf", "t", },
247 { AMLOP_REFOF0x71, "RefOf", "S", },
248 { AMLOP_CONDREFOF0x5B12, "CondRef", "Sr", },
249
250 { AMLOP_LOADTABLE0x5B1F, "LoadTable", "tttttt" },
251 { AMLOP_STALL0x5B21, "Stall", "i", },
252 { AMLOP_SLEEP0x5B22, "Sleep", "i", },
253 { AMLOP_TIMER0x5B33, "Timer", "", },
254 { AMLOP_LOAD0x5B20, "Load", "nS", },
255 { AMLOP_UNLOAD0x5B2A, "Unload", "t" },
256 { AMLOP_STORE0x70, "Store", "tS", },
257 { AMLOP_CONCAT0x73, "Concat", "ttr", },
258 { AMLOP_CONCATRES0x84, "ConcatRes", "ttt" },
259 { AMLOP_NOTIFY0x86, "Notify", "Si", },
260 { AMLOP_SIZEOF0x87, "Sizeof", "S", },
261 { AMLOP_MATCH0x89, "Match", "tbibii", },
262 { AMLOP_OBJECTTYPE0x8E, "ObjectType", "S", },
263 { AMLOP_COPYOBJECT0x9D, "CopyObject", "tS", },
264};
265
266int aml_pc(uint8_t *src)
267{
268 return src - aml_root.start;
9
Returning without writing to '*src', which participates in a condition later
269}
270
271struct aml_scope *aml_lastscope;
272
273void
274_aml_die(const char *fn, int line, const char *fmt, ...)
275{
276#ifndef SMALL_KERNEL
277 struct aml_scope *root;
278 struct aml_value *sp;
279 int idx;
280#endif /* SMALL_KERNEL */
281 va_list ap;
282
283 va_start(ap, fmt)__builtin_va_start((ap), fmt);
284 vprintf(fmt, ap);
285 printf("\n");
286 va_end(ap)__builtin_va_end((ap));
287
288#ifndef SMALL_KERNEL
289 for (root = aml_lastscope; root && root->pos; root = root->parent) {
290 printf("%.4x Called: %s\n", aml_pc(root->pos),
291 aml_nodename(root->node));
292 for (idx = 0; idx < AML_MAX_ARG7; idx++) {
293 sp = aml_getstack(root, AMLOP_ARG00x68+idx);
294 if (sp && sp->type) {
295 printf(" arg%d: ", idx);
296 aml_showvalue(sp);
297 }
298 }
299 for (idx = 0; idx < AML_MAX_LOCAL8; idx++) {
300 sp = aml_getstack(root, AMLOP_LOCAL00x60+idx);
301 if (sp && sp->type) {
302 printf(" local%d: ", idx);
303 aml_showvalue(sp);
304 }
305 }
306 }
307#endif /* SMALL_KERNEL */
308
309 /* XXX: don't panic */
310 panic("aml_die %s:%d", fn, line);
311}
312
313void
314aml_hashopcodes(void)
315{
316 int i;
317
318 /* Dynamically allocate hash table */
319 aml_ophash = (struct aml_opcode **)acpi_os_malloc(HASH_SIZE *_acpi_os_malloc(179 * sizeof(struct aml_opcode *), __FUNCTION__
, 320)
320 sizeof(struct aml_opcode *))_acpi_os_malloc(179 * sizeof(struct aml_opcode *), __FUNCTION__
, 320)
;
321 for (i = 0; i < sizeof(aml_table) / sizeof(aml_table[0]); i++)
322 aml_ophash[HASH_KEY(aml_table[i].opcode)(((aml_table[i].opcode) ^ 6904) % 179)] = &aml_table[i];
323}
324
325struct aml_opcode *
326aml_findopcode(int opcode)
327{
328 struct aml_opcode *hop;
329
330 hop = aml_ophash[HASH_KEY(opcode)(((opcode) ^ 6904) % 179)];
331 if (hop && hop->opcode == opcode)
20
Assuming 'hop' is non-null
21
Assuming 'opcode' is equal to field 'opcode', which participates in a condition later
22
Taking true branch
332 return hop;
333 return NULL((void *)0);
334}
335
336#if defined(DDB1) || !defined(SMALL_KERNEL)
337const char *
338aml_mnem(int opcode, uint8_t *pos)
339{
340 struct aml_opcode *tab;
341 static char mnemstr[32];
342
343 if ((tab = aml_findopcode(opcode)) != NULL((void *)0)) {
344 strlcpy(mnemstr, tab->mnem, sizeof(mnemstr));
345 if (pos != NULL((void *)0)) {
346 switch (opcode) {
347 case AMLOP_STRINGPREFIX0x0D:
348 snprintf(mnemstr, sizeof(mnemstr), "\"%s\"", pos);
349 break;
350 case AMLOP_BYTEPREFIX0x0A:
351 snprintf(mnemstr, sizeof(mnemstr), "0x%.2x",
352 *(uint8_t *)pos);
353 break;
354 case AMLOP_WORDPREFIX0x0B:
355 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
356 *(uint16_t *)pos);
357 break;
358 case AMLOP_DWORDPREFIX0x0C:
359 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
360 *(uint16_t *)pos);
361 break;
362 case AMLOP_NAMECHAR0x5F:
363 strlcpy(mnemstr, aml_getname(pos), sizeof(mnemstr));
364 break;
365 }
366 }
367 return mnemstr;
368 }
369 return ("xxx");
370}
371#endif /* defined(DDB) || !defined(SMALL_KERNEL) */
372
373struct aml_notify_data {
374 struct aml_node *node;
375 char pnpid[20];
376 void *cbarg;
377 int (*cbproc)(struct aml_node *, int, void *);
378 int poll;
379
380 SLIST_ENTRY(aml_notify_data)struct { struct aml_notify_data *sle_next; } link;
381};
382
383SLIST_HEAD(aml_notify_head, aml_notify_data)struct aml_notify_head { struct aml_notify_data *slh_first; };
384struct aml_notify_head aml_notify_list =
385 SLIST_HEAD_INITIALIZER(aml_notify_list){ ((void *)0) };
386
387/*
388 * @@@: Memory management functions
389 */
390
391long acpi_nalloc;
392
393struct acpi_memblock {
394 size_t size;
395#ifdef ACPI_MEMDEBUG
396 const char *fn;
397 int line;
398 int sig;
399 LIST_ENTRY(acpi_memblock)struct { struct acpi_memblock *le_next; struct acpi_memblock *
*le_prev; }
link;
400#endif
401};
402
403#ifdef ACPI_MEMDEBUG
404LIST_HEAD(, acpi_memblock)struct { struct acpi_memblock *lh_first; } acpi_memhead;
405int acpi_memsig;
406
407int
408acpi_walkmem(int sig, const char *lbl)
409{
410 struct acpi_memblock *sptr;
411
412 printf("--- walkmem:%s %x --- %lx bytes alloced\n", lbl, sig,
413 acpi_nalloc);
414 LIST_FOREACH(sptr, &acpi_memhead, link)for((sptr) = ((&acpi_memhead)->lh_first); (sptr)!= ((void
*)0); (sptr) = ((sptr)->link.le_next))
{
415 if (sptr->sig < sig)
416 break;
417 printf("%.4x Alloc %.8lx bytes @ %s:%d\n",
418 sptr->sig, sptr->size, sptr->fn, sptr->line);
419 }
420 return acpi_memsig;
421}
422#endif /* ACPI_MEMDEBUG */
423
424void *
425_acpi_os_malloc(size_t size, const char *fn, int line)
426{
427 struct acpi_memblock *sptr;
428
429 sptr = malloc(size+sizeof(*sptr), M_ACPI33, M_WAITOK0x0001 | M_ZERO0x0008);
430 dnprintf(99, "alloc: %p %s:%d\n", sptr, fn, line);
431 acpi_nalloc += size;
432 sptr->size = size;
433#ifdef ACPI_MEMDEBUG
434 sptr->line = line;
435 sptr->fn = fn;
436 sptr->sig = ++acpi_memsig;
437
438 LIST_INSERT_HEAD(&acpi_memhead, sptr, link)do { if (((sptr)->link.le_next = (&acpi_memhead)->lh_first
) != ((void *)0)) (&acpi_memhead)->lh_first->link.le_prev
= &(sptr)->link.le_next; (&acpi_memhead)->lh_first
= (sptr); (sptr)->link.le_prev = &(&acpi_memhead)
->lh_first; } while (0)
;
439#endif
440
441 return &sptr[1];
442}
443
444void
445_acpi_os_free(void *ptr, const char *fn, int line)
446{
447 struct acpi_memblock *sptr;
448
449 if (ptr != NULL((void *)0)) {
450 sptr = &(((struct acpi_memblock *)ptr)[-1]);
451 acpi_nalloc -= sptr->size;
452
453#ifdef ACPI_MEMDEBUG
454 LIST_REMOVE(sptr, link)do { if ((sptr)->link.le_next != ((void *)0)) (sptr)->link
.le_next->link.le_prev = (sptr)->link.le_prev; *(sptr)->
link.le_prev = (sptr)->link.le_next; ((sptr)->link.le_prev
) = ((void *)-1); ((sptr)->link.le_next) = ((void *)-1); }
while (0)
;
455#endif
456
457 dnprintf(99, "free: %p %s:%d\n", sptr, fn, line);
458 free(sptr, M_ACPI33, sizeof(*sptr) + sptr->size);
459 }
460}
461
462void
463acpi_sleep(int ms, char *reason)
464{
465 static int acpinowait;
466
467 /* XXX ACPI integers are supposed to be unsigned. */
468 ms = MAX(1, ms)(((1)>(ms))?(1):(ms));
469
470 if (cold)
471 delay(ms * 1000)(*delay_func)(ms * 1000);
472 else
473 tsleep_nsec(&acpinowait, PWAIT32, reason, MSEC_TO_NSEC(ms));
474}
475
476void
477acpi_stall(int us)
478{
479 delay(us)(*delay_func)(us);
480}
481
482/*
483 * @@@: Misc utility functions
484 */
485
486#ifdef ACPI_DEBUG
487void
488aml_dump(int len, uint8_t *buf)
489{
490 int idx;
491
492 dnprintf(50, "{ ");
493 for (idx = 0; idx < len; idx++) {
494 dnprintf(50, "%s0x%.2x", idx ? ", " : "", buf[idx]);
495 }
496 dnprintf(50, " }\n");
497}
498#endif
499
500/* Bit mangling code */
501int
502aml_tstbit(const uint8_t *pb, int bit)
503{
504 pb += aml_bytepos(bit)((bit)>>3);
505
506 return (*pb & aml_bitmask(bit)(1L << ((bit) & 0x7)));
507}
508
509void
510aml_setbit(uint8_t *pb, int bit, int val)
511{
512 pb += aml_bytepos(bit)((bit)>>3);
513
514 if (val)
515 *pb |= aml_bitmask(bit)(1L << ((bit) & 0x7));
516 else
517 *pb &= ~aml_bitmask(bit)(1L << ((bit) & 0x7));
518}
519
520/*
521 * @@@: Notify functions
522 */
523void
524acpi_poll(void *arg)
525{
526 int s;
527
528 s = splbio()splraise(0x3);
529 acpi_addtask(acpi_softc, acpi_poll_notify_task, NULL((void *)0), 0);
530 acpi_softc->sc_threadwaiting = 0;
531 wakeup(acpi_softc);
532 splx(s)spllower(s);
533
534 timeout_add_sec(&acpi_softc->sc_dev_timeout, 10);
535}
536
537void
538aml_notify_task(void *node, int notify_value)
539{
540 struct aml_notify_data *pdata = NULL((void *)0);
541
542 dnprintf(10,"run notify: %s %x\n", aml_nodename(node), notify_value);
543 SLIST_FOREACH(pdata, &aml_notify_list, link)for((pdata) = ((&aml_notify_list)->slh_first); (pdata)
!= ((void *)0); (pdata) = ((pdata)->link.sle_next))
544 if (pdata->node == node)
545 pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
546}
547
548void
549aml_register_notify(struct aml_node *node, const char *pnpid,
550 int (*proc)(struct aml_node *, int, void *), void *arg, int poll)
551{
552 struct aml_notify_data *pdata;
553 extern int acpi_poll_enabled;
554
555 dnprintf(10, "aml_register_notify: %s %s %p\n",
556 node->name, pnpid ? pnpid : "", proc);
557
558 pdata = acpi_os_malloc(sizeof(struct aml_notify_data))_acpi_os_malloc(sizeof(struct aml_notify_data), __FUNCTION__,
558)
;
559 pdata->node = node;
560 pdata->cbarg = arg;
561 pdata->cbproc = proc;
562 pdata->poll = poll;
563
564 if (pnpid)
565 strlcpy(pdata->pnpid, pnpid, sizeof(pdata->pnpid));
566
567 SLIST_INSERT_HEAD(&aml_notify_list, pdata, link)do { (pdata)->link.sle_next = (&aml_notify_list)->slh_first
; (&aml_notify_list)->slh_first = (pdata); } while (0)
;
568
569 if (poll && !acpi_poll_enabled)
570 timeout_add_sec(&acpi_softc->sc_dev_timeout, 10);
571}
572
573void
574aml_notify(struct aml_node *node, int notify_value)
575{
576 if (node == NULL((void *)0))
577 return;
578
579 dnprintf(10,"queue notify: %s %x\n", aml_nodename(node), notify_value);
580 acpi_addtask(acpi_softc, aml_notify_task, node, notify_value);
581}
582
583void
584aml_notify_dev(const char *pnpid, int notify_value)
585{
586 struct aml_notify_data *pdata = NULL((void *)0);
587
588 if (pnpid == NULL((void *)0))
589 return;
590
591 SLIST_FOREACH(pdata, &aml_notify_list, link)for((pdata) = ((&aml_notify_list)->slh_first); (pdata)
!= ((void *)0); (pdata) = ((pdata)->link.sle_next))
592 if (strcmp(pdata->pnpid, pnpid) == 0)
593 pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
594}
595
596void
597acpi_poll_notify_task(void *arg0, int arg1)
598{
599 struct aml_notify_data *pdata = NULL((void *)0);
600
601 SLIST_FOREACH(pdata, &aml_notify_list, link)for((pdata) = ((&aml_notify_list)->slh_first); (pdata)
!= ((void *)0); (pdata) = ((pdata)->link.sle_next))
602 if (pdata->cbproc && pdata->poll)
603 pdata->cbproc(pdata->node, 0, pdata->cbarg);
604}
605
606/*
607 * @@@: Namespace functions
608 */
609
610struct aml_node *__aml_search(struct aml_node *, uint8_t *, int);
611struct aml_node *__aml_searchname(struct aml_node *, const void *, int);
612void aml_delchildren(struct aml_node *);
613
614
615/* Search for a name in children nodes */
616struct aml_node *
617__aml_search(struct aml_node *root, uint8_t *nameseg, int create)
618{
619 struct aml_node *node;
620
621 /* XXX: Replace with SLIST/SIMPLEQ routines */
622 if (root == NULL((void *)0))
623 return NULL((void *)0);
624 SIMPLEQ_FOREACH(node, &root->son, sib)for((node) = ((&root->son)->sqh_first); (node) != (
(void *)0); (node) = ((node)->sib.sqe_next))
{
625 if (!strncmp(node->name, nameseg, AML_NAMESEG_LEN4))
626 return node;
627 }
628 if (create) {
629 node = acpi_os_malloc(sizeof(struct aml_node))_acpi_os_malloc(sizeof(struct aml_node), __FUNCTION__, 629);
630 memcpy((void *)node->name, nameseg, AML_NAMESEG_LEN)__builtin_memcpy(((void *)node->name), (nameseg), (4));
631 node->value = aml_allocvalue(0,0,NULL((void *)0));
632 node->value->node = node;
633 node->parent = root;
634
635 SIMPLEQ_INIT(&node->son)do { (&node->son)->sqh_first = ((void *)0); (&node
->son)->sqh_last = &(&node->son)->sqh_first
; } while (0)
;
636 SIMPLEQ_INSERT_TAIL(&root->son, node, sib)do { (node)->sib.sqe_next = ((void *)0); *(&root->son
)->sqh_last = (node); (&root->son)->sqh_last = &
(node)->sib.sqe_next; } while (0)
;
637 return node;
638 }
639 return NULL((void *)0);
640}
641
642/* Get absolute pathname of AML node */
643const char *
644aml_nodename(struct aml_node *node)
645{
646 static char namebuf[128];
647
648 namebuf[0] = 0;
649 if (node) {
650 aml_nodename(node->parent);
651 if (node->parent != &aml_root)
652 strlcat(namebuf, ".", sizeof(namebuf));
653 strlcat(namebuf, node->name, sizeof(namebuf));
654 return namebuf+1;
655 }
656 return namebuf;
657}
658
659const char *
660aml_getname(const char *name)
661{
662 static char namebuf[128], *p;
663 int count;
664
665 p = namebuf;
666 while (*name == AMLOP_ROOTCHAR0x5C || *name == AMLOP_PARENTPREFIX0x5E)
667 *(p++) = *(name++);
668 switch (*name) {
669 case 0x00:
670 count = 0;
671 break;
672 case AMLOP_MULTINAMEPREFIX0x2F:
673 count = name[1];
674 name += 2;
675 break;
676 case AMLOP_DUALNAMEPREFIX0x2E:
677 count = 2;
678 name += 1;
679 break;
680 default:
681 count = 1;
682 }
683 while (count--) {
684 memcpy(p, name, 4)__builtin_memcpy((p), (name), (4));
685 p[4] = '.';
686 p += 5;
687 name += 4;
688 if (*name == '.') name++;
689 }
690 *(--p) = 0;
691 return namebuf;
692}
693
694/* Free all children nodes/values */
695void
696aml_delchildren(struct aml_node *node)
697{
698 struct aml_node *onode;
699
700 if (node == NULL((void *)0))
701 return;
702 while ((onode = SIMPLEQ_FIRST(&node->son)((&node->son)->sqh_first)) != NULL((void *)0)) {
703 SIMPLEQ_REMOVE_HEAD(&node->son, sib)do { if (((&node->son)->sqh_first = (&node->
son)->sqh_first->sib.sqe_next) == ((void *)0)) (&node
->son)->sqh_last = &(&node->son)->sqh_first
; } while (0)
;
704
705 aml_delchildren(onode);
706
707 /* Don't delete values that have references */
708 if (onode->value && onode->value->refcnt > 1)
709 onode->value->node = NULL((void *)0);
710
711 /* Decrease reference count */
712 aml_delref(&onode->value, "");
713
714 /* Delete node */
715 acpi_os_free(onode)_acpi_os_free(onode, __FUNCTION__, 715);
716 }
717}
718
719/*
720 * @@@: Value functions
721 */
722
723/*
724 * Field I/O code
725 */
726void aml_unlockfield(struct aml_scope *, struct aml_value *);
727void aml_lockfield(struct aml_scope *, struct aml_value *);
728
729static long global_lock_count = 0;
730
731void
732acpi_glk_enter(void)
733{
734 int st = 0;
735
736 /* If lock is already ours, just continue. */
737 if (global_lock_count++)
738 return;
739
740 /* Spin to acquire the lock. */
741 while (!st) {
742 st = acpi_acquire_glk(&acpi_softc->sc_facs->global_lock);
743 /* XXX - yield/delay? */
744 }
745}
746
747void
748acpi_glk_leave(void)
749{
750 int st, x;
751
752 /* If we are the last one, turn out the lights. */
753 if (--global_lock_count)
754 return;
755
756 st = acpi_release_glk(&acpi_softc->sc_facs->global_lock);
757 if (!st)
758 return;
759
760 /*
761 * If pending, notify the BIOS that the lock was released by
762 * OSPM. No locking is needed because nobody outside the ACPI
763 * thread is supposed to touch this register.
764 */
765 x = acpi_read_pmreg(acpi_softc, ACPIREG_PM1_CNT0x10, 0);
766 x |= ACPI_PM1_GBL_RLS0x0004;
767 acpi_write_pmreg(acpi_softc, ACPIREG_PM1_CNT0x10, 0, x);
768}
769
770void
771aml_lockfield(struct aml_scope *scope, struct aml_value *field)
772{
773 if (AML_FIELD_LOCK(field->v_field.flags)(((field->_.vfield.flags) >> 4) & 0x1) != AML_FIELD_LOCK_ON0x1)
774 return;
775
776 acpi_glk_enter();
777}
778
779void
780aml_unlockfield(struct aml_scope *scope, struct aml_value *field)
781{
782 if (AML_FIELD_LOCK(field->v_field.flags)(((field->_.vfield.flags) >> 4) & 0x1) != AML_FIELD_LOCK_ON0x1)
783 return;
784
785 acpi_glk_leave();
786}
787
788/*
789 * @@@: Value set/compare/alloc/free routines
790 */
791
792#ifndef SMALL_KERNEL
793void
794aml_showvalue(struct aml_value *val)
795{
796 int idx;
797
798 if (val == NULL((void *)0))
799 return;
800
801 if (val->node)
802 printf(" [%s]", aml_nodename(val->node));
803 printf(" %p cnt:%.2x stk:%.2x", val, val->refcnt, val->stack);
804 switch (val->type) {
805 case AML_OBJTYPE_INTEGER:
806 printf(" integer: %llx\n", val->v_integer_.vinteger);
807 break;
808 case AML_OBJTYPE_STRING:
809 printf(" string: %s\n", val->v_string_.vstring);
810 break;
811 case AML_OBJTYPE_METHOD:
812 printf(" method: %.2x\n", val->v_method_.vmethod.flags);
813 break;
814 case AML_OBJTYPE_PACKAGE:
815 printf(" package: %.2x\n", val->length);
816 for (idx = 0; idx < val->length; idx++)
817 aml_showvalue(val->v_package_.vpackage[idx]);
818 break;
819 case AML_OBJTYPE_BUFFER:
820 printf(" buffer: %.2x {", val->length);
821 for (idx = 0; idx < val->length; idx++)
822 printf("%s%.2x", idx ? ", " : "", val->v_buffer_.vbuffer[idx]);
823 printf("}\n");
824 break;
825 case AML_OBJTYPE_FIELDUNIT:
826 case AML_OBJTYPE_BUFFERFIELD:
827 printf(" field: bitpos=%.4x bitlen=%.4x ref1:%p ref2:%p [%s]\n",
828 val->v_field_.vfield.bitpos, val->v_field_.vfield.bitlen,
829 val->v_field_.vfield.ref1, val->v_field_.vfield.ref2,
830 aml_mnem(val->v_field_.vfield.type, NULL((void *)0)));
831 if (val->v_field_.vfield.ref1)
832 printf(" ref1: %s\n", aml_nodename(val->v_field_.vfield.ref1->node));
833 if (val->v_field_.vfield.ref2)
834 printf(" ref2: %s\n", aml_nodename(val->v_field_.vfield.ref2->node));
835 break;
836 case AML_OBJTYPE_MUTEX:
837 printf(" mutex: %s ref: %d\n",
838 val->v_mutex_.vmutex ? val->v_mutex_.vmutex->amt_name : "",
839 val->v_mutex_.vmutex ? val->v_mutex_.vmutex->amt_ref_count : 0);
840 break;
841 case AML_OBJTYPE_EVENT:
842 printf(" event:\n");
843 break;
844 case AML_OBJTYPE_OPREGION:
845 printf(" opregion: %.2x,%.8llx,%x\n",
846 val->v_opregion_.vopregion.iospace, val->v_opregion_.vopregion.iobase,
847 val->v_opregion_.vopregion.iolen);
848 break;
849 case AML_OBJTYPE_NAMEREF:
850 printf(" nameref: %s\n", aml_getname(val->v_nameref_.vbuffer));
851 break;
852 case AML_OBJTYPE_DEVICE:
853 printf(" device:\n");
854 break;
855 case AML_OBJTYPE_PROCESSOR:
856 printf(" cpu: %.2x,%.4x,%.2x\n",
857 val->v_processor_.vprocessor.proc_id, val->v_processor_.vprocessor.proc_addr,
858 val->v_processor_.vprocessor.proc_len);
859 break;
860 case AML_OBJTYPE_THERMZONE:
861 printf(" thermzone:\n");
862 break;
863 case AML_OBJTYPE_POWERRSRC:
864 printf(" pwrrsrc: %.2x,%.2x\n",
865 val->v_powerrsrc_.vpowerrsrc.pwr_level, val->v_powerrsrc_.vpowerrsrc.pwr_order);
866 break;
867 case AML_OBJTYPE_OBJREF:
868 printf(" objref: %p index:%x opcode:%s\n", val->v_objref_.vobjref.ref,
869 val->v_objref_.vobjref.index, aml_mnem(val->v_objref_.vobjref.type, 0));
870 aml_showvalue(val->v_objref_.vobjref.ref);
871 break;
872 default:
873 printf(" !!type: %x\n", val->type);
874 }
875}
876#endif /* SMALL_KERNEL */
877
878int64_t
879aml_val2int(struct aml_value *rval)
880{
881 int64_t ival = 0;
882
883 if (rval == NULL((void *)0)) {
884 dnprintf(50, "null val2int\n");
885 return (0);
886 }
887 switch (rval->type) {
888 case AML_OBJTYPE_INTEGER:
889 ival = rval->v_integer_.vinteger;
890 break;
891 case AML_OBJTYPE_BUFFER:
892 aml_bufcpy(&ival, 0, rval->v_buffer_.vbuffer, 0,
893 min(aml_intlen, rval->length*8));
894 break;
895 case AML_OBJTYPE_STRING:
896 ival = aml_hextoint(rval->v_string_.vstring);
897 break;
898 }
899 return (ival);
900}
901
902/* Sets value into LHS: lhs must already be cleared */
903struct aml_value *
904_aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
905{
906 memset(&lhs->_, 0x0, sizeof(lhs->_))__builtin_memset((&lhs->_), (0x0), (sizeof(lhs->_))
)
;
907
908 lhs->type = type;
909 switch (lhs->type) {
910 case AML_OBJTYPE_INTEGER:
911 lhs->length = aml_intlen>>3;
912 lhs->v_integer_.vinteger = ival;
913 break;
914 case AML_OBJTYPE_METHOD:
915 lhs->v_method_.vmethod.flags = ival;
916 lhs->v_method_.vmethod.fneval = bval;
917 break;
918 case AML_OBJTYPE_NAMEREF:
919 lhs->v_nameref_.vbuffer = (uint8_t *)bval;
920 break;
921 case AML_OBJTYPE_OBJREF:
922 lhs->v_objref_.vobjref.type = ival;
923 lhs->v_objref_.vobjref.ref = (struct aml_value *)bval;
924 break;
925 case AML_OBJTYPE_BUFFER:
926 lhs->length = ival;
927 lhs->v_buffer_.vbuffer = (uint8_t *)acpi_os_malloc(ival)_acpi_os_malloc(ival, __FUNCTION__, 927);
928 if (bval)
929 memcpy(lhs->v_buffer, bval, ival)__builtin_memcpy((lhs->_.vbuffer), (bval), (ival));
930 break;
931 case AML_OBJTYPE_STRING:
932 if (ival == -1)
933 ival = strlen((const char *)bval);
934 lhs->length = ival;
935 lhs->v_string_.vstring = (char *)acpi_os_malloc(ival+1)_acpi_os_malloc(ival+1, __FUNCTION__, 935);
936 if (bval)
937 strncpy(lhs->v_string_.vstring, (const char *)bval, ival);
938 break;
939 case AML_OBJTYPE_PACKAGE:
940 lhs->length = ival;
941 lhs->v_package_.vpackage = (struct aml_value **)acpi_os_malloc(ival *_acpi_os_malloc(ival * sizeof(struct aml_value *), __FUNCTION__
, 942)
942 sizeof(struct aml_value *))_acpi_os_malloc(ival * sizeof(struct aml_value *), __FUNCTION__
, 942)
;
943 for (ival = 0; ival < lhs->length; ival++)
944 lhs->v_package_.vpackage[ival] = aml_allocvalue(
945 AML_OBJTYPE_UNINITIALIZED, 0, NULL((void *)0));
946 break;
947 }
948 return lhs;
949}
950
951/* Copy object to another value: lhs must already be cleared */
952void
953aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
954{
955 int idx;
956
957 lhs->type = rhs->type;
958 switch (lhs->type) {
959 case AML_OBJTYPE_UNINITIALIZED:
960 break;
961 case AML_OBJTYPE_INTEGER:
962 lhs->length = aml_intlen>>3;
963 lhs->v_integer_.vinteger = rhs->v_integer_.vinteger;
964 break;
965 case AML_OBJTYPE_MUTEX:
966 lhs->v_mutex_.vmutex = rhs->v_mutex_.vmutex;
967 break;
968 case AML_OBJTYPE_POWERRSRC:
969 lhs->node = rhs->node;
970 lhs->v_powerrsrc_.vpowerrsrc = rhs->v_powerrsrc_.vpowerrsrc;
971 break;
972 case AML_OBJTYPE_METHOD:
973 lhs->v_method_.vmethod = rhs->v_method_.vmethod;
974 break;
975 case AML_OBJTYPE_BUFFER:
976 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_buffer_.vbuffer);
977 break;
978 case AML_OBJTYPE_STRING:
979 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_string_.vstring);
980 break;
981 case AML_OBJTYPE_OPREGION:
982 lhs->v_opregion_.vopregion = rhs->v_opregion_.vopregion;
983 break;
984 case AML_OBJTYPE_PROCESSOR:
985 lhs->node = rhs->node;
986 lhs->v_processor_.vprocessor = rhs->v_processor_.vprocessor;
987 break;
988 case AML_OBJTYPE_NAMEREF:
989 lhs->v_nameref_.vbuffer = rhs->v_nameref_.vbuffer;
990 break;
991 case AML_OBJTYPE_PACKAGE:
992 _aml_setvalue(lhs, rhs->type, rhs->length, NULL((void *)0));
993 for (idx = 0; idx < rhs->length; idx++)
994 aml_copyvalue(lhs->v_package_.vpackage[idx], rhs->v_package_.vpackage[idx]);
995 break;
996 case AML_OBJTYPE_OBJREF:
997 lhs->v_objref_.vobjref = rhs->v_objref_.vobjref;
998 aml_addref(lhs->v_objref_.vobjref.ref, "");
999 break;
1000 case AML_OBJTYPE_DEVICE:
1001 case AML_OBJTYPE_THERMZONE:
1002 lhs->node = rhs->node;
1003 break;
1004 default:
1005 printf("copyvalue: %x", rhs->type);
1006 break;
1007 }
1008}
1009
1010/* Allocate dynamic AML value
1011 * type : Type of object to allocate (AML_OBJTYPE_XXXX)
1012 * ival : Integer value (action depends on type)
1013 * bval : Buffer value (action depends on type)
1014 */
1015struct aml_value *
1016aml_allocvalue(int type, int64_t ival, const void *bval)
1017{
1018 struct aml_value *rv;
1019
1020 rv = (struct aml_value *)acpi_os_malloc(sizeof(struct aml_value))_acpi_os_malloc(sizeof(struct aml_value), __FUNCTION__, 1020);
1021 if (rv != NULL((void *)0)) {
1022 aml_addref(rv, "");
1023 return _aml_setvalue(rv, type, ival, bval);
1024 }
1025 return NULL((void *)0);
1026}
1027
1028void
1029aml_freevalue(struct aml_value *val)
1030{
1031 int idx;
1032
1033 if (val == NULL((void *)0))
1034 return;
1035 switch (val->type) {
1036 case AML_OBJTYPE_STRING:
1037 acpi_os_free(val->v_string)_acpi_os_free(val->_.vstring, __FUNCTION__, 1037);
1038 break;
1039 case AML_OBJTYPE_BUFFER:
1040 acpi_os_free(val->v_buffer)_acpi_os_free(val->_.vbuffer, __FUNCTION__, 1040);
1041 break;
1042 case AML_OBJTYPE_PACKAGE:
1043 for (idx = 0; idx < val->length; idx++)
1044 aml_delref(&val->v_package_.vpackage[idx], "");
1045 acpi_os_free(val->v_package)_acpi_os_free(val->_.vpackage, __FUNCTION__, 1045);
1046 break;
1047 case AML_OBJTYPE_OBJREF:
1048 aml_delref(&val->v_objref_.vobjref.ref, "");
1049 break;
1050 case AML_OBJTYPE_BUFFERFIELD:
1051 case AML_OBJTYPE_FIELDUNIT:
1052 aml_delref(&val->v_field_.vfield.ref1, "");
1053 aml_delref(&val->v_field_.vfield.ref2, "");
1054 break;
1055 }
1056 val->type = 0;
1057 memset(&val->_, 0, sizeof(val->_))__builtin_memset((&val->_), (0), (sizeof(val->_)));
1058}
1059
1060/*
1061 * @@@: Math eval routines
1062 */
1063
1064/* Convert number from one radix to another
1065 * Used in BCD conversion routines */
1066uint64_t
1067aml_convradix(uint64_t val, int iradix, int oradix)
1068{
1069 uint64_t rv = 0, pwr;
1070
1071 rv = 0;
1072 pwr = 1;
1073 while (val) {
1074 rv += (val % iradix) * pwr;
1075 val /= iradix;
1076 pwr *= oradix;
1077 }
1078 return rv;
1079}
1080
1081/* Calculate LSB */
1082int
1083aml_lsb(uint64_t val)
1084{
1085 int lsb;
1086
1087 if (val == 0)
1088 return (0);
1089
1090 for (lsb = 1; !(val & 0x1); lsb++)
1091 val >>= 1;
1092
1093 return (lsb);
1094}
1095
1096/* Calculate MSB */
1097int
1098aml_msb(uint64_t val)
1099{
1100 int msb;
1101
1102 if (val == 0)
1103 return (0);
1104
1105 for (msb = 1; val != 0x1; msb++)
1106 val >>= 1;
1107
1108 return (msb);
1109}
1110
1111/* Evaluate Math operands */
1112uint64_t
1113aml_evalexpr(uint64_t lhs, uint64_t rhs, int opcode)
1114{
1115 uint64_t res = 0;
1116
1117 switch (opcode) {
1118 /* Math operations */
1119 case AMLOP_INCREMENT0x75:
1120 case AMLOP_ADD0x72:
1121 res = (lhs + rhs);
1122 break;
1123 case AMLOP_DECREMENT0x76:
1124 case AMLOP_SUBTRACT0x74:
1125 res = (lhs - rhs);
1126 break;
1127 case AMLOP_MULTIPLY0x77:
1128 res = (lhs * rhs);
1129 break;
1130 case AMLOP_DIVIDE0x78:
1131 res = (lhs / rhs);
1132 break;
1133 case AMLOP_MOD0x85:
1134 res = (lhs % rhs);
1135 break;
1136 case AMLOP_SHL0x79:
1137 res = (lhs << rhs);
1138 break;
1139 case AMLOP_SHR0x7A:
1140 res = (lhs >> rhs);
1141 break;
1142 case AMLOP_AND0x7B:
1143 res = (lhs & rhs);
1144 break;
1145 case AMLOP_NAND0x7C:
1146 res = ~(lhs & rhs);
1147 break;
1148 case AMLOP_OR0x7D:
1149 res = (lhs | rhs);
1150 break;
1151 case AMLOP_NOR0x7E:
1152 res = ~(lhs | rhs);
1153 break;
1154 case AMLOP_XOR0x7F:
1155 res = (lhs ^ rhs);
1156 break;
1157 case AMLOP_NOT0x80:
1158 res = ~(lhs);
1159 break;
1160
1161 /* Conversion/misc */
1162 case AMLOP_FINDSETLEFTBIT0x81:
1163 res = aml_msb(lhs);
1164 break;
1165 case AMLOP_FINDSETRIGHTBIT0x82:
1166 res = aml_lsb(lhs);
1167 break;
1168 case AMLOP_TOINTEGER0x99:
1169 res = (lhs);
1170 break;
1171 case AMLOP_FROMBCD0x5B28:
1172 res = aml_convradix(lhs, 16, 10);
1173 break;
1174 case AMLOP_TOBCD0x5B29:
1175 res = aml_convradix(lhs, 10, 16);
1176 break;
1177
1178 /* Logical/Comparison */
1179 case AMLOP_LAND0x90:
1180 res = -(lhs && rhs);
1181 break;
1182 case AMLOP_LOR0x91:
1183 res = -(lhs || rhs);
1184 break;
1185 case AMLOP_LNOT0x92:
1186 res = -(!lhs);
1187 break;
1188 case AMLOP_LNOTEQUAL0x9293:
1189 res = -(lhs != rhs);
1190 break;
1191 case AMLOP_LLESSEQUAL0x9294:
1192 res = -(lhs <= rhs);
1193 break;
1194 case AMLOP_LGREATEREQUAL0x9295:
1195 res = -(lhs >= rhs);
1196 break;
1197 case AMLOP_LEQUAL0x93:
1198 res = -(lhs == rhs);
1199 break;
1200 case AMLOP_LGREATER0x94:
1201 res = -(lhs > rhs);
1202 break;
1203 case AMLOP_LLESS0x95:
1204 res = -(lhs < rhs);
1205 break;
1206 }
1207
1208 dnprintf(15,"aml_evalexpr: %s %llx %llx = %llx\n",
1209 aml_mnem(opcode, NULL), lhs, rhs, res);
1210
1211 return res;
1212}
1213
1214/*
1215 * aml_bufcpy copies/shifts buffer data, special case for aligned transfers
1216 * dstPos/srcPos are bit positions within destination/source buffers
1217 */
1218void
1219aml_bufcpy(void *pvDst, int dstPos, const void *pvSrc, int srcPos, int len)
1220{
1221 const uint8_t *pSrc = pvSrc;
1222 uint8_t *pDst = pvDst;
1223 int idx;
1224
1225 if (aml_bytealigned(dstPos|srcPos|len)!((dstPos|srcPos|len)&0x7)) {
1226 /* Aligned transfer: use memcpy */
1227 memcpy(pDst+aml_bytepos(dstPos), pSrc+aml_bytepos(srcPos),__builtin_memcpy((pDst+((dstPos)>>3)), (pSrc+((srcPos)>>
3)), ((((len)+7)>>3)))
1228 aml_bytelen(len))__builtin_memcpy((pDst+((dstPos)>>3)), (pSrc+((srcPos)>>
3)), ((((len)+7)>>3)))
;
1229 return;
1230 }
1231
1232 /* Misaligned transfer: perform bitwise copy (slow) */
1233 for (idx = 0; idx < len; idx++)
1234 aml_setbit(pDst, idx + dstPos, aml_tstbit(pSrc, idx + srcPos));
1235}
1236
1237/*
1238 * @@@: External API
1239 *
1240 * evaluate an AML node
1241 * Returns a copy of the value in res (must be freed by user)
1242 */
1243
1244void
1245aml_walknodes(struct aml_node *node, int mode,
1246 int (*nodecb)(struct aml_node *, void *), void *arg)
1247{
1248 struct aml_node *child;
1249
1250 if (node == NULL((void *)0))
1251 return;
1252 if (mode == AML_WALK_PRE0x00)
1253 if (nodecb(node, arg))
1254 return;
1255 SIMPLEQ_FOREACH(child, &node->son, sib)for((child) = ((&node->son)->sqh_first); (child) !=
((void *)0); (child) = ((child)->sib.sqe_next))
1256 aml_walknodes(child, mode, nodecb, arg);
1257 if (mode == AML_WALK_POST0x01)
1258 nodecb(node, arg);
1259}
1260
1261void
1262aml_find_node(struct aml_node *node, const char *name,
1263 int (*cbproc)(struct aml_node *, void *arg), void *arg)
1264{
1265 struct aml_node *child;
1266 const char *nn;
1267
1268 /* match child of this node first before recursing */
1269 SIMPLEQ_FOREACH(child, &node->son, sib)for((child) = ((&node->son)->sqh_first); (child) !=
((void *)0); (child) = ((child)->sib.sqe_next))
{
1270 nn = child->name;
1271 if (nn != NULL((void *)0)) {
1272 if (*nn == AMLOP_ROOTCHAR0x5C) nn++;
1273 while (*nn == AMLOP_PARENTPREFIX0x5E) nn++;
1274 if (strcmp(name, nn) == 0) {
1275 /* Only recurse if cbproc() wants us to */
1276 if (cbproc(child, arg) != 0)
1277 return;
1278 }
1279 }
1280 }
1281
1282 SIMPLEQ_FOREACH(child, &node->son, sib)for((child) = ((&node->son)->sqh_first); (child) !=
((void *)0); (child) = ((child)->sib.sqe_next))
1283 aml_find_node(child, name, cbproc, arg);
1284}
1285
1286/*
1287 * @@@: Parser functions
1288 */
1289uint8_t *aml_parsename(struct aml_node *, uint8_t *, struct aml_value **, int);
1290uint8_t *aml_parseend(struct aml_scope *scope);
1291int aml_parselength(struct aml_scope *);
1292int aml_parseopcode(struct aml_scope *);
1293
1294/* Get AML Opcode */
1295int
1296aml_parseopcode(struct aml_scope *scope)
1297{
1298 int opcode = (scope->pos[0]);
1299 int twocode = (scope->pos[0]<<8) + scope->pos[1];
1300
1301 /* Check if this is an embedded name */
1302 switch (opcode) {
1303 case AMLOP_ROOTCHAR0x5C:
1304 case AMLOP_PARENTPREFIX0x5E:
1305 case AMLOP_MULTINAMEPREFIX0x2F:
1306 case AMLOP_DUALNAMEPREFIX0x2E:
1307 case AMLOP_NAMECHAR0x5F:
1308 return AMLOP_NAMECHAR0x5F;
1309 }
1310 if (opcode >= 'A' && opcode <= 'Z')
12
Assuming the condition is false
1311 return AMLOP_NAMECHAR0x5F;
1312 if (twocode == AMLOP_LNOTEQUAL0x9293 || twocode == AMLOP_LLESSEQUAL0x9294 ||
13
Assuming 'twocode' is not equal to AMLOP_LNOTEQUAL
14
Assuming 'twocode' is not equal to AMLOP_LLESSEQUAL
16
Taking false branch
1313 twocode == AMLOP_LGREATEREQUAL0x9295 || opcode
15.1
'opcode' is not equal to AMLOP_EXTPREFIX, which participates in a condition later
== AMLOP_EXTPREFIX0x5B) {
15
Assuming 'twocode' is not equal to AMLOP_LGREATEREQUAL
1314 scope->pos += 2;
1315 return twocode;
1316 }
1317 scope->pos += 1;
1318 return opcode;
17
Returning value (loaded from 'opcode'), which participates in a condition later
1319}
1320
1321/* Decode embedded AML Namestring */
1322uint8_t *
1323aml_parsename(struct aml_node *inode, uint8_t *pos, struct aml_value **rval, int create)
1324{
1325 struct aml_node *relnode, *node = inode;
1326 uint8_t *start = pos;
1327 int i;
1328
1329 if (*pos == AMLOP_ROOTCHAR0x5C) {
1330 pos++;
1331 node = &aml_root;
1332 }
1333 while (*pos == AMLOP_PARENTPREFIX0x5E) {
1334 pos++;
1335 if ((node = node->parent) == NULL((void *)0))
1336 node = &aml_root;
1337 }
1338 switch (*pos) {
1339 case 0x00:
1340 pos++;
1341 break;
1342 case AMLOP_MULTINAMEPREFIX0x2F:
1343 for (i=0; i<pos[1]; i++)
1344 node = __aml_search(node, pos+2+i*AML_NAMESEG_LEN4,
1345 create);
1346 pos += 2+i*AML_NAMESEG_LEN4;
1347 break;
1348 case AMLOP_DUALNAMEPREFIX0x2E:
1349 node = __aml_search(node, pos+1, create);
1350 node = __aml_search(node, pos+1+AML_NAMESEG_LEN4, create);
1351 pos += 1+2*AML_NAMESEG_LEN4;
1352 break;
1353 default:
1354 /* If Relative Search (pos == start), recursively go up root */
1355 relnode = node;
1356 do {
1357 node = __aml_search(relnode, pos, create);
1358 relnode = relnode->parent;
1359 } while (!node && pos == start && relnode);
1360 pos += AML_NAMESEG_LEN4;
1361 break;
1362 }
1363 if (node) {
1364 *rval = node->value;
1365
1366 /* Dereference ALIAS here */
1367 if ((*rval)->type == AML_OBJTYPE_OBJREF &&
1368 (*rval)->v_objref_.vobjref.type == AMLOP_ALIAS0x06) {
1369 dnprintf(10, "deref alias: %s\n", aml_nodename(node));
1370 *rval = (*rval)->v_objref_.vobjref.ref;
1371 }
1372 aml_addref(*rval, 0);
1373
1374 dnprintf(10, "parsename: %s %x\n", aml_nodename(node),
1375 (*rval)->type);
1376 } else {
1377 *rval = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, start);
1378
1379 dnprintf(10, "%s:%s not found\n", aml_nodename(inode),
1380 aml_getname(start));
1381 }
1382
1383 return pos;
1384}
1385
1386/* Decode AML Length field
1387 * AML Length field is encoded:
1388 * byte0 byte1 byte2 byte3
1389 * 00xxxxxx : if upper bits == 00, length = xxxxxx
1390 * 01--xxxx yyyyyyyy : if upper bits == 01, length = yyyyyyyyxxxx
1391 * 10--xxxx yyyyyyyy zzzzzzzz : if upper bits == 10, length = zzzzzzzzyyyyyyyyxxxx
1392 * 11--xxxx yyyyyyyy zzzzzzzz wwwwwwww : if upper bits == 11, length = wwwwwwwwzzzzzzzzyyyyyyyyxxxx
1393 */
1394int
1395aml_parselength(struct aml_scope *scope)
1396{
1397 int len;
1398 uint8_t lcode;
1399
1400 lcode = *(scope->pos++);
1401 if (lcode <= 0x3F)
1402 return lcode;
1403
1404 /* lcode >= 0x40, multibyte length, get first byte of extended length */
1405 len = lcode & 0xF;
1406 len += *(scope->pos++) << 4L;
1407 if (lcode >= 0x80)
1408 len += *(scope->pos++) << 12L;
1409 if (lcode >= 0xC0)
1410 len += *(scope->pos++) << 20L;
1411 return len;
1412}
1413
1414/* Get address of end of scope; based on current address */
1415uint8_t *
1416aml_parseend(struct aml_scope *scope)
1417{
1418 uint8_t *pos = scope->pos;
1419 int len;
1420
1421 len = aml_parselength(scope);
1422 if (pos+len > scope->end) {
1423 dnprintf(10,
1424 "Bad scope... runover pos:%.4x new end:%.4x scope "
1425 "end:%.4x\n", aml_pc(pos), aml_pc(pos+len),
1426 aml_pc(scope->end));
1427 return scope->end;
1428 }
1429 return pos+len;
1430}
1431
1432/*
1433 * @@@: Opcode utility functions
1434 */
1435
1436/*
1437 * @@@: Opcode functions
1438 */
1439
1440int odp;
1441
1442const char hext[] = "0123456789ABCDEF";
1443
1444const char *
1445aml_eisaid(uint32_t pid)
1446{
1447 static char id[8];
1448
1449 id[0] = '@' + ((pid >> 2) & 0x1F);
1450 id[1] = '@' + ((pid << 3) & 0x18) + ((pid >> 13) & 0x7);
1451 id[2] = '@' + ((pid >> 8) & 0x1F);
1452 id[3] = hext[(pid >> 20) & 0xF];
1453 id[4] = hext[(pid >> 16) & 0xF];
1454 id[5] = hext[(pid >> 28) & 0xF];
1455 id[6] = hext[(pid >> 24) & 0xF];
1456 id[7] = 0;
1457 return id;
1458}
1459
1460/*
1461 * @@@: Default Object creation
1462 */
1463static char osstring[] = "Macrosift Windogs MT";
1464struct aml_defval {
1465 const char *name;
1466 int type;
1467 int64_t ival;
1468 const void *bval;
1469 struct aml_value **gval;
1470} aml_defobj[] = {
1471 { "_OS_", AML_OBJTYPE_STRING, -1, osstring },
1472 { "_REV", AML_OBJTYPE_INTEGER, 2, NULL((void *)0) },
1473 { "_GL", AML_OBJTYPE_MUTEX, 1, NULL((void *)0), &aml_global_lock },
1474 { "_OSI", AML_OBJTYPE_METHOD, 1, aml_callosi },
1475
1476 /* Create default scopes */
1477 { "_GPE", AML_OBJTYPE_DEVICE },
1478 { "_PR_", AML_OBJTYPE_DEVICE },
1479 { "_SB_", AML_OBJTYPE_DEVICE },
1480 { "_TZ_", AML_OBJTYPE_DEVICE },
1481 { "_SI_", AML_OBJTYPE_DEVICE },
1482
1483 { NULL((void *)0) }
1484};
1485
1486/* _OSI Default Method:
1487 * Returns True if string argument matches list of known OS strings
1488 * We return True for Windows to fake out nasty bad AML
1489 */
1490char *aml_valid_osi[] = {
1491 AML_VALID_OSI"Windows 2000", "Windows 2001", "Windows 2001.1", "Windows 2001.1 SP1"
, "Windows 2001 SP0", "Windows 2001 SP1", "Windows 2001 SP2",
"Windows 2001 SP3", "Windows 2001 SP4", "Windows 2006", "Windows 2006.1"
, "Windows 2006 SP1", "Windows 2006 SP2", "Windows 2009", "Windows 2012"
, "Windows 2013", "Windows 2015", "Windows 2016", "Windows 2017"
, "Windows 2017.2", "Windows 2018", "Windows 2018.2", "Windows 2019"
, "Windows 2020", "Windows 2021", "Windows 2022"
,
1492 NULL((void *)0)
1493};
1494
1495enum acpi_osi acpi_max_osi = OSI_UNKNOWN;
1496
1497struct aml_value *
1498aml_callosi(struct aml_scope *scope, struct aml_value *val)
1499{
1500 int idx, result=0;
1501 struct aml_value *fa;
1502
1503 fa = aml_getstack(scope, AMLOP_ARG00x68);
1504
1505 if (hw_vendor != NULL((void *)0) &&
1506 (strcmp(hw_vendor, "Apple Inc.") == 0 ||
1507 strcmp(hw_vendor, "Apple Computer, Inc.") == 0)) {
1508 if (strcmp(fa->v_string_.vstring, "Darwin") == 0) {
1509 dnprintf(10,"osi: returning 1 for %s on %s hardware\n",
1510 fa->v_string, hw_vendor);
1511 result = 1;
1512 } else
1513 dnprintf(10,"osi: on %s hardware, but ignoring %s\n",
1514 hw_vendor, fa->v_string);
1515
1516 return aml_allocvalue(AML_OBJTYPE_INTEGER, result, NULL((void *)0));
1517 }
1518
1519 for (idx=0; !result && aml_valid_osi[idx] != NULL((void *)0); idx++) {
1520 dnprintf(10,"osi: %s,%s\n", fa->v_string, aml_valid_osi[idx]);
1521 result = !strcmp(fa->v_string_.vstring, aml_valid_osi[idx]);
1522 if (result) {
1523 if (idx > acpi_max_osi)
1524 acpi_max_osi = idx;
1525 break;
1526 }
1527 }
1528 dnprintf(10,"@@ OSI found: %x\n", result);
1529 return aml_allocvalue(AML_OBJTYPE_INTEGER, result, NULL((void *)0));
1530}
1531
1532void
1533aml_create_defaultobjects(void)
1534{
1535 struct aml_value *tmp;
1536 struct aml_defval *def;
1537
1538#ifdef ACPI_MEMDEBUG
1539 LIST_INIT(&acpi_memhead)do { ((&acpi_memhead)->lh_first) = ((void *)0); } while
(0)
;
1540#endif
1541
1542 osstring[1] = 'i';
1543 osstring[6] = 'o';
1544 osstring[15] = 'w';
1545 osstring[18] = 'N';
1546
1547 SIMPLEQ_INIT(&aml_root.son)do { (&aml_root.son)->sqh_first = ((void *)0); (&aml_root
.son)->sqh_last = &(&aml_root.son)->sqh_first; }
while (0)
;
1548 strlcpy(aml_root.name, "\\", sizeof(aml_root.name));
1549 aml_root.value = aml_allocvalue(0, 0, NULL((void *)0));
1550 aml_root.value->node = &aml_root;
1551
1552 for (def = aml_defobj; def->name; def++) {
1553 /* Allocate object value + add to namespace */
1554 aml_parsename(&aml_root, (uint8_t *)def->name, &tmp, 1);
1555 _aml_setvalue(tmp, def->type, def->ival, def->bval);
1556 if (def->gval) {
1557 /* Set root object pointer */
1558 *def->gval = tmp;
1559 }
1560 aml_delref(&tmp, 0);
1561 }
1562}
1563
1564#ifdef ACPI_DEBUG
1565int
1566aml_print_resource(union acpi_resource *crs, void *arg)
1567{
1568 int typ = AML_CRSTYPE(crs)((crs)->hdr.typecode & 0x80 ? (crs)->hdr.typecode :
(crs)->hdr.typecode >> 3)
;
1569
1570 switch (typ) {
1571 case LR_EXTIRQ0x89:
1572 printf("extirq\tflags:%.2x len:%.2x irq:%.4x\n",
1573 crs->lr_extirq.flags, crs->lr_extirq.irq_count,
1574 letoh32(crs->lr_extirq.irq[0])((__uint32_t)(crs->lr_extirq.irq[0])));
1575 break;
1576 case SR_IRQ0x04:
1577 printf("irq\t%.4x %.2x\n", letoh16(crs->sr_irq.irq_mask)((__uint16_t)(crs->sr_irq.irq_mask)),
1578 crs->sr_irq.irq_flags);
1579 break;
1580 case SR_DMA0x05:
1581 printf("dma\t%.2x %.2x\n", crs->sr_dma.channel,
1582 crs->sr_dma.flags);
1583 break;
1584 case SR_IOPORT0x08:
1585 printf("ioport\tflags:%.2x _min:%.4x _max:%.4x _aln:%.2x _len:%.2x\n",
1586 crs->sr_ioport.flags, crs->sr_ioport._min,
1587 crs->sr_ioport._max, crs->sr_ioport._aln,
1588 crs->sr_ioport._len);
1589 break;
1590 case SR_STARTDEP0x06:
1591 printf("startdep\n");
1592 break;
1593 case SR_ENDDEP0x07:
1594 printf("enddep\n");
1595 break;
1596 case LR_WORD0x88:
1597 printf("word\ttype:%.2x flags:%.2x tflag:%.2x gra:%.4x min:%.4x max:%.4x tra:%.4x len:%.4x\n",
1598 crs->lr_word.type, crs->lr_word.flags, crs->lr_word.tflags,
1599 crs->lr_word._gra, crs->lr_word._min, crs->lr_word._max,
1600 crs->lr_word._tra, crs->lr_word._len);
1601 break;
1602 case LR_DWORD0x87:
1603 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.8x min:%.8x max:%.8x tra:%.8x len:%.8x\n",
1604 crs->lr_dword.type, crs->lr_dword.flags, crs->lr_dword.tflags,
1605 crs->lr_dword._gra, crs->lr_dword._min, crs->lr_dword._max,
1606 crs->lr_dword._tra, crs->lr_dword._len);
1607 break;
1608 case LR_QWORD0x8A:
1609 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.16llx min:%.16llx max:%.16llx tra:%.16llx len:%.16llx\n",
1610 crs->lr_qword.type, crs->lr_qword.flags, crs->lr_qword.tflags,
1611 crs->lr_qword._gra, crs->lr_qword._min, crs->lr_qword._max,
1612 crs->lr_qword._tra, crs->lr_qword._len);
1613 break;
1614 default:
1615 printf("unknown type: %x\n", typ);
1616 break;
1617 }
1618 return (0);
1619}
1620#endif /* ACPI_DEBUG */
1621
1622union acpi_resource *aml_mapresource(union acpi_resource *);
1623
1624union acpi_resource *
1625aml_mapresource(union acpi_resource *crs)
1626{
1627 static union acpi_resource map;
1628 int rlen;
1629
1630 rlen = AML_CRSLEN(crs)((crs)->hdr.typecode & 0x80 ? 3+(crs)->hdr.length :
1+((crs)->hdr.typecode & 0x7))
;
1631 if (rlen >= sizeof(map))
1632 return crs;
1633
1634 memset(&map, 0, sizeof(map))__builtin_memset((&map), (0), (sizeof(map)));
1635 memcpy(&map, crs, rlen)__builtin_memcpy((&map), (crs), (rlen));
1636
1637 return &map;
1638}
1639
1640int
1641aml_parse_resource(struct aml_value *res,
1642 int (*crs_enum)(int, union acpi_resource *, void *), void *arg)
1643{
1644 int off, rlen, crsidx;
1645 union acpi_resource *crs;
1646
1647 if (res->type != AML_OBJTYPE_BUFFER || res->length < 5)
1648 return (-1);
1649 for (off = 0, crsidx = 0; off < res->length; off += rlen, crsidx++) {
1650 crs = (union acpi_resource *)(res->v_buffer_.vbuffer+off);
1651
1652 rlen = AML_CRSLEN(crs)((crs)->hdr.typecode & 0x80 ? 3+(crs)->hdr.length :
1+((crs)->hdr.typecode & 0x7))
;
1653 if (crs->hdr.typecode == SRT_ENDTAG0x79 || !rlen)
1654 break;
1655
1656 crs = aml_mapresource(crs);
1657#ifdef ACPI_DEBUG
1658 aml_print_resource(crs, NULL((void *)0));
1659#endif
1660 crs_enum(crsidx, crs, arg);
1661 }
1662
1663 return (0);
1664}
1665
1666void
1667aml_foreachpkg(struct aml_value *pkg, int start,
1668 void (*fn)(struct aml_value *, void *), void *arg)
1669{
1670 int idx;
1671
1672 if (pkg->type != AML_OBJTYPE_PACKAGE)
1673 return;
1674 for (idx=start; idx<pkg->length; idx++)
1675 fn(pkg->v_package_.vpackage[idx], arg);
1676}
1677
1678/*
1679 * Walk nodes and perform fixups for nameref
1680 */
1681int aml_fixup_node(struct aml_node *, void *);
1682
1683int aml_fixup_node(struct aml_node *node, void *arg)
1684{
1685 struct aml_value *val = arg;
1686 int i;
1687
1688 if (node->value == NULL((void *)0))
1689 return (0);
1690 if (arg == NULL((void *)0))
1691 aml_fixup_node(node, node->value);
1692 else if (val->type == AML_OBJTYPE_NAMEREF) {
1693 node = aml_searchname(node, aml_getname(val->v_nameref_.vbuffer));
1694 if (node && node->value) {
1695 _aml_setvalue(val, AML_OBJTYPE_OBJREF, AMLOP_NAMECHAR0x5F,
1696 node->value);
1697 }
1698 } else if (val->type == AML_OBJTYPE_PACKAGE) {
1699 for (i = 0; i < val->length; i++)
1700 aml_fixup_node(node, val->v_package_.vpackage[i]);
1701 }
1702 return (0);
1703}
1704
1705void
1706aml_postparse(void)
1707{
1708 aml_walknodes(&aml_root, AML_WALK_PRE0x00, aml_fixup_node, NULL((void *)0));
1709}
1710
1711#ifndef SMALL_KERNEL
1712const char *
1713aml_val_to_string(const struct aml_value *val)
1714{
1715 static char buffer[256];
1716
1717 int len;
1718
1719 switch (val->type) {
1720 case AML_OBJTYPE_BUFFER:
1721 len = val->length;
1722 if (len >= sizeof(buffer))
1723 len = sizeof(buffer) - 1;
1724 memcpy(buffer, val->v_buffer, len)__builtin_memcpy((buffer), (val->_.vbuffer), (len));
1725 buffer[len] = 0;
1726 break;
1727 case AML_OBJTYPE_STRING:
1728 strlcpy(buffer, val->v_string_.vstring, sizeof(buffer));
1729 break;
1730 case AML_OBJTYPE_INTEGER:
1731 snprintf(buffer, sizeof(buffer), "%llx", val->v_integer_.vinteger);
1732 break;
1733 default:
1734 snprintf(buffer, sizeof(buffer),
1735 "Failed to convert type %d to string!", val->type);
1736 };
1737
1738 return (buffer);
1739}
1740#endif /* SMALL_KERNEL */
1741
1742int aml_error;
1743
1744struct aml_value *aml_gettgt(struct aml_value *, int);
1745struct aml_value *aml_eval(struct aml_scope *, struct aml_value *, int, int,
1746 struct aml_value *);
1747struct aml_value *aml_parsesimple(struct aml_scope *, char,
1748 struct aml_value *);
1749struct aml_value *aml_parse(struct aml_scope *, int, const char *);
1750struct aml_value *aml_seterror(struct aml_scope *, const char *, ...);
1751
1752struct aml_scope *aml_findscope(struct aml_scope *, int, int);
1753struct aml_scope *aml_pushscope(struct aml_scope *, struct aml_value *,
1754 struct aml_node *, int);
1755struct aml_scope *aml_popscope(struct aml_scope *);
1756
1757void aml_showstack(struct aml_scope *);
1758struct aml_value *aml_convert(struct aml_value *, int, int);
1759
1760int aml_matchtest(int64_t, int64_t, int);
1761int aml_match(struct aml_value *, int, int, int, int, int);
1762
1763int aml_compare(struct aml_value *, struct aml_value *, int);
1764struct aml_value *aml_concat(struct aml_value *, struct aml_value *);
1765struct aml_value *aml_concatres(struct aml_value *, struct aml_value *);
1766struct aml_value *aml_mid(struct aml_value *, int, int);
1767int aml_ccrlen(int, union acpi_resource *, void *);
1768
1769void aml_store(struct aml_scope *, struct aml_value *, int64_t,
1770 struct aml_value *);
1771
1772/*
1773 * Reference Count functions
1774 */
1775void
1776aml_addref(struct aml_value *val, const char *lbl)
1777{
1778 if (val == NULL((void *)0))
1779 return;
1780 dnprintf(50, "XAddRef: %p %s:[%s] %d\n",
1781 val, lbl,
1782 val->node ? aml_nodename(val->node) : "INTERNAL",
1783 val->refcnt);
1784 val->refcnt++;
1785}
1786
1787/* Decrease reference counter */
1788void
1789aml_delref(struct aml_value **pv, const char *lbl)
1790{
1791 struct aml_value *val;
1792
1793 if (pv == NULL((void *)0) || *pv == NULL((void *)0))
1794 return;
1795 val = *pv;
1796 val->refcnt--;
1797 if (val->refcnt == 0) {
1798 dnprintf(50, "XDelRef: %p %s %2d [%s] %s\n",
1799 val, lbl,
1800 val->refcnt,
1801 val->node ? aml_nodename(val->node) : "INTERNAL",
1802 val->refcnt ? "" : "---------------- FREEING");
1803
1804 aml_freevalue(val);
1805 acpi_os_free(val)_acpi_os_free(val, __FUNCTION__, 1805);
1806 *pv = NULL((void *)0);
1807 }
1808}
1809
1810/* Walk list of parent scopes until we find one of 'type'
1811 * If endscope is set, mark all intermediate scopes as invalid (used for Method/While) */
1812struct aml_scope *
1813aml_findscope(struct aml_scope *scope, int type, int endscope)
1814{
1815 while (scope) {
1816 switch (endscope) {
1817 case AMLOP_RETURN0xA4:
1818 scope->pos = scope->end;
1819 if (scope->type == AMLOP_WHILE0xA2)
1820 scope->pos = NULL((void *)0);
1821 break;
1822 case AMLOP_CONTINUE0x9F:
1823 scope->pos = scope->end;
1824 break;
1825 case AMLOP_BREAK0xA5:
1826 scope->pos = scope->end;
1827 if (scope->type == type)
1828 scope->parent->pos = scope->end;
1829 break;
1830 }
1831 if (scope->type == type)
1832 break;
1833 scope = scope->parent;
1834 }
1835 return scope;
1836}
1837
1838struct aml_value *
1839aml_getstack(struct aml_scope *scope, int opcode)
1840{
1841 struct aml_value *sp;
1842
1843 sp = NULL((void *)0);
1844 scope = aml_findscope(scope, AMLOP_METHOD0x14, 0);
1845 if (scope == NULL((void *)0))
1846 return NULL((void *)0);
1847 if (opcode >= AMLOP_LOCAL00x60 && opcode <= AMLOP_LOCAL70x67) {
1848 if (scope->locals == NULL((void *)0))
1849 scope->locals = aml_allocvalue(AML_OBJTYPE_PACKAGE, 8, NULL((void *)0));
1850 sp = scope->locals->v_package_.vpackage[opcode - AMLOP_LOCAL00x60];
1851 sp->stack = opcode;
1852 } else if (opcode >= AMLOP_ARG00x68 && opcode <= AMLOP_ARG60x6E) {
1853 if (scope->args == NULL((void *)0))
1854 scope->args = aml_allocvalue(AML_OBJTYPE_PACKAGE, 7, NULL((void *)0));
1855 sp = scope->args->v_package_.vpackage[opcode - AMLOP_ARG00x68];
1856 if (sp->type == AML_OBJTYPE_OBJREF)
1857 sp = sp->v_objref_.vobjref.ref;
1858 }
1859 return sp;
1860}
1861
1862#ifdef ACPI_DEBUG
1863/* Dump AML Stack */
1864void
1865aml_showstack(struct aml_scope *scope)
1866{
1867 struct aml_value *sp;
1868 int idx;
1869
1870 dnprintf(10, "===== Stack %s:%s\n", aml_nodename(scope->node),
1871 aml_mnem(scope->type, 0));
1872 for (idx=0; scope->args && idx<7; idx++) {
1873 sp = aml_getstack(scope, AMLOP_ARG00x68+idx);
1874 if (sp && sp->type) {
1875 dnprintf(10," Arg%d: ", idx);
1876 aml_showvalue(sp);
1877 }
1878 }
1879 for (idx=0; scope->locals && idx<8; idx++) {
1880 sp = aml_getstack(scope, AMLOP_LOCAL00x60+idx);
1881 if (sp && sp->type) {
1882 dnprintf(10," Local%d: ", idx);
1883 aml_showvalue(sp);
1884 }
1885 }
1886}
1887#endif
1888
1889/* Create a new scope object */
1890struct aml_scope *
1891aml_pushscope(struct aml_scope *parent, struct aml_value *range,
1892 struct aml_node *node, int type)
1893{
1894 struct aml_scope *scope;
1895 uint8_t *start, *end;
1896
1897 if (range->type == AML_OBJTYPE_METHOD) {
1898 start = range->v_method_.vmethod.start;
1899 end = range->v_method_.vmethod.end;
1900 } else {
1901 start = range->v_buffer_.vbuffer;
1902 end = start + range->length;
1903 if (start == end)
1904 return NULL((void *)0);
1905 }
1906 scope = acpi_os_malloc(sizeof(struct aml_scope))_acpi_os_malloc(sizeof(struct aml_scope), __FUNCTION__, 1906);
1907 if (scope == NULL((void *)0))
1908 return NULL((void *)0);
1909
1910 scope->node = node;
1911 scope->start = start;
1912 scope->end = end;
1913 scope->pos = scope->start;
1914 scope->parent = parent;
1915 scope->type = type;
1916 scope->sc = acpi_softc;
1917
1918 if (parent)
1919 scope->depth = parent->depth+1;
1920
1921 aml_lastscope = scope;
1922
1923 return scope;
1924}
1925
1926/* Free a scope object and any children */
1927struct aml_scope *
1928aml_popscope(struct aml_scope *scope)
1929{
1930 struct aml_scope *nscope;
1931
1932 if (scope == NULL((void *)0))
1933 return NULL((void *)0);
1934
1935 nscope = scope->parent;
1936
1937 if (scope->type == AMLOP_METHOD0x14)
1938 aml_delchildren(scope->node);
1939 if (scope->locals) {
1940 aml_freevalue(scope->locals);
1941 acpi_os_free(scope->locals)_acpi_os_free(scope->locals, __FUNCTION__, 1941);
1942 scope->locals = NULL((void *)0);
1943 }
1944 if (scope->args) {
1945 aml_freevalue(scope->args);
1946 acpi_os_free(scope->args)_acpi_os_free(scope->args, __FUNCTION__, 1946);
1947 scope->args = NULL((void *)0);
1948 }
1949 acpi_os_free(scope)_acpi_os_free(scope, __FUNCTION__, 1949);
1950 aml_lastscope = nscope;
1951
1952 return nscope;
1953}
1954
1955/* Test AMLOP_MATCH codes */
1956int
1957aml_matchtest(int64_t a, int64_t b, int op)
1958{
1959 switch (op) {
1960 case AML_MATCH_TR0:
1961 return (1);
1962 case AML_MATCH_EQ1:
1963 return (a == b);
1964 case AML_MATCH_LT3:
1965 return (a < b);
1966 case AML_MATCH_LE2:
1967 return (a <= b);
1968 case AML_MATCH_GE4:
1969 return (a >= b);
1970 case AML_MATCH_GT5:
1971 return (a > b);
1972 }
1973 return (0);
1974}
1975
1976/* Search a package for a matching value */
1977int
1978aml_match(struct aml_value *pkg, int index,
1979 int op1, int v1,
1980 int op2, int v2)
1981{
1982 struct aml_value *tmp;
1983 int flag;
1984
1985 while (index < pkg->length) {
1986 /* Convert package value to integer */
1987 tmp = aml_convert(pkg->v_package_.vpackage[index],
1988 AML_OBJTYPE_INTEGER, -1);
1989
1990 /* Perform test */
1991 flag = aml_matchtest(tmp->v_integer_.vinteger, v1, op1) &&
1992 aml_matchtest(tmp->v_integer_.vinteger, v2, op2);
1993 aml_delref(&tmp, "xmatch");
1994
1995 if (flag)
1996 return index;
1997 index++;
1998 }
1999 return -1;
2000}
2001
2002/*
2003 * Conversion routines
2004 */
2005int64_t
2006aml_hextoint(const char *str)
2007{
2008 int64_t v = 0;
2009 char c;
2010
2011 while (*str) {
2012 if (*str >= '0' && *str <= '9')
2013 c = *(str++) - '0';
2014 else if (*str >= 'a' && *str <= 'f')
2015 c = *(str++) - 'a' + 10;
2016 else if (*str >= 'A' && *str <= 'F')
2017 c = *(str++) - 'A' + 10;
2018 else
2019 break;
2020 v = (v << 4) + c;
2021 }
2022 return v;
2023
2024}
2025
2026struct aml_value *
2027aml_convert(struct aml_value *a, int ctype, int clen)
2028{
2029 struct aml_value *c = NULL((void *)0);
2030
2031 /* Object is already this type */
2032 if (clen == -1)
2033 clen = a->length;
2034 if (a->type == ctype) {
2035 aml_addref(a, "XConvert");
2036 return a;
2037 }
2038 switch (ctype) {
2039 case AML_OBJTYPE_BUFFER:
2040 dnprintf(10,"convert to buffer\n");
2041 switch (a->type) {
2042 case AML_OBJTYPE_INTEGER:
2043 c = aml_allocvalue(AML_OBJTYPE_BUFFER, a->length,
2044 &a->v_integer_.vinteger);
2045 break;
2046 case AML_OBJTYPE_STRING:
2047 c = aml_allocvalue(AML_OBJTYPE_BUFFER, a->length,
2048 a->v_string_.vstring);
2049 break;
2050 }
2051 break;
2052 case AML_OBJTYPE_INTEGER:
2053 dnprintf(10,"convert to integer : %x\n", a->type);
2054 switch (a->type) {
2055 case AML_OBJTYPE_BUFFER:
2056 c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL((void *)0));
2057 memcpy(&c->v_integer, a->v_buffer,__builtin_memcpy((&c->_.vinteger), (a->_.vbuffer), (
min(a->length, c->length)))
2058 min(a->length, c->length))__builtin_memcpy((&c->_.vinteger), (a->_.vbuffer), (
min(a->length, c->length)))
;
2059 break;
2060 case AML_OBJTYPE_STRING:
2061 c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL((void *)0));
2062 c->v_integer_.vinteger = aml_hextoint(a->v_string_.vstring);
2063 break;
2064 case AML_OBJTYPE_UNINITIALIZED:
2065 c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL((void *)0));
2066 break;
2067 }
2068 break;
2069 case AML_OBJTYPE_STRING:
2070 case AML_OBJTYPE_HEXSTRING:
2071 case AML_OBJTYPE_DECSTRING:
2072 dnprintf(10,"convert to string\n");
2073 switch (a->type) {
2074 case AML_OBJTYPE_INTEGER:
2075 c = aml_allocvalue(AML_OBJTYPE_STRING, 20, NULL((void *)0));
2076 snprintf(c->v_string_.vstring, c->length, (ctype == AML_OBJTYPE_HEXSTRING) ?
2077 "0x%llx" : "%lld", a->v_integer_.vinteger);
2078 break;
2079 case AML_OBJTYPE_BUFFER:
2080 c = aml_allocvalue(AML_OBJTYPE_STRING, a->length,
2081 a->v_buffer_.vbuffer);
2082 break;
2083 case AML_OBJTYPE_STRING:
2084 aml_addref(a, "XConvert");
2085 return a;
2086 case AML_OBJTYPE_PACKAGE: /* XXX Deal with broken Lenovo X1 BIOS. */
2087 c = aml_allocvalue(AML_OBJTYPE_STRING, 0, NULL((void *)0));
2088 break;
2089 }
2090 break;
2091 }
2092 if (c == NULL((void *)0)) {
2093#ifndef SMALL_KERNEL
2094 aml_showvalue(a);
2095#endif
2096 aml_die("Could not convert %x to %x\n", a->type, ctype)_aml_die(__FUNCTION__, 2096, "Could not convert %x to %x\n", a
->type, ctype)
;
2097 }
2098 return c;
2099}
2100
2101int
2102aml_compare(struct aml_value *a1, struct aml_value *a2, int opcode)
2103{
2104 int rc = 0;
2105
2106 /* Convert A2 to type of A1 */
2107 a2 = aml_convert(a2, a1->type, -1);
2108 if (a1->type == AML_OBJTYPE_INTEGER)
2109 rc = aml_evalexpr(a1->v_integer_.vinteger, a2->v_integer_.vinteger, opcode);
2110 else {
2111 /* Perform String/Buffer comparison */
2112 rc = memcmp(a1->v_buffer, a2->v_buffer,__builtin_memcmp((a1->_.vbuffer), (a2->_.vbuffer), (min
(a1->length, a2->length)))
2113 min(a1->length, a2->length))__builtin_memcmp((a1->_.vbuffer), (a2->_.vbuffer), (min
(a1->length, a2->length)))
;
2114 if (rc == 0) {
2115 /* If buffers match, which one is longer */
2116 rc = a1->length - a2->length;
2117 }
2118 /* Perform comparison against zero */
2119 rc = aml_evalexpr(rc, 0, opcode);
2120 }
2121 /* Either deletes temp buffer, or decrease refcnt on original A2 */
2122 aml_delref(&a2, "xcompare");
2123 return rc;
2124}
2125
2126/* Concatenate two objects, returning pointer to new object */
2127struct aml_value *
2128aml_concat(struct aml_value *a1, struct aml_value *a2)
2129{
2130 struct aml_value *c = NULL((void *)0);
2131
2132 /* Convert arg2 to type of arg1 */
2133 a2 = aml_convert(a2, a1->type, -1);
2134 switch (a1->type) {
2135 case AML_OBJTYPE_INTEGER:
2136 c = aml_allocvalue(AML_OBJTYPE_BUFFER,
2137 a1->length + a2->length, NULL((void *)0));
2138 memcpy(c->v_buffer, &a1->v_integer, a1->length)__builtin_memcpy((c->_.vbuffer), (&a1->_.vinteger),
(a1->length))
;
2139 memcpy(c->v_buffer+a1->length, &a2->v_integer, a2->length)__builtin_memcpy((c->_.vbuffer+a1->length), (&a2->
_.vinteger), (a2->length))
;
2140 break;
2141 case AML_OBJTYPE_BUFFER:
2142 c = aml_allocvalue(AML_OBJTYPE_BUFFER,
2143 a1->length + a2->length, NULL((void *)0));
2144 memcpy(c->v_buffer, a1->v_buffer, a1->length)__builtin_memcpy((c->_.vbuffer), (a1->_.vbuffer), (a1->
length))
;
2145 memcpy(c->v_buffer+a1->length, a2->v_buffer, a2->length)__builtin_memcpy((c->_.vbuffer+a1->length), (a2->_.vbuffer
), (a2->length))
;
2146 break;
2147 case AML_OBJTYPE_STRING:
2148 c = aml_allocvalue(AML_OBJTYPE_STRING,
2149 a1->length + a2->length, NULL((void *)0));
2150 memcpy(c->v_string, a1->v_string, a1->length)__builtin_memcpy((c->_.vstring), (a1->_.vstring), (a1->
length))
;
2151 memcpy(c->v_string+a1->length, a2->v_string, a2->length)__builtin_memcpy((c->_.vstring+a1->length), (a2->_.vstring
), (a2->length))
;
2152 break;
2153 default:
2154 aml_die("concat type mismatch %d != %d\n", a1->type, a2->type)_aml_die(__FUNCTION__, 2154, "concat type mismatch %d != %d\n"
, a1->type, a2->type)
;
2155 break;
2156 }
2157 /* Either deletes temp buffer, or decrease refcnt on original A2 */
2158 aml_delref(&a2, "xconcat");
2159 return c;
2160}
2161
2162/* Calculate length of Resource Template */
2163int
2164aml_ccrlen(int crsidx, union acpi_resource *rs, void *arg)
2165{
2166 int *plen = arg;
2167
2168 *plen += AML_CRSLEN(rs)((rs)->hdr.typecode & 0x80 ? 3+(rs)->hdr.length : 1
+((rs)->hdr.typecode & 0x7))
;
2169 return (0);
2170}
2171
2172/* Concatenate resource templates, returning pointer to new object */
2173struct aml_value *
2174aml_concatres(struct aml_value *a1, struct aml_value *a2)
2175{
2176 struct aml_value *c;
2177 int l1 = 0, l2 = 0, l3 = 2;
2178 uint8_t a3[] = { SRT_ENDTAG0x79, 0x00 };
2179
2180 if (a1->type != AML_OBJTYPE_BUFFER || a2->type != AML_OBJTYPE_BUFFER)
2181 aml_die("concatres: not buffers\n")_aml_die(__FUNCTION__, 2181, "concatres: not buffers\n");
2182
2183 /* Walk a1, a2, get length minus end tags, concatenate buffers, add end tag */
2184 aml_parse_resource(a1, aml_ccrlen, &l1);
2185 aml_parse_resource(a2, aml_ccrlen, &l2);
2186
2187 /* Concatenate buffers, add end tag */
2188 c = aml_allocvalue(AML_OBJTYPE_BUFFER, l1+l2+l3, NULL((void *)0));
2189 memcpy(c->v_buffer, a1->v_buffer, l1)__builtin_memcpy((c->_.vbuffer), (a1->_.vbuffer), (l1));
2190 memcpy(c->v_buffer+l1, a2->v_buffer, l2)__builtin_memcpy((c->_.vbuffer+l1), (a2->_.vbuffer), (l2
))
;
2191 memcpy(c->v_buffer+l1+l2, a3, l3)__builtin_memcpy((c->_.vbuffer+l1+l2), (a3), (l3));
2192
2193 return c;
2194}
2195
2196/* Extract substring from string or buffer */
2197struct aml_value *
2198aml_mid(struct aml_value *src, int index, int length)
2199{
2200 if (index > src->length)
2201 index = src->length;
2202 if ((index + length) > src->length)
2203 length = src->length - index;
2204 return aml_allocvalue(src->type, length, src->v_buffer_.vbuffer + index);
2205}
2206
2207/*
2208 * Field I/O utility functions
2209 */
2210void aml_createfield(struct aml_value *, int, struct aml_value *, int, int,
2211 struct aml_value *, int, int);
2212void aml_parsefieldlist(struct aml_scope *, int, int,
2213 struct aml_value *, struct aml_value *, int);
2214
2215int
2216aml_evalhid(struct aml_node *node, struct aml_value *val)
2217{
2218 if (aml_evalname(acpi_softc, node, "_HID", 0, NULL((void *)0), val))
2219 return (-1);
2220
2221 /* Integer _HID: convert to EISA ID */
2222 if (val->type == AML_OBJTYPE_INTEGER)
2223 _aml_setvalue(val, AML_OBJTYPE_STRING, -1, aml_eisaid(val->v_integer_.vinteger));
2224 return (0);
2225}
2226
2227int
2228aml_opreg_sysmem_handler(void *cookie, int iodir, uint64_t address, int size,
2229 uint64_t *value)
2230{
2231 return acpi_gasio(acpi_softc, iodir, GAS_SYSTEM_MEMORY0,
2232 address, size, size, value);
2233}
2234
2235int
2236aml_opreg_sysio_handler(void *cookie, int iodir, uint64_t address, int size,
2237 uint64_t *value)
2238{
2239 return acpi_gasio(acpi_softc, iodir, GAS_SYSTEM_IOSPACE1,
2240 address, size, size, value);
2241}
2242
2243int
2244aml_opreg_pcicfg_handler(void *cookie, int iodir, uint64_t address, int size,
2245 uint64_t *value)
2246{
2247 return acpi_gasio(acpi_softc, iodir, GAS_PCI_CFG_SPACE2,
2248 address, size, size, value);
2249}
2250
2251int
2252aml_opreg_ec_handler(void *cookie, int iodir, uint64_t address, int size,
2253 uint64_t *value)
2254{
2255 return acpi_gasio(acpi_softc, iodir, GAS_EMBEDDED3,
2256 address, size, size, value);
2257}
2258
2259struct aml_regionspace {
2260 void *cookie;
2261 int (*handler)(void *, int, uint64_t, int, uint64_t *);
2262};
2263
2264struct aml_regionspace aml_regionspace[256] = {
2265 [ACPI_OPREG_SYSMEM0] = { NULL((void *)0), aml_opreg_sysmem_handler },
2266 [ACPI_OPREG_SYSIO1] = { NULL((void *)0), aml_opreg_sysio_handler },
2267 [ACPI_OPREG_PCICFG2] = { NULL((void *)0), aml_opreg_pcicfg_handler },
2268 [ACPI_OPREG_EC3] = { NULL((void *)0), aml_opreg_ec_handler },
2269};
2270
2271void
2272aml_register_regionspace(struct aml_node *node, int iospace, void *cookie,
2273 int (*handler)(void *, int, uint64_t, int, uint64_t *))
2274{
2275 struct aml_value arg[2];
2276
2277 KASSERT(iospace >= 0 && iospace < 256)((iospace >= 0 && iospace < 256) ? (void)0 : __assert
("diagnostic ", "/usr/src/sys/dev/acpi/dsdt.c", 2277, "iospace >= 0 && iospace < 256"
))
;
2278
2279 aml_regionspace[iospace].cookie = cookie;
2280 aml_regionspace[iospace].handler = handler;
2281
2282 /* Register address space. */
2283 memset(&arg, 0, sizeof(arg))__builtin_memset((&arg), (0), (sizeof(arg)));
2284 arg[0].type = AML_OBJTYPE_INTEGER;
2285 arg[0].v_integer_.vinteger = iospace;
2286 arg[1].type = AML_OBJTYPE_INTEGER;
2287 arg[1].v_integer_.vinteger = 1;
2288 node = aml_searchname(node, "_REG");
2289 if (node)
2290 aml_evalnode(acpi_softc, node, 2, arg, NULL((void *)0));
2291}
2292
2293void aml_rwgen(struct aml_value *, int, int, struct aml_value *, int, int);
2294void aml_rwgpio(struct aml_value *, int, int, struct aml_value *, int, int);
2295void aml_rwgsb(struct aml_value *, int, int, int, struct aml_value *, int, int);
2296void aml_rwindexfield(struct aml_value *, struct aml_value *val, int);
2297void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int);
2298
2299/* Get PCI address for opregion objects */
2300int
2301aml_rdpciaddr(struct aml_node *pcidev, union amlpci_t *addr)
2302{
2303 int64_t res;
2304
2305 addr->bus = 0;
2306 addr->seg = 0;
2307 if (aml_evalinteger(acpi_softc, pcidev, "_ADR", 0, NULL((void *)0), &res) == 0) {
2308 addr->fun = res & 0xFFFF;
2309 addr->dev = res >> 16;
2310 }
2311 while (pcidev != NULL((void *)0)) {
2312 /* HID device (PCI or PCIE root): eval _SEG and _BBN */
2313 if (__aml_search(pcidev, "_HID", 0)) {
2314 if (aml_evalinteger(acpi_softc, pcidev, "_SEG",
2315 0, NULL((void *)0), &res) == 0) {
2316 addr->seg = res;
2317 }
2318 if (aml_evalinteger(acpi_softc, pcidev, "_BBN",
2319 0, NULL((void *)0), &res) == 0) {
2320 addr->bus = res;
2321 break;
2322 }
2323 }
2324 pcidev = pcidev->parent;
2325 }
2326 return (0);
2327}
2328
2329int
2330acpi_genio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
2331 int access_size, int len, void *buffer)
2332{
2333 struct aml_regionspace *region = &aml_regionspace[iospace];
2334 uint8_t *pb;
2335 int reg;
2336
2337 dnprintf(50, "genio: %.2x 0x%.8llx %s\n",
2338 iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read");
2339
2340 KASSERT((len % access_size) == 0)(((len % access_size) == 0) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/acpi/dsdt.c", 2340, "(len % access_size) == 0"
))
;
2341
2342 pb = (uint8_t *)buffer;
2343 for (reg = 0; reg < len; reg += access_size) {
2344 uint64_t value;
2345 int err;
2346
2347 if (iodir == ACPI_IOREAD0) {
2348 err = region->handler(region->cookie, iodir,
2349 address + reg, access_size, &value);
2350 if (err)
2351 return err;
2352 switch (access_size) {
2353 case 1:
2354 *(uint8_t *)(pb + reg) = value;
2355 break;
2356 case 2:
2357 *(uint16_t *)(pb + reg) = value;
2358 break;
2359 case 4:
2360 *(uint32_t *)(pb + reg) = value;
2361 break;
2362 default:
2363 printf("%s: invalid access size %d on read\n",
2364 __func__, access_size);
2365 return -1;
2366 }
2367 } else {
2368 switch (access_size) {
2369 case 1:
2370 value = *(uint8_t *)(pb + reg);
2371 break;
2372 case 2:
2373 value = *(uint16_t *)(pb + reg);
2374 break;
2375 case 4:
2376 value = *(uint32_t *)(pb + reg);
2377 break;
2378 default:
2379 printf("%s: invalid access size %d on write\n",
2380 __func__, access_size);
2381 return -1;
2382 }
2383 err = region->handler(region->cookie, iodir,
2384 address + reg, access_size, &value);
2385 if (err)
2386 return err;
2387 }
2388 }
2389
2390 return 0;
2391}
2392
2393/* Read/Write from opregion object */
2394void
2395aml_rwgen(struct aml_value *rgn, int bpos, int blen, struct aml_value *val,
2396 int mode, int flag)
2397{
2398 struct aml_value tmp;
2399 union amlpci_t pi;
2400 void *tbit, *vbit;
2401 int tlen, type, sz;
2402
2403 dnprintf(10," %5s %.2x %.8llx %.4x [%s]\n",
2404 mode == ACPI_IOREAD ? "read" : "write",
2405 rgn->v_opregion.iospace,
2406 rgn->v_opregion.iobase + (bpos >> 3),
2407 blen, aml_nodename(rgn->node));
2408 memset(&tmp, 0, sizeof(tmp))__builtin_memset((&tmp), (0), (sizeof(tmp)));
2409
2410 /* Get field access size */
2411 switch (AML_FIELD_ACCESS(flag)(((flag) >> 0) & 0xF)) {
2412 case AML_FIELD_WORDACC0x2:
2413 sz = 2;
2414 break;
2415 case AML_FIELD_DWORDACC0x3:
2416 sz = 4;
2417 break;
2418 case AML_FIELD_QWORDACC0x4:
2419 sz = 8;
2420 break;
2421 default:
2422 sz = 1;
2423 break;
2424 }
2425
2426 pi.addr = (rgn->v_opregion_.vopregion.iobase + (bpos >> 3)) & ~(sz - 1);
2427 bpos += ((rgn->v_opregion_.vopregion.iobase & (sz - 1)) << 3);
2428 bpos &= ((sz << 3) - 1);
2429
2430 if (rgn->v_opregion_.vopregion.iospace == ACPI_OPREG_PCICFG2) {
2431 /* Get PCI Root Address for this opregion */
2432 aml_rdpciaddr(rgn->node->parent, &pi);
2433 }
2434
2435 tbit = &tmp.v_integer_.vinteger;
2436 vbit = &val->v_integer_.vinteger;
2437 tlen = roundup(bpos + blen, sz << 3)((((bpos + blen)+((sz << 3)-1))/(sz << 3))*(sz <<
3))
;
2438 type = rgn->v_opregion_.vopregion.iospace;
2439
2440 if (aml_regionspace[type].handler == NULL((void *)0)) {
2441 printf("%s: unregistered RegionSpace 0x%x\n", __func__, type);
2442 return;
2443 }
2444
2445 /* Allocate temporary storage */
2446 if (tlen > aml_intlen) {
2447 _aml_setvalue(&tmp, AML_OBJTYPE_BUFFER, tlen >> 3, 0);
2448 tbit = tmp.v_buffer_.vbuffer;
2449 }
2450
2451 if (blen > aml_intlen) {
2452 if (mode == ACPI_IOREAD0) {
2453 /* Read from a large field: create buffer */
2454 _aml_setvalue(val, AML_OBJTYPE_BUFFER, (blen + 7) >> 3, 0);
2455 } else {
2456 /* Write to a large field.. create or convert buffer */
2457 val = aml_convert(val, AML_OBJTYPE_BUFFER, -1);
2458
2459 if (blen > (val->length << 3))
2460 blen = val->length << 3;
2461 }
2462 vbit = val->v_buffer_.vbuffer;
2463 } else {
2464 if (mode == ACPI_IOREAD0) {
2465 /* Read from a short field.. initialize integer */
2466 _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2467 } else {
2468 /* Write to a short field.. convert to integer */
2469 val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
2470 }
2471 }
2472
2473 if (mode == ACPI_IOREAD0) {
2474 /* Read bits from opregion */
2475 acpi_genio(acpi_softc, ACPI_IOREAD0, type, pi.addr,
2476 sz, tlen >> 3, tbit);
2477 aml_bufcpy(vbit, 0, tbit, bpos, blen);
2478 } else {
2479 /* Write bits to opregion */
2480 if (AML_FIELD_UPDATE(flag)(((flag) >> 5) & 0x3) == AML_FIELD_PRESERVE0x0 &&
2481 (bpos != 0 || blen != tlen)) {
2482 acpi_genio(acpi_softc, ACPI_IOREAD0, type, pi.addr,
2483 sz, tlen >> 3, tbit);
2484 } else if (AML_FIELD_UPDATE(flag)(((flag) >> 5) & 0x3) == AML_FIELD_WRITEASONES0x1) {
2485 memset(tbit, 0xff, tmp.length)__builtin_memset((tbit), (0xff), (tmp.length));
2486 }
2487 /* Copy target bits, then write to region */
2488 aml_bufcpy(tbit, bpos, vbit, 0, blen);
2489 acpi_genio(acpi_softc, ACPI_IOWRITE1, type, pi.addr,
2490 sz, tlen >> 3, tbit);
2491
2492 aml_delref(&val, "fld.write");
2493 }
2494 aml_freevalue(&tmp);
2495}
2496
2497void
2498aml_rwgpio(struct aml_value *conn, int bpos, int blen, struct aml_value *val,
2499 int mode, int flag)
2500{
2501 union acpi_resource *crs = (union acpi_resource *)conn->v_buffer_.vbuffer;
2502 struct aml_node *node;
2503 uint16_t pin;
2504 int v = 0;
2505
2506 if (conn->type != AML_OBJTYPE_BUFFER || conn->length < 5 ||
2507 AML_CRSTYPE(crs)((crs)->hdr.typecode & 0x80 ? (crs)->hdr.typecode :
(crs)->hdr.typecode >> 3)
!= LR_GPIO0x8C || AML_CRSLEN(crs)((crs)->hdr.typecode & 0x80 ? 3+(crs)->hdr.length :
1+((crs)->hdr.typecode & 0x7))
> conn->length)
2508 aml_die("Invalid GpioIo")_aml_die(__FUNCTION__, 2508, "Invalid GpioIo");
2509 if (bpos != 0 || blen != 1)
2510 aml_die("Invalid GpioIo access")_aml_die(__FUNCTION__, 2510, "Invalid GpioIo access");
2511
2512 node = aml_searchname(conn->node,
2513 (char *)&crs->pad[crs->lr_gpio.res_off]);
2514 pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
2515
2516 if (node == NULL((void *)0) || node->gpio == NULL((void *)0))
2517 aml_die("Could not find GpioIo pin")_aml_die(__FUNCTION__, 2517, "Could not find GpioIo pin");
2518
2519 if (mode == ACPI_IOWRITE1) {
2520 v = aml_val2int(val);
2521 node->gpio->write_pin(node->gpio->cookie, pin, v);
2522 } else {
2523 v = node->gpio->read_pin(node->gpio->cookie, pin);
2524 _aml_setvalue(val, AML_OBJTYPE_INTEGER, v, NULL((void *)0));
2525 }
2526}
2527
2528#ifndef SMALL_KERNEL
2529
2530void
2531aml_rwgsb(struct aml_value *conn, int len, int bpos, int blen,
2532 struct aml_value *val, int mode, int flag)
2533{
2534 union acpi_resource *crs = (union acpi_resource *)conn->v_buffer_.vbuffer;
2535 struct aml_node *node;
2536 i2c_tag_t tag;
2537 i2c_op_t op;
2538 i2c_addr_t addr;
2539 int cmdlen, buflen;
2540 uint8_t cmd[2];
2541 uint8_t *buf;
2542 int err;
2543
2544 if (conn->type != AML_OBJTYPE_BUFFER || conn->length < 5 ||
2545 AML_CRSTYPE(crs)((crs)->hdr.typecode & 0x80 ? (crs)->hdr.typecode :
(crs)->hdr.typecode >> 3)
!= LR_SERBUS0x8E || AML_CRSLEN(crs)((crs)->hdr.typecode & 0x80 ? 3+(crs)->hdr.length :
1+((crs)->hdr.typecode & 0x7))
> conn->length ||
2546 crs->lr_i2cbus.revid != 1 || crs->lr_i2cbus.type != LR_SERBUS_I2C1)
2547 aml_die("Invalid GenericSerialBus")_aml_die(__FUNCTION__, 2547, "Invalid GenericSerialBus");
2548 if (AML_FIELD_ACCESS(flag)(((flag) >> 0) & 0xF) != AML_FIELD_BUFFERACC0x5 ||
2549 bpos & 0x3 || (blen % 8) != 0 || blen > 16)
2550 aml_die("Invalid GenericSerialBus access")_aml_die(__FUNCTION__, 2550, "Invalid GenericSerialBus access"
)
;
2551
2552 node = aml_searchname(conn->node,
2553 (char *)&crs->lr_i2cbus.vdata[crs->lr_i2cbus.tlength - 6]);
2554
2555 switch (((flag >> 6) & 0x3)) {
2556 case 0: /* Normal */
2557 switch (AML_FIELD_ATTR(flag)((flag) >> 8)) {
2558 case 0x02: /* AttribQuick */
2559 cmdlen = 0;
2560 buflen = 0;
2561 break;
2562 case 0x04: /* AttribSendReceive */
2563 cmdlen = 0;
2564 buflen = 1;
2565 break;
2566 case 0x06: /* AttribByte */
2567 cmdlen = blen / 8;
2568 buflen = 1;
2569 break;
2570 case 0x08: /* AttribWord */
2571 cmdlen = blen / 8;
2572 buflen = 2;
2573 break;
2574 case 0x0b: /* AttribBytes */
2575 cmdlen = blen / 8;
2576 buflen = len;
2577 break;
2578 case 0x0e: /* AttribRawBytes */
2579 cmdlen = 0;
2580 buflen = len;
2581 break;
2582 default:
2583 aml_die("unsupported access type 0x%x", flag)_aml_die(__FUNCTION__, 2583, "unsupported access type 0x%x", flag
)
;
2584 break;
2585 }
2586 break;
2587 case 1: /* AttribBytes */
2588 cmdlen = blen / 8;
2589 buflen = AML_FIELD_ATTR(flag)((flag) >> 8);
2590 break;
2591 case 2: /* AttribRawBytes */
2592 cmdlen = 0;
2593 buflen = AML_FIELD_ATTR(flag)((flag) >> 8);
2594 break;
2595 default:
2596 aml_die("unsupported access type 0x%x", flag)_aml_die(__FUNCTION__, 2596, "unsupported access type 0x%x", flag
)
;
2597 break;
2598 }
2599
2600 if (mode == ACPI_IOREAD0) {
2601 _aml_setvalue(val, AML_OBJTYPE_BUFFER, buflen + 2, NULL((void *)0));
2602 op = I2C_OP_READ_WITH_STOP;
2603 } else {
2604 op = I2C_OP_WRITE_WITH_STOP;
2605 }
2606
2607 buf = val->v_buffer_.vbuffer;
2608
2609 /*
2610 * Return an error if we can't find the I2C controller that
2611 * we're supposed to use for this request.
2612 */
2613 if (node == NULL((void *)0) || node->i2c == NULL((void *)0)) {
2614 buf[0] = EIO5;
2615 return;
2616 }
2617
2618 tag = node->i2c;
2619 addr = crs->lr_i2cbus._adr;
2620 cmd[0] = bpos >> 3;
2621 cmd[1] = bpos >> 11;
2622
2623 iic_acquire_bus(tag, 0)(*(tag)->ic_acquire_bus)((tag)->ic_cookie, (0));
2624 err = iic_exec(tag, op, addr, &cmd, cmdlen, &buf[2], buflen, 0);
2625 iic_release_bus(tag, 0)(*(tag)->ic_release_bus)((tag)->ic_cookie, (0));
2626
2627 /*
2628 * The ACPI specification doesn't tell us what the status
2629 * codes mean beyond implying that zero means success. So use
2630 * the error returned from the transfer. All possible error
2631 * numbers should fit in a single byte.
2632 */
2633 buf[0] = err;
2634}
2635
2636#else
2637
2638/*
2639 * We don't support GenericSerialBus in RAMDISK kernels. Provide a
2640 * dummy implementation that returns a non-zero error status.
2641 */
2642
2643void
2644aml_rwgsb(struct aml_value *conn, int len, int bpos, int blen,
2645 struct aml_value *val, int mode, int flag)
2646{
2647 int buflen;
2648 uint8_t *buf;
2649
2650 if (AML_FIELD_ACCESS(flag)(((flag) >> 0) & 0xF) != AML_FIELD_BUFFERACC0x5 ||
2651 bpos & 0x3 || (blen % 8) != 0 || blen > 16)
2652 aml_die("Invalid GenericSerialBus access")_aml_die(__FUNCTION__, 2652, "Invalid GenericSerialBus access"
)
;
2653
2654 switch (((flag >> 6) & 0x3)) {
2655 case 0: /* Normal */
2656 switch (AML_FIELD_ATTR(flag)((flag) >> 8)) {
2657 case 0x02: /* AttribQuick */
2658 buflen = 0;
2659 break;
2660 case 0x04: /* AttribSendReceive */
2661 case 0x06: /* AttribByte */
2662 buflen = 1;
2663 break;
2664 case 0x08: /* AttribWord */
2665 buflen = 2;
2666 break;
2667 case 0x0b: /* AttribBytes */
2668 case 0x0e: /* AttribRawBytes */
2669 buflen = len;
2670 break;
2671 default:
2672 aml_die("unsupported access type 0x%x", flag)_aml_die(__FUNCTION__, 2672, "unsupported access type 0x%x", flag
)
;
2673 break;
2674 }
2675 break;
2676 case 1: /* AttribBytes */
2677 case 2: /* AttribRawBytes */
2678 buflen = AML_FIELD_ATTR(flag)((flag) >> 8);
2679 break;
2680 default:
2681 aml_die("unsupported access type 0x%x", flag)_aml_die(__FUNCTION__, 2681, "unsupported access type 0x%x", flag
)
;
2682 break;
2683 }
2684
2685 if (mode == ACPI_IOREAD0)
2686 _aml_setvalue(val, AML_OBJTYPE_BUFFER, buflen + 2, NULL((void *)0));
2687
2688 buf = val->v_buffer_.vbuffer;
2689 buf[0] = EIO5;
2690}
2691
2692#endif
2693
2694void
2695aml_rwindexfield(struct aml_value *fld, struct aml_value *val, int mode)
2696{
2697 struct aml_value tmp, *ref1, *ref2;
2698 void *tbit, *vbit;
2699 int vpos, bpos, blen;
2700 int indexval;
2701 int sz, len;
2702
2703 ref2 = fld->v_field_.vfield.ref2;
2704 ref1 = fld->v_field_.vfield.ref1;
2705 bpos = fld->v_field_.vfield.bitpos;
2706 blen = fld->v_field_.vfield.bitlen;
2707
2708 memset(&tmp, 0, sizeof(tmp))__builtin_memset((&tmp), (0), (sizeof(tmp)));
2709 tmp.refcnt = 99;
2710
2711 /* Get field access size */
2712 switch (AML_FIELD_ACCESS(fld->v_field.flags)(((fld->_.vfield.flags) >> 0) & 0xF)) {
2713 case AML_FIELD_WORDACC0x2:
2714 sz = 2;
2715 break;
2716 case AML_FIELD_DWORDACC0x3:
2717 sz = 4;
2718 break;
2719 case AML_FIELD_QWORDACC0x4:
2720 sz = 8;
2721 break;
2722 default:
2723 sz = 1;
2724 break;
2725 }
2726
2727 if (blen > aml_intlen) {
2728 if (mode == ACPI_IOREAD0) {
2729 /* Read from a large field: create buffer */
2730 _aml_setvalue(val, AML_OBJTYPE_BUFFER,
2731 (blen + 7) >> 3, 0);
2732 }
2733 vbit = val->v_buffer_.vbuffer;
2734 } else {
2735 if (mode == ACPI_IOREAD0) {
2736 /* Read from a short field: initialize integer */
2737 _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2738 }
2739 vbit = &val->v_integer_.vinteger;
2740 }
2741 tbit = &tmp.v_integer_.vinteger;
2742 vpos = 0;
2743
2744 indexval = (bpos >> 3) & ~(sz - 1);
2745 bpos = bpos - (indexval << 3);
2746
2747 while (blen > 0) {
2748 len = min(blen, (sz << 3) - bpos);
2749
2750 /* Write index register */
2751 _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, indexval, 0);
2752 aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE1);
2753 indexval += sz;
2754
2755 /* Read/write data register */
2756 _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, 0, 0);
2757 if (mode == ACPI_IOWRITE1)
2758 aml_bufcpy(tbit, 0, vbit, vpos, len);
2759 aml_rwfield(ref1, bpos, len, &tmp, mode);
2760 if (mode == ACPI_IOREAD0)
2761 aml_bufcpy(vbit, vpos, tbit, 0, len);
2762 vpos += len;
2763 blen -= len;
2764 bpos = 0;
2765 }
2766}
2767
2768void
2769aml_rwfield(struct aml_value *fld, int bpos, int blen, struct aml_value *val,
2770 int mode)
2771{
2772 struct aml_value tmp, *ref1, *ref2;
2773
2774 ref2 = fld->v_field_.vfield.ref2;
2775 ref1 = fld->v_field_.vfield.ref1;
2776 if (blen > fld->v_field_.vfield.bitlen)
2777 blen = fld->v_field_.vfield.bitlen;
2778
2779 aml_lockfield(NULL((void *)0), fld);
2780 memset(&tmp, 0, sizeof(tmp))__builtin_memset((&tmp), (0), (sizeof(tmp)));
2781 aml_addref(&tmp, "fld.write");
2782 if (fld->v_field_.vfield.type == AMLOP_INDEXFIELD0x5B86) {
2783 aml_rwindexfield(fld, val, mode);
2784 } else if (fld->v_field_.vfield.type == AMLOP_BANKFIELD0x5B87) {
2785 _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, fld->v_field_.vfield.ref3, 0);
2786 aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE1);
2787 aml_rwgen(ref1, fld->v_field_.vfield.bitpos, fld->v_field_.vfield.bitlen,
2788 val, mode, fld->v_field_.vfield.flags);
2789 } else if (fld->v_field_.vfield.type == AMLOP_FIELD0x5B81) {
2790 switch (ref1->v_opregion_.vopregion.iospace) {
2791 case ACPI_OPREG_GPIO8:
2792 aml_rwgpio(ref2, bpos, blen, val, mode,
2793 fld->v_field_.vfield.flags);
2794 break;
2795 case ACPI_OPREG_GSB9:
2796 aml_rwgsb(ref2, fld->v_field_.vfield.ref3,
2797 fld->v_field_.vfield.bitpos + bpos, blen,
2798 val, mode, fld->v_field_.vfield.flags);
2799 break;
2800 default:
2801 aml_rwgen(ref1, fld->v_field_.vfield.bitpos + bpos, blen,
2802 val, mode, fld->v_field_.vfield.flags);
2803 break;
2804 }
2805 } else if (mode == ACPI_IOREAD0) {
2806 /* bufferfield:read */
2807 _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2808 aml_bufcpy(&val->v_integer_.vinteger, 0, ref1->v_buffer_.vbuffer,
2809 fld->v_field_.vfield.bitpos, fld->v_field_.vfield.bitlen);
2810 } else {
2811 /* bufferfield:write */
2812 val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
2813 aml_bufcpy(ref1->v_buffer_.vbuffer, fld->v_field_.vfield.bitpos, &val->v_integer_.vinteger,
2814 0, fld->v_field_.vfield.bitlen);
2815 aml_delref(&val, "wrbuffld");
2816 }
2817 aml_unlockfield(NULL((void *)0), fld);
2818}
2819
2820/* Create Field Object data index
2821 * AMLOP_FIELD n:OpRegion NULL
2822 * AMLOP_INDEXFIELD n:Field n:Field
2823 * AMLOP_BANKFIELD n:OpRegion n:Field
2824 * AMLOP_CREATEFIELD t:Buffer NULL
2825 * AMLOP_CREATEBITFIELD t:Buffer NULL
2826 * AMLOP_CREATEBYTEFIELD t:Buffer NULL
2827 * AMLOP_CREATEWORDFIELD t:Buffer NULL
2828 * AMLOP_CREATEDWORDFIELD t:Buffer NULL
2829 * AMLOP_CREATEQWORDFIELD t:Buffer NULL
2830 * AMLOP_INDEX t:Buffer NULL
2831 */
2832void
2833aml_createfield(struct aml_value *field, int opcode,
2834 struct aml_value *data, int bpos, int blen,
2835 struct aml_value *index, int indexval, int flags)
2836{
2837 dnprintf(10, "## %s(%s): %s %.4x-%.4x\n",
2838 aml_mnem(opcode, 0),
2839 blen > aml_intlen ? "BUF" : "INT",
2840 aml_nodename(field->node), bpos, blen);
2841 if (index) {
2842 dnprintf(10, " index:%s:%.2x\n", aml_nodename(index->node),
2843 indexval);
2844 }
2845 dnprintf(10, " data:%s\n", aml_nodename(data->node));
2846 field->type = (opcode == AMLOP_FIELD0x5B81 ||
2847 opcode == AMLOP_INDEXFIELD0x5B86 ||
2848 opcode == AMLOP_BANKFIELD0x5B87) ?
2849 AML_OBJTYPE_FIELDUNIT :
2850 AML_OBJTYPE_BUFFERFIELD;
2851
2852 if (field->type == AML_OBJTYPE_BUFFERFIELD &&
2853 data->type != AML_OBJTYPE_BUFFER)
2854 data = aml_convert(data, AML_OBJTYPE_BUFFER, -1);
2855
2856 field->v_field_.vfield.type = opcode;
2857 field->v_field_.vfield.bitpos = bpos;
2858 field->v_field_.vfield.bitlen = blen;
2859 field->v_field_.vfield.ref3 = indexval;
2860 field->v_field_.vfield.ref2 = index;
2861 field->v_field_.vfield.ref1 = data;
2862 field->v_field_.vfield.flags = flags;
2863
2864 /* Increase reference count */
2865 aml_addref(data, "Field.Data");
2866 aml_addref(index, "Field.Index");
2867}
2868
2869/* Parse Field/IndexField/BankField scope */
2870void
2871aml_parsefieldlist(struct aml_scope *mscope, int opcode, int flags,
2872 struct aml_value *data, struct aml_value *index, int indexval)
2873{
2874 struct aml_value *conn = NULL((void *)0);
2875 struct aml_value *rv;
2876 int bpos, blen;
2877
2878 if (mscope == NULL((void *)0))
2879 return;
2880 bpos = 0;
2881 while (mscope->pos < mscope->end) {
2882 switch (*mscope->pos) {
2883 case 0x00: /* ReservedField */
2884 mscope->pos++;
2885 blen = aml_parselength(mscope);
2886 break;
2887 case 0x01: /* AccessField */
2888 mscope->pos++;
2889 blen = 0;
2890 flags = aml_get8(mscope->pos++)*(uint8_t *)(mscope->pos++);
2891 flags |= aml_get8(mscope->pos++)*(uint8_t *)(mscope->pos++) << 8;
2892 break;
2893 case 0x02: /* ConnectionField */
2894 mscope->pos++;
2895 blen = 0;
2896 conn = aml_parse(mscope, 'o', "Connection");
2897 if (conn == NULL((void *)0))
2898 aml_die("Could not parse connection")_aml_die(__FUNCTION__, 2898, "Could not parse connection");
2899 conn->node = mscope->node;
2900 break;
2901 case 0x03: /* ExtendedAccessField */
2902 mscope->pos++;
2903 blen = 0;
2904 flags = aml_get8(mscope->pos++)*(uint8_t *)(mscope->pos++);
2905 flags |= aml_get8(mscope->pos++)*(uint8_t *)(mscope->pos++) << 8;
2906 indexval = aml_get8(mscope->pos++)*(uint8_t *)(mscope->pos++);
2907 break;
2908 default: /* NamedField */
2909 mscope->pos = aml_parsename(mscope->node, mscope->pos,
2910 &rv, 1);
2911 blen = aml_parselength(mscope);
2912 aml_createfield(rv, opcode, data, bpos, blen,
2913 conn ? conn : index, indexval, flags);
2914 aml_delref(&rv, 0);
2915 break;
2916 }
2917 bpos += blen;
2918 }
2919 aml_popscope(mscope);
2920}
2921
2922/*
2923 * Mutex/Event utility functions
2924 */
2925int acpi_mutex_acquire(struct aml_scope *, struct aml_value *, int);
2926void acpi_mutex_release(struct aml_scope *, struct aml_value *);
2927int acpi_event_wait(struct aml_scope *, struct aml_value *, int);
2928void acpi_event_signal(struct aml_scope *, struct aml_value *);
2929void acpi_event_reset(struct aml_scope *, struct aml_value *);
2930
2931int
2932acpi_mutex_acquire(struct aml_scope *scope, struct aml_value *mtx,
2933 int timeout)
2934{
2935 if (mtx->v_mtx_.Vmutex.owner == NULL((void *)0) || scope == mtx->v_mtx_.Vmutex.owner) {
2936 /* We are now the owner */
2937 mtx->v_mtx_.Vmutex.owner = scope;
2938 if (mtx == aml_global_lock) {
2939 dnprintf(10,"LOCKING GLOBAL\n");
2940 acpi_glk_enter();
2941 }
2942 dnprintf(5,"%s acquires mutex %s\n", scope->node->name,
2943 mtx->node->name);
2944 return (0);
2945 } else if (timeout == 0) {
2946 return (-1);
2947 }
2948 /* Wait for mutex */
2949 return (0);
2950}
2951
2952void
2953acpi_mutex_release(struct aml_scope *scope, struct aml_value *mtx)
2954{
2955 if (mtx == aml_global_lock) {
2956 dnprintf(10,"UNLOCKING GLOBAL\n");
2957 acpi_glk_leave();
2958 }
2959 dnprintf(5, "%s releases mutex %s\n", scope->node->name,
2960 mtx->node->name);
2961 mtx->v_mtx_.Vmutex.owner = NULL((void *)0);
2962 /* Wakeup waiters */
2963}
2964
2965int
2966acpi_event_wait(struct aml_scope *scope, struct aml_value *evt, int timeout)
2967{
2968 /* Wait for event to occur; do work in meantime */
2969 while (evt->v_evt_.Vevent.state == 0 && timeout >= 0) {
2970 if (acpi_dotask(acpi_softc))
2971 continue;
2972 if (!cold) {
2973 if (rwsleep(evt, &acpi_softc->sc_lck, PWAIT32,
2974 "acpievt", 1) == EWOULDBLOCK35) {
2975 if (timeout < AML_NO_TIMEOUT0xffff)
2976 timeout -= (1000 / hz);
2977 }
2978 } else {
2979 delay(1000)(*delay_func)(1000);
2980 if (timeout < AML_NO_TIMEOUT0xffff)
2981 timeout--;
2982 }
2983 }
2984 if (evt->v_evt_.Vevent.state == 0)
2985 return (-1);
2986 evt->v_evt_.Vevent.state--;
2987 return (0);
2988}
2989
2990void
2991acpi_event_signal(struct aml_scope *scope, struct aml_value *evt)
2992{
2993 evt->v_evt_.Vevent.state++;
2994 if (evt->v_evt_.Vevent.state > 0)
2995 wakeup_one(evt)wakeup_n((evt), 1);
2996}
2997
2998void
2999acpi_event_reset(struct aml_scope *scope, struct aml_value *evt)
3000{
3001 evt->v_evt_.Vevent.state = 0;
3002}
3003
3004/* Store result value into an object */
3005void
3006aml_store(struct aml_scope *scope, struct aml_value *lhs , int64_t ival,
3007 struct aml_value *rhs)
3008{
3009 struct aml_value tmp;
3010 struct aml_node *node;
3011 int mlen;
3012
3013 /* Already set */
3014 if (lhs == rhs || lhs == NULL((void *)0) || lhs->type == AML_OBJTYPE_NOTARGET) {
3015 return;
3016 }
3017 memset(&tmp, 0, sizeof(tmp))__builtin_memset((&tmp), (0), (sizeof(tmp)));
3018 tmp.refcnt=99;
3019 if (rhs == NULL((void *)0)) {
3020 rhs = _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, ival, NULL((void *)0));
3021 }
3022 if (rhs->type == AML_OBJTYPE_BUFFERFIELD ||
3023 rhs->type == AML_OBJTYPE_FIELDUNIT) {
3024 aml_rwfield(rhs, 0, rhs->v_field_.vfield.bitlen, &tmp, ACPI_IOREAD0);
3025 rhs = &tmp;
3026 }
3027 /* Store to LocalX: free value */
3028 if (lhs->stack >= AMLOP_LOCAL00x60 && lhs->stack <= AMLOP_LOCAL70x67)
3029 aml_freevalue(lhs);
3030
3031 lhs = aml_gettgt(lhs, AMLOP_STORE0x70);
3032
3033 /* Store to LocalX: free value again */
3034 if (lhs->stack >= AMLOP_LOCAL00x60 && lhs->stack <= AMLOP_LOCAL70x67)
3035 aml_freevalue(lhs);
3036 switch (lhs->type) {
3037 case AML_OBJTYPE_UNINITIALIZED:
3038 aml_copyvalue(lhs, rhs);
3039 break;
3040 case AML_OBJTYPE_BUFFERFIELD:
3041 case AML_OBJTYPE_FIELDUNIT:
3042 aml_rwfield(lhs, 0, lhs->v_field_.vfield.bitlen, rhs, ACPI_IOWRITE1);
3043 break;
3044 case AML_OBJTYPE_DEBUGOBJ:
3045 break;
3046 case AML_OBJTYPE_INTEGER:
3047 rhs = aml_convert(rhs, lhs->type, -1);
3048 lhs->v_integer_.vinteger = rhs->v_integer_.vinteger;
3049 aml_delref(&rhs, "store.int");
3050 break;
3051 case AML_OBJTYPE_BUFFER:
3052 case AML_OBJTYPE_STRING:
3053 rhs = aml_convert(rhs, lhs->type, -1);
3054 if (lhs->length < rhs->length) {
3055 dnprintf(10, "Overrun! %d,%d\n",
3056 lhs->length, rhs->length);
3057 aml_freevalue(lhs);
3058 _aml_setvalue(lhs, rhs->type, rhs->length, NULL((void *)0));
3059 }
3060 mlen = min(lhs->length, rhs->length);
3061 memset(lhs->v_buffer, 0x00, lhs->length)__builtin_memset((lhs->_.vbuffer), (0x00), (lhs->length
))
;
3062 memcpy(lhs->v_buffer, rhs->v_buffer, mlen)__builtin_memcpy((lhs->_.vbuffer), (rhs->_.vbuffer), (mlen
))
;
3063 aml_delref(&rhs, "store.bufstr");
3064 break;
3065 case AML_OBJTYPE_PACKAGE:
3066 /* Convert to LHS type, copy into LHS */
3067 if (rhs->type != AML_OBJTYPE_PACKAGE) {
3068 aml_die("Copy non-package into package?")_aml_die(__FUNCTION__, 3068, "Copy non-package into package?"
)
;
3069 }
3070 aml_freevalue(lhs);
3071 aml_copyvalue(lhs, rhs);
3072 break;
3073 case AML_OBJTYPE_NAMEREF:
3074 node = __aml_searchname(scope->node,
3075 aml_getname(lhs->v_nameref_.vbuffer), 1);
3076 if (node == NULL((void *)0)) {
3077 aml_die("Could not create node %s",_aml_die(__FUNCTION__, 3078, "Could not create node %s", aml_getname
(lhs->_.vbuffer))
3078 aml_getname(lhs->v_nameref))_aml_die(__FUNCTION__, 3078, "Could not create node %s", aml_getname
(lhs->_.vbuffer))
;
3079 }
3080 aml_copyvalue(node->value, rhs);
3081 break;
3082 case AML_OBJTYPE_METHOD:
3083 /* Method override */
3084 if (rhs->type != AML_OBJTYPE_INTEGER) {
3085 aml_die("Overriding a method with a non-int?")_aml_die(__FUNCTION__, 3085, "Overriding a method with a non-int?"
)
;
3086 }
3087 aml_freevalue(lhs);
3088 aml_copyvalue(lhs, rhs);
3089 break;
3090 default:
3091 aml_die("Store to default type! %x\n", lhs->type)_aml_die(__FUNCTION__, 3091, "Store to default type! %x\n", lhs
->type)
;
3092 break;
3093 }
3094 aml_freevalue(&tmp);
3095}
3096
3097#ifdef DDB1
3098/* Disassembler routines */
3099void aml_disprintf(void *arg, const char *fmt, ...);
3100
3101void
3102aml_disprintf(void *arg, const char *fmt, ...)
3103{
3104 va_list ap;
3105
3106 va_start(ap, fmt)__builtin_va_start((ap), fmt);
3107 vprintf(fmt, ap);
3108 va_end(ap)__builtin_va_end((ap));
3109}
3110
3111void
3112aml_disasm(struct aml_scope *scope, int lvl,
3113 void (*dbprintf)(void *, const char *, ...)
3114 __attribute__((__format__(__kprintf__,2,3))),
3115 void *arg)
3116{
3117 int pc, opcode;
3118 struct aml_opcode *htab;
3119 uint64_t ival;
3120 struct aml_value *rv, tmp;
3121 uint8_t *end = NULL((void *)0);
3122 struct aml_scope ms;
3123 char *ch;
3124 char mch[64];
3125
3126 if (dbprintf == NULL((void *)0))
3127 dbprintf = aml_disprintf;
3128
3129 pc = aml_pc(scope->pos);
3130 opcode = aml_parseopcode(scope);
3131 htab = aml_findopcode(opcode);
3132
3133 /* Display address + indent */
3134 if (lvl <= 0x7FFF) {
3135 dbprintf(arg, "%.4x ", pc);
3136 for (pc=0; pc<lvl; pc++) {
3137 dbprintf(arg, " ");
3138 }
3139 }
3140 ch = NULL((void *)0);
3141 switch (opcode) {
3142 case AMLOP_NAMECHAR0x5F:
3143 scope->pos = aml_parsename(scope->node, scope->pos, &rv, 0);
3144 if (rv->type == AML_OBJTYPE_NAMEREF) {
3145 ch = "@@@";
3146 aml_delref(&rv, "disasm");
3147 break;
3148 }
3149 /* if this is a method, get arguments */
3150 strlcpy(mch, aml_nodename(rv->node), sizeof(mch));
3151 if (rv->type == AML_OBJTYPE_METHOD) {
3152 strlcat(mch, "(", sizeof(mch));
3153 for (ival=0;
3154 ival < AML_METHOD_ARGCOUNT(rv->v_method.flags)(((rv->_.vmethod.flags) >> 0) & 0x7);
3155 ival++) {
3156 strlcat(mch, ival ? ", %z" : "%z",
3157 sizeof(mch));
3158 }
3159 strlcat(mch, ")", sizeof(mch));
3160 }
3161 aml_delref(&rv, "");
3162 ch = mch;
3163 break;
3164
3165 case AMLOP_ZERO0x00:
3166 case AMLOP_ONE0x01:
3167 case AMLOP_ONES0xFF:
3168 case AMLOP_LOCAL00x60:
3169 case AMLOP_LOCAL10x61:
3170 case AMLOP_LOCAL20x62:
3171 case AMLOP_LOCAL30x63:
3172 case AMLOP_LOCAL40x64:
3173 case AMLOP_LOCAL50x65:
3174 case AMLOP_LOCAL60x66:
3175 case AMLOP_LOCAL70x67:
3176 case AMLOP_ARG00x68:
3177 case AMLOP_ARG10x69:
3178 case AMLOP_ARG20x6A:
3179 case AMLOP_ARG30x6B:
3180 case AMLOP_ARG40x6C:
3181 case AMLOP_ARG50x6D:
3182 case AMLOP_ARG60x6E:
3183 case AMLOP_NOP0xA3:
3184 case AMLOP_REVISION0x5B30:
3185 case AMLOP_DEBUG0x5B31:
3186 case AMLOP_CONTINUE0x9F:
3187 case AMLOP_BREAKPOINT0xCC:
3188 case AMLOP_BREAK0xA5:
3189 ch="%m";
3190 break;
3191 case AMLOP_BYTEPREFIX0x0A:
3192 ch="%b";
3193 break;
3194 case AMLOP_WORDPREFIX0x0B:
3195 ch="%w";
3196 break;
3197 case AMLOP_DWORDPREFIX0x0C:
3198 ch="%d";
3199 break;
3200 case AMLOP_QWORDPREFIX0x0E:
3201 ch="%q";
3202 break;
3203 case AMLOP_STRINGPREFIX0x0D:
3204 ch="%a";
3205 break;
3206
3207 case AMLOP_INCREMENT0x75:
3208 case AMLOP_DECREMENT0x76:
3209 case AMLOP_LNOT0x92:
3210 case AMLOP_SIZEOF0x87:
3211 case AMLOP_DEREFOF0x83:
3212 case AMLOP_REFOF0x71:
3213 case AMLOP_OBJECTTYPE0x8E:
3214 case AMLOP_UNLOAD0x5B2A:
3215 case AMLOP_RELEASE0x5B27:
3216 case AMLOP_SIGNAL0x5B24:
3217 case AMLOP_RESET0x5B26:
3218 case AMLOP_STALL0x5B21:
3219 case AMLOP_SLEEP0x5B22:
3220 case AMLOP_RETURN0xA4:
3221 ch="%m(%n)";
3222 break;
3223 case AMLOP_OR0x7D:
3224 case AMLOP_ADD0x72:
3225 case AMLOP_AND0x7B:
3226 case AMLOP_NAND0x7C:
3227 case AMLOP_XOR0x7F:
3228 case AMLOP_SHL0x79:
3229 case AMLOP_SHR0x7A:
3230 case AMLOP_NOR0x7E:
3231 case AMLOP_MOD0x85:
3232 case AMLOP_SUBTRACT0x74:
3233 case AMLOP_MULTIPLY0x77:
3234 case AMLOP_INDEX0x88:
3235 case AMLOP_CONCAT0x73:
3236 case AMLOP_CONCATRES0x84:
3237 case AMLOP_TOSTRING0x9C:
3238 ch="%m(%n, %n, %n)";
3239 break;
3240 case AMLOP_CREATEBYTEFIELD0x8C:
3241 case AMLOP_CREATEWORDFIELD0x8B:
3242 case AMLOP_CREATEDWORDFIELD0x8A:
3243 case AMLOP_CREATEQWORDFIELD0x8F:
3244 case AMLOP_CREATEBITFIELD0x8D:
3245 ch="%m(%n, %n, %N)";
3246 break;
3247 case AMLOP_CREATEFIELD0x5B13:
3248 ch="%m(%n, %n, %n, %N)";
3249 break;
3250 case AMLOP_DIVIDE0x78:
3251 case AMLOP_MID0x9E:
3252 ch="%m(%n, %n, %n, %n)";
3253 break;
3254 case AMLOP_LAND0x90:
3255 case AMLOP_LOR0x91:
3256 case AMLOP_LNOTEQUAL0x9293:
3257 case AMLOP_LLESSEQUAL0x9294:
3258 case AMLOP_LLESS0x95:
3259 case AMLOP_LEQUAL0x93:
3260 case AMLOP_LGREATEREQUAL0x9295:
3261 case AMLOP_LGREATER0x94:
3262 case AMLOP_NOT0x80:
3263 case AMLOP_FINDSETLEFTBIT0x81:
3264 case AMLOP_FINDSETRIGHTBIT0x82:
3265 case AMLOP_TOINTEGER0x99:
3266 case AMLOP_TOBUFFER0x96:
3267 case AMLOP_TOHEXSTRING0x98:
3268 case AMLOP_TODECSTRING0x97:
3269 case AMLOP_FROMBCD0x5B28:
3270 case AMLOP_TOBCD0x5B29:
3271 case AMLOP_WAIT0x5B25:
3272 case AMLOP_LOAD0x5B20:
3273 case AMLOP_STORE0x70:
3274 case AMLOP_NOTIFY0x86:
3275 case AMLOP_COPYOBJECT0x9D:
3276 ch="%m(%n, %n)";
3277 break;
3278 case AMLOP_ACQUIRE0x5B23:
3279 ch = "%m(%n, %w)";
3280 break;
3281 case AMLOP_CONDREFOF0x5B12:
3282 ch="%m(%R, %n)";
3283 break;
3284 case AMLOP_ALIAS0x06:
3285 ch="%m(%n, %N)";
3286 break;
3287 case AMLOP_NAME0x08:
3288 ch="%m(%N, %n)";
3289 break;
3290 case AMLOP_EVENT0x5B02:
3291 ch="%m(%N)";
3292 break;
3293 case AMLOP_MUTEX0x5B01:
3294 ch = "%m(%N, %b)";
3295 break;
3296 case AMLOP_OPREGION0x5B80:
3297 ch = "%m(%N, %b, %n, %n)";
3298 break;
3299 case AMLOP_DATAREGION0x5B88:
3300 ch="%m(%N, %n, %n, %n)";
3301 break;
3302 case AMLOP_FATAL0x5B32:
3303 ch = "%m(%b, %d, %n)";
3304 break;
3305 case AMLOP_IF0xA0:
3306 case AMLOP_WHILE0xA2:
3307 case AMLOP_SCOPE0x10:
3308 case AMLOP_THERMALZONE0x5B85:
3309 case AMLOP_VARPACKAGE0x13:
3310 end = aml_parseend(scope);
3311 ch = "%m(%n) {\n%T}";
3312 break;
3313 case AMLOP_DEVICE0x5B82:
3314 end = aml_parseend(scope);
3315 ch = "%m(%N) {\n%T}";
3316 break;
3317 case AMLOP_POWERRSRC0x5B84:
3318 end = aml_parseend(scope);
3319 ch = "%m(%N, %b, %w) {\n%T}";
3320 break;
3321 case AMLOP_PROCESSOR0x5B83:
3322 end = aml_parseend(scope);
3323 ch = "%m(%N, %b, %d, %b) {\n%T}";
3324 break;
3325 case AMLOP_METHOD0x14:
3326 end = aml_parseend(scope);
3327 ch = "%m(%N, %b) {\n%T}";
3328 break;
3329 case AMLOP_PACKAGE0x12:
3330 end = aml_parseend(scope);
3331 ch = "%m(%b) {\n%T}";
3332 break;
3333 case AMLOP_ELSE0xA1:
3334 end = aml_parseend(scope);
3335 ch = "%m {\n%T}";
3336 break;
3337 case AMLOP_BUFFER0x11:
3338 end = aml_parseend(scope);
3339 ch = "%m(%n) { %B }";
3340 break;
3341 case AMLOP_INDEXFIELD0x5B86:
3342 end = aml_parseend(scope);
3343 ch = "%m(%n, %n, %b) {\n%F}";
3344 break;
3345 case AMLOP_BANKFIELD0x5B87:
3346 end = aml_parseend(scope);
3347 ch = "%m(%n, %n, %n, %b) {\n%F}";
3348 break;
3349 case AMLOP_FIELD0x5B81:
3350 end = aml_parseend(scope);
3351 ch = "%m(%n, %b) {\n%F}";
3352 break;
3353 case AMLOP_MATCH0x89:
3354 ch = "%m(%n, %b, %n, %b, %n, %n)";
3355 break;
3356 case AMLOP_LOADTABLE0x5B1F:
3357 ch = "%m(%n, %n, %n, %n, %n, %n)";
3358 break;
3359 default:
3360 aml_die("opcode = %x\n", opcode)_aml_die(__FUNCTION__, 3360, "opcode = %x\n", opcode);
3361 break;
3362 }
3363
3364 /* Parse printable buffer args */
3365 while (ch && *ch) {
3366 char c;
3367
3368 if (*ch != '%') {
3369 dbprintf(arg,"%c", *(ch++));
3370 continue;
3371 }
3372 c = *(++ch);
3373 switch (c) {
3374 case 'b':
3375 case 'w':
3376 case 'd':
3377 case 'q':
3378 /* Parse simple object: don't allocate */
3379 aml_parsesimple(scope, c, &tmp);
3380 dbprintf(arg,"0x%llx", tmp.v_integer_.vinteger);
3381 break;
3382 case 'a':
3383 dbprintf(arg, "\'%s\'", scope->pos);
3384 scope->pos += strlen(scope->pos)+1;
3385 break;
3386 case 'N':
3387 /* Create Name */
3388 rv = aml_parsesimple(scope, c, NULL((void *)0));
3389 dbprintf(arg, "%s", aml_nodename(rv->node));
3390 break;
3391 case 'm':
3392 /* display mnemonic */
3393 dbprintf(arg, "%s", htab->mnem);
3394 break;
3395 case 'R':
3396 /* Search name */
3397 printf("%s", aml_getname(scope->pos));
3398 scope->pos = aml_parsename(scope->node, scope->pos,
3399 &rv, 0);
3400 aml_delref(&rv, 0);
3401 break;
3402 case 'z':
3403 case 'n':
3404 /* generic arg: recurse */
3405 aml_disasm(scope, lvl | 0x8000, dbprintf, arg);
3406 break;
3407 case 'B':
3408 /* Buffer */
3409 scope->pos = end;
3410 break;
3411 case 'F':
3412 /* Scope: Field List */
3413 memset(&ms, 0, sizeof(ms))__builtin_memset((&ms), (0), (sizeof(ms)));
3414 ms.node = scope->node;
3415 ms.start = scope->pos;
3416 ms.end = end;
3417 ms.pos = ms.start;
3418 ms.type = AMLOP_FIELD0x5B81;
3419
3420 while (ms.pos < ms.end) {
3421 if (*ms.pos == 0x00) {
3422 ms.pos++;
3423 aml_parselength(&ms);
3424 } else if (*ms.pos == 0x01) {
3425 ms.pos+=3;
3426 } else {
3427 ms.pos = aml_parsename(ms.node,
3428 ms.pos, &rv, 1);
3429 aml_parselength(&ms);
3430 dbprintf(arg," %s\n",
3431 aml_nodename(rv->node));
3432 aml_delref(&rv, 0);
3433 }
3434 }
3435
3436 /* Display address and closing bracket */
3437 dbprintf(arg,"%.4x ", aml_pc(scope->pos));
3438 for (pc=0; pc<(lvl & 0x7FFF); pc++) {
3439 dbprintf(arg," ");
3440 }
3441 scope->pos = end;
3442 break;
3443 case 'T':
3444 /* Scope: Termlist */
3445 memset(&ms, 0, sizeof(ms))__builtin_memset((&ms), (0), (sizeof(ms)));
3446 ms.node = scope->node;
3447 ms.start = scope->pos;
3448 ms.end = end;
3449 ms.pos = ms.start;
3450 ms.type = AMLOP_SCOPE0x10;
3451
3452 while (ms.pos < ms.end) {
3453 aml_disasm(&ms, (lvl + 1) & 0x7FFF,
3454 dbprintf, arg);
3455 }
3456
3457 /* Display address and closing bracket */
3458 dbprintf(arg,"%.4x ", aml_pc(scope->pos));
3459 for (pc=0; pc<(lvl & 0x7FFF); pc++) {
3460 dbprintf(arg," ");
3461 }
3462 scope->pos = end;
3463 break;
3464 }
3465 ch++;
3466 }
3467 if (lvl <= 0x7FFF) {
3468 dbprintf(arg,"\n");
3469 }
3470}
3471#endif /* DDB */
3472
3473int aml_busy;
3474
3475/* Evaluate method or buffervalue objects */
3476struct aml_value *
3477aml_eval(struct aml_scope *scope, struct aml_value *my_ret, int ret_type,
3478 int argc, struct aml_value *argv)
3479{
3480 struct aml_value *tmp = my_ret;
3481 struct aml_scope *ms;
3482 int idx;
3483
3484 switch (tmp->type) {
3485 case AML_OBJTYPE_NAMEREF:
3486 my_ret = aml_seterror(scope, "Undefined name: %s",
3487 aml_getname(my_ret->v_nameref_.vbuffer));
3488 break;
3489 case AML_OBJTYPE_METHOD:
3490 dnprintf(10,"\n--== Eval Method [%s, %d args] to %c ==--\n",
3491 aml_nodename(tmp->node),
3492 AML_METHOD_ARGCOUNT(tmp->v_method.flags),
3493 ret_type);
3494 ms = aml_pushscope(scope, tmp, tmp->node, AMLOP_METHOD0x14);
3495
3496 /* Parse method arguments */
3497 for (idx=0; idx<AML_METHOD_ARGCOUNT(tmp->v_method.flags)(((tmp->_.vmethod.flags) >> 0) & 0x7); idx++) {
3498 struct aml_value *sp;
3499
3500 sp = aml_getstack(ms, AMLOP_ARG00x68+idx);
3501 if (argv) {
3502 aml_copyvalue(sp, &argv[idx]);
3503 } else {
3504 _aml_setvalue(sp, AML_OBJTYPE_OBJREF, AMLOP_ARG00x68 + idx, 0);
3505 sp->v_objref_.vobjref.ref = aml_parse(scope, 't', "ARGX");
3506 }
3507 }
3508#ifdef ACPI_DEBUG
3509 aml_showstack(ms);
3510#endif
3511
3512 /* Evaluate method scope */
3513 aml_root.start = tmp->v_method_.vmethod.base;
3514 if (tmp->v_method_.vmethod.fneval != NULL((void *)0)) {
3515 my_ret = tmp->v_method_.vmethod.fneval(ms, NULL((void *)0));
3516 } else {
3517 aml_parse(ms, 'T', "METHEVAL");
3518 my_ret = ms->retv;
3519 }
3520 dnprintf(10,"\n--==Finished evaluating method: %s %c\n",
3521 aml_nodename(tmp->node), ret_type);
3522#ifdef ACPI_DEBUG
3523 aml_showvalue(my_ret);
3524 aml_showstack(ms);
3525#endif
3526 aml_popscope(ms);
3527 break;
3528 case AML_OBJTYPE_BUFFERFIELD:
3529 case AML_OBJTYPE_FIELDUNIT:
3530 my_ret = aml_allocvalue(0,0,NULL((void *)0));
3531 dnprintf(20,"quick: Convert Bufferfield to %c %p\n",
3532 ret_type, my_ret);
3533 aml_rwfield(tmp, 0, tmp->v_field_.vfield.bitlen, my_ret, ACPI_IOREAD0);
3534 break;
3535 }
3536 if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
3537#ifndef SMALL_KERNEL
3538 aml_showvalue(my_ret);
3539#endif
3540 aml_die("Not Integer")_aml_die(__FUNCTION__, 3540, "Not Integer");
3541 }
3542 return my_ret;
3543}
3544
3545/*
3546 * The following opcodes produce return values
3547 * TOSTRING -> Str
3548 * TOHEXSTR -> Str
3549 * TODECSTR -> Str
3550 * STRINGPFX -> Str
3551 * BUFFER -> Buf
3552 * CONCATRES -> Buf
3553 * TOBUFFER -> Buf
3554 * MID -> Buf|Str
3555 * CONCAT -> Buf|Str
3556 * PACKAGE -> Pkg
3557 * VARPACKAGE -> Pkg
3558 * LOCALx -> Obj
3559 * ARGx -> Obj
3560 * NAMECHAR -> Obj
3561 * REFOF -> ObjRef
3562 * INDEX -> ObjRef
3563 * DEREFOF -> DataRefObj
3564 * COPYOBJECT -> DataRefObj
3565 * STORE -> DataRefObj
3566
3567 * ZERO -> Int
3568 * ONE -> Int
3569 * ONES -> Int
3570 * REVISION -> Int
3571 * B/W/D/Q -> Int
3572 * OR -> Int
3573 * AND -> Int
3574 * ADD -> Int
3575 * NAND -> Int
3576 * XOR -> Int
3577 * SHL -> Int
3578 * SHR -> Int
3579 * NOR -> Int
3580 * MOD -> Int
3581 * SUBTRACT -> Int
3582 * MULTIPLY -> Int
3583 * DIVIDE -> Int
3584 * NOT -> Int
3585 * TOBCD -> Int
3586 * FROMBCD -> Int
3587 * FSLEFTBIT -> Int
3588 * FSRIGHTBIT -> Int
3589 * INCREMENT -> Int
3590 * DECREMENT -> Int
3591 * TOINTEGER -> Int
3592 * MATCH -> Int
3593 * SIZEOF -> Int
3594 * OBJECTTYPE -> Int
3595 * TIMER -> Int
3596
3597 * CONDREFOF -> Bool
3598 * ACQUIRE -> Bool
3599 * WAIT -> Bool
3600 * LNOT -> Bool
3601 * LAND -> Bool
3602 * LOR -> Bool
3603 * LLESS -> Bool
3604 * LEQUAL -> Bool
3605 * LGREATER -> Bool
3606 * LNOTEQUAL -> Bool
3607 * LLESSEQUAL -> Bool
3608 * LGREATEREQ -> Bool
3609
3610 * LOADTABLE -> DDB
3611 * DEBUG -> Debug
3612
3613 * The following opcodes do not generate a return value:
3614 * NOP
3615 * BREAKPOINT
3616 * RELEASE
3617 * RESET
3618 * SIGNAL
3619 * NAME
3620 * ALIAS
3621 * OPREGION
3622 * DATAREGION
3623 * EVENT
3624 * MUTEX
3625 * SCOPE
3626 * DEVICE
3627 * THERMALZONE
3628 * POWERRSRC
3629 * PROCESSOR
3630 * METHOD
3631 * CREATEFIELD
3632 * CREATEBITFIELD
3633 * CREATEBYTEFIELD
3634 * CREATEWORDFIELD
3635 * CREATEDWORDFIELD
3636 * CREATEQWORDFIELD
3637 * FIELD
3638 * INDEXFIELD
3639 * BANKFIELD
3640 * STALL
3641 * SLEEP
3642 * NOTIFY
3643 * FATAL
3644 * LOAD
3645 * UNLOAD
3646 * IF
3647 * ELSE
3648 * WHILE
3649 * BREAK
3650 * CONTINUE
3651 */
3652
3653/* Parse a simple object from AML Bytestream */
3654struct aml_value *
3655aml_parsesimple(struct aml_scope *scope, char ch, struct aml_value *rv)
3656{
3657 if (rv == NULL((void *)0))
3658 rv = aml_allocvalue(0,0,NULL((void *)0));
3659 switch (ch) {
3660 case AML_ARG_REVISION'R':
3661 _aml_setvalue(rv, AML_OBJTYPE_INTEGER, AML_REVISION0x01, NULL((void *)0));
3662 break;
3663 case AML_ARG_DEBUG'D':
3664 _aml_setvalue(rv, AML_OBJTYPE_DEBUGOBJ, 0, NULL((void *)0));
3665 break;
3666 case AML_ARG_BYTE'b':
3667 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3668 aml_get8(scope->pos)*(uint8_t *)(scope->pos), NULL((void *)0));
3669 scope->pos += 1;
3670 break;
3671 case AML_ARG_WORD'w':
3672 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3673 aml_get16(scope->pos)*(uint16_t *)(scope->pos), NULL((void *)0));
3674 scope->pos += 2;
3675 break;
3676 case AML_ARG_DWORD'd':
3677 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3678 aml_get32(scope->pos)*(uint32_t *)(scope->pos), NULL((void *)0));
3679 scope->pos += 4;
3680 break;
3681 case AML_ARG_QWORD'q':
3682 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3683 aml_get64(scope->pos)*(uint64_t *)(scope->pos), NULL((void *)0));
3684 scope->pos += 8;
3685 break;
3686 case AML_ARG_STRING'a':
3687 _aml_setvalue(rv, AML_OBJTYPE_STRING, -1, scope->pos);
3688 scope->pos += rv->length+1;
3689 break;
3690 }
3691 return rv;
3692}
3693
3694/*
3695 * Main Opcode Parser/Evaluator
3696 *
3697 * ret_type is expected type for return value
3698 * 'o' = Data Object (Int/Str/Buf/Pkg/Name)
3699 * 'i' = Integer
3700 * 't' = TermArg (Int/Str/Buf/Pkg)
3701 * 'r' = Target (NamedObj/Local/Arg/Null)
3702 * 'S' = SuperName (NamedObj/Local/Arg)
3703 * 'T' = TermList
3704 */
3705#define aml_debugger(x)
3706
3707int maxdp;
3708
3709struct aml_value *
3710aml_gettgt(struct aml_value *val, int opcode)
3711{
3712 while (val && val->type == AML_OBJTYPE_OBJREF) {
3713 val = val->v_objref_.vobjref.ref;
3714 }
3715 return val;
3716}
3717
3718struct aml_value *
3719aml_seterror(struct aml_scope *scope, const char *fmt, ...)
3720{
3721 va_list ap;
3722
3723 va_start(ap, fmt)__builtin_va_start((ap), fmt);
3724 printf("### AML PARSE ERROR (0x%x): ", aml_pc(scope->pos));
3725 vprintf(fmt, ap);
3726 printf("\n");
3727 va_end(ap)__builtin_va_end((ap));
3728
3729 while (scope) {
3730 scope->pos = scope->end;
3731 scope = scope->parent;
3732 }
3733 aml_error++;
3734 return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
3735}
3736
3737struct aml_value *
3738aml_loadtable(struct acpi_softc *sc, const char *signature,
3739 const char *oemid, const char *oemtableid, const char *rootpath,
3740 const char *parameterpath, struct aml_value *parameterdata)
3741{
3742 struct acpi_table_header *hdr;
3743 struct acpi_dsdt *p_dsdt;
3744 struct acpi_q *entry;
3745
3746 if (strlen(parameterpath) > 0)
3747 aml_die("LoadTable: ParameterPathString unsupported")_aml_die(__FUNCTION__, 3747, "LoadTable: ParameterPathString unsupported"
)
;
3748
3749 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next)for((entry) = ((&sc->sc_tables)->sqh_first); (entry
) != ((void *)0); (entry) = ((entry)->q_next.sqe_next))
{
3750 hdr = entry->q_table;
3751 if (strncmp(hdr->signature, signature,
3752 sizeof(hdr->signature)) == 0 &&
3753 strncmp(hdr->oemid, oemid, sizeof(hdr->oemid)) == 0 &&
3754 strncmp(hdr->oemtableid, oemtableid,
3755 sizeof(hdr->oemtableid)) == 0) {
3756 p_dsdt = entry->q_table;
3757 acpi_parse_aml(sc, rootpath, p_dsdt->aml,
3758 p_dsdt->hdr_lengthhdr.length - sizeof(p_dsdt->hdr));
3759 return aml_allocvalue(AML_OBJTYPE_DDBHANDLE, 0, 0);
3760 }
3761 }
3762
3763 return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
3764}
3765
3766/* Load new SSDT scope from memory address */
3767struct aml_scope *
3768aml_load(struct acpi_softc *sc, struct aml_scope *scope,
3769 struct aml_value *rgn, struct aml_value *ddb)
3770{
3771 struct acpi_q *entry;
3772 struct acpi_dsdt *p_ssdt;
3773 struct aml_value tmp;
3774
3775 ddb->type = AML_OBJTYPE_DDBHANDLE;
3776 ddb->v_integer_.vinteger = 0;
3777
3778 memset(&tmp, 0, sizeof(tmp))__builtin_memset((&tmp), (0), (sizeof(tmp)));
3779 if (rgn->type != AML_OBJTYPE_OPREGION ||
3780 rgn->v_opregion_.vopregion.iospace != GAS_SYSTEM_MEMORY0)
3781 goto fail;
3782
3783 /* Load SSDT from memory */
3784 entry = acpi_maptable(sc, rgn->v_opregion_.vopregion.iobase, "SSDT", NULL((void *)0), NULL((void *)0), 1);
3785 if (entry == NULL((void *)0))
3786 goto fail;
3787
3788 dnprintf(10, "%s: loaded SSDT %s @ %llx\n", sc->sc_dev.dv_xname,
3789 aml_nodename(rgn->node), rgn->v_opregion.iobase);
3790 ddb->v_integer_.vinteger = entry->q_id;
3791
3792 p_ssdt = entry->q_table;
3793 tmp.v_buffer_.vbuffer = p_ssdt->aml;
3794 tmp.length = p_ssdt->hdr_lengthhdr.length - sizeof(p_ssdt->hdr);
3795
3796 return aml_pushscope(scope, &tmp, scope->node,
3797 AMLOP_LOAD0x5B20);
3798fail:
3799 printf("%s: unable to load %s\n", sc->sc_dev.dv_xname,
3800 aml_nodename(rgn->node));
3801 return NULL((void *)0);
3802}
3803
3804struct aml_value *
3805aml_parse(struct aml_scope *scope, int ret_type, const char *stype)
3806{
3807 int opcode, idx, pc;
3808 struct aml_opcode *htab;
3809 struct aml_value *opargs[8], *my_ret, *rv;
3810 struct aml_scope *mscope, *iscope;
3811 uint8_t *start, *end;
3812 const char *ch;
3813 int64_t ival;
3814 struct timespec ts;
3815
3816 my_ret = NULL((void *)0);
3817 if (scope == NULL((void *)0) || scope->pos >= scope->end) {
1
Assuming 'scope' is not equal to NULL
2
Assuming field 'pos' is < field 'end'
3
Taking false branch
3818 return NULL((void *)0);
3819 }
3820 if (odp++ > 125)
4
Assuming the condition is false
5
Taking false branch
3821 panic("depth");
3822 if (odp > maxdp) {
6
Assuming 'odp' is <= 'maxdp'
7
Taking false branch
3823 maxdp = odp;
3824 dnprintf(10, "max depth: %d\n", maxdp);
3825 }
3826 end = NULL((void *)0);
3827 iscope = scope;
3828 start:
3829 /* --== Stage 0: Get Opcode ==-- */
3830 start = scope->pos;
3831 pc = aml_pc(scope->pos);
8
Calling 'aml_pc'
10
Returning from 'aml_pc'
3832 aml_debugger(scope);
3833
3834 opcode = aml_parseopcode(scope);
11
Calling 'aml_parseopcode'
18
Returning from 'aml_parseopcode'
3835 htab = aml_findopcode(opcode);
19
Calling 'aml_findopcode'
23
Returning from 'aml_findopcode'
3836 if (htab
23.1
'htab' is not equal to NULL
== NULL((void *)0)) {
24
Taking false branch
3837 /* No opcode handler */
3838 aml_die("Unknown opcode: %.4x @ %.4x", opcode, pc)_aml_die(__FUNCTION__, 3838, "Unknown opcode: %.4x @ %.4x", opcode
, pc)
;
3839 }
3840 dnprintf(18,"%.4x %s\n", pc, aml_mnem(opcode, scope->pos));
3841
3842 /* --== Stage 1: Process opcode arguments ==-- */
3843 memset(opargs, 0, sizeof(opargs))__builtin_memset((opargs), (0), (sizeof(opargs)));
25
Storing null pointer value
3844 idx = 0;
3845 for (ch = htab->args; *ch; ch++) {
26
Loop condition is false. Execution continues on line 3919
3846 rv = NULL((void *)0);
3847 switch (*ch) {
3848 case AML_ARG_OBJLEN'p':
3849 end = aml_parseend(scope);
3850 break;
3851 case AML_ARG_IFELSE'I':
3852 /* Special Case: IF-ELSE:piTbpT or IF:piT */
3853 ch = (*end == AMLOP_ELSE0xA1 && end < scope->end) ?
3854 "-TbpT" : "-T";
3855 break;
3856
3857 /* Complex arguments */
3858 case 's':
3859 case 'S':
3860 case AML_ARG_TARGET'r':
3861 case AML_ARG_TERMOBJ't':
3862 case AML_ARG_INTEGER'i':
3863 if (*ch == 'r' && *scope->pos == AMLOP_ZERO0x00) {
3864 /* Special case: NULL Target */
3865 rv = aml_allocvalue(AML_OBJTYPE_NOTARGET, 0, NULL((void *)0));
3866 scope->pos++;
3867 }
3868 else {
3869 rv = aml_parse(scope, *ch, htab->mnem);
3870 if (rv == NULL((void *)0) || aml_error)
3871 goto parse_error;
3872 }
3873 break;
3874
3875 /* Simple arguments */
3876 case AML_ARG_BUFFER'B':
3877 case AML_ARG_METHOD'M':
3878 case AML_ARG_FIELDLIST'F':
3879 case AML_ARG_TERMOBJLIST'T':
3880 rv = aml_allocvalue(AML_OBJTYPE_SCOPE, 0, NULL((void *)0));
3881 rv->v_buffer_.vbuffer = scope->pos;
3882 rv->length = end - scope->pos;
3883 scope->pos = end;
3884 break;
3885 case AML_ARG_CONST'c':
3886 rv = aml_allocvalue(AML_OBJTYPE_INTEGER,
3887 (char)opcode, NULL((void *)0));
3888 break;
3889 case AML_ARG_CREATENAME'N':
3890 scope->pos = aml_parsename(scope->node, scope->pos,
3891 &rv, 1);
3892 break;
3893 case AML_ARG_SEARCHNAME'n':
3894 scope->pos = aml_parsename(scope->node, scope->pos,
3895 &rv, 0);
3896 break;
3897 case AML_ARG_BYTE'b':
3898 case AML_ARG_WORD'w':
3899 case AML_ARG_DWORD'd':
3900 case AML_ARG_QWORD'q':
3901 case AML_ARG_DEBUG'D':
3902 case AML_ARG_STRING'a':
3903 case AML_ARG_REVISION'R':
3904 rv = aml_parsesimple(scope, *ch, NULL((void *)0));
3905 break;
3906 case AML_ARG_STKLOCAL'L':
3907 case AML_ARG_STKARG'A':
3908 rv = aml_getstack(scope, opcode);
3909 break;
3910 default:
3911 aml_die("Unknown arg type: %c\n", *ch)_aml_die(__FUNCTION__, 3911, "Unknown arg type: %c\n", *ch);
3912 break;
3913 }
3914 if (rv != NULL((void *)0))
3915 opargs[idx++] = rv;
3916 }
3917
3918 /* --== Stage 2: Process opcode ==-- */
3919 ival = 0;
3920 my_ret = NULL((void *)0);
3921 mscope = NULL((void *)0);
3922 switch (opcode) {
27
Control jumps to 'case 16:' at line 4286
3923 case AMLOP_NOP0xA3:
3924 case AMLOP_BREAKPOINT0xCC:
3925 break;
3926 case AMLOP_LOCAL00x60:
3927 case AMLOP_LOCAL10x61:
3928 case AMLOP_LOCAL20x62:
3929 case AMLOP_LOCAL30x63:
3930 case AMLOP_LOCAL40x64:
3931 case AMLOP_LOCAL50x65:
3932 case AMLOP_LOCAL60x66:
3933 case AMLOP_LOCAL70x67:
3934 case AMLOP_ARG00x68:
3935 case AMLOP_ARG10x69:
3936 case AMLOP_ARG20x6A:
3937 case AMLOP_ARG30x6B:
3938 case AMLOP_ARG40x6C:
3939 case AMLOP_ARG50x6D:
3940 case AMLOP_ARG60x6E:
3941 my_ret = opargs[0];
3942 aml_addref(my_ret, htab->mnem);
3943 break;
3944 case AMLOP_NAMECHAR0x5F:
3945 /* opargs[0] = named object (node != NULL), or nameref */
3946 my_ret = opargs[0];
3947 if (scope->type == AMLOP_PACKAGE0x12 && my_ret->node) {
3948 /* Special case for package */
3949 my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF,
3950 AMLOP_NAMECHAR0x5F, 0);
3951 my_ret->v_objref_.vobjref.ref = opargs[0];
3952 aml_addref(my_ret, "package");
3953 } else if (my_ret->type == AML_OBJTYPE_OBJREF) {
3954 my_ret = my_ret->v_objref_.vobjref.ref;
3955 aml_addref(my_ret, "de-alias");
3956 }
3957 if (ret_type == 'i' || ret_type == 't' || ret_type == 'T') {
3958 /* Return TermArg or Integer: Evaluate object */
3959 my_ret = aml_eval(scope, my_ret, ret_type, 0, NULL((void *)0));
3960 } else if (my_ret->type == AML_OBJTYPE_METHOD) {
3961 /* This should only happen with CondRef */
3962 dnprintf(12,"non-termarg method : %s\n", stype);
3963 aml_addref(my_ret, "zoom");
3964 }
3965 break;
3966
3967 case AMLOP_ZERO0x00:
3968 case AMLOP_ONE0x01:
3969 case AMLOP_ONES0xFF:
3970 case AMLOP_DEBUG0x5B31:
3971 case AMLOP_REVISION0x5B30:
3972 case AMLOP_BYTEPREFIX0x0A:
3973 case AMLOP_WORDPREFIX0x0B:
3974 case AMLOP_DWORDPREFIX0x0C:
3975 case AMLOP_QWORDPREFIX0x0E:
3976 case AMLOP_STRINGPREFIX0x0D:
3977 my_ret = opargs[0];
3978 break;
3979
3980 case AMLOP_BUFFER0x11:
3981 /* Buffer: iB => Buffer */
3982 my_ret = aml_allocvalue(AML_OBJTYPE_BUFFER,
3983 opargs[0]->v_integer_.vinteger, NULL((void *)0));
3984 memcpy(my_ret->v_buffer, opargs[1]->v_buffer,__builtin_memcpy((my_ret->_.vbuffer), (opargs[1]->_.vbuffer
), (opargs[1]->length))
3985 opargs[1]->length)__builtin_memcpy((my_ret->_.vbuffer), (opargs[1]->_.vbuffer
), (opargs[1]->length))
;
3986 break;
3987 case AMLOP_PACKAGE0x12:
3988 case AMLOP_VARPACKAGE0x13:
3989 /* Package/VarPackage: bT/iT => Package */
3990 my_ret = aml_allocvalue(AML_OBJTYPE_PACKAGE,
3991 opargs[0]->v_integer_.vinteger, 0);
3992 mscope = aml_pushscope(scope, opargs[1], scope->node,
3993 AMLOP_PACKAGE0x12);
3994
3995 /* Recursively parse package contents */
3996 for (idx=0; idx<my_ret->length; idx++) {
3997 rv = aml_parse(mscope, 'o', "Package");
3998 if (rv != NULL((void *)0)) {
3999 aml_delref(&my_ret->v_package_.vpackage[idx], "pkginit");
4000 my_ret->v_package_.vpackage[idx] = rv;
4001 }
4002 }
4003 aml_popscope(mscope);
4004 mscope = NULL((void *)0);
4005 break;
4006
4007 /* Math/Logical operations */
4008 case AMLOP_OR0x7D:
4009 case AMLOP_ADD0x72:
4010 case AMLOP_AND0x7B:
4011 case AMLOP_NAND0x7C:
4012 case AMLOP_XOR0x7F:
4013 case AMLOP_SHL0x79:
4014 case AMLOP_SHR0x7A:
4015 case AMLOP_NOR0x7E:
4016 case AMLOP_MOD0x85:
4017 case AMLOP_SUBTRACT0x74:
4018 case AMLOP_MULTIPLY0x77:
4019 /* XXX: iir => I */
4020 ival = aml_evalexpr(opargs[0]->v_integer_.vinteger,
4021 opargs[1]->v_integer_.vinteger, opcode);
4022 aml_store(scope, opargs[2], ival, NULL((void *)0));
4023 break;
4024 case AMLOP_DIVIDE0x78:
4025 /* Divide: iirr => I */
4026 if (opargs[1]->v_integer_.vinteger == 0) {
4027 my_ret = aml_seterror(scope, "Divide by Zero!");
4028 break;
4029 }
4030 ival = aml_evalexpr(opargs[0]->v_integer_.vinteger,
4031 opargs[1]->v_integer_.vinteger, AMLOP_MOD0x85);
4032 aml_store(scope, opargs[2], ival, NULL((void *)0));
4033
4034 ival = aml_evalexpr(opargs[0]->v_integer_.vinteger,
4035 opargs[1]->v_integer_.vinteger, AMLOP_DIVIDE0x78);
4036 aml_store(scope, opargs[3], ival, NULL((void *)0));
4037 break;
4038 case AMLOP_NOT0x80:
4039 case AMLOP_TOBCD0x5B29:
4040 case AMLOP_FROMBCD0x5B28:
4041 case AMLOP_FINDSETLEFTBIT0x81:
4042 case AMLOP_FINDSETRIGHTBIT0x82:
4043 /* XXX: ir => I */
4044 ival = aml_evalexpr(opargs[0]->v_integer_.vinteger, 0, opcode);
4045 aml_store(scope, opargs[1], ival, NULL((void *)0));
4046 break;
4047 case AMLOP_INCREMENT0x75:
4048 case AMLOP_DECREMENT0x76:
4049 /* Inc/Dec: S => I */
4050 my_ret = aml_eval(scope, opargs[0], AML_ARG_INTEGER'i', 0, NULL((void *)0));
4051 ival = aml_evalexpr(my_ret->v_integer_.vinteger, 1, opcode);
4052 aml_store(scope, opargs[0], ival, NULL((void *)0));
4053 break;
4054 case AMLOP_LNOT0x92:
4055 /* LNot: i => Bool */
4056 ival = aml_evalexpr(opargs[0]->v_integer_.vinteger, 0, opcode);
4057 break;
4058 case AMLOP_LOR0x91:
4059 case AMLOP_LAND0x90:
4060 /* XXX: ii => Bool */
4061 ival = aml_evalexpr(opargs[0]->v_integer_.vinteger,
4062 opargs[1]->v_integer_.vinteger, opcode);
4063 break;
4064 case AMLOP_LLESS0x95:
4065 case AMLOP_LEQUAL0x93:
4066 case AMLOP_LGREATER0x94:
4067 case AMLOP_LNOTEQUAL0x9293:
4068 case AMLOP_LLESSEQUAL0x9294:
4069 case AMLOP_LGREATEREQUAL0x9295:
4070 /* XXX: tt => Bool */
4071 ival = aml_compare(opargs[0], opargs[1], opcode);
4072 break;
4073
4074 /* Reference/Store operations */
4075 case AMLOP_CONDREFOF0x5B12:
4076 /* CondRef: rr => I */
4077 ival = 0;
4078 if (opargs[0]->node != NULL((void *)0)) {
4079 /* Create Object Reference */
4080 rv = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode,
4081 opargs[0]);
4082 aml_addref(opargs[0], "CondRef");
4083 aml_store(scope, opargs[1], 0, rv);
4084 aml_delref(&rv, 0);
4085
4086 /* Mark that we found it */
4087 ival = -1;
4088 }
4089 break;
4090 case AMLOP_REFOF0x71:
4091 /* RefOf: r => ObjRef */
4092 my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode, opargs[0]);
4093 aml_addref(my_ret->v_objref_.vobjref.ref, "RefOf");
4094 break;
4095 case AMLOP_INDEX0x88:
4096 /* Index: tir => ObjRef */
4097 idx = opargs[1]->v_integer_.vinteger;
4098 /* Reading past the end of the array? - Ignore */
4099 if (idx >= opargs[0]->length || idx < 0)
4100 break;
4101 switch (opargs[0]->type) {
4102 case AML_OBJTYPE_PACKAGE:
4103 /* Don't set opargs[0] to NULL */
4104 if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
4105 my_ret = opargs[0]->v_package_.vpackage[idx];
4106 aml_addref(my_ret, "Index.Package");
4107 } else {
4108 my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, AMLOP_PACKAGE0x12,
4109 opargs[0]->v_package_.vpackage[idx]);
4110 aml_addref(my_ret->v_objref_.vobjref.ref,
4111 "Index.Package");
4112 }
4113 break;
4114 case AML_OBJTYPE_BUFFER:
4115 case AML_OBJTYPE_STRING:
4116 case AML_OBJTYPE_INTEGER:
4117 rv = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
4118 if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
4119 dnprintf(12,"Index.Buf Term: %d = %x\n",
4120 idx, rv->v_buffer[idx]);
4121 ival = rv->v_buffer_.vbuffer[idx];
4122 } else {
4123 dnprintf(12, "Index.Buf Targ\n");
4124 my_ret = aml_allocvalue(0,0,NULL((void *)0));
4125 aml_createfield(my_ret, AMLOP_INDEX0x88, rv,
4126 8 * idx, 8, NULL((void *)0), 0, AML_FIELD_BYTEACC0x1);
4127 }
4128 aml_delref(&rv, "Index.BufStr");
4129 break;
4130 default:
4131 aml_die("Unknown index : %x\n", opargs[0]->type)_aml_die(__FUNCTION__, 4131, "Unknown index : %x\n", opargs[0
]->type)
;
4132 break;
4133 }
4134 aml_store(scope, opargs[2], ival, my_ret);
4135 break;
4136 case AMLOP_DEREFOF0x83:
4137 /* DerefOf: t:ObjRef => DataRefObj */
4138 if (opargs[0]->type == AML_OBJTYPE_OBJREF) {
4139 my_ret = opargs[0]->v_objref_.vobjref.ref;
4140 aml_addref(my_ret, "DerefOf");
4141 } else {
4142 my_ret = opargs[0];
4143 //aml_addref(my_ret, "DerefOf");
4144 }
4145 break;
4146 case AMLOP_COPYOBJECT0x9D:
4147 /* CopyObject: t:DataRefObj, s:implename => DataRefObj */
4148 my_ret = opargs[0];
4149 aml_freevalue(opargs[1]);
4150 aml_copyvalue(opargs[1], opargs[0]);
4151 break;
4152 case AMLOP_STORE0x70:
4153 /* Store: t:DataRefObj, S:upername => DataRefObj */
4154 my_ret = opargs[0];
4155 aml_store(scope, opargs[1], 0, opargs[0]);
4156 break;
4157
4158 /* Conversion */
4159 case AMLOP_TOINTEGER0x99:
4160 /* Source:CData, Result => Integer */
4161 my_ret = aml_convert(opargs[0], AML_OBJTYPE_INTEGER, -1);
4162 aml_store(scope, opargs[1], 0, my_ret);
4163 break;
4164 case AMLOP_TOBUFFER0x96:
4165 /* Source:CData, Result => Buffer */
4166 my_ret = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
4167 aml_store(scope, opargs[1], 0, my_ret);
4168 break;
4169 case AMLOP_TOHEXSTRING0x98:
4170 /* Source:CData, Result => String */
4171 my_ret = aml_convert(opargs[0], AML_OBJTYPE_HEXSTRING, -1);
4172 aml_store(scope, opargs[1], 0, my_ret);
4173 break;
4174 case AMLOP_TODECSTRING0x97:
4175 /* Source:CData, Result => String */
4176 my_ret = aml_convert(opargs[0], AML_OBJTYPE_DECSTRING, -1);
4177 aml_store(scope, opargs[1], 0, my_ret);
4178 break;
4179 case AMLOP_TOSTRING0x9C:
4180 /* Source:B, Length:I, Result => String */
4181 my_ret = aml_convert(opargs[0], AML_OBJTYPE_STRING,
4182 opargs[1]->v_integer_.vinteger);
4183 aml_store(scope, opargs[2], 0, my_ret);
4184 break;
4185 case AMLOP_CONCAT0x73:
4186 /* Source1:CData, Source2:CData, Result => CData */
4187 my_ret = aml_concat(opargs[0], opargs[1]);
4188 aml_store(scope, opargs[2], 0, my_ret);
4189 break;
4190 case AMLOP_CONCATRES0x84:
4191 /* Concat two resource buffers: buf1, buf2, result => Buffer */
4192 my_ret = aml_concatres(opargs[0], opargs[1]);
4193 aml_store(scope, opargs[2], 0, my_ret);
4194 break;
4195 case AMLOP_MID0x9E:
4196 /* Source:BS, Index:I, Length:I, Result => BS */
4197 my_ret = aml_mid(opargs[0], opargs[1]->v_integer_.vinteger,
4198 opargs[2]->v_integer_.vinteger);
4199 aml_store(scope, opargs[3], 0, my_ret);
4200 break;
4201 case AMLOP_MATCH0x89:
4202 /* Match: Pkg, Op1, Val1, Op2, Val2, Index */
4203 ival = aml_match(opargs[0], opargs[5]->v_integer_.vinteger,
4204 opargs[1]->v_integer_.vinteger, opargs[2]->v_integer_.vinteger,
4205 opargs[3]->v_integer_.vinteger, opargs[4]->v_integer_.vinteger);
4206 break;
4207 case AMLOP_SIZEOF0x87:
4208 /* Sizeof: S => i */
4209 rv = aml_gettgt(opargs[0], opcode);
4210 ival = rv->length;
4211 break;
4212 case AMLOP_OBJECTTYPE0x8E:
4213 /* ObjectType: S => i */
4214 rv = aml_gettgt(opargs[0], opcode);
4215 ival = rv->type;
4216 break;
4217
4218 /* Mutex/Event handlers */
4219 case AMLOP_ACQUIRE0x5B23:
4220 /* Acquire: Sw => Bool */
4221 rv = aml_gettgt(opargs[0], opcode);
4222 ival = acpi_mutex_acquire(scope, rv,
4223 opargs[1]->v_integer_.vinteger);
4224 break;
4225 case AMLOP_RELEASE0x5B27:
4226 /* Release: S */
4227 rv = aml_gettgt(opargs[0], opcode);
4228 acpi_mutex_release(scope, rv);
4229 break;
4230 case AMLOP_WAIT0x5B25:
4231 /* Wait: Si => Bool */
4232 rv = aml_gettgt(opargs[0], opcode);
4233 ival = acpi_event_wait(scope, rv,
4234 opargs[1]->v_integer_.vinteger);
4235 break;
4236 case AMLOP_RESET0x5B26:
4237 /* Reset: S */
4238 rv = aml_gettgt(opargs[0], opcode);
4239 acpi_event_reset(scope, rv);
4240 break;
4241 case AMLOP_SIGNAL0x5B24:
4242 /* Signal: S */
4243 rv = aml_gettgt(opargs[0], opcode);
4244 acpi_event_signal(scope, rv);
4245 break;
4246
4247 /* Named objects */
4248 case AMLOP_NAME0x08:
4249 /* Name: Nt */
4250 rv = opargs[0];
4251 aml_freevalue(rv);
4252 aml_copyvalue(rv, opargs[1]);
4253 break;
4254 case AMLOP_ALIAS0x06:
4255 /* Alias: nN */
4256 rv = _aml_setvalue(opargs[1], AML_OBJTYPE_OBJREF, opcode, 0);
4257 rv->v_objref_.vobjref.ref = aml_gettgt(opargs[0], opcode);
4258 aml_addref(rv->v_objref_.vobjref.ref, "Alias");
4259 break;
4260 case AMLOP_OPREGION0x5B80:
4261 /* OpRegion: Nbii */
4262 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
4263 rv->v_opregion_.vopregion.iospace = opargs[1]->v_integer_.vinteger;
4264 rv->v_opregion_.vopregion.iobase = opargs[2]->v_integer_.vinteger;
4265 rv->v_opregion_.vopregion.iolen = opargs[3]->v_integer_.vinteger;
4266 rv->v_opregion_.vopregion.flag = 0;
4267 break;
4268 case AMLOP_DATAREGION0x5B88:
4269 /* DataTableRegion: N,t:SigStr,t:OemIDStr,t:OemTableIDStr */
4270 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
4271 rv->v_opregion_.vopregion.iospace = GAS_SYSTEM_MEMORY0;
4272 rv->v_opregion_.vopregion.iobase = 0;
4273 rv->v_opregion_.vopregion.iolen = 0;
4274 aml_die("AML-DataTableRegion\n")_aml_die(__FUNCTION__, 4274, "AML-DataTableRegion\n");
4275 break;
4276 case AMLOP_EVENT0x5B02:
4277 /* Event: N */
4278 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_EVENT, 0, 0);
4279 rv->v_evt_.Vevent.state = 0;
4280 break;
4281 case AMLOP_MUTEX0x5B01:
4282 /* Mutex: Nw */
4283 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_MUTEX, 0, 0);
4284 rv->v_mtx_.Vmutex.synclvl = opargs[1]->v_integer_.vinteger;
4285 break;
4286 case AMLOP_SCOPE0x10:
4287 /* Scope: NT */
4288 rv = opargs[0];
28
Null pointer value stored to 'rv'
4289 if (rv->type == AML_OBJTYPE_NAMEREF) {
29
Access to field 'type' results in a dereference of a null pointer (loaded from variable 'rv')
4290 printf("Undefined scope: %s\n", aml_getname(rv->v_nameref_.vbuffer));
4291 break;
4292 }
4293 mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
4294 break;
4295 case AMLOP_DEVICE0x5B82:
4296 /* Device: NT */
4297 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_DEVICE, 0, 0);
4298 mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
4299 break;
4300 case AMLOP_THERMALZONE0x5B85:
4301 /* ThermalZone: NT */
4302 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_THERMZONE, 0, 0);
4303 mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
4304 break;
4305 case AMLOP_POWERRSRC0x5B84:
4306 /* PowerRsrc: NbwT */
4307 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_POWERRSRC, 0, 0);
4308 rv->v_powerrsrc_.vpowerrsrc.pwr_level = opargs[1]->v_integer_.vinteger;
4309 rv->v_powerrsrc_.vpowerrsrc.pwr_order = opargs[2]->v_integer_.vinteger;
4310 mscope = aml_pushscope(scope, opargs[3], rv->node, opcode);
4311 break;
4312 case AMLOP_PROCESSOR0x5B83:
4313 /* Processor: NbdbT */
4314 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_PROCESSOR, 0, 0);
4315 rv->v_processor_.vprocessor.proc_id = opargs[1]->v_integer_.vinteger;
4316 rv->v_processor_.vprocessor.proc_addr = opargs[2]->v_integer_.vinteger;
4317 rv->v_processor_.vprocessor.proc_len = opargs[3]->v_integer_.vinteger;
4318 mscope = aml_pushscope(scope, opargs[4], rv->node, opcode);
4319 break;
4320 case AMLOP_METHOD0x14:
4321 /* Method: NbM */
4322 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_METHOD, 0, 0);
4323 rv->v_method_.vmethod.flags = opargs[1]->v_integer_.vinteger;
4324 rv->v_method_.vmethod.start = opargs[2]->v_buffer_.vbuffer;
4325 rv->v_method_.vmethod.end = rv->v_method_.vmethod.start + opargs[2]->length;
4326 rv->v_method_.vmethod.base = aml_root.start;
4327 break;
4328
4329 /* Field objects */
4330 case AMLOP_CREATEFIELD0x5B13:
4331 /* Source:B, BitIndex:I, NumBits:I, FieldName */
4332 rv = _aml_setvalue(opargs[3], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4333 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer_.vinteger,
4334 opargs[2]->v_integer_.vinteger, NULL((void *)0), 0, 0);
4335 break;
4336 case AMLOP_CREATEBITFIELD0x8D:
4337 /* Source:B, BitIndex:I, FieldName */
4338 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4339 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer_.vinteger,
4340 1, NULL((void *)0), 0, 0);
4341 break;
4342 case AMLOP_CREATEBYTEFIELD0x8C:
4343 /* Source:B, ByteIndex:I, FieldName */
4344 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4345 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer_.vinteger*8,
4346 8, NULL((void *)0), 0, AML_FIELD_BYTEACC0x1);
4347 break;
4348 case AMLOP_CREATEWORDFIELD0x8B:
4349 /* Source:B, ByteIndex:I, FieldName */
4350 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4351 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer_.vinteger*8,
4352 16, NULL((void *)0), 0, AML_FIELD_WORDACC0x2);
4353 break;
4354 case AMLOP_CREATEDWORDFIELD0x8A:
4355 /* Source:B, ByteIndex:I, FieldName */
4356 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4357 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer_.vinteger*8,
4358 32, NULL((void *)0), 0, AML_FIELD_DWORDACC0x3);
4359 break;
4360 case AMLOP_CREATEQWORDFIELD0x8F:
4361 /* Source:B, ByteIndex:I, FieldName */
4362 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4363 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer_.vinteger*8,
4364 64, NULL((void *)0), 0, AML_FIELD_QWORDACC0x4);
4365 break;
4366 case AMLOP_FIELD0x5B81:
4367 /* Field: n:OpRegion, b:Flags, F:ieldlist */
4368 mscope = aml_pushscope(scope, opargs[2], scope->node, opcode);
4369 aml_parsefieldlist(mscope, opcode, opargs[1]->v_integer_.vinteger,
4370 opargs[0], NULL((void *)0), 0);
4371 mscope = NULL((void *)0);
4372 break;
4373 case AMLOP_INDEXFIELD0x5B86:
4374 /* IndexField: n:Index, n:Data, b:Flags, F:ieldlist */
4375 mscope = aml_pushscope(scope, opargs[3], scope->node, opcode);
4376 aml_parsefieldlist(mscope, opcode, opargs[2]->v_integer_.vinteger,
4377 opargs[1], opargs[0], 0);
4378 mscope = NULL((void *)0);
4379 break;
4380 case AMLOP_BANKFIELD0x5B87:
4381 /* BankField: n:OpRegion, n:Field, i:Bank, b:Flags, F:ieldlist */
4382 mscope = aml_pushscope(scope, opargs[4], scope->node, opcode);
4383 aml_parsefieldlist(mscope, opcode, opargs[3]->v_integer_.vinteger,
4384 opargs[0], opargs[1], opargs[2]->v_integer_.vinteger);
4385 mscope = NULL((void *)0);
4386 break;
4387
4388 /* Misc functions */
4389 case AMLOP_STALL0x5B21:
4390 /* Stall: i */
4391 acpi_stall(opargs[0]->v_integer_.vinteger);
4392 break;
4393 case AMLOP_SLEEP0x5B22:
4394 /* Sleep: i */
4395 acpi_sleep(opargs[0]->v_integer_.vinteger, "amlsleep");
4396 break;
4397 case AMLOP_NOTIFY0x86:
4398 /* Notify: Si */
4399 rv = aml_gettgt(opargs[0], opcode);
4400 dnprintf(50,"Notifying: %s %llx\n",
4401 aml_nodename(rv->node),
4402 opargs[1]->v_integer);
4403 aml_notify(rv->node, opargs[1]->v_integer_.vinteger);
4404 break;
4405 case AMLOP_TIMER0x5B33:
4406 /* Timer: => i */
4407 nanouptime(&ts);
4408 ival = ts.tv_sec * 10000000 + ts.tv_nsec / 100;
4409 break;
4410 case AMLOP_FATAL0x5B32:
4411 /* Fatal: bdi */
4412 aml_die("AML FATAL ERROR: %x,%x,%x\n",_aml_die(__FUNCTION__, 4414, "AML FATAL ERROR: %x,%x,%x\n", opargs
[0]->_.vinteger, opargs[1]->_.vinteger, opargs[2]->_
.vinteger)
4413 opargs[0]->v_integer, opargs[1]->v_integer,_aml_die(__FUNCTION__, 4414, "AML FATAL ERROR: %x,%x,%x\n", opargs
[0]->_.vinteger, opargs[1]->_.vinteger, opargs[2]->_
.vinteger)
4414 opargs[2]->v_integer)_aml_die(__FUNCTION__, 4414, "AML FATAL ERROR: %x,%x,%x\n", opargs
[0]->_.vinteger, opargs[1]->_.vinteger, opargs[2]->_
.vinteger)
;
4415 break;
4416 case AMLOP_LOADTABLE0x5B1F:
4417 /* LoadTable(Sig:Str, OEMID:Str, OEMTable:Str, [RootPath:Str], [ParmPath:Str],
4418 [ParmData:DataRefObj]) => DDBHandle */
4419 my_ret = aml_loadtable(acpi_softc, opargs[0]->v_string_.vstring,
4420 opargs[1]->v_string_.vstring, opargs[2]->v_string_.vstring,
4421 opargs[3]->v_string_.vstring, opargs[4]->v_string_.vstring, opargs[5]);
4422 break;
4423 case AMLOP_LOAD0x5B20:
4424 /* Load(Object:NameString, DDBHandle:SuperName) */
4425 mscope = aml_load(acpi_softc, scope, opargs[0], opargs[1]);
4426 break;
4427 case AMLOP_UNLOAD0x5B2A:
4428 /* DDBHandle */
4429 aml_die("Unload")_aml_die(__FUNCTION__, 4429, "Unload");
4430 break;
4431
4432 /* Control Flow */
4433 case AMLOP_IF0xA0:
4434 /* Arguments: iT or iTbT */
4435 if (opargs[0]->v_integer_.vinteger) {
4436 dnprintf(10,"parse-if @ %.4x\n", pc);
4437 mscope = aml_pushscope(scope, opargs[1], scope->node,
4438 AMLOP_IF0xA0);
4439 } else if (opargs[3] != NULL((void *)0)) {
4440 dnprintf(10,"parse-else @ %.4x\n", pc);
4441 mscope = aml_pushscope(scope, opargs[3], scope->node,
4442 AMLOP_ELSE0xA1);
4443 }
4444 break;
4445 case AMLOP_WHILE0xA2:
4446 if (opargs[0]->v_integer_.vinteger) {
4447 /* Set parent position to start of WHILE */
4448 scope->pos = start;
4449 mscope = aml_pushscope(scope, opargs[1], scope->node,
4450 AMLOP_WHILE0xA2);
4451 }
4452 break;
4453 case AMLOP_BREAK0xA5:
4454 /* Break: Find While Scope parent, mark type as null */
4455 aml_findscope(scope, AMLOP_WHILE0xA2, AMLOP_BREAK0xA5);
4456 break;
4457 case AMLOP_CONTINUE0x9F:
4458 /* Find Scope.. mark all objects as invalid on way to root */
4459 aml_findscope(scope, AMLOP_WHILE0xA2, AMLOP_CONTINUE0x9F);
4460 break;
4461 case AMLOP_RETURN0xA4:
4462 mscope = aml_findscope(scope, AMLOP_METHOD0x14, AMLOP_RETURN0xA4);
4463 if (mscope->retv) {
4464 aml_die("already allocated\n")_aml_die(__FUNCTION__, 4464, "already allocated\n");
4465 }
4466 mscope->retv = aml_allocvalue(0,0,NULL((void *)0));
4467 aml_copyvalue(mscope->retv, opargs[0]);
4468 mscope = NULL((void *)0);
4469 break;
4470 default:
4471 /* may be set direct result */
4472 aml_die("Unknown opcode: %x:%s\n", opcode, htab->mnem)_aml_die(__FUNCTION__, 4472, "Unknown opcode: %x:%s\n", opcode
, htab->mnem)
;
4473 break;
4474 }
4475 if (mscope != NULL((void *)0)) {
4476 /* Change our scope to new scope */
4477 scope = mscope;
4478 }
4479 if ((ret_type == 'i' || ret_type == 't') && my_ret == NULL((void *)0)) {
4480 dnprintf(10,"quick: %.4x [%s] alloc return integer = 0x%llx\n",
4481 pc, htab->mnem, ival);
4482 my_ret = aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL((void *)0));
4483 }
4484 if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
4485 dnprintf(10,"quick: %.4x convert to integer %s -> %s\n",
4486 pc, htab->mnem, stype);
4487 my_ret = aml_convert(my_ret, AML_OBJTYPE_INTEGER, -1);
4488 }
4489 if (my_ret != NULL((void *)0)) {
4490 /* Display result */
4491 dnprintf(20,"quick: %.4x %18s %c %.4x\n", pc, stype,
4492 ret_type, my_ret->stack);
4493 }
4494
4495 /* End opcode: display/free arguments */
4496parse_error:
4497 for (idx=0; idx<8; idx++) {
4498 if (opargs[idx] == my_ret)
4499 opargs[idx] = NULL((void *)0);
4500 aml_delref(&opargs[idx], "oparg");
4501 }
4502
4503 /* If parsing whole scope and not done, start again */
4504 if (ret_type == 'T') {
4505 aml_delref(&my_ret, "scope.loop");
4506 while (scope->pos >= scope->end && scope != iscope) {
4507 /* Pop intermediate scope */
4508 scope = aml_popscope(scope);
4509 }
4510 if (scope->pos && scope->pos < scope->end)
4511 goto start;
4512 }
4513
4514 odp--;
4515 dnprintf(50, ">>return [%s] %s %c %p\n", aml_nodename(scope->node),
4516 stype, ret_type, my_ret);
4517
4518 return my_ret;
4519}
4520
4521int
4522acpi_parse_aml(struct acpi_softc *sc, const char *rootpath,
4523 uint8_t *start, uint32_t length)
4524{
4525 struct aml_node *root = &aml_root;
4526 struct aml_scope *scope;
4527 struct aml_value res;
4528
4529 if (rootpath) {
4530 root = aml_searchname(&aml_root, rootpath);
4531 if (root == NULL((void *)0))
4532 aml_die("Invalid RootPathName %s\n", rootpath)_aml_die(__FUNCTION__, 4532, "Invalid RootPathName %s\n", rootpath
)
;
4533 }
4534
4535 aml_root.start = start;
4536 memset(&res, 0, sizeof(res))__builtin_memset((&res), (0), (sizeof(res)));
4537 res.type = AML_OBJTYPE_SCOPE;
4538 res.length = length;
4539 res.v_buffer_.vbuffer = start;
4540
4541 /* Push toplevel scope, parse AML */
4542 aml_error = 0;
4543 scope = aml_pushscope(NULL((void *)0), &res, &aml_root, AMLOP_SCOPE0x10);
4544 aml_busy++;
4545 aml_parse(scope, 'T', "TopLevel");
4546 aml_busy--;
4547 aml_popscope(scope);
4548
4549 if (aml_error) {
4550 printf("error in acpi_parse_aml\n");
4551 return -1;
4552 }
4553 return (0);
4554}
4555
4556/*
4557 * @@@: External API
4558 *
4559 * evaluate an AML node
4560 * Returns a copy of the value in res (must be freed by user)
4561 */
4562int
4563aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
4564 int argc, struct aml_value *argv, struct aml_value *res)
4565{
4566 struct aml_value *xres;
4567
4568 if (res)
4569 memset(res, 0, sizeof(*res))__builtin_memset((res), (0), (sizeof(*res)));
4570 if (node == NULL((void *)0) || node->value == NULL((void *)0))
4571 return (ACPI_E_BADVALUE0x01);
4572 dnprintf(12,"EVALNODE: %s %lx\n", aml_nodename(node), acpi_nalloc);
4573
4574 aml_error = 0;
4575 xres = aml_eval(NULL((void *)0), node->value, 't', argc, argv);
4576 if (xres) {
4577 if (res)
4578 aml_copyvalue(res, xres);
4579 if (xres != node->value)
4580 aml_delref(&xres, "evalnode");
4581 }
4582 if (aml_error) {
4583 printf("error evaluating: %s\n", aml_nodename(node));
4584 return (-1);
4585 }
4586 return (0);
4587}
4588
4589int
4590aml_node_setval(struct acpi_softc *sc, struct aml_node *node, int64_t val)
4591{
4592 struct aml_value env;
4593
4594 if (!node)
4595 return (0);
4596
4597 memset(&env, 0, sizeof(env))__builtin_memset((&env), (0), (sizeof(env)));
4598 env.type = AML_OBJTYPE_INTEGER;
4599 env.v_integer_.vinteger = val;
4600
4601 return aml_evalnode(sc, node, 1, &env, NULL((void *)0));
4602}
4603
4604/*
4605 * evaluate an AML name
4606 * Returns a copy of the value in res (must be freed by user)
4607 */
4608int
4609aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
4610 int argc, struct aml_value *argv, struct aml_value *res)
4611{
4612 parent = aml_searchname(parent, name);
4613 return aml_evalnode(sc, parent, argc, argv, res);
4614}
4615
4616/*
4617 * evaluate an AML integer object
4618 */
4619int
4620aml_evalinteger(struct acpi_softc *sc, struct aml_node *parent,
4621 const char *name, int argc, struct aml_value *argv, int64_t *ival)
4622{
4623 struct aml_value res;
4624 int rc;
4625
4626 parent = aml_searchname(parent, name);
4627 rc = aml_evalnode(sc, parent, argc, argv, &res);
4628 if (rc == 0) {
4629 *ival = aml_val2int(&res);
4630 aml_freevalue(&res);
4631 }
4632 return rc;
4633}
4634
4635/*
4636 * Search for an AML name in namespace.. root only
4637 */
4638struct aml_node *
4639__aml_searchname(struct aml_node *root, const void *vname, int create)
4640{
4641 char *name = (char *)vname;
4642 char nseg[AML_NAMESEG_LEN4 + 1];
4643 int i;
4644
4645 dnprintf(25,"Searchname: %s:%s = ", aml_nodename(root), name);
4646 while (*name == AMLOP_ROOTCHAR0x5C) {
4647 root = &aml_root;
4648 name++;
4649 }
4650 while (*name != 0) {
4651 /* Ugh.. we can have short names here: append '_' */
4652 strlcpy(nseg, "____", sizeof(nseg));
4653 for (i=0; i < AML_NAMESEG_LEN4 && *name && *name != '.'; i++)
4654 nseg[i] = *name++;
4655 if (*name == '.')
4656 name++;
4657 root = __aml_search(root, nseg, create);
4658 }
4659 dnprintf(25,"%p %s\n", root, aml_nodename(root));
4660 return root;
4661}
4662
4663struct aml_node *
4664aml_searchname(struct aml_node *root, const void *vname)
4665{
4666 return __aml_searchname(root, vname, 0);
4667}
4668
4669/*
4670 * Search for relative name
4671 */
4672struct aml_node *
4673aml_searchrel(struct aml_node *root, const void *vname)
4674{
4675 struct aml_node *res;
4676
4677 while (root) {
4678 res = aml_searchname(root, vname);
4679 if (res != NULL((void *)0))
4680 return res;
4681 root = root->parent;
4682 }
4683 return NULL((void *)0);
4684}
4685
4686#ifndef SMALL_KERNEL
4687
4688void
4689acpi_getdevlist(struct acpi_devlist_head *list, struct aml_node *root,
4690 struct aml_value *pkg, int off)
4691{
4692 struct acpi_devlist *dl;
4693 struct aml_value *val;
4694 struct aml_node *node;
4695 int idx;
4696
4697 for (idx = off; idx < pkg->length; idx++) {
4698 val = pkg->v_package_.vpackage[idx];
4699 if (val->type == AML_OBJTYPE_NAMEREF) {
4700 node = aml_searchrel(root, aml_getname(val->v_nameref_.vbuffer));
4701 if (node == NULL((void *)0)) {
4702 printf("%s: device %s not found\n", __func__,
4703 aml_getname(val->v_nameref_.vbuffer));
4704 continue;
4705 }
4706 val = node->value;
4707 }
4708 if (val->type == AML_OBJTYPE_OBJREF)
4709 val = val->v_objref_.vobjref.ref;
4710 if (val->node) {
4711 dl = acpi_os_malloc(sizeof(*dl))_acpi_os_malloc(sizeof(*dl), __FUNCTION__, 4711);
4712 if (dl) {
4713 dl->dev_node = val->node;
4714 TAILQ_INSERT_TAIL(list, dl, dev_link)do { (dl)->dev_link.tqe_next = ((void *)0); (dl)->dev_link
.tqe_prev = (list)->tqh_last; *(list)->tqh_last = (dl);
(list)->tqh_last = &(dl)->dev_link.tqe_next; } while
(0)
;
4715 }
4716 }
4717 }
4718}
4719
4720void
4721acpi_freedevlist(struct acpi_devlist_head *list)
4722{
4723 struct acpi_devlist *dl;
4724
4725 while ((dl = TAILQ_FIRST(list)((list)->tqh_first)) != NULL((void *)0)) {
4726 TAILQ_REMOVE(list, dl, dev_link)do { if (((dl)->dev_link.tqe_next) != ((void *)0)) (dl)->
dev_link.tqe_next->dev_link.tqe_prev = (dl)->dev_link.tqe_prev
; else (list)->tqh_last = (dl)->dev_link.tqe_prev; *(dl
)->dev_link.tqe_prev = (dl)->dev_link.tqe_next; ((dl)->
dev_link.tqe_prev) = ((void *)-1); ((dl)->dev_link.tqe_next
) = ((void *)-1); } while (0)
;
4727 acpi_os_free(dl)_acpi_os_free(dl, __FUNCTION__, 4727);
4728 }
4729}
4730
4731#endif /* SMALL_KERNEL */