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