[Pdbg] [PATCH 05/17] libsbefifo: Refactor protocol marshalling for ring chip-ops
Amitay Isaacs
amitay at ozlabs.org
Thu Oct 31 17:34:16 AEDT 2019
Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
libsbefifo/cmd_ring.c | 163 +++++++++++++++++++++++++++++-----------
libsbefifo/libsbefifo.h | 9 +++
2 files changed, 129 insertions(+), 43 deletions(-)
diff --git a/libsbefifo/cmd_ring.c b/libsbefifo/cmd_ring.c
index 38df734..d62bc13 100644
--- a/libsbefifo/cmd_ring.c
+++ b/libsbefifo/cmd_ring.c
@@ -23,97 +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)
+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);
+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;
+}
+
+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;
+}
+
+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)
+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[3];
- 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(3); // number of words
- msg[1] = htobe32(target_word);
- msg[2] = htobe32(ring_word);
+ msg[0] = htobe32(nwords);
+ msg[1] = htobe32(cmd);
+ msg[2] = htobe32(target_word);
+ msg[3] = htobe32(ring_word);
+
+ *buf = (uint8_t *)msg;
+ return 0;
+}
+
+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;
}
diff --git a/libsbefifo/libsbefifo.h b/libsbefifo/libsbefifo.h
index b13caa6..d17dd71 100644
--- a/libsbefifo/libsbefifo.h
+++ b/libsbefifo/libsbefifo.h
@@ -81,6 +81,15 @@ int sbefifo_scom_put(struct sbefifo_context *sctx, uint64_t addr, uint64_t value
int sbefifo_scom_modify(struct sbefifo_context *sctx, uint64_t addr, uint64_t value, uint8_t operand);
int sbefifo_scom_put_mask(struct sbefifo_context *sctx, uint64_t addr, uint64_t value, uint64_t mask);
+int sbefifo_ring_get_push(uint32_t ring_addr, uint32_t ring_len_bits, uint16_t flags, uint8_t **buf, uint32_t *buflen);
+int sbefifo_ring_get_pull(uint8_t *buf, uint32_t buflen, uint32_t ring_len_bits, uint8_t **ring_data, uint32_t *ring_len);
+
+int sbefifo_ring_put_push(uint16_t ring_mode, uint8_t *ring_data, uint32_t ring_data_len, uint8_t **buf, uint32_t *buflen);
+int sbefifo_ring_put_pull(uint8_t *buf, uint32_t buflen);
+
+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);
+int sbefifo_ring_put_from_image_pull(uint8_t *buf, uint32_t buflen);
+
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);
int sbefifo_ring_put(struct sbefifo_context *sctx, uint16_t ring_mode, uint8_t *ring_data, uint32_t ring_data_len);
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);
--
2.21.0
More information about the Pdbg
mailing list