/*
 * QTest testcase for PowerNV 10 interrupt controller (xive2)
 *  - Test cache flush/queue sync injection
 *
 * Copyright (c) 2024, IBM Corporation.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */
#include "qemu/osdep.h"
#include "libqtest.h"

#include "pnv-xive2-common.h"
#include "hw/intc/pnv_xive2_regs.h"
#include "hw/ppc/xive_regs.h"
#include "hw/ppc/xive2_regs.h"

#define PNV_XIVE2_QUEUE_IPI              0x00
#define PNV_XIVE2_QUEUE_HW               0x01
#define PNV_XIVE2_QUEUE_NXC              0x02
#define PNV_XIVE2_QUEUE_INT              0x03
#define PNV_XIVE2_QUEUE_OS               0x04
#define PNV_XIVE2_QUEUE_POOL             0x05
#define PNV_XIVE2_QUEUE_HARD             0x06
#define PNV_XIVE2_CACHE_ENDC             0x08
#define PNV_XIVE2_CACHE_ESBC             0x09
#define PNV_XIVE2_CACHE_EASC             0x0a
#define PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO   0x10
#define PNV_XIVE2_QUEUE_NXC_LD_LCL_CO    0x11
#define PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI   0x12
#define PNV_XIVE2_QUEUE_NXC_ST_LCL_CI    0x13
#define PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI   0x14
#define PNV_XIVE2_QUEUE_NXC_ST_RMT_CI    0x15
#define PNV_XIVE2_CACHE_NXC              0x18

#define PNV_XIVE2_SYNC_IPI              0x000
#define PNV_XIVE2_SYNC_HW               0x080
#define PNV_XIVE2_SYNC_NxC              0x100
#define PNV_XIVE2_SYNC_INT              0x180
#define PNV_XIVE2_SYNC_OS_ESC           0x200
#define PNV_XIVE2_SYNC_POOL_ESC         0x280
#define PNV_XIVE2_SYNC_HARD_ESC         0x300
#define PNV_XIVE2_SYNC_NXC_LD_LCL_NCO   0x800
#define PNV_XIVE2_SYNC_NXC_LD_LCL_CO    0x880
#define PNV_XIVE2_SYNC_NXC_ST_LCL_NCI   0x900
#define PNV_XIVE2_SYNC_NXC_ST_LCL_CI    0x980
#define PNV_XIVE2_SYNC_NXC_ST_RMT_NCI   0xA00
#define PNV_XIVE2_SYNC_NXC_ST_RMT_CI    0xA80


static uint64_t get_sync_addr(uint32_t src_pir, int ic_topo_id, int type)
{
    int thread_nr = src_pir & 0x7f;
    uint64_t addr = XIVE_SYNC_MEM +  thread_nr * 512 + ic_topo_id * 32 + type;
    return addr;
}

static uint8_t get_sync(QTestState *qts, uint32_t src_pir, int ic_topo_id,
                        int type)
{
    uint64_t addr = get_sync_addr(src_pir, ic_topo_id, type);
    return qtest_readb(qts, addr);
}

static void clr_sync(QTestState *qts, uint32_t src_pir, int ic_topo_id,
                        int type)
{
    uint64_t addr = get_sync_addr(src_pir, ic_topo_id, type);
    qtest_writeb(qts, addr, 0x0);
}

static void inject_cache_flush(QTestState *qts, int ic_topo_id,
                               uint64_t scom_addr)
{
    (void)ic_topo_id;
    pnv_xive_xscom_write(qts, scom_addr, 0);
}

static void inject_queue_sync(QTestState *qts, int ic_topo_id, uint64_t offset)
{
    (void)ic_topo_id;
    uint64_t addr = XIVE_IC_ADDR + (VST_SYNC << XIVE_PAGE_SHIFT) + offset;
    qtest_writeq(qts, addr, 0);
}

static void inject_op(QTestState *qts, int ic_topo_id, int type)
{
    switch (type) {
    case PNV_XIVE2_QUEUE_IPI:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_IPI);
        break;
    case PNV_XIVE2_QUEUE_HW:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_HW);
        break;
    case PNV_XIVE2_QUEUE_NXC:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NxC);
        break;
    case PNV_XIVE2_QUEUE_INT:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_INT);
        break;
    case PNV_XIVE2_QUEUE_OS:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_OS_ESC);
        break;
    case PNV_XIVE2_QUEUE_POOL:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_POOL_ESC);
        break;
    case PNV_XIVE2_QUEUE_HARD:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_HARD_ESC);
        break;
    case PNV_XIVE2_CACHE_ENDC:
        inject_cache_flush(qts, ic_topo_id, X_VC_ENDC_FLUSH_INJECT);
        break;
    case PNV_XIVE2_CACHE_ESBC:
        inject_cache_flush(qts, ic_topo_id, X_VC_ESBC_FLUSH_INJECT);
        break;
    case PNV_XIVE2_CACHE_EASC:
        inject_cache_flush(qts, ic_topo_id, X_VC_EASC_FLUSH_INJECT);
        break;
    case PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_LD_LCL_NCO);
        break;
    case PNV_XIVE2_QUEUE_NXC_LD_LCL_CO:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_LD_LCL_CO);
        break;
    case PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_LCL_NCI);
        break;
    case PNV_XIVE2_QUEUE_NXC_ST_LCL_CI:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_LCL_CI);
        break;
    case PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_RMT_NCI);
        break;
    case PNV_XIVE2_QUEUE_NXC_ST_RMT_CI:
        inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_RMT_CI);
        break;
    case PNV_XIVE2_CACHE_NXC:
        inject_cache_flush(qts, ic_topo_id, X_PC_NXC_FLUSH_INJECT);
        break;
    default:
        g_assert_not_reached();
        break;
    }
}

const uint8_t xive_inject_tests[] = {
    PNV_XIVE2_QUEUE_IPI,
    PNV_XIVE2_QUEUE_HW,
    PNV_XIVE2_QUEUE_NXC,
    PNV_XIVE2_QUEUE_INT,
    PNV_XIVE2_QUEUE_OS,
    PNV_XIVE2_QUEUE_POOL,
    PNV_XIVE2_QUEUE_HARD,
    PNV_XIVE2_CACHE_ENDC,
    PNV_XIVE2_CACHE_ESBC,
    PNV_XIVE2_CACHE_EASC,
    PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO,
    PNV_XIVE2_QUEUE_NXC_LD_LCL_CO,
    PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI,
    PNV_XIVE2_QUEUE_NXC_ST_LCL_CI,
    PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI,
    PNV_XIVE2_QUEUE_NXC_ST_RMT_CI,
    PNV_XIVE2_CACHE_NXC,
};

void test_flush_sync_inject(QTestState *qts)
{
    int ic_topo_id = 0;

    /*
     * Writes performed by qtest are not done in the context of a thread.
     * This means that QEMU XIVE code doesn't have a way to determine what
     * thread is originating the write.  In order to allow for some testing,
     * QEMU XIVE code will assume a PIR of 0 when unable to determine the
     * source thread for cache flush and queue sync inject operations.
     * See hw/intc/pnv_xive2.c: pnv_xive2_inject_notify() for details.
     */
    int src_pir = 0;
    int test_nr;
    uint8_t byte;

    printf("# ============================================================\n");
    printf("# Starting cache flush/queue sync injection tests...\n");

    for (test_nr = 0; test_nr < sizeof(xive_inject_tests);
         test_nr++) {
        int op_type = xive_inject_tests[test_nr];

        printf("# Running test %d\n", test_nr);

        /* start with status byte set to 0 */
        clr_sync(qts, src_pir, ic_topo_id, op_type);
        byte = get_sync(qts, src_pir, ic_topo_id, op_type);
        g_assert_cmphex(byte, ==, 0);

        /* request cache flush or queue sync operation */
        inject_op(qts, ic_topo_id, op_type);

        /* verify that status byte was written to 0xff */
        byte = get_sync(qts, src_pir, ic_topo_id, op_type);
        g_assert_cmphex(byte, ==, 0xff);

        clr_sync(qts, src_pir, ic_topo_id, op_type);
    }
}

