/*
 * Nuvoton NPCM7xx Random Number Generator.
 *
 * 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/misc/npcm7xx_rng.h"
#include "migration/vmstate.h"
#include "qemu/bitops.h"
#include "qemu/guest-random.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/units.h"

#include "trace.h"

#define NPCM7XX_RNG_REGS_SIZE   (4 * KiB)

#define NPCM7XX_RNGCS           (0x00)
#define NPCM7XX_RNGCS_CLKP(rv)      extract32(rv, 2, 4)
#define NPCM7XX_RNGCS_DVALID        BIT(1)
#define NPCM7XX_RNGCS_RNGE          BIT(0)

#define NPCM7XX_RNGD            (0x04)
#define NPCM7XX_RNGMODE         (0x08)
#define NPCM7XX_RNGMODE_NORMAL      (0x02)

static bool npcm7xx_rng_is_enabled(NPCM7xxRNGState *s)
{
    return (s->rngcs & NPCM7XX_RNGCS_RNGE) &&
        (s->rngmode == NPCM7XX_RNGMODE_NORMAL);
}

static uint64_t npcm7xx_rng_read(void *opaque, hwaddr offset, unsigned size)
{
    NPCM7xxRNGState *s = opaque;
    uint64_t value = 0;

    switch (offset) {
    case NPCM7XX_RNGCS:
        /*
         * If the RNG is enabled, but we don't have any valid random data, try
         * obtaining some and update the DVALID bit accordingly.
         */
        if (!npcm7xx_rng_is_enabled(s)) {
            s->rngcs &= ~NPCM7XX_RNGCS_DVALID;
        } else if (!(s->rngcs & NPCM7XX_RNGCS_DVALID)) {
            uint8_t byte = 0;

            if (qemu_guest_getrandom(&byte, sizeof(byte), NULL) == 0) {
                s->rngd = byte;
                s->rngcs |= NPCM7XX_RNGCS_DVALID;
            }
        }
        value = s->rngcs;
        break;
    case NPCM7XX_RNGD:
        if (npcm7xx_rng_is_enabled(s) && s->rngcs & NPCM7XX_RNGCS_DVALID) {
            s->rngcs &= ~NPCM7XX_RNGCS_DVALID;
            value = s->rngd;
            s->rngd = 0;
        }
        break;
    case NPCM7XX_RNGMODE:
        value = s->rngmode;
        break;

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

    trace_npcm7xx_rng_read(offset, value, size);

    return value;
}

static void npcm7xx_rng_write(void *opaque, hwaddr offset, uint64_t value,
                              unsigned size)
{
    NPCM7xxRNGState *s = opaque;

    trace_npcm7xx_rng_write(offset, value, size);

    switch (offset) {
    case NPCM7XX_RNGCS:
        s->rngcs &= NPCM7XX_RNGCS_DVALID;
        s->rngcs |= value & ~NPCM7XX_RNGCS_DVALID;
        break;
    case NPCM7XX_RNGD:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: write to read-only register @ 0x%" HWADDR_PRIx "\n",
                      DEVICE(s)->canonical_path, offset);
        break;
    case NPCM7XX_RNGMODE:
        s->rngmode = value;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
                      DEVICE(s)->canonical_path, offset);
        break;
    }
}

static const MemoryRegionOps npcm7xx_rng_ops = {
    .read = npcm7xx_rng_read,
    .write = npcm7xx_rng_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
        .unaligned = false,
    },
};

static void npcm7xx_rng_enter_reset(Object *obj, ResetType type)
{
    NPCM7xxRNGState *s = NPCM7XX_RNG(obj);

    s->rngcs = 0;
    s->rngd = 0;
    s->rngmode = 0;
}

static void npcm7xx_rng_init(Object *obj)
{
    NPCM7xxRNGState *s = NPCM7XX_RNG(obj);

    memory_region_init_io(&s->iomem, obj, &npcm7xx_rng_ops, s, "regs",
                          NPCM7XX_RNG_REGS_SIZE);
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}

static const VMStateDescription vmstate_npcm7xx_rng = {
    .name = "npcm7xx-rng",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(rngcs, NPCM7xxRNGState),
        VMSTATE_UINT8(rngd, NPCM7xxRNGState),
        VMSTATE_UINT8(rngmode, NPCM7xxRNGState),
        VMSTATE_END_OF_LIST(),
    },
};

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

    dc->desc = "NPCM7xx Random Number Generator";
    dc->vmsd = &vmstate_npcm7xx_rng;
    rc->phases.enter = npcm7xx_rng_enter_reset;
}

static const TypeInfo npcm7xx_rng_types[] = {
    {
        .name = TYPE_NPCM7XX_RNG,
        .parent = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(NPCM7xxRNGState),
        .class_init = npcm7xx_rng_class_init,
        .instance_init = npcm7xx_rng_init,
    },
};
DEFINE_TYPES(npcm7xx_rng_types);
