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