aml-build.c (98c710f2d5cdf37f29a267352eb1f3c28cbf369d) aml-build.c (cb51ac2ffe3649eb8f5c65dccc2012f0ba2c6b12)
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

--- 212 unchanged lines hidden (view full) ---

221}
222
223static void build_extop_package(GArray *package, uint8_t op)
224{
225 build_package(package, op);
226 build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
227}
228
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

--- 212 unchanged lines hidden (view full) ---

221}
222
223static void build_extop_package(GArray *package, uint8_t op)
224{
225 build_package(package, op);
226 build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
227}
228
229static void build_append_int_noprefix(GArray *table, uint64_t value, int size)
229void build_append_int_noprefix(GArray *table, uint64_t value, int size)
230{
231 int i;
232
233 for (i = 0; i < size; ++i) {
234 build_append_byte(table, value & 0xFF);
235 value = value >> 8;
236 }
237}

--- 417 unchanged lines hidden (view full) ---

655 build_append_namestring(var->buf, "%s", method);
656 aml_append(var, arg1);
657 aml_append(var, arg2);
658 aml_append(var, arg3);
659 aml_append(var, arg4);
660 return var;
661}
662
230{
231 int i;
232
233 for (i = 0; i < size; ++i) {
234 build_append_byte(table, value & 0xFF);
235 value = value >> 8;
236 }
237}

--- 417 unchanged lines hidden (view full) ---

655 build_append_namestring(var->buf, "%s", method);
656 aml_append(var, arg1);
657 aml_append(var, arg2);
658 aml_append(var, arg3);
659 aml_append(var, arg4);
660 return var;
661}
662
663/* helper to call method with 5 arguments */
664Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
665 Aml *arg5)
666{
667 Aml *var = aml_alloc();
668 build_append_namestring(var->buf, "%s", method);
669 aml_append(var, arg1);
670 aml_append(var, arg2);
671 aml_append(var, arg3);
672 aml_append(var, arg4);
673 aml_append(var, arg5);
674 return var;
675}
676
663/*
664 * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
665 * Type 1, Large Item Name 0xC
666 */
667
668static Aml *aml_gpio_connection(AmlGpioConnectionType type,
669 AmlConsumerAndProducer con_and_pro,
670 uint8_t flags, AmlPinConfig pin_config,

--- 805 unchanged lines hidden (view full) ---

1476
1477/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
1478Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
1479{
1480 return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
1481 target);
1482}
1483
677/*
678 * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
679 * Type 1, Large Item Name 0xC
680 */
681
682static Aml *aml_gpio_connection(AmlGpioConnectionType type,
683 AmlConsumerAndProducer con_and_pro,
684 uint8_t flags, AmlPinConfig pin_config,

--- 805 unchanged lines hidden (view full) ---

1490
1491/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
1492Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
1493{
1494 return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
1495 target);
1496}
1497
1498/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
1499Aml *aml_object_type(Aml *object)
1500{
1501 Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
1502 aml_append(var, object);
1503 return var;
1504}
1505
1484void
1485build_header(BIOSLinker *linker, GArray *table_data,
1486 AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
1487 const char *oem_id, const char *oem_table_id)
1488{
1489 unsigned tbl_offset = (char *)h - table_data->data;
1490 unsigned checksum_offset = (char *)&h->checksum - table_data->data;
1491 memcpy(&h->signature, sig, 4);

--- 40 unchanged lines hidden (view full) ---

1532 g_array_append_val(table_offsets, offset);
1533}
1534
1535void acpi_build_tables_init(AcpiBuildTables *tables)
1536{
1537 tables->rsdp = g_array_new(false, true /* clear */, 1);
1538 tables->table_data = g_array_new(false, true /* clear */, 1);
1539 tables->tcpalog = g_array_new(false, true /* clear */, 1);
1506void
1507build_header(BIOSLinker *linker, GArray *table_data,
1508 AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
1509 const char *oem_id, const char *oem_table_id)
1510{
1511 unsigned tbl_offset = (char *)h - table_data->data;
1512 unsigned checksum_offset = (char *)&h->checksum - table_data->data;
1513 memcpy(&h->signature, sig, 4);

--- 40 unchanged lines hidden (view full) ---

1554 g_array_append_val(table_offsets, offset);
1555}
1556
1557void acpi_build_tables_init(AcpiBuildTables *tables)
1558{
1559 tables->rsdp = g_array_new(false, true /* clear */, 1);
1560 tables->table_data = g_array_new(false, true /* clear */, 1);
1561 tables->tcpalog = g_array_new(false, true /* clear */, 1);
1562 tables->vmgenid = g_array_new(false, true /* clear */, 1);
1540 tables->linker = bios_linker_loader_init();
1541}
1542
1543void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
1544{
1545 bios_linker_loader_cleanup(tables->linker);
1546 g_array_free(tables->rsdp, true);
1547 g_array_free(tables->table_data, true);
1548 g_array_free(tables->tcpalog, mfre);
1563 tables->linker = bios_linker_loader_init();
1564}
1565
1566void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
1567{
1568 bios_linker_loader_cleanup(tables->linker);
1569 g_array_free(tables->rsdp, true);
1570 g_array_free(tables->table_data, true);
1571 g_array_free(tables->tcpalog, mfre);
1572 g_array_free(tables->vmgenid, mfre);
1549}
1550
1551/* Build rsdt table */
1552void
1553build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1554 const char *oem_id, const char *oem_table_id)
1555{
1556 int i;

--- 13 unchanged lines hidden (view full) ---

1570 bios_linker_loader_add_pointer(linker,
1571 ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size,
1572 ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1573 }
1574 build_header(linker, table_data,
1575 (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
1576}
1577
1573}
1574
1575/* Build rsdt table */
1576void
1577build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1578 const char *oem_id, const char *oem_table_id)
1579{
1580 int i;

--- 13 unchanged lines hidden (view full) ---

1594 bios_linker_loader_add_pointer(linker,
1595 ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size,
1596 ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1597 }
1598 build_header(linker, table_data,
1599 (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
1600}
1601
1602/* Build xsdt table */
1603void
1604build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
1605 const char *oem_id, const char *oem_table_id)
1606{
1607 int i;
1608 unsigned xsdt_entries_offset;
1609 AcpiXsdtDescriptorRev2 *xsdt;
1610 const unsigned table_data_len = (sizeof(uint64_t) * table_offsets->len);
1611 const unsigned xsdt_entry_size = sizeof(xsdt->table_offset_entry[0]);
1612 const size_t xsdt_len = sizeof(*xsdt) + table_data_len;
1613
1614 xsdt = acpi_data_push(table_data, xsdt_len);
1615 xsdt_entries_offset = (char *)xsdt->table_offset_entry - table_data->data;
1616 for (i = 0; i < table_offsets->len; ++i) {
1617 uint64_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
1618 uint64_t xsdt_entry_offset = xsdt_entries_offset + xsdt_entry_size * i;
1619
1620 /* xsdt->table_offset_entry to be filled by Guest linker */
1621 bios_linker_loader_add_pointer(linker,
1622 ACPI_BUILD_TABLE_FILE, xsdt_entry_offset, xsdt_entry_size,
1623 ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
1624 }
1625 build_header(linker, table_data,
1626 (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
1627}
1628
1578void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
1579 uint64_t len, int node, MemoryAffinityFlags flags)
1580{
1581 numamem->type = ACPI_SRAT_MEMORY;
1582 numamem->length = sizeof(*numamem);
1583 numamem->proximity = cpu_to_le32(node);
1584 numamem->flags = cpu_to_le32(flags);
1585 numamem->base_addr = cpu_to_le64(base);
1586 numamem->range_length = cpu_to_le64(len);
1587}
1629void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
1630 uint64_t len, int node, MemoryAffinityFlags flags)
1631{
1632 numamem->type = ACPI_SRAT_MEMORY;
1633 numamem->length = sizeof(*numamem);
1634 numamem->proximity = cpu_to_le32(node);
1635 numamem->flags = cpu_to_le32(flags);
1636 numamem->base_addr = cpu_to_le64(base);
1637 numamem->range_length = cpu_to_le64(len);
1638}