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