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