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