/*
 * QEMU PowerNV PNOR simple model
 *
 * Copyright (c) 2015-2019, IBM Corporation.
 *
 * This code is licensed under the GPL version 2 or later. See the
 * COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "hw/loader.h"
#include "hw/ppc/pnv_pnor.h"
#include "hw/qdev-properties.h"

static uint64_t pnv_pnor_read(void *opaque, hwaddr addr, unsigned size)
{
    PnvPnor *s = PNV_PNOR(opaque);
    uint64_t ret = 0;
    int i;

    for (i = 0; i < size; i++) {
        ret |= (uint64_t) s->storage[addr + i] << (8 * (size - i - 1));
    }

    return ret;
}

static void pnv_pnor_update(PnvPnor *s, int offset, int size)
{
    int offset_end;

    if (s->blk) {
        return;
    }

    offset_end = offset + size;
    offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
    offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);

    blk_pwrite(s->blk, offset, s->storage + offset,
               offset_end - offset, 0);
}

static void pnv_pnor_write(void *opaque, hwaddr addr, uint64_t data,
                           unsigned size)
{
    PnvPnor *s = PNV_PNOR(opaque);
    int i;

    for (i = 0; i < size; i++) {
        s->storage[addr + i] = (data >> (8 * (size - i - 1))) & 0xFF;
    }
    pnv_pnor_update(s, addr, size);
}

/*
 * TODO: Check endianness: skiboot is BIG, Aspeed AHB is LITTLE, flash
 * is BIG.
 */
static const MemoryRegionOps pnv_pnor_ops = {
    .read = pnv_pnor_read,
    .write = pnv_pnor_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void pnv_pnor_realize(DeviceState *dev, Error **errp)
{
    PnvPnor *s = PNV_PNOR(dev);
    int ret;

    if (s->blk) {
        uint64_t perm = BLK_PERM_CONSISTENT_READ |
                        (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
        ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
        if (ret < 0) {
            return;
        }

        s->size = blk_getlength(s->blk);
        if (s->size <= 0) {
            error_setg(errp, "failed to get flash size");
            return;
        }

        s->storage = blk_blockalign(s->blk, s->size);

        if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
            error_setg(errp, "failed to read the initial flash content");
            return;
        }
    } else {
        s->storage = blk_blockalign(NULL, s->size);
        memset(s->storage, 0xFF, s->size);
    }

    memory_region_init_io(&s->mmio, OBJECT(s), &pnv_pnor_ops, s,
                          TYPE_PNV_PNOR, s->size);
}

static Property pnv_pnor_properties[] = {
    DEFINE_PROP_UINT32("size", PnvPnor, size, 128 << 20),
    DEFINE_PROP_DRIVE("drive", PnvPnor, blk),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = pnv_pnor_realize;
    dc->props = pnv_pnor_properties;
}

static const TypeInfo pnv_pnor_info = {
    .name          = TYPE_PNV_PNOR,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(PnvPnor),
    .class_init    = pnv_pnor_class_init,
};

static void pnv_pnor_register_types(void)
{
    type_register_static(&pnv_pnor_info);
}

type_init(pnv_pnor_register_types)
