diff mbox

tests: add XSCOM tests for the PowerNV machine

Message ID 1478780230-31402-1-git-send-email-clg@kaod.org
State New
Headers show

Commit Message

Cédric Le Goater Nov. 10, 2016, 12:17 p.m. UTC
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 <clg@kaod.org>
---
 tests/Makefile.include |   1 +
 tests/pnv-xscom-test.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+)
 create mode 100644 tests/pnv-xscom-test.c

Comments

David Gibson Nov. 11, 2016, 12:16 a.m. UTC | #1
On Thu, Nov 10, 2016 at 01:17:10PM +0100, Cédric Le Goater wrote:
> 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 <clg@kaod.org>
> ---
>  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);
> +    }
> +}

To make writing future tests which use XSCOM easier, I think it would
be better to actually have xscom_read / xscom_write helper functions.

> +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();
> +}
Cédric Le Goater Nov. 11, 2016, 8:11 a.m. UTC | #2
On 11/11/2016 01:16 AM, David Gibson wrote:
> On Thu, Nov 10, 2016 at 01:17:10PM +0100, Cédric Le Goater wrote:
>> 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 <clg@kaod.org>
>> ---
>>  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);
>> +    }
>> +}
> 
> To make writing future tests which use XSCOM easier, I think it would
> be better to actually have xscom_read / xscom_write helper functions.

yes. you are right. I will add a little libxscom for that then.

Thanks,

C. 


> 
>> +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();
>> +}
>
diff mbox

Patch

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();
+}