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
Alex 2415d5f90d Add soversion to the library build 2024-10-16 17:53:03 -04:00
Richard Acayan 7aab0f2c42 meson.options: disable verbose logging by default
Verbose logging can be useful when something goes wrong, but HexagonRPCD
already works well on some devices. Disable verbose logging by default.

Reported by Adrian on the SDM845 Mainline Matrix channel.

Fixes: 30fa49eb20 ("build: add hexagonrpcd_verbose option")
2024-05-16 16:00:13 -04:00
Joel Selvaraj b7eff23db1 hexagonrpcd/rpcd_builder: introduce /system/vendor mapping
Needed for some Xiaomi phones such as the Poco F1.
Based on https://gitlab.com/sdm670-mainline/hexagonrpc/-/merge_requests/1.
Thanks to the initial work of @longnoserob in the above MR!
2024-05-14 02:03:35 -05:00
Joel Selvaraj 716e1e27c7 README: add socinfo sysfs mapping to HexagonFS table
Introduced in https://gitlab.com/sdm670-mainline/hexagonrpc/-/merge_requests/2.
2024-05-14 02:03:35 -05:00
Joel Selvaraj 54ba43fbc3 hexagonrpcd/rpcd_builder: add mapping for socinfo sysfs
Needed for some Xiaomi phones such as Poco F1.
Based on https://gitlab.com/sdm670-mainline/hexagonrpc/-/merge_requests/1.
Thanks to the initial findings of @longnoserob in the above MR!
2024-05-14 01:49:46 -05:00
Richard Acayan f6d8a0e686 tests: add initial hexagonfs test
The virtual filesystem is important, but is only tested in the full
program. Add the initial test for it.
2024-04-26 17:50:58 -04:00
Richard Acayan 9db873f24f hexagonrpcd: hexagonfs: constify dirent data
The data in the directory entry structure is meant to be used in opening
a file. It should not change during the program.

For the virtual directory, the pointer to constant data must be wrapped
because the data for the open file is not constant.
2024-04-17 17:03:07 -04:00
Richard Acayan 3f46980dc9 hexagonrpcd: correct -d default in help text
The name of the DSP defaults to none, but the -d option is wrongly
documented as having a default of "adsp". Correct this in the help text.
2024-04-15 18:35:46 -04:00
Richard Acayan 30fa49eb20 build: add hexagonrpcd_verbose option
There is extra debug logging in the code which can be activated by
`meson configure build -Dc_args=-DHEXAGONRPC_VERBOSE`. This may be
difficult to trigger, since it requires -D twice in the same argument.
Add the hexagonrpcd_verbose option to make it easier to configure the
extra logging.

This can be activated with `-Dhexagonrpcd_verbose=true` and deactivated
with `-Dhexagonrpcd_verbose=false`.
2024-04-11 17:59:03 -04:00
Richard Acayan b7ad1021a2 build: apply default C flags to all targets
The warning flags should be applied to the entire C codebase in order to
help ensure correct code. No extra warnings are emitted by doing this.
2024-04-11 17:45:47 -04:00
Richard Acayan f23297f962 tests: set warning flags
Most subdirectories in this project have all, pedantic, and some extra
warnings enabled. Set this for tests as well, as there is no real
justification otherwise.
2024-04-09 19:18:44 -04:00
Richard Acayan c4c469bd8a tests: iobuffer: convert binary data to unsigned char arrays
Signed character arrays can overflow when specifying values greater than
127. The actual data is not affected, but this can cause compiler
warnings. Use unsigned character arrays so the compiler does not
complain about overflows.
2024-04-09 19:16:04 -04:00
Richard Acayan 6840e1dcfa tests: iobuffer: exit with code 0 on success
This file seems to implicitly return 0 when everything is successful,
but this is unclear when reading it. Explicitly return zero when all
tests are successful.
2024-04-09 19:10:30 -04:00
Richard Acayan aaef8a1e28 hexagonrpcd: use the dsp directory as the default for libraries
This variable represents the subdirectory in the dsp/ directory where
libraries should be searched. This is the argument to the optional `-d`
and is used when creating the filesystem. Initialize it to an empty
string so HexagonFS searches in /usr/share/qcom/dsp/ by default.
2024-04-09 17:05:21 -04:00
31 changed files with 971 additions and 177 deletions

No files matched your search

+1
View File
@@ -133,6 +133,7 @@ These files are searched for in:
/usr/share/qcom/sensors/config /vendor/etc/sensors/config
/usr/share/qcom/sensors/registry /mnt/vendor/persist/sensors/registry/registry
/usr/share/qcom/sensors/sns_reg.conf /vendor/etc/sensors/sns_reg_config
/usr/share/qcom/socinfo /sys/devices/soc0
These files and directories should be populated with files from your device's
Android firmware.
+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 */
+1 -1
View File
@@ -1,7 +1,7 @@
executable('chrecd',
'interfaces.c',
'main.c',
c_args : ['-Wall', '-Wextra', '-Wpedantic'],
c_args : cflags,
include_directories : include,
install : true,
link_with : libhexagonrpc,
+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,
},
};
+1 -1
View File
@@ -33,7 +33,7 @@ struct hexagonfs_fd;
struct hexagonfs_file_ops {
void (*close)(void *fd_data);
int (*from_dirent)(void *dirent_data, bool dir, void **fd_data);
int (*from_dirent)(const void *dirent_data, bool dir, void **fd_data);
int (*openat)(struct hexagonfs_fd *dir,
const char *segment,
bool expect_dir,
+2 -2
View File
@@ -47,7 +47,7 @@ static void mapped_close(void *fd_data)
free(ctx);
}
static int mapped_from_dirent(void *dirent_data, bool dir, void **fd_data)
static int mapped_from_dirent(const void *dirent_data, bool dir, void **fd_data)
{
struct mapped_ctx *ctx;
const char *name = dirent_data;
@@ -222,7 +222,7 @@ static void mapped_or_empty_close(void *fd_data)
mapped_close(fd_data);
}
static int mapped_or_empty_from_dirent(void *dirent_data, bool dir, void **fd_data)
static int mapped_or_empty_from_dirent(const void *dirent_data, bool dir, void **fd_data)
{
int ret;
+2 -2
View File
@@ -41,7 +41,7 @@ static void plat_subtype_name_close(void *fd_data)
free(ctx->name);
}
static int plat_subtype_name_from_dirent(void *dirent_data,
static int plat_subtype_name_from_dirent(const void *dirent_data,
bool dir,
void **fd_data)
{
@@ -54,7 +54,7 @@ static int plat_subtype_name_from_dirent(void *dirent_data,
if (ctx == NULL)
return -ENOMEM;
ctx->fd = open((const char *) dirent_data, O_RDONLY);
ctx->fd = open(dirent_data, O_RDONLY);
if (ctx->fd == -1)
return -errno;
+16 -7
View File
@@ -31,10 +31,10 @@
* This function searches for the relevant path segment in the path directory.
* It is not optimized because it is dealing with small directories.
*/
static struct hexagonfs_dirent *walk_dir(struct hexagonfs_dirent **dir,
static const struct hexagonfs_dirent *walk_dir(const struct hexagonfs_dirent *const *dir,
const char *segment)
{
struct hexagonfs_dirent **curr = dir;
const struct hexagonfs_dirent *const *curr = dir;
while (*curr != NULL) {
if (!strcmp(segment, (*curr)->name))
@@ -46,9 +46,17 @@ static struct hexagonfs_dirent *walk_dir(struct hexagonfs_dirent **dir,
return *curr;
}
static int virt_dir_from_dirent(void *dirent_data, bool dir, void **fd_data)
static int virt_dir_from_dirent(const void *dirent_data, bool dir, void **fd_data)
{
*fd_data = dirent_data;
const struct hexagonfs_dirent *const **wrapper;
wrapper = malloc(sizeof(*wrapper));
if (wrapper == NULL)
return -ENOMEM;
*wrapper = dirent_data;
*fd_data = wrapper;
return 0;
}
@@ -57,12 +65,12 @@ static int virt_dir_openat(struct hexagonfs_fd *dir,
bool expect_dir,
struct hexagonfs_fd **out)
{
const struct hexagonfs_dirent *const **dirlist = dir->data;
const struct hexagonfs_dirent *ent;
struct hexagonfs_fd *fd;
struct hexagonfs_dirent *ent;
struct hexagonfs_dirent **dirlist = dir->data;
int ret;
ent = walk_dir(dirlist, segment);
ent = walk_dir(*dirlist, segment);
if (ent == NULL)
return -ENOENT;
@@ -89,6 +97,7 @@ err:
static void virt_dir_close(void *fd_data)
{
free(fd_data);
}
static int virt_dir_stat(struct hexagonfs_fd *fd, struct stat *stats)
@@ -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 -2
View File
@@ -1,5 +1,4 @@
executable('hexagonrpcd',
'aee_error.c',
'apps_std.c',
'interfaces.c',
'hexagonfs.c',
@@ -11,7 +10,7 @@ executable('hexagonrpcd',
'localctl.c',
'rpcd.c',
'rpcd_builder.c',
c_args : ['-Wall', '-Wextra', '-Wpedantic', '-Wno-unused-parameter'],
c_args : cflags,
include_directories : include,
install : true,
link_with : libhexagonrpc,
+10 -18
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;
@@ -132,7 +124,7 @@ static void print_usage(const char *argv0)
printf("Usage: %s [options] -f DEVICE\n\n", argv0);
printf("Server for FastRPC remote procedure calls from Qualcomm DSPs\n\n"
"Options:\n"
"\t-d DSP\t\tDSP name (default: adsp)\n"
"\t-d DSP\t\tDSP name (default: "")\n"
"\t-f DEVICE\tFastRPC device node to attach to\n"
"\t-p PROGRAM\tRun client program with shared file descriptor\n"
"\t-R DIR\t\tRoot directory of served files (default: /usr/share/qcom/)\n"
@@ -237,7 +229,7 @@ int main(int argc, char* argv[])
{
char *fastrpc_node = NULL;
const char *device_dir = "/usr/share/qcom/";
const char *dsp;
const char *dsp = "";
const char **progs;
pid_t *pids;
size_t n_progs = 0;
+39 -18
View File
@@ -31,6 +31,7 @@
#define SENSORS_CONFIG "/sensors/config/"
#define SENSORS_REGISTRY "/sensors/registry/"
#define SNS_REG_CONFIG "/sensors/sns_reg.conf"
#define SYSFS_SOCINFO "/socinfo/"
static struct hexagonfs_dirent *hfs_mkdir(const char *name, size_t n_ents, ...)
{
@@ -110,9 +111,9 @@ static struct hexagonfs_dirent *hfs_map_or_empty(const char *name, const char *p
*/
struct hexagonfs_dirent *construct_root_dir(const char *prefix, const char *dsp)
{
char *acdbdata, *dsp_libs, *sns_cfg, *sns_reg, *sns_reg_config;
char *acdbdata, *dsp_libs, *sns_cfg, *sns_reg, *sns_reg_config, *socinfo;
size_t n_prefix;
struct hexagonfs_dirent *persist_dir;
struct hexagonfs_dirent *persist_dir, *vendor_dir;
n_prefix = strlen(prefix);
@@ -120,6 +121,7 @@ struct hexagonfs_dirent *construct_root_dir(const char *prefix, const char *dsp)
sns_cfg = malloc(n_prefix + strlen(SENSORS_CONFIG) + 1);
sns_reg = malloc(n_prefix + strlen(SENSORS_REGISTRY) + 1);
sns_reg_config = malloc(n_prefix + strlen(SNS_REG_CONFIG) + 1);
socinfo = malloc(n_prefix + strlen(SYSFS_SOCINFO) + 1);
dsp_libs = malloc(n_prefix + strlen(DSP_LIBS) + strlen(dsp) + 1);
@@ -143,6 +145,11 @@ struct hexagonfs_dirent *construct_root_dir(const char *prefix, const char *dsp)
strcat(sns_reg_config, SNS_REG_CONFIG);
}
if (socinfo != NULL) {
strcpy(socinfo, prefix);
strcat(socinfo, SYSFS_SOCINFO);
}
if (dsp_libs != NULL) {
strcpy(dsp_libs, prefix);
strcat(dsp_libs, DSP_LIBS);
@@ -161,21 +168,11 @@ struct hexagonfs_dirent *construct_root_dir(const char *prefix, const char *dsp)
)
);
return hfs_mkdir("/", 4,
hfs_mkdir("mnt", 1,
hfs_mkdir("vendor", 1,
persist_dir
)
),
persist_dir,
hfs_mkdir("usr", 1,
hfs_mkdir("lib", 1,
hfs_mkdir("qcom", 1,
hfs_map_or_empty("adsp", dsp_libs)
)
)
),
hfs_mkdir("vendor", 1,
/*
* Some platforms need vendor in / and some need it in /system. Form
* a hard link between both locations.
*/
vendor_dir = hfs_mkdir("vendor", 1,
hfs_mkdir("etc", 2,
hfs_mkdir("sensors", 2,
hfs_map_or_empty("config", sns_cfg),
@@ -183,6 +180,30 @@ struct hexagonfs_dirent *construct_root_dir(const char *prefix, const char *dsp)
),
hfs_map("acdbdata", acdbdata)
)
)
);
return hfs_mkdir("/", 6,
hfs_mkdir("mnt", 1,
hfs_mkdir("vendor", 1,
persist_dir
)
),
persist_dir,
hfs_mkdir("sys", 1,
hfs_mkdir("devices", 1,
hfs_map_or_empty("soc0", socinfo)
)
),
hfs_mkdir("system", 1,
vendor_dir
),
hfs_mkdir("usr", 1,
hfs_mkdir("lib", 1,
hfs_mkdir("qcom", 1,
hfs_map_or_empty("adsp", dsp_libs)
)
)
),
vendor_dir
);
}
@@ -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 */
Loaded 20 of 31 files, more files were not shown because too many files have changed in this diff. Show more