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