diff --git a/sys-utils/libcmt/include/libcmt/rollup.h b/sys-utils/libcmt/include/libcmt/rollup.h index 1c0d72d4..87eed5cf 100644 --- a/sys-utils/libcmt/include/libcmt/rollup.h +++ b/sys-utils/libcmt/include/libcmt/rollup.h @@ -66,6 +66,16 @@ typedef struct cmt_rollup_finish { uint32_t next_request_payload_length; } cmt_rollup_finish_t; +/** Public struct with generic io request/response */ +typedef struct cmt_gio { + uint16_t domain; /**< domain for the gio request */ + uint32_t id_length; /**< length of id */ + void *id; /**< id for the request */ + uint16_t response_code; /**< response */ + uint32_t response_length; /**< length of response data */ + void *response; /**< response data */ +} cmt_gio_request_t; + /** Initialize a @ref cmt_rollup_t state. * * @param [in] me uninitialized state @@ -186,6 +196,19 @@ int cmt_rollup_read_inspect_state(cmt_rollup_t *me, cmt_rollup_inspect_t *inspec * |< 0| failure with a -errno value | */ int cmt_rollup_finish(cmt_rollup_t *me, cmt_rollup_finish_t *finish); + +/** Performs a generic IO request + * + * @param [in,out] me initialized cmt_rollup_t instance + * @param [in,out] req initialized cmt_gio_t structure + * + * @return + * | | | + * |--:|-----------------------------| + * | 0| success | + * |< 0| failure with a -errno value | */ +int cmt_gio_request(cmt_rollup_t *me, cmt_gio_request_t *req); + /** Retrieve the merkle tree and intermediate state from a file @p path * @param [in,out] me initialized cmt_rollup_t instance * @param [in] file path to file (parent directories must exist) diff --git a/sys-utils/libcmt/src/rollup.c b/sys-utils/libcmt/src/rollup.c index dc4fc9bb..eba4c1a9 100644 --- a/sys-utils/libcmt/src/rollup.c +++ b/sys-utils/libcmt/src/rollup.c @@ -278,6 +278,45 @@ int cmt_rollup_finish(cmt_rollup_t *me, cmt_rollup_finish_t *finish) { return 0; } +int cmt_gio_request(cmt_rollup_t *me, cmt_gio_request_t *req) { + if (!me) + return -EINVAL; + if (!req) + return -EINVAL; + + cmt_buf_t tx[1] = {cmt_io_get_tx(me->io)}; + size_t tx_length = tx->end - tx->begin; + if (req->id_length > tx_length || req->id_length > UINT32_MAX) + return -ENOBUFS; + + if (req->id_length > 0) { + if (!req->id) + return -EINVAL; + memcpy(tx->begin, req->id, req->id_length); + } + + struct cmt_io_yield y[1] = {{ + .dev = HTIF_DEVICE_YIELD, + .cmd = HTIF_YIELD_CMD_MANUAL, + .reason = req->domain, + .data = req->id_length, + }}; + + int rc = DBG(cmt_io_yield(me->io, y)); + if (rc != 0) + return rc; + + cmt_buf_t rx[1] = {cmt_io_get_rx(me->io)}; + size_t rx_length = rx->end - rx->begin; + if (rx_length != y->data) + return -EINVAL; + + req->response = rx->begin; + req->response_code = y->reason; + req->response_length = y->data; + return 0; +} + int cmt_rollup_progress(cmt_rollup_t *me, uint32_t progress) { cmt_io_yield_t req[1] = {{ .dev = HTIF_DEVICE_YIELD,