All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API
@ 2015-01-22 14:49 Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Igor Mammedov
                   ` (47 more replies)
  0 siblings, 48 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

changes since RFC:
  * conflicts with vmgenid (broken) patches, so it's not based on PCI tree
  * rebased on top of today's master +
    [PATCH v5 0/5] pc: acpi: various fixes and cleanups +
    some patches from PCI tree that above series depends on
  * small cleanups
  * droped [42/47] acpi: make tables linker-loader available to other targets
    since Michael has a cleaner similar patch(es) in PCI tree,
    so reuse them (not included in here)
  * move SMC device from DSDT to SSDT and create it only when
    applesmc device is present.


This series refactors SSDT runtime composing and gets rid of:
    * patching AML templates, with related pointer arithmetic magic
    * manual AML composition, i.e. creating AML terms practically
      byte by byte
    * using AML templates for SSDT creation, reducing dependency on IASL.
      as result of above, QEMU source tree doesn't have to carry
      'binary' template blobs that used to be part of SSDT.
    * hand-crafted PCI0._CRSes for pc/q35 machines in DSDT with
      manual hole punching of reserved resources
and adds following:
    * introduces ASL like API for creating AML objects using ASL
      like constructs/terms. API: 
          * provides a necessary minimum set of terms/helpers to
            replace currently used SSDT templates.
          * simplifies AML composition and keeps track of AML
            object contexts, transparently managing their 
            (de)allocation and merging into parent context,
            making composition of SSDT 'almost' like writing
            native ASL definition of the table.
          * hides pointer arithmetic from user when composing
            SSDT.
    * dynamically creates unified PCI0._CRS in SSDT for pc/q35
      machines allowing to reserve resources at runtime vs
      current compile time
    * while adding new API, make it target independed CONFIG_ACPI
      and also make some other utilities for composing ACPI tables
      target independed (i.e. utils on which API depends) so that
      they could be reused for ARM target later without moving
      stuff around uncessarily.
    * trims SSDT by not creating objects that are not present
      (S[34] Package if disabled, pvpanic, applesmc)

As result of replacing AML templates with ASL API, codebase
reduces on ~1800LOC even with net addition of API 1050LOC counted in.


Tested with XPsp3, WS2012R2, RHEL6/7 guests. 

Git tree for playing with:
    https://github.com/imammedo/qemu/commits/ASL_API_v2

Igor Mammedov (47):
  acpi: introduce AML composer aml_append()
  acpi: add acpi_scope() term
  acpi: add acpi_device() term
  acpi: add acpi_method() term
  acpi: add acpi_if() term
  acpi: add acpi_name() & acpi_name_decl() term
  acpi: factor out ACPI const int packing out build_append_value()
  acpi: extend build_append_{value|int}() to support 64-bit values
  acpi: add acpi_int() term
  acpi: add acpi_return() term
  acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms
  acpi: add acpi_store() term
  acpi: add acpi_and() term
  acpi: add acpi_notify() term
  acpi: add acpi_call1(), acpi_call2(), acpi_call3(), acpi_call4()
    helpers
  pc: acpi-build: drop template patching and create PCI bus tree
    dynamically
  acpi: add acpi_package() term
  pc: acpi-build: drop unsupported PM1b_CNT.SLP_TYP
  pc: acpi-build: generate _S[345] packages dynamically
  acpi: add acpi_buffer() term
  acpi: add acpi_resource_template() helper
  acpi: add acpi_io() helper
  acpi: include PkgLength size only when requested
  acpi: add acpi_operation_region() term
  acpi: add acpi_field() & acpi_named_field() terms
  acpi: add acpi_local0() term
  acpi: add acpi_string() term
  pc: acpi-build: generate pvpanic device description dynamically
  acpi: add acpi_varpackage() term
  acpi: add acpi_equal() term
  acpi: add acpi_processor() term
  acpi: add acpi_eisaid() term
  pc: acpi-build: drop template patching and CPU hotplug objects
    dynamically
  pc: acpi-build: create CPU hotplug IO region dynamically
  acpi: add acpi_reserved_field() term
  pc: acpi-build: drop template patching and memory hotplug objects
    dynamically
  pc: acpi-build: create memory hotplug IO region dynamically
  acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(),
    acpi_qword_memory() terms
  pc: pcihp: expose MMIO base and len as properties
  pc: acpi-build: reserve PCIHP MMIO resources
  pc: acpi-build: create PCI0._CRS dynamically
  acpi: add acpi_def_block() term
  pc: acpi-build: prepare to make ACPI tables blob opaque for table
    building functions
  pc: acpi-build: drop remaining ssdt_misc template and use
    acpi_def_block()
  acpi: add acpi_iqr_no_flags() term
  pc: export applesmc IO port/len
  pc: acpi-build: drop template patching and create Device(SMC)
    dynamically

 hw/acpi/acpi-build-utils.c         | 689 +++++++++++++++++++++++++++++--
 hw/acpi/pcihp.c                    |  18 +-
 hw/acpi/piix4.c                    |   2 +-
 hw/i386/Makefile.objs              |   4 +-
 hw/i386/acpi-build.c               | 824 +++++++++++++++++++------------------
 hw/i386/acpi-dsdt-cpu-hotplug.dsl  |  17 +-
 hw/i386/acpi-dsdt-isa.dsl          |  11 -
 hw/i386/acpi-dsdt-mem-hotplug.dsl  |  36 +-
 hw/i386/acpi-dsdt-pci-crs.dsl      |  92 -----
 hw/i386/acpi-dsdt.dsl              |  45 --
 hw/i386/q35-acpi-dsdt.dsl          |  18 -
 hw/i386/ssdt-mem.dsl               |  77 ----
 hw/i386/ssdt-mem.hex.generated     | 213 ----------
 hw/i386/ssdt-misc.dsl              | 122 ------
 hw/i386/ssdt-misc.hex.generated    | 399 ------------------
 hw/i386/ssdt-pcihp.dsl             | 100 -----
 hw/i386/ssdt-pcihp.hex.generated   | 251 -----------
 hw/i386/ssdt-proc.dsl              |  63 ---
 hw/i386/ssdt-proc.hex.generated    | 134 ------
 hw/misc/applesmc.c                 |   5 +-
 include/hw/acpi/acpi-build-utils.h | 168 +++++++-
 include/hw/acpi/pc-hotplug.h       |   1 +
 include/hw/acpi/pcihp.h            |   7 +-
 include/hw/isa/isa.h               |  11 +-
 24 files changed, 1304 insertions(+), 2003 deletions(-)
 delete mode 100644 hw/i386/acpi-dsdt-pci-crs.dsl
 delete mode 100644 hw/i386/ssdt-mem.dsl
 delete mode 100644 hw/i386/ssdt-mem.hex.generated
 delete mode 100644 hw/i386/ssdt-misc.dsl
 delete mode 100644 hw/i386/ssdt-misc.hex.generated
 delete mode 100644 hw/i386/ssdt-pcihp.dsl
 delete mode 100644 hw/i386/ssdt-pcihp.hex.generated
 delete mode 100644 hw/i386/ssdt-proc.dsl
 delete mode 100644 hw/i386/ssdt-proc.hex.generated

-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-23  8:03   ` Michael S. Tsirkin
                     ` (2 more replies)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 02/47] acpi: add acpi_scope() term Igor Mammedov
                   ` (46 subsequent siblings)
  47 siblings, 3 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Adds for dynamic AML creation, which will be used
for piecing ASL/AML primitives together and hiding
from user/caller details about how nested context
should be closed/packed leaving less space for
mistakes and necessity to know how AML should be
encoded, allowing user to concentrate on ASL
representation instead.

For example it will allow to create AML like this:

AcpiAml scope = acpi_scope("PCI0")
AcpiAml dev = acpi_device("PM")
    aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
aml_append(&scope, dev);

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 602e68c..547ecaa 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
         build_append_value(table, value, 4);
     }
 }
+
+static void build_prepend_int(GArray *array, uint32_t value)
+{
+    GArray *data = build_alloc_array();
+
+    build_append_int(data, value);
+    g_array_prepend_vals(array, data->data, data->len);
+    build_free_array(data);
+}
+
+void aml_append(AcpiAml *parent_ctx, AcpiAml child)
+{
+    switch (child.block_flags) {
+    case EXT_PACKAGE:
+        build_extop_package(child.buf, child.op);
+        break;
+
+    case PACKAGE:
+        build_package(child.buf, child.op);
+        break;
+
+    case RES_TEMPLATE:
+        build_append_byte(child.buf, 0x79); /* EndTag */
+        /*
+         * checksum operations is treated as succeeded if checksum
+         * field is zero. [ACPI Spec 5.0, 6.4.2.9 End Tag]
+         */
+        build_append_byte(child.buf, 0);
+        /* fall through, to pack resources in buffer */
+    case BUFFER:
+        build_prepend_int(child.buf, child.buf->len);
+        build_package(child.buf, child.op);
+        break;
+    default:
+        break;
+    }
+    build_append_array(parent_ctx->buf, child.buf);
+    build_free_array(child.buf);
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 199f003..64e7ec3 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -5,6 +5,22 @@
 #include <glib.h>
 #include "qemu/compiler.h"
 
+typedef enum {
+    NON_BLOCK,
+    PACKAGE,
+    EXT_PACKAGE,
+    BUFFER,
+    RES_TEMPLATE,
+} AcpiBlockFlags;
+
+typedef struct AcpiAml {
+    GArray *buf;
+    uint8_t op;
+    AcpiBlockFlags block_flags;
+} AcpiAml;
+
+void aml_append(AcpiAml *parent_ctx, AcpiAml child);
+
 GArray *build_alloc_array(void);
 void build_free_array(GArray *array);
 void build_prepend_byte(GArray *array, uint8_t val);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 02/47] acpi: add acpi_scope() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-23  8:02   ` Michael S. Tsirkin
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 03/47] acpi: add acpi_device() term Igor Mammedov
                   ` (45 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 18 ++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  4 ++++
 2 files changed, 22 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 547ecaa..e13d748 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -306,3 +306,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
     build_append_array(parent_ctx->buf, child.buf);
     build_free_array(child.buf);
 }
+
+static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
+{
+    AcpiAml var = { .op = op, .block_flags = flags };
+    var.buf = build_alloc_array();
+    return var;
+}
+
+/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefScope */
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...)
+{
+    va_list ap;
+    AcpiAml var = aml_allocate_internal(0x10 /* ScopeOp */, PACKAGE);
+    va_start(ap, name_format);
+    build_append_namestringv(var.buf, name_format, ap);
+    va_end(ap);
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 64e7ec3..bbb786b 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -21,6 +21,10 @@ typedef struct AcpiAml {
 
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
+/* Block ASL object primitives */
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
+
+/* other helpers */
 GArray *build_alloc_array(void);
 void build_free_array(GArray *array);
 void build_prepend_byte(GArray *array, uint8_t val);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 03/47] acpi: add acpi_device() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 02/47] acpi: add acpi_scope() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 04/47] acpi: add acpi_method() term Igor Mammedov
                   ` (44 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 11 +++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index e13d748..289f1e3 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -324,3 +324,14 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...)
     va_end(ap);
     return var;
 }
+
+/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefDevice */
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...)
+{
+    va_list ap;
+    AcpiAml var = aml_allocate_internal(0x82 /* DeviceOp */, EXT_PACKAGE);
+    va_start(ap, name_format);
+    build_append_namestringv(var.buf, name_format, ap);
+    va_end(ap);
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index bbb786b..56165e6 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -23,6 +23,7 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* Block ASL object primitives */
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
 
 /* other helpers */
 GArray *build_alloc_array(void);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 04/47] acpi: add acpi_method() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (2 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 03/47] acpi: add acpi_device() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 05/47] acpi: add acpi_if() term Igor Mammedov
                   ` (43 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 9 +++++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 289f1e3..d0b0159 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -314,6 +314,15 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefMethod */
+AcpiAml acpi_method(const char *name, int arg_count)
+{
+    AcpiAml var = aml_allocate_internal(0x14 /* MethodOp */, PACKAGE);
+    build_append_namestring(var.buf, "%s", name);
+    build_append_byte(var.buf, arg_count); /* MethodFlags: ArgCount */
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefScope */
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 56165e6..19ebc2d 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -22,6 +22,7 @@ typedef struct AcpiAml {
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* Block ASL object primitives */
+AcpiAml acpi_method(const char *name, int arg_count);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 05/47] acpi: add acpi_if() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (3 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 04/47] acpi: add acpi_method() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-02-05 15:01   ` Marcel Apfelbaum
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term Igor Mammedov
                   ` (42 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 8 ++++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index d0b0159..40a1769 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -314,6 +314,14 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
+AcpiAml acpi_if(AcpiAml predicate)
+{
+    AcpiAml var = aml_allocate_internal(0xA0 /* IfOp */, PACKAGE);
+    aml_append(&var, predicate);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefMethod */
 AcpiAml acpi_method(const char *name, int arg_count)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 19ebc2d..177f9ed 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -22,6 +22,7 @@ typedef struct AcpiAml {
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* Block ASL object primitives */
+AcpiAml acpi_if(AcpiAml predicate);
 AcpiAml acpi_method(const char *name, int arg_count);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (4 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 05/47] acpi: add acpi_if() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-23  8:59   ` Michael S. Tsirkin
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 07/47] acpi: factor out ACPI const int packing out build_append_value() Igor Mammedov
                   ` (41 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 24 ++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  3 +++
 2 files changed, 27 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 40a1769..1bda2ec 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -314,6 +314,30 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
     return var;
 }
 
+/*
+ * help to construct NameString, which return AcpiAml object
+ * for using with other aml_append or other acpi_* terms
+ */
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...)
+{
+    va_list ap;
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    va_start(ap, name_format);
+    build_append_namestringv(var.buf, name_format, ap);
+    va_end(ap);
+    return var;
+}
+
+/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */
+AcpiAml acpi_name_decl(const char *name, AcpiAml val)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x08);
+    build_append_namestring(var.buf, "%s", name);
+    aml_append(&var, val);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 177f9ed..868cfa5 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -21,6 +21,9 @@ typedef struct AcpiAml {
 
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
+/* non block ASL object primitives */
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
+AcpiAml acpi_name_decl(const char *name, AcpiAml val);
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
 AcpiAml acpi_method(const char *name, int arg_count);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 07/47] acpi: factor out ACPI const int packing out build_append_value()
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (5 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 08/47] acpi: extend build_append_{value|int}() to support 64-bit values Igor Mammedov
                   ` (40 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

it will be reused for adding a plain integer
value into AML.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 1bda2ec..be036b4 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -229,24 +229,8 @@ void build_extop_package(GArray *package, uint8_t op)
 
 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;
@@ -260,10 +244,13 @@ void build_append_int(GArray *table, uint32_t value)
     } else if (value == 0x01) {
         build_append_byte(table, 0x01); /* OneOp */
     } else if (value <= 0xFF) {
+        build_append_byte(table, 0x0A); /* BytePrefix */
         build_append_value(table, value, 1);
     } else if (value <= 0xFFFF) {
+        build_append_byte(table, 0x0B); /* WordPrefix */
         build_append_value(table, value, 2);
     } else {
+        build_append_byte(table, 0x0C); /* DWordPrefix */
         build_append_value(table, value, 4);
     }
 }
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 08/47] acpi: extend build_append_{value|int}() to support 64-bit values
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (6 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 07/47] acpi: factor out ACPI const int packing out build_append_value() Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 09/47] acpi: add acpi_int() term Igor Mammedov
                   ` (39 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

it will be used for generating 64bit _CRS entries

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 9 ++++++---
 include/hw/acpi/acpi-build-utils.h | 4 ++--
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index be036b4..b68e1d8 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -227,7 +227,7 @@ void build_extop_package(GArray *package, uint8_t op)
     build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
 }
 
-void build_append_value(GArray *table, uint32_t value, int size)
+void build_append_value(GArray *table, uint64_t value, int size)
 {
     int i;
 
@@ -237,7 +237,7 @@ void build_append_value(GArray *table, uint32_t value, int size)
     }
 }
 
-void build_append_int(GArray *table, uint32_t value)
+void build_append_int(GArray *table, uint64_t value)
 {
     if (value == 0x00) {
         build_append_byte(table, 0x00); /* ZeroOp */
@@ -249,9 +249,12 @@ void build_append_int(GArray *table, uint32_t value)
     } else if (value <= 0xFFFF) {
         build_append_byte(table, 0x0B); /* WordPrefix */
         build_append_value(table, value, 2);
-    } else {
+    } else if (value <= 0xFFFFFFFF) {
         build_append_byte(table, 0x0C); /* DWordPrefix */
         build_append_value(table, value, 4);
+    } else {
+        build_append_byte(table, 0x0E); /* QWordPrefix */
+        build_append_value(table, value, 8);
     }
 }
 
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 868cfa5..d21e107 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -42,8 +42,8 @@ build_append_namestring(GArray *array, const char *format, ...);
 
 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_append_value(GArray *table, uint64_t value, int size);
+void build_append_int(GArray *table, uint64_t value);
 void build_extop_package(GArray *package, uint8_t op);
 
 #endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 09/47] acpi: add acpi_int() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (7 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 08/47] acpi: extend build_append_{value|int}() to support 64-bit values Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 10/47] acpi: add acpi_return() term Igor Mammedov
                   ` (38 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 11 +++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index b68e1d8..745e58b 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -305,6 +305,17 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
 }
 
 /*
+ * ACPI 5.0: 20.2.3 Data Objects Encoding:
+ * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
+ */
+AcpiAml acpi_int(const uint64_t val)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_int(var.buf, val);
+    return var;
+}
+
+/*
  * help to construct NameString, which return AcpiAml object
  * for using with other aml_append or other acpi_* terms
  */
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index d21e107..2ea53f9 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -22,6 +22,7 @@ typedef struct AcpiAml {
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* non block ASL object primitives */
+AcpiAml acpi_int(const uint64_t val);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
 AcpiAml acpi_name_decl(const char *name, AcpiAml val);
 /* Block ASL object primitives */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 10/47] acpi: add acpi_return() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (8 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 09/47] acpi: add acpi_int() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms Igor Mammedov
                   ` (37 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 9 +++++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 745e58b..df5880f 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -304,6 +304,15 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefReturn */
+AcpiAml acpi_return(AcpiAml val)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0xA4); /* ReturnOp */
+    aml_append(&var, val);
+    return var;
+}
+
 /*
  * ACPI 5.0: 20.2.3 Data Objects Encoding:
  * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 2ea53f9..9e9ef1a 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -22,6 +22,7 @@ typedef struct AcpiAml {
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* non block ASL object primitives */
+AcpiAml acpi_return(AcpiAml val);
 AcpiAml acpi_int(const uint64_t val);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
 AcpiAml acpi_name_decl(const char *name, AcpiAml val);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (9 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 10/47] acpi: add acpi_return() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-23  8:32   ` Marcel Apfelbaum
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 12/47] acpi: add acpi_store() term Igor Mammedov
                   ` (36 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 32 ++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  5 +++++
 2 files changed, 37 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index df5880f..6e10712 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -348,6 +348,38 @@ AcpiAml acpi_name_decl(const char *name, AcpiAml val)
     return var;
 }
 
+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg0Op */
+AcpiAml acpi_arg0(void)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x68); /* ARG0 op */
+    return var;
+}
+
+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg1Op */
+AcpiAml acpi_arg1(void)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x69); /* ARG1 op */
+    return var;
+}
+
+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg2Op */
+AcpiAml acpi_arg2(void)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x6A); /* ARG2 op */
+    return var;
+}
+
+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg3Op */
+AcpiAml acpi_arg3(void)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x6B); /* ARG3 op */
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 9e9ef1a..18d9efa 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -26,6 +26,11 @@ AcpiAml acpi_return(AcpiAml val);
 AcpiAml acpi_int(const uint64_t val);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
 AcpiAml acpi_name_decl(const char *name, AcpiAml val);
+AcpiAml acpi_arg0(void);
+AcpiAml acpi_arg1(void);
+AcpiAml acpi_arg2(void);
+AcpiAml acpi_arg3(void);
+
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
 AcpiAml acpi_method(const char *name, int arg_count);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 12/47] acpi: add acpi_store() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (10 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-02-05 15:06   ` Marcel Apfelbaum
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 13/47] acpi: add acpi_and() term Igor Mammedov
                   ` (35 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 10 ++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 6e10712..d78d34f 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -380,6 +380,16 @@ AcpiAml acpi_arg3(void)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefStore */
+AcpiAml acpi_store(AcpiAml val, AcpiAml target)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x70); /* StoreOp */
+    aml_append(&var, val);
+    aml_append(&var, target);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 18d9efa..5d3651d 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -30,6 +30,7 @@ AcpiAml acpi_arg0(void);
 AcpiAml acpi_arg1(void);
 AcpiAml acpi_arg2(void);
 AcpiAml acpi_arg3(void);
+AcpiAml acpi_store(AcpiAml val, AcpiAml target);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 13/47] acpi: add acpi_and() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (11 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 12/47] acpi: add acpi_store() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 14/47] acpi: add acpi_notify() term Igor Mammedov
                   ` (34 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 11 +++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index d78d34f..a575ba1 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -390,6 +390,17 @@ AcpiAml acpi_store(AcpiAml val, AcpiAml target)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefAnd */
+AcpiAml acpi_and(AcpiAml arg1, AcpiAml arg2)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x7B); /* AndOp */
+    aml_append(&var, arg1);
+    aml_append(&var, arg2);
+    build_append_int(var.buf, 0x00); /* NullNameOp */
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 5d3651d..50bb1aa 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -31,6 +31,7 @@ AcpiAml acpi_arg1(void);
 AcpiAml acpi_arg2(void);
 AcpiAml acpi_arg3(void);
 AcpiAml acpi_store(AcpiAml val, AcpiAml target);
+AcpiAml acpi_and(AcpiAml arg1, AcpiAml arg2);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 14/47] acpi: add acpi_notify() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (12 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 13/47] acpi: add acpi_and() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 15/47] acpi: add acpi_call1(), acpi_call2(), acpi_call3(), acpi_call4() helpers Igor Mammedov
                   ` (33 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
  * remove not needed backslash
---
 hw/acpi/acpi-build-utils.c         | 10 ++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index a575ba1..253fa78 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -401,6 +401,16 @@ AcpiAml acpi_and(AcpiAml arg1, AcpiAml arg2)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefNotify */
+AcpiAml acpi_notify(AcpiAml arg1, AcpiAml arg2)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x86); /* NotifyOp */
+    aml_append(&var, arg1);
+    aml_append(&var, arg2);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 50bb1aa..1395b32 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -32,6 +32,7 @@ AcpiAml acpi_arg2(void);
 AcpiAml acpi_arg3(void);
 AcpiAml acpi_store(AcpiAml val, AcpiAml target);
 AcpiAml acpi_and(AcpiAml arg1, AcpiAml arg2);
+AcpiAml acpi_notify(AcpiAml arg1, AcpiAml arg2);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 15/47] acpi: add acpi_call1(), acpi_call2(), acpi_call3(), acpi_call4() helpers
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (13 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 14/47] acpi: add acpi_notify() term Igor Mammedov
@ 2015-01-22 14:49 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 16/47] pc: acpi-build: drop template patching and create PCI bus tree dynamically Igor Mammedov
                   ` (32 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 43 ++++++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  6 ++++++
 2 files changed, 49 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 253fa78..cbeb255 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -411,6 +411,49 @@ AcpiAml acpi_notify(AcpiAml arg1, AcpiAml arg2)
     return var;
 }
 
+/* helper to call method with 1 argument */
+AcpiAml acpi_call1(const char *method, AcpiAml arg1)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var.buf, "%s", method);
+    aml_append(&var, arg1);
+    return var;
+}
+
+/* helper to call method with 2 arguments */
+AcpiAml acpi_call2(const char *method, AcpiAml arg1, AcpiAml arg2)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var.buf, "%s", method);
+    aml_append(&var, arg1);
+    aml_append(&var, arg2);
+    return var;
+}
+
+/* helper to call method with 3 arguments */
+AcpiAml acpi_call3(const char *method, AcpiAml arg1, AcpiAml arg2, AcpiAml arg3)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var.buf, "%s", method);
+    aml_append(&var, arg1);
+    aml_append(&var, arg2);
+    aml_append(&var, arg3);
+    return var;
+}
+
+/* helper to call method with 4 arguments */
+AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
+                   AcpiAml arg3, AcpiAml arg4)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var.buf, "%s", method);
+    aml_append(&var, arg1);
+    aml_append(&var, arg2);
+    aml_append(&var, arg3);
+    aml_append(&var, arg4);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 1395b32..473589d 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -33,6 +33,12 @@ AcpiAml acpi_arg3(void);
 AcpiAml acpi_store(AcpiAml val, AcpiAml target);
 AcpiAml acpi_and(AcpiAml arg1, AcpiAml arg2);
 AcpiAml acpi_notify(AcpiAml arg1, AcpiAml arg2);
+AcpiAml acpi_call1(const char *method, AcpiAml arg1);
+AcpiAml acpi_call2(const char *method, AcpiAml arg1, AcpiAml arg2);
+AcpiAml acpi_call3(const char *method, AcpiAml arg1, AcpiAml arg2,
+                   AcpiAml arg3);
+AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
+                   AcpiAml arg3, AcpiAml arg4);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 16/47] pc: acpi-build: drop template patching and create PCI bus tree dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (14 preceding siblings ...)
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 15/47] acpi: add acpi_call1(), acpi_call2(), acpi_call3(), acpi_call4() helpers Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 17/47] acpi: add acpi_package() term Igor Mammedov
                   ` (31 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Replace AML template patching with direct composing
of PCI device entries in C. It allows to simplify
PCI tree generation further and saves us about 400LOC
scattered through different files, confining tree
generation to one C function which is much easier
to deal with.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
 * rebase on top bridge_in_acpi change, to keep
   the same behavior as upstream did before refactoring
 * drop scopes when building a bus subtree for bridges,
   instead of it embed subtree inside of bridge device
---
 hw/i386/Makefile.objs            |   6 +-
 hw/i386/acpi-build.c             | 232 +++++++++++++-----------------------
 hw/i386/ssdt-pcihp.dsl           | 100 ----------------
 hw/i386/ssdt-pcihp.hex.generated | 251 ---------------------------------------
 4 files changed, 84 insertions(+), 505 deletions(-)
 delete mode 100644 hw/i386/ssdt-pcihp.dsl
 delete mode 100644 hw/i386/ssdt-pcihp.hex.generated

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 2b678ef..4509cd1 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -8,10 +8,8 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/
 obj-y += kvmvapic.o
 obj-y += acpi-build.o
 hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \
-	hw/i386/ssdt-proc.hex hw/i386/ssdt-pcihp.hex hw/i386/ssdt-misc.hex \
-	hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \
-	hw/i386/q35-acpi-dsdt.hex hw/i386/ssdt-mem.hex \
-	hw/i386/ssdt-tpm.hex
+	hw/i386/ssdt-proc.hex hw/i386/ssdt-misc.hex hw/i386/q35-acpi-dsdt.hex \
+	hw/i386/ssdt-mem.hex hw/i386/ssdt-tpm.hex
 
 iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
     ; then echo "$(2)"; else echo "$(3)"; fi ;)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index eebfe8d..c084bb4 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -526,29 +526,6 @@ static inline char acpi_get_hex(uint32_t val)
 #define ACPI_PROC_SIZEOF (*ssdt_proc_end - *ssdt_proc_start)
 #define ACPI_PROC_AML (ssdp_proc_aml + *ssdt_proc_start)
 
-/* 0x5B 0x82 DeviceOp PkgLength NameString */
-#define ACPI_PCIHP_OFFSET_HEX (*ssdt_pcihp_name - *ssdt_pcihp_start + 1)
-#define ACPI_PCIHP_OFFSET_ID (*ssdt_pcihp_id - *ssdt_pcihp_start)
-#define ACPI_PCIHP_OFFSET_ADR (*ssdt_pcihp_adr - *ssdt_pcihp_start)
-#define ACPI_PCIHP_OFFSET_EJ0 (*ssdt_pcihp_ej0 - *ssdt_pcihp_start)
-#define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start)
-#define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start)
-
-#define ACPI_PCINOHP_OFFSET_HEX (*ssdt_pcinohp_name - *ssdt_pcinohp_start + 1)
-#define ACPI_PCINOHP_OFFSET_ADR (*ssdt_pcinohp_adr - *ssdt_pcinohp_start)
-#define ACPI_PCINOHP_SIZEOF (*ssdt_pcinohp_end - *ssdt_pcinohp_start)
-#define ACPI_PCINOHP_AML (ssdp_pcihp_aml + *ssdt_pcinohp_start)
-
-#define ACPI_PCIVGA_OFFSET_HEX (*ssdt_pcivga_name - *ssdt_pcivga_start + 1)
-#define ACPI_PCIVGA_OFFSET_ADR (*ssdt_pcivga_adr - *ssdt_pcivga_start)
-#define ACPI_PCIVGA_SIZEOF (*ssdt_pcivga_end - *ssdt_pcivga_start)
-#define ACPI_PCIVGA_AML (ssdp_pcihp_aml + *ssdt_pcivga_start)
-
-#define ACPI_PCIQXL_OFFSET_HEX (*ssdt_pciqxl_name - *ssdt_pciqxl_start + 1)
-#define ACPI_PCIQXL_OFFSET_ADR (*ssdt_pciqxl_adr - *ssdt_pciqxl_start)
-#define ACPI_PCIQXL_SIZEOF (*ssdt_pciqxl_end - *ssdt_pciqxl_start)
-#define ACPI_PCIQXL_AML (ssdp_pcihp_aml + *ssdt_pciqxl_start)
-
 #include "hw/i386/ssdt-mem.hex"
 
 /* 0x5B 0x82 DeviceOp PkgLength NameString DimmID */
@@ -561,7 +538,6 @@ static inline char acpi_get_hex(uint32_t val)
 #define ACPI_SSDT_HEADER_LENGTH 36
 
 #include "hw/i386/ssdt-misc.hex"
-#include "hw/i386/ssdt-pcihp.hex"
 #include "hw/i386/ssdt-tpm.hex"
 
 static void
@@ -582,43 +558,6 @@ build_append_notify_method(GArray *device, const char *name,
     build_append_and_cleanup_method(device, method);
 }
 
-static void patch_pcihp(int slot, uint8_t *ssdt_ptr)
-{
-    unsigned devfn = PCI_DEVFN(slot, 0);
-
-    ssdt_ptr[ACPI_PCIHP_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
-    ssdt_ptr[ACPI_PCIHP_OFFSET_HEX + 1] = acpi_get_hex(devfn);
-    ssdt_ptr[ACPI_PCIHP_OFFSET_ID] = slot;
-    ssdt_ptr[ACPI_PCIHP_OFFSET_ADR + 2] = slot;
-}
-
-static void patch_pcinohp(int slot, uint8_t *ssdt_ptr)
-{
-    unsigned devfn = PCI_DEVFN(slot, 0);
-
-    ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
-    ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX + 1] = acpi_get_hex(devfn);
-    ssdt_ptr[ACPI_PCINOHP_OFFSET_ADR + 2] = slot;
-}
-
-static void patch_pcivga(int slot, uint8_t *ssdt_ptr)
-{
-    unsigned devfn = PCI_DEVFN(slot, 0);
-
-    ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
-    ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX + 1] = acpi_get_hex(devfn);
-    ssdt_ptr[ACPI_PCIVGA_OFFSET_ADR + 2] = slot;
-}
-
-static void patch_pciqxl(int slot, uint8_t *ssdt_ptr)
-{
-    unsigned devfn = PCI_DEVFN(slot, 0);
-
-    ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
-    ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX + 1] = acpi_get_hex(devfn);
-    ssdt_ptr[ACPI_PCIQXL_OFFSET_ADR + 2] = slot;
-}
-
 /* Assign BSEL property to all buses.  In the future, this can be changed
  * to only assign to buses that support hotplug.
  */
@@ -649,46 +588,30 @@ static void acpi_set_pci_info(void)
     }
 }
 
-static void build_append_pcihp_notify_entry(GArray *method, int slot)
+static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
 {
-    GArray *ifctx;
-
-    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 */
+    AcpiAml if_ctx;
+    int32_t devfn = PCI_DEVFN(slot, 0);
 
-    /* Pack it up */
-    build_package(ifctx, 0xA0 /* IfOp */);
-    build_append_array(method, ifctx);
-    build_free_array(ifctx);
+    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
+    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
+    aml_append(method, if_ctx);
 }
 
-static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus,
+static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
                                          bool pcihp_bridge_en)
 {
-    GArray *bus_table = build_alloc_array();
-    GArray *method = NULL;
+    AcpiAml dev, notify_method, method;
     QObject *bsel;
     PCIBus *sec;
     int i;
 
-    if (bus->parent_dev) {
-        build_append_namestring(bus_table, "S%.02X_", bus->parent_dev->devfn);
-    } else {
-        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_namestring(bus_table, "BSEL");
-        build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel)));
-        method = build_alloc_method("DVNT", 2);
+        int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
+
+        aml_append(parent_scope, acpi_name_decl("BSEL", acpi_int(bsel_val)));
+        notify_method = acpi_method("DVNT", 2);
     }
 
     for (i = 0; i < ARRAY_SIZE(bus->devices); i += PCI_FUNC_MAX) {
@@ -700,18 +623,24 @@ static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus,
 
         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);
+                dev = acpi_device("S%.02X", PCI_DEVFN(slot, 0));
+                aml_append(&dev, acpi_name_decl("_SUN", acpi_int(slot)));
+                aml_append(&dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
+                method = acpi_method("_EJ0", 1);
+                aml_append(&method,
+                    acpi_call2("PCEJ", acpi_name("BSEL"), acpi_name("_SUN"))
+                );
+                aml_append(&dev, method);
+                aml_append(parent_scope, dev);
+
+                build_append_pcihp_notify_entry(&notify_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);
+                dev = acpi_device("S%.02X", PCI_DEVFN(slot, 0));
+                aml_append(&dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
+                aml_append(parent_scope, dev);
             }
             continue;
         }
@@ -724,79 +653,84 @@ static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus,
         }
         bridge_in_acpi = pc->is_bridge && pcihp_bridge_en;
 
+        dev = acpi_device("S%.02X", PCI_DEVFN(slot, 0));
+        aml_append(&dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
+
         if (pc->class_id == PCI_CLASS_DISPLAY_VGA) {
+            int s3d = 0;
 
             if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) {
-                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);
+                s3d = 3;
             }
+
+            method = acpi_method("_S1D", 0);
+            aml_append(&method, acpi_return(acpi_int(0)));
+            aml_append(&dev, method);
+
+            method = acpi_method("_S2D", 0);
+            aml_append(&method, acpi_return(acpi_int(0)));
+            aml_append(&dev, method);
+
+            method = acpi_method("_S3D", 0);
+            aml_append(&method, acpi_return(acpi_int(s3d)));
+            aml_append(&dev, method);
         } 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(slot, pcihp);
+            aml_append(&dev, acpi_name_decl("_SUN", acpi_int(slot)));
+
+            method = acpi_method("_EJ0", 1);
+            aml_append(&method,
+                acpi_call2("PCEJ", acpi_name("BSEL"), acpi_name("_SUN"))
+            );
+            aml_append(&dev, method);
 
             if (bsel) {
-                build_append_pcihp_notify_entry(method, slot);
+                build_append_pcihp_notify_entry(&notify_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);
-
             /* 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_append_pci_bus_devices(bus_table, sec_bus,
-                                             pcihp_bridge_en);
+                build_append_pci_bus_devices(&dev, sec_bus, pcihp_bridge_en);
             }
         }
+        aml_append(parent_scope, dev);
     }
 
     if (bsel) {
-        build_append_and_cleanup_method(bus_table, method);
+        aml_append(parent_scope, notify_method);
     }
 
     /* Append PCNT method to notify about events on local and child buses.
      * Add unconditionally for root since DSDT expects it.
      */
-    method = build_alloc_method("PCNT", 0);
+    method = acpi_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 */
+        int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
+        aml_append(&method, acpi_store(acpi_int(bsel_val), acpi_name("BNUM")));
+        aml_append(&method,
+            acpi_call2("DVNT", acpi_name("PCIU"),
+                       acpi_int(1) /* Device Check */)
+        );
+        aml_append(&method,
+            acpi_call2("DVNT", acpi_name("PCID"),
+                       acpi_int(3)/* Eject Request */)
+        );
     }
 
     /* 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);
+            int32_t devfn = sec->parent_dev->devfn;
+
+            aml_append(&method, acpi_name("^S%.02X.PCNT", devfn));
         }
     }
-
-    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);
+    aml_append(parent_scope, method);
 }
 
 static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
@@ -824,6 +758,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     uint32_t nr_mem = machine->ram_slots;
     unsigned acpi_cpus = guest_info->apic_id_limit;
     int ssdt_start = table_data->len;
+    AcpiAml table_aml = { .buf = table_data };
     uint8_t *ssdt_ptr;
     int i;
 
@@ -854,14 +789,11 @@ build_ssdt(GArray *table_data, GArray *linker,
                       ssdt_mctrl_nr_slots[0], 32, nr_mem);
 
     {
-        GArray *sb_scope = build_alloc_array();
-        uint8_t op = 0x10; /* ScopeOp */
-
-        build_append_namestring(sb_scope, "_SB");
+        AcpiAml sb_scope = acpi_scope("_SB");
 
         /* build Processor object for each processor */
         for (i = 0; i < acpi_cpus; i++) {
-            uint8_t *proc = acpi_data_push(sb_scope, ACPI_PROC_SIZEOF);
+            uint8_t *proc = acpi_data_push(sb_scope.buf, ACPI_PROC_SIZEOF);
             memcpy(proc, ACPI_PROC_AML, ACPI_PROC_SIZEOF);
             proc[ACPI_PROC_OFFSET_CPUHEX] = acpi_get_hex(i >> 4);
             proc[ACPI_PROC_OFFSET_CPUHEX+1] = acpi_get_hex(i);
@@ -873,11 +805,11 @@ build_ssdt(GArray *table_data, GArray *linker,
          *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
          */
         /* Arg0 = Processor ID = APIC ID */
-        build_append_notify_method(sb_scope, "NTFY", "CP%0.02X", acpi_cpus);
+        build_append_notify_method(sb_scope.buf, "NTFY", "CP%0.02X", acpi_cpus);
 
         /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */
-        build_append_byte(sb_scope, 0x08); /* NameOp */
-        build_append_namestring(sb_scope, "CPON");
+        build_append_byte(sb_scope.buf, 0x08); /* NameOp */
+        build_append_namestring(sb_scope.buf, "CPON");
 
         {
             GArray *package = build_alloc_array();
@@ -902,7 +834,7 @@ build_ssdt(GArray *table_data, GArray *linker,
             }
 
             build_package(package, op);
-            build_append_array(sb_scope, package);
+            build_append_array(sb_scope.buf, package);
             build_free_array(package);
         }
 
@@ -911,7 +843,7 @@ build_ssdt(GArray *table_data, GArray *linker,
             /* build memory devices */
             for (i = 0; i < nr_mem; i++) {
                 char id[3];
-                uint8_t *mem = acpi_data_push(sb_scope, ACPI_MEM_SIZEOF);
+                uint8_t *mem = acpi_data_push(sb_scope.buf, ACPI_MEM_SIZEOF);
 
                 snprintf(id, sizeof(id), "%02X", i);
                 memcpy(mem, ACPI_MEM_AML, ACPI_MEM_SIZEOF);
@@ -922,7 +854,7 @@ build_ssdt(GArray *table_data, GArray *linker,
             /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
              *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
              */
-            build_append_notify_method(sb_scope,
+            build_append_notify_method(sb_scope.buf,
                                        stringify(MEMORY_SLOT_NOTIFY_METHOD),
                                        "MP%0.02X", nr_mem);
         }
@@ -938,14 +870,14 @@ build_ssdt(GArray *table_data, GArray *linker,
             }
 
             if (bus) {
+                scope = acpi_scope("PCI0");
                 /* Scan all PCI buses. Generate tables to support hotplug. */
-                build_append_pci_bus_devices(sb_scope, bus,
+                build_append_pci_bus_devices(&scope, bus,
                                              pm->pcihp_bridge_en);
+                aml_append(&sb_scope, scope);
             }
         }
-        build_package(sb_scope, op);
-        build_append_array(table_data, sb_scope);
-        build_free_array(sb_scope);
+        aml_append(&table_aml, sb_scope);
     }
 
     build_header(linker, table_data,
diff --git a/hw/i386/ssdt-pcihp.dsl b/hw/i386/ssdt-pcihp.dsl
deleted file mode 100644
index ac91c05..0000000
--- a/hw/i386/ssdt-pcihp.dsl
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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/>.
- */
-
-ACPI_EXTRACT_ALL_CODE ssdp_pcihp_aml
-
-DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
-{
-
-/****************************************************************
- * PCI hotplug
- ****************************************************************/
-
-    /* Objects supplied by DSDT */
-    External(\_SB.PCI0, DeviceObj)
-    External(\_SB.PCI0.PCEJ, MethodObj)
-    External(BSEL, IntObj)
-
-    Scope(\_SB.PCI0) {
-
-        /* Bulk generated PCI hotplug devices */
-        ACPI_EXTRACT_DEVICE_START ssdt_pcihp_start
-        ACPI_EXTRACT_DEVICE_END ssdt_pcihp_end
-        ACPI_EXTRACT_DEVICE_STRING ssdt_pcihp_name
-
-        // Extract the offsets of the device name, address dword and the slot
-        // name byte - we fill them in for each device.
-        Device(SAA) {
-            ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcihp_id
-            Name(_SUN, 0xAA)
-            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcihp_adr
-            Name(_ADR, 0xAA0000)
-            Method(_EJ0, 1) {
-                PCEJ(BSEL, _SUN)
-            }
-        }
-
-        ACPI_EXTRACT_DEVICE_START ssdt_pcinohp_start
-        ACPI_EXTRACT_DEVICE_END ssdt_pcinohp_end
-        ACPI_EXTRACT_DEVICE_STRING ssdt_pcinohp_name
-
-        // Extract the offsets of the device name, address dword and the slot
-        // name byte - we fill them in for each device.
-        Device(SBB) {
-            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcinohp_adr
-            Name(_ADR, 0xAA0000)
-        }
-
-        ACPI_EXTRACT_DEVICE_START ssdt_pcivga_start
-        ACPI_EXTRACT_DEVICE_END ssdt_pcivga_end
-        ACPI_EXTRACT_DEVICE_STRING ssdt_pcivga_name
-
-        // Extract the offsets of the device name, address dword and the slot
-        // name byte - we fill them in for each device.
-        Device(SCC) {
-            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcivga_adr
-            Name(_ADR, 0xAA0000)
-            Method(_S1D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S2D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S3D, 0, NotSerialized) {
-                Return (0x00)
-            }
-        }
-
-        ACPI_EXTRACT_DEVICE_START ssdt_pciqxl_start
-        ACPI_EXTRACT_DEVICE_END ssdt_pciqxl_end
-        ACPI_EXTRACT_DEVICE_STRING ssdt_pciqxl_name
-
-        // Extract the offsets of the device name, address dword and the slot
-        // name byte - we fill them in for each device.
-        Device(SDD) {
-            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pciqxl_adr
-            Name(_ADR, 0xAA0000)
-            Method(_S1D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S2D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S3D, 0, NotSerialized) {
-                Return (0x03)           // QXL
-            }
-        }
-    }
-}
diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated
deleted file mode 100644
index 72ffa84..0000000
--- a/hw/i386/ssdt-pcihp.hex.generated
+++ /dev/null
@@ -1,251 +0,0 @@
-static unsigned char ssdt_pcihp_name[] = {
-0x34
-};
-static unsigned char ssdt_pcivga_end[] = {
-0x99
-};
-static unsigned char ssdt_pcivga_name[] = {
-0x70
-};
-static unsigned char ssdt_pcihp_adr[] = {
-0x45
-};
-static unsigned char ssdt_pcinohp_end[] = {
-0x6d
-};
-static unsigned char ssdt_pcihp_end[] = {
-0x5c
-};
-static unsigned char ssdt_pciqxl_start[] = {
-0x99
-};
-static unsigned char ssdt_pcinohp_name[] = {
-0x5f
-};
-static unsigned char ssdp_pcihp_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0xc6,
-0x0,
-0x0,
-0x0,
-0x1,
-0x70,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x42,
-0x58,
-0x53,
-0x53,
-0x44,
-0x54,
-0x50,
-0x43,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x15,
-0x11,
-0x13,
-0x20,
-0x10,
-0x41,
-0xa,
-0x5c,
-0x2e,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x5b,
-0x82,
-0x29,
-0x53,
-0x41,
-0x41,
-0x5f,
-0x8,
-0x5f,
-0x53,
-0x55,
-0x4e,
-0xa,
-0xaa,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x14,
-0x12,
-0x5f,
-0x45,
-0x4a,
-0x30,
-0x1,
-0x50,
-0x43,
-0x45,
-0x4a,
-0x42,
-0x53,
-0x45,
-0x4c,
-0x5f,
-0x53,
-0x55,
-0x4e,
-0x5b,
-0x82,
-0xf,
-0x53,
-0x42,
-0x42,
-0x5f,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x5b,
-0x82,
-0x2a,
-0x53,
-0x43,
-0x43,
-0x5f,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x31,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x32,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x33,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x5b,
-0x82,
-0x2b,
-0x53,
-0x44,
-0x44,
-0x5f,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x31,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x32,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x9,
-0x5f,
-0x53,
-0x33,
-0x44,
-0x0,
-0xa4,
-0xa,
-0x3
-};
-static unsigned char ssdt_pciqxl_adr[] = {
-0xa6
-};
-static unsigned char ssdt_pcinohp_adr[] = {
-0x69
-};
-static unsigned char ssdt_pcivga_adr[] = {
-0x7a
-};
-static unsigned char ssdt_pciqxl_name[] = {
-0x9c
-};
-static unsigned char ssdt_pcivga_start[] = {
-0x6d
-};
-static unsigned char ssdt_pciqxl_end[] = {
-0xc6
-};
-static unsigned char ssdt_pcihp_start[] = {
-0x31
-};
-static unsigned char ssdt_pcihp_id[] = {
-0x3e
-};
-static unsigned char ssdt_pcinohp_start[] = {
-0x5c
-};
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 17/47] acpi: add acpi_package() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (15 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 16/47] pc: acpi-build: drop template patching and create PCI bus tree dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 18/47] pc: acpi-build: drop unsupported PM1b_CNT.SLP_TYP Igor Mammedov
                   ` (30 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 8 ++++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index cbeb255..6282865 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -492,3 +492,11 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...)
     va_end(ap);
     return var;
 }
+
+/* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefPackage */
+AcpiAml acpi_package(uint8_t num_elements)
+{
+    AcpiAml var = aml_allocate_internal(0x12 /* PackageOp */, PACKAGE);
+    build_append_byte(var.buf, num_elements);
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 473589d..e34e19a 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -45,6 +45,7 @@ AcpiAml acpi_if(AcpiAml predicate);
 AcpiAml acpi_method(const char *name, int arg_count);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
+AcpiAml acpi_package(uint8_t num_elements);
 
 /* other helpers */
 GArray *build_alloc_array(void);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 18/47] pc: acpi-build: drop unsupported PM1b_CNT.SLP_TYP
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (16 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 17/47] acpi: add acpi_package() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 19/47] pc: acpi-build: generate _S[345] packages dynamically Igor Mammedov
                   ` (29 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

QEMU doesn't implement/advertize PM1b_CNT_BLK
register block so do not set/patch its \_Sx
values to avoid confusion.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c  | 3 +--
 hw/i386/ssdt-misc.dsl | 4 ++--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index c084bb4..9088faa 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -776,8 +776,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     if (pm->s4_disabled) {
         ssdt_ptr[acpi_s4_name[0]] = 'X';
     } else {
-        ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt_ptr[acpi_s4_pkg[0] + 3] =
-            pm->s4_val;
+        ssdt_ptr[acpi_s4_pkg[0] + 1] = pm->s4_val;
     }
 
     patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
index 1e3baae..96382a6 100644
--- a/hw/i386/ssdt-misc.dsl
+++ b/hw/i386/ssdt-misc.dsl
@@ -54,7 +54,7 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
         ACPI_EXTRACT_NAME_STRING acpi_s3_name
         Name(_S3, Package(0x04) {
             One,  /* PM1a_CNT.SLP_TYP */
-            One,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* PM1b_CNT.SLP_TYP, QEMU doesn't provide it */
             Zero,  /* reserved */
             Zero   /* reserved */
         })
@@ -62,7 +62,7 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
         ACPI_EXTRACT_PKG_START acpi_s4_pkg
         Name(_S4, Package(0x04) {
             0x2,  /* PM1a_CNT.SLP_TYP */
-            0x2,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* PM1b_CNT.SLP_TYP, QEMU doesn't provide it */
             Zero,  /* reserved */
             Zero   /* reserved */
         })
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 19/47] pc: acpi-build: generate _S[345] packages dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (17 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 18/47] pc: acpi-build: drop unsupported PM1b_CNT.SLP_TYP Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 20/47] acpi: add acpi_buffer() term Igor Mammedov
                   ` (28 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Replaces template patching with packages composed
using ASL API.

Note on behavior change:
If S3 or S4 is disabled, respective packages won't
be created and put into SSDT. Which saves us some
space in SSDT and doesn't confuse guest OS with
mangled package names as it was done originally.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c  | 39 ++++++++++++++++++++++++++++++---------
 hw/i386/ssdt-misc.dsl | 33 ---------------------------------
 2 files changed, 30 insertions(+), 42 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9088faa..4e5858a 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -760,6 +760,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     int ssdt_start = table_data->len;
     AcpiAml table_aml = { .buf = table_data };
     uint8_t *ssdt_ptr;
+    AcpiAml pkg, scope;
     int i;
 
     /* The current AML generator can cover the APIC ID range [0..255],
@@ -767,17 +768,9 @@ build_ssdt(GArray *table_data, GArray *linker,
     QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
     g_assert(acpi_cpus <= ACPI_CPU_HOTPLUG_ID_LIMIT);
 
-    /* Copy header and patch values in the S3_ / S4_ / S5_ packages */
+    /* Copy header and ssdt template and patch values */
     ssdt_ptr = acpi_data_push(table_data, sizeof(ssdp_misc_aml));
     memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));
-    if (pm->s3_disabled) {
-        ssdt_ptr[acpi_s3_name[0]] = 'X';
-    }
-    if (pm->s4_disabled) {
-        ssdt_ptr[acpi_s4_name[0]] = 'X';
-    } else {
-        ssdt_ptr[acpi_s4_pkg[0] + 1] = pm->s4_val;
-    }
 
     patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
 
@@ -787,6 +780,34 @@ build_ssdt(GArray *table_data, GArray *linker,
     ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
                       ssdt_mctrl_nr_slots[0], 32, nr_mem);
 
+    /*  create S3_ / S4_ / S5_ packages if necessary */
+    scope = acpi_scope("\\");
+    if (!pm->s3_disabled) {
+        pkg = acpi_package(4);
+        aml_append(&pkg, acpi_int(1)); /* PM1a_CNT.SLP_TYP */
+        aml_append(&pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
+        aml_append(&pkg, acpi_int(0)); /* reserved */
+        aml_append(&pkg, acpi_int(0)); /* reserved */
+        aml_append(&scope, acpi_name_decl("_S3", pkg));
+    }
+
+    if (!pm->s4_disabled) {
+        pkg = acpi_package(4);
+        aml_append(&pkg, acpi_int(pm->s4_val)); /* PM1a_CNT.SLP_TYP */
+        aml_append(&pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
+        aml_append(&pkg, acpi_int(0)); /* reserved */
+        aml_append(&pkg, acpi_int(0)); /* reserved */
+        aml_append(&scope, acpi_name_decl("_S4", pkg));
+    }
+
+    pkg = acpi_package(4);
+    aml_append(&pkg, acpi_int(0)); /* PM1a_CNT.SLP_TYP */
+    aml_append(&pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
+    aml_append(&pkg, acpi_int(0)); /* reserved */
+    aml_append(&pkg, acpi_int(0)); /* reserved */
+    aml_append(&scope, acpi_name_decl("_S5", pkg));
+    aml_append(&table_aml, scope);
+
     {
         AcpiAml sb_scope = acpi_scope("_SB");
 
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
index 96382a6..26b9241 100644
--- a/hw/i386/ssdt-misc.dsl
+++ b/hw/i386/ssdt-misc.dsl
@@ -41,39 +41,6 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
     }
 
 
-/****************************************************************
- * Suspend
- ****************************************************************/
-
-    Scope(\) {
-    /*
-     * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
-     * must match piix4 emulation.
-     */
-
-        ACPI_EXTRACT_NAME_STRING acpi_s3_name
-        Name(_S3, Package(0x04) {
-            One,  /* PM1a_CNT.SLP_TYP */
-            Zero,  /* PM1b_CNT.SLP_TYP, QEMU doesn't provide it */
-            Zero,  /* reserved */
-            Zero   /* reserved */
-        })
-        ACPI_EXTRACT_NAME_STRING acpi_s4_name
-        ACPI_EXTRACT_PKG_START acpi_s4_pkg
-        Name(_S4, Package(0x04) {
-            0x2,  /* PM1a_CNT.SLP_TYP */
-            Zero,  /* PM1b_CNT.SLP_TYP, QEMU doesn't provide it */
-            Zero,  /* reserved */
-            Zero   /* reserved */
-        })
-        Name(_S5, Package(0x04) {
-            Zero,  /* PM1a_CNT.SLP_TYP */
-            Zero,  /* PM1b_CNT.SLP_TYP */
-            Zero,  /* reserved */
-            Zero   /* reserved */
-        })
-    }
-
     External(\_SB.PCI0, DeviceObj)
     External(\_SB.PCI0.ISA, DeviceObj)
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 20/47] acpi: add acpi_buffer() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (18 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 19/47] pc: acpi-build: generate _S[345] packages dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 21/47] acpi: add acpi_resource_template() helper Igor Mammedov
                   ` (27 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 7 +++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 6282865..2d5e77a 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -493,6 +493,13 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
+AcpiAml acpi_buffer(void)
+{
+    AcpiAml var = aml_allocate_internal(0x11 /* BufferOp */, BUFFER);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefPackage */
 AcpiAml acpi_package(uint8_t num_elements)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index e34e19a..a79c085 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -45,6 +45,7 @@ AcpiAml acpi_if(AcpiAml predicate);
 AcpiAml acpi_method(const char *name, int arg_count);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
+AcpiAml acpi_buffer(void);
 AcpiAml acpi_package(uint8_t num_elements);
 
 /* other helpers */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 21/47] acpi: add acpi_resource_template() helper
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (19 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 20/47] acpi: add acpi_buffer() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-27 13:26   ` Claudio Fontana
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 22/47] acpi: add acpi_io() helper Igor Mammedov
                   ` (26 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 8 ++++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 2d5e77a..32a4377 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -493,6 +493,14 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...)
     return var;
 }
 
+/* ResourceTemplate marcos helper */
+AcpiAml acpi_resource_template(void)
+{
+    /* ResourceTemplate is a buffer of Resources with EndTag at the end */
+    AcpiAml var = aml_allocate_internal(0x11 /* BufferOp */, RES_TEMPLATE);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
 AcpiAml acpi_buffer(void)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index a79c085..594fae7 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -46,6 +46,7 @@ AcpiAml acpi_method(const char *name, int arg_count);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
 AcpiAml acpi_buffer(void);
+AcpiAml acpi_resource_template(void);
 AcpiAml acpi_package(uint8_t num_elements);
 
 /* other helpers */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 22/47] acpi: add acpi_io() helper
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (20 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 21/47] acpi: add acpi_resource_template() helper Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-02-05 15:19   ` Marcel Apfelbaum
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 23/47] acpi: include PkgLength size only when requested Igor Mammedov
                   ` (25 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 19 +++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  7 +++++++
 2 files changed, 26 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 32a4377..56b237a 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -454,6 +454,25 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
     return var;
 }
 
+/*
+ * ACPI 5.0: 19.5.62 IO (IO Resource Descriptor Macro)
+ *           6.4.2 Small Resource Data Type
+*/
+AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
+                uint8_t aln, uint8_t len)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x47); /* IO port descriptor */
+    build_append_byte(var.buf, dec);
+    build_append_byte(var.buf, min_base & 0xff);
+    build_append_byte(var.buf, (min_base >> 8) & 0xff);
+    build_append_byte(var.buf, max_base & 0xff);
+    build_append_byte(var.buf, (max_base >> 8) & 0xff);
+    build_append_byte(var.buf, aln);
+    build_append_byte(var.buf, len);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 594fae7..91575f1 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -19,6 +19,11 @@ typedef struct AcpiAml {
     AcpiBlockFlags block_flags;
 } AcpiAml;
 
+typedef enum {
+    acpi_decode10 = 0,
+    acpi_decode16 = 1,
+} acpiIODecode;
+
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* non block ASL object primitives */
@@ -39,6 +44,8 @@ AcpiAml acpi_call3(const char *method, AcpiAml arg1, AcpiAml arg2,
                    AcpiAml arg3);
 AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
                    AcpiAml arg3, AcpiAml arg4);
+AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
+                uint8_t aln, uint8_t len);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 23/47] acpi: include PkgLength size only when requested
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (21 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 22/47] acpi: add acpi_io() helper Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 24/47] acpi: add acpi_operation_region() term Igor Mammedov
                   ` (24 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Named/Reserved{Field} definition uses PkgLength [1] encoding to specify
field length, however it doesn't include size of PkgLength field itself,
while other block objects that have explicit length of its body account
for PkgLength size while encoding it [2].
This special casing isn't mentioned in ACPI spec, but that's what 'iasl'
compiles NamedField to so add extra argument to build_prepend_pkg_length()
to allow it handle the case.

--
1. ACPI Spec 5.0, 20.2.5.2 Named Objects Encoding, page 822
2. ACPI Spec 5.0, 5.4 Definition Block Encoding

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 20 +++++++++++++++-----
 include/hw/acpi/acpi-build-utils.h |  3 ++-
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 56b237a..094c821 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -167,10 +167,10 @@ enum {
     PACKAGE_LENGTH_4BYTE_SHIFT = 20,
 };
 
-void build_prepend_package_length(GArray *package)
+void
+build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
 {
     uint8_t byte;
-    unsigned length = package->len;
     unsigned length_bytes;
 
     if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
@@ -183,8 +183,18 @@ void build_prepend_package_length(GArray *package)
         length_bytes = 4;
     }
 
-    /* PkgLength is the length of the inclusive length of the data. */
-    length += length_bytes;
+    /*
+     * NamedField uses PkgLength encoding but it doesn't include length
+     * of PkgLength itself.
+     */
+    if (incl_self) {
+        /*
+         * PkgLength is the length of the inclusive length of the data
+         * and PkgLength's length itself when used for terms with
+         * explitit length.
+         */
+        length += length_bytes;
+    }
 
     switch (length_bytes) {
     case 1:
@@ -217,7 +227,7 @@ void build_prepend_package_length(GArray *package)
 
 void build_package(GArray *package, uint8_t op)
 {
-    build_prepend_package_length(package);
+    build_prepend_package_length(package, package->len, true);
     build_prepend_byte(package, op);
 }
 
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 91575f1..176596e 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -66,7 +66,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);
+void
+build_prepend_package_length(GArray *package, unsigned length, bool incl_self);
 void build_package(GArray *package, uint8_t op);
 void build_append_value(GArray *table, uint64_t value, int size);
 void build_append_int(GArray *table, uint64_t value);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 24/47] acpi: add acpi_operation_region() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (22 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 23/47] acpi: include PkgLength size only when requested Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-02-05 15:28   ` Marcel Apfelbaum
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 25/47] acpi: add acpi_field() & acpi_named_field() terms Igor Mammedov
                   ` (23 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 14 ++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  7 +++++++
 2 files changed, 21 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 094c821..9ac5a0d 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -544,3 +544,17 @@ AcpiAml acpi_package(uint8_t num_elements)
     build_append_byte(var.buf, num_elements);
     return var;
 }
+
+/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefOpRegion */
+AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
+                              uint32_t offset, uint32_t len)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x5B); /* ExtOpPrefix */
+    build_append_byte(var.buf, 0x80); /* OpRegionOp */
+    build_append_namestring(var.buf, "%s", name);
+    build_append_byte(var.buf, rs);
+    build_append_int(var.buf, offset);
+    build_append_int(var.buf, len);
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 176596e..cb45129 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -24,6 +24,11 @@ typedef enum {
     acpi_decode16 = 1,
 } acpiIODecode;
 
+typedef enum {
+    acpi_system_memory = 0x00,
+    acpi_system_io = 0x01,
+} acpiRegionSpace;
+
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* non block ASL object primitives */
@@ -46,6 +51,8 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
                    AcpiAml arg3, AcpiAml arg4);
 AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
                 uint8_t aln, uint8_t len);
+AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
+                              uint32_t offset, uint32_t len);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 25/47] acpi: add acpi_field() & acpi_named_field() terms
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (23 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 24/47] acpi: add acpi_operation_region() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 26/47] acpi: add acpi_local0() term Igor Mammedov
                   ` (22 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
 fix style error: line over 80 chr
---
 hw/acpi/acpi-build-utils.c         | 28 ++++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  6 ++++++
 2 files changed, 34 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 9ac5a0d..8955608 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -225,6 +225,16 @@ build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
     build_prepend_byte(package, byte);
 }
 
+static void
+build_append_pkg_length(GArray *array, unsigned length, bool incl_self)
+{
+    GArray *tmp = build_alloc_array();
+
+    build_prepend_package_length(tmp, length, incl_self);
+    build_append_array(array, tmp);
+    build_free_array(tmp);
+}
+
 void build_package(GArray *package, uint8_t op)
 {
     build_prepend_package_length(package, package->len, true);
@@ -558,3 +568,21 @@ AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
     build_append_int(var.buf, len);
     return var;
 }
+
+/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: NamedField */
+AcpiAml acpi_named_field(const char *name, unsigned length)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_nameseg(var.buf, "%s", name);
+    build_append_pkg_length(var.buf, length, false);
+    return var;
+}
+
+/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefField */
+AcpiAml acpi_field(const char *name, acpiFieldFlags flags)
+{
+    AcpiAml var = aml_allocate_internal(0x81 /* FieldOp */, EXT_PACKAGE);
+    build_append_namestring(var.buf, "%s", name);
+    build_append_byte(var.buf, flags);
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index cb45129..b94098a 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -25,6 +25,10 @@ typedef enum {
 } acpiIODecode;
 
 typedef enum {
+    acpi_byte_acc = 1,
+} acpiFieldFlags;
+
+typedef enum {
     acpi_system_memory = 0x00,
     acpi_system_io = 0x01,
 } acpiRegionSpace;
@@ -53,6 +57,7 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
                 uint8_t aln, uint8_t len);
 AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len);
+AcpiAml acpi_named_field(const char *name, unsigned length);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
@@ -62,6 +67,7 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
 AcpiAml acpi_buffer(void);
 AcpiAml acpi_resource_template(void);
 AcpiAml acpi_package(uint8_t num_elements);
+AcpiAml acpi_field(const char *name, acpiFieldFlags flags);
 
 /* other helpers */
 GArray *build_alloc_array(void);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 26/47] acpi: add acpi_local0() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (24 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 25/47] acpi: add acpi_field() & acpi_named_field() terms Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 27/47] acpi: add acpi_string() term Igor Mammedov
                   ` (21 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 8 ++++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 8955608..1affed2 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -586,3 +586,11 @@ AcpiAml acpi_field(const char *name, acpiFieldFlags flags)
     build_append_byte(var.buf, flags);
     return var;
 }
+
+/* ACPI 5.0: 20.2.6.2 Local Objects Encoding: Local0Op */
+AcpiAml acpi_local0(void)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x60); /* Local0Op */
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index b94098a..8261ee5 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -58,6 +58,7 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
 AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len);
 AcpiAml acpi_named_field(const char *name, unsigned length);
+AcpiAml acpi_local0(void);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 27/47] acpi: add acpi_string() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (25 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 26/47] acpi: add acpi_local0() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 28/47] pc: acpi-build: generate pvpanic device description dynamically Igor Mammedov
                   ` (20 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 26 ++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 27 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 1affed2..fedf871 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -587,6 +587,32 @@ AcpiAml acpi_field(const char *name, acpiFieldFlags flags)
     return var;
 }
 
+/* ACPI 5.0: 20.2.3 Data Objects Encoding: String */
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    va_list ap, va_len;
+    char *s;
+    int len;
+
+    va_start(ap, name_format);
+    va_copy(va_len, ap);
+    len = vsnprintf(NULL, 0, name_format, va_len);
+    va_end(va_len);
+    len += 1;
+    s = g_new(typeof(*s), len);
+
+    len = vsnprintf(s, len, name_format, ap);
+    va_end(ap);
+
+    build_append_byte(var.buf, 0x0D); /* StringPrefix */
+    g_array_append_vals(var.buf, s, len);
+    build_append_byte(var.buf, 0x0); /* NullChar */
+    g_free(s);
+
+    return var;
+}
+
 /* ACPI 5.0: 20.2.6.2 Local Objects Encoding: Local0Op */
 AcpiAml acpi_local0(void)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 8261ee5..c823fb8 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -58,6 +58,7 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
 AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len);
 AcpiAml acpi_named_field(const char *name, unsigned length);
+AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
 AcpiAml acpi_local0(void);
 
 /* Block ASL object primitives */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 28/47] pc: acpi-build: generate pvpanic device description dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (26 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 27/47] acpi: add acpi_string() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 29/47] acpi: add acpi_varpackage() term Igor Mammedov
                   ` (19 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Drops AML template patching and allows to
save some space in SSDT if pvpanic device doesn't
exist by not including disabled device description
into SSDT. It also makes device description
smaller by replacing _STA method with named value
and dropping _INI method.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c  | 36 ++++++++++++++++++++++++++++++++----
 hw/i386/ssdt-misc.dsl | 47 -----------------------------------------------
 2 files changed, 32 insertions(+), 51 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4e5858a..6ae0c81 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -760,7 +760,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     int ssdt_start = table_data->len;
     AcpiAml table_aml = { .buf = table_data };
     uint8_t *ssdt_ptr;
-    AcpiAml pkg, scope;
+    AcpiAml pkg, scope, dev, method, crs, field;
     int i;
 
     /* The current AML generator can cover the APIC ID range [0..255],
@@ -775,9 +775,6 @@ build_ssdt(GArray *table_data, GArray *linker,
     patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
 
     ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
-                      ssdt_isa_pest[0], 16, misc->pvpanic_port);
-
-    ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
                       ssdt_mctrl_nr_slots[0], 32, nr_mem);
 
     /*  create S3_ / S4_ / S5_ packages if necessary */
@@ -808,6 +805,37 @@ build_ssdt(GArray *table_data, GArray *linker,
     aml_append(&scope, acpi_name_decl("_S5", pkg));
     aml_append(&table_aml, scope);
 
+    if (misc->pvpanic_port) {
+        scope = acpi_scope("\\_SB.PCI0.ISA");
+
+        dev = acpi_device("PEVR");
+        aml_append(&dev, acpi_name_decl("_HID", acpi_string("QEMU0002")));
+
+        crs = acpi_resource_template();
+        aml_append(&crs,
+            acpi_io(acpi_decode16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)
+        );
+        aml_append(&dev, acpi_name_decl("_CRS", crs));
+
+        aml_append(&dev, acpi_operation_region("PEOR", acpi_system_io,
+                                               misc->pvpanic_port, 1));
+        field = acpi_field("PEOR", acpi_byte_acc);
+        aml_append(&field, acpi_named_field("PEPT", 8));
+        aml_append(&dev, field);
+
+        method = acpi_method("RDPT", 0);
+        aml_append(&method, acpi_store(acpi_name("PEPT"), acpi_local0()));
+        aml_append(&method, acpi_return(acpi_local0()));
+        aml_append(&dev, method);
+
+        method = acpi_method("WRPT", 1);
+        aml_append(&method, acpi_store(acpi_arg0(), acpi_name("PEPT")));
+        aml_append(&dev, method);
+
+        aml_append(&scope, dev);
+        aml_append(&table_aml, scope);
+    }
+
     {
         AcpiAml sb_scope = acpi_scope("_SB");
 
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
index 26b9241..81be858 100644
--- a/hw/i386/ssdt-misc.dsl
+++ b/hw/i386/ssdt-misc.dsl
@@ -39,51 +39,4 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
        ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
        Name(MEMORY_SLOTS_NUMBER, 0x12345678)
     }
-
-
-    External(\_SB.PCI0, DeviceObj)
-    External(\_SB.PCI0.ISA, DeviceObj)
-
-    Scope(\_SB.PCI0.ISA) {
-        Device(PEVT) {
-            Name(_HID, "QEMU0001")
-            /* PEST will be patched to be Zero if no such device */
-            ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest
-            Name(PEST, 0xFFFF)
-            OperationRegion(PEOR, SystemIO, PEST, 0x01)
-            Field(PEOR, ByteAcc, NoLock, Preserve) {
-                PEPT,   8,
-            }
-
-            Method(_STA, 0, NotSerialized) {
-                Store(PEST, Local0)
-                If (LEqual(Local0, Zero)) {
-                    Return (0x00)
-                } Else {
-                    Return (0x0F)
-                }
-            }
-
-            Method(RDPT, 0, NotSerialized) {
-                Store(PEPT, Local0)
-                Return (Local0)
-            }
-
-            Method(WRPT, 1, NotSerialized) {
-                Store(Arg0, PEPT)
-            }
-
-            Name(_CRS, ResourceTemplate() {
-                IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO)
-            })
-
-            CreateWordField(_CRS, IO._MIN, IOMN)
-            CreateWordField(_CRS, IO._MAX, IOMX)
-
-            Method(_INI, 0, NotSerialized) {
-                Store(PEST, IOMN)
-                Store(PEST, IOMX)
-            }
-        }
-    }
 }
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 29/47] acpi: add acpi_varpackage() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (27 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 28/47] pc: acpi-build: generate pvpanic device description dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 30/47] acpi: add acpi_equal() term Igor Mammedov
                   ` (18 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 8 ++++++++
 include/hw/acpi/acpi-build-utils.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index fedf871..3eccfda 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -620,3 +620,11 @@ AcpiAml acpi_local0(void)
     build_append_byte(var.buf, 0x60); /* Local0Op */
     return var;
 }
+
+/* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefVarPackage */
+AcpiAml acpi_varpackage(uint32_t num_elements)
+{
+    AcpiAml var = aml_allocate_internal(0x13 /* VarPackageOp */, PACKAGE);
+    build_append_int(var.buf, num_elements);
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index c823fb8..8a21b4b 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -70,6 +70,7 @@ AcpiAml acpi_buffer(void);
 AcpiAml acpi_resource_template(void);
 AcpiAml acpi_package(uint8_t num_elements);
 AcpiAml acpi_field(const char *name, acpiFieldFlags flags);
+AcpiAml acpi_varpackage(uint32_t num_elements);
 
 /* other helpers */
 GArray *build_alloc_array(void);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 30/47] acpi: add acpi_equal() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (28 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 29/47] acpi: add acpi_varpackage() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 31/47] acpi: add acpi_processor() term Igor Mammedov
                   ` (17 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 11 +++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 3eccfda..587723d 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -493,6 +493,17 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
+AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var.buf, 0x93); /* LequalOp */
+    aml_append(&var, arg1);
+    aml_append(&var, arg2);
+    build_append_int(var.buf, 0x00); /* NullNameOp */
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml acpi_if(AcpiAml predicate)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 8a21b4b..76b8d9f 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -60,6 +60,7 @@ AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
 AcpiAml acpi_named_field(const char *name, unsigned length);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
 AcpiAml acpi_local0(void);
+AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 31/47] acpi: add acpi_processor() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (29 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 30/47] acpi: add acpi_equal() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 32/47] acpi: add acpi_eisaid() term Igor Mammedov
                   ` (16 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 20 ++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  3 +++
 2 files changed, 23 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 587723d..e51196b 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -639,3 +639,23 @@ AcpiAml acpi_varpackage(uint32_t num_elements)
     build_append_int(var.buf, num_elements);
     return var;
 }
+
+/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefProcessor */
+AcpiAml GCC_FMT_ATTR(4, 5)
+acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
+               const char *name_format, ...)
+{
+    va_list ap;
+    AcpiAml var = aml_allocate_internal(0x83 /* ProcessorOp */, EXT_PACKAGE);
+    va_start(ap, name_format);
+    build_append_namestringv(var.buf, name_format, ap);
+    va_end(ap);
+    build_append_byte(var.buf, proc_id); /* ProcID */
+    /* PblkAddr */
+    build_append_byte(var.buf, pblk_addr & 0xFF);
+    build_append_byte(var.buf, (pblk_addr >> 8) & 0xFF);
+    build_append_byte(var.buf, (pblk_addr >> 16) & 0xFF);
+    build_append_byte(var.buf, (pblk_addr >> 24) & 0xFF);
+    build_append_byte(var.buf, pblk_len); /* PblkLen */
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 76b8d9f..753171f 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -61,6 +61,9 @@ AcpiAml acpi_named_field(const char *name, unsigned length);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
 AcpiAml acpi_local0(void);
 AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2);
+AcpiAml GCC_FMT_ATTR(4, 5)
+acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
+               const char *name_format, ...);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 32/47] acpi: add acpi_eisaid() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (30 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 31/47] acpi: add acpi_processor() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 33/47] pc: acpi-build: drop template patching and CPU hotplug objects dynamically Igor Mammedov
                   ` (15 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 31 +++++++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 32 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index e51196b..cbc1241 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -23,7 +23,9 @@
 #include <stdarg.h>
 #include <assert.h>
 #include <stdbool.h>
+#include <string.h>
 #include "hw/acpi/acpi-build-utils.h"
+#include "qemu/bswap.h"
 
 GArray *build_alloc_array(void)
 {
@@ -659,3 +661,32 @@ acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
     build_append_byte(var.buf, pblk_len); /* PblkLen */
     return var;
 }
+
+static uint8_t Hex2Digit(char c)
+{
+    if (c >= 'A') {
+        return c - 'A' + 10;
+    }
+
+    return c - '0';
+}
+
+/* ACPI 5.0: 19.5.36 EISAID (EISA ID String To Integer Conversion Macro) */
+AcpiAml acpi_eisaid(const char *str)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    uint32_t id;
+
+    g_assert(strlen(str) == 7);
+    id = (str[0] - 0x40) << 26 |
+    (str[1] - 0x40) << 21 |
+    (str[2] - 0x40) << 16 |
+    Hex2Digit(str[3]) << 12 |
+    Hex2Digit(str[4]) << 8 |
+    Hex2Digit(str[5]) << 4 |
+    Hex2Digit(str[6]);
+
+    build_append_byte(var.buf, 0x0C); /* DWordPrefix */
+    build_append_value(var.buf, bswap32(id), sizeof(id));
+    return var;
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 753171f..02d5aa8 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -64,6 +64,7 @@ AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2);
 AcpiAml GCC_FMT_ATTR(4, 5)
 acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
                const char *name_format, ...);
+AcpiAml acpi_eisaid(const char *str);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 33/47] pc: acpi-build: drop template patching and CPU hotplug objects dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (31 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 32/47] acpi: add acpi_eisaid() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 34/47] pc: acpi-build: create CPU hotplug IO region dynamically Igor Mammedov
                   ` (14 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

in addition it saves us ~400LOC and makes it
one binary blob less stored in QEMU source
tree by removing need to keep and update
hw/i386/ssdt-proc.hex.generated file there.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/Makefile.objs           |   2 +-
 hw/i386/acpi-build.c            |  94 ++++++++++++----------------
 hw/i386/ssdt-proc.dsl           |  63 -------------------
 hw/i386/ssdt-proc.hex.generated | 134 ----------------------------------------
 4 files changed, 42 insertions(+), 251 deletions(-)
 delete mode 100644 hw/i386/ssdt-proc.dsl
 delete mode 100644 hw/i386/ssdt-proc.hex.generated

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 4509cd1..a1e5aa2 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -8,7 +8,7 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/
 obj-y += kvmvapic.o
 obj-y += acpi-build.o
 hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \
-	hw/i386/ssdt-proc.hex hw/i386/ssdt-misc.hex hw/i386/q35-acpi-dsdt.hex \
+	hw/i386/ssdt-misc.hex hw/i386/q35-acpi-dsdt.hex \
 	hw/i386/ssdt-mem.hex hw/i386/ssdt-tpm.hex
 
 iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 6ae0c81..1245a38 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -510,22 +510,6 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
                  table_data->len - madt_start, 1);
 }
 
-/* Encode a hex value */
-static inline char acpi_get_hex(uint32_t val)
-{
-    val &= 0x0f;
-    return (val <= 9) ? ('0' + val) : ('A' + val - 10);
-}
-
-#include "hw/i386/ssdt-proc.hex"
-
-/* 0x5B 0x83 ProcessorOp PkgLength NameString ProcID */
-#define ACPI_PROC_OFFSET_CPUHEX (*ssdt_proc_name - *ssdt_proc_start + 2)
-#define ACPI_PROC_OFFSET_CPUID1 (*ssdt_proc_name - *ssdt_proc_start + 4)
-#define ACPI_PROC_OFFSET_CPUID2 (*ssdt_proc_id - *ssdt_proc_start)
-#define ACPI_PROC_SIZEOF (*ssdt_proc_end - *ssdt_proc_start)
-#define ACPI_PROC_AML (ssdp_proc_aml + *ssdt_proc_start)
-
 #include "hw/i386/ssdt-mem.hex"
 
 /* 0x5B 0x82 DeviceOp PkgLength NameString DimmID */
@@ -760,7 +744,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     int ssdt_start = table_data->len;
     AcpiAml table_aml = { .buf = table_data };
     uint8_t *ssdt_ptr;
-    AcpiAml pkg, scope, dev, method, crs, field;
+    AcpiAml pkg, scope, dev, method, crs, field, ifctx;
     int i;
 
     /* The current AML generator can cover the APIC ID range [0..255],
@@ -841,50 +825,54 @@ build_ssdt(GArray *table_data, GArray *linker,
 
         /* build Processor object for each processor */
         for (i = 0; i < acpi_cpus; i++) {
-            uint8_t *proc = acpi_data_push(sb_scope.buf, ACPI_PROC_SIZEOF);
-            memcpy(proc, ACPI_PROC_AML, ACPI_PROC_SIZEOF);
-            proc[ACPI_PROC_OFFSET_CPUHEX] = acpi_get_hex(i >> 4);
-            proc[ACPI_PROC_OFFSET_CPUHEX+1] = acpi_get_hex(i);
-            proc[ACPI_PROC_OFFSET_CPUID1] = i;
-            proc[ACPI_PROC_OFFSET_CPUID2] = i;
+            dev = acpi_processor(i, 0, 0, "CP%.02X", i);
+
+            method = acpi_method("_MAT", 0);
+            aml_append(&method, acpi_return(acpi_call1("CPMA", acpi_int(i))));
+            aml_append(&dev, method);
+
+            method = acpi_method("_STA", 0);
+            aml_append(&method, acpi_return(acpi_call1("CPST", acpi_int(i))));
+            aml_append(&dev, method);
+
+            method = acpi_method("_EJ0", 1);
+            aml_append(&method,
+                acpi_return(acpi_call2("CPEJ", acpi_int(i), acpi_arg0()))
+            );
+            aml_append(&dev, method);
+
+            aml_append(&sb_scope, dev);
         }
 
         /* build this code:
          *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
          */
         /* Arg0 = Processor ID = APIC ID */
-        build_append_notify_method(sb_scope.buf, "NTFY", "CP%0.02X", acpi_cpus);
-
-        /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */
-        build_append_byte(sb_scope.buf, 0x08); /* NameOp */
-        build_append_namestring(sb_scope.buf, "CPON");
-
-        {
-            GArray *package = build_alloc_array();
-            uint8_t op;
-
-            /*
-             * Note: The ability to create variable-sized packages was first introduced in ACPI 2.0. ACPI 1.0 only
-             * allowed fixed-size packages with up to 255 elements.
-             * Windows guests up to win2k8 fail when VarPackageOp is used.
-             */
-            if (acpi_cpus <= 255) {
-                op = 0x12; /* PackageOp */
-                build_append_byte(package, acpi_cpus); /* NumElements */
-            } else {
-                op = 0x13; /* VarPackageOp */
-                build_append_int(package, acpi_cpus); /* VarNumElements */
-            }
-
-            for (i = 0; i < acpi_cpus; i++) {
-                uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;
-                build_append_byte(package, b);
-            }
+        method = acpi_method("NTFY", 2);
+        for (i = 0; i < acpi_cpus; i++) {
+            ifctx = acpi_if(acpi_equal(acpi_arg0(), acpi_int(i)));
+            aml_append(&ifctx,
+                acpi_notify(acpi_name("CP%.02X", i), acpi_arg1())
+            );
+            aml_append(&method, ifctx);
+        }
+        aml_append(&sb_scope, method);
+
+        /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
+         *
+         * Note: The ability to create variable-sized packages was first
+         * ntroduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
+         * ith up to 255 elements. Windows guests up to win2k8 fail when
+         * VarPackageOp is used.
+         */
+        pkg = acpi_cpus <= 255 ? acpi_package(acpi_cpus) :
+                                 acpi_varpackage(acpi_cpus);
 
-            build_package(package, op);
-            build_append_array(sb_scope.buf, package);
-            build_free_array(package);
+        for (i = 0; i < acpi_cpus; i++) {
+            uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;
+            aml_append(&pkg, acpi_int(b));
         }
+        aml_append(&sb_scope, acpi_name_decl("CPON", pkg));
 
         if (nr_mem) {
             assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
diff --git a/hw/i386/ssdt-proc.dsl b/hw/i386/ssdt-proc.dsl
deleted file mode 100644
index 8229bfd..0000000
--- a/hw/i386/ssdt-proc.dsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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/>.
- */
-
-/* This file is the basis for the ssdt table generated in src/acpi.c.
- * It defines the contents of the per-cpu Processor() object.  At
- * runtime, a dynamically generated SSDT will contain one copy of this
- * AML snippet for every possible cpu in the system.  The objects will
- * be placed in the \_SB_ namespace.
- *
- * In addition to the aml code generated from this file, the
- * src/acpi.c file creates a NTFY method with an entry for each cpu:
- *     Method(NTFY, 2) {
- *         If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) }
- *         If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) }
- *         ...
- *     }
- * and a CPON array with the list of active and inactive cpus:
- *     Name(CPON, Package() { One, One, ..., Zero, Zero, ... })
- */
-
-ACPI_EXTRACT_ALL_CODE ssdp_proc_aml
-
-DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1)
-{
-    ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start
-    ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end
-    ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name
-    Processor(CPAA, 0xAA, 0x00000000, 0x0) {
-        ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id
-        Name(ID, 0xAA)
-/*
- * The src/acpi.c code requires the above ACP_EXTRACT tags so that it can update
- * CPAA and 0xAA with the appropriate CPU id (see
- * SD_OFFSET_CPUHEX/CPUID1/CPUID2).  Don't change the above without
- * also updating the C code.
- */
-        Name(_HID, "ACPI0007")
-        External(CPMA, MethodObj)
-        External(CPST, MethodObj)
-        External(CPEJ, MethodObj)
-        Method(_MAT, 0) {
-            Return (CPMA(ID))
-        }
-        Method(_STA, 0) {
-            Return (CPST(ID))
-        }
-        Method(_EJ0, 1, NotSerialized) {
-            CPEJ(ID, Arg0)
-        }
-    }
-}
diff --git a/hw/i386/ssdt-proc.hex.generated b/hw/i386/ssdt-proc.hex.generated
deleted file mode 100644
index 4df0734..0000000
--- a/hw/i386/ssdt-proc.hex.generated
+++ /dev/null
@@ -1,134 +0,0 @@
-static unsigned char ssdt_proc_name[] = {
-0x28
-};
-static unsigned char ssdp_proc_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0x78,
-0x0,
-0x0,
-0x0,
-0x1,
-0x7d,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x42,
-0x58,
-0x53,
-0x53,
-0x44,
-0x54,
-0x0,
-0x0,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x15,
-0x11,
-0x13,
-0x20,
-0x5b,
-0x83,
-0x42,
-0x5,
-0x43,
-0x50,
-0x41,
-0x41,
-0xaa,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0xa,
-0xaa,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xd,
-0x41,
-0x43,
-0x50,
-0x49,
-0x30,
-0x30,
-0x30,
-0x37,
-0x0,
-0x14,
-0xf,
-0x5f,
-0x4d,
-0x41,
-0x54,
-0x0,
-0xa4,
-0x43,
-0x50,
-0x4d,
-0x41,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0x14,
-0xf,
-0x5f,
-0x53,
-0x54,
-0x41,
-0x0,
-0xa4,
-0x43,
-0x50,
-0x53,
-0x54,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0x14,
-0xf,
-0x5f,
-0x45,
-0x4a,
-0x30,
-0x1,
-0x43,
-0x50,
-0x45,
-0x4a,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0x68
-};
-static unsigned char ssdt_proc_id[] = {
-0x38
-};
-static unsigned char ssdt_proc_end[] = {
-0x78
-};
-static unsigned char ssdt_proc_start[] = {
-0x24
-};
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 34/47] pc: acpi-build: create CPU hotplug IO region dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (32 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 33/47] pc: acpi-build: drop template patching and CPU hotplug objects dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 35/47] acpi: add acpi_reserved_field() term Igor Mammedov
                   ` (13 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

it replaces a static complied in DSDT MMIO region
for CPU hotplug with one created at runtime
leaving only truly static CPU hotplug related ASL
bits in DSDT.
It also puts CPU_HOTPLUG_RESOURCE_DEVICE into
PCI0 scope and reserves resources from it,
preparing for dropping manual hole punching
in PCI0._CRS.

Later it also would make easier to reuse current
ACPI CPU hotplug on other targets.

Also later it would be possible to move remaining
CPU hotplug ASL methods into build_ssdt() and
add all CPU hotplug related AML into SSDT only
when CPU hotplug is enabled, further reducing
ACPI tables blob if CPU hotplug isn't used.

impl. detail:
Windows XP can't handle /BSODs/ OperationRegion
declaration in DSDT when variable from SSDT is used
for specifying its address/length and also when
Field declared in DSDT with OperationRegion from
SSDT if DSDT is being parsed before SSDT.
But it works just fine when referencing named
fields from another table. Hence OperationRegion
and Field declaration are moved to SSDT to make
XP based editions work.

PS:
Later Windows editions seem to be fine with above
conditions.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c              | 27 +++++++++++++++++++++++++++
 hw/i386/acpi-dsdt-cpu-hotplug.dsl | 17 +----------------
 include/hw/acpi/pc-hotplug.h      |  1 +
 3 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 1245a38..09219e0 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -101,6 +101,8 @@ typedef struct AcpiPmInfo {
     uint32_t gpe0_blk;
     uint32_t gpe0_blk_len;
     uint32_t io_base;
+    uint16_t cpu_hp_io_base;
+    uint16_t cpu_hp_io_len;
 } AcpiPmInfo;
 
 typedef struct AcpiMiscInfo {
@@ -177,12 +179,15 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
 
     if (piix) {
         obj = piix;
+        pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
     }
     if (lpc) {
         obj = lpc;
+        pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE;
     }
     assert(obj);
 
+    pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN;
     /* Fill in optional s3/s4 related properties */
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
     if (o) {
@@ -823,6 +828,28 @@ build_ssdt(GArray *table_data, GArray *linker,
     {
         AcpiAml sb_scope = acpi_scope("_SB");
 
+        /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
+        dev = acpi_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
+        aml_append(&dev, acpi_name_decl("_HID", acpi_eisaid("PNP0A06")));
+        aml_append(&dev,
+            acpi_name_decl("_UID", acpi_string("CPU Hotplug resources"))
+        );
+        /* device present, functioning, decoding, not shown in UI */
+        aml_append(&dev, acpi_name_decl("_STA", acpi_int(0xB)));
+        crs = acpi_resource_template();
+        aml_append(&crs,
+            acpi_io(acpi_decode16, pm->cpu_hp_io_base, pm->cpu_hp_io_base,
+                    1, pm->cpu_hp_io_len)
+        );
+        aml_append(&dev, acpi_name_decl("_CRS", crs));
+        aml_append(&sb_scope, dev);
+        /* declare CPU hotplug MMIO region and PRS field to access it */
+        aml_append(&sb_scope, acpi_operation_region(
+            "PRST", acpi_system_io, pm->cpu_hp_io_base, pm->cpu_hp_io_len));
+        field = acpi_field("PRST", acpi_byte_acc);
+        aml_append(&field, acpi_named_field("PRS", 256));
+        aml_append(&sb_scope, field);
+
         /* build Processor object for each processor */
         for (i = 0; i < acpi_cpus; i++) {
             dev = acpi_processor(i, 0, 0, "CP%.02X", i);
diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
index 268d870..1aff746 100644
--- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
@@ -16,12 +16,12 @@
 /****************************************************************
  * CPU hotplug
  ****************************************************************/
-#define CPU_HOTPLUG_RESOURCE_DEVICE PRES
 
 Scope(\_SB) {
     /* Objects filled in by run-time generated SSDT */
     External(NTFY, MethodObj)
     External(CPON, PkgObj)
+    External(PRS, FieldUnitObj)
 
     /* Methods called by run-time generated SSDT Processor objects */
     Method(CPMA, 1, NotSerialized) {
@@ -54,10 +54,6 @@ Scope(\_SB) {
     }
 
 #define CPU_STATUS_LEN ACPI_GPE_PROC_LEN
-    OperationRegion(PRST, SystemIO, CPU_STATUS_BASE, CPU_STATUS_LEN)
-    Field(PRST, ByteAcc, NoLock, Preserve) {
-        PRS, 256
-    }
     Method(PRSC, 0) {
         // Local5 = active cpu bitmap
         Store(PRS, Local5)
@@ -91,15 +87,4 @@ Scope(\_SB) {
             Increment(Local0)
         }
     }
-
-    Device(CPU_HOTPLUG_RESOURCE_DEVICE) {
-        Name(_HID, EisaId("PNP0A06"))
-        Name(_UID, "CPU hotplug resources")
-
-        Name(_CRS, ResourceTemplate() {
-            IO(Decode16, CPU_STATUS_BASE, CPU_STATUS_BASE, 0, CPU_STATUS_LEN)
-        })
-
-        Name(_STA, 0xB) /* present, functioning, decoding, not shown in UI */
-    }
 }
diff --git a/include/hw/acpi/pc-hotplug.h b/include/hw/acpi/pc-hotplug.h
index b9db295..efa6ed7 100644
--- a/include/hw/acpi/pc-hotplug.h
+++ b/include/hw/acpi/pc-hotplug.h
@@ -28,6 +28,7 @@
 
 #define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
 #define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
+#define CPU_HOTPLUG_RESOURCE_DEVICE PRES
 
 #define ACPI_MEMORY_HOTPLUG_IO_LEN 24
 #define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 35/47] acpi: add acpi_reserved_field() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (33 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 34/47] pc: acpi-build: create CPU hotplug IO region dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-02-05 15:36   ` Marcel Apfelbaum
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 36/47] pc: acpi-build: drop template patching and memory hotplug objects dynamically Igor Mammedov
                   ` (12 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 10 ++++++++++
 include/hw/acpi/acpi-build-utils.h |  6 ++++++
 2 files changed, 16 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index cbc1241..644af1f 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -591,6 +591,16 @@ AcpiAml acpi_named_field(const char *name, unsigned length)
     return var;
 }
 
+/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: ReservedField */
+AcpiAml acpi_reserved_field(unsigned length)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    /* ReservedField  := 0x00 PkgLength */
+    build_append_byte(var.buf, 0x00);
+    build_append_pkg_length(var.buf, length, false);
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefField */
 AcpiAml acpi_field(const char *name, acpiFieldFlags flags)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 02d5aa8..048ed26 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -25,7 +25,12 @@ typedef enum {
 } acpiIODecode;
 
 typedef enum {
+    acpi_any_acc = 0,
     acpi_byte_acc = 1,
+    acpi_word_acc = 2,
+    acpi_dword_acc = 3,
+    acpi_qword_acc = 4,
+    acpi_buffer_acc = 5,
 } acpiFieldFlags;
 
 typedef enum {
@@ -58,6 +63,7 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
 AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len);
 AcpiAml acpi_named_field(const char *name, unsigned length);
+AcpiAml acpi_reserved_field(unsigned length);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
 AcpiAml acpi_local0(void);
 AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 36/47] pc: acpi-build: drop template patching and memory hotplug objects dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (34 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 35/47] acpi: add acpi_reserved_field() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 37/47] pc: acpi-build: create memory hotplug IO region dynamically Igor Mammedov
                   ` (11 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

in addition it saves us ~330LOC and makes it one binary blob less
stored in QEMU source tree by removing need to keep and update
hw/i386/ssdt-mem.hex.generated file there.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/Makefile.objs          |   2 +-
 hw/i386/acpi-build.c           | 132 +++++++++----------------
 hw/i386/ssdt-mem.dsl           |  77 ---------------
 hw/i386/ssdt-mem.hex.generated | 213 -----------------------------------------
 4 files changed, 47 insertions(+), 377 deletions(-)
 delete mode 100644 hw/i386/ssdt-mem.dsl
 delete mode 100644 hw/i386/ssdt-mem.hex.generated

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index a1e5aa2..6c8705d 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -9,7 +9,7 @@ obj-y += kvmvapic.o
 obj-y += acpi-build.o
 hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \
 	hw/i386/ssdt-misc.hex hw/i386/q35-acpi-dsdt.hex \
-	hw/i386/ssdt-mem.hex hw/i386/ssdt-tpm.hex
+	hw/i386/ssdt-tpm.hex
 
 iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
     ; then echo "$(2)"; else echo "$(3)"; fi ;)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 09219e0..5e20193 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -282,48 +282,6 @@ build_header(GArray *linker, GArray *table_data,
                                     table_data->data, h, len, &h->checksum);
 }
 
-static GArray *build_alloc_method(const char *name, uint8_t arg_count)
-{
-    GArray *method = build_alloc_array();
-
-    build_append_namestring(method, "%s", name);
-    build_append_byte(method, arg_count); /* MethodFlags: ArgCount */
-
-    return method;
-}
-
-static void build_append_and_cleanup_method(GArray *device, GArray *method)
-{
-    uint8_t op = 0x14; /* MethodOp */
-
-    build_package(method, op);
-
-    build_append_array(device, method);
-    build_free_array(method);
-}
-
-static void build_append_notify_target_ifequal(GArray *method,
-                                               GArray *target_name,
-                                               uint32_t value, int size)
-{
-    GArray *notify = build_alloc_array();
-    uint8_t op = 0xA0; /* IfOp */
-
-    build_append_byte(notify, 0x93); /* LEqualOp */
-    build_append_byte(notify, 0x68); /* Arg0Op */
-    build_append_value(notify, value, size);
-    build_append_byte(notify, 0x86); /* NotifyOp */
-    build_append_array(notify, target_name);
-    build_append_byte(notify, 0x69); /* Arg1Op */
-
-    /* Pack it up */
-    build_package(notify, op);
-
-    build_append_array(method, notify);
-
-    build_free_array(notify);
-}
-
 /* End here */
 #define ACPI_PORT_SMI_CMD           0x00b2 /* TODO: this is APM_CNT_IOPORT */
 
@@ -515,38 +473,12 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
                  table_data->len - madt_start, 1);
 }
 
-#include "hw/i386/ssdt-mem.hex"
-
-/* 0x5B 0x82 DeviceOp PkgLength NameString DimmID */
-#define ACPI_MEM_OFFSET_HEX (*ssdt_mem_name - *ssdt_mem_start + 2)
-#define ACPI_MEM_OFFSET_ID (*ssdt_mem_id - *ssdt_mem_start + 7)
-#define ACPI_MEM_SIZEOF (*ssdt_mem_end - *ssdt_mem_start)
-#define ACPI_MEM_AML (ssdm_mem_aml + *ssdt_mem_start)
-
 #define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */
 #define ACPI_SSDT_HEADER_LENGTH 36
 
 #include "hw/i386/ssdt-misc.hex"
 #include "hw/i386/ssdt-tpm.hex"
 
-static void
-build_append_notify_method(GArray *device, const char *name,
-                           const char *format, int count)
-{
-    int i;
-    GArray *method = build_alloc_method(name, 2);
-
-    for (i = 0; i < count; i++) {
-        GArray *target = build_alloc_array();
-        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);
-    }
-
-    build_append_and_cleanup_method(device, method);
-}
-
 /* Assign BSEL property to all buses.  In the future, this can be changed
  * to only assign to buses that support hotplug.
  */
@@ -901,26 +833,54 @@ build_ssdt(GArray *table_data, GArray *linker,
         }
         aml_append(&sb_scope, acpi_name_decl("CPON", pkg));
 
-        if (nr_mem) {
-            assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
-            /* build memory devices */
-            for (i = 0; i < nr_mem; i++) {
-                char id[3];
-                uint8_t *mem = acpi_data_push(sb_scope.buf, ACPI_MEM_SIZEOF);
-
-                snprintf(id, sizeof(id), "%02X", i);
-                memcpy(mem, ACPI_MEM_AML, ACPI_MEM_SIZEOF);
-                memcpy(mem + ACPI_MEM_OFFSET_HEX, id, 2);
-                memcpy(mem + ACPI_MEM_OFFSET_ID, id, 2);
-            }
+        /* build memory devices */
+        assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
 
-            /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
-             *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
-             */
-            build_append_notify_method(sb_scope.buf,
-                                       stringify(MEMORY_SLOT_NOTIFY_METHOD),
-                                       "MP%0.02X", nr_mem);
+        for (i = 0; i < nr_mem; i++) {
+            #define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "."
+            const char *s;
+
+            dev = acpi_device("MP%02X", i);
+            aml_append(&dev, acpi_name_decl("_UID", acpi_string("0x%02X", i)));
+            aml_append(&dev, acpi_name_decl("_HID", acpi_eisaid("PNP0C80")));
+
+            method = acpi_method("_CRS", 0);
+            s = BASEPATH stringify(MEMORY_SLOT_CRS_METHOD);
+            aml_append(&method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
+            aml_append(&dev, method);
+
+            method = acpi_method("_STA", 0);
+            s = BASEPATH stringify(MEMORY_SLOT_STATUS_METHOD);
+            aml_append(&method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
+            aml_append(&dev, method);
+
+            method = acpi_method("_PXM", 0);
+            s = BASEPATH stringify(MEMORY_SLOT_PROXIMITY_METHOD);
+            aml_append(&method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
+            aml_append(&dev, method);
+
+            method = acpi_method("_OST", 3);
+            s = BASEPATH stringify(MEMORY_SLOT_OST_METHOD);
+            aml_append(&method, acpi_return(acpi_call4(
+                s, acpi_name("_UID"), acpi_arg0(), acpi_arg1(), acpi_arg2()
+            )));
+            aml_append(&dev, method);
+
+            aml_append(&sb_scope, dev);
+        }
+
+        /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
+         *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
+         */
+        method = acpi_method(stringify(MEMORY_SLOT_NOTIFY_METHOD), 2);
+        for (i = 0; i < nr_mem; i++) {
+            ifctx = acpi_if(acpi_equal(acpi_arg0(), acpi_int(i)));
+            aml_append(&ifctx,
+                acpi_notify(acpi_name("MP%.02X", i), acpi_arg1())
+            );
+            aml_append(&method, ifctx);
         }
+        aml_append(&sb_scope, method);
 
         {
             Object *pci_host;
diff --git a/hw/i386/ssdt-mem.dsl b/hw/i386/ssdt-mem.dsl
deleted file mode 100644
index 22ff5dd..0000000
--- a/hw/i386/ssdt-mem.dsl
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Memory hotplug ACPI DSDT static objects definitions
- *
- * Copyright ProfitBricks GmbH 2012
- * Copyright (C) 2013-2014 Red Hat Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- */
-
-/* This file is the basis for the ssdt_mem[] variable in src/acpi.c.
- * It defines the contents of the memory device object.  At
- * runtime, a dynamically generated SSDT will contain one copy of this
- * AML snippet for every possible memory device in the system.  The
- * objects will be placed in the \_SB_ namespace.
- *
- * In addition to the aml code generated from this file, the
- * src/acpi.c file creates a MTFY method with an entry for each memdevice:
- *     Method(MTFY, 2) {
- *         If (LEqual(Arg0, 0x00)) { Notify(MP00, Arg1) }
- *         If (LEqual(Arg0, 0x01)) { Notify(MP01, Arg1) }
- *         ...
- *     }
- */
-#include "hw/acpi/pc-hotplug.h"
-
-ACPI_EXTRACT_ALL_CODE ssdm_mem_aml
-
-DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
-{
-
-    External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_CRS_METHOD, MethodObj)
-    External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD, MethodObj)
-    External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD, MethodObj)
-    External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD, MethodObj)
-
-    Scope(\_SB) {
-/*  v------------------ DO NOT EDIT ------------------v */
-        ACPI_EXTRACT_DEVICE_START ssdt_mem_start
-        ACPI_EXTRACT_DEVICE_END ssdt_mem_end
-        ACPI_EXTRACT_DEVICE_STRING ssdt_mem_name
-        Device(MPAA) {
-            ACPI_EXTRACT_NAME_STRING ssdt_mem_id
-            Name(_UID, "0xAA")
-/*  ^------------------ DO NOT EDIT ------------------^
- * Don't change the above without also updating the C code.
- */
-            Name(_HID, EISAID("PNP0C80"))
-
-            Method(_CRS, 0) {
-                Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_CRS_METHOD(_UID))
-            }
-
-            Method(_STA, 0) {
-                Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD(_UID))
-            }
-
-            Method(_PXM, 0) {
-                Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD(_UID))
-            }
-
-            Method(_OST, 3) {
-                \_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD(_UID, Arg0, Arg1, Arg2)
-            }
-        }
-    }
-}
diff --git a/hw/i386/ssdt-mem.hex.generated b/hw/i386/ssdt-mem.hex.generated
deleted file mode 100644
index b3bfbbd..0000000
--- a/hw/i386/ssdt-mem.hex.generated
+++ /dev/null
@@ -1,213 +0,0 @@
-static unsigned char ssdt_mem_id[] = {
-0x35
-};
-static unsigned char ssdm_mem_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0xc7,
-0x0,
-0x0,
-0x0,
-0x2,
-0x66,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x43,
-0x53,
-0x53,
-0x44,
-0x54,
-0x0,
-0x0,
-0x0,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x28,
-0x8,
-0x14,
-0x20,
-0x10,
-0x42,
-0xa,
-0x5c,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x5b,
-0x82,
-0x49,
-0x9,
-0x4d,
-0x50,
-0x41,
-0x41,
-0x8,
-0x5f,
-0x55,
-0x49,
-0x44,
-0xd,
-0x30,
-0x78,
-0x41,
-0x41,
-0x0,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xc,
-0x41,
-0xd0,
-0xc,
-0x80,
-0x14,
-0x1e,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x0,
-0xa4,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x43,
-0x52,
-0x53,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x14,
-0x1e,
-0x5f,
-0x53,
-0x54,
-0x41,
-0x0,
-0xa4,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x52,
-0x53,
-0x54,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x14,
-0x1e,
-0x5f,
-0x50,
-0x58,
-0x4d,
-0x0,
-0xa4,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x50,
-0x58,
-0x4d,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x14,
-0x20,
-0x5f,
-0x4f,
-0x53,
-0x54,
-0x3,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x4f,
-0x53,
-0x54,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x68,
-0x69,
-0x6a
-};
-static unsigned char ssdt_mem_start[] = {
-0x2c
-};
-static unsigned char ssdt_mem_end[] = {
-0xc7
-};
-static unsigned char ssdt_mem_name[] = {
-0x30
-};
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 37/47] pc: acpi-build: create memory hotplug IO region dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (35 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 36/47] pc: acpi-build: drop template patching and memory hotplug objects dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms Igor Mammedov
                   ` (10 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

it replaces a static complied in DSDT MMIO region
for memory hotplug with one created at runtime
leaving only truly static memory hotplug related
ASL bits in DSDT. And replaces template patching
of MEMORY_SLOTS_NUMBER value with ASL API created
named value.

Later it also would make easier to reuse current
ACPI memory hotplug on other targets.

Also later it would be possible to move remaining
memory hotplug ASL methods into build_ssdt() and
add all memory hotplug related AML into SSDT only
when memory hotplug is enabled, further reducing
ACPI tables blob if memory hotplug isn't used.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c              | 57 ++++++++++++++++++++++++++++++++++++---
 hw/i386/acpi-dsdt-mem-hotplug.dsl | 36 +++++++------------------
 hw/i386/ssdt-misc.dsl             |  2 --
 3 files changed, 64 insertions(+), 31 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 5e20193..b26bc6d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -103,6 +103,8 @@ typedef struct AcpiPmInfo {
     uint32_t io_base;
     uint16_t cpu_hp_io_base;
     uint16_t cpu_hp_io_len;
+    uint16_t mem_hp_io_base;
+    uint16_t mem_hp_io_len;
 } AcpiPmInfo;
 
 typedef struct AcpiMiscInfo {
@@ -188,6 +190,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     assert(obj);
 
     pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN;
+    pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
+    pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN;
+
     /* Fill in optional s3/s4 related properties */
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
     if (o) {
@@ -695,9 +700,6 @@ build_ssdt(GArray *table_data, GArray *linker,
 
     patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
 
-    ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
-                      ssdt_mctrl_nr_slots[0], 32, nr_mem);
-
     /*  create S3_ / S4_ / S5_ packages if necessary */
     scope = acpi_scope("\\");
     if (!pm->s3_disabled) {
@@ -835,6 +837,55 @@ build_ssdt(GArray *table_data, GArray *linker,
 
         /* build memory devices */
         assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
+        scope = acpi_scope("\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE));
+        aml_append(&scope,
+            acpi_name_decl(stringify(MEMORY_SLOTS_NUMBER), acpi_int(nr_mem))
+        );
+
+        crs = acpi_resource_template();
+        aml_append(&crs,
+            acpi_io(acpi_decode16, pm->mem_hp_io_base, pm->mem_hp_io_base,
+                    0, pm->mem_hp_io_len)
+        );
+        aml_append(&scope, acpi_name_decl("_CRS", crs));
+
+        aml_append(&scope, acpi_operation_region(
+            stringify(MEMORY_HOTPLUG_IO_REGION), acpi_system_io,
+            pm->mem_hp_io_base, pm->mem_hp_io_len)
+        );
+
+        field = acpi_field(stringify(MEMORY_HOTPLUG_IO_REGION), acpi_dword_acc);
+        aml_append(&field, /* read only */
+            acpi_named_field(stringify(MEMORY_SLOT_ADDR_LOW), 32));
+        aml_append(&field, /* read only */
+            acpi_named_field(stringify(MEMORY_SLOT_ADDR_HIGH), 32));
+        aml_append(&field, /* read only */
+            acpi_named_field(stringify(MEMORY_SLOT_SIZE_LOW), 32));
+        aml_append(&field, /* read only */
+            acpi_named_field(stringify(MEMORY_SLOT_SIZE_HIGH), 32));
+        aml_append(&field, /* read only */
+            acpi_named_field(stringify(MEMORY_SLOT_PROXIMITY), 32));
+        aml_append(&scope, field);
+
+        field = acpi_field(stringify(MEMORY_HOTPLUG_IO_REGION), acpi_byte_acc);
+        aml_append(&field, acpi_reserved_field(160 /* Offset(20) */));
+        aml_append(&field, /* 1 if enabled, read only */
+            acpi_named_field(stringify(MEMORY_SLOT_ENABLED), 1));
+        aml_append(&field,
+            /*(read) 1 if has a insert event. (write) 1 to clear event */
+            acpi_named_field(stringify(MEMORY_SLOT_INSERT_EVENT), 1));
+        aml_append(&scope, field);
+
+        field = acpi_field(stringify(MEMORY_HOTPLUG_IO_REGION), acpi_dword_acc);
+        aml_append(&field, /* DIMM selector, write only */
+            acpi_named_field(stringify(MEMORY_SLOT_SLECTOR), 32));
+        aml_append(&field, /* _OST event code, write only */
+            acpi_named_field(stringify(MEMORY_SLOT_OST_EVENT), 32));
+        aml_append(&field, /* _OST status code, write only */
+            acpi_named_field(stringify(MEMORY_SLOT_OST_STATUS), 32));
+        aml_append(&scope, field);
+
+        aml_append(&sb_scope, scope);
 
         for (i = 0; i < nr_mem; i++) {
             #define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "."
diff --git a/hw/i386/acpi-dsdt-mem-hotplug.dsl b/hw/i386/acpi-dsdt-mem-hotplug.dsl
index 2a36c47..1e9ec39 100644
--- a/hw/i386/acpi-dsdt-mem-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-mem-hotplug.dsl
@@ -22,14 +22,16 @@
             External(MEMORY_SLOTS_NUMBER, IntObj)
 
             /* Memory hotplug IO registers */
-            OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
-                            ACPI_MEMORY_HOTPLUG_BASE,
-                            ACPI_MEMORY_HOTPLUG_IO_LEN)
-
-            Name(_CRS, ResourceTemplate() {
-                IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
-                   0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
-            })
+            External(MEMORY_SLOT_ADDR_LOW, FieldUnitObj) // read only
+            External(MEMORY_SLOT_ADDR_HIGH, FieldUnitObj) // read only
+            External(MEMORY_SLOT_SIZE_LOW, FieldUnitObj) // read only
+            External(MEMORY_SLOT_SIZE_HIGH, FieldUnitObj) // read only
+            External(MEMORY_SLOT_PROXIMITY, FieldUnitObj) // read only
+            External(MEMORY_SLOT_ENABLED, FieldUnitObj) // 1 if enabled, read only
+            External(MEMORY_SLOT_INSERT_EVENT, FieldUnitObj) // (read) 1 if has a insert event. (write) 1 to clear event
+            External(MEMORY_SLOT_SLECTOR, FieldUnitObj) // DIMM selector, write only
+            External(MEMORY_SLOT_OST_EVENT, FieldUnitObj) // _OST event code, write only
+            External(MEMORY_SLOT_OST_STATUS, FieldUnitObj) // _OST status code, write only
 
             Method(_STA, 0) {
                 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
@@ -39,25 +41,7 @@
                 Return(0xB)
             }
 
-            Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
-                MEMORY_SLOT_ADDR_LOW, 32,  // read only
-                MEMORY_SLOT_ADDR_HIGH, 32, // read only
-                MEMORY_SLOT_SIZE_LOW, 32,  // read only
-                MEMORY_SLOT_SIZE_HIGH, 32, // read only
-                MEMORY_SLOT_PROXIMITY, 32, // read only
-            }
-            Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
-                Offset(20),
-                MEMORY_SLOT_ENABLED,  1, // 1 if enabled, read only
-                MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
-            }
-
             Mutex (MEMORY_SLOT_LOCK, 0)
-            Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
-                MEMORY_SLOT_SLECTOR, 32,  // DIMM selector, write only
-                MEMORY_SLOT_OST_EVENT, 32,  // _OST event code, write only
-                MEMORY_SLOT_OST_STATUS, 32,  // _OST status code, write only
-            }
 
             Method(MEMORY_SLOT_SCAN_METHOD, 0) {
                 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
index 81be858..2588e30 100644
--- a/hw/i386/ssdt-misc.dsl
+++ b/hw/i386/ssdt-misc.dsl
@@ -36,7 +36,5 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
        Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
        ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
        Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
-       ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
-       Name(MEMORY_SLOTS_NUMBER, 0x12345678)
     }
 }
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (36 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 37/47] pc: acpi-build: create memory hotplug IO region dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-02-05 15:38   ` Marcel Apfelbaum
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 39/47] pc: pcihp: expose MMIO base and len as properties Igor Mammedov
                   ` (9 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 143 +++++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  73 +++++++++++++++++++
 2 files changed, 216 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 644af1f..b19d370 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -700,3 +700,146 @@ AcpiAml acpi_eisaid(const char *str)
     build_append_value(var.buf, bswap32(id), sizeof(id));
     return var;
 }
+
+/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
+static AcpiAml
+acpi_as_desc_header(acpiResourceType type, acpiMinFixed min_fixed,
+                    acpiMaxFixed max_fixed, acpiDecode dec, uint8_t type_flags)
+{
+    uint8_t flags = max_fixed | min_fixed | dec;
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+
+    build_append_byte(var.buf, type);
+    build_append_byte(var.buf, flags);
+    build_append_byte(var.buf, type_flags); /* Type Specific Flags */
+    return var;
+}
+
+/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
+static AcpiAml acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
+                                 acpiMaxFixed max_fixed, acpiDecode dec,
+                                 uint16_t addr_gran, uint16_t addr_min,
+                                 uint16_t addr_max, uint16_t addr_trans,
+                                 uint16_t len, uint8_t type_flags)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+
+    build_append_byte(var.buf, 0x88); /* Word Address Space Descriptor */
+    /* minimum length since we do not encode optional fields */
+    build_append_byte(var.buf, 0x0D);
+    build_append_byte(var.buf, 0x0);
+
+    aml_append(&var,
+        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
+    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
+    build_append_value(var.buf, addr_min, sizeof(addr_min));
+    build_append_value(var.buf, addr_max, sizeof(addr_max));
+    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
+    build_append_value(var.buf, len, sizeof(len));
+    return var;
+}
+
+/* ACPI 5.0: 6.4.3.5.2 DWord Address Space Descriptor */
+static AcpiAml acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
+                                  acpiMaxFixed max_fixed, acpiDecode dec,
+                                  uint32_t addr_gran, uint32_t addr_min,
+                                  uint32_t addr_max, uint32_t addr_trans,
+                                  uint32_t len, uint8_t type_flags)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+
+    build_append_byte(var.buf, 0x87); /* DWord Address Space Descriptor */
+    /* minimum length since we do not encode optional fields */
+    build_append_byte(var.buf, 23);
+    build_append_byte(var.buf, 0x0);
+
+
+    aml_append(&var,
+        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
+    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
+    build_append_value(var.buf, addr_min, sizeof(addr_min));
+    build_append_value(var.buf, addr_max, sizeof(addr_max));
+    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
+    build_append_value(var.buf, len, sizeof(len));
+    return var;
+}
+
+/* ACPI 5.0: 6.4.3.5.1 QWord Address Space Descriptor */
+static AcpiAml acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
+                                  acpiMaxFixed max_fixed, acpiDecode dec,
+                                  uint64_t addr_gran, uint64_t addr_min,
+                                  uint64_t addr_max, uint64_t addr_trans,
+                                  uint64_t len, uint8_t type_flags)
+{
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+
+    build_append_byte(var.buf, 0x8A); /* QWord Address Space Descriptor */
+    /* minimum length since we do not encode optional fields */
+    build_append_byte(var.buf, 0x2B);
+    build_append_byte(var.buf, 0x0);
+
+    aml_append(&var,
+        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
+    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
+    build_append_value(var.buf, addr_min, sizeof(addr_min));
+    build_append_value(var.buf, addr_max, sizeof(addr_max));
+    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
+    build_append_value(var.buf, len, sizeof(len));
+    return var;
+}
+
+/*
+ * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
+ */
+AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+                             acpiDecode dec, uint16_t addr_gran,
+                             uint16_t addr_min, uint16_t addr_max,
+                             uint16_t addr_trans, uint16_t len)
+
+{
+    return acpi_word_as_desc(acpi_bus_number_range, min_fixed, max_fixed, dec,
+                             addr_gran, addr_min, addr_max, addr_trans, len, 0);
+}
+
+/* ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro) */
+AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+                     acpiDecode dec, acpiISARanges isa_ranges,
+                     uint16_t addr_gran, uint16_t addr_min,
+                     uint16_t addr_max, uint16_t addr_trans,
+                     uint16_t len)
+
+{
+    return acpi_word_as_desc(acpi_io_range, min_fixed, max_fixed, dec,
+                             addr_gran, addr_min, addr_max, addr_trans, len,
+                             isa_ranges);
+}
+
+/* ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro) */
+AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
+                          acpiReadAndWrite read_and_write,
+                          uint32_t addr_gran, uint32_t addr_min,
+                          uint32_t addr_max, uint32_t addr_trans,
+                          uint32_t len)
+{
+    uint8_t flags = read_and_write | (cacheable << 1);
+
+    return acpi_dword_as_desc(acpi_memory_range, min_fixed, max_fixed,
+                              dec, addr_gran, addr_min, addr_max,
+                              addr_trans, len, flags);
+}
+
+/* ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro) */
+AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
+                          acpiReadAndWrite read_and_write,
+                          uint64_t addr_gran, uint64_t addr_min,
+                          uint64_t addr_max, uint64_t addr_trans,
+                          uint64_t len)
+{
+    uint8_t flags = read_and_write | (cacheable << 1);
+
+    return acpi_qword_as_desc(acpi_memory_range, min_fixed, max_fixed,
+                              dec, addr_gran, addr_min, addr_max,
+                              addr_trans, len, flags);
+}
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 048ed26..5e8db3d 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -38,6 +38,58 @@ typedef enum {
     acpi_system_io = 0x01,
 } acpiRegionSpace;
 
+typedef enum {
+    acpi_memory_range = 0,
+    acpi_io_range = 1,
+    acpi_bus_number_range = 2,
+} acpiResourceType;
+
+typedef enum {
+    acpi_sub_decode = 1 << 1,
+    acpi_pos_decode = 0
+} acpiDecode;
+
+typedef enum {
+    acpi_max_fixed = 1 << 3,
+    acpi_max_not_fixed = 0,
+} acpiMaxFixed;
+
+typedef enum {
+    acpi_min_fixed = 1 << 2,
+    acpi_min_not_fixed = 0
+} acpiMinFixed;
+
+/*
+ * ACPI 5.0: Table 6-185 I/O Resource Flag (Resource Type = 1) Definitions
+ * _RNG field definition
+ */
+typedef enum {
+    acpi_isa_only = 1,
+    acpi_non_isa_only = 2,
+    acpi_entire_range = 3,
+} acpiISARanges;
+
+/*
+ * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
+ * _MEM field definition
+ */
+typedef enum {
+    acpi_non_cacheable = 0,
+    acpi_cacheable = 1,
+    acpi_write_combining = 2,
+    acpi_prefetchable = 3,
+} acpiCacheble;
+
+/*
+ * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
+ * _RW field definition
+ */
+typedef enum {
+    acpi_ReadOnly = 0,
+    acpi_ReadWrite = 1,
+} acpiReadAndWrite;
+
+
 void aml_append(AcpiAml *parent_ctx, AcpiAml child);
 
 /* non block ASL object primitives */
@@ -71,6 +123,27 @@ AcpiAml GCC_FMT_ATTR(4, 5)
 acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
                const char *name_format, ...);
 AcpiAml acpi_eisaid(const char *str);
+AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+                             acpiDecode dec, uint16_t addr_gran,
+                             uint16_t addr_min, uint16_t addr_max,
+                             uint16_t addr_trans, uint16_t len);
+AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+                     acpiDecode dec, acpiISARanges isa_ranges,
+                     uint16_t addr_gran, uint16_t addr_min,
+                     uint16_t addr_max, uint16_t addr_trans,
+                     uint16_t len);
+AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
+                          acpiReadAndWrite read_and_write,
+                          uint32_t addr_gran, uint32_t addr_min,
+                          uint32_t addr_max, uint32_t addr_trans,
+                          uint32_t len);
+AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
+                          acpiReadAndWrite read_and_write,
+                          uint64_t addr_gran, uint64_t addr_min,
+                          uint64_t addr_max, uint64_t addr_trans,
+                          uint64_t len);
 
 /* Block ASL object primitives */
 AcpiAml acpi_if(AcpiAml predicate);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 39/47] pc: pcihp: expose MMIO base and len as properties
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (37 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 40/47] pc: acpi-build: reserve PCIHP MMIO resources Igor Mammedov
                   ` (8 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

it will be used later to dynamically reserve MMIO region
instead of manually punching holes in PCI0._CRS

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/pcihp.c         | 18 ++++++++++++------
 hw/acpi/piix4.c         |  2 +-
 include/hw/acpi/pcihp.h |  7 ++++++-
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 34dedf1..612fec0 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -297,10 +297,11 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
     },
 };
 
-void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus,
+void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
                      MemoryRegion *address_space_io, bool bridges_enabled)
 {
-    uint16_t io_size = ACPI_PCIHP_SIZE;
+    s->io_len = ACPI_PCIHP_SIZE;
+    s->io_base = ACPI_PCIHP_ADDR;
 
     s->root= root_bus;
     s->legacy_piix = !bridges_enabled;
@@ -308,16 +309,21 @@ void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus,
     if (s->legacy_piix) {
         unsigned *bus_bsel = g_malloc(sizeof *bus_bsel);
 
-        io_size = ACPI_PCIHP_LEGACY_SIZE;
+        s->io_len = ACPI_PCIHP_LEGACY_SIZE;
 
         *bus_bsel = ACPI_PCIHP_BSEL_DEFAULT;
         object_property_add_uint32_ptr(OBJECT(root_bus), ACPI_PCIHP_PROP_BSEL,
                                        bus_bsel, NULL);
     }
 
-    memory_region_init_io(&s->io, NULL, &acpi_pcihp_io_ops, s,
-                          "acpi-pci-hotplug", io_size);
-    memory_region_add_subregion(address_space_io, ACPI_PCIHP_ADDR, &s->io);
+    memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
+                          "acpi-pci-hotplug", s->io_len);
+    memory_region_add_subregion(address_space_io, s->io_base, &s->io);
+
+    object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
+                                   &error_abort);
+    object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len,
+                                   &error_abort);
 }
 
 const VMStateDescription vmstate_acpi_pcihp_pci_status = {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 481a16c..757f7d8 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -556,7 +556,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                           "acpi-gpe0", GPE_LEN);
     memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
 
-    acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
+    acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent,
                     s->use_acpi_pci_hotplug);
 
     acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 9323838..f3526d4 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -32,6 +32,9 @@
 #include "hw/acpi/acpi.h"
 #include "migration/vmstate.h"
 
+#define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
+#define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len"
+
 typedef struct AcpiPciHpPciStatus {
     uint32_t up;
     uint32_t down;
@@ -48,9 +51,11 @@ typedef struct AcpiPciHpState {
     PCIBus *root;
     MemoryRegion io;
     bool legacy_piix;
+    uint16_t io_base;
+    uint16_t io_len;
 } AcpiPciHpState;
 
-void acpi_pcihp_init(AcpiPciHpState *, PCIBus *root,
+void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
                      MemoryRegion *address_space_io, bool bridges_enabled);
 
 void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 40/47] pc: acpi-build: reserve PCIHP MMIO resources
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (38 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 39/47] pc: pcihp: expose MMIO base and len as properties Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 41/47] pc: acpi-build: create PCI0._CRS dynamically Igor Mammedov
                   ` (7 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b26bc6d..a09bf28 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -105,6 +105,8 @@ typedef struct AcpiPmInfo {
     uint16_t cpu_hp_io_len;
     uint16_t mem_hp_io_base;
     uint16_t mem_hp_io_len;
+    uint16_t pcihp_io_base;
+    uint16_t pcihp_io_len;
 } AcpiPmInfo;
 
 typedef struct AcpiMiscInfo {
@@ -182,6 +184,10 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     if (piix) {
         obj = piix;
         pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
+        pm->pcihp_io_base =
+            object_property_get_int(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
+        pm->pcihp_io_len =
+            object_property_get_int(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
     }
     if (lpc) {
         obj = lpc;
@@ -700,6 +706,25 @@ build_ssdt(GArray *table_data, GArray *linker,
 
     patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
 
+    scope = acpi_scope("\\_SB.PCI0");
+    /* reserve PCIHP resources */
+    if (pm->pcihp_io_len) {
+        dev = acpi_device("PHPR");
+        aml_append(&dev, acpi_name_decl("_HID", acpi_string("PNP0A06")));
+        aml_append(&dev,
+            acpi_name_decl("_UID", acpi_string("PCI Hotplug resources")));
+        /* device present, functioning, decoding, not shown in UI */
+        aml_append(&dev, acpi_name_decl("_STA", acpi_int(0xB)));
+        crs = acpi_resource_template();
+        aml_append(&crs,
+            acpi_io(acpi_decode16, pm->pcihp_io_base, pm->pcihp_io_base,
+                    1, pm->pcihp_io_len)
+        );
+        aml_append(&dev, acpi_name_decl("_CRS", crs));
+        aml_append(&scope, dev);
+    }
+    aml_append(&table_aml, scope);
+
     /*  create S3_ / S4_ / S5_ packages if necessary */
     scope = acpi_scope("\\");
     if (!pm->s3_disabled) {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 41/47] pc: acpi-build: create PCI0._CRS dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (39 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 40/47] pc: acpi-build: reserve PCIHP MMIO resources Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term Igor Mammedov
                   ` (6 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Replace template patching and runtime
calculation in _CRS() method with static _CRS
defined in SSDT.

It also drops manual hole patching for reserved
PCI/MEM/CPU hoptlug MMIO resources and utilizes
the fact that MMIO resources are reserved by
respective child /i.e. PHPR, MHPD, PRES/ containers.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c          | 71 ++++++++++++++++-----------------
 hw/i386/acpi-dsdt-pci-crs.dsl | 92 -------------------------------------------
 hw/i386/acpi-dsdt.dsl         | 45 ---------------------
 hw/i386/q35-acpi-dsdt.dsl     | 18 ---------
 hw/i386/ssdt-misc.dsl         | 19 ---------
 5 files changed, 34 insertions(+), 211 deletions(-)
 delete mode 100644 hw/i386/acpi-dsdt-pci-crs.dsl

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a09bf28..4572c21 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -319,24 +319,6 @@ static void acpi_align_size(GArray *blob, unsigned align)
     g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
 }
 
-/* Set a value within table in a safe manner */
-#define ACPI_BUILD_SET_LE(table, size, off, bits, val) \
-    do { \
-        uint64_t ACPI_BUILD_SET_LE_val = cpu_to_le64(val); \
-        memcpy(acpi_data_get_ptr(table, size, off, \
-                                 (bits) / BITS_PER_BYTE), \
-               &ACPI_BUILD_SET_LE_val, \
-               (bits) / BITS_PER_BYTE); \
-    } while (0)
-
-static inline void *acpi_data_get_ptr(uint8_t *table_data, unsigned table_size,
-                                      unsigned off, unsigned size)
-{
-    assert(off + size > off);
-    assert(off + size <= table_size);
-    return table_data + off;
-}
-
 static inline void acpi_add_table(GArray *table_offsets, GArray *table_data)
 {
     uint32_t offset = cpu_to_le32(table_data->len);
@@ -665,22 +647,6 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
     aml_append(parent_scope, method);
 }
 
-static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
-{
-    ACPI_BUILD_SET_LE(start, size, acpi_pci32_start[0], 32, pci->w32.begin);
-
-    ACPI_BUILD_SET_LE(start, size, acpi_pci32_end[0], 32, pci->w32.end - 1);
-
-    if (pci->w64.end || pci->w64.begin) {
-        ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 1);
-        ACPI_BUILD_SET_LE(start, size, acpi_pci64_start[0], 64, pci->w64.begin);
-        ACPI_BUILD_SET_LE(start, size, acpi_pci64_end[0], 64, pci->w64.end - 1);
-        ACPI_BUILD_SET_LE(start, size, acpi_pci64_length[0], 64, pci->w64.end - pci->w64.begin);
-    } else {
-        ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 0);
-    }
-}
-
 static void
 build_ssdt(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
@@ -700,13 +666,44 @@ build_ssdt(GArray *table_data, GArray *linker,
     QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
     g_assert(acpi_cpus <= ACPI_CPU_HOTPLUG_ID_LIMIT);
 
-    /* Copy header and ssdt template and patch values */
+    /* Copy SSDT  header */
     ssdt_ptr = acpi_data_push(table_data, sizeof(ssdp_misc_aml));
     memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));
 
-    patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
-
     scope = acpi_scope("\\_SB.PCI0");
+    /* build PCI0._CRS */
+    crs = acpi_resource_template();
+    aml_append(&crs,
+        acpi_word_bus_number(acpi_min_fixed, acpi_max_fixed, acpi_pos_decode,
+                             0x0000, 0x0000, 0x00FF, 0x0000, 0x0100));
+    aml_append(&crs, acpi_io(acpi_decode16, 0x0CF8, 0x0CF8, 0x01, 0x08));
+
+    aml_append(&crs,
+        acpi_word_io(acpi_min_fixed, acpi_max_fixed,
+                     acpi_pos_decode, acpi_entire_range,
+                     0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));
+    aml_append(&crs,
+        acpi_word_io(acpi_min_fixed, acpi_max_fixed,
+                     acpi_pos_decode, acpi_entire_range,
+                     0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300));
+    aml_append(&crs,
+        acpi_dword_memory(acpi_pos_decode, acpi_min_fixed, acpi_max_fixed,
+                          acpi_cacheable, acpi_ReadWrite,
+                          0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));
+    aml_append(&crs,
+        acpi_dword_memory(acpi_pos_decode, acpi_min_fixed, acpi_max_fixed,
+                          acpi_non_cacheable, acpi_ReadWrite,
+                          0, pci->w32.begin, pci->w32.end - 1, 0,
+                          pci->w32.end - pci->w32.begin));
+    if (pci->w64.begin) {
+        aml_append(&crs,
+            acpi_qword_memory(acpi_pos_decode, acpi_min_fixed, acpi_max_fixed,
+                              acpi_cacheable, acpi_ReadWrite,
+                              0, pci->w64.begin, pci->w64.end - 1, 0,
+                              pci->w64.end - pci->w64.begin));
+    }
+    aml_append(&scope, acpi_name_decl("_CRS", crs));
+
     /* reserve PCIHP resources */
     if (pm->pcihp_io_len) {
         dev = acpi_device("PHPR");
diff --git a/hw/i386/acpi-dsdt-pci-crs.dsl b/hw/i386/acpi-dsdt-pci-crs.dsl
deleted file mode 100644
index 4648e90..0000000
--- a/hw/i386/acpi-dsdt-pci-crs.dsl
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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/>.
- */
-
-/* PCI CRS (current resources) definition. */
-Scope(\_SB.PCI0) {
-
-    Name(CRES, ResourceTemplate() {
-        WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
-            0x0000,             // Address Space Granularity
-            0x0000,             // Address Range Minimum
-            0x00FF,             // Address Range Maximum
-            0x0000,             // Address Translation Offset
-            0x0100,             // Address Length
-            ,, )
-        IO(Decode16,
-            0x0CF8,             // Address Range Minimum
-            0x0CF8,             // Address Range Maximum
-            0x01,               // Address Alignment
-            0x08,               // Address Length
-            )
-        BOARD_SPECIFIC_PCI_RESOURSES
-        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
-            0x00000000,         // Address Space Granularity
-            0x000A0000,         // Address Range Minimum
-            0x000BFFFF,         // Address Range Maximum
-            0x00000000,         // Address Translation Offset
-            0x00020000,         // Address Length
-            ,, , AddressRangeMemory, TypeStatic)
-        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
-            0x00000000,         // Address Space Granularity
-            0xE0000000,         // Address Range Minimum
-            0xFEBFFFFF,         // Address Range Maximum
-            0x00000000,         // Address Translation Offset
-            0x1EC00000,         // Address Length
-            ,, PW32, AddressRangeMemory, TypeStatic)
-    })
-
-    Name(CR64, ResourceTemplate() {
-        QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
-            0x00000000,          // Address Space Granularity
-            0x8000000000,        // Address Range Minimum
-            0xFFFFFFFFFF,        // Address Range Maximum
-            0x00000000,          // Address Translation Offset
-            0x8000000000,        // Address Length
-            ,, PW64, AddressRangeMemory, TypeStatic)
-    })
-
-    Method(_CRS, 0) {
-        /* Fields provided by dynamically created ssdt */
-        External(P0S, IntObj)
-        External(P0E, IntObj)
-        External(P1V, IntObj)
-        External(P1S, BuffObj)
-        External(P1E, BuffObj)
-        External(P1L, BuffObj)
-
-        /* fixup 32bit pci io window */
-        CreateDWordField(CRES, \_SB.PCI0.PW32._MIN, PS32)
-        CreateDWordField(CRES, \_SB.PCI0.PW32._MAX, PE32)
-        CreateDWordField(CRES, \_SB.PCI0.PW32._LEN, PL32)
-        Store(P0S, PS32)
-        Store(P0E, PE32)
-        Store(Add(Subtract(P0E, P0S), 1), PL32)
-
-        If (LEqual(P1V, Zero)) {
-            Return (CRES)
-        }
-
-        /* fixup 64bit pci io window */
-        CreateQWordField(CR64, \_SB.PCI0.PW64._MIN, PS64)
-        CreateQWordField(CR64, \_SB.PCI0.PW64._MAX, PE64)
-        CreateQWordField(CR64, \_SB.PCI0.PW64._LEN, PL64)
-        Store(P1S, PS64)
-        Store(P1E, PE64)
-        Store(P1L, PL64)
-        /* add window and return result */
-        ConcatenateResTemplate(CRES, CR64, Local0)
-        Return (Local0)
-    }
-}
diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
index a611e07..09b68f0 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -31,50 +31,6 @@ DefinitionBlock (
 
 #include "acpi-dsdt-dbug.dsl"
 
-
-/****************************************************************
- * PCI Bus definition
- ****************************************************************/
-#define BOARD_SPECIFIC_PCI_RESOURSES \
-     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-         0x0000, \
-         0x0000, \
-         0x0CF7, \
-         0x0000, \
-         0x0CF8, \
-         ,, , TypeStatic) \
-     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-         0x0000, \
-         0x0D00, \
-         0xADFF, \
-         0x0000, \
-         0xA100, \
-         ,, , TypeStatic) \
-     /* 0xae00-0xae0e hole for PCI hotplug, hw/acpi/piix4.c:PCI_HOTPLUG_ADDR */ \
-     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-         0x0000, \
-         0xAE0F, \
-         0xAEFF, \
-         0x0000, \
-         0x00F1, \
-         ,, , TypeStatic) \
-     /* 0xaf00-0xaf1f hole for CPU hotplug, hw/acpi/piix4.c:PIIX4_PROC_BASE */ \
-     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-         0x0000, \
-         0xAF20, \
-         0xAFDF, \
-         0x0000, \
-         0x00C0, \
-         ,, , TypeStatic) \
-     /* 0xafe0-0xafe3 hole for ACPI.GPE0, hw/acpi/piix4.c:GPE_BASE */ \
-     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-         0x0000, \
-         0xAFE4, \
-         0xFFFF, \
-         0x0000, \
-         0x501C, \
-         ,, , TypeStatic)
-
     Scope(\_SB) {
         Device(PCI0) {
             Name(_HID, EisaId("PNP0A03"))
@@ -85,7 +41,6 @@ DefinitionBlock (
         }
     }
 
-#include "acpi-dsdt-pci-crs.dsl"
 #include "acpi-dsdt-hpet.dsl"
 
 
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
index e1cee5d..3fb4b2f 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -48,23 +48,6 @@ DefinitionBlock (
 /****************************************************************
  * PCI Bus definition
  ****************************************************************/
-#define BOARD_SPECIFIC_PCI_RESOURSES \
-     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-         0x0000, \
-         0x0000, \
-         0x0CD7, \
-         0x0000, \
-         0x0CD8, \
-         ,, , TypeStatic) \
-     /* 0xcd8-0xcf7 hole for CPU hotplug, hw/acpi/ich9.c:ICH9_PROC_BASE */ \
-     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-         0x0000, \
-         0x0D00, \
-         0xFFFF, \
-         0x0000, \
-         0xF300, \
-         ,, , TypeStatic)
-
     Scope(\_SB) {
         Device(PCI0) {
             Name(_HID, EisaId("PNP0A08"))
@@ -131,7 +114,6 @@ DefinitionBlock (
         }
     }
 
-#include "acpi-dsdt-pci-crs.dsl"
 #include "acpi-dsdt-hpet.dsl"
 
 
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
index 2588e30..8d61f21 100644
--- a/hw/i386/ssdt-misc.dsl
+++ b/hw/i386/ssdt-misc.dsl
@@ -18,23 +18,4 @@ ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
 
 DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
 {
-
-/****************************************************************
- * PCI memory ranges
- ****************************************************************/
-
-    Scope(\) {
-       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start
-       Name(P0S, 0x12345678)
-       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end
-       Name(P0E, 0x12345678)
-       ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid
-       Name(P1V, 0x12)
-       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start
-       Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
-       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end
-       Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
-       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
-       Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
-    }
 }
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (40 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 41/47] pc: acpi-build: create PCI0._CRS dynamically Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-29  8:02   ` Shannon Zhao
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 43/47] pc: acpi-build: prepare to make ACPI tables blob opaque for table building functions Igor Mammedov
                   ` (5 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 47 ++++++++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c               |  1 -
 include/hw/acpi/acpi-build-utils.h |  8 +++++++
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index b19d370..58f88cd 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include "hw/acpi/acpi-build-utils.h"
 #include "qemu/bswap.h"
+#include "hw/acpi/bios-linker-loader.h"
 
 GArray *build_alloc_array(void)
 {
@@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
         build_prepend_int(child.buf, child.buf->len);
         build_package(child.buf, child.op);
         break;
+    case DEF_BLOCK: {
+        uint8_t *start = (uint8_t *)parent_ctx->buf->data +
+                         parent_ctx->buf->len;
+        uint32_t le32_len = cpu_to_le32(child.buf->len);
+
+        /* create linker entry for the DefinitionBlock */
+        bios_linker_loader_add_checksum(parent_ctx->linker,
+            ACPI_BUILD_TABLE_FILE,
+            parent_ctx->buf->data,
+            start, child.buf->len, start + 9 /* checksum offset */);
+
+        /* set DefinitionBlock length at TableLength offset*/
+        memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
+        break;
+    }
     default:
         break;
     }
@@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
                               dec, addr_gran, addr_min, addr_max,
                               addr_trans, len, flags);
 }
+
+/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
+AcpiAml acpi_def_block(const char *signature, uint8_t revision,
+                       const char *oem_id, const char *oem_table_id,
+                       uint32_t oem_revision)
+{
+    int len;
+    AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
+
+    assert(strlen(signature) == 4);
+    g_array_append_vals(var.buf, signature, 4);
+    build_append_value(var.buf, 0, 4); /* Length place holder */
+    build_append_byte(var.buf, revision);
+    build_append_byte(var.buf, 0); /* place holder for Checksum */
+
+    len = strlen(oem_id);
+    assert(len <= 6);
+    g_array_append_vals(var.buf, oem_id, len);
+    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
+
+    len = strlen(oem_table_id);
+    assert(len <= 8);
+    g_array_append_vals(var.buf, oem_table_id, len);
+    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
+
+    build_append_value(var.buf, oem_revision, 4);
+    g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
+    build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
+
+    return var;
+}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4572c21..9ff8d72 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -270,7 +270,6 @@ static void acpi_get_pci_info(PcPciInfo *info)
 #define ACPI_BUILD_APPNAME6 "BOCHS "
 #define ACPI_BUILD_APPNAME4 "BXPC"
 
-#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
 #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
 #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
 
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 5e8db3d..868d439 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -11,12 +11,17 @@ typedef enum {
     EXT_PACKAGE,
     BUFFER,
     RES_TEMPLATE,
+    DEF_BLOCK,
 } AcpiBlockFlags;
 
+#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
+#define ACPI_BUILD_APPNAME4 "BXPC"
+
 typedef struct AcpiAml {
     GArray *buf;
     uint8_t op;
     AcpiBlockFlags block_flags;
+    GArray *linker;
 } AcpiAml;
 
 typedef enum {
@@ -146,6 +151,9 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
                           uint64_t len);
 
 /* Block ASL object primitives */
+AcpiAml acpi_def_block(const char *signature, uint8_t revision,
+                       const char *oem_id, const char *oem_table_id,
+                       uint32_t oem_revision);
 AcpiAml acpi_if(AcpiAml predicate);
 AcpiAml acpi_method(const char *name, int arg_count);
 AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 43/47] pc: acpi-build: prepare to make ACPI tables blob opaque for table building functions
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (41 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 44/47] pc: acpi-build: drop remaining ssdt_misc template and use acpi_def_block() Igor Mammedov
                   ` (4 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

it allows to hide linker and direct access to table's
storage from table building function if it would use
acpi_def_block() to declare table and ASL/AML API to
compose it. Which following patch will do for
build_ssdt() function.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
 fix style error, line over 80 chr

PS:
 this series does it only for build_ssdt(), but it also
 could be done for other tables later by using there
 acpi_def_block() to describe table's header and
 adding addtional API to compose table's entries.
---
 hw/i386/acpi-build.c | 86 +++++++++++++++++++++++++++-------------------------
 1 file changed, 44 insertions(+), 42 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9ff8d72..5821528 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1261,7 +1261,7 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
 
 typedef
 struct AcpiBuildTables {
-    GArray *table_data;
+    AcpiAml table_data;
     GArray *rsdp;
     GArray *tcpalog;
     GArray *linker;
@@ -1270,9 +1270,10 @@ struct AcpiBuildTables {
 static inline void acpi_build_tables_init(AcpiBuildTables *tables)
 {
     tables->rsdp = g_array_new(false, true /* clear */, 1);
-    tables->table_data = g_array_new(false, true /* clear */, 1);
+    tables->table_data.buf = g_array_new(false, true /* clear */, 1);
     tables->tcpalog = g_array_new(false, true /* clear */, 1);
     tables->linker = bios_linker_loader_init();
+    tables->table_data.linker = tables->linker;
 }
 
 static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
@@ -1280,7 +1281,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
     void *linker_data = bios_linker_loader_cleanup(tables->linker);
     g_free(linker_data);
     g_array_free(tables->rsdp, mfre);
-    g_array_free(tables->table_data, true);
+    g_array_free(tables->table_data.buf, true);
     g_array_free(tables->tcpalog, mfre);
 }
 
@@ -1360,66 +1361,66 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
      * We place it first since it's the only table that has alignment
      * requirements.
      */
-    facs = tables->table_data->len;
-    build_facs(tables->table_data, tables->linker, guest_info);
+    facs = tables->table_data.buf->len;
+    build_facs(tables->table_data.buf, tables->linker, guest_info);
 
     /* DSDT is pointed to by FADT */
-    dsdt = tables->table_data->len;
-    build_dsdt(tables->table_data, tables->linker, &misc);
+    dsdt = tables->table_data.buf->len;
+    build_dsdt(tables->table_data.buf, tables->linker, &misc);
 
     /* Count the size of the DSDT and SSDT, we will need it for legacy
      * sizing of ACPI tables.
      */
-    aml_len += tables->table_data->len - dsdt;
+    aml_len += tables->table_data.buf->len - dsdt;
 
     /* ACPI tables pointed to by RSDT */
-    acpi_add_table(table_offsets, tables->table_data);
-    build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
+    acpi_add_table(table_offsets, tables->table_data.buf);
+    build_fadt(tables->table_data.buf, tables->linker, &pm, facs, dsdt);
 
-    ssdt = tables->table_data->len;
-    acpi_add_table(table_offsets, tables->table_data);
-    build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
+    ssdt = tables->table_data.buf->len;
+    acpi_add_table(table_offsets, tables->table_data.buf);
+    build_ssdt(tables->table_data.buf, tables->linker, &cpu, &pm, &misc, &pci,
                guest_info);
-    aml_len += tables->table_data->len - ssdt;
+    aml_len += tables->table_data.buf->len - ssdt;
 
-    acpi_add_table(table_offsets, tables->table_data);
-    build_madt(tables->table_data, tables->linker, &cpu, guest_info);
+    acpi_add_table(table_offsets, tables->table_data.buf);
+    build_madt(tables->table_data.buf, tables->linker, &cpu, guest_info);
 
     if (misc.has_hpet) {
-        acpi_add_table(table_offsets, tables->table_data);
-        build_hpet(tables->table_data, tables->linker);
+        acpi_add_table(table_offsets, tables->table_data.buf);
+        build_hpet(tables->table_data.buf, tables->linker);
     }
     if (misc.has_tpm) {
-        acpi_add_table(table_offsets, tables->table_data);
-        build_tpm_tcpa(tables->table_data, tables->linker, tables->tcpalog);
+        acpi_add_table(table_offsets, tables->table_data.buf);
+        build_tpm_tcpa(tables->table_data.buf, tables->linker, tables->tcpalog);
 
-        acpi_add_table(table_offsets, tables->table_data);
-        build_tpm_ssdt(tables->table_data, tables->linker);
+        acpi_add_table(table_offsets, tables->table_data.buf);
+        build_tpm_ssdt(tables->table_data.buf, tables->linker);
     }
     if (guest_info->numa_nodes) {
-        acpi_add_table(table_offsets, tables->table_data);
-        build_srat(tables->table_data, tables->linker, guest_info);
+        acpi_add_table(table_offsets, tables->table_data.buf);
+        build_srat(tables->table_data.buf, tables->linker, guest_info);
     }
     if (acpi_get_mcfg(&mcfg)) {
-        acpi_add_table(table_offsets, tables->table_data);
-        build_mcfg_q35(tables->table_data, tables->linker, &mcfg);
+        acpi_add_table(table_offsets, tables->table_data.buf);
+        build_mcfg_q35(tables->table_data.buf, tables->linker, &mcfg);
     }
     if (acpi_has_iommu()) {
-        acpi_add_table(table_offsets, tables->table_data);
-        build_dmar_q35(tables->table_data, tables->linker);
+        acpi_add_table(table_offsets, tables->table_data.buf);
+        build_dmar_q35(tables->table_data.buf, tables->linker);
     }
 
     /* Add tables supplied by user (if any) */
     for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
         unsigned len = acpi_table_len(u);
 
-        acpi_add_table(table_offsets, tables->table_data);
-        g_array_append_vals(tables->table_data, u, len);
+        acpi_add_table(table_offsets, tables->table_data.buf);
+        g_array_append_vals(tables->table_data.buf, u, len);
     }
 
     /* RSDT is pointed to by RSDP */
-    rsdt = tables->table_data->len;
-    build_rsdt(tables->table_data, tables->linker, table_offsets);
+    rsdt = tables->table_data.buf->len;
+    build_rsdt(tables->table_data.buf, tables->linker, table_offsets);
 
     /* RSDP is in FSEG memory, so allocate it separately */
     build_rsdp(tables->rsdp, tables->linker, rsdt);
@@ -1451,23 +1452,23 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
             guest_info->legacy_acpi_table_size +
             ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus;
         int legacy_table_size =
-            ROUND_UP(tables->table_data->len - aml_len + legacy_aml_len,
+            ROUND_UP(tables->table_data.buf->len - aml_len + legacy_aml_len,
                      ACPI_BUILD_ALIGN_SIZE);
-        if (tables->table_data->len > legacy_table_size) {
+        if (tables->table_data.buf->len > legacy_table_size) {
             /* Should happen only with PCI bridges and -M pc-i440fx-2.0.  */
             error_report("Warning: migration may not work.");
         }
-        g_array_set_size(tables->table_data, legacy_table_size);
+        g_array_set_size(tables->table_data.buf, legacy_table_size);
     } else {
         /* Make sure we have a buffer in case we need to resize the tables. */
-        if (tables->table_data->len > ACPI_BUILD_TABLE_SIZE / 2) {
+        if (tables->table_data.buf->len > ACPI_BUILD_TABLE_SIZE / 2) {
             /* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots.  */
             error_report("Warning: ACPI tables are larger than 64k.");
             error_report("Warning: migration may not work.");
             error_report("Warning: please remove CPUs, NUMA nodes, "
                          "memory slots or PCI bridges.");
         }
-        acpi_align_size(tables->table_data, ACPI_BUILD_TABLE_SIZE);
+        acpi_align_size(tables->table_data.buf, ACPI_BUILD_TABLE_SIZE);
     }
 
     acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
@@ -1491,14 +1492,14 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
 
     acpi_build(build_state->guest_info, &tables);
 
-    assert(acpi_data_len(tables.table_data) == build_state->table_size);
+    assert(acpi_data_len(tables.table_data.buf) == build_state->table_size);
 
     /* Make sure RAM size is correct - in case it got changed by migration */
     qemu_ram_resize(build_state->table_ram, build_state->table_size,
                     &error_abort);
 
-    memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data,
-           build_state->table_size);
+    memcpy(qemu_get_ram_ptr(build_state->table_ram),
+           tables.table_data.buf->data, build_state->table_size);
 
     cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram,
                                                build_state->table_size);
@@ -1559,11 +1560,12 @@ void acpi_setup(PcGuestInfo *guest_info)
     acpi_build(build_state->guest_info, &tables);
 
     /* Now expose it all to Guest */
-    build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data,
+    build_state->table_ram = acpi_add_rom_blob(build_state,
+                                               tables.table_data.buf,
                                                ACPI_BUILD_TABLE_FILE,
                                                ACPI_BUILD_TABLE_MAX_SIZE);
     assert(build_state->table_ram != RAM_ADDR_MAX);
-    build_state->table_size = acpi_data_len(tables.table_data);
+    build_state->table_size = acpi_data_len(tables.table_data.buf);
 
     acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader", 0);
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 44/47] pc: acpi-build: drop remaining ssdt_misc template and use acpi_def_block()
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (42 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 43/47] pc: acpi-build: prepare to make ACPI tables blob opaque for table building functions Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 45/47] acpi: add acpi_iqr_no_flags() term Igor Mammedov
                   ` (3 subsequent siblings)
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

It completes dynamic SSDT generation and makes it
independed of IASL binary blobs. It also hides
from user all pointer arithmetic when building
SSDT which makes resulting code a bit cleaner
and concentrating only on composing ASL construct
/i.e. a task build_ssdt() should be doing/.

Also it makes one binary blob less stored in QEMU
source tree by removing need to keep and update
hw/i386/ssdt-misc.hex.generated file here in total
saving us ~430LOC.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/Makefile.objs           |   2 +-
 hw/i386/acpi-build.c            |  32 ++--
 hw/i386/ssdt-misc.dsl           |  21 ---
 hw/i386/ssdt-misc.hex.generated | 399 ----------------------------------------
 4 files changed, 12 insertions(+), 442 deletions(-)
 delete mode 100644 hw/i386/ssdt-misc.dsl
 delete mode 100644 hw/i386/ssdt-misc.hex.generated

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 6c8705d..dc8c38a 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -8,7 +8,7 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/
 obj-y += kvmvapic.o
 obj-y += acpi-build.o
 hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \
-	hw/i386/ssdt-misc.hex hw/i386/q35-acpi-dsdt.hex \
+	hw/i386/q35-acpi-dsdt.hex \
 	hw/i386/ssdt-tpm.hex
 
 iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 5821528..5831450 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -268,7 +268,6 @@ static void acpi_get_pci_info(PcPciInfo *info)
 
 #define ACPI_BUILD_APPNAME  "Bochs"
 #define ACPI_BUILD_APPNAME6 "BOCHS "
-#define ACPI_BUILD_APPNAME4 "BXPC"
 
 #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
 #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
@@ -465,10 +464,6 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
                  table_data->len - madt_start, 1);
 }
 
-#define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */
-#define ACPI_SSDT_HEADER_LENGTH 36
-
-#include "hw/i386/ssdt-misc.hex"
 #include "hw/i386/ssdt-tpm.hex"
 
 /* Assign BSEL property to all buses.  In the future, this can be changed
@@ -647,17 +642,14 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
 }
 
 static void
-build_ssdt(GArray *table_data, GArray *linker,
+build_ssdt(AcpiAml *table_aml, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
            PcPciInfo *pci, PcGuestInfo *guest_info)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
     uint32_t nr_mem = machine->ram_slots;
     unsigned acpi_cpus = guest_info->apic_id_limit;
-    int ssdt_start = table_data->len;
-    AcpiAml table_aml = { .buf = table_data };
-    uint8_t *ssdt_ptr;
-    AcpiAml pkg, scope, dev, method, crs, field, ifctx;
+    AcpiAml pkg, scope, dev, method, crs, field, ifctx, ssdt;
     int i;
 
     /* The current AML generator can cover the APIC ID range [0..255],
@@ -665,9 +657,9 @@ build_ssdt(GArray *table_data, GArray *linker,
     QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
     g_assert(acpi_cpus <= ACPI_CPU_HOTPLUG_ID_LIMIT);
 
-    /* Copy SSDT  header */
-    ssdt_ptr = acpi_data_push(table_data, sizeof(ssdp_misc_aml));
-    memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));
+    /* Init SSDT Definition Block */
+    ssdt =
+        acpi_def_block("SSDT", 1, ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4, 1);
 
     scope = acpi_scope("\\_SB.PCI0");
     /* build PCI0._CRS */
@@ -719,7 +711,7 @@ build_ssdt(GArray *table_data, GArray *linker,
         aml_append(&dev, acpi_name_decl("_CRS", crs));
         aml_append(&scope, dev);
     }
-    aml_append(&table_aml, scope);
+    aml_append(&ssdt, scope);
 
     /*  create S3_ / S4_ / S5_ packages if necessary */
     scope = acpi_scope("\\");
@@ -747,7 +739,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     aml_append(&pkg, acpi_int(0)); /* reserved */
     aml_append(&pkg, acpi_int(0)); /* reserved */
     aml_append(&scope, acpi_name_decl("_S5", pkg));
-    aml_append(&table_aml, scope);
+    aml_append(&ssdt, scope);
 
     if (misc->pvpanic_port) {
         scope = acpi_scope("\\_SB.PCI0.ISA");
@@ -777,7 +769,7 @@ build_ssdt(GArray *table_data, GArray *linker,
         aml_append(&dev, method);
 
         aml_append(&scope, dev);
-        aml_append(&table_aml, scope);
+        aml_append(&ssdt, scope);
     }
 
     {
@@ -972,12 +964,10 @@ build_ssdt(GArray *table_data, GArray *linker,
                 aml_append(&sb_scope, scope);
             }
         }
-        aml_append(&table_aml, sb_scope);
+        aml_append(&ssdt, sb_scope);
     }
 
-    build_header(linker, table_data,
-                 (void *)(table_data->data + ssdt_start),
-                 "SSDT", table_data->len - ssdt_start, 1);
+    aml_append(table_aml, ssdt);
 }
 
 static void
@@ -1379,7 +1369,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
 
     ssdt = tables->table_data.buf->len;
     acpi_add_table(table_offsets, tables->table_data.buf);
-    build_ssdt(tables->table_data.buf, tables->linker, &cpu, &pm, &misc, &pci,
+    build_ssdt(&tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
                guest_info);
     aml_len += tables->table_data.buf->len - ssdt;
 
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
deleted file mode 100644
index 8d61f21..0000000
--- a/hw/i386/ssdt-misc.dsl
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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 "hw/acpi/pc-hotplug.h"
-
-ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
-
-DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
-{
-}
diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated
deleted file mode 100644
index cbcf61d..0000000
--- a/hw/i386/ssdt-misc.hex.generated
+++ /dev/null
@@ -1,399 +0,0 @@
-static unsigned char acpi_pci64_length[] = {
-0x6f
-};
-static unsigned char acpi_s4_pkg[] = {
-0x99
-};
-static unsigned char ssdt_mctrl_nr_slots[] = {
-0x7d
-};
-static unsigned char acpi_s3_name[] = {
-0x86
-};
-static unsigned char acpi_pci32_start[] = {
-0x2f
-};
-static unsigned char acpi_pci64_valid[] = {
-0x43
-};
-static unsigned char ssdp_misc_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0x6c,
-0x1,
-0x0,
-0x0,
-0x1,
-0x3,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x42,
-0x58,
-0x53,
-0x53,
-0x44,
-0x54,
-0x53,
-0x55,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x28,
-0x8,
-0x14,
-0x20,
-0x10,
-0x4c,
-0x5,
-0x5c,
-0x0,
-0x8,
-0x50,
-0x30,
-0x53,
-0x5f,
-0xc,
-0x78,
-0x56,
-0x34,
-0x12,
-0x8,
-0x50,
-0x30,
-0x45,
-0x5f,
-0xc,
-0x78,
-0x56,
-0x34,
-0x12,
-0x8,
-0x50,
-0x31,
-0x56,
-0x5f,
-0xa,
-0x12,
-0x8,
-0x50,
-0x31,
-0x53,
-0x5f,
-0x11,
-0xb,
-0xa,
-0x8,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x50,
-0x31,
-0x45,
-0x5f,
-0x11,
-0xb,
-0xa,
-0x8,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x50,
-0x31,
-0x4c,
-0x5f,
-0x11,
-0xb,
-0xa,
-0x8,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x4d,
-0x44,
-0x4e,
-0x52,
-0xc,
-0x78,
-0x56,
-0x34,
-0x12,
-0x10,
-0x29,
-0x5c,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x33,
-0x5f,
-0x12,
-0x6,
-0x4,
-0x1,
-0x1,
-0x0,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x34,
-0x5f,
-0x12,
-0x8,
-0x4,
-0xa,
-0x2,
-0xa,
-0x2,
-0x0,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x35,
-0x5f,
-0x12,
-0x6,
-0x4,
-0x0,
-0x0,
-0x0,
-0x0,
-0x10,
-0x40,
-0xc,
-0x5c,
-0x2f,
-0x3,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x49,
-0x53,
-0x41,
-0x5f,
-0x5b,
-0x82,
-0x4d,
-0xa,
-0x50,
-0x45,
-0x56,
-0x54,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xd,
-0x51,
-0x45,
-0x4d,
-0x55,
-0x30,
-0x30,
-0x30,
-0x31,
-0x0,
-0x8,
-0x50,
-0x45,
-0x53,
-0x54,
-0xb,
-0xff,
-0xff,
-0x5b,
-0x80,
-0x50,
-0x45,
-0x4f,
-0x52,
-0x1,
-0x50,
-0x45,
-0x53,
-0x54,
-0x1,
-0x5b,
-0x81,
-0xb,
-0x50,
-0x45,
-0x4f,
-0x52,
-0x1,
-0x50,
-0x45,
-0x50,
-0x54,
-0x8,
-0x14,
-0x18,
-0x5f,
-0x53,
-0x54,
-0x41,
-0x0,
-0x70,
-0x50,
-0x45,
-0x53,
-0x54,
-0x60,
-0xa0,
-0x6,
-0x93,
-0x60,
-0x0,
-0xa4,
-0x0,
-0xa1,
-0x4,
-0xa4,
-0xa,
-0xf,
-0x14,
-0xe,
-0x52,
-0x44,
-0x50,
-0x54,
-0x0,
-0x70,
-0x50,
-0x45,
-0x50,
-0x54,
-0x60,
-0xa4,
-0x60,
-0x14,
-0xc,
-0x57,
-0x52,
-0x50,
-0x54,
-0x1,
-0x70,
-0x68,
-0x50,
-0x45,
-0x50,
-0x54,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0xd,
-0xa,
-0xa,
-0x47,
-0x1,
-0x0,
-0x0,
-0x0,
-0x0,
-0x1,
-0x1,
-0x79,
-0x0,
-0x8b,
-0x5f,
-0x43,
-0x52,
-0x53,
-0xa,
-0x2,
-0x49,
-0x4f,
-0x4d,
-0x4e,
-0x8b,
-0x5f,
-0x43,
-0x52,
-0x53,
-0xa,
-0x4,
-0x49,
-0x4f,
-0x4d,
-0x58,
-0x14,
-0x18,
-0x5f,
-0x49,
-0x4e,
-0x49,
-0x0,
-0x70,
-0x50,
-0x45,
-0x53,
-0x54,
-0x49,
-0x4f,
-0x4d,
-0x4e,
-0x70,
-0x50,
-0x45,
-0x53,
-0x54,
-0x49,
-0x4f,
-0x4d,
-0x58
-};
-static unsigned char ssdt_isa_pest[] = {
-0xda
-};
-static unsigned char acpi_s4_name[] = {
-0x92
-};
-static unsigned char acpi_pci64_start[] = {
-0x4d
-};
-static unsigned char acpi_pci64_end[] = {
-0x5e
-};
-static unsigned char acpi_pci32_end[] = {
-0x39
-};
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 45/47] acpi: add acpi_iqr_no_flags() term
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (43 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 44/47] pc: acpi-build: drop remaining ssdt_misc template and use acpi_def_block() Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-27 15:37   ` Claudio Fontana
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 46/47] pc: export applesmc IO port/len Igor Mammedov
                   ` (2 subsequent siblings)
  47 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 18 ++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 58f88cd..59873e3 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -511,6 +511,24 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
     return var;
 }
 
+/*
+ * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
+ *           6.4.2.1 IRQ Descriptor
+*/
+AcpiAml acpi_iqr_no_flags(uint8_t irq)
+{
+    uint16_t irq_mask;
+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+
+    assert(irq < 16);
+    build_append_byte(var.buf, 0x22); /* IRQ descriptor 2 byte form */
+
+    irq_mask = 1U << irq;
+    build_append_byte(var.buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
+    build_append_byte(var.buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
+    return var;
+}
+
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
 AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2)
 {
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 868d439..d39b5b1 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -117,6 +117,7 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
                    AcpiAml arg3, AcpiAml arg4);
 AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
                 uint8_t aln, uint8_t len);
+AcpiAml acpi_iqr_no_flags(uint8_t irq);
 AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len);
 AcpiAml acpi_named_field(const char *name, unsigned length);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 46/47] pc: export applesmc IO port/len
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (44 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 45/47] acpi: add acpi_iqr_no_flags() term Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 47/47] pc: acpi-build: drop template patching and create Device(SMC) dynamically Igor Mammedov
  2015-01-28  7:38 ` [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Michael S. Tsirkin
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

IO port and length will be used in following patch
to correctly generate SMC ACPI device in SSDT.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c |  2 +-
 hw/misc/applesmc.c   |  5 ++---
 include/hw/isa/isa.h | 11 +++++++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 5831450..fc9dcfa 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -144,7 +144,7 @@ static void acpi_get_dsdt(AcpiMiscInfo *info)
 
     /* Patch in appropriate value for AppleSMC _STA */
     *(uint8_t *)(info->dsdt_code + *applesmc_sta) =
-        applesmc_find() ? 0x0b : 0x00;
+        applesmc_port() ? 0x0b : 0x00;
 }
 
 static
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 6a56b07..6bd61e7 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -43,7 +43,6 @@
 /* command/status port used by Apple SMC */
 #define APPLESMC_CMD_PORT              0x4
 #define APPLESMC_NR_PORTS              32
-#define APPLESMC_MAX_DATA_LENGTH       32
 
 #define APPLESMC_READ_CMD              0x10
 #define APPLESMC_WRITE_CMD             0x11
@@ -249,8 +248,8 @@ static void applesmc_isa_realize(DeviceState *dev, Error **errp)
 }
 
 static Property applesmc_isa_properties[] = {
-    DEFINE_PROP_UINT32("iobase", AppleSMCState, iobase,
-                      APPLESMC_DEFAULT_IOBASE),
+    DEFINE_PROP_UINT32(APPLESMC_PROP_IO_BASE, AppleSMCState, iobase,
+                       APPLESMC_DEFAULT_IOBASE),
     DEFINE_PROP_STRING("osk", AppleSMCState, osk),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index e0c749f..1ee9fa0 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -21,10 +21,17 @@
 #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
 
 #define TYPE_APPLE_SMC "isa-applesmc"
+#define APPLESMC_MAX_DATA_LENGTH       32
+#define APPLESMC_PROP_IO_BASE "iobase"
 
-static inline bool applesmc_find(void)
+static inline uint16_t applesmc_port(void)
 {
-    return object_resolve_path_type("", TYPE_APPLE_SMC, NULL);
+    Object *obj = object_resolve_path_type("", TYPE_APPLE_SMC, NULL);
+
+    if (obj) {
+        return object_property_get_int(obj, APPLESMC_PROP_IO_BASE, NULL);
+    }
+    return 0;
 }
 
 typedef struct ISADeviceClass {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v2 47/47] pc: acpi-build: drop template patching and create Device(SMC) dynamically
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (45 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 46/47] pc: export applesmc IO port/len Igor Mammedov
@ 2015-01-22 14:50 ` Igor Mammedov
  2015-01-28  7:38 ` [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Michael S. Tsirkin
  47 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-22 14:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

patch moves SMC device into SSDT and creates it only
when device is present, which makes ACPI tables smaller
in default case when device is not present.

PS:
also it fixes wrong IO range in CRS if "iobase"
property is set to a not default value.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c      | 33 ++++++++++++++++++++++++++-------
 hw/i386/acpi-dsdt-isa.dsl | 11 -----------
 2 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index fc9dcfa..f66da5d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -115,6 +115,7 @@ typedef struct AcpiMiscInfo {
     const unsigned char *dsdt_code;
     unsigned dsdt_size;
     uint16_t pvpanic_port;
+    uint16_t applesmc_io_base;
 } AcpiMiscInfo;
 
 typedef struct AcpiBuildPciBusHotplugState {
@@ -126,7 +127,6 @@ typedef struct AcpiBuildPciBusHotplugState {
 
 static void acpi_get_dsdt(AcpiMiscInfo *info)
 {
-    uint16_t *applesmc_sta;
     Object *piix = piix4_pm_find();
     Object *lpc = ich9_lpc_find();
     assert(!!piix != !!lpc);
@@ -134,17 +134,11 @@ static void acpi_get_dsdt(AcpiMiscInfo *info)
     if (piix) {
         info->dsdt_code = AcpiDsdtAmlCode;
         info->dsdt_size = sizeof AcpiDsdtAmlCode;
-        applesmc_sta = piix_dsdt_applesmc_sta;
     }
     if (lpc) {
         info->dsdt_code = Q35AcpiDsdtAmlCode;
         info->dsdt_size = sizeof Q35AcpiDsdtAmlCode;
-        applesmc_sta = q35_dsdt_applesmc_sta;
     }
-
-    /* Patch in appropriate value for AppleSMC _STA */
-    *(uint8_t *)(info->dsdt_code + *applesmc_sta) =
-        applesmc_port() ? 0x0b : 0x00;
 }
 
 static
@@ -241,6 +235,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
     info->has_hpet = hpet_find();
     info->has_tpm = tpm_find();
     info->pvpanic_port = pvpanic_port();
+    info->applesmc_io_base = applesmc_port();
 }
 
 static void acpi_get_pci_info(PcPciInfo *info)
@@ -741,6 +736,30 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
     aml_append(&scope, acpi_name_decl("_S5", pkg));
     aml_append(&ssdt, scope);
 
+    if (misc->applesmc_io_base) {
+        scope = acpi_scope("\\_SB.PCI0.ISA");
+        dev = acpi_device("SMC");
+
+        aml_append(&dev, acpi_name_decl("_HID", acpi_eisaid("APP0001")));
+        /* device present, functioning, decoding, not shown in UI */
+        aml_append(&dev, acpi_name_decl("_STA", acpi_int(0xB)));
+
+        crs = acpi_resource_template();
+        aml_append(&crs,
+            acpi_io(acpi_decode16,
+                    misc->applesmc_io_base,
+                    misc->applesmc_io_base,
+                    0x01,
+                    APPLESMC_MAX_DATA_LENGTH
+            )
+        );
+        aml_append(&crs, acpi_iqr_no_flags(6));
+        aml_append(&dev, acpi_name_decl("_CRS", crs));
+
+        aml_append(&scope, dev);
+        aml_append(&ssdt, scope);
+    }
+
     if (misc->pvpanic_port) {
         scope = acpi_scope("\\_SB.PCI0.ISA");
 
diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl
index deb37de..89caa16 100644
--- a/hw/i386/acpi-dsdt-isa.dsl
+++ b/hw/i386/acpi-dsdt-isa.dsl
@@ -16,17 +16,6 @@
 /* Common legacy ISA style devices. */
 Scope(\_SB.PCI0.ISA) {
 
-    Device (SMC) {
-        Name(_HID, EisaId("APP0001"))
-        /* _STA will be patched to 0x0B if AppleSMC is present */
-        ACPI_EXTRACT_NAME_BYTE_CONST DSDT_APPLESMC_STA
-        Name(_STA, 0xF0)
-        Name(_CRS, ResourceTemplate () {
-            IO (Decode16, 0x0300, 0x0300, 0x01, 0x20)
-            IRQNoFlags() { 6 }
-        })
-    }
-
     Device(RTC) {
         Name(_HID, EisaId("PNP0B00"))
         Name(_CRS, ResourceTemplate() {
-- 
1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 02/47] acpi: add acpi_scope() term
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 02/47] acpi: add acpi_scope() term Igor Mammedov
@ 2015-01-23  8:02   ` Michael S. Tsirkin
  2015-01-23 10:36     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23  8:02 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Thu, Jan 22, 2015 at 02:49:46PM +0000, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 18 ++++++++++++++++++
>  include/hw/acpi/acpi-build-utils.h |  4 ++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 547ecaa..e13d748 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -306,3 +306,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
>      build_append_array(parent_ctx->buf, child.buf);
>      build_free_array(child.buf);
>  }
> +
> +static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
> +{
> +    AcpiAml var = { .op = op, .block_flags = flags };
> +    var.buf = build_alloc_array();
> +    return var;
> +}
> +

Is there also allocate_external? If not - static is enough to
know it's not an API function.

> +/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefScope */
> +AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...)
> +{
> +    va_list ap;
> +    AcpiAml var = aml_allocate_internal(0x10 /* ScopeOp */, PACKAGE);
> +    va_start(ap, name_format);
> +    build_append_namestringv(var.buf, name_format, ap);
> +    va_end(ap);
> +    return var;
> +}
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 64e7ec3..bbb786b 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -21,6 +21,10 @@ typedef struct AcpiAml {
>  
>  void aml_append(AcpiAml *parent_ctx, AcpiAml child);
>  
> +/* Block ASL object primitives */
> +AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
> +
> +/* other helpers */
>  GArray *build_alloc_array(void);
>  void build_free_array(GArray *array);
>  void build_prepend_byte(GArray *array, uint8_t val);
> -- 
> 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Igor Mammedov
@ 2015-01-23  8:03   ` Michael S. Tsirkin
  2015-01-23 10:03     ` Igor Mammedov
  2015-01-23  8:11   ` Michael S. Tsirkin
  2015-01-23  9:14   ` Michael S. Tsirkin
  2 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23  8:03 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> Adds for dynamic AML creation, which will be used
> for piecing ASL/AML primitives together and hiding
> from user/caller details about how nested context
> should be closed/packed leaving less space for
> mistakes and necessity to know how AML should be
> encoded, allowing user to concentrate on ASL
> representation instead.
> 
> For example it will allow to create AML like this:
> 
> AcpiAml scope = acpi_scope("PCI0")
> AcpiAml dev = acpi_device("PM")
>     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> aml_append(&scope, dev);
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
>  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 602e68c..547ecaa 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
>          build_append_value(table, value, 4);
>      }
>  }
> +
> +static void build_prepend_int(GArray *array, uint32_t value)
> +{
> +    GArray *data = build_alloc_array();
> +
> +    build_append_int(data, value);
> +    g_array_prepend_vals(array, data->data, data->len);
> +    build_free_array(data);
> +}
> +
> +void aml_append(AcpiAml *parent_ctx, AcpiAml child)
> +{
> +    switch (child.block_flags) {
> +    case EXT_PACKAGE:
> +        build_extop_package(child.buf, child.op);
> +        break;
> +
> +    case PACKAGE:
> +        build_package(child.buf, child.op);
> +        break;
> +
> +    case RES_TEMPLATE:
> +        build_append_byte(child.buf, 0x79); /* EndTag */
> +        /*
> +         * checksum operations is treated as succeeded if checksum
> +         * field is zero. [ACPI Spec 5.0, 6.4.2.9 End Tag]
> +         */
> +        build_append_byte(child.buf, 0);
> +        /* fall through, to pack resources in buffer */
> +    case BUFFER:
> +        build_prepend_int(child.buf, child.buf->len);
> +        build_package(child.buf, child.op);
> +        break;
> +    default:
> +        break;
> +    }
> +    build_append_array(parent_ctx->buf, child.buf);
> +    build_free_array(child.buf);
> +}
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 199f003..64e7ec3 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -5,6 +5,22 @@
>  #include <glib.h>
>  #include "qemu/compiler.h"
>  
> +typedef enum {
> +    NON_BLOCK,
> +    PACKAGE,
> +    EXT_PACKAGE,
> +    BUFFER,
> +    RES_TEMPLATE,
> +} AcpiBlockFlags;

Please prefix values with ACPI_BUILD_ - don't pollute the
global namespace.
Same elsewhere: add build_ to functions, and Build to types.

This makes it clear these are not Acpi spec types,
but helpers to build Aml.

> +
> +typedef struct AcpiAml {
> +    GArray *buf;
> +    uint8_t op;
> +    AcpiBlockFlags block_flags;
> +} AcpiAml;
> +
> +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> +
>  GArray *build_alloc_array(void);
>  void build_free_array(GArray *array);
>  void build_prepend_byte(GArray *array, uint8_t val);
> -- 
> 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Igor Mammedov
  2015-01-23  8:03   ` Michael S. Tsirkin
@ 2015-01-23  8:11   ` Michael S. Tsirkin
  2015-01-23 10:35     ` Igor Mammedov
  2015-01-23  9:14   ` Michael S. Tsirkin
  2 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23  8:11 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> Adds for dynamic AML creation, which will be used
> for piecing ASL/AML primitives together and hiding
> from user/caller details about how nested context
> should be closed/packed leaving less space for
> mistakes and necessity to know how AML should be
> encoded, allowing user to concentrate on ASL
> representation instead.
> 
> For example it will allow to create AML like this:
> 
> AcpiAml scope = acpi_scope("PCI0")
> AcpiAml dev = acpi_device("PM")
>     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> aml_append(&scope, dev);
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
>  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 602e68c..547ecaa 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
>          build_append_value(table, value, 4);
>      }
>  }
> +
> +static void build_prepend_int(GArray *array, uint32_t value)
> +{
> +    GArray *data = build_alloc_array();
> +
> +    build_append_int(data, value);
> +    g_array_prepend_vals(array, data->data, data->len);
> +    build_free_array(data);
> +}

I don't think prepend is generally justified:
it makes code hard to follow and debug.

Adding length is different: of course you need
to first have the package before you can add length.

We currently have build_prepend_package_length - just move it
to utils, and use everywhere.


> +
> +void aml_append(AcpiAml *parent_ctx, AcpiAml child)
> +{
> +    switch (child.block_flags) {
> +    case EXT_PACKAGE:
> +        build_extop_package(child.buf, child.op);
> +        break;
> +
> +    case PACKAGE:
> +        build_package(child.buf, child.op);
> +        break;
> +
> +    case RES_TEMPLATE:
> +        build_append_byte(child.buf, 0x79); /* EndTag */
> +        /*
> +         * checksum operations is treated as succeeded if checksum
> +         * field is zero. [ACPI Spec 5.0, 6.4.2.9 End Tag]
> +         */

Bad english. Let's quote verbatim:
	If the checksum field is zero, the
	resource data is treated as if the checksum operation succeeded.
Also best to quote earliest spec available so we know it's
compatible with old guests:
Spec 1.0b, 6.4.2.8 End Tag


> +        build_append_byte(child.buf, 0);
> +        /* fall through, to pack resources in buffer */
> +    case BUFFER:
> +        build_prepend_int(child.buf, child.buf->len);
> +        build_package(child.buf, child.op);
> +        break;
> +    default:
> +        break;
> +    }
> +    build_append_array(parent_ctx->buf, child.buf);
> +    build_free_array(child.buf);
> +}
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 199f003..64e7ec3 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -5,6 +5,22 @@
>  #include <glib.h>
>  #include "qemu/compiler.h"
>  
> +typedef enum {
> +    NON_BLOCK,
> +    PACKAGE,
> +    EXT_PACKAGE,
> +    BUFFER,
> +    RES_TEMPLATE,
> +} AcpiBlockFlags;
> +
> +typedef struct AcpiAml {
> +    GArray *buf;
> +    uint8_t op;
> +    AcpiBlockFlags block_flags;
> +} AcpiAml;
> +
> +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> +
>  GArray *build_alloc_array(void);
>  void build_free_array(GArray *array);
>  void build_prepend_byte(GArray *array, uint8_t val);
> -- 
> 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms Igor Mammedov
@ 2015-01-23  8:32   ` Marcel Apfelbaum
  2015-01-23  9:35     ` Michael S. Tsirkin
  2015-01-23 13:34     ` Igor Mammedov
  0 siblings, 2 replies; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-01-23  8:32 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

On 01/22/2015 04:49 PM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 32 ++++++++++++++++++++++++++++++++
>   include/hw/acpi/acpi-build-utils.h |  5 +++++
>   2 files changed, 37 insertions(+)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index df5880f..6e10712 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -348,6 +348,38 @@ AcpiAml acpi_name_decl(const char *name, AcpiAml val)
>       return var;
>   }
Hi Igor,
Very nice series!!!

>
> +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg0Op */
> +AcpiAml acpi_arg0(void)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x68); /* ARG0 op */
> +    return var;
> +}
Maybe we can have a little code reuse and use something like:

static AcpiAml acpi_arg(int idx)
{
     AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
     build_append_byte(var.buf, 0x68 + idx); /* ARG<idx> op */
     return var;
}

and then:

AcpiAml acpi_arg0(void)
{
     return acpi_arg(0);
}
...

I did the same with the local vars.
What do you think?

Thanks,
Marcel

> +
> +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg1Op */
> +AcpiAml acpi_arg1(void)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x69); /* ARG1 op */
> +    return var;
> +}
> +
> +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg2Op */
> +AcpiAml acpi_arg2(void)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x6A); /* ARG2 op */
> +    return var;
> +}
> +
> +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg3Op */
> +AcpiAml acpi_arg3(void)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x6B); /* ARG3 op */
> +    return var;
> +}
> +
>   /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
>   AcpiAml acpi_if(AcpiAml predicate)
>   {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 9e9ef1a..18d9efa 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -26,6 +26,11 @@ AcpiAml acpi_return(AcpiAml val);
>   AcpiAml acpi_int(const uint64_t val);
>   AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
>   AcpiAml acpi_name_decl(const char *name, AcpiAml val);
> +AcpiAml acpi_arg0(void);
> +AcpiAml acpi_arg1(void);
> +AcpiAml acpi_arg2(void);
> +AcpiAml acpi_arg3(void);
> +
>   /* Block ASL object primitives */
>   AcpiAml acpi_if(AcpiAml predicate);
>   AcpiAml acpi_method(const char *name, int arg_count);
>

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

* Re: [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term Igor Mammedov
@ 2015-01-23  8:59   ` Michael S. Tsirkin
  2015-01-23 13:32     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23  8:59 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Thu, Jan 22, 2015 at 02:49:50PM +0000, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 24 ++++++++++++++++++++++++
>  include/hw/acpi/acpi-build-utils.h |  3 +++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 40a1769..1bda2ec 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -314,6 +314,30 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
>      return var;
>  }
>  
> +/*
> + * help to construct NameString, which return AcpiAml object
> + * for using with other aml_append or other acpi_* terms

Here and elsewhere: I can't parse this header text.
I'm guessing you just mean "construct NameString",
and that's it?

Also, most other places use build_append_namestring -
so when should acpi_name be used instead?
This should be made clear here in the comment.

> + */
> +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...)
> +{

This isn't really a name. It just appends a string.  So rename this
acpi_string and then the below one adding a name can be named acpi_name?

Also, in many places one must use only one nameseg.
I think a separate api that actually validates
that it's one segment is better than silently failing.
Do we ever use it for more than 1 segment?
If not, maybe the right thing to do is
to use build_append_nameseg and call this one acpi_nameseg.


> +    va_list ap;
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);

0 hard coded? What does it mean?
Same elsewhere.

> +    va_start(ap, name_format);
> +    build_append_namestringv(var.buf, name_format, ap);
> +    va_end(ap);
> +    return var;
> +
> +/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */

Let's quote the earliest spec which documents each object:
one year from now 5.0 will not be the latest.
Applies here and elsewhere.
In most places this will be 1.0b.
Where the construct is newer, this will automatically
document which guests support it.

> +AcpiAml acpi_name_decl(const char *name, AcpiAml val)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x08);

Pls add comment documenting what 0x08 is here.

> +    build_append_namestring(var.buf, "%s", name);
> +    aml_append(&var, val);
> +    return var;
> +}
> +
>  /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
>  AcpiAml acpi_if(AcpiAml predicate)
>  {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 177f9ed..868cfa5 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -21,6 +21,9 @@ typedef struct AcpiAml {
>  
>  void aml_append(AcpiAml *parent_ctx, AcpiAml child);
>  
> +/* non block ASL object primitives */

what does it mean that it's a "non block primitive"?
I didn't find this concept in the spec.

> +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
> +AcpiAml acpi_name_decl(const char *name, AcpiAml val);
>  /* Block ASL object primitives */
>  AcpiAml acpi_if(AcpiAml predicate);
>  AcpiAml acpi_method(const char *name, int arg_count);
> -- 
> 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Igor Mammedov
  2015-01-23  8:03   ` Michael S. Tsirkin
  2015-01-23  8:11   ` Michael S. Tsirkin
@ 2015-01-23  9:14   ` Michael S. Tsirkin
  2 siblings, 0 replies; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23  9:14 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> Adds for dynamic AML creation, which will be used
> for piecing ASL/AML primitives together and hiding
> from user/caller details about how nested context
> should be closed/packed leaving less space for
> mistakes and necessity to know how AML should be
> encoded, allowing user to concentrate on ASL
> representation instead.
> 
> For example it will allow to create AML like this:
> 
> AcpiAml scope = acpi_scope("PCI0")
> AcpiAml dev = acpi_device("PM")
>     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> aml_append(&scope, dev);
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
>  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 602e68c..547ecaa 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
>          build_append_value(table, value, 4);
>      }
>  }
> +
> +static void build_prepend_int(GArray *array, uint32_t value)
> +{
> +    GArray *data = build_alloc_array();
> +
> +    build_append_int(data, value);
> +    g_array_prepend_vals(array, data->data, data->len);
> +    build_free_array(data);
> +}
> +
> +void aml_append(AcpiAml *parent_ctx, AcpiAml child)
> +{
> +    switch (child.block_flags) {
> +    case EXT_PACKAGE:
> +        build_extop_package(child.buf, child.op);
> +        break;
> +
> +    case PACKAGE:
> +        build_package(child.buf, child.op);
> +        break;
> +
> +    case RES_TEMPLATE:
> +        build_append_byte(child.buf, 0x79); /* EndTag */
> +        /*
> +         * checksum operations is treated as succeeded if checksum
> +         * field is zero. [ACPI Spec 5.0, 6.4.2.9 End Tag]
> +         */
> +        build_append_byte(child.buf, 0);
> +        /* fall through, to pack resources in buffer */
> +    case BUFFER:
> +        build_prepend_int(child.buf, child.buf->len);
> +        build_package(child.buf, child.op);
> +        break;
> +    default:
> +        break;
> +    }
> +    build_append_array(parent_ctx->buf, child.buf);
> +    build_free_array(child.buf);

So looking at this, the API is a bit tricky to use
to avoid use after free.

For example:
	aml_append(&a, b);
	aml_append(&a, b);
this is use after free.

This is C, memory management should not be automatic.
So just move free out of there, get child by const pointer.
Same for alloc: split out allocation and init.
You can still return pointer back to caller,
this will allow chaining just like you do here.

We'll get:

	AcpiAml dev = aml_alloc();

	aml_append(&scope, acpi_device(&dev));

	aml_free(&dev);


which is more verbose, but makes it clear
there's no use after free, additionally,
compiler checks that you don't modify child
where not necessary.


> +}
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 199f003..64e7ec3 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -5,6 +5,22 @@
>  #include <glib.h>
>  #include "qemu/compiler.h"
>  
> +typedef enum {
> +    NON_BLOCK,
> +    PACKAGE,
> +    EXT_PACKAGE,
> +    BUFFER,
> +    RES_TEMPLATE,
> +} AcpiBlockFlags;
> +
> +typedef struct AcpiAml {
> +    GArray *buf;
> +    uint8_t op;
> +    AcpiBlockFlags block_flags;
> +} AcpiAml;
> +
> +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> +
>  GArray *build_alloc_array(void);
>  void build_free_array(GArray *array);
>  void build_prepend_byte(GArray *array, uint8_t val);
> -- 
> 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms
  2015-01-23  8:32   ` Marcel Apfelbaum
@ 2015-01-23  9:35     ` Michael S. Tsirkin
  2015-01-23 13:34     ` Igor Mammedov
  1 sibling, 0 replies; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23  9:35 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, claudio.fontana, qemu-devel, pbonzini, Igor Mammedov

On Fri, Jan 23, 2015 at 10:32:57AM +0200, Marcel Apfelbaum wrote:
> On 01/22/2015 04:49 PM, Igor Mammedov wrote:
> >Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> >---
> >  hw/acpi/acpi-build-utils.c         | 32 ++++++++++++++++++++++++++++++++
> >  include/hw/acpi/acpi-build-utils.h |  5 +++++
> >  2 files changed, 37 insertions(+)
> >
> >diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> >index df5880f..6e10712 100644
> >--- a/hw/acpi/acpi-build-utils.c
> >+++ b/hw/acpi/acpi-build-utils.c
> >@@ -348,6 +348,38 @@ AcpiAml acpi_name_decl(const char *name, AcpiAml val)
> >      return var;
> >  }
> Hi Igor,
> Very nice series!!!
> 
> >
> >+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg0Op */
> >+AcpiAml acpi_arg0(void)
> >+{
> >+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> >+    build_append_byte(var.buf, 0x68); /* ARG0 op */
> >+    return var;
> >+}
> Maybe we can have a little code reuse and use something like:
> 
> static AcpiAml acpi_arg(int idx)
> {
>     AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
>     build_append_byte(var.buf, 0x68 + idx); /* ARG<idx> op */

assert(idx <= 9) as well.

>     return var;
> }
> 
> and then:
> 
> AcpiAml acpi_arg0(void)
> {
>     return acpi_arg(0);
> }

No need for a wrapper even, I would say.

> ...
> 
> I did the same with the local vars.
> What do you think?
> 
> Thanks,
> Marcel
> 
> >+
> >+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg1Op */
> >+AcpiAml acpi_arg1(void)
> >+{
> >+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> >+    build_append_byte(var.buf, 0x69); /* ARG1 op */
> >+    return var;
> >+}
> >+
> >+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg2Op */
> >+AcpiAml acpi_arg2(void)
> >+{
> >+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> >+    build_append_byte(var.buf, 0x6A); /* ARG2 op */
> >+    return var;
> >+}
> >+
> >+/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg3Op */
> >+AcpiAml acpi_arg3(void)
> >+{
> >+    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> >+    build_append_byte(var.buf, 0x6B); /* ARG3 op */
> >+    return var;
> >+}
> >+
> >  /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> >  AcpiAml acpi_if(AcpiAml predicate)
> >  {
> >diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> >index 9e9ef1a..18d9efa 100644
> >--- a/include/hw/acpi/acpi-build-utils.h
> >+++ b/include/hw/acpi/acpi-build-utils.h
> >@@ -26,6 +26,11 @@ AcpiAml acpi_return(AcpiAml val);
> >  AcpiAml acpi_int(const uint64_t val);
> >  AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
> >  AcpiAml acpi_name_decl(const char *name, AcpiAml val);
> >+AcpiAml acpi_arg0(void);
> >+AcpiAml acpi_arg1(void);
> >+AcpiAml acpi_arg2(void);
> >+AcpiAml acpi_arg3(void);
> >+
> >  /* Block ASL object primitives */
> >  AcpiAml acpi_if(AcpiAml predicate);
> >  AcpiAml acpi_method(const char *name, int arg_count);
> >

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23  8:03   ` Michael S. Tsirkin
@ 2015-01-23 10:03     ` Igor Mammedov
  2015-01-23 13:26       ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-23 10:03 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, 23 Jan 2015 10:03:03 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> > +typedef enum {
> > +    NON_BLOCK,
> > +    PACKAGE,
> > +    EXT_PACKAGE,
> > +    BUFFER,
> > +    RES_TEMPLATE,
> > +} AcpiBlockFlags;
> 
> Please prefix values with ACPI_BUILD_ - don't pollute the
> global namespace.
Could we use AML_ prefix instead?

> Same elsewhere: add build_ to functions, and Build to types.
Same here i.e. s/acpi_/aml_/ prefix in API calls?

> 
> This makes it clear these are not Acpi spec types,
> but helpers to build Aml.
> 
> > +
> > +typedef struct AcpiAml {
> > +    GArray *buf;
> > +    uint8_t op;
> > +    AcpiBlockFlags block_flags;
> > +} AcpiAml;
> > +
> > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > +
> >  GArray *build_alloc_array(void);
> >  void build_free_array(GArray *array);
> >  void build_prepend_byte(GArray *array, uint8_t val);
> > -- 
> > 1.8.3.1
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23  8:11   ` Michael S. Tsirkin
@ 2015-01-23 10:35     ` Igor Mammedov
  2015-01-23 13:24       ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-23 10:35 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, 23 Jan 2015 10:11:19 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> > Adds for dynamic AML creation, which will be used
> > for piecing ASL/AML primitives together and hiding
> > from user/caller details about how nested context
> > should be closed/packed leaving less space for
> > mistakes and necessity to know how AML should be
> > encoded, allowing user to concentrate on ASL
> > representation instead.
> > 
> > For example it will allow to create AML like this:
> > 
> > AcpiAml scope = acpi_scope("PCI0")
> > AcpiAml dev = acpi_device("PM")
> >     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> > aml_append(&scope, dev);
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
> >  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
> >  2 files changed, 55 insertions(+)
> > 
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 602e68c..547ecaa 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
> >          build_append_value(table, value, 4);
> >      }
> >  }
> > +
> > +static void build_prepend_int(GArray *array, uint32_t value)
> > +{
> > +    GArray *data = build_alloc_array();
> > +
> > +    build_append_int(data, value);
> > +    g_array_prepend_vals(array, data->data, data->len);
> > +    build_free_array(data);
> > +}
> 
> I don't think prepend is generally justified:
> it makes code hard to follow and debug.
> 
> Adding length is different: of course you need
> to first have the package before you can add length.
> 
> We currently have build_prepend_package_length - just move it
> to utils, and use everywhere.
[...]
> > +    case BUFFER:
> > +        build_prepend_int(child.buf, child.buf->len);
> > +        build_package(child.buf, child.op);
Buffer uses the same concept as package, but adds its own additional length.
Therefore I've added build_prepend_int(),
I can create build_buffer() and mimic build_package()
but it won't change picture.

As for moving to to another file, during all this series lowlevel
build_(some_aml_related_costruct_helper)s are moved into this file
and should be make static to hide from user lowlevel helpers
(including build_package).
That will leave only high level API available.

TODO for me: make sure that moved lowlevel helpers are static


> > +        break;
> > +    default:
> > +        break;
> > +    }
> > +    build_append_array(parent_ctx->buf, child.buf);
> > +    build_free_array(child.buf);
> > +}
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 199f003..64e7ec3 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -5,6 +5,22 @@
> >  #include <glib.h>
> >  #include "qemu/compiler.h"
> >  
> > +typedef enum {
> > +    NON_BLOCK,
> > +    PACKAGE,
> > +    EXT_PACKAGE,
> > +    BUFFER,
> > +    RES_TEMPLATE,
> > +} AcpiBlockFlags;
> > +
> > +typedef struct AcpiAml {
> > +    GArray *buf;
> > +    uint8_t op;
> > +    AcpiBlockFlags block_flags;
> > +} AcpiAml;
> > +
> > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > +
> >  GArray *build_alloc_array(void);
> >  void build_free_array(GArray *array);
> >  void build_prepend_byte(GArray *array, uint8_t val);
> > -- 
> > 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 02/47] acpi: add acpi_scope() term
  2015-01-23  8:02   ` Michael S. Tsirkin
@ 2015-01-23 10:36     ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-23 10:36 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, 23 Jan 2015 10:02:54 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Jan 22, 2015 at 02:49:46PM +0000, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/acpi/acpi-build-utils.c         | 18 ++++++++++++++++++
> >  include/hw/acpi/acpi-build-utils.h |  4 ++++
> >  2 files changed, 22 insertions(+)
> > 
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 547ecaa..e13d748 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -306,3 +306,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
> >      build_append_array(parent_ctx->buf, child.buf);
> >      build_free_array(child.buf);
> >  }
> > +
> > +static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
> > +{
> > +    AcpiAml var = { .op = op, .block_flags = flags };
> > +    var.buf = build_alloc_array();
> > +    return var;
> > +}
> > +
> 
> Is there also allocate_external? If not - static is enough to
> know it's not an API function.
There isn't, I'll fix it up.

> 
> > +/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefScope */
> > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...)
> > +{
> > +    va_list ap;
> > +    AcpiAml var = aml_allocate_internal(0x10 /* ScopeOp */, PACKAGE);
> > +    va_start(ap, name_format);
> > +    build_append_namestringv(var.buf, name_format, ap);
> > +    va_end(ap);
> > +    return var;
> > +}
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 64e7ec3..bbb786b 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -21,6 +21,10 @@ typedef struct AcpiAml {
> >  
> >  void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> >  
> > +/* Block ASL object primitives */
> > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
> > +
> > +/* other helpers */
> >  GArray *build_alloc_array(void);
> >  void build_free_array(GArray *array);
> >  void build_prepend_byte(GArray *array, uint8_t val);
> > -- 
> > 1.8.3.1
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23 10:35     ` Igor Mammedov
@ 2015-01-23 13:24       ` Michael S. Tsirkin
  2015-01-23 13:40         ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23 13:24 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, Jan 23, 2015 at 11:35:29AM +0100, Igor Mammedov wrote:
> On Fri, 23 Jan 2015 10:11:19 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> > > Adds for dynamic AML creation, which will be used
> > > for piecing ASL/AML primitives together and hiding
> > > from user/caller details about how nested context
> > > should be closed/packed leaving less space for
> > > mistakes and necessity to know how AML should be
> > > encoded, allowing user to concentrate on ASL
> > > representation instead.
> > > 
> > > For example it will allow to create AML like this:
> > > 
> > > AcpiAml scope = acpi_scope("PCI0")
> > > AcpiAml dev = acpi_device("PM")
> > >     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> > > aml_append(&scope, dev);
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > >  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
> > >  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
> > >  2 files changed, 55 insertions(+)
> > > 
> > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > index 602e68c..547ecaa 100644
> > > --- a/hw/acpi/acpi-build-utils.c
> > > +++ b/hw/acpi/acpi-build-utils.c
> > > @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
> > >          build_append_value(table, value, 4);
> > >      }
> > >  }
> > > +
> > > +static void build_prepend_int(GArray *array, uint32_t value)
> > > +{
> > > +    GArray *data = build_alloc_array();
> > > +
> > > +    build_append_int(data, value);
> > > +    g_array_prepend_vals(array, data->data, data->len);
> > > +    build_free_array(data);
> > > +}
> > 
> > I don't think prepend is generally justified:
> > it makes code hard to follow and debug.
> > 
> > Adding length is different: of course you need
> > to first have the package before you can add length.
> > 
> > We currently have build_prepend_package_length - just move it
> > to utils, and use everywhere.
> [...]
> > > +    case BUFFER:
> > > +        build_prepend_int(child.buf, child.buf->len);
> > > +        build_package(child.buf, child.op);
> Buffer uses the same concept as package, but adds its own additional length.
> Therefore I've added build_prepend_int(),
> I can create build_buffer() and mimic build_package()

Sounds good, pls do.
The point is to avoid generic prepend calls as an external API.

> but it won't change picture.

It's a better API - what is meant by picture?

> As for moving to to another file, during all this series lowlevel
> build_(some_aml_related_costruct_helper)s are moved into this file
> and should be make static to hide from user lowlevel helpers
> (including build_package).
> That will leave only high level API available.
> 
> TODO for me: make sure that moved lowlevel helpers are static
> 
> 
> > > +        break;
> > > +    default:
> > > +        break;
> > > +    }
> > > +    build_append_array(parent_ctx->buf, child.buf);
> > > +    build_free_array(child.buf);
> > > +}
> > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > index 199f003..64e7ec3 100644
> > > --- a/include/hw/acpi/acpi-build-utils.h
> > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > @@ -5,6 +5,22 @@
> > >  #include <glib.h>
> > >  #include "qemu/compiler.h"
> > >  
> > > +typedef enum {
> > > +    NON_BLOCK,
> > > +    PACKAGE,
> > > +    EXT_PACKAGE,
> > > +    BUFFER,
> > > +    RES_TEMPLATE,
> > > +} AcpiBlockFlags;
> > > +
> > > +typedef struct AcpiAml {
> > > +    GArray *buf;
> > > +    uint8_t op;
> > > +    AcpiBlockFlags block_flags;
> > > +} AcpiAml;
> > > +
> > > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > +
> > >  GArray *build_alloc_array(void);
> > >  void build_free_array(GArray *array);
> > >  void build_prepend_byte(GArray *array, uint8_t val);
> > > -- 
> > > 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23 10:03     ` Igor Mammedov
@ 2015-01-23 13:26       ` Michael S. Tsirkin
  0 siblings, 0 replies; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23 13:26 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, Jan 23, 2015 at 11:03:54AM +0100, Igor Mammedov wrote:
> On Fri, 23 Jan 2015 10:03:03 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > > +typedef enum {
> > > +    NON_BLOCK,
> > > +    PACKAGE,
> > > +    EXT_PACKAGE,
> > > +    BUFFER,
> > > +    RES_TEMPLATE,
> > > +} AcpiBlockFlags;
> > 
> > Please prefix values with ACPI_BUILD_ - don't pollute the
> > global namespace.
> Could we use AML_ prefix instead?
> > Same elsewhere: add build_ to functions, and Build to types.
> Same here i.e. s/acpi_/aml_/ prefix in API calls?

OK.

> 
> > 
> > This makes it clear these are not Acpi spec types,
> > but helpers to build Aml.
> > 
> > > +
> > > +typedef struct AcpiAml {
> > > +    GArray *buf;
> > > +    uint8_t op;
> > > +    AcpiBlockFlags block_flags;
> > > +} AcpiAml;
> > > +
> > > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > +
> > >  GArray *build_alloc_array(void);
> > >  void build_free_array(GArray *array);
> > >  void build_prepend_byte(GArray *array, uint8_t val);
> > > -- 
> > > 1.8.3.1
> > 

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

* Re: [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term
  2015-01-23  8:59   ` Michael S. Tsirkin
@ 2015-01-23 13:32     ` Igor Mammedov
  2015-01-23 13:42       ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-23 13:32 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, 23 Jan 2015 10:59:48 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Jan 22, 2015 at 02:49:50PM +0000, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/acpi/acpi-build-utils.c         | 24 ++++++++++++++++++++++++
> >  include/hw/acpi/acpi-build-utils.h |  3 +++
> >  2 files changed, 27 insertions(+)
> > 
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 40a1769..1bda2ec 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -314,6 +314,30 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
> >      return var;
> >  }
> >  
> > +/*
> > + * help to construct NameString, which return AcpiAml object
> > + * for using with other aml_append or other acpi_* terms
> 
> Here and elsewhere: I can't parse this header text.
> I'm guessing you just mean "construct NameString",
> and that's it?
yes

> 
> Also, most other places use build_append_namestring -
> so when should acpi_name be used instead?
> This should be made clear here in the comment.
acpi_name() is a replacement/wrapper around build_append_namestring()
which returns AcpiAml object. build_append_namestring() is a nonpublic
lowlevel helper that deals with GArray,
while acpi_name() follows semantic of AML API.

> 
> > + */
> > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...)
> > +{
> 
> This isn't really a name. It just appends a string.  So rename this
> acpi_string and then the below one adding a name can be named acpi_name?
acpi_string is introduced in 27/47, which is a prefixed string
as described in spec.

> Also, in many places one must use only one nameseg.
Where is it exactly?
Perhaps we could build in acpi_name() a check if we know in
what context enforce it. Better to have single/uniform API
for names than a several which is confusing.

> I think a separate api that actually validates
> that it's one segment is better than silently failing.
> Do we ever use it for more than 1 segment?
Yes we use names with more than one segment.

> If not, maybe the right thing to do is
> to use build_append_nameseg and call this one acpi_nameseg.
acpi_name() is used only for passing name as arguments to methods,
in spec there isn't a limitation to only one segment when it comes
to names, in ASL part of it. namesegment however only AML construct
which helps to build name, I prefer not expose lowlevel AML
unless we have to.

> 
> 
> > +    va_list ap;
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> 
> 0 hard coded? What does it mean?
1st arg for NON_BLOCK context doesn't mean anything/ignored.
alternatively I can make aml_allocate_nonblock() wrapper
around generic allocator.

> Same elsewhere.
> 
> > +    va_start(ap, name_format);
> > +    build_append_namestringv(var.buf, name_format, ap);
> > +    va_end(ap);
> > +    return var;
> > +
> > +/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */
> 
> Let's quote the earliest spec which documents each object:
> one year from now 5.0 will not be the latest.
> Applies here and elsewhere.
> In most places this will be 1.0b.
> Where the construct is newer, this will automatically
> document which guests support it.
I'll try to do it.

> 
> > +AcpiAml acpi_name_decl(const char *name, AcpiAml val)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    build_append_byte(var.buf, 0x08);
> 
> Pls add comment documenting what 0x08 is here.
sure

> 
> > +    build_append_namestring(var.buf, "%s", name);
> > +    aml_append(&var, val);
> > +    return var;
> > +}
> > +
> >  /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> >  AcpiAml acpi_if(AcpiAml predicate)
> >  {
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 177f9ed..868cfa5 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -21,6 +21,9 @@ typedef struct AcpiAml {
> >  
> >  void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> >  
> > +/* non block ASL object primitives */
> 
> what does it mean that it's a "non block primitive"?
> I didn't find this concept in the spec.
As for a question what is NON_BLOCK, it's for simple inline ASL
construct that doesn't have to be packaged in special way
examles:
  Store(A,B)
  Name(FOO, VAL)
  IO(...)
while there are different block elements differing in how
they are created see 1/47 aml_append():

ResourceTemplate {
 /* block of other ASL items */
}

Package() {
 /* block of other ASL items */
}

if ... else ...

Scope() {
 /* block of other ASL items */
}

and so on.

> 
> > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
> > +AcpiAml acpi_name_decl(const char *name, AcpiAml val);
> >  /* Block ASL object primitives */
> >  AcpiAml acpi_if(AcpiAml predicate);
> >  AcpiAml acpi_method(const char *name, int arg_count);
> > -- 
> > 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms
  2015-01-23  8:32   ` Marcel Apfelbaum
  2015-01-23  9:35     ` Michael S. Tsirkin
@ 2015-01-23 13:34     ` Igor Mammedov
  1 sibling, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-23 13:34 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, mst, claudio.fontana, qemu-devel, pbonzini

On Fri, 23 Jan 2015 10:32:57 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/22/2015 04:49 PM, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >   hw/acpi/acpi-build-utils.c         | 32 ++++++++++++++++++++++++++++++++
> >   include/hw/acpi/acpi-build-utils.h |  5 +++++
> >   2 files changed, 37 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index df5880f..6e10712 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -348,6 +348,38 @@ AcpiAml acpi_name_decl(const char *name, AcpiAml val)
> >       return var;
> >   }
> Hi Igor,
> Very nice series!!!
> 
> >
> > +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg0Op */
> > +AcpiAml acpi_arg0(void)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    build_append_byte(var.buf, 0x68); /* ARG0 op */
> > +    return var;
> > +}
> Maybe we can have a little code reuse and use something like:
> 
> static AcpiAml acpi_arg(int idx)
> {
>      AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
>      build_append_byte(var.buf, 0x68 + idx); /* ARG<idx> op */
>      return var;
> }
> 
> and then:
> 
> AcpiAml acpi_arg0(void)
> {
>      return acpi_arg(0);
> }
> ...
> 
> I did the same with the local vars.
> What do you think?
sure lets use it, and take Michael's suggest dropping wrappers
and just use plain acpi_arg(X)

> Thanks,
> Marcel
> 
> > +
> > +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg1Op */
> > +AcpiAml acpi_arg1(void)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    build_append_byte(var.buf, 0x69); /* ARG1 op */
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg2Op */
> > +AcpiAml acpi_arg2(void)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    build_append_byte(var.buf, 0x6A); /* ARG2 op */
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg3Op */
> > +AcpiAml acpi_arg3(void)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    build_append_byte(var.buf, 0x6B); /* ARG3 op */
> > +    return var;
> > +}
> > +
> >   /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> >   AcpiAml acpi_if(AcpiAml predicate)
> >   {
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 9e9ef1a..18d9efa 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -26,6 +26,11 @@ AcpiAml acpi_return(AcpiAml val);
> >   AcpiAml acpi_int(const uint64_t val);
> >   AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
> >   AcpiAml acpi_name_decl(const char *name, AcpiAml val);
> > +AcpiAml acpi_arg0(void);
> > +AcpiAml acpi_arg1(void);
> > +AcpiAml acpi_arg2(void);
> > +AcpiAml acpi_arg3(void);
> > +
> >   /* Block ASL object primitives */
> >   AcpiAml acpi_if(AcpiAml predicate);
> >   AcpiAml acpi_method(const char *name, int arg_count);
> >
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23 13:24       ` Michael S. Tsirkin
@ 2015-01-23 13:40         ` Igor Mammedov
  2015-01-23 13:55           ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-23 13:40 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, 23 Jan 2015 15:24:24 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Jan 23, 2015 at 11:35:29AM +0100, Igor Mammedov wrote:
> > On Fri, 23 Jan 2015 10:11:19 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> > > > Adds for dynamic AML creation, which will be used
> > > > for piecing ASL/AML primitives together and hiding
> > > > from user/caller details about how nested context
> > > > should be closed/packed leaving less space for
> > > > mistakes and necessity to know how AML should be
> > > > encoded, allowing user to concentrate on ASL
> > > > representation instead.
> > > > 
> > > > For example it will allow to create AML like this:
> > > > 
> > > > AcpiAml scope = acpi_scope("PCI0")
> > > > AcpiAml dev = acpi_device("PM")
> > > >     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> > > > aml_append(&scope, dev);
> > > > 
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > ---
> > > >  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
> > > >  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
> > > >  2 files changed, 55 insertions(+)
> > > > 
> > > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > > index 602e68c..547ecaa 100644
> > > > --- a/hw/acpi/acpi-build-utils.c
> > > > +++ b/hw/acpi/acpi-build-utils.c
> > > > @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
> > > >          build_append_value(table, value, 4);
> > > >      }
> > > >  }
> > > > +
> > > > +static void build_prepend_int(GArray *array, uint32_t value)
> > > > +{
> > > > +    GArray *data = build_alloc_array();
> > > > +
> > > > +    build_append_int(data, value);
> > > > +    g_array_prepend_vals(array, data->data, data->len);
> > > > +    build_free_array(data);
> > > > +}
> > > 
> > > I don't think prepend is generally justified:
> > > it makes code hard to follow and debug.
> > > 
> > > Adding length is different: of course you need
> > > to first have the package before you can add length.
> > > 
> > > We currently have build_prepend_package_length - just move it
> > > to utils, and use everywhere.
> > [...]
> > > > +    case BUFFER:
> > > > +        build_prepend_int(child.buf, child.buf->len);
> > > > +        build_package(child.buf, child.op);
> > Buffer uses the same concept as package, but adds its own additional length.
> > Therefore I've added build_prepend_int(),
> > I can create build_buffer() and mimic build_package()
> 
> Sounds good, pls do.
> The point is to avoid generic prepend calls as an external API.
> 
> > but it won't change picture.
> 
> It's a better API - what is meant by picture?
build_prepend_int() is a static/non public function,
build_buffer() will also be static/non public function for use only by
API internals.

I pretty much hate long build_append_foo() names so I'm hiding all
lowlevel constructs and try to expose only high-level ASL ones.
Which makes me to think that we need to use asl_ prefix for API calls
instead of acpi_ or aml_.

> 
> > As for moving to to another file, during all this series lowlevel
> > build_(some_aml_related_costruct_helper)s are moved into this file
> > and should be make static to hide from user lowlevel helpers
> > (including build_package).
> > That will leave only high level API available.
> > 
> > TODO for me: make sure that moved lowlevel helpers are static
> > 
> > 
> > > > +        break;
> > > > +    default:
> > > > +        break;
> > > > +    }
> > > > +    build_append_array(parent_ctx->buf, child.buf);
> > > > +    build_free_array(child.buf);
> > > > +}
> > > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > > index 199f003..64e7ec3 100644
> > > > --- a/include/hw/acpi/acpi-build-utils.h
> > > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > > @@ -5,6 +5,22 @@
> > > >  #include <glib.h>
> > > >  #include "qemu/compiler.h"
> > > >  
> > > > +typedef enum {
> > > > +    NON_BLOCK,
> > > > +    PACKAGE,
> > > > +    EXT_PACKAGE,
> > > > +    BUFFER,
> > > > +    RES_TEMPLATE,
> > > > +} AcpiBlockFlags;
> > > > +
> > > > +typedef struct AcpiAml {
> > > > +    GArray *buf;
> > > > +    uint8_t op;
> > > > +    AcpiBlockFlags block_flags;
> > > > +} AcpiAml;
> > > > +
> > > > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > > +
> > > >  GArray *build_alloc_array(void);
> > > >  void build_free_array(GArray *array);
> > > >  void build_prepend_byte(GArray *array, uint8_t val);
> > > > -- 
> > > > 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term
  2015-01-23 13:32     ` Igor Mammedov
@ 2015-01-23 13:42       ` Michael S. Tsirkin
  2015-02-02 16:04         ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23 13:42 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, Jan 23, 2015 at 02:32:45PM +0100, Igor Mammedov wrote:
> On Fri, 23 Jan 2015 10:59:48 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Jan 22, 2015 at 02:49:50PM +0000, Igor Mammedov wrote:
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > >  hw/acpi/acpi-build-utils.c         | 24 ++++++++++++++++++++++++
> > >  include/hw/acpi/acpi-build-utils.h |  3 +++
> > >  2 files changed, 27 insertions(+)
> > > 
> > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > index 40a1769..1bda2ec 100644
> > > --- a/hw/acpi/acpi-build-utils.c
> > > +++ b/hw/acpi/acpi-build-utils.c
> > > @@ -314,6 +314,30 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
> > >      return var;
> > >  }
> > >  
> > > +/*
> > > + * help to construct NameString, which return AcpiAml object
> > > + * for using with other aml_append or other acpi_* terms
> > 
> > Here and elsewhere: I can't parse this header text.
> > I'm guessing you just mean "construct NameString",
> > and that's it?
> yes
> 
> > 
> > Also, most other places use build_append_namestring -
> > so when should acpi_name be used instead?
> > This should be made clear here in the comment.
> acpi_name() is a replacement/wrapper around build_append_namestring()
> which returns AcpiAml object. build_append_namestring() is a nonpublic
> lowlevel helper that deals with GArray,
> while acpi_name() follows semantic of AML API.
> 
> > 
> > > + */
> > > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...)
> > > +{
> > 
> > This isn't really a name. It just appends a string.  So rename this
> > acpi_string and then the below one adding a name can be named acpi_name?
> acpi_string is introduced in 27/47, which is a prefixed string
> as described in spec.
> 
> > Also, in many places one must use only one nameseg.
> Where is it exactly?
> Perhaps we could build in acpi_name() a check if we know in
> what context enforce it. Better to have single/uniform API
> for names than a several which is confusing.

I agree here.

> > I think a separate api that actually validates
> > that it's one segment is better than silently failing.
> > Do we ever use it for more than 1 segment?
> Yes we use names with more than one segment.

Interesting. where exactly?

> > If not, maybe the right thing to do is
> > to use build_append_nameseg and call this one acpi_nameseg.
> acpi_name() is used only for passing name as arguments to methods,
> in spec there isn't a limitation to only one segment when it comes
> to names, in ASL part of it. namesegment however only AML construct
> which helps to build name, I prefer not expose lowlevel AML
> unless we have to.

OK, I agree.

> > 
> > 
> > > +    va_list ap;
> > > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > 
> > 0 hard coded? What does it mean?
> 1st arg for NON_BLOCK context doesn't mean anything/ignored.
> alternatively I can make aml_allocate_nonblock() wrapper
> around generic allocator.

0 isn't a valid opcode either, it can really be anything.



> > Same elsewhere.
> > 
> > > +    va_start(ap, name_format);
> > > +    build_append_namestringv(var.buf, name_format, ap);
> > > +    va_end(ap);
> > > +    return var;
> > > +
> > > +/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */
> > 
> > Let's quote the earliest spec which documents each object:
> > one year from now 5.0 will not be the latest.
> > Applies here and elsewhere.
> > In most places this will be 1.0b.
> > Where the construct is newer, this will automatically
> > document which guests support it.
> I'll try to do it.
> 
> > 
> > > +AcpiAml acpi_name_decl(const char *name, AcpiAml val)
> > > +{
> > > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > > +    build_append_byte(var.buf, 0x08);
> > 
> > Pls add comment documenting what 0x08 is here.
> sure
> 
> > 
> > > +    build_append_namestring(var.buf, "%s", name);
> > > +    aml_append(&var, val);
> > > +    return var;
> > > +}
> > > +
> > >  /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> > >  AcpiAml acpi_if(AcpiAml predicate)
> > >  {
> > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > index 177f9ed..868cfa5 100644
> > > --- a/include/hw/acpi/acpi-build-utils.h
> > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > @@ -21,6 +21,9 @@ typedef struct AcpiAml {
> > >  
> > >  void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > >  
> > > +/* non block ASL object primitives */
> > 
> > what does it mean that it's a "non block primitive"?
> > I didn't find this concept in the spec.
> As for a question what is NON_BLOCK, it's for simple inline ASL
> construct that doesn't have to be packaged in special way
> examles:
>   Store(A,B)
>   Name(FOO, VAL)
>   IO(...)
> while there are different block elements differing in how
> they are created see 1/47 aml_append():
> 
> ResourceTemplate {
>  /* block of other ASL items */
> }
> 
> Package() {
>  /* block of other ASL items */
> }
> 
> if ... else ...
> 
> Scope() {
>  /* block of other ASL items */
> }
> 
> and so on.

"special way" is kind of vague.
Maybe add a comment explaining when it's used.
Is it when length isn't used as a prefix?
AML_NO_PREFIX?


> > 
> > > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
> > > +AcpiAml acpi_name_decl(const char *name, AcpiAml val);
> > >  /* Block ASL object primitives */
> > >  AcpiAml acpi_if(AcpiAml predicate);
> > >  AcpiAml acpi_method(const char *name, int arg_count);
> > > -- 
> > > 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23 13:40         ` Igor Mammedov
@ 2015-01-23 13:55           ` Michael S. Tsirkin
  2015-01-23 17:56             ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-23 13:55 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, Jan 23, 2015 at 02:40:30PM +0100, Igor Mammedov wrote:
> On Fri, 23 Jan 2015 15:24:24 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Fri, Jan 23, 2015 at 11:35:29AM +0100, Igor Mammedov wrote:
> > > On Fri, 23 Jan 2015 10:11:19 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> > > > > Adds for dynamic AML creation, which will be used
> > > > > for piecing ASL/AML primitives together and hiding
> > > > > from user/caller details about how nested context
> > > > > should be closed/packed leaving less space for
> > > > > mistakes and necessity to know how AML should be
> > > > > encoded, allowing user to concentrate on ASL
> > > > > representation instead.
> > > > > 
> > > > > For example it will allow to create AML like this:
> > > > > 
> > > > > AcpiAml scope = acpi_scope("PCI0")
> > > > > AcpiAml dev = acpi_device("PM")
> > > > >     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> > > > > aml_append(&scope, dev);
> > > > > 
> > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > ---
> > > > >  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
> > > > >  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
> > > > >  2 files changed, 55 insertions(+)
> > > > > 
> > > > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > > > index 602e68c..547ecaa 100644
> > > > > --- a/hw/acpi/acpi-build-utils.c
> > > > > +++ b/hw/acpi/acpi-build-utils.c
> > > > > @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
> > > > >          build_append_value(table, value, 4);
> > > > >      }
> > > > >  }
> > > > > +
> > > > > +static void build_prepend_int(GArray *array, uint32_t value)
> > > > > +{
> > > > > +    GArray *data = build_alloc_array();
> > > > > +
> > > > > +    build_append_int(data, value);
> > > > > +    g_array_prepend_vals(array, data->data, data->len);
> > > > > +    build_free_array(data);
> > > > > +}
> > > > 
> > > > I don't think prepend is generally justified:
> > > > it makes code hard to follow and debug.
> > > > 
> > > > Adding length is different: of course you need
> > > > to first have the package before you can add length.
> > > > 
> > > > We currently have build_prepend_package_length - just move it
> > > > to utils, and use everywhere.
> > > [...]
> > > > > +    case BUFFER:
> > > > > +        build_prepend_int(child.buf, child.buf->len);
> > > > > +        build_package(child.buf, child.op);
> > > Buffer uses the same concept as package, but adds its own additional length.
> > > Therefore I've added build_prepend_int(),
> > > I can create build_buffer() and mimic build_package()
> > 
> > Sounds good, pls do.
> > The point is to avoid generic prepend calls as an external API.
> > 
> > > but it won't change picture.
> > 
> > It's a better API - what is meant by picture?
> build_prepend_int() is a static/non public function,
> build_buffer() will also be static/non public function for use only by
> API internals.
> 
> I pretty much hate long build_append_foo() names so I'm hiding all
> lowlevel constructs and try to expose only high-level ASL ones.
> Which makes me to think that we need to use asl_ prefix for API calls
> instead of acpi_ or aml_.

This sounds wrong unless we either accept ASL input or
produce ASL output.

Igor, I think you are aiming a bit too high. Don't try to
write your own language, just use C. It does have
overhead like need to declare functions and variables,
and allocate/free memory, but they are well understood.


Your patches are almost there, they are pretty clean, the only issue I
think is this passing of AcpiAml by value, sometimes freeing buffer in
the process, sometimes not.

Just pass AcpiAml* everywhere, add APIs to allocate and free it
together with the internal buffer.
This makes it trivial to see that value is not misused:
just check it's between alloc and free - and that there are
no leaks - just check we call free on each value.
We can write a semantic patch to catch missing free calls,
it's easy.


> > 
> > > As for moving to to another file, during all this series lowlevel
> > > build_(some_aml_related_costruct_helper)s are moved into this file
> > > and should be make static to hide from user lowlevel helpers
> > > (including build_package).
> > > That will leave only high level API available.
> > > 
> > > TODO for me: make sure that moved lowlevel helpers are static
> > > 
> > > 
> > > > > +        break;
> > > > > +    default:
> > > > > +        break;
> > > > > +    }
> > > > > +    build_append_array(parent_ctx->buf, child.buf);
> > > > > +    build_free_array(child.buf);
> > > > > +}
> > > > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > > > index 199f003..64e7ec3 100644
> > > > > --- a/include/hw/acpi/acpi-build-utils.h
> > > > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > > > @@ -5,6 +5,22 @@
> > > > >  #include <glib.h>
> > > > >  #include "qemu/compiler.h"
> > > > >  
> > > > > +typedef enum {
> > > > > +    NON_BLOCK,
> > > > > +    PACKAGE,
> > > > > +    EXT_PACKAGE,
> > > > > +    BUFFER,
> > > > > +    RES_TEMPLATE,
> > > > > +} AcpiBlockFlags;
> > > > > +
> > > > > +typedef struct AcpiAml {
> > > > > +    GArray *buf;
> > > > > +    uint8_t op;
> > > > > +    AcpiBlockFlags block_flags;
> > > > > +} AcpiAml;
> > > > > +
> > > > > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > > > +
> > > > >  GArray *build_alloc_array(void);
> > > > >  void build_free_array(GArray *array);
> > > > >  void build_prepend_byte(GArray *array, uint8_t val);
> > > > > -- 
> > > > > 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23 13:55           ` Michael S. Tsirkin
@ 2015-01-23 17:56             ` Igor Mammedov
  2015-01-24 16:33               ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-23 17:56 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, 23 Jan 2015 15:55:11 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Jan 23, 2015 at 02:40:30PM +0100, Igor Mammedov wrote:
> > On Fri, 23 Jan 2015 15:24:24 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Fri, Jan 23, 2015 at 11:35:29AM +0100, Igor Mammedov wrote:
> > > > On Fri, 23 Jan 2015 10:11:19 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> > > > > > Adds for dynamic AML creation, which will be used
> > > > > > for piecing ASL/AML primitives together and hiding
> > > > > > from user/caller details about how nested context
> > > > > > should be closed/packed leaving less space for
> > > > > > mistakes and necessity to know how AML should be
> > > > > > encoded, allowing user to concentrate on ASL
> > > > > > representation instead.
> > > > > > 
> > > > > > For example it will allow to create AML like this:
> > > > > > 
> > > > > > AcpiAml scope = acpi_scope("PCI0")
> > > > > > AcpiAml dev = acpi_device("PM")
> > > > > >     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> > > > > > aml_append(&scope, dev);
> > > > > > 
> > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > > ---
> > > > > >  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
> > > > > >  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
> > > > > >  2 files changed, 55 insertions(+)
> > > > > > 
> > > > > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > > > > index 602e68c..547ecaa 100644
> > > > > > --- a/hw/acpi/acpi-build-utils.c
> > > > > > +++ b/hw/acpi/acpi-build-utils.c
> > > > > > @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
> > > > > >          build_append_value(table, value, 4);
> > > > > >      }
> > > > > >  }
> > > > > > +
> > > > > > +static void build_prepend_int(GArray *array, uint32_t value)
> > > > > > +{
> > > > > > +    GArray *data = build_alloc_array();
> > > > > > +
> > > > > > +    build_append_int(data, value);
> > > > > > +    g_array_prepend_vals(array, data->data, data->len);
> > > > > > +    build_free_array(data);
> > > > > > +}
> > > > > 
> > > > > I don't think prepend is generally justified:
> > > > > it makes code hard to follow and debug.
> > > > > 
> > > > > Adding length is different: of course you need
> > > > > to first have the package before you can add length.
> > > > > 
> > > > > We currently have build_prepend_package_length - just move it
> > > > > to utils, and use everywhere.
> > > > [...]
> > > > > > +    case BUFFER:
> > > > > > +        build_prepend_int(child.buf, child.buf->len);
> > > > > > +        build_package(child.buf, child.op);
> > > > Buffer uses the same concept as package, but adds its own additional length.
> > > > Therefore I've added build_prepend_int(),
> > > > I can create build_buffer() and mimic build_package()
> > > 
> > > Sounds good, pls do.
> > > The point is to avoid generic prepend calls as an external API.
> > > 
> > > > but it won't change picture.
> > > 
> > > It's a better API - what is meant by picture?
> > build_prepend_int() is a static/non public function,
> > build_buffer() will also be static/non public function for use only by
> > API internals.
> > 
> > I pretty much hate long build_append_foo() names so I'm hiding all
> > lowlevel constructs and try to expose only high-level ASL ones.
> > Which makes me to think that we need to use asl_ prefix for API calls
> > instead of acpi_ or aml_.
> 
> This sounds wrong unless we either accept ASL input or
> produce ASL output.
> 
> Igor, I think you are aiming a bit too high. Don't try to
> write your own language, just use C. It does have
> overhead like need to declare functions and variables,
> and allocate/free memory, but they are well understood.
I refuse to give up on cleaner and simpler API yet :)

> 
> 
> Your patches are almost there, they are pretty clean, the only issue I
> think is this passing of AcpiAml by value, sometimes freeing buffer in
> the process, sometimes not.
Currently buffer is allocated by API and is always freed whenever
it's passed to another API function.
That's why it makes user not to care about memory mgmt.

The only limitation of it is if you store AcpiAml return value into some
variable you are responsible to use it only once for passing to another API
function. Reusing this variable's value (pass it to API function second time)
would cause cause use-after-free and freeing-freed bugs.
Like this:
AcpiAml table = acpi_definition_block("SSDT",...);
AcpiAml scope = acpi_scope("PCI0");
aml_append(&table, scope); // <- here scope becomes invalid
// a bug
aml_append(&table, scope); // use-after-free + freeing-freed bugs

There are several approaches to look for resolving above issues:
1. Adopt and use memory mgmt model used by GTK+
   in nutshell: http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
   In particular adopt behavior of GInitiallyUnowned usage model

   that will allow to keep convenient chained call style and if necessary
   reuse objects returned by API by explicitly referencing/dereferencing
   them if needed.

2. It's possible to drop freeing inside API completely and
   record(store in list) every new object inside a table context.
   When table is constructed, list of created objects could be
   safely freed.
   With that it would be safe to reuse every AcpiAml object
   and avoid free-after-use issues with limitation that created
   AcpiAml objects shouldn't be used after table was closed.
   It should cover all practical use of API, i.e. no cross
   table AcpiAml objects.

3. talloc implementation Amit've mentioned,
   perhaps it might work since it allows to set destructors for
   managed pointers. With this we might get clear abort when
   dereferencing freed pointer see talloc_set()

> 
> Just pass AcpiAml* everywhere, add APIs to allocate and free it
> together with the internal buffer.
> This makes it trivial to see that value is not misused:
> just check it's between alloc and free - and that there are
> no leaks - just check we call free on each value.
> We can write a semantic patch to catch missing free calls,
> it's easy.
> 
> 
> > > 
> > > > As for moving to to another file, during all this series lowlevel
> > > > build_(some_aml_related_costruct_helper)s are moved into this file
> > > > and should be make static to hide from user lowlevel helpers
> > > > (including build_package).
> > > > That will leave only high level API available.
> > > > 
> > > > TODO for me: make sure that moved lowlevel helpers are static
> > > > 
> > > > 
> > > > > > +        break;
> > > > > > +    default:
> > > > > > +        break;
> > > > > > +    }
> > > > > > +    build_append_array(parent_ctx->buf, child.buf);
> > > > > > +    build_free_array(child.buf);
> > > > > > +}
> > > > > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > > > > index 199f003..64e7ec3 100644
> > > > > > --- a/include/hw/acpi/acpi-build-utils.h
> > > > > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > > > > @@ -5,6 +5,22 @@
> > > > > >  #include <glib.h>
> > > > > >  #include "qemu/compiler.h"
> > > > > >  
> > > > > > +typedef enum {
> > > > > > +    NON_BLOCK,
> > > > > > +    PACKAGE,
> > > > > > +    EXT_PACKAGE,
> > > > > > +    BUFFER,
> > > > > > +    RES_TEMPLATE,
> > > > > > +} AcpiBlockFlags;
> > > > > > +
> > > > > > +typedef struct AcpiAml {
> > > > > > +    GArray *buf;
> > > > > > +    uint8_t op;
> > > > > > +    AcpiBlockFlags block_flags;
> > > > > > +} AcpiAml;
> > > > > > +
> > > > > > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > > > > +
> > > > > >  GArray *build_alloc_array(void);
> > > > > >  void build_free_array(GArray *array);
> > > > > >  void build_prepend_byte(GArray *array, uint8_t val);
> > > > > > -- 
> > > > > > 1.8.3.1
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-23 17:56             ` Igor Mammedov
@ 2015-01-24 16:33               ` Michael S. Tsirkin
  2015-01-26  9:57                 ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-24 16:33 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
> On Fri, 23 Jan 2015 15:55:11 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Fri, Jan 23, 2015 at 02:40:30PM +0100, Igor Mammedov wrote:
> > > On Fri, 23 Jan 2015 15:24:24 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Fri, Jan 23, 2015 at 11:35:29AM +0100, Igor Mammedov wrote:
> > > > > On Fri, 23 Jan 2015 10:11:19 +0200
> > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > 
> > > > > > On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> > > > > > > Adds for dynamic AML creation, which will be used
> > > > > > > for piecing ASL/AML primitives together and hiding
> > > > > > > from user/caller details about how nested context
> > > > > > > should be closed/packed leaving less space for
> > > > > > > mistakes and necessity to know how AML should be
> > > > > > > encoded, allowing user to concentrate on ASL
> > > > > > > representation instead.
> > > > > > > 
> > > > > > > For example it will allow to create AML like this:
> > > > > > > 
> > > > > > > AcpiAml scope = acpi_scope("PCI0")
> > > > > > > AcpiAml dev = acpi_device("PM")
> > > > > > >     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> > > > > > > aml_append(&scope, dev);
> > > > > > > 
> > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > > > ---
> > > > > > >  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
> > > > > > >  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
> > > > > > >  2 files changed, 55 insertions(+)
> > > > > > > 
> > > > > > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > > > > > index 602e68c..547ecaa 100644
> > > > > > > --- a/hw/acpi/acpi-build-utils.c
> > > > > > > +++ b/hw/acpi/acpi-build-utils.c
> > > > > > > @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
> > > > > > >          build_append_value(table, value, 4);
> > > > > > >      }
> > > > > > >  }
> > > > > > > +
> > > > > > > +static void build_prepend_int(GArray *array, uint32_t value)
> > > > > > > +{
> > > > > > > +    GArray *data = build_alloc_array();
> > > > > > > +
> > > > > > > +    build_append_int(data, value);
> > > > > > > +    g_array_prepend_vals(array, data->data, data->len);
> > > > > > > +    build_free_array(data);
> > > > > > > +}
> > > > > > 
> > > > > > I don't think prepend is generally justified:
> > > > > > it makes code hard to follow and debug.
> > > > > > 
> > > > > > Adding length is different: of course you need
> > > > > > to first have the package before you can add length.
> > > > > > 
> > > > > > We currently have build_prepend_package_length - just move it
> > > > > > to utils, and use everywhere.
> > > > > [...]
> > > > > > > +    case BUFFER:
> > > > > > > +        build_prepend_int(child.buf, child.buf->len);
> > > > > > > +        build_package(child.buf, child.op);
> > > > > Buffer uses the same concept as package, but adds its own additional length.
> > > > > Therefore I've added build_prepend_int(),
> > > > > I can create build_buffer() and mimic build_package()
> > > > 
> > > > Sounds good, pls do.
> > > > The point is to avoid generic prepend calls as an external API.
> > > > 
> > > > > but it won't change picture.
> > > > 
> > > > It's a better API - what is meant by picture?
> > > build_prepend_int() is a static/non public function,
> > > build_buffer() will also be static/non public function for use only by
> > > API internals.
> > > 
> > > I pretty much hate long build_append_foo() names so I'm hiding all
> > > lowlevel constructs and try to expose only high-level ASL ones.
> > > Which makes me to think that we need to use asl_ prefix for API calls
> > > instead of acpi_ or aml_.
> > 
> > This sounds wrong unless we either accept ASL input or
> > produce ASL output.
> > 
> > Igor, I think you are aiming a bit too high. Don't try to
> > write your own language, just use C. It does have
> > overhead like need to declare functions and variables,
> > and allocate/free memory, but they are well understood.
> I refuse to give up on cleaner and simpler API yet :)
> 
> > 
> > 
> > Your patches are almost there, they are pretty clean, the only issue I
> > think is this passing of AcpiAml by value, sometimes freeing buffer in
> > the process, sometimes not.
> Currently buffer is allocated by API and is always freed whenever
> it's passed to another API function.
> That's why it makes user not to care about memory mgmt.
> 
> The only limitation of it is if you store AcpiAml return value into some
> variable you are responsible to use it only once for passing to another API
> function. Reusing this variable's value (pass it to API function second time)
> would cause cause use-after-free and freeing-freed bugs.
> Like this:
> AcpiAml table = acpi_definition_block("SSDT",...);
> AcpiAml scope = acpi_scope("PCI0");
> aml_append(&table, scope); // <- here scope becomes invalid
> // a bug
> aml_append(&table, scope); // use-after-free + freeing-freed bugs
> 
> There are several approaches to look for resolving above issues:
> 1. Adopt and use memory mgmt model used by GTK+
>    in nutshell: http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
>    In particular adopt behavior of GInitiallyUnowned usage model
> 
>    that will allow to keep convenient chained call style and if necessary
>    reuse objects returned by API by explicitly referencing/dereferencing
>    them if needed.

Hmm, it's still easy to misuse. I think I prefer option 2 below.

> 2. It's possible to drop freeing inside API completely and
>    record(store in list) every new object inside a table context.
>    When table is constructed, list of created objects could be
>    safely freed.
>    With that it would be safe to reuse every AcpiAml object
>    and avoid free-after-use issues with limitation that created
>    AcpiAml objects shouldn't be used after table was closed.
>    It should cover all practical use of API, i.e. no cross
>    table AcpiAml objects.

So each aml_alloc function gets pointer to this list,
and adds the new element there.
Eventually we do free_all to free all elements,
so there isn't even an aml_free to mis-use.

Good idea! I think this will address the issue.


> 3. talloc implementation Amit've mentioned,
>    perhaps it might work since it allows to set destructors for
>    managed pointers. With this we might get clear abort when
>    dereferencing freed pointer see talloc_set()


I think it's a separate discussion. Maybe talloc is a good
allocator to use in qemu, but using a separate allocator
just for acpi generation would be an overkill.

> 
> > 
> > Just pass AcpiAml* everywhere, add APIs to allocate and free it
> > together with the internal buffer.
> > This makes it trivial to see that value is not misused:
> > just check it's between alloc and free - and that there are
> > no leaks - just check we call free on each value.
> > We can write a semantic patch to catch missing free calls,
> > it's easy.
> > 
> > 
> > > > 
> > > > > As for moving to to another file, during all this series lowlevel
> > > > > build_(some_aml_related_costruct_helper)s are moved into this file
> > > > > and should be make static to hide from user lowlevel helpers
> > > > > (including build_package).
> > > > > That will leave only high level API available.
> > > > > 
> > > > > TODO for me: make sure that moved lowlevel helpers are static
> > > > > 
> > > > > 
> > > > > > > +        break;
> > > > > > > +    default:
> > > > > > > +        break;
> > > > > > > +    }
> > > > > > > +    build_append_array(parent_ctx->buf, child.buf);
> > > > > > > +    build_free_array(child.buf);
> > > > > > > +}
> > > > > > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > > > > > index 199f003..64e7ec3 100644
> > > > > > > --- a/include/hw/acpi/acpi-build-utils.h
> > > > > > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > > > > > @@ -5,6 +5,22 @@
> > > > > > >  #include <glib.h>
> > > > > > >  #include "qemu/compiler.h"
> > > > > > >  
> > > > > > > +typedef enum {
> > > > > > > +    NON_BLOCK,
> > > > > > > +    PACKAGE,
> > > > > > > +    EXT_PACKAGE,
> > > > > > > +    BUFFER,
> > > > > > > +    RES_TEMPLATE,
> > > > > > > +} AcpiBlockFlags;
> > > > > > > +
> > > > > > > +typedef struct AcpiAml {
> > > > > > > +    GArray *buf;
> > > > > > > +    uint8_t op;
> > > > > > > +    AcpiBlockFlags block_flags;
> > > > > > > +} AcpiAml;
> > > > > > > +
> > > > > > > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > > > > > +
> > > > > > >  GArray *build_alloc_array(void);
> > > > > > >  void build_free_array(GArray *array);
> > > > > > >  void build_prepend_byte(GArray *array, uint8_t val);
> > > > > > > -- 
> > > > > > > 1.8.3.1
> > 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-24 16:33               ` Michael S. Tsirkin
@ 2015-01-26  9:57                 ` Igor Mammedov
  2015-01-26 10:37                   ` Michael S. Tsirkin
  2015-01-26 15:09                   ` Igor Mammedov
  0 siblings, 2 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-26  9:57 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Sat, 24 Jan 2015 18:33:50 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
> > On Fri, 23 Jan 2015 15:55:11 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Fri, Jan 23, 2015 at 02:40:30PM +0100, Igor Mammedov wrote:
> > > > On Fri, 23 Jan 2015 15:24:24 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Fri, Jan 23, 2015 at 11:35:29AM +0100, Igor Mammedov wrote:
> > > > > > On Fri, 23 Jan 2015 10:11:19 +0200
> > > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > > 
> > > > > > > On Thu, Jan 22, 2015 at 02:49:45PM +0000, Igor Mammedov wrote:
> > > > > > > > Adds for dynamic AML creation, which will be used
> > > > > > > > for piecing ASL/AML primitives together and hiding
> > > > > > > > from user/caller details about how nested context
> > > > > > > > should be closed/packed leaving less space for
> > > > > > > > mistakes and necessity to know how AML should be
> > > > > > > > encoded, allowing user to concentrate on ASL
> > > > > > > > representation instead.
> > > > > > > > 
> > > > > > > > For example it will allow to create AML like this:
> > > > > > > > 
> > > > > > > > AcpiAml scope = acpi_scope("PCI0")
> > > > > > > > AcpiAml dev = acpi_device("PM")
> > > > > > > >     aml_append(&dev, acpi_name_decl("_ADR", acpi_int(addr)))
> > > > > > > > aml_append(&scope, dev);
> > > > > > > > 
> > > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > > > > ---
> > > > > > > >  hw/acpi/acpi-build-utils.c         | 39 ++++++++++++++++++++++++++++++++++++++
> > > > > > > >  include/hw/acpi/acpi-build-utils.h | 16 ++++++++++++++++
> > > > > > > >  2 files changed, 55 insertions(+)
> > > > > > > > 
> > > > > > > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > > > > > > index 602e68c..547ecaa 100644
> > > > > > > > --- a/hw/acpi/acpi-build-utils.c
> > > > > > > > +++ b/hw/acpi/acpi-build-utils.c
> > > > > > > > @@ -267,3 +267,42 @@ void build_append_int(GArray *table, uint32_t value)
> > > > > > > >          build_append_value(table, value, 4);
> > > > > > > >      }
> > > > > > > >  }
> > > > > > > > +
> > > > > > > > +static void build_prepend_int(GArray *array, uint32_t value)
> > > > > > > > +{
> > > > > > > > +    GArray *data = build_alloc_array();
> > > > > > > > +
> > > > > > > > +    build_append_int(data, value);
> > > > > > > > +    g_array_prepend_vals(array, data->data, data->len);
> > > > > > > > +    build_free_array(data);
> > > > > > > > +}
> > > > > > > 
> > > > > > > I don't think prepend is generally justified:
> > > > > > > it makes code hard to follow and debug.
> > > > > > > 
> > > > > > > Adding length is different: of course you need
> > > > > > > to first have the package before you can add length.
> > > > > > > 
> > > > > > > We currently have build_prepend_package_length - just move it
> > > > > > > to utils, and use everywhere.
> > > > > > [...]
> > > > > > > > +    case BUFFER:
> > > > > > > > +        build_prepend_int(child.buf, child.buf->len);
> > > > > > > > +        build_package(child.buf, child.op);
> > > > > > Buffer uses the same concept as package, but adds its own additional length.
> > > > > > Therefore I've added build_prepend_int(),
> > > > > > I can create build_buffer() and mimic build_package()
> > > > > 
> > > > > Sounds good, pls do.
> > > > > The point is to avoid generic prepend calls as an external API.
> > > > > 
> > > > > > but it won't change picture.
> > > > > 
> > > > > It's a better API - what is meant by picture?
> > > > build_prepend_int() is a static/non public function,
> > > > build_buffer() will also be static/non public function for use only by
> > > > API internals.
> > > > 
> > > > I pretty much hate long build_append_foo() names so I'm hiding all
> > > > lowlevel constructs and try to expose only high-level ASL ones.
> > > > Which makes me to think that we need to use asl_ prefix for API calls
> > > > instead of acpi_ or aml_.
> > > 
> > > This sounds wrong unless we either accept ASL input or
> > > produce ASL output.
> > > 
> > > Igor, I think you are aiming a bit too high. Don't try to
> > > write your own language, just use C. It does have
> > > overhead like need to declare functions and variables,
> > > and allocate/free memory, but they are well understood.
> > I refuse to give up on cleaner and simpler API yet :)
> > 
> > > 
> > > 
> > > Your patches are almost there, they are pretty clean, the only issue I
> > > think is this passing of AcpiAml by value, sometimes freeing buffer in
> > > the process, sometimes not.
> > Currently buffer is allocated by API and is always freed whenever
> > it's passed to another API function.
> > That's why it makes user not to care about memory mgmt.
> > 
> > The only limitation of it is if you store AcpiAml return value into some
> > variable you are responsible to use it only once for passing to another API
> > function. Reusing this variable's value (pass it to API function second time)
> > would cause cause use-after-free and freeing-freed bugs.
> > Like this:
> > AcpiAml table = acpi_definition_block("SSDT",...);
> > AcpiAml scope = acpi_scope("PCI0");
> > aml_append(&table, scope); // <- here scope becomes invalid
> > // a bug
> > aml_append(&table, scope); // use-after-free + freeing-freed bugs
> > 
> > There are several approaches to look for resolving above issues:
> > 1. Adopt and use memory mgmt model used by GTK+
> >    in nutshell: http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
> >    In particular adopt behavior of GInitiallyUnowned usage model
> > 
> >    that will allow to keep convenient chained call style and if necessary
> >    reuse objects returned by API by explicitly referencing/dereferencing
> >    them if needed.
> 
> Hmm, it's still easy to misuse. I think I prefer option 2 below.
That's basically what we have/use in QOM with object_new(FOO) + object_unref()
I have no idea why we invented our own Object infrastructure
when we could just use GObject one from already used glib.

> 
> > 2. It's possible to drop freeing inside API completely and
> >    record(store in list) every new object inside a table context.
> >    When table is constructed, list of created objects could be
> >    safely freed.
> >    With that it would be safe to reuse every AcpiAml object
> >    and avoid free-after-use issues with limitation that created
> >    AcpiAml objects shouldn't be used after table was closed.
> >    It should cover all practical use of API, i.e. no cross
> >    table AcpiAml objects.
> 
> So each aml_alloc function gets pointer to this list,
> and adds the new element there.
> Eventually we do free_all to free all elements,
> so there isn't even an aml_free to mis-use.
I'm thinking a little bit different about implementation though.
I still don't like the use of explicit alloc/free being called
by API user since it doesn't allow chained API calls and
I think it's unnecessary complication see below why.

Here is what's true about current API and a I'd like to with it:

  1. Every API call (except aml_append) makes aml_alloc(), it's just
     like a wrapper about object_new(FOO). (current + new impl.)

  2 Every API call that takes AML type as input argument
  2.1 consumes (frees) it (current impl.)
      (it's easy to fix use after free concern too,
       just pass AML by pointer and zero-out memory before it's freed
       and assert whenever one of input arguments is not correct,
       i.e. it was reused second time)
      There is no need for following steps after this one.
  2.2 takes ownership of GInitiallyUnowned and adds it to its list
      of its children.
  3. Free children when AML object is destroyed (i.e. ref count zero)
     That way when toplevel table object (definition block in 42/47)
     is added to ACPI blob we can unref it, which will cause
     its whole children tree freed, except for AML objects where
     API user explicitly took extra reference (i.e. wanted them
     to reuse in another table)

I'd prefer:
 *  2.1 way to address your current concern of use-after-free
    as the most simplest one (no reuse is possible however)
or
 * follow already used by QEMU QOM/GObject pattern of
   implicit alloc/free

since they allow to construct AML in a more simple/manageable way i.e.
 
  aml_append(method,
      aml_store(aml_string("foo"), aml_local(0)))
  );

v.s. explicit headache of alloc/free, which doesn't fix
     use-after-free anyway and just adds more boiler plate
     plus makes code har to read read

  str = aml_alloc();
  aml_string(str, "foo");
  loc0 = aml_alloc();
  aml_local(loc0, 0);
  store = aml_alloc();
  aml_store(store, str, loc0);
  aml_append(method, store);
  aml_free(store);
  aml_free(loc0);
  aml_free(str);

> 
> Good idea! I think this will address the issue.
> 
> 
> > 3. talloc implementation Amit've mentioned,
> >    perhaps it might work since it allows to set destructors for
> >    managed pointers. With this we might get clear abort when
> >    dereferencing freed pointer see talloc_set()
> 
> 
> I think it's a separate discussion. Maybe talloc is a good
> allocator to use in qemu, but using a separate allocator
> just for acpi generation would be an overkill.
> 
> > 
> > > 
> > > Just pass AcpiAml* everywhere, add APIs to allocate and free it
> > > together with the internal buffer.
> > > This makes it trivial to see that value is not misused:
> > > just check it's between alloc and free - and that there are
> > > no leaks - just check we call free on each value.
> > > We can write a semantic patch to catch missing free calls,
> > > it's easy.
> > > 
> > > 
> > > > > 
> > > > > > As for moving to to another file, during all this series lowlevel
> > > > > > build_(some_aml_related_costruct_helper)s are moved into this file
> > > > > > and should be make static to hide from user lowlevel helpers
> > > > > > (including build_package).
> > > > > > That will leave only high level API available.
> > > > > > 
> > > > > > TODO for me: make sure that moved lowlevel helpers are static
> > > > > > 
> > > > > > 
> > > > > > > > +        break;
> > > > > > > > +    default:
> > > > > > > > +        break;
> > > > > > > > +    }
> > > > > > > > +    build_append_array(parent_ctx->buf, child.buf);
> > > > > > > > +    build_free_array(child.buf);
> > > > > > > > +}
> > > > > > > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > > > > > > index 199f003..64e7ec3 100644
> > > > > > > > --- a/include/hw/acpi/acpi-build-utils.h
> > > > > > > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > > > > > > @@ -5,6 +5,22 @@
> > > > > > > >  #include <glib.h>
> > > > > > > >  #include "qemu/compiler.h"
> > > > > > > >  
> > > > > > > > +typedef enum {
> > > > > > > > +    NON_BLOCK,
> > > > > > > > +    PACKAGE,
> > > > > > > > +    EXT_PACKAGE,
> > > > > > > > +    BUFFER,
> > > > > > > > +    RES_TEMPLATE,
> > > > > > > > +} AcpiBlockFlags;
> > > > > > > > +
> > > > > > > > +typedef struct AcpiAml {
> > > > > > > > +    GArray *buf;
> > > > > > > > +    uint8_t op;
> > > > > > > > +    AcpiBlockFlags block_flags;
> > > > > > > > +} AcpiAml;
> > > > > > > > +
> > > > > > > > +void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > > > > > > +
> > > > > > > >  GArray *build_alloc_array(void);
> > > > > > > >  void build_free_array(GArray *array);
> > > > > > > >  void build_prepend_byte(GArray *array, uint8_t val);
> > > > > > > > -- 
> > > > > > > > 1.8.3.1
> > > 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-26  9:57                 ` Igor Mammedov
@ 2015-01-26 10:37                   ` Michael S. Tsirkin
  2015-01-26 15:09                   ` Igor Mammedov
  1 sibling, 0 replies; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-26 10:37 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

> v.s. explicit headache of alloc/free, which doesn't fix
>      use-after-free anyway and just adds more boiler plate
>      plus makes code har to read read
> 
>   str = aml_alloc();
>   aml_string(str, "foo");
>   loc0 = aml_alloc();
>   aml_local(loc0, 0);
>   store = aml_alloc();
>   aml_store(store, str, loc0);
>   aml_append(method, store);
>   aml_free(store);
>   aml_free(loc0);
>   aml_free(str);

Looks like I wasn't clear.  This is what I propose:

void aml_add_method(AmlPool *pool, AmlBlob *aml)
{
   AmlBlob *str = aml_alloc(pool);
   aml_string(str, "foo");
   loc0 = aml_alloc(pool);
   aml_local(loc0, 0);
   AmlBob *store = aml_alloc(pool);
   aml_store(store, str, loc0);
   aml_append(method, store);
}


So just propagare AmlPool* everywhere, don't free.

Then at top level:

	AmlPool *pool = aml_pool_alloc();

	AmlSsdt = aml_add_ssdt(pool, ....);

	....

	aml_pool_free(pool);



So from API perspective, this is very close to
what you posted, with just two changes:

	- pass pool parameter everywhere
	- have an extra alloc/free in only one place.

Happy?

-- 
MST

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-26  9:57                 ` Igor Mammedov
  2015-01-26 10:37                   ` Michael S. Tsirkin
@ 2015-01-26 15:09                   ` Igor Mammedov
  2015-01-26 15:34                     ` Andrew Jones
  1 sibling, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-26 15:09 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Mon, 26 Jan 2015 10:57:21 +0100
Igor Mammedov <imammedo@redhat.com> wrote:

> On Sat, 24 Jan 2015 18:33:50 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
> > > On Fri, 23 Jan 2015 15:55:11 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
[...]
> > > I refuse to give up on cleaner and simpler API yet :)
> > > 
> > > > 
> > > > 
> > > > Your patches are almost there, they are pretty clean, the only issue I
> > > > think is this passing of AcpiAml by value, sometimes freeing buffer in
> > > > the process, sometimes not.
> > > Currently buffer is allocated by API and is always freed whenever
> > > it's passed to another API function.
> > > That's why it makes user not to care about memory mgmt.
> > > 
> > > The only limitation of it is if you store AcpiAml return value into some
> > > variable you are responsible to use it only once for passing to another API
> > > function. Reusing this variable's value (pass it to API function second time)
> > > would cause cause use-after-free and freeing-freed bugs.
> > > Like this:
> > > AcpiAml table = acpi_definition_block("SSDT",...);
> > > AcpiAml scope = acpi_scope("PCI0");
> > > aml_append(&table, scope); // <- here scope becomes invalid
> > > // a bug
> > > aml_append(&table, scope); // use-after-free + freeing-freed bugs
> > > 
> > > There are several approaches to look for resolving above issues:
> > > 1. Adopt and use memory mgmt model used by GTK+
> > >    in nutshell: http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
> > >    In particular adopt behavior of GInitiallyUnowned usage model
> > > 
> > >    that will allow to keep convenient chained call style and if necessary
> > >    reuse objects returned by API by explicitly referencing/dereferencing
> > >    them if needed.
> > 
> > Hmm, it's still easy to misuse. I think I prefer option 2 below.
> That's basically what we have/use in QOM with object_new(FOO) + object_unref()
> I have no idea why we invented our own Object infrastructure
> when we could just use GObject one from already used glib.
> 
> > 
> > > 2. It's possible to drop freeing inside API completely and
> > >    record(store in list) every new object inside a table context.
> > >    When table is constructed, list of created objects could be
> > >    safely freed.
> > >    With that it would be safe to reuse every AcpiAml object
> > >    and avoid free-after-use issues with limitation that created
> > >    AcpiAml objects shouldn't be used after table was closed.
> > >    It should cover all practical use of API, i.e. no cross
> > >    table AcpiAml objects.
> > 
> > So each aml_alloc function gets pointer to this list,
> > and adds the new element there.
> > Eventually we do free_all to free all elements,
> > so there isn't even an aml_free to mis-use.
> I'm thinking a little bit different about implementation though.
> I still don't like the use of explicit alloc/free being called
> by API user since it doesn't allow chained API calls and
> I think it's unnecessary complication see below why.
> 
> Here is what's true about current API and a I'd like to with it:
> 
>   1. Every API call (except aml_append) makes aml_alloc(), it's just
>      like a wrapper about object_new(FOO). (current + new impl.)
> 
>   2 Every API call that takes AML type as input argument
>   2.1 consumes (frees) it (current impl.)
>       (it's easy to fix use after free concern too,
>        just pass AML by pointer and zero-out memory before it's freed
>        and assert whenever one of input arguments is not correct,
>        i.e. it was reused second time)
>       There is no need for following steps after this one.
>   2.2 takes ownership of GInitiallyUnowned and adds it to its list
>       of its children.
>   3. Free children when AML object is destroyed (i.e. ref count zero)
>      That way when toplevel table object (definition block in 42/47)
>      is added to ACPI blob we can unref it, which will cause
>      its whole children tree freed, except for AML objects where
>      API user explicitly took extra reference (i.e. wanted them
>      to reuse in another table)
> 
> I'd prefer:
>  *  2.1 way to address your current concern of use-after-free
>     as the most simplest one (no reuse is possible however)
> or
>  * follow already used by QEMU QOM/GObject pattern of
>    implicit alloc/free
> 
> since they allow to construct AML in a more simple/manageable way i.e.
>  
>   aml_append(method,
>       aml_store(aml_string("foo"), aml_local(0)))
>   );
> 
> v.s. explicit headache of alloc/free, which doesn't fix
>      use-after-free anyway and just adds more boiler plate
>      plus makes code har to read read
> 
>   str = aml_alloc();
>   aml_string(str, "foo");
>   loc0 = aml_alloc();
>   aml_local(loc0, 0);
>   store = aml_alloc();
>   aml_store(store, str, loc0);
>   aml_append(method, store);
>   aml_free(store);
>   aml_free(loc0);
>   aml_free(str);

Here is a compromise what I and Michael came to on a phone call:

Externally API usage would look like:

AmlAllocList *p = some_list_alloc();

Aml *ssdt = aml_def_block(p, "SSDT", ...);
Aml *dev = aml_device(p, "PCI0");
aml_append(dev,
    aml_name_def(p, "_STA", aml_int(p, 0xF /* present */))
);
aml_append(ssdt, dev);

aml_append(acpi_tables_blob, ssdt);

free_aml_alloc_list(p);


Each of aml_foo() will take other Aml arguments by pointer.
Also every aml_foo(), except of aml_append() will allocate
Aml struct and return pointer to it and also add this pointer
into AmlAllocList which is passed as first argument to each
aml_foo() call.
aml_append() becomes nondestructive function and just adds
child(2nd arg) to the parent context (1st arg).

After API user is done with building table and pushed it
into tables blob, he/she calls free_aml_alloc_list() to free
all Aml objects created during process of building the table
content.

> 
> > 
> > Good idea! I think this will address the issue.
> > 
> > 
> > > 3. talloc implementation Amit've mentioned,
> > >    perhaps it might work since it allows to set destructors for
> > >    managed pointers. With this we might get clear abort when
> > >    dereferencing freed pointer see talloc_set()
> > 
> > 
> > I think it's a separate discussion. Maybe talloc is a good
> > allocator to use in qemu, but using a separate allocator
> > just for acpi generation would be an overkill.
> > 
> > > 
> > > > 
> > > > Just pass AcpiAml* everywhere, add APIs to allocate and free it
> > > > together with the internal buffer.
> > > > This makes it trivial to see that value is not misused:
> > > > just check it's between alloc and free - and that there are
> > > > no leaks - just check we call free on each value.
> > > > We can write a semantic patch to catch missing free calls,
> > > > it's easy.
> > > > 
> > > > 
> > > > > > 
> > > > > > > As for moving to to another file, during all this series lowlevel
> > > > > > > build_(some_aml_related_costruct_helper)s are moved into this file
> > > > > > > and should be make static to hide from user lowlevel helpers
> > > > > > > (including build_package).
> > > > > > > That will leave only high level API available.
> > > > > > > 
> > > > > > > TODO for me: make sure that moved lowlevel helpers are static
> > > > > > > 
> > > > > > > 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-26 15:09                   ` Igor Mammedov
@ 2015-01-26 15:34                     ` Andrew Jones
  2015-01-26 16:17                       ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Andrew Jones @ 2015-01-26 15:34 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: pbonzini, marcel.a, claudio.fontana, qemu-devel, Michael S. Tsirkin

On Mon, Jan 26, 2015 at 04:09:20PM +0100, Igor Mammedov wrote:
> On Mon, 26 Jan 2015 10:57:21 +0100
> Igor Mammedov <imammedo@redhat.com> wrote:
> 
> > On Sat, 24 Jan 2015 18:33:50 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
> > > > On Fri, 23 Jan 2015 15:55:11 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> [...]
> > > > I refuse to give up on cleaner and simpler API yet :)
> > > > 
> > > > > 
> > > > > 
> > > > > Your patches are almost there, they are pretty clean, the only issue I
> > > > > think is this passing of AcpiAml by value, sometimes freeing buffer in
> > > > > the process, sometimes not.
> > > > Currently buffer is allocated by API and is always freed whenever
> > > > it's passed to another API function.
> > > > That's why it makes user not to care about memory mgmt.
> > > > 
> > > > The only limitation of it is if you store AcpiAml return value into some
> > > > variable you are responsible to use it only once for passing to another API
> > > > function. Reusing this variable's value (pass it to API function second time)
> > > > would cause cause use-after-free and freeing-freed bugs.
> > > > Like this:
> > > > AcpiAml table = acpi_definition_block("SSDT",...);
> > > > AcpiAml scope = acpi_scope("PCI0");
> > > > aml_append(&table, scope); // <- here scope becomes invalid
> > > > // a bug
> > > > aml_append(&table, scope); // use-after-free + freeing-freed bugs
> > > > 
> > > > There are several approaches to look for resolving above issues:
> > > > 1. Adopt and use memory mgmt model used by GTK+
> > > >    in nutshell: http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
> > > >    In particular adopt behavior of GInitiallyUnowned usage model
> > > > 
> > > >    that will allow to keep convenient chained call style and if necessary
> > > >    reuse objects returned by API by explicitly referencing/dereferencing
> > > >    them if needed.
> > > 
> > > Hmm, it's still easy to misuse. I think I prefer option 2 below.
> > That's basically what we have/use in QOM with object_new(FOO) + object_unref()
> > I have no idea why we invented our own Object infrastructure
> > when we could just use GObject one from already used glib.
> > 
> > > 
> > > > 2. It's possible to drop freeing inside API completely and
> > > >    record(store in list) every new object inside a table context.
> > > >    When table is constructed, list of created objects could be
> > > >    safely freed.
> > > >    With that it would be safe to reuse every AcpiAml object
> > > >    and avoid free-after-use issues with limitation that created
> > > >    AcpiAml objects shouldn't be used after table was closed.
> > > >    It should cover all practical use of API, i.e. no cross
> > > >    table AcpiAml objects.
> > > 
> > > So each aml_alloc function gets pointer to this list,
> > > and adds the new element there.
> > > Eventually we do free_all to free all elements,
> > > so there isn't even an aml_free to mis-use.
> > I'm thinking a little bit different about implementation though.
> > I still don't like the use of explicit alloc/free being called
> > by API user since it doesn't allow chained API calls and
> > I think it's unnecessary complication see below why.
> > 
> > Here is what's true about current API and a I'd like to with it:
> > 
> >   1. Every API call (except aml_append) makes aml_alloc(), it's just
> >      like a wrapper about object_new(FOO). (current + new impl.)
> > 
> >   2 Every API call that takes AML type as input argument
> >   2.1 consumes (frees) it (current impl.)
> >       (it's easy to fix use after free concern too,
> >        just pass AML by pointer and zero-out memory before it's freed
> >        and assert whenever one of input arguments is not correct,
> >        i.e. it was reused second time)
> >       There is no need for following steps after this one.
> >   2.2 takes ownership of GInitiallyUnowned and adds it to its list
> >       of its children.
> >   3. Free children when AML object is destroyed (i.e. ref count zero)
> >      That way when toplevel table object (definition block in 42/47)
> >      is added to ACPI blob we can unref it, which will cause
> >      its whole children tree freed, except for AML objects where
> >      API user explicitly took extra reference (i.e. wanted them
> >      to reuse in another table)
> > 
> > I'd prefer:
> >  *  2.1 way to address your current concern of use-after-free
> >     as the most simplest one (no reuse is possible however)
> > or
> >  * follow already used by QEMU QOM/GObject pattern of
> >    implicit alloc/free
> > 
> > since they allow to construct AML in a more simple/manageable way i.e.
> >  
> >   aml_append(method,
> >       aml_store(aml_string("foo"), aml_local(0)))
> >   );
> > 
> > v.s. explicit headache of alloc/free, which doesn't fix
> >      use-after-free anyway and just adds more boiler plate
> >      plus makes code har to read read
> > 
> >   str = aml_alloc();
> >   aml_string(str, "foo");
> >   loc0 = aml_alloc();
> >   aml_local(loc0, 0);
> >   store = aml_alloc();
> >   aml_store(store, str, loc0);
> >   aml_append(method, store);
> >   aml_free(store);
> >   aml_free(loc0);
> >   aml_free(str);
> 
> Here is a compromise what I and Michael came to on a phone call:
> 
> Externally API usage would look like:
> 
> AmlAllocList *p = some_list_alloc();
> 
> Aml *ssdt = aml_def_block(p, "SSDT", ...);
> Aml *dev = aml_device(p, "PCI0");
> aml_append(dev,
>     aml_name_def(p, "_STA", aml_int(p, 0xF /* present */))
> );
> aml_append(ssdt, dev);
> 
> aml_append(acpi_tables_blob, ssdt);
> 
> free_aml_alloc_list(p);
> 
> 
> Each of aml_foo() will take other Aml arguments by pointer.
> Also every aml_foo(), except of aml_append() will allocate
> Aml struct and return pointer to it and also add this pointer
> into AmlAllocList which is passed as first argument to each
> aml_foo() call.
> aml_append() becomes nondestructive function and just adds
> child(2nd arg) to the parent context (1st arg).
> 
> After API user is done with building table and pushed it
> into tables blob, he/she calls free_aml_alloc_list() to free
> all Aml objects created during process of building the table
> content.

Hmm, passing 'p' around somewhat muddies an otherwise clean
interface, but the concern with aml_append silently freeing
memory still accessible by the caller is definitely valid. I
only wonder how things would look with Igor's option 2.2 above.
The caller still only needs to free the final table, but it
also becomes safe to use the same object references multiple
times before freeing the table. Using QOM also seems reasonable
to me, as it appears it's the accepted way to do garbage
collection in QEMU. Is it possible to do 2.2 with QOM?

> 
> > 
> > > 
> > > Good idea! I think this will address the issue.
> > > 
> > > 
> > > > 3. talloc implementation Amit've mentioned,
> > > >    perhaps it might work since it allows to set destructors for
> > > >    managed pointers. With this we might get clear abort when
> > > >    dereferencing freed pointer see talloc_set()
> > > 
> > > 
> > > I think it's a separate discussion. Maybe talloc is a good
> > > allocator to use in qemu, but using a separate allocator
> > > just for acpi generation would be an overkill.
> > > 
> > > > 
> > > > > 
> > > > > Just pass AcpiAml* everywhere, add APIs to allocate and free it
> > > > > together with the internal buffer.
> > > > > This makes it trivial to see that value is not misused:
> > > > > just check it's between alloc and free - and that there are
> > > > > no leaks - just check we call free on each value.
> > > > > We can write a semantic patch to catch missing free calls,
> > > > > it's easy.
> > > > > 
> > > > > 
> > > > > > > 
> > > > > > > > As for moving to to another file, during all this series lowlevel
> > > > > > > > build_(some_aml_related_costruct_helper)s are moved into this file
> > > > > > > > and should be make static to hide from user lowlevel helpers
> > > > > > > > (including build_package).
> > > > > > > > That will leave only high level API available.
> > > > > > > > 
> > > > > > > > TODO for me: make sure that moved lowlevel helpers are static
> > > > > > > > 
> > > > > > > > 
> 
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-26 15:34                     ` Andrew Jones
@ 2015-01-26 16:17                       ` Michael S. Tsirkin
  2015-01-27 22:29                         ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-26 16:17 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Igor Mammedov, marcel.a, claudio.fontana, qemu-devel, pbonzini

On Mon, Jan 26, 2015 at 04:34:01PM +0100, Andrew Jones wrote:
> On Mon, Jan 26, 2015 at 04:09:20PM +0100, Igor Mammedov wrote:
> > On Mon, 26 Jan 2015 10:57:21 +0100
> > Igor Mammedov <imammedo@redhat.com> wrote:
> > 
> > > On Sat, 24 Jan 2015 18:33:50 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
> > > > > On Fri, 23 Jan 2015 15:55:11 +0200
> > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > 
> > [...]
> > > > > I refuse to give up on cleaner and simpler API yet :)
> > > > > 
> > > > > > 
> > > > > > 
> > > > > > Your patches are almost there, they are pretty clean, the only issue I
> > > > > > think is this passing of AcpiAml by value, sometimes freeing buffer in
> > > > > > the process, sometimes not.
> > > > > Currently buffer is allocated by API and is always freed whenever
> > > > > it's passed to another API function.
> > > > > That's why it makes user not to care about memory mgmt.
> > > > > 
> > > > > The only limitation of it is if you store AcpiAml return value into some
> > > > > variable you are responsible to use it only once for passing to another API
> > > > > function. Reusing this variable's value (pass it to API function second time)
> > > > > would cause cause use-after-free and freeing-freed bugs.
> > > > > Like this:
> > > > > AcpiAml table = acpi_definition_block("SSDT",...);
> > > > > AcpiAml scope = acpi_scope("PCI0");
> > > > > aml_append(&table, scope); // <- here scope becomes invalid
> > > > > // a bug
> > > > > aml_append(&table, scope); // use-after-free + freeing-freed bugs
> > > > > 
> > > > > There are several approaches to look for resolving above issues:
> > > > > 1. Adopt and use memory mgmt model used by GTK+
> > > > >    in nutshell: http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
> > > > >    In particular adopt behavior of GInitiallyUnowned usage model
> > > > > 
> > > > >    that will allow to keep convenient chained call style and if necessary
> > > > >    reuse objects returned by API by explicitly referencing/dereferencing
> > > > >    them if needed.
> > > > 
> > > > Hmm, it's still easy to misuse. I think I prefer option 2 below.
> > > That's basically what we have/use in QOM with object_new(FOO) + object_unref()
> > > I have no idea why we invented our own Object infrastructure
> > > when we could just use GObject one from already used glib.
> > > 
> > > > 
> > > > > 2. It's possible to drop freeing inside API completely and
> > > > >    record(store in list) every new object inside a table context.
> > > > >    When table is constructed, list of created objects could be
> > > > >    safely freed.
> > > > >    With that it would be safe to reuse every AcpiAml object
> > > > >    and avoid free-after-use issues with limitation that created
> > > > >    AcpiAml objects shouldn't be used after table was closed.
> > > > >    It should cover all practical use of API, i.e. no cross
> > > > >    table AcpiAml objects.
> > > > 
> > > > So each aml_alloc function gets pointer to this list,
> > > > and adds the new element there.
> > > > Eventually we do free_all to free all elements,
> > > > so there isn't even an aml_free to mis-use.
> > > I'm thinking a little bit different about implementation though.
> > > I still don't like the use of explicit alloc/free being called
> > > by API user since it doesn't allow chained API calls and
> > > I think it's unnecessary complication see below why.
> > > 
> > > Here is what's true about current API and a I'd like to with it:
> > > 
> > >   1. Every API call (except aml_append) makes aml_alloc(), it's just
> > >      like a wrapper about object_new(FOO). (current + new impl.)
> > > 
> > >   2 Every API call that takes AML type as input argument
> > >   2.1 consumes (frees) it (current impl.)
> > >       (it's easy to fix use after free concern too,
> > >        just pass AML by pointer and zero-out memory before it's freed
> > >        and assert whenever one of input arguments is not correct,
> > >        i.e. it was reused second time)
> > >       There is no need for following steps after this one.
> > >   2.2 takes ownership of GInitiallyUnowned and adds it to its list
> > >       of its children.
> > >   3. Free children when AML object is destroyed (i.e. ref count zero)
> > >      That way when toplevel table object (definition block in 42/47)
> > >      is added to ACPI blob we can unref it, which will cause
> > >      its whole children tree freed, except for AML objects where
> > >      API user explicitly took extra reference (i.e. wanted them
> > >      to reuse in another table)
> > > 
> > > I'd prefer:
> > >  *  2.1 way to address your current concern of use-after-free
> > >     as the most simplest one (no reuse is possible however)
> > > or
> > >  * follow already used by QEMU QOM/GObject pattern of
> > >    implicit alloc/free
> > > 
> > > since they allow to construct AML in a more simple/manageable way i.e.
> > >  
> > >   aml_append(method,
> > >       aml_store(aml_string("foo"), aml_local(0)))
> > >   );
> > > 
> > > v.s. explicit headache of alloc/free, which doesn't fix
> > >      use-after-free anyway and just adds more boiler plate
> > >      plus makes code har to read read
> > > 
> > >   str = aml_alloc();
> > >   aml_string(str, "foo");
> > >   loc0 = aml_alloc();
> > >   aml_local(loc0, 0);
> > >   store = aml_alloc();
> > >   aml_store(store, str, loc0);
> > >   aml_append(method, store);
> > >   aml_free(store);
> > >   aml_free(loc0);
> > >   aml_free(str);
> > 
> > Here is a compromise what I and Michael came to on a phone call:
> > 
> > Externally API usage would look like:
> > 
> > AmlAllocList *p = some_list_alloc();
> > 
> > Aml *ssdt = aml_def_block(p, "SSDT", ...);
> > Aml *dev = aml_device(p, "PCI0");
> > aml_append(dev,
> >     aml_name_def(p, "_STA", aml_int(p, 0xF /* present */))
> > );
> > aml_append(ssdt, dev);
> > 
> > aml_append(acpi_tables_blob, ssdt);
> > 
> > free_aml_alloc_list(p);
> > 
> > 
> > Each of aml_foo() will take other Aml arguments by pointer.
> > Also every aml_foo(), except of aml_append() will allocate
> > Aml struct and return pointer to it and also add this pointer
> > into AmlAllocList which is passed as first argument to each
> > aml_foo() call.
> > aml_append() becomes nondestructive function and just adds
> > child(2nd arg) to the parent context (1st arg).
> > 
> > After API user is done with building table and pushed it
> > into tables blob, he/she calls free_aml_alloc_list() to free
> > all Aml objects created during process of building the table
> > content.
> 
> Hmm, passing 'p' around somewhat muddies an otherwise clean
> interface, but the concern with aml_append silently freeing
> memory still accessible by the caller is definitely valid. I
> only wonder how things would look with Igor's option 2.2 above.
> The caller still only needs to free the final table, but it
> also becomes safe to use the same object references multiple
> times before freeing the table. Using QOM also seems reasonable
> to me, as it appears it's the accepted way to do garbage
> collection in QEMU. Is it possible to do 2.2 with QOM?

I'd rather not go there: QOM was really invented for introspection, and
for long-lived heavy-weight objects.  And to me, code using QOM is
harder to understand than simple alloc/free. It's worth it where we need
the features it offers, e.g. it has run-time checks where we previously
just did a cast. But in this case I'd rather use something simpler and
with compile-time checks.



> > 
> > > 
> > > > 
> > > > Good idea! I think this will address the issue.
> > > > 
> > > > 
> > > > > 3. talloc implementation Amit've mentioned,
> > > > >    perhaps it might work since it allows to set destructors for
> > > > >    managed pointers. With this we might get clear abort when
> > > > >    dereferencing freed pointer see talloc_set()
> > > > 
> > > > 
> > > > I think it's a separate discussion. Maybe talloc is a good
> > > > allocator to use in qemu, but using a separate allocator
> > > > just for acpi generation would be an overkill.
> > > > 
> > > > > 
> > > > > > 
> > > > > > Just pass AcpiAml* everywhere, add APIs to allocate and free it
> > > > > > together with the internal buffer.
> > > > > > This makes it trivial to see that value is not misused:
> > > > > > just check it's between alloc and free - and that there are
> > > > > > no leaks - just check we call free on each value.
> > > > > > We can write a semantic patch to catch missing free calls,
> > > > > > it's easy.
> > > > > > 
> > > > > > 
> > > > > > > > 
> > > > > > > > > As for moving to to another file, during all this series lowlevel
> > > > > > > > > build_(some_aml_related_costruct_helper)s are moved into this file
> > > > > > > > > and should be make static to hide from user lowlevel helpers
> > > > > > > > > (including build_package).
> > > > > > > > > That will leave only high level API available.
> > > > > > > > > 
> > > > > > > > > TODO for me: make sure that moved lowlevel helpers are static
> > > > > > > > > 
> > > > > > > > > 
> > 
> > 

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

* Re: [Qemu-devel] [PATCH v2 21/47] acpi: add acpi_resource_template() helper
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 21/47] acpi: add acpi_resource_template() helper Igor Mammedov
@ 2015-01-27 13:26   ` Claudio Fontana
  2015-01-27 13:41     ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Claudio Fontana @ 2015-01-27 13:26 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: pbonzini, drjones, marcel.a, mst

Hello Igor,

On 22.01.2015 15:50, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 8 ++++++++
>  include/hw/acpi/acpi-build-utils.h | 1 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 2d5e77a..32a4377 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -493,6 +493,14 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...)
>      return var;
>  }
> 

> +/* ResourceTemplate marcos helper */

Since you have been so careful about putting references to the spec everywhere else,
what about adding something for ResourceTemplate macros too (note typo above)?

For example 19.2.3 "ASL Resource Templates" if that's the right one. (I am looking at version 5.1)

Thanks,

Claudio

> +AcpiAml acpi_resource_template(void)
> +{
> +    /* ResourceTemplate is a buffer of Resources with EndTag at the end */
> +    AcpiAml var = aml_allocate_internal(0x11 /* BufferOp */, RES_TEMPLATE);
> +    return var;
> +}
> +
>  /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
>  AcpiAml acpi_buffer(void)
>  {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index a79c085..594fae7 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -46,6 +46,7 @@ AcpiAml acpi_method(const char *name, int arg_count);
>  AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
>  AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
>  AcpiAml acpi_buffer(void);
> +AcpiAml acpi_resource_template(void);
>  AcpiAml acpi_package(uint8_t num_elements);
>  
>  /* other helpers */
> 

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

* Re: [Qemu-devel] [PATCH v2 21/47] acpi: add acpi_resource_template() helper
  2015-01-27 13:26   ` Claudio Fontana
@ 2015-01-27 13:41     ` Michael S. Tsirkin
  0 siblings, 0 replies; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-27 13:41 UTC (permalink / raw)
  To: Claudio Fontana; +Cc: Igor Mammedov, drjones, marcel.a, qemu-devel, pbonzini

On Tue, Jan 27, 2015 at 02:26:34PM +0100, Claudio Fontana wrote:
> Hello Igor,
> 
> On 22.01.2015 15:50, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/acpi/acpi-build-utils.c         | 8 ++++++++
> >  include/hw/acpi/acpi-build-utils.h | 1 +
> >  2 files changed, 9 insertions(+)
> > 
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 2d5e77a..32a4377 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -493,6 +493,14 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...)
> >      return var;
> >  }
> > 
> 
> > +/* ResourceTemplate marcos helper */
> 
> Since you have been so careful about putting references to the spec everywhere else,
> what about adding something for ResourceTemplate macros too (note typo above)?
> 
> For example 19.2.3 "ASL Resource Templates" if that's the right one. (I am looking at version 5.1)

Pls don't, pls refer to the oldest spec that has support
for a given feature, not the newest one.

> Thanks,
> 
> Claudio
> 
> > +AcpiAml acpi_resource_template(void)
> > +{
> > +    /* ResourceTemplate is a buffer of Resources with EndTag at the end */
> > +    AcpiAml var = aml_allocate_internal(0x11 /* BufferOp */, RES_TEMPLATE);
> > +    return var;
> > +}
> > +
> >  /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
> >  AcpiAml acpi_buffer(void)
> >  {
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index a79c085..594fae7 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -46,6 +46,7 @@ AcpiAml acpi_method(const char *name, int arg_count);
> >  AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
> >  AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
> >  AcpiAml acpi_buffer(void);
> > +AcpiAml acpi_resource_template(void);
> >  AcpiAml acpi_package(uint8_t num_elements);
> >  
> >  /* other helpers */
> > 
> 
> 

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

* Re: [Qemu-devel] [PATCH v2 45/47] acpi: add acpi_iqr_no_flags() term
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 45/47] acpi: add acpi_iqr_no_flags() term Igor Mammedov
@ 2015-01-27 15:37   ` Claudio Fontana
  2015-01-28 12:15     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Claudio Fontana @ 2015-01-27 15:37 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: pbonzini, drjones, marcel.a, mst

Hi,

I think you have to replace "iqr" with "irq" in the function definition and in the commit message.

Ciao,

Claudio

On 22.01.2015 15:50, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 18 ++++++++++++++++++
>  include/hw/acpi/acpi-build-utils.h |  1 +
>  2 files changed, 19 insertions(+)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 58f88cd..59873e3 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -511,6 +511,24 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
>      return var;
>  }
>  
> +/*
> + * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
> + *           6.4.2.1 IRQ Descriptor
> +*/
> +AcpiAml acpi_iqr_no_flags(uint8_t irq)
> +{
> +    uint16_t irq_mask;
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +
> +    assert(irq < 16);
> +    build_append_byte(var.buf, 0x22); /* IRQ descriptor 2 byte form */
> +
> +    irq_mask = 1U << irq;
> +    build_append_byte(var.buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
> +    build_append_byte(var.buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
> +    return var;
> +}
> +
>  /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
>  AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2)
>  {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 868d439..d39b5b1 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -117,6 +117,7 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
>                     AcpiAml arg3, AcpiAml arg4);
>  AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
>                  uint8_t aln, uint8_t len);
> +AcpiAml acpi_iqr_no_flags(uint8_t irq);
>  AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
>                                uint32_t offset, uint32_t len);
>  AcpiAml acpi_named_field(const char *name, unsigned length);
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-26 16:17                       ` Michael S. Tsirkin
@ 2015-01-27 22:29                         ` Igor Mammedov
  2015-01-28  7:27                           ` Michael S. Tsirkin
                                             ` (2 more replies)
  0 siblings, 3 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-27 22:29 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, Andrew Jones, claudio.fontana, qemu-devel, marcel.a

On Mon, 26 Jan 2015 18:17:55 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Mon, Jan 26, 2015 at 04:34:01PM +0100, Andrew Jones wrote:
> > On Mon, Jan 26, 2015 at 04:09:20PM +0100, Igor Mammedov wrote:
> > > On Mon, 26 Jan 2015 10:57:21 +0100
> > > Igor Mammedov <imammedo@redhat.com> wrote:
> > > 
> > > > On Sat, 24 Jan 2015 18:33:50 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
> > > > > > On Fri, 23 Jan 2015 15:55:11 +0200
> > > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > > 
> > > [...]
> > > > > > I refuse to give up on cleaner and simpler API yet :)
> > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > Your patches are almost there, they are pretty clean, the
> > > > > > > only issue I think is this passing of AcpiAml by value,
> > > > > > > sometimes freeing buffer in the process, sometimes not.
> > > > > > Currently buffer is allocated by API and is always freed
> > > > > > whenever it's passed to another API function.
> > > > > > That's why it makes user not to care about memory mgmt.
> > > > > > 
> > > > > > The only limitation of it is if you store AcpiAml return
> > > > > > value into some variable you are responsible to use it only
> > > > > > once for passing to another API function. Reusing this
> > > > > > variable's value (pass it to API function second time)
> > > > > > would cause cause use-after-free and freeing-freed bugs.
> > > > > > Like this: AcpiAml table =
> > > > > > acpi_definition_block("SSDT",...); AcpiAml scope =
> > > > > > acpi_scope("PCI0"); aml_append(&table, scope); // <- here
> > > > > > scope becomes invalid // a bug
> > > > > > aml_append(&table, scope); // use-after-free +
> > > > > > freeing-freed bugs
> > > > > > 
> > > > > > There are several approaches to look for resolving above
> > > > > > issues: 1. Adopt and use memory mgmt model used by GTK+
> > > > > >    in nutshell:
> > > > > > http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
> > > > > > In particular adopt behavior of GInitiallyUnowned usage
> > > > > > model
> > > > > > 
> > > > > >    that will allow to keep convenient chained call style
> > > > > > and if necessary reuse objects returned by API by
> > > > > > explicitly referencing/dereferencing them if needed.
> > > > > 
> > > > > Hmm, it's still easy to misuse. I think I prefer option 2
> > > > > below.
> > > > That's basically what we have/use in QOM with object_new(FOO) +
> > > > object_unref() I have no idea why we invented our own Object
> > > > infrastructure when we could just use GObject one from already
> > > > used glib.
> > > > 
> > > > > 
> > > > > > 2. It's possible to drop freeing inside API completely and
> > > > > >    record(store in list) every new object inside a table
> > > > > > context. When table is constructed, list of created objects
> > > > > > could be safely freed.
> > > > > >    With that it would be safe to reuse every AcpiAml object
> > > > > >    and avoid free-after-use issues with limitation that
> > > > > > created AcpiAml objects shouldn't be used after table was
> > > > > > closed. It should cover all practical use of API, i.e. no
> > > > > > cross table AcpiAml objects.
> > > > > 
> > > > > So each aml_alloc function gets pointer to this list,
> > > > > and adds the new element there.
> > > > > Eventually we do free_all to free all elements,
> > > > > so there isn't even an aml_free to mis-use.
> > > > I'm thinking a little bit different about implementation though.
> > > > I still don't like the use of explicit alloc/free being called
> > > > by API user since it doesn't allow chained API calls and
> > > > I think it's unnecessary complication see below why.
> > > > 
> > > > Here is what's true about current API and a I'd like to with it:
> > > > 
> > > >   1. Every API call (except aml_append) makes aml_alloc(), it's
> > > > just like a wrapper about object_new(FOO). (current + new impl.)
> > > > 
> > > >   2 Every API call that takes AML type as input argument
> > > >   2.1 consumes (frees) it (current impl.)
> > > >       (it's easy to fix use after free concern too,
> > > >        just pass AML by pointer and zero-out memory before it's
> > > > freed and assert whenever one of input arguments is not correct,
> > > >        i.e. it was reused second time)
> > > >       There is no need for following steps after this one.
> > > >   2.2 takes ownership of GInitiallyUnowned and adds it to its
> > > > list of its children.
> > > >   3. Free children when AML object is destroyed (i.e. ref count
> > > > zero) That way when toplevel table object (definition block in
> > > > 42/47) is added to ACPI blob we can unref it, which will cause
> > > >      its whole children tree freed, except for AML objects where
> > > >      API user explicitly took extra reference (i.e. wanted them
> > > >      to reuse in another table)
> > > > 
> > > > I'd prefer:
> > > >  *  2.1 way to address your current concern of use-after-free
> > > >     as the most simplest one (no reuse is possible however)
> > > > or
> > > >  * follow already used by QEMU QOM/GObject pattern of
> > > >    implicit alloc/free
> > > > 
> > > > since they allow to construct AML in a more simple/manageable
> > > > way i.e. 
> > > >   aml_append(method,
> > > >       aml_store(aml_string("foo"), aml_local(0)))
> > > >   );
> > > > 
> > > > v.s. explicit headache of alloc/free, which doesn't fix
> > > >      use-after-free anyway and just adds more boiler plate
> > > >      plus makes code har to read read
> > > > 
> > > >   str = aml_alloc();
> > > >   aml_string(str, "foo");
> > > >   loc0 = aml_alloc();
> > > >   aml_local(loc0, 0);
> > > >   store = aml_alloc();
> > > >   aml_store(store, str, loc0);
> > > >   aml_append(method, store);
> > > >   aml_free(store);
> > > >   aml_free(loc0);
> > > >   aml_free(str);
> > > 
> > > Here is a compromise what I and Michael came to on a phone call:
> > > 
> > > Externally API usage would look like:
> > > 
> > > AmlAllocList *p = some_list_alloc();
> > > 
> > > Aml *ssdt = aml_def_block(p, "SSDT", ...);
> > > Aml *dev = aml_device(p, "PCI0");
> > > aml_append(dev,
> > >     aml_name_def(p, "_STA", aml_int(p, 0xF /* present */))
> > > );
> > > aml_append(ssdt, dev);
> > > 
> > > aml_append(acpi_tables_blob, ssdt);
> > > 
> > > free_aml_alloc_list(p);
> > > 
> > > 
> > > Each of aml_foo() will take other Aml arguments by pointer.
> > > Also every aml_foo(), except of aml_append() will allocate
> > > Aml struct and return pointer to it and also add this pointer
> > > into AmlAllocList which is passed as first argument to each
> > > aml_foo() call.
> > > aml_append() becomes nondestructive function and just adds
> > > child(2nd arg) to the parent context (1st arg).
> > > 
> > > After API user is done with building table and pushed it
> > > into tables blob, he/she calls free_aml_alloc_list() to free
> > > all Aml objects created during process of building the table
> > > content.
> > 
> > Hmm, passing 'p' around somewhat muddies an otherwise clean
> > interface, but the concern with aml_append silently freeing
> > memory still accessible by the caller is definitely valid. I
I've tried redo series with passing alloc list as first argument,
looks ugly as hell and I still doubt that explicit recording of every
allocation is necessary. I'd rather use QOM tree for AML objects.

If we still don't want to use QOM and considering that ACPI
tables are build in one thread/function, I'd prefer to hide
allocation list inside API making it static variable for now. With
external  init/free_all API to allow explicitly do this operations
before/after table is build. It would still provide explicit
alloc/free but would keep AML API clean/simple since we won't have to
pass alloc list to every API function which are called quite a lot
times. It also would allow transparently for users switch from this
allocation scheme to QOM one when such need arises.

> > only wonder how things would look with Igor's option 2.2 above.
> > The caller still only needs to free the final table, but it
> > also becomes safe to use the same object references multiple
> > times before freeing the table. Using QOM also seems reasonable
> > to me, as it appears it's the accepted way to do garbage
> > collection in QEMU. Is it possible to do 2.2 with QOM?
> 
> I'd rather not go there: QOM was really invented for introspection,
> and for long-lived heavy-weight objects.  And to me, code using QOM is
> harder to understand than simple alloc/free. It's worth it where we
> need the features it offers, e.g. it has run-time checks where we
> previously just did a cast. But in this case I'd rather use something
> simpler and with compile-time checks.

I'll post example on top of v2 that does it QOM way as Drew suggested
for discussion. Resut looks relatively simple and keeps API clean,
it replaces alloc/free with widely used object_new/object_unref
and allows to free table tree including all its children in one call
object_unref(table).
It also allows to extend generic AML object to types like AML tables
blob (there is patch in example) or AML table (haven't tried yet but
see need for it) and automatically enforces type checks whenever we do
casts, and we have to do casts to access type specific fields
internally. At the same time it keeps API simple and uniform (single
typed Aml* as parameters/return values) from user POV.
Making type for every AML object probably would be overkill right now
but we could do it for generic AML object, AML table and AML tables
blob objects, that helps to generalize table building functions that
has been just copied from x86 to ARM series in latest ACPI for ARM
series. Later if there would be need it would be possible to extend
AML types internally without touching/breaking API users.

> 
> 
> 
> > > 
> > > > 
> > > > > 
> > > > > Good idea! I think this will address the issue.
> > > > > 
> > > > > 
> > > > > > 3. talloc implementation Amit've mentioned,
> > > > > >    perhaps it might work since it allows to set destructors
> > > > > > for managed pointers. With this we might get clear abort
> > > > > > when dereferencing freed pointer see talloc_set()
> > > > > 
> > > > > 
> > > > > I think it's a separate discussion. Maybe talloc is a good
> > > > > allocator to use in qemu, but using a separate allocator
> > > > > just for acpi generation would be an overkill.
> > > > > 
> > > > > > 
> > > > > > > 
> > > > > > > Just pass AcpiAml* everywhere, add APIs to allocate and
> > > > > > > free it together with the internal buffer.
> > > > > > > This makes it trivial to see that value is not misused:
> > > > > > > just check it's between alloc and free - and that there
> > > > > > > are no leaks - just check we call free on each value.
> > > > > > > We can write a semantic patch to catch missing free calls,
> > > > > > > it's easy.
> > > > > > > 
> > > > > > > 
> > > > > > > > > 
> > > > > > > > > > As for moving to to another file, during all this
> > > > > > > > > > series lowlevel
> > > > > > > > > > build_(some_aml_related_costruct_helper)s are moved
> > > > > > > > > > into this file and should be make static to hide
> > > > > > > > > > from user lowlevel helpers (including
> > > > > > > > > > build_package). That will leave only high level API
> > > > > > > > > > available.
> > > > > > > > > > 
> > > > > > > > > > TODO for me: make sure that moved lowlevel helpers
> > > > > > > > > > are static
> > > > > > > > > > 
> > > > > > > > > > 
> > > 
> > > 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-27 22:29                         ` Igor Mammedov
@ 2015-01-28  7:27                           ` Michael S. Tsirkin
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
  2015-01-28  7:56                           ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Michael S. Tsirkin
  2015-02-05 14:09                           ` Marcel Apfelbaum
  2 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-28  7:27 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: pbonzini, Andrew Jones, claudio.fontana, qemu-devel, marcel.a

On Tue, Jan 27, 2015 at 11:29:09PM +0100, Igor Mammedov wrote:
> On Mon, 26 Jan 2015 18:17:55 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Mon, Jan 26, 2015 at 04:34:01PM +0100, Andrew Jones wrote:
> > > On Mon, Jan 26, 2015 at 04:09:20PM +0100, Igor Mammedov wrote:
> > > > On Mon, 26 Jan 2015 10:57:21 +0100
> > > > Igor Mammedov <imammedo@redhat.com> wrote:
> > > > 
> > > > > On Sat, 24 Jan 2015 18:33:50 +0200
> > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > 
> > > > > > On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
> > > > > > > On Fri, 23 Jan 2015 15:55:11 +0200
> > > > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > > > 
> > > > [...]
> > > > > > > I refuse to give up on cleaner and simpler API yet :)
> > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > Your patches are almost there, they are pretty clean, the
> > > > > > > > only issue I think is this passing of AcpiAml by value,
> > > > > > > > sometimes freeing buffer in the process, sometimes not.
> > > > > > > Currently buffer is allocated by API and is always freed
> > > > > > > whenever it's passed to another API function.
> > > > > > > That's why it makes user not to care about memory mgmt.
> > > > > > > 
> > > > > > > The only limitation of it is if you store AcpiAml return
> > > > > > > value into some variable you are responsible to use it only
> > > > > > > once for passing to another API function. Reusing this
> > > > > > > variable's value (pass it to API function second time)
> > > > > > > would cause cause use-after-free and freeing-freed bugs.
> > > > > > > Like this: AcpiAml table =
> > > > > > > acpi_definition_block("SSDT",...); AcpiAml scope =
> > > > > > > acpi_scope("PCI0"); aml_append(&table, scope); // <- here
> > > > > > > scope becomes invalid // a bug
> > > > > > > aml_append(&table, scope); // use-after-free +
> > > > > > > freeing-freed bugs
> > > > > > > 
> > > > > > > There are several approaches to look for resolving above
> > > > > > > issues: 1. Adopt and use memory mgmt model used by GTK+
> > > > > > >    in nutshell:
> > > > > > > http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
> > > > > > > In particular adopt behavior of GInitiallyUnowned usage
> > > > > > > model
> > > > > > > 
> > > > > > >    that will allow to keep convenient chained call style
> > > > > > > and if necessary reuse objects returned by API by
> > > > > > > explicitly referencing/dereferencing them if needed.
> > > > > > 
> > > > > > Hmm, it's still easy to misuse. I think I prefer option 2
> > > > > > below.
> > > > > That's basically what we have/use in QOM with object_new(FOO) +
> > > > > object_unref() I have no idea why we invented our own Object
> > > > > infrastructure when we could just use GObject one from already
> > > > > used glib.
> > > > > 
> > > > > > 
> > > > > > > 2. It's possible to drop freeing inside API completely and
> > > > > > >    record(store in list) every new object inside a table
> > > > > > > context. When table is constructed, list of created objects
> > > > > > > could be safely freed.
> > > > > > >    With that it would be safe to reuse every AcpiAml object
> > > > > > >    and avoid free-after-use issues with limitation that
> > > > > > > created AcpiAml objects shouldn't be used after table was
> > > > > > > closed. It should cover all practical use of API, i.e. no
> > > > > > > cross table AcpiAml objects.
> > > > > > 
> > > > > > So each aml_alloc function gets pointer to this list,
> > > > > > and adds the new element there.
> > > > > > Eventually we do free_all to free all elements,
> > > > > > so there isn't even an aml_free to mis-use.
> > > > > I'm thinking a little bit different about implementation though.
> > > > > I still don't like the use of explicit alloc/free being called
> > > > > by API user since it doesn't allow chained API calls and
> > > > > I think it's unnecessary complication see below why.
> > > > > 
> > > > > Here is what's true about current API and a I'd like to with it:
> > > > > 
> > > > >   1. Every API call (except aml_append) makes aml_alloc(), it's
> > > > > just like a wrapper about object_new(FOO). (current + new impl.)
> > > > > 
> > > > >   2 Every API call that takes AML type as input argument
> > > > >   2.1 consumes (frees) it (current impl.)
> > > > >       (it's easy to fix use after free concern too,
> > > > >        just pass AML by pointer and zero-out memory before it's
> > > > > freed and assert whenever one of input arguments is not correct,
> > > > >        i.e. it was reused second time)
> > > > >       There is no need for following steps after this one.
> > > > >   2.2 takes ownership of GInitiallyUnowned and adds it to its
> > > > > list of its children.
> > > > >   3. Free children when AML object is destroyed (i.e. ref count
> > > > > zero) That way when toplevel table object (definition block in
> > > > > 42/47) is added to ACPI blob we can unref it, which will cause
> > > > >      its whole children tree freed, except for AML objects where
> > > > >      API user explicitly took extra reference (i.e. wanted them
> > > > >      to reuse in another table)
> > > > > 
> > > > > I'd prefer:
> > > > >  *  2.1 way to address your current concern of use-after-free
> > > > >     as the most simplest one (no reuse is possible however)
> > > > > or
> > > > >  * follow already used by QEMU QOM/GObject pattern of
> > > > >    implicit alloc/free
> > > > > 
> > > > > since they allow to construct AML in a more simple/manageable
> > > > > way i.e. 
> > > > >   aml_append(method,
> > > > >       aml_store(aml_string("foo"), aml_local(0)))
> > > > >   );
> > > > > 
> > > > > v.s. explicit headache of alloc/free, which doesn't fix
> > > > >      use-after-free anyway and just adds more boiler plate
> > > > >      plus makes code har to read read
> > > > > 
> > > > >   str = aml_alloc();
> > > > >   aml_string(str, "foo");
> > > > >   loc0 = aml_alloc();
> > > > >   aml_local(loc0, 0);
> > > > >   store = aml_alloc();
> > > > >   aml_store(store, str, loc0);
> > > > >   aml_append(method, store);
> > > > >   aml_free(store);
> > > > >   aml_free(loc0);
> > > > >   aml_free(str);
> > > > 
> > > > Here is a compromise what I and Michael came to on a phone call:
> > > > 
> > > > Externally API usage would look like:
> > > > 
> > > > AmlAllocList *p = some_list_alloc();
> > > > 
> > > > Aml *ssdt = aml_def_block(p, "SSDT", ...);
> > > > Aml *dev = aml_device(p, "PCI0");
> > > > aml_append(dev,
> > > >     aml_name_def(p, "_STA", aml_int(p, 0xF /* present */))
> > > > );
> > > > aml_append(ssdt, dev);
> > > > 
> > > > aml_append(acpi_tables_blob, ssdt);
> > > > 
> > > > free_aml_alloc_list(p);
> > > > 
> > > > 
> > > > Each of aml_foo() will take other Aml arguments by pointer.
> > > > Also every aml_foo(), except of aml_append() will allocate
> > > > Aml struct and return pointer to it and also add this pointer
> > > > into AmlAllocList which is passed as first argument to each
> > > > aml_foo() call.
> > > > aml_append() becomes nondestructive function and just adds
> > > > child(2nd arg) to the parent context (1st arg).
> > > > 
> > > > After API user is done with building table and pushed it
> > > > into tables blob, he/she calls free_aml_alloc_list() to free
> > > > all Aml objects created during process of building the table
> > > > content.
> > > 
> > > Hmm, passing 'p' around somewhat muddies an otherwise clean
> > > interface, but the concern with aml_append silently freeing
> > > memory still accessible by the caller is definitely valid. I
> I've tried redo series with passing alloc list as first argument,
> looks ugly as hell

Just make names shorter, something like "p" will do the trick.
It's hard to argue about subjective ugly/not ugly.

Have you seen Rusty's design manifesto?
You current code is at best at level 2:
read the implementation and you will get it right.
Moving to QOM gets you to level 4:
follow common convention and you'll get it right.
But alloc/free is at level 7:
the obvious use is (probably) the correct one.

> and I still doubt that explicit recording of every
> allocation is necessary. I'd rather use QOM tree for AML objects.
> If we still don't want to use QOM and considering that ACPI
> tables are build in one thread/function, I'd prefer to hide
> allocation list inside API making it static variable for now. With
> external  init/free_all API to allow explicitly do this operations
> before/after table is build. It would still provide explicit
> alloc/free but would keep AML API clean/simple since we won't have to
> pass alloc list to every API function which are called quite a lot
> times. It also would allow transparently for users switch from this
> allocation scheme to QOM one when such need arises.
>
> > > only wonder how things would look with Igor's option 2.2 above.
> > > The caller still only needs to free the final table, but it
> > > also becomes safe to use the same object references multiple
> > > times before freeing the table. Using QOM also seems reasonable
> > > to me, as it appears it's the accepted way to do garbage
> > > collection in QEMU. Is it possible to do 2.2 with QOM?
> > 
> > I'd rather not go there: QOM was really invented for introspection,
> > and for long-lived heavy-weight objects.  And to me, code using QOM is
> > harder to understand than simple alloc/free. It's worth it where we
> > need the features it offers, e.g. it has run-time checks where we
> > previously just did a cast. But in this case I'd rather use something
> > simpler and with compile-time checks.
> 
> I'll post example on top of v2 that does it QOM way as Drew suggested
> for discussion. Resut looks relatively simple and keeps API clean,
> it replaces alloc/free with widely used object_new/object_unref
> and allows to free table tree including all its children in one call
> object_unref(table).

Having just tried to fix QOM induced memory leaks, I'm not impressed.
Basically, the rule that people seem to agree on is that
it's always a mistake to create QOM objects in response
to guest activity, and this is what we are doing here, after all.

> It also allows to extend generic AML object to types like AML tables
> blob (there is patch in example) or AML table (haven't tried yet but
> see need for it) and automatically enforces type checks whenever we do
> casts, and we have to do casts to access type specific fields
> internally. At the same time it keeps API simple and uniform (single
> typed Aml* as parameters/return values) from user POV.
> Making type for every AML object probably would be overkill right now
> but we could do it for generic AML object, AML table and AML tables
> blob objects, that helps to generalize table building functions that
> has been just copied from x86 to ARM series in latest ACPI for ARM
> series. Later if there would be need it would be possible to extend
> AML types internally without touching/breaking API users.
> > 
> > 
> > 
> > > > 
> > > > > 
> > > > > > 
> > > > > > Good idea! I think this will address the issue.
> > > > > > 
> > > > > > 
> > > > > > > 3. talloc implementation Amit've mentioned,
> > > > > > >    perhaps it might work since it allows to set destructors
> > > > > > > for managed pointers. With this we might get clear abort
> > > > > > > when dereferencing freed pointer see talloc_set()
> > > > > > 
> > > > > > 
> > > > > > I think it's a separate discussion. Maybe talloc is a good
> > > > > > allocator to use in qemu, but using a separate allocator
> > > > > > just for acpi generation would be an overkill.
> > > > > > 
> > > > > > > 
> > > > > > > > 
> > > > > > > > Just pass AcpiAml* everywhere, add APIs to allocate and
> > > > > > > > free it together with the internal buffer.
> > > > > > > > This makes it trivial to see that value is not misused:
> > > > > > > > just check it's between alloc and free - and that there
> > > > > > > > are no leaks - just check we call free on each value.
> > > > > > > > We can write a semantic patch to catch missing free calls,
> > > > > > > > it's easy.
> > > > > > > > 
> > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > > As for moving to to another file, during all this
> > > > > > > > > > > series lowlevel
> > > > > > > > > > > build_(some_aml_related_costruct_helper)s are moved
> > > > > > > > > > > into this file and should be make static to hide
> > > > > > > > > > > from user lowlevel helpers (including
> > > > > > > > > > > build_package). That will leave only high level API
> > > > > > > > > > > available.
> > > > > > > > > > > 
> > > > > > > > > > > TODO for me: make sure that moved lowlevel helpers
> > > > > > > > > > > are static
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > 
> > > > 

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

* Re: [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API
  2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
                   ` (46 preceding siblings ...)
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 47/47] pc: acpi-build: drop template patching and create Device(SMC) dynamically Igor Mammedov
@ 2015-01-28  7:38 ` Michael S. Tsirkin
  2015-01-28 10:07   ` Igor Mammedov
  47 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-28  7:38 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Thu, Jan 22, 2015 at 02:49:44PM +0000, Igor Mammedov wrote:
> Git tree for playing with:
>     https://github.com/imammedo/qemu/commits/ASL_API_v2
> 
> Igor Mammedov (47):
>   acpi: introduce AML composer aml_append()
>   acpi: add acpi_scope() term
>   acpi: add acpi_device() term
>   acpi: add acpi_method() term
>   acpi: add acpi_if() term
>   acpi: add acpi_name() & acpi_name_decl() term
>   acpi: factor out ACPI const int packing out build_append_value()
>   acpi: extend build_append_{value|int}() to support 64-bit values
>   acpi: add acpi_int() term
>   acpi: add acpi_return() term
>   acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms
>   acpi: add acpi_store() term
>   acpi: add acpi_and() term
>   acpi: add acpi_notify() term
>   acpi: add acpi_call1(), acpi_call2(), acpi_call3(), acpi_call4()
>     helpers
>   pc: acpi-build: drop template patching and create PCI bus tree
>     dynamically
>   acpi: add acpi_package() term
>   pc: acpi-build: drop unsupported PM1b_CNT.SLP_TYP
>   pc: acpi-build: generate _S[345] packages dynamically
>   acpi: add acpi_buffer() term
>   acpi: add acpi_resource_template() helper
>   acpi: add acpi_io() helper
>   acpi: include PkgLength size only when requested
>   acpi: add acpi_operation_region() term
>   acpi: add acpi_field() & acpi_named_field() terms
>   acpi: add acpi_local0() term
>   acpi: add acpi_string() term
>   pc: acpi-build: generate pvpanic device description dynamically
>   acpi: add acpi_varpackage() term
>   acpi: add acpi_equal() term
>   acpi: add acpi_processor() term
>   acpi: add acpi_eisaid() term
>   pc: acpi-build: drop template patching and CPU hotplug objects
>     dynamically
>   pc: acpi-build: create CPU hotplug IO region dynamically
>   acpi: add acpi_reserved_field() term
>   pc: acpi-build: drop template patching and memory hotplug objects
>     dynamically
>   pc: acpi-build: create memory hotplug IO region dynamically
>   acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(),
>     acpi_qword_memory() terms
>   pc: pcihp: expose MMIO base and len as properties
>   pc: acpi-build: reserve PCIHP MMIO resources
>   pc: acpi-build: create PCI0._CRS dynamically
>   acpi: add acpi_def_block() term
>   pc: acpi-build: prepare to make ACPI tables blob opaque for table
>     building functions
>   pc: acpi-build: drop remaining ssdt_misc template and use
>     acpi_def_block()
>   acpi: add acpi_iqr_no_flags() term
>   pc: export applesmc IO port/len
>   pc: acpi-build: drop template patching and create Device(SMC)
>     dynamically


Looking at the patch list, I think it's not split optimally:
a single patch adding all of the helpers will be easier to
work with, and won't be harder to review I think.

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-27 22:29                         ` Igor Mammedov
  2015-01-28  7:27                           ` Michael S. Tsirkin
@ 2015-01-28  7:56                           ` Michael S. Tsirkin
  2015-01-28 10:00                             ` Igor Mammedov
                                               ` (2 more replies)
  2015-02-05 14:09                           ` Marcel Apfelbaum
  2 siblings, 3 replies; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-28  7:56 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: pbonzini, Andrew Jones, claudio.fontana, qemu-devel, marcel.a

> I've tried redo series with passing alloc list as first argument,
> looks ugly as hell

I tried too. Not too bad at all. See below:

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f66da5d..820504a 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
     }
 }
 
-static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
+static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
 {
-    AcpiAml if_ctx;
+    AcpiAml *if_ctx;
     int32_t devfn = PCI_DEVFN(slot, 0);
 
-    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
-    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
-    aml_append(method, if_ctx);
+    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
+    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
+    aml_append(p, method, if_ctx);
 }
 
 static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,

What exactly is the problem?  A tiny bit more verbose but the lifetime
of all objects is now explicit.


-- 
MST

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28  7:56                           ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Michael S. Tsirkin
@ 2015-01-28 10:00                             ` Igor Mammedov
  2015-01-28 10:24                               ` Michael S. Tsirkin
                                                 ` (3 more replies)
  2015-01-28 10:45                             ` Andrew Jones
  2015-02-05 14:30                             ` Marcel Apfelbaum
  2 siblings, 4 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:00 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Andrew Jones, marcel.a, claudio.fontana, qemu-devel,
	Shannon Zhao, pbonzini

On Wed, 28 Jan 2015 09:56:26 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> > I've tried redo series with passing alloc list as first argument,
> > looks ugly as hell
> 
> I tried too. Not too bad at all. See below:
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index f66da5d..820504a 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
>      }
>  }
>  
> -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
>  {
> -    AcpiAml if_ctx;
> +    AcpiAml *if_ctx;
>      int32_t devfn = PCI_DEVFN(slot, 0);
>  
> -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
> -    aml_append(method, if_ctx);
> +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
> +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
> +    aml_append(p, method, if_ctx);
>  }
>  
>  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
> 
> What exactly is the problem?  A tiny bit more verbose but the lifetime
> of all objects is now explicit.
every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
extra pointer which is not really necessary for user to know. If possible
user shouldn't care about it and concentrate on composing AML instead.

Whole point of passing AmlPool and record every allocation is to avoid
mistakes like:

acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));

and forgetting to assign object returned by call anywhere,
it's basically the same as calling malloc() without
using result anywhere, however neither libc nor glib
force user to pass allocator (in our case garbage collector)
in every call that allocates memory. Let's just follow common
convention here (#4) where an object is allocated by API call
(i.e like object_new(FOO), gtk_widget_foo()).

Hence is suggesting at least to hide AmlPool internally in API
without exposing it to user. We can provide for user
init/free API to manage internal AmlPool manually, allowing
him to select when to do initialization and cleanup.

Claudio, Marcel, Shannon,
As the first API users, could you give your feedback on the topic.

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

* [Qemu-devel] [PATCH 00/13] convert AML API to QOM
  2015-01-28  7:27                           ` Michael S. Tsirkin
@ 2015-01-28 10:03                             ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 01/13] convert to passing AcpiAml by pointers Igor Mammedov
                                                 ` (13 more replies)
  0 siblings, 14 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a


Example demonstrates use of QOM object for building AML
objects tree and freeing it explicitly when requested.

Top level ACPI tables blob object is only partially
switched to object model now but I hope it demostrates
the point of absracting code and hiding parts of code
that could be done without user intervention.

Pathes 1/2/8 are just a convertion boiler plate which
will go away on respin.


Igor Mammedov (13):
  convert to passing AcpiAml by pointers
  make toplevel ACPI tables blob a pointer
  qom: add support for weak referenced object: aka UnownedObject
  acpi: make AcpiAml an OQM object
  acpi: use TYPE_AML_OBJECT inside of AML API
  acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob
  acpi: make toplevel ACPI tables blob a dedicated object
  i386: acpi: hack not yet converted tables calls to deal with
    table_data being a pointer
  acpi: add aml_blob() helper
  i386: acpi: add DSDT table using AML API
  acpi: acpi_add_table() to common cross target file
  acpi: prepare for API internal collection of RSDT entries
  i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT
    automatically

 hw/acpi/acpi-build-utils.c         | 537 +++++++++++++++++++++----------------
 hw/i386/acpi-build.c               | 388 +++++++++++++--------------
 include/hw/acpi/acpi-build-utils.h | 119 +++++---
 include/qom/object.h               |  20 ++
 qom/object.c                       |  20 +-
 5 files changed, 620 insertions(+), 464 deletions(-)

-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 01/13] convert to passing AcpiAml by pointers
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 02/13] make toplevel ACPI tables blob a pointer Igor Mammedov
                                                 ` (12 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 446 +++++++++++++++++++------------------
 hw/i386/acpi-build.c               | 270 +++++++++++-----------
 include/hw/acpi/acpi-build-utils.h |  84 +++----
 3 files changed, 401 insertions(+), 399 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 59873e3..5bfb74d 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -290,64 +290,66 @@ static void build_prepend_int(GArray *array, uint32_t value)
     build_free_array(data);
 }
 
-void aml_append(AcpiAml *parent_ctx, AcpiAml child)
+void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
 {
-    switch (child.block_flags) {
+    switch (child->block_flags) {
     case EXT_PACKAGE:
-        build_extop_package(child.buf, child.op);
+        build_extop_package(child->buf, child->op);
         break;
 
     case PACKAGE:
-        build_package(child.buf, child.op);
+        build_package(child->buf, child->op);
         break;
 
     case RES_TEMPLATE:
-        build_append_byte(child.buf, 0x79); /* EndTag */
+        build_append_byte(child->buf, 0x79); /* EndTag */
         /*
          * checksum operations is treated as succeeded if checksum
          * field is zero. [ACPI Spec 5.0, 6.4.2.9 End Tag]
          */
-        build_append_byte(child.buf, 0);
+        build_append_byte(child->buf, 0);
         /* fall through, to pack resources in buffer */
     case BUFFER:
-        build_prepend_int(child.buf, child.buf->len);
-        build_package(child.buf, child.op);
+        build_prepend_int(child->buf, child->buf->len);
+        build_package(child->buf, child->op);
         break;
     case DEF_BLOCK: {
         uint8_t *start = (uint8_t *)parent_ctx->buf->data +
                          parent_ctx->buf->len;
-        uint32_t le32_len = cpu_to_le32(child.buf->len);
+        uint32_t le32_len = cpu_to_le32(child->buf->len);
 
         /* create linker entry for the DefinitionBlock */
         bios_linker_loader_add_checksum(parent_ctx->linker,
             ACPI_BUILD_TABLE_FILE,
             parent_ctx->buf->data,
-            start, child.buf->len, start + 9 /* checksum offset */);
+            start, child->buf->len, start + 9 /* checksum offset */);
 
         /* set DefinitionBlock length at TableLength offset*/
-        memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
+        memcpy(child->buf->data + 4, &le32_len, sizeof le32_len);
         break;
     }
     default:
         break;
     }
-    build_append_array(parent_ctx->buf, child.buf);
-    build_free_array(child.buf);
+    build_append_array(parent_ctx->buf, child->buf);
+    build_free_array(child->buf);
 }
 
-static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
+static AcpiAml *aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
 {
-    AcpiAml var = { .op = op, .block_flags = flags };
-    var.buf = build_alloc_array();
+    AcpiAml *var = g_malloc0(sizeof(AcpiAml));
+    var->op = op;
+    var->block_flags = flags;
+    var->buf = build_alloc_array();
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefReturn */
-AcpiAml acpi_return(AcpiAml val)
+AcpiAml *acpi_return(AcpiAml *val)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0xA4); /* ReturnOp */
-    aml_append(&var, val);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0xA4); /* ReturnOp */
+    aml_append(var, val);
     return var;
 }
 
@@ -355,10 +357,10 @@ AcpiAml acpi_return(AcpiAml val)
  * ACPI 5.0: 20.2.3 Data Objects Encoding:
  * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
  */
-AcpiAml acpi_int(const uint64_t val)
+AcpiAml *acpi_int(const uint64_t val)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_int(var.buf, val);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_int(var->buf, val);
     return var;
 }
 
@@ -366,129 +368,129 @@ AcpiAml acpi_int(const uint64_t val)
  * help to construct NameString, which return AcpiAml object
  * for using with other aml_append or other acpi_* terms
  */
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...)
+AcpiAml GCC_FMT_ATTR(1, 2) *acpi_name(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
     va_start(ap, name_format);
-    build_append_namestringv(var.buf, name_format, ap);
+    build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */
-AcpiAml acpi_name_decl(const char *name, AcpiAml val)
+AcpiAml *acpi_name_decl(const char *name, AcpiAml *val)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x08);
-    build_append_namestring(var.buf, "%s", name);
-    aml_append(&var, val);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x08);
+    build_append_namestring(var->buf, "%s", name);
+    aml_append(var, val);
     return var;
 }
 
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg0Op */
-AcpiAml acpi_arg0(void)
+AcpiAml *acpi_arg0(void)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x68); /* ARG0 op */
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x68); /* ARG0 op */
     return var;
 }
 
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg1Op */
-AcpiAml acpi_arg1(void)
+AcpiAml *acpi_arg1(void)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x69); /* ARG1 op */
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x69); /* ARG1 op */
     return var;
 }
 
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg2Op */
-AcpiAml acpi_arg2(void)
+AcpiAml *acpi_arg2(void)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x6A); /* ARG2 op */
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x6A); /* ARG2 op */
     return var;
 }
 
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg3Op */
-AcpiAml acpi_arg3(void)
+AcpiAml *acpi_arg3(void)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x6B); /* ARG3 op */
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x6B); /* ARG3 op */
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefStore */
-AcpiAml acpi_store(AcpiAml val, AcpiAml target)
+AcpiAml *acpi_store(AcpiAml *val, AcpiAml *target)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x70); /* StoreOp */
-    aml_append(&var, val);
-    aml_append(&var, target);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x70); /* StoreOp */
+    aml_append(var, val);
+    aml_append(var, target);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefAnd */
-AcpiAml acpi_and(AcpiAml arg1, AcpiAml arg2)
+AcpiAml *acpi_and(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x7B); /* AndOp */
-    aml_append(&var, arg1);
-    aml_append(&var, arg2);
-    build_append_int(var.buf, 0x00); /* NullNameOp */
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x7B); /* AndOp */
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    build_append_int(var->buf, 0x00); /* NullNameOp */
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefNotify */
-AcpiAml acpi_notify(AcpiAml arg1, AcpiAml arg2)
+AcpiAml *acpi_notify(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x86); /* NotifyOp */
-    aml_append(&var, arg1);
-    aml_append(&var, arg2);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x86); /* NotifyOp */
+    aml_append(var, arg1);
+    aml_append(var, arg2);
     return var;
 }
 
 /* helper to call method with 1 argument */
-AcpiAml acpi_call1(const char *method, AcpiAml arg1)
+AcpiAml *acpi_call1(const char *method, AcpiAml *arg1)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_namestring(var.buf, "%s", method);
-    aml_append(&var, arg1);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var->buf, "%s", method);
+    aml_append(var, arg1);
     return var;
 }
 
 /* helper to call method with 2 arguments */
-AcpiAml acpi_call2(const char *method, AcpiAml arg1, AcpiAml arg2)
+AcpiAml *acpi_call2(const char *method, AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_namestring(var.buf, "%s", method);
-    aml_append(&var, arg1);
-    aml_append(&var, arg2);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var->buf, "%s", method);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
     return var;
 }
 
 /* helper to call method with 3 arguments */
-AcpiAml acpi_call3(const char *method, AcpiAml arg1, AcpiAml arg2, AcpiAml arg3)
+AcpiAml *acpi_call3(const char *method, AcpiAml* arg1, AcpiAml *arg2, AcpiAml *arg3)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_namestring(var.buf, "%s", method);
-    aml_append(&var, arg1);
-    aml_append(&var, arg2);
-    aml_append(&var, arg3);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var->buf, "%s", method);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    aml_append(var, arg3);
     return var;
 }
 
 /* helper to call method with 4 arguments */
-AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
-                   AcpiAml arg3, AcpiAml arg4)
+AcpiAml *acpi_call4(const char *method, AcpiAml *arg1, AcpiAml *arg2,
+                   AcpiAml *arg3, AcpiAml *arg4)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_namestring(var.buf, "%s", method);
-    aml_append(&var, arg1);
-    aml_append(&var, arg2);
-    aml_append(&var, arg3);
-    aml_append(&var, arg4);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_namestring(var->buf, "%s", method);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    aml_append(var, arg3);
+    aml_append(var, arg4);
     return var;
 }
 
@@ -496,18 +498,18 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
  * ACPI 5.0: 19.5.62 IO (IO Resource Descriptor Macro)
  *           6.4.2 Small Resource Data Type
 */
-AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
+AcpiAml *acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
                 uint8_t aln, uint8_t len)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x47); /* IO port descriptor */
-    build_append_byte(var.buf, dec);
-    build_append_byte(var.buf, min_base & 0xff);
-    build_append_byte(var.buf, (min_base >> 8) & 0xff);
-    build_append_byte(var.buf, max_base & 0xff);
-    build_append_byte(var.buf, (max_base >> 8) & 0xff);
-    build_append_byte(var.buf, aln);
-    build_append_byte(var.buf, len);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x47); /* IO port descriptor */
+    build_append_byte(var->buf, dec);
+    build_append_byte(var->buf, min_base & 0xff);
+    build_append_byte(var->buf, (min_base >> 8) & 0xff);
+    build_append_byte(var->buf, max_base & 0xff);
+    build_append_byte(var->buf, (max_base >> 8) & 0xff);
+    build_append_byte(var->buf, aln);
+    build_append_byte(var->buf, len);
     return var;
 }
 
@@ -515,139 +517,139 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
  * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
  *           6.4.2.1 IRQ Descriptor
 */
-AcpiAml acpi_iqr_no_flags(uint8_t irq)
+AcpiAml *acpi_iqr_no_flags(uint8_t irq)
 {
     uint16_t irq_mask;
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
 
     assert(irq < 16);
-    build_append_byte(var.buf, 0x22); /* IRQ descriptor 2 byte form */
+    build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
 
     irq_mask = 1U << irq;
-    build_append_byte(var.buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
-    build_append_byte(var.buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
+    build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
+    build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
-AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2)
+AcpiAml *acpi_equal(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x93); /* LequalOp */
-    aml_append(&var, arg1);
-    aml_append(&var, arg2);
-    build_append_int(var.buf, 0x00); /* NullNameOp */
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x93); /* LequalOp */
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    build_append_int(var->buf, 0x00); /* NullNameOp */
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
-AcpiAml acpi_if(AcpiAml predicate)
+AcpiAml *acpi_if(AcpiAml *predicate)
 {
-    AcpiAml var = aml_allocate_internal(0xA0 /* IfOp */, PACKAGE);
-    aml_append(&var, predicate);
+    AcpiAml *var = aml_allocate_internal(0xA0 /* IfOp */, PACKAGE);
+    aml_append(var, predicate);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefMethod */
-AcpiAml acpi_method(const char *name, int arg_count)
+AcpiAml *acpi_method(const char *name, int arg_count)
 {
-    AcpiAml var = aml_allocate_internal(0x14 /* MethodOp */, PACKAGE);
-    build_append_namestring(var.buf, "%s", name);
-    build_append_byte(var.buf, arg_count); /* MethodFlags: ArgCount */
+    AcpiAml *var = aml_allocate_internal(0x14 /* MethodOp */, PACKAGE);
+    build_append_namestring(var->buf, "%s", name);
+    build_append_byte(var->buf, arg_count); /* MethodFlags: ArgCount */
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefScope */
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...)
+AcpiAml GCC_FMT_ATTR(1, 2) *acpi_scope(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml var = aml_allocate_internal(0x10 /* ScopeOp */, PACKAGE);
+    AcpiAml *var = aml_allocate_internal(0x10 /* ScopeOp */, PACKAGE);
     va_start(ap, name_format);
-    build_append_namestringv(var.buf, name_format, ap);
+    build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefDevice */
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...)
+AcpiAml GCC_FMT_ATTR(1, 2) *acpi_device(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml var = aml_allocate_internal(0x82 /* DeviceOp */, EXT_PACKAGE);
+    AcpiAml *var = aml_allocate_internal(0x82 /* DeviceOp */, EXT_PACKAGE);
     va_start(ap, name_format);
-    build_append_namestringv(var.buf, name_format, ap);
+    build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
     return var;
 }
 
 /* ResourceTemplate marcos helper */
-AcpiAml acpi_resource_template(void)
+AcpiAml *acpi_resource_template(void)
 {
     /* ResourceTemplate is a buffer of Resources with EndTag at the end */
-    AcpiAml var = aml_allocate_internal(0x11 /* BufferOp */, RES_TEMPLATE);
+    AcpiAml *var = aml_allocate_internal(0x11 /* BufferOp */, RES_TEMPLATE);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
-AcpiAml acpi_buffer(void)
+AcpiAml *acpi_buffer(void)
 {
-    AcpiAml var = aml_allocate_internal(0x11 /* BufferOp */, BUFFER);
+    AcpiAml *var = aml_allocate_internal(0x11 /* BufferOp */, BUFFER);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefPackage */
-AcpiAml acpi_package(uint8_t num_elements)
+AcpiAml *acpi_package(uint8_t num_elements)
 {
-    AcpiAml var = aml_allocate_internal(0x12 /* PackageOp */, PACKAGE);
-    build_append_byte(var.buf, num_elements);
+    AcpiAml *var = aml_allocate_internal(0x12 /* PackageOp */, PACKAGE);
+    build_append_byte(var->buf, num_elements);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefOpRegion */
-AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
+AcpiAml *acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x5B); /* ExtOpPrefix */
-    build_append_byte(var.buf, 0x80); /* OpRegionOp */
-    build_append_namestring(var.buf, "%s", name);
-    build_append_byte(var.buf, rs);
-    build_append_int(var.buf, offset);
-    build_append_int(var.buf, len);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+    build_append_byte(var->buf, 0x80); /* OpRegionOp */
+    build_append_namestring(var->buf, "%s", name);
+    build_append_byte(var->buf, rs);
+    build_append_int(var->buf, offset);
+    build_append_int(var->buf, len);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: NamedField */
-AcpiAml acpi_named_field(const char *name, unsigned length)
+AcpiAml *acpi_named_field(const char *name, unsigned length)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_nameseg(var.buf, "%s", name);
-    build_append_pkg_length(var.buf, length, false);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_nameseg(var->buf, "%s", name);
+    build_append_pkg_length(var->buf, length, false);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: ReservedField */
-AcpiAml acpi_reserved_field(unsigned length)
+AcpiAml *acpi_reserved_field(unsigned length)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
     /* ReservedField  := 0x00 PkgLength */
-    build_append_byte(var.buf, 0x00);
-    build_append_pkg_length(var.buf, length, false);
+    build_append_byte(var->buf, 0x00);
+    build_append_pkg_length(var->buf, length, false);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefField */
-AcpiAml acpi_field(const char *name, acpiFieldFlags flags)
+AcpiAml *acpi_field(const char *name, acpiFieldFlags flags)
 {
-    AcpiAml var = aml_allocate_internal(0x81 /* FieldOp */, EXT_PACKAGE);
-    build_append_namestring(var.buf, "%s", name);
-    build_append_byte(var.buf, flags);
+    AcpiAml *var = aml_allocate_internal(0x81 /* FieldOp */, EXT_PACKAGE);
+    build_append_namestring(var->buf, "%s", name);
+    build_append_byte(var->buf, flags);
     return var;
 }
 
 /* ACPI 5.0: 20.2.3 Data Objects Encoding: String */
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...)
+AcpiAml GCC_FMT_ATTR(1, 2) *acpi_string(const char *name_format, ...)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
     va_list ap, va_len;
     char *s;
     int len;
@@ -662,47 +664,47 @@ AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...)
     len = vsnprintf(s, len, name_format, ap);
     va_end(ap);
 
-    build_append_byte(var.buf, 0x0D); /* StringPrefix */
-    g_array_append_vals(var.buf, s, len);
-    build_append_byte(var.buf, 0x0); /* NullChar */
+    build_append_byte(var->buf, 0x0D); /* StringPrefix */
+    g_array_append_vals(var->buf, s, len);
+    build_append_byte(var->buf, 0x0); /* NullChar */
     g_free(s);
 
     return var;
 }
 
 /* ACPI 5.0: 20.2.6.2 Local Objects Encoding: Local0Op */
-AcpiAml acpi_local0(void)
+AcpiAml *acpi_local0(void)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
-    build_append_byte(var.buf, 0x60); /* Local0Op */
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    build_append_byte(var->buf, 0x60); /* Local0Op */
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefVarPackage */
-AcpiAml acpi_varpackage(uint32_t num_elements)
+AcpiAml *acpi_varpackage(uint32_t num_elements)
 {
-    AcpiAml var = aml_allocate_internal(0x13 /* VarPackageOp */, PACKAGE);
-    build_append_int(var.buf, num_elements);
+    AcpiAml *var = aml_allocate_internal(0x13 /* VarPackageOp */, PACKAGE);
+    build_append_int(var->buf, num_elements);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefProcessor */
 AcpiAml GCC_FMT_ATTR(4, 5)
-acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
+*acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
                const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml var = aml_allocate_internal(0x83 /* ProcessorOp */, EXT_PACKAGE);
+    AcpiAml *var = aml_allocate_internal(0x83 /* ProcessorOp */, EXT_PACKAGE);
     va_start(ap, name_format);
-    build_append_namestringv(var.buf, name_format, ap);
+    build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
-    build_append_byte(var.buf, proc_id); /* ProcID */
+    build_append_byte(var->buf, proc_id); /* ProcID */
     /* PblkAddr */
-    build_append_byte(var.buf, pblk_addr & 0xFF);
-    build_append_byte(var.buf, (pblk_addr >> 8) & 0xFF);
-    build_append_byte(var.buf, (pblk_addr >> 16) & 0xFF);
-    build_append_byte(var.buf, (pblk_addr >> 24) & 0xFF);
-    build_append_byte(var.buf, pblk_len); /* PblkLen */
+    build_append_byte(var->buf, pblk_addr & 0xFF);
+    build_append_byte(var->buf, (pblk_addr >> 8) & 0xFF);
+    build_append_byte(var->buf, (pblk_addr >> 16) & 0xFF);
+    build_append_byte(var->buf, (pblk_addr >> 24) & 0xFF);
+    build_append_byte(var->buf, pblk_len); /* PblkLen */
     return var;
 }
 
@@ -716,9 +718,9 @@ static uint8_t Hex2Digit(char c)
 }
 
 /* ACPI 5.0: 19.5.36 EISAID (EISA ID String To Integer Conversion Macro) */
-AcpiAml acpi_eisaid(const char *str)
+AcpiAml *acpi_eisaid(const char *str)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
     uint32_t id;
 
     g_assert(strlen(str) == 7);
@@ -730,102 +732,102 @@ AcpiAml acpi_eisaid(const char *str)
     Hex2Digit(str[5]) << 4 |
     Hex2Digit(str[6]);
 
-    build_append_byte(var.buf, 0x0C); /* DWordPrefix */
-    build_append_value(var.buf, bswap32(id), sizeof(id));
+    build_append_byte(var->buf, 0x0C); /* DWordPrefix */
+    build_append_value(var->buf, bswap32(id), sizeof(id));
     return var;
 }
 
 /* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
-static AcpiAml
+static AcpiAml *
 acpi_as_desc_header(acpiResourceType type, acpiMinFixed min_fixed,
                     acpiMaxFixed max_fixed, acpiDecode dec, uint8_t type_flags)
 {
     uint8_t flags = max_fixed | min_fixed | dec;
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
 
-    build_append_byte(var.buf, type);
-    build_append_byte(var.buf, flags);
-    build_append_byte(var.buf, type_flags); /* Type Specific Flags */
+    build_append_byte(var->buf, type);
+    build_append_byte(var->buf, flags);
+    build_append_byte(var->buf, type_flags); /* Type Specific Flags */
     return var;
 }
 
 /* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
-static AcpiAml acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
+static AcpiAml *acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
                                  acpiMaxFixed max_fixed, acpiDecode dec,
                                  uint16_t addr_gran, uint16_t addr_min,
                                  uint16_t addr_max, uint16_t addr_trans,
                                  uint16_t len, uint8_t type_flags)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
 
-    build_append_byte(var.buf, 0x88); /* Word Address Space Descriptor */
+    build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
-    build_append_byte(var.buf, 0x0D);
-    build_append_byte(var.buf, 0x0);
+    build_append_byte(var->buf, 0x0D);
+    build_append_byte(var->buf, 0x0);
 
-    aml_append(&var,
+    aml_append(var,
         acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
-    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
-    build_append_value(var.buf, addr_min, sizeof(addr_min));
-    build_append_value(var.buf, addr_max, sizeof(addr_max));
-    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
-    build_append_value(var.buf, len, sizeof(len));
+    build_append_value(var->buf, addr_gran, sizeof(addr_gran));
+    build_append_value(var->buf, addr_min, sizeof(addr_min));
+    build_append_value(var->buf, addr_max, sizeof(addr_max));
+    build_append_value(var->buf, addr_trans, sizeof(addr_trans));
+    build_append_value(var->buf, len, sizeof(len));
     return var;
 }
 
 /* ACPI 5.0: 6.4.3.5.2 DWord Address Space Descriptor */
-static AcpiAml acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
+static AcpiAml *acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
                                   acpiMaxFixed max_fixed, acpiDecode dec,
                                   uint32_t addr_gran, uint32_t addr_min,
                                   uint32_t addr_max, uint32_t addr_trans,
                                   uint32_t len, uint8_t type_flags)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
 
-    build_append_byte(var.buf, 0x87); /* DWord Address Space Descriptor */
+    build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
-    build_append_byte(var.buf, 23);
-    build_append_byte(var.buf, 0x0);
+    build_append_byte(var->buf, 23);
+    build_append_byte(var->buf, 0x0);
 
 
-    aml_append(&var,
+    aml_append(var,
         acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
-    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
-    build_append_value(var.buf, addr_min, sizeof(addr_min));
-    build_append_value(var.buf, addr_max, sizeof(addr_max));
-    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
-    build_append_value(var.buf, len, sizeof(len));
+    build_append_value(var->buf, addr_gran, sizeof(addr_gran));
+    build_append_value(var->buf, addr_min, sizeof(addr_min));
+    build_append_value(var->buf, addr_max, sizeof(addr_max));
+    build_append_value(var->buf, addr_trans, sizeof(addr_trans));
+    build_append_value(var->buf, len, sizeof(len));
     return var;
 }
 
 /* ACPI 5.0: 6.4.3.5.1 QWord Address Space Descriptor */
-static AcpiAml acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
+static AcpiAml *acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
                                   acpiMaxFixed max_fixed, acpiDecode dec,
                                   uint64_t addr_gran, uint64_t addr_min,
                                   uint64_t addr_max, uint64_t addr_trans,
                                   uint64_t len, uint8_t type_flags)
 {
-    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
 
-    build_append_byte(var.buf, 0x8A); /* QWord Address Space Descriptor */
+    build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
-    build_append_byte(var.buf, 0x2B);
-    build_append_byte(var.buf, 0x0);
+    build_append_byte(var->buf, 0x2B);
+    build_append_byte(var->buf, 0x0);
 
-    aml_append(&var,
+    aml_append(var,
         acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
-    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
-    build_append_value(var.buf, addr_min, sizeof(addr_min));
-    build_append_value(var.buf, addr_max, sizeof(addr_max));
-    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
-    build_append_value(var.buf, len, sizeof(len));
+    build_append_value(var->buf, addr_gran, sizeof(addr_gran));
+    build_append_value(var->buf, addr_min, sizeof(addr_min));
+    build_append_value(var->buf, addr_max, sizeof(addr_max));
+    build_append_value(var->buf, addr_trans, sizeof(addr_trans));
+    build_append_value(var->buf, len, sizeof(len));
     return var;
 }
 
 /*
  * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
  */
-AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+AcpiAml *acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
                              acpiDecode dec, uint16_t addr_gran,
                              uint16_t addr_min, uint16_t addr_max,
                              uint16_t addr_trans, uint16_t len)
@@ -836,7 +838,7 @@ AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
 }
 
 /* ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro) */
-AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+AcpiAml *acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
                      acpiDecode dec, acpiISARanges isa_ranges,
                      uint16_t addr_gran, uint16_t addr_min,
                      uint16_t addr_max, uint16_t addr_trans,
@@ -849,7 +851,7 @@ AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
 }
 
 /* ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro) */
-AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+AcpiAml *acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
                           acpiMaxFixed max_fixed, acpiCacheble cacheable,
                           acpiReadAndWrite read_and_write,
                           uint32_t addr_gran, uint32_t addr_min,
@@ -864,7 +866,7 @@ AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
 }
 
 /* ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro) */
-AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+AcpiAml *acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
                           acpiMaxFixed max_fixed, acpiCacheble cacheable,
                           acpiReadAndWrite read_and_write,
                           uint64_t addr_gran, uint64_t addr_min,
@@ -879,32 +881,32 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
 }
 
 /* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
-AcpiAml acpi_def_block(const char *signature, uint8_t revision,
+AcpiAml *acpi_def_block(const char *signature, uint8_t revision,
                        const char *oem_id, const char *oem_table_id,
                        uint32_t oem_revision)
 {
     int len;
-    AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
+    AcpiAml *var = aml_allocate_internal(0, DEF_BLOCK);
 
     assert(strlen(signature) == 4);
-    g_array_append_vals(var.buf, signature, 4);
-    build_append_value(var.buf, 0, 4); /* Length place holder */
-    build_append_byte(var.buf, revision);
-    build_append_byte(var.buf, 0); /* place holder for Checksum */
+    g_array_append_vals(var->buf, signature, 4);
+    build_append_value(var->buf, 0, 4); /* Length place holder */
+    build_append_byte(var->buf, revision);
+    build_append_byte(var->buf, 0); /* place holder for Checksum */
 
     len = strlen(oem_id);
     assert(len <= 6);
-    g_array_append_vals(var.buf, oem_id, len);
-    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
+    g_array_append_vals(var->buf, oem_id, len);
+    g_array_append_vals(var->buf, "\0\0\0\0\0\0\0\0", 6 - len);
 
     len = strlen(oem_table_id);
     assert(len <= 8);
-    g_array_append_vals(var.buf, oem_table_id, len);
-    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
+    g_array_append_vals(var->buf, oem_table_id, len);
+    g_array_append_vals(var->buf, "\0\0\0\0\0\0\0\0", 8 - len);
 
-    build_append_value(var.buf, oem_revision, 4);
-    g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
-    build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
+    build_append_value(var->buf, oem_revision, 4);
+    g_array_append_vals(var->buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
+    build_append_value(var->buf, 1, 4); /* asl_compiler_revision */
 
     return var;
 }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f66da5d..c7f492e 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -493,18 +493,18 @@ static void acpi_set_pci_info(void)
 
 static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
 {
-    AcpiAml if_ctx;
+    AcpiAml *if_ctx;
     int32_t devfn = PCI_DEVFN(slot, 0);
 
     if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
-    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
+    aml_append(if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
     aml_append(method, if_ctx);
 }
 
 static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
                                          bool pcihp_bridge_en)
 {
-    AcpiAml dev, notify_method, method;
+    AcpiAml *dev, *notify_method, *method;
     QObject *bsel;
     PCIBus *sec;
     int i;
@@ -527,22 +527,22 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
         if (!pdev) {
             if (bsel) {
                 dev = acpi_device("S%.02X", PCI_DEVFN(slot, 0));
-                aml_append(&dev, acpi_name_decl("_SUN", acpi_int(slot)));
-                aml_append(&dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
+                aml_append(dev, acpi_name_decl("_SUN", acpi_int(slot)));
+                aml_append(dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
                 method = acpi_method("_EJ0", 1);
-                aml_append(&method,
+                aml_append(method,
                     acpi_call2("PCEJ", acpi_name("BSEL"), acpi_name("_SUN"))
                 );
-                aml_append(&dev, method);
+                aml_append(dev, method);
                 aml_append(parent_scope, dev);
 
-                build_append_pcihp_notify_entry(&notify_method, slot);
+                build_append_pcihp_notify_entry(notify_method, slot);
             } else {
                 /* no much sense to create empty non hotpluggable slots,
                  * but it's what original code did before. TODO: remove it.
                  */
                 dev = acpi_device("S%.02X", PCI_DEVFN(slot, 0));
-                aml_append(&dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
+                aml_append(dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
                 aml_append(parent_scope, dev);
             }
             continue;
@@ -557,7 +557,7 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
         bridge_in_acpi = pc->is_bridge && pcihp_bridge_en;
 
         dev = acpi_device("S%.02X", PCI_DEVFN(slot, 0));
-        aml_append(&dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
+        aml_append(dev, acpi_name_decl("_ADR", acpi_int(slot << 16)));
 
         if (pc->class_id == PCI_CLASS_DISPLAY_VGA) {
             int s3d = 0;
@@ -567,27 +567,27 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
             }
 
             method = acpi_method("_S1D", 0);
-            aml_append(&method, acpi_return(acpi_int(0)));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_int(0)));
+            aml_append(dev, method);
 
             method = acpi_method("_S2D", 0);
-            aml_append(&method, acpi_return(acpi_int(0)));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_int(0)));
+            aml_append(dev, method);
 
             method = acpi_method("_S3D", 0);
-            aml_append(&method, acpi_return(acpi_int(s3d)));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_int(s3d)));
+            aml_append(dev, method);
         } else if (dc->hotpluggable && !bridge_in_acpi) {
-            aml_append(&dev, acpi_name_decl("_SUN", acpi_int(slot)));
+            aml_append(dev, acpi_name_decl("_SUN", acpi_int(slot)));
 
             method = acpi_method("_EJ0", 1);
-            aml_append(&method,
+            aml_append(method,
                 acpi_call2("PCEJ", acpi_name("BSEL"), acpi_name("_SUN"))
             );
-            aml_append(&dev, method);
+            aml_append(dev, method);
 
             if (bsel) {
-                build_append_pcihp_notify_entry(&notify_method, slot);
+                build_append_pcihp_notify_entry(notify_method, slot);
             }
         } else {
             /* When hotplug for bridges is enabled, bridges that are
@@ -596,7 +596,7 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
             if (bridge_in_acpi) {
                 PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
 
-                build_append_pci_bus_devices(&dev, sec_bus, pcihp_bridge_en);
+                build_append_pci_bus_devices(dev, sec_bus, pcihp_bridge_en);
             }
         }
         aml_append(parent_scope, dev);
@@ -614,12 +614,12 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
     /* If bus supports hotplug select it and notify about local events */
     if (bsel) {
         int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
-        aml_append(&method, acpi_store(acpi_int(bsel_val), acpi_name("BNUM")));
-        aml_append(&method,
+        aml_append(method, acpi_store(acpi_int(bsel_val), acpi_name("BNUM")));
+        aml_append(method,
             acpi_call2("DVNT", acpi_name("PCIU"),
                        acpi_int(1) /* Device Check */)
         );
-        aml_append(&method,
+        aml_append(method,
             acpi_call2("DVNT", acpi_name("PCID"),
                        acpi_int(3)/* Eject Request */)
         );
@@ -630,7 +630,7 @@ static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
         QLIST_FOREACH(sec, &bus->child, sibling) {
             int32_t devfn = sec->parent_dev->devfn;
 
-            aml_append(&method, acpi_name("^S%.02X.PCNT", devfn));
+            aml_append(method, acpi_name("^S%.02X.PCNT", devfn));
         }
     }
     aml_append(parent_scope, method);
@@ -644,7 +644,7 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
     MachineState *machine = MACHINE(qdev_get_machine());
     uint32_t nr_mem = machine->ram_slots;
     unsigned acpi_cpus = guest_info->apic_id_limit;
-    AcpiAml pkg, scope, dev, method, crs, field, ifctx, ssdt;
+    AcpiAml *pkg, *scope, *dev, *method, *crs, *field, *ifctx, *ssdt;
     int i;
 
     /* The current AML generator can cover the APIC ID range [0..255],
@@ -659,93 +659,93 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
     scope = acpi_scope("\\_SB.PCI0");
     /* build PCI0._CRS */
     crs = acpi_resource_template();
-    aml_append(&crs,
+    aml_append(crs,
         acpi_word_bus_number(acpi_min_fixed, acpi_max_fixed, acpi_pos_decode,
                              0x0000, 0x0000, 0x00FF, 0x0000, 0x0100));
-    aml_append(&crs, acpi_io(acpi_decode16, 0x0CF8, 0x0CF8, 0x01, 0x08));
+    aml_append(crs, acpi_io(acpi_decode16, 0x0CF8, 0x0CF8, 0x01, 0x08));
 
-    aml_append(&crs,
+    aml_append(crs,
         acpi_word_io(acpi_min_fixed, acpi_max_fixed,
                      acpi_pos_decode, acpi_entire_range,
                      0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));
-    aml_append(&crs,
+    aml_append(crs,
         acpi_word_io(acpi_min_fixed, acpi_max_fixed,
                      acpi_pos_decode, acpi_entire_range,
                      0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300));
-    aml_append(&crs,
+    aml_append(crs,
         acpi_dword_memory(acpi_pos_decode, acpi_min_fixed, acpi_max_fixed,
                           acpi_cacheable, acpi_ReadWrite,
                           0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));
-    aml_append(&crs,
+    aml_append(crs,
         acpi_dword_memory(acpi_pos_decode, acpi_min_fixed, acpi_max_fixed,
                           acpi_non_cacheable, acpi_ReadWrite,
                           0, pci->w32.begin, pci->w32.end - 1, 0,
                           pci->w32.end - pci->w32.begin));
     if (pci->w64.begin) {
-        aml_append(&crs,
+        aml_append(crs,
             acpi_qword_memory(acpi_pos_decode, acpi_min_fixed, acpi_max_fixed,
                               acpi_cacheable, acpi_ReadWrite,
                               0, pci->w64.begin, pci->w64.end - 1, 0,
                               pci->w64.end - pci->w64.begin));
     }
-    aml_append(&scope, acpi_name_decl("_CRS", crs));
+    aml_append(scope, acpi_name_decl("_CRS", crs));
 
     /* reserve PCIHP resources */
     if (pm->pcihp_io_len) {
         dev = acpi_device("PHPR");
-        aml_append(&dev, acpi_name_decl("_HID", acpi_string("PNP0A06")));
-        aml_append(&dev,
+        aml_append(dev, acpi_name_decl("_HID", acpi_string("PNP0A06")));
+        aml_append(dev,
             acpi_name_decl("_UID", acpi_string("PCI Hotplug resources")));
         /* device present, functioning, decoding, not shown in UI */
-        aml_append(&dev, acpi_name_decl("_STA", acpi_int(0xB)));
+        aml_append(dev, acpi_name_decl("_STA", acpi_int(0xB)));
         crs = acpi_resource_template();
-        aml_append(&crs,
+        aml_append(crs,
             acpi_io(acpi_decode16, pm->pcihp_io_base, pm->pcihp_io_base,
                     1, pm->pcihp_io_len)
         );
-        aml_append(&dev, acpi_name_decl("_CRS", crs));
-        aml_append(&scope, dev);
+        aml_append(dev, acpi_name_decl("_CRS", crs));
+        aml_append(scope, dev);
     }
-    aml_append(&ssdt, scope);
+    aml_append(ssdt, scope);
 
     /*  create S3_ / S4_ / S5_ packages if necessary */
     scope = acpi_scope("\\");
     if (!pm->s3_disabled) {
         pkg = acpi_package(4);
-        aml_append(&pkg, acpi_int(1)); /* PM1a_CNT.SLP_TYP */
-        aml_append(&pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
-        aml_append(&pkg, acpi_int(0)); /* reserved */
-        aml_append(&pkg, acpi_int(0)); /* reserved */
-        aml_append(&scope, acpi_name_decl("_S3", pkg));
+        aml_append(pkg, acpi_int(1)); /* PM1a_CNT.SLP_TYP */
+        aml_append(pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
+        aml_append(pkg, acpi_int(0)); /* reserved */
+        aml_append(pkg, acpi_int(0)); /* reserved */
+        aml_append(scope, acpi_name_decl("_S3", pkg));
     }
 
     if (!pm->s4_disabled) {
         pkg = acpi_package(4);
-        aml_append(&pkg, acpi_int(pm->s4_val)); /* PM1a_CNT.SLP_TYP */
-        aml_append(&pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
-        aml_append(&pkg, acpi_int(0)); /* reserved */
-        aml_append(&pkg, acpi_int(0)); /* reserved */
-        aml_append(&scope, acpi_name_decl("_S4", pkg));
+        aml_append(pkg, acpi_int(pm->s4_val)); /* PM1a_CNT.SLP_TYP */
+        aml_append(pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
+        aml_append(pkg, acpi_int(0)); /* reserved */
+        aml_append(pkg, acpi_int(0)); /* reserved */
+        aml_append(scope, acpi_name_decl("_S4", pkg));
     }
 
     pkg = acpi_package(4);
-    aml_append(&pkg, acpi_int(0)); /* PM1a_CNT.SLP_TYP */
-    aml_append(&pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
-    aml_append(&pkg, acpi_int(0)); /* reserved */
-    aml_append(&pkg, acpi_int(0)); /* reserved */
-    aml_append(&scope, acpi_name_decl("_S5", pkg));
-    aml_append(&ssdt, scope);
+    aml_append(pkg, acpi_int(0)); /* PM1a_CNT.SLP_TYP */
+    aml_append(pkg, acpi_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
+    aml_append(pkg, acpi_int(0)); /* reserved */
+    aml_append(pkg, acpi_int(0)); /* reserved */
+    aml_append(scope, acpi_name_decl("_S5", pkg));
+    aml_append(ssdt, scope);
 
     if (misc->applesmc_io_base) {
         scope = acpi_scope("\\_SB.PCI0.ISA");
         dev = acpi_device("SMC");
 
-        aml_append(&dev, acpi_name_decl("_HID", acpi_eisaid("APP0001")));
+        aml_append(dev, acpi_name_decl("_HID", acpi_eisaid("APP0001")));
         /* device present, functioning, decoding, not shown in UI */
-        aml_append(&dev, acpi_name_decl("_STA", acpi_int(0xB)));
+        aml_append(dev, acpi_name_decl("_STA", acpi_int(0xB)));
 
         crs = acpi_resource_template();
-        aml_append(&crs,
+        aml_append(crs,
             acpi_io(acpi_decode16,
                     misc->applesmc_io_base,
                     misc->applesmc_io_base,
@@ -753,88 +753,88 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
                     APPLESMC_MAX_DATA_LENGTH
             )
         );
-        aml_append(&crs, acpi_iqr_no_flags(6));
-        aml_append(&dev, acpi_name_decl("_CRS", crs));
+        aml_append(crs, acpi_iqr_no_flags(6));
+        aml_append(dev, acpi_name_decl("_CRS", crs));
 
-        aml_append(&scope, dev);
-        aml_append(&ssdt, scope);
+        aml_append(scope, dev);
+        aml_append(ssdt, scope);
     }
 
     if (misc->pvpanic_port) {
         scope = acpi_scope("\\_SB.PCI0.ISA");
 
         dev = acpi_device("PEVR");
-        aml_append(&dev, acpi_name_decl("_HID", acpi_string("QEMU0002")));
+        aml_append(dev, acpi_name_decl("_HID", acpi_string("QEMU0002")));
 
         crs = acpi_resource_template();
-        aml_append(&crs,
+        aml_append(crs,
             acpi_io(acpi_decode16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)
         );
-        aml_append(&dev, acpi_name_decl("_CRS", crs));
+        aml_append(dev, acpi_name_decl("_CRS", crs));
 
-        aml_append(&dev, acpi_operation_region("PEOR", acpi_system_io,
+        aml_append(dev, acpi_operation_region("PEOR", acpi_system_io,
                                                misc->pvpanic_port, 1));
         field = acpi_field("PEOR", acpi_byte_acc);
-        aml_append(&field, acpi_named_field("PEPT", 8));
-        aml_append(&dev, field);
+        aml_append(field, acpi_named_field("PEPT", 8));
+        aml_append(dev, field);
 
         method = acpi_method("RDPT", 0);
-        aml_append(&method, acpi_store(acpi_name("PEPT"), acpi_local0()));
-        aml_append(&method, acpi_return(acpi_local0()));
-        aml_append(&dev, method);
+        aml_append(method, acpi_store(acpi_name("PEPT"), acpi_local0()));
+        aml_append(method, acpi_return(acpi_local0()));
+        aml_append(dev, method);
 
         method = acpi_method("WRPT", 1);
-        aml_append(&method, acpi_store(acpi_arg0(), acpi_name("PEPT")));
-        aml_append(&dev, method);
+        aml_append(method, acpi_store(acpi_arg0(), acpi_name("PEPT")));
+        aml_append(dev, method);
 
-        aml_append(&scope, dev);
-        aml_append(&ssdt, scope);
+        aml_append(scope, dev);
+        aml_append(ssdt, scope);
     }
 
     {
-        AcpiAml sb_scope = acpi_scope("_SB");
+        AcpiAml *sb_scope = acpi_scope("_SB");
 
         /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
         dev = acpi_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
-        aml_append(&dev, acpi_name_decl("_HID", acpi_eisaid("PNP0A06")));
-        aml_append(&dev,
+        aml_append(dev, acpi_name_decl("_HID", acpi_eisaid("PNP0A06")));
+        aml_append(dev,
             acpi_name_decl("_UID", acpi_string("CPU Hotplug resources"))
         );
         /* device present, functioning, decoding, not shown in UI */
-        aml_append(&dev, acpi_name_decl("_STA", acpi_int(0xB)));
+        aml_append(dev, acpi_name_decl("_STA", acpi_int(0xB)));
         crs = acpi_resource_template();
-        aml_append(&crs,
+        aml_append(crs,
             acpi_io(acpi_decode16, pm->cpu_hp_io_base, pm->cpu_hp_io_base,
                     1, pm->cpu_hp_io_len)
         );
-        aml_append(&dev, acpi_name_decl("_CRS", crs));
-        aml_append(&sb_scope, dev);
+        aml_append(dev, acpi_name_decl("_CRS", crs));
+        aml_append(sb_scope, dev);
         /* declare CPU hotplug MMIO region and PRS field to access it */
-        aml_append(&sb_scope, acpi_operation_region(
+        aml_append(sb_scope, acpi_operation_region(
             "PRST", acpi_system_io, pm->cpu_hp_io_base, pm->cpu_hp_io_len));
         field = acpi_field("PRST", acpi_byte_acc);
-        aml_append(&field, acpi_named_field("PRS", 256));
-        aml_append(&sb_scope, field);
+        aml_append(field, acpi_named_field("PRS", 256));
+        aml_append(sb_scope, field);
 
         /* build Processor object for each processor */
         for (i = 0; i < acpi_cpus; i++) {
             dev = acpi_processor(i, 0, 0, "CP%.02X", i);
 
             method = acpi_method("_MAT", 0);
-            aml_append(&method, acpi_return(acpi_call1("CPMA", acpi_int(i))));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_call1("CPMA", acpi_int(i))));
+            aml_append(dev, method);
 
             method = acpi_method("_STA", 0);
-            aml_append(&method, acpi_return(acpi_call1("CPST", acpi_int(i))));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_call1("CPST", acpi_int(i))));
+            aml_append(dev, method);
 
             method = acpi_method("_EJ0", 1);
-            aml_append(&method,
+            aml_append(method,
                 acpi_return(acpi_call2("CPEJ", acpi_int(i), acpi_arg0()))
             );
-            aml_append(&dev, method);
+            aml_append(dev, method);
 
-            aml_append(&sb_scope, dev);
+            aml_append(sb_scope, dev);
         }
 
         /* build this code:
@@ -844,12 +844,12 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
         method = acpi_method("NTFY", 2);
         for (i = 0; i < acpi_cpus; i++) {
             ifctx = acpi_if(acpi_equal(acpi_arg0(), acpi_int(i)));
-            aml_append(&ifctx,
+            aml_append(ifctx,
                 acpi_notify(acpi_name("CP%.02X", i), acpi_arg1())
             );
-            aml_append(&method, ifctx);
+            aml_append(method, ifctx);
         }
-        aml_append(&sb_scope, method);
+        aml_append(sb_scope, method);
 
         /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
          *
@@ -863,93 +863,93 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
 
         for (i = 0; i < acpi_cpus; i++) {
             uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;
-            aml_append(&pkg, acpi_int(b));
+            aml_append(pkg, acpi_int(b));
         }
-        aml_append(&sb_scope, acpi_name_decl("CPON", pkg));
+        aml_append(sb_scope, acpi_name_decl("CPON", pkg));
 
         /* build memory devices */
         assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
         scope = acpi_scope("\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE));
-        aml_append(&scope,
+        aml_append(scope,
             acpi_name_decl(stringify(MEMORY_SLOTS_NUMBER), acpi_int(nr_mem))
         );
 
         crs = acpi_resource_template();
-        aml_append(&crs,
+        aml_append(crs,
             acpi_io(acpi_decode16, pm->mem_hp_io_base, pm->mem_hp_io_base,
                     0, pm->mem_hp_io_len)
         );
-        aml_append(&scope, acpi_name_decl("_CRS", crs));
+        aml_append(scope, acpi_name_decl("_CRS", crs));
 
-        aml_append(&scope, acpi_operation_region(
+        aml_append(scope, acpi_operation_region(
             stringify(MEMORY_HOTPLUG_IO_REGION), acpi_system_io,
             pm->mem_hp_io_base, pm->mem_hp_io_len)
         );
 
         field = acpi_field(stringify(MEMORY_HOTPLUG_IO_REGION), acpi_dword_acc);
-        aml_append(&field, /* read only */
+        aml_append(field, /* read only */
             acpi_named_field(stringify(MEMORY_SLOT_ADDR_LOW), 32));
-        aml_append(&field, /* read only */
+        aml_append(field, /* read only */
             acpi_named_field(stringify(MEMORY_SLOT_ADDR_HIGH), 32));
-        aml_append(&field, /* read only */
+        aml_append(field, /* read only */
             acpi_named_field(stringify(MEMORY_SLOT_SIZE_LOW), 32));
-        aml_append(&field, /* read only */
+        aml_append(field, /* read only */
             acpi_named_field(stringify(MEMORY_SLOT_SIZE_HIGH), 32));
-        aml_append(&field, /* read only */
+        aml_append(field, /* read only */
             acpi_named_field(stringify(MEMORY_SLOT_PROXIMITY), 32));
-        aml_append(&scope, field);
+        aml_append(scope, field);
 
         field = acpi_field(stringify(MEMORY_HOTPLUG_IO_REGION), acpi_byte_acc);
-        aml_append(&field, acpi_reserved_field(160 /* Offset(20) */));
-        aml_append(&field, /* 1 if enabled, read only */
+        aml_append(field, acpi_reserved_field(160 /* Offset(20) */));
+        aml_append(field, /* 1 if enabled, read only */
             acpi_named_field(stringify(MEMORY_SLOT_ENABLED), 1));
-        aml_append(&field,
+        aml_append(field,
             /*(read) 1 if has a insert event. (write) 1 to clear event */
             acpi_named_field(stringify(MEMORY_SLOT_INSERT_EVENT), 1));
-        aml_append(&scope, field);
+        aml_append(scope, field);
 
         field = acpi_field(stringify(MEMORY_HOTPLUG_IO_REGION), acpi_dword_acc);
-        aml_append(&field, /* DIMM selector, write only */
+        aml_append(field, /* DIMM selector, write only */
             acpi_named_field(stringify(MEMORY_SLOT_SLECTOR), 32));
-        aml_append(&field, /* _OST event code, write only */
+        aml_append(field, /* _OST event code, write only */
             acpi_named_field(stringify(MEMORY_SLOT_OST_EVENT), 32));
-        aml_append(&field, /* _OST status code, write only */
+        aml_append(field, /* _OST status code, write only */
             acpi_named_field(stringify(MEMORY_SLOT_OST_STATUS), 32));
-        aml_append(&scope, field);
+        aml_append(scope, field);
 
-        aml_append(&sb_scope, scope);
+        aml_append(sb_scope, scope);
 
         for (i = 0; i < nr_mem; i++) {
             #define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "."
             const char *s;
 
             dev = acpi_device("MP%02X", i);
-            aml_append(&dev, acpi_name_decl("_UID", acpi_string("0x%02X", i)));
-            aml_append(&dev, acpi_name_decl("_HID", acpi_eisaid("PNP0C80")));
+            aml_append(dev, acpi_name_decl("_UID", acpi_string("0x%02X", i)));
+            aml_append(dev, acpi_name_decl("_HID", acpi_eisaid("PNP0C80")));
 
             method = acpi_method("_CRS", 0);
             s = BASEPATH stringify(MEMORY_SLOT_CRS_METHOD);
-            aml_append(&method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
+            aml_append(dev, method);
 
             method = acpi_method("_STA", 0);
             s = BASEPATH stringify(MEMORY_SLOT_STATUS_METHOD);
-            aml_append(&method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
+            aml_append(dev, method);
 
             method = acpi_method("_PXM", 0);
             s = BASEPATH stringify(MEMORY_SLOT_PROXIMITY_METHOD);
-            aml_append(&method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
-            aml_append(&dev, method);
+            aml_append(method, acpi_return(acpi_call1(s, acpi_name("_UID"))));
+            aml_append(dev, method);
 
             method = acpi_method("_OST", 3);
             s = BASEPATH stringify(MEMORY_SLOT_OST_METHOD);
-            aml_append(&method, acpi_return(acpi_call4(
+            aml_append(method, acpi_return(acpi_call4(
                 s, acpi_name("_UID"), acpi_arg0(), acpi_arg1(), acpi_arg2()
             )));
-            aml_append(&dev, method);
+            aml_append(dev, method);
 
-            aml_append(&sb_scope, dev);
+            aml_append(sb_scope, dev);
         }
 
         /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
@@ -958,12 +958,12 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
         method = acpi_method(stringify(MEMORY_SLOT_NOTIFY_METHOD), 2);
         for (i = 0; i < nr_mem; i++) {
             ifctx = acpi_if(acpi_equal(acpi_arg0(), acpi_int(i)));
-            aml_append(&ifctx,
+            aml_append(ifctx,
                 acpi_notify(acpi_name("MP%.02X", i), acpi_arg1())
             );
-            aml_append(&method, ifctx);
+            aml_append(method, ifctx);
         }
-        aml_append(&sb_scope, method);
+        aml_append(sb_scope, method);
 
         {
             Object *pci_host;
@@ -978,12 +978,12 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
             if (bus) {
                 scope = acpi_scope("PCI0");
                 /* Scan all PCI buses. Generate tables to support hotplug. */
-                build_append_pci_bus_devices(&scope, bus,
+                build_append_pci_bus_devices(scope, bus,
                                              pm->pcihp_bridge_en);
-                aml_append(&sb_scope, scope);
+                aml_append(sb_scope, scope);
             }
         }
-        aml_append(&ssdt, sb_scope);
+        aml_append(ssdt, sb_scope);
     }
 
     aml_append(table_aml, ssdt);
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index d39b5b1..0e068f1 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -95,56 +95,56 @@ typedef enum {
 } acpiReadAndWrite;
 
 
-void aml_append(AcpiAml *parent_ctx, AcpiAml child);
+void aml_append(AcpiAml *parent_ctx, AcpiAml *child);
 
 /* non block ASL object primitives */
-AcpiAml acpi_return(AcpiAml val);
-AcpiAml acpi_int(const uint64_t val);
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
-AcpiAml acpi_name_decl(const char *name, AcpiAml val);
-AcpiAml acpi_arg0(void);
-AcpiAml acpi_arg1(void);
-AcpiAml acpi_arg2(void);
-AcpiAml acpi_arg3(void);
-AcpiAml acpi_store(AcpiAml val, AcpiAml target);
-AcpiAml acpi_and(AcpiAml arg1, AcpiAml arg2);
-AcpiAml acpi_notify(AcpiAml arg1, AcpiAml arg2);
-AcpiAml acpi_call1(const char *method, AcpiAml arg1);
-AcpiAml acpi_call2(const char *method, AcpiAml arg1, AcpiAml arg2);
-AcpiAml acpi_call3(const char *method, AcpiAml arg1, AcpiAml arg2,
-                   AcpiAml arg3);
-AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
-                   AcpiAml arg3, AcpiAml arg4);
-AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
+AcpiAml *acpi_return(AcpiAml *val);
+AcpiAml *acpi_int(const uint64_t val);
+AcpiAml *GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
+AcpiAml *acpi_name_decl(const char *name, AcpiAml *val);
+AcpiAml *acpi_arg0(void);
+AcpiAml *acpi_arg1(void);
+AcpiAml *acpi_arg2(void);
+AcpiAml *acpi_arg3(void);
+AcpiAml *acpi_store(AcpiAml *val, AcpiAml *target);
+AcpiAml *acpi_and(AcpiAml *arg1, AcpiAml *arg2);
+AcpiAml *acpi_notify(AcpiAml *arg1, AcpiAml *arg2);
+AcpiAml *acpi_call1(const char *method, AcpiAml *arg1);
+AcpiAml *acpi_call2(const char *method, AcpiAml *arg1, AcpiAml *arg2);
+AcpiAml *acpi_call3(const char *method, AcpiAml *arg1, AcpiAml *arg2,
+                   AcpiAml *arg3);
+AcpiAml *acpi_call4(const char *method, AcpiAml *arg1, AcpiAml *arg2,
+                   AcpiAml *arg3, AcpiAml *arg4);
+AcpiAml *acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
                 uint8_t aln, uint8_t len);
-AcpiAml acpi_iqr_no_flags(uint8_t irq);
-AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
+AcpiAml *acpi_iqr_no_flags(uint8_t irq);
+AcpiAml *acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len);
-AcpiAml acpi_named_field(const char *name, unsigned length);
-AcpiAml acpi_reserved_field(unsigned length);
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
-AcpiAml acpi_local0(void);
-AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2);
-AcpiAml GCC_FMT_ATTR(4, 5)
+AcpiAml *acpi_named_field(const char *name, unsigned length);
+AcpiAml *acpi_reserved_field(unsigned length);
+AcpiAml *GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
+AcpiAml *acpi_local0(void);
+AcpiAml *acpi_equal(AcpiAml *arg1, AcpiAml *arg2);
+AcpiAml *GCC_FMT_ATTR(4, 5)
 acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
                const char *name_format, ...);
-AcpiAml acpi_eisaid(const char *str);
-AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+AcpiAml *acpi_eisaid(const char *str);
+AcpiAml *acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
                              acpiDecode dec, uint16_t addr_gran,
                              uint16_t addr_min, uint16_t addr_max,
                              uint16_t addr_trans, uint16_t len);
-AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
+AcpiAml *acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
                      acpiDecode dec, acpiISARanges isa_ranges,
                      uint16_t addr_gran, uint16_t addr_min,
                      uint16_t addr_max, uint16_t addr_trans,
                      uint16_t len);
-AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+AcpiAml *acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
                           acpiMaxFixed max_fixed, acpiCacheble cacheable,
                           acpiReadAndWrite read_and_write,
                           uint32_t addr_gran, uint32_t addr_min,
                           uint32_t addr_max, uint32_t addr_trans,
                           uint32_t len);
-AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
+AcpiAml *acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
                           acpiMaxFixed max_fixed, acpiCacheble cacheable,
                           acpiReadAndWrite read_and_write,
                           uint64_t addr_gran, uint64_t addr_min,
@@ -152,18 +152,18 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
                           uint64_t len);
 
 /* Block ASL object primitives */
-AcpiAml acpi_def_block(const char *signature, uint8_t revision,
+AcpiAml *acpi_def_block(const char *signature, uint8_t revision,
                        const char *oem_id, const char *oem_table_id,
                        uint32_t oem_revision);
-AcpiAml acpi_if(AcpiAml predicate);
-AcpiAml acpi_method(const char *name, int arg_count);
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
-AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
-AcpiAml acpi_buffer(void);
-AcpiAml acpi_resource_template(void);
-AcpiAml acpi_package(uint8_t num_elements);
-AcpiAml acpi_field(const char *name, acpiFieldFlags flags);
-AcpiAml acpi_varpackage(uint32_t num_elements);
+AcpiAml *acpi_if(AcpiAml *predicate);
+AcpiAml *acpi_method(const char *name, int arg_count);
+AcpiAml *GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
+AcpiAml *GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
+AcpiAml *acpi_buffer(void);
+AcpiAml *acpi_resource_template(void);
+AcpiAml *acpi_package(uint8_t num_elements);
+AcpiAml *acpi_field(const char *name, acpiFieldFlags flags);
+AcpiAml *acpi_varpackage(uint32_t num_elements);
 
 /* other helpers */
 GArray *build_alloc_array(void);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 02/13] make toplevel ACPI tables blob a pointer
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 01/13] convert to passing AcpiAml by pointers Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 03/13] qom: add support for weak referenced object: aka UnownedObject Igor Mammedov
                                                 ` (11 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

in following patch toplevel blob would be switched to
QOM AML_OBJECT model vs manually constructed now.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index c7f492e..f24f92b 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1270,7 +1270,7 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
 
 typedef
 struct AcpiBuildTables {
-    AcpiAml table_data;
+    AcpiAml* table_data;
     GArray *rsdp;
     GArray *tcpalog;
     GArray *linker;
@@ -1279,10 +1279,10 @@ struct AcpiBuildTables {
 static inline void acpi_build_tables_init(AcpiBuildTables *tables)
 {
     tables->rsdp = g_array_new(false, true /* clear */, 1);
-    tables->table_data.buf = g_array_new(false, true /* clear */, 1);
+    tables->table_data->buf = g_array_new(false, true /* clear */, 1);
     tables->tcpalog = g_array_new(false, true /* clear */, 1);
     tables->linker = bios_linker_loader_init();
-    tables->table_data.linker = tables->linker;
+    tables->table_data->linker = tables->linker;
 }
 
 static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
@@ -1290,7 +1290,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
     void *linker_data = bios_linker_loader_cleanup(tables->linker);
     g_free(linker_data);
     g_array_free(tables->rsdp, mfre);
-    g_array_free(tables->table_data.buf, true);
+    g_array_free(tables->table_data->buf, true);
     g_array_free(tables->tcpalog, mfre);
 }
 
@@ -1461,23 +1461,23 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
             guest_info->legacy_acpi_table_size +
             ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus;
         int legacy_table_size =
-            ROUND_UP(tables->table_data.buf->len - aml_len + legacy_aml_len,
+            ROUND_UP(tables->table_data->buf->len - aml_len + legacy_aml_len,
                      ACPI_BUILD_ALIGN_SIZE);
-        if (tables->table_data.buf->len > legacy_table_size) {
+        if (tables->table_data->buf->len > legacy_table_size) {
             /* Should happen only with PCI bridges and -M pc-i440fx-2.0.  */
             error_report("Warning: migration may not work.");
         }
-        g_array_set_size(tables->table_data.buf, legacy_table_size);
+        g_array_set_size(tables->table_data->buf, legacy_table_size);
     } else {
         /* Make sure we have a buffer in case we need to resize the tables. */
-        if (tables->table_data.buf->len > ACPI_BUILD_TABLE_SIZE / 2) {
+        if (tables->table_data->buf->len > ACPI_BUILD_TABLE_SIZE / 2) {
             /* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots.  */
             error_report("Warning: ACPI tables are larger than 64k.");
             error_report("Warning: migration may not work.");
             error_report("Warning: please remove CPUs, NUMA nodes, "
                          "memory slots or PCI bridges.");
         }
-        acpi_align_size(tables->table_data.buf, ACPI_BUILD_TABLE_SIZE);
+        acpi_align_size(tables->table_data->buf, ACPI_BUILD_TABLE_SIZE);
     }
 
     acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
@@ -1501,14 +1501,14 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
 
     acpi_build(build_state->guest_info, &tables);
 
-    assert(acpi_data_len(tables.table_data.buf) == build_state->table_size);
+    assert(acpi_data_len(tables.table_data->buf) == build_state->table_size);
 
     /* Make sure RAM size is correct - in case it got changed by migration */
     qemu_ram_resize(build_state->table_ram, build_state->table_size,
                     &error_abort);
 
     memcpy(qemu_get_ram_ptr(build_state->table_ram),
-           tables.table_data.buf->data, build_state->table_size);
+           tables.table_data->buf->data, build_state->table_size);
 
     cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram,
                                                build_state->table_size);
@@ -1570,11 +1570,11 @@ void acpi_setup(PcGuestInfo *guest_info)
 
     /* Now expose it all to Guest */
     build_state->table_ram = acpi_add_rom_blob(build_state,
-                                               tables.table_data.buf,
+                                               tables.table_data->buf,
                                                ACPI_BUILD_TABLE_FILE,
                                                ACPI_BUILD_TABLE_MAX_SIZE);
     assert(build_state->table_ram != RAM_ADDR_MAX);
-    build_state->table_size = acpi_data_len(tables.table_data.buf);
+    build_state->table_size = acpi_data_len(tables.table_data->buf);
 
     acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader", 0);
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 03/13] qom: add support for weak referenced object: aka UnownedObject
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 01/13] convert to passing AcpiAml by pointers Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 02/13] make toplevel ACPI tables blob a pointer Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:09                                 ` Paolo Bonzini
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 04/13] acpi: make AcpiAml an OQM object Igor Mammedov
                                                 ` (10 subsequent siblings)
  13 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

it adds support for weak reference model used by glib's
GInitiallyUnowned to QEMU's QOM model.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 include/qom/object.h | 20 ++++++++++++++++++++
 qom/object.c         | 20 +++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 89c3092..e0e4cc8 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1314,5 +1314,25 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
  */
 Object *container_get(Object *root, const char *path);
 
+#define TYPE_UNOWNED_OBJECT "unowned-object"
+#define UNOWNED_OBJECT(obj) \
+     OBJECT_CHECK(UnownedObject, (obj), TYPE_UNOWNED_OBJECT)
+#define UNOWNED_OBJECT_CLASS(klass) \
+     OBJECT_CLASS_CHECK(UnownedObjectClass, (klass), TYPE_UNOWNED_OBJECT)
+#define UNOWNED_OBJECT_GET_CLASS \
+     OBJECT_GET_CLASS(UnownedObjectClass, (obj), TYPE_UNOWNED_OBJECT)
+#define OBJECT_WEAK_REF (1UL << 31)
+
+typedef struct UnownedObjectClass
+{
+    /*< private >*/
+    ObjectClass parent_class;
+} UnownedObjectClass;
+
+typedef struct UnownedObject
+{
+    /*< private >*/
+    Object parent_obj;
+} UnownedObject;
 
 #endif
diff --git a/qom/object.c b/qom/object.c
index 1812c73..96842c7 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -705,6 +705,10 @@ void object_ref(Object *obj)
     if (!obj) {
         return;
     }
+    if (atomic_fetch_and(&obj->ref, ~OBJECT_WEAK_REF) & OBJECT_WEAK_REF)
+    {
+        return;
+    }
      atomic_inc(&obj->ref);
 }
 
@@ -713,7 +717,7 @@ void object_unref(Object *obj)
     if (!obj) {
         return;
     }
-    g_assert(obj->ref > 0);
+    g_assert((obj->ref & ~OBJECT_WEAK_REF) > 0);
 
     /* parent always holds a reference to its children */
     if (atomic_fetch_dec(&obj->ref) == 1) {
@@ -1709,6 +1713,12 @@ static void object_instance_init(Object *obj)
     object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
 }
 
+
+static void unowned_object_instance_init(Object *obj)
+{
+    obj->ref |= OBJECT_WEAK_REF;
+}
+
 static void register_types(void)
 {
     static TypeInfo interface_info = {
@@ -1724,8 +1734,16 @@ static void register_types(void)
         .abstract = true,
     };
 
+    static TypeInfo unowned_object_info = {
+        .name = TYPE_UNOWNED_OBJECT,
+        .instance_size = sizeof(UnownedObject),
+        .instance_init = unowned_object_instance_init,
+        .abstract = true,
+    };
+
     type_interface = type_register_internal(&interface_info);
     type_register_internal(&object_info);
+    type_register_internal(&unowned_object_info);
 }
 
 type_init(register_types)
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 04/13] acpi: make AcpiAml an OQM object
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (2 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 03/13] qom: add support for weak referenced object: aka UnownedObject Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 05/13] acpi: use TYPE_AML_OBJECT inside of AML API Igor Mammedov
                                                 ` (9 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

it allows to build table tree by assigning
child AML objects to parent AML object and
reuse the same AML objects multiple times.

When table is build and added to ACPI
tables blob, it will create the same
parent->child relation, and when ACPI tables
blob is destroyed (object_unref()), it will
automatically cleanup all children AML objects
that has been created for it.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 31 +++++++++++++++++++++++++++++++
 include/hw/acpi/acpi-build-utils.h | 13 +++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 5bfb74d..1041865 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -27,6 +27,7 @@
 #include "hw/acpi/acpi-build-utils.h"
 #include "qemu/bswap.h"
 #include "hw/acpi/bios-linker-loader.h"
+#include "qemu/module.h"
 
 GArray *build_alloc_array(void)
 {
@@ -910,3 +911,33 @@ AcpiAml *acpi_def_block(const char *signature, uint8_t revision,
 
     return var;
 }
+
+static void aml_object_initfn(Object *obj) {
+    AcpiAml *aml = AML_OBJECT(obj);
+
+    aml->buf = build_alloc_array();
+}
+
+static void aml_object_finalize(Object *obj) {
+    AcpiAml *aml = AML_OBJECT(obj);
+
+    build_free_array(aml->buf);
+    memset(aml, 0, sizeof(*aml));
+}
+
+static const TypeInfo aml_object_type_info = {
+    .name = TYPE_AML_OBJECT,
+    .parent = TYPE_UNOWNED_OBJECT,
+    .instance_size = sizeof(AcpiAml),
+    .instance_init = aml_object_initfn,
+    .instance_finalize = aml_object_finalize,
+    .abstract = false,
+    .class_size = sizeof(AcpiAmlClass),
+};
+
+static void aml_register_types(void)
+{
+    type_register_static(&aml_object_type_info);
+}
+
+type_init(aml_register_types)
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 0e068f1..c36ddb6 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -4,6 +4,7 @@
 #include <stdint.h>
 #include <glib.h>
 #include "qemu/compiler.h"
+#include "qom/object.h"
 
 typedef enum {
     NON_BLOCK,
@@ -17,13 +18,25 @@ typedef enum {
 #define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
 #define ACPI_BUILD_APPNAME4 "BXPC"
 
+#define TYPE_AML_OBJECT "aml-object"
+#define AML_OBJECT(obj) OBJECT_CHECK(AcpiAml, (obj), TYPE_AML_OBJECT)
+#define AML_OBJECT_CLASS(klass) \
+     OBJECT_CLASS_CHECK(AcpiAmlClass, (klass), TYPE_AML_OBJECT)
+#define AML_OBJECT_GET_CLASS \
+     OBJECT_GET_CLASS(AcpiAmlClass, (obj), TYPE_AML_OBJECT)
+
 typedef struct AcpiAml {
+    Object parent_obj;
     GArray *buf;
     uint8_t op;
     AcpiBlockFlags block_flags;
     GArray *linker;
 } AcpiAml;
 
+typedef struct AcpiAmlClass {
+    ObjectClass parent_class;
+} AcpiAmlClass;
+
 typedef enum {
     acpi_decode10 = 0,
     acpi_decode16 = 1,
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 05/13] acpi: use TYPE_AML_OBJECT inside of AML API
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (3 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 04/13] acpi: make AcpiAml an OQM object Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 06/13] acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob Igor Mammedov
                                                 ` (8 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c | 101 +++++++++++++++++++++++++--------------------
 1 file changed, 57 insertions(+), 44 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 1041865..02f60d7 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -293,6 +293,8 @@ static void build_prepend_int(GArray *array, uint32_t value)
 
 void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
 {
+    char *child_name;
+
     switch (child->block_flags) {
     case EXT_PACKAGE:
         build_extop_package(child->buf, child->op);
@@ -333,22 +335,22 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
         break;
     }
     build_append_array(parent_ctx->buf, child->buf);
-    build_free_array(child->buf);
+
+    child_name = g_strdup_printf("%s[%p]'", object_get_typename(OBJECT(child)), child);
+    object_property_add_child(OBJECT(parent_ctx), child_name, OBJECT(child), &error_abort);
+    g_free(child_name);
 }
 
-static AcpiAml *aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
+static void aml_set_pack_options(AcpiAml *var, uint8_t op, AcpiBlockFlags flags)
 {
-    AcpiAml *var = g_malloc0(sizeof(AcpiAml));
     var->op = op;
     var->block_flags = flags;
-    var->buf = build_alloc_array();
-    return var;
 }
 
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefReturn */
 AcpiAml *acpi_return(AcpiAml *val)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0xA4); /* ReturnOp */
     aml_append(var, val);
     return var;
@@ -360,7 +362,7 @@ AcpiAml *acpi_return(AcpiAml *val)
  */
 AcpiAml *acpi_int(const uint64_t val)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_int(var->buf, val);
     return var;
 }
@@ -372,7 +374,7 @@ AcpiAml *acpi_int(const uint64_t val)
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_name(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -382,7 +384,7 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_name(const char *name_format, ...)
 /* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */
 AcpiAml *acpi_name_decl(const char *name, AcpiAml *val)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x08);
     build_append_namestring(var->buf, "%s", name);
     aml_append(var, val);
@@ -392,7 +394,7 @@ AcpiAml *acpi_name_decl(const char *name, AcpiAml *val)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg0Op */
 AcpiAml *acpi_arg0(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x68); /* ARG0 op */
     return var;
 }
@@ -400,7 +402,7 @@ AcpiAml *acpi_arg0(void)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg1Op */
 AcpiAml *acpi_arg1(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x69); /* ARG1 op */
     return var;
 }
@@ -408,7 +410,7 @@ AcpiAml *acpi_arg1(void)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg2Op */
 AcpiAml *acpi_arg2(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x6A); /* ARG2 op */
     return var;
 }
@@ -416,7 +418,7 @@ AcpiAml *acpi_arg2(void)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg3Op */
 AcpiAml *acpi_arg3(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x6B); /* ARG3 op */
     return var;
 }
@@ -424,7 +426,7 @@ AcpiAml *acpi_arg3(void)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefStore */
 AcpiAml *acpi_store(AcpiAml *val, AcpiAml *target)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x70); /* StoreOp */
     aml_append(var, val);
     aml_append(var, target);
@@ -434,7 +436,7 @@ AcpiAml *acpi_store(AcpiAml *val, AcpiAml *target)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefAnd */
 AcpiAml *acpi_and(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x7B); /* AndOp */
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -445,7 +447,7 @@ AcpiAml *acpi_and(AcpiAml *arg1, AcpiAml *arg2)
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefNotify */
 AcpiAml *acpi_notify(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x86); /* NotifyOp */
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -455,7 +457,7 @@ AcpiAml *acpi_notify(AcpiAml *arg1, AcpiAml *arg2)
 /* helper to call method with 1 argument */
 AcpiAml *acpi_call1(const char *method, AcpiAml *arg1)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     return var;
@@ -464,7 +466,7 @@ AcpiAml *acpi_call1(const char *method, AcpiAml *arg1)
 /* helper to call method with 2 arguments */
 AcpiAml *acpi_call2(const char *method, AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -474,7 +476,7 @@ AcpiAml *acpi_call2(const char *method, AcpiAml *arg1, AcpiAml *arg2)
 /* helper to call method with 3 arguments */
 AcpiAml *acpi_call3(const char *method, AcpiAml* arg1, AcpiAml *arg2, AcpiAml *arg3)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -486,7 +488,7 @@ AcpiAml *acpi_call3(const char *method, AcpiAml* arg1, AcpiAml *arg2, AcpiAml *a
 AcpiAml *acpi_call4(const char *method, AcpiAml *arg1, AcpiAml *arg2,
                    AcpiAml *arg3, AcpiAml *arg4)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -502,7 +504,7 @@ AcpiAml *acpi_call4(const char *method, AcpiAml *arg1, AcpiAml *arg2,
 AcpiAml *acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
                 uint8_t aln, uint8_t len)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x47); /* IO port descriptor */
     build_append_byte(var->buf, dec);
     build_append_byte(var->buf, min_base & 0xff);
@@ -521,7 +523,7 @@ AcpiAml *acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
 AcpiAml *acpi_iqr_no_flags(uint8_t irq)
 {
     uint16_t irq_mask;
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     assert(irq < 16);
     build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
@@ -535,7 +537,7 @@ AcpiAml *acpi_iqr_no_flags(uint8_t irq)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
 AcpiAml *acpi_equal(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x93); /* LequalOp */
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -546,7 +548,8 @@ AcpiAml *acpi_equal(AcpiAml *arg1, AcpiAml *arg2)
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml *acpi_if(AcpiAml *predicate)
 {
-    AcpiAml *var = aml_allocate_internal(0xA0 /* IfOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0xA0 /* IfOp */, PACKAGE);
     aml_append(var, predicate);
     return var;
 }
@@ -554,7 +557,8 @@ AcpiAml *acpi_if(AcpiAml *predicate)
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefMethod */
 AcpiAml *acpi_method(const char *name, int arg_count)
 {
-    AcpiAml *var = aml_allocate_internal(0x14 /* MethodOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x14 /* MethodOp */, PACKAGE);
     build_append_namestring(var->buf, "%s", name);
     build_append_byte(var->buf, arg_count); /* MethodFlags: ArgCount */
     return var;
@@ -564,7 +568,8 @@ AcpiAml *acpi_method(const char *name, int arg_count)
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_scope(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0x10 /* ScopeOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x10 /* ScopeOp */, PACKAGE);
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -575,7 +580,8 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_scope(const char *name_format, ...)
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_device(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0x82 /* DeviceOp */, EXT_PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x82 /* DeviceOp */, EXT_PACKAGE);
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -586,21 +592,24 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_device(const char *name_format, ...)
 AcpiAml *acpi_resource_template(void)
 {
     /* ResourceTemplate is a buffer of Resources with EndTag at the end */
-    AcpiAml *var = aml_allocate_internal(0x11 /* BufferOp */, RES_TEMPLATE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x11 /* BufferOp */, RES_TEMPLATE);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
 AcpiAml *acpi_buffer(void)
 {
-    AcpiAml *var = aml_allocate_internal(0x11 /* BufferOp */, BUFFER);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x11 /* BufferOp */, BUFFER);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefPackage */
 AcpiAml *acpi_package(uint8_t num_elements)
 {
-    AcpiAml *var = aml_allocate_internal(0x12 /* PackageOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x12 /* PackageOp */, PACKAGE);
     build_append_byte(var->buf, num_elements);
     return var;
 }
@@ -609,7 +618,7 @@ AcpiAml *acpi_package(uint8_t num_elements)
 AcpiAml *acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
     build_append_byte(var->buf, 0x80); /* OpRegionOp */
     build_append_namestring(var->buf, "%s", name);
@@ -622,7 +631,7 @@ AcpiAml *acpi_operation_region(const char *name, acpiRegionSpace rs,
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: NamedField */
 AcpiAml *acpi_named_field(const char *name, unsigned length)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_nameseg(var->buf, "%s", name);
     build_append_pkg_length(var->buf, length, false);
     return var;
@@ -631,7 +640,7 @@ AcpiAml *acpi_named_field(const char *name, unsigned length)
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: ReservedField */
 AcpiAml *acpi_reserved_field(unsigned length)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     /* ReservedField  := 0x00 PkgLength */
     build_append_byte(var->buf, 0x00);
     build_append_pkg_length(var->buf, length, false);
@@ -641,7 +650,8 @@ AcpiAml *acpi_reserved_field(unsigned length)
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefField */
 AcpiAml *acpi_field(const char *name, acpiFieldFlags flags)
 {
-    AcpiAml *var = aml_allocate_internal(0x81 /* FieldOp */, EXT_PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x81 /* FieldOp */, EXT_PACKAGE);
     build_append_namestring(var->buf, "%s", name);
     build_append_byte(var->buf, flags);
     return var;
@@ -650,7 +660,7 @@ AcpiAml *acpi_field(const char *name, acpiFieldFlags flags)
 /* ACPI 5.0: 20.2.3 Data Objects Encoding: String */
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_string(const char *name_format, ...)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     va_list ap, va_len;
     char *s;
     int len;
@@ -676,7 +686,7 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_string(const char *name_format, ...)
 /* ACPI 5.0: 20.2.6.2 Local Objects Encoding: Local0Op */
 AcpiAml *acpi_local0(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x60); /* Local0Op */
     return var;
 }
@@ -684,7 +694,8 @@ AcpiAml *acpi_local0(void)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefVarPackage */
 AcpiAml *acpi_varpackage(uint32_t num_elements)
 {
-    AcpiAml *var = aml_allocate_internal(0x13 /* VarPackageOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x13 /* VarPackageOp */, PACKAGE);
     build_append_int(var->buf, num_elements);
     return var;
 }
@@ -695,7 +706,8 @@ AcpiAml GCC_FMT_ATTR(4, 5)
                const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0x83 /* ProcessorOp */, EXT_PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x83 /* ProcessorOp */, EXT_PACKAGE);
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -721,7 +733,7 @@ static uint8_t Hex2Digit(char c)
 /* ACPI 5.0: 19.5.36 EISAID (EISA ID String To Integer Conversion Macro) */
 AcpiAml *acpi_eisaid(const char *str)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     uint32_t id;
 
     g_assert(strlen(str) == 7);
@@ -744,7 +756,7 @@ acpi_as_desc_header(acpiResourceType type, acpiMinFixed min_fixed,
                     acpiMaxFixed max_fixed, acpiDecode dec, uint8_t type_flags)
 {
     uint8_t flags = max_fixed | min_fixed | dec;
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, type);
     build_append_byte(var->buf, flags);
@@ -759,7 +771,7 @@ static AcpiAml *acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
                                  uint16_t addr_max, uint16_t addr_trans,
                                  uint16_t len, uint8_t type_flags)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
@@ -783,7 +795,7 @@ static AcpiAml *acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed
                                   uint32_t addr_max, uint32_t addr_trans,
                                   uint32_t len, uint8_t type_flags)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
@@ -808,7 +820,7 @@ static AcpiAml *acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed
                                   uint64_t addr_max, uint64_t addr_trans,
                                   uint64_t len, uint8_t type_flags)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
@@ -887,7 +899,8 @@ AcpiAml *acpi_def_block(const char *signature, uint8_t revision,
                        uint32_t oem_revision)
 {
     int len;
-    AcpiAml *var = aml_allocate_internal(0, DEF_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0, DEF_BLOCK);
 
     assert(strlen(signature) == 4);
     g_array_append_vals(var->buf, signature, 4);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 06/13] acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (4 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 05/13] acpi: use TYPE_AML_OBJECT inside of AML API Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 07/13] acpi: make toplevel ACPI tables blob a dedicated object Igor Mammedov
                                                 ` (7 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

it allows to use blob with AML API like the rest of
AML objects and use object_unref() to destroy it cleaning up
all child AML objects that we used for tables construction.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f24f92b..f456f53 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1279,7 +1279,7 @@ struct AcpiBuildTables {
 static inline void acpi_build_tables_init(AcpiBuildTables *tables)
 {
     tables->rsdp = g_array_new(false, true /* clear */, 1);
-    tables->table_data->buf = g_array_new(false, true /* clear */, 1);
+    tables->table_data = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     tables->tcpalog = g_array_new(false, true /* clear */, 1);
     tables->linker = bios_linker_loader_init();
     tables->table_data->linker = tables->linker;
@@ -1290,7 +1290,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
     void *linker_data = bios_linker_loader_cleanup(tables->linker);
     g_free(linker_data);
     g_array_free(tables->rsdp, mfre);
-    g_array_free(tables->table_data->buf, true);
+    object_unref(OBJECT(tables->table_data));
     g_array_free(tables->tcpalog, mfre);
 }
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 07/13] acpi: make toplevel ACPI tables blob a dedicated object
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (5 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 06/13] acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 08/13] i386: acpi: hack not yet converted tables calls to deal with table_data being a pointer Igor Mammedov
                                                 ` (6 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

it will help to generalize and reuse blob intitalization/
destruction code.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 12 +++++++++++-
 hw/i386/acpi-build.c               |  4 ++--
 include/hw/acpi/acpi-build-utils.h | 17 ++++++++++++++++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 02f60d7..bffad1e 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -320,9 +320,10 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
         uint8_t *start = (uint8_t *)parent_ctx->buf->data +
                          parent_ctx->buf->len;
         uint32_t le32_len = cpu_to_le32(child->buf->len);
+        AcpiAmlTablesBlob *tables_blob = AML_TABLES_BLOB(parent_ctx);
 
         /* create linker entry for the DefinitionBlock */
-        bios_linker_loader_add_checksum(parent_ctx->linker,
+        bios_linker_loader_add_checksum(tables_blob->linker,
             ACPI_BUILD_TABLE_FILE,
             parent_ctx->buf->data,
             start, child->buf->len, start + 9 /* checksum offset */);
@@ -948,9 +949,18 @@ static const TypeInfo aml_object_type_info = {
     .class_size = sizeof(AcpiAmlClass),
 };
 
+static const TypeInfo aml_tables_blob_type_info = {
+    .name = TYPE_AML_TABLES_BLOB,
+    .parent = TYPE_AML_OBJECT,
+    .instance_size = sizeof(AcpiAmlTablesBlob),
+    .abstract = false,
+    .class_size = sizeof(AcpiAmlTablesBlobClass),
+};
+
 static void aml_register_types(void)
 {
     type_register_static(&aml_object_type_info);
+    type_register_static(&aml_tables_blob_type_info);
 }
 
 type_init(aml_register_types)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f456f53..624c903 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1279,10 +1279,10 @@ struct AcpiBuildTables {
 static inline void acpi_build_tables_init(AcpiBuildTables *tables)
 {
     tables->rsdp = g_array_new(false, true /* clear */, 1);
-    tables->table_data = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     tables->tcpalog = g_array_new(false, true /* clear */, 1);
     tables->linker = bios_linker_loader_init();
-    tables->table_data->linker = tables->linker;
+    tables->table_data = AML_OBJECT(object_new(TYPE_AML_TABLES_BLOB));
+    AML_TABLES_BLOB(tables->table_data)->linker = tables->linker;
 }
 
 static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index c36ddb6..b2d023e 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -30,13 +30,28 @@ typedef struct AcpiAml {
     GArray *buf;
     uint8_t op;
     AcpiBlockFlags block_flags;
-    GArray *linker;
 } AcpiAml;
 
 typedef struct AcpiAmlClass {
     ObjectClass parent_class;
 } AcpiAmlClass;
 
+#define TYPE_AML_TABLES_BLOB "aml-tables-blob"
+#define AML_TABLES_BLOB(obj) OBJECT_CHECK(AcpiAmlTablesBlob, (obj), TYPE_AML_TABLES_BLOB)
+#define AML_TABLES_BLOB_CLASS(klass) \
+     OBJECT_CLASS_CHECK(AcpiAmlTablesBlobClass, (klass), TYPE_AML_TABLES_BLOB)
+#define AML_TABLES_BLOB_GET_CLASS \
+     OBJECT_GET_CLASS(AcpiAmlTablesBlobClass, (obj), TYPE_AML_TABLES_BLOB)
+
+typedef struct AcpiAmlTablesBlob {
+    AcpiAml parent_obj;
+    GArray *linker;
+} AcpiAmlTablesBlob;
+
+typedef struct AcpiAmlTablesBlobClass {
+  AcpiAmlClass parent_class;
+} AcpiAmlTablesBlobClass;
+
 typedef enum {
     acpi_decode10 = 0,
     acpi_decode16 = 1,
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 08/13] i386: acpi: hack not yet converted tables calls to deal with table_data being a pointer
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (6 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 07/13] acpi: make toplevel ACPI tables blob a dedicated object Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 09/13] acpi: add aml_blob() helper Igor Mammedov
                                                 ` (5 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c | 58 ++++++++++++++++++++++++++--------------------------
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 624c903..bac0156 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1370,66 +1370,66 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
      * We place it first since it's the only table that has alignment
      * requirements.
      */
-    facs = tables->table_data.buf->len;
-    build_facs(tables->table_data.buf, tables->linker, guest_info);
+    facs = tables->table_data->buf->len;
+    build_facs(tables->table_data->buf, tables->linker, guest_info);
 
     /* DSDT is pointed to by FADT */
-    dsdt = tables->table_data.buf->len;
-    build_dsdt(tables->table_data.buf, tables->linker, &misc);
+    dsdt = tables->table_data->buf->len;
+    build_dsdt(tables->table_data->buf, tables->linker, &misc);
 
     /* Count the size of the DSDT and SSDT, we will need it for legacy
      * sizing of ACPI tables.
      */
-    aml_len += tables->table_data.buf->len - dsdt;
+    aml_len += tables->table_data->buf->len - dsdt;
 
     /* ACPI tables pointed to by RSDT */
-    acpi_add_table(table_offsets, tables->table_data.buf);
-    build_fadt(tables->table_data.buf, tables->linker, &pm, facs, dsdt);
+    acpi_add_table(table_offsets, tables->table_data->buf);
+    build_fadt(tables->table_data->buf, tables->linker, &pm, facs, dsdt);
 
-    ssdt = tables->table_data.buf->len;
-    acpi_add_table(table_offsets, tables->table_data.buf);
-    build_ssdt(&tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
+    ssdt = tables->table_data->buf->len;
+    acpi_add_table(table_offsets, tables->table_data->buf);
+    build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
                guest_info);
-    aml_len += tables->table_data.buf->len - ssdt;
+    aml_len += tables->table_data->buf->len - ssdt;
 
-    acpi_add_table(table_offsets, tables->table_data.buf);
-    build_madt(tables->table_data.buf, tables->linker, &cpu, guest_info);
+    acpi_add_table(table_offsets, tables->table_data->buf);
+    build_madt(tables->table_data->buf, tables->linker, &cpu, guest_info);
 
     if (misc.has_hpet) {
-        acpi_add_table(table_offsets, tables->table_data.buf);
-        build_hpet(tables->table_data.buf, tables->linker);
+        acpi_add_table(table_offsets, tables->table_data->buf);
+        build_hpet(tables->table_data->buf, tables->linker);
     }
     if (misc.has_tpm) {
-        acpi_add_table(table_offsets, tables->table_data.buf);
-        build_tpm_tcpa(tables->table_data.buf, tables->linker, tables->tcpalog);
+        acpi_add_table(table_offsets, tables->table_data->buf);
+        build_tpm_tcpa(tables->table_data->buf, tables->linker, tables->tcpalog);
 
-        acpi_add_table(table_offsets, tables->table_data.buf);
-        build_tpm_ssdt(tables->table_data.buf, tables->linker);
+        acpi_add_table(table_offsets, tables->table_data->buf);
+        build_tpm_ssdt(tables->table_data->buf, tables->linker);
     }
     if (guest_info->numa_nodes) {
-        acpi_add_table(table_offsets, tables->table_data.buf);
-        build_srat(tables->table_data.buf, tables->linker, guest_info);
+        acpi_add_table(table_offsets, tables->table_data->buf);
+        build_srat(tables->table_data->buf, tables->linker, guest_info);
     }
     if (acpi_get_mcfg(&mcfg)) {
-        acpi_add_table(table_offsets, tables->table_data.buf);
-        build_mcfg_q35(tables->table_data.buf, tables->linker, &mcfg);
+        acpi_add_table(table_offsets, tables->table_data->buf);
+        build_mcfg_q35(tables->table_data->buf, tables->linker, &mcfg);
     }
     if (acpi_has_iommu()) {
-        acpi_add_table(table_offsets, tables->table_data.buf);
-        build_dmar_q35(tables->table_data.buf, tables->linker);
+        acpi_add_table(table_offsets, tables->table_data->buf);
+        build_dmar_q35(tables->table_data->buf, tables->linker);
     }
 
     /* Add tables supplied by user (if any) */
     for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
         unsigned len = acpi_table_len(u);
 
-        acpi_add_table(table_offsets, tables->table_data.buf);
-        g_array_append_vals(tables->table_data.buf, u, len);
+        acpi_add_table(table_offsets, tables->table_data->buf);
+        g_array_append_vals(tables->table_data->buf, u, len);
     }
 
     /* RSDT is pointed to by RSDP */
-    rsdt = tables->table_data.buf->len;
-    build_rsdt(tables->table_data.buf, tables->linker, table_offsets);
+    rsdt = tables->table_data->buf->len;
+    build_rsdt(tables->table_data->buf, tables->linker, table_offsets);
 
     /* RSDP is in FSEG memory, so allocate it separately */
     build_rsdp(tables->rsdp, tables->linker, rsdt);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 09/13] acpi: add aml_blob() helper
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (7 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 08/13] i386: acpi: hack not yet converted tables calls to deal with table_data being a pointer Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 10/13] i386: acpi: add DSDT table using AML API Igor Mammedov
                                                 ` (4 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

it will help to add external (user provided) tables
into ACPI tables blob.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 8 ++++++++
 include/hw/acpi/acpi-build-utils.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index bffad1e..41341a4 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -926,6 +926,14 @@ AcpiAml *acpi_def_block(const char *signature, uint8_t revision,
     return var;
 }
 
+AcpiAml *aml_blob(const unsigned char *data, int size)
+{
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+
+    g_array_append_vals(var->buf, data, size);
+    return var;
+}
+
 static void aml_object_initfn(Object *obj) {
     AcpiAml *aml = AML_OBJECT(obj);
 
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index b2d023e..f36e23a 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -194,6 +194,8 @@ AcpiAml *acpi_field(const char *name, acpiFieldFlags flags);
 AcpiAml *acpi_varpackage(uint32_t num_elements);
 
 /* other helpers */
+AcpiAml *aml_blob(const unsigned char *data, int size);
+
 GArray *build_alloc_array(void);
 void build_free_array(GArray *array);
 void build_prepend_byte(GArray *array, uint8_t val);
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 10/13] i386: acpi: add DSDT table using AML API
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (8 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 09/13] acpi: add aml_blob() helper Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 11/13] acpi: acpi_add_table() to common cross target file Igor Mammedov
                                                 ` (3 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index bac0156..c8e38ff 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1206,18 +1206,16 @@ build_dmar_q35(GArray *table_data, GArray *linker)
 }
 
 static void
-build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
+build_dsdt(AcpiAml *table_data, AcpiMiscInfo *misc)
 {
-    AcpiTableHeader *dsdt;
+    AcpiAml *dsdt =
+        acpi_def_block("DSDT", 1, ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4, 1);
 
     assert(misc->dsdt_code && misc->dsdt_size);
+    aml_append(dsdt, aml_blob(misc->dsdt_code + sizeof(AcpiTableHeader),
+                              misc->dsdt_size - sizeof(AcpiTableHeader)));
 
-    dsdt = acpi_data_push(table_data, misc->dsdt_size);
-    memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
-
-    memset(dsdt, 0, sizeof *dsdt);
-    build_header(linker, table_data, dsdt, "DSDT",
-                 misc->dsdt_size, 1);
+    aml_append(table_data, dsdt);
 }
 
 /* Build final rsdt table */
@@ -1375,7 +1373,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
 
     /* DSDT is pointed to by FADT */
     dsdt = tables->table_data->buf->len;
-    build_dsdt(tables->table_data->buf, tables->linker, &misc);
+    build_dsdt(tables->table_data, &misc);
 
     /* Count the size of the DSDT and SSDT, we will need it for legacy
      * sizing of ACPI tables.
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 11/13] acpi: acpi_add_table() to common cross target file
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (9 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 10/13] i386: acpi: add DSDT table using AML API Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 12/13] acpi: prepare for API internal collection of RSDT entries Igor Mammedov
                                                 ` (2 subsequent siblings)
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 6 ++++++
 hw/i386/acpi-build.c               | 6 ------
 include/hw/acpi/acpi-build-utils.h | 1 +
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 41341a4..fe598ff 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -29,6 +29,12 @@
 #include "hw/acpi/bios-linker-loader.h"
 #include "qemu/module.h"
 
+void acpi_add_table(GArray *table_offsets, GArray *table_data)
+{
+    uint32_t offset = cpu_to_le32(table_data->len);
+    g_array_append_val(table_offsets, offset);
+}
+
 GArray *build_alloc_array(void)
 {
     return g_array_new(false, true /* clear */, 1);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index c8e38ff..d923ac2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -312,12 +312,6 @@ static void acpi_align_size(GArray *blob, unsigned align)
     g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
 }
 
-static inline void acpi_add_table(GArray *table_offsets, GArray *table_data)
-{
-    uint32_t offset = cpu_to_le32(table_data->len);
-    g_array_append_val(table_offsets, offset);
-}
-
 /* FACS */
 static void
 build_facs(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index f36e23a..4bbe6b5 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -211,5 +211,6 @@ void build_package(GArray *package, uint8_t op);
 void build_append_value(GArray *table, uint64_t value, int size);
 void build_append_int(GArray *table, uint64_t value);
 void build_extop_package(GArray *package, uint8_t op);
+void acpi_add_table(GArray *table_offsets, GArray *table_data);
 
 #endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 12/13] acpi: prepare for API internal collection of RSDT entries
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (10 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 11/13] acpi: acpi_add_table() to common cross target file Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 13/13] i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT automatically Igor Mammedov
  2015-01-28 12:44                               ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Andrew Jones
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/acpi-build-utils.c         | 19 +++++++++++++++++++
 hw/i386/acpi-build.c               | 16 ++++++++++------
 include/hw/acpi/acpi-build-utils.h |  2 ++
 3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index fe598ff..ae62da6 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -328,6 +328,10 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
         uint32_t le32_len = cpu_to_le32(child->buf->len);
         AcpiAmlTablesBlob *tables_blob = AML_TABLES_BLOB(parent_ctx);
 
+        if (child->has_rsdt_entry) {
+           acpi_add_table(tables_blob->rsdt_entries, parent_ctx->buf);
+        }
+
         /* create linker entry for the DefinitionBlock */
         bios_linker_loader_add_checksum(tables_blob->linker,
             ACPI_BUILD_TABLE_FILE,
@@ -963,10 +967,25 @@ static const TypeInfo aml_object_type_info = {
     .class_size = sizeof(AcpiAmlClass),
 };
 
+static void aml_tables_blob_initfn(Object *obj) {
+     AcpiAmlTablesBlob *tbobj = AML_TABLES_BLOB(obj);
+
+     tbobj->rsdt_entries = g_array_new(false, true /* clear */,
+                                       sizeof(uint32_t));
+}
+
+static void aml_tables_blob_finalize(Object *obj) {
+     AcpiAmlTablesBlob *tbobj = AML_TABLES_BLOB(obj);
+
+     g_array_free(tbobj->rsdt_entries, true);
+}
+
 static const TypeInfo aml_tables_blob_type_info = {
     .name = TYPE_AML_TABLES_BLOB,
     .parent = TYPE_AML_OBJECT,
     .instance_size = sizeof(AcpiAmlTablesBlob),
+    .instance_init = aml_tables_blob_initfn,
+    .instance_finalize = aml_tables_blob_finalize,
     .abstract = false,
     .class_size = sizeof(AcpiAmlTablesBlobClass),
 };
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d923ac2..d7d2590 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1270,11 +1270,17 @@ struct AcpiBuildTables {
 
 static inline void acpi_build_tables_init(AcpiBuildTables *tables)
 {
+    AcpiAmlTablesBlob *tables_blob_obj;
+
     tables->rsdp = g_array_new(false, true /* clear */, 1);
+    tables->table_data = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     tables->tcpalog = g_array_new(false, true /* clear */, 1);
     tables->linker = bios_linker_loader_init();
     tables->table_data = AML_OBJECT(object_new(TYPE_AML_TABLES_BLOB));
-    AML_TABLES_BLOB(tables->table_data)->linker = tables->linker;
+    tables_blob_obj = AML_TABLES_BLOB(tables->table_data);
+    tables_blob_obj->linker = tables->linker;
+    tables_blob_obj->rsdt_entries = g_array_new(false, true /* clear */,
+                                                sizeof(uint32_t));
 }
 
 static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
@@ -1282,6 +1288,8 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
     void *linker_data = bios_linker_loader_cleanup(tables->linker);
     g_free(linker_data);
     g_array_free(tables->rsdp, mfre);
+
+    /* Cleanup memory that's no longer used. */
     object_unref(OBJECT(tables->table_data));
     g_array_free(tables->tcpalog, mfre);
 }
@@ -1349,8 +1357,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
     acpi_get_misc_info(&misc);
     acpi_get_pci_info(&pci);
 
-    table_offsets = g_array_new(false, true /* clear */,
-                                        sizeof(uint32_t));
+    table_offsets = AML_TABLES_BLOB(tables->table_data)->rsdt_entries;
     ACPI_BUILD_DPRINTF("init ACPI tables\n");
 
     bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
@@ -1473,9 +1480,6 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
     }
 
     acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
-
-    /* Cleanup memory that's no longer used. */
-    g_array_free(table_offsets, true);
 }
 
 static void acpi_build_update(void *build_opaque, uint32_t offset)
diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
index 4bbe6b5..6a0c9a1 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -30,6 +30,7 @@ typedef struct AcpiAml {
     GArray *buf;
     uint8_t op;
     AcpiBlockFlags block_flags;
+    bool has_rsdt_entry;
 } AcpiAml;
 
 typedef struct AcpiAmlClass {
@@ -46,6 +47,7 @@ typedef struct AcpiAmlClass {
 typedef struct AcpiAmlTablesBlob {
     AcpiAml parent_obj;
     GArray *linker;
+    GArray *rsdt_entries;
 } AcpiAmlTablesBlob;
 
 typedef struct AcpiAmlTablesBlobClass {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 13/13] i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT automatically
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (11 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 12/13] acpi: prepare for API internal collection of RSDT entries Igor Mammedov
@ 2015-01-28 10:03                               ` Igor Mammedov
  2015-01-28 12:44                               ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Andrew Jones
  13 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, drjones, zhaoshenglong, claudio.fontana, marcel.a

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d7d2590..da259aa 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -649,6 +649,7 @@ build_ssdt(AcpiAml *table_aml, GArray *linker,
     /* Init SSDT Definition Block */
     ssdt =
         acpi_def_block("SSDT", 1, ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4, 1);
+    ssdt->has_rsdt_entry = true;
 
     scope = acpi_scope("\\_SB.PCI0");
     /* build PCI0._CRS */
@@ -1386,7 +1387,6 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
     build_fadt(tables->table_data->buf, tables->linker, &pm, facs, dsdt);
 
     ssdt = tables->table_data->buf->len;
-    acpi_add_table(table_offsets, tables->table_data->buf);
     build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
                guest_info);
     aml_len += tables->table_data->buf->len - ssdt;
-- 
1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API
  2015-01-28  7:38 ` [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Michael S. Tsirkin
@ 2015-01-28 10:07   ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:07 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Wed, 28 Jan 2015 09:38:27 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Jan 22, 2015 at 02:49:44PM +0000, Igor Mammedov wrote:
> > Git tree for playing with:
> >     https://github.com/imammedo/qemu/commits/ASL_API_v2
> > 
> > Igor Mammedov (47):
> >   acpi: introduce AML composer aml_append()
> >   acpi: add acpi_scope() term
> >   acpi: add acpi_device() term
> >   acpi: add acpi_method() term
> >   acpi: add acpi_if() term
> >   acpi: add acpi_name() & acpi_name_decl() term
> >   acpi: factor out ACPI const int packing out build_append_value()
> >   acpi: extend build_append_{value|int}() to support 64-bit values
> >   acpi: add acpi_int() term
> >   acpi: add acpi_return() term
> >   acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms
> >   acpi: add acpi_store() term
> >   acpi: add acpi_and() term
> >   acpi: add acpi_notify() term
> >   acpi: add acpi_call1(), acpi_call2(), acpi_call3(), acpi_call4()
> >     helpers
> >   pc: acpi-build: drop template patching and create PCI bus tree
> >     dynamically
> >   acpi: add acpi_package() term
> >   pc: acpi-build: drop unsupported PM1b_CNT.SLP_TYP
> >   pc: acpi-build: generate _S[345] packages dynamically
> >   acpi: add acpi_buffer() term
> >   acpi: add acpi_resource_template() helper
> >   acpi: add acpi_io() helper
> >   acpi: include PkgLength size only when requested
> >   acpi: add acpi_operation_region() term
> >   acpi: add acpi_field() & acpi_named_field() terms
> >   acpi: add acpi_local0() term
> >   acpi: add acpi_string() term
> >   pc: acpi-build: generate pvpanic device description dynamically
> >   acpi: add acpi_varpackage() term
> >   acpi: add acpi_equal() term
> >   acpi: add acpi_processor() term
> >   acpi: add acpi_eisaid() term
> >   pc: acpi-build: drop template patching and CPU hotplug objects
> >     dynamically
> >   pc: acpi-build: create CPU hotplug IO region dynamically
> >   acpi: add acpi_reserved_field() term
> >   pc: acpi-build: drop template patching and memory hotplug objects
> >     dynamically
> >   pc: acpi-build: create memory hotplug IO region dynamically
> >   acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(),
> >     acpi_qword_memory() terms
> >   pc: pcihp: expose MMIO base and len as properties
> >   pc: acpi-build: reserve PCIHP MMIO resources
> >   pc: acpi-build: create PCI0._CRS dynamically
> >   acpi: add acpi_def_block() term
> >   pc: acpi-build: prepare to make ACPI tables blob opaque for table
> >     building functions
> >   pc: acpi-build: drop remaining ssdt_misc template and use
> >     acpi_def_block()
> >   acpi: add acpi_iqr_no_flags() term
> >   pc: export applesmc IO port/len
> >   pc: acpi-build: drop template patching and create Device(SMC)
> >     dynamically
> 
> 
> Looking at the patch list, I think it's not split optimally:
> a single patch adding all of the helpers will be easier to
> work with, and won't be harder to review I think.
small helper patches help with incremental review, but I did them
so that they are totally squash-able once they are reviewed into
the big one without any patch ordering issues.

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

* Re: [Qemu-devel] [PATCH 03/13] qom: add support for weak referenced object: aka UnownedObject
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 03/13] qom: add support for weak referenced object: aka UnownedObject Igor Mammedov
@ 2015-01-28 10:09                                 ` Paolo Bonzini
  2015-01-28 12:55                                   ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Paolo Bonzini @ 2015-01-28 10:09 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: drjones, zhaoshenglong, claudio.fontana, marcel.a



On 28/01/2015 11:03, Igor Mammedov wrote:
> it adds support for weak reference model used by glib's
> GInitiallyUnowned to QEMU's QOM model.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  include/qom/object.h | 20 ++++++++++++++++++++
>  qom/object.c         | 20 +++++++++++++++++++-
>  2 files changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 89c3092..e0e4cc8 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -1314,5 +1314,25 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
>   */
>  Object *container_get(Object *root, const char *path);
>  
> +#define TYPE_UNOWNED_OBJECT "unowned-object"
> +#define UNOWNED_OBJECT(obj) \
> +     OBJECT_CHECK(UnownedObject, (obj), TYPE_UNOWNED_OBJECT)
> +#define UNOWNED_OBJECT_CLASS(klass) \
> +     OBJECT_CLASS_CHECK(UnownedObjectClass, (klass), TYPE_UNOWNED_OBJECT)
> +#define UNOWNED_OBJECT_GET_CLASS \
> +     OBJECT_GET_CLASS(UnownedObjectClass, (obj), TYPE_UNOWNED_OBJECT)
> +#define OBJECT_WEAK_REF (1UL << 31)
> +
> +typedef struct UnownedObjectClass
> +{
> +    /*< private >*/
> +    ObjectClass parent_class;
> +} UnownedObjectClass;
> +
> +typedef struct UnownedObject
> +{
> +    /*< private >*/
> +    Object parent_obj;
> +} UnownedObject;
>  
>  #endif
> diff --git a/qom/object.c b/qom/object.c
> index 1812c73..96842c7 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -705,6 +705,10 @@ void object_ref(Object *obj)
>      if (!obj) {
>          return;
>      }
> +    if (atomic_fetch_and(&obj->ref, ~OBJECT_WEAK_REF) & OBJECT_WEAK_REF)

Please first do a non-atomic test, since this is unlikely to happen but
atomic_fetch_and is quite expensive (it compiles into a cmpxchg loop).

Paolo

> +    {
> +        return;
> +    }
>       atomic_inc(&obj->ref);
>  }
>  
> @@ -713,7 +717,7 @@ void object_unref(Object *obj)
>      if (!obj) {
>          return;
>      }
> -    g_assert(obj->ref > 0);
> +    g_assert((obj->ref & ~OBJECT_WEAK_REF) > 0);
>  
>      /* parent always holds a reference to its children */
>      if (atomic_fetch_dec(&obj->ref) == 1) {
> @@ -1709,6 +1713,12 @@ static void object_instance_init(Object *obj)
>      object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
>  }
>  
> +
> +static void unowned_object_instance_init(Object *obj)
> +{
> +    obj->ref |= OBJECT_WEAK_REF;
> +}
> +
>  static void register_types(void)
>  {
>      static TypeInfo interface_info = {
> @@ -1724,8 +1734,16 @@ static void register_types(void)
>          .abstract = true,
>      };
>  
> +    static TypeInfo unowned_object_info = {
> +        .name = TYPE_UNOWNED_OBJECT,
> +        .instance_size = sizeof(UnownedObject),
> +        .instance_init = unowned_object_instance_init,
> +        .abstract = true,
> +    };
> +
>      type_interface = type_register_internal(&interface_info);
>      type_register_internal(&object_info);
> +    type_register_internal(&unowned_object_info);
>  }
>  
>  type_init(register_types)
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28 10:00                             ` Igor Mammedov
@ 2015-01-28 10:24                               ` Michael S. Tsirkin
  2015-01-28 10:50                                 ` Igor Mammedov
  2015-01-28 10:32                               ` Claudio Fontana
                                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-28 10:24 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Andrew Jones, marcel.a, claudio.fontana, qemu-devel,
	Shannon Zhao, pbonzini

On Wed, Jan 28, 2015 at 11:00:23AM +0100, Igor Mammedov wrote:
> On Wed, 28 Jan 2015 09:56:26 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > > I've tried redo series with passing alloc list as first argument,
> > > looks ugly as hell
> > 
> > I tried too. Not too bad at all. See below:
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index f66da5d..820504a 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
> >      }
> >  }
> >  
> > -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> > +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
> >  {
> > -    AcpiAml if_ctx;
> > +    AcpiAml *if_ctx;
> >      int32_t devfn = PCI_DEVFN(slot, 0);
> >  
> > -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> > -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
> > -    aml_append(method, if_ctx);
> > +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
> > +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
> > +    aml_append(p, method, if_ctx);
> >  }
> >  
> >  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
> > 
> > What exactly is the problem?  A tiny bit more verbose but the lifetime
> > of all objects is now explicit.
> every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
> extra pointer which is not really necessary for user to know.

It's necessary to make memory management explicit. Consider:

alloc_pool();
acpi_arg0();
free_pool();
acpi_arg1();

Looks ok but isn't because acpi_arg1 silently allocates memory.

p = alloc_pool();
acpi_arg0(p);
free_pool(p);
acpi_arg1(p);

It's obvious what's wrong here: p is used after it's freed.

Come on, it's 3 characters per call.  I think it's a reasonable
compromize.

-- 
MST

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28 10:00                             ` Igor Mammedov
  2015-01-28 10:24                               ` Michael S. Tsirkin
@ 2015-01-28 10:32                               ` Claudio Fontana
  2015-01-29  7:46                               ` Shannon Zhao
  2015-02-05 14:35                               ` Marcel Apfelbaum
  3 siblings, 0 replies; 128+ messages in thread
From: Claudio Fontana @ 2015-01-28 10:32 UTC (permalink / raw)
  To: Igor Mammedov, Michael S. Tsirkin
  Cc: pbonzini, Andrew Jones, Shannon Zhao, qemu-devel, marcel.a

Hello Igor,

It's quite difficult to understand all the different options, there have been quite a few flying around.
I'll comment this mail in particular, ignoring for the moment all the other exchanges
(about QOM etc).

On 28.01.2015 11:00, Igor Mammedov wrote:
> On Wed, 28 Jan 2015 09:56:26 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
>>> I've tried redo series with passing alloc list as first argument,
>>> looks ugly as hell
>>
>> I tried too. Not too bad at all. See below:
>>
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index f66da5d..820504a 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
>>      }
>>  }
>>  
>> -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
>> +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
>>  {
>> -    AcpiAml if_ctx;
>> +    AcpiAml *if_ctx;
>>      int32_t devfn = PCI_DEVFN(slot, 0);
>>  
>> -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
>> -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
>> -    aml_append(method, if_ctx);
>> +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
>> +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
>> +    aml_append(p, method, if_ctx);
>>  }
>>  
>>  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
>>
>> What exactly is the problem?  A tiny bit more verbose but the lifetime
>> of all objects is now explicit.

I think both options are ok.
The extra parameter is just basically passed around if I understand correctly, that doesn't seem terrible.

> every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
> extra pointer which is not really necessary for user to know. If possible
> user shouldn't care about it and concentrate on composing AML instead.
> 
> Whole point of passing AmlPool and record every allocation is to avoid
> mistakes like:
> 
> acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> 
> and forgetting to assign object returned by call anywhere,
> it's basically the same as calling malloc() without
> using result anywhere, however neither libc nor glib
> force user to pass allocator (in our case garbage collector)
> in every call that allocates memory. Let's just follow common
> convention here (#4) where an object is allocated by API call
> (i.e like object_new(FOO), gtk_widget_foo()).
> 
> Hence is suggesting at least to hide AmlPool internally in API
> without exposing it to user. We can provide for user
> init/free API to manage internal AmlPool manually, allowing
> him to select when to do initialization and cleanup.
> 
> Claudio, Marcel, Shannon,
> As the first API users, could you give your feedback on the topic.
> 

Personally I find as mentioned both options ok.

Your (Igor's) proposal "looks better" when staring at the code which uses the API,
Michael's suggestion is to avoid any confusion around when an object is allocated / freed, and that's a valid point.

Sorry for being so neutral, but really both options seem to have their merits and both seem substantially fine to me.

Ciao,

Claudio

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28  7:56                           ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Michael S. Tsirkin
  2015-01-28 10:00                             ` Igor Mammedov
@ 2015-01-28 10:45                             ` Andrew Jones
  2015-02-05 14:30                             ` Marcel Apfelbaum
  2 siblings, 0 replies; 128+ messages in thread
From: Andrew Jones @ 2015-01-28 10:45 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Igor Mammedov, marcel.a, claudio.fontana, qemu-devel, pbonzini

On Wed, Jan 28, 2015 at 09:56:26AM +0200, Michael S. Tsirkin wrote:
> > I've tried redo series with passing alloc list as first argument,
> > looks ugly as hell
> 
> I tried too. Not too bad at all. See below:

I'm not so sure. Looking at the version below, I find the
acpi_arg1(p) the most distracting. That API call creates
the simplest object, so should be the simplest looking. Actually,
you suggested that acpi_arg1(), a wrapper to make things look
even simpler, wasn't necessary, acpi_arg(1) would be fine. I
agree with that, but now we'd have acpi_arg(p, 1), which is
really starting to clutter an AML composition built with many
such calls.

> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index f66da5d..820504a 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
>      }
>  }
>  
> -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
>  {
> -    AcpiAml if_ctx;
> +    AcpiAml *if_ctx;
>      int32_t devfn = PCI_DEVFN(slot, 0);
>  
> -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
> -    aml_append(method, if_ctx);
> +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
                                                ^ forgot your p here
> +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
> +    aml_append(p, method, if_ctx);
>  }
>  
>  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
> 
> What exactly is the problem?  A tiny bit more verbose but the lifetime
> of all objects is now explicit.

It's probably just a personal preference thing. Igor and I prefer the
sequence of AML composing calls to appear as simple as possible, i.e.
develop the cleanest API as possible. To do this we need to find ways
to hide the memory management, which comes at a cost of using a model
that supports garbage collection, or adding a global variable to hide
the pool. Your preference appears to be to keep memory management as
simple and explicit as possible, at the expense of peppering each AML
build function with a bunch of 'p's. I agree with Igor that we should
get votes from the initial consumers of this API.

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28 10:24                               ` Michael S. Tsirkin
@ 2015-01-28 10:50                                 ` Igor Mammedov
  2015-01-28 13:12                                   ` Michael S. Tsirkin
  0 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 10:50 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Andrew Jones, marcel.a, claudio.fontana, qemu-devel,
	Shannon Zhao, pbonzini

On Wed, 28 Jan 2015 12:24:23 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, Jan 28, 2015 at 11:00:23AM +0100, Igor Mammedov wrote:
> > On Wed, 28 Jan 2015 09:56:26 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > > I've tried redo series with passing alloc list as first argument,
> > > > looks ugly as hell
> > > 
> > > I tried too. Not too bad at all. See below:
> > > 
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index f66da5d..820504a 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
> > >      }
> > >  }
> > >  
> > > -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> > > +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
> > >  {
> > > -    AcpiAml if_ctx;
> > > +    AcpiAml *if_ctx;
> > >      int32_t devfn = PCI_DEVFN(slot, 0);
> > >  
> > > -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> > > -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
> > > -    aml_append(method, if_ctx);
> > > +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
> > > +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
> > > +    aml_append(p, method, if_ctx);
> > >  }
> > >  
> > >  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
> > > 
> > > What exactly is the problem?  A tiny bit more verbose but the lifetime
> > > of all objects is now explicit.
> > every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
> > extra pointer which is not really necessary for user to know.
> 
> It's necessary to make memory management explicit. Consider:
> 
> alloc_pool();
> acpi_arg0();
> free_pool();
> acpi_arg1();
> 
> Looks ok but isn't because acpi_arg1 silently allocates memory.
with pool hidden inside API, acpi_arg1() would crash
when accessing freed pool.

> p = alloc_pool();
> acpi_arg0(p);
> free_pool(p);
> acpi_arg1(p);
> 
> It's obvious what's wrong here: p is used after it's freed.
it's just like above but more verbose with the same end result.
 
> Come on, it's 3 characters per call.  I think it's a reasonable
> compromize.
That characters will spread over all API usage and I don't really
wish to invent garbage collection and then rewrite everything
to a cleaner API afterwards.
I admit that internal global pool is not the best thing,
but that would be reasonable compromise to still get garbage
collection without polluting API.
Otherwise lets use common pattern and go QOM way, which also takes
care about use-after-free concern but lacks garbage collector.

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

* Re: [Qemu-devel] [PATCH v2 45/47] acpi: add acpi_iqr_no_flags() term
  2015-01-27 15:37   ` Claudio Fontana
@ 2015-01-28 12:15     ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 12:15 UTC (permalink / raw)
  To: Claudio Fontana; +Cc: pbonzini, drjones, mst, qemu-devel, marcel.a

On Tue, 27 Jan 2015 16:37:45 +0100
Claudio Fontana <claudio.fontana@huawei.com> wrote:

> Hi,
> 
> I think you have to replace "iqr" with "irq" in the function definition and in the commit message.
sure, I'll fix it.

> 
> Ciao,
> 
> Claudio
> 
> On 22.01.2015 15:50, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/acpi/acpi-build-utils.c         | 18 ++++++++++++++++++
> >  include/hw/acpi/acpi-build-utils.h |  1 +
> >  2 files changed, 19 insertions(+)
> > 
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 58f88cd..59873e3 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -511,6 +511,24 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> >      return var;
> >  }
> >  
> > +/*
> > + * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
> > + *           6.4.2.1 IRQ Descriptor
> > +*/
> > +AcpiAml acpi_iqr_no_flags(uint8_t irq)
> > +{
> > +    uint16_t irq_mask;
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    assert(irq < 16);
> > +    build_append_byte(var.buf, 0x22); /* IRQ descriptor 2 byte form */
> > +
> > +    irq_mask = 1U << irq;
> > +    build_append_byte(var.buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
> > +    build_append_byte(var.buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
> > +    return var;
> > +}
> > +
> >  /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
> >  AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2)
> >  {
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 868d439..d39b5b1 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -117,6 +117,7 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
> >                     AcpiAml arg3, AcpiAml arg4);
> >  AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> >                  uint8_t aln, uint8_t len);
> > +AcpiAml acpi_iqr_no_flags(uint8_t irq);
> >  AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
> >                                uint32_t offset, uint32_t len);
> >  AcpiAml acpi_named_field(const char *name, unsigned length);
> > 
> 
> 
> 

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

* Re: [Qemu-devel] [PATCH 00/13] convert AML API to QOM
  2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
                                                 ` (12 preceding siblings ...)
  2015-01-28 10:03                               ` [Qemu-devel] [PATCH 13/13] i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT automatically Igor Mammedov
@ 2015-01-28 12:44                               ` Andrew Jones
  2015-02-05 14:28                                 ` Marcel Apfelbaum
  13 siblings, 1 reply; 128+ messages in thread
From: Andrew Jones @ 2015-01-28 12:44 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: pbonzini, zhaoshenglong, claudio.fontana, qemu-devel, marcel.a

On Wed, Jan 28, 2015 at 10:03:24AM +0000, Igor Mammedov wrote:
> 
> Example demonstrates use of QOM object for building AML
> objects tree and freeing it explicitly when requested.
> 
> Top level ACPI tables blob object is only partially
> switched to object model now but I hope it demostrates
> the point of absracting code and hiding parts of code
> that could be done without user intervention.
> 
> Pathes 1/2/8 are just a convertion boiler plate which
> will go away on respin.
> 
> 
> Igor Mammedov (13):
>   convert to passing AcpiAml by pointers
>   make toplevel ACPI tables blob a pointer
>   qom: add support for weak referenced object: aka UnownedObject
>   acpi: make AcpiAml an OQM object
>   acpi: use TYPE_AML_OBJECT inside of AML API
>   acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob
>   acpi: make toplevel ACPI tables blob a dedicated object
>   i386: acpi: hack not yet converted tables calls to deal with
>     table_data being a pointer
>   acpi: add aml_blob() helper
>   i386: acpi: add DSDT table using AML API
>   acpi: acpi_add_table() to common cross target file
>   acpi: prepare for API internal collection of RSDT entries
>   i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT
>     automatically
> 
>  hw/acpi/acpi-build-utils.c         | 537 +++++++++++++++++++++----------------
>  hw/i386/acpi-build.c               | 388 +++++++++++++--------------
>  include/hw/acpi/acpi-build-utils.h | 119 +++++---
>  include/qom/object.h               |  20 ++
>  qom/object.c                       |  20 +-
>  5 files changed, 620 insertions(+), 464 deletions(-)
> 
> -- 
> 1.8.3.1
>

Thanks for doing this. It's satisfied my curiosity as to how
much boilerplate we'd need for the conversion. I looked mainly
at the first half of this series, as it appears the second half
is an add-on, not directly relevant to the explicit memory
management vs. object model memory management discussion. The
additional code, and need for QOM knowledge, appears pretty low.
So, as this would allow developers focused on ACPI table
construction to almost completely avoid doing any memory
management themselves, then, FWIW, it looks like a good trade
off to me.

drew

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

* Re: [Qemu-devel] [PATCH 03/13] qom: add support for weak referenced object: aka UnownedObject
  2015-01-28 10:09                                 ` Paolo Bonzini
@ 2015-01-28 12:55                                   ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-28 12:55 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: drjones, zhaoshenglong, claudio.fontana, qemu-devel, marcel.a

On Wed, 28 Jan 2015 11:09:22 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> 
> 
> On 28/01/2015 11:03, Igor Mammedov wrote:
> > it adds support for weak reference model used by glib's
> > GInitiallyUnowned to QEMU's QOM model.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  include/qom/object.h | 20 ++++++++++++++++++++
> >  qom/object.c         | 20 +++++++++++++++++++-
> >  2 files changed, 39 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/qom/object.h b/include/qom/object.h
> > index 89c3092..e0e4cc8 100644
> > --- a/include/qom/object.h
> > +++ b/include/qom/object.h
> > @@ -1314,5 +1314,25 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
> >   */
> >  Object *container_get(Object *root, const char *path);
> >  
> > +#define TYPE_UNOWNED_OBJECT "unowned-object"
> > +#define UNOWNED_OBJECT(obj) \
> > +     OBJECT_CHECK(UnownedObject, (obj), TYPE_UNOWNED_OBJECT)
> > +#define UNOWNED_OBJECT_CLASS(klass) \
> > +     OBJECT_CLASS_CHECK(UnownedObjectClass, (klass), TYPE_UNOWNED_OBJECT)
> > +#define UNOWNED_OBJECT_GET_CLASS \
> > +     OBJECT_GET_CLASS(UnownedObjectClass, (obj), TYPE_UNOWNED_OBJECT)
> > +#define OBJECT_WEAK_REF (1UL << 31)
> > +
> > +typedef struct UnownedObjectClass
> > +{
> > +    /*< private >*/
> > +    ObjectClass parent_class;
> > +} UnownedObjectClass;
> > +
> > +typedef struct UnownedObject
> > +{
> > +    /*< private >*/
> > +    Object parent_obj;
> > +} UnownedObject;
> >  
> >  #endif
> > diff --git a/qom/object.c b/qom/object.c
> > index 1812c73..96842c7 100644
> > --- a/qom/object.c
> > +++ b/qom/object.c
> > @@ -705,6 +705,10 @@ void object_ref(Object *obj)
> >      if (!obj) {
> >          return;
> >      }
> > +    if (atomic_fetch_and(&obj->ref, ~OBJECT_WEAK_REF) & OBJECT_WEAK_REF)
> 
> Please first do a non-atomic test, since this is unlikely to happen but
> atomic_fetch_and is quite expensive (it compiles into a cmpxchg loop).
sure

> 
> Paolo
> 
> > +    {
> > +        return;
> > +    }
> >       atomic_inc(&obj->ref);
> >  }
> >  
> > @@ -713,7 +717,7 @@ void object_unref(Object *obj)
> >      if (!obj) {
> >          return;
> >      }
> > -    g_assert(obj->ref > 0);
> > +    g_assert((obj->ref & ~OBJECT_WEAK_REF) > 0);
> >  
> >      /* parent always holds a reference to its children */
> >      if (atomic_fetch_dec(&obj->ref) == 1) {
> > @@ -1709,6 +1713,12 @@ static void object_instance_init(Object *obj)
> >      object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
> >  }
> >  
> > +
> > +static void unowned_object_instance_init(Object *obj)
> > +{
> > +    obj->ref |= OBJECT_WEAK_REF;
> > +}
> > +
> >  static void register_types(void)
> >  {
> >      static TypeInfo interface_info = {
> > @@ -1724,8 +1734,16 @@ static void register_types(void)
> >          .abstract = true,
> >      };
> >  
> > +    static TypeInfo unowned_object_info = {
> > +        .name = TYPE_UNOWNED_OBJECT,
> > +        .instance_size = sizeof(UnownedObject),
> > +        .instance_init = unowned_object_instance_init,
> > +        .abstract = true,
> > +    };
> > +
> >      type_interface = type_register_internal(&interface_info);
> >      type_register_internal(&object_info);
> > +    type_register_internal(&unowned_object_info);
> >  }
> >  
> >  type_init(register_types)
> > 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28 10:50                                 ` Igor Mammedov
@ 2015-01-28 13:12                                   ` Michael S. Tsirkin
  0 siblings, 0 replies; 128+ messages in thread
From: Michael S. Tsirkin @ 2015-01-28 13:12 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Andrew Jones, marcel.a, claudio.fontana, qemu-devel,
	Shannon Zhao, pbonzini

On Wed, Jan 28, 2015 at 11:50:14AM +0100, Igor Mammedov wrote:
> On Wed, 28 Jan 2015 12:24:23 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, Jan 28, 2015 at 11:00:23AM +0100, Igor Mammedov wrote:
> > > On Wed, 28 Jan 2015 09:56:26 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > > I've tried redo series with passing alloc list as first argument,
> > > > > looks ugly as hell
> > > > 
> > > > I tried too. Not too bad at all. See below:
> > > > 
> > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > index f66da5d..820504a 100644
> > > > --- a/hw/i386/acpi-build.c
> > > > +++ b/hw/i386/acpi-build.c
> > > > @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
> > > >      }
> > > >  }
> > > >  
> > > > -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> > > > +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
> > > >  {
> > > > -    AcpiAml if_ctx;
> > > > +    AcpiAml *if_ctx;
> > > >      int32_t devfn = PCI_DEVFN(slot, 0);
> > > >  
> > > > -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> > > > -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
> > > > -    aml_append(method, if_ctx);
> > > > +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
> > > > +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
> > > > +    aml_append(p, method, if_ctx);
> > > >  }
> > > >  
> > > >  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
> > > > 
> > > > What exactly is the problem?  A tiny bit more verbose but the lifetime
> > > > of all objects is now explicit.
> > > every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
> > > extra pointer which is not really necessary for user to know.
> > 
> > It's necessary to make memory management explicit. Consider:
> > 
> > alloc_pool();
> > acpi_arg0();
> > free_pool();
> > acpi_arg1();
> > 
> > Looks ok but isn't because acpi_arg1 silently allocates memory.
> with pool hidden inside API, acpi_arg1() would crash
> when accessing freed pool.
> > p = alloc_pool();
> > acpi_arg0(p);
> > free_pool(p);
> > acpi_arg1(p);
> > 
> > It's obvious what's wrong here: p is used after it's freed.
> it's just like above but more verbose with the same end result.
>
> > Come on, it's 3 characters per call.  I think it's a reasonable
> > compromize.
> That characters will spread over all API usage and I don't really
> wish to invent garbage collection and then rewrite everything
> to a cleaner API afterwards.

If the cleaner API is just a removed parameter, a single sparse
patch will do it automatically.
Something like the following:

identifier func;
identifier call;
@@

-func(AmlPool *p, ...)
+func(...)
{
-call(p, ...)
+call(...)
}

> I admit that internal global pool is not the best thing,
> but that would be reasonable compromise to still get garbage
> collection without polluting API.

The issue is lifetime of objects being implicit in the API,
it doesn't look like a global pool fixes that.


> Otherwise lets use common pattern and go QOM way, which also takes
> care about use-after-free concern but lacks garbage collector.

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28 10:00                             ` Igor Mammedov
  2015-01-28 10:24                               ` Michael S. Tsirkin
  2015-01-28 10:32                               ` Claudio Fontana
@ 2015-01-29  7:46                               ` Shannon Zhao
  2015-01-29  8:42                                 ` Igor Mammedov
  2015-02-05 14:35                               ` Marcel Apfelbaum
  3 siblings, 1 reply; 128+ messages in thread
From: Shannon Zhao @ 2015-01-29  7:46 UTC (permalink / raw)
  To: Igor Mammedov, Michael S. Tsirkin
  Cc: pbonzini, Andrew Jones, claudio.fontana, qemu-devel, marcel.a

On 2015/1/28 18:00, Igor Mammedov wrote:
> On Wed, 28 Jan 2015 09:56:26 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
>>> I've tried redo series with passing alloc list as first argument,
>>> looks ugly as hell
>>
>> I tried too. Not too bad at all. See below:
>>
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index f66da5d..820504a 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
>>      }
>>  }
>>  
>> -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
>> +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
>>  {
>> -    AcpiAml if_ctx;
>> +    AcpiAml *if_ctx;
>>      int32_t devfn = PCI_DEVFN(slot, 0);
>>  
>> -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
>> -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
>> -    aml_append(method, if_ctx);
>> +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
>> +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
>> +    aml_append(p, method, if_ctx);
>>  }
>>  
>>  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
>>
>> What exactly is the problem?  A tiny bit more verbose but the lifetime
>> of all objects is now explicit.
> every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
> extra pointer which is not really necessary for user to know. If possible
> user shouldn't care about it and concentrate on composing AML instead.
> 
> Whole point of passing AmlPool and record every allocation is to avoid
> mistakes like:
> 
> acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> 
> and forgetting to assign object returned by call anywhere,
> it's basically the same as calling malloc() without
> using result anywhere, however neither libc nor glib
> force user to pass allocator (in our case garbage collector)
> in every call that allocates memory. Let's just follow common
> convention here (#4) where an object is allocated by API call
> (i.e like object_new(FOO), gtk_widget_foo()).
> 
> Hence is suggesting at least to hide AmlPool internally in API
> without exposing it to user. We can provide for user
> init/free API to manage internal AmlPool manually, allowing
> him to select when to do initialization and cleanup.
> 
> Claudio, Marcel, Shannon,
> As the first API users, could you give your feedback on the topic.
> 

In my opinion, it's good to make users focused on ACPI table construction through
auto memory management. And it makes the code clear.

PS:
We're talking about use-after-free, like below example. But this example really exist?
During generating ACPI tables for virt machine, I don't encounter this case.

For example:
	aml_append(&a, b);
	aml_append(&a, b);

Thanks,
Shannon

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

* Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term Igor Mammedov
@ 2015-01-29  8:02   ` Shannon Zhao
  2015-01-29  8:45     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Shannon Zhao @ 2015-01-29  8:02 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, mst, claudio.fontana, marcel.a

On 2015/1/22 22:50, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/acpi-build-utils.c         | 47 ++++++++++++++++++++++++++++++++++++++
>  hw/i386/acpi-build.c               |  1 -
>  include/hw/acpi/acpi-build-utils.h |  8 +++++++
>  3 files changed, 55 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index b19d370..58f88cd 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -26,6 +26,7 @@
>  #include <string.h>
>  #include "hw/acpi/acpi-build-utils.h"
>  #include "qemu/bswap.h"
> +#include "hw/acpi/bios-linker-loader.h"
>  
>  GArray *build_alloc_array(void)
>  {
> @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
>          build_prepend_int(child.buf, child.buf->len);
>          build_package(child.buf, child.op);
>          break;
> +    case DEF_BLOCK: {
> +        uint8_t *start = (uint8_t *)parent_ctx->buf->data +
> +                         parent_ctx->buf->len;
> +        uint32_t le32_len = cpu_to_le32(child.buf->len);
> +
> +        /* create linker entry for the DefinitionBlock */
> +        bios_linker_loader_add_checksum(parent_ctx->linker,
> +            ACPI_BUILD_TABLE_FILE,
> +            parent_ctx->buf->data,
> +            start, child.buf->len, start + 9 /* checksum offset */);
> +
> +        /* set DefinitionBlock length at TableLength offset*/
> +        memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
> +        break;
> +    }
>      default:
>          break;
>      }
> @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
>                                dec, addr_gran, addr_min, addr_max,
>                                addr_trans, len, flags);
>  }
> +
> +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
> +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> +                       const char *oem_id, const char *oem_table_id,
> +                       uint32_t oem_revision)
> +{
> +    int len;
> +    AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
> +
> +    assert(strlen(signature) == 4);
> +    g_array_append_vals(var.buf, signature, 4);
> +    build_append_value(var.buf, 0, 4); /* Length place holder */
> +    build_append_byte(var.buf, revision);
> +    build_append_byte(var.buf, 0); /* place holder for Checksum */
> +
> +    len = strlen(oem_id);
> +    assert(len <= 6);
> +    g_array_append_vals(var.buf, oem_id, len);
> +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
> +
> +    len = strlen(oem_table_id);
> +    assert(len <= 8);
> +    g_array_append_vals(var.buf, oem_table_id, len);
> +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
> +
> +    build_append_value(var.buf, oem_revision, 4);
> +    g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
> +    build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
> +
> +    return var;
> +}

This function is similar with build_header() in hw/i386/acpi-build.c
But the format of omt_id, oem_table_id, asl_compiler_id are not exactly same.
Maybe we should make it consistent.


> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 4572c21..9ff8d72 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -270,7 +270,6 @@ static void acpi_get_pci_info(PcPciInfo *info)
>  #define ACPI_BUILD_APPNAME6 "BOCHS "
>  #define ACPI_BUILD_APPNAME4 "BXPC"
>  
> -#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
>  #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
>  #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
>  
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 5e8db3d..868d439 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -11,12 +11,17 @@ typedef enum {
>      EXT_PACKAGE,
>      BUFFER,
>      RES_TEMPLATE,
> +    DEF_BLOCK,
>  } AcpiBlockFlags;
>  
> +#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
> +#define ACPI_BUILD_APPNAME4 "BXPC"
> +
>  typedef struct AcpiAml {
>      GArray *buf;
>      uint8_t op;
>      AcpiBlockFlags block_flags;
> +    GArray *linker;
>  } AcpiAml;
>  
>  typedef enum {
> @@ -146,6 +151,9 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
>                            uint64_t len);
>  
>  /* Block ASL object primitives */
> +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> +                       const char *oem_id, const char *oem_table_id,
> +                       uint32_t oem_revision);
>  AcpiAml acpi_if(AcpiAml predicate);
>  AcpiAml acpi_method(const char *name, int arg_count);
>  AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
> 

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-29  7:46                               ` Shannon Zhao
@ 2015-01-29  8:42                                 ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-29  8:42 UTC (permalink / raw)
  To: Shannon Zhao
  Cc: Andrew Jones, marcel.a, Michael S. Tsirkin, claudio.fontana,
	qemu-devel, pbonzini

On Thu, 29 Jan 2015 15:46:32 +0800
Shannon Zhao <zhaoshenglong@huawei.com> wrote:

> On 2015/1/28 18:00, Igor Mammedov wrote:
> > On Wed, 28 Jan 2015 09:56:26 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> >>> I've tried redo series with passing alloc list as first argument,
> >>> looks ugly as hell
> >>
> >> I tried too. Not too bad at all. See below:
> >>
> >> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> >> index f66da5d..820504a 100644
> >> --- a/hw/i386/acpi-build.c
> >> +++ b/hw/i386/acpi-build.c
> >> @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
> >>      }
> >>  }
> >>  
> >> -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> >> +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
> >>  {
> >> -    AcpiAml if_ctx;
> >> +    AcpiAml *if_ctx;
> >>      int32_t devfn = PCI_DEVFN(slot, 0);
> >>  
> >> -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> >> -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
> >> -    aml_append(method, if_ctx);
> >> +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
> >> +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
> >> +    aml_append(p, method, if_ctx);
> >>  }
> >>  
> >>  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
> >>
> >> What exactly is the problem?  A tiny bit more verbose but the lifetime
> >> of all objects is now explicit.
> > every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
> > extra pointer which is not really necessary for user to know. If possible
> > user shouldn't care about it and concentrate on composing AML instead.
> > 
> > Whole point of passing AmlPool and record every allocation is to avoid
> > mistakes like:
> > 
> > acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> > 
> > and forgetting to assign object returned by call anywhere,
> > it's basically the same as calling malloc() without
> > using result anywhere, however neither libc nor glib
> > force user to pass allocator (in our case garbage collector)
> > in every call that allocates memory. Let's just follow common
> > convention here (#4) where an object is allocated by API call
> > (i.e like object_new(FOO), gtk_widget_foo()).
> > 
> > Hence is suggesting at least to hide AmlPool internally in API
> > without exposing it to user. We can provide for user
> > init/free API to manage internal AmlPool manually, allowing
> > him to select when to do initialization and cleanup.
> > 
> > Claudio, Marcel, Shannon,
> > As the first API users, could you give your feedback on the topic.
> > 
> 
> In my opinion, it's good to make users focused on ACPI table construction through
> auto memory management. And it makes the code clear.
> 
> PS:
> We're talking about use-after-free, like below example. But this example really exist?
> During generating ACPI tables for virt machine, I don't encounter this case.
> 
> For example:
> 	aml_append(&a, b);
> 	aml_append(&a, b);
Thanks for your reply,

yesterday we've came to a compromise, where API will stay as it is externally
only it will take all AML arguments by pointer. And we would introduce
allocation list internally inside API, User only would need to initialize it
before using API and free it after using API.

> 
> Thanks,
> Shannon
> 
> 

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

* Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term
  2015-01-29  8:02   ` Shannon Zhao
@ 2015-01-29  8:45     ` Igor Mammedov
  2015-01-29  9:01       ` Shannon Zhao
  0 siblings, 1 reply; 128+ messages in thread
From: Igor Mammedov @ 2015-01-29  8:45 UTC (permalink / raw)
  To: Shannon Zhao
  Cc: drjones, mst, marcel.a, claudio.fontana, qemu-devel, pbonzini

On Thu, 29 Jan 2015 16:02:47 +0800
Shannon Zhao <zhaoshenglong@huawei.com> wrote:

> On 2015/1/22 22:50, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/acpi/acpi-build-utils.c         | 47 ++++++++++++++++++++++++++++++++++++++
> >  hw/i386/acpi-build.c               |  1 -
> >  include/hw/acpi/acpi-build-utils.h |  8 +++++++
> >  3 files changed, 55 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index b19d370..58f88cd 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -26,6 +26,7 @@
> >  #include <string.h>
> >  #include "hw/acpi/acpi-build-utils.h"
> >  #include "qemu/bswap.h"
> > +#include "hw/acpi/bios-linker-loader.h"
> >  
> >  GArray *build_alloc_array(void)
> >  {
> > @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
> >          build_prepend_int(child.buf, child.buf->len);
> >          build_package(child.buf, child.op);
> >          break;
> > +    case DEF_BLOCK: {
> > +        uint8_t *start = (uint8_t *)parent_ctx->buf->data +
> > +                         parent_ctx->buf->len;
> > +        uint32_t le32_len = cpu_to_le32(child.buf->len);
> > +
> > +        /* create linker entry for the DefinitionBlock */
> > +        bios_linker_loader_add_checksum(parent_ctx->linker,
> > +            ACPI_BUILD_TABLE_FILE,
> > +            parent_ctx->buf->data,
> > +            start, child.buf->len, start + 9 /* checksum offset */);
> > +
> > +        /* set DefinitionBlock length at TableLength offset*/
> > +        memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
> > +        break;
> > +    }
> >      default:
> >          break;
> >      }
> > @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> >                                dec, addr_gran, addr_min, addr_max,
> >                                addr_trans, len, flags);
> >  }
> > +
> > +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
> > +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> > +                       const char *oem_id, const char *oem_table_id,
> > +                       uint32_t oem_revision)
> > +{
> > +    int len;
> > +    AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
> > +
> > +    assert(strlen(signature) == 4);
> > +    g_array_append_vals(var.buf, signature, 4);
> > +    build_append_value(var.buf, 0, 4); /* Length place holder */
> > +    build_append_byte(var.buf, revision);
> > +    build_append_byte(var.buf, 0); /* place holder for Checksum */
> > +
> > +    len = strlen(oem_id);
> > +    assert(len <= 6);
> > +    g_array_append_vals(var.buf, oem_id, len);
> > +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
> > +
> > +    len = strlen(oem_table_id);
> > +    assert(len <= 8);
> > +    g_array_append_vals(var.buf, oem_table_id, len);
> > +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
> > +
> > +    build_append_value(var.buf, oem_revision, 4);
> > +    g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
> > +    build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
> > +
> > +    return var;
> > +}
> 
> This function is similar with build_header() in hw/i386/acpi-build.c
> But the format of omt_id, oem_table_id, asl_compiler_id are not exactly same.
> Maybe we should make it consistent.
I've tried to follow APCI spec for definition block here,
which should be identical to build_header().
What exactly is not the same?

> 
> 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 4572c21..9ff8d72 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -270,7 +270,6 @@ static void acpi_get_pci_info(PcPciInfo *info)
> >  #define ACPI_BUILD_APPNAME6 "BOCHS "
> >  #define ACPI_BUILD_APPNAME4 "BXPC"
> >  
> > -#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
> >  #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
> >  #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
> >  
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 5e8db3d..868d439 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -11,12 +11,17 @@ typedef enum {
> >      EXT_PACKAGE,
> >      BUFFER,
> >      RES_TEMPLATE,
> > +    DEF_BLOCK,
> >  } AcpiBlockFlags;
> >  
> > +#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
> > +#define ACPI_BUILD_APPNAME4 "BXPC"
> > +
> >  typedef struct AcpiAml {
> >      GArray *buf;
> >      uint8_t op;
> >      AcpiBlockFlags block_flags;
> > +    GArray *linker;
> >  } AcpiAml;
> >  
> >  typedef enum {
> > @@ -146,6 +151,9 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> >                            uint64_t len);
> >  
> >  /* Block ASL object primitives */
> > +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> > +                       const char *oem_id, const char *oem_table_id,
> > +                       uint32_t oem_revision);
> >  AcpiAml acpi_if(AcpiAml predicate);
> >  AcpiAml acpi_method(const char *name, int arg_count);
> >  AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
> > 
> 
> 

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

* Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term
  2015-01-29  8:45     ` Igor Mammedov
@ 2015-01-29  9:01       ` Shannon Zhao
  2015-01-29  9:21         ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Shannon Zhao @ 2015-01-29  9:01 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: drjones, mst, marcel.a, claudio.fontana, qemu-devel, pbonzini

On 2015/1/29 16:45, Igor Mammedov wrote:
> On Thu, 29 Jan 2015 16:02:47 +0800
> Shannon Zhao <zhaoshenglong@huawei.com> wrote:
> 
>> > On 2015/1/22 22:50, Igor Mammedov wrote:
>>> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>>> > > ---
>>> > >  hw/acpi/acpi-build-utils.c         | 47 ++++++++++++++++++++++++++++++++++++++
>>> > >  hw/i386/acpi-build.c               |  1 -
>>> > >  include/hw/acpi/acpi-build-utils.h |  8 +++++++
>>> > >  3 files changed, 55 insertions(+), 1 deletion(-)
>>> > > 
>>> > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
>>> > > index b19d370..58f88cd 100644
>>> > > --- a/hw/acpi/acpi-build-utils.c
>>> > > +++ b/hw/acpi/acpi-build-utils.c
>>> > > @@ -26,6 +26,7 @@
>>> > >  #include <string.h>
>>> > >  #include "hw/acpi/acpi-build-utils.h"
>>> > >  #include "qemu/bswap.h"
>>> > > +#include "hw/acpi/bios-linker-loader.h"
>>> > >  
>>> > >  GArray *build_alloc_array(void)
>>> > >  {
>>> > > @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
>>> > >          build_prepend_int(child.buf, child.buf->len);
>>> > >          build_package(child.buf, child.op);
>>> > >          break;
>>> > > +    case DEF_BLOCK: {
>>> > > +        uint8_t *start = (uint8_t *)parent_ctx->buf->data +
>>> > > +                         parent_ctx->buf->len;
>>> > > +        uint32_t le32_len = cpu_to_le32(child.buf->len);
>>> > > +
>>> > > +        /* create linker entry for the DefinitionBlock */
>>> > > +        bios_linker_loader_add_checksum(parent_ctx->linker,
>>> > > +            ACPI_BUILD_TABLE_FILE,
>>> > > +            parent_ctx->buf->data,
>>> > > +            start, child.buf->len, start + 9 /* checksum offset */);
>>> > > +
>>> > > +        /* set DefinitionBlock length at TableLength offset*/
>>> > > +        memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
>>> > > +        break;
>>> > > +    }
>>> > >      default:
>>> > >          break;
>>> > >      }
>>> > > @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
>>> > >                                dec, addr_gran, addr_min, addr_max,
>>> > >                                addr_trans, len, flags);
>>> > >  }
>>> > > +
>>> > > +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
>>> > > +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
>>> > > +                       const char *oem_id, const char *oem_table_id,
>>> > > +                       uint32_t oem_revision)
>>> > > +{
>>> > > +    int len;
>>> > > +    AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
>>> > > +
>>> > > +    assert(strlen(signature) == 4);
>>> > > +    g_array_append_vals(var.buf, signature, 4);
>>> > > +    build_append_value(var.buf, 0, 4); /* Length place holder */
>>> > > +    build_append_byte(var.buf, revision);
>>> > > +    build_append_byte(var.buf, 0); /* place holder for Checksum */
>>> > > +
>>> > > +    len = strlen(oem_id);
>>> > > +    assert(len <= 6);
>>> > > +    g_array_append_vals(var.buf, oem_id, len);
>>> > > +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
>>> > > +
>>> > > +    len = strlen(oem_table_id);
>>> > > +    assert(len <= 8);
>>> > > +    g_array_append_vals(var.buf, oem_table_id, len);
>>> > > +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
>>> > > +
>>> > > +    build_append_value(var.buf, oem_revision, 4);
>>> > > +    g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
>>> > > +    build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
>>> > > +
>>> > > +    return var;
>>> > > +}
>> > 
>> > This function is similar with build_header() in hw/i386/acpi-build.c
>> > But the format of omt_id, oem_table_id, asl_compiler_id are not exactly same.
>> > Maybe we should make it consistent.
> I've tried to follow APCI spec for definition block here,
> which should be identical to build_header().
> What exactly is not the same?
> 

Sorry, I don make myself clear.
I mean that the values of omt_id, oem_table_id, asl_compiler_id are different between
using build_header and acpi_def_block.
E.g. using acpi_def_block the asl_compiler_id would be "BXPC" while build_header is blank.

I think we should make the omt_id, oem_table_id, asl_compiler_id as parameters of the
functions, then users assign the value.

Thanks,
Shannon

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

* Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term
  2015-01-29  9:01       ` Shannon Zhao
@ 2015-01-29  9:21         ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-01-29  9:21 UTC (permalink / raw)
  To: Shannon Zhao
  Cc: drjones, mst, marcel.a, claudio.fontana, qemu-devel, pbonzini

On Thu, 29 Jan 2015 17:01:02 +0800
Shannon Zhao <zhaoshenglong@huawei.com> wrote:

> On 2015/1/29 16:45, Igor Mammedov wrote:
> > On Thu, 29 Jan 2015 16:02:47 +0800
> > Shannon Zhao <zhaoshenglong@huawei.com> wrote:
> > 
> >> > On 2015/1/22 22:50, Igor Mammedov wrote:
> >>> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> >>> > > ---
> >>> > >  hw/acpi/acpi-build-utils.c         | 47 ++++++++++++++++++++++++++++++++++++++
> >>> > >  hw/i386/acpi-build.c               |  1 -
> >>> > >  include/hw/acpi/acpi-build-utils.h |  8 +++++++
> >>> > >  3 files changed, 55 insertions(+), 1 deletion(-)
> >>> > > 
> >>> > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> >>> > > index b19d370..58f88cd 100644
> >>> > > --- a/hw/acpi/acpi-build-utils.c
> >>> > > +++ b/hw/acpi/acpi-build-utils.c
> >>> > > @@ -26,6 +26,7 @@
> >>> > >  #include <string.h>
> >>> > >  #include "hw/acpi/acpi-build-utils.h"
> >>> > >  #include "qemu/bswap.h"
> >>> > > +#include "hw/acpi/bios-linker-loader.h"
> >>> > >  
> >>> > >  GArray *build_alloc_array(void)
> >>> > >  {
> >>> > > @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
> >>> > >          build_prepend_int(child.buf, child.buf->len);
> >>> > >          build_package(child.buf, child.op);
> >>> > >          break;
> >>> > > +    case DEF_BLOCK: {
> >>> > > +        uint8_t *start = (uint8_t *)parent_ctx->buf->data +
> >>> > > +                         parent_ctx->buf->len;
> >>> > > +        uint32_t le32_len = cpu_to_le32(child.buf->len);
> >>> > > +
> >>> > > +        /* create linker entry for the DefinitionBlock */
> >>> > > +        bios_linker_loader_add_checksum(parent_ctx->linker,
> >>> > > +            ACPI_BUILD_TABLE_FILE,
> >>> > > +            parent_ctx->buf->data,
> >>> > > +            start, child.buf->len, start + 9 /* checksum offset */);
> >>> > > +
> >>> > > +        /* set DefinitionBlock length at TableLength offset*/
> >>> > > +        memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
> >>> > > +        break;
> >>> > > +    }
> >>> > >      default:
> >>> > >          break;
> >>> > >      }
> >>> > > @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> >>> > >                                dec, addr_gran, addr_min, addr_max,
> >>> > >                                addr_trans, len, flags);
> >>> > >  }
> >>> > > +
> >>> > > +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
> >>> > > +AcpiAml ()(const char *signature, uint8_t revision,
> >>> > > +                       const char *oem_id, const char *oem_table_id,
> >>> > > +                       uint32_t oem_revision)
> >>> > > +{
> >>> > > +    int len;
> >>> > > +    AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
> >>> > > +
> >>> > > +    assert(strlen(signature) == 4);
> >>> > > +    g_array_append_vals(var.buf, signature, 4);
> >>> > > +    build_append_value(var.buf, 0, 4); /* Length place holder */
> >>> > > +    build_append_byte(var.buf, revision);
> >>> > > +    build_append_byte(var.buf, 0); /* place holder for Checksum */
> >>> > > +
> >>> > > +    len = strlen(oem_id);
> >>> > > +    assert(len <= 6);
> >>> > > +    g_array_append_vals(var.buf, oem_id, len);
> >>> > > +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
> >>> > > +
> >>> > > +    len = strlen(oem_table_id);
> >>> > > +    assert(len <= 8);
> >>> > > +    g_array_append_vals(var.buf, oem_table_id, len);
> >>> > > +    g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
> >>> > > +
> >>> > > +    build_append_value(var.buf, oem_revision, 4);
> >>> > > +    g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
> >>> > > +    build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
> >>> > > +
> >>> > > +    return var;
> >>> > > +}
> >> > 
> >> > This function is similar with build_header() in hw/i386/acpi-build.c
> >> > But the format of omt_id, oem_table_id, asl_compiler_id are not exactly same.
> >> > Maybe we should make it consistent.
> > I've tried to follow APCI spec for definition block here,
> > which should be identical to build_header().
> > What exactly is not the same?
> > 
> 
> Sorry, I don make myself clear.
> I mean that the values of omt_id, oem_table_id, asl_compiler_id are different between
> using build_header and acpi_def_block.
> E.g. using acpi_def_block the asl_compiler_id would be "BXPC" while build_header is blank.
That's no true, build_header() sets asl_compiler_id to ACPI_BUILD_APPNAME4
the same way as does acpi_def_block().

> 
> I think we should make the omt_id, oem_table_id, asl_compiler_id as parameters of the
> functions, then users assign the value.
The only thing not exposed to API user is asl_compiler_id and
asl_compiler_revision, I'll add them as arguments of acpi_def_block()
on the next respin to be closer to ACPI spec.

> 
> Thanks,
> Shannon
> 

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

* Re: [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term
  2015-01-23 13:42       ` Michael S. Tsirkin
@ 2015-02-02 16:04         ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-02 16:04 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: pbonzini, drjones, claudio.fontana, qemu-devel, marcel.a

On Fri, 23 Jan 2015 15:42:30 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Jan 23, 2015 at 02:32:45PM +0100, Igor Mammedov wrote:
> > On Fri, 23 Jan 2015 10:59:48 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Jan 22, 2015 at 02:49:50PM +0000, Igor Mammedov wrote:
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > ---
> > > >  hw/acpi/acpi-build-utils.c         | 24 ++++++++++++++++++++++++
> > > >  include/hw/acpi/acpi-build-utils.h |  3 +++
> > > >  2 files changed, 27 insertions(+)
> > > > 
> > > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > > > index 40a1769..1bda2ec 100644
> > > > --- a/hw/acpi/acpi-build-utils.c
> > > > +++ b/hw/acpi/acpi-build-utils.c
> > > > @@ -314,6 +314,30 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
> > > >      return var;
> > > >  }
> > > >  
> > > > +/*
> > > > + * help to construct NameString, which return AcpiAml object
> > > > + * for using with other aml_append or other acpi_* terms
> > > 
> > > Here and elsewhere: I can't parse this header text.
> > > I'm guessing you just mean "construct NameString",
> > > and that's it?
> > yes
> > 
> > > 
> > > Also, most other places use build_append_namestring -
> > > so when should acpi_name be used instead?
> > > This should be made clear here in the comment.
> > acpi_name() is a replacement/wrapper around build_append_namestring()
> > which returns AcpiAml object. build_append_namestring() is a nonpublic
> > lowlevel helper that deals with GArray,
> > while acpi_name() follows semantic of AML API.
> > 
> > > 
> > > > + */
> > > > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...)
> > > > +{
> > > 
> > > This isn't really a name. It just appends a string.  So rename this
> > > acpi_string and then the below one adding a name can be named acpi_name?
> > acpi_string is introduced in 27/47, which is a prefixed string
> > as described in spec.
> > 
> > > Also, in many places one must use only one nameseg.
> > Where is it exactly?
> > Perhaps we could build in acpi_name() a check if we know in
> > what context enforce it. Better to have single/uniform API
> > for names than a several which is confusing.
> 
> I agree here.
> 
> > > I think a separate api that actually validates
> > > that it's one segment is better than silently failing.
> > > Do we ever use it for more than 1 segment?
> > Yes we use names with more than one segment.
> 
> Interesting. where exactly?
For example:

build_append_namestring(method, "^S%.02X.PCNT"

> 
> > > If not, maybe the right thing to do is
> > > to use build_append_nameseg and call this one acpi_nameseg.
> > acpi_name() is used only for passing name as arguments to methods,
> > in spec there isn't a limitation to only one segment when it comes
> > to names, in ASL part of it. namesegment however only AML construct
> > which helps to build name, I prefer not expose lowlevel AML
> > unless we have to.
> 
> OK, I agree.
> 
> > > 
> > > 
> > > > +    va_list ap;
> > > > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > > 
> > > 0 hard coded? What does it mean?
> > 1st arg for NON_BLOCK context doesn't mean anything/ignored.
> > alternatively I can make aml_allocate_nonblock() wrapper
> > around generic allocator.
> 
> 0 isn't a valid opcode either, it can really be anything.
yes, it could.
So I leave it as it's
or is there any other way that you'd prefer here?

> 
> 
> 
> > > Same elsewhere.
> > > 
> > > > +    va_start(ap, name_format);
> > > > +    build_append_namestringv(var.buf, name_format, ap);
> > > > +    va_end(ap);
> > > > +    return var;
> > > > +
> > > > +/* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */
> > > 
> > > Let's quote the earliest spec which documents each object:
> > > one year from now 5.0 will not be the latest.
> > > Applies here and elsewhere.
> > > In most places this will be 1.0b.
> > > Where the construct is newer, this will automatically
> > > document which guests support it.
> > I'll try to do it.
> > 
> > > 
> > > > +AcpiAml acpi_name_decl(const char *name, AcpiAml val)
> > > > +{
> > > > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > > > +    build_append_byte(var.buf, 0x08);
> > > 
> > > Pls add comment documenting what 0x08 is here.
> > sure
> > 
> > > 
> > > > +    build_append_namestring(var.buf, "%s", name);
> > > > +    aml_append(&var, val);
> > > > +    return var;
> > > > +}
> > > > +
> > > >  /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> > > >  AcpiAml acpi_if(AcpiAml predicate)
> > > >  {
> > > > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > > > index 177f9ed..868cfa5 100644
> > > > --- a/include/hw/acpi/acpi-build-utils.h
> > > > +++ b/include/hw/acpi/acpi-build-utils.h
> > > > @@ -21,6 +21,9 @@ typedef struct AcpiAml {
> > > >  
> > > >  void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> > > >  
> > > > +/* non block ASL object primitives */
> > > 
> > > what does it mean that it's a "non block primitive"?
> > > I didn't find this concept in the spec.
> > As for a question what is NON_BLOCK, it's for simple inline ASL
> > construct that doesn't have to be packaged in special way
> > examles:
> >   Store(A,B)
> >   Name(FOO, VAL)
> >   IO(...)
> > while there are different block elements differing in how
> > they are created see 1/47 aml_append():
> > 
> > ResourceTemplate {
> >  /* block of other ASL items */
> > }
> > 
> > Package() {
> >  /* block of other ASL items */
> > }
> > 
> > if ... else ...
> > 
> > Scope() {
> >  /* block of other ASL items */
> > }
> > 
> > and so on.
> 
> "special way" is kind of vague.
> Maybe add a comment explaining when it's used.
> Is it when length isn't used as a prefix?
> AML_NO_PREFIX?
There are terms that have 'prefix' in definition but are still
inline elements, like:
DWordConst := DWordPrefix DWordData
String := StringPrefix AsciiCharList NullChar

using prefix would be confusing.

Having(/not having) prefix doesn't make objects into block one,
that can embed other objects. And although length-less is the closest
definition for them but it also doesn't match all objects, for
example:
NamedField := NameSeg PkgLength
uses PkgLength but still isn't a block element that includes
other objects.

That's why I've used NON_BLOCK as a neutral name but still
describing what's going on.

> 
> 
> > > 
> > > > +AcpiAml GCC_FMT_ATTR(1, 2) acpi_name(const char *name_format, ...);
> > > > +AcpiAml acpi_name_decl(const char *name, AcpiAml val);
> > > >  /* Block ASL object primitives */
> > > >  AcpiAml acpi_if(AcpiAml predicate);
> > > >  AcpiAml acpi_method(const char *name, int arg_count);
> > > > -- 
> > > > 1.8.3.1

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-27 22:29                         ` Igor Mammedov
  2015-01-28  7:27                           ` Michael S. Tsirkin
  2015-01-28  7:56                           ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Michael S. Tsirkin
@ 2015-02-05 14:09                           ` Marcel Apfelbaum
  2 siblings, 0 replies; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 14:09 UTC (permalink / raw)
  To: Igor Mammedov, Michael S. Tsirkin
  Cc: pbonzini, Andrew Jones, claudio.fontana, qemu-devel, marcel.a

On 01/28/2015 12:29 AM, Igor Mammedov wrote:
> On Mon, 26 Jan 2015 18:17:55 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
>> On Mon, Jan 26, 2015 at 04:34:01PM +0100, Andrew Jones wrote:
>>> On Mon, Jan 26, 2015 at 04:09:20PM +0100, Igor Mammedov wrote:
>>>> On Mon, 26 Jan 2015 10:57:21 +0100
>>>> Igor Mammedov <imammedo@redhat.com> wrote:
>>>>
>>>>> On Sat, 24 Jan 2015 18:33:50 +0200
>>>>> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>>>>>
>>>>>> On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
>>>>>>> On Fri, 23 Jan 2015 15:55:11 +0200
>>>>>>> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>>>>>>>
>>>> [...]
>>>>>>> I refuse to give up on cleaner and simpler API yet :)
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Your patches are almost there, they are pretty clean, the
>>>>>>>> only issue I think is this passing of AcpiAml by value,
>>>>>>>> sometimes freeing buffer in the process, sometimes not.
>>>>>>> Currently buffer is allocated by API and is always freed
>>>>>>> whenever it's passed to another API function.
>>>>>>> That's why it makes user not to care about memory mgmt.
>>>>>>>
>>>>>>> The only limitation of it is if you store AcpiAml return
>>>>>>> value into some variable you are responsible to use it only
>>>>>>> once for passing to another API function. Reusing this
>>>>>>> variable's value (pass it to API function second time)
>>>>>>> would cause cause use-after-free and freeing-freed bugs.
>>>>>>> Like this: AcpiAml table =
>>>>>>> acpi_definition_block("SSDT",...); AcpiAml scope =
>>>>>>> acpi_scope("PCI0"); aml_append(&table, scope); // <- here
>>>>>>> scope becomes invalid // a bug
>>>>>>> aml_append(&table, scope); // use-after-free +
>>>>>>> freeing-freed bugs
>>>>>>>
>>>>>>> There are several approaches to look for resolving above
>>>>>>> issues: 1. Adopt and use memory mgmt model used by GTK+
>>>>>>>     in nutshell:
>>>>>>> http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
>>>>>>> In particular adopt behavior of GInitiallyUnowned usage
>>>>>>> model
>>>>>>>
>>>>>>>     that will allow to keep convenient chained call style
>>>>>>> and if necessary reuse objects returned by API by
>>>>>>> explicitly referencing/dereferencing them if needed.
>>>>>>
>>>>>> Hmm, it's still easy to misuse. I think I prefer option 2
>>>>>> below.
>>>>> That's basically what we have/use in QOM with object_new(FOO) +
>>>>> object_unref() I have no idea why we invented our own Object
>>>>> infrastructure when we could just use GObject one from already
>>>>> used glib.
>>>>>
>>>>>>
>>>>>>> 2. It's possible to drop freeing inside API completely and
>>>>>>>     record(store in list) every new object inside a table
>>>>>>> context. When table is constructed, list of created objects
>>>>>>> could be safely freed.
>>>>>>>     With that it would be safe to reuse every AcpiAml object
>>>>>>>     and avoid free-after-use issues with limitation that
>>>>>>> created AcpiAml objects shouldn't be used after table was
>>>>>>> closed. It should cover all practical use of API, i.e. no
>>>>>>> cross table AcpiAml objects.
>>>>>>
>>>>>> So each aml_alloc function gets pointer to this list,
>>>>>> and adds the new element there.
>>>>>> Eventually we do free_all to free all elements,
>>>>>> so there isn't even an aml_free to mis-use.
>>>>> I'm thinking a little bit different about implementation though.
>>>>> I still don't like the use of explicit alloc/free being called
>>>>> by API user since it doesn't allow chained API calls and
>>>>> I think it's unnecessary complication see below why.
>>>>>
>>>>> Here is what's true about current API and a I'd like to with it:
>>>>>
>>>>>    1. Every API call (except aml_append) makes aml_alloc(), it's
>>>>> just like a wrapper about object_new(FOO). (current + new impl.)
>>>>>
>>>>>    2 Every API call that takes AML type as input argument
>>>>>    2.1 consumes (frees) it (current impl.)
>>>>>        (it's easy to fix use after free concern too,
>>>>>         just pass AML by pointer and zero-out memory before it's
>>>>> freed and assert whenever one of input arguments is not correct,
>>>>>         i.e. it was reused second time)
>>>>>        There is no need for following steps after this one.
>>>>>    2.2 takes ownership of GInitiallyUnowned and adds it to its
>>>>> list of its children.
>>>>>    3. Free children when AML object is destroyed (i.e. ref count
>>>>> zero) That way when toplevel table object (definition block in
>>>>> 42/47) is added to ACPI blob we can unref it, which will cause
>>>>>       its whole children tree freed, except for AML objects where
>>>>>       API user explicitly took extra reference (i.e. wanted them
>>>>>       to reuse in another table)
>>>>>
>>>>> I'd prefer:
>>>>>   *  2.1 way to address your current concern of use-after-free
>>>>>      as the most simplest one (no reuse is possible however)
>>>>> or
>>>>>   * follow already used by QEMU QOM/GObject pattern of
>>>>>     implicit alloc/free
>>>>>
>>>>> since they allow to construct AML in a more simple/manageable
>>>>> way i.e.
>>>>>    aml_append(method,
>>>>>        aml_store(aml_string("foo"), aml_local(0)))
>>>>>    );
>>>>>
>>>>> v.s. explicit headache of alloc/free, which doesn't fix
>>>>>       use-after-free anyway and just adds more boiler plate
>>>>>       plus makes code har to read read
>>>>>
>>>>>    str = aml_alloc();
>>>>>    aml_string(str, "foo");
>>>>>    loc0 = aml_alloc();
>>>>>    aml_local(loc0, 0);
>>>>>    store = aml_alloc();
>>>>>    aml_store(store, str, loc0);
>>>>>    aml_append(method, store);
>>>>>    aml_free(store);
>>>>>    aml_free(loc0);
>>>>>    aml_free(str);
>>>>
>>>> Here is a compromise what I and Michael came to on a phone call:
>>>>
>>>> Externally API usage would look like:
>>>>
>>>> AmlAllocList *p = some_list_alloc();
>>>>
>>>> Aml *ssdt = aml_def_block(p, "SSDT", ...);
>>>> Aml *dev = aml_device(p, "PCI0");
>>>> aml_append(dev,
>>>>      aml_name_def(p, "_STA", aml_int(p, 0xF /* present */))
>>>> );
>>>> aml_append(ssdt, dev);
>>>>
>>>> aml_append(acpi_tables_blob, ssdt);
>>>>
>>>> free_aml_alloc_list(p);
>>>>
>>>>
>>>> Each of aml_foo() will take other Aml arguments by pointer.
>>>> Also every aml_foo(), except of aml_append() will allocate
>>>> Aml struct and return pointer to it and also add this pointer
>>>> into AmlAllocList which is passed as first argument to each
>>>> aml_foo() call.
>>>> aml_append() becomes nondestructive function and just adds
>>>> child(2nd arg) to the parent context (1st arg).
>>>>
>>>> After API user is done with building table and pushed it
>>>> into tables blob, he/she calls free_aml_alloc_list() to free
>>>> all Aml objects created during process of building the table
>>>> content.
>>>
>>> Hmm, passing 'p' around somewhat muddies an otherwise clean
>>> interface, but the concern with aml_append silently freeing
>>> memory still accessible by the caller is definitely valid. I
> I've tried redo series with passing alloc list as first argument,
> looks ugly as hell
I don't like that either.

  and I still doubt that explicit recording of every
> allocation is necessary.
This would be nice since is simple, it doesn't hurt
and it releases us from the use-after-free problem.


  I'd rather use QOM tree for AML objects.
If you must :(, it looks like an overkill since those objects will live
a very short life and your proposed table does the trick.
Keeping references and a whole tree seems unnecessary.

>
> If we still don't want to use QOM and considering that ACPI
> tables are build in one thread/function, I'd prefer to hide
> allocation list inside API making it static variable for now.
Why not, would be an internal static variable acceptable?
Do we have to worry of multiple threads for this?
If not, I would suggest going with that and close the day.

My opinion, of course.
Thanks,
Marcel

[...]

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

* Re: [Qemu-devel] [PATCH 00/13] convert AML API to QOM
  2015-01-28 12:44                               ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Andrew Jones
@ 2015-02-05 14:28                                 ` Marcel Apfelbaum
  2015-02-05 17:36                                   ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 14:28 UTC (permalink / raw)
  To: Andrew Jones, Igor Mammedov
  Cc: pbonzini, zhaoshenglong, claudio.fontana, qemu-devel, marcel.a

On 01/28/2015 02:44 PM, Andrew Jones wrote:
> On Wed, Jan 28, 2015 at 10:03:24AM +0000, Igor Mammedov wrote:
>>
>> Example demonstrates use of QOM object for building AML
>> objects tree and freeing it explicitly when requested.
>>
>> Top level ACPI tables blob object is only partially
>> switched to object model now but I hope it demostrates
>> the point of absracting code and hiding parts of code
>> that could be done without user intervention.
>>
>> Pathes 1/2/8 are just a convertion boiler plate which
>> will go away on respin.
>>
>>
>> Igor Mammedov (13):
>>    convert to passing AcpiAml by pointers
>>    make toplevel ACPI tables blob a pointer
>>    qom: add support for weak referenced object: aka UnownedObject
>>    acpi: make AcpiAml an OQM object
>>    acpi: use TYPE_AML_OBJECT inside of AML API
>>    acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob
>>    acpi: make toplevel ACPI tables blob a dedicated object
>>    i386: acpi: hack not yet converted tables calls to deal with
>>      table_data being a pointer
>>    acpi: add aml_blob() helper
>>    i386: acpi: add DSDT table using AML API
>>    acpi: acpi_add_table() to common cross target file
>>    acpi: prepare for API internal collection of RSDT entries
>>    i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT
>>      automatically
>>
>>   hw/acpi/acpi-build-utils.c         | 537 +++++++++++++++++++++----------------
>>   hw/i386/acpi-build.c               | 388 +++++++++++++--------------
>>   include/hw/acpi/acpi-build-utils.h | 119 +++++---
>>   include/qom/object.h               |  20 ++
>>   qom/object.c                       |  20 +-
>>   5 files changed, 620 insertions(+), 464 deletions(-)
>>
>> --
>> 1.8.3.1
>>
>
> Thanks for doing this.
Thanks also fomr me! It is really  interesting to see this.

  It's satisfied my curiosity as to how
> much boilerplate we'd need for the conversion. I looked mainly
> at the first half of this series, as it appears the second half
> is an add-on, not directly relevant to the explicit memory
> management vs. object model memory management discussion. The
> additional code, and need for QOM knowledge, appears pretty low.
> So, as this would allow developers focused on ACPI table
> construction to almost completely avoid doing any memory
> management themselves, then, FWIW, it looks like a good trade
> off to me.

While I am not against this approach, maybe a simpler idea of keeping
an internal static map of allocated vars and freeing it in the end would be enough.

That being said, this approach gives us the opportunity to create QOM objects
for all AML constructs as AcpiArg for example:
     AcpiAml arg = object_new(ACPI_ARG_TYPE);
and handling the implementation inside the corresponding init function.

Thanks,
Marcel

>
> drew
>

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28  7:56                           ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Michael S. Tsirkin
  2015-01-28 10:00                             ` Igor Mammedov
  2015-01-28 10:45                             ` Andrew Jones
@ 2015-02-05 14:30                             ` Marcel Apfelbaum
  2 siblings, 0 replies; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 14:30 UTC (permalink / raw)
  To: Michael S. Tsirkin, Igor Mammedov
  Cc: pbonzini, Andrew Jones, claudio.fontana, qemu-devel, marcel.a

On 01/28/2015 09:56 AM, Michael S. Tsirkin wrote:
>> I've tried redo series with passing alloc list as first argument,
>> looks ugly as hell
>
> I tried too. Not too bad at all. See below:
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index f66da5d..820504a 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
>       }
>   }
>
> -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, int slot)
>   {
> -    AcpiAml if_ctx;
> +    AcpiAml *if_ctx;
>       int32_t devfn = PCI_DEVFN(slot, 0);
>
> -    if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> -    aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), acpi_arg1()));
> -    aml_append(method, if_ctx);
> +    if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << slot)));
> +    aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), acpi_arg1(p)));
> +    aml_append(p, method, if_ctx);
>   }
>
>   static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus *bus,
>
> What exactly is the problem?  A tiny bit more verbose but the lifetime
> of all objects is now explicit.
A matter of taste, but I personally don't like this p everywhere,
it makes everything hard to read.

I am still wondering about the static variable that will hold
all of the instances and will be explicitly freed at the end.

Thanks,
Marcel

>
>

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

* Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()
  2015-01-28 10:00                             ` Igor Mammedov
                                                 ` (2 preceding siblings ...)
  2015-01-29  7:46                               ` Shannon Zhao
@ 2015-02-05 14:35                               ` Marcel Apfelbaum
  3 siblings, 0 replies; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 14:35 UTC (permalink / raw)
  To: Igor Mammedov, Michael S. Tsirkin
  Cc: Andrew Jones, marcel.a, claudio.fontana, qemu-devel,
	Shannon Zhao, pbonzini

On 01/28/2015 12:00 PM, Igor Mammedov wrote:
> On Wed, 28 Jan 2015 09:56:26 +0200
[...]
>
> Hence is suggesting at least to hide AmlPool internally in API
> without exposing it to user. We can provide for user
> init/free API to manage internal AmlPool manually, allowing
> him to select when to do initialization and cleanup.
This I like the most.

>
> Claudio, Marcel, Shannon,
> As the first API users, could you give your feedback on the topic.
As a happy API user, I really like it as it is.
Since we do need to address the allocation/freeing issues
I like the internal AmlPool as I stated already in a few places :)

Thanks,
Marcel

>

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

* Re: [Qemu-devel] [PATCH v2 05/47] acpi: add acpi_if() term
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 05/47] acpi: add acpi_if() term Igor Mammedov
@ 2015-02-05 15:01   ` Marcel Apfelbaum
  2015-02-05 17:54     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 15:01 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

On 01/22/2015 04:49 PM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 8 ++++++++
>   include/hw/acpi/acpi-build-utils.h | 1 +
>   2 files changed, 9 insertions(+)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index d0b0159..40a1769 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -314,6 +314,14 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
>       return var;
>   }
>
> +/* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> +AcpiAml acpi_if(AcpiAml predicate)
> +{
> +    AcpiAml var = aml_allocate_internal(0xA0 /* IfOp */, PACKAGE);
> +    aml_append(&var, predicate);
> +    return var;
> +}
There are other ACPI constructs exactly like the above, except
the operation number (0xA0).
Maybe we can have a generic internal function and the API
will call it.

For example IfWhile has the same structure except the op number,
and maybe many other Type 1 Opcodes.

Thanks,
Marcel

> +
>   /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefMethod */
>   AcpiAml acpi_method(const char *name, int arg_count)
>   {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 19ebc2d..177f9ed 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -22,6 +22,7 @@ typedef struct AcpiAml {
>   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
>
>   /* Block ASL object primitives */
> +AcpiAml acpi_if(AcpiAml predicate);
>   AcpiAml acpi_method(const char *name, int arg_count);
>   AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
>   AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
>

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

* Re: [Qemu-devel] [PATCH v2 12/47] acpi: add acpi_store() term
  2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 12/47] acpi: add acpi_store() term Igor Mammedov
@ 2015-02-05 15:06   ` Marcel Apfelbaum
  0 siblings, 0 replies; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 15:06 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

On 01/22/2015 04:49 PM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 10 ++++++++++
>   include/hw/acpi/acpi-build-utils.h |  1 +
>   2 files changed, 11 insertions(+)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 6e10712..d78d34f 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -380,6 +380,16 @@ AcpiAml acpi_arg3(void)
>       return var;
>   }
>
> +/* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefStore */
> +AcpiAml acpi_store(AcpiAml val, AcpiAml target)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x70); /* StoreOp */
> +    aml_append(&var, val);
> +    aml_append(&var, target);
> +    return var;
> +}

The same comment here:
There are other ACPI constructs exactly like the above, except
the operation number (0x70).
Maybe we can have a generic internal function and the API
will call it.
For example OrOp and AddOp.

Instead of rewriting the same code, I propose (for all cases)
to create an internal function, for this example:
  - AcpiAml acpi_2_args_op(AcpiAml arg1, AcpiAml arg2, int op)
And have a wrapper for each op.

A better name will be welcomed, maybe it can be extracted from the APCI spec.

Thanks,
Marcel


> +
>   /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
>   AcpiAml acpi_if(AcpiAml predicate)
>   {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 18d9efa..5d3651d 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -30,6 +30,7 @@ AcpiAml acpi_arg0(void);
>   AcpiAml acpi_arg1(void);
>   AcpiAml acpi_arg2(void);
>   AcpiAml acpi_arg3(void);
> +AcpiAml acpi_store(AcpiAml val, AcpiAml target);
>
>   /* Block ASL object primitives */
>   AcpiAml acpi_if(AcpiAml predicate);
>

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

* Re: [Qemu-devel] [PATCH v2 22/47] acpi: add acpi_io() helper
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 22/47] acpi: add acpi_io() helper Igor Mammedov
@ 2015-02-05 15:19   ` Marcel Apfelbaum
  2015-02-05 17:56     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 15:19 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 19 +++++++++++++++++++
>   include/hw/acpi/acpi-build-utils.h |  7 +++++++
>   2 files changed, 26 insertions(+)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 32a4377..56b237a 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -454,6 +454,25 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
>       return var;
>   }
>
> +/*
> + * ACPI 5.0: 19.5.62 IO (IO Resource Descriptor Macro)
> + *           6.4.2 Small Resource Data Type
> +*/
> +AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> +                uint8_t aln, uint8_t len)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x47); /* IO port descriptor */
> +    build_append_byte(var.buf, dec);
> +    build_append_byte(var.buf, min_base & 0xff);
> +    build_append_byte(var.buf, (min_base >> 8) & 0xff);
> +    build_append_byte(var.buf, max_base & 0xff);
> +    build_append_byte(var.buf, (max_base >> 8) & 0xff);
> +    build_append_byte(var.buf, aln);
> +    build_append_byte(var.buf, len);
> +    return var;
> +}
> +
>   /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
>   AcpiAml acpi_if(AcpiAml predicate)
>   {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 594fae7..91575f1 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -19,6 +19,11 @@ typedef struct AcpiAml {
>       AcpiBlockFlags block_flags;
>   } AcpiAml;
>
> +typedef enum {
> +    acpi_decode10 = 0,
> +    acpi_decode16 = 1,
> +} acpiIODecode;
A really small comment, you mean AcpiIODecode and not acpiIODecode, right?

Thanks,
Marcel

> +
>   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
>
>   /* non block ASL object primitives */
> @@ -39,6 +44,8 @@ AcpiAml acpi_call3(const char *method, AcpiAml arg1, AcpiAml arg2,
>                      AcpiAml arg3);
>   AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
>                      AcpiAml arg3, AcpiAml arg4);
> +AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> +                uint8_t aln, uint8_t len);
>
>   /* Block ASL object primitives */
>   AcpiAml acpi_if(AcpiAml predicate);
>

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

* Re: [Qemu-devel] [PATCH v2 24/47] acpi: add acpi_operation_region() term
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 24/47] acpi: add acpi_operation_region() term Igor Mammedov
@ 2015-02-05 15:28   ` Marcel Apfelbaum
  2015-02-05 17:57     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 15:28 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 14 ++++++++++++++
>   include/hw/acpi/acpi-build-utils.h |  7 +++++++
>   2 files changed, 21 insertions(+)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 094c821..9ac5a0d 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -544,3 +544,17 @@ AcpiAml acpi_package(uint8_t num_elements)
>       build_append_byte(var.buf, num_elements);
>       return var;
>   }
> +
> +/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefOpRegion */
> +AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
> +                              uint32_t offset, uint32_t len)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    build_append_byte(var.buf, 0x5B); /* ExtOpPrefix */
> +    build_append_byte(var.buf, 0x80); /* OpRegionOp */
> +    build_append_namestring(var.buf, "%s", name);
> +    build_append_byte(var.buf, rs);
> +    build_append_int(var.buf, offset);
> +    build_append_int(var.buf, len);
> +    return var;
> +}
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 176596e..cb45129 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -24,6 +24,11 @@ typedef enum {
>       acpi_decode16 = 1,
>   } acpiIODecode;
      ^^^
Why do you want enums to no start with capital letters?

Thanks,
Marcel

>
> +typedef enum {
> +    acpi_system_memory = 0x00,
> +    acpi_system_io = 0x01,
> +} acpiRegionSpace;
> +
>   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
>
>   /* non block ASL object primitives */
> @@ -46,6 +51,8 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
>                      AcpiAml arg3, AcpiAml arg4);
>   AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
>                   uint8_t aln, uint8_t len);
> +AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
> +                              uint32_t offset, uint32_t len);
>
>   /* Block ASL object primitives */
>   AcpiAml acpi_if(AcpiAml predicate);
>

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

* Re: [Qemu-devel] [PATCH v2 35/47] acpi: add acpi_reserved_field() term
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 35/47] acpi: add acpi_reserved_field() term Igor Mammedov
@ 2015-02-05 15:36   ` Marcel Apfelbaum
  2015-02-05 17:57     ` Igor Mammedov
  0 siblings, 1 reply; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 15:36 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 10 ++++++++++
>   include/hw/acpi/acpi-build-utils.h |  6 ++++++
>   2 files changed, 16 insertions(+)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index cbc1241..644af1f 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -591,6 +591,16 @@ AcpiAml acpi_named_field(const char *name, unsigned length)
>       return var;
>   }
>
> +/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: ReservedField */
> +AcpiAml acpi_reserved_field(unsigned length)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +    /* ReservedField  := 0x00 PkgLength */
> +    build_append_byte(var.buf, 0x00);
> +    build_append_pkg_length(var.buf, length, false);
> +    return var;
> +}
> +
>   /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefField */
>   AcpiAml acpi_field(const char *name, acpiFieldFlags flags)
>   {
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 02d5aa8..048ed26 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -25,7 +25,12 @@ typedef enum {
>   } acpiIODecode;
     ^^^
>
>   typedef enum {
> +    acpi_any_acc = 0,
>       acpi_byte_acc = 1,
> +    acpi_word_acc = 2,
> +    acpi_dword_acc = 3,
> +    acpi_qword_acc = 4,
> +    acpi_buffer_acc = 5,
>   } acpiFieldFlags;
      ^^^
I missed that, is there any way it was like that already? Do we have such
a coding convention on QEMU?

Thanks,
Marcel

>
>   typedef enum {
> @@ -58,6 +63,7 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
>   AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
>                                 uint32_t offset, uint32_t len);
>   AcpiAml acpi_named_field(const char *name, unsigned length);
> +AcpiAml acpi_reserved_field(unsigned length);
>   AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
>   AcpiAml acpi_local0(void);
>   AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2);
>

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

* Re: [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms
  2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms Igor Mammedov
@ 2015-02-05 15:38   ` Marcel Apfelbaum
  2015-02-05 17:58     ` Igor Mammedov
  2015-02-05 17:59     ` Igor Mammedov
  0 siblings, 2 replies; 128+ messages in thread
From: Marcel Apfelbaum @ 2015-02-05 15:38 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: pbonzini, drjones, marcel.a, claudio.fontana, mst

On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>   hw/acpi/acpi-build-utils.c         | 143 +++++++++++++++++++++++++++++++++++++
>   include/hw/acpi/acpi-build-utils.h |  73 +++++++++++++++++++
>   2 files changed, 216 insertions(+)
>
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index 644af1f..b19d370 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -700,3 +700,146 @@ AcpiAml acpi_eisaid(const char *str)
>       build_append_value(var.buf, bswap32(id), sizeof(id));
>       return var;
>   }
> +
> +/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
> +static AcpiAml
> +acpi_as_desc_header(acpiResourceType type, acpiMinFixed min_fixed,
> +                    acpiMaxFixed max_fixed, acpiDecode dec, uint8_t type_flags)
> +{
> +    uint8_t flags = max_fixed | min_fixed | dec;
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +
> +    build_append_byte(var.buf, type);
> +    build_append_byte(var.buf, flags);
> +    build_append_byte(var.buf, type_flags); /* Type Specific Flags */
> +    return var;
> +}
> +
> +/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
> +static AcpiAml acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> +                                 acpiMaxFixed max_fixed, acpiDecode dec,
> +                                 uint16_t addr_gran, uint16_t addr_min,
> +                                 uint16_t addr_max, uint16_t addr_trans,
> +                                 uint16_t len, uint8_t type_flags)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +
> +    build_append_byte(var.buf, 0x88); /* Word Address Space Descriptor */
> +    /* minimum length since we do not encode optional fields */
> +    build_append_byte(var.buf, 0x0D);
> +    build_append_byte(var.buf, 0x0);
> +
> +    aml_append(&var,
> +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> +    build_append_value(var.buf, len, sizeof(len));
> +    return var;
> +}
> +
> +/* ACPI 5.0: 6.4.3.5.2 DWord Address Space Descriptor */
> +static AcpiAml acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> +                                  acpiMaxFixed max_fixed, acpiDecode dec,
> +                                  uint32_t addr_gran, uint32_t addr_min,
> +                                  uint32_t addr_max, uint32_t addr_trans,
> +                                  uint32_t len, uint8_t type_flags)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +
> +    build_append_byte(var.buf, 0x87); /* DWord Address Space Descriptor */
> +    /* minimum length since we do not encode optional fields */
> +    build_append_byte(var.buf, 23);
> +    build_append_byte(var.buf, 0x0);
> +
> +
> +    aml_append(&var,
> +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> +    build_append_value(var.buf, len, sizeof(len));
> +    return var;
> +}
> +
> +/* ACPI 5.0: 6.4.3.5.1 QWord Address Space Descriptor */
> +static AcpiAml acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> +                                  acpiMaxFixed max_fixed, acpiDecode dec,
> +                                  uint64_t addr_gran, uint64_t addr_min,
> +                                  uint64_t addr_max, uint64_t addr_trans,
> +                                  uint64_t len, uint8_t type_flags)
> +{
> +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> +
> +    build_append_byte(var.buf, 0x8A); /* QWord Address Space Descriptor */
> +    /* minimum length since we do not encode optional fields */
> +    build_append_byte(var.buf, 0x2B);
> +    build_append_byte(var.buf, 0x0);
> +
> +    aml_append(&var,
> +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> +    build_append_value(var.buf, len, sizeof(len));
> +    return var;
> +}
> +
> +/*
> + * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
> + */
> +AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> +                             acpiDecode dec, uint16_t addr_gran,
> +                             uint16_t addr_min, uint16_t addr_max,
> +                             uint16_t addr_trans, uint16_t len)
> +
> +{
> +    return acpi_word_as_desc(acpi_bus_number_range, min_fixed, max_fixed, dec,
> +                             addr_gran, addr_min, addr_max, addr_trans, len, 0);
> +}
> +
> +/* ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro) */
> +AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> +                     acpiDecode dec, acpiISARanges isa_ranges,
> +                     uint16_t addr_gran, uint16_t addr_min,
> +                     uint16_t addr_max, uint16_t addr_trans,
> +                     uint16_t len)
> +
> +{
> +    return acpi_word_as_desc(acpi_io_range, min_fixed, max_fixed, dec,
> +                             addr_gran, addr_min, addr_max, addr_trans, len,
> +                             isa_ranges);
> +}
> +
> +/* ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro) */
> +AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> +                          acpiReadAndWrite read_and_write,
> +                          uint32_t addr_gran, uint32_t addr_min,
> +                          uint32_t addr_max, uint32_t addr_trans,
> +                          uint32_t len)
> +{
> +    uint8_t flags = read_and_write | (cacheable << 1);
> +
> +    return acpi_dword_as_desc(acpi_memory_range, min_fixed, max_fixed,
> +                              dec, addr_gran, addr_min, addr_max,
> +                              addr_trans, len, flags);
> +}
> +
> +/* ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro) */
> +AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> +                          acpiReadAndWrite read_and_write,
> +                          uint64_t addr_gran, uint64_t addr_min,
> +                          uint64_t addr_max, uint64_t addr_trans,
> +                          uint64_t len)
> +{
> +    uint8_t flags = read_and_write | (cacheable << 1);
> +
> +    return acpi_qword_as_desc(acpi_memory_range, min_fixed, max_fixed,
> +                              dec, addr_gran, addr_min, addr_max,
> +                              addr_trans, len, flags);
> +}
> diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> index 048ed26..5e8db3d 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -38,6 +38,58 @@ typedef enum {
>       acpi_system_io = 0x01,
>   } acpiRegionSpace;
      ^^^
I am sorry for repeating myself, the same for others

Thanks,
Marcel
>
> +typedef enum {
> +    acpi_memory_range = 0,
> +    acpi_io_range = 1,
> +    acpi_bus_number_range = 2,
> +} acpiResourceType;
> +
> +typedef enum {
> +    acpi_sub_decode = 1 << 1,
> +    acpi_pos_decode = 0
> +} acpiDecode;
> +
> +typedef enum {
> +    acpi_max_fixed = 1 << 3,
> +    acpi_max_not_fixed = 0,
> +} acpiMaxFixed;
> +
> +typedef enum {
> +    acpi_min_fixed = 1 << 2,
> +    acpi_min_not_fixed = 0
> +} acpiMinFixed;
> +
> +/*
> + * ACPI 5.0: Table 6-185 I/O Resource Flag (Resource Type = 1) Definitions
> + * _RNG field definition
> + */
> +typedef enum {
> +    acpi_isa_only = 1,
> +    acpi_non_isa_only = 2,
> +    acpi_entire_range = 3,
> +} acpiISARanges;
> +
> +/*
> + * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
> + * _MEM field definition
> + */
> +typedef enum {
> +    acpi_non_cacheable = 0,
> +    acpi_cacheable = 1,
> +    acpi_write_combining = 2,
> +    acpi_prefetchable = 3,
> +} acpiCacheble;
> +
> +/*
> + * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
> + * _RW field definition
> + */
> +typedef enum {
> +    acpi_ReadOnly = 0,
> +    acpi_ReadWrite = 1,
> +} acpiReadAndWrite;
> +
> +
>   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
>
>   /* non block ASL object primitives */
> @@ -71,6 +123,27 @@ AcpiAml GCC_FMT_ATTR(4, 5)
>   acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
>                  const char *name_format, ...);
>   AcpiAml acpi_eisaid(const char *str);
> +AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> +                             acpiDecode dec, uint16_t addr_gran,
> +                             uint16_t addr_min, uint16_t addr_max,
> +                             uint16_t addr_trans, uint16_t len);
> +AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> +                     acpiDecode dec, acpiISARanges isa_ranges,
> +                     uint16_t addr_gran, uint16_t addr_min,
> +                     uint16_t addr_max, uint16_t addr_trans,
> +                     uint16_t len);
> +AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> +                          acpiReadAndWrite read_and_write,
> +                          uint32_t addr_gran, uint32_t addr_min,
> +                          uint32_t addr_max, uint32_t addr_trans,
> +                          uint32_t len);
> +AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> +                          acpiReadAndWrite read_and_write,
> +                          uint64_t addr_gran, uint64_t addr_min,
> +                          uint64_t addr_max, uint64_t addr_trans,
> +                          uint64_t len);
>
>   /* Block ASL object primitives */
>   AcpiAml acpi_if(AcpiAml predicate);
>

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

* Re: [Qemu-devel] [PATCH 00/13] convert AML API to QOM
  2015-02-05 14:28                                 ` Marcel Apfelbaum
@ 2015-02-05 17:36                                   ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-05 17:36 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: Andrew Jones, marcel.a, claudio.fontana, qemu-devel,
	zhaoshenglong, pbonzini

On Thu, 05 Feb 2015 16:28:03 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/28/2015 02:44 PM, Andrew Jones wrote:
> > On Wed, Jan 28, 2015 at 10:03:24AM +0000, Igor Mammedov wrote:
> >>
> >> Example demonstrates use of QOM object for building AML
> >> objects tree and freeing it explicitly when requested.
> >>
> >> Top level ACPI tables blob object is only partially
> >> switched to object model now but I hope it demostrates
> >> the point of absracting code and hiding parts of code
> >> that could be done without user intervention.
> >>
> >> Pathes 1/2/8 are just a convertion boiler plate which
> >> will go away on respin.
> >>
> >>
> >> Igor Mammedov (13):
> >>    convert to passing AcpiAml by pointers
> >>    make toplevel ACPI tables blob a pointer
> >>    qom: add support for weak referenced object: aka UnownedObject
> >>    acpi: make AcpiAml an OQM object
> >>    acpi: use TYPE_AML_OBJECT inside of AML API
> >>    acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob
> >>    acpi: make toplevel ACPI tables blob a dedicated object
> >>    i386: acpi: hack not yet converted tables calls to deal with
> >>      table_data being a pointer
> >>    acpi: add aml_blob() helper
> >>    i386: acpi: add DSDT table using AML API
> >>    acpi: acpi_add_table() to common cross target file
> >>    acpi: prepare for API internal collection of RSDT entries
> >>    i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT
> >>      automatically
> >>
> >>   hw/acpi/acpi-build-utils.c         | 537 +++++++++++++++++++++----------------
> >>   hw/i386/acpi-build.c               | 388 +++++++++++++--------------
> >>   include/hw/acpi/acpi-build-utils.h | 119 +++++---
> >>   include/qom/object.h               |  20 ++
> >>   qom/object.c                       |  20 +-
> >>   5 files changed, 620 insertions(+), 464 deletions(-)
> >>
> >> --
> >> 1.8.3.1
> >>
> >
> > Thanks for doing this.
> Thanks also fomr me! It is really  interesting to see this.
> 
>   It's satisfied my curiosity as to how
> > much boilerplate we'd need for the conversion. I looked mainly
> > at the first half of this series, as it appears the second half
> > is an add-on, not directly relevant to the explicit memory
> > management vs. object model memory management discussion. The
> > additional code, and need for QOM knowledge, appears pretty low.
> > So, as this would allow developers focused on ACPI table
> > construction to almost completely avoid doing any memory
> > management themselves, then, FWIW, it looks like a good trade
> > off to me.
> 
> While I am not against this approach, maybe a simpler idea of keeping
> an internal static map of allocated vars and freeing it in the end would be enough.
> 
> That being said, this approach gives us the opportunity to create QOM objects
> for all AML constructs as AcpiArg for example:
>      AcpiAml arg = object_new(ACPI_ARG_TYPE);
> and handling the implementation inside the corresponding init function.
That was my idea bind using QOM,
later we could slowly split different AML constructs into different types
and e.t.c., which helps to abstract code and override with inherited
target specific types.

But we could switch to QOM later when we have to without affecting users,
since external API will stay the same.

> 
> Thanks,
> Marcel
> 
> >
> > drew
> >
> 
> 

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

* Re: [Qemu-devel] [PATCH v2 05/47] acpi: add acpi_if() term
  2015-02-05 15:01   ` Marcel Apfelbaum
@ 2015-02-05 17:54     ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-05 17:54 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, mst, claudio.fontana, qemu-devel, pbonzini

On Thu, 05 Feb 2015 17:01:33 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/22/2015 04:49 PM, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >   hw/acpi/acpi-build-utils.c         | 8 ++++++++
> >   include/hw/acpi/acpi-build-utils.h | 1 +
> >   2 files changed, 9 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index d0b0159..40a1769 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -314,6 +314,14 @@ static AcpiAml aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
> >       return var;
> >   }
> >
> > +/* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> > +AcpiAml acpi_if(AcpiAml predicate)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0xA0 /* IfOp */, PACKAGE);
> > +    aml_append(&var, predicate);
> > +    return var;
> > +}
> There are other ACPI constructs exactly like the above, except
> the operation number (0xA0).
> Maybe we can have a generic internal function and the API
> will call it.
> 
> For example IfWhile has the same structure except the op number,
> and maybe many other Type 1 Opcodes.
since wrappers are trivial and very simple I'd prefer to keep 2 similar
functions than 2 wrappers and more generic one, which would force
me to jump around code when reading it.
It also helps to compare functions with ABNF for term in spec.


> 
> Thanks,
> Marcel
> 
> > +
> >   /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefMethod */
> >   AcpiAml acpi_method(const char *name, int arg_count)
> >   {
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 19ebc2d..177f9ed 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -22,6 +22,7 @@ typedef struct AcpiAml {
> >   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> >
> >   /* Block ASL object primitives */
> > +AcpiAml acpi_if(AcpiAml predicate);
> >   AcpiAml acpi_method(const char *name, int arg_count);
> >   AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
> >   AcpiAml GCC_FMT_ATTR(1, 2) acpi_device(const char *name_format, ...);
> >
> 

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

* Re: [Qemu-devel] [PATCH v2 22/47] acpi: add acpi_io() helper
  2015-02-05 15:19   ` Marcel Apfelbaum
@ 2015-02-05 17:56     ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-05 17:56 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, mst, claudio.fontana, qemu-devel, pbonzini

On Thu, 05 Feb 2015 17:19:39 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >   hw/acpi/acpi-build-utils.c         | 19 +++++++++++++++++++
> >   include/hw/acpi/acpi-build-utils.h |  7 +++++++
> >   2 files changed, 26 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 32a4377..56b237a 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -454,6 +454,25 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
> >       return var;
> >   }
> >
> > +/*
> > + * ACPI 5.0: 19.5.62 IO (IO Resource Descriptor Macro)
> > + *           6.4.2 Small Resource Data Type
> > +*/
> > +AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> > +                uint8_t aln, uint8_t len)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    build_append_byte(var.buf, 0x47); /* IO port descriptor */
> > +    build_append_byte(var.buf, dec);
> > +    build_append_byte(var.buf, min_base & 0xff);
> > +    build_append_byte(var.buf, (min_base >> 8) & 0xff);
> > +    build_append_byte(var.buf, max_base & 0xff);
> > +    build_append_byte(var.buf, (max_base >> 8) & 0xff);
> > +    build_append_byte(var.buf, aln);
> > +    build_append_byte(var.buf, len);
> > +    return var;
> > +}
> > +
> >   /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
> >   AcpiAml acpi_if(AcpiAml predicate)
> >   {
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 594fae7..91575f1 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -19,6 +19,11 @@ typedef struct AcpiAml {
> >       AcpiBlockFlags block_flags;
> >   } AcpiAml;
> >
> > +typedef enum {
> > +    acpi_decode10 = 0,
> > +    acpi_decode16 = 1,
> > +} acpiIODecode;
> A really small comment, you mean AcpiIODecode and not acpiIODecode, right?
Yep, it is renamed to AmlIODecode in coming v3.
You can see intermediate result on github.

> 
> Thanks,
> Marcel
> 
> > +
> >   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> >
> >   /* non block ASL object primitives */
> > @@ -39,6 +44,8 @@ AcpiAml acpi_call3(const char *method, AcpiAml arg1, AcpiAml arg2,
> >                      AcpiAml arg3);
> >   AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
> >                      AcpiAml arg3, AcpiAml arg4);
> > +AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> > +                uint8_t aln, uint8_t len);
> >
> >   /* Block ASL object primitives */
> >   AcpiAml acpi_if(AcpiAml predicate);
> >
> 

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

* Re: [Qemu-devel] [PATCH v2 24/47] acpi: add acpi_operation_region() term
  2015-02-05 15:28   ` Marcel Apfelbaum
@ 2015-02-05 17:57     ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-05 17:57 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, mst, claudio.fontana, qemu-devel, pbonzini

On Thu, 05 Feb 2015 17:28:39 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >   hw/acpi/acpi-build-utils.c         | 14 ++++++++++++++
> >   include/hw/acpi/acpi-build-utils.h |  7 +++++++
> >   2 files changed, 21 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 094c821..9ac5a0d 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -544,3 +544,17 @@ AcpiAml acpi_package(uint8_t num_elements)
> >       build_append_byte(var.buf, num_elements);
> >       return var;
> >   }
> > +
> > +/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefOpRegion */
> > +AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
> > +                              uint32_t offset, uint32_t len)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    build_append_byte(var.buf, 0x5B); /* ExtOpPrefix */
> > +    build_append_byte(var.buf, 0x80); /* OpRegionOp */
> > +    build_append_namestring(var.buf, "%s", name);
> > +    build_append_byte(var.buf, rs);
> > +    build_append_int(var.buf, offset);
> > +    build_append_int(var.buf, len);
> > +    return var;
> > +}
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 176596e..cb45129 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -24,6 +24,11 @@ typedef enum {
> >       acpi_decode16 = 1,
> >   } acpiIODecode;
>       ^^^
> Why do you want enums to no start with capital letters?
fixed

> 
> Thanks,
> Marcel
> 
> >
> > +typedef enum {
> > +    acpi_system_memory = 0x00,
> > +    acpi_system_io = 0x01,
> > +} acpiRegionSpace;
> > +
> >   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> >
> >   /* non block ASL object primitives */
> > @@ -46,6 +51,8 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
> >                      AcpiAml arg3, AcpiAml arg4);
> >   AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> >                   uint8_t aln, uint8_t len);
> > +AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
> > +                              uint32_t offset, uint32_t len);
> >
> >   /* Block ASL object primitives */
> >   AcpiAml acpi_if(AcpiAml predicate);
> >
> 

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

* Re: [Qemu-devel] [PATCH v2 35/47] acpi: add acpi_reserved_field() term
  2015-02-05 15:36   ` Marcel Apfelbaum
@ 2015-02-05 17:57     ` Igor Mammedov
  0 siblings, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-05 17:57 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, mst, claudio.fontana, qemu-devel, pbonzini

On Thu, 05 Feb 2015 17:36:16 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >   hw/acpi/acpi-build-utils.c         | 10 ++++++++++
> >   include/hw/acpi/acpi-build-utils.h |  6 ++++++
> >   2 files changed, 16 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index cbc1241..644af1f 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -591,6 +591,16 @@ AcpiAml acpi_named_field(const char *name, unsigned length)
> >       return var;
> >   }
> >
> > +/* ACPI 5.0: 20.2.5.2 Named Objects Encoding: ReservedField */
> > +AcpiAml acpi_reserved_field(unsigned length)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +    /* ReservedField  := 0x00 PkgLength */
> > +    build_append_byte(var.buf, 0x00);
> > +    build_append_pkg_length(var.buf, length, false);
> > +    return var;
> > +}
> > +
> >   /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefField */
> >   AcpiAml acpi_field(const char *name, acpiFieldFlags flags)
> >   {
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 02d5aa8..048ed26 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -25,7 +25,12 @@ typedef enum {
> >   } acpiIODecode;
>      ^^^
> >
> >   typedef enum {
> > +    acpi_any_acc = 0,
> >       acpi_byte_acc = 1,
> > +    acpi_word_acc = 2,
> > +    acpi_dword_acc = 3,
> > +    acpi_qword_acc = 4,
> > +    acpi_buffer_acc = 5,
> >   } acpiFieldFlags;
>       ^^^
> I missed that, is there any way it was like that already? Do we have such
> a coding convention on QEMU?
Fixed

> 
> Thanks,
> Marcel
> 
> >
> >   typedef enum {
> > @@ -58,6 +63,7 @@ AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
> >   AcpiAml acpi_operation_region(const char *name, acpiRegionSpace rs,
> >                                 uint32_t offset, uint32_t len);
> >   AcpiAml acpi_named_field(const char *name, unsigned length);
> > +AcpiAml acpi_reserved_field(unsigned length);
> >   AcpiAml GCC_FMT_ATTR(1, 2) acpi_string(const char *name_format, ...);
> >   AcpiAml acpi_local0(void);
> >   AcpiAml acpi_equal(AcpiAml arg1, AcpiAml arg2);
> >
> 

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

* Re: [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms
  2015-02-05 15:38   ` Marcel Apfelbaum
@ 2015-02-05 17:58     ` Igor Mammedov
  2015-02-05 17:59     ` Igor Mammedov
  1 sibling, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-05 17:58 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, mst, claudio.fontana, qemu-devel, pbonzini

On Thu, 05 Feb 2015 17:38:17 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >   hw/acpi/acpi-build-utils.c         | 143 +++++++++++++++++++++++++++++++++++++
> >   include/hw/acpi/acpi-build-utils.h |  73 +++++++++++++++++++
> >   2 files changed, 216 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 644af1f..b19d370 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -700,3 +700,146 @@ AcpiAml acpi_eisaid(const char *str)
> >       build_append_value(var.buf, bswap32(id), sizeof(id));
> >       return var;
> >   }
> > +
> > +/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
> > +static AcpiAml
> > +acpi_as_desc_header(acpiResourceType type, acpiMinFixed min_fixed,
> > +                    acpiMaxFixed max_fixed, acpiDecode dec, uint8_t type_flags)
> > +{
> > +    uint8_t flags = max_fixed | min_fixed | dec;
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, type);
> > +    build_append_byte(var.buf, flags);
> > +    build_append_byte(var.buf, type_flags); /* Type Specific Flags */
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
> > +static AcpiAml acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> > +                                 acpiMaxFixed max_fixed, acpiDecode dec,
> > +                                 uint16_t addr_gran, uint16_t addr_min,
> > +                                 uint16_t addr_max, uint16_t addr_trans,
> > +                                 uint16_t len, uint8_t type_flags)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, 0x88); /* Word Address Space Descriptor */
> > +    /* minimum length since we do not encode optional fields */
> > +    build_append_byte(var.buf, 0x0D);
> > +    build_append_byte(var.buf, 0x0);
> > +
> > +    aml_append(&var,
> > +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> > +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> > +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> > +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> > +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> > +    build_append_value(var.buf, len, sizeof(len));
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 6.4.3.5.2 DWord Address Space Descriptor */
> > +static AcpiAml acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> > +                                  acpiMaxFixed max_fixed, acpiDecode dec,
> > +                                  uint32_t addr_gran, uint32_t addr_min,
> > +                                  uint32_t addr_max, uint32_t addr_trans,
> > +                                  uint32_t len, uint8_t type_flags)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, 0x87); /* DWord Address Space Descriptor */
> > +    /* minimum length since we do not encode optional fields */
> > +    build_append_byte(var.buf, 23);
> > +    build_append_byte(var.buf, 0x0);
> > +
> > +
> > +    aml_append(&var,
> > +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> > +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> > +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> > +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> > +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> > +    build_append_value(var.buf, len, sizeof(len));
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 6.4.3.5.1 QWord Address Space Descriptor */
> > +static AcpiAml acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> > +                                  acpiMaxFixed max_fixed, acpiDecode dec,
> > +                                  uint64_t addr_gran, uint64_t addr_min,
> > +                                  uint64_t addr_max, uint64_t addr_trans,
> > +                                  uint64_t len, uint8_t type_flags)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, 0x8A); /* QWord Address Space Descriptor */
> > +    /* minimum length since we do not encode optional fields */
> > +    build_append_byte(var.buf, 0x2B);
> > +    build_append_byte(var.buf, 0x0);
> > +
> > +    aml_append(&var,
> > +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> > +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> > +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> > +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> > +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> > +    build_append_value(var.buf, len, sizeof(len));
> > +    return var;
> > +}
> > +
> > +/*
> > + * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
> > + */
> > +AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                             acpiDecode dec, uint16_t addr_gran,
> > +                             uint16_t addr_min, uint16_t addr_max,
> > +                             uint16_t addr_trans, uint16_t len)
> > +
> > +{
> > +    return acpi_word_as_desc(acpi_bus_number_range, min_fixed, max_fixed, dec,
> > +                             addr_gran, addr_min, addr_max, addr_trans, len, 0);
> > +}
> > +
> > +/* ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro) */
> > +AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                     acpiDecode dec, acpiISARanges isa_ranges,
> > +                     uint16_t addr_gran, uint16_t addr_min,
> > +                     uint16_t addr_max, uint16_t addr_trans,
> > +                     uint16_t len)
> > +
> > +{
> > +    return acpi_word_as_desc(acpi_io_range, min_fixed, max_fixed, dec,
> > +                             addr_gran, addr_min, addr_max, addr_trans, len,
> > +                             isa_ranges);
> > +}
> > +
> > +/* ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro) */
> > +AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint32_t addr_gran, uint32_t addr_min,
> > +                          uint32_t addr_max, uint32_t addr_trans,
> > +                          uint32_t len)
> > +{
> > +    uint8_t flags = read_and_write | (cacheable << 1);
> > +
> > +    return acpi_dword_as_desc(acpi_memory_range, min_fixed, max_fixed,
> > +                              dec, addr_gran, addr_min, addr_max,
> > +                              addr_trans, len, flags);
> > +}
> > +
> > +/* ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro) */
> > +AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint64_t addr_gran, uint64_t addr_min,
> > +                          uint64_t addr_max, uint64_t addr_trans,
> > +                          uint64_t len)
> > +{
> > +    uint8_t flags = read_and_write | (cacheable << 1);
> > +
> > +    return acpi_qword_as_desc(acpi_memory_range, min_fixed, max_fixed,
> > +                              dec, addr_gran, addr_min, addr_max,
> > +                              addr_trans, len, flags);
> > +}
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 048ed26..5e8db3d 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -38,6 +38,58 @@ typedef enum {
> >       acpi_system_io = 0x01,
> >   } acpiRegionSpace;
>       ^^^
> I am sorry for repeating myself, the same for others
Thanks,
fixed

> 
> Thanks,
> Marcel
> >
> > +typedef enum {
> > +    acpi_memory_range = 0,
> > +    acpi_io_range = 1,
> > +    acpi_bus_number_range = 2,
> > +} acpiResourceType;
> > +
> > +typedef enum {
> > +    acpi_sub_decode = 1 << 1,
> > +    acpi_pos_decode = 0
> > +} acpiDecode;
> > +
> > +typedef enum {
> > +    acpi_max_fixed = 1 << 3,
> > +    acpi_max_not_fixed = 0,
> > +} acpiMaxFixed;
> > +
> > +typedef enum {
> > +    acpi_min_fixed = 1 << 2,
> > +    acpi_min_not_fixed = 0
> > +} acpiMinFixed;
> > +
> > +/*
> > + * ACPI 5.0: Table 6-185 I/O Resource Flag (Resource Type = 1) Definitions
> > + * _RNG field definition
> > + */
> > +typedef enum {
> > +    acpi_isa_only = 1,
> > +    acpi_non_isa_only = 2,
> > +    acpi_entire_range = 3,
> > +} acpiISARanges;
> > +
> > +/*
> > + * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
> > + * _MEM field definition
> > + */
> > +typedef enum {
> > +    acpi_non_cacheable = 0,
> > +    acpi_cacheable = 1,
> > +    acpi_write_combining = 2,
> > +    acpi_prefetchable = 3,
> > +} acpiCacheble;
> > +
> > +/*
> > + * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
> > + * _RW field definition
> > + */
> > +typedef enum {
> > +    acpi_ReadOnly = 0,
> > +    acpi_ReadWrite = 1,
> > +} acpiReadAndWrite;
> > +
> > +
> >   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> >
> >   /* non block ASL object primitives */
> > @@ -71,6 +123,27 @@ AcpiAml GCC_FMT_ATTR(4, 5)
> >   acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
> >                  const char *name_format, ...);
> >   AcpiAml acpi_eisaid(const char *str);
> > +AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                             acpiDecode dec, uint16_t addr_gran,
> > +                             uint16_t addr_min, uint16_t addr_max,
> > +                             uint16_t addr_trans, uint16_t len);
> > +AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                     acpiDecode dec, acpiISARanges isa_ranges,
> > +                     uint16_t addr_gran, uint16_t addr_min,
> > +                     uint16_t addr_max, uint16_t addr_trans,
> > +                     uint16_t len);
> > +AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint32_t addr_gran, uint32_t addr_min,
> > +                          uint32_t addr_max, uint32_t addr_trans,
> > +                          uint32_t len);
> > +AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint64_t addr_gran, uint64_t addr_min,
> > +                          uint64_t addr_max, uint64_t addr_trans,
> > +                          uint64_t len);
> >
> >   /* Block ASL object primitives */
> >   AcpiAml acpi_if(AcpiAml predicate);
> >
> 

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

* Re: [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms
  2015-02-05 15:38   ` Marcel Apfelbaum
  2015-02-05 17:58     ` Igor Mammedov
@ 2015-02-05 17:59     ` Igor Mammedov
  1 sibling, 0 replies; 128+ messages in thread
From: Igor Mammedov @ 2015-02-05 17:59 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: drjones, marcel.a, mst, claudio.fontana, qemu-devel, pbonzini

On Thu, 05 Feb 2015 17:38:17 +0200
Marcel Apfelbaum <marcel@redhat.com> wrote:

> On 01/22/2015 04:50 PM, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >   hw/acpi/acpi-build-utils.c         | 143 +++++++++++++++++++++++++++++++++++++
> >   include/hw/acpi/acpi-build-utils.h |  73 +++++++++++++++++++
> >   2 files changed, 216 insertions(+)
> >
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index 644af1f..b19d370 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -700,3 +700,146 @@ AcpiAml acpi_eisaid(const char *str)
> >       build_append_value(var.buf, bswap32(id), sizeof(id));
> >       return var;
> >   }
> > +
> > +/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
> > +static AcpiAml
> > +acpi_as_desc_header(acpiResourceType type, acpiMinFixed min_fixed,
> > +                    acpiMaxFixed max_fixed, acpiDecode dec, uint8_t type_flags)
> > +{
> > +    uint8_t flags = max_fixed | min_fixed | dec;
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, type);
> > +    build_append_byte(var.buf, flags);
> > +    build_append_byte(var.buf, type_flags); /* Type Specific Flags */
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 6.4.3.5.3 Word Address Space Descriptor */
> > +static AcpiAml acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> > +                                 acpiMaxFixed max_fixed, acpiDecode dec,
> > +                                 uint16_t addr_gran, uint16_t addr_min,
> > +                                 uint16_t addr_max, uint16_t addr_trans,
> > +                                 uint16_t len, uint8_t type_flags)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, 0x88); /* Word Address Space Descriptor */
> > +    /* minimum length since we do not encode optional fields */
> > +    build_append_byte(var.buf, 0x0D);
> > +    build_append_byte(var.buf, 0x0);
> > +
> > +    aml_append(&var,
> > +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> > +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> > +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> > +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> > +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> > +    build_append_value(var.buf, len, sizeof(len));
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 6.4.3.5.2 DWord Address Space Descriptor */
> > +static AcpiAml acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> > +                                  acpiMaxFixed max_fixed, acpiDecode dec,
> > +                                  uint32_t addr_gran, uint32_t addr_min,
> > +                                  uint32_t addr_max, uint32_t addr_trans,
> > +                                  uint32_t len, uint8_t type_flags)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, 0x87); /* DWord Address Space Descriptor */
> > +    /* minimum length since we do not encode optional fields */
> > +    build_append_byte(var.buf, 23);
> > +    build_append_byte(var.buf, 0x0);
> > +
> > +
> > +    aml_append(&var,
> > +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> > +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> > +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> > +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> > +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> > +    build_append_value(var.buf, len, sizeof(len));
> > +    return var;
> > +}
> > +
> > +/* ACPI 5.0: 6.4.3.5.1 QWord Address Space Descriptor */
> > +static AcpiAml acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
> > +                                  acpiMaxFixed max_fixed, acpiDecode dec,
> > +                                  uint64_t addr_gran, uint64_t addr_min,
> > +                                  uint64_t addr_max, uint64_t addr_trans,
> > +                                  uint64_t len, uint8_t type_flags)
> > +{
> > +    AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
> > +
> > +    build_append_byte(var.buf, 0x8A); /* QWord Address Space Descriptor */
> > +    /* minimum length since we do not encode optional fields */
> > +    build_append_byte(var.buf, 0x2B);
> > +    build_append_byte(var.buf, 0x0);
> > +
> > +    aml_append(&var,
> > +        acpi_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
> > +    build_append_value(var.buf, addr_gran, sizeof(addr_gran));
> > +    build_append_value(var.buf, addr_min, sizeof(addr_min));
> > +    build_append_value(var.buf, addr_max, sizeof(addr_max));
> > +    build_append_value(var.buf, addr_trans, sizeof(addr_trans));
> > +    build_append_value(var.buf, len, sizeof(len));
> > +    return var;
> > +}
> > +
> > +/*
> > + * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
> > + */
> > +AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                             acpiDecode dec, uint16_t addr_gran,
> > +                             uint16_t addr_min, uint16_t addr_max,
> > +                             uint16_t addr_trans, uint16_t len)
> > +
> > +{
> > +    return acpi_word_as_desc(acpi_bus_number_range, min_fixed, max_fixed, dec,
> > +                             addr_gran, addr_min, addr_max, addr_trans, len, 0);
> > +}
> > +
> > +/* ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro) */
> > +AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                     acpiDecode dec, acpiISARanges isa_ranges,
> > +                     uint16_t addr_gran, uint16_t addr_min,
> > +                     uint16_t addr_max, uint16_t addr_trans,
> > +                     uint16_t len)
> > +
> > +{
> > +    return acpi_word_as_desc(acpi_io_range, min_fixed, max_fixed, dec,
> > +                             addr_gran, addr_min, addr_max, addr_trans, len,
> > +                             isa_ranges);
> > +}
> > +
> > +/* ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro) */
> > +AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint32_t addr_gran, uint32_t addr_min,
> > +                          uint32_t addr_max, uint32_t addr_trans,
> > +                          uint32_t len)
> > +{
> > +    uint8_t flags = read_and_write | (cacheable << 1);
> > +
> > +    return acpi_dword_as_desc(acpi_memory_range, min_fixed, max_fixed,
> > +                              dec, addr_gran, addr_min, addr_max,
> > +                              addr_trans, len, flags);
> > +}
> > +
> > +/* ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro) */
> > +AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint64_t addr_gran, uint64_t addr_min,
> > +                          uint64_t addr_max, uint64_t addr_trans,
> > +                          uint64_t len)
> > +{
> > +    uint8_t flags = read_and_write | (cacheable << 1);
> > +
> > +    return acpi_qword_as_desc(acpi_memory_range, min_fixed, max_fixed,
> > +                              dec, addr_gran, addr_min, addr_max,
> > +                              addr_trans, len, flags);
> > +}
> > diff --git a/include/hw/acpi/acpi-build-utils.h b/include/hw/acpi/acpi-build-utils.h
> > index 048ed26..5e8db3d 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -38,6 +38,58 @@ typedef enum {
> >       acpi_system_io = 0x01,
> >   } acpiRegionSpace;
>       ^^^
> I am sorry for repeating myself, the same for others
Thanks,
fixed

> 
> Thanks,
> Marcel
> >
> > +typedef enum {
> > +    acpi_memory_range = 0,
> > +    acpi_io_range = 1,
> > +    acpi_bus_number_range = 2,
> > +} acpiResourceType;
> > +
> > +typedef enum {
> > +    acpi_sub_decode = 1 << 1,
> > +    acpi_pos_decode = 0
> > +} acpiDecode;
> > +
> > +typedef enum {
> > +    acpi_max_fixed = 1 << 3,
> > +    acpi_max_not_fixed = 0,
> > +} acpiMaxFixed;
> > +
> > +typedef enum {
> > +    acpi_min_fixed = 1 << 2,
> > +    acpi_min_not_fixed = 0
> > +} acpiMinFixed;
> > +
> > +/*
> > + * ACPI 5.0: Table 6-185 I/O Resource Flag (Resource Type = 1) Definitions
> > + * _RNG field definition
> > + */
> > +typedef enum {
> > +    acpi_isa_only = 1,
> > +    acpi_non_isa_only = 2,
> > +    acpi_entire_range = 3,
> > +} acpiISARanges;
> > +
> > +/*
> > + * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
> > + * _MEM field definition
> > + */
> > +typedef enum {
> > +    acpi_non_cacheable = 0,
> > +    acpi_cacheable = 1,
> > +    acpi_write_combining = 2,
> > +    acpi_prefetchable = 3,
> > +} acpiCacheble;
> > +
> > +/*
> > + * ACPI 5.0: Table 6-184 Memory Resource Flag (Resource Type = 0) Definitions
> > + * _RW field definition
> > + */
> > +typedef enum {
> > +    acpi_ReadOnly = 0,
> > +    acpi_ReadWrite = 1,
> > +} acpiReadAndWrite;
> > +
> > +
> >   void aml_append(AcpiAml *parent_ctx, AcpiAml child);
> >
> >   /* non block ASL object primitives */
> > @@ -71,6 +123,27 @@ AcpiAml GCC_FMT_ATTR(4, 5)
> >   acpi_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
> >                  const char *name_format, ...);
> >   AcpiAml acpi_eisaid(const char *str);
> > +AcpiAml acpi_word_bus_number(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                             acpiDecode dec, uint16_t addr_gran,
> > +                             uint16_t addr_min, uint16_t addr_max,
> > +                             uint16_t addr_trans, uint16_t len);
> > +AcpiAml acpi_word_io(acpiMinFixed min_fixed, acpiMaxFixed max_fixed,
> > +                     acpiDecode dec, acpiISARanges isa_ranges,
> > +                     uint16_t addr_gran, uint16_t addr_min,
> > +                     uint16_t addr_max, uint16_t addr_trans,
> > +                     uint16_t len);
> > +AcpiAml acpi_dword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint32_t addr_gran, uint32_t addr_min,
> > +                          uint32_t addr_max, uint32_t addr_trans,
> > +                          uint32_t len);
> > +AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed min_fixed,
> > +                          acpiMaxFixed max_fixed, acpiCacheble cacheable,
> > +                          acpiReadAndWrite read_and_write,
> > +                          uint64_t addr_gran, uint64_t addr_min,
> > +                          uint64_t addr_max, uint64_t addr_trans,
> > +                          uint64_t len);
> >
> >   /* Block ASL object primitives */
> >   AcpiAml acpi_if(AcpiAml predicate);
> >
> 

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

end of thread, other threads:[~2015-02-05 17:59 UTC | newest]

Thread overview: 128+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-22 14:49 [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Igor Mammedov
2015-01-23  8:03   ` Michael S. Tsirkin
2015-01-23 10:03     ` Igor Mammedov
2015-01-23 13:26       ` Michael S. Tsirkin
2015-01-23  8:11   ` Michael S. Tsirkin
2015-01-23 10:35     ` Igor Mammedov
2015-01-23 13:24       ` Michael S. Tsirkin
2015-01-23 13:40         ` Igor Mammedov
2015-01-23 13:55           ` Michael S. Tsirkin
2015-01-23 17:56             ` Igor Mammedov
2015-01-24 16:33               ` Michael S. Tsirkin
2015-01-26  9:57                 ` Igor Mammedov
2015-01-26 10:37                   ` Michael S. Tsirkin
2015-01-26 15:09                   ` Igor Mammedov
2015-01-26 15:34                     ` Andrew Jones
2015-01-26 16:17                       ` Michael S. Tsirkin
2015-01-27 22:29                         ` Igor Mammedov
2015-01-28  7:27                           ` Michael S. Tsirkin
2015-01-28 10:03                             ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 01/13] convert to passing AcpiAml by pointers Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 02/13] make toplevel ACPI tables blob a pointer Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 03/13] qom: add support for weak referenced object: aka UnownedObject Igor Mammedov
2015-01-28 10:09                                 ` Paolo Bonzini
2015-01-28 12:55                                   ` Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 04/13] acpi: make AcpiAml an OQM object Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 05/13] acpi: use TYPE_AML_OBJECT inside of AML API Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 06/13] acpi: use TYPE_AML_OBJECT for toplevel ACPI tables blob Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 07/13] acpi: make toplevel ACPI tables blob a dedicated object Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 08/13] i386: acpi: hack not yet converted tables calls to deal with table_data being a pointer Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 09/13] acpi: add aml_blob() helper Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 10/13] i386: acpi: add DSDT table using AML API Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 11/13] acpi: acpi_add_table() to common cross target file Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 12/13] acpi: prepare for API internal collection of RSDT entries Igor Mammedov
2015-01-28 10:03                               ` [Qemu-devel] [PATCH 13/13] i386: acpi: mark SSDT as RSDT entry so API would add entry to RSDT automatically Igor Mammedov
2015-01-28 12:44                               ` [Qemu-devel] [PATCH 00/13] convert AML API to QOM Andrew Jones
2015-02-05 14:28                                 ` Marcel Apfelbaum
2015-02-05 17:36                                   ` Igor Mammedov
2015-01-28  7:56                           ` [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append() Michael S. Tsirkin
2015-01-28 10:00                             ` Igor Mammedov
2015-01-28 10:24                               ` Michael S. Tsirkin
2015-01-28 10:50                                 ` Igor Mammedov
2015-01-28 13:12                                   ` Michael S. Tsirkin
2015-01-28 10:32                               ` Claudio Fontana
2015-01-29  7:46                               ` Shannon Zhao
2015-01-29  8:42                                 ` Igor Mammedov
2015-02-05 14:35                               ` Marcel Apfelbaum
2015-01-28 10:45                             ` Andrew Jones
2015-02-05 14:30                             ` Marcel Apfelbaum
2015-02-05 14:09                           ` Marcel Apfelbaum
2015-01-23  9:14   ` Michael S. Tsirkin
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 02/47] acpi: add acpi_scope() term Igor Mammedov
2015-01-23  8:02   ` Michael S. Tsirkin
2015-01-23 10:36     ` Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 03/47] acpi: add acpi_device() term Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 04/47] acpi: add acpi_method() term Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 05/47] acpi: add acpi_if() term Igor Mammedov
2015-02-05 15:01   ` Marcel Apfelbaum
2015-02-05 17:54     ` Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 06/47] acpi: add acpi_name() & acpi_name_decl() term Igor Mammedov
2015-01-23  8:59   ` Michael S. Tsirkin
2015-01-23 13:32     ` Igor Mammedov
2015-01-23 13:42       ` Michael S. Tsirkin
2015-02-02 16:04         ` Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 07/47] acpi: factor out ACPI const int packing out build_append_value() Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 08/47] acpi: extend build_append_{value|int}() to support 64-bit values Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 09/47] acpi: add acpi_int() term Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 10/47] acpi: add acpi_return() term Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 11/47] acpi: add acpi_arg0(), acpi_arg1(), acpi_arg2(), acpi_arg3() terms Igor Mammedov
2015-01-23  8:32   ` Marcel Apfelbaum
2015-01-23  9:35     ` Michael S. Tsirkin
2015-01-23 13:34     ` Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 12/47] acpi: add acpi_store() term Igor Mammedov
2015-02-05 15:06   ` Marcel Apfelbaum
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 13/47] acpi: add acpi_and() term Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 14/47] acpi: add acpi_notify() term Igor Mammedov
2015-01-22 14:49 ` [Qemu-devel] [PATCH v2 15/47] acpi: add acpi_call1(), acpi_call2(), acpi_call3(), acpi_call4() helpers Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 16/47] pc: acpi-build: drop template patching and create PCI bus tree dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 17/47] acpi: add acpi_package() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 18/47] pc: acpi-build: drop unsupported PM1b_CNT.SLP_TYP Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 19/47] pc: acpi-build: generate _S[345] packages dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 20/47] acpi: add acpi_buffer() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 21/47] acpi: add acpi_resource_template() helper Igor Mammedov
2015-01-27 13:26   ` Claudio Fontana
2015-01-27 13:41     ` Michael S. Tsirkin
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 22/47] acpi: add acpi_io() helper Igor Mammedov
2015-02-05 15:19   ` Marcel Apfelbaum
2015-02-05 17:56     ` Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 23/47] acpi: include PkgLength size only when requested Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 24/47] acpi: add acpi_operation_region() term Igor Mammedov
2015-02-05 15:28   ` Marcel Apfelbaum
2015-02-05 17:57     ` Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 25/47] acpi: add acpi_field() & acpi_named_field() terms Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 26/47] acpi: add acpi_local0() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 27/47] acpi: add acpi_string() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 28/47] pc: acpi-build: generate pvpanic device description dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 29/47] acpi: add acpi_varpackage() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 30/47] acpi: add acpi_equal() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 31/47] acpi: add acpi_processor() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 32/47] acpi: add acpi_eisaid() term Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 33/47] pc: acpi-build: drop template patching and CPU hotplug objects dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 34/47] pc: acpi-build: create CPU hotplug IO region dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 35/47] acpi: add acpi_reserved_field() term Igor Mammedov
2015-02-05 15:36   ` Marcel Apfelbaum
2015-02-05 17:57     ` Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 36/47] pc: acpi-build: drop template patching and memory hotplug objects dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 37/47] pc: acpi-build: create memory hotplug IO region dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 38/47] acpi: add acpi_word_bus_number(), acpi_word_io(), acpi_dword_memory(), acpi_qword_memory() terms Igor Mammedov
2015-02-05 15:38   ` Marcel Apfelbaum
2015-02-05 17:58     ` Igor Mammedov
2015-02-05 17:59     ` Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 39/47] pc: pcihp: expose MMIO base and len as properties Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 40/47] pc: acpi-build: reserve PCIHP MMIO resources Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 41/47] pc: acpi-build: create PCI0._CRS dynamically Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term Igor Mammedov
2015-01-29  8:02   ` Shannon Zhao
2015-01-29  8:45     ` Igor Mammedov
2015-01-29  9:01       ` Shannon Zhao
2015-01-29  9:21         ` Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 43/47] pc: acpi-build: prepare to make ACPI tables blob opaque for table building functions Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 44/47] pc: acpi-build: drop remaining ssdt_misc template and use acpi_def_block() Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 45/47] acpi: add acpi_iqr_no_flags() term Igor Mammedov
2015-01-27 15:37   ` Claudio Fontana
2015-01-28 12:15     ` Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 46/47] pc: export applesmc IO port/len Igor Mammedov
2015-01-22 14:50 ` [Qemu-devel] [PATCH v2 47/47] pc: acpi-build: drop template patching and create Device(SMC) dynamically Igor Mammedov
2015-01-28  7:38 ` [Qemu-devel] [PATCH v2 00/47] ACPI refactoring: replace template patching with C ASL API Michael S. Tsirkin
2015-01-28 10:07   ` Igor Mammedov

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.