/*
 * ARM IoTKit system control element
 *
 * Copyright (c) 2018 Linaro Limited
 * Written by Peter Maydell
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 or
 *  (at your option) any later version.
 */

/*
 * This is a model of the "system control element" which is part of the
 * Arm IoTKit and documented in
 * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
 * Specifically, it implements the "system control register" blocks.
 */

#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"
#include "qapi/error.h"
#include "sysemu/sysemu.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "hw/registerfields.h"
#include "hw/misc/iotkit-sysctl.h"
#include "hw/qdev-properties.h"
#include "target/arm/arm-powerctl.h"
#include "target/arm/cpu.h"

REG32(SECDBGSTAT, 0x0)
REG32(SECDBGSET, 0x4)
REG32(SECDBGCLR, 0x8)
REG32(SCSECCTRL, 0xc)
REG32(FCLK_DIV, 0x10)
REG32(SYSCLK_DIV, 0x14)
REG32(CLOCK_FORCE, 0x18)
REG32(RESET_SYNDROME, 0x100)
REG32(RESET_MASK, 0x104)
REG32(SWRESET, 0x108)
    FIELD(SWRESET, SWRESETREQ, 9, 1)
REG32(GRETREG, 0x10c)
REG32(INITSVTOR0, 0x110)
REG32(INITSVTOR1, 0x114)
REG32(CPUWAIT, 0x118)
REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
REG32(WICCTRL, 0x120)
REG32(EWCTRL, 0x124)
REG32(PDCM_PD_SYS_SENSE, 0x200)
REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
REG32(PDCM_PD_SRAM1_SENSE, 0x210)
REG32(PDCM_PD_SRAM2_SENSE, 0x214)
REG32(PDCM_PD_SRAM3_SENSE, 0x218)
REG32(PID4, 0xfd0)
REG32(PID5, 0xfd4)
REG32(PID6, 0xfd8)
REG32(PID7, 0xfdc)
REG32(PID0, 0xfe0)
REG32(PID1, 0xfe4)
REG32(PID2, 0xfe8)
REG32(PID3, 0xfec)
REG32(CID0, 0xff0)
REG32(CID1, 0xff4)
REG32(CID2, 0xff8)
REG32(CID3, 0xffc)

/* PID/CID values */
static const int sysctl_id[] = {
    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
    0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};

/*
 * Set the initial secure vector table offset address for the core.
 * This will take effect when the CPU next resets.
 */
static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
{
    Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));

    if (cpuobj) {
        if (object_property_find(cpuobj, "init-svtor", NULL)) {
            object_property_set_uint(cpuobj, vtor, "init-svtor", &error_abort);
        }
    }
}

static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
                                    unsigned size)
{
    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
    uint64_t r;

    switch (offset) {
    case A_SECDBGSTAT:
        r = s->secure_debug;
        break;
    case A_SCSECCTRL:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->scsecctrl;
        break;
    case A_FCLK_DIV:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->fclk_div;
        break;
    case A_SYSCLK_DIV:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->sysclk_div;
        break;
    case A_CLOCK_FORCE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->clock_force;
        break;
    case A_RESET_SYNDROME:
        r = s->reset_syndrome;
        break;
    case A_RESET_MASK:
        r = s->reset_mask;
        break;
    case A_GRETREG:
        r = s->gretreg;
        break;
    case A_INITSVTOR0:
        r = s->initsvtor0;
        break;
    case A_INITSVTOR1:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->initsvtor1;
        break;
    case A_CPUWAIT:
        r = s->cpuwait;
        break;
    case A_NMI_ENABLE:
        /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
        if (!s->is_sse200) {
            r = 0;
            break;
        }
        r = s->nmi_enable;
        break;
    case A_WICCTRL:
        r = s->wicctrl;
        break;
    case A_EWCTRL:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->ewctrl;
        break;
    case A_PDCM_PD_SYS_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->pdcm_pd_sys_sense;
        break;
    case A_PDCM_PD_SRAM0_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->pdcm_pd_sram0_sense;
        break;
    case A_PDCM_PD_SRAM1_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->pdcm_pd_sram1_sense;
        break;
    case A_PDCM_PD_SRAM2_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->pdcm_pd_sram2_sense;
        break;
    case A_PDCM_PD_SRAM3_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        r = s->pdcm_pd_sram3_sense;
        break;
    case A_PID4 ... A_CID3:
        r = sysctl_id[(offset - A_PID4) / 4];
        break;
    case A_SECDBGSET:
    case A_SECDBGCLR:
    case A_SWRESET:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IoTKit SysCtl read: read of WO offset %x\n",
                      (int)offset);
        r = 0;
        break;
    default:
    bad_offset:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IoTKit SysCtl read: bad offset %x\n", (int)offset);
        r = 0;
        break;
    }
    trace_iotkit_sysctl_read(offset, r, size);
    return r;
}

static void iotkit_sysctl_write(void *opaque, hwaddr offset,
                                 uint64_t value, unsigned size)
{
    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);

    trace_iotkit_sysctl_write(offset, value, size);

    /*
     * Most of the state here has to do with control of reset and
     * similar kinds of power up -- for instance the guest can ask
     * what the reason for the last reset was, or forbid reset for
     * some causes (like the non-secure watchdog). Most of this is
     * not relevant to QEMU, which doesn't really model anything other
     * than a full power-on reset.
     * We just model the registers as reads-as-written.
     */

    switch (offset) {
    case A_RESET_SYNDROME:
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
        s->reset_syndrome = value;
        break;
    case A_RESET_MASK:
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
        s->reset_mask = value;
        break;
    case A_GRETREG:
        /*
         * General retention register, which is only reset by a power-on
         * reset. Technically this implementation is complete, since
         * QEMU only supports power-on resets...
         */
        s->gretreg = value;
        break;
    case A_INITSVTOR0:
        s->initsvtor0 = value;
        set_init_vtor(0, s->initsvtor0);
        break;
    case A_CPUWAIT:
        if ((s->cpuwait & 1) && !(value & 1)) {
            /* Powering up CPU 0 */
            arm_set_cpu_on_and_reset(0);
        }
        if ((s->cpuwait & 2) && !(value & 2)) {
            /* Powering up CPU 1 */
            arm_set_cpu_on_and_reset(1);
        }
        s->cpuwait = value;
        break;
    case A_WICCTRL:
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
        s->wicctrl = value;
        break;
    case A_SECDBGSET:
        /* write-1-to-set */
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
        s->secure_debug |= value;
        break;
    case A_SECDBGCLR:
        /* write-1-to-clear */
        s->secure_debug &= ~value;
        break;
    case A_SWRESET:
        /* One w/o bit to request a reset; all other bits reserved */
        if (value & R_SWRESET_SWRESETREQ_MASK) {
            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
        }
        break;
    case A_SCSECCTRL:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
        s->scsecctrl = value;
        break;
    case A_FCLK_DIV:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
        s->fclk_div = value;
        break;
    case A_SYSCLK_DIV:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
        s->sysclk_div = value;
        break;
    case A_CLOCK_FORCE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
        s->clock_force = value;
        break;
    case A_INITSVTOR1:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        s->initsvtor1 = value;
        set_init_vtor(1, s->initsvtor1);
        break;
    case A_EWCTRL:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
        s->ewctrl = value;
        break;
    case A_PDCM_PD_SYS_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
        s->pdcm_pd_sys_sense = value;
        break;
    case A_PDCM_PD_SRAM0_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
        s->pdcm_pd_sram0_sense = value;
        break;
    case A_PDCM_PD_SRAM1_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
        s->pdcm_pd_sram1_sense = value;
        break;
    case A_PDCM_PD_SRAM2_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
        s->pdcm_pd_sram2_sense = value;
        break;
    case A_PDCM_PD_SRAM3_SENSE:
        if (!s->is_sse200) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
        s->pdcm_pd_sram3_sense = value;
        break;
    case A_NMI_ENABLE:
        /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
        if (!s->is_sse200) {
            goto ro_offset;
        }
        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
        s->nmi_enable = value;
        break;
    case A_SECDBGSTAT:
    case A_PID4 ... A_CID3:
    ro_offset:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IoTKit SysCtl write: write of RO offset %x\n",
                      (int)offset);
        break;
    default:
    bad_offset:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IoTKit SysCtl write: bad offset %x\n", (int)offset);
        break;
    }
}

static const MemoryRegionOps iotkit_sysctl_ops = {
    .read = iotkit_sysctl_read,
    .write = iotkit_sysctl_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    /* byte/halfword accesses are just zero-padded on reads and writes */
    .impl.min_access_size = 4,
    .impl.max_access_size = 4,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
};

static void iotkit_sysctl_reset(DeviceState *dev)
{
    IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);

    trace_iotkit_sysctl_reset();
    s->secure_debug = 0;
    s->reset_syndrome = 1;
    s->reset_mask = 0;
    s->gretreg = 0;
    s->initsvtor0 = s->initsvtor0_rst;
    s->initsvtor1 = s->initsvtor1_rst;
    s->cpuwait = s->cpuwait_rst;
    s->wicctrl = 0;
    s->scsecctrl = 0;
    s->fclk_div = 0;
    s->sysclk_div = 0;
    s->clock_force = 0;
    s->nmi_enable = 0;
    s->ewctrl = 0;
    s->pdcm_pd_sys_sense = 0x7f;
    s->pdcm_pd_sram0_sense = 0;
    s->pdcm_pd_sram1_sense = 0;
    s->pdcm_pd_sram2_sense = 0;
    s->pdcm_pd_sram3_sense = 0;
}

static void iotkit_sysctl_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);

    memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
                          s, "iotkit-sysctl", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
}

static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
{
    IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);

    /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
    if (extract32(s->sys_version, 28, 4) == 2) {
        s->is_sse200 = true;
    }
}

static bool sse200_needed(void *opaque)
{
    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);

    return s->is_sse200;
}

static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
    .name = "iotkit-sysctl/sse-200",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = sse200_needed,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
        VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
        VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
        VMSTATE_UINT32(clock_force, IoTKitSysCtl),
        VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
        VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
        VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
        VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
        VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
        VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
        VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription iotkit_sysctl_vmstate = {
    .name = "iotkit-sysctl",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
        VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
        VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
        VMSTATE_UINT32(gretreg, IoTKitSysCtl),
        VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
        VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
        VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription*[]) {
        &iotkit_sysctl_sse200_vmstate,
        NULL
    }
};

static Property iotkit_sysctl_props[] = {
    DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
    DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
    DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
                       0x10000000),
    DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
                       0x10000000),
    DEFINE_PROP_END_OF_LIST()
};

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

    dc->vmsd = &iotkit_sysctl_vmstate;
    dc->reset = iotkit_sysctl_reset;
    dc->props = iotkit_sysctl_props;
    dc->realize = iotkit_sysctl_realize;
}

static const TypeInfo iotkit_sysctl_info = {
    .name = TYPE_IOTKIT_SYSCTL,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IoTKitSysCtl),
    .instance_init = iotkit_sysctl_init,
    .class_init = iotkit_sysctl_class_init,
};

static void iotkit_sysctl_register_types(void)
{
    type_register_static(&iotkit_sysctl_info);
}

type_init(iotkit_sysctl_register_types);
