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