/*
 * QEMU PowerPC PowerNV CPU Core model
 *
 * Copyright (c) 2016, IBM Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "sysemu/reset.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "target/ppc/cpu.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_chip.h"
#include "hw/ppc/pnv_core.h"
#include "hw/ppc/pnv_xscom.h"
#include "hw/ppc/xics.h"
#include "hw/qdev-properties.h"
#include "helper_regs.h"

static const char *pnv_core_cpu_typename(PnvCore *pc)
{
    const char *core_type = object_class_get_name(object_get_class(OBJECT(pc)));
    int len = strlen(core_type) - strlen(PNV_CORE_TYPE_SUFFIX);
    char *s = g_strdup_printf(POWERPC_CPU_TYPE_NAME("%.*s"), len, core_type);
    const char *cpu_type = object_class_get_name(object_class_by_name(s));
    g_free(s);
    return cpu_type;
}

static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu)
{
    CPUState *cs = CPU(cpu);
    CPUPPCState *env = &cpu->env;
    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);

    cpu_reset(cs);

    /*
     * the skiboot firmware elects a primary thread to initialize the
     * system and it can be any.
     */
    env->gpr[3] = PNV_FDT_ADDR;
    env->nip = 0x10;
    env->msr |= MSR_HVB; /* Hypervisor mode */
    env->spr[SPR_HRMOR] = pc->hrmor;
    hreg_compute_hflags(env);
    ppc_maybe_interrupt(env);

    pcc->intc_reset(pc->chip, cpu);
}

/*
 * These values are read by the PowerNV HW monitors under Linux
 */
#define PNV_XSCOM_EX_DTS_RESULT0     0x50000
#define PNV_XSCOM_EX_DTS_RESULT1     0x50001

static uint64_t pnv_core_power8_xscom_read(void *opaque, hwaddr addr,
                                           unsigned int width)
{
    uint32_t offset = addr >> 3;
    uint64_t val = 0;

    /* The result should be 38 C */
    switch (offset) {
    case PNV_XSCOM_EX_DTS_RESULT0:
        val = 0x26f024f023f0000ull;
        break;
    case PNV_XSCOM_EX_DTS_RESULT1:
        val = 0x24f000000000000ull;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n",
                  addr);
    }

    return val;
}

static void pnv_core_power8_xscom_write(void *opaque, hwaddr addr, uint64_t val,
                                        unsigned int width)
{
    qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
                  addr);
}

static const MemoryRegionOps pnv_core_power8_xscom_ops = {
    .read = pnv_core_power8_xscom_read,
    .write = pnv_core_power8_xscom_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,
};


/*
 * POWER9 core controls
 */
#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP 0xf010d
#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR 0xf010a

static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr,
                                           unsigned int width)
{
    uint32_t offset = addr >> 3;
    uint64_t val = 0;

    /* The result should be 38 C */
    switch (offset) {
    case PNV_XSCOM_EX_DTS_RESULT0:
        val = 0x26f024f023f0000ull;
        break;
    case PNV_XSCOM_EX_DTS_RESULT1:
        val = 0x24f000000000000ull;
        break;
    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
        val = 0x0;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n",
                  addr);
    }

    return val;
}

static void pnv_core_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val,
                                        unsigned int width)
{
    uint32_t offset = addr >> 3;

    switch (offset) {
    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
                      addr);
    }
}

static const MemoryRegionOps pnv_core_power9_xscom_ops = {
    .read = pnv_core_power9_xscom_read,
    .write = pnv_core_power9_xscom_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_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp)
{
    CPUPPCState *env = &cpu->env;
    int core_pir;
    int thread_index = 0; /* TODO: TCG supports only one thread */
    ppc_spr_t *pir = &env->spr_cb[SPR_PIR];
    Error *local_err = NULL;
    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);

    if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
        return;
    }

    pcc->intc_create(pc->chip, cpu, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    core_pir = object_property_get_uint(OBJECT(pc), "pir", &error_abort);

    /*
     * The PIR of a thread is the core PIR + the thread index. We will
     * need to find a way to get the thread index when TCG supports
     * more than 1. We could use the object name ?
     */
    pir->default_value = core_pir + thread_index;

    /* Set time-base frequency to 512 MHz */
    cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ);
}

static void pnv_core_reset(void *dev)
{
    CPUCore *cc = CPU_CORE(dev);
    PnvCore *pc = PNV_CORE(dev);
    int i;

    for (i = 0; i < cc->nr_threads; i++) {
        pnv_core_cpu_reset(pc, pc->threads[i]);
    }
}

static void pnv_core_realize(DeviceState *dev, Error **errp)
{
    PnvCore *pc = PNV_CORE(OBJECT(dev));
    PnvCoreClass *pcc = PNV_CORE_GET_CLASS(pc);
    CPUCore *cc = CPU_CORE(OBJECT(dev));
    const char *typename = pnv_core_cpu_typename(pc);
    Error *local_err = NULL;
    void *obj;
    int i, j;
    char name[32];

    assert(pc->chip);

    pc->threads = g_new(PowerPCCPU *, cc->nr_threads);
    for (i = 0; i < cc->nr_threads; i++) {
        PowerPCCPU *cpu;

        obj = object_new(typename);
        cpu = POWERPC_CPU(obj);

        pc->threads[i] = POWERPC_CPU(obj);

        snprintf(name, sizeof(name), "thread[%d]", i);
        object_property_add_child(OBJECT(pc), name, obj);

        cpu->machine_data = g_new0(PnvCPUState, 1);

        object_unref(obj);
    }

    for (j = 0; j < cc->nr_threads; j++) {
        pnv_core_cpu_realize(pc, pc->threads[j], &local_err);
        if (local_err) {
            goto err;
        }
    }

    snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
    /* TODO: check PNV_XSCOM_EX_SIZE for p10 */
    pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops,
                          pc, name, PNV_XSCOM_EX_SIZE);

    qemu_register_reset(pnv_core_reset, pc);
    return;

err:
    while (--i >= 0) {
        obj = OBJECT(pc->threads[i]);
        object_unparent(obj);
    }
    g_free(pc->threads);
    error_propagate(errp, local_err);
}

static void pnv_core_cpu_unrealize(PnvCore *pc, PowerPCCPU *cpu)
{
    PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);

    pcc->intc_destroy(pc->chip, cpu);
    cpu_remove_sync(CPU(cpu));
    cpu->machine_data = NULL;
    g_free(pnv_cpu);
    object_unparent(OBJECT(cpu));
}

static void pnv_core_unrealize(DeviceState *dev)
{
    PnvCore *pc = PNV_CORE(dev);
    CPUCore *cc = CPU_CORE(dev);
    int i;

    qemu_unregister_reset(pnv_core_reset, pc);

    for (i = 0; i < cc->nr_threads; i++) {
        pnv_core_cpu_unrealize(pc, pc->threads[i]);
    }
    g_free(pc->threads);
}

static Property pnv_core_properties[] = {
    DEFINE_PROP_UINT32("pir", PnvCore, pir, 0),
    DEFINE_PROP_UINT64("hrmor", PnvCore, hrmor, 0),
    DEFINE_PROP_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *),
    DEFINE_PROP_END_OF_LIST(),
};

static void pnv_core_power8_class_init(ObjectClass *oc, void *data)
{
    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);

    pcc->xscom_ops = &pnv_core_power8_xscom_ops;
}

static void pnv_core_power9_class_init(ObjectClass *oc, void *data)
{
    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);

    pcc->xscom_ops = &pnv_core_power9_xscom_ops;
}

static void pnv_core_power10_class_init(ObjectClass *oc, void *data)
{
    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);

    /* TODO: Use the P9 XSCOMs for now on P10 */
    pcc->xscom_ops = &pnv_core_power9_xscom_ops;
}

static void pnv_core_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->realize = pnv_core_realize;
    dc->unrealize = pnv_core_unrealize;
    device_class_set_props(dc, pnv_core_properties);
    dc->user_creatable = false;
}

#define DEFINE_PNV_CORE_TYPE(family, cpu_model) \
    {                                           \
        .parent = TYPE_PNV_CORE,                \
        .name = PNV_CORE_TYPE_NAME(cpu_model),  \
        .class_init = pnv_core_##family##_class_init, \
    }

static const TypeInfo pnv_core_infos[] = {
    {
        .name           = TYPE_PNV_CORE,
        .parent         = TYPE_CPU_CORE,
        .instance_size  = sizeof(PnvCore),
        .class_size     = sizeof(PnvCoreClass),
        .class_init = pnv_core_class_init,
        .abstract       = true,
    },
    DEFINE_PNV_CORE_TYPE(power8, "power8e_v2.1"),
    DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
    DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
    DEFINE_PNV_CORE_TYPE(power9, "power9_v2.2"),
    DEFINE_PNV_CORE_TYPE(power10, "power10_v2.0"),
};

DEFINE_TYPES(pnv_core_infos)

/*
 * POWER9 Quads
 */

#define P9X_EX_NCU_SPEC_BAR                     0x11010

static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr,
                                    unsigned int width)
{
    uint32_t offset = addr >> 3;
    uint64_t val = -1;

    switch (offset) {
    case P9X_EX_NCU_SPEC_BAR:
    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
        val = 0;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
                      offset);
    }

    return val;
}

static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val,
                                 unsigned int width)
{
    uint32_t offset = addr >> 3;

    switch (offset) {
    case P9X_EX_NCU_SPEC_BAR:
    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
                  offset);
    }
}

static const MemoryRegionOps pnv_quad_xscom_ops = {
    .read = pnv_quad_xscom_read,
    .write = pnv_quad_xscom_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_quad_realize(DeviceState *dev, Error **errp)
{
    PnvQuad *eq = PNV_QUAD(dev);
    char name[32];

    snprintf(name, sizeof(name), "xscom-quad.%d", eq->quad_id);
    pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), &pnv_quad_xscom_ops,
                          eq, name, PNV9_XSCOM_EQ_SIZE);
}

static Property pnv_quad_properties[] = {
    DEFINE_PROP_UINT32("quad-id", PnvQuad, quad_id, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void pnv_quad_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->realize = pnv_quad_realize;
    device_class_set_props(dc, pnv_quad_properties);
    dc->user_creatable = false;
}

static const TypeInfo pnv_quad_info = {
    .name          = TYPE_PNV_QUAD,
    .parent        = TYPE_DEVICE,
    .instance_size = sizeof(PnvQuad),
    .class_init    = pnv_quad_class_init,
};

static void pnv_core_register_types(void)
{
    type_register_static(&pnv_quad_info);
}

type_init(pnv_core_register_types)
