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 <stdio.h> 23 #include <stdarg.h> 24 #include <assert.h> 25 #include <stdbool.h> 26 #include <string.h> 27 #include "hw/acpi/aml-build.h" 28 #include "qemu/bswap.h" 29 #include "qemu/bitops.h" 30 #include "hw/acpi/bios-linker-loader.h" 31 32 static GArray *build_alloc_array(void) 33 { 34 return g_array_new(false, true /* clear */, 1); 35 } 36 37 static void build_free_array(GArray *array) 38 { 39 g_array_free(array, true); 40 } 41 42 static void build_prepend_byte(GArray *array, uint8_t val) 43 { 44 g_array_prepend_val(array, val); 45 } 46 47 static void build_append_byte(GArray *array, uint8_t val) 48 { 49 g_array_append_val(array, val); 50 } 51 52 static void build_append_array(GArray *array, GArray *val) 53 { 54 g_array_append_vals(array, val->data, val->len); 55 } 56 57 #define ACPI_NAMESEG_LEN 4 58 59 static void 60 build_append_nameseg(GArray *array, const char *seg) 61 { 62 /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */ 63 int len; 64 65 len = strlen(seg); 66 assert(len <= ACPI_NAMESEG_LEN); 67 68 g_array_append_vals(array, seg, len); 69 /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */ 70 g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len); 71 } 72 73 static void GCC_FMT_ATTR(2, 0) 74 build_append_namestringv(GArray *array, const char *format, va_list ap) 75 { 76 /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */ 77 char *s; 78 int len; 79 va_list va_len; 80 char **segs; 81 char **segs_iter; 82 int seg_count = 0; 83 84 va_copy(va_len, ap); 85 len = vsnprintf(NULL, 0, format, va_len); 86 va_end(va_len); 87 len += 1; 88 s = g_new(typeof(*s), len); 89 90 len = vsnprintf(s, len, format, ap); 91 92 segs = g_strsplit(s, ".", 0); 93 g_free(s); 94 95 /* count segments */ 96 segs_iter = segs; 97 while (*segs_iter) { 98 ++segs_iter; 99 ++seg_count; 100 } 101 /* 102 * ACPI 5.0 spec: 20.2.2 Name Objects Encoding: 103 * "SegCount can be from 1 to 255" 104 */ 105 assert(seg_count > 0 && seg_count <= 255); 106 107 /* handle RootPath || PrefixPath */ 108 s = *segs; 109 while (*s == '\\' || *s == '^') { 110 build_append_byte(array, *s); 111 ++s; 112 } 113 114 switch (seg_count) { 115 case 1: 116 if (!*s) { 117 build_append_byte(array, 0x00); /* NullName */ 118 } else { 119 build_append_nameseg(array, s); 120 } 121 break; 122 123 case 2: 124 build_append_byte(array, 0x2E); /* DualNamePrefix */ 125 build_append_nameseg(array, s); 126 build_append_nameseg(array, segs[1]); 127 break; 128 default: 129 build_append_byte(array, 0x2F); /* MultiNamePrefix */ 130 build_append_byte(array, seg_count); 131 132 /* handle the 1st segment manually due to prefix/root path */ 133 build_append_nameseg(array, s); 134 135 /* add the rest of segments */ 136 segs_iter = segs + 1; 137 while (*segs_iter) { 138 build_append_nameseg(array, *segs_iter); 139 ++segs_iter; 140 } 141 break; 142 } 143 g_strfreev(segs); 144 } 145 146 GCC_FMT_ATTR(2, 3) 147 static void build_append_namestring(GArray *array, const char *format, ...) 148 { 149 va_list ap; 150 151 va_start(ap, format); 152 build_append_namestringv(array, format, ap); 153 va_end(ap); 154 } 155 156 /* 5.4 Definition Block Encoding */ 157 enum { 158 PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */ 159 PACKAGE_LENGTH_2BYTE_SHIFT = 4, 160 PACKAGE_LENGTH_3BYTE_SHIFT = 12, 161 PACKAGE_LENGTH_4BYTE_SHIFT = 20, 162 }; 163 164 static void 165 build_prepend_package_length(GArray *package, unsigned length, bool incl_self) 166 { 167 uint8_t byte; 168 unsigned length_bytes; 169 170 if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) { 171 length_bytes = 1; 172 } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) { 173 length_bytes = 2; 174 } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) { 175 length_bytes = 3; 176 } else { 177 length_bytes = 4; 178 } 179 180 /* 181 * NamedField uses PkgLength encoding but it doesn't include length 182 * of PkgLength itself. 183 */ 184 if (incl_self) { 185 /* 186 * PkgLength is the length of the inclusive length of the data 187 * and PkgLength's length itself when used for terms with 188 * explitit length. 189 */ 190 length += length_bytes; 191 } 192 193 switch (length_bytes) { 194 case 1: 195 byte = length; 196 build_prepend_byte(package, byte); 197 return; 198 case 4: 199 byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT; 200 build_prepend_byte(package, byte); 201 length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1; 202 /* fall through */ 203 case 3: 204 byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT; 205 build_prepend_byte(package, byte); 206 length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1; 207 /* fall through */ 208 case 2: 209 byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT; 210 build_prepend_byte(package, byte); 211 length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1; 212 /* fall through */ 213 } 214 /* 215 * Most significant two bits of byte zero indicate how many following bytes 216 * are in PkgLength encoding. 217 */ 218 byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length; 219 build_prepend_byte(package, byte); 220 } 221 222 static void 223 build_append_pkg_length(GArray *array, unsigned length, bool incl_self) 224 { 225 GArray *tmp = build_alloc_array(); 226 227 build_prepend_package_length(tmp, length, incl_self); 228 build_append_array(array, tmp); 229 build_free_array(tmp); 230 } 231 232 static void build_package(GArray *package, uint8_t op) 233 { 234 build_prepend_package_length(package, package->len, true); 235 build_prepend_byte(package, op); 236 } 237 238 static void build_extop_package(GArray *package, uint8_t op) 239 { 240 build_package(package, op); 241 build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ 242 } 243 244 static void build_append_int_noprefix(GArray *table, uint64_t value, int size) 245 { 246 int i; 247 248 for (i = 0; i < size; ++i) { 249 build_append_byte(table, value & 0xFF); 250 value = value >> 8; 251 } 252 } 253 254 static void build_append_int(GArray *table, uint64_t value) 255 { 256 if (value == 0x00) { 257 build_append_byte(table, 0x00); /* ZeroOp */ 258 } else if (value == 0x01) { 259 build_append_byte(table, 0x01); /* OneOp */ 260 } else if (value <= 0xFF) { 261 build_append_byte(table, 0x0A); /* BytePrefix */ 262 build_append_int_noprefix(table, value, 1); 263 } else if (value <= 0xFFFF) { 264 build_append_byte(table, 0x0B); /* WordPrefix */ 265 build_append_int_noprefix(table, value, 2); 266 } else if (value <= 0xFFFFFFFF) { 267 build_append_byte(table, 0x0C); /* DWordPrefix */ 268 build_append_int_noprefix(table, value, 4); 269 } else { 270 build_append_byte(table, 0x0E); /* QWordPrefix */ 271 build_append_int_noprefix(table, value, 8); 272 } 273 } 274 275 static GPtrArray *alloc_list; 276 277 static Aml *aml_alloc(void) 278 { 279 Aml *var = g_new0(typeof(*var), 1); 280 281 g_ptr_array_add(alloc_list, var); 282 var->block_flags = AML_NO_OPCODE; 283 var->buf = build_alloc_array(); 284 return var; 285 } 286 287 static Aml *aml_opcode(uint8_t op) 288 { 289 Aml *var = aml_alloc(); 290 291 var->op = op; 292 var->block_flags = AML_OPCODE; 293 return var; 294 } 295 296 static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags) 297 { 298 Aml *var = aml_alloc(); 299 300 var->op = op; 301 var->block_flags = flags; 302 return var; 303 } 304 305 static void aml_free(gpointer data, gpointer user_data) 306 { 307 Aml *var = data; 308 build_free_array(var->buf); 309 } 310 311 Aml *init_aml_allocator(void) 312 { 313 Aml *var; 314 315 assert(!alloc_list); 316 alloc_list = g_ptr_array_new(); 317 var = aml_alloc(); 318 return var; 319 } 320 321 void free_aml_allocator(void) 322 { 323 g_ptr_array_foreach(alloc_list, aml_free, NULL); 324 g_ptr_array_free(alloc_list, true); 325 alloc_list = 0; 326 } 327 328 /* pack data with DefBuffer encoding */ 329 static void build_buffer(GArray *array, uint8_t op) 330 { 331 GArray *data = build_alloc_array(); 332 333 build_append_int(data, array->len); 334 g_array_prepend_vals(array, data->data, data->len); 335 build_free_array(data); 336 build_package(array, op); 337 } 338 339 void aml_append(Aml *parent_ctx, Aml *child) 340 { 341 GArray *buf = build_alloc_array(); 342 build_append_array(buf, child->buf); 343 344 switch (child->block_flags) { 345 case AML_OPCODE: 346 build_append_byte(parent_ctx->buf, child->op); 347 break; 348 case AML_EXT_PACKAGE: 349 build_extop_package(buf, child->op); 350 break; 351 case AML_PACKAGE: 352 build_package(buf, child->op); 353 break; 354 case AML_RES_TEMPLATE: 355 build_append_byte(buf, 0x79); /* EndTag */ 356 /* 357 * checksum operations are treated as succeeded if checksum 358 * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag] 359 */ 360 build_append_byte(buf, 0); 361 /* fall through, to pack resources in buffer */ 362 case AML_BUFFER: 363 build_buffer(buf, child->op); 364 break; 365 case AML_NO_OPCODE: 366 break; 367 default: 368 assert(0); 369 break; 370 } 371 build_append_array(parent_ctx->buf, buf); 372 build_free_array(buf); 373 } 374 375 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */ 376 Aml *aml_scope(const char *name_format, ...) 377 { 378 va_list ap; 379 Aml *var = aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE); 380 va_start(ap, name_format); 381 build_append_namestringv(var->buf, name_format, ap); 382 va_end(ap); 383 return var; 384 } 385 386 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */ 387 Aml *aml_return(Aml *val) 388 { 389 Aml *var = aml_opcode(0xA4 /* ReturnOp */); 390 aml_append(var, val); 391 return var; 392 } 393 394 /* 395 * ACPI 1.0b: 16.2.3 Data Objects Encoding: 396 * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp 397 */ 398 Aml *aml_int(const uint64_t val) 399 { 400 Aml *var = aml_alloc(); 401 build_append_int(var->buf, val); 402 return var; 403 } 404 405 /* 406 * helper to construct NameString, which returns Aml object 407 * for using with aml_append or other aml_* terms 408 */ 409 Aml *aml_name(const char *name_format, ...) 410 { 411 va_list ap; 412 Aml *var = aml_alloc(); 413 va_start(ap, name_format); 414 build_append_namestringv(var->buf, name_format, ap); 415 va_end(ap); 416 return var; 417 } 418 419 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */ 420 Aml *aml_name_decl(const char *name, Aml *val) 421 { 422 Aml *var = aml_opcode(0x08 /* NameOp */); 423 build_append_namestring(var->buf, "%s", name); 424 aml_append(var, val); 425 return var; 426 } 427 428 /* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */ 429 Aml *aml_arg(int pos) 430 { 431 Aml *var; 432 uint8_t op = 0x68 /* ARG0 op */ + pos; 433 434 assert(pos <= 6); 435 var = aml_opcode(op); 436 return var; 437 } 438 439 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */ 440 Aml *aml_store(Aml *val, Aml *target) 441 { 442 Aml *var = aml_opcode(0x70 /* StoreOp */); 443 aml_append(var, val); 444 aml_append(var, target); 445 return var; 446 } 447 448 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */ 449 Aml *aml_and(Aml *arg1, Aml *arg2) 450 { 451 Aml *var = aml_opcode(0x7B /* AndOp */); 452 aml_append(var, arg1); 453 aml_append(var, arg2); 454 build_append_byte(var->buf, 0x00 /* NullNameOp */); 455 return var; 456 } 457 458 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */ 459 Aml *aml_or(Aml *arg1, Aml *arg2) 460 { 461 Aml *var = aml_opcode(0x7D /* OrOp */); 462 aml_append(var, arg1); 463 aml_append(var, arg2); 464 build_append_byte(var->buf, 0x00 /* NullNameOp */); 465 return var; 466 } 467 468 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */ 469 Aml *aml_notify(Aml *arg1, Aml *arg2) 470 { 471 Aml *var = aml_opcode(0x86 /* NotifyOp */); 472 aml_append(var, arg1); 473 aml_append(var, arg2); 474 return var; 475 } 476 477 /* helper to call method with 1 argument */ 478 Aml *aml_call1(const char *method, Aml *arg1) 479 { 480 Aml *var = aml_alloc(); 481 build_append_namestring(var->buf, "%s", method); 482 aml_append(var, arg1); 483 return var; 484 } 485 486 /* helper to call method with 2 arguments */ 487 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2) 488 { 489 Aml *var = aml_alloc(); 490 build_append_namestring(var->buf, "%s", method); 491 aml_append(var, arg1); 492 aml_append(var, arg2); 493 return var; 494 } 495 496 /* helper to call method with 3 arguments */ 497 Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3) 498 { 499 Aml *var = aml_alloc(); 500 build_append_namestring(var->buf, "%s", method); 501 aml_append(var, arg1); 502 aml_append(var, arg2); 503 aml_append(var, arg3); 504 return var; 505 } 506 507 /* helper to call method with 4 arguments */ 508 Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4) 509 { 510 Aml *var = aml_alloc(); 511 build_append_namestring(var->buf, "%s", method); 512 aml_append(var, arg1); 513 aml_append(var, arg2); 514 aml_append(var, arg3); 515 aml_append(var, arg4); 516 return var; 517 } 518 519 /* 520 * ACPI 1.0b: 6.4.3.4 32-Bit Fixed Location Memory Range Descriptor 521 * (Type 1, Large Item Name 0x6) 522 */ 523 Aml *aml_memory32_fixed(uint32_t addr, uint32_t size, 524 AmlReadAndWrite read_and_write) 525 { 526 Aml *var = aml_alloc(); 527 build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */ 528 build_append_byte(var->buf, 9); /* Length, bits[7:0] value = 9 */ 529 build_append_byte(var->buf, 0); /* Length, bits[15:8] value = 0 */ 530 build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */ 531 532 /* Range base address */ 533 build_append_byte(var->buf, extract32(addr, 0, 8)); /* bits[7:0] */ 534 build_append_byte(var->buf, extract32(addr, 8, 8)); /* bits[15:8] */ 535 build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */ 536 build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */ 537 538 /* Range length */ 539 build_append_byte(var->buf, extract32(size, 0, 8)); /* bits[7:0] */ 540 build_append_byte(var->buf, extract32(size, 8, 8)); /* bits[15:8] */ 541 build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */ 542 build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */ 543 return var; 544 } 545 546 /* 547 * ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor 548 * Type 1, Large Item Name 0x9 549 */ 550 Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro, 551 AmlLevelAndEdge level_and_edge, 552 AmlActiveHighAndLow high_and_low, AmlShared shared, 553 uint32_t irq) 554 { 555 Aml *var = aml_alloc(); 556 uint8_t irq_flags = con_and_pro | (level_and_edge << 1) 557 | (high_and_low << 2) | (shared << 3); 558 559 build_append_byte(var->buf, 0x89); /* Extended irq descriptor */ 560 build_append_byte(var->buf, 6); /* Length, bits[7:0] minimum value = 6 */ 561 build_append_byte(var->buf, 0); /* Length, bits[15:8] minimum value = 0 */ 562 build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */ 563 build_append_byte(var->buf, 0x01); /* Interrupt table length = 1 */ 564 565 /* Interrupt Number */ 566 build_append_byte(var->buf, extract32(irq, 0, 8)); /* bits[7:0] */ 567 build_append_byte(var->buf, extract32(irq, 8, 8)); /* bits[15:8] */ 568 build_append_byte(var->buf, extract32(irq, 16, 8)); /* bits[23:16] */ 569 build_append_byte(var->buf, extract32(irq, 24, 8)); /* bits[31:24] */ 570 return var; 571 } 572 573 /* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */ 574 Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, 575 uint8_t aln, uint8_t len) 576 { 577 Aml *var = aml_alloc(); 578 build_append_byte(var->buf, 0x47); /* IO port descriptor */ 579 build_append_byte(var->buf, dec); 580 build_append_byte(var->buf, min_base & 0xff); 581 build_append_byte(var->buf, (min_base >> 8) & 0xff); 582 build_append_byte(var->buf, max_base & 0xff); 583 build_append_byte(var->buf, (max_base >> 8) & 0xff); 584 build_append_byte(var->buf, aln); 585 build_append_byte(var->buf, len); 586 return var; 587 } 588 589 /* 590 * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor 591 * 592 * More verbose description at: 593 * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro) 594 * 6.4.2.1 IRQ Descriptor 595 */ 596 Aml *aml_irq_no_flags(uint8_t irq) 597 { 598 uint16_t irq_mask; 599 Aml *var = aml_alloc(); 600 601 assert(irq < 16); 602 build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */ 603 604 irq_mask = 1U << irq; 605 build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */ 606 build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */ 607 return var; 608 } 609 610 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */ 611 Aml *aml_lnot(Aml *arg) 612 { 613 Aml *var = aml_opcode(0x92 /* LNotOp */); 614 aml_append(var, arg); 615 return var; 616 } 617 618 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */ 619 Aml *aml_equal(Aml *arg1, Aml *arg2) 620 { 621 Aml *var = aml_opcode(0x93 /* LequalOp */); 622 aml_append(var, arg1); 623 aml_append(var, arg2); 624 return var; 625 } 626 627 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */ 628 Aml *aml_if(Aml *predicate) 629 { 630 Aml *var = aml_bundle(0xA0 /* IfOp */, AML_PACKAGE); 631 aml_append(var, predicate); 632 return var; 633 } 634 635 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */ 636 Aml *aml_else(void) 637 { 638 Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE); 639 return var; 640 } 641 642 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */ 643 Aml *aml_method(const char *name, int arg_count) 644 { 645 Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE); 646 build_append_namestring(var->buf, "%s", name); 647 build_append_byte(var->buf, arg_count); /* MethodFlags: ArgCount */ 648 return var; 649 } 650 651 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */ 652 Aml *aml_device(const char *name_format, ...) 653 { 654 va_list ap; 655 Aml *var = aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE); 656 va_start(ap, name_format); 657 build_append_namestringv(var->buf, name_format, ap); 658 va_end(ap); 659 return var; 660 } 661 662 /* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */ 663 Aml *aml_resource_template(void) 664 { 665 /* ResourceTemplate is a buffer of Resources with EndTag at the end */ 666 Aml *var = aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE); 667 return var; 668 } 669 670 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer 671 * Pass byte_list as NULL to request uninitialized buffer to reserve space. 672 */ 673 Aml *aml_buffer(int buffer_size, uint8_t *byte_list) 674 { 675 int i; 676 Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER); 677 678 for (i = 0; i < buffer_size; i++) { 679 if (byte_list == NULL) { 680 build_append_byte(var->buf, 0x0); 681 } else { 682 build_append_byte(var->buf, byte_list[i]); 683 } 684 } 685 686 return var; 687 } 688 689 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */ 690 Aml *aml_package(uint8_t num_elements) 691 { 692 Aml *var = aml_bundle(0x12 /* PackageOp */, AML_PACKAGE); 693 build_append_byte(var->buf, num_elements); 694 return var; 695 } 696 697 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */ 698 Aml *aml_operation_region(const char *name, AmlRegionSpace rs, 699 uint32_t offset, uint32_t len) 700 { 701 Aml *var = aml_alloc(); 702 build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */ 703 build_append_byte(var->buf, 0x80); /* OpRegionOp */ 704 build_append_namestring(var->buf, "%s", name); 705 build_append_byte(var->buf, rs); 706 build_append_int(var->buf, offset); 707 build_append_int(var->buf, len); 708 return var; 709 } 710 711 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */ 712 Aml *aml_named_field(const char *name, unsigned length) 713 { 714 Aml *var = aml_alloc(); 715 build_append_nameseg(var->buf, name); 716 build_append_pkg_length(var->buf, length, false); 717 return var; 718 } 719 720 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */ 721 Aml *aml_reserved_field(unsigned length) 722 { 723 Aml *var = aml_alloc(); 724 /* ReservedField := 0x00 PkgLength */ 725 build_append_byte(var->buf, 0x00); 726 build_append_pkg_length(var->buf, length, false); 727 return var; 728 } 729 730 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */ 731 Aml *aml_field(const char *name, AmlAccessType type, AmlUpdateRule rule) 732 { 733 Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE); 734 uint8_t flags = rule << 5 | type; 735 736 build_append_namestring(var->buf, "%s", name); 737 build_append_byte(var->buf, flags); 738 return var; 739 } 740 741 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */ 742 Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name) 743 { 744 Aml *var = aml_alloc(); 745 build_append_byte(var->buf, 0x8A); /* CreateDWordFieldOp */ 746 aml_append(var, srcbuf); 747 aml_append(var, index); 748 build_append_namestring(var->buf, "%s", name); 749 return var; 750 } 751 752 /* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */ 753 Aml *aml_string(const char *name_format, ...) 754 { 755 Aml *var = aml_opcode(0x0D /* StringPrefix */); 756 va_list ap, va_len; 757 char *s; 758 int len; 759 760 va_start(ap, name_format); 761 va_copy(va_len, ap); 762 len = vsnprintf(NULL, 0, name_format, va_len); 763 va_end(va_len); 764 len += 1; 765 s = g_new0(typeof(*s), len); 766 767 len = vsnprintf(s, len, name_format, ap); 768 va_end(ap); 769 770 g_array_append_vals(var->buf, s, len); 771 build_append_byte(var->buf, 0x0); /* NullChar */ 772 g_free(s); 773 774 return var; 775 } 776 777 /* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */ 778 Aml *aml_local(int num) 779 { 780 Aml *var; 781 uint8_t op = 0x60 /* Local0Op */ + num; 782 783 assert(num <= 7); 784 var = aml_opcode(op); 785 return var; 786 } 787 788 /* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */ 789 Aml *aml_varpackage(uint32_t num_elements) 790 { 791 Aml *var = aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE); 792 build_append_int(var->buf, num_elements); 793 return var; 794 } 795 796 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */ 797 Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len, 798 const char *name_format, ...) 799 { 800 va_list ap; 801 Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE); 802 va_start(ap, name_format); 803 build_append_namestringv(var->buf, name_format, ap); 804 va_end(ap); 805 build_append_byte(var->buf, proc_id); /* ProcID */ 806 build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr)); 807 build_append_byte(var->buf, pblk_len); /* PblkLen */ 808 return var; 809 } 810 811 static uint8_t Hex2Digit(char c) 812 { 813 if (c >= 'A') { 814 return c - 'A' + 10; 815 } 816 817 return c - '0'; 818 } 819 820 /* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */ 821 Aml *aml_eisaid(const char *str) 822 { 823 Aml *var = aml_alloc(); 824 uint32_t id; 825 826 g_assert(strlen(str) == 7); 827 id = (str[0] - 0x40) << 26 | 828 (str[1] - 0x40) << 21 | 829 (str[2] - 0x40) << 16 | 830 Hex2Digit(str[3]) << 12 | 831 Hex2Digit(str[4]) << 8 | 832 Hex2Digit(str[5]) << 4 | 833 Hex2Digit(str[6]); 834 835 build_append_byte(var->buf, 0x0C); /* DWordPrefix */ 836 build_append_int_noprefix(var->buf, bswap32(id), sizeof(id)); 837 return var; 838 } 839 840 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */ 841 static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed, 842 AmlMaxFixed max_fixed, AmlDecode dec, 843 uint8_t type_flags) 844 { 845 uint8_t flags = max_fixed | min_fixed | dec; 846 Aml *var = aml_alloc(); 847 848 build_append_byte(var->buf, type); 849 build_append_byte(var->buf, flags); 850 build_append_byte(var->buf, type_flags); /* Type Specific Flags */ 851 return var; 852 } 853 854 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */ 855 static Aml *aml_word_as_desc(AmlResourceType type, AmlMinFixed min_fixed, 856 AmlMaxFixed max_fixed, AmlDecode dec, 857 uint16_t addr_gran, uint16_t addr_min, 858 uint16_t addr_max, uint16_t addr_trans, 859 uint16_t len, uint8_t type_flags) 860 { 861 Aml *var = aml_alloc(); 862 863 build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */ 864 /* minimum length since we do not encode optional fields */ 865 build_append_byte(var->buf, 0x0D); 866 build_append_byte(var->buf, 0x0); 867 868 aml_append(var, 869 aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags)); 870 build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran)); 871 build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min)); 872 build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max)); 873 build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans)); 874 build_append_int_noprefix(var->buf, len, sizeof(len)); 875 return var; 876 } 877 878 /* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */ 879 static Aml *aml_dword_as_desc(AmlResourceType type, AmlMinFixed min_fixed, 880 AmlMaxFixed max_fixed, AmlDecode dec, 881 uint32_t addr_gran, uint32_t addr_min, 882 uint32_t addr_max, uint32_t addr_trans, 883 uint32_t len, uint8_t type_flags) 884 { 885 Aml *var = aml_alloc(); 886 887 build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */ 888 /* minimum length since we do not encode optional fields */ 889 build_append_byte(var->buf, 23); 890 build_append_byte(var->buf, 0x0); 891 892 893 aml_append(var, 894 aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags)); 895 build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran)); 896 build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min)); 897 build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max)); 898 build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans)); 899 build_append_int_noprefix(var->buf, len, sizeof(len)); 900 return var; 901 } 902 903 /* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */ 904 static Aml *aml_qword_as_desc(AmlResourceType type, AmlMinFixed min_fixed, 905 AmlMaxFixed max_fixed, AmlDecode dec, 906 uint64_t addr_gran, uint64_t addr_min, 907 uint64_t addr_max, uint64_t addr_trans, 908 uint64_t len, uint8_t type_flags) 909 { 910 Aml *var = aml_alloc(); 911 912 build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */ 913 /* minimum length since we do not encode optional fields */ 914 build_append_byte(var->buf, 0x2B); 915 build_append_byte(var->buf, 0x0); 916 917 aml_append(var, 918 aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags)); 919 build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran)); 920 build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min)); 921 build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max)); 922 build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans)); 923 build_append_int_noprefix(var->buf, len, sizeof(len)); 924 return var; 925 } 926 927 /* 928 * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor 929 * 930 * More verbose description at: 931 * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro) 932 */ 933 Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed, 934 AmlDecode dec, uint16_t addr_gran, 935 uint16_t addr_min, uint16_t addr_max, 936 uint16_t addr_trans, uint16_t len) 937 938 { 939 return aml_word_as_desc(AML_BUS_NUMBER_RANGE, min_fixed, max_fixed, dec, 940 addr_gran, addr_min, addr_max, addr_trans, len, 0); 941 } 942 943 /* 944 * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor 945 * 946 * More verbose description at: 947 * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro) 948 */ 949 Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed, 950 AmlDecode dec, AmlISARanges isa_ranges, 951 uint16_t addr_gran, uint16_t addr_min, 952 uint16_t addr_max, uint16_t addr_trans, 953 uint16_t len) 954 955 { 956 return aml_word_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec, 957 addr_gran, addr_min, addr_max, addr_trans, len, 958 isa_ranges); 959 } 960 961 /* 962 * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor 963 * 964 * More verbose description at: 965 * ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro) 966 */ 967 Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed, 968 AmlDecode dec, AmlISARanges isa_ranges, 969 uint32_t addr_gran, uint32_t addr_min, 970 uint32_t addr_max, uint32_t addr_trans, 971 uint32_t len) 972 973 { 974 return aml_dword_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec, 975 addr_gran, addr_min, addr_max, addr_trans, len, 976 isa_ranges); 977 } 978 979 /* 980 * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor 981 * 982 * More verbose description at: 983 * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro) 984 */ 985 Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed, 986 AmlMaxFixed max_fixed, AmlCacheable cacheable, 987 AmlReadAndWrite read_and_write, 988 uint32_t addr_gran, uint32_t addr_min, 989 uint32_t addr_max, uint32_t addr_trans, 990 uint32_t len) 991 { 992 uint8_t flags = read_and_write | (cacheable << 1); 993 994 return aml_dword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed, 995 dec, addr_gran, addr_min, addr_max, 996 addr_trans, len, flags); 997 } 998 999 /* 1000 * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor 1001 * 1002 * More verbose description at: 1003 * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro) 1004 */ 1005 Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed, 1006 AmlMaxFixed max_fixed, AmlCacheable cacheable, 1007 AmlReadAndWrite read_and_write, 1008 uint64_t addr_gran, uint64_t addr_min, 1009 uint64_t addr_max, uint64_t addr_trans, 1010 uint64_t len) 1011 { 1012 uint8_t flags = read_and_write | (cacheable << 1); 1013 1014 return aml_qword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed, 1015 dec, addr_gran, addr_min, addr_max, 1016 addr_trans, len, flags); 1017 } 1018 1019 static uint8_t Hex2Byte(const char *src) 1020 { 1021 int hi, lo; 1022 1023 hi = Hex2Digit(src[0]); 1024 assert(hi >= 0); 1025 assert(hi <= 15); 1026 1027 lo = Hex2Digit(src[1]); 1028 assert(lo >= 0); 1029 assert(lo <= 15); 1030 return (hi << 4) | lo; 1031 } 1032 1033 /* 1034 * ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro) 1035 * e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp 1036 * call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp"); 1037 */ 1038 Aml *aml_touuid(const char *uuid) 1039 { 1040 Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER); 1041 1042 assert(strlen(uuid) == 36); 1043 assert(uuid[8] == '-'); 1044 assert(uuid[13] == '-'); 1045 assert(uuid[18] == '-'); 1046 assert(uuid[23] == '-'); 1047 1048 build_append_byte(var->buf, Hex2Byte(uuid + 6)); /* dd - at offset 00 */ 1049 build_append_byte(var->buf, Hex2Byte(uuid + 4)); /* cc - at offset 01 */ 1050 build_append_byte(var->buf, Hex2Byte(uuid + 2)); /* bb - at offset 02 */ 1051 build_append_byte(var->buf, Hex2Byte(uuid + 0)); /* aa - at offset 03 */ 1052 1053 build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */ 1054 build_append_byte(var->buf, Hex2Byte(uuid + 9)); /* ee - at offset 05 */ 1055 1056 build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */ 1057 build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */ 1058 1059 build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */ 1060 build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */ 1061 1062 build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */ 1063 build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */ 1064 build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */ 1065 build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */ 1066 build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */ 1067 build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */ 1068 1069 return var; 1070 } 1071 1072 /* 1073 * ACPI 2.0b: 16.2.3.6.4.3 Unicode Macro (Convert Ascii String To Unicode) 1074 */ 1075 Aml *aml_unicode(const char *str) 1076 { 1077 int i = 0; 1078 Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER); 1079 1080 do { 1081 build_append_byte(var->buf, str[i]); 1082 build_append_byte(var->buf, 0); 1083 i++; 1084 } while (i <= strlen(str)); 1085 1086 return var; 1087 } 1088 1089 void 1090 build_header(GArray *linker, GArray *table_data, 1091 AcpiTableHeader *h, const char *sig, int len, uint8_t rev) 1092 { 1093 memcpy(&h->signature, sig, 4); 1094 h->length = cpu_to_le32(len); 1095 h->revision = rev; 1096 memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6); 1097 memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4); 1098 memcpy(h->oem_table_id + 4, sig, 4); 1099 h->oem_revision = cpu_to_le32(1); 1100 memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4); 1101 h->asl_compiler_revision = cpu_to_le32(1); 1102 h->checksum = 0; 1103 /* Checksum to be filled in by Guest linker */ 1104 bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE, 1105 table_data->data, h, len, &h->checksum); 1106 } 1107 1108 void *acpi_data_push(GArray *table_data, unsigned size) 1109 { 1110 unsigned off = table_data->len; 1111 g_array_set_size(table_data, off + size); 1112 return table_data->data + off; 1113 } 1114 1115 unsigned acpi_data_len(GArray *table) 1116 { 1117 #if GLIB_CHECK_VERSION(2, 22, 0) 1118 assert(g_array_get_element_size(table) == 1); 1119 #endif 1120 return table->len; 1121 } 1122 1123 void acpi_add_table(GArray *table_offsets, GArray *table_data) 1124 { 1125 uint32_t offset = cpu_to_le32(table_data->len); 1126 g_array_append_val(table_offsets, offset); 1127 } 1128 1129 void acpi_build_tables_init(AcpiBuildTables *tables) 1130 { 1131 tables->rsdp = g_array_new(false, true /* clear */, 1); 1132 tables->table_data = g_array_new(false, true /* clear */, 1); 1133 tables->tcpalog = g_array_new(false, true /* clear */, 1); 1134 tables->linker = bios_linker_loader_init(); 1135 } 1136 1137 void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) 1138 { 1139 void *linker_data = bios_linker_loader_cleanup(tables->linker); 1140 g_free(linker_data); 1141 g_array_free(tables->rsdp, true); 1142 g_array_free(tables->table_data, true); 1143 g_array_free(tables->tcpalog, mfre); 1144 } 1145 1146 /* Build rsdt table */ 1147 void 1148 build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets) 1149 { 1150 AcpiRsdtDescriptorRev1 *rsdt; 1151 size_t rsdt_len; 1152 int i; 1153 const int table_data_len = (sizeof(uint32_t) * table_offsets->len); 1154 1155 rsdt_len = sizeof(*rsdt) + table_data_len; 1156 rsdt = acpi_data_push(table_data, rsdt_len); 1157 memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len); 1158 for (i = 0; i < table_offsets->len; ++i) { 1159 /* rsdt->table_offset_entry to be filled by Guest linker */ 1160 bios_linker_loader_add_pointer(linker, 1161 ACPI_BUILD_TABLE_FILE, 1162 ACPI_BUILD_TABLE_FILE, 1163 table_data, &rsdt->table_offset_entry[i], 1164 sizeof(uint32_t)); 1165 } 1166 build_header(linker, table_data, 1167 (void *)rsdt, "RSDT", rsdt_len, 1); 1168 } 1169