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