mirror of
https://github.com/linux-msm/hexagonrpc.git
synced 2026-10-07 15:29:50 -07:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92237debf1 | ||
|
|
64bff607fe | ||
|
|
b15e721660 | ||
|
|
eee667b6cc | ||
|
|
13c14c1611 | ||
|
|
916db473b4 | ||
|
|
09add3eecc |
No files matched your search
@@ -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
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,5 +1,4 @@
|
||||
executable('hexagonrpcd',
|
||||
'aee_error.c',
|
||||
'apps_std.c',
|
||||
'interfaces.c',
|
||||
'hexagonfs.c',
|
||||
|
||||
+8
-16
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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,5 +1,6 @@
|
||||
libhexagonrpc = shared_library('hexagonrpc',
|
||||
'context.c',
|
||||
'error.c',
|
||||
'fastrpc.c',
|
||||
'interfaces.c',
|
||||
'session.c',
|
||||
|
||||
Reference in new issue
Block a user