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