/*
 * QEMU PowerPC nest pervasive common chiplet model
 *
 * Copyright (c) 2023, IBM Corporation.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_xscom.h"
#include "hw/ppc/pnv_nest_pervasive.h"

/*
 * Status, configuration, and control units in POWER chips is provided
 * by the pervasive subsystem, which connects registers to the SCOM bus,
 * which can be programmed by processor cores, other units on the chip,
 * BMCs, or other POWER chips.
 *
 * A POWER10 chip is divided into logical units called chiplets. Chiplets
 * are broadly divided into "core chiplets" (with the processor cores) and
 * "nest chiplets" (with everything else). Each chiplet has an attachment
 * to the pervasive bus (PIB) and with chiplet-specific registers.
 * All nest chiplets have a common basic set of registers.
 *
 * This model will provide the registers functionality for common registers of
 * nest unit (PB Chiplet, PCI Chiplets, MC Chiplet, PAU Chiplets)
 *
 * Currently this model provide the read/write functionality of chiplet control
 * scom registers.
 */

#define CPLT_CONF0               0x08
#define CPLT_CONF0_OR            0x18
#define CPLT_CONF0_CLEAR         0x28
#define CPLT_CONF1               0x09
#define CPLT_CONF1_OR            0x19
#define CPLT_CONF1_CLEAR         0x29
#define CPLT_STAT0               0x100
#define CPLT_MASK0               0x101
#define CPLT_PROTECT_MODE        0x3FE
#define CPLT_ATOMIC_CLOCK        0x3FF

static uint64_t pnv_chiplet_ctrl_read(void *opaque, hwaddr addr, unsigned size)
{
    PnvNestChipletPervasive *nest_pervasive = PNV_NEST_CHIPLET_PERVASIVE(
                                              opaque);
    uint32_t reg = addr >> 3;
    uint64_t val = ~0ull;

    /* CPLT_CTRL0 to CPLT_CTRL5 */
    for (int i = 0; i < PNV_CPLT_CTRL_SIZE; i++) {
        if (reg == i) {
            return nest_pervasive->control_regs.cplt_ctrl[i];
        } else if ((reg == (i + 0x10)) || (reg == (i + 0x20))) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
                                           "xscom read at 0x%" PRIx32 "\n",
                                           __func__, reg);
            return val;
        }
    }

    switch (reg) {
    case CPLT_CONF0:
        val = nest_pervasive->control_regs.cplt_cfg0;
        break;
    case CPLT_CONF0_OR:
    case CPLT_CONF0_CLEAR:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
                                   "xscom read at 0x%" PRIx32 "\n",
                                   __func__, reg);
        break;
    case CPLT_CONF1:
        val = nest_pervasive->control_regs.cplt_cfg1;
        break;
    case CPLT_CONF1_OR:
    case CPLT_CONF1_CLEAR:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
                                   "xscom read at 0x%" PRIx32 "\n",
                                   __func__, reg);
        break;
    case CPLT_STAT0:
        val = nest_pervasive->control_regs.cplt_stat0;
        break;
    case CPLT_MASK0:
        val = nest_pervasive->control_regs.cplt_mask0;
        break;
    case CPLT_PROTECT_MODE:
        val = nest_pervasive->control_regs.ctrl_protect_mode;
        break;
    case CPLT_ATOMIC_CLOCK:
        val = nest_pervasive->control_regs.ctrl_atomic_lock;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: Chiplet_control_regs: Invalid xscom "
                 "read at 0x%" PRIx32 "\n", __func__, reg);
    }
    return val;
}

static void pnv_chiplet_ctrl_write(void *opaque, hwaddr addr,
                                 uint64_t val, unsigned size)
{
    PnvNestChipletPervasive *nest_pervasive = PNV_NEST_CHIPLET_PERVASIVE(
                                              opaque);
    uint32_t reg = addr >> 3;

    /* CPLT_CTRL0 to CPLT_CTRL5 */
    for (int i = 0; i < PNV_CPLT_CTRL_SIZE; i++) {
        if (reg == i) {
            nest_pervasive->control_regs.cplt_ctrl[i] = val;
            return;
        } else if (reg == (i + 0x10)) {
            nest_pervasive->control_regs.cplt_ctrl[i] |= val;
            return;
        } else if (reg == (i + 0x20)) {
            nest_pervasive->control_regs.cplt_ctrl[i] &= ~val;
            return;
        }
    }

    switch (reg) {
    case CPLT_CONF0:
        nest_pervasive->control_regs.cplt_cfg0 = val;
        break;
    case CPLT_CONF0_OR:
        nest_pervasive->control_regs.cplt_cfg0 |= val;
        break;
    case CPLT_CONF0_CLEAR:
        nest_pervasive->control_regs.cplt_cfg0 &= ~val;
        break;
    case CPLT_CONF1:
        nest_pervasive->control_regs.cplt_cfg1 = val;
        break;
    case CPLT_CONF1_OR:
        nest_pervasive->control_regs.cplt_cfg1 |= val;
        break;
    case CPLT_CONF1_CLEAR:
        nest_pervasive->control_regs.cplt_cfg1 &= ~val;
        break;
    case CPLT_STAT0:
        nest_pervasive->control_regs.cplt_stat0 = val;
        break;
    case CPLT_MASK0:
        nest_pervasive->control_regs.cplt_mask0 = val;
        break;
    case CPLT_PROTECT_MODE:
        nest_pervasive->control_regs.ctrl_protect_mode = val;
        break;
    case CPLT_ATOMIC_CLOCK:
        nest_pervasive->control_regs.ctrl_atomic_lock = val;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: Chiplet_control_regs: Invalid xscom "
                                 "write at 0x%" PRIx32 "\n",
                                 __func__, reg);
    }
}

static const MemoryRegionOps pnv_nest_pervasive_control_xscom_ops = {
    .read = pnv_chiplet_ctrl_read,
    .write = pnv_chiplet_ctrl_write,
    .valid.min_access_size = 8,
    .valid.max_access_size = 8,
    .impl.min_access_size = 8,
    .impl.max_access_size = 8,
    .endianness = DEVICE_BIG_ENDIAN,
};

static void pnv_nest_pervasive_realize(DeviceState *dev, Error **errp)
{
    PnvNestChipletPervasive *nest_pervasive = PNV_NEST_CHIPLET_PERVASIVE(dev);

    /* Chiplet control scoms */
    pnv_xscom_region_init(&nest_pervasive->xscom_ctrl_regs_mr,
                          OBJECT(nest_pervasive),
                          &pnv_nest_pervasive_control_xscom_ops,
                          nest_pervasive, "pervasive-control",
                          PNV10_XSCOM_CHIPLET_CTRL_REGS_SIZE);
}

static void pnv_nest_pervasive_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->desc = "PowerNV nest pervasive chiplet";
    dc->realize = pnv_nest_pervasive_realize;
}

static const TypeInfo pnv_nest_pervasive_info = {
    .name          = TYPE_PNV_NEST_CHIPLET_PERVASIVE,
    .parent        = TYPE_DEVICE,
    .instance_size = sizeof(PnvNestChipletPervasive),
    .class_init    = pnv_nest_pervasive_class_init,
    .interfaces    = (InterfaceInfo[]) {
        { TYPE_PNV_XSCOM_INTERFACE },
        { }
    }
};

static void pnv_nest_pervasive_register_types(void)
{
    type_register_static(&pnv_nest_pervasive_info);
}

type_init(pnv_nest_pervasive_register_types);
