cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

aml-build.c (76836B)


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