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