[Pdbg] [PATCH v2 08/24] libsbefifo: Refactor protocol marshalling for ring chip-ops

Amitay Isaacs amitay at ozlabs.org
Thu Nov 7 13:27:52 AEDT 2019


Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
 libsbefifo/cmd_ring.c | 158 +++++++++++++++++++++++++++++++-----------
 1 file changed, 117 insertions(+), 41 deletions(-)

diff --git a/libsbefifo/cmd_ring.c b/libsbefifo/cmd_ring.c
index 7d239b5..c1c0ec2 100644
--- a/libsbefifo/cmd_ring.c
+++ b/libsbefifo/cmd_ring.c
@@ -23,98 +23,174 @@
 #include "libsbefifo.h"
 #include "sbefifo_private.h"
 
-int sbefifo_ring_get(struct sbefifo_context *sctx, uint32_t ring_addr, uint32_t ring_len_bits, uint16_t flags, uint8_t **ring_data, uint32_t *ring_len)
+static int sbefifo_ring_get_push(uint32_t ring_addr, uint32_t ring_len_bits, uint16_t flags, uint8_t **buf, uint32_t *buflen)
 {
-	uint8_t *out;
-	uint32_t msg[5];
-	uint32_t cmd, out_len;
-	int rc;
+	uint32_t *msg;
+	uint32_t nwords, cmd;
+
+	nwords = 5;
+	*buflen = nwords * sizeof(uint32_t);
+	msg = malloc(*buflen);
+	if (!msg)
+		return ENOMEM;
 
 	cmd = SBEFIFO_CMD_CLASS_RING | SBEFIFO_CMD_GET_RING;
 
-	msg[0] = htobe32(5);	// number of words
+	msg[0] = htobe32(nwords);
 	msg[1] = htobe32(cmd);
 	msg[2] = htobe32(ring_addr);
 	msg[3] = htobe32(ring_len_bits);
 	msg[4] = htobe32(flags);
 
-	/* multiples of 64 bits */
-	out_len = (ring_len_bits + 63) / 8;
-	rc = sbefifo_operation(sctx, (uint8_t *)msg, 5 * 4, &out, &out_len);
-	if (rc)
-		return rc;
+	*buf = (uint8_t *)msg;
+	return 0;
+}
 
-	if (out_len*8 < ring_len_bits) {
-		free(out);
+static int sbefifo_ring_get_pull(uint8_t *buf, uint32_t buflen, uint32_t ring_len_bits, uint8_t **ring_data, uint32_t *ring_len)
+{
+	if (buflen*8 < ring_len_bits) {
 		return EPROTO;
 	}
 
-	*ring_len = be32toh(*(uint32_t *) &out[out_len-4]);
+	*ring_len = be32toh(*(uint32_t *) &buf[buflen-4]);
 	*ring_data = malloc(*ring_len);
-	if (! *ring_data) {
-		free(out);
+	if (! *ring_data)
 		return ENOMEM;
-	}
-	memcpy(*ring_data, out, *ring_len);
 
-	free(out);
+	memcpy(*ring_data, buf, *ring_len);
 	return 0;
 }
 
-int sbefifo_ring_put(struct sbefifo_context *sctx, uint16_t ring_mode, uint8_t *ring_data, uint32_t ring_data_len)
+int sbefifo_ring_get(struct sbefifo_context *sctx, uint32_t ring_addr, uint32_t ring_len_bits, uint16_t flags, uint8_t **ring_data, uint32_t *ring_len)
 {
-	uint8_t *out;
-	uint32_t nwords = (ring_data_len + 3) / 4;
-	uint32_t msg[3+nwords];
-	uint32_t cmd, out_len;
+	uint8_t *msg, *out;
+	uint32_t msg_len, out_len;
 	int rc;
 
+	rc = sbefifo_ring_get_push(ring_addr, ring_len_bits, flags, &msg, &msg_len);
+	if (rc)
+		return rc;
+
+	/* multiples of 64 bits */
+	out_len = (ring_len_bits + 63) / 8;
+	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	free(msg);
+	if (rc)
+		return rc;
+
+	rc = sbefifo_ring_get_pull(out, out_len, ring_len_bits, ring_data, ring_len);
+	if (out)
+		free(out);
+
+	return rc;
+}
+
+static int sbefifo_ring_put_push(uint16_t ring_mode, uint8_t *ring_data, uint32_t ring_data_len, uint8_t **buf, uint32_t *buflen)
+{
+	uint32_t *msg;
+	uint32_t nwords, cmd;
+
+	nwords = 3 + (ring_data_len + 3) / 4;
+	*buflen = nwords * sizeof(uint32_t);
+	msg = malloc(*buflen);
+	if (!msg)
+		return ENOMEM;
+
 	cmd = SBEFIFO_CMD_CLASS_RING | SBEFIFO_CMD_PUT_RING;
 
-	msg[0] = htobe32(3 + nwords); // number of words
+	msg[0] = htobe32(nwords);
 	msg[1] = htobe32(cmd);
 	msg[2] = htobe32(ring_mode);
 	memcpy(&msg[3], ring_data, ring_data_len);
 
+	*buf = (uint8_t *)msg;
+	return 0;
+}
+
+static int sbefifo_ring_put_pull(uint8_t *buf, uint32_t buflen)
+{
+	if (buflen != 0)
+		return EPROTO;
+
+	return 0;
+}
+
+int sbefifo_ring_put(struct sbefifo_context *sctx, uint16_t ring_mode, uint8_t *ring_data, uint32_t ring_data_len)
+{
+	uint8_t *msg, *out;
+	uint32_t msg_len, out_len;
+	int rc;
+
+	rc = sbefifo_ring_put_push(ring_mode, ring_data, ring_data_len, &msg, &msg_len);
+	if (rc)
+		return rc;
+
 	out_len = 0;
-	rc = sbefifo_operation(sctx, (uint8_t *)msg, (3+nwords) * 4, &out, &out_len);
+	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	free(msg);
 	if (rc)
 		return rc;
 
-	if (out_len != 0) {
+	rc = sbefifo_ring_put_pull(out, out_len);
+	if (out)
 		free(out);
-		return EPROTO;
-	}
 
-	return 0;
+	return rc;
 }
 
-int sbefifo_ring_put_from_image(struct sbefifo_context *sctx, uint16_t target, uint8_t chiplet_id, uint16_t ring_id, uint16_t ring_mode)
+static int sbefifo_ring_put_from_image_push(uint16_t target, uint8_t chiplet_id, uint16_t ring_id, uint16_t ring_mode, uint8_t **buf, uint32_t *buflen)
 {
-	uint8_t *out;
-	uint32_t msg[4];
-	uint32_t cmd, out_len;
+	uint32_t *msg;
+	uint32_t nwords, cmd;
 	uint32_t target_word, ring_word;
-	int rc;
+
+	nwords = 4;
+	*buflen = nwords * sizeof(uint32_t);
+	msg = malloc(*buflen);
+	if (!msg)
+		return ENOMEM;
 
 	cmd = SBEFIFO_CMD_CLASS_RING | SBEFIFO_CMD_PUT_RING_IMAGE;
+
 	target_word = ((uint32_t)target << 16) | (uint32_t)chiplet_id;
 	ring_word = ((uint32_t)ring_id << 16) | (uint32_t)ring_mode;
 
-	msg[0] = htobe32(4);	// number of words
+	msg[0] = htobe32(nwords);
 	msg[1] = htobe32(cmd);
 	msg[2] = htobe32(target_word);
 	msg[3] = htobe32(ring_word);
 
+	*buf = (uint8_t *)msg;
+	return 0;
+}
+
+static int sbefifo_ring_put_from_image_pull(uint8_t *buf, uint32_t buflen)
+{
+	if (buflen != 0)
+		return EPROTO;
+
+	return 0;
+}
+
+int sbefifo_ring_put_from_image(struct sbefifo_context *sctx, uint16_t target, uint8_t chiplet_id, uint16_t ring_id, uint16_t ring_mode)
+{
+	uint8_t *msg, *out;
+	uint32_t msg_len, out_len;
+	int rc;
+
+	rc = sbefifo_ring_put_from_image_push(target, chiplet_id, ring_id, ring_mode, &msg, &msg_len);
+	if (rc)
+		return rc;
+
 	out_len = 0;
-	rc = sbefifo_operation(sctx, (uint8_t *)msg, 3 * 4, &out, &out_len);
+	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	free(out);
 	if (rc)
 		return rc;
 
-	if (out_len != 0) {
+	rc = sbefifo_ring_put_from_image_pull(out, out_len);
+	if (out)
 		free(out);
-		return EPROTO;
-	}
 
-	return 0;
+	return rc;
 }
-- 
2.21.0



More information about the Pdbg mailing list