qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] tests: add XSCOM tests for the PowerNV machine


From: Cédric Le Goater
Subject: [Qemu-devel] [PATCH] tests: add XSCOM tests for the PowerNV machine
Date: Thu, 10 Nov 2016 13:17:10 +0100

Add a couple of tests on the XSCOM bus of the PowerNV machine for the
the POWER8 and POWER9 CPUs. The first tests reads the CFAM identifier
of the chip. The second test goes further in the XSCOM address space
and reaches the cores to read their DTS registers. This last one is
disabled on P9 for the moment as the EQ/EX/EC XSCOM mapping needs more
work to be functional.

Signed-off-by: Cédric Le Goater <address@hidden>
---
 tests/Makefile.include |   1 +
 tests/pnv-xscom-test.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+)
 create mode 100644 tests/pnv-xscom-test.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index de516341fd44..90c9ad9ac6e1 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -270,6 +270,7 @@ gcov-files-ppc64-y = ppc64-softmmu/hw/ppc/spapr_pci.c
 check-qtest-ppc64-y += tests/endianness-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
 check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
+check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF)
 check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
 check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-serial-test$(EXESUF)
diff --git a/tests/pnv-xscom-test.c b/tests/pnv-xscom-test.c
new file mode 100644
index 000000000000..994dd015c425
--- /dev/null
+++ b/tests/pnv-xscom-test.c
@@ -0,0 +1,138 @@
+/*
+ * QTest testcase for PowerNV XSCOM bus
+ *
+ * Copyright (c) 2016, IBM Corporation.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+
+typedef enum PnvChipType {
+    PNV_CHIP_POWER8E,     /* AKA Murano (default) */
+    PNV_CHIP_POWER8,      /* AKA Venice */
+    PNV_CHIP_POWER8NVL,   /* AKA Naples */
+    PNV_CHIP_POWER9,      /* AKA Nimbus */
+} PnvChipType;
+
+#define PNV_XSCOM_EX_BASE         0x10000000
+#define PNV_XSCOM_EX_CORE_BASE(i) (PNV_XSCOM_EX_BASE | (((uint64_t)i) << 24))
+
+static const struct pnv_chip {
+    PnvChipType chip_type;
+    const char *cpu_model;
+    uint64_t    xscom_base;
+    uint64_t    cfam_id;
+    uint32_t    first_core;
+} pnv_chips[] = {
+    {
+        .chip_type  = PNV_CHIP_POWER8,
+        .cpu_model  = "POWER8",
+        .xscom_base = 0x003fc0000000000ull,
+        .cfam_id    = 0x220ea04980000000ull,
+        .first_core = 0x1,
+    },
+    {
+        .chip_type  = PNV_CHIP_POWER8NVL,
+        .cpu_model  = "POWER8NVL",
+        .xscom_base = 0x003fc0000000000ull,
+        .cfam_id    = 0x120d304980000000ull,
+        .first_core = 0x1,
+    },
+    {
+        .chip_type  = PNV_CHIP_POWER9,
+        .cpu_model  = "POWER9",
+        .xscom_base = 0x00603fc00000000ull,
+        .cfam_id    = 0x100d104980000000ull,
+        .first_core = 0x20,
+    },
+};
+
+static uint64_t pnv_xscom_addr(const struct pnv_chip *chip, uint32_t pcba)
+{
+    uint64_t addr = chip->xscom_base;
+
+    if (chip->chip_type == PNV_CHIP_POWER9) {
+        return addr | ((uint64_t) pcba << 3);
+    } else {
+        return addr | (((uint64_t) pcba << 4) & ~0xfful) |
+            (((uint64_t) pcba << 3) & 0x78);
+    }
+}
+
+static void test_xscom_cfam_id(const struct pnv_chip *chip)
+{
+    uint64_t f000f = readq(pnv_xscom_addr(chip, 0xf000f));
+
+    g_assert_cmphex(f000f, ==, chip->cfam_id);
+}
+
+static void test_cfam_id(const void *data)
+{
+    char *args;
+    const struct pnv_chip *chip = data;
+
+    args = g_strdup_printf("-M powernv,accel=tcg -cpu %s", chip->cpu_model);
+
+    qtest_start(args);
+    test_xscom_cfam_id(chip);
+    qtest_quit(global_qtest);
+
+    g_free(args);
+}
+
+static void test_xscom_core(const struct pnv_chip *chip)
+{
+    uint32_t first_core_dts0 =
+        PNV_XSCOM_EX_CORE_BASE(chip->first_core) | 0x50000;
+    uint64_t dts0 = readq(pnv_xscom_addr(chip, first_core_dts0));
+
+    g_assert_cmphex(dts0, ==, 0x26f024f023f0000ull);
+}
+
+static void test_core(const void *data)
+{
+    char *args;
+    const struct pnv_chip *chip = data;
+
+    args = g_strdup_printf("-M powernv,accel=tcg -cpu %s", chip->cpu_model);
+
+    qtest_start(args);
+    test_xscom_core(chip);
+    qtest_quit(global_qtest);
+
+    g_free(args);
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+
+    g_test_init(&argc, &argv, NULL);
+
+    for (i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
+        char *name = g_strdup_printf("pnv-xscom/cfam_id/%s",
+                                     pnv_chips[i].cpu_model);
+        qtest_add_data_func(name, &pnv_chips[i], test_cfam_id);
+        g_free(name);
+    }
+
+    for (i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
+        /*
+         * Discard P9 for the moment as EQ/EX/EC XSCOM mapping needs a
+         * rework
+         */
+        if (pnv_chips[i].chip_type == PNV_CHIP_POWER9) {
+            continue;
+        }
+
+        char *name = g_strdup_printf("pnv-xscom/core/%s",
+                                     pnv_chips[i].cpu_model);
+        qtest_add_data_func(name, &pnv_chips[i], test_core);
+        g_free(name);
+    }
+
+    return g_test_run();
+}
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]