Author SHA1 Message Date
Richard Acayan 92237debf1 fastrpc: hexagonrpcd: listener: switch to interp3
For a proper transition to version 3 of the method definitions, switch
the reverse tunnel to version 3.
2024-12-30 18:11:00 -05:00
Richard Acayan 64bff607fe fastrpc: hexagonrpcd: use interface-defined inline functions
The inline functions are convenient, but shouldn't be defined in every
source file that uses them. Use the new functions defined in the
interface definitions.
2024-12-30 18:11:00 -05:00
Richard Acayan b15e721660 fastrpc: chrecd: interfaces: convert to interp3
Add the remote method definitions for the CHRE interface according to
the 3rd format version.
2024-12-30 18:11:00 -05:00
Richard Acayan eee667b6cc fastrpc: hexagonrpcd: interfaces: convert to interp3
Add the remote method definitions for interfaces used by HexagonRPCD
according to the 3rd format version.
2024-12-30 18:11:00 -05:00
Richard Acayan 13c14c1611 fastrpc: libhexagonrpc: add error API
When the kernel side of FastRPC fails, the return value is -1 and errno
is set. When the remote side of FastRPC fails, the return value is an
AEE error code. It is not specialized for the reverse tunnel. Add an
error API that can convert the return value to a string-based error.
2024-12-30 18:11:00 -05:00
Richard Acayan 916db473b4 fastrpc: libhexagonrpc: interfaces: remotectl: add interp3 definitions
Add the remote method definitions according to the 3rd format version.
2024-12-30 18:10:44 -05:00
Richard Acayan 09add3eecc fastrpc: libhexagonrpc: add interpretation three of method call format
The method call format as interpreted last time had some limitations.
First, input words could not appear after the input buffers, making it
impossible to represent the apps_std_mkdir method accurately. Second, it
was assumed that the lengths in the primary input buffer represent the
number of bytes. In reality, the lengths represent the number of
elements, which just happened to be octets in the majority of remote
methods found, and the adsp_perf_get_usecs remote method could not be
represented. Update the format for the third time to remove these
limitations.

This format allows the mixing of words and lengths of other buffers in
the primary buffer by using 0 to denote words in an array of arguments.
It also allows a greater size of elements, denoted by any non-zero
value.
2024-10-16 19:43:41 -04:00
18 changed files with 679 additions and 134 deletions

No files matched your search

+14
View File
@@ -27,4 +27,18 @@
HEXAGONRPC_DEFINE_REMOTE_METHOD(0, chre_slpi_start_thread, 0, 0, 0, 0)
HEXAGONRPC_DEFINE_REMOTE_METHOD(1, chre_slpi_wait_on_thread_exit, 0, 0, 0, 0)
HEXAGONRPC_DEFINE_REMOTE_METHOD3_EMPTY(0, chre_slpi3_start_thread)
static inline int chre_slpi3_start_thread(const struct fastrpc_context *ctx)
{
return hexagonrpc(&chre_slpi3_start_thread_def, ctx);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3_EMPTY(1, chre_slpi3_wait_on_thread_exit)
static inline int chre_slpi3_wait_on_thread_exit(const struct fastrpc_context *ctx)
{
return hexagonrpc(&chre_slpi3_wait_on_thread_exit_def, ctx);
}
#endif /* INTERFACE_CHRE_SLPI_DEF */
+10 -10
View File
@@ -20,13 +20,13 @@
*/
#include <errno.h>
#include <libhexagonrpc/error.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "aee_error.h"
#include "interfaces/apps_std.def"
#include "hexagonfs.h"
#include "iobuffer.h"
@@ -408,15 +408,15 @@ static const struct fastrpc_function_impl apps_std_procs[] = {
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
{
.def = &apps_std_fflush_def,
.def = &apps_std3_fflush_def,
.impl = apps_std_fflush,
},
{
.def = &apps_std_fclose_def,
.def = &apps_std3_fclose_def,
.impl = apps_std_fclose,
},
{
.def = &apps_std_fread_def,
.def = &apps_std3_fread_def,
.impl = apps_std_fread,
},
{ .def = NULL, .impl = NULL, },
@@ -424,7 +424,7 @@ static const struct fastrpc_function_impl apps_std_procs[] = {
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
{
.def = &apps_std_fseek_def,
.def = &apps_std3_fseek_def,
.impl = apps_std_fseek,
},
{ .def = NULL, .impl = NULL, },
@@ -437,7 +437,7 @@ static const struct fastrpc_function_impl apps_std_procs[] = {
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
{
.def = &apps_std_fopen_with_env_def,
.def = &apps_std3_fopen_with_env_def,
.impl = apps_std_fopen_with_env,
},
{ .def = NULL, .impl = NULL, },
@@ -447,21 +447,21 @@ static const struct fastrpc_function_impl apps_std_procs[] = {
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
{
.def = &apps_std_opendir_def,
.def = &apps_std3_opendir_def,
.impl = apps_std_opendir,
},
{
.def = &apps_std_closedir_def,
.def = &apps_std3_closedir_def,
.impl = apps_std_closedir,
},
{
.def = &apps_std_readdir_def,
.def = &apps_std3_readdir_def,
.impl = apps_std_readdir,
},
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
{
.def = &apps_std_stat_def,
.def = &apps_std3_stat_def,
.impl = apps_std_stat,
},
};
@@ -26,4 +26,11 @@
HEXAGONRPC_DEFINE_REMOTE_METHOD(0, adsp_default_listener_register, 0, 0, 0, 0)
HEXAGONRPC_DEFINE_REMOTE_METHOD3_EMPTY(0, adsp_default_listener3_register)
static inline int adsp_default_listener3_register(const struct fastrpc_context *ctx)
{
return hexagonrpc(&adsp_default_listener3_register_def, ctx);
}
#endif /* INTERFACE_ADSP_DEFAULT_LISTENER_DEF */
+25
View File
@@ -29,4 +29,29 @@
HEXAGONRPC_DEFINE_REMOTE_METHOD(3, adsp_listener_init2, 0, 0, 0, 0)
HEXAGONRPC_DEFINE_REMOTE_METHOD(4, adsp_listener_next2, 2, 1, 4, 1)
HEXAGONRPC_DEFINE_REMOTE_METHOD3_EMPTY(3, adsp_listener3_init2)
static inline int adsp_listener3_init2(int fd)
{
return hexagonrpc2(&adsp_listener3_init2_def, fd, ADSP_LISTENER_HANDLE);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(4, adsp_listener3_next2, true,
0, 0, 1, HEXAGONRPC_DELIMITER, 0, 0, 0, 0, 1)
static inline int adsp_listener3_next2(int fd,
uint32_t ret_rctx,
uint32_t ret_res,
uint32_t ret_outbufs_len, const void *ret_outbufs,
uint32_t *rctx,
uint32_t *handle,
uint32_t *sc,
uint32_t *inbufs_len,
uint32_t inbufs_size, void *inbufs)
{
return hexagonrpc2(&adsp_listener3_next2_def, fd, ADSP_LISTENER_HANDLE,
ret_rctx, ret_res, ret_outbufs_len, ret_outbufs,
rctx, handle, sc, inbufs_len, inbufs_size, inbufs);
}
#endif /* INTERFACE_ADSP_LISTENER_DEF */
+158
View File
@@ -35,4 +35,162 @@ HEXAGONRPC_DEFINE_REMOTE_METHOD(27, apps_std_closedir, 2, 0, 0, 0)
HEXAGONRPC_DEFINE_REMOTE_METHOD(28, apps_std_readdir, 2, 0, 66, 0)
HEXAGONRPC_DEFINE_REMOTE_METHOD(31, apps_std_stat, 1, 1, 24, 0)
HEXAGONRPC_DEFINE_REMOTE_METHOD3(1, apps_std3_freopen, true,
0, HEXAGONRPC_DELIMITER, 0, 1)
HEXAGONRPC_DEFINE_REMOTE_METHOD3(2, apps_std3_fflush, false,
0, HEXAGONRPC_DELIMITER)
static inline int apps_std3_fflush(struct fastrpc_context *ctx, uint32_t stream)
{
return hexagonrpc(&apps_std3_fflush_def, ctx, stream);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(3, apps_std3_fclose, false,
0, HEXAGONRPC_DELIMITER)
static inline int apps_std3_fclose(struct fastrpc_context *ctx, uint32_t stream)
{
return hexagonrpc(&apps_std3_fclose_def, ctx, stream);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(4, apps_std3_fread, true,
0, HEXAGONRPC_DELIMITER, 0, 0, 1)
static inline int apps_std3_fread(struct fastrpc_context *ctx,
uint32_t stream,
uint32_t *written, uint32_t *is_eof,
uint32_t size, void *buf)
{
return hexagonrpc(&apps_std3_fread_def, ctx,
stream, written, is_eof, size, buf);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(9, apps_std3_fseek, false,
0, 0, 0, HEXAGONRPC_DELIMITER)
static inline int apps_std3_fseek(struct fastrpc_context *ctx,
uint32_t stream, uint32_t pos, uint32_t whence)
{
return hexagonrpc(&apps_std3_fseek_def, ctx, stream, pos, whence);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(19, apps_std3_fopen_with_env, true,
1, 1, 1, 1, HEXAGONRPC_DELIMITER, 0)
static inline int apps_std3_fopen_with_env(struct fastrpc_context *ctx,
uint32_t envvar_len, const char *envvar,
uint32_t delim_len, const char *delim,
uint32_t name_len, const char *name,
uint32_t mode_len, const char *mode)
{
return hexagonrpc(&apps_std3_fopen_with_env_def, ctx,
envvar_len, (const void *) envvar,
delim_len, (const void *) delim,
name_len, (const void *) name,
mode_len, (const void *) mode);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(26, apps_std3_opendir, true,
1, HEXAGONRPC_DELIMITER, 0, 0)
static inline int apps_std3_opendir(struct fastrpc_context *ctx,
uint32_t path_len, const char *path,
uint32_t *handle_lo, uint32_t *handle_hi)
{
return hexagonrpc(&apps_std3_opendir_def, ctx,
path_len, (const void *) path,
handle_lo, handle_hi);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(27, apps_std3_closedir, false,
0, 0, HEXAGONRPC_DELIMITER)
static inline int apps_std3_closedir(struct fastrpc_context *ctx,
uint32_t handle_lo, uint32_t handle_hi)
{
return hexagonrpc(&apps_std3_closedir_def, ctx, handle_lo, handle_hi);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(28, apps_std3_readdir, true,
0, 0, HEXAGONRPC_DELIMITER,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0)
static inline int apps_std3_readdir(struct fastrpc_context *ctx,
uint32_t handle_lo, uint32_t handle_hi,
uint32_t *inode, char *path, uint32_t *eof)
{
uint32_t *buf = (uint32_t *) path;
return hexagonrpc(&apps_std3_readdir_def, ctx,
handle_lo, handle_hi, inode,
&buf[0], &buf[1], &buf[2], &buf[3],
&buf[4], &buf[5], &buf[6], &buf[7],
&buf[8], &buf[9], &buf[10], &buf[11],
&buf[12], &buf[13], &buf[14], &buf[15],
&buf[16], &buf[17], &buf[18], &buf[19],
&buf[20], &buf[21], &buf[22], &buf[23],
&buf[24], &buf[25], &buf[26], &buf[27],
&buf[28], &buf[29], &buf[30], &buf[31],
&buf[32], &buf[33], &buf[34], &buf[35],
&buf[36], &buf[37], &buf[38], &buf[39],
&buf[40], &buf[41], &buf[42], &buf[43],
&buf[44], &buf[45], &buf[46], &buf[47],
&buf[48], &buf[49], &buf[50], &buf[51],
&buf[52], &buf[53], &buf[54], &buf[55],
&buf[56], &buf[57], &buf[58], &buf[57],
&buf[60], &buf[61], &buf[62], &buf[63], eof);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(29, apps_std3_mkdir, false,
1, 0, HEXAGONRPC_DELIMITER)
static inline int apps_std3_mkdir(struct fastrpc_context *ctx,
uint32_t path_size, const char *path,
uint32_t mode)
{
return hexagonrpc(&apps_std3_mkdir_def, ctx,
path_size, (const void *) path, mode);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(31, apps_std3_stat, true,
1, HEXAGONRPC_DELIMITER,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0)
static inline int apps_std3_stat(struct fastrpc_context *ctx,
uint32_t path_size, const char *path,
uint32_t *tsz_lo, uint32_t *tsz_hi,
uint32_t *dev_lo, uint32_t *dev_hi,
uint32_t *ino_lo, uint32_t *ino_hi,
uint32_t *mode, uint32_t *nlink,
uint32_t *rdev_lo, uint32_t *rdev_hi,
uint32_t *size_lo, uint32_t *size_hi,
uint32_t *atime_sec_lo, uint32_t *atime_sec_hi,
uint32_t *atime_nsec_lo, uint32_t *atime_nsec_hi,
uint32_t *mtime_sec_lo, uint32_t *mtime_sec_hi,
uint32_t *mtime_nsec_lo, uint32_t *mtime_nsec_hi,
uint32_t *ctime_sec_lo, uint32_t *ctime_sec_hi,
uint32_t *ctime_nsec_lo, uint32_t *ctime_nsec_hi)
{
return hexagonrpc(&apps_std3_stat_def, ctx,
path_size, (const void *) path,
tsz_lo, tsz_hi,
dev_lo, dev_hi,
ino_lo, ino_hi,
mode, nlink,
rdev_lo, rdev_hi,
size_lo, size_hi,
atime_sec_lo, atime_sec_hi,
atime_nsec_lo, atime_nsec_hi,
mtime_sec_lo, mtime_sec_hi,
mtime_nsec_lo, mtime_nsec_hi,
ctime_sec_lo, ctime_sec_hi,
ctime_nsec_lo, ctime_nsec_hi);
}
#endif /* INTERFACE_APPS_STD_DEF */
+124 -101
View File
@@ -20,119 +20,148 @@
*/
#include <inttypes.h>
#include <libhexagonrpc/error.h>
#include <libhexagonrpc/fastrpc.h>
#include <libhexagonrpc/interfaces/remotectl.def>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include "aee_error.h"
#include "interfaces/adsp_listener.def"
#include "iobuffer.h"
#include "listener.h"
static int adsp_listener_init2(int fd)
static int check_buf_sizes(const struct hrpc_method_def_interp3 *def,
uint8_t n_inbufs, uint8_t n_outbufs,
const struct fastrpc_io_buffer *inbufs)
{
return fastrpc2(&adsp_listener_init2_def, fd, ADSP_LISTENER_HANDLE);
const uint32_t *prim_in = inbufs[0].p;
uint8_t n_def_outbufs;
size_t i, j = 1;
size_t off;
size_t n_prim_in;
if (def->msg_id < 31)
off = 0;
else
off = 1;
for (i = 0; i < def->n_args; i++) {
if (def->args[i] == HEXAGONRPC_DELIMITER)
break;
if (!def->args[i])
continue;
/*
* We can't check the size because the primary input buffer is
* too small, so skip checking and print an error later.
*/
if ((off + i) * sizeof(uint32_t) >= inbufs[0].s)
continue;
if (j >= n_inbufs) {
fprintf(stderr, "listener: not enough input buffers\n");
return 1;
}
if ((size_t) prim_in[off + i] * def->args[i] > inbufs[j].s) {
fprintf(stderr, "listener: input buffer too small\n");
return 1;
}
j++;
}
n_prim_in = i;
if (def->args[i] == HEXAGONRPC_DELIMITER)
i++;
if (def->has_prim_out)
n_def_outbufs = 1;
else
n_def_outbufs = 0;
for (; i < def->n_args; i++) {
if (def->args[i]) {
n_def_outbufs++;
n_prim_in++;
}
}
if (n_def_outbufs != n_outbufs) {
fprintf(stderr, "listener: wrong amount of output buffers\n");
return 1;
}
if ((off + n_prim_in) * sizeof(uint32_t) > inbufs[0].s) {
fprintf(stderr, "listener: primary input buffer too small\n");
return 1;
}
return 0;
}
static int adsp_listener_next2(int fd,
uint32_t ret_rctx,
uint32_t ret_res,
uint32_t ret_outbuf_len, void *ret_outbuf,
uint32_t *rctx,
uint32_t *handle,
uint32_t *sc,
uint32_t *inbufs_len,
uint32_t inbufs_size, void *inbufs)
{
return fastrpc2(&adsp_listener_next2_def, fd, ADSP_LISTENER_HANDLE,
ret_rctx,
ret_res,
ret_outbuf_len, ret_outbuf,
rctx,
handle,
sc,
inbufs_len,
inbufs_size, inbufs);
}
static struct fastrpc_io_buffer *allocate_outbufs(const struct fastrpc_function_def_interp2 *def,
uint32_t *first_inbuf)
static struct fastrpc_io_buffer *allocate_outbufs(const struct hrpc_method_def_interp3 *def,
const uint32_t *prim_in)
{
struct fastrpc_io_buffer *out;
size_t out_count;
size_t i, j;
off_t off;
uint32_t *sizes;
// This is only used when there is a delimiter.
const uint32_t *size = NULL;
size_t n_outbufs, n_prim_out = 0;
size_t i;
out_count = def->out_bufs + (def->out_nums && 1);
/*
* POSIX allows malloc to return a non-NULL pointer to a zero-size area
* in memory. Since the code below assumes non-zero size if the pointer
* is non-NULL, exit early if we do not need to allocate anything.
*/
if (out_count == 0)
return NULL;
out = malloc(sizeof(struct fastrpc_io_buffer) * out_count);
out = malloc(sizeof(struct fastrpc_io_buffer) * def->n_args);
if (out == NULL)
return NULL;
out[0].s = def->out_nums * 4;
if (out[0].s) {
out[0].p = malloc(def->out_nums * 4);
if (out[0].p == NULL)
goto err_free_out;
if (def->has_prim_out)
n_outbufs = 1;
else
n_outbufs = 0;
for (i = 0; i < def->n_args; i++) {
if (def->args[i] == HEXAGONRPC_DELIMITER) {
size = &prim_in[i];
i++;
break;
}
}
off = def->out_nums && 1;
sizes = &first_inbuf[def->in_nums + def->in_bufs];
for (; i < def->n_args; i++) {
if (def->args[i]) {
out[n_outbufs].s = (size_t) def->args[i] * *size;
out[n_outbufs].p = malloc(out[n_outbufs].s);
if (out[n_outbufs].p == NULL && out[n_outbufs].s)
goto err_free_outbufs;
for (i = 0; i < def->out_bufs; i++) {
out[off + i].s = sizes[i];
out[off + i].p = malloc(sizes[i]);
if (out[off + i].p == NULL)
goto err_free_prev;
n_outbufs++;
size = &size[1];
} else {
n_prim_out++;
}
}
if (def->has_prim_out) {
out[0].s = sizeof(uint32_t) * n_prim_out;
out[0].p = malloc(out[0].s);
if (out[0].p == NULL && out[0].s)
goto err_free_outbufs;
}
return out;
err_free_prev:
for (j = 0; j < i; j++)
free(out[off + j].p);
err_free_outbufs:
if (!def->has_prim_out)
free(out[0].p);
for (i = 1; i < n_outbufs; i++)
free(out[i].p);
err_free_out:
free(out);
return NULL;
}
static int check_inbuf_sizes(const struct fastrpc_function_def_interp2 *def,
const struct fastrpc_io_buffer *inbufs)
{
uint8_t i;
const uint32_t *sizes = &((const uint32_t *) inbufs[0].p)[def->in_nums];
if (inbufs[0].s != 4 * (def->in_nums
+ def->in_bufs
+ def->out_bufs)) {
fprintf(stderr, "Invalid number of input numbers: %" PRIu32 " (expected %u)\n",
inbufs[0].s,
4 * (def->in_nums
+ def->in_bufs
+ def->out_bufs));
return -1;
}
for (i = 0; i < def->in_bufs; i++) {
if (inbufs[i + 1].s != sizes[i]) {
fprintf(stderr, "Invalid buffer size\n");
return -1;
}
}
return 0;
}
static int return_for_next_invoke(int fd,
uint32_t result,
uint32_t *rctx,
@@ -160,7 +189,7 @@ static int return_for_next_invoke(int fd,
outbufs_encode(REMOTE_SCALARS_OUTBUFS(*sc), returned, outbufs);
}
ret = adsp_listener_next2(fd,
ret = adsp_listener3_next2(fd,
*rctx, result,
outbufs_len, outbufs,
rctx, handle, sc,
@@ -215,11 +244,16 @@ static int invoke_requested_procedure(size_t n_ifaces,
struct fastrpc_io_buffer **returned)
{
const struct fastrpc_function_impl *impl;
uint8_t in_count;
uint8_t out_count;
uint32_t method = REMOTE_SCALARS_METHOD(sc);
int ret;
if (method < 31)
method = REMOTE_SCALARS_METHOD(sc);
else if (decoded[0].s >= sizeof(uint32_t))
method = *(const uint32_t *) decoded[0].p;
else
method = UINT32_MAX;
if (sc & 0xff) {
fprintf(stderr, "Handles are not supported, but got %u in, %u out\n",
(sc & 0xf0) >> 4, sc & 0xf);
@@ -247,26 +281,15 @@ static int invoke_requested_procedure(size_t n_ifaces,
return 1;
}
in_count = impl->def->in_bufs + ((impl->def->in_nums
|| impl->def->in_bufs
|| impl->def->out_bufs) && 1);
out_count = impl->def->out_bufs + (impl->def->out_nums && 1);
if (REMOTE_SCALARS_INBUFS(sc) != in_count
|| REMOTE_SCALARS_OUTBUFS(sc) != out_count) {
fprintf(stderr, "Unexpected buffer count: %08x\n", sc);
*result = AEE_EBADPARM;
return 1;
}
ret = check_inbuf_sizes(impl->def, decoded);
ret = check_buf_sizes(impl->def, REMOTE_SCALARS_INBUFS(sc),
REMOTE_SCALARS_OUTBUFS(sc), decoded);
if (ret) {
*result = AEE_EBADPARM;
return 1;
}
*returned = allocate_outbufs(impl->def, decoded[0].p);
if (*returned == NULL && out_count > 0) {
if (*returned == NULL && impl->def->n_args > 0) {
perror("Could not allocate output buffers");
*result = AEE_ENOMEMORY;
return 1;
@@ -290,7 +313,7 @@ int run_fastrpc_listener(int fd,
uint32_t n_outbufs = 0;
int ret;
ret = adsp_listener_init2(fd);
ret = adsp_listener3_init2(fd);
if (ret) {
fprintf(stderr, "Could not initialize the listener: %u\n", ret);
return ret;
+1 -1
View File
@@ -29,7 +29,7 @@
#include "iobuffer.h"
struct fastrpc_function_impl {
const struct fastrpc_function_def_interp2 *def;
const struct hrpc_method_def_interp3 *def;
uint32_t (*impl)(void *data,
const struct fastrpc_io_buffer *inbufs,
struct fastrpc_io_buffer *outbufs);
+9 -3
View File
@@ -19,13 +19,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <libhexagonrpc/error.h>
#include <libhexagonrpc/interfaces/remotectl.def>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aee_error.h"
#include "iobuffer.h"
#include "listener.h"
#include "localctl.h"
@@ -145,8 +145,14 @@ void fastrpc_localctl_deinit(struct fastrpc_interface *iface)
}
static const struct fastrpc_function_impl localctl_procs[] = {
{ .def = &remotectl_open_def, .impl = localctl_open, },
{ .def = &remotectl_close_def, .impl = localctl_close, },
{
.def = &remotectl3_open_def,
.impl = localctl_open,
},
{
.def = &remotectl3_close_def,
.impl = localctl_close,
},
};
const struct fastrpc_interface localctl_interface = {
-1
View File
@@ -1,5 +1,4 @@
executable('hexagonrpcd',
'aee_error.c',
'apps_std.c',
'interfaces.c',
'hexagonfs.c',
+8 -16
View File
@@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
#include <libhexagonrpc/error.h>
#include <libhexagonrpc/fastrpc.h>
#include <libhexagonrpc/interfaces/remotectl.def>
#include <misc/fastrpc.h>
@@ -32,7 +33,6 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include "aee_error.h"
#include "apps_std.h"
#include "hexagonfs.h"
#include "interfaces/adsp_default_listener.def"
@@ -53,17 +53,14 @@ static int remotectl_open(int fd, char *name, struct fastrpc_context **ctx, void
&dlret,
256, err);
if (ret == -1) {
err_cb(strerror(errno));
if (ret) {
err_cb(hexagonrpc_strerror(errno));
return ret;
}
if (dlret == -5) {
if (dlret) {
err_cb(err);
return dlret;
} else if (dlret) {
err_cb(aee_strerror[dlret]);
return dlret;
}
*ctx = fastrpc_create_context(fd, handle);
@@ -82,13 +79,13 @@ static int remotectl_close(struct fastrpc_context *ctx, void (*err_cb)(const cha
&dlret,
256, err);
if (ret == -1) {
err_cb(strerror(errno));
if (ret) {
err_cb(hexagonrpc_strerror(errno));
return ret;
}
if (dlret) {
err_cb(aee_strerror[dlret]);
err_cb(err);
return dlret;
}
@@ -97,11 +94,6 @@ static int remotectl_close(struct fastrpc_context *ctx, void (*err_cb)(const cha
return ret;
}
static int adsp_default_listener_register(struct fastrpc_context *ctx)
{
return fastrpc(&adsp_default_listener_register_def, ctx);
}
static void remotectl_err(const char *err)
{
fprintf(stderr, "Could not remotectl: %s\n", err);
@@ -116,7 +108,7 @@ static int register_fastrpc_listener(int fd)
if (ret)
return 1;
ret = adsp_default_listener_register(ctx);
ret = adsp_default_listener3_register(ctx);
if (ret) {
fprintf(stderr, "Could not register ADSP default listener\n");
goto err;
@@ -2,6 +2,7 @@
* Imported FastRPC error numbers
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, The Sensor Shell Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -83,6 +84,6 @@
#define AEE_ECPUEXCEPTION 48
#define AEE_EREADONLY 49
extern const char *aee_strerror[];
const char *hexagonrpc_strerror(int ret);
#endif
+20
View File
@@ -23,6 +23,7 @@
#define FASTRPC_H
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -41,6 +42,8 @@
#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0xff)
#define REMOTE_SCALARS_OUTBUFS(sc) (((sc) >> 8) & 0xff)
#define HEXAGONRPC_DELIMITER 0xFFFFFFFF
struct fastrpc_context {
int fd;
uint32_t handle;
@@ -54,6 +57,13 @@ struct fastrpc_function_def_interp2 {
uint8_t out_bufs;
};
struct hrpc_method_def_interp3 {
uint32_t msg_id;
bool has_prim_out;
size_t n_args;
const uint32_t *args;
};
struct fastrpc_context *fastrpc_create_context(int fd, uint32_t handle);
static inline void fastrpc_destroy_context(struct fastrpc_context *ctx)
@@ -70,4 +80,14 @@ int fastrpc2(const struct fastrpc_function_def_interp2 *def,
int fastrpc(const struct fastrpc_function_def_interp2 *def,
const struct fastrpc_context *ctx, ...);
int vhexagonrpc2(const struct hrpc_method_def_interp3 *def,
int fd, uint32_t handle, va_list list);
int vhexagonrpc(const struct hrpc_method_def_interp3 *def,
const struct fastrpc_context *ctx, va_list list);
int hexagonrpc2(const struct hrpc_method_def_interp3 *def,
int fd, uint32_t handle, ...);
int hexagonrpc(const struct hrpc_method_def_interp3 *def,
const struct fastrpc_context *ctx, ...);
#endif
+23
View File
@@ -36,6 +36,12 @@
outnums, outbufs) \
extern const struct fastrpc_function_def_interp2 name##_def;
#define HEXAGONRPC_DEFINE_REMOTE_METHOD3_EMPTY(mid, name) \
extern const struct hrpc_method_def_interp3 name##_def;
#define HEXAGONRPC_DEFINE_REMOTE_METHOD3(mid, name, has_oprim, ...) \
HEXAGONRPC_DEFINE_REMOTE_METHOD3_EMPTY(mid, name)
#else /* HEXAGONRPC_BUILD_METHOD_DEFINITIONS */
#define HEXAGONRPC_DEFINE_REMOTE_METHOD(mid, name, \
@@ -49,6 +55,23 @@
.out_bufs = outbufs, \
};
#define HEXAGONRPC_DEFINE_REMOTE_METHOD3_EMPTY(mid, name) \
const struct hrpc_method_def_interp3 name##_def = { \
.msg_id = mid, \
.has_prim_out = false, \
.n_args = 0, \
.args = NULL, \
};
#define HEXAGONRPC_DEFINE_REMOTE_METHOD3(mid, name, has_oprim, ...) \
static const uint32_t name##_args[] = { __VA_ARGS__ }; \
const struct hrpc_method_def_interp3 name##_def = { \
.msg_id = mid, \
.has_prim_out = has_oprim, \
.n_args = sizeof(name##_args) / sizeof(*name##_args), \
.args = name##_args, \
};
#endif /* HEXAGONRPC_BUILD_METHOD_DEFINITIONS */
#endif /* LIBHEXAGONRPC_INTERFACE_H */
@@ -29,4 +29,30 @@
HEXAGONRPC_DEFINE_REMOTE_METHOD(0, remotectl_open, 0, 1, 2, 1)
HEXAGONRPC_DEFINE_REMOTE_METHOD(1, remotectl_close, 1, 0, 1, 1)
HEXAGONRPC_DEFINE_REMOTE_METHOD3(0, remotectl3_open, true,
1, HEXAGONRPC_DELIMITER, 0, 1, 0)
static inline int remotectl3_open(int fd,
uint32_t n_str, const char *str,
uint32_t *handle,
uint32_t err_len, char *err,
uint32_t *dlerr)
{
return hexagonrpc2(&remotectl3_open_def, fd, REMOTECTL_HANDLE,
n_str, (const void *) str,
handle, err_len, (void *) err, dlerr);
}
HEXAGONRPC_DEFINE_REMOTE_METHOD3(0, remotectl3_close, true,
0, HEXAGONRPC_DELIMITER, 1, 0)
static inline int remotectl3_close(int fd,
uint32_t handle,
uint32_t err_len, char *err,
uint32_t *dlerr)
{
return hexagonrpc2(&remotectl3_close_def, fd, REMOTECTL_HANDLE,
handle, err_len, (void *) err, dlerr);
}
#endif /* INTERFACE_REMOTECTL_DEF */
+18
View File
@@ -54,3 +54,21 @@ int fastrpc(const struct fastrpc_function_def_interp2 *def,
return ret;
}
int vhexagonrpc(const struct hrpc_method_def_interp3 *def,
const struct fastrpc_context *ctx, va_list arg_list)
{
return vhexagonrpc2(def, ctx->fd, ctx->handle, arg_list);
}
int hexagonrpc(const struct hrpc_method_def_interp3 *def,
const struct fastrpc_context *ctx, ...)
{
va_list arg_list;
int ret;
va_start(arg_list, ctx);
ret = vhexagonrpc(def, ctx, arg_list);
va_end(arg_list);
return ret;
}
@@ -2,6 +2,7 @@
* Imported FastRPC error messages
*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, The Sensor Shell Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,7 +30,10 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
const char *aee_strerror[] = {
#include <errno.h>
#include <string.h>
static const char *err_tab[] = {
"No error",
"General failure",
"Insufficient RAM",
@@ -81,3 +85,13 @@ const char *aee_strerror[] = {
"A CPU exception occurred",
"Cannot change read-only object or parameter",
};
const char *hexagonrpc_strerror(int ret)
{
if (ret == -1)
return strerror(errno);
else if (ret >= 0 && (unsigned int) ret < sizeof(err_tab) / sizeof(*err_tab))
return err_tab[ret];
return "Unknown error";
}
+218
View File
@@ -250,3 +250,221 @@ int fastrpc2(const struct fastrpc_function_def_interp2 *def,
return ret;
}
/*
* This populates relevant arguments with information necessary to receive
* output from the remote processor.
*
* First, it allocates a new first output buffer to contain the returned 32-bit
* integers. This output buffer must be freed after use.
*
* With a peek at the output arguments, it populates the fastrpc_invoke_args
* struct to give information about the provided buffers to the kernel, and
* adds an entry to the first input buffer to tell the remote processor the
* size of the function-level output buffer.
*/
static void prepare_outbufs3(const struct hrpc_method_def_interp3 *def,
struct fastrpc_invoke_args *args,
size_t delim,
uint32_t *n_prim_in, uint8_t *n_outbufs,
uint32_t *prim,
va_list peek)
{
uint32_t n_prim_out = 0;
size_t i;
if (def->has_prim_out)
*n_outbufs = 1;
else
*n_outbufs = 0;
for (i = delim; i < def->n_args; i++) {
if (def->args[i]) {
prim[*n_prim_in] = va_arg(peek, uint32_t);
args[*n_outbufs].length = prim[*n_prim_in] * def->args[i];
args[*n_outbufs].ptr = (__u64) va_arg(peek, void *);
args[*n_outbufs].fd = -1;
(*n_prim_in)++;
(*n_outbufs)++;
} else {
va_arg(peek, uint32_t *);
n_prim_out++;
}
}
if (def->has_prim_out) {
args[0].length = sizeof(uint32_t) * n_prim_out;
args[0].ptr = (__u64) &prim[*n_prim_in];
args[0].fd = -1;
}
}
static void return_prim_out(const struct hrpc_method_def_interp3 *def,
size_t delim,
const uint32_t *prim_out,
va_list list)
{
uint32_t *ptr;
size_t i, j = 0;
for (i = delim; i < def->n_args; i++) {
if (def->args[i]) {
va_arg(list, uint32_t);
va_arg(list, void *);
} else {
ptr = va_arg(list, uint32_t *);
*ptr = prim_out[j];
j++;
}
}
}
/*
* This is the main function to invoke a FastRPC procedure call. The first
* parameter specifies how to populate the ioctl-level buffers. The second and
* third parameters specify where to send the invocation to. The fourth is the
* list of arguments that the procedure call should interact with.
*
* A good example for this would be the adsp_listener_next2 call:
*
* static inline void adsp_listener_next2(int fd, uint32_t handle,
* uint32_t prev_ctx,
* uint32_t prev_result,
* uint32_t nested_outbufs_len,
* void *nested_outbufs,
* uint32_t *ctx,
* uint32_t *nested_handle,
* uint32_t *nested_sc,
* uint32_t *nested_inbufs_len,
* uint32_t nested_inbufs_size,
* void *nested_inbufs)
* {
* uint32_t args[] = { 0, 0, 1, HEXAGONRPC_DELIMITER, 0, 0, 0, 1 };
* struct hrpc_method_def_interp3 def = {
* .mid = 4,
* .has_out_prim = true,
* .n_args = 8,
* .args = args,
* };
* return vhexagonrpc2(def, fd, handle,
* prev_ctx,
* prev_result,
* nested_outbufs_len,
* nested_outbufs,
* ctx,
* nested_handle,
* nested_sc,
* nested_inbufs_len,
* nested_inbufs_size,
* nested_inbufs);
* }
*/
int vhexagonrpc2(const struct hrpc_method_def_interp3 *def,
int fd, uint32_t handle, va_list list)
{
va_list peek;
struct fastrpc_invoke invoke;
struct fastrpc_invoke_args *args;
uint32_t *prim;
uint32_t n_prim_in = 0;
uint32_t msg_id;
uint8_t n_inbufs = 1, n_outbufs;
size_t i;
int ret = -1;
/*
* If there are only input buffers specified in the method definition,
* we need an extra primary input argument for their sizes.
*/
args = malloc(sizeof(struct fastrpc_invoke_args) * (def->n_args + 1));
if (args == NULL)
return -1;
/*
* The input and output buffers need a size in the primary input buffer
* so all arguments except the optional delimiter contribute to the
* primary buffers.
*/
prim = malloc(sizeof(uint32_t) * (def->n_args + 1));
if (prim == NULL)
goto err_free_args;
/*
* The apps_std interface demonstrates that there is support
* for more than 32 methods for a single interface. Support
* extended method IDs that go beyond 5 bits and the ID
* reserved for this purpose.
*/
if (def->msg_id >= 31) {
prim[n_prim_in] = def->msg_id;
n_prim_in++;
msg_id = 31;
} else {
msg_id = def->msg_id;
}
for (i = 0; i < def->n_args; i++) {
if (def->args[i] == HEXAGONRPC_DELIMITER) {
i++;
break;
}
prim[n_prim_in] = va_arg(list, uint32_t);
if (def->args[i]) {
args[n_inbufs].length = prim[n_prim_in] * def->args[i];
args[n_inbufs].ptr = (__u64) va_arg(list, const void *);
args[n_inbufs].fd = -1;
n_inbufs++;
}
n_prim_in++;
}
va_copy(peek, list);
prepare_outbufs3(def, &args[n_inbufs], i, &n_prim_in, &n_outbufs, prim, peek);
va_end(peek);
args[0].length = sizeof(uint32_t) * n_prim_in;
args[0].ptr = (__u64) prim;
args[0].fd = -1;
// Pass the primary input buffer if not empty, otherwise skip it.
if (n_prim_in != 0) {
invoke.args = (__u64) args;
} else {
invoke.args = (__u64) &args[1];
n_inbufs--;
}
invoke.handle = handle;
invoke.sc = REMOTE_SCALARS_MAKE(msg_id, n_inbufs, n_outbufs);
ret = ioctl(fd, FASTRPC_IOCTL_INVOKE, (__u64) &invoke);
if (ret == -1)
goto err_free_prim;
return_prim_out(def, i, &prim[n_prim_in], list);
err_free_prim:
free(prim);
err_free_args:
free(args);
return ret;
}
int hexagonrpc2(const struct hrpc_method_def_interp3 *def,
int fd, uint32_t handle, ...)
{
va_list list;
int ret;
va_start(list, handle);
ret = vhexagonrpc2(def, fd, handle, list);
va_end(list);
return ret;
}
+1
View File
@@ -1,5 +1,6 @@
libhexagonrpc = shared_library('hexagonrpc',
'context.c',
'error.c',
'fastrpc.c',
'interfaces.c',
'session.c',