This source file includes following definitions.
- aml_pc
- _aml_die
- aml_hashopcodes
- aml_findopcode
- aml_mnem
- aml_args
- _acpi_os_malloc
- _acpi_os_free
- acpi_sleep
- acpi_stall
- acpi_mutex_acquire
- acpi_mutex_release
- aml_dump
- aml_tstbit
- aml_setbit
- aml_gasio
- acpi_poll
- aml_register_notify
- aml_notify
- aml_notify_dev
- acpi_poll_notify
- __aml_search
- aml_nodename
- aml_getname
- aml_createname
- aml_searchname
- aml_delchildren
- aml_alloctmp
- aml_pushscope
- aml_popscope
- aml_parsenode
- aml_setbufint
- aml_getbufint
- aml_lockfield
- aml_unlockfield
- aml_getbuffer
- aml_fieldio
- aml_showvalue
- aml_derefvalue
- aml_str2int
- aml_val2int
- _aml_setvalue
- aml_copyvalue
- is_local
- aml_setvalue
- aml_allocvalue
- aml_freevalue
- aml_addref
- _aml_delref
- aml_convradix
- aml_lsb
- aml_msb
- aml_evalexpr
- aml_cmpvalue
- aml_bufcpy
- aml_callmethod
- aml_evalmethod
- aml_evalnode
- aml_evalname
- aml_evalinteger
- aml_walknodes
- aml_walktree
- aml_walkroot
- aml_find_node
- aml_parseopcode
- aml_parsename
- aml_parselength
- aml_parseend
- aml_resize
- aml_match
- aml_getpciaddr
- aml_fixref
- aml_parseint
- aml_evaltarget
- aml_evalterm
- aml_parsenamed
- aml_parsenamedscope
- aml_parsemath
- aml_parsecompare
- aml_parseif
- aml_parsewhile
- aml_parsebufpkg
- aml_parsemethod
- aml_parsesimple
- aml_parsefieldunit
- aml_parsebufferfield
- aml_parsemuxaction
- aml_parsemisc2
- aml_parsemisc3
- aml_parsematch
- aml_parseref
- aml_parsestring
- aml_parseterm
- aml_parsetarget
- aml_parseop
- aml_eisaid
- aml_fixup_dsdt
- aml_callosi
- aml_create_defaultobjects
- aml_print_resource
- aml_mapresource
- aml_parse_resource
- aml_foreachpkg
- acpi_parse_aml
- aml_fixup_node
- aml_postparse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/malloc.h>
22 #include <sys/proc.h>
23
24 #include <machine/bus.h>
25
26 #ifdef DDB
27 #include <machine/db_machdep.h>
28 #include <ddb/db_command.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 #define opsize(opcode) (((opcode) & 0xFF00) ? 2 : 1)
37
38 #define AML_CHECKSTACK()
39
40 #define AML_FIELD_RESERVED 0x00
41 #define AML_FIELD_ATTRIB 0x01
42
43 #define AML_REVISION 0x01
44 #define AML_INTSTRLEN 16
45 #define AML_NAMESEG_LEN 4
46
47 #define aml_valid(pv) ((pv) != NULL)
48
49 #define aml_ipaddr(n) ((n)-aml_root.start)
50
51 extern int hz;
52
53 struct aml_scope;
54
55 int aml_cmpvalue(struct aml_value *, struct aml_value *, int);
56 void aml_copyvalue(struct aml_value *, struct aml_value *);
57
58 void aml_setvalue(struct aml_scope *, struct aml_value *,
59 struct aml_value *, int64_t);
60 void aml_freevalue(struct aml_value *);
61 struct aml_value *aml_allocvalue(int, int64_t, const void *);
62 struct aml_value *_aml_setvalue(struct aml_value *, int, int64_t,
63 const void *);
64
65 u_int64_t aml_convradix(u_int64_t, int, int);
66 int64_t aml_evalexpr(int64_t, int64_t, int);
67 int aml_lsb(u_int64_t);
68 int aml_msb(u_int64_t);
69
70 int aml_tstbit(const u_int8_t *, int);
71 void aml_setbit(u_int8_t *, int, int);
72
73 void aml_bufcpy(void *, int, const void *, int, int);
74 int aml_evalinteger(struct acpi_softc *, struct aml_node *,
75 const char *, int, struct aml_value *, int64_t *);
76
77 void _aml_delref(struct aml_value **val, const char *, int);
78 void aml_delref(struct aml_value **);
79 void aml_addref(struct aml_value *);
80 int aml_pc(uint8_t *);
81
82 #define aml_delref(x) _aml_delref(x, __FUNCTION__, __LINE__)
83
84 struct aml_value *aml_parseop(struct aml_scope *, struct aml_value *);
85 struct aml_value *aml_parsetarget(struct aml_scope *, struct aml_value *,
86 struct aml_value **);
87 struct aml_value *aml_parseterm(struct aml_scope *, struct aml_value *);
88
89 struct aml_value *aml_evaltarget(struct aml_scope *scope,
90 struct aml_value *res);
91 int aml_evalterm(struct aml_scope *scope,
92 struct aml_value *raw, struct aml_value *dst);
93 void aml_gasio(struct acpi_softc *, int, uint64_t, uint64_t,
94 int, int, int, void *, int);
95
96 struct aml_opcode *aml_findopcode(int);
97
98 #define acpi_os_malloc(sz) _acpi_os_malloc(sz, __FUNCTION__, __LINE__)
99 #define acpi_os_free(ptr) _acpi_os_free(ptr, __FUNCTION__, __LINE__)
100
101 void *_acpi_os_malloc(size_t, const char *, int);
102 void _acpi_os_free(void *, const char *, int);
103 void acpi_sleep(int);
104 void acpi_stall(int);
105
106 struct aml_value *aml_callosi(struct aml_scope *, struct aml_value *);
107 struct aml_value *aml_callmethod(struct aml_scope *, struct aml_value *);
108 struct aml_value *aml_evalmethod(struct aml_scope *, struct aml_node *,
109 int, struct aml_value *, struct aml_value *);
110
111 const char *aml_getname(const char *);
112 void aml_dump(int, u_int8_t *);
113 void _aml_die(const char *fn, int line, const char *fmt, ...);
114 #define aml_die(x...) _aml_die(__FUNCTION__, __LINE__, x)
115
116
117
118
119 int aml_intlen = 64;
120 struct aml_node aml_root;
121 struct aml_value *aml_global_lock;
122 struct acpi_softc *dsdt_softc;
123
124 struct aml_value *aml_parsenamed(struct aml_scope *, int, struct aml_value *);
125 struct aml_value *aml_parsenamedscope(struct aml_scope *, int, struct aml_value *);
126 struct aml_value *aml_parsemath(struct aml_scope *, int, struct aml_value *);
127 struct aml_value *aml_parsecompare(struct aml_scope *, int, struct aml_value *);
128 struct aml_value *aml_parseif(struct aml_scope *, int, struct aml_value *);
129 struct aml_value *aml_parsewhile(struct aml_scope *, int, struct aml_value *);
130 struct aml_value *aml_parsebufpkg(struct aml_scope *, int, struct aml_value *);
131 struct aml_value *aml_parsemethod(struct aml_scope *, int, struct aml_value *);
132 struct aml_value *aml_parsesimple(struct aml_scope *, int, struct aml_value *);
133 struct aml_value *aml_parsefieldunit(struct aml_scope *, int, struct aml_value *);
134 struct aml_value *aml_parsebufferfield(struct aml_scope *, int, struct aml_value *);
135 struct aml_value *aml_parsemisc3(struct aml_scope *, int, struct aml_value *);
136 struct aml_value *aml_parsemuxaction(struct aml_scope *, int, struct aml_value *);
137 struct aml_value *aml_parsemisc2(struct aml_scope *, int, struct aml_value *);
138 struct aml_value *aml_parsematch(struct aml_scope *, int, struct aml_value *);
139 struct aml_value *aml_parseref(struct aml_scope *, int, struct aml_value *);
140 struct aml_value *aml_parsestring(struct aml_scope *, int, struct aml_value *);
141
142
143 #define HASH_OFF 6904
144 #define HASH_SIZE 179
145 #define HASH_KEY(k) (((k) ^ HASH_OFF) % HASH_SIZE)
146
147
148
149
150
151 struct aml_opcode **aml_ophash;
152 struct aml_opcode aml_table[] = {
153
154 { AMLOP_ZERO, "Zero", "c", aml_parsesimple },
155 { AMLOP_ONE, "One", "c", aml_parsesimple },
156 { AMLOP_ONES, "Ones", "c", aml_parsesimple },
157 { AMLOP_REVISION, "Revision", "R", aml_parsesimple },
158 { AMLOP_BYTEPREFIX, ".Byte", "b", aml_parsesimple },
159 { AMLOP_WORDPREFIX, ".Word", "w", aml_parsesimple },
160 { AMLOP_DWORDPREFIX, ".DWord", "d", aml_parsesimple },
161 { AMLOP_QWORDPREFIX, ".QWord", "q", aml_parsesimple },
162 { AMLOP_STRINGPREFIX, ".String", "a", aml_parsesimple },
163 { AMLOP_DEBUG, "DebugOp", "D", aml_parsesimple },
164 { AMLOP_BUFFER, "Buffer", "piB", aml_parsebufpkg },
165 { AMLOP_PACKAGE, "Package", "pbT", aml_parsebufpkg },
166 { AMLOP_VARPACKAGE, "VarPackage", "piT", aml_parsebufpkg },
167
168
169 { AMLOP_LOCAL0, "Local0", "L", aml_parseref },
170 { AMLOP_LOCAL1, "Local1", "L", aml_parseref },
171 { AMLOP_LOCAL2, "Local2", "L", aml_parseref },
172 { AMLOP_LOCAL3, "Local3", "L", aml_parseref },
173 { AMLOP_LOCAL4, "Local4", "L", aml_parseref },
174 { AMLOP_LOCAL5, "Local5", "L", aml_parseref },
175 { AMLOP_LOCAL6, "Local6", "L", aml_parseref },
176 { AMLOP_LOCAL7, "Local7", "L", aml_parseref },
177 { AMLOP_ARG0, "Arg0", "A", aml_parseref },
178 { AMLOP_ARG1, "Arg1", "A", aml_parseref },
179 { AMLOP_ARG2, "Arg2", "A", aml_parseref },
180 { AMLOP_ARG3, "Arg3", "A", aml_parseref },
181 { AMLOP_ARG4, "Arg4", "A", aml_parseref },
182 { AMLOP_ARG5, "Arg5", "A", aml_parseref },
183 { AMLOP_ARG6, "Arg6", "A", aml_parseref },
184
185
186 { AMLOP_IF, "If", "pI", aml_parseif },
187 { AMLOP_ELSE, "Else", "pT" },
188 { AMLOP_WHILE, "While", "piT", aml_parsewhile },
189 { AMLOP_BREAK, "Break", "" },
190 { AMLOP_CONTINUE, "Continue", "" },
191 { AMLOP_RETURN, "Return", "t", aml_parseref },
192 { AMLOP_FATAL, "Fatal", "bdi", aml_parsemisc2 },
193 { AMLOP_NOP, "Nop", "", aml_parsesimple },
194 { AMLOP_BREAKPOINT, "BreakPoint", "" },
195
196
197 { AMLOP_INCREMENT, "Increment", "t", aml_parsemath },
198 { AMLOP_DECREMENT, "Decrement", "t", aml_parsemath },
199 { AMLOP_ADD, "Add", "iir", aml_parsemath },
200 { AMLOP_SUBTRACT, "Subtract", "iir", aml_parsemath },
201 { AMLOP_MULTIPLY, "Multiply", "iir", aml_parsemath },
202 { AMLOP_DIVIDE, "Divide", "iirr", aml_parsemath },
203 { AMLOP_SHL, "ShiftLeft", "iir", aml_parsemath },
204 { AMLOP_SHR, "ShiftRight", "iir", aml_parsemath },
205 { AMLOP_AND, "And", "iir", aml_parsemath },
206 { AMLOP_NAND, "Nand", "iir", aml_parsemath },
207 { AMLOP_OR, "Or", "iir", aml_parsemath },
208 { AMLOP_NOR, "Nor", "iir", aml_parsemath },
209 { AMLOP_XOR, "Xor", "iir", aml_parsemath },
210 { AMLOP_NOT, "Not", "ir", aml_parsemath },
211 { AMLOP_MOD, "Mod", "iir", aml_parsemath },
212 { AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "ir", aml_parsemath },
213 { AMLOP_FINDSETRIGHTBIT,"FindSetRightBit", "ir",aml_parsemath },
214
215
216 { AMLOP_LAND, "LAnd", "ii", aml_parsemath },
217 { AMLOP_LOR, "LOr", "ii", aml_parsemath },
218 { AMLOP_LNOT, "LNot", "i", aml_parsemath },
219 { AMLOP_LNOTEQUAL, "LNotEqual", "tt", aml_parsecompare },
220 { AMLOP_LLESSEQUAL, "LLessEqual", "tt", aml_parsecompare },
221 { AMLOP_LGREATEREQUAL, "LGreaterEqual", "tt", aml_parsecompare },
222 { AMLOP_LEQUAL, "LEqual", "tt", aml_parsecompare },
223 { AMLOP_LGREATER, "LGreater", "tt", aml_parsecompare },
224 { AMLOP_LLESS, "LLess", "tt", aml_parsecompare },
225
226
227 { AMLOP_NAMECHAR, ".NameRef", "n", aml_parsesimple },
228 { AMLOP_ALIAS, "Alias", "nN", aml_parsenamed },
229 { AMLOP_NAME, "Name", "Nt", aml_parsenamed },
230 { AMLOP_EVENT, "Event", "N", aml_parsenamed },
231 { AMLOP_MUTEX, "Mutex", "Nb", aml_parsenamed },
232 { AMLOP_DATAREGION, "DataRegion", "Nttt", aml_parsenamed },
233 { AMLOP_OPREGION, "OpRegion", "Nbii", aml_parsenamed },
234 { AMLOP_SCOPE, "Scope", "pNT", aml_parsenamedscope },
235 { AMLOP_DEVICE, "Device", "pNT", aml_parsenamedscope },
236 { AMLOP_POWERRSRC, "Power Resource", "pNbwT", aml_parsenamedscope },
237 { AMLOP_THERMALZONE, "ThermalZone", "pNT", aml_parsenamedscope },
238 { AMLOP_PROCESSOR, "Processor", "pNbdbT", aml_parsenamedscope },
239 { AMLOP_METHOD, "Method", "pNfM", aml_parsemethod },
240
241
242 { AMLOP_FIELD, "Field", "pnfF", aml_parsefieldunit },
243 { AMLOP_INDEXFIELD, "IndexField", "pntfF", aml_parsefieldunit },
244 { AMLOP_BANKFIELD, "BankField", "pnnifF", aml_parsefieldunit },
245 { AMLOP_CREATEFIELD, "CreateField", "tiiN", aml_parsebufferfield },
246 { AMLOP_CREATEQWORDFIELD, "CreateQWordField","tiN", aml_parsebufferfield },
247 { AMLOP_CREATEDWORDFIELD, "CreateDWordField","tiN", aml_parsebufferfield },
248 { AMLOP_CREATEWORDFIELD, "CreateWordField", "tiN", aml_parsebufferfield },
249 { AMLOP_CREATEBYTEFIELD, "CreateByteField", "tiN", aml_parsebufferfield },
250 { AMLOP_CREATEBITFIELD, "CreateBitField", "tiN", aml_parsebufferfield },
251
252
253 { AMLOP_TOINTEGER, "ToInteger", "tr", aml_parsemath },
254 { AMLOP_TOBUFFER, "ToBuffer", "tr", },
255 { AMLOP_TODECSTRING, "ToDecString", "ir", aml_parsestring },
256 { AMLOP_TOHEXSTRING, "ToHexString", "ir", aml_parsestring },
257 { AMLOP_TOSTRING, "ToString", "t", aml_parsestring },
258 { AMLOP_MID, "Mid", "tiir", aml_parsestring },
259 { AMLOP_FROMBCD, "FromBCD", "ir", aml_parsemath },
260 { AMLOP_TOBCD, "ToBCD", "ir", aml_parsemath },
261
262
263 { AMLOP_ACQUIRE, "Acquire", "tw", aml_parsemuxaction },
264 { AMLOP_RELEASE, "Release", "t", aml_parsemuxaction },
265 { AMLOP_SIGNAL, "Signal", "t", aml_parsemuxaction },
266 { AMLOP_WAIT, "Wait", "ti", aml_parsemuxaction },
267 { AMLOP_RESET, "Reset", "t", aml_parsemuxaction },
268
269 { AMLOP_INDEX, "Index", "tir", aml_parseref },
270 { AMLOP_DEREFOF, "DerefOf", "t", aml_parseref },
271 { AMLOP_REFOF, "RefOf", "t", aml_parseref },
272 { AMLOP_CONDREFOF, "CondRef", "nr", aml_parseref },
273
274 { AMLOP_LOADTABLE, "LoadTable", "tttttt" },
275 { AMLOP_STALL, "Stall", "i", aml_parsemisc2 },
276 { AMLOP_SLEEP, "Sleep", "i", aml_parsemisc2 },
277 { AMLOP_LOAD, "Load", "nt", aml_parseref },
278 { AMLOP_UNLOAD, "Unload", "t" },
279 { AMLOP_STORE, "Store", "tr", aml_parseref },
280 { AMLOP_CONCAT, "Concat", "ttr", aml_parsestring },
281 { AMLOP_CONCATRES, "ConcatRes", "ttt" },
282 { AMLOP_NOTIFY, "Notify", "ti", aml_parsemisc2 },
283 { AMLOP_SIZEOF, "Sizeof", "t", aml_parsemisc3 },
284 { AMLOP_MATCH, "Match", "tbibii", aml_parsematch },
285 { AMLOP_OBJECTTYPE, "ObjectType", "t", aml_parsemisc3 },
286 { AMLOP_COPYOBJECT, "CopyObject", "tr", aml_parseref },
287 };
288
289 int aml_pc(uint8_t *src)
290 {
291 return src - aml_root.start;
292 }
293
294 struct aml_scope *aml_lastscope;
295
296 void _aml_die(const char *fn, int line, const char *fmt, ...)
297 {
298 struct aml_scope *root;
299 va_list ap;
300 int idx;
301
302 va_start(ap, fmt);
303 vprintf(fmt, ap);
304 printf("\n");
305 va_end(ap);
306
307 for (root = aml_lastscope; root && root->pos; root = root->parent) {
308 printf("%.4x Called: %s\n", aml_pc(root->pos),
309 aml_nodename(root->node));
310 for (idx = 0; idx < root->nargs; idx++) {
311 printf(" arg%d: ", idx);
312 aml_showvalue(&root->args[idx], 0);
313 }
314 for (idx = 0; root->locals && idx < AML_MAX_LOCAL; idx++) {
315 if (root->locals[idx].type) {
316 printf(" local%d: ", idx);
317 aml_showvalue(&root->locals[idx], 0);
318 }
319 }
320 }
321
322
323 panic("aml_die %s:%d", fn, line);
324 }
325
326 void
327 aml_hashopcodes(void)
328 {
329 int i;
330
331
332 aml_ophash = (struct aml_opcode **)acpi_os_malloc(HASH_SIZE*sizeof(struct aml_opcode *));
333 for (i = 0; i < sizeof(aml_table) / sizeof(aml_table[0]); i++)
334 aml_ophash[HASH_KEY(aml_table[i].opcode)] = &aml_table[i];
335 }
336
337 struct aml_opcode *
338 aml_findopcode(int opcode)
339 {
340 struct aml_opcode *hop;
341
342 hop = aml_ophash[HASH_KEY(opcode)];
343 if (hop && hop->opcode == opcode)
344 return hop;
345 return NULL;
346 }
347
348 const char *
349 aml_mnem(int opcode, uint8_t *pos)
350 {
351 struct aml_opcode *tab;
352 static char mnemstr[32];
353
354 if ((tab = aml_findopcode(opcode)) != NULL) {
355 strlcpy(mnemstr, tab->mnem, sizeof(mnemstr));
356 if (pos != NULL) {
357 switch (opcode) {
358 case AMLOP_STRINGPREFIX:
359 snprintf(mnemstr, sizeof(mnemstr), "\"%s\"", pos);
360 break;
361 case AMLOP_BYTEPREFIX:
362 snprintf(mnemstr, sizeof(mnemstr), "0x%.2x",
363 *(uint8_t *)pos);
364 break;
365 case AMLOP_WORDPREFIX:
366 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
367 *(uint16_t *)pos);
368 break;
369 case AMLOP_DWORDPREFIX:
370 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
371 *(uint16_t *)pos);
372 break;
373 case AMLOP_NAMECHAR:
374 strlcpy(mnemstr, aml_getname(pos), sizeof(mnemstr));
375 break;
376 }
377 }
378 return mnemstr;
379 }
380 return ("xxx");
381 }
382
383 const char *
384 aml_args(int opcode)
385 {
386 struct aml_opcode *tab;
387
388 if ((tab = aml_findopcode(opcode)) != NULL)
389 return tab->args;
390 return ("");
391 }
392
393 struct aml_notify_data {
394 struct aml_node *node;
395 char pnpid[20];
396 void *cbarg;
397 int (*cbproc)(struct aml_node *, int, void *);
398 int poll;
399
400 SLIST_ENTRY(aml_notify_data) link;
401 };
402
403 SLIST_HEAD(aml_notify_head, aml_notify_data);
404 struct aml_notify_head aml_notify_list =
405 LIST_HEAD_INITIALIZER(&aml_notify_list);
406
407
408
409
410
411 long acpi_nalloc;
412
413 struct acpi_memblock {
414 size_t size;
415 };
416
417 void *
418 _acpi_os_malloc(size_t size, const char *fn, int line)
419 {
420 struct acpi_memblock *sptr;
421
422 sptr = malloc(size+sizeof(*sptr), M_DEVBUF, M_WAITOK);
423 dnprintf(99, "alloc: %x %s:%d\n", sptr, fn, line);
424 if (sptr) {
425 acpi_nalloc += size;
426 sptr->size = size;
427 memset(&sptr[1], 0, size);
428 return &sptr[1];
429 }
430 return NULL;
431 }
432
433 void
434 _acpi_os_free(void *ptr, const char *fn, int line)
435 {
436 struct acpi_memblock *sptr;
437
438 if (ptr != NULL) {
439 sptr = &(((struct acpi_memblock *)ptr)[-1]);
440 acpi_nalloc -= sptr->size;
441
442 dnprintf(99, "free: %x %s:%d\n", sptr, fn, line);
443 free(sptr, M_DEVBUF);
444 }
445 }
446
447 void
448 acpi_sleep(int ms)
449 {
450 int to = ms * hz / 1000;
451
452 if (cold)
453 delay(ms * 1000);
454 else {
455 if (to <= 0)
456 to = 1;
457 while (tsleep(dsdt_softc, PWAIT, "asleep", to) !=
458 EWOULDBLOCK);
459 }
460 }
461
462 void
463 acpi_stall(int us)
464 {
465 delay(us);
466 }
467
468 int
469 acpi_mutex_acquire(struct aml_value *val, int timeout)
470 {
471
472 dnprintf(50, "acpi_mutex_acquire\n");
473
474 return (0);
475 #if 0
476 struct acpi_mutex *mtx = val->v_mutex;
477 int rv = 0, ts, tries = 0;
478
479 if (val->type != AML_OBJTYPE_MUTEX) {
480 printf("acpi_mutex_acquire: invalid mutex\n");
481 return (1);
482 }
483
484 if (timeout == 0xffff)
485 timeout = 0;
486
487
488 rw_enter_write(&mtx->amt_lock);
489 while (mtx->amt_ref_count) {
490 rw_exit_write(&mtx->amt_lock);
491
492 ts = tsleep(mtx, PWAIT, mtx->amt_name, timeout / hz);
493 if (ts == EWOULDBLOCK) {
494 rv = 1;
495 goto done;
496 }
497 tries++;
498 rw_enter_write(&mtx->amt_lock);
499 }
500
501 mtx->amt_ref_count++;
502 rw_exit_write(&mtx->amt_lock);
503 done:
504 return (rv);
505 #endif
506 }
507
508 void
509 acpi_mutex_release(struct aml_value *val)
510 {
511 dnprintf(50, "acpi_mutex_release\n");
512 #if 0
513 struct acpi_mutex *mtx = val->v_mutex;
514
515
516 if (val->type != AML_OBJTYPE_MUTEX) {
517 printf("acpi_mutex_acquire: invalid mutex\n");
518 return;
519 }
520
521 rw_enter_write(&mtx->amt_lock);
522
523 if (mtx->amt_ref_count == 0) {
524 printf("acpi_mutex_release underflow %s\n", mtx->amt_name);
525 goto done;
526 }
527
528 mtx->amt_ref_count--;
529 wakeup(mtx);
530 done:
531 rw_exit_write(&mtx->amt_lock);
532 #endif
533 }
534
535
536
537
538
539 void
540 aml_dump(int len, u_int8_t *buf)
541 {
542 int idx;
543
544 dnprintf(50, "{ ");
545 for (idx = 0; idx < len; idx++) {
546 dnprintf(50, "%s0x%.2x", idx ? ", " : "", buf[idx]);
547 }
548 dnprintf(50, " }\n");
549 }
550
551
552 int
553 aml_tstbit(const u_int8_t *pb, int bit)
554 {
555 pb += aml_bytepos(bit);
556
557 return (*pb & aml_bitmask(bit));
558 }
559
560 void
561 aml_setbit(u_int8_t *pb, int bit, int val)
562 {
563 pb += aml_bytepos(bit);
564
565 if (val)
566 *pb |= aml_bitmask(bit);
567 else
568 *pb &= ~aml_bitmask(bit);
569 }
570
571
572 void
573 aml_gasio(struct acpi_softc *sc, int type, uint64_t base, uint64_t length,
574 int bitpos, int bitlen, int size, void *buf, int mode)
575 {
576 dnprintf(10, "-- aml_gasio: %.2x"
577 " base:%llx len:%llx bpos:%.4x blen:%.4x sz:%.2x mode=%s\n",
578 type, base, length, bitpos, bitlen, size,
579 mode==ACPI_IOREAD?"read":"write");
580 acpi_gasio(sc, mode, type, base+(bitpos>>3),
581 (size>>3), (bitlen>>3), buf);
582 #ifdef ACPI_DEBUG
583 while (bitlen > 0) {
584 dnprintf(10, "%.2x ", *(uint8_t *)buf);
585 buf++;
586 bitlen -=8;
587 }
588 dnprintf(10, "\n");
589 #endif
590 }
591
592
593
594
595 void
596 acpi_poll(void *arg)
597 {
598 dsdt_softc->sc_poll = 1;
599 dsdt_softc->sc_wakeup = 0;
600 wakeup(dsdt_softc);
601
602 timeout_add(&dsdt_softc->sc_dev_timeout, 10 * hz);
603 }
604
605 void
606 aml_register_notify(struct aml_node *node, const char *pnpid,
607 int (*proc)(struct aml_node *, int, void *), void *arg, int poll)
608 {
609 struct aml_notify_data *pdata;
610 extern int acpi_poll_enabled;
611
612 dnprintf(10, "aml_register_notify: %s %s %x\n",
613 node->name, pnpid ? pnpid : "", proc);
614
615 pdata = acpi_os_malloc(sizeof(struct aml_notify_data));
616 pdata->node = node;
617 pdata->cbarg = arg;
618 pdata->cbproc = proc;
619 pdata->poll = poll;
620
621 if (pnpid)
622 strlcpy(pdata->pnpid, pnpid, sizeof(pdata->pnpid));
623
624 SLIST_INSERT_HEAD(&aml_notify_list, pdata, link);
625
626 if (poll && !acpi_poll_enabled)
627 timeout_add(&dsdt_softc->sc_dev_timeout, 10 * hz);
628 }
629
630 void
631 aml_notify(struct aml_node *node, int notify_value)
632 {
633 struct aml_notify_data *pdata = NULL;
634
635 if (node == NULL)
636 return;
637
638 SLIST_FOREACH(pdata, &aml_notify_list, link)
639 if (pdata->node == node)
640 pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
641 }
642
643 void
644 aml_notify_dev(const char *pnpid, int notify_value)
645 {
646 struct aml_notify_data *pdata = NULL;
647
648 if (pnpid == NULL)
649 return;
650
651 SLIST_FOREACH(pdata, &aml_notify_list, link)
652 if (pdata->pnpid && !strcmp(pdata->pnpid, pnpid))
653 pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
654 }
655
656 void acpi_poll_notify(void)
657 {
658 struct aml_notify_data *pdata = NULL;
659
660 SLIST_FOREACH(pdata, &aml_notify_list, link)
661 if (pdata->cbproc && pdata->poll)
662 pdata->cbproc(pdata->node, 0, pdata->cbarg);
663 }
664
665
666
667
668
669 struct aml_node *__aml_search(struct aml_node *, uint8_t *);
670 void aml_delchildren(struct aml_node *);
671
672
673
674 struct aml_node *
675 __aml_search(struct aml_node *root, uint8_t *nameseg)
676 {
677 if (root == NULL)
678 return NULL;
679 for (root = root->child; root; root = root->sibling) {
680 if (!memcmp(root->name, nameseg, AML_NAMESEG_LEN))
681 return root;
682 }
683 return NULL;
684 }
685
686
687 const char *
688 aml_nodename(struct aml_node *node)
689 {
690 static char namebuf[128];
691
692 namebuf[0] = 0;
693 if (node) {
694 aml_nodename(node->parent);
695 if (node->parent != &aml_root)
696 strlcat(namebuf, ".", sizeof(namebuf));
697 strlcat(namebuf, node->name, sizeof(namebuf));
698 return namebuf+1;
699 }
700 return namebuf;
701 }
702
703 const char *
704 aml_getname(const char *name)
705 {
706 static char namebuf[128], *p;
707 int count;
708
709 p = namebuf;
710 while (*name == AMLOP_ROOTCHAR || *name == AMLOP_PARENTPREFIX) {
711 *(p++) = *(name++);
712 }
713 switch (*name) {
714 case 0x00:
715 count = 0;
716 break;
717 case AMLOP_MULTINAMEPREFIX:
718 count = name[1];
719 name += 2;
720 break;
721 case AMLOP_DUALNAMEPREFIX:
722 count = 2;
723 name += 1;
724 break;
725 default:
726 count = 1;
727 }
728 while (count--) {
729 memcpy(p, name, 4);
730 p[4] = '.';
731 p += 5;
732 name += 4;
733 if (*name == '.') name++;
734 }
735 *(--p) = 0;
736 return namebuf;
737 }
738
739
740 struct aml_node *
741 aml_createname(struct aml_node *root, const void *vname, struct aml_value *value)
742 {
743 struct aml_node *node, **pp;
744 uint8_t *name = (uint8_t *)vname;
745 int count;
746
747 if (*name == AMLOP_ROOTCHAR) {
748 root = &aml_root;
749 name++;
750 }
751 while (*name == AMLOP_PARENTPREFIX && root) {
752 root = root->parent;
753 name++;
754 }
755 switch (*name) {
756 case 0x00:
757 return root;
758 case AMLOP_MULTINAMEPREFIX:
759 count = name[1];
760 name += 2;
761 break;
762 case AMLOP_DUALNAMEPREFIX:
763 count = 2;
764 name += 1;
765 break;
766 default:
767 count = 1;
768 break;
769 }
770 node = NULL;
771 while (count-- && root) {
772
773 if ((node = __aml_search(root, name)) == NULL) {
774 node = acpi_os_malloc(sizeof(struct aml_node));
775
776 memcpy((void *)node->name, name, AML_NAMESEG_LEN);
777 for (pp = &root->child; *pp; pp = &(*pp)->sibling)
778 ;
779 node->parent = root;
780 node->sibling = NULL;
781 *pp = node;
782 }
783 root = node;
784 name += AML_NAMESEG_LEN;
785 }
786
787 if (node && value) {
788 node->value = value;
789 value->node = node;
790 }
791 return node;
792 }
793
794
795 struct aml_node *
796 aml_searchname(struct aml_node *root, const void *vname)
797 {
798 struct aml_node *node;
799 uint8_t *name = (uint8_t *)vname;
800 int count;
801
802 if (*name == AMLOP_ROOTCHAR) {
803 root = &aml_root;
804 name++;
805 }
806 while (*name == AMLOP_PARENTPREFIX && root) {
807 root = root->parent;
808 name++;
809 }
810 if (strlen(name) < AML_NAMESEG_LEN) {
811 aml_die("bad name");
812 }
813 switch (*name) {
814 case 0x00:
815 return root;
816 case AMLOP_MULTINAMEPREFIX:
817 count = name[1];
818 name += 2;
819 break;
820 case AMLOP_DUALNAMEPREFIX:
821 count = 2;
822 name += 1;
823 break;
824 default:
825 if (name[4] == '.') {
826
827 while (*name && (root = __aml_search(root, name)) != NULL) {
828 name += AML_NAMESEG_LEN+1;
829 }
830 return root;
831 }
832
833 while (root && (node = __aml_search(root, name)) == NULL) {
834 root = root->parent;
835 }
836 return node;
837 }
838
839 while (count-- && (root = __aml_search(root, name)) != NULL) {
840 name += AML_NAMESEG_LEN;
841 }
842 return root;
843 }
844
845
846 void
847 aml_delchildren(struct aml_node *node)
848 {
849 struct aml_node *onode;
850
851 if (node == NULL)
852 return;
853 while ((onode = node->child) != NULL) {
854 node->child = onode->sibling;
855
856 aml_delchildren(onode);
857
858
859 aml_delref(&onode->value);
860
861
862 acpi_os_free(onode);
863 }
864 }
865
866
867
868
869
870 struct aml_value *aml_alloctmp(struct aml_scope *, int);
871 struct aml_scope *aml_pushscope(struct aml_scope *, uint8_t *,
872 uint8_t *, struct aml_node *);
873 struct aml_scope *aml_popscope(struct aml_scope *);
874 int aml_parsenode(struct aml_scope *, struct aml_node *,
875 uint8_t *, uint8_t **, struct aml_value *);
876
877 #define AML_LHS 0
878 #define AML_RHS 1
879 #define AML_DST 2
880 #define AML_DST2 3
881
882
883 struct aml_value *
884 aml_alloctmp(struct aml_scope *scope, int narg)
885 {
886 struct aml_vallist *tmp;
887
888
889 tmp = (struct aml_vallist *)acpi_os_malloc(sizeof(struct aml_vallist) +
890 narg * sizeof(struct aml_value));
891
892 tmp->obj = (struct aml_value *)&tmp[1];
893 tmp->nobj = narg;
894
895
896 tmp->next = scope->tmpvals;
897 scope->tmpvals = tmp;
898
899
900 return tmp->obj;
901 }
902
903
904 struct aml_scope *
905 aml_pushscope(struct aml_scope *parent, uint8_t *start, uint8_t *end,
906 struct aml_node *node)
907 {
908 struct aml_scope *scope;
909
910 scope = acpi_os_malloc(sizeof(struct aml_scope));
911 scope->pos = start;
912 scope->end = end;
913 scope->node = node;
914 scope->parent = parent;
915 scope->sc = dsdt_softc;
916
917 aml_lastscope = scope;
918
919 return scope;
920 }
921
922 struct aml_scope *
923 aml_popscope(struct aml_scope *scope)
924 {
925 struct aml_scope *nscope;
926 struct aml_vallist *ol;
927 int idx;
928
929 if (scope == NULL)
930 return NULL;
931 nscope = scope->parent;
932
933
934 while ((ol = scope->tmpvals) != NULL) {
935 scope->tmpvals = ol->next;
936 for (idx = 0; idx < ol->nobj; idx++) {
937 aml_freevalue(&ol->obj[idx]);
938 }
939 acpi_os_free(ol);
940 }
941 acpi_os_free(scope);
942
943 aml_lastscope = nscope;
944
945 return nscope;
946 }
947
948 int
949 aml_parsenode(struct aml_scope *parent, struct aml_node *node, uint8_t *start,
950 uint8_t **end, struct aml_value *res)
951 {
952 struct aml_scope *scope;
953
954
955 if (start == *end)
956 return 0;
957 scope = aml_pushscope(parent, start, *end, node);
958 if (res == NULL)
959 res = aml_alloctmp(scope, 1);
960 while (scope != parent) {
961 while (scope->pos < scope->end)
962 aml_parseop(scope, res);
963 scope = aml_popscope(scope);
964 }
965 return 0;
966 }
967
968
969
970
971 void aml_setbufint(struct aml_value *, int, int, struct aml_value *);
972 void aml_getbufint(struct aml_value *, int, int, struct aml_value *);
973 void aml_fieldio(struct aml_scope *, struct aml_value *, struct aml_value *, int);
974 void aml_unlockfield(struct aml_scope *, struct aml_value *);
975 void aml_lockfield(struct aml_scope *, struct aml_value *);
976
977
978 void
979 aml_setbufint(struct aml_value *dst, int bitpos, int bitlen,
980 struct aml_value *src)
981 {
982 if (src->type != AML_OBJTYPE_BUFFER)
983 aml_die("wrong setbufint type\n");
984
985 #if 1
986
987 _aml_setvalue(dst, AML_OBJTYPE_BUFFER, (bitlen+7)>>3, NULL);
988 aml_bufcpy(dst->v_buffer, 0, src->v_buffer, bitpos, bitlen);
989 #else
990 if (bitlen < aml_intlen) {
991
992
993 _aml_setvalue(dst, AML_OBJTYPE_INTEGER, 0, NULL);
994 aml_bufcpy(&dst->v_integer, 0, src->v_buffer, bitpos, bitlen);
995 } else {
996
997 _aml_setvalue(dst, AML_OBJTYPE_BUFFER, (bitlen+7)>>3, NULL);
998 aml_bufcpy(dst->v_buffer, 0, src->v_buffer, bitpos, bitlen);
999 }
1000 #endif
1001 }
1002
1003
1004 void
1005 aml_getbufint(struct aml_value *src, int bitpos, int bitlen,
1006 struct aml_value *dst)
1007 {
1008 if (dst->type != AML_OBJTYPE_BUFFER)
1009 aml_die("wrong getbufint type\n");
1010 switch (src->type) {
1011 case AML_OBJTYPE_INTEGER:
1012 if (bitlen >= aml_intlen)
1013 bitlen = aml_intlen;
1014 aml_bufcpy(dst->v_buffer, bitpos, &src->v_integer, 0, bitlen);
1015 break;
1016 case AML_OBJTYPE_BUFFER:
1017 if (bitlen >= 8*src->length)
1018 bitlen = 8*src->length;
1019 aml_bufcpy(dst->v_buffer, bitpos, src->v_buffer, 0, bitlen);
1020 break;
1021 case AML_OBJTYPE_STRING:
1022 if (bitlen >= 8*src->length)
1023 bitlen = 8*src->length;
1024 aml_bufcpy(dst->v_buffer, bitpos, src->v_string, 0, bitlen);
1025 break;
1026 }
1027 }
1028
1029 void
1030 aml_lockfield(struct aml_scope *scope, struct aml_value *field)
1031 {
1032 if (AML_FIELD_LOCK(field->v_field.flags) == AML_FIELD_LOCK_ON) {
1033
1034 }
1035 }
1036
1037 void
1038 aml_unlockfield(struct aml_scope *scope, struct aml_value *field)
1039 {
1040 if (AML_FIELD_LOCK(field->v_field.flags) == AML_FIELD_LOCK_ON) {
1041
1042 }
1043 }
1044
1045 void *aml_getbuffer(struct aml_value *, int *);
1046
1047 void *
1048 aml_getbuffer(struct aml_value *val, int *bitlen)
1049 {
1050 switch (val->type) {
1051 case AML_OBJTYPE_INTEGER:
1052 case AML_OBJTYPE_STATICINT:
1053 *bitlen = aml_intlen;
1054 return (&val->v_integer);
1055
1056 case AML_OBJTYPE_BUFFER:
1057 case AML_OBJTYPE_STRING:
1058 *bitlen = val->length<<3;
1059 return (val->v_buffer);
1060
1061 default:
1062 aml_die("getvbi");
1063 }
1064
1065 return (NULL);
1066 }
1067
1068
1069
1070
1071 void
1072 aml_fieldio(struct aml_scope *scope, struct aml_value *field,
1073 struct aml_value *res, int mode)
1074 {
1075 struct aml_value *pop, tf;
1076 int bpos, blen, aligned, mask;
1077 void *iobuf, *iobuf2;
1078 uint64_t iobase;
1079
1080 pop = field->v_field.ref1;
1081 bpos = field->v_field.bitpos;
1082 blen = field->v_field.bitlen;
1083
1084 dnprintf(55,"--fieldio: %s [%s] bp:%.4x bl:%.4x\n",
1085 mode == ACPI_IOREAD ? "rd" : "wr",
1086 aml_nodename(field->node), bpos, blen);
1087
1088 aml_lockfield(scope, field);
1089 switch (field->v_field.type) {
1090 case AMLOP_INDEXFIELD:
1091
1092 memcpy(&tf, field->v_field.ref2, sizeof(struct aml_value));
1093 tf.v_field.bitpos += (bpos & 7);
1094 tf.v_field.bitlen = blen;
1095
1096 aml_setvalue(scope, pop, NULL, bpos>>3);
1097 aml_fieldio(scope, &tf, res, mode);
1098 #ifdef ACPI_DEBUG
1099 dnprintf(55, "-- post indexfield %x,%x @ %x,%x\n",
1100 bpos & 3, blen,
1101 field->v_field.ref2->v_field.bitpos,
1102 field->v_field.ref2->v_field.bitlen);
1103
1104 iobuf = aml_getbuffer(res, &aligned);
1105 aml_dump(aligned >> 3, iobuf);
1106 #endif
1107 break;
1108 case AMLOP_BANKFIELD:
1109
1110 memcpy(&tf, field->v_field.ref2, sizeof(struct aml_value));
1111 tf.v_field.bitpos += (bpos & 7);
1112 tf.v_field.bitlen = blen;
1113
1114 aml_setvalue(scope, pop, NULL, field->v_field.ref3);
1115 aml_fieldio(scope, &tf, res, mode);
1116 #ifdef ACPI_DEBUG
1117 dnprintf(55, "-- post bankfield %x,%x @ %x,%x\n",
1118 bpos & 3, blen,
1119 field->v_field.ref2->v_field.bitpos,
1120 field->v_field.ref2->v_field.bitlen);
1121
1122 iobuf = aml_getbuffer(res, &aligned);
1123 aml_dump(aligned >> 3, iobuf);
1124 #endif
1125 break;
1126 case AMLOP_FIELD:
1127
1128 if (pop->type != AML_OBJTYPE_OPREGION)
1129 aml_die("Not an opregion!\n");
1130
1131
1132 switch (AML_FIELD_ACCESS(field->v_field.flags)) {
1133 case AML_FIELD_ANYACC:
1134 case AML_FIELD_BYTEACC:
1135 mask = 7;
1136 break;
1137 case AML_FIELD_WORDACC:
1138 mask = 15;
1139 break;
1140 case AML_FIELD_DWORDACC:
1141 mask = 31;
1142 break;
1143 case AML_FIELD_QWORDACC:
1144 mask = 63;
1145 break;
1146 }
1147
1148
1149 if (mode == ACPI_IOREAD)
1150 _aml_setvalue(res, AML_OBJTYPE_BUFFER,
1151 (field->v_field.bitlen+7)>>3, NULL);
1152
1153
1154 blen = ((bpos & mask) + blen + mask) & ~mask;
1155 bpos = bpos & ~mask;
1156 aligned = (bpos == field->v_field.bitpos &&
1157 blen == field->v_field.bitlen);
1158 iobase = pop->v_opregion.iobase;
1159
1160
1161 if (aligned) {
1162 iobuf = aml_getbuffer(res, &aligned);
1163 aml_gasio(scope->sc, pop->v_opregion.iospace,
1164 iobase, pop->v_opregion.iolen, bpos, blen,
1165 mask + 1, iobuf, mode);
1166 #ifdef ACPI_DEBUG
1167 dnprintf(55, "aligned: %s @ %.4x:%.4x + %.4x\n",
1168 mode == ACPI_IOREAD ? "rd" : "wr",
1169 bpos, blen, aligned);
1170
1171 aml_dump(blen >> 3, iobuf);
1172 #endif
1173 }
1174 else if (mode == ACPI_IOREAD) {
1175 iobuf = acpi_os_malloc(blen>>3);
1176 aml_gasio(scope->sc, pop->v_opregion.iospace,
1177 iobase, pop->v_opregion.iolen, bpos, blen,
1178 mask + 1, iobuf, mode);
1179
1180
1181 aml_bufcpy(res->v_buffer, 0, iobuf,
1182 field->v_field.bitpos & mask,
1183 field->v_field.bitlen);
1184
1185 #ifdef ACPI_DEBUG
1186 dnprintf(55,"non-aligned read: %.4x:%.4x : ",
1187 field->v_field.bitpos & mask,
1188 field->v_field.bitlen);
1189
1190 aml_dump(blen >> 3, iobuf);
1191 dnprintf(55,"post-read: ");
1192 aml_dump((field->v_field.bitlen+7)>>3, res->v_buffer);
1193 #endif
1194 acpi_os_free(iobuf);
1195 }
1196 else {
1197 iobuf = acpi_os_malloc(blen >> 3);
1198 switch (AML_FIELD_UPDATE(field->v_field.flags)) {
1199 case AML_FIELD_WRITEASONES:
1200 memset(iobuf, 0xFF, blen >> 3);
1201 break;
1202 case AML_FIELD_PRESERVE:
1203 aml_gasio(scope->sc, pop->v_opregion.iospace,
1204 iobase, pop->v_opregion.iolen, bpos, blen,
1205 mask + 1, iobuf, ACPI_IOREAD);
1206 break;
1207 }
1208
1209 iobuf2 = aml_getbuffer(res, &aligned);
1210 aml_bufcpy(iobuf, field->v_field.bitpos & mask,
1211 iobuf2, 0, field->v_field.bitlen);
1212
1213 #ifdef ACPI_DEBUG
1214 dnprintf(55,"non-aligned write: %.4x:%.4x : ",
1215 field->v_field.bitpos & mask,
1216 field->v_field.bitlen);
1217
1218 aml_dump(blen >> 3, iobuf);
1219 #endif
1220 aml_gasio(scope->sc, pop->v_opregion.iospace,
1221 iobase, pop->v_opregion.iolen, bpos, blen,
1222 mask + 1, iobuf, mode);
1223
1224 acpi_os_free(iobuf);
1225 }
1226
1227 #if 0
1228
1229
1230
1231
1232
1233 if ((bpos+blen) >= (pop->v_opregion.iolen * 8)) {
1234 aml_die("Out of bounds I/O!!! region:%x:%llx:%x %x\n",
1235 pop->v_opregion.iospace, pop->v_opregion.iobase,
1236 pop->v_opregion.iolen, bpos+blen);
1237 }
1238 #endif
1239 break;
1240 default:
1241
1242 if (mode == ACPI_IOREAD)
1243 aml_setbufint(res, bpos, blen, pop);
1244 else
1245 aml_getbufint(res, bpos, blen, pop);
1246 break;
1247 }
1248 aml_unlockfield(scope, field);
1249 }
1250
1251
1252
1253
1254 int64_t aml_str2int(const char *, int);
1255 struct aml_value *aml_derefvalue(struct aml_scope *, struct aml_value *, int);
1256 #define aml_dereftarget(s, v) aml_derefvalue(s, v, ACPI_IOWRITE)
1257 #define aml_derefterm(s, v, m) aml_derefvalue(s, v, ACPI_IOREAD)
1258
1259 void
1260 aml_showvalue(struct aml_value *val, int lvl)
1261 {
1262 int idx;
1263
1264 if (val == NULL)
1265 return;
1266
1267 if (val->node)
1268 printf(" [%s]", aml_nodename(val->node));
1269 printf(" %p cnt:%.2x stk:%.2x", val, val->refcnt, val->stack);
1270 switch (val->type) {
1271 case AML_OBJTYPE_STATICINT:
1272 case AML_OBJTYPE_INTEGER:
1273 printf(" integer: %llx\n", val->v_integer);
1274 break;
1275 case AML_OBJTYPE_STRING:
1276 printf(" string: %s\n", val->v_string);
1277 break;
1278 case AML_OBJTYPE_METHOD:
1279 printf(" method: %.2x\n", val->v_method.flags);
1280 break;
1281 case AML_OBJTYPE_PACKAGE:
1282 printf(" package: %.2x\n", val->length);
1283 for (idx = 0; idx < val->length; idx++)
1284 aml_showvalue(val->v_package[idx], lvl);
1285 break;
1286 case AML_OBJTYPE_BUFFER:
1287 printf(" buffer: %.2x {", val->length);
1288 for (idx = 0; idx < val->length; idx++)
1289 printf("%s%.2x", idx ? ", " : "", val->v_buffer[idx]);
1290 printf("}\n");
1291 break;
1292 case AML_OBJTYPE_FIELDUNIT:
1293 case AML_OBJTYPE_BUFFERFIELD:
1294 printf(" field: bitpos=%.4x bitlen=%.4x ref1:%x ref2:%x [%s]\n",
1295 val->v_field.bitpos, val->v_field.bitlen,
1296 val->v_field.ref1, val->v_field.ref2,
1297 aml_mnem(val->v_field.type, NULL));
1298 aml_showvalue(val->v_field.ref1, lvl);
1299 aml_showvalue(val->v_field.ref2, lvl);
1300 break;
1301 case AML_OBJTYPE_MUTEX:
1302 printf(" mutex: %s ref: %d\n",
1303 val->v_mutex ? val->v_mutex->amt_name : "",
1304 val->v_mutex ? val->v_mutex->amt_ref_count : 0);
1305 break;
1306 case AML_OBJTYPE_EVENT:
1307 printf(" event:\n");
1308 break;
1309 case AML_OBJTYPE_OPREGION:
1310 printf(" opregion: %.2x,%.8llx,%x\n",
1311 val->v_opregion.iospace, val->v_opregion.iobase,
1312 val->v_opregion.iolen);
1313 break;
1314 case AML_OBJTYPE_NAMEREF:
1315 printf(" nameref: %s\n", aml_getname(val->v_nameref));
1316 break;
1317 case AML_OBJTYPE_DEVICE:
1318 printf(" device:\n");
1319 break;
1320 case AML_OBJTYPE_PROCESSOR:
1321 printf(" cpu: %.2x,%.4x,%.2x\n",
1322 val->v_processor.proc_id, val->v_processor.proc_addr,
1323 val->v_processor.proc_len);
1324 break;
1325 case AML_OBJTYPE_THERMZONE:
1326 printf(" thermzone:\n");
1327 break;
1328 case AML_OBJTYPE_POWERRSRC:
1329 printf(" pwrrsrc: %.2x,%.2x\n",
1330 val->v_powerrsrc.pwr_level, val->v_powerrsrc.pwr_order);
1331 break;
1332 case AML_OBJTYPE_OBJREF:
1333 printf(" objref: %p index:%x\n", val->v_objref.ref,
1334 val->v_objref.index);
1335 aml_showvalue(val->v_objref.ref, lvl);
1336 break;
1337 default:
1338 printf(" !!type: %x\n", val->type);
1339 }
1340 }
1341
1342
1343 struct aml_value *
1344 aml_derefvalue(struct aml_scope *scope, struct aml_value *ref, int mode)
1345 {
1346 struct aml_node *node;
1347 struct aml_value *tmp;
1348 int64_t tmpint;
1349 int argc, index;
1350
1351 for (;;) {
1352 switch (ref->type) {
1353 case AML_OBJTYPE_NAMEREF:
1354 node = aml_searchname(scope->node, ref->v_nameref);
1355 if (node == NULL || node->value == NULL)
1356 return ref;
1357 ref = node->value;
1358 break;
1359
1360 case AML_OBJTYPE_OBJREF:
1361 index = ref->v_objref.index;
1362 ref = aml_dereftarget(scope, ref->v_objref.ref);
1363 if (index != -1) {
1364 if (index >= ref->length)
1365 aml_die("index.buf out of bounds: "
1366 "%d/%d\n", index, ref->length);
1367 switch (ref->type) {
1368 case AML_OBJTYPE_PACKAGE:
1369 ref = ref->v_package[index];
1370 break;
1371 case AML_OBJTYPE_STATICINT:
1372 case AML_OBJTYPE_INTEGER:
1373
1374 if (ref->node)
1375 aml_die("named integer index\n");
1376 tmpint = ref->v_integer;
1377 _aml_setvalue(ref, AML_OBJTYPE_BUFFER,
1378 aml_intlen>>3, &tmpint);
1379
1380 case AML_OBJTYPE_BUFFER:
1381 case AML_OBJTYPE_STRING:
1382
1383 tmp = aml_alloctmp(scope, 1);
1384 if (mode == ACPI_IOREAD) {
1385
1386
1387 _aml_setvalue(tmp,
1388 AML_OBJTYPE_INTEGER,
1389 ref->v_buffer[index], NULL);
1390 } else {
1391 _aml_setvalue(tmp,
1392 AML_OBJTYPE_BUFFERFIELD,
1393 0, NULL);
1394 tmp->v_field.type =
1395 AMLOP_CREATEBYTEFIELD;
1396 tmp->v_field.bitpos = index * 8;
1397 tmp->v_field.bitlen = 8;
1398 tmp->v_field.ref1 = ref;
1399 aml_addref(ref);
1400 }
1401 return tmp;
1402 default:
1403 aml_die("unknown index type: %d", ref->type);
1404 break;
1405 }
1406 }
1407 break;
1408
1409 case AML_OBJTYPE_METHOD:
1410
1411 argc = AML_METHOD_ARGCOUNT(ref->v_method.flags);
1412 tmp = aml_alloctmp(scope, argc+1);
1413 for (index = 0; index < argc; index++) {
1414 aml_parseop(scope, &tmp[index]);
1415 aml_addref(&tmp[index]);
1416 }
1417 ref = aml_evalmethod(scope, ref->node, argc, tmp, &tmp[argc]);
1418 break;
1419
1420 case AML_OBJTYPE_BUFFERFIELD:
1421 case AML_OBJTYPE_FIELDUNIT:
1422 if (mode == ACPI_IOREAD) {
1423
1424 tmp = aml_alloctmp(scope, 1);
1425 aml_fieldio(scope, ref, tmp, ACPI_IOREAD);
1426 return tmp;
1427 }
1428 return ref;
1429
1430 default:
1431 return ref;
1432 }
1433
1434 }
1435 }
1436
1437 int64_t
1438 aml_str2int(const char *str, int radix)
1439 {
1440
1441 return 0;
1442 }
1443
1444 int64_t
1445 aml_val2int(struct aml_value *rval)
1446 {
1447 int64_t ival = 0;
1448
1449 if (rval == NULL) {
1450 dnprintf(50, "null val2int\n");
1451 return (0);
1452 }
1453 switch (rval->type) {
1454 case AML_OBJTYPE_INTEGER:
1455 case AML_OBJTYPE_STATICINT:
1456 ival = rval->v_integer;
1457 break;
1458 case AML_OBJTYPE_BUFFER:
1459 aml_bufcpy(&ival, 0, rval->v_buffer, 0,
1460 min(aml_intlen, rval->length*8));
1461 break;
1462 case AML_OBJTYPE_STRING:
1463 ival = (strncmp(rval->v_string, "0x", 2) == 0) ?
1464 aml_str2int(rval->v_string+2, 16) :
1465 aml_str2int(rval->v_string, 10);
1466 break;
1467 }
1468 return (ival);
1469 }
1470
1471
1472 struct aml_value *
1473 _aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
1474 {
1475 memset(&lhs->_, 0x0, sizeof(lhs->_));
1476
1477 lhs->type = type;
1478 switch (lhs->type) {
1479 case AML_OBJTYPE_INTEGER:
1480 case AML_OBJTYPE_STATICINT:
1481 lhs->length = aml_intlen>>3;
1482 lhs->v_integer = ival;
1483 break;
1484 case AML_OBJTYPE_METHOD:
1485 lhs->v_method.flags = ival;
1486 lhs->v_method.fneval = bval;
1487 break;
1488 case AML_OBJTYPE_NAMEREF:
1489 lhs->v_nameref = (uint8_t *)bval;
1490 break;
1491 case AML_OBJTYPE_OBJREF:
1492 lhs->v_objref.index = ival;
1493 lhs->v_objref.ref = (struct aml_value *)bval;
1494 break;
1495 case AML_OBJTYPE_BUFFER:
1496 lhs->length = ival;
1497 lhs->v_buffer = (uint8_t *)acpi_os_malloc(ival);
1498 if (bval)
1499 memcpy(lhs->v_buffer, bval, ival);
1500 break;
1501 case AML_OBJTYPE_STRING:
1502 if (ival == -1)
1503 ival = strlen((const char *)bval);
1504 lhs->length = ival;
1505 lhs->v_string = (char *)acpi_os_malloc(ival+1);
1506 if (bval)
1507 strncpy(lhs->v_string, (const char *)bval, ival);
1508 break;
1509 case AML_OBJTYPE_PACKAGE:
1510 lhs->length = ival;
1511 lhs->v_package = (struct aml_value **)acpi_os_malloc(ival *
1512 sizeof(struct aml_value *));
1513 for (ival = 0; ival < lhs->length; ival++)
1514 lhs->v_package[ival] = aml_allocvalue(
1515 AML_OBJTYPE_UNINITIALIZED, 0, NULL);
1516 break;
1517 }
1518 return lhs;
1519 }
1520
1521
1522 void
1523 aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
1524 {
1525 int idx;
1526
1527 lhs->type = rhs->type & ~AML_STATIC;
1528 switch (lhs->type) {
1529 case AML_OBJTYPE_UNINITIALIZED:
1530 break;
1531 case AML_OBJTYPE_STATICINT:
1532 case AML_OBJTYPE_INTEGER:
1533 lhs->length = aml_intlen>>3;
1534 lhs->v_integer = rhs->v_integer;
1535 break;
1536 case AML_OBJTYPE_MUTEX:
1537 lhs->v_mutex = rhs->v_mutex;
1538 break;
1539 case AML_OBJTYPE_POWERRSRC:
1540 lhs->v_powerrsrc = rhs->v_powerrsrc;
1541 break;
1542 case AML_OBJTYPE_METHOD:
1543 lhs->v_method = rhs->v_method;
1544 break;
1545 case AML_OBJTYPE_BUFFER:
1546 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_buffer);
1547 break;
1548 case AML_OBJTYPE_STRING:
1549 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_string);
1550 break;
1551 case AML_OBJTYPE_OPREGION:
1552 lhs->v_opregion = rhs->v_opregion;
1553 break;
1554 case AML_OBJTYPE_PROCESSOR:
1555 lhs->v_processor = rhs->v_processor;
1556 break;
1557 case AML_OBJTYPE_NAMEREF:
1558 lhs->v_nameref = rhs->v_nameref;
1559 break;
1560 case AML_OBJTYPE_PACKAGE:
1561 _aml_setvalue(lhs, rhs->type, rhs->length, NULL);
1562 for (idx = 0; idx < rhs->length; idx++)
1563 aml_copyvalue(lhs->v_package[idx], rhs->v_package[idx]);
1564 break;
1565 case AML_OBJTYPE_OBJREF:
1566 lhs->v_objref = rhs->v_objref;
1567 break;
1568 default:
1569 printf("copyvalue: %x", rhs->type);
1570 break;
1571 }
1572 }
1573
1574 int is_local(struct aml_scope *, struct aml_value *);
1575
1576 int is_local(struct aml_scope *scope, struct aml_value *val)
1577 {
1578 return val->stack;
1579 }
1580
1581
1582 void
1583 aml_setvalue(struct aml_scope *scope, struct aml_value *lhs,
1584 struct aml_value *rhs, int64_t ival)
1585 {
1586 struct aml_value tmpint;
1587
1588
1589 if (rhs == NULL) {
1590 memset(&tmpint, 0, sizeof(tmpint));
1591 rhs = _aml_setvalue(&tmpint, AML_OBJTYPE_INTEGER, ival, NULL);
1592 }
1593
1594 if (is_local(scope, lhs)) {
1595
1596 aml_freevalue(lhs);
1597 }
1598 else {
1599 lhs = aml_dereftarget(scope, lhs);
1600 }
1601
1602 switch (lhs->type) {
1603 case AML_OBJTYPE_UNINITIALIZED:
1604 aml_copyvalue(lhs, rhs);
1605 break;
1606 case AML_OBJTYPE_BUFFERFIELD:
1607 case AML_OBJTYPE_FIELDUNIT:
1608 aml_fieldio(scope, lhs, rhs, ACPI_IOWRITE);
1609 break;
1610 case AML_OBJTYPE_DEBUGOBJ:
1611 #ifdef ACPI_DEBUG
1612 printf("-- debug --\n");
1613 aml_showvalue(rhs, 50);
1614 #endif
1615 break;
1616 case AML_OBJTYPE_STATICINT:
1617 if (lhs->node) {
1618 lhs->v_integer = aml_val2int(rhs);
1619 }
1620 break;
1621 case AML_OBJTYPE_INTEGER:
1622 lhs->v_integer = aml_val2int(rhs);
1623 break;
1624 case AML_OBJTYPE_BUFFER:
1625 if (lhs->node)
1626 dnprintf(40, "named.buffer\n");
1627 aml_freevalue(lhs);
1628 if (rhs->type == AML_OBJTYPE_BUFFER)
1629 _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length,
1630 rhs->v_buffer);
1631 else if (rhs->type == AML_OBJTYPE_INTEGER ||
1632 rhs->type == AML_OBJTYPE_STATICINT)
1633 _aml_setvalue(lhs, AML_OBJTYPE_BUFFER,
1634 sizeof(rhs->v_integer), &rhs->v_integer);
1635 else if (rhs->type == AML_OBJTYPE_STRING)
1636 _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length+1,
1637 rhs->v_string);
1638 else {
1639
1640 aml_die("setvalue.buf : %x", aml_pc(scope->pos));
1641 }
1642 break;
1643 case AML_OBJTYPE_STRING:
1644 if (lhs->node)
1645 dnprintf(40, "named string\n");
1646 aml_freevalue(lhs);
1647 if (rhs->type == AML_OBJTYPE_STRING)
1648 _aml_setvalue(lhs, AML_OBJTYPE_STRING, rhs->length,
1649 rhs->v_string);
1650 else if (rhs->type == AML_OBJTYPE_BUFFER)
1651 _aml_setvalue(lhs, AML_OBJTYPE_STRING, rhs->length,
1652 rhs->v_buffer);
1653 else if (rhs->type == AML_OBJTYPE_INTEGER || rhs->type == AML_OBJTYPE_STATICINT) {
1654 _aml_setvalue(lhs, AML_OBJTYPE_STRING, 10, NULL);
1655 snprintf(lhs->v_string, lhs->length, "%lld",
1656 rhs->v_integer);
1657 } else {
1658
1659 aml_die("setvalue.str");
1660 }
1661 break;
1662 default:
1663
1664 dnprintf(10, "setvalue.unknown: %x", lhs->type);
1665 break;
1666 }
1667 }
1668
1669
1670
1671
1672
1673
1674 struct aml_value *
1675 aml_allocvalue(int type, int64_t ival, const void *bval)
1676 {
1677 struct aml_value *rv;
1678
1679 rv = (struct aml_value *)acpi_os_malloc(sizeof(struct aml_value));
1680 if (rv != NULL) {
1681 aml_addref(rv);
1682 return _aml_setvalue(rv, type, ival, bval);
1683 }
1684 return NULL;
1685 }
1686
1687 void
1688 aml_freevalue(struct aml_value *val)
1689 {
1690 int idx;
1691
1692 if (val == NULL)
1693 return;
1694 switch (val->type) {
1695 case AML_OBJTYPE_STRING:
1696 acpi_os_free(val->v_string);
1697 break;
1698 case AML_OBJTYPE_BUFFER:
1699 acpi_os_free(val->v_buffer);
1700 break;
1701 case AML_OBJTYPE_PACKAGE:
1702 for (idx = 0; idx < val->length; idx++) {
1703 aml_freevalue(val->v_package[idx]);
1704 acpi_os_free(val->v_package[idx]);
1705 }
1706 acpi_os_free(val->v_package);
1707 break;
1708 case AML_OBJTYPE_BUFFERFIELD:
1709 case AML_OBJTYPE_FIELDUNIT:
1710 aml_delref(&val->v_field.ref1);
1711 aml_delref(&val->v_field.ref2);
1712 break;
1713 }
1714 val->type = 0;
1715 memset(&val->_, 0, sizeof(val->_));
1716 }
1717
1718
1719 void
1720 aml_addref(struct aml_value *val)
1721 {
1722 if (val)
1723 val->refcnt++;
1724 }
1725
1726
1727
1728 void
1729 _aml_delref(struct aml_value **val, const char *fn, int line)
1730 {
1731 if (val == NULL || *val == NULL)
1732 return;
1733 if ((*val)->stack > 0) {
1734
1735 return;
1736 }
1737 if ((*val)->refcnt & ~0xFF)
1738 printf("-- invalid ref: %x:%s:%d\n", (*val)->refcnt, fn, line);
1739 if (--(*val)->refcnt == 0) {
1740 aml_freevalue(*val);
1741 acpi_os_free(*val);
1742 *val = NULL;
1743 }
1744 }
1745
1746
1747
1748
1749
1750
1751
1752 u_int64_t
1753 aml_convradix(u_int64_t val, int iradix, int oradix)
1754 {
1755 u_int64_t rv = 0, pwr;
1756
1757 rv = 0;
1758 pwr = 1;
1759 while (val) {
1760 rv += (val % iradix) * pwr;
1761 val /= iradix;
1762 pwr *= oradix;
1763 }
1764 return rv;
1765 }
1766
1767
1768 int
1769 aml_lsb(u_int64_t val)
1770 {
1771 int lsb;
1772
1773 if (val == 0)
1774 return (0);
1775
1776 for (lsb = 1; !(val & 0x1); lsb++)
1777 val >>= 1;
1778
1779 return (lsb);
1780 }
1781
1782
1783 int
1784 aml_msb(u_int64_t val)
1785 {
1786 int msb;
1787
1788 if (val == 0)
1789 return (0);
1790
1791 for (msb = 1; val != 0x1; msb++)
1792 val >>= 1;
1793
1794 return (msb);
1795 }
1796
1797
1798 int64_t
1799 aml_evalexpr(int64_t lhs, int64_t rhs, int opcode)
1800 {
1801 int64_t res;
1802
1803 switch (opcode) {
1804
1805 case AMLOP_INCREMENT:
1806 case AMLOP_ADD:
1807 res = (lhs + rhs);
1808 break;
1809 case AMLOP_DECREMENT:
1810 case AMLOP_SUBTRACT:
1811 res = (lhs - rhs);
1812 break;
1813 case AMLOP_MULTIPLY:
1814 res = (lhs * rhs);
1815 break;
1816 case AMLOP_DIVIDE:
1817 res = (lhs / rhs);
1818 break;
1819 case AMLOP_MOD:
1820 res = (lhs % rhs);
1821 break;
1822 case AMLOP_SHL:
1823 res = (lhs << rhs);
1824 break;
1825 case AMLOP_SHR:
1826 res = (lhs >> rhs);
1827 break;
1828 case AMLOP_AND:
1829 res = (lhs & rhs);
1830 break;
1831 case AMLOP_NAND:
1832 res = ~(lhs & rhs);
1833 break;
1834 case AMLOP_OR:
1835 res = (lhs | rhs);
1836 break;
1837 case AMLOP_NOR:
1838 res = ~(lhs | rhs);
1839 break;
1840 case AMLOP_XOR:
1841 res = (lhs ^ rhs);
1842 break;
1843 case AMLOP_NOT:
1844 res = ~(lhs);
1845 break;
1846
1847
1848 case AMLOP_FINDSETLEFTBIT:
1849 res = aml_msb(lhs);
1850 break;
1851 case AMLOP_FINDSETRIGHTBIT:
1852 res = aml_lsb(lhs);
1853 break;
1854 case AMLOP_TOINTEGER:
1855 res = (lhs);
1856 break;
1857 case AMLOP_FROMBCD:
1858 res = aml_convradix(lhs, 16, 10);
1859 break;
1860 case AMLOP_TOBCD:
1861 res = aml_convradix(lhs, 10, 16);
1862 break;
1863
1864
1865 case AMLOP_LAND:
1866 res = (lhs && rhs);
1867 break;
1868 case AMLOP_LOR:
1869 res = (lhs || rhs);
1870 break;
1871 case AMLOP_LNOT:
1872 res = (!lhs);
1873 break;
1874 case AMLOP_LNOTEQUAL:
1875 res = (lhs != rhs);
1876 break;
1877 case AMLOP_LLESSEQUAL:
1878 res = (lhs <= rhs);
1879 break;
1880 case AMLOP_LGREATEREQUAL:
1881 res = (lhs >= rhs);
1882 break;
1883 case AMLOP_LEQUAL:
1884 res = (lhs == rhs);
1885 break;
1886 case AMLOP_LGREATER:
1887 res = (lhs > rhs);
1888 break;
1889 case AMLOP_LLESS:
1890 res = (lhs < rhs);
1891 break;
1892 }
1893
1894 dnprintf(50,"aml_evalexpr: %s %llx %llx = %llx\n",
1895 aml_mnem(opcode, NULL), lhs, rhs, res);
1896
1897 return res;
1898 }
1899
1900 int
1901 aml_cmpvalue(struct aml_value *lhs, struct aml_value *rhs, int opcode)
1902 {
1903 int rc, lt, rt;
1904
1905 rc = 0;
1906 lt = lhs->type & ~AML_STATIC;
1907 rt = rhs->type & ~AML_STATIC;
1908 if (lt == rt) {
1909 switch (lt) {
1910 case AML_OBJTYPE_STATICINT:
1911 case AML_OBJTYPE_INTEGER:
1912 rc = (lhs->v_integer - rhs->v_integer);
1913 break;
1914 case AML_OBJTYPE_STRING:
1915 rc = strncmp(lhs->v_string, rhs->v_string,
1916 min(lhs->length, rhs->length));
1917 if (rc == 0)
1918 rc = lhs->length - rhs->length;
1919 break;
1920 case AML_OBJTYPE_BUFFER:
1921 rc = memcmp(lhs->v_buffer, rhs->v_buffer,
1922 min(lhs->length, rhs->length));
1923 if (rc == 0)
1924 rc = lhs->length - rhs->length;
1925 break;
1926 }
1927 } else if (lt == AML_OBJTYPE_INTEGER) {
1928 rc = lhs->v_integer - aml_val2int(rhs);
1929 } else if (rt == AML_OBJTYPE_INTEGER) {
1930 rc = aml_val2int(lhs) - rhs->v_integer;
1931 } else {
1932 aml_die("mismatched compare\n");
1933 }
1934 return aml_evalexpr(rc, 0, opcode);
1935 }
1936
1937
1938
1939
1940
1941 void
1942 aml_bufcpy(void *pvDst, int dstPos, const void *pvSrc, int srcPos, int len)
1943 {
1944 const u_int8_t *pSrc = pvSrc;
1945 u_int8_t *pDst = pvDst;
1946 int idx;
1947
1948 if (aml_bytealigned(dstPos|srcPos|len)) {
1949
1950 memcpy(pDst+aml_bytepos(dstPos), pSrc+aml_bytepos(srcPos),
1951 aml_bytelen(len));
1952 return;
1953 }
1954
1955
1956 for (idx = 0; idx < len; idx++)
1957 aml_setbit(pDst, idx + dstPos, aml_tstbit(pSrc, idx + srcPos));
1958 }
1959
1960 struct aml_value *
1961 aml_callmethod(struct aml_scope *scope, struct aml_value *val)
1962 {
1963 while (scope->pos < scope->end)
1964 aml_parseterm(scope, val);
1965 return val;
1966 }
1967
1968
1969
1970
1971
1972
1973 struct aml_value *
1974 aml_evalmethod(struct aml_scope *parent, struct aml_node *node,
1975 int argc, struct aml_value *argv, struct aml_value *res)
1976 {
1977 struct aml_scope *scope;
1978
1979 scope = aml_pushscope(parent, node->value->v_method.start,
1980 node->value->v_method.end, node);
1981 scope->args = argv;
1982 scope->nargs = argc;
1983
1984 if (res == NULL)
1985 res = aml_alloctmp(scope, 1);
1986
1987 #ifdef ACPI_DEBUG
1988 dnprintf(10, "calling [%s] (%d args)\n",
1989 aml_nodename(node), scope->nargs);
1990 for (argc = 0; argc < scope->nargs; argc++) {
1991 dnprintf(10, " arg%d: ", argc);
1992 aml_showvalue(&scope->args[argc], 10);
1993 }
1994 node->value->v_method.fneval(scope, res);
1995 dnprintf(10, "[%s] returns: ", aml_nodename(node));
1996 aml_showvalue(res, 10);
1997 #else
1998 node->value->v_method.fneval(scope, res);
1999 #endif
2000
2001 aml_delchildren(node);
2002 aml_popscope(scope);
2003
2004 return res;
2005 }
2006
2007
2008
2009
2010
2011
2012
2013 int
2014 aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
2015 int argc, struct aml_value *argv, struct aml_value *res)
2016 {
2017 static int lastck;
2018 struct aml_node *ref;
2019
2020 if (res)
2021 memset(res, 0, sizeof(struct aml_value));
2022 if (node == NULL || node->value == NULL)
2023 return (ACPI_E_BADVALUE);
2024
2025 switch (node->value->type) {
2026 case AML_OBJTYPE_METHOD:
2027 aml_evalmethod(NULL, node, argc, argv, res);
2028 if (acpi_nalloc > lastck) {
2029
2030 dnprintf(10, "Leaked: [%s] %d\n",
2031 aml_nodename(node), acpi_nalloc);
2032 lastck = acpi_nalloc;
2033 }
2034 break;
2035 case AML_OBJTYPE_STATICINT:
2036 case AML_OBJTYPE_INTEGER:
2037 case AML_OBJTYPE_STRING:
2038 case AML_OBJTYPE_BUFFER:
2039 case AML_OBJTYPE_PACKAGE:
2040 case AML_OBJTYPE_EVENT:
2041 case AML_OBJTYPE_DEVICE:
2042 case AML_OBJTYPE_MUTEX:
2043 case AML_OBJTYPE_OPREGION:
2044 case AML_OBJTYPE_POWERRSRC:
2045 case AML_OBJTYPE_PROCESSOR:
2046 case AML_OBJTYPE_THERMZONE:
2047 case AML_OBJTYPE_DEBUGOBJ:
2048 if (res)
2049 aml_copyvalue(res, node->value);
2050 break;
2051 case AML_OBJTYPE_NAMEREF:
2052 if (res == NULL)
2053 break;
2054 if ((ref = aml_searchname(node, node->value->v_nameref)) != NULL)
2055 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, ref);
2056 else
2057 aml_copyvalue(res, node->value);
2058 break;
2059 default:
2060 break;
2061 }
2062 return (0);
2063 }
2064
2065
2066
2067
2068
2069 int
2070 aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
2071 int argc, struct aml_value *argv, struct aml_value *res)
2072 {
2073 return aml_evalnode(sc, aml_searchname(parent, name), argc, argv, res);
2074 }
2075
2076 int
2077 aml_evalinteger(struct acpi_softc *sc, struct aml_node *parent,
2078 const char *name, int argc, struct aml_value *argv, int64_t *ival)
2079 {
2080 struct aml_value res;
2081
2082 if (name != NULL)
2083 parent = aml_searchname(parent, name);
2084 if (aml_evalnode(sc, parent, argc, argv, &res) == 0) {
2085 *ival = aml_val2int(&res);
2086 aml_freevalue(&res);
2087 return 0;
2088 }
2089 return 1;
2090 }
2091
2092 void
2093 aml_walknodes(struct aml_node *node, int mode,
2094 int (*nodecb)(struct aml_node *, void *), void *arg)
2095 {
2096 struct aml_node *child;
2097
2098 if (node == NULL)
2099 return;
2100 if (mode == AML_WALK_PRE)
2101 nodecb(node, arg);
2102 for (child = node->child; child; child = child->sibling)
2103 aml_walknodes(child, mode, nodecb, arg);
2104 if (mode == AML_WALK_POST)
2105 nodecb(node, arg);
2106 }
2107
2108 void
2109 aml_walktree(struct aml_node *node)
2110 {
2111 while (node) {
2112 aml_showvalue(node->value, 0);
2113 aml_walktree(node->child);
2114 node = node->sibling;
2115 }
2116 }
2117
2118 void
2119 aml_walkroot(void)
2120 {
2121 aml_walktree(aml_root.child);
2122 }
2123
2124 int
2125 aml_find_node(struct aml_node *node, const char *name,
2126 void (*cbproc)(struct aml_node *, void *arg), void *arg)
2127 {
2128 const char *nn;
2129
2130 while (node) {
2131 if ((nn = node->name) != NULL) {
2132 if (*nn == AMLOP_ROOTCHAR) nn++;
2133 while (*nn == AMLOP_PARENTPREFIX) nn++;
2134 if (!strcmp(name, nn))
2135 cbproc(node, arg);
2136 }
2137 aml_find_node(node->child, name, cbproc, arg);
2138 node = node->sibling;
2139 }
2140 return (0);
2141 }
2142
2143
2144
2145
2146 uint8_t *aml_parsename(struct aml_scope *);
2147 uint8_t *aml_parseend(struct aml_scope *scope);
2148 int aml_parselength(struct aml_scope *);
2149 int aml_parseopcode(struct aml_scope *);
2150
2151
2152 int
2153 aml_parseopcode(struct aml_scope *scope)
2154 {
2155 int opcode = (scope->pos[0]);
2156 int twocode = (scope->pos[0]<<8) + scope->pos[1];
2157
2158
2159 switch (opcode) {
2160 case AMLOP_ROOTCHAR:
2161 case AMLOP_PARENTPREFIX:
2162 case AMLOP_MULTINAMEPREFIX:
2163 case AMLOP_DUALNAMEPREFIX:
2164 case AMLOP_NAMECHAR:
2165 case 'A' ... 'Z':
2166 return AMLOP_NAMECHAR;
2167 }
2168 if (twocode == AMLOP_LNOTEQUAL || twocode == AMLOP_LLESSEQUAL ||
2169 twocode == AMLOP_LGREATEREQUAL || opcode == AMLOP_EXTPREFIX) {
2170 scope->pos += 2;
2171 return twocode;
2172 }
2173 scope->pos += 1;
2174 return opcode;
2175 }
2176
2177
2178 uint8_t *
2179 aml_parsename(struct aml_scope *scope)
2180 {
2181 uint8_t *name = scope->pos;
2182
2183 while (*scope->pos == AMLOP_ROOTCHAR || *scope->pos == AMLOP_PARENTPREFIX)
2184 scope->pos++;
2185
2186 switch (*scope->pos) {
2187 case 0x00:
2188 break;
2189 case AMLOP_MULTINAMEPREFIX:
2190 scope->pos += 2+AML_NAMESEG_LEN*scope->pos[1];
2191 break;
2192 case AMLOP_DUALNAMEPREFIX:
2193 scope->pos += 1+AML_NAMESEG_LEN*2;
2194 break;
2195 default:
2196 scope->pos += AML_NAMESEG_LEN;
2197 break;
2198 }
2199 return name;
2200 }
2201
2202
2203 int
2204 aml_parselength(struct aml_scope *scope)
2205 {
2206 int len = (*scope->pos & 0xF);
2207
2208 switch (*scope->pos >> 6) {
2209 case 0x00:
2210 len = scope->pos[0] & 0x3F;
2211 scope->pos += 1;
2212 break;
2213 case 0x01:
2214 len += (scope->pos[1]<<4L);
2215 scope->pos += 2;
2216 break;
2217 case 0x02:
2218 len += (scope->pos[1]<<4L) + (scope->pos[2]<<12L);
2219 scope->pos += 3;
2220 break;
2221 case 0x03:
2222 len += (scope->pos[1]<<4L) + (scope->pos[2]<<12L) +
2223 (scope->pos[3]<<20L);
2224 scope->pos += 4;
2225 break;
2226 }
2227 return len;
2228 }
2229
2230
2231 uint8_t *
2232 aml_parseend(struct aml_scope *scope)
2233 {
2234 uint8_t *pos = scope->pos;
2235 int len;
2236
2237 len = aml_parselength(scope);
2238 if (pos+len > scope->end) {
2239 dnprintf(10,
2240 "Bad scope... runover pos:%.4x new end:%.4x scope "
2241 "end:%.4x\n", aml_pc(pos), aml_pc(pos+len),
2242 aml_pc(scope->end));
2243 pos = scope->end;
2244 }
2245 return pos+len;
2246 }
2247
2248
2249
2250
2251 int aml_match(int, int64_t, struct aml_value *);
2252 void aml_fixref(struct aml_value **);
2253 int64_t aml_parseint(struct aml_scope *, int);
2254 void aml_resize(struct aml_value *val, int newsize);
2255
2256 void
2257 aml_resize(struct aml_value *val, int newsize)
2258 {
2259 void *oldptr;
2260 int oldsize;
2261
2262 if (val->length >= newsize)
2263 return;
2264 oldsize = val->length;
2265 switch (val->type) {
2266 case AML_OBJTYPE_BUFFER:
2267 oldptr = val->v_buffer;
2268 _aml_setvalue(val, val->type, newsize, NULL);
2269 memcpy(val->v_buffer, oldptr, oldsize);
2270 acpi_os_free(oldptr);
2271 break;
2272 case AML_OBJTYPE_STRING:
2273 oldptr = val->v_string;
2274 _aml_setvalue(val, val->type, newsize+1, NULL);
2275 memcpy(val->v_string, oldptr, oldsize);
2276 acpi_os_free(oldptr);
2277 break;
2278 }
2279 }
2280
2281
2282 int
2283 aml_match(int op, int64_t mv1, struct aml_value *mv2)
2284 {
2285 struct aml_value tmpint;
2286
2287 memset(&tmpint, 0, sizeof(tmpint));
2288 _aml_setvalue(&tmpint, AML_OBJTYPE_INTEGER, mv1, NULL);
2289 switch (op) {
2290 case AML_MATCH_EQ:
2291 return aml_cmpvalue(&tmpint, mv2, AMLOP_LEQUAL);
2292 case AML_MATCH_LT:
2293 return aml_cmpvalue(&tmpint, mv2, AMLOP_LLESS);
2294 case AML_MATCH_LE:
2295 return aml_cmpvalue(&tmpint, mv2, AMLOP_LLESSEQUAL);
2296 case AML_MATCH_GE:
2297 return aml_cmpvalue(&tmpint, mv2, AMLOP_LGREATEREQUAL);
2298 case AML_MATCH_GT:
2299 return aml_cmpvalue(&tmpint, mv2, AMLOP_LGREATER);
2300 }
2301 return (1);
2302 }
2303
2304 int amlop_delay;
2305
2306 u_int64_t
2307 aml_getpciaddr(struct acpi_softc *sc, struct aml_node *root)
2308 {
2309 struct aml_value tmpres;
2310 u_int64_t pciaddr;
2311
2312
2313 pciaddr = 0;
2314 if (!aml_evalname(dsdt_softc, root, "_ADR", 0, NULL, &tmpres)) {
2315
2316 pciaddr += (aml_val2int(&tmpres) << 16L);
2317 aml_freevalue(&tmpres);
2318 dnprintf(20, "got _adr [%s]\n", aml_nodename(root));
2319 } else {
2320
2321 pciaddr += (0xFFFF << 16L);
2322 return pciaddr;
2323 }
2324
2325 if (!aml_evalname(dsdt_softc, root, "_BBN", 0, NULL, &tmpres)) {
2326
2327 pciaddr += (aml_val2int(&tmpres) << 48L);
2328 aml_freevalue(&tmpres);
2329 dnprintf(20, "got _bbn [%s]\n", aml_nodename(root));
2330 }
2331 dnprintf(20, "got pciaddr: %s:%llx\n", aml_nodename(root), pciaddr);
2332 return pciaddr;
2333 }
2334
2335
2336 void
2337 aml_fixref(struct aml_value **res)
2338 {
2339 struct aml_value *oldres;
2340
2341 while (*res && (*res)->type == AML_OBJTYPE_OBJREF &&
2342 (*res)->v_objref.index == -1) {
2343 oldres = (*res)->v_objref.ref;
2344 aml_delref(res);
2345 aml_addref(oldres);
2346 *res = oldres;
2347 }
2348 }
2349
2350 int64_t
2351 aml_parseint(struct aml_scope *scope, int opcode)
2352 {
2353 uint8_t *np = scope->pos;
2354 struct aml_value *tmpval;
2355 int64_t rval;
2356
2357 if (opcode == AML_ANYINT)
2358 opcode = aml_parseopcode(scope);
2359 switch (opcode) {
2360 case AMLOP_ZERO:
2361 rval = 0;
2362 break;
2363 case AMLOP_ONE:
2364 rval = 1;
2365 break;
2366 case AMLOP_ONES:
2367 rval = -1;
2368 break;
2369 case AMLOP_REVISION:
2370 rval = AML_REVISION;
2371 break;
2372 case AMLOP_BYTEPREFIX:
2373 np = scope->pos;
2374 rval = *(uint8_t *)scope->pos;
2375 scope->pos += 1;
2376 break;
2377 case AMLOP_WORDPREFIX:
2378 np = scope->pos;
2379 rval = aml_letohost16(*(uint16_t *)scope->pos);
2380 scope->pos += 2;
2381 break;
2382 case AMLOP_DWORDPREFIX:
2383 np = scope->pos;
2384 rval = aml_letohost32(*(uint32_t *)scope->pos);
2385 scope->pos += 4;
2386 break;
2387 case AMLOP_QWORDPREFIX:
2388 np = scope->pos;
2389 rval = aml_letohost64(*(uint64_t *)scope->pos);
2390 scope->pos += 8;
2391 break;
2392 default:
2393 scope->pos = np;
2394 tmpval = aml_alloctmp(scope, 1);
2395 aml_parseterm(scope, tmpval);
2396 return aml_val2int(tmpval);
2397 }
2398 dnprintf(15, "%.4x: [%s] %s\n", aml_pc(scope->pos-opsize(opcode)),
2399 aml_nodename(scope->node), aml_mnem(opcode, np));
2400 return rval;
2401 }
2402
2403 struct aml_value *
2404 aml_evaltarget(struct aml_scope *scope, struct aml_value *res)
2405 {
2406 return res;
2407 }
2408
2409 int
2410 aml_evalterm(struct aml_scope *scope, struct aml_value *raw,
2411 struct aml_value *dst)
2412 {
2413 struct aml_value *deref;
2414
2415 aml_freevalue(dst);
2416 deref = aml_derefterm(scope, raw, 0);
2417 aml_copyvalue(dst, deref);
2418 return 0;
2419 }
2420
2421
2422
2423
2424
2425
2426
2427 struct aml_value *
2428 aml_parsenamed(struct aml_scope *scope, int opcode, struct aml_value *res)
2429 {
2430 uint8_t *name;
2431 int s, offs = 0;
2432
2433 AML_CHECKSTACK();
2434 name = aml_parsename(scope);
2435
2436 res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
2437 switch (opcode) {
2438 case AMLOP_NAME:
2439 aml_parseop(scope, res);
2440 break;
2441 case AMLOP_ALIAS:
2442 _aml_setvalue(res, AML_OBJTYPE_NAMEREF, 0, name);
2443 name = aml_parsename(scope);
2444 break;
2445 case AMLOP_EVENT:
2446 _aml_setvalue(res, AML_OBJTYPE_EVENT, 0, NULL);
2447 break;
2448 case AMLOP_MUTEX:
2449
2450 _aml_setvalue(res, AML_OBJTYPE_MUTEX, 0, NULL);
2451 res->v_mutex = (struct acpi_mutex *)acpi_os_malloc(
2452 sizeof(struct acpi_mutex));
2453 res->v_mutex->amt_synclevel = aml_parseint(scope,
2454 AMLOP_BYTEPREFIX);
2455 s = strlen(aml_getname(name));
2456 if (s > 4)
2457 offs = s - 4;
2458 strlcpy(res->v_mutex->amt_name, aml_getname(name) + offs,
2459 ACPI_MTX_MAXNAME);
2460 rw_init(&res->v_mutex->amt_lock, res->v_mutex->amt_name);
2461 break;
2462 case AMLOP_OPREGION:
2463 _aml_setvalue(res, AML_OBJTYPE_OPREGION, 0, NULL);
2464 res->v_opregion.iospace = aml_parseint(scope, AMLOP_BYTEPREFIX);
2465 res->v_opregion.iobase = aml_parseint(scope, AML_ANYINT);
2466 res->v_opregion.iolen = aml_parseint(scope, AML_ANYINT);
2467 if (res->v_opregion.iospace == GAS_PCI_CFG_SPACE) {
2468 res->v_opregion.iobase += aml_getpciaddr(dsdt_softc,
2469 scope->node);
2470 dnprintf(20, "got ioaddr: %s.%s:%llx\n",
2471 aml_nodename(scope->node), aml_getname(name),
2472 res->v_opregion.iobase);
2473 }
2474 break;
2475 }
2476 aml_createname(scope->node, name, res);
2477
2478 return res;
2479 }
2480
2481
2482 struct aml_value *
2483 aml_parsenamedscope(struct aml_scope *scope, int opcode, struct aml_value *res)
2484 {
2485 uint8_t *end, *name;
2486 struct aml_node *node;
2487
2488 AML_CHECKSTACK();
2489 end = aml_parseend(scope);
2490 name = aml_parsename(scope);
2491
2492 switch (opcode) {
2493 case AMLOP_DEVICE:
2494 res = aml_allocvalue(AML_OBJTYPE_DEVICE, 0, NULL);
2495 break;
2496 case AMLOP_SCOPE:
2497 res = NULL;
2498 break;
2499 case AMLOP_PROCESSOR:
2500 res = aml_allocvalue(AML_OBJTYPE_PROCESSOR, 0, NULL);
2501 res->v_processor.proc_id = aml_parseint(scope, AMLOP_BYTEPREFIX);
2502 res->v_processor.proc_addr = aml_parseint(scope, AMLOP_DWORDPREFIX);
2503 res->v_processor.proc_len = aml_parseint(scope, AMLOP_BYTEPREFIX);
2504 break;
2505 case AMLOP_POWERRSRC:
2506 res = aml_allocvalue(AML_OBJTYPE_POWERRSRC, 0, NULL);
2507 res->v_powerrsrc.pwr_level = aml_parseint(scope, AMLOP_BYTEPREFIX);
2508 res->v_powerrsrc.pwr_order = aml_parseint(scope, AMLOP_BYTEPREFIX);
2509 break;
2510 case AMLOP_THERMALZONE:
2511 res = aml_allocvalue(AML_OBJTYPE_THERMZONE, 0, NULL);
2512 break;
2513 }
2514 node = aml_createname(scope->node, name, res);
2515 aml_parsenode(scope, node, scope->pos, &end, NULL);
2516 scope->pos = end;
2517
2518 return res;
2519 }
2520
2521
2522 struct aml_value *
2523 aml_parsemath(struct aml_scope *scope, int opcode, struct aml_value *res)
2524 {
2525 struct aml_value *tmparg;
2526 int64_t i1, i2, i3;
2527
2528 tmparg = aml_alloctmp(scope, 1);
2529 AML_CHECKSTACK();
2530 switch (opcode) {
2531 case AMLOP_LNOT:
2532 i2 = 0;
2533 i1 = aml_parseint(scope, AML_ANYINT);
2534 break;
2535 case AMLOP_LAND:
2536 case AMLOP_LOR:
2537 i1 = aml_parseint(scope, AML_ANYINT);
2538 i2 = aml_parseint(scope, AML_ANYINT);
2539 break;
2540 case AMLOP_NOT:
2541 case AMLOP_TOBCD:
2542 case AMLOP_FROMBCD:
2543 case AMLOP_TOINTEGER:
2544 case AMLOP_FINDSETLEFTBIT:
2545 case AMLOP_FINDSETRIGHTBIT:
2546 i2 = 0;
2547 i1 = aml_parseint(scope, AML_ANYINT);
2548 aml_parsetarget(scope, tmparg, NULL);
2549 break;
2550 case AMLOP_INCREMENT:
2551 case AMLOP_DECREMENT:
2552 aml_parsetarget(scope, tmparg, NULL);
2553 i1 = aml_val2int(aml_derefterm(scope, tmparg, 0));
2554 i2 = 1;
2555 break;
2556 case AMLOP_DIVIDE:
2557 i1 = aml_parseint(scope, AML_ANYINT);
2558 i2 = aml_parseint(scope, AML_ANYINT);
2559
2560 aml_parsetarget(scope, tmparg, NULL);
2561 aml_setvalue(scope, tmparg, NULL, (i1 % i2));
2562
2563 aml_parsetarget(scope, tmparg, NULL);
2564 break;
2565 default:
2566 i1 = aml_parseint(scope, AML_ANYINT);
2567 i2 = aml_parseint(scope, AML_ANYINT);
2568 aml_parsetarget(scope, tmparg, NULL);
2569 break;
2570 }
2571 i3 = aml_evalexpr(i1, i2, opcode);
2572 aml_setvalue(scope, res, NULL, i3);
2573 aml_setvalue(scope, tmparg, NULL, i3);
2574 return (res);
2575 }
2576
2577
2578 struct aml_value *
2579 aml_parsecompare(struct aml_scope *scope, int opcode, struct aml_value *res)
2580 {
2581 struct aml_value *tmparg;
2582 int rc;
2583
2584 AML_CHECKSTACK();
2585 tmparg = aml_alloctmp(scope, 2);
2586 aml_parseterm(scope, &tmparg[AML_LHS]);
2587 aml_parseterm(scope, &tmparg[AML_RHS]);
2588
2589
2590 rc = aml_cmpvalue(&tmparg[AML_LHS], &tmparg[AML_RHS], opcode);
2591 aml_setvalue(scope, res, NULL, rc);
2592
2593 return res;
2594 }
2595
2596
2597 struct aml_value *
2598 aml_parseif(struct aml_scope *scope, int opcode, struct aml_value *res)
2599 {
2600 int64_t test;
2601 uint8_t *end;
2602
2603 AML_CHECKSTACK();
2604 end = aml_parseend(scope);
2605 test = aml_parseint(scope, AML_ANYINT);
2606
2607 dnprintf(40, "@ iftest: %llx\n", test);
2608 while (test && scope->pos < end) {
2609
2610 aml_parseterm(scope, res);
2611 }
2612 if (scope->pos >= scope->end)
2613 return res;
2614
2615 if (*end == AMLOP_ELSE) {
2616 scope->pos = ++end;
2617 end = aml_parseend(scope);
2618 while (!test && scope->pos < end) {
2619
2620 aml_parseterm(scope, res);
2621 }
2622 }
2623 if (scope->pos < end)
2624 scope->pos = end;
2625 return res;
2626 }
2627
2628 struct aml_value *
2629 aml_parsewhile(struct aml_scope *scope, int opcode, struct aml_value *res)
2630 {
2631 uint8_t *end, *start;
2632 int test, cnt;
2633
2634 AML_CHECKSTACK();
2635 end = aml_parseend(scope);
2636 start = scope->pos;
2637 cnt = 0;
2638 do {
2639 test = 1;
2640 if (scope->pos == start || scope->pos == end) {
2641 scope->pos = start;
2642 test = aml_parseint(scope, AML_ANYINT);
2643 dnprintf(40, "@whiletest = %d %x\n", test, cnt++);
2644 } else if (*scope->pos == AMLOP_BREAK) {
2645 scope->pos++;
2646 test = 0;
2647 } else if (*scope->pos == AMLOP_CONTINUE) {
2648 scope->pos = start;
2649 } else {
2650 aml_parseterm(scope, res);
2651 }
2652 } while (test && scope->pos <= end && cnt < 0x199);
2653
2654
2655 dnprintf(40, "Set While end : %x\n", cnt);
2656 if (scope->pos < end)
2657 scope->pos = end;
2658 return res;
2659 }
2660
2661
2662 struct aml_value *
2663 aml_parsebufpkg(struct aml_scope *scope, int opcode, struct aml_value *res)
2664 {
2665 uint8_t *end;
2666 int len;
2667
2668 AML_CHECKSTACK();
2669 end = aml_parseend(scope);
2670 len = aml_parseint(scope, (opcode == AMLOP_PACKAGE) ?
2671 AMLOP_BYTEPREFIX : AML_ANYINT);
2672
2673 switch (opcode) {
2674 case AMLOP_BUFFER:
2675 _aml_setvalue(res, AML_OBJTYPE_BUFFER, len, NULL);
2676 if (scope->pos < end) {
2677 memcpy(res->v_buffer, scope->pos, end-scope->pos);
2678 }
2679 if (len != end-scope->pos) {
2680 dnprintf(99, "buffer: %.4x %.4x\n", len, end-scope->pos);
2681 }
2682 break;
2683 case AMLOP_PACKAGE:
2684 case AMLOP_VARPACKAGE:
2685 _aml_setvalue(res, AML_OBJTYPE_PACKAGE, len, NULL);
2686 for (len = 0; len < res->length && scope->pos < end; len++) {
2687 aml_parseop(scope, res->v_package[len]);
2688 }
2689 if (scope->pos != end) {
2690 dnprintf(99, "Package not equiv!! %.4x %.4x %d of %d\n",
2691 aml_pc(scope->pos), aml_pc(end), len, res->length);
2692 }
2693 break;
2694 }
2695 scope->pos = end;
2696 return res;
2697 }
2698
2699 struct aml_value *
2700 aml_parsemethod(struct aml_scope *scope, int opcode, struct aml_value *res)
2701 {
2702 uint8_t *end, *name;
2703
2704 AML_CHECKSTACK();
2705 end = aml_parseend(scope);
2706 name = aml_parsename(scope);
2707
2708 res = aml_allocvalue(AML_OBJTYPE_METHOD, 0, NULL);
2709 res->v_method.flags = aml_parseint(scope, AMLOP_BYTEPREFIX);
2710 res->v_method.start = scope->pos;
2711 res->v_method.end = end;
2712 res->v_method.fneval = aml_callmethod;
2713 aml_createname(scope->node, name, res);
2714
2715 scope->pos = end;
2716
2717 return res;
2718 }
2719
2720
2721 struct aml_value *
2722 aml_parsesimple(struct aml_scope *scope, int opcode, struct aml_value *res)
2723 {
2724 struct aml_node *node;
2725
2726 AML_CHECKSTACK();
2727 switch (opcode) {
2728 case AMLOP_ZERO:
2729 _aml_setvalue(res, AML_OBJTYPE_INTEGER+AML_STATIC,
2730 aml_parseint(scope, opcode), NULL);
2731 break;
2732 case AMLOP_ONE:
2733 case AMLOP_ONES:
2734 case AMLOP_BYTEPREFIX:
2735 case AMLOP_WORDPREFIX:
2736 case AMLOP_DWORDPREFIX:
2737 case AMLOP_QWORDPREFIX:
2738 case AMLOP_REVISION:
2739 _aml_setvalue(res, AML_OBJTYPE_INTEGER,
2740 aml_parseint(scope, opcode), NULL);
2741 break;
2742 case AMLOP_DEBUG:
2743 _aml_setvalue(res, AML_OBJTYPE_DEBUGOBJ, 0, NULL);
2744 break;
2745 case AMLOP_STRINGPREFIX:
2746 _aml_setvalue(res, AML_OBJTYPE_STRING, -1, scope->pos);
2747 scope->pos += res->length+1;
2748 break;
2749 case AMLOP_NAMECHAR:
2750 _aml_setvalue(res, AML_OBJTYPE_NAMEREF, 0, NULL);
2751 res->v_nameref = aml_parsename(scope);
2752 node = aml_searchname(scope->node, res->v_nameref);
2753 if (node && node->value)
2754 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, node->value);
2755 break;
2756 }
2757 return res;
2758 }
2759
2760
2761 struct aml_value *
2762 aml_parsefieldunit(struct aml_scope *scope, int opcode, struct aml_value *res)
2763 {
2764 uint8_t *end, *name;
2765 struct aml_value *fld;
2766
2767 AML_CHECKSTACK();
2768 end = aml_parseend(scope);
2769
2770 switch (opcode) {
2771 case AMLOP_FIELD:
2772 aml_parsetarget(scope, NULL, &res->v_field.ref1);
2773 break;
2774 case AMLOP_INDEXFIELD:
2775 aml_parsetarget(scope, NULL, &res->v_field.ref1);
2776 aml_parsetarget(scope, NULL, &res->v_field.ref2);
2777 break;
2778 case AMLOP_BANKFIELD:
2779 aml_parsetarget(scope, NULL, &res->v_field.ref1);
2780 aml_parsetarget(scope, NULL, &res->v_field.ref2);
2781 res->v_field.ref3 = aml_parseint(scope, AML_ANYINT);
2782 break;
2783 }
2784 res->v_field.flags = aml_parseint(scope, AMLOP_BYTEPREFIX);
2785 res->v_field.type = opcode;
2786
2787 aml_fixref(&res->v_field.ref1);
2788 aml_fixref(&res->v_field.ref2);
2789
2790 while (scope->pos < end) {
2791 switch (*scope->pos) {
2792 case 0x00:
2793 scope->pos++;
2794 res->v_field.bitlen = aml_parselength(scope);
2795 break;
2796 case 0x01:
2797 scope->pos++;
2798
2799 aml_parseint(scope, AMLOP_BYTEPREFIX);
2800 aml_parseint(scope, AMLOP_BYTEPREFIX);
2801 res->v_field.bitlen = 0;
2802 break;
2803 default:
2804 name = aml_parsename(scope);
2805 res->v_field.bitlen = aml_parselength(scope);
2806
2807
2808 fld = aml_allocvalue(AML_OBJTYPE_FIELDUNIT, 0, NULL);
2809
2810
2811 fld->v_field = res->v_field;
2812 aml_addref(fld->v_field.ref1);
2813 aml_addref(fld->v_field.ref2);
2814
2815 aml_createname(scope->node, name, fld);
2816 break;
2817 }
2818 res->v_field.bitpos += res->v_field.bitlen;
2819 }
2820
2821 aml_delref(&res->v_field.ref1);
2822 aml_delref(&res->v_field.ref2);
2823 return res;
2824 }
2825
2826
2827 struct aml_value *
2828 aml_parsebufferfield(struct aml_scope *scope, int opcode,
2829 struct aml_value *res)
2830 {
2831 uint8_t *name;
2832
2833 AML_CHECKSTACK();
2834 res = aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 0, NULL);
2835 res->v_field.type = opcode;
2836 aml_parsetarget(scope, NULL, &res->v_field.ref1);
2837 res->v_field.bitpos = aml_parseint(scope, AML_ANYINT);
2838
2839 aml_fixref(&res->v_field.ref1);
2840
2841 switch (opcode) {
2842 case AMLOP_CREATEFIELD:
2843 res->v_field.bitlen = aml_parseint(scope, AML_ANYINT);
2844 break;
2845 case AMLOP_CREATEBITFIELD:
2846 res->v_field.bitlen = 1;
2847 break;
2848 case AMLOP_CREATEBYTEFIELD:
2849 res->v_field.bitlen = 8;
2850 res->v_field.bitpos *= 8;
2851 break;
2852 case AMLOP_CREATEWORDFIELD:
2853 res->v_field.bitlen = 16;
2854 res->v_field.bitpos *= 8;
2855 break;
2856 case AMLOP_CREATEDWORDFIELD:
2857 res->v_field.bitlen = 32;
2858 res->v_field.bitpos *= 8;
2859 break;
2860 case AMLOP_CREATEQWORDFIELD:
2861 res->v_field.bitlen = 64;
2862 res->v_field.bitpos *= 8;
2863 break;
2864 }
2865 name = aml_parsename(scope);
2866 aml_createname(scope->node, name, res);
2867
2868 return res;
2869 }
2870
2871
2872 struct aml_value *
2873 aml_parsemuxaction(struct aml_scope *scope, int opcode, struct aml_value *res)
2874 {
2875 struct aml_value *tmparg;
2876 int64_t i1;
2877 int rv;
2878
2879 AML_CHECKSTACK();
2880
2881 tmparg = aml_alloctmp(scope, 1);
2882 aml_parsetarget(scope, tmparg, NULL);
2883 switch (opcode) {
2884 case AMLOP_ACQUIRE:
2885
2886 i1 = aml_parseint(scope, AMLOP_WORDPREFIX);
2887 rv = acpi_mutex_acquire(tmparg->v_objref.ref, i1);
2888
2889 aml_setvalue(scope, res, NULL, rv);
2890 break;
2891 case AMLOP_RELEASE:
2892 acpi_mutex_release(tmparg->v_objref.ref);
2893 break;
2894
2895 case AMLOP_WAIT:
2896
2897 i1 = aml_parseint(scope, AML_ANYINT);
2898
2899
2900 aml_setvalue(scope, res, NULL, 0);
2901 break;
2902 case AMLOP_SIGNAL:
2903 break;
2904 case AMLOP_RESET:
2905 break;
2906 }
2907
2908 return res;
2909 }
2910
2911
2912 struct aml_value *
2913 aml_parsemisc2(struct aml_scope *scope, int opcode, struct aml_value *res)
2914 {
2915 struct aml_value *tmparg, *dev;
2916 int i1, i2, i3;
2917
2918 AML_CHECKSTACK();
2919
2920 switch (opcode) {
2921 case AMLOP_NOTIFY:
2922
2923 tmparg = aml_alloctmp(scope, 1);
2924 aml_parseop(scope, tmparg);
2925 dev = aml_dereftarget(scope, tmparg);
2926
2927 i1 = aml_parseint(scope, AML_ANYINT);
2928 if (dev && dev->node) {
2929 dnprintf(10, "Notify: [%s] %.2x\n",
2930 aml_nodename(dev->node), i1);
2931 aml_notify(dev->node, i1);
2932 }
2933 break;
2934 case AMLOP_SLEEP:
2935 i1 = aml_parseint(scope, AML_ANYINT);
2936 dnprintf(50, "SLEEP: %x\n", i1);
2937 if (i1)
2938 acpi_sleep(i1);
2939 else {
2940 dnprintf(10, "acpi_sleep(0)\n");
2941 }
2942 break;
2943 case AMLOP_STALL:
2944 i1 = aml_parseint(scope, AML_ANYINT);
2945 dnprintf(50, "STALL: %x\n", i1);
2946 if (i1)
2947 acpi_stall(i1);
2948 else {
2949 dnprintf(10, "acpi_stall(0)\n");
2950 }
2951 break;
2952 case AMLOP_FATAL:
2953 i1 = aml_parseint(scope, AMLOP_BYTEPREFIX);
2954 i2 = aml_parseint(scope, AMLOP_DWORDPREFIX);
2955 i3 = aml_parseint(scope, AML_ANYINT);
2956 aml_die("FATAL: %x %x %x\n", i1, i2, i3);
2957 break;
2958 }
2959 return res;
2960 }
2961
2962
2963 struct aml_value *
2964 aml_parsemisc3(struct aml_scope *scope, int opcode, struct aml_value *res)
2965 {
2966 struct aml_value *tmparg;
2967
2968 AML_CHECKSTACK();
2969 tmparg = aml_alloctmp(scope, 1);
2970 aml_parseterm(scope, tmparg);
2971 switch (opcode) {
2972 case AMLOP_SIZEOF:
2973 aml_setvalue(scope, res, NULL, tmparg->length);
2974 break;
2975 case AMLOP_OBJECTTYPE:
2976 aml_setvalue(scope, res, NULL, tmparg->type);
2977 break;
2978 }
2979
2980 return res;
2981 }
2982
2983
2984 struct aml_value *
2985 aml_parsematch(struct aml_scope *scope, int opcode, struct aml_value *res)
2986 {
2987 struct aml_value *pkg;
2988 int op1, op2, idx, mv1, mv2;
2989
2990 AML_CHECKSTACK();
2991 pkg = aml_parseterm(scope, NULL);
2992 op1 = aml_parseint(scope, AMLOP_BYTEPREFIX);
2993 mv1 = aml_parseint(scope, AML_ANYINT);
2994 op2 = aml_parseint(scope, AMLOP_BYTEPREFIX);
2995 mv2 = aml_parseint(scope, AML_ANYINT);
2996 idx = aml_parseint(scope, AML_ANYINT);
2997
2998 aml_setvalue(scope, res, NULL, -1);
2999 while (idx < pkg->length) {
3000 if (aml_match(op1, mv1, pkg->v_package[idx]) ||
3001 aml_match(op2, mv2, pkg->v_package[idx])) {
3002 aml_setvalue(scope, res, NULL, idx);
3003 break;
3004 }
3005 idx++;
3006 }
3007 aml_delref(&pkg);
3008 return res;
3009 }
3010
3011
3012 struct aml_value *
3013 aml_parseref(struct aml_scope *scope, int opcode, struct aml_value *res)
3014 {
3015 struct aml_value *tmparg;
3016
3017 AML_CHECKSTACK();
3018
3019 switch (opcode) {
3020 case AMLOP_INDEX:
3021 tmparg = aml_alloctmp(scope, 1);
3022 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, NULL);
3023 aml_parsetarget(scope, tmparg, NULL);
3024
3025 res->v_objref.index = aml_parseint(scope, AML_ANYINT);
3026 res->v_objref.ref = aml_dereftarget(scope, tmparg);
3027
3028 aml_parsetarget(scope, tmparg, NULL);
3029 aml_setvalue(scope, tmparg, res, 0);
3030 break;
3031 case AMLOP_DEREFOF:
3032 aml_parseop(scope, res);
3033 break;
3034 case AMLOP_RETURN:
3035 tmparg = aml_alloctmp(scope, 1);
3036 aml_parseterm(scope, tmparg);
3037 aml_setvalue(scope, res, tmparg, 0);
3038 scope->pos = scope->end;
3039 break;
3040 case AMLOP_ARG0 ... AMLOP_ARG6:
3041 opcode -= AMLOP_ARG0;
3042 if (scope->args == NULL || opcode >= scope->nargs)
3043 aml_die("arg %d out of range", opcode);
3044
3045
3046 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1,
3047 &scope->args[opcode]);
3048 break;
3049 case AMLOP_LOCAL0 ... AMLOP_LOCAL7:
3050 opcode -= AMLOP_LOCAL0;
3051
3052
3053 if (scope->locals == NULL) {
3054 dnprintf(10, "Lazy alloc locals\n");
3055 scope->locals = aml_alloctmp(scope, AML_MAX_LOCAL);
3056 }
3057
3058
3059 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1,
3060 &scope->locals[opcode]);
3061 res->v_objref.ref->stack = opcode+AMLOP_LOCAL0;
3062 break;
3063 case AMLOP_LOAD:
3064 tmparg = aml_alloctmp(scope, 2);
3065 aml_parseop(scope, &tmparg[0]);
3066 aml_parseop(scope, &tmparg[1]);
3067 break;
3068 case AMLOP_STORE:
3069 tmparg = aml_alloctmp(scope, 1);
3070 aml_parseterm(scope, res);
3071 aml_parsetarget(scope, tmparg, NULL);
3072
3073 while (tmparg->type == AML_OBJTYPE_OBJREF) {
3074 if (tmparg->v_objref.index != -1)
3075 break;
3076 tmparg = tmparg->v_objref.ref;
3077 }
3078 aml_setvalue(scope, tmparg, res, 0);
3079 break;
3080 case AMLOP_REFOF:
3081 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, NULL);
3082 aml_parsetarget(scope, NULL, &res->v_objref.ref);
3083 break;
3084 case AMLOP_CONDREFOF:
3085
3086 tmparg = aml_alloctmp(scope, 2);
3087 aml_parsetarget(scope, &tmparg[0], NULL);
3088 aml_parsetarget(scope, &tmparg[1], NULL);
3089 if (tmparg[0].type != AML_OBJTYPE_NAMEREF) {
3090
3091 aml_freevalue(&tmparg[1]);
3092 aml_setvalue(scope, &tmparg[1], &tmparg[0], 0);
3093 aml_setvalue(scope, res, NULL, 1);
3094 } else {
3095
3096 aml_setvalue(scope, res, NULL, 0);
3097 }
3098 break;
3099 }
3100
3101 return res;
3102 }
3103
3104 struct aml_value *
3105 aml_parsestring(struct aml_scope *scope, int opcode, struct aml_value *res)
3106 {
3107 struct aml_value *tmpval;
3108 int i1, i2;
3109
3110 AML_CHECKSTACK();
3111 switch (opcode) {
3112 case AMLOP_CONCAT:
3113 tmpval = aml_alloctmp(scope, 4);
3114 aml_parseterm(scope, &tmpval[AML_LHS]);
3115 aml_parseterm(scope, &tmpval[AML_RHS]);
3116 aml_parsetarget(scope, &tmpval[AML_DST], NULL);
3117 if (tmpval[AML_LHS].type == AML_OBJTYPE_BUFFER &&
3118 tmpval[AML_RHS].type == AML_OBJTYPE_BUFFER) {
3119 aml_resize(&tmpval[AML_LHS],
3120 tmpval[AML_LHS].length+tmpval[AML_RHS].length);
3121 memcpy(&tmpval[AML_LHS].v_buffer+tmpval[AML_LHS].length,
3122 tmpval[AML_RHS].v_buffer, tmpval[AML_RHS].length);
3123 aml_setvalue(scope, &tmpval[AML_DST], &tmpval[AML_LHS], 0);
3124 }
3125 if (tmpval[AML_LHS].type == AML_OBJTYPE_STRING &&
3126 tmpval[AML_RHS].type == AML_OBJTYPE_STRING) {
3127 aml_resize(&tmpval[AML_LHS],
3128 tmpval[AML_LHS].length+tmpval[AML_RHS].length);
3129 memcpy(&tmpval[AML_LHS].v_string+tmpval[AML_LHS].length,
3130 tmpval[AML_RHS].v_buffer, tmpval[AML_RHS].length);
3131 aml_setvalue(scope, &tmpval[AML_DST], &tmpval[AML_LHS], 0);
3132 } else {
3133 aml_die("concat");
3134 }
3135 break;
3136 case AMLOP_MID:
3137 tmpval = aml_alloctmp(scope, 2);
3138 aml_parseterm(scope, &tmpval[0]);
3139 i1 = aml_parseint(scope, AML_ANYINT);
3140 i2 = aml_parseint(scope, AML_ANYINT);
3141 aml_parsetarget(scope, &tmpval[1], NULL);
3142 if (i1 > tmpval[0].length)
3143 i1 = tmpval[0].length;
3144 if (i1+i2 > tmpval[0].length)
3145 i2 = tmpval[0].length-i1;
3146 _aml_setvalue(res, AML_OBJTYPE_STRING, i2, tmpval[0].v_string+i1);
3147 break;
3148 case AMLOP_TODECSTRING:
3149 case AMLOP_TOHEXSTRING:
3150 i1 = aml_parseint(scope, AML_ANYINT);
3151 _aml_setvalue(res, AML_OBJTYPE_STRING, 20, NULL);
3152 snprintf(res->v_string, res->length,
3153 ((opcode == AMLOP_TODECSTRING) ? "%d" : "%x"), i1);
3154 break;
3155 default:
3156 aml_die("to_string");
3157 break;
3158 }
3159
3160 return res;
3161 }
3162
3163 struct aml_value *
3164 aml_parseterm(struct aml_scope *scope, struct aml_value *res)
3165 {
3166 struct aml_value *tmpres;
3167
3168
3169 if (res == NULL)
3170 res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
3171 tmpres = aml_alloctmp(scope, 1);
3172 aml_parseop(scope, tmpres);
3173 aml_evalterm(scope, tmpres, res);
3174 return res;
3175 }
3176
3177 struct aml_value *
3178 aml_parsetarget(struct aml_scope *scope, struct aml_value *res,
3179 struct aml_value **opt)
3180 {
3181 struct aml_value *dummy;
3182
3183
3184 if (res == NULL)
3185 res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
3186 aml_parseop(scope, res);
3187 if (opt == NULL)
3188 opt = &dummy;
3189
3190 *opt = aml_evaltarget(scope, res);
3191
3192 return res;
3193 }
3194
3195 int odp;
3196
3197
3198 struct aml_value *
3199 aml_parseop(struct aml_scope *scope, struct aml_value *res)
3200 {
3201 int opcode;
3202 struct aml_opcode *htab;
3203 struct aml_value *rv = NULL;
3204
3205 if (odp++ > 25)
3206 panic("depth");
3207
3208 aml_freevalue(res);
3209 opcode = aml_parseopcode(scope);
3210 dnprintf(15, "%.4x: [%s] %s\n", aml_pc(scope->pos-opsize(opcode)),
3211 aml_nodename(scope->node), aml_mnem(opcode, scope->pos));
3212 delay(amlop_delay);
3213
3214 htab = aml_findopcode(opcode);
3215 if (htab && htab->handler) {
3216 rv = htab->handler(scope, opcode, res);
3217 } else {
3218
3219 aml_die("Unknown opcode: %.4x @ %.4x", opcode,
3220 aml_pc(scope->pos - opsize(opcode)));
3221 }
3222 odp--;
3223 return rv;
3224 }
3225
3226 const char hext[] = "0123456789ABCDEF";
3227
3228 const char *
3229 aml_eisaid(u_int32_t pid)
3230 {
3231 static char id[8];
3232
3233 id[0] = '@' + ((pid >> 2) & 0x1F);
3234 id[1] = '@' + ((pid << 3) & 0x18) + ((pid >> 13) & 0x7);
3235 id[2] = '@' + ((pid >> 8) & 0x1F);
3236 id[3] = hext[(pid >> 20) & 0xF];
3237 id[4] = hext[(pid >> 16) & 0xF];
3238 id[5] = hext[(pid >> 28) & 0xF];
3239 id[6] = hext[(pid >> 24) & 0xF];
3240 id[7] = 0;
3241 return id;
3242 }
3243
3244
3245
3246
3247 struct aml_fixup {
3248 int offset;
3249 u_int8_t oldv, newv;
3250 } __ibm300gl[] = {
3251 { 0x19, 0x3a, 0x3b },
3252 { -1 }
3253 };
3254
3255 struct aml_blacklist {
3256 const char *oem, *oemtbl;
3257 struct aml_fixup *fixtab;
3258 u_int8_t cksum;
3259 } amlfix_list[] = {
3260 { "IBM ", "CDTPWSNH", __ibm300gl, 0x41 },
3261 { NULL },
3262 };
3263
3264 void
3265 aml_fixup_dsdt(u_int8_t *acpi_hdr, u_int8_t *base, int len)
3266 {
3267 struct acpi_table_header *hdr = (struct acpi_table_header *)acpi_hdr;
3268 struct aml_blacklist *fixlist;
3269 struct aml_fixup *fixtab;
3270
3271 for (fixlist = amlfix_list; fixlist->oem; fixlist++) {
3272 if (!memcmp(fixlist->oem, hdr->oemid, 6) &&
3273 !memcmp(fixlist->oemtbl, hdr->oemtableid, 8) &&
3274 fixlist->cksum == hdr->checksum) {
3275
3276 for (fixtab = fixlist->fixtab; fixtab->offset != -1;
3277 fixtab++) {
3278 if (base[fixtab->offset] == fixtab->oldv)
3279 base[fixtab->offset] = fixtab->newv;
3280 }
3281 }
3282 }
3283 }
3284
3285
3286
3287
3288 struct aml_defval {
3289 const char *name;
3290 int type;
3291 int64_t ival;
3292 const void *bval;
3293 struct aml_value **gval;
3294 } aml_defobj[] = {
3295 { "_OS_", AML_OBJTYPE_STRING, -1, "OpenBSD" },
3296 { "_REV", AML_OBJTYPE_INTEGER, 2, NULL },
3297 { "_GL", AML_OBJTYPE_MUTEX, 1, NULL, &aml_global_lock },
3298 { "_OSI", AML_OBJTYPE_METHOD, 1, aml_callosi },
3299 { NULL }
3300 };
3301
3302
3303
3304
3305
3306 char *aml_valid_osi[] = {
3307 "OpenBSD",
3308 "Windows 2000",
3309 "Windows 2001",
3310 "Windows 2001.1",
3311 "Windows 2001 SP0",
3312 "Windows 2001 SP1",
3313 "Windows 2001 SP2",
3314 "Windows 2001 SP3",
3315 "Windows 2001 SP4",
3316 "Windows 2006",
3317 NULL
3318 };
3319
3320 struct aml_value *
3321 aml_callosi(struct aml_scope *scope, struct aml_value *val)
3322 {
3323 struct aml_value tmpstr, *arg;
3324 int idx, result;
3325
3326
3327 result = 0;
3328 memset(&tmpstr, 0, sizeof(tmpstr));
3329 tmpstr.type = AML_OBJTYPE_STRING;
3330 arg = aml_derefvalue(scope, &scope->args[0], ACPI_IOREAD);
3331
3332 for (idx=0; !result && aml_valid_osi[idx] != NULL; idx++) {
3333 tmpstr.v_string = aml_valid_osi[idx];
3334 tmpstr.length = strlen(tmpstr.v_string);
3335
3336 result = aml_cmpvalue(arg, &tmpstr, AMLOP_LEQUAL);
3337 }
3338 aml_setvalue(scope, val, NULL, result);
3339 return val;
3340 }
3341
3342 void
3343 aml_create_defaultobjects()
3344 {
3345 struct aml_value *tmp;
3346 struct aml_defval *def;
3347
3348 for (def = aml_defobj; def->name; def++) {
3349
3350 tmp = aml_allocvalue(def->type, def->ival, def->bval);
3351 aml_createname(&aml_root, def->name, tmp);
3352 if (def->gval) {
3353
3354 *def->gval = tmp;
3355 }
3356 }
3357 }
3358
3359 int
3360 aml_print_resource(union acpi_resource *crs, void *arg)
3361 {
3362 int typ = AML_CRSTYPE(crs);
3363
3364 switch (typ) {
3365 case LR_EXTIRQ:
3366 printf("extirq\tflags:%.2x len:%.2x irq:%.4x\n",
3367 crs->lr_extirq.flags, crs->lr_extirq.irq_count,
3368 aml_letohost32(crs->lr_extirq.irq[0]));
3369 break;
3370 case SR_IRQ:
3371 printf("irq\t%.4x %.2x\n", aml_letohost16(crs->sr_irq.irq_mask),
3372 crs->sr_irq.irq_flags);
3373 break;
3374 case SR_DMA:
3375 printf("dma\t%.2x %.2x\n", crs->sr_dma.channel,
3376 crs->sr_dma.flags);
3377 break;
3378 case SR_IOPORT:
3379 printf("ioport\tflags:%.2x _min:%.4x _max:%.4x _aln:%.2x _len:%.2x\n",
3380 crs->sr_ioport.flags, crs->sr_ioport._min,
3381 crs->sr_ioport._max, crs->sr_ioport._aln,
3382 crs->sr_ioport._len);
3383 break;
3384 case SR_STARTDEP:
3385 printf("startdep\n");
3386 break;
3387 case SR_ENDDEP:
3388 printf("enddep\n");
3389 break;
3390 case LR_WORD:
3391 printf("word\ttype:%.2x flags:%.2x tflag:%.2x gra:%.4x min:%.4x max:%.4x tra:%.4x len:%.4x\n",
3392 crs->lr_word.type, crs->lr_word.flags, crs->lr_word.tflags,
3393 crs->lr_word._gra, crs->lr_word._min, crs->lr_word._max,
3394 crs->lr_word._tra, crs->lr_word._len);
3395 break;
3396 case LR_DWORD:
3397 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.8x min:%.8x max:%.8x tra:%.8x len:%.8x\n",
3398 crs->lr_dword.type, crs->lr_dword.flags, crs->lr_dword.tflags,
3399 crs->lr_dword._gra, crs->lr_dword._min, crs->lr_dword._max,
3400 crs->lr_dword._tra, crs->lr_dword._len);
3401 break;
3402 case LR_QWORD:
3403 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.16llx min:%.16llx max:%.16llx tra:%.16llx len:%.16llx\n",
3404 crs->lr_qword.type, crs->lr_qword.flags, crs->lr_qword.tflags,
3405 crs->lr_qword._gra, crs->lr_qword._min, crs->lr_qword._max,
3406 crs->lr_qword._tra, crs->lr_qword._len);
3407 break;
3408 default:
3409 printf("unknown type: %x\n", typ);
3410 break;
3411 }
3412 return (0);
3413 }
3414
3415 union acpi_resource *aml_mapresource(union acpi_resource *);
3416
3417 union acpi_resource *
3418 aml_mapresource(union acpi_resource *crs)
3419 {
3420 static union acpi_resource map;
3421 int rlen;
3422
3423 rlen = AML_CRSLEN(crs);
3424 if (rlen >= sizeof(map))
3425 return crs;
3426
3427 memset(&map, 0, sizeof(map));
3428 memcpy(&map, crs, rlen);
3429
3430 return ↦
3431 }
3432
3433 int
3434 aml_parse_resource(int length, uint8_t *buffer,
3435 int (*crs_enum)(union acpi_resource *, void *), void *arg)
3436 {
3437 int off, rlen;
3438 union acpi_resource *crs;
3439
3440 for (off = 0; off < length; off += rlen) {
3441 crs = (union acpi_resource *)(buffer+off);
3442
3443 rlen = AML_CRSLEN(crs);
3444 if (crs->hdr.typecode == 0x79 || rlen <= 3)
3445 break;
3446
3447 crs = aml_mapresource(crs);
3448 #ifdef ACPI_DEBUG
3449 aml_print_resource(crs, NULL);
3450 #endif
3451 crs_enum(crs, arg);
3452 }
3453
3454 return 0;
3455 }
3456
3457 void
3458 aml_foreachpkg(struct aml_value *pkg, int start,
3459 void (*fn)(struct aml_value *, void *),
3460 void *arg)
3461 {
3462 int idx;
3463
3464 if (pkg->type != AML_OBJTYPE_PACKAGE)
3465 return;
3466 for (idx=start; idx<pkg->length; idx++)
3467 fn(pkg->v_package[idx], arg);
3468 }
3469
3470 int
3471 acpi_parse_aml(struct acpi_softc *sc, u_int8_t *start, u_int32_t length)
3472 {
3473 u_int8_t *end;
3474
3475 dsdt_softc = sc;
3476
3477 strlcpy(aml_root.name, "\\", sizeof(aml_root.name));
3478 if (aml_root.start == NULL) {
3479 aml_root.start = start;
3480 aml_root.end = start+length;
3481 }
3482 end = start+length;
3483 aml_parsenode(NULL, &aml_root, start, &end, NULL);
3484 dnprintf(50, " : parsed %d AML bytes\n", length);
3485
3486 return (0);
3487 }
3488
3489
3490
3491
3492 int aml_fixup_node(struct aml_node *, void *);
3493
3494 int aml_fixup_node(struct aml_node *node, void *arg)
3495 {
3496 struct aml_value *val = arg;
3497 int i;
3498
3499 if (node->value == NULL)
3500 return (0);
3501 if (arg == NULL)
3502 aml_fixup_node(node, node->value);
3503 else if (val->type == AML_OBJTYPE_NAMEREF) {
3504 node = aml_searchname(node, val->v_nameref);
3505 if (node && node->value) {
3506 _aml_setvalue(val, AML_OBJTYPE_OBJREF, -1,
3507 node->value);
3508 }
3509 } else if (val->type == AML_OBJTYPE_PACKAGE) {
3510 for (i = 0; i < val->length; i++)
3511 aml_fixup_node(node, val->v_package[i]);
3512 } else if (val->type == AML_OBJTYPE_OPREGION) {
3513 if (val->v_opregion.iospace != GAS_PCI_CFG_SPACE)
3514 return (0);
3515 if (ACPI_PCI_FN(val->v_opregion.iobase) != 0xFFFF)
3516 return (0);
3517 val->v_opregion.iobase =
3518 ACPI_PCI_REG(val->v_opregion.iobase) +
3519 aml_getpciaddr(dsdt_softc, node);
3520 dnprintf(20, "late ioaddr : %s:%llx\n",
3521 aml_nodename(node), val->v_opregion.iobase);
3522 }
3523 return (0);
3524 }
3525
3526 void
3527 aml_postparse()
3528 {
3529 aml_walknodes(&aml_root, AML_WALK_PRE, aml_fixup_node, NULL);
3530 }