/*
 * 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/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)
{
    /* Empty the RX FIFO and assert RXEMPTY */
    fifo8_reset(&s->rx_fifo);
    s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXFULL_MASK;
    s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXEMPTY_MASK;
}

static void ibex_spi_txfifo_reset(IbexSPIHostState *s)
{
    /* Empty the TX FIFO and assert TXEMPTY */
    fifo8_reset(&s->tx_fifo);
    s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK;
    s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXEMPTY_MASK;
}

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)
{
    bool error_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE]
                    & R_INTR_ENABLE_ERROR_MASK;
    bool event_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE]
                    & R_INTR_ENABLE_SPI_EVENT_MASK;
    bool err_pending = s->regs[IBEX_SPI_HOST_INTR_STATE]
                        & R_INTR_STATE_ERROR_MASK;
    bool status_pending = s->regs[IBEX_SPI_HOST_INTR_STATE]
                        & R_INTR_STATE_SPI_EVENT_MASK;
    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 (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_ERROR_MASK) {
            err_irq = 1;
        } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE]
                    &  R_ERROR_ENABLE_CMDBUSY_MASK) &&
                    s->regs[IBEX_SPI_HOST_ERROR_STATUS]
                    & R_ERROR_STATUS_CMDBUSY_MASK) {
            /* Wrote to COMMAND when not READY */
            err_irq = 1;
        } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE]
                    &  R_ERROR_ENABLE_CMDINVAL_MASK) &&
                    s->regs[IBEX_SPI_HOST_ERROR_STATUS]
                    & R_ERROR_STATUS_CMDINVAL_MASK) {
            /* Invalid command segment */
            err_irq = 1;
        } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE]
                    & R_ERROR_ENABLE_CSIDINVAL_MASK) &&
                    s->regs[IBEX_SPI_HOST_ERROR_STATUS]
                    & R_ERROR_STATUS_CSIDINVAL_MASK) {
            /* 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 (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_SPI_EVENT_MASK) {
            /* Event enabled, Interrupt Test Event */
            event_irq = 1;
        } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE]
                    & R_EVENT_ENABLE_READY_MASK) &&
                    (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) {
            /* SPI Host ready for next command */
            event_irq = 1;
        } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE]
                    & R_EVENT_ENABLE_TXEMPTY_MASK) &&
                    (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_TXEMPTY_MASK)) {
            /* SPI TXEMPTY, TXFIFO drained */
            event_irq = 1;
        } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE]
                    & R_EVENT_ENABLE_RXFULL_MASK) &&
                    (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_RXFULL_MASK)) {
            /* 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;
    /* Get num of one byte transfers */
    uint8_t segment_len = ((s->regs[IBEX_SPI_HOST_COMMAND] & R_COMMAND_LEN_MASK)
                          >> R_COMMAND_LEN_SHIFT);
    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;
    }

    /* Assert Ready */
    s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK;
    /* Set RXQD */
    s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXQD_MASK;
    s->regs[IBEX_SPI_HOST_STATUS] |= (R_STATUS_RXQD_MASK
                                    & div4_round_up(segment_len));
    /* Set TXQD */
    s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK;
    s->regs[IBEX_SPI_HOST_STATUS] |= (fifo8_num_used(&s->tx_fifo) / 4)
                                    & R_STATUS_TXQD_MASK;
    /* Clear TXFULL */
    s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK;
    /* Assert TXEMPTY and drop remaining bytes that exceed segment_len */
    ibex_spi_txfifo_reset(s);
    /* Reset RXEMPTY */
    s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXEMPTY_MASK;

    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;
    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...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 (!(s->regs[IBEX_SPI_HOST_CONTROL] & R_CONTROL_SPIEN_MASK)) {
            return;
        }

        /* SPI not ready, IRQ Error */
        if (!(s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) {
            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 (((val32 & R_COMMAND_DIRECTION_MASK) >> R_COMMAND_DIRECTION_SHIFT)
            != 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 */
            if ((s->regs[IBEX_SPI_HOST_STATUS] &
                R_STATUS_BYTEORDER_MASK) == 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));
        }

        /* Reset TXEMPTY */
        s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXEMPTY_MASK;
        /* Update TXQD */
        txqd_len = (s->regs[IBEX_SPI_HOST_STATUS] &
                    R_STATUS_TXQD_MASK) >> R_STATUS_TXQD_SHIFT;
        /* Partial bytes (size < 4) are padded, in words. */
        txqd_len += 1;
        s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK;
        s->regs[IBEX_SPI_HOST_STATUS] |= txqd_len;
        /* Assert Ready */
        s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK;
        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
     */
        s->regs[addr] = val32;
        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)
