From nobody Wed Nov 27 14:38:56 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1731427169; cv=none; d=zohomail.com; s=zohoarc; b=fZJRQ6MWtRKDPeRWEa2ryJJzfJ72P0t9gEGay4Yc7tAihmBFBLVSYFqgXqUMQ0BF/Ql9MkINEaI7f9FCgxowXPRZ35J1wPmcrpiojnzrJ1hS0HWNt7RqegXQ/wIGDHTDDO4RQS/7y3mLNJKnYpVVCQjBpMI+ZSD2oykd7JBi6Qc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1731427169; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Zx9gzYyBt0X55NoZ9J4+1yQlbR527P1a0px/CZN2GWE=; b=M/q2sLyqFcE7uqMHQGPobqfW/3hSw9fbstWucVbqZsO+oTzvYdQ+IZY4UroLfEdNXNn6YTwcBCEG9hlM9sGIQhX6Ang7nf6Qfp3Ne7fzGi6CZdLzlNQUolCbDX3wJdR9/hZ67fi6tEX7AaqKRtgGpTJkHnNkp+rSEfL38wjxMkI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1731427169194810.2520356959627; Tue, 12 Nov 2024 07:59:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tAtHe-0002Mz-Ok; Tue, 12 Nov 2024 10:58:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tAtHQ-0002Kt-VT; Tue, 12 Nov 2024 10:58:15 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tAtHK-0001e6-4j; Tue, 12 Nov 2024 10:58:12 -0500 Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4ACEeaku008175; Tue, 12 Nov 2024 15:57:54 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 42v8yv8d6y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 12 Nov 2024 15:57:53 +0000 (GMT) Received: from m0356517.ppops.net (m0356517.ppops.net [127.0.0.1]) by pps.reinject (8.18.0.8/8.18.0.8) with ESMTP id 4ACFvrnn011263; Tue, 12 Nov 2024 15:57:53 GMT Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 42v8yv8d6s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 12 Nov 2024 15:57:53 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 4AC6oBlT002777; Tue, 12 Nov 2024 15:57:52 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 42tms14chj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 12 Nov 2024 15:57:52 +0000 Received: from smtpav02.fra02v.mail.ibm.com (smtpav02.fra02v.mail.ibm.com [10.20.54.101]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 4ACFvmnd37683478 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 12 Nov 2024 15:57:48 GMT Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A085720043; Tue, 12 Nov 2024 15:57:48 +0000 (GMT) Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6FCEF20040; Tue, 12 Nov 2024 15:57:46 +0000 (GMT) Received: from gfwr515.rchland.ibm.com (unknown [9.10.239.103]) by smtpav02.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 12 Nov 2024 15:57:46 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=Zx9gzYyBt0X55NoZ9 J4+1yQlbR527P1a0px/CZN2GWE=; b=rJCpQSWmMWMsE4y7jge1HnsajXa2sbiRQ Xs87EnWXlmGwfOWWuej/Y9WZ/5sASJ7Mf/GEMMkBBxmjYTsXS7S2IXyO9iAHvIye 31ITx/FUTv7z+/MBEWP8DPrN9FCbXmgkVYE9QGx3iHv/he/OPJWgxBfR9RM7YUz/ IYRolTR2FipsVD8E2YwaJFUuow4UeR9As3u36sZ65Ywx2Bt1Tv2W9ZVAIQ/l3YNZ k36R5VGbHaZzOPnRrSBe14DgarJxdLM+RUlzJ+7eyVsw7zsH3agpFGK2rcKxFiSb wLe1fv0KK2cQSqnfO2afWQ0+EJmiNlZCJTQ8GguGcqFZkQqE4IiDA== From: Chalapathi V To: qemu-devel@nongnu.org Cc: qemu-ppc@nongnu.org, fbarrat@linux.ibm.com, npiggin@gmail.com, clg@kaod.org, calebs@linux.ibm.com, chalapathi.v@ibm.com, chalapathi.v@linux.ibm.com, saif.abrar@linux.ibm.com, dantan@linux.vnet.ibm.com, milesg@linux.ibm.com, philmd@linaro.org, alistair@alistair23.me Subject: [PATCH v4 1/2] hw/ssi/pnv_spi: Replace PnvXferBuffer with Fifo8 structure Date: Tue, 12 Nov 2024 09:57:38 -0600 Message-Id: <20241112155739.4447-2-chalapathi.v@linux.ibm.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241112155739.4447-1-chalapathi.v@linux.ibm.com> References: <20241112155739.4447-1-chalapathi.v@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: WgCza5ZW0p4pkIR9u-E2y8545RLEtamx X-Proofpoint-ORIG-GUID: KfC8AbS1vWm_sRlzEmtX849P9ysXIFJV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1051,Hydra:6.0.680,FMLib:17.12.62.30 definitions=2024-10-15_01,2024-10-11_01,2024-09-30_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 priorityscore=1501 suspectscore=0 impostorscore=0 mlxscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxlogscore=999 spamscore=0 clxscore=1015 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2411120125 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=chalapathi.v@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1731427171220116600 Content-Type: text/plain; charset="utf-8" In PnvXferBuffer dynamically allocating and freeing is a process overhead. Hence used an existing Fifo8 buffer with capacity of 16 bytes. Signed-off-by: Chalapathi V --- include/hw/ssi/pnv_spi.h | 3 + hw/ssi/pnv_spi.c | 237 +++++++++++++-------------------------- 2 files changed, 81 insertions(+), 159 deletions(-) diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h index 8815f67d45..9878d9a25f 100644 --- a/include/hw/ssi/pnv_spi.h +++ b/include/hw/ssi/pnv_spi.h @@ -23,6 +23,7 @@ =20 #include "hw/ssi/ssi.h" #include "hw/sysbus.h" +#include "qemu/fifo8.h" =20 #define TYPE_PNV_SPI "pnv-spi" OBJECT_DECLARE_SIMPLE_TYPE(PnvSpi, PNV_SPI) @@ -37,6 +38,8 @@ typedef struct PnvSpi { SSIBus *ssi_bus; qemu_irq *cs_line; MemoryRegion xscom_spic_regs; + Fifo8 tx_fifo; + Fifo8 rx_fifo; /* SPI object number */ uint32_t spic_num; uint8_t transfer_len; diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index c21b2ebb3c..c2f1c6ca8e 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -19,6 +19,7 @@ =20 #define PNV_SPI_OPCODE_LO_NIBBLE(x) (x & 0x0F) #define PNV_SPI_MASKED_OPCODE(x) (x & 0xF0) +#define PNV_SPI_FIFO_SIZE 16 =20 /* * Macro from include/hw/ppc/fdt.h @@ -35,48 +36,14 @@ } \ } while (0) =20 -/* 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 =3D 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 =3D offset + length; - payload->data =3D 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 =3D GETFIELD(SPI_MM_RDR_MATCH_MASK, - s->regs[SPI_MM_REG]); - uint16_t rdr_match_val =3D GETFIELD(SPI_MM_RDR_MATCH_VAL, - s->regs[SPI_MM_REG]); + uint16_t rdr_match_mask =3D GETFIELD(SPI_MM_RDR_MATCH_MASK, s->regs[SP= I_MM_REG]); + uint16_t rdr_match_val =3D GETFIELD(SPI_MM_RDR_MATCH_VAL, s->regs[SPI_= MM_REG]); =20 if ((~rdr_match_mask & rdr_match_val) =3D=3D ((~rdr_match_mask) & GETFIELD(PPC_BITMASK(48, 63), s->regs[SPI_RCV_DATA_REG]))) { @@ -107,8 +74,8 @@ static uint8_t get_from_offset(PnvSpi *s, uint8_t offset) return byte; } =20 -static uint8_t read_from_frame(PnvSpi *s, uint8_t *read_buf, uint8_t nr_by= tes, - uint8_t ecc_count, uint8_t shift_in_count) +static uint8_t read_from_frame(PnvSpi *s, uint8_t nr_bytes, uint8_t ecc_co= unt, + uint8_t shift_in_count) { uint8_t byte; int count =3D 0; @@ -118,20 +85,23 @@ static uint8_t read_from_frame(PnvSpi *s, uint8_t *rea= d_buf, uint8_t nr_bytes, if ((ecc_count !=3D 0) && (shift_in_count =3D=3D (PNV_SPI_REG_SIZE + ecc_count))) { shift_in_count =3D 0; - } else { - byte =3D read_buf[count]; + } else if (!fifo8_is_empty(&s->rx_fifo)) { + byte =3D fifo8_pop(&s->rx_fifo); trace_pnv_spi_shift_rx(byte, count); s->regs[SPI_RCV_DATA_REG] =3D (s->regs[SPI_RCV_DATA_REG] << 8)= | byte; + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: Reading empty RX_FIFO= \n"); } count++; } /* end of while */ return shift_in_count; } =20 -static void spi_response(PnvSpi *s, int bits, PnvXferBuffer *rsp_payload) +static void spi_response(PnvSpi *s) { uint8_t ecc_count; uint8_t shift_in_count; + uint32_t rx_len; =20 /* * Processing here must handle: @@ -144,13 +114,14 @@ static void spi_response(PnvSpi *s, int bits, PnvXfer= Buffer *rsp_payload) * First check that the response payload is the exact same * number of bytes as the request payload was */ - if (rsp_payload->len !=3D (s->N1_bytes + s->N2_bytes)) { + rx_len =3D fifo8_num_used(&s->rx_fifo); + if (rx_len !=3D (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); + (s->N1_bytes + s->N2_bytes), rx_len); } else { uint8_t ecc_control; - trace_pnv_spi_rx_received(rsp_payload->len); + trace_pnv_spi_rx_received(rx_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); /* @@ -175,15 +146,12 @@ static void spi_response(PnvSpi *s, int bits, PnvXfer= Buffer *rsp_payload) /* Handle the N1 portion of the frame first */ if (s->N1_rx !=3D 0) { trace_pnv_spi_rx_read_N1frame(); - shift_in_count =3D read_from_frame(s, &rsp_payload->data[0], - s->N1_bytes, ecc_count, shift_in_count); + shift_in_count =3D read_from_frame(s, s->N1_bytes, ecc_count, = shift_in_count); } /* Handle the N2 portion of the frame */ if (s->N2_rx !=3D 0) { trace_pnv_spi_rx_read_N2frame(); - shift_in_count =3D read_from_frame(s, - &rsp_payload->data[s->N1_bytes], s->N2_bytes, - ecc_count, shift_in_count); + shift_in_count =3D read_from_frame(s, s->N2_bytes, ecc_count, = shift_in_count); } if ((s->N1_rx + s->N2_rx) > 0) { /* @@ -210,36 +178,38 @@ static void spi_response(PnvSpi *s, int bits, PnvXfer= Buffer *rsp_payload) } /* end of else */ } /* end of spi_response() */ =20 -static void transfer(PnvSpi *s, PnvXferBuffer *payload) +static void transfer(PnvSpi *s) { - uint32_t tx; - uint32_t rx; - PnvXferBuffer *rsp_payload =3D NULL; + uint32_t tx, rx, payload_len; + uint8_t rx_byte; =20 - rsp_payload =3D pnv_spi_xfer_buffer_new(); - if (!rsp_payload) { - return; - } - for (int offset =3D 0; offset < payload->len; offset +=3D s->transfer_= len) { + payload_len =3D fifo8_num_used(&s->tx_fifo); + for (int offset =3D 0; offset < payload_len; offset +=3D s->transfer_l= en) { tx =3D 0; for (int i =3D 0; i < s->transfer_len; i++) { - if ((offset + i) >=3D payload->len) { + if ((offset + i) >=3D payload_len) { tx <<=3D 8; + } else if (!fifo8_is_empty(&s->tx_fifo)) { + tx =3D (tx << 8) | fifo8_pop(&s->tx_fifo); } else { - tx =3D (tx << 8) | payload->data[offset + i]; + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO underflow= \n"); } } rx =3D ssi_transfer(s->ssi_bus, tx); for (int i =3D 0; i < s->transfer_len; i++) { - if ((offset + i) >=3D payload->len) { + if (((offset + i) >=3D payload_len) || fifo8_is_full(&s->rx_fi= fo)) { break; } - *(pnv_spi_xfer_buffer_write_ptr(rsp_payload, rsp_payload->len,= 1)) =3D - (rx >> (8 * (s->transfer_len - 1) - i * 8)) & 0xFF; + rx_byte =3D (rx >> (8 * (s->transfer_len - 1) - i * 8)) & 0xFF; + if (!fifo8_is_full(&s->rx_fifo)) { + fifo8_push(&s->rx_fifo, rx_byte); + } } } - spi_response(s, s->N1_bits, rsp_payload); - pnv_spi_xfer_buffer_free(rsp_payload); + spi_response(s); + /* Reset fifo for next frame */ + fifo8_reset(&s->tx_fifo); + fifo8_reset(&s->rx_fifo); } =20 static inline uint8_t get_seq_index(PnvSpi *s) @@ -310,13 +280,11 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) * 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]) =3D=3D 0) { + if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B2, s->regs[SPI_CTR_CFG_REG])= =3D=3D 0) { s->N1_tx =3D 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]) =3D=3D 1) { + if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B3, s->regs[SPI_CTR_CFG_REG])= =3D=3D 1) { s->N1_rx =3D s->N1_bytes; } } @@ -328,8 +296,7 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) * cap the size at a max of 64 bits or 72 bits and set the sequencer F= SM * error bit. */ - uint8_t ecc_control =3D GETFIELD(SPI_CLK_CFG_ECC_CTRL, - s->regs[SPI_CLK_CFG_REG]); + uint8_t ecc_control =3D GETFIELD(SPI_CLK_CFG_ECC_CTRL, s->regs[SPI_CLK= _CFG_REG]); if (ecc_control =3D=3D 0 || ecc_control =3D=3D 2) { if (s->N1_bytes > (PNV_SPI_REG_SIZE + 1)) { qemu_log_mask(LOG_GUEST_ERROR, "Unsupported N1 shift size when= " @@ -340,8 +307,7 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) } } else if (s->N1_bytes > PNV_SPI_REG_SIZE) { qemu_log_mask(LOG_GUEST_ERROR, "Unsupported N1 shift size, " - "bytes =3D 0x%x, bits =3D 0x%x\n", - s->N1_bytes, s->N1_bits); + "bytes =3D 0x%x, bits =3D 0x%x\n", s->N1_bytes, s->N= 1_bits); s->N1_bytes =3D PNV_SPI_REG_SIZE; s->N1_bits =3D s->N1_bytes * 8; } @@ -350,19 +316,10 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) /* * Shift_N1 operation handler method */ -static bool operation_shiftn1(PnvSpi *s, uint8_t opcode, - PnvXferBuffer **payload, bool send_n1_alone) +static bool operation_shiftn1(PnvSpi *s, uint8_t opcode, bool send_n1_alon= e) { uint8_t n1_count; bool stop =3D false; - - /* - * If there isn't a current payload left over from a stopped sequence - * create a new one. - */ - if (*payload =3D=3D NULL) { - *payload =3D pnv_spi_xfer_buffer_new(); - } /* * Use a combination of N1 counters to build the N1 portion of the * transmit payload. @@ -413,9 +370,10 @@ static bool operation_shiftn1(PnvSpi *s, uint8_t opcod= e, */ uint8_t n1_byte =3D 0x00; n1_byte =3D 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)) =3D - n1_byte; + if (!fifo8_is_full(&s->tx_fifo)) { + trace_pnv_spi_tx_append("n1_byte", n1_byte, n1_count); + fifo8_push(&s->tx_fifo, n1_byte); + } } else { /* * We hit a shift_n1 opcode TX but the TDR is empty, tell = the @@ -436,16 +394,14 @@ static bool operation_shiftn1(PnvSpi *s, uint8_t opco= de, * - we are receiving and the RDR is empty so we allow the ope= ration * to proceed. */ - if ((s->N1_rx !=3D 0) && (GETFIELD(SPI_STS_RDR_FULL, - s->status) =3D=3D 1)) { + if ((s->N1_rx !=3D 0) && (GETFIELD(SPI_STS_RDR_FULL, s->status= ) =3D=3D 1)) { trace_pnv_spi_sequencer_stop_requested("shift N1" "set for receive but RDR is full"); stop =3D true; break; - } else { + } else if (!fifo8_is_full(&s->tx_fifo)) { trace_pnv_spi_tx_append_FF("n1_byte"); - *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len,= 1)) - =3D 0xff; + fifo8_push(&s->tx_fifo, 0xff); } } n1_count++; @@ -486,15 +442,13 @@ static bool operation_shiftn1(PnvSpi *s, uint8_t opco= de, */ 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); + trace_pnv_spi_tx_request("Shifting N1 frame", fifo8_num_used(&s->t= x_fifo)); + transfer(s); /* The N1 frame shift is complete so reset the N1 counters */ s->N2_bits =3D 0; s->N2_bytes =3D 0; s->N2_tx =3D 0; s->N2_rx =3D 0; - pnv_spi_xfer_buffer_free(*payload); - *payload =3D NULL; } return stop; } /* end of operation_shiftn1() */ @@ -552,13 +506,11 @@ static void calculate_N2(PnvSpi *s, uint8_t opcode) * 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]) =3D=3D 0) { + if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B3, s->regs[SPI_CTR_CFG_REG])= =3D=3D 0) { s->N2_rx =3D 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]) =3D=3D 1) { + if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B2, s->regs[SPI_CTR_CFG_REG])= =3D=3D 1) { s->N2_tx =3D s->N2_bytes; } } @@ -571,8 +523,7 @@ static void calculate_N2(PnvSpi *s, uint8_t opcode) * cap the size at a max of 64 bits or 72 bits and set the sequencer F= SM * error bit. */ - uint8_t ecc_control =3D GETFIELD(SPI_CLK_CFG_ECC_CTRL, - s->regs[SPI_CLK_CFG_REG]); + uint8_t ecc_control =3D GETFIELD(SPI_CLK_CFG_ECC_CTRL, s->regs[SPI_CLK= _CFG_REG]); if (ecc_control =3D=3D 0 || ecc_control =3D=3D 2) { if (s->N2_bytes > (PNV_SPI_REG_SIZE + 1)) { /* Unsupported N2 shift size when ECC enabled */ @@ -590,19 +541,10 @@ static void calculate_N2(PnvSpi *s, uint8_t opcode) * Shift_N2 operation handler method */ =20 -static bool operation_shiftn2(PnvSpi *s, uint8_t opcode, - PnvXferBuffer **payload) +static bool operation_shiftn2(PnvSpi *s, uint8_t opcode) { uint8_t n2_count; bool stop =3D false; - - /* - * If there isn't a current payload left over from a stopped sequence - * create a new one. - */ - if (*payload =3D=3D NULL) { - *payload =3D pnv_spi_xfer_buffer_new(); - } /* * Use a combination of N2 counters to build the N2 portion of the * transmit payload. @@ -629,44 +571,41 @@ static bool operation_shiftn2(PnvSpi *s, uint8_t opco= de, * 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 !=3D 0) && - (GETFIELD(SPI_STS_RDR_FULL, s->status) =3D=3D 1)) { + if ((s->N2_rx !=3D 0) && (GETFIELD(SPI_STS_RDR_FULL, s->status) = =3D=3D 1)) { trace_pnv_spi_sequencer_stop_requested("shift N2 set" "for receive but RDR is full"); stop =3D true; break; } - if ((s->N2_tx !=3D 0) && ((s->N1_tx + n2_count) < - PNV_SPI_REG_SIZE)) { + if ((s->N2_tx !=3D 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 =3D 0x00; n2_byte =3D get_from_offset(s, (s->N1_tx + n2_count)); - trace_pnv_spi_tx_append("n2_byte", n2_byte, (s->N1_tx + n2_cou= nt)); - *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1)) - =3D n2_byte; - } else { + if (!fifo8_is_full(&s->tx_fifo)) { + trace_pnv_spi_tx_append("n2_byte", n2_byte, (s->N1_tx + n2= _count)); + fifo8_push(&s->tx_fifo, n2_byte); + } + } else if (!fifo8_is_full(&s->tx_fifo)) { /* * 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 len= gth * of the operation. */ trace_pnv_spi_tx_append_FF("n2_byte"); - *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1)) - =3D 0xff; + fifo8_push(&s->tx_fifo, 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); + trace_pnv_spi_tx_request("Shifting N2 frame", fifo8_num_used(&s->t= x_fifo)); + transfer(s); /* * If we are doing an N2 TX and the TDR is full we need to clear t= he * TDR_full status. Do this here instead of up in the loop above s= o we * don't log the message in every loop iteration. */ - if ((s->N2_tx !=3D 0) && - (GETFIELD(SPI_STS_TDR_FULL, s->status) =3D=3D 1)) { + if ((s->N2_tx !=3D 0) && (GETFIELD(SPI_STS_TDR_FULL, s->status) = =3D=3D 1)) { s->status =3D SETFIELD(SPI_STS_TDR_FULL, s->status, 0); } /* @@ -682,8 +621,6 @@ static bool operation_shiftn2(PnvSpi *s, uint8_t opcode, s->N1_bytes =3D 0; s->N1_tx =3D 0; s->N1_rx =3D 0; - pnv_spi_xfer_buffer_free(*payload); - *payload =3D NULL; } return stop; } /* end of operation_shiftn2()*/ @@ -701,19 +638,6 @@ static void operation_sequencer(PnvSpi *s) uint8_t opcode =3D 0; uint8_t masked_opcode =3D 0; =20 - /* - * PnvXferBuffer for containing the payload of the SPI frame. - * This is a static because there are cases where a sequence has to st= op - * and wait for the target application to unload the RDR. If this occ= urs - * during a sequence where N1 is not sent alone and instead combined w= ith - * N2 since the N1 tx length + the N2 tx length is less than the size = of - * the TDR. - */ - static PnvXferBuffer *payload; - - if (payload =3D=3D NULL) { - payload =3D pnv_spi_xfer_buffer_new(); - } /* * Clear the sequencer FSM error bit - general_SPI_status[3] * before starting a sequence. @@ -775,10 +699,8 @@ static void operation_sequencer(PnvSpi *s) s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM= _DONE); } else if (s->responder_select !=3D 1) { qemu_log_mask(LOG_GUEST_ERROR, "Slave selection other than= 1 " - "not supported, select =3D 0x%x\n", - s->responder_select); - trace_pnv_spi_sequencer_stop_requested("invalid " - "responder select"); + "not supported, select =3D 0x%x\n", s->respo= nder_select); + trace_pnv_spi_sequencer_stop_requested("invalid responder = select"); s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM= _IDLE); stop =3D true; } else { @@ -840,9 +762,8 @@ static void operation_sequencer(PnvSpi *s) =3D=3D SEQ_OP_SHIFT_N2) { send_n1_alone =3D false; } - s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_SHIFT_N1); - stop =3D operation_shiftn1(s, opcode, &payload, send_n1_al= one); + s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM= _SHIFT_N1); + stop =3D operation_shiftn1(s, opcode, send_n1_alone); if (stop) { /* * The operation code says to stop, this can occur if: @@ -858,7 +779,7 @@ static void operation_sequencer(PnvSpi *s) if (GETFIELD(SPI_STS_TDR_UNDERRUN, s->status)) { s->shift_n1_done =3D true; s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->sta= tus, - FSM_SHIFT_N2); + FSM_SHIFT_N2); s->status =3D SETFIELD(SPI_STS_SEQ_INDEX, s->statu= s, (get_seq_index(s) + 1)); } else { @@ -866,8 +787,7 @@ static void operation_sequencer(PnvSpi *s) * This is case (1) or (2) so the sequencer needs = to * wait and NOT go to the next sequence yet. */ - s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->sta= tus, - FSM_WAIT); + s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->sta= tus, FSM_WAIT); } } else { /* Ok to move on to the next index */ @@ -890,21 +810,18 @@ static void operation_sequencer(PnvSpi *s) * error bit 3 (general_SPI_status[3]) in status reg. */ s->status =3D SETFIELD(SPI_STS_GEN_STATUS_B3, s->status, 1= ); - trace_pnv_spi_sequencer_stop_requested("shift_n2 " - "w/no shift_n1 done"); + trace_pnv_spi_sequencer_stop_requested("shift_n2 w/no shif= t_n1 done"); stop =3D true; } else { /* Ok to do a Shift_N2 */ - s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_SHIFT_N2); - stop =3D operation_shiftn2(s, opcode, &payload); + s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM= _SHIFT_N2); + stop =3D operation_shiftn2(s, opcode); /* * If the operation code says to stop set the shifter stat= e to * wait and stop */ if (stop) { - s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_WAIT); + s->status =3D SETFIELD(SPI_STS_SHIFTER_FSM, s->status,= FSM_WAIT); } else { /* Ok to move on to the next index */ next_sequencer_fsm(s); @@ -988,8 +905,7 @@ static void operation_sequencer(PnvSpi *s) case SEQ_OP_BRANCH_IFNEQ_INC_2: s->status =3D SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_E= XECUTE); trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_2", get_seq_index= (s)); - uint8_t condition2 =3D GETFIELD(SPI_CTR_CFG_CMP2, - s->regs[SPI_CTR_CFG_REG]); + uint8_t condition2 =3D GETFIELD(SPI_CTR_CFG_CMP2, s->regs[SPI_= CTR_CFG_REG]); /* * The spec says the loop should execute count compare + 1 tim= es. * However we learned from engineering that we really only loop @@ -1210,6 +1126,9 @@ static void pnv_spi_realize(DeviceState *dev, Error *= *errp) s->cs_line =3D g_new0(qemu_irq, 1); qdev_init_gpio_out_named(DEVICE(s), s->cs_line, "cs", 1); =20 + fifo8_create(&s->tx_fifo, PNV_SPI_FIFO_SIZE); + fifo8_create(&s->rx_fifo, PNV_SPI_FIFO_SIZE); + /* spi scoms */ pnv_xscom_region_init(&s->xscom_spic_regs, OBJECT(s), &pnv_spi_xscom_o= ps, s, "xscom-spi", PNV10_XSCOM_PIB_SPIC_SIZE); --=20 2.39.5