/*
 * QEMU model of the EFuse_Cache
 *
 * Copyright (c) 2017 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-versal-efuse.h"

#include "qemu/log.h"
#include "hw/qdev-properties.h"

#define MR_SIZE 0xC00

static uint64_t efuse_cache_read(void *opaque, hwaddr addr, unsigned size)
{
    XlnxVersalEFuseCache *s = XLNX_VERSAL_EFUSE_CACHE(opaque);
    unsigned int w0 = QEMU_ALIGN_DOWN(addr * 8, 32);
    unsigned int w1 = QEMU_ALIGN_DOWN((addr + size - 1) * 8, 32);

    uint64_t ret;

    assert(w0 == w1 || (w0 + 32) == w1);

    ret = xlnx_versal_efuse_read_row(s->efuse, w1, NULL);
    if (w0 < w1) {
        ret <<= 32;
        ret |= xlnx_versal_efuse_read_row(s->efuse, w0, NULL);
    }

    /* If 'addr' unaligned, the guest is always assumed to be little-endian. */
    addr &= 3;
    if (addr) {
        ret >>= 8 * addr;
    }

    return ret;
}

static void efuse_cache_write(void *opaque, hwaddr addr, uint64_t value,
                              unsigned size)
{
    /* No Register Writes allowed */
    qemu_log_mask(LOG_GUEST_ERROR, "%s: efuse cache registers are read-only",
                  __func__);
}

static const MemoryRegionOps efuse_cache_ops = {
    .read = efuse_cache_read,
    .write = efuse_cache_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void efuse_cache_init(Object *obj)
{
    XlnxVersalEFuseCache *s = XLNX_VERSAL_EFUSE_CACHE(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->iomem, obj, &efuse_cache_ops, s,
                          TYPE_XLNX_VERSAL_EFUSE_CACHE, MR_SIZE);
    sysbus_init_mmio(sbd, &s->iomem);
}

static Property efuse_cache_props[] = {
    DEFINE_PROP_LINK("efuse",
                     XlnxVersalEFuseCache, efuse,
                     TYPE_XLNX_EFUSE, XlnxEFuse *),

    DEFINE_PROP_END_OF_LIST(),
};

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

    device_class_set_props(dc, efuse_cache_props);
}

static const TypeInfo efuse_cache_info = {
    .name          = TYPE_XLNX_VERSAL_EFUSE_CACHE,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(XlnxVersalEFuseCache),
    .class_init    = efuse_cache_class_init,
    .instance_init = efuse_cache_init,
};

static void efuse_cache_register_types(void)
{
    type_register_static(&efuse_cache_info);
}

type_init(efuse_cache_register_types)
