xref: /openbmc/qemu/tests/qtest/pnv-xive2-nvpg_bar.c (revision 71569cd8aba31fcb3a326c56c307d2b811417c0b)
196a2132cSFrederic Barrat /*
296a2132cSFrederic Barrat  * QTest testcase for PowerNV 10 interrupt controller (xive2)
396a2132cSFrederic Barrat  *  - Test NVPG BAR MMIO operations
496a2132cSFrederic Barrat  *
596a2132cSFrederic Barrat  * Copyright (c) 2024, IBM Corporation.
696a2132cSFrederic Barrat  *
7*c4b50387SGlenn Miles  * SPDX-License-Identifier: GPL-2.0-or-later
896a2132cSFrederic Barrat  */
996a2132cSFrederic Barrat #include "qemu/osdep.h"
1096a2132cSFrederic Barrat #include "libqtest.h"
1196a2132cSFrederic Barrat 
1296a2132cSFrederic Barrat #include "pnv-xive2-common.h"
1396a2132cSFrederic Barrat 
1496a2132cSFrederic Barrat #define NVPG_BACKLOG_OP_SHIFT   10
1596a2132cSFrederic Barrat #define NVPG_BACKLOG_PRIO_SHIFT 4
1696a2132cSFrederic Barrat 
1796a2132cSFrederic Barrat #define XIVE_PRIORITY_MAX       7
1896a2132cSFrederic Barrat 
1996a2132cSFrederic Barrat enum NVx {
2096a2132cSFrederic Barrat     NVP,
2196a2132cSFrederic Barrat     NVG,
2296a2132cSFrederic Barrat     NVC
2396a2132cSFrederic Barrat };
2496a2132cSFrederic Barrat 
2596a2132cSFrederic Barrat typedef enum {
2696a2132cSFrederic Barrat     INCR_STORE = 0b100,
2796a2132cSFrederic Barrat     INCR_LOAD  = 0b000,
2896a2132cSFrederic Barrat     DECR_STORE = 0b101,
2996a2132cSFrederic Barrat     DECR_LOAD  = 0b001,
3096a2132cSFrederic Barrat     READ_x     = 0b010,
3196a2132cSFrederic Barrat     READ_y     = 0b011,
3296a2132cSFrederic Barrat } backlog_op;
3396a2132cSFrederic Barrat 
nvpg_backlog_op(QTestState * qts,backlog_op op,enum NVx type,uint64_t index,uint8_t priority,uint8_t delta)3496a2132cSFrederic Barrat static uint32_t nvpg_backlog_op(QTestState *qts, backlog_op op,
3596a2132cSFrederic Barrat                                 enum NVx type, uint64_t index,
3696a2132cSFrederic Barrat                                 uint8_t priority, uint8_t delta)
3796a2132cSFrederic Barrat {
3896a2132cSFrederic Barrat     uint64_t addr, offset;
3996a2132cSFrederic Barrat     uint32_t count = 0;
4096a2132cSFrederic Barrat 
4196a2132cSFrederic Barrat     switch (type) {
4296a2132cSFrederic Barrat     case NVP:
4396a2132cSFrederic Barrat         addr = XIVE_NVPG_ADDR + (index << (XIVE_PAGE_SHIFT + 1));
4496a2132cSFrederic Barrat         break;
4596a2132cSFrederic Barrat     case NVG:
4696a2132cSFrederic Barrat         addr = XIVE_NVPG_ADDR + (index << (XIVE_PAGE_SHIFT + 1)) +
4796a2132cSFrederic Barrat             (1 << XIVE_PAGE_SHIFT);
4896a2132cSFrederic Barrat         break;
4996a2132cSFrederic Barrat     case NVC:
5096a2132cSFrederic Barrat         addr = XIVE_NVC_ADDR + (index << XIVE_PAGE_SHIFT);
5196a2132cSFrederic Barrat         break;
5296a2132cSFrederic Barrat     default:
5396a2132cSFrederic Barrat         g_assert_not_reached();
5496a2132cSFrederic Barrat     }
5596a2132cSFrederic Barrat 
5696a2132cSFrederic Barrat     offset = (op & 0b11) << NVPG_BACKLOG_OP_SHIFT;
5796a2132cSFrederic Barrat     offset |= priority << NVPG_BACKLOG_PRIO_SHIFT;
5896a2132cSFrederic Barrat     if (op >> 2) {
5996a2132cSFrederic Barrat         qtest_writeb(qts, addr + offset, delta);
6096a2132cSFrederic Barrat     } else {
6196a2132cSFrederic Barrat         count = qtest_readw(qts, addr + offset);
6296a2132cSFrederic Barrat     }
6396a2132cSFrederic Barrat     return count;
6496a2132cSFrederic Barrat }
6596a2132cSFrederic Barrat 
test_nvpg_bar(QTestState * qts)6696a2132cSFrederic Barrat void test_nvpg_bar(QTestState *qts)
6796a2132cSFrederic Barrat {
6896a2132cSFrederic Barrat     uint32_t nvp_target = 0x11;
6996a2132cSFrederic Barrat     uint32_t group_target = 0x17; /* size 16 */
7096a2132cSFrederic Barrat     uint32_t vp_irq = 33, group_irq = 47;
7196a2132cSFrederic Barrat     uint32_t vp_end = 3, group_end = 97;
7296a2132cSFrederic Barrat     uint32_t vp_irq_data = 0x33333333;
7396a2132cSFrederic Barrat     uint32_t group_irq_data = 0x66666666;
7496a2132cSFrederic Barrat     uint8_t vp_priority = 0, group_priority = 5;
7596a2132cSFrederic Barrat     uint32_t vp_count[XIVE_PRIORITY_MAX + 1] = { 0 };
7696a2132cSFrederic Barrat     uint32_t group_count[XIVE_PRIORITY_MAX + 1] = { 0 };
7796a2132cSFrederic Barrat     uint32_t count, delta;
7896a2132cSFrederic Barrat     uint8_t i;
7996a2132cSFrederic Barrat 
80*c4b50387SGlenn Miles     g_test_message("=========================================================");
81*c4b50387SGlenn Miles     g_test_message("Testing NVPG BAR operations");
8296a2132cSFrederic Barrat 
8396a2132cSFrederic Barrat     set_nvg(qts, group_target, 0);
8496a2132cSFrederic Barrat     set_nvp(qts, nvp_target, 0x04);
8596a2132cSFrederic Barrat     set_nvp(qts, group_target, 0x04);
8696a2132cSFrederic Barrat 
8796a2132cSFrederic Barrat     /*
8896a2132cSFrederic Barrat      * Setup: trigger a VP-specific interrupt and a group interrupt
8996a2132cSFrederic Barrat      * so that the backlog counters are initialized to something else
9096a2132cSFrederic Barrat      * than 0 for at least one priority level
9196a2132cSFrederic Barrat      */
9296a2132cSFrederic Barrat     set_eas(qts, vp_irq, vp_end, vp_irq_data);
9396a2132cSFrederic Barrat     set_end(qts, vp_end, nvp_target, vp_priority, false /* group */);
9496a2132cSFrederic Barrat 
9596a2132cSFrederic Barrat     set_eas(qts, group_irq, group_end, group_irq_data);
9696a2132cSFrederic Barrat     set_end(qts, group_end, group_target, group_priority, true /* group */);
9796a2132cSFrederic Barrat 
9896a2132cSFrederic Barrat     get_esb(qts, vp_irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00);
9996a2132cSFrederic Barrat     set_esb(qts, vp_irq, XIVE_TRIGGER_PAGE, 0, 0);
10096a2132cSFrederic Barrat     vp_count[vp_priority]++;
10196a2132cSFrederic Barrat 
10296a2132cSFrederic Barrat     get_esb(qts, group_irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00);
10396a2132cSFrederic Barrat     set_esb(qts, group_irq, XIVE_TRIGGER_PAGE, 0, 0);
10496a2132cSFrederic Barrat     group_count[group_priority]++;
10596a2132cSFrederic Barrat 
10696a2132cSFrederic Barrat     /* check the initial counters */
10796a2132cSFrederic Barrat     for (i = 0; i <= XIVE_PRIORITY_MAX; i++) {
10896a2132cSFrederic Barrat         count = nvpg_backlog_op(qts, READ_x, NVP, nvp_target, i, 0);
10996a2132cSFrederic Barrat         g_assert_cmpuint(count, ==, vp_count[i]);
11096a2132cSFrederic Barrat 
11196a2132cSFrederic Barrat         count = nvpg_backlog_op(qts, READ_y, NVG, group_target, i, 0);
11296a2132cSFrederic Barrat         g_assert_cmpuint(count, ==, group_count[i]);
11396a2132cSFrederic Barrat     }
11496a2132cSFrederic Barrat 
11596a2132cSFrederic Barrat     /* do a few ops on the VP. Counter can only be 0 and 1 */
11696a2132cSFrederic Barrat     vp_priority = 2;
11796a2132cSFrederic Barrat     delta = 7;
11896a2132cSFrederic Barrat     nvpg_backlog_op(qts, INCR_STORE, NVP, nvp_target, vp_priority, delta);
11996a2132cSFrederic Barrat     vp_count[vp_priority] = 1;
12096a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, INCR_LOAD, NVP, nvp_target, vp_priority, 0);
12196a2132cSFrederic Barrat     g_assert_cmpuint(count, ==, vp_count[vp_priority]);
12296a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, READ_y, NVP, nvp_target, vp_priority, 0);
12396a2132cSFrederic Barrat     g_assert_cmpuint(count, ==, vp_count[vp_priority]);
12496a2132cSFrederic Barrat 
12596a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, DECR_LOAD, NVP, nvp_target, vp_priority, 0);
12696a2132cSFrederic Barrat     g_assert_cmpuint(count, ==, vp_count[vp_priority]);
12796a2132cSFrederic Barrat     vp_count[vp_priority] = 0;
12896a2132cSFrederic Barrat     nvpg_backlog_op(qts, DECR_STORE, NVP, nvp_target, vp_priority, delta);
12996a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, READ_x, NVP, nvp_target, vp_priority, 0);
13096a2132cSFrederic Barrat     g_assert_cmpuint(count, ==, vp_count[vp_priority]);
13196a2132cSFrederic Barrat 
13296a2132cSFrederic Barrat     /* do a few ops on the group */
13396a2132cSFrederic Barrat     group_priority = 2;
13496a2132cSFrederic Barrat     delta = 9;
13596a2132cSFrederic Barrat     /* can't go negative */
13696a2132cSFrederic Barrat     nvpg_backlog_op(qts, DECR_STORE, NVG, group_target, group_priority, delta);
13796a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, READ_y, NVG, group_target, group_priority, 0);
13896a2132cSFrederic Barrat     g_assert_cmpuint(count, ==, 0);
13996a2132cSFrederic Barrat     nvpg_backlog_op(qts, INCR_STORE, NVG, group_target, group_priority, delta);
14096a2132cSFrederic Barrat     group_count[group_priority] += delta;
14196a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, INCR_LOAD, NVG, group_target,
14296a2132cSFrederic Barrat                             group_priority, delta);
14396a2132cSFrederic Barrat     g_assert_cmpuint(count, ==, group_count[group_priority]);
14496a2132cSFrederic Barrat     group_count[group_priority]++;
14596a2132cSFrederic Barrat 
14696a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, DECR_LOAD, NVG, group_target,
14796a2132cSFrederic Barrat                             group_priority, delta);
14896a2132cSFrederic Barrat     g_assert_cmpuint(count, ==,  group_count[group_priority]);
14996a2132cSFrederic Barrat     group_count[group_priority]--;
15096a2132cSFrederic Barrat     count = nvpg_backlog_op(qts, READ_x, NVG, group_target, group_priority, 0);
15196a2132cSFrederic Barrat     g_assert_cmpuint(count, ==, group_count[group_priority]);
15296a2132cSFrederic Barrat }
153