/*
 * 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)
{
    g_free(payload->data);
    g_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();
    if (!rsp_payload) {
        return;
    }
    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;
        }
    }
    spi_response(s, s->N1_bits, rsp_payload);
    pnv_spi_xfer_buffer_free(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);
