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