131bfbc00SFrederic Barrat /*
231bfbc00SFrederic Barrat * QTest testcase for PowerNV 10 interrupt controller (xive2)
331bfbc00SFrederic Barrat * - Test cache flush/queue sync injection
431bfbc00SFrederic Barrat *
531bfbc00SFrederic Barrat * Copyright (c) 2024, IBM Corporation.
631bfbc00SFrederic Barrat *
731bfbc00SFrederic Barrat * SPDX-License-Identifier: GPL-2.0-or-later
831bfbc00SFrederic Barrat */
931bfbc00SFrederic Barrat #include "qemu/osdep.h"
1031bfbc00SFrederic Barrat #include "libqtest.h"
1131bfbc00SFrederic Barrat
1231bfbc00SFrederic Barrat #include "pnv-xive2-common.h"
1331bfbc00SFrederic Barrat #include "hw/intc/pnv_xive2_regs.h"
1431bfbc00SFrederic Barrat #include "hw/ppc/xive_regs.h"
1531bfbc00SFrederic Barrat #include "hw/ppc/xive2_regs.h"
1631bfbc00SFrederic Barrat
1731bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_IPI 0x00
1831bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_HW 0x01
1931bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_NXC 0x02
2031bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_INT 0x03
2131bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_OS 0x04
2231bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_POOL 0x05
2331bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_HARD 0x06
2431bfbc00SFrederic Barrat #define PNV_XIVE2_CACHE_ENDC 0x08
2531bfbc00SFrederic Barrat #define PNV_XIVE2_CACHE_ESBC 0x09
2631bfbc00SFrederic Barrat #define PNV_XIVE2_CACHE_EASC 0x0a
2731bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO 0x10
2831bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_NXC_LD_LCL_CO 0x11
2931bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI 0x12
3031bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_NXC_ST_LCL_CI 0x13
3131bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI 0x14
3231bfbc00SFrederic Barrat #define PNV_XIVE2_QUEUE_NXC_ST_RMT_CI 0x15
3331bfbc00SFrederic Barrat #define PNV_XIVE2_CACHE_NXC 0x18
3431bfbc00SFrederic Barrat
3531bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_IPI 0x000
3631bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_HW 0x080
3731bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_NxC 0x100
3831bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_INT 0x180
3931bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_OS_ESC 0x200
4031bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_POOL_ESC 0x280
4131bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_HARD_ESC 0x300
4231bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_NXC_LD_LCL_NCO 0x800
4331bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_NXC_LD_LCL_CO 0x880
4431bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_NXC_ST_LCL_NCI 0x900
4531bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_NXC_ST_LCL_CI 0x980
4631bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_NXC_ST_RMT_NCI 0xA00
4731bfbc00SFrederic Barrat #define PNV_XIVE2_SYNC_NXC_ST_RMT_CI 0xA80
4831bfbc00SFrederic Barrat
4931bfbc00SFrederic Barrat
get_sync_addr(uint32_t src_pir,int ic_topo_id,int type)5031bfbc00SFrederic Barrat static uint64_t get_sync_addr(uint32_t src_pir, int ic_topo_id, int type)
5131bfbc00SFrederic Barrat {
5231bfbc00SFrederic Barrat int thread_nr = src_pir & 0x7f;
5331bfbc00SFrederic Barrat uint64_t addr = XIVE_SYNC_MEM + thread_nr * 512 + ic_topo_id * 32 + type;
5431bfbc00SFrederic Barrat return addr;
5531bfbc00SFrederic Barrat }
5631bfbc00SFrederic Barrat
get_sync(QTestState * qts,uint32_t src_pir,int ic_topo_id,int type)5731bfbc00SFrederic Barrat static uint8_t get_sync(QTestState *qts, uint32_t src_pir, int ic_topo_id,
5831bfbc00SFrederic Barrat int type)
5931bfbc00SFrederic Barrat {
6031bfbc00SFrederic Barrat uint64_t addr = get_sync_addr(src_pir, ic_topo_id, type);
6131bfbc00SFrederic Barrat return qtest_readb(qts, addr);
6231bfbc00SFrederic Barrat }
6331bfbc00SFrederic Barrat
clr_sync(QTestState * qts,uint32_t src_pir,int ic_topo_id,int type)6431bfbc00SFrederic Barrat static void clr_sync(QTestState *qts, uint32_t src_pir, int ic_topo_id,
6531bfbc00SFrederic Barrat int type)
6631bfbc00SFrederic Barrat {
6731bfbc00SFrederic Barrat uint64_t addr = get_sync_addr(src_pir, ic_topo_id, type);
6831bfbc00SFrederic Barrat qtest_writeb(qts, addr, 0x0);
6931bfbc00SFrederic Barrat }
7031bfbc00SFrederic Barrat
inject_cache_flush(QTestState * qts,int ic_topo_id,uint64_t scom_addr)7131bfbc00SFrederic Barrat static void inject_cache_flush(QTestState *qts, int ic_topo_id,
7231bfbc00SFrederic Barrat uint64_t scom_addr)
7331bfbc00SFrederic Barrat {
7431bfbc00SFrederic Barrat (void)ic_topo_id;
7531bfbc00SFrederic Barrat pnv_xive_xscom_write(qts, scom_addr, 0);
7631bfbc00SFrederic Barrat }
7731bfbc00SFrederic Barrat
inject_queue_sync(QTestState * qts,int ic_topo_id,uint64_t offset)7831bfbc00SFrederic Barrat static void inject_queue_sync(QTestState *qts, int ic_topo_id, uint64_t offset)
7931bfbc00SFrederic Barrat {
8031bfbc00SFrederic Barrat (void)ic_topo_id;
8131bfbc00SFrederic Barrat uint64_t addr = XIVE_IC_ADDR + (VST_SYNC << XIVE_PAGE_SHIFT) + offset;
8231bfbc00SFrederic Barrat qtest_writeq(qts, addr, 0);
8331bfbc00SFrederic Barrat }
8431bfbc00SFrederic Barrat
inject_op(QTestState * qts,int ic_topo_id,int type)8531bfbc00SFrederic Barrat static void inject_op(QTestState *qts, int ic_topo_id, int type)
8631bfbc00SFrederic Barrat {
8731bfbc00SFrederic Barrat switch (type) {
8831bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_IPI:
8931bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_IPI);
9031bfbc00SFrederic Barrat break;
9131bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_HW:
9231bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_HW);
9331bfbc00SFrederic Barrat break;
9431bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_NXC:
9531bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NxC);
9631bfbc00SFrederic Barrat break;
9731bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_INT:
9831bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_INT);
9931bfbc00SFrederic Barrat break;
10031bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_OS:
10131bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_OS_ESC);
10231bfbc00SFrederic Barrat break;
10331bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_POOL:
10431bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_POOL_ESC);
10531bfbc00SFrederic Barrat break;
10631bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_HARD:
10731bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_HARD_ESC);
10831bfbc00SFrederic Barrat break;
10931bfbc00SFrederic Barrat case PNV_XIVE2_CACHE_ENDC:
11031bfbc00SFrederic Barrat inject_cache_flush(qts, ic_topo_id, X_VC_ENDC_FLUSH_INJECT);
11131bfbc00SFrederic Barrat break;
11231bfbc00SFrederic Barrat case PNV_XIVE2_CACHE_ESBC:
11331bfbc00SFrederic Barrat inject_cache_flush(qts, ic_topo_id, X_VC_ESBC_FLUSH_INJECT);
11431bfbc00SFrederic Barrat break;
11531bfbc00SFrederic Barrat case PNV_XIVE2_CACHE_EASC:
11631bfbc00SFrederic Barrat inject_cache_flush(qts, ic_topo_id, X_VC_EASC_FLUSH_INJECT);
11731bfbc00SFrederic Barrat break;
11831bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO:
11931bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_LD_LCL_NCO);
12031bfbc00SFrederic Barrat break;
12131bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_NXC_LD_LCL_CO:
12231bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_LD_LCL_CO);
12331bfbc00SFrederic Barrat break;
12431bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI:
12531bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_LCL_NCI);
12631bfbc00SFrederic Barrat break;
12731bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_NXC_ST_LCL_CI:
12831bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_LCL_CI);
12931bfbc00SFrederic Barrat break;
13031bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI:
13131bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_RMT_NCI);
13231bfbc00SFrederic Barrat break;
13331bfbc00SFrederic Barrat case PNV_XIVE2_QUEUE_NXC_ST_RMT_CI:
13431bfbc00SFrederic Barrat inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_RMT_CI);
13531bfbc00SFrederic Barrat break;
13631bfbc00SFrederic Barrat case PNV_XIVE2_CACHE_NXC:
13731bfbc00SFrederic Barrat inject_cache_flush(qts, ic_topo_id, X_PC_NXC_FLUSH_INJECT);
13831bfbc00SFrederic Barrat break;
13931bfbc00SFrederic Barrat default:
14031bfbc00SFrederic Barrat g_assert_not_reached();
14131bfbc00SFrederic Barrat break;
14231bfbc00SFrederic Barrat }
14331bfbc00SFrederic Barrat }
14431bfbc00SFrederic Barrat
14531bfbc00SFrederic Barrat const uint8_t xive_inject_tests[] = {
14631bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_IPI,
14731bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_HW,
14831bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_NXC,
14931bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_INT,
15031bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_OS,
15131bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_POOL,
15231bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_HARD,
15331bfbc00SFrederic Barrat PNV_XIVE2_CACHE_ENDC,
15431bfbc00SFrederic Barrat PNV_XIVE2_CACHE_ESBC,
15531bfbc00SFrederic Barrat PNV_XIVE2_CACHE_EASC,
15631bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO,
15731bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_NXC_LD_LCL_CO,
15831bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI,
15931bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_NXC_ST_LCL_CI,
16031bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI,
16131bfbc00SFrederic Barrat PNV_XIVE2_QUEUE_NXC_ST_RMT_CI,
16231bfbc00SFrederic Barrat PNV_XIVE2_CACHE_NXC,
16331bfbc00SFrederic Barrat };
16431bfbc00SFrederic Barrat
test_flush_sync_inject(QTestState * qts)16531bfbc00SFrederic Barrat void test_flush_sync_inject(QTestState *qts)
16631bfbc00SFrederic Barrat {
16731bfbc00SFrederic Barrat int ic_topo_id = 0;
16831bfbc00SFrederic Barrat
16931bfbc00SFrederic Barrat /*
17031bfbc00SFrederic Barrat * Writes performed by qtest are not done in the context of a thread.
17131bfbc00SFrederic Barrat * This means that QEMU XIVE code doesn't have a way to determine what
17231bfbc00SFrederic Barrat * thread is originating the write. In order to allow for some testing,
17331bfbc00SFrederic Barrat * QEMU XIVE code will assume a PIR of 0 when unable to determine the
17431bfbc00SFrederic Barrat * source thread for cache flush and queue sync inject operations.
17531bfbc00SFrederic Barrat * See hw/intc/pnv_xive2.c: pnv_xive2_inject_notify() for details.
17631bfbc00SFrederic Barrat */
17731bfbc00SFrederic Barrat int src_pir = 0;
17831bfbc00SFrederic Barrat int test_nr;
17931bfbc00SFrederic Barrat uint8_t byte;
18031bfbc00SFrederic Barrat
181*c4b50387SGlenn Miles g_test_message("=========================================================");
182*c4b50387SGlenn Miles g_test_message("Starting cache flush/queue sync injection tests...");
18331bfbc00SFrederic Barrat
18431bfbc00SFrederic Barrat for (test_nr = 0; test_nr < sizeof(xive_inject_tests);
18531bfbc00SFrederic Barrat test_nr++) {
18631bfbc00SFrederic Barrat int op_type = xive_inject_tests[test_nr];
18731bfbc00SFrederic Barrat
188*c4b50387SGlenn Miles g_test_message("Running test %d", test_nr);
18931bfbc00SFrederic Barrat
19031bfbc00SFrederic Barrat /* start with status byte set to 0 */
19131bfbc00SFrederic Barrat clr_sync(qts, src_pir, ic_topo_id, op_type);
19231bfbc00SFrederic Barrat byte = get_sync(qts, src_pir, ic_topo_id, op_type);
19331bfbc00SFrederic Barrat g_assert_cmphex(byte, ==, 0);
19431bfbc00SFrederic Barrat
19531bfbc00SFrederic Barrat /* request cache flush or queue sync operation */
19631bfbc00SFrederic Barrat inject_op(qts, ic_topo_id, op_type);
19731bfbc00SFrederic Barrat
19831bfbc00SFrederic Barrat /* verify that status byte was written to 0xff */
19931bfbc00SFrederic Barrat byte = get_sync(qts, src_pir, ic_topo_id, op_type);
20031bfbc00SFrederic Barrat g_assert_cmphex(byte, ==, 0xff);
20131bfbc00SFrederic Barrat
20231bfbc00SFrederic Barrat clr_sync(qts, src_pir, ic_topo_id, op_type);
20331bfbc00SFrederic Barrat }
20431bfbc00SFrederic Barrat }
20531bfbc00SFrederic Barrat
206