/*
 * QEMU PowerPC SPI model
 *
 * Copyright (c) 2024, IBM Corporation.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/pnv_xscom.h"
#include "hw/ssi/pnv_spi.h"
#include "hw/ssi/pnv_spi_regs.h"
#include "hw/ssi/ssi.h"
#include <libfdt.h>
#include "hw/irq.h"
#include "trace.h"

#define PNV_SPI_OPCODE_LO_NIBBLE(x) (x & 0x0F)
#define PNV_SPI_MASKED_OPCODE(x) (x & 0xF0)

/*
 * Macro from include/hw/ppc/fdt.h
 * fdt.h cannot be included here as it contain ppc target specific dependency.
 */
#define _FDT(exp)                                                  \
    do {                                                           \
        int _ret = (exp);                                          \
        if (_ret < 0) {                                            \
            qemu_log_mask(LOG_GUEST_ERROR,                         \
                    "error creating device tree: %s: %s",          \
                    #exp, fdt_strerror(_ret));                     \
            exit(1);                                               \
        }                                                          \
    } while (0)

/* PnvXferBuffer */
typedef struct PnvXferBuffer {

    uint32_t    len;
    uint8_t    *data;

} PnvXferBuffer;

/* pnv_spi_xfer_buffer_methods */
static PnvXferBuffer *pnv_spi_xfer_buffer_new(void)
{
    PnvXferBuffer *payload = g_malloc0(sizeof(*payload));

    return payload;
}

static void pnv_spi_xfer_buffer_free(PnvXferBuffer *payload)
{
    free(payload->data);
    free(payload);
}

static uint8_t *pnv_spi_xfer_buffer_write_ptr(PnvXferBuffer *payload,
                uint32_t offset, uint32_t length)
{
    if (payload->len < (offset + length)) {
        payload->len = offset + length;
        payload->data = g_realloc(payload->data, payload->len);
    }
    return &payload->data[offset];
}

static bool does_rdr_match(PnvSpi *s)
{
    /*
     * According to spec, the mask bits that are 0 are compared and the
     * bits that are 1 are ignored.
     */
    uint16_t rdr_match_mask = GETFIELD(SPI_MM_RDR_MATCH_MASK,
                                        s->regs[SPI_MM_REG]);
    uint16_t rdr_match_val = GETFIELD(SPI_MM_RDR_MATCH_VAL,
                                        s->regs[SPI_MM_REG]);

    if ((~rdr_match_mask & rdr_match_val) == ((~rdr_match_mask) &
            GETFIELD(PPC_BITMASK(48, 63), s->regs[SPI_RCV_DATA_REG]))) {
        return true;
    }
    return false;
}

static uint8_t get_from_offset(PnvSpi *s, uint8_t offset)
{
    uint8_t byte;

    /*
     * Offset is an index between 0 and PNV_SPI_REG_SIZE - 1
     * Check the offset before using it.
     */
    if (offset < PNV_SPI_REG_SIZE) {
        byte = (s->regs[SPI_XMIT_DATA_REG] >> (56 - offset * 8)) & 0xFF;
    } else {
        /*
         * Log an error and return a 0xFF since we have to assign something
         * to byte before returning.
         */
        qemu_log_mask(LOG_GUEST_ERROR, "Invalid offset = %d used to get byte "
                      "from TDR\n", offset);
        byte = 0xff;
    }
    return byte;
}

static uint8_t read_from_frame(PnvSpi *s, uint8_t *read_buf, uint8_t nr_bytes,
                uint8_t ecc_count, uint8_t shift_in_count)
{
    uint8_t byte;
    int count = 0;

    while (count < nr_bytes) {
        shift_in_count++;
        if ((ecc_count != 0) &&
            (shift_in_count == (PNV_SPI_REG_SIZE + ecc_count))) {
            shift_in_count = 0;
        } else {
            byte = read_buf[count];
            trace_pnv_spi_shift_rx(byte, count);
            s->regs[SPI_RCV_DATA_REG] = (s->regs[SPI_RCV_DATA_REG] << 8) | byte;
        }
        count++;
    } /* end of while */
    return shift_in_count;
}

static void spi_response(PnvSpi *s, int bits, PnvXferBuffer *rsp_payload)
{
    uint8_t ecc_count;
    uint8_t shift_in_count;

    /*
     * Processing here must handle:
     * - Which bytes in the payload we should move to the RDR
     * - Explicit mode counter configuration settings
     * - RDR full and RDR overrun status
     */

    /*
     * First check that the response payload is the exact same
     * number of bytes as the request payload was
     */
    if (rsp_payload->len != (s->N1_bytes + s->N2_bytes)) {
        qemu_log_mask(LOG_GUEST_ERROR, "Invalid response payload size in "
                       "bytes, expected %d, got %d\n",
                       (s->N1_bytes + s->N2_bytes), rsp_payload->len);
    } else {
        uint8_t ecc_control;
        trace_pnv_spi_rx_received(rsp_payload->len);
        trace_pnv_spi_log_Ncounts(s->N1_bits, s->N1_bytes, s->N1_tx,
                        s->N1_rx, s->N2_bits, s->N2_bytes, s->N2_tx, s->N2_rx);
        /*
         * Adding an ECC count let's us know when we have found a payload byte
         * that was shifted in but cannot be loaded into RDR.  Bits 29-30 of
         * clock_config_reset_control register equal to either 0b00 or 0b10
         * indicate that we are taking in data with ECC and either applying
         * the ECC or discarding it.
         */
        ecc_count = 0;
        ecc_control = GETFIELD(SPI_CLK_CFG_ECC_CTRL, s->regs[SPI_CLK_CFG_REG]);
        if (ecc_control == 0 || ecc_control == 2) {
            ecc_count = 1;
        }
        /*
         * Use the N1_rx and N2_rx counts to control shifting data from the
         * payload into the RDR.  Keep an overall count of the number of bytes
         * shifted into RDR so we can discard every 9th byte when ECC is
         * enabled.
         */
        shift_in_count = 0;
        /* Handle the N1 portion of the frame first */
        if (s->N1_rx != 0) {
            trace_pnv_spi_rx_read_N1frame();
            shift_in_count = read_from_frame(s, &rsp_payload->data[0],
                            s->N1_bytes, ecc_count, shift_in_count);
        }
        /* Handle the N2 portion of the frame */
        if (s->N2_rx != 0) {
            trace_pnv_spi_rx_read_N2frame();
            shift_in_count = read_from_frame(s,
                            &rsp_payload->data[s->N1_bytes], s->N2_bytes,
                            ecc_count, shift_in_count);
        }
        if ((s->N1_rx + s->N2_rx) > 0) {
            /*
             * Data was received so handle RDR status.
             * It is easier to handle RDR_full and RDR_overrun status here
             * since the RDR register's shift_byte_in method is called
             * multiple times in a row. Controlling RDR status is done here
             * instead of in the RDR scoped methods for that reason.
             */
            if (GETFIELD(SPI_STS_RDR_FULL, s->status) == 1) {
                /*
                 * Data was shifted into the RDR before having been read
                 * causing previous data to have been overrun.
                 */
                s->status = SETFIELD(SPI_STS_RDR_OVERRUN, s->status, 1);
            } else {
                /*
                 * Set status to indicate that the received data register is
                 * full. This flag is only cleared once the RDR is unloaded.
                 */
                s->status = SETFIELD(SPI_STS_RDR_FULL, s->status, 1);
            }
        }
    } /* end of else */
} /* end of spi_response() */

static void transfer(PnvSpi *s, PnvXferBuffer *payload)
{
    uint32_t tx;
    uint32_t rx;
    PnvXferBuffer *rsp_payload = NULL;

    rsp_payload = pnv_spi_xfer_buffer_new();
    for (int offset = 0; offset < payload->len; offset += s->transfer_len) {
        tx = 0;
        for (int i = 0; i < s->transfer_len; i++) {
            if ((offset + i) >= payload->len) {
                tx <<= 8;
            } else {
                tx = (tx << 8) | payload->data[offset + i];
            }
        }
        rx = ssi_transfer(s->ssi_bus, tx);
        for (int i = 0; i < s->transfer_len; i++) {
            if ((offset + i) >= payload->len) {
                break;
            }
            *(pnv_spi_xfer_buffer_write_ptr(rsp_payload, rsp_payload->len, 1)) =
                    (rx >> (8 * (s->transfer_len - 1) - i * 8)) & 0xFF;
        }
    }
    if (rsp_payload != NULL) {
        spi_response(s, s->N1_bits, rsp_payload);
    }
}

static inline uint8_t get_seq_index(PnvSpi *s)
{
    return GETFIELD(SPI_STS_SEQ_INDEX, s->status);
}

static inline void next_sequencer_fsm(PnvSpi *s)
{
    uint8_t seq_index = get_seq_index(s);
    s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, (seq_index + 1));
    s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT);
}

/*
 * Calculate the N1 counters based on passed in opcode and
 * internal register values.
 * The method assumes that the opcode is a Shift_N1 opcode
 * and doesn't test it.
 * The counters returned are:
 * N1 bits: Number of bits in the payload data that are significant
 * to the responder.
 * N1_bytes: Total count of payload bytes for the N1 (portion of the) frame.
 * N1_tx: Total number of bytes taken from TDR for N1
 * N1_rx: Total number of bytes taken from the payload for N1
 */
static void calculate_N1(PnvSpi *s, uint8_t opcode)
{
    /*
     * Shift_N1 opcode form: 0x3M
     * Implicit mode:
     * If M != 0 the shift count is M bytes and M is the number of tx bytes.
     * Forced Implicit mode:
     * M is the shift count but tx and rx is determined by the count control
     * register fields.  Note that we only check for forced Implicit mode when
     * M != 0 since the mode doesn't make sense when M = 0.
     * Explicit mode:
     * If M == 0 then shift count is number of bits defined in the
     * Counter Configuration Register's shift_count_N1 field.
     */
    if (PNV_SPI_OPCODE_LO_NIBBLE(opcode) == 0) {
        /* Explicit mode */
        s->N1_bits = GETFIELD(SPI_CTR_CFG_N1, s->regs[SPI_CTR_CFG_REG]);
        s->N1_bytes = (s->N1_bits + 7) / 8;
        s->N1_tx = 0;
        s->N1_rx = 0;
        /* If tx count control for N1 is set, load the tx value */
        if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B2, s->regs[SPI_CTR_CFG_REG]) == 1) {
            s->N1_tx = s->N1_bytes;
        }
        /* If rx count control for N1 is set, load the rx value */
        if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B3, s->regs[SPI_CTR_CFG_REG]) == 1) {
            s->N1_rx = s->N1_bytes;
        }
    } else {
        /* Implicit mode/Forced Implicit mode, use M field from opcode */
        s->N1_bytes = PNV_SPI_OPCODE_LO_NIBBLE(opcode);
        s->N1_bits = s->N1_bytes * 8;
        /*
         * Assume that we are going to transmit the count
         * (pure Implicit only)
         */
        s->N1_tx = s->N1_bytes;
        s->N1_rx = 0;
        /* Let Forced Implicit mode have an effect on the counts */
        if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B1, s->regs[SPI_CTR_CFG_REG]) == 1) {
            /*
             * If Forced Implicit mode and count control doesn't
             * indicate transmit then reset the tx count to 0
             */
            if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B2,
                                    s->regs[SPI_CTR_CFG_REG]) == 0) {
                s->N1_tx = 0;
            }
            /* If rx count control for N1 is set, load the rx value */
            if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B3,
                                    s->regs[SPI_CTR_CFG_REG]) == 1) {
                s->N1_rx = s->N1_bytes;
            }
        }
    }
    /*
     * Enforce an upper limit on the size of N1 that is equal to the known size
     * of the shift register, 64 bits or 72 bits if ECC is enabled.
     * If the size exceeds 72 bits it is a user error so log an error,
     * cap the size at a max of 64 bits or 72 bits and set the sequencer FSM
     * error bit.
     */
    uint8_t ecc_control = GETFIELD(SPI_CLK_CFG_ECC_CTRL,
                                   s->regs[SPI_CLK_CFG_REG]);
    if (ecc_control == 0 || ecc_control == 2) {
        if (s->N1_bytes > (PNV_SPI_REG_SIZE + 1)) {
            qemu_log_mask(LOG_GUEST_ERROR, "Unsupported N1 shift size when "
                          "ECC enabled, bytes = 0x%x, bits = 0x%x\n",
                          s->N1_bytes, s->N1_bits);
            s->N1_bytes = PNV_SPI_REG_SIZE + 1;
            s->N1_bits = s->N1_bytes * 8;
        }
    } else if (s->N1_bytes > PNV_SPI_REG_SIZE) {
        qemu_log_mask(LOG_GUEST_ERROR, "Unsupported N1 shift size, "
                      "bytes = 0x%x, bits = 0x%x\n",
                      s->N1_bytes, s->N1_bits);
        s->N1_bytes = PNV_SPI_REG_SIZE;
        s->N1_bits = s->N1_bytes * 8;
    }
} /* end of calculate_N1 */

/*
 * Shift_N1 operation handler method
 */
static bool operation_shiftn1(PnvSpi *s, uint8_t opcode,
                       PnvXferBuffer **payload, bool send_n1_alone)
{
    uint8_t n1_count;
    bool stop = false;

    /*
     * If there isn't a current payload left over from a stopped sequence
     * create a new one.
     */
    if (*payload == NULL) {
        *payload = pnv_spi_xfer_buffer_new();
    }
    /*
     * Use a combination of N1 counters to build the N1 portion of the
     * transmit payload.
     * We only care about transmit at this time since the request payload
     * only represents data going out on the controller output line.
     * Leave mode specific considerations in the calculate function since
     * all we really care about are counters that tell use exactly how
     * many bytes are in the payload and how many of those bytes to
     * include from the TDR into the payload.
     */
    calculate_N1(s, opcode);
    trace_pnv_spi_log_Ncounts(s->N1_bits, s->N1_bytes, s->N1_tx,
                    s->N1_rx, s->N2_bits, s->N2_bytes, s->N2_tx, s->N2_rx);
    /*
     * Zero out the N2 counters here in case there is no N2 operation following
     * the N1 operation in the sequencer.  This keeps leftover N2 information
     * from interfering with spi_response logic.
     */
    s->N2_bits = 0;
    s->N2_bytes = 0;
    s->N2_tx = 0;
    s->N2_rx = 0;
    /*
     * N1_bytes is the overall size of the N1 portion of the frame regardless of
     * whether N1 is used for tx, rx or both.  Loop over the size to build a
     * payload that is N1_bytes long.
     * N1_tx is the count of bytes to take from the TDR and "shift" into the
     * frame which means append those bytes to the payload for the N1 portion
     * of the frame.
     * If N1_tx is 0 or if the count exceeds the size of the TDR append 0xFF to
     * the frame until the overall N1 count is reached.
     */
    n1_count = 0;
    while (n1_count < s->N1_bytes) {
        /*
         * Assuming that if N1_tx is not equal to 0 then it is the same as
         * N1_bytes.
         */
        if ((s->N1_tx != 0) && (n1_count < PNV_SPI_REG_SIZE)) {

            if (GETFIELD(SPI_STS_TDR_FULL, s->status) == 1) {
                /*
                 * Note that we are only appending to the payload IF the TDR
                 * is full otherwise we don't touch the payload because we are
                 * going to NOT send the payload and instead tell the sequencer
                 * that called us to stop and wait for a TDR write so we have
                 * data to load into the payload.
                 */
                uint8_t n1_byte = 0x00;
                n1_byte = get_from_offset(s, n1_count);
                trace_pnv_spi_tx_append("n1_byte", n1_byte, n1_count);
                *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1)) =
                        n1_byte;
            } else {
                /*
                 * We hit a shift_n1 opcode TX but the TDR is empty, tell the
                 * sequencer to stop and break this loop.
                 */
                trace_pnv_spi_sequencer_stop_requested("Shift N1"
                                "set for transmit but TDR is empty");
                stop = true;
                break;
            }
        } else {
            /*
             * Cases here:
             * - we are receiving during the N1 frame segment and the RDR
             *   is full so we need to stop until the RDR is read
             * - we are transmitting and we don't care about RDR status
             *   since we won't be loading RDR during the frame segment.
             * - we are receiving and the RDR is empty so we allow the operation
             *   to proceed.
             */
            if ((s->N1_rx != 0) && (GETFIELD(SPI_STS_RDR_FULL,
                                           s->status) == 1)) {
                trace_pnv_spi_sequencer_stop_requested("shift N1"
                                "set for receive but RDR is full");
                stop = true;
                break;
            } else {
                trace_pnv_spi_tx_append_FF("n1_byte");
                *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1))
                        = 0xff;
            }
        }
        n1_count++;
    } /* end of while */
    /*
     * If we are not stopping due to an empty TDR and we are doing an N1 TX
     * and the TDR is full we need to clear the TDR_full status.
     * Do this here instead of up in the loop above so we don't log the message
     * in every loop iteration.
     * Ignore the send_n1_alone flag, all that does is defer the TX until the N2
     * operation, which was found immediately after the current opcode.  The TDR
     * was unloaded and will be shifted so we have to clear the TDR_full status.
     */
    if (!stop && (s->N1_tx != 0) &&
        (GETFIELD(SPI_STS_TDR_FULL, s->status) == 1)) {
        s->status = SETFIELD(SPI_STS_TDR_FULL, s->status, 0);
    }
    /*
     * There are other reasons why the shifter would stop, such as a TDR empty
     * or RDR full condition with N1 set to receive.  If we haven't stopped due
     * to either one of those conditions then check if the send_n1_alone flag is
     * equal to False, indicating the next opcode is an N2 operation, AND if
     * the N2 counter reload switch (bit 0 of the N2 count control field) is
     * set.  This condition requires a pacing write to "kick" off the N2
     * shift which includes the N1 shift as well when send_n1_alone is False.
     */
    if (!stop && !send_n1_alone &&
       (GETFIELD(SPI_CTR_CFG_N2_CTRL_B0, s->regs[SPI_CTR_CFG_REG]) == 1)) {
        trace_pnv_spi_sequencer_stop_requested("N2 counter reload "
                        "active, stop N1 shift, TDR_underrun set to 1");
        stop = true;
        s->status = SETFIELD(SPI_STS_TDR_UNDERRUN, s->status, 1);
    }
    /*
     * If send_n1_alone is set AND we have a full TDR then this is the first and
     * last payload to send and we don't have an N2 frame segment to add to the
     * payload.
     */
    if (send_n1_alone && !stop) {
        /* We have a TX and a full TDR or an RX and an empty RDR */
        trace_pnv_spi_tx_request("Shifting N1 frame", (*payload)->len);
        transfer(s, *payload);
        /* The N1 frame shift is complete so reset the N1 counters */
        s->N2_bits = 0;
        s->N2_bytes = 0;
        s->N2_tx = 0;
        s->N2_rx = 0;
        pnv_spi_xfer_buffer_free(*payload);
        *payload = NULL;
    }
    return stop;
} /* end of operation_shiftn1() */

/*
 * Calculate the N2 counters based on passed in opcode and
 * internal register values.
 * The method assumes that the opcode is a Shift_N2 opcode
 * and doesn't test it.
 * The counters returned are:
 * N2 bits: Number of bits in the payload data that are significant
 * to the responder.
 * N2_bytes: Total count of payload bytes for the N2 frame.
 * N2_tx: Total number of bytes taken from TDR for N2
 * N2_rx: Total number of bytes taken from the payload for N2
 */
static void calculate_N2(PnvSpi *s, uint8_t opcode)
{
    /*
     * Shift_N2 opcode form: 0x4M
     * Implicit mode:
     * If M!=0 the shift count is M bytes and M is the number of rx bytes.
     * Forced Implicit mode:
     * M is the shift count but tx and rx is determined by the count control
     * register fields.  Note that we only check for Forced Implicit mode when
     * M != 0 since the mode doesn't make sense when M = 0.
     * Explicit mode:
     * If M==0 then shift count is number of bits defined in the
     * Counter Configuration Register's shift_count_N1 field.
     */
    if (PNV_SPI_OPCODE_LO_NIBBLE(opcode) == 0) {
        /* Explicit mode */
        s->N2_bits = GETFIELD(SPI_CTR_CFG_N2, s->regs[SPI_CTR_CFG_REG]);
        s->N2_bytes = (s->N2_bits + 7) / 8;
        s->N2_tx = 0;
        s->N2_rx = 0;
        /* If tx count control for N2 is set, load the tx value */
        if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B2, s->regs[SPI_CTR_CFG_REG]) == 1) {
            s->N2_tx = s->N2_bytes;
        }
        /* If rx count control for N2 is set, load the rx value */
        if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B3, s->regs[SPI_CTR_CFG_REG]) == 1) {
            s->N2_rx = s->N2_bytes;
        }
    } else {
        /* Implicit mode/Forced Implicit mode, use M field from opcode */
        s->N2_bytes = PNV_SPI_OPCODE_LO_NIBBLE(opcode);
        s->N2_bits = s->N2_bytes * 8;
        /* Assume that we are going to receive the count */
        s->N2_rx = s->N2_bytes;
        s->N2_tx = 0;
        /* Let Forced Implicit mode have an effect on the counts */
        if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B1, s->regs[SPI_CTR_CFG_REG]) == 1) {
            /*
             * If Forced Implicit mode and count control doesn't
             * indicate a receive then reset the rx count to 0
             */
            if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B3,
                                    s->regs[SPI_CTR_CFG_REG]) == 0) {
                s->N2_rx = 0;
            }
            /* If tx count control for N2 is set, load the tx value */
            if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B2,
                                    s->regs[SPI_CTR_CFG_REG]) == 1) {
                s->N2_tx = s->N2_bytes;
            }
        }
    }
    /*
     * Enforce an upper limit on the size of N1 that is equal to the
     * known size of the shift register, 64 bits or 72 bits if ECC
     * is enabled.
     * If the size exceeds 72 bits it is a user error so log an error,
     * cap the size at a max of 64 bits or 72 bits and set the sequencer FSM
     * error bit.
     */
    uint8_t ecc_control = GETFIELD(SPI_CLK_CFG_ECC_CTRL,
                    s->regs[SPI_CLK_CFG_REG]);
    if (ecc_control == 0 || ecc_control == 2) {
        if (s->N2_bytes > (PNV_SPI_REG_SIZE + 1)) {
            /* Unsupported N2 shift size when ECC enabled */
            s->N2_bytes = PNV_SPI_REG_SIZE + 1;
            s->N2_bits = s->N2_bytes * 8;
        }
    } else if (s->N2_bytes > PNV_SPI_REG_SIZE) {
        /* Unsupported N2 shift size */
        s->N2_bytes = PNV_SPI_REG_SIZE;
        s->N2_bits = s->N2_bytes * 8;
    }
} /* end of calculate_N2 */

/*
 * Shift_N2 operation handler method
 */

static bool operation_shiftn2(PnvSpi *s, uint8_t opcode,
                       PnvXferBuffer **payload)
{
    uint8_t n2_count;
    bool stop = false;

    /*
     * If there isn't a current payload left over from a stopped sequence
     * create a new one.
     */
    if (*payload == NULL) {
        *payload = pnv_spi_xfer_buffer_new();
    }
    /*
     * Use a combination of N2 counters to build the N2 portion of the
     * transmit payload.
     */
    calculate_N2(s, opcode);
    trace_pnv_spi_log_Ncounts(s->N1_bits, s->N1_bytes, s->N1_tx,
                    s->N1_rx, s->N2_bits, s->N2_bytes, s->N2_tx, s->N2_rx);
    /*
     * The only difference between this code and the code for shift N1 is
     * that this code has to account for the possible presence of N1 transmit
     * bytes already taken from the TDR.
     * If there are bytes to be transmitted for the N2 portion of the frame
     * and there are still bytes in TDR that have not been copied into the
     * TX data of the payload, this code will handle transmitting those
     * remaining bytes.
     * If for some reason the transmit count(s) add up to more than the size
     * of the TDR we will just append 0xFF to the transmit payload data until
     * the payload is N1 + N2 bytes long.
     */
    n2_count = 0;
    while (n2_count < s->N2_bytes) {
        /*
         * If the RDR is full and we need to RX just bail out, letting the
         * code continue will end up building the payload twice in the same
         * buffer since RDR full causes a sequence stop and restart.
         */
        if ((s->N2_rx != 0) &&
            (GETFIELD(SPI_STS_RDR_FULL, s->status) == 1)) {
            trace_pnv_spi_sequencer_stop_requested("shift N2 set"
                            "for receive but RDR is full");
            stop = true;
            break;
        }
        if ((s->N2_tx != 0) && ((s->N1_tx + n2_count) <
                                PNV_SPI_REG_SIZE)) {
            /* Always append data for the N2 segment if it is set for TX */
            uint8_t n2_byte = 0x00;
            n2_byte = get_from_offset(s, (s->N1_tx + n2_count));
            trace_pnv_spi_tx_append("n2_byte", n2_byte, (s->N1_tx + n2_count));
            *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1))
                    = n2_byte;
        } else {
            /*
             * Regardless of whether or not N2 is set for TX or RX, we need
             * the number of bytes in the payload to match the overall length
             * of the operation.
             */
            trace_pnv_spi_tx_append_FF("n2_byte");
            *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1))
                    = 0xff;
        }
        n2_count++;
    } /* end of while */
    if (!stop) {
        /* We have a TX and a full TDR or an RX and an empty RDR */
        trace_pnv_spi_tx_request("Shifting N2 frame", (*payload)->len);
        transfer(s, *payload);
        /*
         * If we are doing an N2 TX and the TDR is full we need to clear the
         * TDR_full status. Do this here instead of up in the loop above so we
         * don't log the message in every loop iteration.
         */
        if ((s->N2_tx != 0) &&
            (GETFIELD(SPI_STS_TDR_FULL, s->status) == 1)) {
            s->status = SETFIELD(SPI_STS_TDR_FULL, s->status, 0);
        }
        /*
         * The N2 frame shift is complete so reset the N2 counters.
         * Reset the N1 counters also in case the frame was a combination of
         * N1 and N2 segments.
         */
        s->N2_bits = 0;
        s->N2_bytes = 0;
        s->N2_tx = 0;
        s->N2_rx = 0;
        s->N1_bits = 0;
        s->N1_bytes = 0;
        s->N1_tx = 0;
        s->N1_rx = 0;
        pnv_spi_xfer_buffer_free(*payload);
        *payload = NULL;
    }
    return stop;
} /*  end of operation_shiftn2()*/

static void operation_sequencer(PnvSpi *s)
{
    /*
     * Loop through each sequencer operation ID and perform the requested
     *  operations.
     * Flag for indicating if we should send the N1 frame or wait to combine
     * it with a preceding N2 frame.
     */
    bool send_n1_alone = true;
    bool stop = false; /* Flag to stop the sequencer */
    uint8_t opcode = 0;
    uint8_t masked_opcode = 0;

    /*
     * PnvXferBuffer for containing the payload of the SPI frame.
     * This is a static because there are cases where a sequence has to stop
     * and wait for the target application to unload the RDR.  If this occurs
     * during a sequence where N1 is not sent alone and instead combined with
     * N2 since the N1 tx length + the N2 tx length is less than the size of
     * the TDR.
     */
    static PnvXferBuffer *payload;

    if (payload == NULL) {
        payload = pnv_spi_xfer_buffer_new();
    }
    /*
     * Clear the sequencer FSM error bit - general_SPI_status[3]
     * before starting a sequence.
     */
    s->status = SETFIELD(SPI_STS_GEN_STATUS_B3, s->status, 0);
    /*
     * If the FSM is idle set the sequencer index to 0
     * (new/restarted sequence)
     */
    if (GETFIELD(SPI_STS_SEQ_FSM, s->status) == SEQ_STATE_IDLE) {
        s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, 0);
    }
    /*
     * There are only 8 possible operation IDs to iterate through though
     * some operations may cause more than one frame to be sequenced.
     */
    while (get_seq_index(s) < NUM_SEQ_OPS) {
        opcode = s->seq_op[get_seq_index(s)];
        /* Set sequencer state to decode */
        s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_DECODE);
        /*
         * Only the upper nibble of the operation ID is needed to know what
         * kind of operation is requested.
         */
        masked_opcode = PNV_SPI_MASKED_OPCODE(opcode);
        switch (masked_opcode) {
        /*
         * Increment the operation index in each case instead of just
         * once at the end in case an operation like the branch
         * operation needs to change the index.
         */
        case SEQ_OP_STOP:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            /* A stop operation in any position stops the sequencer */
            trace_pnv_spi_sequencer_op("STOP", get_seq_index(s));

            stop = true;
            s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE);
            s->loop_counter_1 = 0;
            s->loop_counter_2 = 0;
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_IDLE);
            break;

        case SEQ_OP_SELECT_SLAVE:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            trace_pnv_spi_sequencer_op("SELECT_SLAVE", get_seq_index(s));
            /*
             * This device currently only supports a single responder
             * connection at position 0.  De-selecting a responder is fine
             * and expected at the end of a sequence but selecting any
             * responder other than 0 should cause an error.
             */
            s->responder_select = PNV_SPI_OPCODE_LO_NIBBLE(opcode);
            if (s->responder_select == 0) {
                trace_pnv_spi_shifter_done();
                qemu_set_irq(s->cs_line[0], 1);
                s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status,
                                (get_seq_index(s) + 1));
                s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_DONE);
            } else if (s->responder_select != 1) {
                qemu_log_mask(LOG_GUEST_ERROR, "Slave selection other than 1 "
                              "not supported, select = 0x%x\n",
                               s->responder_select);
                trace_pnv_spi_sequencer_stop_requested("invalid "
                                "responder select");
                s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE);
                stop = true;
            } else {
                /*
                 * Only allow an FSM_START state when a responder is
                 * selected
                 */
                s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_START);
                trace_pnv_spi_shifter_stating();
                qemu_set_irq(s->cs_line[0], 0);
                /*
                 * A Shift_N2 operation is only valid after a Shift_N1
                 * according to the spec. The spec doesn't say if that means
                 * immediately after or just after at any point. We will track
                 * the occurrence of a Shift_N1 to enforce this requirement in
                 * the most generic way possible by assuming that the rule
                 * applies once a valid responder select has occurred.
                 */
                s->shift_n1_done = false;
                next_sequencer_fsm(s);
            }
            break;

        case SEQ_OP_SHIFT_N1:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            trace_pnv_spi_sequencer_op("SHIFT_N1", get_seq_index(s));
            /*
             * Only allow a shift_n1 when the state is not IDLE or DONE.
             * In either of those two cases the sequencer is not in a proper
             * state to perform shift operations because the sequencer has:
             * - processed a responder deselect (DONE)
             * - processed a stop opcode (IDLE)
             * - encountered an error (IDLE)
             */
            if ((GETFIELD(SPI_STS_SHIFTER_FSM, s->status) == FSM_IDLE) ||
                (GETFIELD(SPI_STS_SHIFTER_FSM, s->status) == FSM_DONE)) {
                qemu_log_mask(LOG_GUEST_ERROR, "Shift_N1 not allowed in "
                              "shifter state = 0x%llx", GETFIELD(
                        SPI_STS_SHIFTER_FSM, s->status));
                /*
                 * Set sequencer FSM error bit 3 (general_SPI_status[3])
                 * in status reg.
                 */
                s->status = SETFIELD(SPI_STS_GEN_STATUS_B3, s->status, 1);
                trace_pnv_spi_sequencer_stop_requested("invalid shifter state");
                stop = true;
            } else {
                /*
                 * Look for the special case where there is a shift_n1 set for
                 * transmit and it is followed by a shift_n2 set for transmit
                 * AND the combined transmit length of the two operations is
                 * less than or equal to the size of the TDR register. In this
                 * case we want to use both this current shift_n1 opcode and the
                 * following shift_n2 opcode to assemble the frame for
                 * transmission to the responder without requiring a refill of
                 * the TDR between the two operations.
                 */
                if (PNV_SPI_MASKED_OPCODE(s->seq_op[get_seq_index(s) + 1])
                                == SEQ_OP_SHIFT_N2) {
                    send_n1_alone = false;
                }
                s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status,
                                FSM_SHIFT_N1);
                stop = operation_shiftn1(s, opcode, &payload, send_n1_alone);
                if (stop) {
                    /*
                     *  The operation code says to stop, this can occur if:
                     * (1) RDR is full and the N1 shift is set for receive
                     * (2) TDR was empty at the time of the N1 shift so we need
                     * to wait for data.
                     * (3) Neither 1 nor 2 are occurring and we aren't sending
                     * N1 alone and N2 counter reload is set (bit 0 of the N2
                     * counter reload field).  In this case TDR_underrun will
                     * will be set and the Payload has been loaded so it is
                     * ok to advance the sequencer.
                     */
                    if (GETFIELD(SPI_STS_TDR_UNDERRUN, s->status)) {
                        s->shift_n1_done = true;
                        s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status,
                                                  FSM_SHIFT_N2);
                        s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status,
                                        (get_seq_index(s) + 1));
                    } else {
                        /*
                         * This is case (1) or (2) so the sequencer needs to
                         * wait and NOT go to the next sequence yet.
                         */
                        s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status,
                                        FSM_WAIT);
                    }
                } else {
                    /* Ok to move on to the next index */
                    s->shift_n1_done = true;
                    next_sequencer_fsm(s);
                }
            }
            break;

        case SEQ_OP_SHIFT_N2:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            trace_pnv_spi_sequencer_op("SHIFT_N2", get_seq_index(s));
            if (!s->shift_n1_done) {
                qemu_log_mask(LOG_GUEST_ERROR, "Shift_N2 is not allowed if a "
                              "Shift_N1 is not done, shifter state = 0x%llx",
                              GETFIELD(SPI_STS_SHIFTER_FSM, s->status));
                /*
                 * In case the sequencer actually stops if an N2 shift is
                 * requested before any N1 shift is done. Set sequencer FSM
                 * error bit 3 (general_SPI_status[3]) in status reg.
                 */
                s->status = SETFIELD(SPI_STS_GEN_STATUS_B3, s->status, 1);
                trace_pnv_spi_sequencer_stop_requested("shift_n2 "
                                    "w/no shift_n1 done");
                stop = true;
            } else {
                /* Ok to do a Shift_N2 */
                s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status,
                                FSM_SHIFT_N2);
                stop = operation_shiftn2(s, opcode, &payload);
                /*
                 * If the operation code says to stop set the shifter state to
                 * wait and stop
                 */
                if (stop) {
                    s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status,
                                    FSM_WAIT);
                } else {
                    /* Ok to move on to the next index */
                    next_sequencer_fsm(s);
                }
            }
            break;

        case SEQ_OP_BRANCH_IFNEQ_RDR:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_RDR", get_seq_index(s));
            /*
             * The memory mapping register RDR match value is compared against
             * the 16 rightmost bytes of the RDR (potentially with masking).
             * Since this comparison is performed against the contents of the
             * RDR then a receive must have previously occurred otherwise
             * there is no data to compare and the operation cannot be
             * completed and will stop the sequencer until RDR full is set to
             * 1.
             */
            if (GETFIELD(SPI_STS_RDR_FULL, s->status) == 1) {
                bool rdr_matched = false;
                rdr_matched = does_rdr_match(s);
                if (rdr_matched) {
                    trace_pnv_spi_RDR_match("success");
                    /* A match occurred, increment the sequencer index. */
                    next_sequencer_fsm(s);
                } else {
                    trace_pnv_spi_RDR_match("failed");
                    /*
                     * Branch the sequencer to the index coded into the op
                     * code.
                     */
                    s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status,
                                    PNV_SPI_OPCODE_LO_NIBBLE(opcode));
                }
                /*
                 * Regardless of where the branch ended up we want the
                 * sequencer to continue shifting so we have to clear
                 * RDR_full.
                 */
                s->status = SETFIELD(SPI_STS_RDR_FULL, s->status, 0);
            } else {
                trace_pnv_spi_sequencer_stop_requested("RDR not"
                                "full for 0x6x opcode");
                stop = true;
                s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_WAIT);
            }
            break;

        case SEQ_OP_TRANSFER_TDR:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            qemu_log_mask(LOG_GUEST_ERROR, "Transfer TDR is not supported\n");
            next_sequencer_fsm(s);
            break;

        case SEQ_OP_BRANCH_IFNEQ_INC_1:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_1", get_seq_index(s));
            /*
             * The spec says the loop should execute count compare + 1 times.
             * However we learned from engineering that we really only loop
             * count_compare times, count compare = 0 makes this op code a
             * no-op
             */
            if (s->loop_counter_1 !=
                GETFIELD(SPI_CTR_CFG_CMP1, s->regs[SPI_CTR_CFG_REG])) {
                /*
                 * Next index is the lower nibble of the branch operation ID,
                 * mask off all but the first three bits so we don't try to
                 * access beyond the sequencer_operation_reg boundary.
                 */
                s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status,
                                PNV_SPI_OPCODE_LO_NIBBLE(opcode));
                s->loop_counter_1++;
            } else {
                /* Continue to next index if loop counter is reached */
                next_sequencer_fsm(s);
            }
            break;

        case SEQ_OP_BRANCH_IFNEQ_INC_2:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_2", get_seq_index(s));
            uint8_t condition2 = GETFIELD(SPI_CTR_CFG_CMP2,
                              s->regs[SPI_CTR_CFG_REG]);
            /*
             * The spec says the loop should execute count compare + 1 times.
             * However we learned from engineering that we really only loop
             * count_compare times, count compare = 0 makes this op code a
             * no-op
             */
            if (s->loop_counter_2 != condition2) {
                /*
                 * Next index is the lower nibble of the branch operation ID,
                 * mask off all but the first three bits so we don't try to
                 * access beyond the sequencer_operation_reg boundary.
                 */
                s->status = SETFIELD(SPI_STS_SEQ_INDEX,
                                s->status, PNV_SPI_OPCODE_LO_NIBBLE(opcode));
                s->loop_counter_2++;
            } else {
                /* Continue to next index if loop counter is reached */
                next_sequencer_fsm(s);
            }
            break;

        default:
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
            /* Ignore unsupported operations. */
            next_sequencer_fsm(s);
            break;
        } /* end of switch */
        /*
         * If we used all 8 opcodes without seeing a 00 - STOP in the sequence
         * we need to go ahead and end things as if there was a STOP at the
         * end.
         */
        if (get_seq_index(s) == NUM_SEQ_OPS) {
            /* All 8 opcodes completed, sequencer idling */
            s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE);
            s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, 0);
            s->loop_counter_1 = 0;
            s->loop_counter_2 = 0;
            s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_IDLE);
            break;
        }
        /* Break the loop if a stop was requested */
        if (stop) {
            break;
        }
    } /* end of while */
    return;
} /* end of operation_sequencer() */

/*
 * The SPIC engine and its internal sequencer can be interrupted and reset by
 * a hardware signal, the sbe_spicst_hard_reset bits from Pervasive
 * Miscellaneous Register of sbe_register_bo device.
 * Reset immediately aborts any SPI transaction in progress and returns the
 * sequencer and state machines to idle state.
 * The configuration register values are not changed. The status register is
 * not reset. The engine registers are not reset.
 * The SPIC engine reset does not have any affect on the attached devices.
 * Reset handling of any attached devices is beyond the scope of the engine.
 */
static void do_reset(DeviceState *dev)
{
    PnvSpi *s = PNV_SPI(dev);
    DeviceState *ssi_dev;

    trace_pnv_spi_reset();

    /* Connect cs irq */
    ssi_dev = ssi_get_cs(s->ssi_bus, 0);
    if (ssi_dev) {
        qemu_irq cs_line = qdev_get_gpio_in_named(ssi_dev, SSI_GPIO_CS, 0);
        qdev_connect_gpio_out_named(DEVICE(s), "cs", 0, cs_line);
    }

    /* Reset all N1 and N2 counters, and other constants */
    s->N2_bits = 0;
    s->N2_bytes = 0;
    s->N2_tx = 0;
    s->N2_rx = 0;
    s->N1_bits = 0;
    s->N1_bytes = 0;
    s->N1_tx = 0;
    s->N1_rx = 0;
    s->loop_counter_1 = 0;
    s->loop_counter_2 = 0;
    /* Disconnected from responder */
    qemu_set_irq(s->cs_line[0], 1);
}

static uint64_t pnv_spi_xscom_read(void *opaque, hwaddr addr, unsigned size)
{
    PnvSpi *s = PNV_SPI(opaque);
    uint32_t reg = addr >> 3;
    uint64_t val = ~0ull;

    switch (reg) {
    case ERROR_REG:
    case SPI_CTR_CFG_REG:
    case CONFIG_REG1:
    case SPI_CLK_CFG_REG:
    case SPI_MM_REG:
    case SPI_XMIT_DATA_REG:
        val = s->regs[reg];
        break;
    case SPI_RCV_DATA_REG:
        val = s->regs[reg];
        trace_pnv_spi_read_RDR(val);
        s->status = SETFIELD(SPI_STS_RDR_FULL, s->status, 0);
        if (GETFIELD(SPI_STS_SHIFTER_FSM, s->status) == FSM_WAIT) {
            trace_pnv_spi_start_sequencer();
            operation_sequencer(s);
        }
        break;
    case SPI_SEQ_OP_REG:
        val = 0;
        for (int i = 0; i < PNV_SPI_REG_SIZE; i++) {
            val = (val << 8) | s->seq_op[i];
        }
        break;
    case SPI_STS_REG:
        val = s->status;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi_regs: Invalid xscom "
                 "read at 0x%" PRIx32 "\n", reg);
    }

    trace_pnv_spi_read(addr, val);
    return val;
}

static void pnv_spi_xscom_write(void *opaque, hwaddr addr,
                                 uint64_t val, unsigned size)
{
    PnvSpi *s = PNV_SPI(opaque);
    uint32_t reg = addr >> 3;

    trace_pnv_spi_write(addr, val);

    switch (reg) {
    case ERROR_REG:
    case SPI_CTR_CFG_REG:
    case CONFIG_REG1:
    case SPI_MM_REG:
    case SPI_RCV_DATA_REG:
        s->regs[reg] = val;
        break;
    case SPI_CLK_CFG_REG:
        /*
         * To reset the SPI controller write the sequence 0x5 0xA to
         * reset_control field
         */
        if ((GETFIELD(SPI_CLK_CFG_RST_CTRL, s->regs[SPI_CLK_CFG_REG]) == 0x5)
             && (GETFIELD(SPI_CLK_CFG_RST_CTRL, val) == 0xA)) {
                /* SPI controller reset sequence completed, resetting */
            s->regs[reg] = SPI_CLK_CFG_HARD_RST;
        } else {
            s->regs[reg] = val;
        }
        break;
    case SPI_XMIT_DATA_REG:
        /*
         * Writing to the transmit data register causes the transmit data
         * register full status bit in the status register to be set.  Writing
         * when the transmit data register full status bit is already set
         * causes a "Resource Not Available" condition.  This is not possible
         * in the model since writes to this register are not asynchronous to
         * the operation sequence like it would be in hardware.
         */
        s->regs[reg] = val;
        trace_pnv_spi_write_TDR(val);
        s->status = SETFIELD(SPI_STS_TDR_FULL, s->status, 1);
        s->status = SETFIELD(SPI_STS_TDR_UNDERRUN, s->status, 0);
        trace_pnv_spi_start_sequencer();
        operation_sequencer(s);
        break;
    case SPI_SEQ_OP_REG:
        for (int i = 0; i < PNV_SPI_REG_SIZE; i++) {
            s->seq_op[i] = (val >> (56 - i * 8)) & 0xFF;
        }
        break;
    case SPI_STS_REG:
        /* other fields are ignore_write */
        s->status = SETFIELD(SPI_STS_RDR_OVERRUN, s->status,
                                  GETFIELD(SPI_STS_RDR, val));
        s->status = SETFIELD(SPI_STS_TDR_OVERRUN, s->status,
                                  GETFIELD(SPI_STS_TDR, val));
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi_regs: Invalid xscom "
                 "write at 0x%" PRIx32 "\n", reg);
    }
    return;
}

static const MemoryRegionOps pnv_spi_xscom_ops = {
    .read = pnv_spi_xscom_read,
    .write = pnv_spi_xscom_write,
    .valid.min_access_size = 8,
    .valid.max_access_size = 8,
    .impl.min_access_size = 8,
    .impl.max_access_size = 8,
    .endianness = DEVICE_BIG_ENDIAN,
};

static Property pnv_spi_properties[] = {
    DEFINE_PROP_UINT32("spic_num", PnvSpi, spic_num, 0),
    DEFINE_PROP_UINT8("transfer_len", PnvSpi, transfer_len, 4),
    DEFINE_PROP_END_OF_LIST(),
};

static void pnv_spi_realize(DeviceState *dev, Error **errp)
{
    PnvSpi *s = PNV_SPI(dev);
    g_autofree char *name = g_strdup_printf(TYPE_PNV_SPI_BUS ".%d",
                    s->spic_num);
    s->ssi_bus = ssi_create_bus(dev, name);
    s->cs_line = g_new0(qemu_irq, 1);
    qdev_init_gpio_out_named(DEVICE(s), s->cs_line, "cs", 1);

    /* spi scoms */
    pnv_xscom_region_init(&s->xscom_spic_regs, OBJECT(s), &pnv_spi_xscom_ops,
                          s, "xscom-spi", PNV10_XSCOM_PIB_SPIC_SIZE);
}

static int pnv_spi_dt_xscom(PnvXScomInterface *dev, void *fdt,
                             int offset)
{
    PnvSpi *s = PNV_SPI(dev);
    g_autofree char *name;
    int s_offset;
    const char compat[] = "ibm,power10-spi";
    uint32_t spic_pcba = PNV10_XSCOM_PIB_SPIC_BASE +
        s->spic_num * PNV10_XSCOM_PIB_SPIC_SIZE;
    uint32_t reg[] = {
        cpu_to_be32(spic_pcba),
        cpu_to_be32(PNV10_XSCOM_PIB_SPIC_SIZE)
    };
    name = g_strdup_printf("pnv_spi@%x", spic_pcba);
    s_offset = fdt_add_subnode(fdt, offset, name);
    _FDT(s_offset);

    _FDT(fdt_setprop(fdt, s_offset, "reg", reg, sizeof(reg)));
    _FDT(fdt_setprop(fdt, s_offset, "compatible", compat, sizeof(compat)));
    _FDT((fdt_setprop_cell(fdt, s_offset, "spic_num#", s->spic_num)));
    return 0;
}

static void pnv_spi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PnvXScomInterfaceClass *xscomc = PNV_XSCOM_INTERFACE_CLASS(klass);

    xscomc->dt_xscom = pnv_spi_dt_xscom;

    dc->desc = "PowerNV SPI";
    dc->realize = pnv_spi_realize;
    device_class_set_legacy_reset(dc, do_reset);
    device_class_set_props(dc, pnv_spi_properties);
}

static const TypeInfo pnv_spi_info = {
    .name          = TYPE_PNV_SPI,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(PnvSpi),
    .class_init    = pnv_spi_class_init,
    .interfaces    = (InterfaceInfo[]) {
        { TYPE_PNV_XSCOM_INTERFACE },
        { }
    }
};

static void pnv_spi_register_types(void)
{
    type_register_static(&pnv_spi_info);
}

type_init(pnv_spi_register_types);
