qemu

Форк
0
/
aml-build.c 
2522 строки · 81.4 Кб
1
/* Support for generating ACPI tables and passing them to Guests
2
 *
3
 * Copyright (C) 2015 Red Hat Inc
4
 *
5
 * Author: Michael S. Tsirkin <mst@redhat.com>
6
 * Author: Igor Mammedov <imammedo@redhat.com>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12

13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17

18
 * You should have received a copy of the GNU General Public License along
19
 * with this program; if not, see <http://www.gnu.org/licenses/>.
20
 */
21

22
#include "qemu/osdep.h"
23
#include <glib/gprintf.h>
24
#include "hw/acpi/aml-build.h"
25
#include "qemu/bswap.h"
26
#include "qemu/bitops.h"
27
#include "sysemu/numa.h"
28
#include "hw/boards.h"
29
#include "hw/acpi/tpm.h"
30
#include "hw/pci/pci_host.h"
31
#include "hw/pci/pci_bus.h"
32
#include "hw/pci/pci_bridge.h"
33
#include "qemu/cutils.h"
34

35
static GArray *build_alloc_array(void)
36
{
37
    return g_array_new(false, true /* clear */, 1);
38
}
39

40
static void build_free_array(GArray *array)
41
{
42
    g_array_free(array, true);
43
}
44

45
static void build_prepend_byte(GArray *array, uint8_t val)
46
{
47
    g_array_prepend_val(array, val);
48
}
49

50
static void build_append_byte(GArray *array, uint8_t val)
51
{
52
    g_array_append_val(array, val);
53
}
54

55
static void build_append_padded_str(GArray *array, const char *str,
56
                                    size_t maxlen, char pad)
57
{
58
    size_t i;
59
    size_t len = strlen(str);
60

61
    g_assert(len <= maxlen);
62
    g_array_append_vals(array, str, len);
63
    for (i = maxlen - len; i > 0; i--) {
64
        g_array_append_val(array, pad);
65
    }
66
}
67

68
static void build_append_array(GArray *array, GArray *val)
69
{
70
    g_array_append_vals(array, val->data, val->len);
71
}
72

73
#define ACPI_NAMESEG_LEN 4
74

75
void crs_range_insert(GPtrArray *ranges, uint64_t base, uint64_t limit)
76
{
77
    CrsRangeEntry *entry;
78

79
    entry = g_malloc(sizeof(*entry));
80
    entry->base = base;
81
    entry->limit = limit;
82

83
    g_ptr_array_add(ranges, entry);
84
}
85

86
static void crs_range_free(gpointer data)
87
{
88
    CrsRangeEntry *entry = (CrsRangeEntry *)data;
89
    g_free(entry);
90
}
91

92
void crs_range_set_init(CrsRangeSet *range_set)
93
{
94
    range_set->io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
95
    range_set->mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
96
    range_set->mem_64bit_ranges =
97
            g_ptr_array_new_with_free_func(crs_range_free);
98
}
99

100
void crs_range_set_free(CrsRangeSet *range_set)
101
{
102
    g_ptr_array_free(range_set->io_ranges, true);
103
    g_ptr_array_free(range_set->mem_ranges, true);
104
    g_ptr_array_free(range_set->mem_64bit_ranges, true);
105
}
106

107
static gint crs_range_compare(gconstpointer a, gconstpointer b)
108
{
109
    CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
110
    CrsRangeEntry *entry_b = *(CrsRangeEntry **)b;
111

112
    if (entry_a->base < entry_b->base) {
113
        return -1;
114
    } else if (entry_a->base > entry_b->base) {
115
        return 1;
116
    } else {
117
        return 0;
118
    }
119
}
120

121
/*
122
 * crs_replace_with_free_ranges - given the 'used' ranges within [start - end]
123
 * interval, computes the 'free' ranges from the same interval.
124
 * Example: If the input array is { [a1 - a2],[b1 - b2] }, the function
125
 * will return { [base - a1], [a2 - b1], [b2 - limit] }.
126
 */
127
void crs_replace_with_free_ranges(GPtrArray *ranges,
128
                                  uint64_t start, uint64_t end)
129
{
130
    GPtrArray *free_ranges = g_ptr_array_new();
131
    uint64_t free_base = start;
132
    int i;
133

134
    g_ptr_array_sort(ranges, crs_range_compare);
135
    for (i = 0; i < ranges->len; i++) {
136
        CrsRangeEntry *used = g_ptr_array_index(ranges, i);
137

138
        if (free_base < used->base) {
139
            crs_range_insert(free_ranges, free_base, used->base - 1);
140
        }
141

142
        free_base = used->limit + 1;
143
    }
144

145
    if (free_base < end) {
146
        crs_range_insert(free_ranges, free_base, end);
147
    }
148

149
    g_ptr_array_set_size(ranges, 0);
150
    for (i = 0; i < free_ranges->len; i++) {
151
        g_ptr_array_add(ranges, g_ptr_array_index(free_ranges, i));
152
    }
153

154
    g_ptr_array_free(free_ranges, true);
155
}
156

157
/*
158
 * crs_range_merge - merges adjacent ranges in the given array.
159
 * Array elements are deleted and replaced with the merged ranges.
160
 */
161
static void crs_range_merge(GPtrArray *range)
162
{
163
    GPtrArray *tmp = g_ptr_array_new_with_free_func(crs_range_free);
164
    CrsRangeEntry *entry;
165
    uint64_t range_base, range_limit;
166
    int i;
167

168
    if (!range->len) {
169
        return;
170
    }
171

172
    g_ptr_array_sort(range, crs_range_compare);
173

174
    entry = g_ptr_array_index(range, 0);
175
    range_base = entry->base;
176
    range_limit = entry->limit;
177
    for (i = 1; i < range->len; i++) {
178
        entry = g_ptr_array_index(range, i);
179
        if (entry->base - 1 == range_limit) {
180
            range_limit = entry->limit;
181
        } else {
182
            crs_range_insert(tmp, range_base, range_limit);
183
            range_base = entry->base;
184
            range_limit = entry->limit;
185
        }
186
    }
187
    crs_range_insert(tmp, range_base, range_limit);
188

189
    g_ptr_array_set_size(range, 0);
190
    for (i = 0; i < tmp->len; i++) {
191
        entry = g_ptr_array_index(tmp, i);
192
        crs_range_insert(range, entry->base, entry->limit);
193
    }
194
    g_ptr_array_free(tmp, true);
195
}
196

197
static void
198
build_append_nameseg(GArray *array, const char *seg)
199
{
200
    int len;
201

202
    len = strlen(seg);
203
    assert(len <= ACPI_NAMESEG_LEN);
204

205
    g_array_append_vals(array, seg, len);
206
    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
207
    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
208
}
209

210
static void G_GNUC_PRINTF(2, 0)
211
build_append_namestringv(GArray *array, const char *format, va_list ap)
212
{
213
    char *s;
214
    char **segs;
215
    char **segs_iter;
216
    int seg_count = 0;
217

218
    s = g_strdup_vprintf(format, ap);
219
    segs = g_strsplit(s, ".", 0);
220
    g_free(s);
221

222
    /* count segments */
223
    segs_iter = segs;
224
    while (*segs_iter) {
225
        ++segs_iter;
226
        ++seg_count;
227
    }
228
    /*
229
     * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
230
     * "SegCount can be from 1 to 255"
231
     */
232
    assert(seg_count > 0 && seg_count <= 255);
233

234
    /* handle RootPath || PrefixPath */
235
    s = *segs;
236
    while (*s == '\\' || *s == '^') {
237
        build_append_byte(array, *s);
238
        ++s;
239
    }
240

241
    switch (seg_count) {
242
    case 1:
243
        if (!*s) {
244
            build_append_byte(array, 0x00); /* NullName */
245
        } else {
246
            build_append_nameseg(array, s);
247
        }
248
        break;
249

250
    case 2:
251
        build_append_byte(array, 0x2E); /* DualNamePrefix */
252
        build_append_nameseg(array, s);
253
        build_append_nameseg(array, segs[1]);
254
        break;
255
    default:
256
        build_append_byte(array, 0x2F); /* MultiNamePrefix */
257
        build_append_byte(array, seg_count);
258

259
        /* handle the 1st segment manually due to prefix/root path */
260
        build_append_nameseg(array, s);
261

262
        /* add the rest of segments */
263
        segs_iter = segs + 1;
264
        while (*segs_iter) {
265
            build_append_nameseg(array, *segs_iter);
266
            ++segs_iter;
267
        }
268
        break;
269
    }
270
    g_strfreev(segs);
271
}
272

273
G_GNUC_PRINTF(2, 3)
274
static void build_append_namestring(GArray *array, const char *format, ...)
275
{
276
    va_list ap;
277

278
    va_start(ap, format);
279
    build_append_namestringv(array, format, ap);
280
    va_end(ap);
281
}
282

283
/* 5.4 Definition Block Encoding */
284
enum {
285
    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
286
    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
287
    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
288
    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
289
};
290

291
static void
292
build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
293
{
294
    uint8_t byte;
295
    unsigned length_bytes;
296

297
    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
298
        length_bytes = 1;
299
    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
300
        length_bytes = 2;
301
    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
302
        length_bytes = 3;
303
    } else {
304
        length_bytes = 4;
305
    }
306

307
    /*
308
     * NamedField uses PkgLength encoding but it doesn't include length
309
     * of PkgLength itself.
310
     */
311
    if (incl_self) {
312
        /*
313
         * PkgLength is the length of the inclusive length of the data
314
         * and PkgLength's length itself when used for terms with
315
         * explicit length.
316
         */
317
        length += length_bytes;
318
    }
319

320
    switch (length_bytes) {
321
    case 1:
322
        byte = length;
323
        build_prepend_byte(package, byte);
324
        return;
325
    case 4:
326
        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
327
        build_prepend_byte(package, byte);
328
        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
329
        /* fall through */
330
    case 3:
331
        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
332
        build_prepend_byte(package, byte);
333
        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
334
        /* fall through */
335
    case 2:
336
        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
337
        build_prepend_byte(package, byte);
338
        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
339
        /* fall through */
340
    }
341
    /*
342
     * Most significant two bits of byte zero indicate how many following bytes
343
     * are in PkgLength encoding.
344
     */
345
    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
346
    build_prepend_byte(package, byte);
347
}
348

349
static void
350
build_append_pkg_length(GArray *array, unsigned length, bool incl_self)
351
{
352
    GArray *tmp = build_alloc_array();
353

354
    build_prepend_package_length(tmp, length, incl_self);
355
    build_append_array(array, tmp);
356
    build_free_array(tmp);
357
}
358

359
static void build_package(GArray *package, uint8_t op)
360
{
361
    build_prepend_package_length(package, package->len, true);
362
    build_prepend_byte(package, op);
363
}
364

365
static void build_extop_package(GArray *package, uint8_t op)
366
{
367
    build_package(package, op);
368
    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
369
}
370

371
void build_append_int_noprefix(GArray *table, uint64_t value, int size)
372
{
373
    int i;
374

375
    for (i = 0; i < size; ++i) {
376
        build_append_byte(table, value & 0xFF);
377
        value = value >> 8;
378
    }
379
}
380

381
static void build_append_int(GArray *table, uint64_t value)
382
{
383
    if (value == 0x00) {
384
        build_append_byte(table, 0x00); /* ZeroOp */
385
    } else if (value == 0x01) {
386
        build_append_byte(table, 0x01); /* OneOp */
387
    } else if (value <= 0xFF) {
388
        build_append_byte(table, 0x0A); /* BytePrefix */
389
        build_append_int_noprefix(table, value, 1);
390
    } else if (value <= 0xFFFF) {
391
        build_append_byte(table, 0x0B); /* WordPrefix */
392
        build_append_int_noprefix(table, value, 2);
393
    } else if (value <= 0xFFFFFFFF) {
394
        build_append_byte(table, 0x0C); /* DWordPrefix */
395
        build_append_int_noprefix(table, value, 4);
396
    } else {
397
        build_append_byte(table, 0x0E); /* QWordPrefix */
398
        build_append_int_noprefix(table, value, 8);
399
    }
400
}
401

402
/* Generic Address Structure (GAS)
403
 * ACPI 2.0/3.0: 5.2.3.1 Generic Address Structure
404
 * 2.0 compat note:
405
 *    @access_width must be 0, see ACPI 2.0:Table 5-1
406
 */
407
void build_append_gas(GArray *table, AmlAddressSpace as,
408
                      uint8_t bit_width, uint8_t bit_offset,
409
                      uint8_t access_width, uint64_t address)
410
{
411
    build_append_int_noprefix(table, as, 1);
412
    build_append_int_noprefix(table, bit_width, 1);
413
    build_append_int_noprefix(table, bit_offset, 1);
414
    build_append_int_noprefix(table, access_width, 1);
415
    build_append_int_noprefix(table, address, 8);
416
}
417

418
/*
419
 * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword,
420
 * and return the offset to 0x00000000 for runtime patching.
421
 *
422
 * Warning: runtime patching is best avoided. Only use this as
423
 * a replacement for DataTableRegion (for guests that don't
424
 * support it).
425
 */
426
int
427
build_append_named_dword(GArray *array, const char *name_format, ...)
428
{
429
    int offset;
430
    va_list ap;
431

432
    build_append_byte(array, 0x08); /* NameOp */
433
    va_start(ap, name_format);
434
    build_append_namestringv(array, name_format, ap);
435
    va_end(ap);
436

437
    build_append_byte(array, 0x0C); /* DWordPrefix */
438

439
    offset = array->len;
440
    build_append_int_noprefix(array, 0x00000000, 4);
441
    assert(array->len == offset + 4);
442

443
    return offset;
444
}
445

446
static GPtrArray *alloc_list;
447

448
static Aml *aml_alloc(void)
449
{
450
    Aml *var = g_new0(typeof(*var), 1);
451

452
    g_ptr_array_add(alloc_list, var);
453
    var->block_flags = AML_NO_OPCODE;
454
    var->buf = build_alloc_array();
455
    return var;
456
}
457

458
static Aml *aml_opcode(uint8_t op)
459
{
460
    Aml *var = aml_alloc();
461

462
    var->op  = op;
463
    var->block_flags = AML_OPCODE;
464
    return var;
465
}
466

467
static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags)
468
{
469
    Aml *var = aml_alloc();
470

471
    var->op  = op;
472
    var->block_flags = flags;
473
    return var;
474
}
475

476
static void aml_free(gpointer data, gpointer user_data)
477
{
478
    Aml *var = data;
479
    build_free_array(var->buf);
480
    g_free(var);
481
}
482

483
Aml *init_aml_allocator(void)
484
{
485
    assert(!alloc_list);
486
    alloc_list = g_ptr_array_new();
487
    return aml_alloc();
488
}
489

490
void free_aml_allocator(void)
491
{
492
    g_ptr_array_foreach(alloc_list, aml_free, NULL);
493
    g_ptr_array_free(alloc_list, true);
494
    alloc_list = 0;
495
}
496

497
/* pack data with DefBuffer encoding */
498
static void build_buffer(GArray *array, uint8_t op)
499
{
500
    GArray *data = build_alloc_array();
501

502
    build_append_int(data, array->len);
503
    g_array_prepend_vals(array, data->data, data->len);
504
    build_free_array(data);
505
    build_package(array, op);
506
}
507

508
void aml_append(Aml *parent_ctx, Aml *child)
509
{
510
    GArray *buf = build_alloc_array();
511
    build_append_array(buf, child->buf);
512

513
    switch (child->block_flags) {
514
    case AML_OPCODE:
515
        build_append_byte(parent_ctx->buf, child->op);
516
        break;
517
    case AML_EXT_PACKAGE:
518
        build_extop_package(buf, child->op);
519
        break;
520
    case AML_PACKAGE:
521
        build_package(buf, child->op);
522
        break;
523
    case AML_RES_TEMPLATE:
524
        build_append_byte(buf, 0x79); /* EndTag */
525
        /*
526
         * checksum operations are treated as succeeded if checksum
527
         * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
528
         */
529
        build_append_byte(buf, 0);
530
        /* fall through, to pack resources in buffer */
531
    case AML_BUFFER:
532
        build_buffer(buf, child->op);
533
        break;
534
    case AML_NO_OPCODE:
535
        break;
536
    default:
537
        assert(0);
538
        break;
539
    }
540
    build_append_array(parent_ctx->buf, buf);
541
    build_free_array(buf);
542
}
543

544
/* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */
545
Aml *aml_scope(const char *name_format, ...)
546
{
547
    va_list ap;
548
    Aml *var = aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE);
549
    va_start(ap, name_format);
550
    build_append_namestringv(var->buf, name_format, ap);
551
    va_end(ap);
552
    return var;
553
}
554

555
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */
556
Aml *aml_return(Aml *val)
557
{
558
    Aml *var = aml_opcode(0xA4 /* ReturnOp */);
559
    aml_append(var, val);
560
    return var;
561
}
562

563
/* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */
564
Aml *aml_debug(void)
565
{
566
    Aml *var = aml_alloc();
567
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
568
    build_append_byte(var->buf, 0x31); /* DebugOp */
569
    return var;
570
}
571

572
/*
573
 * ACPI 1.0b: 16.2.3 Data Objects Encoding:
574
 * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
575
 */
576
Aml *aml_int(const uint64_t val)
577
{
578
    Aml *var = aml_alloc();
579
    build_append_int(var->buf, val);
580
    return var;
581
}
582

583
/*
584
 * helper to construct NameString, which returns Aml object
585
 * for using with aml_append or other aml_* terms
586
 */
587
Aml *aml_name(const char *name_format, ...)
588
{
589
    va_list ap;
590
    Aml *var = aml_alloc();
591
    va_start(ap, name_format);
592
    build_append_namestringv(var->buf, name_format, ap);
593
    va_end(ap);
594
    return var;
595
}
596

597
/* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */
598
Aml *aml_name_decl(const char *name, Aml *val)
599
{
600
    Aml *var = aml_opcode(0x08 /* NameOp */);
601
    build_append_namestring(var->buf, "%s", name);
602
    aml_append(var, val);
603
    return var;
604
}
605

606
/* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
607
Aml *aml_arg(int pos)
608
{
609
    uint8_t op = 0x68 /* ARG0 op */ + pos;
610

611
    assert(pos <= 6);
612
    return aml_opcode(op);
613
}
614

615
/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToInteger */
616
Aml *aml_to_integer(Aml *arg)
617
{
618
    Aml *var = aml_opcode(0x99 /* ToIntegerOp */);
619
    aml_append(var, arg);
620
    build_append_byte(var->buf, 0x00 /* NullNameOp */);
621
    return var;
622
}
623

624
/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToHexString */
625
Aml *aml_to_hexstring(Aml *src, Aml *dst)
626
{
627
    Aml *var = aml_opcode(0x98 /* ToHexStringOp */);
628
    aml_append(var, src);
629
    if (dst) {
630
        aml_append(var, dst);
631
    } else {
632
        build_append_byte(var->buf, 0x00 /* NullNameOp */);
633
    }
634
    return var;
635
}
636

637
/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToBuffer */
638
Aml *aml_to_buffer(Aml *src, Aml *dst)
639
{
640
    Aml *var = aml_opcode(0x96 /* ToBufferOp */);
641
    aml_append(var, src);
642
    if (dst) {
643
        aml_append(var, dst);
644
    } else {
645
        build_append_byte(var->buf, 0x00 /* NullNameOp */);
646
    }
647
    return var;
648
}
649

650
/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToDecimalString */
651
Aml *aml_to_decimalstring(Aml *src, Aml *dst)
652
{
653
    Aml *var = aml_opcode(0x97 /* ToDecimalStringOp */);
654
    aml_append(var, src);
655
    if (dst) {
656
        aml_append(var, dst);
657
    } else {
658
        build_append_byte(var->buf, 0x00 /* NullNameOp */);
659
    }
660
    return var;
661
}
662

663
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
664
Aml *aml_store(Aml *val, Aml *target)
665
{
666
    Aml *var = aml_opcode(0x70 /* StoreOp */);
667
    aml_append(var, val);
668
    aml_append(var, target);
669
    return var;
670
}
671

672
/**
673
 * build_opcode_2arg_dst:
674
 * @op: 1-byte opcode
675
 * @arg1: 1st operand
676
 * @arg2: 2nd operand
677
 * @dst: optional target to store to, set to NULL if it's not required
678
 *
679
 * An internal helper to compose AML terms that have
680
 *   "Op Operand Operand Target"
681
 * pattern.
682
 *
683
 * Returns: The newly allocated and composed according to pattern Aml object.
684
 */
685
static Aml *
686
build_opcode_2arg_dst(uint8_t op, Aml *arg1, Aml *arg2, Aml *dst)
687
{
688
    Aml *var = aml_opcode(op);
689
    aml_append(var, arg1);
690
    aml_append(var, arg2);
691
    if (dst) {
692
        aml_append(var, dst);
693
    } else {
694
        build_append_byte(var->buf, 0x00 /* NullNameOp */);
695
    }
696
    return var;
697
}
698

699
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
700
Aml *aml_and(Aml *arg1, Aml *arg2, Aml *dst)
701
{
702
    return build_opcode_2arg_dst(0x7B /* AndOp */, arg1, arg2, dst);
703
}
704

705
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
706
Aml *aml_or(Aml *arg1, Aml *arg2, Aml *dst)
707
{
708
    return build_opcode_2arg_dst(0x7D /* OrOp */, arg1, arg2, dst);
709
}
710

711
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLAnd */
712
Aml *aml_land(Aml *arg1, Aml *arg2)
713
{
714
    Aml *var = aml_opcode(0x90 /* LAndOp */);
715
    aml_append(var, arg1);
716
    aml_append(var, arg2);
717
    return var;
718
}
719

720
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLOr */
721
Aml *aml_lor(Aml *arg1, Aml *arg2)
722
{
723
    Aml *var = aml_opcode(0x91 /* LOrOp */);
724
    aml_append(var, arg1);
725
    aml_append(var, arg2);
726
    return var;
727
}
728

729
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftLeft */
730
Aml *aml_shiftleft(Aml *arg1, Aml *count)
731
{
732
    return build_opcode_2arg_dst(0x79 /* ShiftLeftOp */, arg1, count, NULL);
733
}
734

735
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftRight */
736
Aml *aml_shiftright(Aml *arg1, Aml *count, Aml *dst)
737
{
738
    return build_opcode_2arg_dst(0x7A /* ShiftRightOp */, arg1, count, dst);
739
}
740

741
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
742
Aml *aml_lless(Aml *arg1, Aml *arg2)
743
{
744
    Aml *var = aml_opcode(0x95 /* LLessOp */);
745
    aml_append(var, arg1);
746
    aml_append(var, arg2);
747
    return var;
748
}
749

750
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */
751
Aml *aml_add(Aml *arg1, Aml *arg2, Aml *dst)
752
{
753
    return build_opcode_2arg_dst(0x72 /* AddOp */, arg1, arg2, dst);
754
}
755

756
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSubtract */
757
Aml *aml_subtract(Aml *arg1, Aml *arg2, Aml *dst)
758
{
759
    return build_opcode_2arg_dst(0x74 /* SubtractOp */, arg1, arg2, dst);
760
}
761

762
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIncrement */
763
Aml *aml_increment(Aml *arg)
764
{
765
    Aml *var = aml_opcode(0x75 /* IncrementOp */);
766
    aml_append(var, arg);
767
    return var;
768
}
769

770
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDecrement */
771
Aml *aml_decrement(Aml *arg)
772
{
773
    Aml *var = aml_opcode(0x76 /* DecrementOp */);
774
    aml_append(var, arg);
775
    return var;
776
}
777

778
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */
779
Aml *aml_index(Aml *arg1, Aml *idx)
780
{
781
    return build_opcode_2arg_dst(0x88 /* IndexOp */, arg1, idx, NULL);
782
}
783

784
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
785
Aml *aml_notify(Aml *arg1, Aml *arg2)
786
{
787
    Aml *var = aml_opcode(0x86 /* NotifyOp */);
788
    aml_append(var, arg1);
789
    aml_append(var, arg2);
790
    return var;
791
}
792

793
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefBreak */
794
Aml *aml_break(void)
795
{
796
    Aml *var = aml_opcode(0xa5 /* BreakOp */);
797
    return var;
798
}
799

800
/* helper to call method without argument */
801
Aml *aml_call0(const char *method)
802
{
803
    Aml *var = aml_alloc();
804
    build_append_namestring(var->buf, "%s", method);
805
    return var;
806
}
807

808
/* helper to call method with 1 argument */
809
Aml *aml_call1(const char *method, Aml *arg1)
810
{
811
    Aml *var = aml_alloc();
812
    build_append_namestring(var->buf, "%s", method);
813
    aml_append(var, arg1);
814
    return var;
815
}
816

817
/* helper to call method with 2 arguments */
818
Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2)
819
{
820
    Aml *var = aml_alloc();
821
    build_append_namestring(var->buf, "%s", method);
822
    aml_append(var, arg1);
823
    aml_append(var, arg2);
824
    return var;
825
}
826

827
/* helper to call method with 3 arguments */
828
Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3)
829
{
830
    Aml *var = aml_alloc();
831
    build_append_namestring(var->buf, "%s", method);
832
    aml_append(var, arg1);
833
    aml_append(var, arg2);
834
    aml_append(var, arg3);
835
    return var;
836
}
837

838
/* helper to call method with 4 arguments */
839
Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
840
{
841
    Aml *var = aml_alloc();
842
    build_append_namestring(var->buf, "%s", method);
843
    aml_append(var, arg1);
844
    aml_append(var, arg2);
845
    aml_append(var, arg3);
846
    aml_append(var, arg4);
847
    return var;
848
}
849

850
/* helper to call method with 5 arguments */
851
Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
852
               Aml *arg5)
853
{
854
    Aml *var = aml_alloc();
855
    build_append_namestring(var->buf, "%s", method);
856
    aml_append(var, arg1);
857
    aml_append(var, arg2);
858
    aml_append(var, arg3);
859
    aml_append(var, arg4);
860
    aml_append(var, arg5);
861
    return var;
862
}
863

864
/* helper to call method with 5 arguments */
865
Aml *aml_call6(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
866
               Aml *arg5, Aml *arg6)
867
{
868
    Aml *var = aml_alloc();
869
    build_append_namestring(var->buf, "%s", method);
870
    aml_append(var, arg1);
871
    aml_append(var, arg2);
872
    aml_append(var, arg3);
873
    aml_append(var, arg4);
874
    aml_append(var, arg5);
875
    aml_append(var, arg6);
876
    return var;
877
}
878

879
/*
880
 * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
881
 * Type 1, Large Item Name 0xC
882
 */
883

884
static Aml *aml_gpio_connection(AmlGpioConnectionType type,
885
                                AmlConsumerAndProducer con_and_pro,
886
                                uint8_t flags, AmlPinConfig pin_config,
887
                                uint16_t output_drive,
888
                                uint16_t debounce_timeout,
889
                                const uint32_t pin_list[], uint32_t pin_count,
890
                                const char *resource_source_name,
891
                                const uint8_t *vendor_data,
892
                                uint16_t vendor_data_len)
893
{
894
    Aml *var = aml_alloc();
895
    const uint16_t min_desc_len = 0x16;
896
    uint16_t resource_source_name_len, length;
897
    uint16_t pin_table_offset, resource_source_name_offset, vendor_data_offset;
898
    uint32_t i;
899

900
    assert(resource_source_name);
901
    resource_source_name_len = strlen(resource_source_name) + 1;
902
    length = min_desc_len + resource_source_name_len + vendor_data_len;
903
    pin_table_offset = min_desc_len + 1;
904
    resource_source_name_offset = pin_table_offset + pin_count * 2;
905
    vendor_data_offset = resource_source_name_offset + resource_source_name_len;
906

907
    build_append_byte(var->buf, 0x8C);  /* GPIO Connection Descriptor */
908
    build_append_int_noprefix(var->buf, length, 2); /* Length */
909
    build_append_byte(var->buf, 1);     /* Revision ID */
910
    build_append_byte(var->buf, type);  /* GPIO Connection Type */
911
    /* General Flags (2 bytes) */
912
    build_append_int_noprefix(var->buf, con_and_pro, 2);
913
    /* Interrupt and IO Flags (2 bytes) */
914
    build_append_int_noprefix(var->buf, flags, 2);
915
    /* Pin Configuration 0 = Default 1 = Pull-up 2 = Pull-down 3 = No Pull */
916
    build_append_byte(var->buf, pin_config);
917
    /* Output Drive Strength (2 bytes) */
918
    build_append_int_noprefix(var->buf, output_drive, 2);
919
    /* Debounce Timeout (2 bytes) */
920
    build_append_int_noprefix(var->buf, debounce_timeout, 2);
921
    /* Pin Table Offset (2 bytes) */
922
    build_append_int_noprefix(var->buf, pin_table_offset, 2);
923
    build_append_byte(var->buf, 0);     /* Resource Source Index */
924
    /* Resource Source Name Offset (2 bytes) */
925
    build_append_int_noprefix(var->buf, resource_source_name_offset, 2);
926
    /* Vendor Data Offset (2 bytes) */
927
    build_append_int_noprefix(var->buf, vendor_data_offset, 2);
928
    /* Vendor Data Length (2 bytes) */
929
    build_append_int_noprefix(var->buf, vendor_data_len, 2);
930
    /* Pin Number (2n bytes)*/
931
    for (i = 0; i < pin_count; i++) {
932
        build_append_int_noprefix(var->buf, pin_list[i], 2);
933
    }
934

935
    /* Resource Source Name */
936
    build_append_namestring(var->buf, "%s", resource_source_name);
937
    build_append_byte(var->buf, '\0');
938

939
    /* Vendor-defined Data */
940
    if (vendor_data != NULL) {
941
        g_array_append_vals(var->buf, vendor_data, vendor_data_len);
942
    }
943

944
    return var;
945
}
946

947
/*
948
 * ACPI 5.0: 19.5.53
949
 * GpioInt(GPIO Interrupt Connection Resource Descriptor Macro)
950
 */
951
Aml *aml_gpio_int(AmlConsumerAndProducer con_and_pro,
952
                  AmlLevelAndEdge edge_level,
953
                  AmlActiveHighAndLow active_level, AmlShared shared,
954
                  AmlPinConfig pin_config, uint16_t debounce_timeout,
955
                  const uint32_t pin_list[], uint32_t pin_count,
956
                  const char *resource_source_name,
957
                  const uint8_t *vendor_data, uint16_t vendor_data_len)
958
{
959
    uint8_t flags = edge_level | (active_level << 1) | (shared << 3);
960

961
    return aml_gpio_connection(AML_INTERRUPT_CONNECTION, con_and_pro, flags,
962
                               pin_config, 0, debounce_timeout, pin_list,
963
                               pin_count, resource_source_name, vendor_data,
964
                               vendor_data_len);
965
}
966

967
/*
968
 * ACPI 1.0b: 6.4.3.4 32-Bit Fixed Location Memory Range Descriptor
969
 * (Type 1, Large Item Name 0x6)
970
 */
971
Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
972
                        AmlReadAndWrite read_and_write)
973
{
974
    Aml *var = aml_alloc();
975
    build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */
976
    build_append_byte(var->buf, 9);    /* Length, bits[7:0] value = 9 */
977
    build_append_byte(var->buf, 0);    /* Length, bits[15:8] value = 0 */
978
    build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */
979

980
    /* Range base address */
981
    build_append_byte(var->buf, extract32(addr, 0, 8));  /* bits[7:0] */
982
    build_append_byte(var->buf, extract32(addr, 8, 8));  /* bits[15:8] */
983
    build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */
984
    build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */
985

986
    /* Range length */
987
    build_append_byte(var->buf, extract32(size, 0, 8));  /* bits[7:0] */
988
    build_append_byte(var->buf, extract32(size, 8, 8));  /* bits[15:8] */
989
    build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */
990
    build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */
991
    return var;
992
}
993

994
/*
995
 * ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor
996
 * Type 1, Large Item Name 0x9
997
 */
998
Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
999
                   AmlLevelAndEdge level_and_edge,
1000
                   AmlActiveHighAndLow high_and_low, AmlShared shared,
1001
                   uint32_t *irq_list, uint8_t irq_count)
1002
{
1003
    int i;
1004
    Aml *var = aml_alloc();
1005
    uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
1006
                        | (high_and_low << 2) | (shared << 3);
1007
    const int header_bytes_in_len = 2;
1008
    uint16_t len = header_bytes_in_len + irq_count * sizeof(uint32_t);
1009

1010
    assert(irq_count > 0);
1011

1012
    build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
1013
    build_append_byte(var->buf, len & 0xFF); /* Length, bits[7:0] */
1014
    build_append_byte(var->buf, len >> 8); /* Length, bits[15:8] */
1015
    build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
1016
    build_append_byte(var->buf, irq_count);   /* Interrupt table length */
1017

1018
    /* Interrupt Number List */
1019
    for (i = 0; i < irq_count; i++) {
1020
        build_append_int_noprefix(var->buf, irq_list[i], 4);
1021
    }
1022
    return var;
1023
}
1024

1025
/* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
1026
Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
1027
            uint8_t aln, uint8_t len)
1028
{
1029
    Aml *var = aml_alloc();
1030
    build_append_byte(var->buf, 0x47); /* IO port descriptor */
1031
    build_append_byte(var->buf, dec);
1032
    build_append_byte(var->buf, min_base & 0xff);
1033
    build_append_byte(var->buf, (min_base >> 8) & 0xff);
1034
    build_append_byte(var->buf, max_base & 0xff);
1035
    build_append_byte(var->buf, (max_base >> 8) & 0xff);
1036
    build_append_byte(var->buf, aln);
1037
    build_append_byte(var->buf, len);
1038
    return var;
1039
}
1040

1041
/*
1042
 * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
1043
 *
1044
 * More verbose description at:
1045
 * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
1046
 *           6.4.2.1 IRQ Descriptor
1047
 */
1048
Aml *aml_irq_no_flags(uint8_t irq)
1049
{
1050
    uint16_t irq_mask;
1051
    Aml *var = aml_alloc();
1052

1053
    assert(irq < 16);
1054
    build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
1055

1056
    irq_mask = 1U << irq;
1057
    build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
1058
    build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
1059
    return var;
1060
}
1061

1062
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
1063
Aml *aml_lnot(Aml *arg)
1064
{
1065
    Aml *var = aml_opcode(0x92 /* LNotOp */);
1066
    aml_append(var, arg);
1067
    return var;
1068
}
1069

1070
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
1071
Aml *aml_equal(Aml *arg1, Aml *arg2)
1072
{
1073
    Aml *var = aml_opcode(0x93 /* LequalOp */);
1074
    aml_append(var, arg1);
1075
    aml_append(var, arg2);
1076
    return var;
1077
}
1078

1079
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreater */
1080
Aml *aml_lgreater(Aml *arg1, Aml *arg2)
1081
{
1082
    Aml *var = aml_opcode(0x94 /* LGreaterOp */);
1083
    aml_append(var, arg1);
1084
    aml_append(var, arg2);
1085
    return var;
1086
}
1087

1088
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreaterEqual */
1089
Aml *aml_lgreater_equal(Aml *arg1, Aml *arg2)
1090
{
1091
    /* LGreaterEqualOp := LNotOp LLessOp */
1092
    Aml *var = aml_opcode(0x92 /* LNotOp */);
1093
    build_append_byte(var->buf, 0x95 /* LLessOp */);
1094
    aml_append(var, arg1);
1095
    aml_append(var, arg2);
1096
    return var;
1097
}
1098

1099
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
1100
Aml *aml_if(Aml *predicate)
1101
{
1102
    Aml *var = aml_bundle(0xA0 /* IfOp */, AML_PACKAGE);
1103
    aml_append(var, predicate);
1104
    return var;
1105
}
1106

1107
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */
1108
Aml *aml_else(void)
1109
{
1110
    Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
1111
    return var;
1112
}
1113

1114
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefWhile */
1115
Aml *aml_while(Aml *predicate)
1116
{
1117
    Aml *var = aml_bundle(0xA2 /* WhileOp */, AML_PACKAGE);
1118
    aml_append(var, predicate);
1119
    return var;
1120
}
1121

1122
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
1123
Aml *aml_method(const char *name, int arg_count, AmlSerializeFlag sflag)
1124
{
1125
    Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
1126
    int methodflags;
1127

1128
    /*
1129
     * MethodFlags:
1130
     *   bit 0-2: ArgCount (0-7)
1131
     *   bit 3: SerializeFlag
1132
     *     0: NotSerialized
1133
     *     1: Serialized
1134
     *   bit 4-7: reserved (must be 0)
1135
     */
1136
    assert(arg_count < 8);
1137
    methodflags = arg_count | (sflag << 3);
1138

1139
    build_append_namestring(var->buf, "%s", name);
1140
    build_append_byte(var->buf, methodflags); /* MethodFlags: ArgCount */
1141
    return var;
1142
}
1143

1144
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
1145
Aml *aml_device(const char *name_format, ...)
1146
{
1147
    va_list ap;
1148
    Aml *var = aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE);
1149
    va_start(ap, name_format);
1150
    build_append_namestringv(var->buf, name_format, ap);
1151
    va_end(ap);
1152
    return var;
1153
}
1154

1155
/* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */
1156
Aml *aml_resource_template(void)
1157
{
1158
    /* ResourceTemplate is a buffer of Resources with EndTag at the end */
1159
    Aml *var = aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE);
1160
    return var;
1161
}
1162

1163
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer
1164
 * Pass byte_list as NULL to request uninitialized buffer to reserve space.
1165
 */
1166
Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
1167
{
1168
    int i;
1169
    Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1170

1171
    for (i = 0; i < buffer_size; i++) {
1172
        if (byte_list == NULL) {
1173
            build_append_byte(var->buf, 0x0);
1174
        } else {
1175
            build_append_byte(var->buf, byte_list[i]);
1176
        }
1177
    }
1178

1179
    return var;
1180
}
1181

1182
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */
1183
Aml *aml_package(uint8_t num_elements)
1184
{
1185
    Aml *var = aml_bundle(0x12 /* PackageOp */, AML_PACKAGE);
1186
    build_append_byte(var->buf, num_elements);
1187
    return var;
1188
}
1189

1190
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
1191
Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
1192
                          Aml *offset, uint32_t len)
1193
{
1194
    Aml *var = aml_alloc();
1195
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1196
    build_append_byte(var->buf, 0x80); /* OpRegionOp */
1197
    build_append_namestring(var->buf, "%s", name);
1198
    build_append_byte(var->buf, rs);
1199
    aml_append(var, offset);
1200
    build_append_int(var->buf, len);
1201
    return var;
1202
}
1203

1204
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */
1205
Aml *aml_named_field(const char *name, unsigned length)
1206
{
1207
    Aml *var = aml_alloc();
1208
    build_append_nameseg(var->buf, name);
1209
    build_append_pkg_length(var->buf, length, false);
1210
    return var;
1211
}
1212

1213
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
1214
Aml *aml_reserved_field(unsigned length)
1215
{
1216
    Aml *var = aml_alloc();
1217
    /* ReservedField  := 0x00 PkgLength */
1218
    build_append_byte(var->buf, 0x00);
1219
    build_append_pkg_length(var->buf, length, false);
1220
    return var;
1221
}
1222

1223
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
1224
Aml *aml_field(const char *name, AmlAccessType type, AmlLockRule lock,
1225
               AmlUpdateRule rule)
1226
{
1227
    Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
1228
    uint8_t flags = rule << 5 | type;
1229

1230
    flags |= lock << 4; /* LockRule at 4 bit offset */
1231

1232
    build_append_namestring(var->buf, "%s", name);
1233
    build_append_byte(var->buf, flags);
1234
    return var;
1235
}
1236

1237
static
1238
Aml *create_field_common(int opcode, Aml *srcbuf, Aml *index, const char *name)
1239
{
1240
    Aml *var = aml_opcode(opcode);
1241
    aml_append(var, srcbuf);
1242
    aml_append(var, index);
1243
    build_append_namestring(var->buf, "%s", name);
1244
    return var;
1245
}
1246

1247
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
1248
Aml *aml_create_field(Aml *srcbuf, Aml *bit_index, Aml *num_bits,
1249
                      const char *name)
1250
{
1251
    Aml *var = aml_alloc();
1252
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1253
    build_append_byte(var->buf, 0x13); /* CreateFieldOp */
1254
    aml_append(var, srcbuf);
1255
    aml_append(var, bit_index);
1256
    aml_append(var, num_bits);
1257
    build_append_namestring(var->buf, "%s", name);
1258
    return var;
1259
}
1260

1261
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
1262
Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
1263
{
1264
    return create_field_common(0x8A /* CreateDWordFieldOp */,
1265
                               srcbuf, index, name);
1266
}
1267

1268
/* ACPI 2.0a: 17.2.4.2 Named Objects Encoding: DefCreateQWordField */
1269
Aml *aml_create_qword_field(Aml *srcbuf, Aml *index, const char *name)
1270
{
1271
    return create_field_common(0x8F /* CreateQWordFieldOp */,
1272
                               srcbuf, index, name);
1273
}
1274

1275
/* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
1276
Aml *aml_string(const char *name_format, ...)
1277
{
1278
    Aml *var = aml_opcode(0x0D /* StringPrefix */);
1279
    va_list ap;
1280
    char *s;
1281
    int len;
1282

1283
    va_start(ap, name_format);
1284
    len = g_vasprintf(&s, name_format, ap);
1285
    va_end(ap);
1286

1287
    g_array_append_vals(var->buf, s, len + 1);
1288
    g_free(s);
1289

1290
    return var;
1291
}
1292

1293
/* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
1294
Aml *aml_local(int num)
1295
{
1296
    uint8_t op = 0x60 /* Local0Op */ + num;
1297

1298
    assert(num <= 7);
1299
    return aml_opcode(op);
1300
}
1301

1302
/* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
1303
Aml *aml_varpackage(uint32_t num_elements)
1304
{
1305
    Aml *var = aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE);
1306
    build_append_int(var->buf, num_elements);
1307
    return var;
1308
}
1309

1310
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
1311
Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
1312
                   const char *name_format, ...)
1313
{
1314
    va_list ap;
1315
    Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE);
1316
    va_start(ap, name_format);
1317
    build_append_namestringv(var->buf, name_format, ap);
1318
    va_end(ap);
1319
    build_append_byte(var->buf, proc_id); /* ProcID */
1320
    build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr));
1321
    build_append_byte(var->buf, pblk_len); /* PblkLen */
1322
    return var;
1323
}
1324

1325
static uint8_t Hex2Digit(char c)
1326
{
1327
    if (c >= 'A') {
1328
        return c - 'A' + 10;
1329
    }
1330

1331
    return c - '0';
1332
}
1333

1334
/* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */
1335
Aml *aml_eisaid(const char *str)
1336
{
1337
    Aml *var = aml_alloc();
1338
    uint32_t id;
1339

1340
    g_assert(strlen(str) == 7);
1341
    id = (str[0] - 0x40) << 26 |
1342
    (str[1] - 0x40) << 21 |
1343
    (str[2] - 0x40) << 16 |
1344
    Hex2Digit(str[3]) << 12 |
1345
    Hex2Digit(str[4]) << 8 |
1346
    Hex2Digit(str[5]) << 4 |
1347
    Hex2Digit(str[6]);
1348

1349
    build_append_byte(var->buf, 0x0C); /* DWordPrefix */
1350
    build_append_int_noprefix(var->buf, bswap32(id), sizeof(id));
1351
    return var;
1352
}
1353

1354
/* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
1355
static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed,
1356
                               AmlMaxFixed max_fixed, AmlDecode dec,
1357
                               uint8_t type_flags)
1358
{
1359
    uint8_t flags = max_fixed | min_fixed | dec;
1360
    Aml *var = aml_alloc();
1361

1362
    build_append_byte(var->buf, type);
1363
    build_append_byte(var->buf, flags);
1364
    build_append_byte(var->buf, type_flags); /* Type Specific Flags */
1365
    return var;
1366
}
1367

1368
/* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */
1369
static Aml *aml_word_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1370
                             AmlMaxFixed max_fixed, AmlDecode dec,
1371
                             uint16_t addr_gran, uint16_t addr_min,
1372
                             uint16_t addr_max, uint16_t addr_trans,
1373
                             uint16_t len, uint8_t type_flags)
1374
{
1375
    Aml *var = aml_alloc();
1376

1377
    build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
1378
    /* minimum length since we do not encode optional fields */
1379
    build_append_byte(var->buf, 0x0D);
1380
    build_append_byte(var->buf, 0x0);
1381

1382
    aml_append(var,
1383
        aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1384
    build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1385
    build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1386
    build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1387
    build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1388
    build_append_int_noprefix(var->buf, len, sizeof(len));
1389
    return var;
1390
}
1391

1392
/* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */
1393
static Aml *aml_dword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1394
                              AmlMaxFixed max_fixed, AmlDecode dec,
1395
                              uint32_t addr_gran, uint32_t addr_min,
1396
                              uint32_t addr_max, uint32_t addr_trans,
1397
                              uint32_t len, uint8_t type_flags)
1398
{
1399
    Aml *var = aml_alloc();
1400

1401
    build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
1402
    /* minimum length since we do not encode optional fields */
1403
    build_append_byte(var->buf, 23);
1404
    build_append_byte(var->buf, 0x0);
1405

1406

1407
    aml_append(var,
1408
        aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1409
    build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1410
    build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1411
    build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1412
    build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1413
    build_append_int_noprefix(var->buf, len, sizeof(len));
1414
    return var;
1415
}
1416

1417
/* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */
1418
static Aml *aml_qword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
1419
                              AmlMaxFixed max_fixed, AmlDecode dec,
1420
                              uint64_t addr_gran, uint64_t addr_min,
1421
                              uint64_t addr_max, uint64_t addr_trans,
1422
                              uint64_t len, uint8_t type_flags)
1423
{
1424
    Aml *var = aml_alloc();
1425

1426
    build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
1427
    /* minimum length since we do not encode optional fields */
1428
    build_append_byte(var->buf, 0x2B);
1429
    build_append_byte(var->buf, 0x0);
1430

1431
    aml_append(var,
1432
        aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
1433
    build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
1434
    build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
1435
    build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
1436
    build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
1437
    build_append_int_noprefix(var->buf, len, sizeof(len));
1438
    return var;
1439
}
1440

1441
/*
1442
 * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
1443
 *
1444
 * More verbose description at:
1445
 * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
1446
 */
1447
Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1448
                         AmlDecode dec, uint16_t addr_gran,
1449
                         uint16_t addr_min, uint16_t addr_max,
1450
                         uint16_t addr_trans, uint16_t len)
1451

1452
{
1453
    return aml_word_as_desc(AML_BUS_NUMBER_RANGE, min_fixed, max_fixed, dec,
1454
                            addr_gran, addr_min, addr_max, addr_trans, len, 0);
1455
}
1456

1457
/*
1458
 * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
1459
 *
1460
 * More verbose description at:
1461
 * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro)
1462
 */
1463
Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1464
                 AmlDecode dec, AmlISARanges isa_ranges,
1465
                 uint16_t addr_gran, uint16_t addr_min,
1466
                 uint16_t addr_max, uint16_t addr_trans,
1467
                 uint16_t len)
1468

1469
{
1470
    return aml_word_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
1471
                            addr_gran, addr_min, addr_max, addr_trans, len,
1472
                            isa_ranges);
1473
}
1474

1475
/*
1476
 * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor
1477
 *
1478
 * More verbose description at:
1479
 * ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro)
1480
 */
1481
Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
1482
                 AmlDecode dec, AmlISARanges isa_ranges,
1483
                 uint32_t addr_gran, uint32_t addr_min,
1484
                 uint32_t addr_max, uint32_t addr_trans,
1485
                 uint32_t len)
1486

1487
{
1488
    return aml_dword_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
1489
                            addr_gran, addr_min, addr_max, addr_trans, len,
1490
                            isa_ranges);
1491
}
1492

1493
/*
1494
 * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
1495
 *
1496
 * More verbose description at:
1497
 * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
1498
 */
1499
Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
1500
                      AmlMaxFixed max_fixed, AmlCacheable cacheable,
1501
                      AmlReadAndWrite read_and_write,
1502
                      uint32_t addr_gran, uint32_t addr_min,
1503
                      uint32_t addr_max, uint32_t addr_trans,
1504
                      uint32_t len)
1505
{
1506
    uint8_t flags = read_and_write | (cacheable << 1);
1507

1508
    return aml_dword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
1509
                             dec, addr_gran, addr_min, addr_max,
1510
                             addr_trans, len, flags);
1511
}
1512

1513
/*
1514
 * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor
1515
 *
1516
 * More verbose description at:
1517
 * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
1518
 */
1519
Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
1520
                      AmlMaxFixed max_fixed, AmlCacheable cacheable,
1521
                      AmlReadAndWrite read_and_write,
1522
                      uint64_t addr_gran, uint64_t addr_min,
1523
                      uint64_t addr_max, uint64_t addr_trans,
1524
                      uint64_t len)
1525
{
1526
    uint8_t flags = read_and_write | (cacheable << 1);
1527

1528
    return aml_qword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
1529
                             dec, addr_gran, addr_min, addr_max,
1530
                             addr_trans, len, flags);
1531
}
1532

1533
/* ACPI 1.0b: 6.4.2.2 DMA Format/6.4.2.2.1 ASL Macro for DMA Descriptor */
1534
Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
1535
             uint8_t channel)
1536
{
1537
    Aml *var = aml_alloc();
1538
    uint8_t flags = sz | bm << 2 | typ << 5;
1539

1540
    assert(channel < 8);
1541
    build_append_byte(var->buf, 0x2A);    /* Byte 0: DMA Descriptor */
1542
    build_append_byte(var->buf, 1U << channel); /* Byte 1: _DMA - DmaChannel */
1543
    build_append_byte(var->buf, flags);   /* Byte 2 */
1544
    return var;
1545
}
1546

1547
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefSleep */
1548
Aml *aml_sleep(uint64_t msec)
1549
{
1550
    Aml *var = aml_alloc();
1551
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1552
    build_append_byte(var->buf, 0x22); /* SleepOp */
1553
    aml_append(var, aml_int(msec));
1554
    return var;
1555
}
1556

1557
static uint8_t Hex2Byte(const char *src)
1558
{
1559
    int hi, lo;
1560

1561
    hi = Hex2Digit(src[0]);
1562
    assert(hi >= 0);
1563
    assert(hi <= 15);
1564

1565
    lo = Hex2Digit(src[1]);
1566
    assert(lo >= 0);
1567
    assert(lo <= 15);
1568
    return (hi << 4) | lo;
1569
}
1570

1571
/*
1572
 * ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro)
1573
 * e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1574
 * call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
1575
 */
1576
Aml *aml_touuid(const char *uuid)
1577
{
1578
    Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1579

1580
    assert(strlen(uuid) == 36);
1581
    assert(uuid[8] == '-');
1582
    assert(uuid[13] == '-');
1583
    assert(uuid[18] == '-');
1584
    assert(uuid[23] == '-');
1585

1586
    build_append_byte(var->buf, Hex2Byte(uuid + 6));  /* dd - at offset 00 */
1587
    build_append_byte(var->buf, Hex2Byte(uuid + 4));  /* cc - at offset 01 */
1588
    build_append_byte(var->buf, Hex2Byte(uuid + 2));  /* bb - at offset 02 */
1589
    build_append_byte(var->buf, Hex2Byte(uuid + 0));  /* aa - at offset 03 */
1590

1591
    build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */
1592
    build_append_byte(var->buf, Hex2Byte(uuid + 9));  /* ee - at offset 05 */
1593

1594
    build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */
1595
    build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */
1596

1597
    build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */
1598
    build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */
1599

1600
    build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */
1601
    build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */
1602
    build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */
1603
    build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */
1604
    build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */
1605
    build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */
1606

1607
    return var;
1608
}
1609

1610
/*
1611
 * ACPI 2.0b: 16.2.3.6.4.3  Unicode Macro (Convert Ascii String To Unicode)
1612
 */
1613
Aml *aml_unicode(const char *str)
1614
{
1615
    int i = 0;
1616
    Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
1617

1618
    do {
1619
        build_append_byte(var->buf, str[i]);
1620
        build_append_byte(var->buf, 0);
1621
        i++;
1622
    } while (i <= strlen(str));
1623

1624
    return var;
1625
}
1626

1627
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */
1628
Aml *aml_refof(Aml *arg)
1629
{
1630
    Aml *var = aml_opcode(0x71 /* RefOfOp */);
1631
    aml_append(var, arg);
1632
    return var;
1633
}
1634

1635
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
1636
Aml *aml_derefof(Aml *arg)
1637
{
1638
    Aml *var = aml_opcode(0x83 /* DerefOfOp */);
1639
    aml_append(var, arg);
1640
    return var;
1641
}
1642

1643
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSizeOf */
1644
Aml *aml_sizeof(Aml *arg)
1645
{
1646
    Aml *var = aml_opcode(0x87 /* SizeOfOp */);
1647
    aml_append(var, arg);
1648
    return var;
1649
}
1650

1651
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMutex */
1652
Aml *aml_mutex(const char *name, uint8_t sync_level)
1653
{
1654
    Aml *var = aml_alloc();
1655
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1656
    build_append_byte(var->buf, 0x01); /* MutexOp */
1657
    build_append_namestring(var->buf, "%s", name);
1658
    assert(!(sync_level & 0xF0));
1659
    build_append_byte(var->buf, sync_level);
1660
    return var;
1661
}
1662

1663
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAcquire */
1664
Aml *aml_acquire(Aml *mutex, uint16_t timeout)
1665
{
1666
    Aml *var = aml_alloc();
1667
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1668
    build_append_byte(var->buf, 0x23); /* AcquireOp */
1669
    aml_append(var, mutex);
1670
    build_append_int_noprefix(var->buf, timeout, sizeof(timeout));
1671
    return var;
1672
}
1673

1674
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefRelease */
1675
Aml *aml_release(Aml *mutex)
1676
{
1677
    Aml *var = aml_alloc();
1678
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
1679
    build_append_byte(var->buf, 0x27); /* ReleaseOp */
1680
    aml_append(var, mutex);
1681
    return var;
1682
}
1683

1684
/* ACPI 1.0b: 16.2.5.1 Name Space Modifier Objects Encoding: DefAlias */
1685
Aml *aml_alias(const char *source_object, const char *alias_object)
1686
{
1687
    Aml *var = aml_opcode(0x06 /* AliasOp */);
1688
    aml_append(var, aml_name("%s", source_object));
1689
    aml_append(var, aml_name("%s", alias_object));
1690
    return var;
1691
}
1692

1693
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
1694
Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
1695
{
1696
    return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
1697
                                 target);
1698
}
1699

1700
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
1701
Aml *aml_object_type(Aml *object)
1702
{
1703
    Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
1704
    aml_append(var, object);
1705
    return var;
1706
}
1707

1708
void acpi_table_begin(AcpiTable *desc, GArray *array)
1709
{
1710

1711
    desc->array = array;
1712
    desc->table_offset = array->len;
1713

1714
    /*
1715
     * ACPI spec 1.0b
1716
     * 5.2.3 System Description Table Header
1717
     */
1718
    g_assert(strlen(desc->sig) == 4);
1719
    g_array_append_vals(array, desc->sig, 4); /* Signature */
1720
    /*
1721
     * reserve space for Length field, which will be patched by
1722
     * acpi_table_end() when the table creation is finished.
1723
     */
1724
    build_append_int_noprefix(array, 0, 4); /* Length */
1725
    build_append_int_noprefix(array, desc->rev, 1); /* Revision */
1726
    build_append_int_noprefix(array, 0, 1); /* Checksum */
1727
    build_append_padded_str(array, desc->oem_id, 6, '\0'); /* OEMID */
1728
    /* OEM Table ID */
1729
    build_append_padded_str(array, desc->oem_table_id, 8, '\0');
1730
    build_append_int_noprefix(array, 1, 4); /* OEM Revision */
1731
    g_array_append_vals(array, ACPI_BUILD_APPNAME8, 4); /* Creator ID */
1732
    build_append_int_noprefix(array, 1, 4); /* Creator Revision */
1733
}
1734

1735
void acpi_table_end(BIOSLinker *linker, AcpiTable *desc)
1736
{
1737
    /*
1738
     * ACPI spec 1.0b
1739
     * 5.2.3 System Description Table Header
1740
     * Table 5-2 DESCRIPTION_HEADER Fields
1741
     */
1742
    const unsigned checksum_offset = 9;
1743
    uint32_t table_len = desc->array->len - desc->table_offset;
1744
    uint32_t table_len_le = cpu_to_le32(table_len);
1745
    gchar *len_ptr = &desc->array->data[desc->table_offset + 4];
1746

1747
    /* patch "Length" field that has been reserved by acpi_table_begin()
1748
     * to the actual length, i.e. accumulated table length from
1749
     * acpi_table_begin() till acpi_table_end()
1750
     */
1751
    memcpy(len_ptr, &table_len_le, sizeof table_len_le);
1752

1753
    bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
1754
        desc->table_offset, table_len, desc->table_offset + checksum_offset);
1755
}
1756

1757
void *acpi_data_push(GArray *table_data, unsigned size)
1758
{
1759
    unsigned off = table_data->len;
1760
    g_array_set_size(table_data, off + size);
1761
    return table_data->data + off;
1762
}
1763

1764
unsigned acpi_data_len(GArray *table)
1765
{
1766
    assert(g_array_get_element_size(table) == 1);
1767
    return table->len;
1768
}
1769

1770
void acpi_add_table(GArray *table_offsets, GArray *table_data)
1771
{
1772
    uint32_t offset = table_data->len;
1773
    g_array_append_val(table_offsets, offset);
1774
}
1775

1776
void acpi_build_tables_init(AcpiBuildTables *tables)
1777
{
1778
    tables->rsdp = g_array_new(false, true /* clear */, 1);
1779
    tables->table_data = g_array_new(false, true /* clear */, 1);
1780
    tables->tcpalog = g_array_new(false, true /* clear */, 1);
1781
    tables->vmgenid = g_array_new(false, true /* clear */, 1);
1782
    tables->hardware_errors = g_array_new(false, true /* clear */, 1);
1783
    tables->linker = bios_linker_loader_init();
1784
}
1785

1786
void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
1787
{
1788
    bios_linker_loader_cleanup(tables->linker);
1789
    g_array_free(tables->rsdp, true);
1790
    g_array_free(tables->table_data, true);
1791
    g_array_free(tables->tcpalog, mfre);
1792
    g_array_free(tables->vmgenid, mfre);
1793
    g_array_free(tables->hardware_errors, mfre);
1794
}
1795

1796
/*
1797
 * ACPI spec 5.2.5.3 Root System Description Pointer (RSDP).
1798
 * (Revision 1.0 or later)
1799
 */
1800
void
1801
build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
1802
{
1803
    int tbl_off = tbl->len; /* Table offset in the RSDP file */
1804

1805
    switch (rsdp_data->revision) {
1806
    case 0:
1807
        /* With ACPI 1.0, we must have an RSDT pointer */
1808
        g_assert(rsdp_data->rsdt_tbl_offset);
1809
        break;
1810
    case 2:
1811
        /* With ACPI 2.0+, we must have an XSDT pointer */
1812
        g_assert(rsdp_data->xsdt_tbl_offset);
1813
        break;
1814
    default:
1815
        /* Only revisions 0 (ACPI 1.0) and 2 (ACPI 2.0+) are valid for RSDP */
1816
        g_assert_not_reached();
1817
    }
1818

1819
    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16,
1820
                             true /* fseg memory */);
1821

1822
    g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */
1823
    build_append_int_noprefix(tbl, 0, 1); /* Checksum */
1824
    g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */
1825
    build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */
1826
    build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */
1827
    if (rsdp_data->rsdt_tbl_offset) {
1828
        /* RSDT address to be filled by guest linker */
1829
        bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
1830
                                       tbl_off + 16, 4,
1831
                                       ACPI_BUILD_TABLE_FILE,
1832
                                       *rsdp_data->rsdt_tbl_offset);
1833
    }
1834

1835
    /* Checksum to be filled by guest linker */
1836
    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
1837
                                    tbl_off, 20, /* ACPI rev 1.0 RSDP size */
1838
                                    8);
1839

1840
    if (rsdp_data->revision == 0) {
1841
        /* ACPI 1.0 RSDP, we're done */
1842
        return;
1843
    }
1844

1845
    build_append_int_noprefix(tbl, 36, 4); /* Length */
1846

1847
    /* XSDT address to be filled by guest linker */
1848
    build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */
1849
    /* We already validated our xsdt pointer */
1850
    bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
1851
                                   tbl_off + 24, 8,
1852
                                   ACPI_BUILD_TABLE_FILE,
1853
                                   *rsdp_data->xsdt_tbl_offset);
1854

1855
    build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */
1856
    build_append_int_noprefix(tbl, 0, 3); /* Reserved */
1857

1858
    /* Extended checksum to be filled by Guest linker */
1859
    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
1860
                                    tbl_off, 36, /* ACPI rev 2.0 RSDP size */
1861
                                    32);
1862
}
1863

1864
/*
1865
 * ACPI 1.0 Root System Description Table (RSDT)
1866
 */
1867
void
1868
build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1869
           const char *oem_id, const char *oem_table_id)
1870
{
1871
    int i;
1872
    AcpiTable table = { .sig = "RSDT", .rev = 1,
1873
                        .oem_id = oem_id, .oem_table_id = oem_table_id };
1874

1875
    acpi_table_begin(&table, table_data);
1876
    for (i = 0; i < table_offsets->len; ++i) {
1877
        uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
1878
        uint32_t rsdt_entry_offset = table.array->len;
1879

1880
        /* reserve space for entry */
1881
        build_append_int_noprefix(table.array, 0, 4);
1882

1883
        /* mark position of RSDT entry to be filled by Guest linker */
1884
        bios_linker_loader_add_pointer(linker,
1885
            ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, 4,
1886
            ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1887

1888
    }
1889
    acpi_table_end(linker, &table);
1890
}
1891

1892
/*
1893
 * ACPI 2.0 eXtended System Description Table (XSDT)
1894
 */
1895
void
1896
build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1897
           const char *oem_id, const char *oem_table_id)
1898
{
1899
    int i;
1900
    AcpiTable table = { .sig = "XSDT", .rev = 1,
1901
                        .oem_id = oem_id, .oem_table_id = oem_table_id };
1902

1903
    acpi_table_begin(&table, table_data);
1904

1905
    for (i = 0; i < table_offsets->len; ++i) {
1906
        uint64_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
1907
        uint64_t xsdt_entry_offset = table.array->len;
1908

1909
        /* reserve space for entry */
1910
        build_append_int_noprefix(table.array, 0, 8);
1911

1912
        /* mark position of RSDT entry to be filled by Guest linker */
1913
        bios_linker_loader_add_pointer(linker,
1914
            ACPI_BUILD_TABLE_FILE, xsdt_entry_offset, 8,
1915
            ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1916
    }
1917
    acpi_table_end(linker, &table);
1918
}
1919

1920
/*
1921
 * ACPI spec, Revision 4.0
1922
 * 5.2.16.2 Memory Affinity Structure
1923
 */
1924
void build_srat_memory(GArray *table_data, uint64_t base,
1925
                       uint64_t len, int node, MemoryAffinityFlags flags)
1926
{
1927
    build_append_int_noprefix(table_data, 1, 1); /* Type */
1928
    build_append_int_noprefix(table_data, 40, 1); /* Length */
1929
    build_append_int_noprefix(table_data, node, 4); /* Proximity Domain */
1930
    build_append_int_noprefix(table_data, 0, 2); /* Reserved */
1931
    build_append_int_noprefix(table_data, base, 4); /* Base Address Low */
1932
    /* Base Address High */
1933
    build_append_int_noprefix(table_data, base >> 32, 4);
1934
    build_append_int_noprefix(table_data, len, 4); /* Length Low */
1935
    build_append_int_noprefix(table_data, len >> 32, 4); /* Length High */
1936
    build_append_int_noprefix(table_data, 0, 4); /* Reserved */
1937
    build_append_int_noprefix(table_data, flags, 4); /* Flags */
1938
    build_append_int_noprefix(table_data, 0, 8); /* Reserved */
1939
}
1940

1941
/*
1942
 * ACPI spec 5.2.17 System Locality Distance Information Table
1943
 * (Revision 2.0 or later)
1944
 */
1945
void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
1946
                const char *oem_id, const char *oem_table_id)
1947
{
1948
    int i, j;
1949
    int nb_numa_nodes = ms->numa_state->num_nodes;
1950
    AcpiTable table = { .sig = "SLIT", .rev = 1,
1951
                        .oem_id = oem_id, .oem_table_id = oem_table_id };
1952

1953
    acpi_table_begin(&table, table_data);
1954

1955
    build_append_int_noprefix(table_data, nb_numa_nodes, 8);
1956
    for (i = 0; i < nb_numa_nodes; i++) {
1957
        for (j = 0; j < nb_numa_nodes; j++) {
1958
            assert(ms->numa_state->nodes[i].distance[j]);
1959
            build_append_int_noprefix(table_data,
1960
                                      ms->numa_state->nodes[i].distance[j],
1961
                                      1);
1962
        }
1963
    }
1964
    acpi_table_end(linker, &table);
1965
}
1966

1967
/*
1968
 * ACPI spec, Revision 6.3
1969
 * 5.2.29.1 Processor hierarchy node structure (Type 0)
1970
 */
1971
static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
1972
                                           uint32_t parent, uint32_t id,
1973
                                           uint32_t *priv_rsrc,
1974
                                           uint32_t priv_num)
1975
{
1976
    int i;
1977

1978
    build_append_byte(tbl, 0);                 /* Type 0 - processor */
1979
    build_append_byte(tbl, 20 + priv_num * 4); /* Length */
1980
    build_append_int_noprefix(tbl, 0, 2);      /* Reserved */
1981
    build_append_int_noprefix(tbl, flags, 4);  /* Flags */
1982
    build_append_int_noprefix(tbl, parent, 4); /* Parent */
1983
    build_append_int_noprefix(tbl, id, 4);     /* ACPI Processor ID */
1984

1985
    /* Number of private resources */
1986
    build_append_int_noprefix(tbl, priv_num, 4);
1987

1988
    /* Private resources[N] */
1989
    if (priv_num > 0) {
1990
        assert(priv_rsrc);
1991
        for (i = 0; i < priv_num; i++) {
1992
            build_append_int_noprefix(tbl, priv_rsrc[i], 4);
1993
        }
1994
    }
1995
}
1996

1997
void build_spcr(GArray *table_data, BIOSLinker *linker,
1998
                const AcpiSpcrData *f, const uint8_t rev,
1999
                const char *oem_id, const char *oem_table_id)
2000
{
2001
    AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
2002
                        .oem_table_id = oem_table_id };
2003

2004
    acpi_table_begin(&table, table_data);
2005
    /* Interface type */
2006
    build_append_int_noprefix(table_data, f->interface_type, 1);
2007
    /* Reserved */
2008
    build_append_int_noprefix(table_data, 0, 3);
2009
    /* Base Address */
2010
    build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
2011
                     f->base_addr.offset, f->base_addr.size,
2012
                     f->base_addr.addr);
2013
    /* Interrupt type */
2014
    build_append_int_noprefix(table_data, f->interrupt_type, 1);
2015
    /* IRQ */
2016
    build_append_int_noprefix(table_data, f->pc_interrupt, 1);
2017
    /* Global System Interrupt */
2018
    build_append_int_noprefix(table_data, f->interrupt, 4);
2019
    /* Baud Rate */
2020
    build_append_int_noprefix(table_data, f->baud_rate, 1);
2021
    /* Parity */
2022
    build_append_int_noprefix(table_data, f->parity, 1);
2023
    /* Stop Bits */
2024
    build_append_int_noprefix(table_data, f->stop_bits, 1);
2025
    /* Flow Control */
2026
    build_append_int_noprefix(table_data, f->flow_control, 1);
2027
    /* Language */
2028
    build_append_int_noprefix(table_data, f->language, 1);
2029
    /* Terminal Type */
2030
    build_append_int_noprefix(table_data, f->terminal_type, 1);
2031
    /* PCI Device ID  */
2032
    build_append_int_noprefix(table_data, f->pci_device_id, 2);
2033
    /* PCI Vendor ID */
2034
    build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
2035
    /* PCI Bus Number */
2036
    build_append_int_noprefix(table_data, f->pci_bus, 1);
2037
    /* PCI Device Number */
2038
    build_append_int_noprefix(table_data, f->pci_device, 1);
2039
    /* PCI Function Number */
2040
    build_append_int_noprefix(table_data, f->pci_function, 1);
2041
    /* PCI Flags */
2042
    build_append_int_noprefix(table_data, f->pci_flags, 4);
2043
    /* PCI Segment */
2044
    build_append_int_noprefix(table_data, f->pci_segment, 1);
2045
    /* Reserved */
2046
    build_append_int_noprefix(table_data, 0, 4);
2047

2048
    acpi_table_end(linker, &table);
2049
}
2050
/*
2051
 * ACPI spec, Revision 6.3
2052
 * 5.2.29 Processor Properties Topology Table (PPTT)
2053
 */
2054
void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
2055
                const char *oem_id, const char *oem_table_id)
2056
{
2057
    MachineClass *mc = MACHINE_GET_CLASS(ms);
2058
    CPUArchIdList *cpus = ms->possible_cpus;
2059
    int64_t socket_id = -1, cluster_id = -1, core_id = -1;
2060
    uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
2061
    uint32_t pptt_start = table_data->len;
2062
    int n;
2063
    AcpiTable table = { .sig = "PPTT", .rev = 2,
2064
                        .oem_id = oem_id, .oem_table_id = oem_table_id };
2065

2066
    acpi_table_begin(&table, table_data);
2067

2068
    /*
2069
     * This works with the assumption that cpus[n].props.*_id has been
2070
     * sorted from top to down levels in mc->possible_cpu_arch_ids().
2071
     * Otherwise, the unexpected and duplicated containers will be
2072
     * created.
2073
     */
2074
    for (n = 0; n < cpus->len; n++) {
2075
        if (cpus->cpus[n].props.socket_id != socket_id) {
2076
            assert(cpus->cpus[n].props.socket_id > socket_id);
2077
            socket_id = cpus->cpus[n].props.socket_id;
2078
            cluster_id = -1;
2079
            core_id = -1;
2080
            socket_offset = table_data->len - pptt_start;
2081
            build_processor_hierarchy_node(table_data,
2082
                (1 << 0), /* Physical package */
2083
                0, socket_id, NULL, 0);
2084
        }
2085

2086
        if (mc->smp_props.clusters_supported && mc->smp_props.has_clusters) {
2087
            if (cpus->cpus[n].props.cluster_id != cluster_id) {
2088
                assert(cpus->cpus[n].props.cluster_id > cluster_id);
2089
                cluster_id = cpus->cpus[n].props.cluster_id;
2090
                core_id = -1;
2091
                cluster_offset = table_data->len - pptt_start;
2092
                build_processor_hierarchy_node(table_data,
2093
                    (0 << 0), /* Not a physical package */
2094
                    socket_offset, cluster_id, NULL, 0);
2095
            }
2096
        } else {
2097
            cluster_offset = socket_offset;
2098
        }
2099

2100
        if (ms->smp.threads == 1) {
2101
            build_processor_hierarchy_node(table_data,
2102
                (1 << 1) | /* ACPI Processor ID valid */
2103
                (1 << 3),  /* Node is a Leaf */
2104
                cluster_offset, n, NULL, 0);
2105
        } else {
2106
            if (cpus->cpus[n].props.core_id != core_id) {
2107
                assert(cpus->cpus[n].props.core_id > core_id);
2108
                core_id = cpus->cpus[n].props.core_id;
2109
                core_offset = table_data->len - pptt_start;
2110
                build_processor_hierarchy_node(table_data,
2111
                    (0 << 0), /* Not a physical package */
2112
                    cluster_offset, core_id, NULL, 0);
2113
            }
2114

2115
            build_processor_hierarchy_node(table_data,
2116
                (1 << 1) | /* ACPI Processor ID valid */
2117
                (1 << 2) | /* Processor is a Thread */
2118
                (1 << 3),  /* Node is a Leaf */
2119
                core_offset, n, NULL, 0);
2120
        }
2121
    }
2122

2123
    acpi_table_end(linker, &table);
2124
}
2125

2126
/* build rev1/rev3/rev5.1/rev6.0 FADT */
2127
void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
2128
                const char *oem_id, const char *oem_table_id)
2129
{
2130
    int off;
2131
    AcpiTable table = { .sig = "FACP", .rev = f->rev,
2132
                        .oem_id = oem_id, .oem_table_id = oem_table_id };
2133

2134
    acpi_table_begin(&table, tbl);
2135

2136
    /* FACS address to be filled by Guest linker at runtime */
2137
    off = tbl->len;
2138
    build_append_int_noprefix(tbl, 0, 4); /* FIRMWARE_CTRL */
2139
    if (f->facs_tbl_offset) { /* don't patch if not supported by platform */
2140
        bios_linker_loader_add_pointer(linker,
2141
            ACPI_BUILD_TABLE_FILE, off, 4,
2142
            ACPI_BUILD_TABLE_FILE, *f->facs_tbl_offset);
2143
    }
2144

2145
    /* DSDT address to be filled by Guest linker at runtime */
2146
    off = tbl->len;
2147
    build_append_int_noprefix(tbl, 0, 4); /* DSDT */
2148
    if (f->dsdt_tbl_offset) { /* don't patch if not supported by platform */
2149
        bios_linker_loader_add_pointer(linker,
2150
            ACPI_BUILD_TABLE_FILE, off, 4,
2151
            ACPI_BUILD_TABLE_FILE, *f->dsdt_tbl_offset);
2152
    }
2153

2154
    /* ACPI1.0: INT_MODEL, ACPI2.0+: Reserved */
2155
    build_append_int_noprefix(tbl, f->int_model /* Multiple APIC */, 1);
2156
    /* Preferred_PM_Profile */
2157
    build_append_int_noprefix(tbl, 0 /* Unspecified */, 1);
2158
    build_append_int_noprefix(tbl, f->sci_int, 2); /* SCI_INT */
2159
    build_append_int_noprefix(tbl, f->smi_cmd, 4); /* SMI_CMD */
2160
    build_append_int_noprefix(tbl, f->acpi_enable_cmd, 1); /* ACPI_ENABLE */
2161
    build_append_int_noprefix(tbl, f->acpi_disable_cmd, 1); /* ACPI_DISABLE */
2162
    build_append_int_noprefix(tbl, 0 /* not supported */, 1); /* S4BIOS_REQ */
2163
    /* ACPI1.0: Reserved, ACPI2.0+: PSTATE_CNT */
2164
    build_append_int_noprefix(tbl, 0, 1);
2165
    build_append_int_noprefix(tbl, f->pm1a_evt.address, 4); /* PM1a_EVT_BLK */
2166
    build_append_int_noprefix(tbl, 0, 4); /* PM1b_EVT_BLK */
2167
    build_append_int_noprefix(tbl, f->pm1a_cnt.address, 4); /* PM1a_CNT_BLK */
2168
    build_append_int_noprefix(tbl, 0, 4); /* PM1b_CNT_BLK */
2169
    build_append_int_noprefix(tbl, 0, 4); /* PM2_CNT_BLK */
2170
    build_append_int_noprefix(tbl, f->pm_tmr.address, 4); /* PM_TMR_BLK */
2171
    build_append_int_noprefix(tbl, f->gpe0_blk.address, 4); /* GPE0_BLK */
2172
    build_append_int_noprefix(tbl, 0, 4); /* GPE1_BLK */
2173
    /* PM1_EVT_LEN */
2174
    build_append_int_noprefix(tbl, f->pm1a_evt.bit_width / 8, 1);
2175
    /* PM1_CNT_LEN */
2176
    build_append_int_noprefix(tbl, f->pm1a_cnt.bit_width / 8, 1);
2177
    build_append_int_noprefix(tbl, 0, 1); /* PM2_CNT_LEN */
2178
    build_append_int_noprefix(tbl, f->pm_tmr.bit_width / 8, 1); /* PM_TMR_LEN */
2179
    /* GPE0_BLK_LEN */
2180
    build_append_int_noprefix(tbl, f->gpe0_blk.bit_width / 8, 1);
2181
    build_append_int_noprefix(tbl, 0, 1); /* GPE1_BLK_LEN */
2182
    build_append_int_noprefix(tbl, 0, 1); /* GPE1_BASE */
2183
    build_append_int_noprefix(tbl, 0, 1); /* CST_CNT */
2184
    build_append_int_noprefix(tbl, f->plvl2_lat, 2); /* P_LVL2_LAT */
2185
    build_append_int_noprefix(tbl, f->plvl3_lat, 2); /* P_LVL3_LAT */
2186
    build_append_int_noprefix(tbl, 0, 2); /* FLUSH_SIZE */
2187
    build_append_int_noprefix(tbl, 0, 2); /* FLUSH_STRIDE */
2188
    build_append_int_noprefix(tbl, 0, 1); /* DUTY_OFFSET */
2189
    build_append_int_noprefix(tbl, 0, 1); /* DUTY_WIDTH */
2190
    build_append_int_noprefix(tbl, 0, 1); /* DAY_ALRM */
2191
    build_append_int_noprefix(tbl, 0, 1); /* MON_ALRM */
2192
    build_append_int_noprefix(tbl, f->rtc_century, 1); /* CENTURY */
2193
    /* IAPC_BOOT_ARCH */
2194
    if (f->rev == 1) {
2195
        build_append_int_noprefix(tbl, 0, 2);
2196
    } else {
2197
        /* since ACPI v2.0 */
2198
        build_append_int_noprefix(tbl, f->iapc_boot_arch, 2);
2199
    }
2200
    build_append_int_noprefix(tbl, 0, 1); /* Reserved */
2201
    build_append_int_noprefix(tbl, f->flags, 4); /* Flags */
2202

2203
    if (f->rev == 1) {
2204
        goto done;
2205
    }
2206

2207
    build_append_gas_from_struct(tbl, &f->reset_reg); /* RESET_REG */
2208
    build_append_int_noprefix(tbl, f->reset_val, 1); /* RESET_VALUE */
2209
    /* Since ACPI 5.1 */
2210
    if ((f->rev >= 6) || ((f->rev == 5) && f->minor_ver > 0)) {
2211
        build_append_int_noprefix(tbl, f->arm_boot_arch, 2); /* ARM_BOOT_ARCH */
2212
        /* FADT Minor Version */
2213
        build_append_int_noprefix(tbl, f->minor_ver, 1);
2214
    } else {
2215
        build_append_int_noprefix(tbl, 0, 3); /* Reserved up to ACPI 5.0 */
2216
    }
2217
    build_append_int_noprefix(tbl, 0, 8); /* X_FIRMWARE_CTRL */
2218

2219
    /* XDSDT address to be filled by Guest linker at runtime */
2220
    off = tbl->len;
2221
    build_append_int_noprefix(tbl, 0, 8); /* X_DSDT */
2222
    if (f->xdsdt_tbl_offset) {
2223
        bios_linker_loader_add_pointer(linker,
2224
            ACPI_BUILD_TABLE_FILE, off, 8,
2225
            ACPI_BUILD_TABLE_FILE, *f->xdsdt_tbl_offset);
2226
    }
2227

2228
    build_append_gas_from_struct(tbl, &f->pm1a_evt); /* X_PM1a_EVT_BLK */
2229
    /* X_PM1b_EVT_BLK */
2230
    build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
2231
    build_append_gas_from_struct(tbl, &f->pm1a_cnt); /* X_PM1a_CNT_BLK */
2232
    /* X_PM1b_CNT_BLK */
2233
    build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
2234
    /* X_PM2_CNT_BLK */
2235
    build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
2236
    build_append_gas_from_struct(tbl, &f->pm_tmr); /* X_PM_TMR_BLK */
2237
    build_append_gas_from_struct(tbl, &f->gpe0_blk); /* X_GPE0_BLK */
2238
    build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0); /* X_GPE1_BLK */
2239

2240
    if (f->rev <= 4) {
2241
        goto done;
2242
    }
2243

2244
    /* SLEEP_CONTROL_REG */
2245
    build_append_gas_from_struct(tbl, &f->sleep_ctl);
2246
    /* SLEEP_STATUS_REG */
2247
    build_append_gas_from_struct(tbl, &f->sleep_sts);
2248

2249
    if (f->rev == 5) {
2250
        goto done;
2251
    }
2252

2253
    /* Hypervisor Vendor Identity */
2254
    build_append_padded_str(tbl, "QEMU", 8, '\0');
2255

2256
    /* TODO: extra fields need to be added to support revisions above rev6 */
2257
    assert(f->rev == 6);
2258

2259
done:
2260
    acpi_table_end(linker, &table);
2261
}
2262

2263
#ifdef CONFIG_TPM
2264
/*
2265
 * build_tpm2 - Build the TPM2 table as specified in
2266
 * table 7: TCG Hardware Interface Description Table Format for TPM 2.0
2267
 * of TCG ACPI Specification, Family “1.2” and “2.0”, Version 1.2, Rev 8
2268
 */
2269
void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
2270
                const char *oem_id, const char *oem_table_id)
2271
{
2272
    uint8_t start_method_params[12] = {};
2273
    unsigned log_addr_offset;
2274
    uint64_t control_area_start_address;
2275
    TPMIf *tpmif = tpm_find();
2276
    uint32_t start_method;
2277
    AcpiTable table = { .sig = "TPM2", .rev = 4,
2278
                        .oem_id = oem_id, .oem_table_id = oem_table_id };
2279

2280
    acpi_table_begin(&table, table_data);
2281

2282
    /* Platform Class */
2283
    build_append_int_noprefix(table_data, TPM2_ACPI_CLASS_CLIENT, 2);
2284
    /* Reserved */
2285
    build_append_int_noprefix(table_data, 0, 2);
2286
    if (TPM_IS_TIS_ISA(tpmif) || TPM_IS_TIS_SYSBUS(tpmif)) {
2287
        control_area_start_address = 0;
2288
        start_method = TPM2_START_METHOD_MMIO;
2289
    } else if (TPM_IS_CRB(tpmif)) {
2290
        control_area_start_address = TPM_CRB_ADDR_CTRL;
2291
        start_method = TPM2_START_METHOD_CRB;
2292
    } else {
2293
        g_assert_not_reached();
2294
    }
2295
    /* Address of Control Area */
2296
    build_append_int_noprefix(table_data, control_area_start_address, 8);
2297
    /* Start Method */
2298
    build_append_int_noprefix(table_data, start_method, 4);
2299

2300
    /* Platform Specific Parameters */
2301
    g_array_append_vals(table_data, &start_method_params,
2302
                        ARRAY_SIZE(start_method_params));
2303

2304
    /* Log Area Minimum Length */
2305
    build_append_int_noprefix(table_data, TPM_LOG_AREA_MINIMUM_SIZE, 4);
2306

2307
    acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
2308
    bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, tcpalog, 1,
2309
                             false);
2310

2311
    log_addr_offset = table_data->len;
2312

2313
    /* Log Area Start Address to be filled by Guest linker */
2314
    build_append_int_noprefix(table_data, 0, 8);
2315
    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
2316
                                   log_addr_offset, 8,
2317
                                   ACPI_BUILD_TPMLOG_FILE, 0);
2318
    acpi_table_end(linker, &table);
2319
}
2320
#endif
2321

2322
Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set, uint32_t io_offset,
2323
               uint32_t mmio32_offset, uint64_t mmio64_offset,
2324
               uint16_t bus_nr_offset)
2325
{
2326
    Aml *crs = aml_resource_template();
2327
    CrsRangeSet temp_range_set;
2328
    CrsRangeEntry *entry;
2329
    uint8_t max_bus = pci_bus_num(host->bus);
2330
    uint8_t type;
2331
    int devfn;
2332
    int i;
2333

2334
    crs_range_set_init(&temp_range_set);
2335
    for (devfn = 0; devfn < ARRAY_SIZE(host->bus->devices); devfn++) {
2336
        uint64_t range_base, range_limit;
2337
        PCIDevice *dev = host->bus->devices[devfn];
2338

2339
        if (!dev) {
2340
            continue;
2341
        }
2342

2343
        for (i = 0; i < PCI_NUM_REGIONS; i++) {
2344
            PCIIORegion *r = &dev->io_regions[i];
2345

2346
            range_base = r->addr;
2347
            range_limit = r->addr + r->size - 1;
2348

2349
            /*
2350
             * Work-around for old bioses
2351
             * that do not support multiple root buses
2352
             */
2353
            if (!range_base || range_base > range_limit) {
2354
                continue;
2355
            }
2356

2357
            if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
2358
                crs_range_insert(temp_range_set.io_ranges,
2359
                                 range_base, range_limit);
2360
            } else { /* "memory" */
2361
                uint64_t length = range_limit - range_base + 1;
2362
                if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
2363
                    crs_range_insert(temp_range_set.mem_ranges, range_base,
2364
                                     range_limit);
2365
                } else {
2366
                    crs_range_insert(temp_range_set.mem_64bit_ranges,
2367
                                     range_base, range_limit);
2368
                }
2369
            }
2370
        }
2371

2372
        type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
2373
        if (type == PCI_HEADER_TYPE_BRIDGE) {
2374
            uint8_t subordinate = dev->config[PCI_SUBORDINATE_BUS];
2375
            if (subordinate > max_bus) {
2376
                max_bus = subordinate;
2377
            }
2378

2379
            range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
2380
            range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
2381

2382
             /*
2383
              * Work-around for old bioses
2384
              * that do not support multiple root buses
2385
              */
2386
            if (range_base && range_base <= range_limit) {
2387
                crs_range_insert(temp_range_set.io_ranges,
2388
                                 range_base, range_limit);
2389
            }
2390

2391
            range_base =
2392
                pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
2393
            range_limit =
2394
                pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
2395

2396
            /*
2397
             * Work-around for old bioses
2398
             * that do not support multiple root buses
2399
             */
2400
            if (range_base && range_base <= range_limit) {
2401
                uint64_t length = range_limit - range_base + 1;
2402
                if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
2403
                    crs_range_insert(temp_range_set.mem_ranges,
2404
                                     range_base, range_limit);
2405
                } else {
2406
                    crs_range_insert(temp_range_set.mem_64bit_ranges,
2407
                                     range_base, range_limit);
2408
                }
2409
            }
2410

2411
            range_base =
2412
                pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
2413
            range_limit =
2414
                pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
2415

2416
            /*
2417
             * Work-around for old bioses
2418
             * that do not support multiple root buses
2419
             */
2420
            if (range_base && range_base <= range_limit) {
2421
                uint64_t length = range_limit - range_base + 1;
2422
                if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
2423
                    crs_range_insert(temp_range_set.mem_ranges,
2424
                                     range_base, range_limit);
2425
                } else {
2426
                    crs_range_insert(temp_range_set.mem_64bit_ranges,
2427
                                     range_base, range_limit);
2428
                }
2429
            }
2430
        }
2431
    }
2432

2433
    crs_range_merge(temp_range_set.io_ranges);
2434
    for (i = 0; i < temp_range_set.io_ranges->len; i++) {
2435
        entry = g_ptr_array_index(temp_range_set.io_ranges, i);
2436
        aml_append(crs,
2437
                   aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED,
2438
                                AML_POS_DECODE, AML_ENTIRE_RANGE,
2439
                                0, entry->base, entry->limit, io_offset,
2440
                                entry->limit - entry->base + 1));
2441
        crs_range_insert(range_set->io_ranges, entry->base, entry->limit);
2442
    }
2443

2444
    crs_range_merge(temp_range_set.mem_ranges);
2445
    for (i = 0; i < temp_range_set.mem_ranges->len; i++) {
2446
        entry = g_ptr_array_index(temp_range_set.mem_ranges, i);
2447
        assert(entry->limit <= UINT32_MAX &&
2448
               (entry->limit - entry->base + 1) <= UINT32_MAX);
2449
        aml_append(crs,
2450
                   aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
2451
                                    AML_MAX_FIXED, AML_NON_CACHEABLE,
2452
                                    AML_READ_WRITE,
2453
                                    0, entry->base, entry->limit, mmio32_offset,
2454
                                    entry->limit - entry->base + 1));
2455
        crs_range_insert(range_set->mem_ranges, entry->base, entry->limit);
2456
    }
2457

2458
    crs_range_merge(temp_range_set.mem_64bit_ranges);
2459
    for (i = 0; i < temp_range_set.mem_64bit_ranges->len; i++) {
2460
        entry = g_ptr_array_index(temp_range_set.mem_64bit_ranges, i);
2461
        aml_append(crs,
2462
                   aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED,
2463
                                    AML_MAX_FIXED, AML_NON_CACHEABLE,
2464
                                    AML_READ_WRITE,
2465
                                    0, entry->base, entry->limit, mmio64_offset,
2466
                                    entry->limit - entry->base + 1));
2467
        crs_range_insert(range_set->mem_64bit_ranges,
2468
                         entry->base, entry->limit);
2469
    }
2470

2471
    crs_range_set_free(&temp_range_set);
2472

2473
    aml_append(crs,
2474
        aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
2475
                            0,
2476
                            pci_bus_num(host->bus),
2477
                            max_bus,
2478
                            bus_nr_offset,
2479
                            max_bus - pci_bus_num(host->bus) + 1));
2480

2481
    return crs;
2482
}
2483

2484
/* ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors */
2485
static Aml *aml_serial_bus_device(uint8_t serial_bus_type, uint8_t flags,
2486
                                  uint16_t type_flags,
2487
                                  uint8_t revid, uint16_t data_length,
2488
                                  uint16_t resource_source_len)
2489
{
2490
    Aml *var = aml_alloc();
2491
    uint16_t length = data_length + resource_source_len + 9;
2492

2493
    build_append_byte(var->buf, 0x8e); /* Serial Bus Connection Descriptor */
2494
    build_append_int_noprefix(var->buf, length, sizeof(length));
2495
    build_append_byte(var->buf, 1);    /* Revision ID */
2496
    build_append_byte(var->buf, 0);    /* Resource Source Index */
2497
    build_append_byte(var->buf, serial_bus_type); /* Serial Bus Type */
2498
    build_append_byte(var->buf, flags); /* General Flags */
2499
    build_append_int_noprefix(var->buf, type_flags, /* Type Specific Flags */
2500
                              sizeof(type_flags));
2501
    build_append_byte(var->buf, revid); /* Type Specification Revision ID */
2502
    build_append_int_noprefix(var->buf, data_length, sizeof(data_length));
2503

2504
    return var;
2505
}
2506

2507
/* ACPI 5.0: 6.4.3.8.2.1 I2C Serial Bus Connection Resource Descriptor */
2508
Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source)
2509
{
2510
    uint16_t resource_source_len = strlen(resource_source) + 1;
2511
    Aml *var = aml_serial_bus_device(AML_SERIAL_BUS_TYPE_I2C, 0, 0, 1,
2512
                                     6, resource_source_len);
2513

2514
    /* Connection Speed.  Just set to 100K for now, it doesn't really matter. */
2515
    build_append_int_noprefix(var->buf, 100000, 4);
2516
    build_append_int_noprefix(var->buf, address, sizeof(address));
2517

2518
    /* This is a string, not a name, so just copy it directly in. */
2519
    g_array_append_vals(var->buf, resource_source, resource_source_len);
2520

2521
    return var;
2522
}
2523

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.