/*
 * QEMU model of the Ibex SPI Controller
 * SPEC Reference: https://docs.opentitan.org/hw/ip/spi_host/doc/
 *
 * Copyright (C) 2022 Western Digital
 *
 * 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 "qemu/log.h"
#include "qemu/module.h"
#include "hw/registerfields.h"
#include "hw/ssi/ibex_spi_host.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
#include "trace.h"

REG32(INTR_STATE, 0x00)
    FIELD(INTR_STATE, ERROR, 0, 1)
    FIELD(INTR_STATE, SPI_EVENT, 1, 1)
REG32(INTR_ENABLE, 0x04)
    FIELD(INTR_ENABLE, ERROR, 0, 1)
    FIELD(INTR_ENABLE, SPI_EVENT, 1, 1)
REG32(INTR_TEST, 0x08)
    FIELD(INTR_TEST, ERROR, 0, 1)
    FIELD(INTR_TEST, SPI_EVENT, 1, 1)
REG32(ALERT_TEST, 0x0c)
    FIELD(ALERT_TEST, FETAL_TEST, 0, 1)
REG32(CONTROL, 0x10)
    FIELD(CONTROL, RX_WATERMARK, 0, 8)
    FIELD(CONTROL, TX_WATERMARK, 1, 8)
    FIELD(CONTROL, OUTPUT_EN, 29, 1)
    FIELD(CONTROL, SW_RST, 30, 1)
    FIELD(CONTROL, SPIEN, 31, 1)
REG32(STATUS, 0x14)
    FIELD(STATUS, TXQD, 0, 8)
    FIELD(STATUS, RXQD, 18, 8)
    FIELD(STATUS, CMDQD, 16, 3)
    FIELD(STATUS, RXWM, 20, 1)
    FIELD(STATUS, BYTEORDER, 22, 1)
    FIELD(STATUS, RXSTALL, 23, 1)
    FIELD(STATUS, RXEMPTY, 24, 1)
    FIELD(STATUS, RXFULL, 25, 1)
    FIELD(STATUS, TXWM, 26, 1)
    FIELD(STATUS, TXSTALL, 27, 1)
    FIELD(STATUS, TXEMPTY, 28, 1)
    FIELD(STATUS, TXFULL, 29, 1)
    FIELD(STATUS, ACTIVE, 30, 1)
    FIELD(STATUS, READY, 31, 1)
REG32(CONFIGOPTS, 0x18)
    FIELD(CONFIGOPTS, CLKDIV_0, 0, 16)
    FIELD(CONFIGOPTS, CSNIDLE_0, 16, 4)
    FIELD(CONFIGOPTS, CSNTRAIL_0, 20, 4)
    FIELD(CONFIGOPTS, CSNLEAD_0, 24, 4)
    FIELD(CONFIGOPTS, FULLCYC_0, 29, 1)
    FIELD(CONFIGOPTS, CPHA_0, 30, 1)
    FIELD(CONFIGOPTS, CPOL_0, 31, 1)
REG32(CSID, 0x1c)
    FIELD(CSID, CSID, 0, 32)
REG32(COMMAND, 0x20)
    FIELD(COMMAND, LEN, 0, 8)
    FIELD(COMMAND, CSAAT, 9, 1)
    FIELD(COMMAND, SPEED, 10, 2)
    FIELD(COMMAND, DIRECTION, 12, 2)
REG32(ERROR_ENABLE, 0x2c)
    FIELD(ERROR_ENABLE, CMDBUSY, 0, 1)
    FIELD(ERROR_ENABLE, OVERFLOW, 1, 1)
    FIELD(ERROR_ENABLE, UNDERFLOW, 2, 1)
    FIELD(ERROR_ENABLE, CMDINVAL, 3, 1)
    FIELD(ERROR_ENABLE, CSIDINVAL, 4, 1)
REG32(ERROR_STATUS, 0x30)
    FIELD(ERROR_STATUS, CMDBUSY, 0, 1)
    FIELD(ERROR_STATUS, OVERFLOW, 1, 1)
    FIELD(ERROR_STATUS, UNDERFLOW, 2, 1)
    FIELD(ERROR_STATUS, CMDINVAL, 3, 1)
    FIELD(ERROR_STATUS, CSIDINVAL, 4, 1)
    FIELD(ERROR_STATUS, ACCESSINVAL, 5, 1)
REG32(EVENT_ENABLE, 0x34)
    FIELD(EVENT_ENABLE, RXFULL, 0, 1)
    FIELD(EVENT_ENABLE, TXEMPTY, 1, 1)
    FIELD(EVENT_ENABLE, RXWM, 2, 1)
    FIELD(EVENT_ENABLE, TXWM, 3, 1)
    FIELD(EVENT_ENABLE, READY, 4, 1)
    FIELD(EVENT_ENABLE, IDLE, 5, 1)

static inline uint8_t div4_round_up(uint8_t dividend)
{
    return (dividend + 3) / 4;
}

static void ibex_spi_rxfifo_reset(IbexSPIHostState *s)
{
    uint32_t data = s->regs[IBEX_SPI_HOST_STATUS];
    /* Empty the RX FIFO and assert RXEMPTY */
    fifo8_reset(&s->rx_fifo);
    data = FIELD_DP32(data, STATUS, RXFULL, 0);
    data = FIELD_DP32(data, STATUS, RXEMPTY, 1);
    s->regs[IBEX_SPI_HOST_STATUS] = data;
}

static void ibex_spi_txfifo_reset(IbexSPIHostState *s)
{
    uint32_t data = s->regs[IBEX_SPI_HOST_STATUS];
    /* Empty the TX FIFO and assert TXEMPTY */
    fifo8_reset(&s->tx_fifo);
    data = FIELD_DP32(data, STATUS, TXFULL, 0);
    data = FIELD_DP32(data, STATUS, TXEMPTY, 1);
    s->regs[IBEX_SPI_HOST_STATUS] = data;
}

static void ibex_spi_host_reset(DeviceState *dev)
{
    IbexSPIHostState *s = IBEX_SPI_HOST(dev);
    trace_ibex_spi_host_reset("Resetting Ibex SPI");

    /* SPI Host Register Reset */
    s->regs[IBEX_SPI_HOST_INTR_STATE]   = 0x00;
    s->regs[IBEX_SPI_HOST_INTR_ENABLE]  = 0x00;
    s->regs[IBEX_SPI_HOST_INTR_TEST]    = 0x00;
    s->regs[IBEX_SPI_HOST_ALERT_TEST]   = 0x00;
    s->regs[IBEX_SPI_HOST_CONTROL]      = 0x7f;
    s->regs[IBEX_SPI_HOST_STATUS]       = 0x00;
    s->regs[IBEX_SPI_HOST_CONFIGOPTS]   = 0x00;
    s->regs[IBEX_SPI_HOST_CSID]         = 0x00;
    s->regs[IBEX_SPI_HOST_COMMAND]      = 0x00;
    /* RX/TX Modelled by FIFO */
    s->regs[IBEX_SPI_HOST_RXDATA]       = 0x00;
    s->regs[IBEX_SPI_HOST_TXDATA]       = 0x00;

    s->regs[IBEX_SPI_HOST_ERROR_ENABLE] = 0x1F;
    s->regs[IBEX_SPI_HOST_ERROR_STATUS] = 0x00;
    s->regs[IBEX_SPI_HOST_EVENT_ENABLE] = 0x00;

    ibex_spi_rxfifo_reset(s);
    ibex_spi_txfifo_reset(s);

    s->init_status = true;
    return;
}

/*
 * Check if we need to trigger an interrupt.
 * The two interrupts lines (host_err and event) can
 * be enabled separately in 'IBEX_SPI_HOST_INTR_ENABLE'.
 *
 * Interrupts are triggered based on the ones
 * enabled in the `IBEX_SPI_HOST_EVENT_ENABLE` and `IBEX_SPI_HOST_ERROR_ENABLE`.
 */
static void ibex_spi_host_irq(IbexSPIHostState *s)
{
    uint32_t intr_test_reg = s->regs[IBEX_SPI_HOST_INTR_TEST];
    uint32_t intr_en_reg = s->regs[IBEX_SPI_HOST_INTR_ENABLE];
    uint32_t intr_state_reg = s->regs[IBEX_SPI_HOST_INTR_STATE];

    uint32_t err_en_reg = s->regs[IBEX_SPI_HOST_ERROR_ENABLE];
    uint32_t event_en_reg = s->regs[IBEX_SPI_HOST_EVENT_ENABLE];
    uint32_t err_status_reg = s->regs[IBEX_SPI_HOST_ERROR_STATUS];
    uint32_t status_reg = s->regs[IBEX_SPI_HOST_STATUS];


    bool error_en = FIELD_EX32(intr_en_reg, INTR_ENABLE, ERROR);
    bool event_en = FIELD_EX32(intr_en_reg, INTR_ENABLE, SPI_EVENT);
    bool err_pending = FIELD_EX32(intr_state_reg, INTR_STATE, ERROR);
    bool status_pending = FIELD_EX32(intr_state_reg, INTR_STATE, SPI_EVENT);

    int err_irq = 0, event_irq = 0;

    /* Error IRQ enabled and Error IRQ Cleared */
    if (error_en && !err_pending) {
        /* Event enabled, Interrupt Test Error */
        if (FIELD_EX32(intr_test_reg, INTR_TEST,  ERROR)) {
            err_irq = 1;
        } else if (FIELD_EX32(err_en_reg, ERROR_ENABLE,  CMDBUSY) &&
                   FIELD_EX32(err_status_reg, ERROR_STATUS,  CMDBUSY)) {
            /* Wrote to COMMAND when not READY */
            err_irq = 1;
        } else if (FIELD_EX32(err_en_reg, ERROR_ENABLE,  CMDINVAL)  &&
                   FIELD_EX32(err_status_reg, ERROR_STATUS,  CMDINVAL)) {
            /* Invalid command segment */
            err_irq = 1;
        } else if (FIELD_EX32(err_en_reg, ERROR_ENABLE,  CSIDINVAL) &&
                   FIELD_EX32(err_status_reg, ERROR_STATUS,  CSIDINVAL)) {
            /* Invalid value for CSID */
            err_irq = 1;
        }
        if (err_irq) {
            s->regs[IBEX_SPI_HOST_INTR_STATE] |= R_INTR_STATE_ERROR_MASK;
        }
        qemu_set_irq(s->host_err, err_irq);
    }

    /* Event IRQ Enabled and Event IRQ Cleared */
    if (event_en && !status_pending) {
        if (FIELD_EX32(intr_test_reg, INTR_STATE,  SPI_EVENT)) {
            /* Event enabled, Interrupt Test Event */
            event_irq = 1;
        } else if (FIELD_EX32(event_en_reg, EVENT_ENABLE,  READY) &&
                   FIELD_EX32(status_reg, STATUS, READY)) {
            /* SPI Host ready for next command */
            event_irq = 1;
        } else if (FIELD_EX32(event_en_reg, EVENT_ENABLE,  TXEMPTY) &&
                   FIELD_EX32(status_reg, STATUS,  TXEMPTY)) {
            /* SPI TXEMPTY, TXFIFO drained */
            event_irq = 1;
        } else if (FIELD_EX32(event_en_reg, EVENT_ENABLE,  RXFULL) &&
                   FIELD_EX32(status_reg, STATUS,  RXFULL)) {
            /* SPI RXFULL, RXFIFO  full */
            event_irq = 1;
        }
        if (event_irq) {
            s->regs[IBEX_SPI_HOST_INTR_STATE] |= R_INTR_STATE_SPI_EVENT_MASK;
        }
        qemu_set_irq(s->event, event_irq);
    }
}

static void ibex_spi_host_transfer(IbexSPIHostState *s)
{
    uint32_t rx, tx, data;
    /* Get num of one byte transfers */
    uint8_t segment_len = FIELD_EX32(s->regs[IBEX_SPI_HOST_COMMAND],
                                     COMMAND,  LEN);

    while (segment_len > 0) {
        if (fifo8_is_empty(&s->tx_fifo)) {
            /* Assert Stall */
            s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXSTALL_MASK;
            break;
        } else if (fifo8_is_full(&s->rx_fifo)) {
            /* Assert Stall */
            s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXSTALL_MASK;
            break;
        } else {
            tx = fifo8_pop(&s->tx_fifo);
        }

        rx = ssi_transfer(s->ssi, tx);

        trace_ibex_spi_host_transfer(tx, rx);

        if (!fifo8_is_full(&s->rx_fifo)) {
            fifo8_push(&s->rx_fifo, rx);
        } else {
            /* Assert RXFULL */
            s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXFULL_MASK;
        }
        --segment_len;
    }

    data = s->regs[IBEX_SPI_HOST_STATUS];
    /* Assert Ready */
    data = FIELD_DP32(data, STATUS, READY, 1);
    /* Set RXQD */
    data = FIELD_DP32(data, STATUS, RXQD, div4_round_up(segment_len));
    /* Set TXQD */
    data = FIELD_DP32(data, STATUS, TXQD, fifo8_num_used(&s->tx_fifo) / 4);
    /* Clear TXFULL */
    data = FIELD_DP32(data, STATUS, TXFULL, 0);
    /* Reset RXEMPTY */
    data = FIELD_DP32(data, STATUS, RXEMPTY, 0);
    /* Update register status */
    s->regs[IBEX_SPI_HOST_STATUS] = data;
    /* Drop remaining bytes that exceed segment_len */
    ibex_spi_txfifo_reset(s);

    ibex_spi_host_irq(s);
}

static uint64_t ibex_spi_host_read(void *opaque, hwaddr addr,
                                     unsigned int size)
{
    IbexSPIHostState *s = opaque;
    uint32_t rc = 0;
    uint8_t rx_byte = 0;

    trace_ibex_spi_host_read(addr, size);

    /* Match reg index */
    addr = addr >> 2;
    switch (addr) {
    /* Skipping any W/O registers */
    case IBEX_SPI_HOST_INTR_STATE...IBEX_SPI_HOST_INTR_ENABLE:
    case IBEX_SPI_HOST_CONTROL...IBEX_SPI_HOST_STATUS:
        rc = s->regs[addr];
        break;
    case IBEX_SPI_HOST_CSID:
        rc = s->regs[addr];
        break;
    case IBEX_SPI_HOST_CONFIGOPTS:
        rc = s->config_opts[s->regs[IBEX_SPI_HOST_CSID]];
        break;
    case IBEX_SPI_HOST_TXDATA:
        rc = s->regs[addr];
        break;
    case IBEX_SPI_HOST_RXDATA:
        /* Clear RXFULL */
        s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXFULL_MASK;

        for (int i = 0; i < 4; ++i) {
            if (fifo8_is_empty(&s->rx_fifo)) {
                /* Assert RXEMPTY, no IRQ */
                s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXEMPTY_MASK;
                s->regs[IBEX_SPI_HOST_ERROR_STATUS] |=
                                                R_ERROR_STATUS_UNDERFLOW_MASK;
                return rc;
            }
            rx_byte = fifo8_pop(&s->rx_fifo);
            rc |= rx_byte << (i * 8);
        }
        break;
    case IBEX_SPI_HOST_ERROR_ENABLE...IBEX_SPI_HOST_EVENT_ENABLE:
        rc = s->regs[addr];
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "Bad offset 0x%" HWADDR_PRIx "\n",
                      addr << 2);
    }
    return rc;
}


static void ibex_spi_host_write(void *opaque, hwaddr addr,
                                uint64_t val64, unsigned int size)
{
    IbexSPIHostState *s = opaque;
    uint32_t val32 = val64;
    uint32_t shift_mask = 0xff, status = 0, data = 0;
    uint8_t txqd_len;

    trace_ibex_spi_host_write(addr, size, val64);

    /* Match reg index */
    addr = addr >> 2;

    switch (addr) {
    /* Skipping any R/O registers */
    case IBEX_SPI_HOST_INTR_STATE:
        /* rw1c status register */
        if (FIELD_EX32(val32, INTR_STATE, ERROR)) {
            data = FIELD_DP32(data, INTR_STATE, ERROR, 0);
        }
        if (FIELD_EX32(val32, INTR_STATE, SPI_EVENT)) {
            data = FIELD_DP32(data, INTR_STATE, SPI_EVENT, 0);
        }
        s->regs[addr] = data;
        break;
    case IBEX_SPI_HOST_INTR_ENABLE:
        s->regs[addr] = val32;
        break;
    case IBEX_SPI_HOST_INTR_TEST:
        s->regs[addr] = val32;
        ibex_spi_host_irq(s);
        break;
    case IBEX_SPI_HOST_ALERT_TEST:
        s->regs[addr] = val32;
        qemu_log_mask(LOG_UNIMP,
                        "%s: SPI_ALERT_TEST is not supported\n", __func__);
        break;
    case IBEX_SPI_HOST_CONTROL:
        s->regs[addr] = val32;

        if (val32 & R_CONTROL_SW_RST_MASK)  {
            ibex_spi_host_reset((DeviceState *)s);
            /* Clear active if any */
            s->regs[IBEX_SPI_HOST_STATUS] &=  ~R_STATUS_ACTIVE_MASK;
        }

        if (val32 & R_CONTROL_OUTPUT_EN_MASK)  {
            qemu_log_mask(LOG_UNIMP,
                          "%s: CONTROL_OUTPUT_EN is not supported\n", __func__);
        }
        break;
    case IBEX_SPI_HOST_CONFIGOPTS:
        /* Update the respective config-opts register based on CSIDth index */
        s->config_opts[s->regs[IBEX_SPI_HOST_CSID]] = val32;
        qemu_log_mask(LOG_UNIMP,
                      "%s: CONFIGOPTS Hardware settings not supported\n",
                         __func__);
        break;
    case IBEX_SPI_HOST_CSID:
        if (val32 >= s->num_cs) {
            /* CSID exceeds max num_cs */
            s->regs[IBEX_SPI_HOST_ERROR_STATUS] |=
                                                R_ERROR_STATUS_CSIDINVAL_MASK;
            ibex_spi_host_irq(s);
            return;
        }
        s->regs[addr] = val32;
        break;
    case IBEX_SPI_HOST_COMMAND:
        s->regs[addr] = val32;

        /* STALL, IP not enabled */
        if (!(FIELD_EX32(s->regs[IBEX_SPI_HOST_CONTROL],
                         CONTROL, SPIEN))) {
            return;
        }

        /* SPI not ready, IRQ Error */
        if (!(FIELD_EX32(s->regs[IBEX_SPI_HOST_STATUS],
                         STATUS, READY))) {
            s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= R_ERROR_STATUS_CMDBUSY_MASK;
            ibex_spi_host_irq(s);
            return;
        }

        /* Assert Not Ready */
        s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_READY_MASK;

        if (FIELD_EX32(val32, COMMAND, DIRECTION) != BIDIRECTIONAL_TRANSFER) {
            qemu_log_mask(LOG_UNIMP,
                          "%s: Rx Only/Tx Only are not supported\n", __func__);
        }

        if (val32 & R_COMMAND_CSAAT_MASK)  {
            qemu_log_mask(LOG_UNIMP,
                          "%s: CSAAT is not supported\n", __func__);
        }
        if (val32 & R_COMMAND_SPEED_MASK)  {
            qemu_log_mask(LOG_UNIMP,
                          "%s: SPEED is not supported\n", __func__);
        }

        /* Set Transfer Callback */
        timer_mod(s->fifo_trigger_handle,
                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    (TX_INTERRUPT_TRIGGER_DELAY_NS));

        break;
    case IBEX_SPI_HOST_TXDATA:
        /*
         * This is a hardware `feature` where
         * the first word written to TXDATA after init is omitted entirely
         */
        if (s->init_status) {
            s->init_status = false;
            return;
        }

        for (int i = 0; i < 4; ++i) {
            /* Attempting to write when TXFULL */
            if (fifo8_is_full(&s->tx_fifo)) {
                /* Assert RXEMPTY, no IRQ */
                s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXFULL_MASK;
                s->regs[IBEX_SPI_HOST_ERROR_STATUS] |=
                                                 R_ERROR_STATUS_OVERFLOW_MASK;
                ibex_spi_host_irq(s);
                return;
            }
            /* Byte ordering is set by the IP */
            status = s->regs[IBEX_SPI_HOST_STATUS];
            if (FIELD_EX32(status, STATUS, BYTEORDER) == 0) {
                /* LE: LSB transmitted first (default for ibex processor) */
                shift_mask = 0xff << (i * 8);
            } else {
                /* BE: MSB transmitted first */
                qemu_log_mask(LOG_UNIMP,
                             "%s: Big endian is not supported\n", __func__);
            }

            fifo8_push(&s->tx_fifo, (val32 & shift_mask) >> (i * 8));
        }
        status = s->regs[IBEX_SPI_HOST_STATUS];
        /* Reset TXEMPTY */
        status = FIELD_DP32(status, STATUS, TXEMPTY, 0);
        /* Update TXQD */
        txqd_len = FIELD_EX32(status, STATUS, TXQD);
        /* Partial bytes (size < 4) are padded, in words. */
        txqd_len += 1;
        status = FIELD_DP32(status, STATUS, TXQD, txqd_len);
        /* Assert Ready */
        status = FIELD_DP32(status, STATUS, READY, 1);
        /* Update register status */
        s->regs[IBEX_SPI_HOST_STATUS] = status;
        break;
    case IBEX_SPI_HOST_ERROR_ENABLE:
        s->regs[addr] = val32;

        if (val32 & R_ERROR_ENABLE_CMDINVAL_MASK)  {
            qemu_log_mask(LOG_UNIMP,
                          "%s: Segment Length is not supported\n", __func__);
        }
        break;
    case IBEX_SPI_HOST_ERROR_STATUS:
    /*
     *  Indicates any errors that have occurred.
     *  When an error occurs, the corresponding bit must be cleared
     *  here before issuing any further commands
     */
        status = s->regs[addr];
        /* rw1c status register */
        if (FIELD_EX32(val32, ERROR_STATUS, CMDBUSY)) {
            status = FIELD_DP32(status, ERROR_STATUS, CMDBUSY, 0);
        }
        if (FIELD_EX32(val32, ERROR_STATUS, OVERFLOW)) {
            status = FIELD_DP32(status, ERROR_STATUS, OVERFLOW, 0);
        }
        if (FIELD_EX32(val32, ERROR_STATUS, UNDERFLOW)) {
            status = FIELD_DP32(status, ERROR_STATUS, UNDERFLOW, 0);
        }
        if (FIELD_EX32(val32, ERROR_STATUS, CMDINVAL)) {
            status = FIELD_DP32(status, ERROR_STATUS, CMDINVAL, 0);
        }
        if (FIELD_EX32(val32, ERROR_STATUS, CSIDINVAL)) {
            status = FIELD_DP32(status, ERROR_STATUS, CSIDINVAL, 0);
        }
        if (FIELD_EX32(val32, ERROR_STATUS, ACCESSINVAL)) {
            status = FIELD_DP32(status, ERROR_STATUS, ACCESSINVAL, 0);
        }
        s->regs[addr] = status;
        break;
    case IBEX_SPI_HOST_EVENT_ENABLE:
    /* Controls which classes of SPI events raise an interrupt. */
        s->regs[addr] = val32;

        if (val32 & R_EVENT_ENABLE_RXWM_MASK)  {
            qemu_log_mask(LOG_UNIMP,
                          "%s: RXWM is not supported\n", __func__);
        }
        if (val32 & R_EVENT_ENABLE_TXWM_MASK)  {
            qemu_log_mask(LOG_UNIMP,
                          "%s: TXWM is not supported\n", __func__);
        }

        if (val32 & R_EVENT_ENABLE_IDLE_MASK)  {
            qemu_log_mask(LOG_UNIMP,
                          "%s: IDLE is not supported\n", __func__);
        }
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "Bad offset 0x%" HWADDR_PRIx "\n",
                      addr << 2);
    }
}

static const MemoryRegionOps ibex_spi_ops = {
    .read = ibex_spi_host_read,
    .write = ibex_spi_host_write,
    /* Ibex default LE */
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static Property ibex_spi_properties[] = {
    DEFINE_PROP_UINT32("num_cs", IbexSPIHostState, num_cs, 1),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vmstate_ibex = {
    .name = TYPE_IBEX_SPI_HOST,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, IbexSPIHostState, IBEX_SPI_HOST_MAX_REGS),
        VMSTATE_VARRAY_UINT32(config_opts, IbexSPIHostState,
                              num_cs, 0, vmstate_info_uint32, uint32_t),
        VMSTATE_FIFO8(rx_fifo, IbexSPIHostState),
        VMSTATE_FIFO8(tx_fifo, IbexSPIHostState),
        VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexSPIHostState),
        VMSTATE_BOOL(init_status, IbexSPIHostState),
        VMSTATE_END_OF_LIST()
    }
};

static void fifo_trigger_update(void *opaque)
{
    IbexSPIHostState *s = opaque;
    ibex_spi_host_transfer(s);
}

static void ibex_spi_host_realize(DeviceState *dev, Error **errp)
{
    IbexSPIHostState *s = IBEX_SPI_HOST(dev);
    int i;

    s->ssi = ssi_create_bus(dev, "ssi");
    s->cs_lines = g_new0(qemu_irq, s->num_cs);

    for (i = 0; i < s->num_cs; ++i) {
        sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]);
    }

    /* Setup CONFIGOPTS Multi-register */
    s->config_opts = g_new0(uint32_t, s->num_cs);

    /* Setup FIFO Interrupt Timer */
    s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                          fifo_trigger_update, s);

    /* FIFO sizes as per OT Spec */
    fifo8_create(&s->tx_fifo, IBEX_SPI_HOST_TXFIFO_LEN);
    fifo8_create(&s->rx_fifo, IBEX_SPI_HOST_RXFIFO_LEN);
}

static void ibex_spi_host_init(Object *obj)
{
    IbexSPIHostState *s = IBEX_SPI_HOST(obj);

    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->host_err);
    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->event);

    memory_region_init_io(&s->mmio, obj, &ibex_spi_ops, s,
                          TYPE_IBEX_SPI_HOST, 0x1000);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
}

static void ibex_spi_host_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    dc->realize = ibex_spi_host_realize;
    dc->reset = ibex_spi_host_reset;
    dc->vmsd = &vmstate_ibex;
    device_class_set_props(dc, ibex_spi_properties);
}

static const TypeInfo ibex_spi_host_info = {
    .name          = TYPE_IBEX_SPI_HOST,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IbexSPIHostState),
    .instance_init = ibex_spi_host_init,
    .class_init    = ibex_spi_host_class_init,
};

static void ibex_spi_host_register_types(void)
{
    type_register_static(&ibex_spi_host_info);
}

type_init(ibex_spi_host_register_types)
