All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 0/5] pc: acpi: various fixes and cleanups
@ 2015-01-21  9:09 Igor Mammedov
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 1/5] pc: acpi-build: cleanup AcpiPmInfo initialization Igor Mammedov
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Igor Mammedov @ 2015-01-21  9:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: marcel.a, mst

NOTE to maintainer: please update test data (ACPI blobs) in test cases

changes from v4:
 * rebased on top of PCI tree, dropping 2 patches
   that are already there

changes from v3:
 * rename acpi_gen_utils.[ch] to acpi-build-utils.[ch]
 * copy GLP license block from acpi-build.c
 * assert on wrong Segcount earlier and extend condition to
   seg_count > 0 && seg_count <= 255
 * drop "pc: acpi: decribe bridge device as not hotpluggable"
 * keep original logic of creating bridge devices as it was done
   in 133a2da48 "pc: acpi: generate AML only for PCI0 ..."
 * if bus is non hotpluggable, add child slots to bus as non
   hotpluggable as it was done in original code.

changes from v2:
 * codding style fixups
 * check for SegCount earlier
 * use hotpluggable device object instead of not hotpluggable
    for non present devices, and add it only when bus itself is
    hotpluggable

changes from v1:
 * drop: [PATCH 7/9] acpi: replace opencoded notify codes with named values
 * use Michael's suggestion to improve build_append_nameseg()
 * drop long scope names and go back to recursion,
   but still significantly simplify building of PCI tree

this series is an attempt to shave off a bunch of
not directly related patches from already big dynamic
AML series (although it's dependency for it)

Tested: on XPsp3 to WS2012R2 and REHL6/7 guests.

Git tree for testing:
 https://github.com/imammedo/qemu/commits/acpi_pci_gen_simplification_v4

Igor Mammedov (5):
  pc: acpi-build: cleanup AcpiPmInfo initialization
  acpi: move generic aml building helpers into dedictated file
  acpi: add build_append_namestring() helper
  acpi: drop min-bytes in build_package()
  pc: acpi-build: simplify PCI bus tree generation

 hw/acpi/Makefile.objs              |   1 +
 hw/acpi/acpi-build-utils.c         | 269 +++++++++++++++++++++
 hw/i386/acpi-build.c               | 469 ++++++++-----------------------------
 include/hw/acpi/acpi-build-utils.h |  23 ++
 4 files changed, 397 insertions(+), 365 deletions(-)
 create mode 100644 hw/acpi/acpi-build-utils.c
 create mode 100644 include/hw/acpi/acpi-build-utils.h

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v5 1/5] pc: acpi-build: cleanup AcpiPmInfo initialization
  2015-01-21  9:09 [Qemu-devel] [PATCH v5 0/5] pc: acpi: various fixes and cleanups Igor Mammedov
@ 2015-01-21  9:09 ` Igor Mammedov
  2015-01-21  9:11   ` Marcel Apfelbaum
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file Igor Mammedov
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Igor Mammedov @ 2015-01-21  9:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: marcel.a, mst

zero initialize AcpiPmInfo struct to reduce code bloat
a little bit.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
---
 hw/i386/acpi-build.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 77a124e..4c0536f 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -172,6 +172,8 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     Object *obj = NULL;
     QObject *o;
 
+    memset(pm, 0, sizeof(*pm));
+
     if (piix) {
         obj = piix;
     }
@@ -184,22 +186,16 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
     if (o) {
         pm->s3_disabled = qint_get_int(qobject_to_qint(o));
-    } else {
-        pm->s3_disabled = false;
     }
     qobject_decref(o);
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
     if (o) {
         pm->s4_disabled = qint_get_int(qobject_to_qint(o));
-    } else {
-        pm->s4_disabled = false;
     }
     qobject_decref(o);
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
     if (o) {
         pm->s4_val = qint_get_int(qobject_to_qint(o));
-    } else {
-        pm->s4_val = false;
     }
     qobject_decref(o);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file
  2015-01-21  9:09 [Qemu-devel] [PATCH v5 0/5] pc: acpi: various fixes and cleanups Igor Mammedov
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 1/5] pc: acpi-build: cleanup AcpiPmInfo initialization Igor Mammedov
@ 2015-01-21  9:09 ` Igor Mammedov
  2015-01-21  9:13   ` Marcel Apfelbaum
  2015-01-27 12:23   ` Michael S. Tsirkin
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 3/5] acpi: add build_append_namestring() helper Igor Mammedov
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 13+ messages in thread
From: Igor Mammedov @ 2015-01-21  9:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: marcel.a, mst

the will be later used for composing AML primitives
and all that could be reused later for ARM machines
as well.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v3:
  * rename acpi_gen_utils.[ch] to acpi-build-utils.[ch]
  * copy GLP license block from acpi-build.c
v2:
  * fix wrong ident in moved code
---
 hw/acpi/Makefile.objs              |   1 +
 hw/acpi/acpi-build-utils.c         | 187 +++++++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c               | 162 +-------------------------------
 include/hw/acpi/acpi-build-utils.h |  23 +++++
 4 files changed, 213 insertions(+), 160 deletions(-)
 create mode 100644 hw/acpi/acpi-build-utils.c
 create mode 100644 include/hw/acpi/acpi-build-utils.h

diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index ee82073..cad0355 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -2,3 +2,4 @@ common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
 common-obj-$(CONFIG_ACPI) += memory_hotplug.o
 common-obj-$(CONFIG_ACPI) += acpi_interface.o
 common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
+common-obj-$(CONFIG_ACPI) += acpi-build-utils.o
diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
new file mode 100644
index 0000000..79aa610
--- /dev/null
+++ b/hw/acpi/acpi-build-utils.c
@@ -0,0 +1,187 @@
+/* Support for generating ACPI tables and passing them to Guests
+ *
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ * Author: Igor Mammedov <imammedo@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <stdbool.h>
+#include "hw/acpi/acpi-build-utils.h"
+
+GArray *build_alloc_array(void)
+{
+    return g_array_new(false, true /* clear */, 1);
+}
+
+void build_free_array(GArray *array)
+{
+    g_array_free(array, true);
+}
+
+void build_prepend_byte(GArray *array, uint8_t val)
+{
+    g_array_prepend_val(array, val);
+}
+
+void build_append_byte(GArray *array, uint8_t val)
+{
+    g_array_append_val(array, val);
+}
+
+void build_append_array(GArray *array, GArray *val)
+{
+    g_array_append_vals(array, val->data, val->len);
+}
+
+#define ACPI_NAMESEG_LEN 4
+
+void GCC_FMT_ATTR(2, 3)
+build_append_nameseg(GArray *array, const char *format, ...)
+{
+    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
+    char s[] = "XXXX";
+    int len;
+    va_list args;
+
+    va_start(args, format);
+    len = vsnprintf(s, sizeof s, format, args);
+    va_end(args);
+
+    assert(len <= ACPI_NAMESEG_LEN);
+
+    g_array_append_vals(array, s, len);
+    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
+    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
+}
+
+/* 5.4 Definition Block Encoding */
+enum {
+    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
+    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
+    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
+    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
+};
+
+void build_prepend_package_length(GArray *package, unsigned min_bytes)
+{
+    uint8_t byte;
+    unsigned length = package->len;
+    unsigned length_bytes;
+
+    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
+        length_bytes = 1;
+    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
+        length_bytes = 2;
+    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
+        length_bytes = 3;
+    } else {
+        length_bytes = 4;
+    }
+
+    /* Force length to at least min_bytes.
+     * This wastes memory but that's how bios did it.
+     */
+    length_bytes = MAX(length_bytes, min_bytes);
+
+    /* PkgLength is the length of the inclusive length of the data. */
+    length += length_bytes;
+
+    switch (length_bytes) {
+    case 1:
+        byte = length;
+        build_prepend_byte(package, byte);
+        return;
+    case 4:
+        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
+        build_prepend_byte(package, byte);
+        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
+        /* fall through */
+    case 3:
+        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
+        build_prepend_byte(package, byte);
+        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
+        /* fall through */
+    case 2:
+        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
+        build_prepend_byte(package, byte);
+        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
+        /* fall through */
+    }
+    /*
+     * Most significant two bits of byte zero indicate how many following bytes
+     * are in PkgLength encoding.
+     */
+    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
+    build_prepend_byte(package, byte);
+}
+
+void build_package(GArray *package, uint8_t op, unsigned min_bytes)
+{
+    build_prepend_package_length(package, min_bytes);
+    build_prepend_byte(package, op);
+}
+
+void build_extop_package(GArray *package, uint8_t op)
+{
+    build_package(package, op, 1);
+    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
+}
+
+void build_append_value(GArray *table, uint32_t value, int size)
+{
+    uint8_t prefix;
+    int i;
+
+    switch (size) {
+    case 1:
+        prefix = 0x0A; /* BytePrefix */
+        break;
+    case 2:
+        prefix = 0x0B; /* WordPrefix */
+        break;
+    case 4:
+        prefix = 0x0C; /* DWordPrefix */
+        break;
+    default:
+        assert(0);
+        return;
+    }
+    build_append_byte(table, prefix);
+    for (i = 0; i < size; ++i) {
+        build_append_byte(table, value & 0xFF);
+        value = value >> 8;
+    }
+}
+
+void build_append_int(GArray *table, uint32_t value)
+{
+    if (value == 0x00) {
+        build_append_byte(table, 0x00); /* ZeroOp */
+    } else if (value == 0x01) {
+        build_append_byte(table, 0x01); /* OneOp */
+    } else if (value <= 0xFF) {
+        build_append_value(table, value, 1);
+    } else if (value <= 0xFFFF) {
+        build_append_value(table, value, 2);
+    } else {
+        build_append_value(table, value, 4);
+    }
+}
+
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4c0536f..8ee15ab 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -54,6 +54,8 @@
 #include "hw/i386/q35-acpi-dsdt.hex"
 #include "hw/i386/acpi-dsdt.hex"
 
+#include "hw/acpi/acpi-build-utils.h"
+
 #include "qapi/qmp/qint.h"
 #include "qom/qom-qobject.h"
 #include "exec/ram_addr.h"
@@ -277,166 +279,6 @@ build_header(GArray *linker, GArray *table_data,
                                     table_data->data, h, len, &h->checksum);
 }
 
-static inline GArray *build_alloc_array(void)
-{
-    return g_array_new(false, true /* clear */, 1);
-}
-
-static inline void build_free_array(GArray *array)
-{
-    g_array_free(array, true);
-}
-
-static inline void build_prepend_byte(GArray *array, uint8_t val)
-{
-    g_array_prepend_val(array, val);
-}
-
-static inline void build_append_byte(GArray *array, uint8_t val)
-{
-    g_array_append_val(array, val);
-}
-
-static inline void build_append_array(GArray *array, GArray *val)
-{
-    g_array_append_vals(array, val->data, val->len);
-}
-
-#define ACPI_NAMESEG_LEN 4
-
-static void GCC_FMT_ATTR(2, 3)
-build_append_nameseg(GArray *array, const char *format, ...)
-{
-    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
-    char s[] = "XXXX";
-    int len;
-    va_list args;
-
-    va_start(args, format);
-    len = vsnprintf(s, sizeof s, format, args);
-    va_end(args);
-
-    assert(len <= ACPI_NAMESEG_LEN);
-
-    g_array_append_vals(array, s, len);
-    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
-    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
-}
-
-/* 5.4 Definition Block Encoding */
-enum {
-    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
-    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
-    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
-    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
-};
-
-static void build_prepend_package_length(GArray *package, unsigned min_bytes)
-{
-    uint8_t byte;
-    unsigned length = package->len;
-    unsigned length_bytes;
-
-    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
-        length_bytes = 1;
-    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
-        length_bytes = 2;
-    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
-        length_bytes = 3;
-    } else {
-        length_bytes = 4;
-    }
-
-    /* Force length to at least min_bytes.
-     * This wastes memory but that's how bios did it.
-     */
-    length_bytes = MAX(length_bytes, min_bytes);
-
-    /* PkgLength is the length of the inclusive length of the data. */
-    length += length_bytes;
-
-    switch (length_bytes) {
-    case 1:
-        byte = length;
-        build_prepend_byte(package, byte);
-        return;
-    case 4:
-        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
-        build_prepend_byte(package, byte);
-        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
-        /* fall through */
-    case 3:
-        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
-        build_prepend_byte(package, byte);
-        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
-        /* fall through */
-    case 2:
-        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
-        build_prepend_byte(package, byte);
-        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
-        /* fall through */
-    }
-    /*
-     * Most significant two bits of byte zero indicate how many following bytes
-     * are in PkgLength encoding.
-     */
-    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
-    build_prepend_byte(package, byte);
-}
-
-static void build_package(GArray *package, uint8_t op, unsigned min_bytes)
-{
-    build_prepend_package_length(package, min_bytes);
-    build_prepend_byte(package, op);
-}
-
-static void build_extop_package(GArray *package, uint8_t op)
-{
-    build_package(package, op, 1);
-    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
-}
-
-static void build_append_value(GArray *table, uint32_t value, int size)
-{
-    uint8_t prefix;
-    int i;
-
-    switch (size) {
-    case 1:
-        prefix = 0x0A; /* BytePrefix */
-        break;
-    case 2:
-        prefix = 0x0B; /* WordPrefix */
-        break;
-    case 4:
-        prefix = 0x0C; /* DWordPrefix */
-        break;
-    default:
-        assert(0);
-        return;
-    }
-    build_append_byte(table, prefix);
-    for (i = 0; i < size; ++i) {
-        build_append_byte(table, value & 0xFF);
-        value = value >> 8;
-    }
-}
-
-static void build_append_int(GArray *table, uint32_t value)
-{
-    if (value == 0x00) {
-        build_append_byte(table, 0x00); /* ZeroOp */
-    } else if (value == 0x01) {
-        build_append_byte(table, 0x01); /* OneOp */
-    } else if (value <= 0xFF) {
-        build_append_value(table, value, 1);
-    } else if (value <= 0xFFFF) {
-        build_append_value(table, value, 2);
-    } else {
-        build_append_value(table, value, 4);
-    }
-}
-
 static GArray *build_alloc_method(const char *name, uint8_t arg_count)
 {
     GArray *method = build_alloc_array();
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
new file mode 100644
index 0000000..e6a0b28
--- /dev/null
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -0,0 +1,23 @@
+#ifndef HW_ACPI_GEN_UTILS_H
+#define HW_ACPI_GEN_UTILS_H
+
+#include <stdint.h>
+#include <glib.h>
+#include "qemu/compiler.h"
+
+GArray *build_alloc_array(void);
+void build_free_array(GArray *array);
+void build_prepend_byte(GArray *array, uint8_t val);
+void build_append_byte(GArray *array, uint8_t val);
+void build_append_array(GArray *array, GArray *val);
+
+void GCC_FMT_ATTR(2, 3)
+build_append_nameseg(GArray *array, const char *format, ...);
+
+void build_prepend_package_length(GArray *package, unsigned min_bytes);
+void build_package(GArray *package, uint8_t op, unsigned min_bytes);
+void build_append_value(GArray *table, uint32_t value, int size);
+void build_append_int(GArray *table, uint32_t value);
+void build_extop_package(GArray *package, uint8_t op);
+
+#endif
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v5 3/5] acpi: add build_append_namestring() helper
  2015-01-21  9:09 [Qemu-devel] [PATCH v5 0/5] pc: acpi: various fixes and cleanups Igor Mammedov
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 1/5] pc: acpi-build: cleanup AcpiPmInfo initialization Igor Mammedov
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file Igor Mammedov
@ 2015-01-21  9:09 ` Igor Mammedov
  2015-01-21  9:22   ` Marcel Apfelbaum
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 4/5] acpi: drop min-bytes in build_package() Igor Mammedov
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 5/5] pc: acpi-build: simplify PCI bus tree generation Igor Mammedov
  4 siblings, 1 reply; 13+ messages in thread
From: Igor Mammedov @ 2015-01-21  9:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: marcel.a, mst

Use build_append_namestring() instead of build_append_nameseg()
So user won't have to care whether name is NameSeg, NamePath or
NameString.

See for refernce ACPI 5.0: 20.2.2 Name Objects Encoding

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
---
v3:
 assert on wrong Segcount earlier and extend condition to
  seg_count > 0 && seg_count <= 255
 as suggested by Claudio Fontana <claudio.fontana@huawei.com>
---
 hw/acpi/acpi-build-utils.c         | 90 +++++++++++++++++++++++++++++++++++++-
 hw/i386/acpi-build.c               | 35 +++++++--------
 include/hw/acpi/acpi-build-utils.h |  2 +-
 3 files changed, 106 insertions(+), 21 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 79aa610..aed9066 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -52,7 +52,7 @@ void build_append_array(GArray *array, GArray *val)
 
 #define ACPI_NAMESEG_LEN 4
 
-void GCC_FMT_ATTR(2, 3)
+static void GCC_FMT_ATTR(2, 3)
 build_append_nameseg(GArray *array, const char *format, ...)
 {
     /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
@@ -71,6 +71,94 @@ build_append_nameseg(GArray *array, const char *format, ...)
     g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
 }
 
+static const uint8_t ACPI_DualNamePrefix  = 0x2E;
+static const uint8_t ACPI_MultiNamePrefix = 0x2F;
+
+static void
+build_append_namestringv(GArray *array, const char *format, va_list ap)
+{
+    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
+    char *s;
+    int len;
+    va_list va_len;
+    char **segs;
+    char **segs_iter;
+    int seg_count = 0;
+
+    va_copy(va_len, ap);
+    len = vsnprintf(NULL, 0, format, va_len);
+    va_end(va_len);
+    len += 1;
+    s = g_new(typeof(*s), len);
+
+    len = vsnprintf(s, len, format, ap);
+
+    segs = g_strsplit(s, ".", 0);
+    g_free(s);
+
+    /* count segments */
+    segs_iter = segs;
+    while (*segs_iter) {
+        ++segs_iter;
+        ++seg_count;
+    }
+    /*
+     * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
+     * "SegCount can be from 1 to 255"
+     */
+    assert(seg_count > 0 && seg_count <= 255);
+
+    /* handle RootPath || PrefixPath */
+    s = *segs;
+    while (*s == '\\' || *s == '^') {
+        g_array_append_val(array, *s);
+        ++s;
+    }
+
+    switch (seg_count) {
+    case 1:
+        if (!*s) { /* NullName */
+            const uint8_t nullpath = 0;
+            g_array_append_val(array, nullpath);
+        } else {
+            build_append_nameseg(array, "%s", s);
+        }
+        break;
+
+    case 2:
+        g_array_append_val(array, ACPI_DualNamePrefix);
+        build_append_nameseg(array, "%s", s);
+        build_append_nameseg(array, "%s", segs[1]);
+        break;
+
+    default:
+        g_array_append_val(array, ACPI_MultiNamePrefix);
+        g_array_append_val(array, seg_count);
+
+        /* handle the 1st segment manually due to prefix/root path */
+        build_append_nameseg(array, "%s", s);
+
+        /* add the rest of segments */
+        segs_iter = segs + 1;
+        while (*segs_iter) {
+            build_append_nameseg(array, "%s", *segs_iter);
+            ++segs_iter;
+        }
+        break;
+    }
+    g_strfreev(segs);
+}
+
+void GCC_FMT_ATTR(2, 3)
+build_append_namestring(GArray *array, const char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    build_append_namestringv(array, format, ap);
+    va_end(ap);
+}
+
 /* 5.4 Definition Block Encoding */
 enum {
     PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 8ee15ab..e3ac1a14 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -283,7 +283,7 @@ static GArray *build_alloc_method(const char *name, uint8_t arg_count)
 {
     GArray *method = build_alloc_array();
 
-    build_append_nameseg(method, "%s", name);
+    build_append_namestring(method, "%s", name);
     build_append_byte(method, arg_count); /* MethodFlags: ArgCount */
 
     return method;
@@ -575,7 +575,7 @@ build_append_notify_method(GArray *device, const char *name,
 
     for (i = 0; i < count; i++) {
         GArray *target = build_alloc_array();
-        build_append_nameseg(target, format, i);
+        build_append_namestring(target, format, i);
         assert(i < 256); /* Fits in 1 byte */
         build_append_notify_target_ifequal(method, target, i, 1);
         build_free_array(target);
@@ -703,24 +703,24 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
 
     if (bus->parent_dev) {
         op = 0x82; /* DeviceOp */
-        build_append_nameseg(bus_table, "S%.02X",
+        build_append_namestring(bus_table, "S%.02X",
                              bus->parent_dev->devfn);
         build_append_byte(bus_table, 0x08); /* NameOp */
-        build_append_nameseg(bus_table, "_SUN");
+        build_append_namestring(bus_table, "_SUN");
         build_append_value(bus_table, PCI_SLOT(bus->parent_dev->devfn), 1);
         build_append_byte(bus_table, 0x08); /* NameOp */
-        build_append_nameseg(bus_table, "_ADR");
+        build_append_namestring(bus_table, "_ADR");
         build_append_value(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) |
                            PCI_FUNC(bus->parent_dev->devfn), 4);
     } else {
         op = 0x10; /* ScopeOp */;
-        build_append_nameseg(bus_table, "PCI0");
+        build_append_namestring(bus_table, "PCI0");
     }
 
     bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
     if (bsel) {
         build_append_byte(bus_table, 0x08); /* NameOp */
-        build_append_nameseg(bus_table, "BSEL");
+        build_append_namestring(bus_table, "BSEL");
         build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel)));
         memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable);
     } else {
@@ -823,7 +823,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
             build_append_int(notify, 0x1U << i);
             build_append_byte(notify, 0x00); /* NullName */
             build_append_byte(notify, 0x86); /* NotifyOp */
-            build_append_nameseg(notify, "S%.02X", PCI_DEVFN(i, 0));
+            build_append_namestring(notify, "S%.02X", PCI_DEVFN(i, 0));
             build_append_byte(notify, 0x69); /* Arg1Op */
 
             /* Pack it up */
@@ -847,12 +847,12 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
         if (bsel) {
             build_append_byte(method, 0x70); /* StoreOp */
             build_append_int(method, qint_get_int(qobject_to_qint(bsel)));
-            build_append_nameseg(method, "BNUM");
-            build_append_nameseg(method, "DVNT");
-            build_append_nameseg(method, "PCIU");
+            build_append_namestring(method, "BNUM");
+            build_append_namestring(method, "DVNT");
+            build_append_namestring(method, "PCIU");
             build_append_int(method, 1); /* Device Check */
-            build_append_nameseg(method, "DVNT");
-            build_append_nameseg(method, "PCID");
+            build_append_namestring(method, "DVNT");
+            build_append_namestring(method, "PCID");
             build_append_int(method, 3); /* Eject Request */
         }
 
@@ -878,11 +878,8 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
          * At the moment this is not needed for root as we have a single root.
          */
         if (bus->parent_dev) {
-            build_append_byte(parent->notify_table, '^'); /* ParentPrefixChar */
-            build_append_byte(parent->notify_table, 0x2E); /* DualNamePrefix */
-            build_append_nameseg(parent->notify_table, "S%.02X",
+            build_append_namestring(parent->notify_table, "^PCNT.S%.02X",
                                  bus->parent_dev->devfn);
-            build_append_nameseg(parent->notify_table, "PCNT");
         }
     }
 
@@ -967,7 +964,7 @@ build_ssdt(GArray *table_data, GArray *linker,
         GArray *sb_scope = build_alloc_array();
         uint8_t op = 0x10; /* ScopeOp */
 
-        build_append_nameseg(sb_scope, "_SB");
+        build_append_namestring(sb_scope, "_SB");
 
         /* build Processor object for each processor */
         for (i = 0; i < acpi_cpus; i++) {
@@ -987,7 +984,7 @@ build_ssdt(GArray *table_data, GArray *linker,
 
         /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */
         build_append_byte(sb_scope, 0x08); /* NameOp */
-        build_append_nameseg(sb_scope, "CPON");
+        build_append_namestring(sb_scope, "CPON");
 
         {
             GArray *package = build_alloc_array();
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index e6a0b28..fd50625 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -12,7 +12,7 @@ void build_append_byte(GArray *array, uint8_t val);
 void build_append_array(GArray *array, GArray *val);
 
 void GCC_FMT_ATTR(2, 3)
-build_append_nameseg(GArray *array, const char *format, ...);
+build_append_namestring(GArray *array, const char *format, ...);
 
 void build_prepend_package_length(GArray *package, unsigned min_bytes);
 void build_package(GArray *package, uint8_t op, unsigned min_bytes);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v5 4/5] acpi: drop min-bytes in build_package()
  2015-01-21  9:09 [Qemu-devel] [PATCH v5 0/5] pc: acpi: various fixes and cleanups Igor Mammedov
                   ` (2 preceding siblings ...)
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 3/5] acpi: add build_append_namestring() helper Igor Mammedov
@ 2015-01-21  9:09 ` Igor Mammedov
  2015-01-21  9:25   ` Marcel Apfelbaum
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 5/5] pc: acpi-build: simplify PCI bus tree generation Igor Mammedov
  4 siblings, 1 reply; 13+ messages in thread
From: Igor Mammedov @ 2015-01-21  9:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: marcel.a, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
---
 hw/acpi/acpi-build-utils.c         | 14 ++++----------
 hw/i386/acpi-build.c               | 13 ++++++-------
 include/hw/acpi/acpi-build-utils.h |  4 ++--
 3 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index aed9066..602e68c 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -167,7 +167,7 @@ enum {
     PACKAGE_LENGTH_4BYTE_SHIFT = 20,
 };
 
-void build_prepend_package_length(GArray *package, unsigned min_bytes)
+void build_prepend_package_length(GArray *package)
 {
     uint8_t byte;
     unsigned length = package->len;
@@ -183,11 +183,6 @@ void build_prepend_package_length(GArray *package, unsigned min_bytes)
         length_bytes = 4;
     }
 
-    /* Force length to at least min_bytes.
-     * This wastes memory but that's how bios did it.
-     */
-    length_bytes = MAX(length_bytes, min_bytes);
-
     /* PkgLength is the length of the inclusive length of the data. */
     length += length_bytes;
 
@@ -220,15 +215,15 @@ void build_prepend_package_length(GArray *package, unsigned min_bytes)
     build_prepend_byte(package, byte);
 }
 
-void build_package(GArray *package, uint8_t op, unsigned min_bytes)
+void build_package(GArray *package, uint8_t op)
 {
-    build_prepend_package_length(package, min_bytes);
+    build_prepend_package_length(package);
     build_prepend_byte(package, op);
 }
 
 void build_extop_package(GArray *package, uint8_t op)
 {
-    build_package(package, op, 1);
+    build_package(package, op);
     build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
 }
 
@@ -272,4 +267,3 @@ void build_append_int(GArray *table, uint32_t value)
         build_append_value(table, value, 4);
     }
 }
-
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index e3ac1a14..a010f3b 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -293,7 +293,7 @@ static void build_append_and_cleanup_method(GArray *device, GArray *method)
 {
     uint8_t op = 0x14; /* MethodOp */
 
-    build_package(method, op, 0);
+    build_package(method, op);
 
     build_append_array(device, method);
     build_free_array(method);
@@ -314,7 +314,7 @@ static void build_append_notify_target_ifequal(GArray *method,
     build_append_byte(notify, 0x69); /* Arg1Op */
 
     /* Pack it up */
-    build_package(notify, op, 1);
+    build_package(notify, op);
 
     build_append_array(method, notify);
 
@@ -827,7 +827,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
             build_append_byte(notify, 0x69); /* Arg1Op */
 
             /* Pack it up */
-            build_package(notify, op, 0);
+            build_package(notify, op);
 
             build_append_array(method, notify);
 
@@ -868,7 +868,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
         if (bus->parent_dev) {
             build_extop_package(bus_table, op);
         } else {
-            build_package(bus_table, op, 0);
+            build_package(bus_table, op);
         }
 
         /* Append our bus description to parent table */
@@ -1008,7 +1008,7 @@ build_ssdt(GArray *table_data, GArray *linker,
                 build_append_byte(package, b);
             }
 
-            build_package(package, op, 2);
+            build_package(package, op);
             build_append_array(sb_scope, package);
             build_free_array(package);
         }
@@ -1056,8 +1056,7 @@ build_ssdt(GArray *table_data, GArray *linker,
             build_append_array(sb_scope, hotplug_state.device_table);
             build_pci_bus_state_cleanup(&hotplug_state);
         }
-
-        build_package(sb_scope, op, 3);
+        build_package(sb_scope, op);
         build_append_array(table_data, sb_scope);
         build_free_array(sb_scope);
     }
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index fd50625..199f003 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -14,8 +14,8 @@ void build_append_array(GArray *array, GArray *val);
 void GCC_FMT_ATTR(2, 3)
 build_append_namestring(GArray *array, const char *format, ...);
 
-void build_prepend_package_length(GArray *package, unsigned min_bytes);
-void build_package(GArray *package, uint8_t op, unsigned min_bytes);
+void build_prepend_package_length(GArray *package);
+void build_package(GArray *package, uint8_t op);
 void build_append_value(GArray *table, uint32_t value, int size);
 void build_append_int(GArray *table, uint32_t value);
 void build_extop_package(GArray *package, uint8_t op);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v5 5/5] pc: acpi-build: simplify PCI bus tree generation
  2015-01-21  9:09 [Qemu-devel] [PATCH v5 0/5] pc: acpi: various fixes and cleanups Igor Mammedov
                   ` (3 preceding siblings ...)
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 4/5] acpi: drop min-bytes in build_package() Igor Mammedov
@ 2015-01-21  9:09 ` Igor Mammedov
  2015-01-21  9:51   ` Marcel Apfelbaum
  4 siblings, 1 reply; 13+ messages in thread
From: Igor Mammedov @ 2015-01-21  9:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: marcel.a, mst

it basicaly does the same as original approach,
* just without bus/notify tables tracking (less obscure)
  which is easier to follow.
* drops unnecessary loops and bitmaps,
  creating devices and notification method in the same loop.
* saves us ~100LOC

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v4:
  * keep original logic of creating bridge devices as it was done
    in 133a2da48 "pc: acpi: generate AML only for PCI0 ..."
  * if bus is non hotpluggable, add child slots to bus as non
    hotpluggable as it was done in original code.
v3:
  * use hotpluggable device object instead of not hotpluggable
    for non present devices, and add it only when bus itself is
    hotpluggable
---
 hw/i386/acpi-build.c | 275 +++++++++++++++++----------------------------------
 1 file changed, 90 insertions(+), 185 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a010f3b..5255428 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -106,7 +106,6 @@ typedef struct AcpiPmInfo {
 typedef struct AcpiMiscInfo {
     bool has_hpet;
     bool has_tpm;
-    DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX);
     const unsigned char *dsdt_code;
     unsigned dsdt_size;
     uint16_t pvpanic_port;
@@ -651,69 +650,37 @@ static void acpi_set_pci_info(void)
     }
 }
 
-static void build_pci_bus_state_init(AcpiBuildPciBusHotplugState *state,
-                                     AcpiBuildPciBusHotplugState *parent,
-                                     bool pcihp_bridge_en)
+static void build_append_pcihp_notify_entry(GArray *method, int slot)
 {
-    state->parent = parent;
-    state->device_table = build_alloc_array();
-    state->notify_table = build_alloc_array();
-    state->pcihp_bridge_en = pcihp_bridge_en;
-}
-
-static void build_pci_bus_state_cleanup(AcpiBuildPciBusHotplugState *state)
-{
-    build_free_array(state->device_table);
-    build_free_array(state->notify_table);
-}
+    GArray *ifctx;
 
-static void *build_pci_bus_begin(PCIBus *bus, void *parent_state)
-{
-    AcpiBuildPciBusHotplugState *parent = parent_state;
-    AcpiBuildPciBusHotplugState *child = g_malloc(sizeof *child);
-
-    build_pci_bus_state_init(child, parent, parent->pcihp_bridge_en);
+    ifctx = build_alloc_array();
+    build_append_byte(ifctx, 0x7B); /* AndOp */
+    build_append_byte(ifctx, 0x68); /* Arg0Op */
+    build_append_int(ifctx, 0x1U << slot);
+    build_append_byte(ifctx, 0x00); /* NullName */
+    build_append_byte(ifctx, 0x86); /* NotifyOp */
+    build_append_namestring(ifctx, "S%.02X", PCI_DEVFN(slot, 0));
+    build_append_byte(ifctx, 0x69); /* Arg1Op */
 
-    return child;
+    /* Pack it up */
+    build_package(ifctx, 0xA0 /* IfOp */);
+    build_append_array(method, ifctx);
+    build_free_array(ifctx);
 }
 
-static void build_pci_bus_end(PCIBus *bus, void *bus_state)
+static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus,
+                                         bool pcihp_bridge_en)
 {
-    AcpiBuildPciBusHotplugState *child = bus_state;
-    AcpiBuildPciBusHotplugState *parent = child->parent;
     GArray *bus_table = build_alloc_array();
-    DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX);
-    DECLARE_BITMAP(slot_device_present, PCI_SLOT_MAX);
-    DECLARE_BITMAP(slot_device_system, PCI_SLOT_MAX);
-    DECLARE_BITMAP(slot_device_vga, PCI_SLOT_MAX);
-    DECLARE_BITMAP(slot_device_qxl, PCI_SLOT_MAX);
-    uint8_t op;
-    int i;
+    GArray *method = NULL;
     QObject *bsel;
-    GArray *method;
-    bool bus_hotplug_support = false;
-
-    /*
-     * Skip bridge subtree creation if bridge hotplug is disabled
-     * to make acpi tables compatible with legacy machine types.
-     */
-    if (!child->pcihp_bridge_en && bus->parent_dev) {
-        return;
-    }
+    PCIBus *sec;
+    int i;
 
     if (bus->parent_dev) {
-        op = 0x82; /* DeviceOp */
-        build_append_namestring(bus_table, "S%.02X",
-                             bus->parent_dev->devfn);
-        build_append_byte(bus_table, 0x08); /* NameOp */
-        build_append_namestring(bus_table, "_SUN");
-        build_append_value(bus_table, PCI_SLOT(bus->parent_dev->devfn), 1);
-        build_append_byte(bus_table, 0x08); /* NameOp */
-        build_append_namestring(bus_table, "_ADR");
-        build_append_value(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) |
-                           PCI_FUNC(bus->parent_dev->devfn), 4);
+        build_append_namestring(bus_table, "S%.02X_", bus->parent_dev->devfn);
     } else {
-        op = 0x10; /* ScopeOp */;
         build_append_namestring(bus_table, "PCI0");
     }
 
@@ -722,17 +689,9 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
         build_append_byte(bus_table, 0x08); /* NameOp */
         build_append_namestring(bus_table, "BSEL");
         build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel)));
-        memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable);
-    } else {
-        /* No bsel - no slots are hot-pluggable */
-        memset(slot_hotplug_enable, 0x00, sizeof slot_hotplug_enable);
+        method = build_alloc_method("DVNT", 2);
     }
 
-    memset(slot_device_present, 0x00, sizeof slot_device_present);
-    memset(slot_device_system, 0x00, sizeof slot_device_present);
-    memset(slot_device_vga, 0x00, sizeof slot_device_vga);
-    memset(slot_device_qxl, 0x00, sizeof slot_device_qxl);
-
     for (i = 0; i < ARRAY_SIZE(bus->devices); i += PCI_FUNC_MAX) {
         DeviceClass *dc;
         PCIDeviceClass *pc;
@@ -741,152 +700,104 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
         bool bridge_in_acpi;
 
         if (!pdev) {
+            if (bsel) {
+                void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF);
+                memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF);
+                patch_pcihp(slot, pcihp);
+
+                build_append_pcihp_notify_entry(method, slot);
+            } else {
+                /* no much sense to create empty non hotpluggable slots,
+                 * but it's what original code did before. TODO: remove it.
+                 */
+                void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF);
+                memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF);
+                patch_pcinohp(slot, pcihp);
+            }
             continue;
         }
 
-        set_bit(slot, slot_device_present);
         pc = PCI_DEVICE_GET_CLASS(pdev);
         dc = DEVICE_GET_CLASS(pdev);
 
-        /* When hotplug for bridges is enabled, bridges are
-         * described in ACPI separately (see build_pci_bus_end).
-         * In this case they aren't themselves hot-pluggable.
-         */
-        bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en;
-
-        if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) {
-            set_bit(slot, slot_device_system);
+        if (pc->class_id == PCI_CLASS_BRIDGE_ISA) {
+            continue;
         }
+        bridge_in_acpi = pc->is_bridge && pcihp_bridge_en;
 
         if (pc->class_id == PCI_CLASS_DISPLAY_VGA) {
-            set_bit(slot, slot_device_vga);
 
             if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) {
-                set_bit(slot, slot_device_qxl);
+                void *pcihp = acpi_data_push(bus_table,
+                                             ACPI_PCIQXL_SIZEOF);
+                      memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF);
+                      patch_pciqxl(slot, pcihp);
+            } else {
+                void *pcihp = acpi_data_push(bus_table,
+                                             ACPI_PCIVGA_SIZEOF);
+                memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF);
+                patch_pcivga(slot, pcihp);
             }
-        }
-
-        if (!dc->hotpluggable || bridge_in_acpi) {
-            clear_bit(slot, slot_hotplug_enable);
-        }
-    }
-
-    /* Append Device object for each slot */
-    for (i = 0; i < PCI_SLOT_MAX; i++) {
-        bool can_eject = test_bit(i, slot_hotplug_enable);
-        bool present = test_bit(i, slot_device_present);
-        bool vga = test_bit(i, slot_device_vga);
-        bool qxl = test_bit(i, slot_device_qxl);
-        bool system = test_bit(i, slot_device_system);
-        if (can_eject) {
-            void *pcihp = acpi_data_push(bus_table,
-                                         ACPI_PCIHP_SIZEOF);
+        } else if (dc->hotpluggable && !bridge_in_acpi) {
+            void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF);
             memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF);
-            patch_pcihp(i, pcihp);
-            bus_hotplug_support = true;
-        } else if (qxl) {
-            void *pcihp = acpi_data_push(bus_table,
-                                         ACPI_PCIQXL_SIZEOF);
-            memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF);
-            patch_pciqxl(i, pcihp);
-        } else if (vga) {
-            void *pcihp = acpi_data_push(bus_table,
-                                         ACPI_PCIVGA_SIZEOF);
-            memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF);
-            patch_pcivga(i, pcihp);
-        } else if (system) {
-            /* Nothing to do: system devices are in DSDT or in SSDT above. */
-        } else if (present) {
-            void *pcihp = acpi_data_push(bus_table,
-                                         ACPI_PCINOHP_SIZEOF);
-            memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF);
-            patch_pcinohp(i, pcihp);
-        }
-    }
-
-    if (bsel) {
-        method = build_alloc_method("DVNT", 2);
-
-        for (i = 0; i < PCI_SLOT_MAX; i++) {
-            GArray *notify;
-            uint8_t op;
+            patch_pcihp(slot, pcihp);
 
-            if (!test_bit(i, slot_hotplug_enable)) {
-                continue;
+            if (bsel) {
+                build_append_pcihp_notify_entry(method, slot);
             }
+        } else {
+            void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF);
+            memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF);
+            patch_pcinohp(slot, pcihp);
 
-            notify = build_alloc_array();
-            op = 0xA0; /* IfOp */
-
-            build_append_byte(notify, 0x7B); /* AndOp */
-            build_append_byte(notify, 0x68); /* Arg0Op */
-            build_append_int(notify, 0x1U << i);
-            build_append_byte(notify, 0x00); /* NullName */
-            build_append_byte(notify, 0x86); /* NotifyOp */
-            build_append_namestring(notify, "S%.02X", PCI_DEVFN(i, 0));
-            build_append_byte(notify, 0x69); /* Arg1Op */
-
-            /* Pack it up */
-            build_package(notify, op);
-
-            build_append_array(method, notify);
+            /* When hotplug for bridges is enabled, bridges that are
+             * described in ACPI separately aren't themselves hot-pluggable.
+             */
+            if (bridge_in_acpi) {
+                PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
 
-            build_free_array(notify);
+                build_append_pci_bus_devices(bus_table, sec_bus,
+                                             pcihp_bridge_en);
+            }
         }
+    }
 
+    if (bsel) {
         build_append_and_cleanup_method(bus_table, method);
     }
 
     /* Append PCNT method to notify about events on local and child buses.
      * Add unconditionally for root since DSDT expects it.
      */
-    if (bus_hotplug_support || child->notify_table->len || !bus->parent_dev) {
-        method = build_alloc_method("PCNT", 0);
-
-        /* If bus supports hotplug select it and notify about local events */
-        if (bsel) {
-            build_append_byte(method, 0x70); /* StoreOp */
-            build_append_int(method, qint_get_int(qobject_to_qint(bsel)));
-            build_append_namestring(method, "BNUM");
-            build_append_namestring(method, "DVNT");
-            build_append_namestring(method, "PCIU");
-            build_append_int(method, 1); /* Device Check */
-            build_append_namestring(method, "DVNT");
-            build_append_namestring(method, "PCID");
-            build_append_int(method, 3); /* Eject Request */
-        }
-
-        /* Notify about child bus events in any case */
-        build_append_array(method, child->notify_table);
-
-        build_append_and_cleanup_method(bus_table, method);
-
-        /* Append description of child buses */
-        build_append_array(bus_table, child->device_table);
+    method = build_alloc_method("PCNT", 0);
 
-        /* Pack it up */
-        if (bus->parent_dev) {
-            build_extop_package(bus_table, op);
-        } else {
-            build_package(bus_table, op);
-        }
-
-        /* Append our bus description to parent table */
-        build_append_array(parent->device_table, bus_table);
+    /* If bus supports hotplug select it and notify about local events */
+    if (bsel) {
+        build_append_byte(method, 0x70); /* StoreOp */
+        build_append_int(method, qint_get_int(qobject_to_qint(bsel)));
+        build_append_namestring(method, "BNUM");
+        build_append_namestring(method, "DVNT");
+        build_append_namestring(method, "PCIU");
+        build_append_int(method, 1); /* Device Check */
+        build_append_namestring(method, "DVNT");
+        build_append_namestring(method, "PCID");
+        build_append_int(method, 3); /* Eject Request */
+    }
 
-        /* Also tell parent how to notify us, invoking PCNT method.
-         * At the moment this is not needed for root as we have a single root.
-         */
-        if (bus->parent_dev) {
-            build_append_namestring(parent->notify_table, "^PCNT.S%.02X",
-                                 bus->parent_dev->devfn);
+    /* Notify about child bus events in any case */
+    if (pcihp_bridge_en) {
+        QLIST_FOREACH(sec, &bus->child, sibling) {
+            build_append_namestring(method, "^S%.02X.PCNT",
+                                    sec->parent_dev->devfn);
         }
     }
 
-    qobject_decref(bsel);
+    build_append_and_cleanup_method(bus_table, method);
+
+    build_package(bus_table, 0x10); /* ScopeOp */
+    build_append_array(parent_scope, bus_table);
     build_free_array(bus_table);
-    build_pci_bus_state_cleanup(child);
-    g_free(child);
 }
 
 static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
@@ -1035,7 +946,6 @@ build_ssdt(GArray *table_data, GArray *linker,
         }
 
         {
-            AcpiBuildPciBusHotplugState hotplug_state;
             Object *pci_host;
             PCIBus *bus = NULL;
             bool ambiguous;
@@ -1045,16 +955,11 @@ build_ssdt(GArray *table_data, GArray *linker,
                 bus = PCI_HOST_BRIDGE(pci_host)->bus;
             }
 
-            build_pci_bus_state_init(&hotplug_state, NULL, pm->pcihp_bridge_en);
-
             if (bus) {
                 /* Scan all PCI buses. Generate tables to support hotplug. */
-                pci_for_each_bus_depth_first(bus, build_pci_bus_begin,
-                                             build_pci_bus_end, &hotplug_state);
+                build_append_pci_bus_devices(sb_scope, bus,
+                                             pm->pcihp_bridge_en);
             }
-
-            build_append_array(sb_scope, hotplug_state.device_table);
-            build_pci_bus_state_cleanup(&hotplug_state);
         }
         build_package(sb_scope, op);
         build_append_array(table_data, sb_scope);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v5 1/5] pc: acpi-build: cleanup AcpiPmInfo initialization
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 1/5] pc: acpi-build: cleanup AcpiPmInfo initialization Igor Mammedov
@ 2015-01-21  9:11   ` Marcel Apfelbaum
  0 siblings, 0 replies; 13+ messages in thread
From: Marcel Apfelbaum @ 2015-01-21  9:11 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: marcel.a, mst

On 01/21/2015 11:09 AM, Igor Mammedov wrote:
> zero initialize AcpiPmInfo struct to reduce code bloat
> a little bit.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
> ---
>   hw/i386/acpi-build.c | 8 ++------
>   1 file changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 77a124e..4c0536f 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -172,6 +172,8 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
>       Object *obj = NULL;
>       QObject *o;
>
> +    memset(pm, 0, sizeof(*pm));
> +
>       if (piix) {
>           obj = piix;
>       }
> @@ -184,22 +186,16 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
>       o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
>       if (o) {
>           pm->s3_disabled = qint_get_int(qobject_to_qint(o));
> -    } else {
> -        pm->s3_disabled = false;
>       }
>       qobject_decref(o);
>       o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
>       if (o) {
>           pm->s4_disabled = qint_get_int(qobject_to_qint(o));
> -    } else {
> -        pm->s4_disabled = false;
>       }
>       qobject_decref(o);
>       o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
>       if (o) {
>           pm->s4_val = qint_get_int(qobject_to_qint(o));
> -    } else {
> -        pm->s4_val = false;
>       }
>       qobject_decref(o);
>
>

Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file Igor Mammedov
@ 2015-01-21  9:13   ` Marcel Apfelbaum
  2015-01-27 12:23   ` Michael S. Tsirkin
  1 sibling, 0 replies; 13+ messages in thread
From: Marcel Apfelbaum @ 2015-01-21  9:13 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: marcel.a, mst

On 01/21/2015 11:09 AM, Igor Mammedov wrote:
> the will be later used for composing AML primitives
> and all that could be reused later for ARM machines
> as well.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> v3:
>    * rename acpi_gen_utils.[ch] to acpi-build-utils.[ch]
>    * copy GLP license block from acpi-build.c
> v2:
>    * fix wrong ident in moved code
> ---
>   hw/acpi/Makefile.objs              |   1 +
>   hw/acpi/acpi-build-utils.c         | 187 +++++++++++++++++++++++++++++++++++++
>   hw/i386/acpi-build.c               | 162 +-------------------------------
>   include/hw/acpi/acpi-build-utils.h |  23 +++++
>   4 files changed, 213 insertions(+), 160 deletions(-)
>   create mode 100644 hw/acpi/acpi-build-utils.c
>   create mode 100644 include/hw/acpi/acpi-build-utils.h
>
> diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
> index ee82073..cad0355 100644
> --- a/hw/acpi/Makefile.objs
> +++ b/hw/acpi/Makefile.objs
> @@ -2,3 +2,4 @@ common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
>   common-obj-$(CONFIG_ACPI) += memory_hotplug.o
>   common-obj-$(CONFIG_ACPI) += acpi_interface.o
>   common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
> +common-obj-$(CONFIG_ACPI) += acpi-build-utils.o
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> new file mode 100644
> index 0000000..79aa610
> --- /dev/null
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -0,0 +1,187 @@
> +/* Support for generating ACPI tables and passing them to Guests
> + *
> + * Copyright (C) 2014 Red Hat Inc
                     ^^^^
2015?
Michael, can you change this on the fly?

Other than that:
Acked-by: Marcel Apfelbaum <marcel@redhat.com>

> + *
> + * Author: Michael S. Tsirkin <mst@redhat.com>
> + * Author: Igor Mammedov <imammedo@redhat.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> +
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> +
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <stdio.h>
> +#include <stdarg.h>
> +#include <assert.h>
> +#include <stdbool.h>
> +#include "hw/acpi/acpi-build-utils.h"
> +
> +GArray *build_alloc_array(void)
> +{
> +    return g_array_new(false, true /* clear */, 1);
> +}
> +
> +void build_free_array(GArray *array)
> +{
> +    g_array_free(array, true);
> +}
> +
> +void build_prepend_byte(GArray *array, uint8_t val)
> +{
> +    g_array_prepend_val(array, val);
> +}
> +
> +void build_append_byte(GArray *array, uint8_t val)
> +{
> +    g_array_append_val(array, val);
> +}
> +
> +void build_append_array(GArray *array, GArray *val)
> +{
> +    g_array_append_vals(array, val->data, val->len);
> +}
> +
> +#define ACPI_NAMESEG_LEN 4
> +
> +void GCC_FMT_ATTR(2, 3)
> +build_append_nameseg(GArray *array, const char *format, ...)
> +{
> +    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> +    char s[] = "XXXX";
> +    int len;
> +    va_list args;
> +
> +    va_start(args, format);
> +    len = vsnprintf(s, sizeof s, format, args);
> +    va_end(args);
> +
> +    assert(len <= ACPI_NAMESEG_LEN);
> +
> +    g_array_append_vals(array, s, len);
> +    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
> +    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
> +}
> +
> +/* 5.4 Definition Block Encoding */
> +enum {
> +    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
> +    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
> +    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
> +    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
> +};
> +
> +void build_prepend_package_length(GArray *package, unsigned min_bytes)
> +{
> +    uint8_t byte;
> +    unsigned length = package->len;
> +    unsigned length_bytes;
> +
> +    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
> +        length_bytes = 1;
> +    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
> +        length_bytes = 2;
> +    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
> +        length_bytes = 3;
> +    } else {
> +        length_bytes = 4;
> +    }
> +
> +    /* Force length to at least min_bytes.
> +     * This wastes memory but that's how bios did it.
> +     */
> +    length_bytes = MAX(length_bytes, min_bytes);
> +
> +    /* PkgLength is the length of the inclusive length of the data. */
> +    length += length_bytes;
> +
> +    switch (length_bytes) {
> +    case 1:
> +        byte = length;
> +        build_prepend_byte(package, byte);
> +        return;
> +    case 4:
> +        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
> +        build_prepend_byte(package, byte);
> +        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
> +        /* fall through */
> +    case 3:
> +        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
> +        build_prepend_byte(package, byte);
> +        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
> +        /* fall through */
> +    case 2:
> +        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
> +        build_prepend_byte(package, byte);
> +        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
> +        /* fall through */
> +    }
> +    /*
> +     * Most significant two bits of byte zero indicate how many following bytes
> +     * are in PkgLength encoding.
> +     */
> +    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
> +    build_prepend_byte(package, byte);
> +}
> +
> +void build_package(GArray *package, uint8_t op, unsigned min_bytes)
> +{
> +    build_prepend_package_length(package, min_bytes);
> +    build_prepend_byte(package, op);
> +}
> +
> +void build_extop_package(GArray *package, uint8_t op)
> +{
> +    build_package(package, op, 1);
> +    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
> +}
> +
> +void build_append_value(GArray *table, uint32_t value, int size)
> +{
> +    uint8_t prefix;
> +    int i;
> +
> +    switch (size) {
> +    case 1:
> +        prefix = 0x0A; /* BytePrefix */
> +        break;
> +    case 2:
> +        prefix = 0x0B; /* WordPrefix */
> +        break;
> +    case 4:
> +        prefix = 0x0C; /* DWordPrefix */
> +        break;
> +    default:
> +        assert(0);
> +        return;
> +    }
> +    build_append_byte(table, prefix);
> +    for (i = 0; i < size; ++i) {
> +        build_append_byte(table, value & 0xFF);
> +        value = value >> 8;
> +    }
> +}
> +
> +void build_append_int(GArray *table, uint32_t value)
> +{
> +    if (value == 0x00) {
> +        build_append_byte(table, 0x00); /* ZeroOp */
> +    } else if (value == 0x01) {
> +        build_append_byte(table, 0x01); /* OneOp */
> +    } else if (value <= 0xFF) {
> +        build_append_value(table, value, 1);
> +    } else if (value <= 0xFFFF) {
> +        build_append_value(table, value, 2);
> +    } else {
> +        build_append_value(table, value, 4);
> +    }
> +}
> +
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 4c0536f..8ee15ab 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -54,6 +54,8 @@
>   #include "hw/i386/q35-acpi-dsdt.hex"
>   #include "hw/i386/acpi-dsdt.hex"
>
> +#include "hw/acpi/acpi-build-utils.h"
> +
>   #include "qapi/qmp/qint.h"
>   #include "qom/qom-qobject.h"
>   #include "exec/ram_addr.h"
> @@ -277,166 +279,6 @@ build_header(GArray *linker, GArray *table_data,
>                                       table_data->data, h, len, &h->checksum);
>   }
>
> -static inline GArray *build_alloc_array(void)
> -{
> -    return g_array_new(false, true /* clear */, 1);
> -}
> -
> -static inline void build_free_array(GArray *array)
> -{
> -    g_array_free(array, true);
> -}
> -
> -static inline void build_prepend_byte(GArray *array, uint8_t val)
> -{
> -    g_array_prepend_val(array, val);
> -}
> -
> -static inline void build_append_byte(GArray *array, uint8_t val)
> -{
> -    g_array_append_val(array, val);
> -}
> -
> -static inline void build_append_array(GArray *array, GArray *val)
> -{
> -    g_array_append_vals(array, val->data, val->len);
> -}
> -
> -#define ACPI_NAMESEG_LEN 4
> -
> -static void GCC_FMT_ATTR(2, 3)
> -build_append_nameseg(GArray *array, const char *format, ...)
> -{
> -    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> -    char s[] = "XXXX";
> -    int len;
> -    va_list args;
> -
> -    va_start(args, format);
> -    len = vsnprintf(s, sizeof s, format, args);
> -    va_end(args);
> -
> -    assert(len <= ACPI_NAMESEG_LEN);
> -
> -    g_array_append_vals(array, s, len);
> -    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
> -    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
> -}
> -
> -/* 5.4 Definition Block Encoding */
> -enum {
> -    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
> -    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
> -    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
> -    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
> -};
> -
> -static void build_prepend_package_length(GArray *package, unsigned min_bytes)
> -{
> -    uint8_t byte;
> -    unsigned length = package->len;
> -    unsigned length_bytes;
> -
> -    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
> -        length_bytes = 1;
> -    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
> -        length_bytes = 2;
> -    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
> -        length_bytes = 3;
> -    } else {
> -        length_bytes = 4;
> -    }
> -
> -    /* Force length to at least min_bytes.
> -     * This wastes memory but that's how bios did it.
> -     */
> -    length_bytes = MAX(length_bytes, min_bytes);
> -
> -    /* PkgLength is the length of the inclusive length of the data. */
> -    length += length_bytes;
> -
> -    switch (length_bytes) {
> -    case 1:
> -        byte = length;
> -        build_prepend_byte(package, byte);
> -        return;
> -    case 4:
> -        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
> -        build_prepend_byte(package, byte);
> -        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
> -        /* fall through */
> -    case 3:
> -        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
> -        build_prepend_byte(package, byte);
> -        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
> -        /* fall through */
> -    case 2:
> -        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
> -        build_prepend_byte(package, byte);
> -        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
> -        /* fall through */
> -    }
> -    /*
> -     * Most significant two bits of byte zero indicate how many following bytes
> -     * are in PkgLength encoding.
> -     */
> -    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
> -    build_prepend_byte(package, byte);
> -}
> -
> -static void build_package(GArray *package, uint8_t op, unsigned min_bytes)
> -{
> -    build_prepend_package_length(package, min_bytes);
> -    build_prepend_byte(package, op);
> -}
> -
> -static void build_extop_package(GArray *package, uint8_t op)
> -{
> -    build_package(package, op, 1);
> -    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
> -}
> -
> -static void build_append_value(GArray *table, uint32_t value, int size)
> -{
> -    uint8_t prefix;
> -    int i;
> -
> -    switch (size) {
> -    case 1:
> -        prefix = 0x0A; /* BytePrefix */
> -        break;
> -    case 2:
> -        prefix = 0x0B; /* WordPrefix */
> -        break;
> -    case 4:
> -        prefix = 0x0C; /* DWordPrefix */
> -        break;
> -    default:
> -        assert(0);
> -        return;
> -    }
> -    build_append_byte(table, prefix);
> -    for (i = 0; i < size; ++i) {
> -        build_append_byte(table, value & 0xFF);
> -        value = value >> 8;
> -    }
> -}
> -
> -static void build_append_int(GArray *table, uint32_t value)
> -{
> -    if (value == 0x00) {
> -        build_append_byte(table, 0x00); /* ZeroOp */
> -    } else if (value == 0x01) {
> -        build_append_byte(table, 0x01); /* OneOp */
> -    } else if (value <= 0xFF) {
> -        build_append_value(table, value, 1);
> -    } else if (value <= 0xFFFF) {
> -        build_append_value(table, value, 2);
> -    } else {
> -        build_append_value(table, value, 4);
> -    }
> -}
> -
>   static GArray *build_alloc_method(const char *name, uint8_t arg_count)
>   {
>       GArray *method = build_alloc_array();
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> new file mode 100644
> index 0000000..e6a0b28
> --- /dev/null
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -0,0 +1,23 @@
> +#ifndef HW_ACPI_GEN_UTILS_H
> +#define HW_ACPI_GEN_UTILS_H
> +
> +#include <stdint.h>
> +#include <glib.h>
> +#include "qemu/compiler.h"
> +
> +GArray *build_alloc_array(void);
> +void build_free_array(GArray *array);
> +void build_prepend_byte(GArray *array, uint8_t val);
> +void build_append_byte(GArray *array, uint8_t val);
> +void build_append_array(GArray *array, GArray *val);
> +
> +void GCC_FMT_ATTR(2, 3)
> +build_append_nameseg(GArray *array, const char *format, ...);
> +
> +void build_prepend_package_length(GArray *package, unsigned min_bytes);
> +void build_package(GArray *package, uint8_t op, unsigned min_bytes);
> +void build_append_value(GArray *table, uint32_t value, int size);
> +void build_append_int(GArray *table, uint32_t value);
> +void build_extop_package(GArray *package, uint8_t op);
> +
> +#endif
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v5 3/5] acpi: add build_append_namestring() helper
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 3/5] acpi: add build_append_namestring() helper Igor Mammedov
@ 2015-01-21  9:22   ` Marcel Apfelbaum
  0 siblings, 0 replies; 13+ messages in thread
From: Marcel Apfelbaum @ 2015-01-21  9:22 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: marcel.a, mst

On 01/21/2015 11:09 AM, Igor Mammedov wrote:
> Use build_append_namestring() instead of build_append_nameseg()
> So user won't have to care whether name is NameSeg, NamePath or
> NameString.
>
> See for refernce ACPI 5.0: 20.2.2 Name Objects Encoding
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
> ---
> v3:
>   assert on wrong Segcount earlier and extend condition to
>    seg_count > 0 && seg_count <= 255
>   as suggested by Claudio Fontana <claudio.fontana@huawei.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 90 +++++++++++++++++++++++++++++++++++++-
>   hw/i386/acpi-build.c               | 35 +++++++--------
>   include/hw/acpi/acpi-build-utils.h |  2 +-
>   3 files changed, 106 insertions(+), 21 deletions(-)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 79aa610..aed9066 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -52,7 +52,7 @@ void build_append_array(GArray *array, GArray *val)
>
>   #define ACPI_NAMESEG_LEN 4
>
> -void GCC_FMT_ATTR(2, 3)
> +static void GCC_FMT_ATTR(2, 3)
>   build_append_nameseg(GArray *array, const char *format, ...)
>   {
>       /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> @@ -71,6 +71,94 @@ build_append_nameseg(GArray *array, const char *format, ...)
>       g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
>   }
>
> +static const uint8_t ACPI_DualNamePrefix  = 0x2E;
> +static const uint8_t ACPI_MultiNamePrefix = 0x2F;
> +
> +static void
> +build_append_namestringv(GArray *array, const char *format, va_list ap)
> +{
> +    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> +    char *s;
> +    int len;
> +    va_list va_len;
> +    char **segs;
> +    char **segs_iter;
> +    int seg_count = 0;
> +
> +    va_copy(va_len, ap);
> +    len = vsnprintf(NULL, 0, format, va_len);
> +    va_end(va_len);
> +    len += 1;
> +    s = g_new(typeof(*s), len);
> +
> +    len = vsnprintf(s, len, format, ap);
> +
> +    segs = g_strsplit(s, ".", 0);
> +    g_free(s);
> +
> +    /* count segments */
> +    segs_iter = segs;
> +    while (*segs_iter) {
> +        ++segs_iter;
> +        ++seg_count;
> +    }
> +    /*
> +     * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
> +     * "SegCount can be from 1 to 255"
> +     */
> +    assert(seg_count > 0 && seg_count <= 255);
> +
> +    /* handle RootPath || PrefixPath */
> +    s = *segs;
> +    while (*s == '\\' || *s == '^') {
> +        g_array_append_val(array, *s);
> +        ++s;
> +    }
> +
> +    switch (seg_count) {
> +    case 1:
> +        if (!*s) { /* NullName */
> +            const uint8_t nullpath = 0;
> +            g_array_append_val(array, nullpath);
> +        } else {
> +            build_append_nameseg(array, "%s", s);
> +        }
> +        break;
> +
> +    case 2:
> +        g_array_append_val(array, ACPI_DualNamePrefix);
> +        build_append_nameseg(array, "%s", s);
> +        build_append_nameseg(array, "%s", segs[1]);
> +        break;
> +
> +    default:
> +        g_array_append_val(array, ACPI_MultiNamePrefix);
> +        g_array_append_val(array, seg_count);
> +
> +        /* handle the 1st segment manually due to prefix/root path */
> +        build_append_nameseg(array, "%s", s);
> +
> +        /* add the rest of segments */
> +        segs_iter = segs + 1;
> +        while (*segs_iter) {
> +            build_append_nameseg(array, "%s", *segs_iter);
> +            ++segs_iter;
> +        }
> +        break;
> +    }
> +    g_strfreev(segs);
> +}
> +
> +void GCC_FMT_ATTR(2, 3)
> +build_append_namestring(GArray *array, const char *format, ...)
> +{
> +    va_list ap;
> +
> +    va_start(ap, format);
> +    build_append_namestringv(array, format, ap);
> +    va_end(ap);
> +}
> +
>   /* 5.4 Definition Block Encoding */
>   enum {
>       PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 8ee15ab..e3ac1a14 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -283,7 +283,7 @@ static GArray *build_alloc_method(const char *name, uint8_t arg_count)
>   {
>       GArray *method = build_alloc_array();
>
> -    build_append_nameseg(method, "%s", name);
> +    build_append_namestring(method, "%s", name);
>       build_append_byte(method, arg_count); /* MethodFlags: ArgCount */
>
>       return method;
> @@ -575,7 +575,7 @@ build_append_notify_method(GArray *device, const char *name,
>
>       for (i = 0; i < count; i++) {
>           GArray *target = build_alloc_array();
> -        build_append_nameseg(target, format, i);
> +        build_append_namestring(target, format, i);
>           assert(i < 256); /* Fits in 1 byte */
>           build_append_notify_target_ifequal(method, target, i, 1);
>           build_free_array(target);
> @@ -703,24 +703,24 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>
>       if (bus->parent_dev) {
>           op = 0x82; /* DeviceOp */
> -        build_append_nameseg(bus_table, "S%.02X",
> +        build_append_namestring(bus_table, "S%.02X",
>                                bus->parent_dev->devfn);
>           build_append_byte(bus_table, 0x08); /* NameOp */
> -        build_append_nameseg(bus_table, "_SUN");
> +        build_append_namestring(bus_table, "_SUN");
>           build_append_value(bus_table, PCI_SLOT(bus->parent_dev->devfn), 1);
>           build_append_byte(bus_table, 0x08); /* NameOp */
> -        build_append_nameseg(bus_table, "_ADR");
> +        build_append_namestring(bus_table, "_ADR");
>           build_append_value(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) |
>                              PCI_FUNC(bus->parent_dev->devfn), 4);
>       } else {
>           op = 0x10; /* ScopeOp */;
> -        build_append_nameseg(bus_table, "PCI0");
> +        build_append_namestring(bus_table, "PCI0");
>       }
>
>       bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
>       if (bsel) {
>           build_append_byte(bus_table, 0x08); /* NameOp */
> -        build_append_nameseg(bus_table, "BSEL");
> +        build_append_namestring(bus_table, "BSEL");
>           build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel)));
>           memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable);
>       } else {
> @@ -823,7 +823,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>               build_append_int(notify, 0x1U << i);
>               build_append_byte(notify, 0x00); /* NullName */
>               build_append_byte(notify, 0x86); /* NotifyOp */
> -            build_append_nameseg(notify, "S%.02X", PCI_DEVFN(i, 0));
> +            build_append_namestring(notify, "S%.02X", PCI_DEVFN(i, 0));
>               build_append_byte(notify, 0x69); /* Arg1Op */
>
>               /* Pack it up */
> @@ -847,12 +847,12 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>           if (bsel) {
>               build_append_byte(method, 0x70); /* StoreOp */
>               build_append_int(method, qint_get_int(qobject_to_qint(bsel)));
> -            build_append_nameseg(method, "BNUM");
> -            build_append_nameseg(method, "DVNT");
> -            build_append_nameseg(method, "PCIU");
> +            build_append_namestring(method, "BNUM");
> +            build_append_namestring(method, "DVNT");
> +            build_append_namestring(method, "PCIU");
>               build_append_int(method, 1); /* Device Check */
> -            build_append_nameseg(method, "DVNT");
> -            build_append_nameseg(method, "PCID");
> +            build_append_namestring(method, "DVNT");
> +            build_append_namestring(method, "PCID");
>               build_append_int(method, 3); /* Eject Request */
>           }
>
> @@ -878,11 +878,8 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>            * At the moment this is not needed for root as we have a single root.
>            */
>           if (bus->parent_dev) {
> -            build_append_byte(parent->notify_table, '^'); /* ParentPrefixChar */
> -            build_append_byte(parent->notify_table, 0x2E); /* DualNamePrefix */
> -            build_append_nameseg(parent->notify_table, "S%.02X",
> +            build_append_namestring(parent->notify_table, "^PCNT.S%.02X",
>                                    bus->parent_dev->devfn);
> -            build_append_nameseg(parent->notify_table, "PCNT");
>           }
>       }
>
> @@ -967,7 +964,7 @@ build_ssdt(GArray *table_data, GArray *linker,
>           GArray *sb_scope = build_alloc_array();
>           uint8_t op = 0x10; /* ScopeOp */
>
> -        build_append_nameseg(sb_scope, "_SB");
> +        build_append_namestring(sb_scope, "_SB");
>
>           /* build Processor object for each processor */
>           for (i = 0; i < acpi_cpus; i++) {
> @@ -987,7 +984,7 @@ build_ssdt(GArray *table_data, GArray *linker,
>
>           /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */
>           build_append_byte(sb_scope, 0x08); /* NameOp */
> -        build_append_nameseg(sb_scope, "CPON");
> +        build_append_namestring(sb_scope, "CPON");
>
>           {
>               GArray *package = build_alloc_array();
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index e6a0b28..fd50625 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -12,7 +12,7 @@ void build_append_byte(GArray *array, uint8_t val);
>   void build_append_array(GArray *array, GArray *val);
>
>   void GCC_FMT_ATTR(2, 3)
> -build_append_nameseg(GArray *array, const char *format, ...);
> +build_append_namestring(GArray *array, const char *format, ...);
>
>   void build_prepend_package_length(GArray *package, unsigned min_bytes);
>   void build_package(GArray *package, uint8_t op, unsigned min_bytes);
>

Acked-by: Marcel Apfelbaum <marcel@redhat.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v5 4/5] acpi: drop min-bytes in build_package()
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 4/5] acpi: drop min-bytes in build_package() Igor Mammedov
@ 2015-01-21  9:25   ` Marcel Apfelbaum
  0 siblings, 0 replies; 13+ messages in thread
From: Marcel Apfelbaum @ 2015-01-21  9:25 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: marcel.a, mst

On 01/21/2015 11:09 AM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 14 ++++----------
>   hw/i386/acpi-build.c               | 13 ++++++-------
>   include/hw/acpi/acpi-build-utils.h |  4 ++--
>   3 files changed, 12 insertions(+), 19 deletions(-)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index aed9066..602e68c 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -167,7 +167,7 @@ enum {
>       PACKAGE_LENGTH_4BYTE_SHIFT = 20,
>   };
>
> -void build_prepend_package_length(GArray *package, unsigned min_bytes)
> +void build_prepend_package_length(GArray *package)
>   {
>       uint8_t byte;
>       unsigned length = package->len;
> @@ -183,11 +183,6 @@ void build_prepend_package_length(GArray *package, unsigned min_bytes)
>           length_bytes = 4;
>       }
>
> -    /* Force length to at least min_bytes.
> -     * This wastes memory but that's how bios did it.
> -     */
> -    length_bytes = MAX(length_bytes, min_bytes);
> -
>       /* PkgLength is the length of the inclusive length of the data. */
>       length += length_bytes;
>
> @@ -220,15 +215,15 @@ void build_prepend_package_length(GArray *package, unsigned min_bytes)
>       build_prepend_byte(package, byte);
>   }
>
> -void build_package(GArray *package, uint8_t op, unsigned min_bytes)
> +void build_package(GArray *package, uint8_t op)
>   {
> -    build_prepend_package_length(package, min_bytes);
> +    build_prepend_package_length(package);
>       build_prepend_byte(package, op);
>   }
>
>   void build_extop_package(GArray *package, uint8_t op)
>   {
> -    build_package(package, op, 1);
> +    build_package(package, op);
>       build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
>   }
>
> @@ -272,4 +267,3 @@ void build_append_int(GArray *table, uint32_t value)
>           build_append_value(table, value, 4);
>       }
>   }
> -
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index e3ac1a14..a010f3b 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -293,7 +293,7 @@ static void build_append_and_cleanup_method(GArray *device, GArray *method)
>   {
>       uint8_t op = 0x14; /* MethodOp */
>
> -    build_package(method, op, 0);
> +    build_package(method, op);
>
>       build_append_array(device, method);
>       build_free_array(method);
> @@ -314,7 +314,7 @@ static void build_append_notify_target_ifequal(GArray *method,
>       build_append_byte(notify, 0x69); /* Arg1Op */
>
>       /* Pack it up */
> -    build_package(notify, op, 1);
> +    build_package(notify, op);
>
>       build_append_array(method, notify);
>
> @@ -827,7 +827,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>               build_append_byte(notify, 0x69); /* Arg1Op */
>
>               /* Pack it up */
> -            build_package(notify, op, 0);
> +            build_package(notify, op);
>
>               build_append_array(method, notify);
>
> @@ -868,7 +868,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>           if (bus->parent_dev) {
>               build_extop_package(bus_table, op);
>           } else {
> -            build_package(bus_table, op, 0);
> +            build_package(bus_table, op);
>           }
>
>           /* Append our bus description to parent table */
> @@ -1008,7 +1008,7 @@ build_ssdt(GArray *table_data, GArray *linker,
>                   build_append_byte(package, b);
>               }
>
> -            build_package(package, op, 2);
> +            build_package(package, op);
>               build_append_array(sb_scope, package);
>               build_free_array(package);
>           }
> @@ -1056,8 +1056,7 @@ build_ssdt(GArray *table_data, GArray *linker,
>               build_append_array(sb_scope, hotplug_state.device_table);
>               build_pci_bus_state_cleanup(&hotplug_state);
>           }
> -
> -        build_package(sb_scope, op, 3);
> +        build_package(sb_scope, op);
>           build_append_array(table_data, sb_scope);
>           build_free_array(sb_scope);
>       }
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index fd50625..199f003 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -14,8 +14,8 @@ void build_append_array(GArray *array, GArray *val);
>   void GCC_FMT_ATTR(2, 3)
>   build_append_namestring(GArray *array, const char *format, ...);
>
> -void build_prepend_package_length(GArray *package, unsigned min_bytes);
> -void build_package(GArray *package, uint8_t op, unsigned min_bytes);
> +void build_prepend_package_length(GArray *package);
> +void build_package(GArray *package, uint8_t op);
>   void build_append_value(GArray *table, uint32_t value, int size);
>   void build_append_int(GArray *table, uint32_t value);
>   void build_extop_package(GArray *package, uint8_t op);
>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v5 5/5] pc: acpi-build: simplify PCI bus tree generation
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 5/5] pc: acpi-build: simplify PCI bus tree generation Igor Mammedov
@ 2015-01-21  9:51   ` Marcel Apfelbaum
  0 siblings, 0 replies; 13+ messages in thread
From: Marcel Apfelbaum @ 2015-01-21  9:51 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: marcel.a, mst

On 01/21/2015 11:09 AM, Igor Mammedov wrote:
> it basicaly does the same as original approach,
> * just without bus/notify tables tracking (less obscure)
>    which is easier to follow.
> * drops unnecessary loops and bitmaps,
>    creating devices and notification method in the same loop.
> * saves us ~100LOC
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> v4:
>    * keep original logic of creating bridge devices as it was done
>      in 133a2da48 "pc: acpi: generate AML only for PCI0 ..."
>    * if bus is non hotpluggable, add child slots to bus as non
>      hotpluggable as it was done in original code.
> v3:
>    * use hotpluggable device object instead of not hotpluggable
>      for non present devices, and add it only when bus itself is
>      hotpluggable
> ---
>   hw/i386/acpi-build.c | 275 +++++++++++++++++----------------------------------
>   1 file changed, 90 insertions(+), 185 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index a010f3b..5255428 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -106,7 +106,6 @@ typedef struct AcpiPmInfo {
>   typedef struct AcpiMiscInfo {
>       bool has_hpet;
>       bool has_tpm;
> -    DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX);
>       const unsigned char *dsdt_code;
>       unsigned dsdt_size;
>       uint16_t pvpanic_port;
> @@ -651,69 +650,37 @@ static void acpi_set_pci_info(void)
>       }
>   }
>
> -static void build_pci_bus_state_init(AcpiBuildPciBusHotplugState *state,
> -                                     AcpiBuildPciBusHotplugState *parent,
> -                                     bool pcihp_bridge_en)
> +static void build_append_pcihp_notify_entry(GArray *method, int slot)
>   {
> -    state->parent = parent;
> -    state->device_table = build_alloc_array();
> -    state->notify_table = build_alloc_array();
> -    state->pcihp_bridge_en = pcihp_bridge_en;
> -}
> -
> -static void build_pci_bus_state_cleanup(AcpiBuildPciBusHotplugState *state)
> -{
> -    build_free_array(state->device_table);
> -    build_free_array(state->notify_table);
> -}
> +    GArray *ifctx;
>
> -static void *build_pci_bus_begin(PCIBus *bus, void *parent_state)
> -{
> -    AcpiBuildPciBusHotplugState *parent = parent_state;
> -    AcpiBuildPciBusHotplugState *child = g_malloc(sizeof *child);
> -
> -    build_pci_bus_state_init(child, parent, parent->pcihp_bridge_en);
> +    ifctx = build_alloc_array();
> +    build_append_byte(ifctx, 0x7B); /* AndOp */
> +    build_append_byte(ifctx, 0x68); /* Arg0Op */
> +    build_append_int(ifctx, 0x1U << slot);
> +    build_append_byte(ifctx, 0x00); /* NullName */
> +    build_append_byte(ifctx, 0x86); /* NotifyOp */
> +    build_append_namestring(ifctx, "S%.02X", PCI_DEVFN(slot, 0));
> +    build_append_byte(ifctx, 0x69); /* Arg1Op */
>
> -    return child;
> +    /* Pack it up */
> +    build_package(ifctx, 0xA0 /* IfOp */);
> +    build_append_array(method, ifctx);
> +    build_free_array(ifctx);
>   }
>
> -static void build_pci_bus_end(PCIBus *bus, void *bus_state)
> +static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus,
> +                                         bool pcihp_bridge_en)
>   {
> -    AcpiBuildPciBusHotplugState *child = bus_state;
> -    AcpiBuildPciBusHotplugState *parent = child->parent;
>       GArray *bus_table = build_alloc_array();
> -    DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX);
> -    DECLARE_BITMAP(slot_device_present, PCI_SLOT_MAX);
> -    DECLARE_BITMAP(slot_device_system, PCI_SLOT_MAX);
> -    DECLARE_BITMAP(slot_device_vga, PCI_SLOT_MAX);
> -    DECLARE_BITMAP(slot_device_qxl, PCI_SLOT_MAX);
> -    uint8_t op;
> -    int i;
> +    GArray *method = NULL;
>       QObject *bsel;
> -    GArray *method;
> -    bool bus_hotplug_support = false;
> -
> -    /*
> -     * Skip bridge subtree creation if bridge hotplug is disabled
> -     * to make acpi tables compatible with legacy machine types.
> -     */
> -    if (!child->pcihp_bridge_en && bus->parent_dev) {
> -        return;
> -    }
> +    PCIBus *sec;
> +    int i;
>
>       if (bus->parent_dev) {
> -        op = 0x82; /* DeviceOp */
> -        build_append_namestring(bus_table, "S%.02X",
> -                             bus->parent_dev->devfn);
> -        build_append_byte(bus_table, 0x08); /* NameOp */
> -        build_append_namestring(bus_table, "_SUN");
> -        build_append_value(bus_table, PCI_SLOT(bus->parent_dev->devfn), 1);
> -        build_append_byte(bus_table, 0x08); /* NameOp */
> -        build_append_namestring(bus_table, "_ADR");
> -        build_append_value(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) |
> -                           PCI_FUNC(bus->parent_dev->devfn), 4);
> +        build_append_namestring(bus_table, "S%.02X_", bus->parent_dev->devfn);
>       } else {
> -        op = 0x10; /* ScopeOp */;
>           build_append_namestring(bus_table, "PCI0");
>       }
>
> @@ -722,17 +689,9 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>           build_append_byte(bus_table, 0x08); /* NameOp */
>           build_append_namestring(bus_table, "BSEL");
>           build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel)));
> -        memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable);
> -    } else {
> -        /* No bsel - no slots are hot-pluggable */
> -        memset(slot_hotplug_enable, 0x00, sizeof slot_hotplug_enable);
> +        method = build_alloc_method("DVNT", 2);
>       }
>
> -    memset(slot_device_present, 0x00, sizeof slot_device_present);
> -    memset(slot_device_system, 0x00, sizeof slot_device_present);
> -    memset(slot_device_vga, 0x00, sizeof slot_device_vga);
> -    memset(slot_device_qxl, 0x00, sizeof slot_device_qxl);
> -
>       for (i = 0; i < ARRAY_SIZE(bus->devices); i += PCI_FUNC_MAX) {
>           DeviceClass *dc;
>           PCIDeviceClass *pc;
> @@ -741,152 +700,104 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
>           bool bridge_in_acpi;
>
>           if (!pdev) {
> +            if (bsel) {
> +                void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF);
> +                memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF);
> +                patch_pcihp(slot, pcihp);
> +
> +                build_append_pcihp_notify_entry(method, slot);
> +            } else {
> +                /* no much sense to create empty non hotpluggable slots,
> +                 * but it's what original code did before. TODO: remove it.
> +                 */
> +                void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF);
> +                memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF);
> +                patch_pcinohp(slot, pcihp);
> +            }
>               continue;
>           }
>
> -        set_bit(slot, slot_device_present);
>           pc = PCI_DEVICE_GET_CLASS(pdev);
>           dc = DEVICE_GET_CLASS(pdev);
>
> -        /* When hotplug for bridges is enabled, bridges are
> -         * described in ACPI separately (see build_pci_bus_end).
> -         * In this case they aren't themselves hot-pluggable.
> -         */
> -        bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en;
> -
> -        if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) {
> -            set_bit(slot, slot_device_system);
> +        if (pc->class_id == PCI_CLASS_BRIDGE_ISA) {
> +            continue;
>           }
> +        bridge_in_acpi = pc->is_bridge && pcihp_bridge_en;
>
>           if (pc->class_id == PCI_CLASS_DISPLAY_VGA) {
> -            set_bit(slot, slot_device_vga);
>
>               if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) {
> -                set_bit(slot, slot_device_qxl);
> +                void *pcihp = acpi_data_push(bus_table,
> +                                             ACPI_PCIQXL_SIZEOF);
> +                      memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF);
> +                      patch_pciqxl(slot, pcihp);
> +            } else {
> +                void *pcihp = acpi_data_push(bus_table,
> +                                             ACPI_PCIVGA_SIZEOF);
> +                memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF);
> +                patch_pcivga(slot, pcihp);
>               }
> -        }
> -
> -        if (!dc->hotpluggable || bridge_in_acpi) {
> -            clear_bit(slot, slot_hotplug_enable);
> -        }
> -    }
> -
> -    /* Append Device object for each slot */
> -    for (i = 0; i < PCI_SLOT_MAX; i++) {
> -        bool can_eject = test_bit(i, slot_hotplug_enable);
> -        bool present = test_bit(i, slot_device_present);
> -        bool vga = test_bit(i, slot_device_vga);
> -        bool qxl = test_bit(i, slot_device_qxl);
> -        bool system = test_bit(i, slot_device_system);
> -        if (can_eject) {
> -            void *pcihp = acpi_data_push(bus_table,
> -                                         ACPI_PCIHP_SIZEOF);
> +        } else if (dc->hotpluggable && !bridge_in_acpi) {
> +            void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF);
>               memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF);
> -            patch_pcihp(i, pcihp);
> -            bus_hotplug_support = true;
> -        } else if (qxl) {
> -            void *pcihp = acpi_data_push(bus_table,
> -                                         ACPI_PCIQXL_SIZEOF);
> -            memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF);
> -            patch_pciqxl(i, pcihp);
> -        } else if (vga) {
> -            void *pcihp = acpi_data_push(bus_table,
> -                                         ACPI_PCIVGA_SIZEOF);
> -            memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF);
> -            patch_pcivga(i, pcihp);
> -        } else if (system) {
> -            /* Nothing to do: system devices are in DSDT or in SSDT above. */
> -        } else if (present) {
> -            void *pcihp = acpi_data_push(bus_table,
> -                                         ACPI_PCINOHP_SIZEOF);
> -            memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF);
> -            patch_pcinohp(i, pcihp);
> -        }
> -    }
> -
> -    if (bsel) {
> -        method = build_alloc_method("DVNT", 2);
> -
> -        for (i = 0; i < PCI_SLOT_MAX; i++) {
> -            GArray *notify;
> -            uint8_t op;
> +            patch_pcihp(slot, pcihp);
>
> -            if (!test_bit(i, slot_hotplug_enable)) {
> -                continue;
> +            if (bsel) {
> +                build_append_pcihp_notify_entry(method, slot);
>               }
> +        } else {
> +            void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF);
> +            memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF);
> +            patch_pcinohp(slot, pcihp);
>
> -            notify = build_alloc_array();
> -            op = 0xA0; /* IfOp */
> -
> -            build_append_byte(notify, 0x7B); /* AndOp */
> -            build_append_byte(notify, 0x68); /* Arg0Op */
> -            build_append_int(notify, 0x1U << i);
> -            build_append_byte(notify, 0x00); /* NullName */
> -            build_append_byte(notify, 0x86); /* NotifyOp */
> -            build_append_namestring(notify, "S%.02X", PCI_DEVFN(i, 0));
> -            build_append_byte(notify, 0x69); /* Arg1Op */
> -
> -            /* Pack it up */
> -            build_package(notify, op);
> -
> -            build_append_array(method, notify);
> +            /* When hotplug for bridges is enabled, bridges that are
> +             * described in ACPI separately aren't themselves hot-pluggable.
> +             */
> +            if (bridge_in_acpi) {
> +                PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
>
> -            build_free_array(notify);
> +                build_append_pci_bus_devices(bus_table, sec_bus,
> +                                             pcihp_bridge_en);
> +            }
>           }
> +    }
>
> +    if (bsel) {
>           build_append_and_cleanup_method(bus_table, method);
>       }
>
>       /* Append PCNT method to notify about events on local and child buses.
>        * Add unconditionally for root since DSDT expects it.
>        */
> -    if (bus_hotplug_support || child->notify_table->len || !bus->parent_dev) {
> -        method = build_alloc_method("PCNT", 0);
> -
> -        /* If bus supports hotplug select it and notify about local events */
> -        if (bsel) {
> -            build_append_byte(method, 0x70); /* StoreOp */
> -            build_append_int(method, qint_get_int(qobject_to_qint(bsel)));
> -            build_append_namestring(method, "BNUM");
> -            build_append_namestring(method, "DVNT");
> -            build_append_namestring(method, "PCIU");
> -            build_append_int(method, 1); /* Device Check */
> -            build_append_namestring(method, "DVNT");
> -            build_append_namestring(method, "PCID");
> -            build_append_int(method, 3); /* Eject Request */
> -        }
> -
> -        /* Notify about child bus events in any case */
> -        build_append_array(method, child->notify_table);
> -
> -        build_append_and_cleanup_method(bus_table, method);
> -
> -        /* Append description of child buses */
> -        build_append_array(bus_table, child->device_table);
> +    method = build_alloc_method("PCNT", 0);
>
> -        /* Pack it up */
> -        if (bus->parent_dev) {
> -            build_extop_package(bus_table, op);
> -        } else {
> -            build_package(bus_table, op);
> -        }
> -
> -        /* Append our bus description to parent table */
> -        build_append_array(parent->device_table, bus_table);
> +    /* If bus supports hotplug select it and notify about local events */
> +    if (bsel) {
> +        build_append_byte(method, 0x70); /* StoreOp */
> +        build_append_int(method, qint_get_int(qobject_to_qint(bsel)));
> +        build_append_namestring(method, "BNUM");
> +        build_append_namestring(method, "DVNT");
> +        build_append_namestring(method, "PCIU");
> +        build_append_int(method, 1); /* Device Check */
> +        build_append_namestring(method, "DVNT");
> +        build_append_namestring(method, "PCID");
> +        build_append_int(method, 3); /* Eject Request */
> +    }
>
> -        /* Also tell parent how to notify us, invoking PCNT method.
> -         * At the moment this is not needed for root as we have a single root.
> -         */
> -        if (bus->parent_dev) {
> -            build_append_namestring(parent->notify_table, "^PCNT.S%.02X",
> -                                 bus->parent_dev->devfn);
> +    /* Notify about child bus events in any case */
> +    if (pcihp_bridge_en) {
> +        QLIST_FOREACH(sec, &bus->child, sibling) {
> +            build_append_namestring(method, "^S%.02X.PCNT",
> +                                    sec->parent_dev->devfn);
>           }
>       }
>
> -    qobject_decref(bsel);
> +    build_append_and_cleanup_method(bus_table, method);
> +
> +    build_package(bus_table, 0x10); /* ScopeOp */
> +    build_append_array(parent_scope, bus_table);
>       build_free_array(bus_table);
> -    build_pci_bus_state_cleanup(child);
> -    g_free(child);
>   }
>
>   static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
> @@ -1035,7 +946,6 @@ build_ssdt(GArray *table_data, GArray *linker,
>           }
>
>           {
> -            AcpiBuildPciBusHotplugState hotplug_state;
>               Object *pci_host;
>               PCIBus *bus = NULL;
>               bool ambiguous;
> @@ -1045,16 +955,11 @@ build_ssdt(GArray *table_data, GArray *linker,
>                   bus = PCI_HOST_BRIDGE(pci_host)->bus;
>               }
>
> -            build_pci_bus_state_init(&hotplug_state, NULL, pm->pcihp_bridge_en);
> -
>               if (bus) {
>                   /* Scan all PCI buses. Generate tables to support hotplug. */
> -                pci_for_each_bus_depth_first(bus, build_pci_bus_begin,
> -                                             build_pci_bus_end, &hotplug_state);
> +                build_append_pci_bus_devices(sb_scope, bus,
> +                                             pm->pcihp_bridge_en);
>               }
> -
> -            build_append_array(sb_scope, hotplug_state.device_table);
> -            build_pci_bus_state_cleanup(&hotplug_state);
>           }
>           build_package(sb_scope, op);
>           build_append_array(table_data, sb_scope);
>

This one is tricky to review...
I do agree with the concept, I like the simplification,
and no obvious errors were found.

So ... "light":
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file
  2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file Igor Mammedov
  2015-01-21  9:13   ` Marcel Apfelbaum
@ 2015-01-27 12:23   ` Michael S. Tsirkin
  2015-01-28 12:34     ` Igor Mammedov
  1 sibling, 1 reply; 13+ messages in thread
From: Michael S. Tsirkin @ 2015-01-27 12:23 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel, marcel.a

On Wed, Jan 21, 2015 at 09:09:10AM +0000, Igor Mammedov wrote:
> the will be later used for composing AML primitives
> and all that could be reused later for ARM machines
> as well.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

OK so the only thing holding this up is really that
you have indicated that in the follow-up patches
you want to add here more stuff with
aml_ prefix instead of acpi_.

In that case let's name this file aml-build.c?


> ---
> v3:
>   * rename acpi_gen_utils.[ch] to acpi-build-utils.[ch]
>   * copy GLP license block from acpi-build.c
> v2:
>   * fix wrong ident in moved code
> ---
>  hw/acpi/Makefile.objs              |   1 +
>  hw/acpi/acpi-build-utils.c         | 187 +++++++++++++++++++++++++++++++++++++
>  hw/i386/acpi-build.c               | 162 +-------------------------------
>  include/hw/acpi/acpi-build-utils.h |  23 +++++
>  4 files changed, 213 insertions(+), 160 deletions(-)
>  create mode 100644 hw/acpi/acpi-build-utils.c
>  create mode 100644 include/hw/acpi/acpi-build-utils.h
> 
> diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
> index ee82073..cad0355 100644
> --- a/hw/acpi/Makefile.objs
> +++ b/hw/acpi/Makefile.objs
> @@ -2,3 +2,4 @@ common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
>  common-obj-$(CONFIG_ACPI) += memory_hotplug.o
>  common-obj-$(CONFIG_ACPI) += acpi_interface.o
>  common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
> +common-obj-$(CONFIG_ACPI) += acpi-build-utils.o
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> new file mode 100644
> index 0000000..79aa610
> --- /dev/null
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -0,0 +1,187 @@
> +/* Support for generating ACPI tables and passing them to Guests
> + *
> + * Copyright (C) 2014 Red Hat Inc
> + *
> + * Author: Michael S. Tsirkin <mst@redhat.com>
> + * Author: Igor Mammedov <imammedo@redhat.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> +
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> +
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <stdio.h>
> +#include <stdarg.h>
> +#include <assert.h>
> +#include <stdbool.h>
> +#include "hw/acpi/acpi-build-utils.h"
> +
> +GArray *build_alloc_array(void)
> +{
> +    return g_array_new(false, true /* clear */, 1);
> +}
> +
> +void build_free_array(GArray *array)
> +{
> +    g_array_free(array, true);
> +}
> +
> +void build_prepend_byte(GArray *array, uint8_t val)
> +{
> +    g_array_prepend_val(array, val);
> +}
> +
> +void build_append_byte(GArray *array, uint8_t val)
> +{
> +    g_array_append_val(array, val);
> +}
> +
> +void build_append_array(GArray *array, GArray *val)
> +{
> +    g_array_append_vals(array, val->data, val->len);
> +}
> +
> +#define ACPI_NAMESEG_LEN 4
> +
> +void GCC_FMT_ATTR(2, 3)
> +build_append_nameseg(GArray *array, const char *format, ...)
> +{
> +    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> +    char s[] = "XXXX";
> +    int len;
> +    va_list args;
> +
> +    va_start(args, format);
> +    len = vsnprintf(s, sizeof s, format, args);
> +    va_end(args);
> +
> +    assert(len <= ACPI_NAMESEG_LEN);
> +
> +    g_array_append_vals(array, s, len);
> +    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
> +    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
> +}
> +
> +/* 5.4 Definition Block Encoding */
> +enum {
> +    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
> +    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
> +    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
> +    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
> +};
> +
> +void build_prepend_package_length(GArray *package, unsigned min_bytes)
> +{
> +    uint8_t byte;
> +    unsigned length = package->len;
> +    unsigned length_bytes;
> +
> +    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
> +        length_bytes = 1;
> +    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
> +        length_bytes = 2;
> +    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
> +        length_bytes = 3;
> +    } else {
> +        length_bytes = 4;
> +    }
> +
> +    /* Force length to at least min_bytes.
> +     * This wastes memory but that's how bios did it.
> +     */
> +    length_bytes = MAX(length_bytes, min_bytes);
> +
> +    /* PkgLength is the length of the inclusive length of the data. */
> +    length += length_bytes;
> +
> +    switch (length_bytes) {
> +    case 1:
> +        byte = length;
> +        build_prepend_byte(package, byte);
> +        return;
> +    case 4:
> +        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
> +        build_prepend_byte(package, byte);
> +        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
> +        /* fall through */
> +    case 3:
> +        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
> +        build_prepend_byte(package, byte);
> +        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
> +        /* fall through */
> +    case 2:
> +        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
> +        build_prepend_byte(package, byte);
> +        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
> +        /* fall through */
> +    }
> +    /*
> +     * Most significant two bits of byte zero indicate how many following bytes
> +     * are in PkgLength encoding.
> +     */
> +    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
> +    build_prepend_byte(package, byte);
> +}
> +
> +void build_package(GArray *package, uint8_t op, unsigned min_bytes)
> +{
> +    build_prepend_package_length(package, min_bytes);
> +    build_prepend_byte(package, op);
> +}
> +
> +void build_extop_package(GArray *package, uint8_t op)
> +{
> +    build_package(package, op, 1);
> +    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
> +}
> +
> +void build_append_value(GArray *table, uint32_t value, int size)
> +{
> +    uint8_t prefix;
> +    int i;
> +
> +    switch (size) {
> +    case 1:
> +        prefix = 0x0A; /* BytePrefix */
> +        break;
> +    case 2:
> +        prefix = 0x0B; /* WordPrefix */
> +        break;
> +    case 4:
> +        prefix = 0x0C; /* DWordPrefix */
> +        break;
> +    default:
> +        assert(0);
> +        return;
> +    }
> +    build_append_byte(table, prefix);
> +    for (i = 0; i < size; ++i) {
> +        build_append_byte(table, value & 0xFF);
> +        value = value >> 8;
> +    }
> +}
> +
> +void build_append_int(GArray *table, uint32_t value)
> +{
> +    if (value == 0x00) {
> +        build_append_byte(table, 0x00); /* ZeroOp */
> +    } else if (value == 0x01) {
> +        build_append_byte(table, 0x01); /* OneOp */
> +    } else if (value <= 0xFF) {
> +        build_append_value(table, value, 1);
> +    } else if (value <= 0xFFFF) {
> +        build_append_value(table, value, 2);
> +    } else {
> +        build_append_value(table, value, 4);
> +    }
> +}
> +
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 4c0536f..8ee15ab 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -54,6 +54,8 @@
>  #include "hw/i386/q35-acpi-dsdt.hex"
>  #include "hw/i386/acpi-dsdt.hex"
>  
> +#include "hw/acpi/acpi-build-utils.h"
> +
>  #include "qapi/qmp/qint.h"
>  #include "qom/qom-qobject.h"
>  #include "exec/ram_addr.h"
> @@ -277,166 +279,6 @@ build_header(GArray *linker, GArray *table_data,
>                                      table_data->data, h, len, &h->checksum);
>  }
>  
> -static inline GArray *build_alloc_array(void)
> -{
> -    return g_array_new(false, true /* clear */, 1);
> -}
> -
> -static inline void build_free_array(GArray *array)
> -{
> -    g_array_free(array, true);
> -}
> -
> -static inline void build_prepend_byte(GArray *array, uint8_t val)
> -{
> -    g_array_prepend_val(array, val);
> -}
> -
> -static inline void build_append_byte(GArray *array, uint8_t val)
> -{
> -    g_array_append_val(array, val);
> -}
> -
> -static inline void build_append_array(GArray *array, GArray *val)
> -{
> -    g_array_append_vals(array, val->data, val->len);
> -}
> -
> -#define ACPI_NAMESEG_LEN 4
> -
> -static void GCC_FMT_ATTR(2, 3)
> -build_append_nameseg(GArray *array, const char *format, ...)
> -{
> -    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> -    char s[] = "XXXX";
> -    int len;
> -    va_list args;
> -
> -    va_start(args, format);
> -    len = vsnprintf(s, sizeof s, format, args);
> -    va_end(args);
> -
> -    assert(len <= ACPI_NAMESEG_LEN);
> -
> -    g_array_append_vals(array, s, len);
> -    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
> -    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
> -}
> -
> -/* 5.4 Definition Block Encoding */
> -enum {
> -    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
> -    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
> -    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
> -    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
> -};
> -
> -static void build_prepend_package_length(GArray *package, unsigned min_bytes)
> -{
> -    uint8_t byte;
> -    unsigned length = package->len;
> -    unsigned length_bytes;
> -
> -    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
> -        length_bytes = 1;
> -    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
> -        length_bytes = 2;
> -    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
> -        length_bytes = 3;
> -    } else {
> -        length_bytes = 4;
> -    }
> -
> -    /* Force length to at least min_bytes.
> -     * This wastes memory but that's how bios did it.
> -     */
> -    length_bytes = MAX(length_bytes, min_bytes);
> -
> -    /* PkgLength is the length of the inclusive length of the data. */
> -    length += length_bytes;
> -
> -    switch (length_bytes) {
> -    case 1:
> -        byte = length;
> -        build_prepend_byte(package, byte);
> -        return;
> -    case 4:
> -        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
> -        build_prepend_byte(package, byte);
> -        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
> -        /* fall through */
> -    case 3:
> -        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
> -        build_prepend_byte(package, byte);
> -        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
> -        /* fall through */
> -    case 2:
> -        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
> -        build_prepend_byte(package, byte);
> -        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
> -        /* fall through */
> -    }
> -    /*
> -     * Most significant two bits of byte zero indicate how many following bytes
> -     * are in PkgLength encoding.
> -     */
> -    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
> -    build_prepend_byte(package, byte);
> -}
> -
> -static void build_package(GArray *package, uint8_t op, unsigned min_bytes)
> -{
> -    build_prepend_package_length(package, min_bytes);
> -    build_prepend_byte(package, op);
> -}
> -
> -static void build_extop_package(GArray *package, uint8_t op)
> -{
> -    build_package(package, op, 1);
> -    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
> -}
> -
> -static void build_append_value(GArray *table, uint32_t value, int size)
> -{
> -    uint8_t prefix;
> -    int i;
> -
> -    switch (size) {
> -    case 1:
> -        prefix = 0x0A; /* BytePrefix */
> -        break;
> -    case 2:
> -        prefix = 0x0B; /* WordPrefix */
> -        break;
> -    case 4:
> -        prefix = 0x0C; /* DWordPrefix */
> -        break;
> -    default:
> -        assert(0);
> -        return;
> -    }
> -    build_append_byte(table, prefix);
> -    for (i = 0; i < size; ++i) {
> -        build_append_byte(table, value & 0xFF);
> -        value = value >> 8;
> -    }
> -}
> -
> -static void build_append_int(GArray *table, uint32_t value)
> -{
> -    if (value == 0x00) {
> -        build_append_byte(table, 0x00); /* ZeroOp */
> -    } else if (value == 0x01) {
> -        build_append_byte(table, 0x01); /* OneOp */
> -    } else if (value <= 0xFF) {
> -        build_append_value(table, value, 1);
> -    } else if (value <= 0xFFFF) {
> -        build_append_value(table, value, 2);
> -    } else {
> -        build_append_value(table, value, 4);
> -    }
> -}
> -
>  static GArray *build_alloc_method(const char *name, uint8_t arg_count)
>  {
>      GArray *method = build_alloc_array();
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> new file mode 100644
> index 0000000..e6a0b28
> --- /dev/null
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -0,0 +1,23 @@
> +#ifndef HW_ACPI_GEN_UTILS_H
> +#define HW_ACPI_GEN_UTILS_H
> +
> +#include <stdint.h>
> +#include <glib.h>
> +#include "qemu/compiler.h"
> +
> +GArray *build_alloc_array(void);
> +void build_free_array(GArray *array);
> +void build_prepend_byte(GArray *array, uint8_t val);
> +void build_append_byte(GArray *array, uint8_t val);
> +void build_append_array(GArray *array, GArray *val);
> +
> +void GCC_FMT_ATTR(2, 3)
> +build_append_nameseg(GArray *array, const char *format, ...);
> +
> +void build_prepend_package_length(GArray *package, unsigned min_bytes);
> +void build_package(GArray *package, uint8_t op, unsigned min_bytes);
> +void build_append_value(GArray *table, uint32_t value, int size);
> +void build_append_int(GArray *table, uint32_t value);
> +void build_extop_package(GArray *package, uint8_t op);
> +
> +#endif
> -- 
> 1.8.3.1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file
  2015-01-27 12:23   ` Michael S. Tsirkin
@ 2015-01-28 12:34     ` Igor Mammedov
  0 siblings, 0 replies; 13+ messages in thread
From: Igor Mammedov @ 2015-01-28 12:34 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel, marcel.a

On Tue, 27 Jan 2015 14:23:18 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 21, 2015 at 09:09:10AM +0000, Igor Mammedov wrote:
> > the will be later used for composing AML primitives
> > and all that could be reused later for ARM machines
> > as well.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> OK so the only thing holding this up is really that
> you have indicated that in the follow-up patches
> you want to add here more stuff with
> aml_ prefix instead of acpi_.
> 
> In that case let's name this file aml-build.c?
sure, I'll rename it.

> 
> 
> > ---
> > v3:
> >   * rename acpi_gen_utils.[ch] to acpi-build-utils.[ch]
> >   * copy GLP license block from acpi-build.c
> > v2:
> >   * fix wrong ident in moved code
> > ---
> >  hw/acpi/Makefile.objs              |   1 +
> >  hw/acpi/acpi-build-utils.c         | 187 +++++++++++++++++++++++++++++++++++++
> >  hw/i386/acpi-build.c               | 162 +-------------------------------
> >  include/hw/acpi/acpi-build-utils.h |  23 +++++
> >  4 files changed, 213 insertions(+), 160 deletions(-)
> >  create mode 100644 hw/acpi/acpi-build-utils.c
> >  create mode 100644 include/hw/acpi/acpi-build-utils.h
> > 
> > diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
> > index ee82073..cad0355 100644
> > --- a/hw/acpi/Makefile.objs
> > +++ b/hw/acpi/Makefile.objs
> > @@ -2,3 +2,4 @@ common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
> >  common-obj-$(CONFIG_ACPI) += memory_hotplug.o
> >  common-obj-$(CONFIG_ACPI) += acpi_interface.o
> >  common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
> > +common-obj-$(CONFIG_ACPI) += acpi-build-utils.o
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > new file mode 100644
> > index 0000000..79aa610
> > --- /dev/null
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -0,0 +1,187 @@
> > +/* Support for generating ACPI tables and passing them to Guests
> > + *
> > + * Copyright (C) 2014 Red Hat Inc
> > + *
> > + * Author: Michael S. Tsirkin <mst@redhat.com>
> > + * Author: Igor Mammedov <imammedo@redhat.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > +
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > +
> > + * You should have received a copy of the GNU General Public License along
> > + * with this program; if not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#include <stdio.h>
> > +#include <stdarg.h>
> > +#include <assert.h>
> > +#include <stdbool.h>
> > +#include "hw/acpi/acpi-build-utils.h"
> > +
> > +GArray *build_alloc_array(void)
> > +{
> > +    return g_array_new(false, true /* clear */, 1);
> > +}
> > +
> > +void build_free_array(GArray *array)
> > +{
> > +    g_array_free(array, true);
> > +}
> > +
> > +void build_prepend_byte(GArray *array, uint8_t val)
> > +{
> > +    g_array_prepend_val(array, val);
> > +}
> > +
> > +void build_append_byte(GArray *array, uint8_t val)
> > +{
> > +    g_array_append_val(array, val);
> > +}
> > +
> > +void build_append_array(GArray *array, GArray *val)
> > +{
> > +    g_array_append_vals(array, val->data, val->len);
> > +}
> > +
> > +#define ACPI_NAMESEG_LEN 4
> > +
> > +void GCC_FMT_ATTR(2, 3)
> > +build_append_nameseg(GArray *array, const char *format, ...)
> > +{
> > +    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> > +    char s[] = "XXXX";
> > +    int len;
> > +    va_list args;
> > +
> > +    va_start(args, format);
> > +    len = vsnprintf(s, sizeof s, format, args);
> > +    va_end(args);
> > +
> > +    assert(len <= ACPI_NAMESEG_LEN);
> > +
> > +    g_array_append_vals(array, s, len);
> > +    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
> > +    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
> > +}
> > +
> > +/* 5.4 Definition Block Encoding */
> > +enum {
> > +    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
> > +    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
> > +    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
> > +    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
> > +};
> > +
> > +void build_prepend_package_length(GArray *package, unsigned min_bytes)
> > +{
> > +    uint8_t byte;
> > +    unsigned length = package->len;
> > +    unsigned length_bytes;
> > +
> > +    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
> > +        length_bytes = 1;
> > +    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
> > +        length_bytes = 2;
> > +    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
> > +        length_bytes = 3;
> > +    } else {
> > +        length_bytes = 4;
> > +    }
> > +
> > +    /* Force length to at least min_bytes.
> > +     * This wastes memory but that's how bios did it.
> > +     */
> > +    length_bytes = MAX(length_bytes, min_bytes);
> > +
> > +    /* PkgLength is the length of the inclusive length of the data. */
> > +    length += length_bytes;
> > +
> > +    switch (length_bytes) {
> > +    case 1:
> > +        byte = length;
> > +        build_prepend_byte(package, byte);
> > +        return;
> > +    case 4:
> > +        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
> > +        build_prepend_byte(package, byte);
> > +        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
> > +        /* fall through */
> > +    case 3:
> > +        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
> > +        build_prepend_byte(package, byte);
> > +        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
> > +        /* fall through */
> > +    case 2:
> > +        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
> > +        build_prepend_byte(package, byte);
> > +        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
> > +        /* fall through */
> > +    }
> > +    /*
> > +     * Most significant two bits of byte zero indicate how many following bytes
> > +     * are in PkgLength encoding.
> > +     */
> > +    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
> > +    build_prepend_byte(package, byte);
> > +}
> > +
> > +void build_package(GArray *package, uint8_t op, unsigned min_bytes)
> > +{
> > +    build_prepend_package_length(package, min_bytes);
> > +    build_prepend_byte(package, op);
> > +}
> > +
> > +void build_extop_package(GArray *package, uint8_t op)
> > +{
> > +    build_package(package, op, 1);
> > +    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
> > +}
> > +
> > +void build_append_value(GArray *table, uint32_t value, int size)
> > +{
> > +    uint8_t prefix;
> > +    int i;
> > +
> > +    switch (size) {
> > +    case 1:
> > +        prefix = 0x0A; /* BytePrefix */
> > +        break;
> > +    case 2:
> > +        prefix = 0x0B; /* WordPrefix */
> > +        break;
> > +    case 4:
> > +        prefix = 0x0C; /* DWordPrefix */
> > +        break;
> > +    default:
> > +        assert(0);
> > +        return;
> > +    }
> > +    build_append_byte(table, prefix);
> > +    for (i = 0; i < size; ++i) {
> > +        build_append_byte(table, value & 0xFF);
> > +        value = value >> 8;
> > +    }
> > +}
> > +
> > +void build_append_int(GArray *table, uint32_t value)
> > +{
> > +    if (value == 0x00) {
> > +        build_append_byte(table, 0x00); /* ZeroOp */
> > +    } else if (value == 0x01) {
> > +        build_append_byte(table, 0x01); /* OneOp */
> > +    } else if (value <= 0xFF) {
> > +        build_append_value(table, value, 1);
> > +    } else if (value <= 0xFFFF) {
> > +        build_append_value(table, value, 2);
> > +    } else {
> > +        build_append_value(table, value, 4);
> > +    }
> > +}
> > +
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 4c0536f..8ee15ab 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -54,6 +54,8 @@
> >  #include "hw/i386/q35-acpi-dsdt.hex"
> >  #include "hw/i386/acpi-dsdt.hex"
> >  
> > +#include "hw/acpi/acpi-build-utils.h"
> > +
> >  #include "qapi/qmp/qint.h"
> >  #include "qom/qom-qobject.h"
> >  #include "exec/ram_addr.h"
> > @@ -277,166 +279,6 @@ build_header(GArray *linker, GArray *table_data,
> >                                      table_data->data, h, len, &h->checksum);
> >  }
> >  
> > -static inline GArray *build_alloc_array(void)
> > -{
> > -    return g_array_new(false, true /* clear */, 1);
> > -}
> > -
> > -static inline void build_free_array(GArray *array)
> > -{
> > -    g_array_free(array, true);
> > -}
> > -
> > -static inline void build_prepend_byte(GArray *array, uint8_t val)
> > -{
> > -    g_array_prepend_val(array, val);
> > -}
> > -
> > -static inline void build_append_byte(GArray *array, uint8_t val)
> > -{
> > -    g_array_append_val(array, val);
> > -}
> > -
> > -static inline void build_append_array(GArray *array, GArray *val)
> > -{
> > -    g_array_append_vals(array, val->data, val->len);
> > -}
> > -
> > -#define ACPI_NAMESEG_LEN 4
> > -
> > -static void GCC_FMT_ATTR(2, 3)
> > -build_append_nameseg(GArray *array, const char *format, ...)
> > -{
> > -    /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
> > -    char s[] = "XXXX";
> > -    int len;
> > -    va_list args;
> > -
> > -    va_start(args, format);
> > -    len = vsnprintf(s, sizeof s, format, args);
> > -    va_end(args);
> > -
> > -    assert(len <= ACPI_NAMESEG_LEN);
> > -
> > -    g_array_append_vals(array, s, len);
> > -    /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
> > -    g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
> > -}
> > -
> > -/* 5.4 Definition Block Encoding */
> > -enum {
> > -    PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
> > -    PACKAGE_LENGTH_2BYTE_SHIFT = 4,
> > -    PACKAGE_LENGTH_3BYTE_SHIFT = 12,
> > -    PACKAGE_LENGTH_4BYTE_SHIFT = 20,
> > -};
> > -
> > -static void build_prepend_package_length(GArray *package, unsigned min_bytes)
> > -{
> > -    uint8_t byte;
> > -    unsigned length = package->len;
> > -    unsigned length_bytes;
> > -
> > -    if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
> > -        length_bytes = 1;
> > -    } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
> > -        length_bytes = 2;
> > -    } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
> > -        length_bytes = 3;
> > -    } else {
> > -        length_bytes = 4;
> > -    }
> > -
> > -    /* Force length to at least min_bytes.
> > -     * This wastes memory but that's how bios did it.
> > -     */
> > -    length_bytes = MAX(length_bytes, min_bytes);
> > -
> > -    /* PkgLength is the length of the inclusive length of the data. */
> > -    length += length_bytes;
> > -
> > -    switch (length_bytes) {
> > -    case 1:
> > -        byte = length;
> > -        build_prepend_byte(package, byte);
> > -        return;
> > -    case 4:
> > -        byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
> > -        build_prepend_byte(package, byte);
> > -        length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
> > -        /* fall through */
> > -    case 3:
> > -        byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
> > -        build_prepend_byte(package, byte);
> > -        length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
> > -        /* fall through */
> > -    case 2:
> > -        byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
> > -        build_prepend_byte(package, byte);
> > -        length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
> > -        /* fall through */
> > -    }
> > -    /*
> > -     * Most significant two bits of byte zero indicate how many following bytes
> > -     * are in PkgLength encoding.
> > -     */
> > -    byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
> > -    build_prepend_byte(package, byte);
> > -}
> > -
> > -static void build_package(GArray *package, uint8_t op, unsigned min_bytes)
> > -{
> > -    build_prepend_package_length(package, min_bytes);
> > -    build_prepend_byte(package, op);
> > -}
> > -
> > -static void build_extop_package(GArray *package, uint8_t op)
> > -{
> > -    build_package(package, op, 1);
> > -    build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
> > -}
> > -
> > -static void build_append_value(GArray *table, uint32_t value, int size)
> > -{
> > -    uint8_t prefix;
> > -    int i;
> > -
> > -    switch (size) {
> > -    case 1:
> > -        prefix = 0x0A; /* BytePrefix */
> > -        break;
> > -    case 2:
> > -        prefix = 0x0B; /* WordPrefix */
> > -        break;
> > -    case 4:
> > -        prefix = 0x0C; /* DWordPrefix */
> > -        break;
> > -    default:
> > -        assert(0);
> > -        return;
> > -    }
> > -    build_append_byte(table, prefix);
> > -    for (i = 0; i < size; ++i) {
> > -        build_append_byte(table, value & 0xFF);
> > -        value = value >> 8;
> > -    }
> > -}
> > -
> > -static void build_append_int(GArray *table, uint32_t value)
> > -{
> > -    if (value == 0x00) {
> > -        build_append_byte(table, 0x00); /* ZeroOp */
> > -    } else if (value == 0x01) {
> > -        build_append_byte(table, 0x01); /* OneOp */
> > -    } else if (value <= 0xFF) {
> > -        build_append_value(table, value, 1);
> > -    } else if (value <= 0xFFFF) {
> > -        build_append_value(table, value, 2);
> > -    } else {
> > -        build_append_value(table, value, 4);
> > -    }
> > -}
> > -
> >  static GArray *build_alloc_method(const char *name, uint8_t arg_count)
> >  {
> >      GArray *method = build_alloc_array();
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > new file mode 100644
> > index 0000000..e6a0b28
> > --- /dev/null
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -0,0 +1,23 @@
> > +#ifndef HW_ACPI_GEN_UTILS_H
> > +#define HW_ACPI_GEN_UTILS_H
> > +
> > +#include <stdint.h>
> > +#include <glib.h>
> > +#include "qemu/compiler.h"
> > +
> > +GArray *build_alloc_array(void);
> > +void build_free_array(GArray *array);
> > +void build_prepend_byte(GArray *array, uint8_t val);
> > +void build_append_byte(GArray *array, uint8_t val);
> > +void build_append_array(GArray *array, GArray *val);
> > +
> > +void GCC_FMT_ATTR(2, 3)
> > +build_append_nameseg(GArray *array, const char *format, ...);
> > +
> > +void build_prepend_package_length(GArray *package, unsigned min_bytes);
> > +void build_package(GArray *package, uint8_t op, unsigned min_bytes);
> > +void build_append_value(GArray *table, uint32_t value, int size);
> > +void build_append_int(GArray *table, uint32_t value);
> > +void build_extop_package(GArray *package, uint8_t op);
> > +
> > +#endif
> > -- 
> > 1.8.3.1
> > 
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-01-28 12:34 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-21  9:09 [Qemu-devel] [PATCH v5 0/5] pc: acpi: various fixes and cleanups Igor Mammedov
2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 1/5] pc: acpi-build: cleanup AcpiPmInfo initialization Igor Mammedov
2015-01-21  9:11   ` Marcel Apfelbaum
2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 2/5] acpi: move generic aml building helpers into dedictated file Igor Mammedov
2015-01-21  9:13   ` Marcel Apfelbaum
2015-01-27 12:23   ` Michael S. Tsirkin
2015-01-28 12:34     ` Igor Mammedov
2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 3/5] acpi: add build_append_namestring() helper Igor Mammedov
2015-01-21  9:22   ` Marcel Apfelbaum
2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 4/5] acpi: drop min-bytes in build_package() Igor Mammedov
2015-01-21  9:25   ` Marcel Apfelbaum
2015-01-21  9:09 ` [Qemu-devel] [PATCH v5 5/5] pc: acpi-build: simplify PCI bus tree generation Igor Mammedov
2015-01-21  9:51   ` Marcel Apfelbaum

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.