xref: /openbmc/qemu/hw/acpi/aml-build.c (revision 761a9c58)
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 #include "hw/pci/pci_host.h"
31 #include "hw/pci/pci_bus.h"
32 #include "hw/pci/pci_bridge.h"
33 #include "qemu/cutils.h"
34 
35 static GArray *build_alloc_array(void)
36 {
37     return g_array_new(false, true /* clear */, 1);
38 }
39 
40 static void build_free_array(GArray *array)
41 {
42     g_array_free(array, true);
43 }
44 
45 static void build_prepend_byte(GArray *array, uint8_t val)
46 {
47     g_array_prepend_val(array, val);
48 }
49 
50 static void build_append_byte(GArray *array, uint8_t val)
51 {
52     g_array_append_val(array, val);
53 }
54 
55 static void build_append_padded_str(GArray *array, const char *str,
56                                     size_t maxlen, char pad)
57 {
58     size_t i;
59     size_t len = strlen(str);
60 
61     g_assert(len <= maxlen);
62     g_array_append_vals(array, str, len);
63     for (i = maxlen - len; i > 0; i--) {
64         g_array_append_val(array, pad);
65     }
66 }
67 
68 static void build_append_array(GArray *array, GArray *val)
69 {
70     g_array_append_vals(array, val->data, val->len);
71 }
72 
73 #define ACPI_NAMESEG_LEN 4
74 
75 void crs_range_insert(GPtrArray *ranges, uint64_t base, uint64_t limit)
76 {
77     CrsRangeEntry *entry;
78 
79     entry = g_malloc(sizeof(*entry));
80     entry->base = base;
81     entry->limit = limit;
82 
83     g_ptr_array_add(ranges, entry);
84 }
85 
86 static void crs_range_free(gpointer data)
87 {
88     CrsRangeEntry *entry = (CrsRangeEntry *)data;
89     g_free(entry);
90 }
91 
92 void crs_range_set_init(CrsRangeSet *range_set)
93 {
94     range_set->io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
95     range_set->mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
96     range_set->mem_64bit_ranges =
97             g_ptr_array_new_with_free_func(crs_range_free);
98 }
99 
100 void crs_range_set_free(CrsRangeSet *range_set)
101 {
102     g_ptr_array_free(range_set->io_ranges, true);
103     g_ptr_array_free(range_set->mem_ranges, true);
104     g_ptr_array_free(range_set->mem_64bit_ranges, true);
105 }
106 
107 static gint crs_range_compare(gconstpointer a, gconstpointer b)
108 {
109     CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
110     CrsRangeEntry *entry_b = *(CrsRangeEntry **)b;
111 
112     if (entry_a->base < entry_b->base) {
113         return -1;
114     } else if (entry_a->base > entry_b->base) {
115         return 1;
116     } else {
117         return 0;
118     }
119 }
120 
121 /*
122  * crs_replace_with_free_ranges - given the 'used' ranges within [start - end]
123  * interval, computes the 'free' ranges from the same interval.
124  * Example: If the input array is { [a1 - a2],[b1 - b2] }, the function
125  * will return { [base - a1], [a2 - b1], [b2 - limit] }.
126  */
127 void crs_replace_with_free_ranges(GPtrArray *ranges,
128                                   uint64_t start, uint64_t end)
129 {
130     GPtrArray *free_ranges = g_ptr_array_new();
131     uint64_t free_base = start;
132     int i;
133 
134     g_ptr_array_sort(ranges, crs_range_compare);
135     for (i = 0; i < ranges->len; i++) {
136         CrsRangeEntry *used = g_ptr_array_index(ranges, i);
137 
138         if (free_base < used->base) {
139             crs_range_insert(free_ranges, free_base, used->base - 1);
140         }
141 
142         free_base = used->limit + 1;
143     }
144 
145     if (free_base < end) {
146         crs_range_insert(free_ranges, free_base, end);
147     }
148 
149     g_ptr_array_set_size(ranges, 0);
150     for (i = 0; i < free_ranges->len; i++) {
151         g_ptr_array_add(ranges, g_ptr_array_index(free_ranges, i));
152     }
153 
154     g_ptr_array_free(free_ranges, true);
155 }
156 
157 /*
158  * crs_range_merge - merges adjacent ranges in the given array.
159  * Array elements are deleted and replaced with the merged ranges.
160  */
161 static void crs_range_merge(GPtrArray *range)
162 {
163     GPtrArray *tmp = g_ptr_array_new_with_free_func(crs_range_free);
164     CrsRangeEntry *entry;
165     uint64_t range_base, range_limit;
166     int i;
167 
168     if (!range->len) {
169         return;
170     }
171 
172     g_ptr_array_sort(range, crs_range_compare);
173 
174     entry = g_ptr_array_index(range, 0);
175     range_base = entry->base;
176     range_limit = entry->limit;
177     for (i = 1; i < range->len; i++) {
178         entry = g_ptr_array_index(range, i);
179         if (entry->base - 1 == range_limit) {
180             range_limit = entry->limit;
181         } else {
182             crs_range_insert(tmp, range_base, range_limit);
183             range_base = entry->base;
184             range_limit = entry->limit;
185         }
186     }
187     crs_range_insert(tmp, range_base, range_limit);
188 
189     g_ptr_array_set_size(range, 0);
190     for (i = 0; i < tmp->len; i++) {
191         entry = g_ptr_array_index(tmp, i);
192         crs_range_insert(range, entry->base, entry->limit);
193     }
194     g_ptr_array_free(tmp, true);
195 }
196 
197 static void
198 build_append_nameseg(GArray *array, const char *seg)
199 {
200     int len;
201 
202     len = strlen(seg);
203     assert(len <= ACPI_NAMESEG_LEN);
204 
205     g_array_append_vals(array, seg, len);
206     /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
207     g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
208 }
209 
210 static void G_GNUC_PRINTF(2, 0)
211 build_append_namestringv(GArray *array, const char *format, va_list ap)
212 {
213     char *s;
214     char **segs;
215     char **segs_iter;
216     int seg_count = 0;
217 
218     s = g_strdup_vprintf(format, ap);
219     segs = g_strsplit(s, ".", 0);
220     g_free(s);
221 
222     /* count segments */
223     segs_iter = segs;
224     while (*segs_iter) {
225         ++segs_iter;
226         ++seg_count;
227     }
228     /*
229      * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
230      * "SegCount can be from 1 to 255"
231      */
232     assert(seg_count > 0 && seg_count <= 255);
233 
234     /* handle RootPath || PrefixPath */
235     s = *segs;
236     while (*s == '\\' || *s == '^') {
237         build_append_byte(array, *s);
238         ++s;
239     }
240 
241     switch (seg_count) {
242     case 1:
243         if (!*s) {
244             build_append_byte(array, 0x00); /* NullName */
245         } else {
246             build_append_nameseg(array, s);
247         }
248         break;
249 
250     case 2:
251         build_append_byte(array, 0x2E); /* DualNamePrefix */
252         build_append_nameseg(array, s);
253         build_append_nameseg(array, segs[1]);
254         break;
255     default:
256         build_append_byte(array, 0x2F); /* MultiNamePrefix */
257         build_append_byte(array, seg_count);
258 
259         /* handle the 1st segment manually due to prefix/root path */
260         build_append_nameseg(array, s);
261 
262         /* add the rest of segments */
263         segs_iter = segs + 1;
264         while (*segs_iter) {
265             build_append_nameseg(array, *segs_iter);
266             ++segs_iter;
267         }
268         break;
269     }
270     g_strfreev(segs);
271 }
272 
273 G_GNUC_PRINTF(2, 3)
274 static void build_append_namestring(GArray *array, const char *format, ...)
275 {
276     va_list ap;
277 
278     va_start(ap, format);
279     build_append_namestringv(array, format, ap);
280     va_end(ap);
281 }
282 
283 /* 5.4 Definition Block Encoding */
284 enum {
285     PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
286     PACKAGE_LENGTH_2BYTE_SHIFT = 4,
287     PACKAGE_LENGTH_3BYTE_SHIFT = 12,
288     PACKAGE_LENGTH_4BYTE_SHIFT = 20,
289 };
290 
291 static void
292 build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
293 {
294     uint8_t byte;
295     unsigned length_bytes;
296 
297     if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
298         length_bytes = 1;
299     } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
300         length_bytes = 2;
301     } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
302         length_bytes = 3;
303     } else {
304         length_bytes = 4;
305     }
306 
307     /*
308      * NamedField uses PkgLength encoding but it doesn't include length
309      * of PkgLength itself.
310      */
311     if (incl_self) {
312         /*
313          * PkgLength is the length of the inclusive length of the data
314          * and PkgLength's length itself when used for terms with
315          * explicit length.
316          */
317         length += length_bytes;
318     }
319 
320     switch (length_bytes) {
321     case 1:
322         byte = length;
323         build_prepend_byte(package, byte);
324         return;
325     case 4:
326         byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
327         build_prepend_byte(package, byte);
328         length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
329         /* fall through */
330     case 3:
331         byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
332         build_prepend_byte(package, byte);
333         length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
334         /* fall through */
335     case 2:
336         byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
337         build_prepend_byte(package, byte);
338         length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
339         /* fall through */
340     }
341     /*
342      * Most significant two bits of byte zero indicate how many following bytes
343      * are in PkgLength encoding.
344      */
345     byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
346     build_prepend_byte(package, byte);
347 }
348 
349 static void
350 build_append_pkg_length(GArray *array, unsigned length, bool incl_self)
351 {
352     GArray *tmp = build_alloc_array();
353 
354     build_prepend_package_length(tmp, length, incl_self);
355     build_append_array(array, tmp);
356     build_free_array(tmp);
357 }
358 
359 static void build_package(GArray *package, uint8_t op)
360 {
361     build_prepend_package_length(package, package->len, true);
362     build_prepend_byte(package, op);
363 }
364 
365 static void build_extop_package(GArray *package, uint8_t op)
366 {
367     build_package(package, op);
368     build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
369 }
370 
371 void build_append_int_noprefix(GArray *table, uint64_t value, int size)
372 {
373     int i;
374 
375     for (i = 0; i < size; ++i) {
376         build_append_byte(table, value & 0xFF);
377         value = value >> 8;
378     }
379 }
380 
381 static void build_append_int(GArray *table, uint64_t value)
382 {
383     if (value == 0x00) {
384         build_append_byte(table, 0x00); /* ZeroOp */
385     } else if (value == 0x01) {
386         build_append_byte(table, 0x01); /* OneOp */
387     } else if (value <= 0xFF) {
388         build_append_byte(table, 0x0A); /* BytePrefix */
389         build_append_int_noprefix(table, value, 1);
390     } else if (value <= 0xFFFF) {
391         build_append_byte(table, 0x0B); /* WordPrefix */
392         build_append_int_noprefix(table, value, 2);
393     } else if (value <= 0xFFFFFFFF) {
394         build_append_byte(table, 0x0C); /* DWordPrefix */
395         build_append_int_noprefix(table, value, 4);
396     } else {
397         build_append_byte(table, 0x0E); /* QWordPrefix */
398         build_append_int_noprefix(table, value, 8);
399     }
400 }
401 
402 /* Generic Address Structure (GAS)
403  * ACPI 2.0/3.0: 5.2.3.1 Generic Address Structure
404  * 2.0 compat note:
405  *    @access_width must be 0, see ACPI 2.0:Table 5-1
406  */
407 void build_append_gas(GArray *table, AmlAddressSpace as,
408                       uint8_t bit_width, uint8_t bit_offset,
409                       uint8_t access_width, uint64_t address)
410 {
411     build_append_int_noprefix(table, as, 1);
412     build_append_int_noprefix(table, bit_width, 1);
413     build_append_int_noprefix(table, bit_offset, 1);
414     build_append_int_noprefix(table, access_width, 1);
415     build_append_int_noprefix(table, address, 8);
416 }
417 
418 /*
419  * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword,
420  * and return the offset to 0x00000000 for runtime patching.
421  *
422  * Warning: runtime patching is best avoided. Only use this as
423  * a replacement for DataTableRegion (for guests that don't
424  * support it).
425  */
426 int
427 build_append_named_dword(GArray *array, const char *name_format, ...)
428 {
429     int offset;
430     va_list ap;
431 
432     build_append_byte(array, 0x08); /* NameOp */
433     va_start(ap, name_format);
434     build_append_namestringv(array, name_format, ap);
435     va_end(ap);
436 
437     build_append_byte(array, 0x0C); /* DWordPrefix */
438 
439     offset = array->len;
440     build_append_int_noprefix(array, 0x00000000, 4);
441     assert(array->len == offset + 4);
442 
443     return offset;
444 }
445 
446 static GPtrArray *alloc_list;
447 
448 static Aml *aml_alloc(void)
449 {
450     Aml *var = g_new0(typeof(*var), 1);
451 
452     g_ptr_array_add(alloc_list, var);
453     var->block_flags = AML_NO_OPCODE;
454     var->buf = build_alloc_array();
455     return var;
456 }
457 
458 static Aml *aml_opcode(uint8_t op)
459 {
460     Aml *var = aml_alloc();
461 
462     var->op  = op;
463     var->block_flags = AML_OPCODE;
464     return var;
465 }
466 
467 static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags)
468 {
469     Aml *var = aml_alloc();
470 
471     var->op  = op;
472     var->block_flags = flags;
473     return var;
474 }
475 
476 static void aml_free(gpointer data, gpointer user_data)
477 {
478     Aml *var = data;
479     build_free_array(var->buf);
480     g_free(var);
481 }
482 
483 Aml *init_aml_allocator(void)
484 {
485     assert(!alloc_list);
486     alloc_list = g_ptr_array_new();
487     return aml_alloc();
488 }
489 
490 void free_aml_allocator(void)
491 {
492     g_ptr_array_foreach(alloc_list, aml_free, NULL);
493     g_ptr_array_free(alloc_list, true);
494     alloc_list = 0;
495 }
496 
497 /* pack data with DefBuffer encoding */
498 static void build_buffer(GArray *array, uint8_t op)
499 {
500     GArray *data = build_alloc_array();
501 
502     build_append_int(data, array->len);
503     g_array_prepend_vals(array, data->data, data->len);
504     build_free_array(data);
505     build_package(array, op);
506 }
507 
508 void aml_append(Aml *parent_ctx, Aml *child)
509 {
510     GArray *buf = build_alloc_array();
511     build_append_array(buf, child->buf);
512 
513     switch (child->block_flags) {
514     case AML_OPCODE:
515         build_append_byte(parent_ctx->buf, child->op);
516         break;
517     case AML_EXT_PACKAGE:
518         build_extop_package(buf, child->op);
519         break;
520     case AML_PACKAGE:
521         build_package(buf, child->op);
522         break;
523     case AML_RES_TEMPLATE:
524         build_append_byte(buf, 0x79); /* EndTag */
525         /*
526          * checksum operations are treated as succeeded if checksum
527          * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
528          */
529         build_append_byte(buf, 0);
530         /* fall through, to pack resources in buffer */
531     case AML_BUFFER:
532         build_buffer(buf, child->op);
533         break;
534     case AML_NO_OPCODE:
535         break;
536     default:
537         g_assert_not_reached();
538     }
539     build_append_array(parent_ctx->buf, buf);
540     build_free_array(buf);
541 }
542 
543 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */
544 Aml *aml_scope(const char *name_format, ...)
545 {
546     va_list ap;
547     Aml *var = aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE);
548     va_start(ap, name_format);
549     build_append_namestringv(var->buf, name_format, ap);
550     va_end(ap);
551     return var;
552 }
553 
554 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */
555 Aml *aml_return(Aml *val)
556 {
557     Aml *var = aml_opcode(0xA4 /* ReturnOp */);
558     aml_append(var, val);
559     return var;
560 }
561 
562 /* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */
563 Aml *aml_debug(void)
564 {
565     Aml *var = aml_alloc();
566     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
567     build_append_byte(var->buf, 0x31); /* DebugOp */
568     return var;
569 }
570 
571 /*
572  * ACPI 1.0b: 16.2.3 Data Objects Encoding:
573  * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
574  */
575 Aml *aml_int(const uint64_t val)
576 {
577     Aml *var = aml_alloc();
578     build_append_int(var->buf, val);
579     return var;
580 }
581 
582 /*
583  * helper to construct NameString, which returns Aml object
584  * for using with aml_append or other aml_* terms
585  */
586 Aml *aml_name(const char *name_format, ...)
587 {
588     va_list ap;
589     Aml *var = aml_alloc();
590     va_start(ap, name_format);
591     build_append_namestringv(var->buf, name_format, ap);
592     va_end(ap);
593     return var;
594 }
595 
596 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */
597 Aml *aml_name_decl(const char *name, Aml *val)
598 {
599     Aml *var = aml_opcode(0x08 /* NameOp */);
600     build_append_namestring(var->buf, "%s", name);
601     aml_append(var, val);
602     return var;
603 }
604 
605 /* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
606 Aml *aml_arg(int pos)
607 {
608     uint8_t op = 0x68 /* ARG0 op */ + pos;
609 
610     assert(pos <= 6);
611     return aml_opcode(op);
612 }
613 
614 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToInteger */
615 Aml *aml_to_integer(Aml *arg)
616 {
617     Aml *var = aml_opcode(0x99 /* ToIntegerOp */);
618     aml_append(var, arg);
619     build_append_byte(var->buf, 0x00 /* NullNameOp */);
620     return var;
621 }
622 
623 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToHexString */
624 Aml *aml_to_hexstring(Aml *src, Aml *dst)
625 {
626     Aml *var = aml_opcode(0x98 /* ToHexStringOp */);
627     aml_append(var, src);
628     if (dst) {
629         aml_append(var, dst);
630     } else {
631         build_append_byte(var->buf, 0x00 /* NullNameOp */);
632     }
633     return var;
634 }
635 
636 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToBuffer */
637 Aml *aml_to_buffer(Aml *src, Aml *dst)
638 {
639     Aml *var = aml_opcode(0x96 /* ToBufferOp */);
640     aml_append(var, src);
641     if (dst) {
642         aml_append(var, dst);
643     } else {
644         build_append_byte(var->buf, 0x00 /* NullNameOp */);
645     }
646     return var;
647 }
648 
649 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToDecimalString */
650 Aml *aml_to_decimalstring(Aml *src, Aml *dst)
651 {
652     Aml *var = aml_opcode(0x97 /* ToDecimalStringOp */);
653     aml_append(var, src);
654     if (dst) {
655         aml_append(var, dst);
656     } else {
657         build_append_byte(var->buf, 0x00 /* NullNameOp */);
658     }
659     return var;
660 }
661 
662 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
663 Aml *aml_store(Aml *val, Aml *target)
664 {
665     Aml *var = aml_opcode(0x70 /* StoreOp */);
666     aml_append(var, val);
667     aml_append(var, target);
668     return var;
669 }
670 
671 /**
672  * build_opcode_2arg_dst:
673  * @op: 1-byte opcode
674  * @arg1: 1st operand
675  * @arg2: 2nd operand
676  * @dst: optional target to store to, set to NULL if it's not required
677  *
678  * An internal helper to compose AML terms that have
679  *   "Op Operand Operand Target"
680  * pattern.
681  *
682  * Returns: The newly allocated and composed according to pattern Aml object.
683  */
684 static Aml *
685 build_opcode_2arg_dst(uint8_t op, Aml *arg1, Aml *arg2, Aml *dst)
686 {
687     Aml *var = aml_opcode(op);
688     aml_append(var, arg1);
689     aml_append(var, arg2);
690     if (dst) {
691         aml_append(var, dst);
692     } else {
693         build_append_byte(var->buf, 0x00 /* NullNameOp */);
694     }
695     return var;
696 }
697 
698 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
699 Aml *aml_and(Aml *arg1, Aml *arg2, Aml *dst)
700 {
701     return build_opcode_2arg_dst(0x7B /* AndOp */, arg1, arg2, dst);
702 }
703 
704 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
705 Aml *aml_or(Aml *arg1, Aml *arg2, Aml *dst)
706 {
707     return build_opcode_2arg_dst(0x7D /* OrOp */, arg1, arg2, dst);
708 }
709 
710 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLAnd */
711 Aml *aml_land(Aml *arg1, Aml *arg2)
712 {
713     Aml *var = aml_opcode(0x90 /* LAndOp */);
714     aml_append(var, arg1);
715     aml_append(var, arg2);
716     return var;
717 }
718 
719 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLOr */
720 Aml *aml_lor(Aml *arg1, Aml *arg2)
721 {
722     Aml *var = aml_opcode(0x91 /* LOrOp */);
723     aml_append(var, arg1);
724     aml_append(var, arg2);
725     return var;
726 }
727 
728 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftLeft */
729 Aml *aml_shiftleft(Aml *arg1, Aml *count)
730 {
731     return build_opcode_2arg_dst(0x79 /* ShiftLeftOp */, arg1, count, NULL);
732 }
733 
734 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftRight */
735 Aml *aml_shiftright(Aml *arg1, Aml *count, Aml *dst)
736 {
737     return build_opcode_2arg_dst(0x7A /* ShiftRightOp */, arg1, count, dst);
738 }
739 
740 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
741 Aml *aml_lless(Aml *arg1, Aml *arg2)
742 {
743     Aml *var = aml_opcode(0x95 /* LLessOp */);
744     aml_append(var, arg1);
745     aml_append(var, arg2);
746     return var;
747 }
748 
749 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */
750 Aml *aml_add(Aml *arg1, Aml *arg2, Aml *dst)
751 {
752     return build_opcode_2arg_dst(0x72 /* AddOp */, arg1, arg2, dst);
753 }
754 
755 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSubtract */
756 Aml *aml_subtract(Aml *arg1, Aml *arg2, Aml *dst)
757 {
758     return build_opcode_2arg_dst(0x74 /* SubtractOp */, arg1, arg2, dst);
759 }
760 
761 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIncrement */
762 Aml *aml_increment(Aml *arg)
763 {
764     Aml *var = aml_opcode(0x75 /* IncrementOp */);
765     aml_append(var, arg);
766     return var;
767 }
768 
769 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDecrement */
770 Aml *aml_decrement(Aml *arg)
771 {
772     Aml *var = aml_opcode(0x76 /* DecrementOp */);
773     aml_append(var, arg);
774     return var;
775 }
776 
777 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */
778 Aml *aml_index(Aml *arg1, Aml *idx)
779 {
780     return build_opcode_2arg_dst(0x88 /* IndexOp */, arg1, idx, NULL);
781 }
782 
783 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
784 Aml *aml_notify(Aml *arg1, Aml *arg2)
785 {
786     Aml *var = aml_opcode(0x86 /* NotifyOp */);
787     aml_append(var, arg1);
788     aml_append(var, arg2);
789     return var;
790 }
791 
792 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefBreak */
793 Aml *aml_break(void)
794 {
795     Aml *var = aml_opcode(0xa5 /* BreakOp */);
796     return var;
797 }
798 
799 /* helper to call method without argument */
800 Aml *aml_call0(const char *method)
801 {
802     Aml *var = aml_alloc();
803     build_append_namestring(var->buf, "%s", method);
804     return var;
805 }
806 
807 /* helper to call method with 1 argument */
808 Aml *aml_call1(const char *method, Aml *arg1)
809 {
810     Aml *var = aml_alloc();
811     build_append_namestring(var->buf, "%s", method);
812     aml_append(var, arg1);
813     return var;
814 }
815 
816 /* helper to call method with 2 arguments */
817 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2)
818 {
819     Aml *var = aml_alloc();
820     build_append_namestring(var->buf, "%s", method);
821     aml_append(var, arg1);
822     aml_append(var, arg2);
823     return var;
824 }
825 
826 /* helper to call method with 3 arguments */
827 Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3)
828 {
829     Aml *var = aml_alloc();
830     build_append_namestring(var->buf, "%s", method);
831     aml_append(var, arg1);
832     aml_append(var, arg2);
833     aml_append(var, arg3);
834     return var;
835 }
836 
837 /* helper to call method with 4 arguments */
838 Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
839 {
840     Aml *var = aml_alloc();
841     build_append_namestring(var->buf, "%s", method);
842     aml_append(var, arg1);
843     aml_append(var, arg2);
844     aml_append(var, arg3);
845     aml_append(var, arg4);
846     return var;
847 }
848 
849 /* helper to call method with 5 arguments */
850 Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
851                Aml *arg5)
852 {
853     Aml *var = aml_alloc();
854     build_append_namestring(var->buf, "%s", method);
855     aml_append(var, arg1);
856     aml_append(var, arg2);
857     aml_append(var, arg3);
858     aml_append(var, arg4);
859     aml_append(var, arg5);
860     return var;
861 }
862 
863 /* helper to call method with 5 arguments */
864 Aml *aml_call6(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
865                Aml *arg5, Aml *arg6)
866 {
867     Aml *var = aml_alloc();
868     build_append_namestring(var->buf, "%s", method);
869     aml_append(var, arg1);
870     aml_append(var, arg2);
871     aml_append(var, arg3);
872     aml_append(var, arg4);
873     aml_append(var, arg5);
874     aml_append(var, arg6);
875     return var;
876 }
877 
878 /*
879  * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
880  * Type 1, Large Item Name 0xC
881  */
882 
883 static Aml *aml_gpio_connection(AmlGpioConnectionType type,
884                                 AmlConsumerAndProducer con_and_pro,
885                                 uint8_t flags, AmlPinConfig pin_config,
886                                 uint16_t output_drive,
887                                 uint16_t debounce_timeout,
888                                 const uint32_t pin_list[], uint32_t pin_count,
889                                 const char *resource_source_name,
890                                 const uint8_t *vendor_data,
891                                 uint16_t vendor_data_len)
892 {
893     Aml *var = aml_alloc();
894     const uint16_t min_desc_len = 0x16;
895     uint16_t resource_source_name_len, length;
896     uint16_t pin_table_offset, resource_source_name_offset, vendor_data_offset;
897     uint32_t i;
898 
899     assert(resource_source_name);
900     resource_source_name_len = strlen(resource_source_name) + 1;
901     length = min_desc_len + resource_source_name_len + vendor_data_len;
902     pin_table_offset = min_desc_len + 1;
903     resource_source_name_offset = pin_table_offset + pin_count * 2;
904     vendor_data_offset = resource_source_name_offset + resource_source_name_len;
905 
906     build_append_byte(var->buf, 0x8C);  /* GPIO Connection Descriptor */
907     build_append_int_noprefix(var->buf, length, 2); /* Length */
908     build_append_byte(var->buf, 1);     /* Revision ID */
909     build_append_byte(var->buf, type);  /* GPIO Connection Type */
910     /* General Flags (2 bytes) */
911     build_append_int_noprefix(var->buf, con_and_pro, 2);
912     /* Interrupt and IO Flags (2 bytes) */
913     build_append_int_noprefix(var->buf, flags, 2);
914     /* Pin Configuration 0 = Default 1 = Pull-up 2 = Pull-down 3 = No Pull */
915     build_append_byte(var->buf, pin_config);
916     /* Output Drive Strength (2 bytes) */
917     build_append_int_noprefix(var->buf, output_drive, 2);
918     /* Debounce Timeout (2 bytes) */
919     build_append_int_noprefix(var->buf, debounce_timeout, 2);
920     /* Pin Table Offset (2 bytes) */
921     build_append_int_noprefix(var->buf, pin_table_offset, 2);
922     build_append_byte(var->buf, 0);     /* Resource Source Index */
923     /* Resource Source Name Offset (2 bytes) */
924     build_append_int_noprefix(var->buf, resource_source_name_offset, 2);
925     /* Vendor Data Offset (2 bytes) */
926     build_append_int_noprefix(var->buf, vendor_data_offset, 2);
927     /* Vendor Data Length (2 bytes) */
928     build_append_int_noprefix(var->buf, vendor_data_len, 2);
929     /* Pin Number (2n bytes)*/
930     for (i = 0; i < pin_count; i++) {
931         build_append_int_noprefix(var->buf, pin_list[i], 2);
932     }
933 
934     /* Resource Source Name */
935     build_append_namestring(var->buf, "%s", resource_source_name);
936     build_append_byte(var->buf, '\0');
937 
938     /* Vendor-defined Data */
939     if (vendor_data != NULL) {
940         g_array_append_vals(var->buf, vendor_data, vendor_data_len);
941     }
942 
943     return var;
944 }
945 
946 /*
947  * ACPI 5.0: 19.5.53
948  * GpioInt(GPIO Interrupt Connection Resource Descriptor Macro)
949  */
950 Aml *aml_gpio_int(AmlConsumerAndProducer con_and_pro,
951                   AmlLevelAndEdge edge_level,
952                   AmlActiveHighAndLow active_level, AmlShared shared,
953                   AmlPinConfig pin_config, uint16_t debounce_timeout,
954                   const uint32_t pin_list[], uint32_t pin_count,
955                   const char *resource_source_name,
956                   const uint8_t *vendor_data, uint16_t vendor_data_len)
957 {
958     uint8_t flags = edge_level | (active_level << 1) | (shared << 3);
959 
960     return aml_gpio_connection(AML_INTERRUPT_CONNECTION, con_and_pro, flags,
961                                pin_config, 0, debounce_timeout, pin_list,
962                                pin_count, resource_source_name, vendor_data,
963                                vendor_data_len);
964 }
965 
966 /*
967  * ACPI 1.0b: 6.4.3.4 32-Bit Fixed Location Memory Range Descriptor
968  * (Type 1, Large Item Name 0x6)
969  */
970 Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
971                         AmlReadAndWrite read_and_write)
972 {
973     Aml *var = aml_alloc();
974     build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */
975     build_append_byte(var->buf, 9);    /* Length, bits[7:0] value = 9 */
976     build_append_byte(var->buf, 0);    /* Length, bits[15:8] value = 0 */
977     build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */
978 
979     /* Range base address */
980     build_append_byte(var->buf, extract32(addr, 0, 8));  /* bits[7:0] */
981     build_append_byte(var->buf, extract32(addr, 8, 8));  /* bits[15:8] */
982     build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */
983     build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */
984 
985     /* Range length */
986     build_append_byte(var->buf, extract32(size, 0, 8));  /* bits[7:0] */
987     build_append_byte(var->buf, extract32(size, 8, 8));  /* bits[15:8] */
988     build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */
989     build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */
990     return var;
991 }
992 
993 /*
994  * ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor
995  * Type 1, Large Item Name 0x9
996  */
997 Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
998                    AmlLevelAndEdge level_and_edge,
999                    AmlActiveHighAndLow high_and_low, AmlShared shared,
1000                    uint32_t *irq_list, uint8_t irq_count)
1001 {
1002     int i;
1003     Aml *var = aml_alloc();
1004     uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
1005                         | (high_and_low << 2) | (shared << 3);
1006     const int header_bytes_in_len = 2;
1007     uint16_t len = header_bytes_in_len + irq_count * sizeof(uint32_t);
1008 
1009     assert(irq_count > 0);
1010 
1011     build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
1012     build_append_byte(var->buf, len & 0xFF); /* Length, bits[7:0] */
1013     build_append_byte(var->buf, len >> 8); /* Length, bits[15:8] */
1014     build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
1015     build_append_byte(var->buf, irq_count);   /* Interrupt table length */
1016 
1017     /* Interrupt Number List */
1018     for (i = 0; i < irq_count; i++) {
1019         build_append_int_noprefix(var->buf, irq_list[i], 4);
1020     }
1021     return var;
1022 }
1023 
1024 /* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
1025 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
1026             uint8_t aln, uint8_t len)
1027 {
1028     Aml *var = aml_alloc();
1029     build_append_byte(var->buf, 0x47); /* IO port descriptor */
1030     build_append_byte(var->buf, dec);
1031     build_append_byte(var->buf, min_base & 0xff);
1032     build_append_byte(var->buf, (min_base >> 8) & 0xff);
1033     build_append_byte(var->buf, max_base & 0xff);
1034     build_append_byte(var->buf, (max_base >> 8) & 0xff);
1035     build_append_byte(var->buf, aln);
1036     build_append_byte(var->buf, len);
1037     return var;
1038 }
1039 
1040 /*
1041  * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
1042  *
1043  * More verbose description at:
1044  * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
1045  *           6.4.2.1 IRQ Descriptor
1046  */
1047 Aml *aml_irq_no_flags(uint8_t irq)
1048 {
1049     uint16_t irq_mask;
1050     Aml *var = aml_alloc();
1051 
1052     assert(irq < 16);
1053     build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
1054 
1055     irq_mask = 1U << irq;
1056     build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
1057     build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
1058     return var;
1059 }
1060 
1061 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
1062 Aml *aml_lnot(Aml *arg)
1063 {
1064     Aml *var = aml_opcode(0x92 /* LNotOp */);
1065     aml_append(var, arg);
1066     return var;
1067 }
1068 
1069 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
1070 Aml *aml_equal(Aml *arg1, Aml *arg2)
1071 {
1072     Aml *var = aml_opcode(0x93 /* LequalOp */);
1073     aml_append(var, arg1);
1074     aml_append(var, arg2);
1075     return var;
1076 }
1077 
1078 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreater */
1079 Aml *aml_lgreater(Aml *arg1, Aml *arg2)
1080 {
1081     Aml *var = aml_opcode(0x94 /* LGreaterOp */);
1082     aml_append(var, arg1);
1083     aml_append(var, arg2);
1084     return var;
1085 }
1086 
1087 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreaterEqual */
1088 Aml *aml_lgreater_equal(Aml *arg1, Aml *arg2)
1089 {
1090     /* LGreaterEqualOp := LNotOp LLessOp */
1091     Aml *var = aml_opcode(0x92 /* LNotOp */);
1092     build_append_byte(var->buf, 0x95 /* LLessOp */);
1093     aml_append(var, arg1);
1094     aml_append(var, arg2);
1095     return var;
1096 }
1097 
1098 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
1099 Aml *aml_if(Aml *predicate)
1100 {
1101     Aml *var = aml_bundle(0xA0 /* IfOp */, AML_PACKAGE);
1102     aml_append(var, predicate);
1103     return var;
1104 }
1105 
1106 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */
1107 Aml *aml_else(void)
1108 {
1109     Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
1110     return var;
1111 }
1112 
1113 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefWhile */
1114 Aml *aml_while(Aml *predicate)
1115 {
1116     Aml *var = aml_bundle(0xA2 /* WhileOp */, AML_PACKAGE);
1117     aml_append(var, predicate);
1118     return var;
1119 }
1120 
1121 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
1122 Aml *aml_method(const char *name, int arg_count, AmlSerializeFlag sflag)
1123 {
1124     Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
1125     int methodflags;
1126 
1127     /*
1128      * MethodFlags:
1129      *   bit 0-2: ArgCount (0-7)
1130      *   bit 3: SerializeFlag
1131      *     0: NotSerialized
1132      *     1: Serialized
1133      *   bit 4-7: reserved (must be 0)
1134      */
1135     assert(arg_count < 8);
1136     methodflags = arg_count | (sflag << 3);
1137 
1138     build_append_namestring(var->buf, "%s", name);
1139     build_append_byte(var->buf, methodflags); /* MethodFlags: ArgCount */
1140     return var;
1141 }
1142 
1143 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
1144 Aml *aml_device(const char *name_format, ...)
1145 {
1146     va_list ap;
1147     Aml *var = aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE);
1148     va_start(ap, name_format);
1149     build_append_namestringv(var->buf, name_format, ap);
1150     va_end(ap);
1151     return var;
1152 }
1153 
1154 /* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */
1155 Aml *aml_resource_template(void)
1156 {
1157     /* ResourceTemplate is a buffer of Resources with EndTag at the end */
1158     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE);
1159     return var;
1160 }
1161 
1162 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer
1163  * Pass byte_list as NULL to request uninitialized buffer to reserve space.
1164  */
1165 Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
1166 {
1167     int i;
1168     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1169 
1170     for (i = 0; i < buffer_size; i++) {
1171         if (byte_list == NULL) {
1172             build_append_byte(var->buf, 0x0);
1173         } else {
1174             build_append_byte(var->buf, byte_list[i]);
1175         }
1176     }
1177 
1178     return var;
1179 }
1180 
1181 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */
1182 Aml *aml_package(uint8_t num_elements)
1183 {
1184     Aml *var = aml_bundle(0x12 /* PackageOp */, AML_PACKAGE);
1185     build_append_byte(var->buf, num_elements);
1186     return var;
1187 }
1188 
1189 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
1190 Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
1191                           Aml *offset, uint32_t len)
1192 {
1193     Aml *var = aml_alloc();
1194     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1195     build_append_byte(var->buf, 0x80); /* OpRegionOp */
1196     build_append_namestring(var->buf, "%s", name);
1197     build_append_byte(var->buf, rs);
1198     aml_append(var, offset);
1199     build_append_int(var->buf, len);
1200     return var;
1201 }
1202 
1203 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */
1204 Aml *aml_named_field(const char *name, unsigned length)
1205 {
1206     Aml *var = aml_alloc();
1207     build_append_nameseg(var->buf, name);
1208     build_append_pkg_length(var->buf, length, false);
1209     return var;
1210 }
1211 
1212 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
1213 Aml *aml_reserved_field(unsigned length)
1214 {
1215     Aml *var = aml_alloc();
1216     /* ReservedField  := 0x00 PkgLength */
1217     build_append_byte(var->buf, 0x00);
1218     build_append_pkg_length(var->buf, length, false);
1219     return var;
1220 }
1221 
1222 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
1223 Aml *aml_field(const char *name, AmlAccessType type, AmlLockRule lock,
1224                AmlUpdateRule rule)
1225 {
1226     Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
1227     uint8_t flags = rule << 5 | type;
1228 
1229     flags |= lock << 4; /* LockRule at 4 bit offset */
1230 
1231     build_append_namestring(var->buf, "%s", name);
1232     build_append_byte(var->buf, flags);
1233     return var;
1234 }
1235 
1236 static
1237 Aml *create_field_common(int opcode, Aml *srcbuf, Aml *index, const char *name)
1238 {
1239     Aml *var = aml_opcode(opcode);
1240     aml_append(var, srcbuf);
1241     aml_append(var, index);
1242     build_append_namestring(var->buf, "%s", name);
1243     return var;
1244 }
1245 
1246 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
1247 Aml *aml_create_field(Aml *srcbuf, Aml *bit_index, Aml *num_bits,
1248                       const char *name)
1249 {
1250     Aml *var = aml_alloc();
1251     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1252     build_append_byte(var->buf, 0x13); /* CreateFieldOp */
1253     aml_append(var, srcbuf);
1254     aml_append(var, bit_index);
1255     aml_append(var, num_bits);
1256     build_append_namestring(var->buf, "%s", name);
1257     return var;
1258 }
1259 
1260 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
1261 Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
1262 {
1263     return create_field_common(0x8A /* CreateDWordFieldOp */,
1264                                srcbuf, index, name);
1265 }
1266 
1267 /* ACPI 2.0a: 17.2.4.2 Named Objects Encoding: DefCreateQWordField */
1268 Aml *aml_create_qword_field(Aml *srcbuf, Aml *index, const char *name)
1269 {
1270     return create_field_common(0x8F /* CreateQWordFieldOp */,
1271                                srcbuf, index, name);
1272 }
1273 
1274 /* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
1275 Aml *aml_string(const char *name_format, ...)
1276 {
1277     Aml *var = aml_opcode(0x0D /* StringPrefix */);
1278     va_list ap;
1279     char *s;
1280     int len;
1281 
1282     va_start(ap, name_format);
1283     len = g_vasprintf(&s, name_format, ap);
1284     va_end(ap);
1285 
1286     g_array_append_vals(var->buf, s, len + 1);
1287     g_free(s);
1288 
1289     return var;
1290 }
1291 
1292 /* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
1293 Aml *aml_local(int num)
1294 {
1295     uint8_t op = 0x60 /* Local0Op */ + num;
1296 
1297     assert(num <= 7);
1298     return aml_opcode(op);
1299 }
1300 
1301 /* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
1302 Aml *aml_varpackage(uint32_t num_elements)
1303 {
1304     Aml *var = aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE);
1305     build_append_int(var->buf, num_elements);
1306     return var;
1307 }
1308 
1309 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
1310 Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
1311                    const char *name_format, ...)
1312 {
1313     va_list ap;
1314     Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE);
1315     va_start(ap, name_format);
1316     build_append_namestringv(var->buf, name_format, ap);
1317     va_end(ap);
1318     build_append_byte(var->buf, proc_id); /* ProcID */
1319     build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr));
1320     build_append_byte(var->buf, pblk_len); /* PblkLen */
1321     return var;
1322 }
1323 
1324 static uint8_t Hex2Digit(char c)
1325 {
1326     if (c >= 'A') {
1327         return c - 'A' + 10;
1328     }
1329 
1330     return c - '0';
1331 }
1332 
1333 /* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */
1334 Aml *aml_eisaid(const char *str)
1335 {
1336     Aml *var = aml_alloc();
1337     uint32_t id;
1338 
1339     g_assert(strlen(str) == 7);
1340     id = (str[0] - 0x40) << 26 |
1341     (str[1] - 0x40) << 21 |
1342     (str[2] - 0x40) << 16 |
1343     Hex2Digit(str[3]) << 12 |
1344     Hex2Digit(str[4]) << 8 |
1345     Hex2Digit(str[5]) << 4 |
1346     Hex2Digit(str[6]);
1347 
1348     build_append_byte(var->buf, 0x0C); /* DWordPrefix */
1349     build_append_int_noprefix(var->buf, bswap32(id), sizeof(id));
1350     return var;
1351 }
1352 
1353 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
1354 static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed,
1355                                AmlMaxFixed max_fixed, AmlDecode dec,
1356                                uint8_t type_flags)
1357 {
1358     uint8_t flags = max_fixed | min_fixed | dec;
1359     Aml *var = aml_alloc();
1360 
1361     build_append_byte(var->buf, type);
1362     build_append_byte(var->buf, flags);
1363     build_append_byte(var->buf, type_flags); /* Type Specific Flags */
1364     return var;
1365 }
1366 
1367 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */
1368 static Aml *aml_word_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1369                              AmlMaxFixed max_fixed, AmlDecode dec,
1370                              uint16_t addr_gran, uint16_t addr_min,
1371                              uint16_t addr_max, uint16_t addr_trans,
1372                              uint16_t len, uint8_t type_flags)
1373 {
1374     Aml *var = aml_alloc();
1375 
1376     build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
1377     /* minimum length since we do not encode optional fields */
1378     build_append_byte(var->buf, 0x0D);
1379     build_append_byte(var->buf, 0x0);
1380 
1381     aml_append(var,
1382         aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1383     build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1384     build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1385     build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1386     build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1387     build_append_int_noprefix(var->buf, len, sizeof(len));
1388     return var;
1389 }
1390 
1391 /* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */
1392 static Aml *aml_dword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1393                               AmlMaxFixed max_fixed, AmlDecode dec,
1394                               uint32_t addr_gran, uint32_t addr_min,
1395                               uint32_t addr_max, uint32_t addr_trans,
1396                               uint32_t len, uint8_t type_flags)
1397 {
1398     Aml *var = aml_alloc();
1399 
1400     build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
1401     /* minimum length since we do not encode optional fields */
1402     build_append_byte(var->buf, 23);
1403     build_append_byte(var->buf, 0x0);
1404 
1405 
1406     aml_append(var,
1407         aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1408     build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1409     build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1410     build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1411     build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1412     build_append_int_noprefix(var->buf, len, sizeof(len));
1413     return var;
1414 }
1415 
1416 /* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */
1417 static Aml *aml_qword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1418                               AmlMaxFixed max_fixed, AmlDecode dec,
1419                               uint64_t addr_gran, uint64_t addr_min,
1420                               uint64_t addr_max, uint64_t addr_trans,
1421                               uint64_t len, uint8_t type_flags)
1422 {
1423     Aml *var = aml_alloc();
1424 
1425     build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
1426     /* minimum length since we do not encode optional fields */
1427     build_append_byte(var->buf, 0x2B);
1428     build_append_byte(var->buf, 0x0);
1429 
1430     aml_append(var,
1431         aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1432     build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1433     build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1434     build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1435     build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1436     build_append_int_noprefix(var->buf, len, sizeof(len));
1437     return var;
1438 }
1439 
1440 /*
1441  * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
1442  *
1443  * More verbose description at:
1444  * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
1445  */
1446 Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1447                          AmlDecode dec, uint16_t addr_gran,
1448                          uint16_t addr_min, uint16_t addr_max,
1449                          uint16_t addr_trans, uint16_t len)
1450 
1451 {
1452     return aml_word_as_desc(AML_BUS_NUMBER_RANGE, min_fixed, max_fixed, dec,
1453                             addr_gran, addr_min, addr_max, addr_trans, len, 0);
1454 }
1455 
1456 /*
1457  * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
1458  *
1459  * More verbose description at:
1460  * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro)
1461  */
1462 Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1463                  AmlDecode dec, AmlISARanges isa_ranges,
1464                  uint16_t addr_gran, uint16_t addr_min,
1465                  uint16_t addr_max, uint16_t addr_trans,
1466                  uint16_t len)
1467 
1468 {
1469     return aml_word_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
1470                             addr_gran, addr_min, addr_max, addr_trans, len,
1471                             isa_ranges);
1472 }
1473 
1474 /*
1475  * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor
1476  *
1477  * More verbose description at:
1478  * ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro)
1479  */
1480 Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1481                  AmlDecode dec, AmlISARanges isa_ranges,
1482                  uint32_t addr_gran, uint32_t addr_min,
1483                  uint32_t addr_max, uint32_t addr_trans,
1484                  uint32_t len)
1485 
1486 {
1487     return aml_dword_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
1488                             addr_gran, addr_min, addr_max, addr_trans, len,
1489                             isa_ranges);
1490 }
1491 
1492 /*
1493  * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
1494  *
1495  * More verbose description at:
1496  * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
1497  */
1498 Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
1499                       AmlMaxFixed max_fixed, AmlCacheable cacheable,
1500                       AmlReadAndWrite read_and_write,
1501                       uint32_t addr_gran, uint32_t addr_min,
1502                       uint32_t addr_max, uint32_t addr_trans,
1503                       uint32_t len)
1504 {
1505     uint8_t flags = read_and_write | (cacheable << 1);
1506 
1507     return aml_dword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
1508                              dec, addr_gran, addr_min, addr_max,
1509                              addr_trans, len, flags);
1510 }
1511 
1512 /*
1513  * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor
1514  *
1515  * More verbose description at:
1516  * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
1517  */
1518 Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
1519                       AmlMaxFixed max_fixed, AmlCacheable cacheable,
1520                       AmlReadAndWrite read_and_write,
1521                       uint64_t addr_gran, uint64_t addr_min,
1522                       uint64_t addr_max, uint64_t addr_trans,
1523                       uint64_t len)
1524 {
1525     uint8_t flags = read_and_write | (cacheable << 1);
1526 
1527     return aml_qword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
1528                              dec, addr_gran, addr_min, addr_max,
1529                              addr_trans, len, flags);
1530 }
1531 
1532 /* ACPI 1.0b: 6.4.2.2 DMA Format/6.4.2.2.1 ASL Macro for DMA Descriptor */
1533 Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
1534              uint8_t channel)
1535 {
1536     Aml *var = aml_alloc();
1537     uint8_t flags = sz | bm << 2 | typ << 5;
1538 
1539     assert(channel < 8);
1540     build_append_byte(var->buf, 0x2A);    /* Byte 0: DMA Descriptor */
1541     build_append_byte(var->buf, 1U << channel); /* Byte 1: _DMA - DmaChannel */
1542     build_append_byte(var->buf, flags);   /* Byte 2 */
1543     return var;
1544 }
1545 
1546 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefSleep */
1547 Aml *aml_sleep(uint64_t msec)
1548 {
1549     Aml *var = aml_alloc();
1550     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1551     build_append_byte(var->buf, 0x22); /* SleepOp */
1552     aml_append(var, aml_int(msec));
1553     return var;
1554 }
1555 
1556 static uint8_t Hex2Byte(const char *src)
1557 {
1558     int hi, lo;
1559 
1560     hi = Hex2Digit(src[0]);
1561     assert(hi >= 0);
1562     assert(hi <= 15);
1563 
1564     lo = Hex2Digit(src[1]);
1565     assert(lo >= 0);
1566     assert(lo <= 15);
1567     return (hi << 4) | lo;
1568 }
1569 
1570 /*
1571  * ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro)
1572  * e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1573  * call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
1574  */
1575 Aml *aml_touuid(const char *uuid)
1576 {
1577     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1578 
1579     assert(strlen(uuid) == 36);
1580     assert(uuid[8] == '-');
1581     assert(uuid[13] == '-');
1582     assert(uuid[18] == '-');
1583     assert(uuid[23] == '-');
1584 
1585     build_append_byte(var->buf, Hex2Byte(uuid + 6));  /* dd - at offset 00 */
1586     build_append_byte(var->buf, Hex2Byte(uuid + 4));  /* cc - at offset 01 */
1587     build_append_byte(var->buf, Hex2Byte(uuid + 2));  /* bb - at offset 02 */
1588     build_append_byte(var->buf, Hex2Byte(uuid + 0));  /* aa - at offset 03 */
1589 
1590     build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */
1591     build_append_byte(var->buf, Hex2Byte(uuid + 9));  /* ee - at offset 05 */
1592 
1593     build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */
1594     build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */
1595 
1596     build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */
1597     build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */
1598 
1599     build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */
1600     build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */
1601     build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */
1602     build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */
1603     build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */
1604     build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */
1605 
1606     return var;
1607 }
1608 
1609 /*
1610  * ACPI 2.0b: 16.2.3.6.4.3  Unicode Macro (Convert Ascii String To Unicode)
1611  */
1612 Aml *aml_unicode(const char *str)
1613 {
1614     int i = 0;
1615     Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1616 
1617     do {
1618         build_append_byte(var->buf, str[i]);
1619         build_append_byte(var->buf, 0);
1620         i++;
1621     } while (i <= strlen(str));
1622 
1623     return var;
1624 }
1625 
1626 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */
1627 Aml *aml_refof(Aml *arg)
1628 {
1629     Aml *var = aml_opcode(0x71 /* RefOfOp */);
1630     aml_append(var, arg);
1631     return var;
1632 }
1633 
1634 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
1635 Aml *aml_derefof(Aml *arg)
1636 {
1637     Aml *var = aml_opcode(0x83 /* DerefOfOp */);
1638     aml_append(var, arg);
1639     return var;
1640 }
1641 
1642 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSizeOf */
1643 Aml *aml_sizeof(Aml *arg)
1644 {
1645     Aml *var = aml_opcode(0x87 /* SizeOfOp */);
1646     aml_append(var, arg);
1647     return var;
1648 }
1649 
1650 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMutex */
1651 Aml *aml_mutex(const char *name, uint8_t sync_level)
1652 {
1653     Aml *var = aml_alloc();
1654     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1655     build_append_byte(var->buf, 0x01); /* MutexOp */
1656     build_append_namestring(var->buf, "%s", name);
1657     assert(!(sync_level & 0xF0));
1658     build_append_byte(var->buf, sync_level);
1659     return var;
1660 }
1661 
1662 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAcquire */
1663 Aml *aml_acquire(Aml *mutex, uint16_t timeout)
1664 {
1665     Aml *var = aml_alloc();
1666     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1667     build_append_byte(var->buf, 0x23); /* AcquireOp */
1668     aml_append(var, mutex);
1669     build_append_int_noprefix(var->buf, timeout, sizeof(timeout));
1670     return var;
1671 }
1672 
1673 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefRelease */
1674 Aml *aml_release(Aml *mutex)
1675 {
1676     Aml *var = aml_alloc();
1677     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1678     build_append_byte(var->buf, 0x27); /* ReleaseOp */
1679     aml_append(var, mutex);
1680     return var;
1681 }
1682 
1683 /* ACPI 1.0b: 16.2.5.1 Name Space Modifier Objects Encoding: DefAlias */
1684 Aml *aml_alias(const char *source_object, const char *alias_object)
1685 {
1686     Aml *var = aml_opcode(0x06 /* AliasOp */);
1687     aml_append(var, aml_name("%s", source_object));
1688     aml_append(var, aml_name("%s", alias_object));
1689     return var;
1690 }
1691 
1692 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
1693 Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
1694 {
1695     return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
1696                                  target);
1697 }
1698 
1699 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
1700 Aml *aml_object_type(Aml *object)
1701 {
1702     Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
1703     aml_append(var, object);
1704     return var;
1705 }
1706 
1707 void acpi_table_begin(AcpiTable *desc, GArray *array)
1708 {
1709 
1710     desc->array = array;
1711     desc->table_offset = array->len;
1712 
1713     /*
1714      * ACPI spec 1.0b
1715      * 5.2.3 System Description Table Header
1716      */
1717     g_assert(strlen(desc->sig) == 4);
1718     g_array_append_vals(array, desc->sig, 4); /* Signature */
1719     /*
1720      * reserve space for Length field, which will be patched by
1721      * acpi_table_end() when the table creation is finished.
1722      */
1723     build_append_int_noprefix(array, 0, 4); /* Length */
1724     build_append_int_noprefix(array, desc->rev, 1); /* Revision */
1725     build_append_int_noprefix(array, 0, 1); /* Checksum */
1726     build_append_padded_str(array, desc->oem_id, 6, '\0'); /* OEMID */
1727     /* OEM Table ID */
1728     build_append_padded_str(array, desc->oem_table_id, 8, '\0');
1729     build_append_int_noprefix(array, 1, 4); /* OEM Revision */
1730     g_array_append_vals(array, ACPI_BUILD_APPNAME8, 4); /* Creator ID */
1731     build_append_int_noprefix(array, 1, 4); /* Creator Revision */
1732 }
1733 
1734 void acpi_table_end(BIOSLinker *linker, AcpiTable *desc)
1735 {
1736     /*
1737      * ACPI spec 1.0b
1738      * 5.2.3 System Description Table Header
1739      * Table 5-2 DESCRIPTION_HEADER Fields
1740      */
1741     const unsigned checksum_offset = 9;
1742     uint32_t table_len = desc->array->len - desc->table_offset;
1743     uint32_t table_len_le = cpu_to_le32(table_len);
1744     gchar *len_ptr = &desc->array->data[desc->table_offset + 4];
1745 
1746     /* patch "Length" field that has been reserved by acpi_table_begin()
1747      * to the actual length, i.e. accumulated table length from
1748      * acpi_table_begin() till acpi_table_end()
1749      */
1750     memcpy(len_ptr, &table_len_le, sizeof table_len_le);
1751 
1752     bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
1753         desc->table_offset, table_len, desc->table_offset + checksum_offset);
1754 }
1755 
1756 void *acpi_data_push(GArray *table_data, unsigned size)
1757 {
1758     unsigned off = table_data->len;
1759     g_array_set_size(table_data, off + size);
1760     return table_data->data + off;
1761 }
1762 
1763 unsigned acpi_data_len(GArray *table)
1764 {
1765     assert(g_array_get_element_size(table) == 1);
1766     return table->len;
1767 }
1768 
1769 void acpi_add_table(GArray *table_offsets, GArray *table_data)
1770 {
1771     uint32_t offset = table_data->len;
1772     g_array_append_val(table_offsets, offset);
1773 }
1774 
1775 void acpi_build_tables_init(AcpiBuildTables *tables)
1776 {
1777     tables->rsdp = g_array_new(false, true /* clear */, 1);
1778     tables->table_data = g_array_new(false, true /* clear */, 1);
1779     tables->tcpalog = g_array_new(false, true /* clear */, 1);
1780     tables->vmgenid = g_array_new(false, true /* clear */, 1);
1781     tables->hardware_errors = g_array_new(false, true /* clear */, 1);
1782     tables->linker = bios_linker_loader_init();
1783 }
1784 
1785 void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
1786 {
1787     bios_linker_loader_cleanup(tables->linker);
1788     g_array_free(tables->rsdp, true);
1789     g_array_free(tables->table_data, true);
1790     g_array_free(tables->tcpalog, mfre);
1791     g_array_free(tables->vmgenid, mfre);
1792     g_array_free(tables->hardware_errors, mfre);
1793 }
1794 
1795 /*
1796  * ACPI spec 5.2.5.3 Root System Description Pointer (RSDP).
1797  * (Revision 1.0 or later)
1798  */
1799 void
1800 build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
1801 {
1802     int tbl_off = tbl->len; /* Table offset in the RSDP file */
1803 
1804     switch (rsdp_data->revision) {
1805     case 0:
1806         /* With ACPI 1.0, we must have an RSDT pointer */
1807         g_assert(rsdp_data->rsdt_tbl_offset);
1808         break;
1809     case 2:
1810         /* With ACPI 2.0+, we must have an XSDT pointer */
1811         g_assert(rsdp_data->xsdt_tbl_offset);
1812         break;
1813     default:
1814         /* Only revisions 0 (ACPI 1.0) and 2 (ACPI 2.0+) are valid for RSDP */
1815         g_assert_not_reached();
1816     }
1817 
1818     bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16,
1819                              true /* fseg memory */);
1820 
1821     g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */
1822     build_append_int_noprefix(tbl, 0, 1); /* Checksum */
1823     g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */
1824     build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */
1825     build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */
1826     if (rsdp_data->rsdt_tbl_offset) {
1827         /* RSDT address to be filled by guest linker */
1828         bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
1829                                        tbl_off + 16, 4,
1830                                        ACPI_BUILD_TABLE_FILE,
1831                                        *rsdp_data->rsdt_tbl_offset);
1832     }
1833 
1834     /* Checksum to be filled by guest linker */
1835     bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
1836                                     tbl_off, 20, /* ACPI rev 1.0 RSDP size */
1837                                     8);
1838 
1839     if (rsdp_data->revision == 0) {
1840         /* ACPI 1.0 RSDP, we're done */
1841         return;
1842     }
1843 
1844     build_append_int_noprefix(tbl, 36, 4); /* Length */
1845 
1846     /* XSDT address to be filled by guest linker */
1847     build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */
1848     /* We already validated our xsdt pointer */
1849     bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
1850                                    tbl_off + 24, 8,
1851                                    ACPI_BUILD_TABLE_FILE,
1852                                    *rsdp_data->xsdt_tbl_offset);
1853 
1854     build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */
1855     build_append_int_noprefix(tbl, 0, 3); /* Reserved */
1856 
1857     /* Extended checksum to be filled by Guest linker */
1858     bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
1859                                     tbl_off, 36, /* ACPI rev 2.0 RSDP size */
1860                                     32);
1861 }
1862 
1863 /*
1864  * ACPI 1.0 Root System Description Table (RSDT)
1865  */
1866 void
1867 build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1868            const char *oem_id, const char *oem_table_id)
1869 {
1870     int i;
1871     AcpiTable table = { .sig = "RSDT", .rev = 1,
1872                         .oem_id = oem_id, .oem_table_id = oem_table_id };
1873 
1874     acpi_table_begin(&table, table_data);
1875     for (i = 0; i < table_offsets->len; ++i) {
1876         uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
1877         uint32_t rsdt_entry_offset = table.array->len;
1878 
1879         /* reserve space for entry */
1880         build_append_int_noprefix(table.array, 0, 4);
1881 
1882         /* mark position of RSDT entry to be filled by Guest linker */
1883         bios_linker_loader_add_pointer(linker,
1884             ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, 4,
1885             ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1886 
1887     }
1888     acpi_table_end(linker, &table);
1889 }
1890 
1891 /*
1892  * ACPI 2.0 eXtended System Description Table (XSDT)
1893  */
1894 void
1895 build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1896            const char *oem_id, const char *oem_table_id)
1897 {
1898     int i;
1899     AcpiTable table = { .sig = "XSDT", .rev = 1,
1900                         .oem_id = oem_id, .oem_table_id = oem_table_id };
1901 
1902     acpi_table_begin(&table, table_data);
1903 
1904     for (i = 0; i < table_offsets->len; ++i) {
1905         uint64_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
1906         uint64_t xsdt_entry_offset = table.array->len;
1907 
1908         /* reserve space for entry */
1909         build_append_int_noprefix(table.array, 0, 8);
1910 
1911         /* mark position of RSDT entry to be filled by Guest linker */
1912         bios_linker_loader_add_pointer(linker,
1913             ACPI_BUILD_TABLE_FILE, xsdt_entry_offset, 8,
1914             ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1915     }
1916     acpi_table_end(linker, &table);
1917 }
1918 
1919 /*
1920  * ACPI spec, Revision 4.0
1921  * 5.2.16.2 Memory Affinity Structure
1922  */
1923 void build_srat_memory(GArray *table_data, uint64_t base,
1924                        uint64_t len, int node, MemoryAffinityFlags flags)
1925 {
1926     build_append_int_noprefix(table_data, 1, 1); /* Type */
1927     build_append_int_noprefix(table_data, 40, 1); /* Length */
1928     build_append_int_noprefix(table_data, node, 4); /* Proximity Domain */
1929     build_append_int_noprefix(table_data, 0, 2); /* Reserved */
1930     build_append_int_noprefix(table_data, base, 4); /* Base Address Low */
1931     /* Base Address High */
1932     build_append_int_noprefix(table_data, base >> 32, 4);
1933     build_append_int_noprefix(table_data, len, 4); /* Length Low */
1934     build_append_int_noprefix(table_data, len >> 32, 4); /* Length High */
1935     build_append_int_noprefix(table_data, 0, 4); /* Reserved */
1936     build_append_int_noprefix(table_data, flags, 4); /* Flags */
1937     build_append_int_noprefix(table_data, 0, 8); /* Reserved */
1938 }
1939 
1940 /*
1941  * ACPI spec 5.2.17 System Locality Distance Information Table
1942  * (Revision 2.0 or later)
1943  */
1944 void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
1945                 const char *oem_id, const char *oem_table_id)
1946 {
1947     int i, j;
1948     int nb_numa_nodes = ms->numa_state->num_nodes;
1949     AcpiTable table = { .sig = "SLIT", .rev = 1,
1950                         .oem_id = oem_id, .oem_table_id = oem_table_id };
1951 
1952     acpi_table_begin(&table, table_data);
1953 
1954     build_append_int_noprefix(table_data, nb_numa_nodes, 8);
1955     for (i = 0; i < nb_numa_nodes; i++) {
1956         for (j = 0; j < nb_numa_nodes; j++) {
1957             assert(ms->numa_state->nodes[i].distance[j]);
1958             build_append_int_noprefix(table_data,
1959                                       ms->numa_state->nodes[i].distance[j],
1960                                       1);
1961         }
1962     }
1963     acpi_table_end(linker, &table);
1964 }
1965 
1966 /*
1967  * ACPI spec, Revision 6.3
1968  * 5.2.29.1 Processor hierarchy node structure (Type 0)
1969  */
1970 static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
1971                                            uint32_t parent, uint32_t id,
1972                                            uint32_t *priv_rsrc,
1973                                            uint32_t priv_num)
1974 {
1975     int i;
1976 
1977     build_append_byte(tbl, 0);                 /* Type 0 - processor */
1978     build_append_byte(tbl, 20 + priv_num * 4); /* Length */
1979     build_append_int_noprefix(tbl, 0, 2);      /* Reserved */
1980     build_append_int_noprefix(tbl, flags, 4);  /* Flags */
1981     build_append_int_noprefix(tbl, parent, 4); /* Parent */
1982     build_append_int_noprefix(tbl, id, 4);     /* ACPI Processor ID */
1983 
1984     /* Number of private resources */
1985     build_append_int_noprefix(tbl, priv_num, 4);
1986 
1987     /* Private resources[N] */
1988     if (priv_num > 0) {
1989         assert(priv_rsrc);
1990         for (i = 0; i < priv_num; i++) {
1991             build_append_int_noprefix(tbl, priv_rsrc[i], 4);
1992         }
1993     }
1994 }
1995 
1996 void build_spcr(GArray *table_data, BIOSLinker *linker,
1997                 const AcpiSpcrData *f, const uint8_t rev,
1998                 const char *oem_id, const char *oem_table_id)
1999 {
2000     AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
2001                         .oem_table_id = oem_table_id };
2002 
2003     acpi_table_begin(&table, table_data);
2004     /* Interface type */
2005     build_append_int_noprefix(table_data, f->interface_type, 1);
2006     /* Reserved */
2007     build_append_int_noprefix(table_data, 0, 3);
2008     /* Base Address */
2009     build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
2010                      f->base_addr.offset, f->base_addr.size,
2011                      f->base_addr.addr);
2012     /* Interrupt type */
2013     build_append_int_noprefix(table_data, f->interrupt_type, 1);
2014     /* IRQ */
2015     build_append_int_noprefix(table_data, f->pc_interrupt, 1);
2016     /* Global System Interrupt */
2017     build_append_int_noprefix(table_data, f->interrupt, 4);
2018     /* Baud Rate */
2019     build_append_int_noprefix(table_data, f->baud_rate, 1);
2020     /* Parity */
2021     build_append_int_noprefix(table_data, f->parity, 1);
2022     /* Stop Bits */
2023     build_append_int_noprefix(table_data, f->stop_bits, 1);
2024     /* Flow Control */
2025     build_append_int_noprefix(table_data, f->flow_control, 1);
2026     /* Language */
2027     build_append_int_noprefix(table_data, f->language, 1);
2028     /* Terminal Type */
2029     build_append_int_noprefix(table_data, f->terminal_type, 1);
2030     /* PCI Device ID  */
2031     build_append_int_noprefix(table_data, f->pci_device_id, 2);
2032     /* PCI Vendor ID */
2033     build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
2034     /* PCI Bus Number */
2035     build_append_int_noprefix(table_data, f->pci_bus, 1);
2036     /* PCI Device Number */
2037     build_append_int_noprefix(table_data, f->pci_device, 1);
2038     /* PCI Function Number */
2039     build_append_int_noprefix(table_data, f->pci_function, 1);
2040     /* PCI Flags */
2041     build_append_int_noprefix(table_data, f->pci_flags, 4);
2042     /* PCI Segment */
2043     build_append_int_noprefix(table_data, f->pci_segment, 1);
2044     /* Reserved */
2045     build_append_int_noprefix(table_data, 0, 4);
2046 
2047     acpi_table_end(linker, &table);
2048 }
2049 /*
2050  * ACPI spec, Revision 6.3
2051  * 5.2.29 Processor Properties Topology Table (PPTT)
2052  */
2053 void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
2054                 const char *oem_id, const char *oem_table_id)
2055 {
2056     MachineClass *mc = MACHINE_GET_CLASS(ms);
2057     CPUArchIdList *cpus = ms->possible_cpus;
2058     int64_t socket_id = -1, cluster_id = -1, core_id = -1;
2059     uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
2060     uint32_t pptt_start = table_data->len;
2061     int n;
2062     AcpiTable table = { .sig = "PPTT", .rev = 2,
2063                         .oem_id = oem_id, .oem_table_id = oem_table_id };
2064 
2065     acpi_table_begin(&table, table_data);
2066 
2067     /*
2068      * This works with the assumption that cpus[n].props.*_id has been
2069      * sorted from top to down levels in mc->possible_cpu_arch_ids().
2070      * Otherwise, the unexpected and duplicated containers will be
2071      * created.
2072      */
2073     for (n = 0; n < cpus->len; n++) {
2074         if (cpus->cpus[n].props.socket_id != socket_id) {
2075             assert(cpus->cpus[n].props.socket_id > socket_id);
2076             socket_id = cpus->cpus[n].props.socket_id;
2077             cluster_id = -1;
2078             core_id = -1;
2079             socket_offset = table_data->len - pptt_start;
2080             build_processor_hierarchy_node(table_data,
2081                 (1 << 0), /* Physical package */
2082                 0, socket_id, NULL, 0);
2083         }
2084 
2085         if (mc->smp_props.clusters_supported && mc->smp_props.has_clusters) {
2086             if (cpus->cpus[n].props.cluster_id != cluster_id) {
2087                 assert(cpus->cpus[n].props.cluster_id > cluster_id);
2088                 cluster_id = cpus->cpus[n].props.cluster_id;
2089                 core_id = -1;
2090                 cluster_offset = table_data->len - pptt_start;
2091                 build_processor_hierarchy_node(table_data,
2092                     (0 << 0), /* Not a physical package */
2093                     socket_offset, cluster_id, NULL, 0);
2094             }
2095         } else {
2096             cluster_offset = socket_offset;
2097         }
2098 
2099         if (ms->smp.threads == 1) {
2100             build_processor_hierarchy_node(table_data,
2101                 (1 << 1) | /* ACPI Processor ID valid */
2102                 (1 << 3),  /* Node is a Leaf */
2103                 cluster_offset, n, NULL, 0);
2104         } else {
2105             if (cpus->cpus[n].props.core_id != core_id) {
2106                 assert(cpus->cpus[n].props.core_id > core_id);
2107                 core_id = cpus->cpus[n].props.core_id;
2108                 core_offset = table_data->len - pptt_start;
2109                 build_processor_hierarchy_node(table_data,
2110                     (0 << 0), /* Not a physical package */
2111                     cluster_offset, core_id, NULL, 0);
2112             }
2113 
2114             build_processor_hierarchy_node(table_data,
2115                 (1 << 1) | /* ACPI Processor ID valid */
2116                 (1 << 2) | /* Processor is a Thread */
2117                 (1 << 3),  /* Node is a Leaf */
2118                 core_offset, n, NULL, 0);
2119         }
2120     }
2121 
2122     acpi_table_end(linker, &table);
2123 }
2124 
2125 /* build rev1/rev3/rev5.1/rev6.0 FADT */
2126 void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
2127                 const char *oem_id, const char *oem_table_id)
2128 {
2129     int off;
2130     AcpiTable table = { .sig = "FACP", .rev = f->rev,
2131                         .oem_id = oem_id, .oem_table_id = oem_table_id };
2132 
2133     acpi_table_begin(&table, tbl);
2134 
2135     /* FACS address to be filled by Guest linker at runtime */
2136     off = tbl->len;
2137     build_append_int_noprefix(tbl, 0, 4); /* FIRMWARE_CTRL */
2138     if (f->facs_tbl_offset) { /* don't patch if not supported by platform */
2139         bios_linker_loader_add_pointer(linker,
2140             ACPI_BUILD_TABLE_FILE, off, 4,
2141             ACPI_BUILD_TABLE_FILE, *f->facs_tbl_offset);
2142     }
2143 
2144     /* DSDT address to be filled by Guest linker at runtime */
2145     off = tbl->len;
2146     build_append_int_noprefix(tbl, 0, 4); /* DSDT */
2147     if (f->dsdt_tbl_offset) { /* don't patch if not supported by platform */
2148         bios_linker_loader_add_pointer(linker,
2149             ACPI_BUILD_TABLE_FILE, off, 4,
2150             ACPI_BUILD_TABLE_FILE, *f->dsdt_tbl_offset);
2151     }
2152 
2153     /* ACPI1.0: INT_MODEL, ACPI2.0+: Reserved */
2154     build_append_int_noprefix(tbl, f->int_model /* Multiple APIC */, 1);
2155     /* Preferred_PM_Profile */
2156     build_append_int_noprefix(tbl, 0 /* Unspecified */, 1);
2157     build_append_int_noprefix(tbl, f->sci_int, 2); /* SCI_INT */
2158     build_append_int_noprefix(tbl, f->smi_cmd, 4); /* SMI_CMD */
2159     build_append_int_noprefix(tbl, f->acpi_enable_cmd, 1); /* ACPI_ENABLE */
2160     build_append_int_noprefix(tbl, f->acpi_disable_cmd, 1); /* ACPI_DISABLE */
2161     build_append_int_noprefix(tbl, 0 /* not supported */, 1); /* S4BIOS_REQ */
2162     /* ACPI1.0: Reserved, ACPI2.0+: PSTATE_CNT */
2163     build_append_int_noprefix(tbl, 0, 1);
2164     build_append_int_noprefix(tbl, f->pm1a_evt.address, 4); /* PM1a_EVT_BLK */
2165     build_append_int_noprefix(tbl, 0, 4); /* PM1b_EVT_BLK */
2166     build_append_int_noprefix(tbl, f->pm1a_cnt.address, 4); /* PM1a_CNT_BLK */
2167     build_append_int_noprefix(tbl, 0, 4); /* PM1b_CNT_BLK */
2168     build_append_int_noprefix(tbl, 0, 4); /* PM2_CNT_BLK */
2169     build_append_int_noprefix(tbl, f->pm_tmr.address, 4); /* PM_TMR_BLK */
2170     build_append_int_noprefix(tbl, f->gpe0_blk.address, 4); /* GPE0_BLK */
2171     build_append_int_noprefix(tbl, 0, 4); /* GPE1_BLK */
2172     /* PM1_EVT_LEN */
2173     build_append_int_noprefix(tbl, f->pm1a_evt.bit_width / 8, 1);
2174     /* PM1_CNT_LEN */
2175     build_append_int_noprefix(tbl, f->pm1a_cnt.bit_width / 8, 1);
2176     build_append_int_noprefix(tbl, 0, 1); /* PM2_CNT_LEN */
2177     build_append_int_noprefix(tbl, f->pm_tmr.bit_width / 8, 1); /* PM_TMR_LEN */
2178     /* GPE0_BLK_LEN */
2179     build_append_int_noprefix(tbl, f->gpe0_blk.bit_width / 8, 1);
2180     build_append_int_noprefix(tbl, 0, 1); /* GPE1_BLK_LEN */
2181     build_append_int_noprefix(tbl, 0, 1); /* GPE1_BASE */
2182     build_append_int_noprefix(tbl, 0, 1); /* CST_CNT */
2183     build_append_int_noprefix(tbl, f->plvl2_lat, 2); /* P_LVL2_LAT */
2184     build_append_int_noprefix(tbl, f->plvl3_lat, 2); /* P_LVL3_LAT */
2185     build_append_int_noprefix(tbl, 0, 2); /* FLUSH_SIZE */
2186     build_append_int_noprefix(tbl, 0, 2); /* FLUSH_STRIDE */
2187     build_append_int_noprefix(tbl, 0, 1); /* DUTY_OFFSET */
2188     build_append_int_noprefix(tbl, 0, 1); /* DUTY_WIDTH */
2189     build_append_int_noprefix(tbl, 0, 1); /* DAY_ALRM */
2190     build_append_int_noprefix(tbl, 0, 1); /* MON_ALRM */
2191     build_append_int_noprefix(tbl, f->rtc_century, 1); /* CENTURY */
2192     /* IAPC_BOOT_ARCH */
2193     if (f->rev == 1) {
2194         build_append_int_noprefix(tbl, 0, 2);
2195     } else {
2196         /* since ACPI v2.0 */
2197         build_append_int_noprefix(tbl, f->iapc_boot_arch, 2);
2198     }
2199     build_append_int_noprefix(tbl, 0, 1); /* Reserved */
2200     build_append_int_noprefix(tbl, f->flags, 4); /* Flags */
2201 
2202     if (f->rev == 1) {
2203         goto done;
2204     }
2205 
2206     build_append_gas_from_struct(tbl, &f->reset_reg); /* RESET_REG */
2207     build_append_int_noprefix(tbl, f->reset_val, 1); /* RESET_VALUE */
2208     /* Since ACPI 5.1 */
2209     if ((f->rev >= 6) || ((f->rev == 5) && f->minor_ver > 0)) {
2210         build_append_int_noprefix(tbl, f->arm_boot_arch, 2); /* ARM_BOOT_ARCH */
2211         /* FADT Minor Version */
2212         build_append_int_noprefix(tbl, f->minor_ver, 1);
2213     } else {
2214         build_append_int_noprefix(tbl, 0, 3); /* Reserved up to ACPI 5.0 */
2215     }
2216     build_append_int_noprefix(tbl, 0, 8); /* X_FIRMWARE_CTRL */
2217 
2218     /* XDSDT address to be filled by Guest linker at runtime */
2219     off = tbl->len;
2220     build_append_int_noprefix(tbl, 0, 8); /* X_DSDT */
2221     if (f->xdsdt_tbl_offset) {
2222         bios_linker_loader_add_pointer(linker,
2223             ACPI_BUILD_TABLE_FILE, off, 8,
2224             ACPI_BUILD_TABLE_FILE, *f->xdsdt_tbl_offset);
2225     }
2226 
2227     build_append_gas_from_struct(tbl, &f->pm1a_evt); /* X_PM1a_EVT_BLK */
2228     /* X_PM1b_EVT_BLK */
2229     build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
2230     build_append_gas_from_struct(tbl, &f->pm1a_cnt); /* X_PM1a_CNT_BLK */
2231     /* X_PM1b_CNT_BLK */
2232     build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
2233     /* X_PM2_CNT_BLK */
2234     build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
2235     build_append_gas_from_struct(tbl, &f->pm_tmr); /* X_PM_TMR_BLK */
2236     build_append_gas_from_struct(tbl, &f->gpe0_blk); /* X_GPE0_BLK */
2237     build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0); /* X_GPE1_BLK */
2238 
2239     if (f->rev <= 4) {
2240         goto done;
2241     }
2242 
2243     /* SLEEP_CONTROL_REG */
2244     build_append_gas_from_struct(tbl, &f->sleep_ctl);
2245     /* SLEEP_STATUS_REG */
2246     build_append_gas_from_struct(tbl, &f->sleep_sts);
2247 
2248     if (f->rev == 5) {
2249         goto done;
2250     }
2251 
2252     /* Hypervisor Vendor Identity */
2253     build_append_padded_str(tbl, "QEMU", 8, '\0');
2254 
2255     /* TODO: extra fields need to be added to support revisions above rev6 */
2256     assert(f->rev == 6);
2257 
2258 done:
2259     acpi_table_end(linker, &table);
2260 }
2261 
2262 #ifdef CONFIG_TPM
2263 /*
2264  * build_tpm2 - Build the TPM2 table as specified in
2265  * table 7: TCG Hardware Interface Description Table Format for TPM 2.0
2266  * of TCG ACPI Specification, Family “1.2” and “2.0”, Version 1.2, Rev 8
2267  */
2268 void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
2269                 const char *oem_id, const char *oem_table_id)
2270 {
2271     uint8_t start_method_params[12] = {};
2272     unsigned log_addr_offset;
2273     uint64_t control_area_start_address;
2274     TPMIf *tpmif = tpm_find();
2275     uint32_t start_method;
2276     AcpiTable table = { .sig = "TPM2", .rev = 4,
2277                         .oem_id = oem_id, .oem_table_id = oem_table_id };
2278 
2279     acpi_table_begin(&table, table_data);
2280 
2281     /* Platform Class */
2282     build_append_int_noprefix(table_data, TPM2_ACPI_CLASS_CLIENT, 2);
2283     /* Reserved */
2284     build_append_int_noprefix(table_data, 0, 2);
2285     if (TPM_IS_TIS_ISA(tpmif) || TPM_IS_TIS_SYSBUS(tpmif)) {
2286         control_area_start_address = 0;
2287         start_method = TPM2_START_METHOD_MMIO;
2288     } else if (TPM_IS_CRB(tpmif)) {
2289         control_area_start_address = TPM_CRB_ADDR_CTRL;
2290         start_method = TPM2_START_METHOD_CRB;
2291     } else {
2292         g_assert_not_reached();
2293     }
2294     /* Address of Control Area */
2295     build_append_int_noprefix(table_data, control_area_start_address, 8);
2296     /* Start Method */
2297     build_append_int_noprefix(table_data, start_method, 4);
2298 
2299     /* Platform Specific Parameters */
2300     g_array_append_vals(table_data, &start_method_params,
2301                         ARRAY_SIZE(start_method_params));
2302 
2303     /* Log Area Minimum Length */
2304     build_append_int_noprefix(table_data, TPM_LOG_AREA_MINIMUM_SIZE, 4);
2305 
2306     acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
2307     bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, tcpalog, 1,
2308                              false);
2309 
2310     log_addr_offset = table_data->len;
2311 
2312     /* Log Area Start Address to be filled by Guest linker */
2313     build_append_int_noprefix(table_data, 0, 8);
2314     bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
2315                                    log_addr_offset, 8,
2316                                    ACPI_BUILD_TPMLOG_FILE, 0);
2317     acpi_table_end(linker, &table);
2318 }
2319 #endif
2320 
2321 Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set, uint32_t io_offset,
2322                uint32_t mmio32_offset, uint64_t mmio64_offset,
2323                uint16_t bus_nr_offset)
2324 {
2325     Aml *crs = aml_resource_template();
2326     CrsRangeSet temp_range_set;
2327     CrsRangeEntry *entry;
2328     uint8_t max_bus = pci_bus_num(host->bus);
2329     uint8_t type;
2330     int devfn;
2331     int i;
2332 
2333     crs_range_set_init(&temp_range_set);
2334     for (devfn = 0; devfn < ARRAY_SIZE(host->bus->devices); devfn++) {
2335         uint64_t range_base, range_limit;
2336         PCIDevice *dev = host->bus->devices[devfn];
2337 
2338         if (!dev) {
2339             continue;
2340         }
2341 
2342         for (i = 0; i < PCI_NUM_REGIONS; i++) {
2343             PCIIORegion *r = &dev->io_regions[i];
2344 
2345             range_base = r->addr;
2346             range_limit = r->addr + r->size - 1;
2347 
2348             /*
2349              * Work-around for old bioses
2350              * that do not support multiple root buses
2351              */
2352             if (!range_base || range_base > range_limit) {
2353                 continue;
2354             }
2355 
2356             if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
2357                 crs_range_insert(temp_range_set.io_ranges,
2358                                  range_base, range_limit);
2359             } else { /* "memory" */
2360                 uint64_t length = range_limit - range_base + 1;
2361                 if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
2362                     crs_range_insert(temp_range_set.mem_ranges, range_base,
2363                                      range_limit);
2364                 } else {
2365                     crs_range_insert(temp_range_set.mem_64bit_ranges,
2366                                      range_base, range_limit);
2367                 }
2368             }
2369         }
2370 
2371         type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
2372         if (type == PCI_HEADER_TYPE_BRIDGE) {
2373             uint8_t subordinate = dev->config[PCI_SUBORDINATE_BUS];
2374             if (subordinate > max_bus) {
2375                 max_bus = subordinate;
2376             }
2377 
2378             range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
2379             range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
2380 
2381              /*
2382               * Work-around for old bioses
2383               * that do not support multiple root buses
2384               */
2385             if (range_base && range_base <= range_limit) {
2386                 crs_range_insert(temp_range_set.io_ranges,
2387                                  range_base, range_limit);
2388             }
2389 
2390             range_base =
2391                 pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
2392             range_limit =
2393                 pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
2394 
2395             /*
2396              * Work-around for old bioses
2397              * that do not support multiple root buses
2398              */
2399             if (range_base && range_base <= range_limit) {
2400                 uint64_t length = range_limit - range_base + 1;
2401                 if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
2402                     crs_range_insert(temp_range_set.mem_ranges,
2403                                      range_base, range_limit);
2404                 } else {
2405                     crs_range_insert(temp_range_set.mem_64bit_ranges,
2406                                      range_base, range_limit);
2407                 }
2408             }
2409 
2410             range_base =
2411                 pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
2412             range_limit =
2413                 pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
2414 
2415             /*
2416              * Work-around for old bioses
2417              * that do not support multiple root buses
2418              */
2419             if (range_base && range_base <= range_limit) {
2420                 uint64_t length = range_limit - range_base + 1;
2421                 if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
2422                     crs_range_insert(temp_range_set.mem_ranges,
2423                                      range_base, range_limit);
2424                 } else {
2425                     crs_range_insert(temp_range_set.mem_64bit_ranges,
2426                                      range_base, range_limit);
2427                 }
2428             }
2429         }
2430     }
2431 
2432     crs_range_merge(temp_range_set.io_ranges);
2433     for (i = 0; i < temp_range_set.io_ranges->len; i++) {
2434         entry = g_ptr_array_index(temp_range_set.io_ranges, i);
2435         aml_append(crs,
2436                    aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED,
2437                                 AML_POS_DECODE, AML_ENTIRE_RANGE,
2438                                 0, entry->base, entry->limit, io_offset,
2439                                 entry->limit - entry->base + 1));
2440         crs_range_insert(range_set->io_ranges, entry->base, entry->limit);
2441     }
2442 
2443     crs_range_merge(temp_range_set.mem_ranges);
2444     for (i = 0; i < temp_range_set.mem_ranges->len; i++) {
2445         entry = g_ptr_array_index(temp_range_set.mem_ranges, i);
2446         assert(entry->limit <= UINT32_MAX &&
2447                (entry->limit - entry->base + 1) <= UINT32_MAX);
2448         aml_append(crs,
2449                    aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
2450                                     AML_MAX_FIXED, AML_NON_CACHEABLE,
2451                                     AML_READ_WRITE,
2452                                     0, entry->base, entry->limit, mmio32_offset,
2453                                     entry->limit - entry->base + 1));
2454         crs_range_insert(range_set->mem_ranges, entry->base, entry->limit);
2455     }
2456 
2457     crs_range_merge(temp_range_set.mem_64bit_ranges);
2458     for (i = 0; i < temp_range_set.mem_64bit_ranges->len; i++) {
2459         entry = g_ptr_array_index(temp_range_set.mem_64bit_ranges, i);
2460         aml_append(crs,
2461                    aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED,
2462                                     AML_MAX_FIXED, AML_NON_CACHEABLE,
2463                                     AML_READ_WRITE,
2464                                     0, entry->base, entry->limit, mmio64_offset,
2465                                     entry->limit - entry->base + 1));
2466         crs_range_insert(range_set->mem_64bit_ranges,
2467                          entry->base, entry->limit);
2468     }
2469 
2470     crs_range_set_free(&temp_range_set);
2471 
2472     aml_append(crs,
2473         aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
2474                             0,
2475                             pci_bus_num(host->bus),
2476                             max_bus,
2477                             bus_nr_offset,
2478                             max_bus - pci_bus_num(host->bus) + 1));
2479 
2480     return crs;
2481 }
2482 
2483 /* ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors */
2484 static Aml *aml_serial_bus_device(uint8_t serial_bus_type, uint8_t flags,
2485                                   uint16_t type_flags,
2486                                   uint8_t revid, uint16_t data_length,
2487                                   uint16_t resource_source_len)
2488 {
2489     Aml *var = aml_alloc();
2490     uint16_t length = data_length + resource_source_len + 9;
2491 
2492     build_append_byte(var->buf, 0x8e); /* Serial Bus Connection Descriptor */
2493     build_append_int_noprefix(var->buf, length, sizeof(length));
2494     build_append_byte(var->buf, 1);    /* Revision ID */
2495     build_append_byte(var->buf, 0);    /* Resource Source Index */
2496     build_append_byte(var->buf, serial_bus_type); /* Serial Bus Type */
2497     build_append_byte(var->buf, flags); /* General Flags */
2498     build_append_int_noprefix(var->buf, type_flags, /* Type Specific Flags */
2499                               sizeof(type_flags));
2500     build_append_byte(var->buf, revid); /* Type Specification Revision ID */
2501     build_append_int_noprefix(var->buf, data_length, sizeof(data_length));
2502 
2503     return var;
2504 }
2505 
2506 /* ACPI 5.0: 6.4.3.8.2.1 I2C Serial Bus Connection Resource Descriptor */
2507 Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source)
2508 {
2509     uint16_t resource_source_len = strlen(resource_source) + 1;
2510     Aml *var = aml_serial_bus_device(AML_SERIAL_BUS_TYPE_I2C, 0, 0, 1,
2511                                      6, resource_source_len);
2512 
2513     /* Connection Speed.  Just set to 100K for now, it doesn't really matter. */
2514     build_append_int_noprefix(var->buf, 100000, 4);
2515     build_append_int_noprefix(var->buf, address, sizeof(address));
2516 
2517     /* This is a string, not a name, so just copy it directly in. */
2518     g_array_append_vals(var->buf, resource_source, resource_source_len);
2519 
2520     return var;
2521 }
2522