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