/*
 * 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 = NULL;

    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, nr, ram, 0) < 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, 4, &le32, 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)
