/*
 * Nuvoton NPCM7xx OTP (Fuse Array) Interface
 *
 * Copyright 2020 Google LLC
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 */

#include "qemu/osdep.h"

#include "hw/nvram/npcm7xx_otp.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/units.h"

/* Each module has 4 KiB of register space. Only a fraction of it is used. */
#define NPCM7XX_OTP_REGS_SIZE (4 * KiB)

/* 32-bit register indices. */
typedef enum NPCM7xxOTPRegister {
    NPCM7XX_OTP_FST,
    NPCM7XX_OTP_FADDR,
    NPCM7XX_OTP_FDATA,
    NPCM7XX_OTP_FCFG,
    /* Offset 0x10 is FKEYIND in OTP1, FUSTRAP in OTP2 */
    NPCM7XX_OTP_FKEYIND = 0x0010 / sizeof(uint32_t),
    NPCM7XX_OTP_FUSTRAP = 0x0010 / sizeof(uint32_t),
    NPCM7XX_OTP_FCTL,
    NPCM7XX_OTP_REGS_END,
} NPCM7xxOTPRegister;

/* Register field definitions. */
#define FST_RIEN BIT(2)
#define FST_RDST BIT(1)
#define FST_RDY BIT(0)
#define FST_RO_MASK (FST_RDST | FST_RDY)

#define FADDR_BYTEADDR(rv) extract32((rv), 0, 10)
#define FADDR_BITPOS(rv) extract32((rv), 10, 3)

#define FDATA_CLEAR 0x00000001

#define FCFG_FDIS BIT(31)
#define FCFG_FCFGLK_MASK 0x00ff0000

#define FCTL_PROG_CMD1 0x00000001
#define FCTL_PROG_CMD2 0xbf79e5d0
#define FCTL_READ_CMD 0x00000002

/**
 * struct NPCM7xxOTPClass - OTP module class.
 * @parent: System bus device class.
 * @mmio_ops: MMIO register operations for this type of module.
 *
 * The two OTP modules (key-storage and fuse-array) have slightly different
 * behavior, so we give them different MMIO register operations.
 */
struct NPCM7xxOTPClass {
    SysBusDeviceClass parent;

    const MemoryRegionOps *mmio_ops;
};

#define NPCM7XX_OTP_CLASS(klass) \
    OBJECT_CLASS_CHECK(NPCM7xxOTPClass, (klass), TYPE_NPCM7XX_OTP)
#define NPCM7XX_OTP_GET_CLASS(obj) \
    OBJECT_GET_CLASS(NPCM7xxOTPClass, (obj), TYPE_NPCM7XX_OTP)

static uint8_t ecc_encode_nibble(uint8_t n)
{
    uint8_t result = n;

    result |= (((n >> 0) & 1) ^ ((n >> 1) & 1)) << 4;
    result |= (((n >> 2) & 1) ^ ((n >> 3) & 1)) << 5;
    result |= (((n >> 0) & 1) ^ ((n >> 2) & 1)) << 6;
    result |= (((n >> 1) & 1) ^ ((n >> 3) & 1)) << 7;

    return result;
}

void npcm7xx_otp_array_write(NPCM7xxOTPState *s, const void *data,
                             unsigned int offset, unsigned int len)
{
    const uint8_t *src = data;
    uint8_t *dst = &s->array[offset];

    while (len-- > 0) {
        uint8_t c = *src++;

        *dst++ = ecc_encode_nibble(extract8(c, 0, 4));
        *dst++ = ecc_encode_nibble(extract8(c, 4, 4));
    }
}

/* Common register read handler for both OTP classes. */
static uint64_t npcm7xx_otp_read(NPCM7xxOTPState *s, NPCM7xxOTPRegister reg)
{
    uint32_t value = 0;

    switch (reg) {
    case NPCM7XX_OTP_FST:
    case NPCM7XX_OTP_FADDR:
    case NPCM7XX_OTP_FDATA:
    case NPCM7XX_OTP_FCFG:
        value = s->regs[reg];
        break;

    case NPCM7XX_OTP_FCTL:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: read from write-only FCTL register\n",
                      DEVICE(s)->canonical_path);
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: read from invalid offset 0x%zx\n",
                      DEVICE(s)->canonical_path, reg * sizeof(uint32_t));
        break;
    }

    return value;
}

/* Read a byte from the OTP array into the data register. */
static void npcm7xx_otp_read_array(NPCM7xxOTPState *s)
{
    uint32_t faddr = s->regs[NPCM7XX_OTP_FADDR];

    s->regs[NPCM7XX_OTP_FDATA] = s->array[FADDR_BYTEADDR(faddr)];
    s->regs[NPCM7XX_OTP_FST] |= FST_RDST | FST_RDY;
}

/* Program a byte from the data register into the OTP array. */
static void npcm7xx_otp_program_array(NPCM7xxOTPState *s)
{
    uint32_t faddr = s->regs[NPCM7XX_OTP_FADDR];

    /* Bits can only go 0->1, never 1->0. */
    s->array[FADDR_BYTEADDR(faddr)] |= (1U << FADDR_BITPOS(faddr));
    s->regs[NPCM7XX_OTP_FST] |= FST_RDST | FST_RDY;
}

/* Compute the next value of the FCFG register. */
static uint32_t npcm7xx_otp_compute_fcfg(uint32_t cur_value, uint32_t new_value)
{
    uint32_t lock_mask;
    uint32_t value;

    /*
     * FCFGLK holds sticky bits 16..23, indicating which bits in FPRGLK (8..15)
     * and FRDLK (0..7) that are read-only.
     */
    lock_mask = (cur_value & FCFG_FCFGLK_MASK) >> 8;
    lock_mask |= lock_mask >> 8;
    /* FDIS and FCFGLK bits are sticky (write 1 to set; can't clear). */
    value = cur_value & (FCFG_FDIS | FCFG_FCFGLK_MASK);
    /* Preserve read-only bits in FPRGLK and FRDLK */
    value |= cur_value & lock_mask;
    /* Set all bits that aren't read-only. */
    value |= new_value & ~lock_mask;

    return value;
}

/* Common register write handler for both OTP classes. */
static void npcm7xx_otp_write(NPCM7xxOTPState *s, NPCM7xxOTPRegister reg,
                              uint32_t value)
{
    switch (reg) {
    case NPCM7XX_OTP_FST:
        /* RDST is cleared by writing 1 to it. */
        if (value & FST_RDST) {
            s->regs[NPCM7XX_OTP_FST] &= ~FST_RDST;
        }
        /* Preserve read-only and write-one-to-clear bits */
        value &= ~FST_RO_MASK;
        value |= s->regs[NPCM7XX_OTP_FST] & FST_RO_MASK;
        break;

    case NPCM7XX_OTP_FADDR:
        break;

    case NPCM7XX_OTP_FDATA:
        /*
         * This register is cleared by writing a magic value to it; no other
         * values can be written.
         */
        if (value == FDATA_CLEAR) {
            value = 0;
        } else {
            value = s->regs[NPCM7XX_OTP_FDATA];
        }
        break;

    case NPCM7XX_OTP_FCFG:
        value = npcm7xx_otp_compute_fcfg(s->regs[NPCM7XX_OTP_FCFG], value);
        break;

    case NPCM7XX_OTP_FCTL:
        switch (value) {
        case FCTL_READ_CMD:
            npcm7xx_otp_read_array(s);
            break;

        case FCTL_PROG_CMD1:
            /*
             * Programming requires writing two separate magic values to this
             * register; this is the first one. Just store it so it can be
             * verified later when the second magic value is received.
             */
            break;

        case FCTL_PROG_CMD2:
            /*
             * Only initiate programming if we received the first half of the
             * command immediately before this one.
             */
            if (s->regs[NPCM7XX_OTP_FCTL] == FCTL_PROG_CMD1) {
                npcm7xx_otp_program_array(s);
            }
            break;

        default:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "%s: unrecognized FCNTL value 0x%" PRIx32 "\n",
                          DEVICE(s)->canonical_path, value);
            break;
        }
        if (value != FCTL_PROG_CMD1) {
            value = 0;
        }
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: write to invalid offset 0x%zx\n",
                      DEVICE(s)->canonical_path, reg * sizeof(uint32_t));
        return;
    }

    s->regs[reg] = value;
}

/* Register read handler specific to the fuse array OTP module. */
static uint64_t npcm7xx_fuse_array_read(void *opaque, hwaddr addr,
                                        unsigned int size)
{
    NPCM7xxOTPRegister reg = addr / sizeof(uint32_t);
    NPCM7xxOTPState *s = opaque;
    uint32_t value;

    /*
     * Only the Fuse Strap register needs special handling; all other registers
     * work the same way for both kinds of OTP modules.
     */
    if (reg != NPCM7XX_OTP_FUSTRAP) {
        value = npcm7xx_otp_read(s, reg);
    } else {
        /* FUSTRAP is stored as three copies in the OTP array. */
        uint32_t fustrap[3];

        memcpy(fustrap, &s->array[0], sizeof(fustrap));

        /* Determine value by a majority vote on each bit. */
        value = (fustrap[0] & fustrap[1]) | (fustrap[0] & fustrap[2]) |
                (fustrap[1] & fustrap[2]);
    }

    return value;
}

/* Register write handler specific to the fuse array OTP module. */
static void npcm7xx_fuse_array_write(void *opaque, hwaddr addr, uint64_t v,
                                     unsigned int size)
{
    NPCM7xxOTPRegister reg = addr / sizeof(uint32_t);
    NPCM7xxOTPState *s = opaque;

    /*
     * The Fuse Strap register is read-only. Other registers are handled by
     * common code.
     */
    if (reg != NPCM7XX_OTP_FUSTRAP) {
        npcm7xx_otp_write(s, reg, v);
    }
}

static const MemoryRegionOps npcm7xx_fuse_array_ops = {
    .read       = npcm7xx_fuse_array_read,
    .write      = npcm7xx_fuse_array_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid      = {
        .min_access_size        = 4,
        .max_access_size        = 4,
        .unaligned              = false,
    },
};

/* Register read handler specific to the key storage OTP module. */
static uint64_t npcm7xx_key_storage_read(void *opaque, hwaddr addr,
                                         unsigned int size)
{
    NPCM7xxOTPRegister reg = addr / sizeof(uint32_t);
    NPCM7xxOTPState *s = opaque;

    /*
     * Only the Fuse Key Index register needs special handling; all other
     * registers work the same way for both kinds of OTP modules.
     */
    if (reg != NPCM7XX_OTP_FKEYIND) {
        return npcm7xx_otp_read(s, reg);
    }

    qemu_log_mask(LOG_UNIMP, "%s: FKEYIND is not implemented\n", __func__);

    return s->regs[NPCM7XX_OTP_FKEYIND];
}

/* Register write handler specific to the key storage OTP module. */
static void npcm7xx_key_storage_write(void *opaque, hwaddr addr, uint64_t v,
                                      unsigned int size)
{
    NPCM7xxOTPRegister reg = addr / sizeof(uint32_t);
    NPCM7xxOTPState *s = opaque;

    /*
     * Only the Fuse Key Index register needs special handling; all other
     * registers work the same way for both kinds of OTP modules.
     */
    if (reg != NPCM7XX_OTP_FKEYIND) {
        npcm7xx_otp_write(s, reg, v);
        return;
    }

    qemu_log_mask(LOG_UNIMP, "%s: FKEYIND is not implemented\n", __func__);

    s->regs[NPCM7XX_OTP_FKEYIND] = v;
}

static const MemoryRegionOps npcm7xx_key_storage_ops = {
    .read       = npcm7xx_key_storage_read,
    .write      = npcm7xx_key_storage_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid      = {
        .min_access_size        = 4,
        .max_access_size        = 4,
        .unaligned              = false,
    },
};

static void npcm7xx_otp_enter_reset(Object *obj, ResetType type)
{
    NPCM7xxOTPState *s = NPCM7XX_OTP(obj);

    memset(s->regs, 0, sizeof(s->regs));

    s->regs[NPCM7XX_OTP_FST] = 0x00000001;
    s->regs[NPCM7XX_OTP_FCFG] = 0x20000000;
}

static void npcm7xx_otp_realize(DeviceState *dev, Error **errp)
{
    NPCM7xxOTPClass *oc = NPCM7XX_OTP_GET_CLASS(dev);
    NPCM7xxOTPState *s = NPCM7XX_OTP(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    memset(s->array, 0, sizeof(s->array));

    memory_region_init_io(&s->mmio, OBJECT(s), oc->mmio_ops, s, "regs",
                          NPCM7XX_OTP_REGS_SIZE);
    sysbus_init_mmio(sbd, &s->mmio);
}

static const VMStateDescription vmstate_npcm7xx_otp = {
    .name = "npcm7xx-otp",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, NPCM7xxOTPState, NPCM7XX_OTP_NR_REGS),
        VMSTATE_UINT8_ARRAY(array, NPCM7xxOTPState, NPCM7XX_OTP_ARRAY_BYTES),
        VMSTATE_END_OF_LIST(),
    },
};

static void npcm7xx_otp_class_init(ObjectClass *klass, void *data)
{
    ResettableClass *rc = RESETTABLE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    QEMU_BUILD_BUG_ON(NPCM7XX_OTP_REGS_END > NPCM7XX_OTP_NR_REGS);

    dc->realize = npcm7xx_otp_realize;
    dc->vmsd = &vmstate_npcm7xx_otp;
    rc->phases.enter = npcm7xx_otp_enter_reset;
}

static void npcm7xx_key_storage_class_init(ObjectClass *klass, void *data)
{
    NPCM7xxOTPClass *oc = NPCM7XX_OTP_CLASS(klass);

    oc->mmio_ops = &npcm7xx_key_storage_ops;
}

static void npcm7xx_fuse_array_class_init(ObjectClass *klass, void *data)
{
    NPCM7xxOTPClass *oc = NPCM7XX_OTP_CLASS(klass);

    oc->mmio_ops = &npcm7xx_fuse_array_ops;
}

static const TypeInfo npcm7xx_otp_types[] = {
    {
        .name = TYPE_NPCM7XX_OTP,
        .parent = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(NPCM7xxOTPState),
        .class_size = sizeof(NPCM7xxOTPClass),
        .class_init = npcm7xx_otp_class_init,
        .abstract = true,
    },
    {
        .name = TYPE_NPCM7XX_KEY_STORAGE,
        .parent = TYPE_NPCM7XX_OTP,
        .class_init = npcm7xx_key_storage_class_init,
    },
    {
        .name = TYPE_NPCM7XX_FUSE_ARRAY,
        .parent = TYPE_NPCM7XX_OTP,
        .class_init = npcm7xx_fuse_array_class_init,
    },
};
DEFINE_TYPES(npcm7xx_otp_types);
