Message ID | 1478780230-31402-1-git-send-email-clg@kaod.org |
---|---|
State | New |
Headers | show |
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(); > +}
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 --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(); +}
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