25 Commits
Author SHA1 Message Date
Richard Acayan 23a69640bf tools: make json-c optional
This shouldn't be a requirement to compile anything else. Stop requiring
it for building anything, and assume the user just wants to compile the
main project.

Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-19 22:30:25 -04:00
Richard Acayan 18e2ca3178 CI: depend on libjson-c-dev
This is a dependency of the newly imported sscregistrygen.

Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-19 22:27:14 -04:00
Richard Acayan ffca60917c meson.build: bump to 0.4.0
No breaking changes

New features:
- man page for hexagonrpcd
- support for FASTRPC_IOCTL_INIT_CREATE with fastrpc_shell_X
- apps_mem interface (mostly allocating memory for now)
- logic for hexagonfs root directory
- sscregistrygen tool to generate sensor registry
- Github CI (successful compilation only)

Fixes:
- Disabled verbose logging by default
- Documented the paths relative to the root directory
- Made apps_std_stat relative to ADSP libs directory
- Fixed unsigned/signed comparison in reverse tunnel
- Declared minimum meson version for meson.options
- Added soversion to the library build

Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-19 22:15:27 -04:00
Richard Acayan 6e1281dc8d tools: add sscregistrygen from sensh
From the sensor shell repository, sscregistrygen is a tool for
generating the sensor registry from the sensor config. It is useful when
the sensor registry is not included in device firmware. Add
sscregistrygen here since it is more directly used by hexagonrpc rather
than sensh.

Link: https://gitlab.com/flamingradian/sensh/-/blob/23b7681f3faad422fa5751886f901bf03775243d/tools/sscregistrygen.c
Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-19 22:13:32 -04:00
Jens Reidel 948c5d0d37 hexagonrpcd: Guess directory for hexagonfs from compatible
Signed-off-by: Jens Reidel <adrian@travitia.xyz>
Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-18 22:49:26 -04:00
Dmitry Baryshkov e52da43a63 apps_mem: specify int argument to fastrpc_apps_mem_init()
Without this building fails with:

../git/hexagonrpcd/rpcd.c: In function 'start_reverse_tunnel':
../git/hexagonrpcd/rpcd.c:275:21: error: too many arguments to function 'fastrpc_apps_mem_init'; expected 0, have 1
  275 |         ifaces[2] = fastrpc_apps_mem_init(fd);
      |                     ^~~~~~~~~~~~~~~~~~~~~ ~~
In file included from ../git/hexagonrpcd/rpcd.c:38:
../git/hexagonrpcd/apps_mem.h:27:27: note: declared here
   27 | struct fastrpc_interface *fastrpc_apps_mem_init();
      |                           ^~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
2025-05-13 04:59:23 +03:00
Dmitry Baryshkov 6e5f7d9d54 CI: add simple workflow
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
2025-05-12 13:32:42 +03:00
Dmitry Baryshkov 9a68ca3abf meson.build: declare minimum meson version
The project uses meson.options rather than meson_options.txt. Document
the minimum meson version that can be used to build the project.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
2025-05-12 13:32:42 +03:00
Dmitry Baryshkov 146d0e1dab listener: fix Wsign-compare error
Fix warning / error reported by gcc:

../git/hexagonrpcd/listener.c:115:25: warning: comparison of integer expressions of different signedness: 'uint32_t' {aka 'unsigned int'} and 'int' [-Wsign-compare]
         if (inbufs[0].s != 4 * (def->in_nums
                         ^~

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
2025-05-12 13:32:42 +03:00
Richard Acayan 2377fd46f0 hexagonrpcd: add apps_mem interface implementation
The apps_mem interface enables the FastRPC shell to load skel ELFs,
such as libhexagon_nn_skel.so.
2025-05-09 19:36:50 -04:00
Richard Acayan 372ca67d7a hexagonrpcd: interfaces: add apps_mem interface
The apps_mem interface is the interface that allows the DSP to map
memory and to allocate more memory. Add a method definition for it.
2025-05-09 19:36:50 -04:00
Richard Acayan 4b1ecd8505 hexagonrpcd: apps_std: perform stat relative to ADSP libs directory
When loading a new skel file, the DSP may access a testsig.so file. This
calls apps_std_fopen_with_env which is relative to a specified
directory, but also apps_std_stat. Since the same "testsig.so"
path is accessed relative to ADSP_LIBRARY_PATH and to the current
working directory, infer that the current working directory should be
ADSP_LIBRARY_PATH.
2025-05-09 19:36:50 -04:00
Richard Acayan 53e347f39d hexagonrpcd.1: add -c option 2025-05-09 19:36:50 -04:00
Richard Acayan 75150d4860 hexagonrpcd: add -c option to start with pd 2025-05-09 19:36:49 -04:00
Richard Acayan 5620db43a7 hexagonrpcd.1: document the paths relative to the root directory
The files shouldn't be installed right in /usr/share/qcom except for
testing. Rather, they should be installed in some device-specific
directory to make packaging easier on some distros. Document the paths
relative to the root directory for served files.
2024-11-05 21:41:35 -05:00
Richard Acayan 0e9e03b37b README: document the paths relative to the root directory
The absolute paths shouldn't be installed right in /usr/share/qcom
except for testing. Document the modifiable directory where served files
are retrieved from and the convention of where this directory should be
located.

Link: https://gitlab.com/flamingradian/sensh/-/issues/1
2024-11-05 21:41:26 -05:00
Alexandre Viard 61bb51bbc9 Use Major.Minor for the lib soversion derived from project version
[richard: rebase and squash; remove leading whitespace in commit message]
2024-11-01 19:15:29 -04:00
Alexandre Viard ffbc4da830 Add man page for hexagonrpcd
[richard: remove trailing whitespace under -s; squash]
2024-10-21 19:06:54 -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
25 changed files with 1096 additions and 43 deletions

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
name: Buildtest
on:
pull_request:
push:
jobs:
build-linux:
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-24.04
# 22.04 has old meson
# - runner: ubuntu-22.04
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Dependencies
run: |
sudo apt update
sudo apt install -y meson ninja-build libjson-c-dev
- name: build
run: |
meson setup build
ninja -C build
+15 -7
View File
@@ -125,18 +125,26 @@ Interfaces are initialized in the `start_reverse_tunnel` function, in hexagonrpc
## HexagonFS
The reverse tunnel's `apps_std` interface serves files to the remote processor.
These files are searched for in:
These files are searched for in a directory tree, starting at the location
defined by the `-R` option, or in `/usr/share/qcom` by default:
Physical file/dir Android file/dir
/usr/share/qcom/acdb /vendor/etc/acdbdata
/usr/share/qcom/dsp /vendor/dsp
/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
HexagonRPCD file/dir Android file/dir
acdb /vendor/etc/acdbdata
dsp /vendor/dsp
sensors/config /vendor/etc/sensors/config
sensors/registry /mnt/vendor/persist/sensors/registry/registry
sensors/sns_reg.conf /vendor/etc/sensors/sns_reg_config
socinfo /sys/devices/soc0
These files and directories should be populated with files from your device's
Android firmware.
If you can pass the `-R` option, the convention is to pass `-R
/usr/share/qcom/SOC/VENDOR/DEVICE`, where SOC is the SoC name in lowercase,
VENDOR is the capitalized name of the device vendor, and DEVICE is the device
name (e.g. `-R /usr/share/qcom/sdm845/SHIFT/axolotl` or `-R
/usr/share/qcom/sdm845/Thundercomm/db845c`).
# Future plans
Reverse tunnels are separated by the process that opens the file descriptor and
+143
View File
@@ -0,0 +1,143 @@
/*
* FastRPC memory mapping interface implementation
*
* Copyright (C) 2024 The Sensor Shell Contributors
*
* This file is part of sensh.
*
* Sensh is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <misc/fastrpc.h>
#include <sys/ioctl.h>
#include "aee_error.h"
#include "apps_mem.h"
#include "interfaces/apps_mem.def"
#include "listener.h"
// See fastrpc.git/src/apps_mem_imp.c
#define ADSP_MMAP_HEAP_ADDR 4
#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
#define ADSP_MMAP_ADD_PAGES 0x1000
struct apps_mem_ctx {
int fd;
};
static uint32_t apps_mem_request_map64(void *data,
const struct fastrpc_io_buffer *inbufs,
struct fastrpc_io_buffer *outbufs)
{
struct apps_mem_ctx *ctx = data;
const struct {
uint32_t heap_id;
uint32_t lflags;
uint32_t rflags;
uint32_t padding;
uint64_t vin;
uint64_t len;
} *first_in = inbufs[0].p;
struct {
uint64_t vapps;
uint64_t vadsp;
} *first_out = outbufs[0].p;
struct fastrpc_req_mmap mmap;
int ret;
if (!(first_in->rflags & ADSP_MMAP_ADD_PAGES)) {
fprintf(stderr, "Unsupported mmap operation: DMA buffer request\n");
return AEE_EUNSUPPORTED;
}
mmap.fd = -1;
mmap.flags = first_in->rflags;
mmap.vaddrin = 0;
mmap.size = first_in->len;
ret = ioctl(ctx->fd, FASTRPC_IOCTL_MMAP, &mmap);
if (ret == -1) {
perror("Memory map failed");
return AEE_EFAILED;
} else if (ret) {
fprintf(stderr, "Memory map failed: %s\n", aee_strerror[ret]);
return ret;
}
#if HEXAGONRPC_VERBOSE
printf("mmap(%d, %x, %x, %lu, %lu) -> %" PRIx64 "\n",
first_in->heap_id,
first_in->lflags,
first_in->rflags,
first_in->vin,
first_in->len,
mmap.vaddrout);
#endif
first_out->vapps = 0;
first_out->vadsp = mmap.vaddrout & 0xFFFFFFFF;
return 0;
}
struct fastrpc_interface *fastrpc_apps_mem_init(int fd)
{
struct fastrpc_interface *iface;
struct apps_mem_ctx *ctx;
iface = malloc(sizeof(*iface));
if (iface == NULL)
return NULL;
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL)
goto err_free_iface;
memcpy(iface, &apps_mem_interface, sizeof(*iface));
ctx->fd = fd;
iface->data = ctx;
return iface;
err_free_iface:
free(iface);
return NULL;
}
void fastrpc_apps_mem_deinit(struct fastrpc_interface *iface)
{
free(iface->data);
free(iface);
}
static const struct fastrpc_function_impl apps_mem_procs[] = {
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
{ .def = &apps_mem_request_map64_def, .impl = apps_mem_request_map64, },
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
{ .def = NULL, .impl = NULL, },
};
const struct fastrpc_interface apps_mem_interface = {
.name = "apps_mem",
.n_procs = 6,
.procs = apps_mem_procs,
};
+30
View File
@@ -0,0 +1,30 @@
/*
* FastRPC operating system interface - context initialization
*
* Copyright (C) 2024 The Sensor Shell Contributors
*
* This file is part of HexagonRPC.
*
* HexagonRPC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef APPS_MEM_H
#define APPS_MEM_H
#include "listener.h"
struct fastrpc_interface *fastrpc_apps_mem_init(int fd);
void fastrpc_apps_mem_deinit(struct fastrpc_interface *iface);
#endif
+1 -1
View File
@@ -312,7 +312,7 @@ static uint32_t apps_std_stat(void *data,
if (((const char *) inbufs[1].p)[inbufs[1].s - 1] != 0)
return AEE_EBADPARM;
fd = hexagonfs_openat(ctx->fds, ctx->rootfd, ctx->rootfd, pathname);
fd = hexagonfs_openat(ctx->fds, ctx->rootfd, ctx->adsp_library_dirfd, pathname);
if (fd < 0) {
fprintf(stderr, "Could not open %s: %s\n",
pathname, strerror(-fd));
+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)
+66
View File
@@ -0,0 +1,66 @@
'\" t
.TH HEXAGONRPCD 1 "2024-09-28" "hexagonrpcd" "Server for FastRPC remote procedure calls from Qualcomm DSPs"
.SH NAME
hexagonrpcd - Server for FastRPC remote procedure calls from Qualcomm DSPs
.SH SYNOPSIS
\fBhexagonrpcd\fP [\fIoptions\&.\&.\&.\fP] -f \fIDEVICE
.SH DESCRIPTION
Server for FastRPC remote procedure calls from Qualcomm DSPs\&.
.PP
.SH OPTIONS
.TP
\fB\-c \fISHELL\fP
Create a new pd running the specified ELF
\fB\-d \fIDSP\fP
DSP name (default: )
.TP
\fB\-f \fIDEVICE\fP
FastRPC device node to attach to
.TP
\fB\-p \fIPROGRAM\fP
Run client program with shared file descriptor
.TP
\fB\-R \fIDIR\fP
Root directory of served files (default: /usr/share/qcom/)
.TP
\fB\-s\fP
Attach to sensorspd
.PP
.SH NOTES
Hexagonrpcd serves files to the remote processor via a reverse tunnel interface
to the remote processor. These files are by default searched for in:
These files are searched for in a directory tree, starting at the location
defined by the -R option, or in /usr/share/qcom by default:
.TS
l l
---
l l.
HexagonRPCD file/dir Android file/dir
acdb /vendor/etc/acdbdata
dsp /vendor/dsp
sensors/config /vendor/etc/sensors/config
sensors/registry /mnt/vendor/persist/sensors/registry/registry
sensors/sns_reg.conf /vendor/etc/sensors/sns_reg_config
socinfo /sys/devices/soc0
.TE
These files and directories should be populated with files from your device's
Android firmware.
If you can pass the -R option, the convention is to pass -R
/usr/share/qcom/SOC/VENDOR/DEVICE, where SOC is the SoC name in lowercase,
VENDOR is the capitalized name of the device vendor, and DEVICE is the device
name (e.g. -R /usr/share/qcom/sdm845/SHIFT/axolotl or -R
/usr/share/qcom/sdm845/Thundercomm/db845c).
.SH AUTHORS
hexagonrpcd was written by The HexagonRPC Contributors <https://github.com/linux-msm/hexagonrpc>
.SH COPYRIGHT
Copyright (C) 2024 The HexagonRPC Contributors <https://github.com/linux-msm/hexagonrpc>
Copyright (C) 2023 The Sensor Shell Contributors <https://github.com/linux-msm/hexagonrpc>
.PP
Released under GPL-3+ license\&.
+1
View File
@@ -22,5 +22,6 @@
#define HEXAGONRPC_BUILD_METHOD_DEFINITIONS 1
#include "interfaces/adsp_default_listener.def"
#include "interfaces/apps_mem.def"
#include "interfaces/apps_std.def"
#include "interfaces/adsp_listener.def"
+29
View File
@@ -0,0 +1,29 @@
/*
* FastRPC operating system interface
*
* Copyright (C) 2024 The Sensor Shell Contributors
*
* This file is part of sensh.
*
* Sensh is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef INTERFACE_APPS_MEM_DEF
#define INTERFACE_APPS_MEM_DEF
#include <libhexagonrpc/interface.h>
HEXAGONRPC_DEFINE_REMOTE_METHOD(2, apps_mem_request_map64, 8, 0, 4, 0)
#endif /* INTERFACE_APPS_MEM_DEF */
+1 -1
View File
@@ -112,7 +112,7 @@ static int check_inbuf_sizes(const struct fastrpc_function_def_interp2 *def,
uint8_t i;
const uint32_t *sizes = &((const uint32_t *) inbufs[0].p)[def->in_nums];
if (inbufs[0].s != 4 * (def->in_nums
if (inbufs[0].s != 4U * (def->in_nums
+ def->in_bufs
+ def->out_bufs)) {
fprintf(stderr, "Invalid number of input numbers: %" PRIu32 " (expected %u)\n",
+1
View File
@@ -44,6 +44,7 @@ struct fastrpc_interface {
extern const struct fastrpc_interface localctl_interface;
extern const struct fastrpc_interface apps_mem_interface;
extern const struct fastrpc_interface apps_std_interface;
int run_fastrpc_listener(int fd,
+2
View File
@@ -1,5 +1,6 @@
executable('hexagonrpcd',
'aee_error.c',
'apps_mem.c',
'apps_std.c',
'interfaces.c',
'hexagonfs.c',
@@ -17,3 +18,4 @@ executable('hexagonrpcd',
link_with : libhexagonrpc,
install_dir : get_option('bindir'),
)
install_man('hexagonrpcd.1')
+186 -2
View File
@@ -30,9 +30,12 @@
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "aee_error.h"
#include "apps_mem.h"
#include "apps_std.h"
#include "hexagonfs.h"
#include "interfaces/adsp_default_listener.def"
@@ -132,6 +135,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-c SHELL\t\tCreate a new pd running the specified ELF\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"
@@ -139,6 +143,60 @@ static void print_usage(const char *argv0)
"\t-s\t\tAttach to sensorspd\n");
}
static int create_shell_pd(int fd, const char *create_shell)
{
char *buf;
int shellfd, ret;
struct stat stats;
struct fastrpc_alloc_dma_buf dmabuf;
long page_size;
struct fastrpc_init_create init = {
.attrs = 0,
.siglen = 0,
};
shellfd = open(create_shell, O_RDONLY);
if (shellfd == -1) {
fprintf(stderr, "Could not open %s: %s\n",
create_shell, strerror(errno));
return -1;
}
ret = fstat(shellfd, &stats);
if (ret == -1)
goto err_close_fd;
page_size = sysconf(_SC_PAGE_SIZE);
dmabuf.size = (stats.st_size + page_size - 1) & ~(page_size - 1);
dmabuf.flags = 0;
ret = ioctl(fd, FASTRPC_IOCTL_ALLOC_DMA_BUFF, &dmabuf);
if (ret)
goto err_close_fd;
buf = mmap(NULL, dmabuf.size, PROT_WRITE, MAP_SHARED, dmabuf.fd, 0);
if (buf == MAP_FAILED) {
ret = -1;
goto err_close_dmabuf;
}
read(shellfd, buf, stats.st_size);
init.file = (__u64) buf;
init.filefd = dmabuf.fd;
init.filelen = stats.st_size;
ret = ioctl(fd, FASTRPC_IOCTL_INIT_CREATE, &init);
munmap(buf, dmabuf.size);
err_close_dmabuf:
close(dmabuf.fd);
err_close_fd:
close(shellfd);
return ret;
}
static int setup_environment(int fd)
{
char *buf;
@@ -196,7 +254,7 @@ static void *start_reverse_tunnel(int fd, const char *device_dir, const char *ds
{
struct fastrpc_interface **ifaces;
struct hexagonfs_dirent *root_dir;
size_t n_ifaces = 2;
size_t n_ifaces = 3;
int ret;
ifaces = malloc(sizeof(struct fastrpc_interface) * n_ifaces);
@@ -214,6 +272,7 @@ static void *start_reverse_tunnel(int fd, const char *device_dir, const char *ds
// Dynamic interfaces with no hardcoded handle
ifaces[1] = fastrpc_apps_std_init(root_dir);
ifaces[2] = fastrpc_apps_mem_init(fd);
ret = register_fastrpc_listener(fd);
if (ret)
@@ -233,11 +292,127 @@ err:
return NULL;
}
static char *read_sysfs_file(const char *path, struct stat *file_stat)
{
char *contents = NULL;
int fd, res, n_bytes;
fd = open(path, O_RDONLY);
if (fd == -1)
return NULL;
res = fstat(fd, file_stat);
if (res)
goto close_fd;
contents = malloc(file_stat->st_size);
if (contents == NULL)
goto close_fd;
n_bytes = read(fd, contents, file_stat->st_size);
if (n_bytes != file_stat->st_size) {
free(contents);
contents = NULL;
}
close_fd:
close(fd);
return contents;
}
/*
* Guesses the device's HexagonFS directory from the model and compatible
* properties in the device-tree.
*
* The vendor name is guessed by splitting the model property at the first
* space to preserve the canonical capitalization of the name.
*
* The SoC name is assumed to be part of the first property in the compatible
* list that starts with "qcom,".
*
* Finally, all compatible entries are split at the first , and the all
* right-hand sides of the entry considered as the codename.
*
* It returns the first guessed combination of all 3 for which a path exists
* at /usr/share/qcom/{soc}/{vendor}/{codename}.
* If no match is found, a null pointer is returned.
*/
static char *guess_device_directory_from_compatible(void)
{
char *compatible_ptr, *device_name, *model_ptr, *orig_compatible_ptr,
*end_of_vendor_name, *vendor_name;
char *chipset_name = NULL;
char *ret = NULL;
struct stat compatible_stat, model_stat;
compatible_ptr = read_sysfs_file("/proc/device-tree/compatible",
&compatible_stat);
if (compatible_ptr == NULL)
return NULL;
orig_compatible_ptr = compatible_ptr;
model_ptr = read_sysfs_file("/proc/device-tree/model", &model_stat);
if (model_ptr == NULL)
goto free_compatible;
end_of_vendor_name = strchr(model_ptr, ' ');
if (end_of_vendor_name == NULL)
end_of_vendor_name = model_ptr + model_stat.st_size - 1;
vendor_name = strndup(model_ptr, end_of_vendor_name - model_ptr);
if (vendor_name == NULL)
goto free_model;
while (compatible_ptr < orig_compatible_ptr + compatible_stat.st_size) {
if (strncmp("qcom,", compatible_ptr, sizeof("qcom,") - 1) == 0) {
chipset_name = compatible_ptr + sizeof("qcom,") - 1;
break;
}
compatible_ptr += strlen(compatible_ptr) + 1;
}
if (chipset_name == NULL)
goto free_model;
compatible_ptr = orig_compatible_ptr;
while (compatible_ptr < orig_compatible_ptr + compatible_stat.st_size) {
char *try_path = NULL;
device_name = strchr(compatible_ptr, ',');
if (device_name == NULL)
continue;
device_name += 1;
if (asprintf(&try_path, "/usr/share/qcom/%s/%s/%s",
chipset_name, vendor_name, device_name) < 0)
goto free_model;
if (!access(try_path, R_OK)) {
ret = try_path;
break;
}
free(try_path);
compatible_ptr += strlen(compatible_ptr) + 1;
}
free_model:
free(model_ptr);
free_compatible:
free(orig_compatible_ptr);
return ret;
}
int main(int argc, char* argv[])
{
char *fastrpc_node = NULL;
const char *device_dir = "/usr/share/qcom/";
const char *dsp = "";
const char *create_shell = NULL;
const char *guessed_device_dir;
const char **progs;
pid_t *pids;
size_t n_progs = 0;
@@ -256,8 +431,15 @@ int main(int argc, char* argv[])
goto err_free_progs;
}
while ((opt = getopt(argc, argv, "d:f:p:R:s")) != -1) {
guessed_device_dir = guess_device_directory_from_compatible();
if (guessed_device_dir != NULL)
device_dir = guessed_device_dir;
while ((opt = getopt(argc, argv, "c:d:f:p:R:s")) != -1) {
switch (opt) {
case 'c':
create_shell = optarg;
break;
case 'd':
dsp = optarg;
break;
@@ -295,6 +477,8 @@ int main(int argc, char* argv[])
if (attach_sns)
ret = ioctl(fd, FASTRPC_IOCTL_INIT_ATTACH_SNS, NULL);
else if (create_shell != NULL)
ret = create_shell_pd(fd, create_shell);
else
ret = ioctl(fd, FASTRPC_IOCTL_INIT_ATTACH, NULL);
if (ret) {
+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
);
}
+1
View File
@@ -5,6 +5,7 @@ libhexagonrpc = shared_library('hexagonrpc',
'session.c',
c_args : cflags,
include_directories : include,
soversion : api_version,
install : true
)
+6 -1
View File
@@ -1,4 +1,7 @@
project('fastrpc', 'c')
project('fastrpc', 'c', version: '0.4.0', meson_version: '>=1.1')
version_array = meson.project_version().split('.')
api_version = version_array[0] + '.' + version_array[1]
include = include_directories('include')
client_target = get_option('libexecdir') / 'hexagonrpc'
@@ -13,4 +16,6 @@ subdir('libhexagonrpc')
subdir('hexagonrpcd')
subdir('chrecd')
subdir('tools')
subdir('tests')
+1 -1
View File
@@ -1,2 +1,2 @@
option('hexagonrpcd_verbose', type : 'boolean', value : true,
option('hexagonrpcd_verbose', type : 'boolean', value : false,
description : 'Compile hexagonrpcd with extra logging for each remote method invocation')
Loaded 20 of 25 files, more files were not shown because too many files have changed in this diff. Show more