/*
 * QEMU PowerPC PowerNV Emulation of a few HOMER related registers
 *
 * Copyright (c) 2019, IBM Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "exec/hwaddr.h"
#include "exec/memory.h"
#include "sysemu/cpus.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_homer.h"
#include "hw/ppc/pnv_xscom.h"


static bool core_max_array(PnvHomer *homer, hwaddr addr)
{
    int i;
    PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);

    for (i = 0; i <= homer->chip->nr_cores; i++) {
        if (addr == (hmrc->core_max_base + i)) {
            return true;
       }
    }
    return false;
}

/* P8 Pstate table */

#define PNV8_OCC_PSTATE_VERSION          0x1f8001
#define PNV8_OCC_PSTATE_MIN              0x1f8003
#define PNV8_OCC_PSTATE_VALID            0x1f8000
#define PNV8_OCC_PSTATE_THROTTLE         0x1f8002
#define PNV8_OCC_PSTATE_NOM              0x1f8004
#define PNV8_OCC_PSTATE_TURBO            0x1f8005
#define PNV8_OCC_PSTATE_ULTRA_TURBO      0x1f8006
#define PNV8_OCC_PSTATE_DATA             0x1f8008
#define PNV8_OCC_PSTATE_ID_ZERO          0x1f8010
#define PNV8_OCC_PSTATE_ID_ONE           0x1f8018
#define PNV8_OCC_PSTATE_ID_TWO           0x1f8020
#define PNV8_OCC_VDD_VOLTAGE_IDENTIFIER  0x1f8012
#define PNV8_OCC_VCS_VOLTAGE_IDENTIFIER  0x1f8013
#define PNV8_OCC_PSTATE_ZERO_FREQUENCY   0x1f8014
#define PNV8_OCC_PSTATE_ONE_FREQUENCY    0x1f801c
#define PNV8_OCC_PSTATE_TWO_FREQUENCY    0x1f8024
#define PNV8_CORE_MAX_BASE               0x1f8810


static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr,
                                      unsigned size)
{
    PnvHomer *homer = PNV_HOMER(opaque);

    switch (addr) {
    case PNV8_OCC_PSTATE_VERSION:
    case PNV8_OCC_PSTATE_MIN:
    case PNV8_OCC_PSTATE_ID_ZERO:
        return 0;
    case PNV8_OCC_PSTATE_VALID:
    case PNV8_OCC_PSTATE_THROTTLE:
    case PNV8_OCC_PSTATE_NOM:
    case PNV8_OCC_PSTATE_TURBO:
    case PNV8_OCC_PSTATE_ID_ONE:
    case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER:
    case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER:
        return 1;
    case PNV8_OCC_PSTATE_ULTRA_TURBO:
    case PNV8_OCC_PSTATE_ID_TWO:
        return 2;
    case PNV8_OCC_PSTATE_DATA:
        return 0x1000000000000000;
    /* P8 frequency for 0, 1, and 2 pstates */
    case PNV8_OCC_PSTATE_ZERO_FREQUENCY:
    case PNV8_OCC_PSTATE_ONE_FREQUENCY:
    case PNV8_OCC_PSTATE_TWO_FREQUENCY:
        return 3000;
    }
    /* pstate table core max array */
    if (core_max_array(homer, addr)) {
        return 1;
    }
    return 0;
}

static void pnv_power8_homer_write(void *opaque, hwaddr addr,
                                   uint64_t val, unsigned size)
{
    /* callback function defined to homer write */
    return;
}

static const MemoryRegionOps pnv_power8_homer_ops = {
    .read = pnv_power8_homer_read,
    .write = pnv_power8_homer_write,
    .valid.min_access_size = 1,
    .valid.max_access_size = 8,
    .impl.min_access_size = 1,
    .impl.max_access_size = 8,
    .endianness = DEVICE_BIG_ENDIAN,
};

/* P8 PBA BARs */
#define PBA_BAR0                     0x00
#define PBA_BAR1                     0x01
#define PBA_BAR2                     0x02
#define PBA_BAR3                     0x03
#define PBA_BARMASK0                 0x04
#define PBA_BARMASK1                 0x05
#define PBA_BARMASK2                 0x06
#define PBA_BARMASK3                 0x07

static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr,
                                          unsigned size)
{
    PnvHomer *homer = PNV_HOMER(opaque);
    PnvChip *chip = homer->chip;
    uint32_t reg = addr >> 3;
    uint64_t val = 0;

    switch (reg) {
    case PBA_BAR0:
        val = PNV_HOMER_BASE(chip);
        break;
    case PBA_BARMASK0: /* P8 homer region mask */
        val = (PNV_HOMER_SIZE - 1) & 0x300000;
        break;
    case PBA_BAR3: /* P8 occ common area */
        val = PNV_OCC_COMMON_AREA_BASE;
        break;
    case PBA_BARMASK3: /* P8 occ common area mask */
        val = (PNV_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
                      HWADDR_PRIx "\n", addr >> 3);
    }
    return val;
}

static void pnv_homer_power8_pba_write(void *opaque, hwaddr addr,
                                         uint64_t val, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
                  HWADDR_PRIx "\n", addr >> 3);
}

static const MemoryRegionOps pnv_homer_power8_pba_ops = {
    .read = pnv_homer_power8_pba_read,
    .write = pnv_homer_power8_pba_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_homer_power8_class_init(ObjectClass *klass, void *data)
{
    PnvHomerClass *homer = PNV_HOMER_CLASS(klass);

    homer->pba_size = PNV_XSCOM_PBA_SIZE;
    homer->pba_ops = &pnv_homer_power8_pba_ops;
    homer->homer_size = PNV_HOMER_SIZE;
    homer->homer_ops = &pnv_power8_homer_ops;
    homer->core_max_base = PNV8_CORE_MAX_BASE;
}

static const TypeInfo pnv_homer_power8_type_info = {
    .name          = TYPE_PNV8_HOMER,
    .parent        = TYPE_PNV_HOMER,
    .instance_size = sizeof(PnvHomer),
    .class_init    = pnv_homer_power8_class_init,
};

/* P9 Pstate table */

#define PNV9_OCC_PSTATE_ID_ZERO          0xe2018
#define PNV9_OCC_PSTATE_ID_ONE           0xe2020
#define PNV9_OCC_PSTATE_ID_TWO           0xe2028
#define PNV9_OCC_PSTATE_DATA             0xe2000
#define PNV9_OCC_PSTATE_DATA_AREA        0xe2008
#define PNV9_OCC_PSTATE_MIN              0xe2003
#define PNV9_OCC_PSTATE_NOM              0xe2004
#define PNV9_OCC_PSTATE_TURBO            0xe2005
#define PNV9_OCC_PSTATE_ULTRA_TURBO      0xe2818
#define PNV9_OCC_MAX_PSTATE_ULTRA_TURBO  0xe2006
#define PNV9_OCC_PSTATE_MAJOR_VERSION    0xe2001
#define PNV9_OCC_OPAL_RUNTIME_DATA       0xe2b85
#define PNV9_CHIP_HOMER_IMAGE_POINTER    0x200008
#define PNV9_CHIP_HOMER_BASE             0x0
#define PNV9_OCC_PSTATE_ZERO_FREQUENCY   0xe201c
#define PNV9_OCC_PSTATE_ONE_FREQUENCY    0xe2024
#define PNV9_OCC_PSTATE_TWO_FREQUENCY    0xe202c
#define PNV9_OCC_ROLE_MASTER_OR_SLAVE    0xe2002
#define PNV9_CORE_MAX_BASE               0xe2819


static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr,
                                      unsigned size)
{
    PnvHomer *homer = PNV_HOMER(opaque);

    switch (addr) {
    case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO:
    case PNV9_OCC_PSTATE_ID_ZERO:
        return 0;
    case PNV9_OCC_PSTATE_DATA:
    case PNV9_OCC_ROLE_MASTER_OR_SLAVE:
    case PNV9_OCC_PSTATE_NOM:
    case PNV9_OCC_PSTATE_TURBO:
    case PNV9_OCC_PSTATE_ID_ONE:
    case PNV9_OCC_PSTATE_ULTRA_TURBO:
    case PNV9_OCC_OPAL_RUNTIME_DATA:
        return 1;
    case PNV9_OCC_PSTATE_MIN:
    case PNV9_OCC_PSTATE_ID_TWO:
        return 2;

    /* 3000 khz frequency for 0, 1, and 2 pstates */
    case PNV9_OCC_PSTATE_ZERO_FREQUENCY:
    case PNV9_OCC_PSTATE_ONE_FREQUENCY:
    case PNV9_OCC_PSTATE_TWO_FREQUENCY:
        return 3000;
    case PNV9_OCC_PSTATE_MAJOR_VERSION:
        return 0x90;
    case PNV9_CHIP_HOMER_BASE:
    case PNV9_OCC_PSTATE_DATA_AREA:
    case PNV9_CHIP_HOMER_IMAGE_POINTER:
        return 0x1000000000000000;
    }
    /* pstate table core max array */
    if (core_max_array(homer, addr)) {
        return 1;
    }
    return 0;
}

static void pnv_power9_homer_write(void *opaque, hwaddr addr,
                                   uint64_t val, unsigned size)
{
    /* callback function defined to homer write */
    return;
}

static const MemoryRegionOps pnv_power9_homer_ops = {
    .read = pnv_power9_homer_read,
    .write = pnv_power9_homer_write,
    .valid.min_access_size = 1,
    .valid.max_access_size = 8,
    .impl.min_access_size = 1,
    .impl.max_access_size = 8,
    .endianness = DEVICE_BIG_ENDIAN,
};

static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr,
                                          unsigned size)
{
    PnvHomer *homer = PNV_HOMER(opaque);
    PnvChip *chip = homer->chip;
    uint32_t reg = addr >> 3;
    uint64_t val = 0;

    switch (reg) {
    case PBA_BAR0:
        val = PNV9_HOMER_BASE(chip);
        break;
    case PBA_BARMASK0: /* P9 homer region mask */
        val = (PNV9_HOMER_SIZE - 1) & 0x300000;
        break;
    case PBA_BAR2: /* P9 occ common area */
        val = PNV9_OCC_COMMON_AREA_BASE;
        break;
    case PBA_BARMASK2: /* P9 occ common area size */
        val = (PNV9_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
                      HWADDR_PRIx "\n", addr >> 3);
    }
    return val;
}

static void pnv_homer_power9_pba_write(void *opaque, hwaddr addr,
                                         uint64_t val, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
                  HWADDR_PRIx "\n", addr >> 3);
}

static const MemoryRegionOps pnv_homer_power9_pba_ops = {
    .read = pnv_homer_power9_pba_read,
    .write = pnv_homer_power9_pba_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_homer_power9_class_init(ObjectClass *klass, void *data)
{
    PnvHomerClass *homer = PNV_HOMER_CLASS(klass);

    homer->pba_size = PNV9_XSCOM_PBA_SIZE;
    homer->pba_ops = &pnv_homer_power9_pba_ops;
    homer->homer_size = PNV9_HOMER_SIZE;
    homer->homer_ops = &pnv_power9_homer_ops;
    homer->core_max_base = PNV9_CORE_MAX_BASE;
}

static const TypeInfo pnv_homer_power9_type_info = {
    .name          = TYPE_PNV9_HOMER,
    .parent        = TYPE_PNV_HOMER,
    .instance_size = sizeof(PnvHomer),
    .class_init    = pnv_homer_power9_class_init,
};

static uint64_t pnv_homer_power10_pba_read(void *opaque, hwaddr addr,
                                          unsigned size)
{
    PnvHomer *homer = PNV_HOMER(opaque);
    PnvChip *chip = homer->chip;
    uint32_t reg = addr >> 3;
    uint64_t val = 0;

    switch (reg) {
    case PBA_BAR0:
        val = PNV10_HOMER_BASE(chip);
        break;
    case PBA_BARMASK0: /* P10 homer region mask */
        val = (PNV10_HOMER_SIZE - 1) & 0x300000;
        break;
    case PBA_BAR2: /* P10 occ common area */
        val = PNV10_OCC_COMMON_AREA_BASE;
        break;
    case PBA_BARMASK2: /* P10 occ common area size */
        val = (PNV10_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
                      HWADDR_PRIx "\n", addr >> 3);
    }
    return val;
}

static void pnv_homer_power10_pba_write(void *opaque, hwaddr addr,
                                         uint64_t val, unsigned size)
{
    qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
                  HWADDR_PRIx "\n", addr >> 3);
}

static const MemoryRegionOps pnv_homer_power10_pba_ops = {
    .read = pnv_homer_power10_pba_read,
    .write = pnv_homer_power10_pba_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_homer_power10_class_init(ObjectClass *klass, void *data)
{
    PnvHomerClass *homer = PNV_HOMER_CLASS(klass);

    homer->pba_size = PNV10_XSCOM_PBA_SIZE;
    homer->pba_ops = &pnv_homer_power10_pba_ops;
    homer->homer_size = PNV10_HOMER_SIZE;
    homer->homer_ops = &pnv_power9_homer_ops; /* TODO */
    homer->core_max_base = PNV9_CORE_MAX_BASE;
}

static const TypeInfo pnv_homer_power10_type_info = {
    .name          = TYPE_PNV10_HOMER,
    .parent        = TYPE_PNV_HOMER,
    .instance_size = sizeof(PnvHomer),
    .class_init    = pnv_homer_power10_class_init,
};

static void pnv_homer_realize(DeviceState *dev, Error **errp)
{
    PnvHomer *homer = PNV_HOMER(dev);
    PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);

    assert(homer->chip);

    pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops,
                          homer, "xscom-pba", hmrc->pba_size);

    /* homer region */
    memory_region_init_io(&homer->regs, OBJECT(dev),
                          hmrc->homer_ops, homer, "homer-main-memory",
                          hmrc->homer_size);
}

static Property pnv_homer_properties[] = {
    DEFINE_PROP_LINK("chip", PnvHomer, chip, TYPE_PNV_CHIP, PnvChip *),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = pnv_homer_realize;
    dc->desc = "PowerNV HOMER Memory";
    device_class_set_props(dc, pnv_homer_properties);
    dc->user_creatable = false;
}

static const TypeInfo pnv_homer_type_info = {
    .name          = TYPE_PNV_HOMER,
    .parent        = TYPE_DEVICE,
    .instance_size = sizeof(PnvHomer),
    .class_init    = pnv_homer_class_init,
    .class_size    = sizeof(PnvHomerClass),
    .abstract      = true,
};

static void pnv_homer_register_types(void)
{
    type_register_static(&pnv_homer_type_info);
    type_register_static(&pnv_homer_power8_type_info);
    type_register_static(&pnv_homer_power9_type_info);
    type_register_static(&pnv_homer_power10_type_info);
}

type_init(pnv_homer_register_types);
