/*
 * QEMU model of the Xilinx BBRAM Battery Backed RAM
 *
 * Copyright (c) 2014-2021 Xilinx Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "hw/nvram/xlnx-bbram.h"

#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "sysemu/blockdev.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/nvram/xlnx-efuse.h"

#ifndef XLNX_BBRAM_ERR_DEBUG
#define XLNX_BBRAM_ERR_DEBUG 0
#endif

REG32(BBRAM_STATUS, 0x0)
    FIELD(BBRAM_STATUS, AES_CRC_PASS, 9, 1)
    FIELD(BBRAM_STATUS, AES_CRC_DONE, 8, 1)
    FIELD(BBRAM_STATUS, BBRAM_ZEROIZED, 4, 1)
    FIELD(BBRAM_STATUS, PGM_MODE, 0, 1)
REG32(BBRAM_CTRL, 0x4)
    FIELD(BBRAM_CTRL, ZEROIZE, 0, 1)
REG32(PGM_MODE, 0x8)
REG32(BBRAM_AES_CRC, 0xc)
REG32(BBRAM_0, 0x10)
REG32(BBRAM_1, 0x14)
REG32(BBRAM_2, 0x18)
REG32(BBRAM_3, 0x1c)
REG32(BBRAM_4, 0x20)
REG32(BBRAM_5, 0x24)
REG32(BBRAM_6, 0x28)
REG32(BBRAM_7, 0x2c)
REG32(BBRAM_8, 0x30)
REG32(BBRAM_SLVERR, 0x34)
    FIELD(BBRAM_SLVERR, ENABLE, 0, 1)
REG32(BBRAM_ISR, 0x38)
    FIELD(BBRAM_ISR, APB_SLVERR, 0, 1)
REG32(BBRAM_IMR, 0x3c)
    FIELD(BBRAM_IMR, APB_SLVERR, 0, 1)
REG32(BBRAM_IER, 0x40)
    FIELD(BBRAM_IER, APB_SLVERR, 0, 1)
REG32(BBRAM_IDR, 0x44)
    FIELD(BBRAM_IDR, APB_SLVERR, 0, 1)
REG32(BBRAM_MSW_LOCK, 0x4c)
    FIELD(BBRAM_MSW_LOCK, VAL, 0, 1)

#define R_MAX (R_BBRAM_MSW_LOCK + 1)

#define RAM_MAX (A_BBRAM_8 + 4 - A_BBRAM_0)

#define BBRAM_PGM_MAGIC 0x757bdf0d

QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxBBRam *)0)->regs));

static bool bbram_msw_locked(XlnxBBRam *s)
{
    return ARRAY_FIELD_EX32(s->regs, BBRAM_MSW_LOCK, VAL) != 0;
}

static bool bbram_pgm_enabled(XlnxBBRam *s)
{
    return ARRAY_FIELD_EX32(s->regs, BBRAM_STATUS, PGM_MODE) != 0;
}

static void bbram_bdrv_error(XlnxBBRam *s, int rc, gchar *detail)
{
    Error *errp;

    error_setg_errno(&errp, -rc, "%s: BBRAM backstore %s failed.",
                     blk_name(s->blk), detail);
    error_report("%s", error_get_pretty(errp));
    error_free(errp);

    g_free(detail);
}

static void bbram_bdrv_read(XlnxBBRam *s, Error **errp)
{
    uint32_t *ram = &s->regs[R_BBRAM_0];
    int nr = RAM_MAX;

    if (!s->blk) {
        return;
    }

    s->blk_ro = !blk_supports_write_perm(s->blk);
    if (!s->blk_ro) {
        int rc;

        rc = blk_set_perm(s->blk,
                          (BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE),
                          BLK_PERM_ALL, NULL);
        if (rc) {
            s->blk_ro = true;
        }
    }
    if (s->blk_ro) {
        warn_report("%s: Skip saving updates to read-only BBRAM backstore.",
                    blk_name(s->blk));
    }

    if (blk_pread(s->blk, 0, ram, nr) < 0) {
        error_setg(errp,
                   "%s: Failed to read %u bytes from BBRAM backstore.",
                   blk_name(s->blk), nr);
        return;
    }

    /* Convert from little-endian backstore for each 32-bit word */
    nr /= 4;
    while (nr--) {
        ram[nr] = le32_to_cpu(ram[nr]);
    }
}

static void bbram_bdrv_sync(XlnxBBRam *s, uint64_t hwaddr)
{
    uint32_t le32;
    unsigned offset;
    int rc;

    assert(A_BBRAM_0 <= hwaddr && hwaddr <= A_BBRAM_8);

    /* Backstore is always in little-endian */
    le32 = cpu_to_le32(s->regs[hwaddr / 4]);

    /* Update zeroized flag */
    if (le32 && (hwaddr != A_BBRAM_8 || s->bbram8_wo)) {
        ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, BBRAM_ZEROIZED, 0);
    }

    if (!s->blk || s->blk_ro) {
        return;
    }

    offset = hwaddr - A_BBRAM_0;
    rc = blk_pwrite(s->blk, offset, &le32, 4, 0);
    if (rc < 0) {
        bbram_bdrv_error(s, rc, g_strdup_printf("write to offset %u", offset));
    }
}

static void bbram_bdrv_zero(XlnxBBRam *s)
{
    int rc;

    ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, BBRAM_ZEROIZED, 1);

    if (!s->blk || s->blk_ro) {
        return;
    }

    rc = blk_make_zero(s->blk, 0);
    if (rc < 0) {
        bbram_bdrv_error(s, rc, g_strdup("zeroizing"));
    }

    /* Restore bbram8 if it is non-zero */
    if (s->regs[R_BBRAM_8]) {
        bbram_bdrv_sync(s, A_BBRAM_8);
    }
}

static void bbram_zeroize(XlnxBBRam *s)
{
    int nr = RAM_MAX - (s->bbram8_wo ? 0 : 4); /* only wo bbram8 is cleared */

    memset(&s->regs[R_BBRAM_0], 0, nr);
    bbram_bdrv_zero(s);
}

static void bbram_update_irq(XlnxBBRam *s)
{
    bool pending = s->regs[R_BBRAM_ISR] & ~s->regs[R_BBRAM_IMR];

    qemu_set_irq(s->irq_bbram, pending);
}

static void bbram_ctrl_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
    uint32_t val = val64;

    if (val & R_BBRAM_CTRL_ZEROIZE_MASK) {
        bbram_zeroize(s);
        /* The bit is self clearing */
        s->regs[R_BBRAM_CTRL] &= ~R_BBRAM_CTRL_ZEROIZE_MASK;
    }
}

static void bbram_pgm_mode_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
    uint32_t val = val64;

    if (val == BBRAM_PGM_MAGIC) {
        bbram_zeroize(s);

        /* The status bit is cleared only by POR */
        ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, PGM_MODE, 1);
    }
}

static void bbram_aes_crc_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
    uint32_t calc_crc;

    if (!bbram_pgm_enabled(s)) {
        /* We are not in programming mode, don't do anything */
        return;
    }

    /* Perform the AES integrity check */
    s->regs[R_BBRAM_STATUS] |= R_BBRAM_STATUS_AES_CRC_DONE_MASK;

    /*
     * Set check status.
     *
     * ZynqMP BBRAM check has a zero-u32 prepended; see:
     *  https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_bbramps_zynqmp.c#L311
     */
    calc_crc = xlnx_efuse_calc_crc(&s->regs[R_BBRAM_0],
                                   (R_BBRAM_8 - R_BBRAM_0), s->crc_zpads);

    ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, AES_CRC_PASS,
                     (s->regs[R_BBRAM_AES_CRC] == calc_crc));
}

static uint64_t bbram_key_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
    uint32_t original_data = *(uint32_t *) reg->data;

    if (bbram_pgm_enabled(s)) {
        return val64;
    } else {
        /* We are not in programming mode, don't do anything */
        qemu_log_mask(LOG_GUEST_ERROR,
                      "Not in programming mode, dropping the write\n");
        return original_data;
    }
}

static void bbram_key_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);

    bbram_bdrv_sync(s, reg->access->addr);
}

static uint64_t bbram_wo_postr(RegisterInfo *reg, uint64_t val)
{
    return 0;
}

static uint64_t bbram_r8_postr(RegisterInfo *reg, uint64_t val)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);

    return s->bbram8_wo ? bbram_wo_postr(reg, val) : val;
}

static bool bbram_r8_readonly(XlnxBBRam *s)
{
    return !bbram_pgm_enabled(s) || bbram_msw_locked(s);
}

static uint64_t bbram_r8_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);

    if (bbram_r8_readonly(s)) {
        val64 = *(uint32_t *)reg->data;
    }

    return val64;
}

static void bbram_r8_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);

    if (!bbram_r8_readonly(s)) {
        bbram_bdrv_sync(s, A_BBRAM_8);
    }
}

static uint64_t bbram_msw_lock_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);

    /* Never lock if bbram8 is wo; and, only POR can clear the lock */
    if (s->bbram8_wo) {
        val64 = 0;
    } else {
        val64 |= s->regs[R_BBRAM_MSW_LOCK];
    }

    return val64;
}

static void bbram_isr_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);

    bbram_update_irq(s);
}

static uint64_t bbram_ier_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
    uint32_t val = val64;

    s->regs[R_BBRAM_IMR] &= ~val;
    bbram_update_irq(s);
    return 0;
}

static uint64_t bbram_idr_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxBBRam *s = XLNX_BBRAM(reg->opaque);
    uint32_t val = val64;

    s->regs[R_BBRAM_IMR] |= val;
    bbram_update_irq(s);
    return 0;
}

static RegisterAccessInfo bbram_ctrl_regs_info[] = {
    {   .name = "BBRAM_STATUS",  .addr = A_BBRAM_STATUS,
        .rsvd = 0xee,
        .ro = 0x3ff,
    },{ .name = "BBRAM_CTRL",  .addr = A_BBRAM_CTRL,
        .post_write = bbram_ctrl_postw,
    },{ .name = "PGM_MODE",  .addr = A_PGM_MODE,
        .post_write = bbram_pgm_mode_postw,
    },{ .name = "BBRAM_AES_CRC",  .addr = A_BBRAM_AES_CRC,
        .post_write = bbram_aes_crc_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_0",  .addr = A_BBRAM_0,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_1",  .addr = A_BBRAM_1,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_2",  .addr = A_BBRAM_2,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_3",  .addr = A_BBRAM_3,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_4",  .addr = A_BBRAM_4,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_5",  .addr = A_BBRAM_5,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_6",  .addr = A_BBRAM_6,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_7",  .addr = A_BBRAM_7,
        .pre_write = bbram_key_prew,
        .post_write = bbram_key_postw,
        .post_read = bbram_wo_postr,
    },{ .name = "BBRAM_8",  .addr = A_BBRAM_8,
        .pre_write = bbram_r8_prew,
        .post_write = bbram_r8_postw,
        .post_read = bbram_r8_postr,
    },{ .name = "BBRAM_SLVERR",  .addr = A_BBRAM_SLVERR,
        .rsvd = ~1,
    },{ .name = "BBRAM_ISR",  .addr = A_BBRAM_ISR,
        .w1c = 0x1,
        .post_write = bbram_isr_postw,
    },{ .name = "BBRAM_IMR",  .addr = A_BBRAM_IMR,
        .ro = 0x1,
    },{ .name = "BBRAM_IER",  .addr = A_BBRAM_IER,
        .pre_write = bbram_ier_prew,
    },{ .name = "BBRAM_IDR",  .addr = A_BBRAM_IDR,
        .pre_write = bbram_idr_prew,
    },{ .name = "BBRAM_MSW_LOCK",  .addr = A_BBRAM_MSW_LOCK,
        .pre_write = bbram_msw_lock_prew,
        .ro = ~R_BBRAM_MSW_LOCK_VAL_MASK,
    }
};

static void bbram_ctrl_reset(DeviceState *dev)
{
    XlnxBBRam *s = XLNX_BBRAM(dev);
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
        if (i < R_BBRAM_0 || i > R_BBRAM_8) {
            register_reset(&s->regs_info[i]);
        }
    }

    bbram_update_irq(s);
}

static const MemoryRegionOps bbram_ctrl_ops = {
    .read = register_read_memory,
    .write = register_write_memory,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void bbram_ctrl_realize(DeviceState *dev, Error **errp)
{
    XlnxBBRam *s = XLNX_BBRAM(dev);

    if (s->crc_zpads) {
        s->bbram8_wo = true;
    }

    bbram_bdrv_read(s, errp);
}

static void bbram_ctrl_init(Object *obj)
{
    XlnxBBRam *s = XLNX_BBRAM(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    RegisterInfoArray *reg_array;

    reg_array =
        register_init_block32(DEVICE(obj), bbram_ctrl_regs_info,
                              ARRAY_SIZE(bbram_ctrl_regs_info),
                              s->regs_info, s->regs,
                              &bbram_ctrl_ops,
                              XLNX_BBRAM_ERR_DEBUG,
                              R_MAX * 4);

    sysbus_init_mmio(sbd, &reg_array->mem);
    sysbus_init_irq(sbd, &s->irq_bbram);
}

static void bbram_prop_set_drive(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
{
    DeviceState *dev = DEVICE(obj);

    qdev_prop_drive.set(obj, v, name, opaque, errp);

    /* Fill initial data if backend is attached after realized */
    if (dev->realized) {
        bbram_bdrv_read(XLNX_BBRAM(obj), errp);
    }
}

static void bbram_prop_get_drive(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
{
    qdev_prop_drive.get(obj, v, name, opaque, errp);
}

static void bbram_prop_release_drive(Object *obj, const char *name,
                                     void *opaque)
{
    qdev_prop_drive.release(obj, name, opaque);
}

static const PropertyInfo bbram_prop_drive = {
    .name  = "str",
    .description = "Node name or ID of a block device to use as BBRAM backend",
    .realized_set_allowed = true,
    .get = bbram_prop_get_drive,
    .set = bbram_prop_set_drive,
    .release = bbram_prop_release_drive,
};

static const VMStateDescription vmstate_bbram_ctrl = {
    .name = TYPE_XLNX_BBRAM,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, XlnxBBRam, R_MAX),
        VMSTATE_END_OF_LIST(),
    }
};

static Property bbram_ctrl_props[] = {
    DEFINE_PROP("drive", XlnxBBRam, blk, bbram_prop_drive, BlockBackend *),
    DEFINE_PROP_UINT32("crc-zpads", XlnxBBRam, crc_zpads, 1),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->reset = bbram_ctrl_reset;
    dc->realize = bbram_ctrl_realize;
    dc->vmsd = &vmstate_bbram_ctrl;
    device_class_set_props(dc, bbram_ctrl_props);
}

static const TypeInfo bbram_ctrl_info = {
    .name          = TYPE_XLNX_BBRAM,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(XlnxBBRam),
    .class_init    = bbram_ctrl_class_init,
    .instance_init = bbram_ctrl_init,
};

static void bbram_ctrl_register_types(void)
{
    type_register_static(&bbram_ctrl_info);
}

type_init(bbram_ctrl_register_types)
