xref: /qemu/hw/acpi/aml-build.c (revision 52ea63de)
1 /* Support for generating ACPI tables and passing them to Guests
2  *
3  * Copyright (C) 2015 Red Hat Inc
4  *
5  * Author: Michael S. Tsirkin <mst@redhat.com>
6  * Author: Igor Mammedov <imammedo@redhat.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17 
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "qemu/osdep.h"
23 #include <glib/gprintf.h>
24 #include "hw/acpi/aml-build.h"
25 #include "qemu/bswap.h"
26 #include "qemu/bitops.h"
27 
28 static GArray *build_alloc_array(void)
29 {
30     return g_array_new(false, true /* clear */, 1);
31 }
32 
33 static void build_free_array(GArray *array)
34 {
35     g_array_free(array, true);
36 }
37 
38 static void build_prepend_byte(GArray *array, uint8_t val)
39 {
40     g_array_prepend_val(array, val);
41 }
42 
43 static void build_append_byte(GArray *array, uint8_t val)
44 {
45     g_array_append_val(array, val);
46 }
47 
48 static void build_append_array(GArray *array, GArray *val)
49 {
50     g_array_append_vals(array, val->data, val->len);
51 }
52 
53 #define ACPI_NAMESEG_LEN 4
54 
55 static void
56 build_append_nameseg(GArray *array, const char *seg)
57 {
58     int len;
59 
60     len = strlen(seg);
61     assert(len <= ACPI_NAMESEG_LEN);
62 
63     g_array_append_vals(array, seg, len);
64     /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
65     g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
66 }
67 
68 static void GCC_FMT_ATTR(2, 0)
69 build_append_namestringv(GArray *array, const char *format, va_list ap)
70 {
71     char *s;
72     char **segs;
73     char **segs_iter;
74     int seg_count = 0;
75 
76     s = g_strdup_vprintf(format, ap);
77     segs = g_strsplit(s, ".", 0);
78     g_free(s);
79 
80     /* count segments */
81     segs_iter = segs;
82     while (*segs_iter) {
83         ++segs_iter;
84         ++seg_count;
85     }
86     /*
87      * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
88      * "SegCount can be from 1 to 255"
89      */
90     assert(seg_count > 0 && seg_count <= 255);
91 
92     /* handle RootPath || PrefixPath */
93     s = *segs;
94     while (*s == '\\' || *s == '^') {
95         build_append_byte(array, *s);
96         ++s;
97     }
98 
99     switch (seg_count) {
100     case 1:
101         if (!*s) {
102             build_append_byte(array, 0x00); /* NullName */
103         } else {
104             build_append_nameseg(array, s);
105         }
106         break;
107 
108     case 2:
109         build_append_byte(array, 0x2E); /* DualNamePrefix */
110         build_append_nameseg(array, s);
111         build_append_nameseg(array, segs[1]);
112         break;
113     default:
114         build_append_byte(array, 0x2F); /* MultiNamePrefix */
115         build_append_byte(array, seg_count);
116 
117         /* handle the 1st segment manually due to prefix/root path */
118         build_append_nameseg(array, s);
119 
120         /* add the rest of segments */
121         segs_iter = segs + 1;
122         while (*segs_iter) {
123             build_append_nameseg(array, *segs_iter);
124             ++segs_iter;
125         }
126         break;
127     }
128     g_strfreev(segs);
129 }
130 
131 GCC_FMT_ATTR(2, 3)
132 static void build_append_namestring(GArray *array, const char *format, ...)
133 {
134     va_list ap;
135 
136     va_start(ap, format);
137     build_append_namestringv(array, format, ap);
138     va_end(ap);
139 }
140 
141 /* 5.4 Definition Block Encoding */
142 enum {
143     PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
144     PACKAGE_LENGTH_2BYTE_SHIFT = 4,
145     PACKAGE_LENGTH_3BYTE_SHIFT = 12,
146     PACKAGE_LENGTH_4BYTE_SHIFT = 20,
147 };
148 
149 static void
150 build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
151 {
152     uint8_t byte;
153     unsigned length_bytes;
154 
155     if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
156         length_bytes = 1;
157     } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
158         length_bytes = 2;
159     } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
160         length_bytes = 3;
161     } else {
162         length_bytes = 4;
163     }
164 
165     /*
166      * NamedField uses PkgLength encoding but it doesn't include length
167      * of PkgLength itself.
168      */
169     if (incl_self) {
170         /*
171          * PkgLength is the length of the inclusive length of the data
172          * and PkgLength's length itself when used for terms with
173          * explitit length.
174          */
175         length += length_bytes;
176     }
177 
178     switch (length_bytes) {
179     case 1:
180         byte = length;
181         build_prepend_byte(package, byte);
182         return;
183     case 4:
184         byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
185         build_prepend_byte(package, byte);
186         length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
187         /* fall through */
188     case 3:
189         byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
190         build_prepend_byte(package, byte);
191         length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
192         /* fall through */
193     case 2:
194         byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
195         build_prepend_byte(package, byte);
196         length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
197         /* fall through */
198     }
199     /*
200      * Most significant two bits of byte zero indicate how many following bytes
201      * are in PkgLength encoding.
202      */
203     byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
204     build_prepend_byte(package, byte);
205 }
206 
207 static void
208 build_append_pkg_length(GArray *array, unsigned length, bool incl_self)
209 {
210     GArray *tmp = build_alloc_array();
211 
212     build_prepend_package_length(tmp, length, incl_self);
213     build_append_array(array, tmp);
214     build_free_array(tmp);
215 }
216 
217 static void build_package(GArray *package, uint8_t op)
218 {
219     build_prepend_package_length(package, package->len, true);
220     build_prepend_byte(package, op);
221 }
222 
223 static void build_extop_package(GArray *package, uint8_t op)
224 {
225     build_package(package, op);
226     build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
227 }
228 
229 static void build_append_int_noprefix(GArray *table, uint64_t value, int size)
230 {
231     int i;
232 
233     for (i = 0; i < size; ++i) {
234         build_append_byte(table, value & 0xFF);
235         value = value >> 8;
236     }
237 }
238 
239 static void build_append_int(GArray *table, uint64_t value)
240 {
241     if (value == 0x00) {
242         build_append_byte(table, 0x00); /* ZeroOp */
243     } else if (value == 0x01) {
244         build_append_byte(table, 0x01); /* OneOp */
245     } else if (value <= 0xFF) {
246         build_append_byte(table, 0x0A); /* BytePrefix */
247         build_append_int_noprefix(table, value, 1);
248     } else if (value <= 0xFFFF) {
249         build_append_byte(table, 0x0B); /* WordPrefix */
250         build_append_int_noprefix(table, value, 2);
251     } else if (value <= 0xFFFFFFFF) {
252         build_append_byte(table, 0x0C); /* DWordPrefix */
253         build_append_int_noprefix(table, value, 4);
254     } else {
255         build_append_byte(table, 0x0E); /* QWordPrefix */
256         build_append_int_noprefix(table, value, 8);
257     }
258 }
259 
260 /*
261  * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword,
262  * and return the offset to 0x00000000 for runtime patching.
263  *
264  * Warning: runtime patching is best avoided. Only use this as
265  * a replacement for DataTableRegion (for guests that don't
266  * support it).
267  */
268 int
269 build_append_named_dword(GArray *array, const char *name_format, ...)
270 {
271     int offset;
272     va_list ap;
273 
274     build_append_byte(array, 0x08); /* NameOp */
275     va_start(ap, name_format);
276     build_append_namestringv(array, name_format, ap);
277     va_end(ap);
278 
279     build_append_byte(array, 0x0C); /* DWordPrefix */
280 
281     offset = array->len;
282     build_append_int_noprefix(array, 0x00000000, 4);
283     assert(array->len == offset + 4);
284 
285     return offset;
286 }
287 
288 static GPtrArray *alloc_list;
289 
290 static Aml *aml_alloc(void)
291 {
292     Aml *var = g_new0(typeof(*var), 1);
293 
294     g_ptr_array_add(alloc_list, var);
295     var->block_flags = AML_NO_OPCODE;
296     var->buf = build_alloc_array();
297     return var;
298 }
299 
300 static Aml *aml_opcode(uint8_t op)
301 {
302     Aml *var = aml_alloc();
303 
304     var->op  = op;
305     var->block_flags = AML_OPCODE;
306     return var;
307 }
308 
309 static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags)
310 {
311     Aml *var = aml_alloc();
312 
313     var->op  = op;
314     var->block_flags = flags;
315     return var;
316 }
317 
318 static void aml_free(gpointer data, gpointer user_data)
319 {
320     Aml *var = data;
321     build_free_array(var->buf);
322     g_free(var);
323 }
324 
325 Aml *init_aml_allocator(void)
326 {
327     Aml *var;
328 
329     assert(!alloc_list);
330     alloc_list = g_ptr_array_new();
331     var = aml_alloc();
332     return var;
333 }
334 
335 void free_aml_allocator(void)
336 {
337     g_ptr_array_foreach(alloc_list, aml_free, NULL);
338     g_ptr_array_free(alloc_list, true);
339     alloc_list = 0;
340 }
341 
342 /* pack data with DefBuffer encoding */
343 static void build_buffer(GArray *array, uint8_t op)
344 {
345     GArray *data = build_alloc_array();
346 
347     build_append_int(data, array->len);
348     g_array_prepend_vals(array, data->data, data->len);
349     build_free_array(data);
350     build_package(array, op);
351 }
352 
353 void aml_append(Aml *parent_ctx, Aml *child)
354 {
355     GArray *buf = build_alloc_array();
356     build_append_array(buf, child->buf);
357 
358     switch (child->block_flags) {
359     case AML_OPCODE:
360         build_append_byte(parent_ctx->buf, child->op);
361         break;
362     case AML_EXT_PACKAGE:
363         build_extop_package(buf, child->op);
364         break;
365     case AML_PACKAGE:
366         build_package(buf, child->op);
367         break;
368     case AML_RES_TEMPLATE:
369         build_append_byte(buf, 0x79); /* EndTag */
370         /*
371          * checksum operations are treated as succeeded if checksum
372          * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
373          */
374         build_append_byte(buf, 0);
375         /* fall through, to pack resources in buffer */
376     case AML_BUFFER:
377         build_buffer(buf, child->op);
378         break;
379     case AML_NO_OPCODE:
380         break;
381     default:
382         assert(0);
383         break;
384     }
385     build_append_array(parent_ctx->buf, buf);
386     build_free_array(buf);
387 }
388 
389 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */
390 Aml *aml_scope(const char *name_format, ...)
391 {
392     va_list ap;
393     Aml *var = aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE);
394     va_start(ap, name_format);
395     build_append_namestringv(var->buf, name_format, ap);
396     va_end(ap);
397     return var;
398 }
399 
400 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */
401 Aml *aml_return(Aml *val)
402 {
403     Aml *var = aml_opcode(0xA4 /* ReturnOp */);
404     aml_append(var, val);
405     return var;
406 }
407 
408 /* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */
409 Aml *aml_debug(void)
410 {
411     Aml *var = aml_alloc();
412     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
413     build_append_byte(var->buf, 0x31); /* DebugOp */
414     return var;
415 }
416 
417 /*
418  * ACPI 1.0b: 16.2.3 Data Objects Encoding:
419  * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
420  */
421 Aml *aml_int(const uint64_t val)
422 {
423     Aml *var = aml_alloc();
424     build_append_int(var->buf, val);
425     return var;
426 }
427 
428 /*
429  * helper to construct NameString, which returns Aml object
430  * for using with aml_append or other aml_* terms
431  */
432 Aml *aml_name(const char *name_format, ...)
433 {
434     va_list ap;
435     Aml *var = aml_alloc();
436     va_start(ap, name_format);
437     build_append_namestringv(var->buf, name_format, ap);
438     va_end(ap);
439     return var;
440 }
441 
442 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */
443 Aml *aml_name_decl(const char *name, Aml *val)
444 {
445     Aml *var = aml_opcode(0x08 /* NameOp */);
446     build_append_namestring(var->buf, "%s", name);
447     aml_append(var, val);
448     return var;
449 }
450 
451 /* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
452 Aml *aml_arg(int pos)
453 {
454     Aml *var;
455     uint8_t op = 0x68 /* ARG0 op */ + pos;
456 
457     assert(pos <= 6);
458     var = aml_opcode(op);
459     return var;
460 }
461 
462 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToInteger */
463 Aml *aml_to_integer(Aml *arg)
464 {
465     Aml *var = aml_opcode(0x99 /* ToIntegerOp */);
466     aml_append(var, arg);
467     build_append_byte(var->buf, 0x00 /* NullNameOp */);
468     return var;
469 }
470 
471 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToHexString */
472 Aml *aml_to_hexstring(Aml *src, Aml *dst)
473 {
474     Aml *var = aml_opcode(0x98 /* ToHexStringOp */);
475     aml_append(var, src);
476     if (dst) {
477         aml_append(var, dst);
478     } else {
479         build_append_byte(var->buf, 0x00 /* NullNameOp */);
480     }
481     return var;
482 }
483 
484 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToBuffer */
485 Aml *aml_to_buffer(Aml *src, Aml *dst)
486 {
487     Aml *var = aml_opcode(0x96 /* ToBufferOp */);
488     aml_append(var, src);
489     if (dst) {
490         aml_append(var, dst);
491     } else {
492         build_append_byte(var->buf, 0x00 /* NullNameOp */);
493     }
494     return var;
495 }
496 
497 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
498 Aml *aml_store(Aml *val, Aml *target)
499 {
500     Aml *var = aml_opcode(0x70 /* StoreOp */);
501     aml_append(var, val);
502     aml_append(var, target);
503     return var;
504 }
505 
506 /**
507  * build_opcode_2arg_dst:
508  * @op: 1-byte opcode
509  * @arg1: 1st operand
510  * @arg2: 2nd operand
511  * @dst: optional target to store to, set to NULL if it's not required
512  *
513  * An internal helper to compose AML terms that have
514  *   "Op Operand Operand Target"
515  * pattern.
516  *
517  * Returns: The newly allocated and composed according to patter Aml object.
518  */
519 static Aml *
520 build_opcode_2arg_dst(uint8_t op, Aml *arg1, Aml *arg2, Aml *dst)
521 {
522     Aml *var = aml_opcode(op);
523     aml_append(var, arg1);
524     aml_append(var, arg2);
525     if (dst) {
526         aml_append(var, dst);
527     } else {
528         build_append_byte(var->buf, 0x00 /* NullNameOp */);
529     }
530     return var;
531 }
532 
533 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
534 Aml *aml_and(Aml *arg1, Aml *arg2, Aml *dst)
535 {
536     return build_opcode_2arg_dst(0x7B /* AndOp */, arg1, arg2, dst);
537 }
538 
539 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
540 Aml *aml_or(Aml *arg1, Aml *arg2, Aml *dst)
541 {
542     return build_opcode_2arg_dst(0x7D /* OrOp */, arg1, arg2, dst);
543 }
544 
545 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLOr */
546 Aml *aml_lor(Aml *arg1, Aml *arg2)
547 {
548     Aml *var = aml_opcode(0x91 /* LOrOp */);
549     aml_append(var, arg1);
550     aml_append(var, arg2);
551     return var;
552 }
553 
554 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftLeft */
555 Aml *aml_shiftleft(Aml *arg1, Aml *count)
556 {
557     return build_opcode_2arg_dst(0x79 /* ShiftLeftOp */, arg1, count, NULL);
558 }
559 
560 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftRight */
561 Aml *aml_shiftright(Aml *arg1, Aml *count, Aml *dst)
562 {
563     return build_opcode_2arg_dst(0x7A /* ShiftRightOp */, arg1, count, dst);
564 }
565 
566 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
567 Aml *aml_lless(Aml *arg1, Aml *arg2)
568 {
569     Aml *var = aml_opcode(0x95 /* LLessOp */);
570     aml_append(var, arg1);
571     aml_append(var, arg2);
572     return var;
573 }
574 
575 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */
576 Aml *aml_add(Aml *arg1, Aml *arg2, Aml *dst)
577 {
578     return build_opcode_2arg_dst(0x72 /* AddOp */, arg1, arg2, dst);
579 }
580 
581 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSubtract */
582 Aml *aml_subtract(Aml *arg1, Aml *arg2, Aml *dst)
583 {
584     return build_opcode_2arg_dst(0x74 /* SubtractOp */, arg1, arg2, dst);
585 }
586 
587 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIncrement */
588 Aml *aml_increment(Aml *arg)
589 {
590     Aml *var = aml_opcode(0x75 /* IncrementOp */);
591     aml_append(var, arg);
592     return var;
593 }
594 
595 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDecrement */
596 Aml *aml_decrement(Aml *arg)
597 {
598     Aml *var = aml_opcode(0x76 /* DecrementOp */);
599     aml_append(var, arg);
600     return var;
601 }
602 
603 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */
604 Aml *aml_index(Aml *arg1, Aml *idx)
605 {
606     return build_opcode_2arg_dst(0x88 /* IndexOp */, arg1, idx, NULL);
607 }
608 
609 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
610 Aml *aml_notify(Aml *arg1, Aml *arg2)
611 {
612     Aml *var = aml_opcode(0x86 /* NotifyOp */);
613     aml_append(var, arg1);
614     aml_append(var, arg2);
615     return var;
616 }
617 
618 /* helper to call method with 1 argument */
619 Aml *aml_call0(const char *method)
620 {
621     Aml *var = aml_alloc();
622     build_append_namestring(var->buf, "%s", method);
623     return var;
624 }
625 
626 /* helper to call method with 1 argument */
627 Aml *aml_call1(const char *method, Aml *arg1)
628 {
629     Aml *var = aml_alloc();
630     build_append_namestring(var->buf, "%s", method);
631     aml_append(var, arg1);
632     return var;
633 }
634 
635 /* helper to call method with 2 arguments */
636 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2)
637 {
638     Aml *var = aml_alloc();
639     build_append_namestring(var->buf, "%s", method);
640     aml_append(var, arg1);
641     aml_append(var, arg2);
642     return var;
643 }
644 
645 /* helper to call method with 3 arguments */
646 Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3)
647 {
648     Aml *var = aml_alloc();
649     build_append_namestring(var->buf, "%s", method);
650     aml_append(var, arg1);
651     aml_append(var, arg2);
652     aml_append(var, arg3);
653     return var;
654 }
655 
656 /* helper to call method with 4 arguments */
657 Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
658 {
659     Aml *var = aml_alloc();
660     build_append_namestring(var->buf, "%s", method);
661     aml_append(var, arg1);
662     aml_append(var, arg2);
663     aml_append(var, arg3);
664     aml_append(var, arg4);
665     return var;
666 }
667 
668 /*
669  * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
670  * Type 1, Large Item Name 0xC
671  */
672 
673 static Aml *aml_gpio_connection(AmlGpioConnectionType type,
674                                 AmlConsumerAndProducer con_and_pro,
675                                 uint8_t flags, AmlPinConfig pin_config,
676                                 uint16_t output_drive,
677                                 uint16_t debounce_timeout,
678                                 const uint32_t pin_list[], uint32_t pin_count,
679                                 const char *resource_source_name,
680                                 const uint8_t *vendor_data,
681                                 uint16_t vendor_data_len)
682 {
683     Aml *var = aml_alloc();
684     const uint16_t min_desc_len = 0x16;
685     uint16_t resource_source_name_len, length;
686     uint16_t pin_table_offset, resource_source_name_offset, vendor_data_offset;
687     uint32_t i;
688 
689     assert(resource_source_name);
690     resource_source_name_len = strlen(resource_source_name) + 1;
691     length = min_desc_len + resource_source_name_len + vendor_data_len;
692     pin_table_offset = min_desc_len + 1;
693     resource_source_name_offset = pin_table_offset + pin_count * 2;
694     vendor_data_offset = resource_source_name_offset + resource_source_name_len;
695 
696     build_append_byte(var->buf, 0x8C);  /* GPIO Connection Descriptor */
697     build_append_int_noprefix(var->buf, length, 2); /* Length */
698     build_append_byte(var->buf, 1);     /* Revision ID */
699     build_append_byte(var->buf, type);  /* GPIO Connection Type */
700     /* General Flags (2 bytes) */
701     build_append_int_noprefix(var->buf, con_and_pro, 2);
702     /* Interrupt and IO Flags (2 bytes) */
703     build_append_int_noprefix(var->buf, flags, 2);
704     /* Pin Configuration 0 = Default 1 = Pull-up 2 = Pull-down 3 = No Pull */
705     build_append_byte(var->buf, pin_config);
706     /* Output Drive Strength (2 bytes) */
707     build_append_int_noprefix(var->buf, output_drive, 2);
708     /* Debounce Timeout (2 bytes) */
709     build_append_int_noprefix(var->buf, debounce_timeout, 2);
710     /* Pin Table Offset (2 bytes) */
711     build_append_int_noprefix(var->buf, pin_table_offset, 2);
712     build_append_byte(var->buf, 0);     /* Resource Source Index */
713     /* Resource Source Name Offset (2 bytes) */
714     build_append_int_noprefix(var->buf, resource_source_name_offset, 2);
715     /* Vendor Data Offset (2 bytes) */
716     build_append_int_noprefix(var->buf, vendor_data_offset, 2);
717     /* Vendor Data Length (2 bytes) */
718     build_append_int_noprefix(var->buf, vendor_data_len, 2);
719     /* Pin Number (2n bytes)*/
720     for (i = 0; i < pin_count; i++) {
721         build_append_int_noprefix(var->buf, pin_list[i], 2);
722     }
723 
724     /* Resource Source Name */
725     build_append_namestring(var->buf, "%s", resource_source_name);
726     build_append_byte(var->buf, '\0');
727 
728     /* Vendor-defined Data */
729     if (vendor_data != NULL) {
730         g_array_append_vals(var->buf, vendor_data, vendor_data_len);
731     }
732 
733     return var;
734 }
735 
736 /*
737  * ACPI 5.0: 19.5.53
738  * GpioInt(GPIO Interrupt Connection Resource Descriptor Macro)
739  */
740 Aml *aml_gpio_int(AmlConsumerAndProducer con_and_pro,
741                   AmlLevelAndEdge edge_level,
742                   AmlActiveHighAndLow active_level, AmlShared shared,
743                   AmlPinConfig pin_config, uint16_t debounce_timeout,
744                   const uint32_t pin_list[], uint32_t pin_count,
745                   const char *resource_source_name,
746                   const uint8_t *vendor_data, uint16_t vendor_data_len)
747 {
748     uint8_t flags = edge_level | (active_level << 1) | (shared << 3);
749 
750     return aml_gpio_connection(AML_INTERRUPT_CONNECTION, con_and_pro, flags,
751                                pin_config, 0, debounce_timeout, pin_list,
752                                pin_count, resource_source_name, vendor_data,
753                                vendor_data_len);
754 }
755 
756 /*
757  * ACPI 1.0b: 6.4.3.4 32-Bit Fixed Location Memory Range Descriptor
758  * (Type 1, Large Item Name 0x6)
759  */
760 Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
761                         AmlReadAndWrite read_and_write)
762 {
763     Aml *var = aml_alloc();
764     build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */
765     build_append_byte(var->buf, 9);    /* Length, bits[7:0] value = 9 */
766     build_append_byte(var->buf, 0);    /* Length, bits[15:8] value = 0 */
767     build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */
768 
769     /* Range base address */
770     build_append_byte(var->buf, extract32(addr, 0, 8));  /* bits[7:0] */
771     build_append_byte(var->buf, extract32(addr, 8, 8));  /* bits[15:8] */
772     build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */
773     build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */
774 
775     /* Range length */
776     build_append_byte(var->buf, extract32(size, 0, 8));  /* bits[7:0] */
777     build_append_byte(var->buf, extract32(size, 8, 8));  /* bits[15:8] */
778     build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */
779     build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */
780     return var;
781 }
782 
783 /*
784  * ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor
785  * Type 1, Large Item Name 0x9
786  */
787 Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
788                    AmlLevelAndEdge level_and_edge,
789                    AmlActiveHighAndLow high_and_low, AmlShared shared,
790                    uint32_t *irq_list, uint8_t irq_count)
791 {
792     int i;
793     Aml *var = aml_alloc();
794     uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
795                         | (high_and_low << 2) | (shared << 3);
796     const int header_bytes_in_len = 2;
797     uint16_t len = header_bytes_in_len + irq_count * sizeof(uint32_t);
798 
799     assert(irq_count > 0);
800 
801     build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
802     build_append_byte(var->buf, len & 0xFF); /* Length, bits[7:0] */
803     build_append_byte(var->buf, len >> 8); /* Length, bits[15:8] */
804     build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
805     build_append_byte(var->buf, irq_count);   /* Interrupt table length */
806 
807     /* Interrupt Number List */
808     for (i = 0; i < irq_count; i++) {
809         build_append_int_noprefix(var->buf, irq_list[i], 4);
810     }
811     return var;
812 }
813 
814 /* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
815 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
816             uint8_t aln, uint8_t len)
817 {
818     Aml *var = aml_alloc();
819     build_append_byte(var->buf, 0x47); /* IO port descriptor */
820     build_append_byte(var->buf, dec);
821     build_append_byte(var->buf, min_base & 0xff);
822     build_append_byte(var->buf, (min_base >> 8) & 0xff);
823     build_append_byte(var->buf, max_base & 0xff);
824     build_append_byte(var->buf, (max_base >> 8) & 0xff);
825     build_append_byte(var->buf, aln);
826     build_append_byte(var->buf, len);
827     return var;
828 }
829 
830 /*
831  * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
832  *
833  * More verbose description at:
834  * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
835  *           6.4.2.1 IRQ Descriptor
836  */
837 Aml *aml_irq_no_flags(uint8_t irq)
838 {
839     uint16_t irq_mask;
840     Aml *var = aml_alloc();
841 
842     assert(irq < 16);
843     build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
844 
845     irq_mask = 1U << irq;
846     build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
847     build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
848     return var;
849 }
850 
851 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
852 Aml *aml_lnot(Aml *arg)
853 {
854     Aml *var = aml_opcode(0x92 /* LNotOp */);
855     aml_append(var, arg);
856     return var;
857 }
858 
859 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
860 Aml *aml_equal(Aml *arg1, Aml *arg2)
861 {
862     Aml *var = aml_opcode(0x93 /* LequalOp */);
863     aml_append(var, arg1);
864     aml_append(var, arg2);
865     return var;
866 }
867 
868 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreater */
869 Aml *aml_lgreater(Aml *arg1, Aml *arg2)
870 {
871     Aml *var = aml_opcode(0x94 /* LGreaterOp */);
872     aml_append(var, arg1);
873     aml_append(var, arg2);
874     return var;
875 }
876 
877 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreaterEqual */
878 Aml *aml_lgreater_equal(Aml *arg1, Aml *arg2)
879 {
880     /* LGreaterEqualOp := LNotOp LLessOp */
881     Aml *var = aml_opcode(0x92 /* LNotOp */);
882     build_append_byte(var->buf, 0x95 /* LLessOp */);
883     aml_append(var, arg1);
884     aml_append(var, arg2);
885     return var;
886 }
887 
888 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
889 Aml *aml_if(Aml *predicate)
890 {
891     Aml *var = aml_bundle(0xA0 /* IfOp */, AML_PACKAGE);
892     aml_append(var, predicate);
893     return var;
894 }
895 
896 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */
897 Aml *aml_else(void)
898 {
899     Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
900     return var;
901 }
902 
903 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefWhile */
904 Aml *aml_while(Aml *predicate)
905 {
906     Aml *var = aml_bundle(0xA2 /* WhileOp */, AML_PACKAGE);
907     aml_append(var, predicate);
908     return var;
909 }
910 
911 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
912 Aml *aml_method(const char *name, int arg_count, AmlSerializeFlag sflag)
913 {
914     Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
915     int methodflags;
916 
917     /*
918      * MethodFlags:
919      *   bit 0-2: ArgCount (0-7)
920      *   bit 3: SerializeFlag
921      *     0: NotSerialized
922      *     1: Serialized
923      *   bit 4-7: reserved (must be 0)
924      */
925     assert(arg_count < 8);
926     methodflags = arg_count | (sflag << 3);
927 
928     build_append_namestring(var->buf, "%s", name);
929     build_append_byte(var->buf, methodflags); /* MethodFlags: ArgCount */
930     return var;
931 }
932 
933 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
934 Aml *aml_device(const char *name_format, ...)
935 {
936     va_list ap;
937     Aml *var = aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE);
938     va_start(ap, name_format);
939     build_append_namestringv(var->buf, name_format, ap);
940     va_end(ap);
941     return var;
942 }
943 
944 /* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */
945 Aml *aml_resource_template(void)
946 {
947     /* ResourceTemplate is a buffer of Resources with EndTag at the end */
948     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE);
949     return var;
950 }
951 
952 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer
953  * Pass byte_list as NULL to request uninitialized buffer to reserve space.
954  */
955 Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
956 {
957     int i;
958     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
959 
960     for (i = 0; i < buffer_size; i++) {
961         if (byte_list == NULL) {
962             build_append_byte(var->buf, 0x0);
963         } else {
964             build_append_byte(var->buf, byte_list[i]);
965         }
966     }
967 
968     return var;
969 }
970 
971 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */
972 Aml *aml_package(uint8_t num_elements)
973 {
974     Aml *var = aml_bundle(0x12 /* PackageOp */, AML_PACKAGE);
975     build_append_byte(var->buf, num_elements);
976     return var;
977 }
978 
979 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
980 Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
981                           Aml *offset, uint32_t len)
982 {
983     Aml *var = aml_alloc();
984     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
985     build_append_byte(var->buf, 0x80); /* OpRegionOp */
986     build_append_namestring(var->buf, "%s", name);
987     build_append_byte(var->buf, rs);
988     aml_append(var, offset);
989     build_append_int(var->buf, len);
990     return var;
991 }
992 
993 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */
994 Aml *aml_named_field(const char *name, unsigned length)
995 {
996     Aml *var = aml_alloc();
997     build_append_nameseg(var->buf, name);
998     build_append_pkg_length(var->buf, length, false);
999     return var;
1000 }
1001 
1002 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
1003 Aml *aml_reserved_field(unsigned length)
1004 {
1005     Aml *var = aml_alloc();
1006     /* ReservedField  := 0x00 PkgLength */
1007     build_append_byte(var->buf, 0x00);
1008     build_append_pkg_length(var->buf, length, false);
1009     return var;
1010 }
1011 
1012 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
1013 Aml *aml_field(const char *name, AmlAccessType type, AmlLockRule lock,
1014                AmlUpdateRule rule)
1015 {
1016     Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
1017     uint8_t flags = rule << 5 | type;
1018 
1019     flags |= lock << 4; /* LockRule at 4 bit offset */
1020 
1021     build_append_namestring(var->buf, "%s", name);
1022     build_append_byte(var->buf, flags);
1023     return var;
1024 }
1025 
1026 static
1027 Aml *create_field_common(int opcode, Aml *srcbuf, Aml *index, const char *name)
1028 {
1029     Aml *var = aml_opcode(opcode);
1030     aml_append(var, srcbuf);
1031     aml_append(var, index);
1032     build_append_namestring(var->buf, "%s", name);
1033     return var;
1034 }
1035 
1036 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
1037 Aml *aml_create_field(Aml *srcbuf, Aml *bit_index, Aml *num_bits,
1038                       const char *name)
1039 {
1040     Aml *var = aml_alloc();
1041     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1042     build_append_byte(var->buf, 0x13); /* CreateFieldOp */
1043     aml_append(var, srcbuf);
1044     aml_append(var, bit_index);
1045     aml_append(var, num_bits);
1046     build_append_namestring(var->buf, "%s", name);
1047     return var;
1048 }
1049 
1050 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
1051 Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
1052 {
1053     return create_field_common(0x8A /* CreateDWordFieldOp */,
1054                                srcbuf, index, name);
1055 }
1056 
1057 /* ACPI 2.0a: 17.2.4.2 Named Objects Encoding: DefCreateQWordField */
1058 Aml *aml_create_qword_field(Aml *srcbuf, Aml *index, const char *name)
1059 {
1060     return create_field_common(0x8F /* CreateQWordFieldOp */,
1061                                srcbuf, index, name);
1062 }
1063 
1064 /* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
1065 Aml *aml_string(const char *name_format, ...)
1066 {
1067     Aml *var = aml_opcode(0x0D /* StringPrefix */);
1068     va_list ap;
1069     char *s;
1070     int len;
1071 
1072     va_start(ap, name_format);
1073     len = g_vasprintf(&s, name_format, ap);
1074     va_end(ap);
1075 
1076     g_array_append_vals(var->buf, s, len + 1);
1077     g_free(s);
1078 
1079     return var;
1080 }
1081 
1082 /* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
1083 Aml *aml_local(int num)
1084 {
1085     Aml *var;
1086     uint8_t op = 0x60 /* Local0Op */ + num;
1087 
1088     assert(num <= 7);
1089     var = aml_opcode(op);
1090     return var;
1091 }
1092 
1093 /* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
1094 Aml *aml_varpackage(uint32_t num_elements)
1095 {
1096     Aml *var = aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE);
1097     build_append_int(var->buf, num_elements);
1098     return var;
1099 }
1100 
1101 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
1102 Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
1103                    const char *name_format, ...)
1104 {
1105     va_list ap;
1106     Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE);
1107     va_start(ap, name_format);
1108     build_append_namestringv(var->buf, name_format, ap);
1109     va_end(ap);
1110     build_append_byte(var->buf, proc_id); /* ProcID */
1111     build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr));
1112     build_append_byte(var->buf, pblk_len); /* PblkLen */
1113     return var;
1114 }
1115 
1116 static uint8_t Hex2Digit(char c)
1117 {
1118     if (c >= 'A') {
1119         return c - 'A' + 10;
1120     }
1121 
1122     return c - '0';
1123 }
1124 
1125 /* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */
1126 Aml *aml_eisaid(const char *str)
1127 {
1128     Aml *var = aml_alloc();
1129     uint32_t id;
1130 
1131     g_assert(strlen(str) == 7);
1132     id = (str[0] - 0x40) << 26 |
1133     (str[1] - 0x40) << 21 |
1134     (str[2] - 0x40) << 16 |
1135     Hex2Digit(str[3]) << 12 |
1136     Hex2Digit(str[4]) << 8 |
1137     Hex2Digit(str[5]) << 4 |
1138     Hex2Digit(str[6]);
1139 
1140     build_append_byte(var->buf, 0x0C); /* DWordPrefix */
1141     build_append_int_noprefix(var->buf, bswap32(id), sizeof(id));
1142     return var;
1143 }
1144 
1145 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
1146 static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed,
1147                                AmlMaxFixed max_fixed, AmlDecode dec,
1148                                uint8_t type_flags)
1149 {
1150     uint8_t flags = max_fixed | min_fixed | dec;
1151     Aml *var = aml_alloc();
1152 
1153     build_append_byte(var->buf, type);
1154     build_append_byte(var->buf, flags);
1155     build_append_byte(var->buf, type_flags); /* Type Specific Flags */
1156     return var;
1157 }
1158 
1159 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */
1160 static Aml *aml_word_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1161                              AmlMaxFixed max_fixed, AmlDecode dec,
1162                              uint16_t addr_gran, uint16_t addr_min,
1163                              uint16_t addr_max, uint16_t addr_trans,
1164                              uint16_t len, uint8_t type_flags)
1165 {
1166     Aml *var = aml_alloc();
1167 
1168     build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
1169     /* minimum length since we do not encode optional fields */
1170     build_append_byte(var->buf, 0x0D);
1171     build_append_byte(var->buf, 0x0);
1172 
1173     aml_append(var,
1174         aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1175     build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1176     build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1177     build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1178     build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1179     build_append_int_noprefix(var->buf, len, sizeof(len));
1180     return var;
1181 }
1182 
1183 /* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */
1184 static Aml *aml_dword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1185                               AmlMaxFixed max_fixed, AmlDecode dec,
1186                               uint32_t addr_gran, uint32_t addr_min,
1187                               uint32_t addr_max, uint32_t addr_trans,
1188                               uint32_t len, uint8_t type_flags)
1189 {
1190     Aml *var = aml_alloc();
1191 
1192     build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
1193     /* minimum length since we do not encode optional fields */
1194     build_append_byte(var->buf, 23);
1195     build_append_byte(var->buf, 0x0);
1196 
1197 
1198     aml_append(var,
1199         aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1200     build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1201     build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1202     build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1203     build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1204     build_append_int_noprefix(var->buf, len, sizeof(len));
1205     return var;
1206 }
1207 
1208 /* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */
1209 static Aml *aml_qword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1210                               AmlMaxFixed max_fixed, AmlDecode dec,
1211                               uint64_t addr_gran, uint64_t addr_min,
1212                               uint64_t addr_max, uint64_t addr_trans,
1213                               uint64_t len, uint8_t type_flags)
1214 {
1215     Aml *var = aml_alloc();
1216 
1217     build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
1218     /* minimum length since we do not encode optional fields */
1219     build_append_byte(var->buf, 0x2B);
1220     build_append_byte(var->buf, 0x0);
1221 
1222     aml_append(var,
1223         aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1224     build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1225     build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1226     build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1227     build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1228     build_append_int_noprefix(var->buf, len, sizeof(len));
1229     return var;
1230 }
1231 
1232 /*
1233  * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
1234  *
1235  * More verbose description at:
1236  * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
1237  */
1238 Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1239                          AmlDecode dec, uint16_t addr_gran,
1240                          uint16_t addr_min, uint16_t addr_max,
1241                          uint16_t addr_trans, uint16_t len)
1242 
1243 {
1244     return aml_word_as_desc(AML_BUS_NUMBER_RANGE, min_fixed, max_fixed, dec,
1245                             addr_gran, addr_min, addr_max, addr_trans, len, 0);
1246 }
1247 
1248 /*
1249  * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
1250  *
1251  * More verbose description at:
1252  * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro)
1253  */
1254 Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1255                  AmlDecode dec, AmlISARanges isa_ranges,
1256                  uint16_t addr_gran, uint16_t addr_min,
1257                  uint16_t addr_max, uint16_t addr_trans,
1258                  uint16_t len)
1259 
1260 {
1261     return aml_word_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
1262                             addr_gran, addr_min, addr_max, addr_trans, len,
1263                             isa_ranges);
1264 }
1265 
1266 /*
1267  * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor
1268  *
1269  * More verbose description at:
1270  * ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro)
1271  */
1272 Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1273                  AmlDecode dec, AmlISARanges isa_ranges,
1274                  uint32_t addr_gran, uint32_t addr_min,
1275                  uint32_t addr_max, uint32_t addr_trans,
1276                  uint32_t len)
1277 
1278 {
1279     return aml_dword_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
1280                             addr_gran, addr_min, addr_max, addr_trans, len,
1281                             isa_ranges);
1282 }
1283 
1284 /*
1285  * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
1286  *
1287  * More verbose description at:
1288  * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
1289  */
1290 Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
1291                       AmlMaxFixed max_fixed, AmlCacheable cacheable,
1292                       AmlReadAndWrite read_and_write,
1293                       uint32_t addr_gran, uint32_t addr_min,
1294                       uint32_t addr_max, uint32_t addr_trans,
1295                       uint32_t len)
1296 {
1297     uint8_t flags = read_and_write | (cacheable << 1);
1298 
1299     return aml_dword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
1300                              dec, addr_gran, addr_min, addr_max,
1301                              addr_trans, len, flags);
1302 }
1303 
1304 /*
1305  * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor
1306  *
1307  * More verbose description at:
1308  * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
1309  */
1310 Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
1311                       AmlMaxFixed max_fixed, AmlCacheable cacheable,
1312                       AmlReadAndWrite read_and_write,
1313                       uint64_t addr_gran, uint64_t addr_min,
1314                       uint64_t addr_max, uint64_t addr_trans,
1315                       uint64_t len)
1316 {
1317     uint8_t flags = read_and_write | (cacheable << 1);
1318 
1319     return aml_qword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
1320                              dec, addr_gran, addr_min, addr_max,
1321                              addr_trans, len, flags);
1322 }
1323 
1324 /* ACPI 1.0b: 6.4.2.2 DMA Format/6.4.2.2.1 ASL Macro for DMA Descriptor */
1325 Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
1326              uint8_t channel)
1327 {
1328     Aml *var = aml_alloc();
1329     uint8_t flags = sz | bm << 2 | typ << 5;
1330 
1331     assert(channel < 8);
1332     build_append_byte(var->buf, 0x2A);    /* Byte 0: DMA Descriptor */
1333     build_append_byte(var->buf, 1U << channel); /* Byte 1: _DMA - DmaChannel */
1334     build_append_byte(var->buf, flags);   /* Byte 2 */
1335     return var;
1336 }
1337 
1338 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefSleep */
1339 Aml *aml_sleep(uint64_t msec)
1340 {
1341     Aml *var = aml_alloc();
1342     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1343     build_append_byte(var->buf, 0x22); /* SleepOp */
1344     aml_append(var, aml_int(msec));
1345     return var;
1346 }
1347 
1348 static uint8_t Hex2Byte(const char *src)
1349 {
1350     int hi, lo;
1351 
1352     hi = Hex2Digit(src[0]);
1353     assert(hi >= 0);
1354     assert(hi <= 15);
1355 
1356     lo = Hex2Digit(src[1]);
1357     assert(lo >= 0);
1358     assert(lo <= 15);
1359     return (hi << 4) | lo;
1360 }
1361 
1362 /*
1363  * ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro)
1364  * e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1365  * call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
1366  */
1367 Aml *aml_touuid(const char *uuid)
1368 {
1369     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1370 
1371     assert(strlen(uuid) == 36);
1372     assert(uuid[8] == '-');
1373     assert(uuid[13] == '-');
1374     assert(uuid[18] == '-');
1375     assert(uuid[23] == '-');
1376 
1377     build_append_byte(var->buf, Hex2Byte(uuid + 6));  /* dd - at offset 00 */
1378     build_append_byte(var->buf, Hex2Byte(uuid + 4));  /* cc - at offset 01 */
1379     build_append_byte(var->buf, Hex2Byte(uuid + 2));  /* bb - at offset 02 */
1380     build_append_byte(var->buf, Hex2Byte(uuid + 0));  /* aa - at offset 03 */
1381 
1382     build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */
1383     build_append_byte(var->buf, Hex2Byte(uuid + 9));  /* ee - at offset 05 */
1384 
1385     build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */
1386     build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */
1387 
1388     build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */
1389     build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */
1390 
1391     build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */
1392     build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */
1393     build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */
1394     build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */
1395     build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */
1396     build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */
1397 
1398     return var;
1399 }
1400 
1401 /*
1402  * ACPI 2.0b: 16.2.3.6.4.3  Unicode Macro (Convert Ascii String To Unicode)
1403  */
1404 Aml *aml_unicode(const char *str)
1405 {
1406     int i = 0;
1407     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1408 
1409     do {
1410         build_append_byte(var->buf, str[i]);
1411         build_append_byte(var->buf, 0);
1412         i++;
1413     } while (i <= strlen(str));
1414 
1415     return var;
1416 }
1417 
1418 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */
1419 Aml *aml_refof(Aml *arg)
1420 {
1421     Aml *var = aml_opcode(0x71 /* RefOfOp */);
1422     aml_append(var, arg);
1423     return var;
1424 }
1425 
1426 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
1427 Aml *aml_derefof(Aml *arg)
1428 {
1429     Aml *var = aml_opcode(0x83 /* DerefOfOp */);
1430     aml_append(var, arg);
1431     return var;
1432 }
1433 
1434 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSizeOf */
1435 Aml *aml_sizeof(Aml *arg)
1436 {
1437     Aml *var = aml_opcode(0x87 /* SizeOfOp */);
1438     aml_append(var, arg);
1439     return var;
1440 }
1441 
1442 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMutex */
1443 Aml *aml_mutex(const char *name, uint8_t sync_level)
1444 {
1445     Aml *var = aml_alloc();
1446     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1447     build_append_byte(var->buf, 0x01); /* MutexOp */
1448     build_append_namestring(var->buf, "%s", name);
1449     assert(!(sync_level & 0xF0));
1450     build_append_byte(var->buf, sync_level);
1451     return var;
1452 }
1453 
1454 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAcquire */
1455 Aml *aml_acquire(Aml *mutex, uint16_t timeout)
1456 {
1457     Aml *var = aml_alloc();
1458     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1459     build_append_byte(var->buf, 0x23); /* AcquireOp */
1460     aml_append(var, mutex);
1461     build_append_int_noprefix(var->buf, timeout, sizeof(timeout));
1462     return var;
1463 }
1464 
1465 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefRelease */
1466 Aml *aml_release(Aml *mutex)
1467 {
1468     Aml *var = aml_alloc();
1469     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1470     build_append_byte(var->buf, 0x27); /* ReleaseOp */
1471     aml_append(var, mutex);
1472     return var;
1473 }
1474 
1475 /* ACPI 1.0b: 16.2.5.1 Name Space Modifier Objects Encoding: DefAlias */
1476 Aml *aml_alias(const char *source_object, const char *alias_object)
1477 {
1478     Aml *var = aml_opcode(0x06 /* AliasOp */);
1479     aml_append(var, aml_name("%s", source_object));
1480     aml_append(var, aml_name("%s", alias_object));
1481     return var;
1482 }
1483 
1484 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
1485 Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
1486 {
1487     return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
1488                                  target);
1489 }
1490 
1491 void
1492 build_header(BIOSLinker *linker, GArray *table_data,
1493              AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
1494              const char *oem_id, const char *oem_table_id)
1495 {
1496     unsigned tbl_offset = (char *)h - table_data->data;
1497     unsigned checksum_offset = (char *)&h->checksum - table_data->data;
1498     memcpy(&h->signature, sig, 4);
1499     h->length = cpu_to_le32(len);
1500     h->revision = rev;
1501 
1502     if (oem_id) {
1503         strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
1504     } else {
1505         memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
1506     }
1507 
1508     if (oem_table_id) {
1509         strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
1510     } else {
1511         memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
1512         memcpy(h->oem_table_id + 4, sig, 4);
1513     }
1514 
1515     h->oem_revision = cpu_to_le32(1);
1516     memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
1517     h->asl_compiler_revision = cpu_to_le32(1);
1518     /* Checksum to be filled in by Guest linker */
1519     bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
1520         tbl_offset, len, checksum_offset);
1521 }
1522 
1523 void *acpi_data_push(GArray *table_data, unsigned size)
1524 {
1525     unsigned off = table_data->len;
1526     g_array_set_size(table_data, off + size);
1527     return table_data->data + off;
1528 }
1529 
1530 unsigned acpi_data_len(GArray *table)
1531 {
1532     assert(g_array_get_element_size(table) == 1);
1533     return table->len;
1534 }
1535 
1536 void acpi_add_table(GArray *table_offsets, GArray *table_data)
1537 {
1538     uint32_t offset = table_data->len;
1539     g_array_append_val(table_offsets, offset);
1540 }
1541 
1542 void acpi_build_tables_init(AcpiBuildTables *tables)
1543 {
1544     tables->rsdp = g_array_new(false, true /* clear */, 1);
1545     tables->table_data = g_array_new(false, true /* clear */, 1);
1546     tables->tcpalog = g_array_new(false, true /* clear */, 1);
1547     tables->linker = bios_linker_loader_init();
1548 }
1549 
1550 void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
1551 {
1552     bios_linker_loader_cleanup(tables->linker);
1553     g_array_free(tables->rsdp, true);
1554     g_array_free(tables->table_data, true);
1555     g_array_free(tables->tcpalog, mfre);
1556 }
1557 
1558 /* Build rsdt table */
1559 void
1560 build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1561            const char *oem_id, const char *oem_table_id)
1562 {
1563     int i;
1564     unsigned rsdt_entries_offset;
1565     AcpiRsdtDescriptorRev1 *rsdt;
1566     const unsigned table_data_len = (sizeof(uint32_t) * table_offsets->len);
1567     const unsigned rsdt_entry_size = sizeof(rsdt->table_offset_entry[0]);
1568     const size_t rsdt_len = sizeof(*rsdt) + table_data_len;
1569 
1570     rsdt = acpi_data_push(table_data, rsdt_len);
1571     rsdt_entries_offset = (char *)rsdt->table_offset_entry - table_data->data;
1572     for (i = 0; i < table_offsets->len; ++i) {
1573         uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
1574         uint32_t rsdt_entry_offset = rsdt_entries_offset + rsdt_entry_size * i;
1575 
1576         /* rsdt->table_offset_entry to be filled by Guest linker */
1577         bios_linker_loader_add_pointer(linker,
1578             ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size,
1579             ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1580     }
1581     build_header(linker, table_data,
1582                  (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
1583 }
1584 
1585 void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
1586                        uint64_t len, int node, MemoryAffinityFlags flags)
1587 {
1588     numamem->type = ACPI_SRAT_MEMORY;
1589     numamem->length = sizeof(*numamem);
1590     numamem->proximity = cpu_to_le32(node);
1591     numamem->flags = cpu_to_le32(flags);
1592     numamem->base_addr = cpu_to_le64(base);
1593     numamem->range_length = cpu_to_le64(len);
1594 }
1595