On Mon, Dec 08, 2014 at 04:08:04PM +0000, Igor Mammedov wrote: > the will be later used for composing AML primitives > and all that could be reused later for ARM machines > as well. > > Signed-off-by: Igor Mammedov <imamm...@redhat.com>
It will be easy to move when needed. Why do it now? > --- > hw/acpi/Makefile.objs | 1 + > hw/acpi/acpi_gen_utils.c | 169 > +++++++++++++++++++++++++++++++++++++++ > hw/i386/acpi-build.c | 165 +------------------------------------- > include/hw/acpi/acpi_gen_utils.h | 23 ++++++ > 4 files changed, 195 insertions(+), 163 deletions(-) > create mode 100644 hw/acpi/acpi_gen_utils.c > create mode 100644 include/hw/acpi/acpi_gen_utils.h > > diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs > index acd2389..4237232 100644 > --- a/hw/acpi/Makefile.objs > +++ b/hw/acpi/Makefile.objs > @@ -1,3 +1,4 @@ > common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o > common-obj-$(CONFIG_ACPI) += memory_hotplug.o > common-obj-$(CONFIG_ACPI) += acpi_interface.o > +common-obj-$(CONFIG_ACPI) += acpi_gen_utils.o > diff --git a/hw/acpi/acpi_gen_utils.c b/hw/acpi/acpi_gen_utils.c > new file mode 100644 > index 0000000..1583b35 > --- /dev/null > +++ b/hw/acpi/acpi_gen_utils.c > @@ -0,0 +1,169 @@ > +#include <stdio.h> > +#include <stdarg.h> > +#include <assert.h> > +#include <stdbool.h> > +#include "hw/acpi/acpi_gen_utils.h" > + > +GArray *build_alloc_array(void) > +{ > + return g_array_new(false, true /* clear */, 1); > +} > + > +void build_free_array(GArray *array) > +{ > + g_array_free(array, true); > +} > + > +void build_prepend_byte(GArray *array, uint8_t val) > +{ > + g_array_prepend_val(array, val); > +} > + > +void build_append_byte(GArray *array, uint8_t val) > +{ > + g_array_append_val(array, val); > +} > + > +void build_append_array(GArray *array, GArray *val) > +{ > + g_array_append_vals(array, val->data, val->len); > +} > + > +#define ACPI_NAMESEG_LEN 4 > + > +void GCC_FMT_ATTR(2, 3) > +build_append_nameseg(GArray *array, const char *format, ...) > +{ > + /* It would be nicer to use g_string_vprintf but it's only there in 2.22 > */ > + char s[] = "XXXX"; > + int len; > + va_list args; > + const char padding = '_'; > + > + va_start(args, format); > + len = vsnprintf(s, sizeof s, format, args); > + va_end(args); > + > + g_assert(len <= ACPI_NAMESEG_LEN); > + > + g_array_append_vals(array, s, len); > + while (len != ACPI_NAMESEG_LEN) { > + g_array_append_val(array, padding); > + ++len; > + } > +} > + > +/* 5.4 Definition Block Encoding */ > +enum { > + PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */ > + PACKAGE_LENGTH_2BYTE_SHIFT = 4, > + PACKAGE_LENGTH_3BYTE_SHIFT = 12, > + PACKAGE_LENGTH_4BYTE_SHIFT = 20, > +}; > + > +void build_prepend_package_length(GArray *package, unsigned min_bytes) > +{ > + uint8_t byte; > + unsigned length = package->len; > + unsigned length_bytes; > + > + if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) { > + length_bytes = 1; > + } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) { > + length_bytes = 2; > + } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) { > + length_bytes = 3; > + } else { > + length_bytes = 4; > + } > + > + /* Force length to at least min_bytes. > + * This wastes memory but that's how bios did it. > + */ > + length_bytes = MAX(length_bytes, min_bytes); > + > + /* PkgLength is the length of the inclusive length of the data. */ > + length += length_bytes; > + > + switch (length_bytes) { > + case 1: > + byte = length; > + build_prepend_byte(package, byte); > + return; > + case 4: > + byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT; > + build_prepend_byte(package, byte); > + length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1; > + /* fall through */ > + case 3: > + byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT; > + build_prepend_byte(package, byte); > + length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1; > + /* fall through */ > + case 2: > + byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT; > + build_prepend_byte(package, byte); > + length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1; > + /* fall through */ > + } > + /* > + * Most significant two bits of byte zero indicate how many following > bytes > + * are in PkgLength encoding. > + */ > + byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length; > + build_prepend_byte(package, byte); > +} > + > +void build_package(GArray *package, uint8_t op, unsigned min_bytes) > +{ > + build_prepend_package_length(package, min_bytes); > + build_prepend_byte(package, op); > +} > + > +void build_extop_package(GArray *package, uint8_t op) > +{ > + build_package(package, op, 1); > + build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ > +} > + > +void build_append_value(GArray *table, uint32_t value, int size) > +{ > + uint8_t prefix; > + int i; > + > + switch (size) { > + case 1: > + prefix = 0x0A; /* BytePrefix */ > + break; > + case 2: > + prefix = 0x0B; /* WordPrefix */ > + break; > + case 4: > + prefix = 0x0C; /* DWordPrefix */ > + break; > + default: > + assert(0); > + return; > + } > + build_append_byte(table, prefix); > + for (i = 0; i < size; ++i) { > + build_append_byte(table, value & 0xFF); > + value = value >> 8; > + } > +} > + > +void build_append_int(GArray *table, uint32_t value) > +{ > + if (value == 0x00) { > + build_append_byte(table, 0x00); /* ZeroOp */ > + } else if (value == 0x01) { > + build_append_byte(table, 0x01); /* OneOp */ > + } else if (value <= 0xFF) { > + build_append_value(table, value, 1); > + } else if (value <= 0xFFFF) { > + build_append_value(table, value, 2); > + } else { > + build_append_value(table, value, 4); > + } > +} > + > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c > index a8b7a2b..870e4a0 100644 > --- a/hw/i386/acpi-build.c > +++ b/hw/i386/acpi-build.c > @@ -54,6 +54,8 @@ > #include "hw/i386/q35-acpi-dsdt.hex" > #include "hw/i386/acpi-dsdt.hex" > > +#include "hw/acpi/acpi_gen_utils.h" > + > #include "qapi/qmp/qint.h" > #include "qom/qom-qobject.h" > #include "exec/ram_addr.h" > @@ -267,169 +269,6 @@ build_header(GArray *linker, GArray *table_data, > table_data->data, h, len, &h->checksum); > } > > -static inline GArray *build_alloc_array(void) > -{ > - return g_array_new(false, true /* clear */, 1); > -} > - > -static inline void build_free_array(GArray *array) > -{ > - g_array_free(array, true); > -} > - > -static inline void build_prepend_byte(GArray *array, uint8_t val) > -{ > - g_array_prepend_val(array, val); > -} > - > -static inline void build_append_byte(GArray *array, uint8_t val) > -{ > - g_array_append_val(array, val); > -} > - > -static inline void build_append_array(GArray *array, GArray *val) > -{ > - g_array_append_vals(array, val->data, val->len); > -} > - > -#define ACPI_NAMESEG_LEN 4 > - > -static void GCC_FMT_ATTR(2, 3) > -build_append_nameseg(GArray *array, const char *format, ...) > -{ > - /* It would be nicer to use g_string_vprintf but it's only there in 2.22 > */ > - char s[] = "XXXX"; > - int len; > - va_list args; > - const char padding = '_'; > - > - va_start(args, format); > - len = vsnprintf(s, sizeof s, format, args); > - va_end(args); > - > - g_assert(len <= ACPI_NAMESEG_LEN); > - > - g_array_append_vals(array, s, len); > - while (len != ACPI_NAMESEG_LEN) { > - g_array_append_val(array, padding); > - ++len; > - } > -} > - > -/* 5.4 Definition Block Encoding */ > -enum { > - PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */ > - PACKAGE_LENGTH_2BYTE_SHIFT = 4, > - PACKAGE_LENGTH_3BYTE_SHIFT = 12, > - PACKAGE_LENGTH_4BYTE_SHIFT = 20, > -}; > - > -static void build_prepend_package_length(GArray *package, unsigned min_bytes) > -{ > - uint8_t byte; > - unsigned length = package->len; > - unsigned length_bytes; > - > - if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) { > - length_bytes = 1; > - } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) { > - length_bytes = 2; > - } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) { > - length_bytes = 3; > - } else { > - length_bytes = 4; > - } > - > - /* Force length to at least min_bytes. > - * This wastes memory but that's how bios did it. > - */ > - length_bytes = MAX(length_bytes, min_bytes); > - > - /* PkgLength is the length of the inclusive length of the data. */ > - length += length_bytes; > - > - switch (length_bytes) { > - case 1: > - byte = length; > - build_prepend_byte(package, byte); > - return; > - case 4: > - byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT; > - build_prepend_byte(package, byte); > - length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1; > - /* fall through */ > - case 3: > - byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT; > - build_prepend_byte(package, byte); > - length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1; > - /* fall through */ > - case 2: > - byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT; > - build_prepend_byte(package, byte); > - length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1; > - /* fall through */ > - } > - /* > - * Most significant two bits of byte zero indicate how many following > bytes > - * are in PkgLength encoding. > - */ > - byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length; > - build_prepend_byte(package, byte); > -} > - > -static void build_package(GArray *package, uint8_t op, unsigned min_bytes) > -{ > - build_prepend_package_length(package, min_bytes); > - build_prepend_byte(package, op); > -} > - > -static void build_extop_package(GArray *package, uint8_t op) > -{ > - build_package(package, op, 1); > - build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ > -} > - > -static void build_append_value(GArray *table, uint32_t value, int size) > -{ > - uint8_t prefix; > - int i; > - > - switch (size) { > - case 1: > - prefix = 0x0A; /* BytePrefix */ > - break; > - case 2: > - prefix = 0x0B; /* WordPrefix */ > - break; > - case 4: > - prefix = 0x0C; /* DWordPrefix */ > - break; > - default: > - assert(0); > - return; > - } > - build_append_byte(table, prefix); > - for (i = 0; i < size; ++i) { > - build_append_byte(table, value & 0xFF); > - value = value >> 8; > - } > -} > - > -static void build_append_int(GArray *table, uint32_t value) > -{ > - if (value == 0x00) { > - build_append_byte(table, 0x00); /* ZeroOp */ > - } else if (value == 0x01) { > - build_append_byte(table, 0x01); /* OneOp */ > - } else if (value <= 0xFF) { > - build_append_value(table, value, 1); > - } else if (value <= 0xFFFF) { > - build_append_value(table, value, 2); > - } else { > - build_append_value(table, value, 4); > - } > -} > - > static GArray *build_alloc_method(const char *name, uint8_t arg_count) > { > GArray *method = build_alloc_array(); > diff --git a/include/hw/acpi/acpi_gen_utils.h > b/include/hw/acpi/acpi_gen_utils.h > new file mode 100644 > index 0000000..e6a0b28 > --- /dev/null > +++ b/include/hw/acpi/acpi_gen_utils.h > @@ -0,0 +1,23 @@ > +#ifndef HW_ACPI_GEN_UTILS_H > +#define HW_ACPI_GEN_UTILS_H > + > +#include <stdint.h> > +#include <glib.h> > +#include "qemu/compiler.h" > + > +GArray *build_alloc_array(void); > +void build_free_array(GArray *array); > +void build_prepend_byte(GArray *array, uint8_t val); > +void build_append_byte(GArray *array, uint8_t val); > +void build_append_array(GArray *array, GArray *val); > + > +void GCC_FMT_ATTR(2, 3) > +build_append_nameseg(GArray *array, const char *format, ...); > + > +void build_prepend_package_length(GArray *package, unsigned min_bytes); > +void build_package(GArray *package, uint8_t op, unsigned min_bytes); > +void build_append_value(GArray *table, uint32_t value, int size); > +void build_append_int(GArray *table, uint32_t value); > +void build_extop_package(GArray *package, uint8_t op); > + > +#endif > -- > 1.8.3.1