diff --git a/tests/acpi-test.c b/tests/acpi-test.c
index ca83b1d..d08720d 100644
--- a/tests/acpi-test.c
+++ b/tests/acpi-test.c
@@ -18,14 +18,26 @@
 #include "qemu/compiler.h"
 #include "hw/i386/acpi-defs.h"
 
+#define MACHINE_PC "pc"
+#define MACHINE_Q35 "q35"
+
 /* DSDT and SSDTs format */
 typedef struct {
     AcpiTableHeader header;
-    uint8_t *aml;
-    int aml_len;
-} AcpiSdtTable;
+    gchar *aml;            /* aml bytecode from guest */
+    gsize aml_len;
+    gchar *aml_file;
+    gchar *asl;            /* asl code generated from aml */
+    gsize asl_len;
+    gchar *asl_file;
+    gchar *exp_aml;        /* expected asl from test file */
+    gsize exp_aml_len;
+    gchar *exp_asl;        /* expected asl from test file */
+    gsize exp_asl_len;
+} QEMU_PACKED AcpiSdtTable;
 
 typedef struct {
+    const char *machine;
     uint32_t rsdp_addr;
     AcpiRsdpDescriptor rsdp_table;
     AcpiRsdtDescriptorRev1 rsdt_table;
@@ -33,8 +45,7 @@ typedef struct {
     AcpiFacsDescriptorRev1 facs_table;
     uint32_t *rsdt_tables_addr;
     int rsdt_tables_nr;
-    AcpiSdtTable dsdt_table;
-    GArray *ssdt_tables;
+    GArray *ssdt_tables; /* first is DSDT */
 } test_data;
 
 #define LOW(x) ((x) & 0xff)
@@ -91,8 +102,10 @@ typedef struct {
 
 /* Boot sector code: write SIGNATURE into memory,
  * then halt.
+ * Q35 machine requires a minimum 0x7e000 bytes disk.
+ * (bug or feature?)
  */
-static uint8_t boot_sector[0x200] = {
+static uint8_t boot_sector[0x7e000] = {
     /* 7c00: mov $0xdead,%ax */
     [0x00] = 0xb8,
     [0x01] = LOW(SIGNATURE),
@@ -117,17 +130,37 @@ static uint8_t boot_sector[0x200] = {
 };
 
 static const char *disk = "tests/acpi-test-disk.raw";
+static const char *data_dir = "tests/acpi-test-data";
 
 static void free_test_data(test_data *data)
 {
+    AcpiSdtTable *temp;
     int i;
 
     g_free(data->rsdt_tables_addr);
+
     for (i = 0; i < data->ssdt_tables->len; ++i) {
-        g_free(g_array_index(data->ssdt_tables, AcpiSdtTable, i).aml);
+        temp = &g_array_index(data->ssdt_tables, AcpiSdtTable, i);
+        if (temp->aml) {
+            g_free(temp->aml);
+        }
+        if (temp->aml_file) {
+            unlink(temp->aml_file);
+            g_free(temp->aml_file);
+        }
+        if (temp->asl) {
+            g_free(temp->asl);
+        }
+        if (temp->asl_file) {
+            unlink(temp->asl_file);
+            g_free(temp->asl_file);
+        }
+        if (temp->exp_asl) {
+            g_free(temp->exp_asl);
+        }
     }
+
     g_array_free(data->ssdt_tables, false);
-    g_free(data->dsdt_table.aml);
 }
 
 static uint8_t acpi_checksum(const uint8_t *data, int len)
@@ -292,34 +325,178 @@ static void test_dst_table(AcpiSdtTable *sdt_table, uint32_t addr)
     ACPI_READ_ARRAY_PTR(sdt_table->aml, sdt_table->aml_len, addr);
 
     checksum = acpi_checksum((uint8_t *)sdt_table, sizeof(AcpiTableHeader)) +
-               acpi_checksum(sdt_table->aml, sdt_table->aml_len);
+               acpi_checksum((uint8_t *)sdt_table->aml, sdt_table->aml_len);
     g_assert(!checksum);
 }
 
 static void test_acpi_dsdt_table(test_data *data)
 {
-    AcpiSdtTable *dsdt_table = &data->dsdt_table;
+    AcpiSdtTable dsdt_table;
     uint32_t addr = data->fadt_table.dsdt;
 
-    test_dst_table(dsdt_table, addr);
-    g_assert_cmphex(dsdt_table->header.signature, ==, ACPI_DSDT_SIGNATURE);
+    memset(&dsdt_table, 0, sizeof(dsdt_table));
+    data->ssdt_tables = g_array_new(false, true, sizeof(AcpiSdtTable));
+
+    test_dst_table(&dsdt_table, addr);
+    g_assert_cmphex(dsdt_table.header.signature, ==, ACPI_DSDT_SIGNATURE);
+
+    /* Place DSDT first */
+    g_array_append_val(data->ssdt_tables, dsdt_table);
 }
 
 static void test_acpi_ssdt_tables(test_data *data)
 {
-    GArray *ssdt_tables;
     int ssdt_tables_nr = data->rsdt_tables_nr - 1; /* fadt is first */
     int i;
 
-    ssdt_tables = g_array_sized_new(false, true, sizeof(AcpiSdtTable),
-                                    ssdt_tables_nr);
     for (i = 0; i < ssdt_tables_nr; i++) {
         AcpiSdtTable ssdt_table;
+
+        memset(&ssdt_table, 0 , sizeof(ssdt_table));
         uint32_t addr = data->rsdt_tables_addr[i + 1]; /* fadt is first */
         test_dst_table(&ssdt_table, addr);
-        g_array_append_val(ssdt_tables, ssdt_table);
+        g_array_append_val(data->ssdt_tables, ssdt_table);
+    }
+}
+
+static bool iasl_installed(void)
+{
+    gchar *out = NULL, *out_err = NULL;
+    bool ret;
+
+    /* pass 'out' and 'out_err' in order to be redirected */
+    ret = g_spawn_command_line_sync("iasl", &out, &out_err, NULL, NULL);
+
+    if (out_err) {
+        ret = ret && (out_err[0] == '\0');
+        g_free(out_err);
+    }
+
+    if (out) {
+        g_free(out);
+    }
+
+    return ret;
+}
+
+static void dump_aml_files(test_data *data)
+{
+    AcpiSdtTable *sdt;
+    GError *error = NULL;
+    gint fd;
+    int i;
+
+    for (i = 0; i < data->ssdt_tables->len; ++i) {
+        sdt = &g_array_index(data->ssdt_tables, AcpiSdtTable, i);
+        g_assert(sdt->aml);
+
+        fd = g_file_open_tmp("aml-XXXXXX", &sdt->aml_file, &error);
+        g_assert_no_error(error);
+
+        write(fd, sdt, sizeof(AcpiTableHeader));
+        write(fd, sdt->aml, sdt->aml_len);
+        close(fd);
+    }
+}
+
+static void load_asl_from_data(test_data *data, AcpiSdtTable *sdt)
+{
+    AcpiSdtTable *temp;
+    GError *error = NULL;
+    GString *command_line = g_string_new("'iasl' ");
+    gint fd;
+    gchar *out, *out_err;
+    gboolean ret;
+    int i;
+
+    fd = g_file_open_tmp("asl-XXXXXX.dsl", &sdt->asl_file, &error);
+    g_assert_no_error(error);
+    close(fd);
+
+    /* build command line */
+    g_string_append_printf(command_line, "-p %s ", sdt->asl_file);
+    for (i = 0; i < 2; ++i) { /* reference DSDT and SSDT */
+        temp = &g_array_index(data->ssdt_tables, AcpiSdtTable, i);
+        g_string_append_printf(command_line, "-e %s ", temp->aml_file);
+    }
+    g_string_append_printf(command_line, "-d %s", sdt->aml_file);
+
+    /* pass 'out' and 'out_err' in order to be redirected */
+    g_spawn_command_line_sync(command_line->str, &out, &out_err, NULL, &error);
+    g_assert_no_error(error);
+
+    ret = g_file_get_contents(sdt->asl_file, (gchar **)&sdt->asl,
+                              &sdt->asl_len, &error);
+    g_assert(ret);
+    g_assert_no_error(error);
+    g_assert(sdt->asl_len);
+
+    g_free(out);
+    g_free(out_err);
+    g_string_free(command_line, true);
+}
+
+static void load_asl_from_file(test_data *data, AcpiSdtTable *sdt)
+{
+    gchar *asl_file;
+    GError *error = NULL;
+    gboolean ret;
+
+    asl_file = g_strdup_printf("%s/%s/%.4s.dsl", data_dir, data->machine,
+                               (gchar *)&sdt->header.signature);
+    g_assert(g_file_test(asl_file, G_FILE_TEST_EXISTS));
+    ret = g_file_get_contents(asl_file, &sdt->exp_asl,
+                              &sdt->exp_asl_len, &error);
+    g_assert(ret);
+    g_assert_no_error(error);
+    g_assert(sdt->exp_asl_len);
+}
+
+#define COMMENT_END "*/"
+#define DEF_BLOCK "DefinitionBlock ("
+#define BLOCK_NAME_END ".aml"
+
+static GString *normalize_asl(gchar *asl_code)
+{
+    GString *asl = g_string_new(asl_code);
+    gchar *comment, *block_name;
+
+    /* strip comments (different generation days) */
+    comment = g_strstr_len(asl->str, asl->len, COMMENT_END);
+    if (comment) {
+        asl = g_string_erase(asl, 0, comment + sizeof(COMMENT_END) - asl->str);
+    }
+
+    /* strip def block name (it has file path in it) */
+    if (g_str_has_prefix(asl->str, DEF_BLOCK)) {
+        block_name = g_strstr_len(asl->str, asl->len, BLOCK_NAME_END);
+        g_assert(block_name);
+        asl = g_string_erase(asl, 0,
+                             block_name + sizeof(BLOCK_NAME_END) - asl->str);
+    }
+
+    return asl;
+}
+
+static void test_acpi_asl(test_data *data)
+{
+    int i;
+
+    dump_aml_files(data);
+    for (i = 0; i < data->ssdt_tables->len; ++i) {
+        GString *asl, *expected;
+        AcpiSdtTable *sdt = &g_array_index(data->ssdt_tables, AcpiSdtTable, i);
+
+        load_asl_from_data(data, sdt);
+        asl = normalize_asl(sdt->asl);
+
+        load_asl_from_file(data, sdt);
+        expected = normalize_asl(sdt->exp_asl);
+
+        g_assert(!g_strcmp0(asl->str, expected->str));
+        g_string_free(asl, true);
+        g_string_free(expected, true);
     }
-    data->ssdt_tables = ssdt_tables;
 }
 
 static void test_acpi_one(const char *params, test_data *data)
@@ -329,10 +506,14 @@ static void test_acpi_one(const char *params, test_data *data)
     uint8_t signature_high;
     uint16_t signature;
     int i;
+    const char *device = "";
+
+    if (!g_strcmp0(data->machine, MACHINE_Q35)) {
+        device = ",id=hd -device ide-hd,drive=hd";
+    }
 
-    memset(data, 0, sizeof(*data));
-    args = g_strdup_printf("-net none -display none %s %s",
-                           params ? params : "", disk);
+    args = g_strdup_printf("-net none -display none %s -drive file=%s%s,",
+                           params ? params : "", disk, device);
     qtest_start(args);
 
    /* Wait at most 1 minute */
@@ -362,6 +543,10 @@ static void test_acpi_one(const char *params, test_data *data)
     test_acpi_dsdt_table(data);
     test_acpi_ssdt_tables(data);
 
+    if (iasl_installed()) {
+        test_acpi_asl(data);
+    }
+
     qtest_quit(global_qtest);
     g_free(args);
 }
@@ -373,8 +558,14 @@ static void test_acpi_tcg(void)
     /* Supplying -machine accel argument overrides the default (qtest).
      * This is to make guest actually run.
      */
+    memset(&data, 0, sizeof(data));
+    data.machine = MACHINE_PC;
     test_acpi_one("-machine accel=tcg", &data);
+    free_test_data(&data);
 
+    memset(&data, 0, sizeof(data));
+    data.machine = MACHINE_Q35;
+    test_acpi_one("-machine q35,accel=tcg", &data);
     free_test_data(&data);
 }
 
