mirror of
https://github.com/linux-msm/hexagonrpc.git
synced 2026-10-07 15:29:50 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7eff23db1 | ||
|
|
716e1e27c7 | ||
|
|
54ba43fbc3 | ||
|
|
f6d8a0e686 | ||
|
|
9db873f24f | ||
|
|
3f46980dc9 | ||
|
|
30fa49eb20 | ||
|
|
b7ad1021a2 | ||
|
|
f23297f962 | ||
|
|
c4c469bd8a | ||
|
|
6840e1dcfa | ||
|
|
aaef8a1e28 | ||
|
|
63b1711021 | ||
|
|
39dd3aec6e | ||
|
|
892b9f549e | ||
|
|
b410c74a81 | ||
|
|
24c3eea173 | ||
|
|
8949140fa6 | ||
|
|
154bd2631c |
No files matched your search
@@ -1,65 +0,0 @@
|
||||
#
|
||||
# Build system
|
||||
#
|
||||
# Copyright (C) 2022 Richard Acayan
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
QMIC = qmic
|
||||
CC = gcc
|
||||
LIBS = -lprotobuf-c -lqrtr
|
||||
CFLAGS = -Wall -Wextra -Wpedantic -Ibuild -I.
|
||||
PROTOC_C = protoc-c
|
||||
|
||||
build/sensh: build/sensh.o build/qmi_sns_client.o build/sns_client_event_msg.pb-c.o build/sns_client_request_msg.pb-c.o build/sns_proximity_event.pb-c.o build/sns_std_attr_event.pb-c.o build/sns_std_attr_req.pb-c.o build/sns_std_sensor_event.pb-c.o build/sns_std_suid.pb-c.o build/sns_suid_event.pb-c.o build/sns_suid_req.pb-c.o
|
||||
$(CC) -o build/sensh build/sensh.o build/qmi_sns_client.o build/sns_client_event_msg.pb-c.o build/sns_client_request_msg.pb-c.o build/sns_proximity_event.pb-c.o build/sns_std_attr_event.pb-c.o build/sns_std_attr_req.pb-c.o build/sns_std_sensor_event.pb-c.o build/sns_std_suid.pb-c.o build/sns_suid_event.pb-c.o build/sns_suid_req.pb-c.o $(LIBS)
|
||||
|
||||
build/qmi_%.d: build/qmi_%.c
|
||||
$(CC) $(CFLAGS) -MM -MT build/$*.o -o $@ $<
|
||||
|
||||
build/%.pb-c.d: build/%.pb-c.c
|
||||
$(CC) $(CFLAGS) -MM -MT build/$*.o -o $@ $<
|
||||
|
||||
build/%.d: %.c
|
||||
$(CC) $(CFLAGS) -MM -MT build/$*.o -o $@ $<
|
||||
|
||||
build/qmi_%.o: build/qmi_%.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
build/%.pb-c.o: build/%.pb-c.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
build/%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
build/qmi_%.c build/qmi_%.h: qmi/%.qmi
|
||||
cd build && $(QMIC) -k < ../$<
|
||||
|
||||
build/%.pb-c.c build/%.pb-c.h: protobuf/%.proto
|
||||
$(PROTOC_C) --c_out=build -Iprotobuf $<
|
||||
|
||||
include build/sensh.d
|
||||
include build/qmi_sns_client.d
|
||||
include build/sns_client_event_msg.pb-c.d
|
||||
include build/sns_client_request_msg.pb-c.d
|
||||
include build/sns_proximity_event.pb-c.d
|
||||
include build/sns_std_attr_event.pb-c.d
|
||||
include build/sns_std_attr_req.pb-c.d
|
||||
include build/sns_std_sensor_event.pb-c.d
|
||||
include build/sns_std_suid.pb-c.d
|
||||
include build/sns_suid_event.pb-c.d
|
||||
include build/sns_suid_req.pb-c.d
|
||||
@@ -1,64 +1,151 @@
|
||||
This is a proof-of-concept for interacting with the Snapdragon Sensor Core
|
||||
using the reverse-engineered protocol buffers. It was made to try to
|
||||
initialize it, but the Pixel 3a is missing some sensors once the firmware is
|
||||
loaded.
|
||||
This directory contains a FastRPC ioctl wrapper and a reverse tunnel.
|
||||
|
||||
A best effort is made to prefix all log messages with `sensh: ` so it's clear
|
||||
which lines were entered by the user.
|
||||
FastRPC is used to communicate with the Context Hub Runtime Environment, a
|
||||
program on the DSP that manages sensors, and to serve files to remote
|
||||
processors.
|
||||
|
||||
# Requirements
|
||||
# Wrapper function
|
||||
|
||||
- gcc
|
||||
- libqrtr
|
||||
- meson or make
|
||||
- protobuf-c
|
||||
- qmic (optional for regenerating QMI, at https://github.com/andersson/qmic)
|
||||
The wrapper function is designed so that the ioctl arguments do not need to be
|
||||
constructed for each remote method. Instead, it accepts an open file descriptor,
|
||||
handle, method definition, and arguments to the remote method using `va_args`.
|
||||
This makes it relatively easy to add remote methods without the use of the QAIC
|
||||
interface compiler or a free software alternative.
|
||||
|
||||
# Installation
|
||||
## Installation
|
||||
|
||||
This can be compiled using Meson:
|
||||
You can build and install this project using meson:
|
||||
|
||||
$ meson setup build
|
||||
$ ninja -C build
|
||||
~/sensh/fastrpc $ meson setup build
|
||||
~/sensh/fastrpc $ ninja -C build
|
||||
~/sensh/fastrpc # ninja -C build install
|
||||
|
||||
There is also a Makefile to compile this, if you can get it to work:
|
||||
## Usage
|
||||
|
||||
$ mkdir build
|
||||
$ make -k
|
||||
Making already-defined method calls is relatively straightforward, depending on
|
||||
the remote method that you're calling. You just need the function definition, an
|
||||
open file descriptor, the handle, and the arguments for it.
|
||||
|
||||
# Usage
|
||||
uint32_t prev_ctx, prev_result, nested_outbufs_len;
|
||||
uint32_t ctx, nested_handle, nested_sc, nested_inbufs_len;
|
||||
uint32_t nested_inbufs_size;
|
||||
const void *nested_outbufs;
|
||||
void *nested_inbufs;
|
||||
int fd;
|
||||
|
||||
Sensh doesn't automatically track, probe, or look up sensors; that is for a full
|
||||
implementation. Instead, it expects you to look up the sensor and copy the ID
|
||||
with your terminal emulator:
|
||||
ret = fastrpc2(&adsp_listener_next2_def, fd, ADSP_LISTENER_HANDLE,
|
||||
prev_ctx,
|
||||
prev_result,
|
||||
nested_outbufs_len, nested_outbufs,
|
||||
&ctx,
|
||||
&nested_handle,
|
||||
&nested_sc,
|
||||
&nested_inbufs_len,
|
||||
nested_inbufs_size, nested_inbufs);
|
||||
|
||||
lookup accel_cal
|
||||
sensh: accel_cal sensor found: A1392FDF217B7D9EI6648AED8C04DDFB9
|
||||
attr A1392FDF217B7D9EI6648AED8C04DDFB9
|
||||
sensh: name: ASH_CAL
|
||||
sensh: vendor: GOOGLE
|
||||
sensh: type: accel_cal
|
||||
sensh: version: 1
|
||||
sensh: api: sns_cal.proto
|
||||
sensh: rates: 10.000000
|
||||
sensh: stream type: 1
|
||||
sensh: physical sensor: 0
|
||||
sensh: available: 1
|
||||
All inputs are specified before all outputs. Words in the first (called "prim",
|
||||
or primary in QAIC-generated code) input and output buffers go in the form of
|
||||
`uint32_t` arguments. Each buffer is accepted as a `uint32_t` length and a
|
||||
pointer.
|
||||
|
||||
You can send 3 messages: lookup, attr, and watch. The lookup command returns
|
||||
SUIDs for the passed data type. The attr command returns attributes for the
|
||||
sensor. Finally, the watch command tells the sensor core to send events from a
|
||||
sensor whenever the sensor's value changes.
|
||||
### Creating function definitions
|
||||
|
||||
An EOF (normally Ctrl+D) is enough to exit the shell unless the sensor core
|
||||
died.
|
||||
Assuming you already have knowledge about the remote method to call, you must
|
||||
first write a function definition for it. A function definition is a struct with
|
||||
information on its method ID and the arguments it accepts.
|
||||
|
||||
# References
|
||||
First, the method ID is taken from the first argument of the
|
||||
`REMOTE_SCALARS_MAKE()` macro or the second argument of the
|
||||
`REMOTE_SCALARS_MAKEX()` macro
|
||||
(defined [here](https://android.googlesource.com/platform/external/fastrpc/+/d6d6e3bba244e40e6043bd687f4cacf090a767b5/inc/remote.h#80)).
|
||||
|
||||
The following sources were used as reference:
|
||||
Example:
|
||||
|
||||
- [https://android.googlesource.com/platform/system/chre](https://android.googlesource.com/platform/system/chre)
|
||||
- [https://android.googlesource.com/platform/external/fastrpc](https://android.googlesource.com/platform/external/fastrpc)
|
||||
- [https://github.com/calebccff/sensordaemon-re](https://github.com/calebccff/sensordaemon-re)
|
||||
- [https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/merge\_requests/346](https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/merge_requests/346)
|
||||
- [https://git.linaro.org/landing-teams/working/qualcomm/fastrpc.git](https://git.linaro.org/landing-teams/working/qualcomm/fastrpc.git)
|
||||
REMOTE_SCALARS_MAKE(4, 2, 2)
|
||||
|
||||
has the method 4.
|
||||
|
||||
Next, information on how many arguments it takes must be specified. There are
|
||||
four types of arguments:
|
||||
|
||||
- 32-bit input words in the first input buffer, excluding lengths for the input
|
||||
and output buffers
|
||||
- 32-bit output words in the first output buffer
|
||||
- input buffers, excluding the first
|
||||
- output buffers, excluding the first
|
||||
|
||||
To get the size of the first input and output buffers, a dump must be consulted,
|
||||
or the prim argument of generated C files:
|
||||
|
||||
invoking via fastrpc, handle 3, method 4, 2 inbufs, 2 outbufs, 0 inhandles, 0 outhandles
|
||||
fastrpc argument 00000000FFFFFFFF0000000000000000 // 16 bytes, or 4 words
|
||||
fastrpc argument
|
||||
invoking via fastrpc, handle 5, method 4, 1 inbufs, 1 outbufs, 0 inhandles, 0 outhandles
|
||||
fastrpc return 91000000000000000002020029000000 // 16 bytes, or 4 words
|
||||
fastrpc return
|
||||
|
||||
Since there are 2 input buffers excluding the first (these can have a variable
|
||||
size), 2 must be subtracted from the 4 input words. These will be provided by
|
||||
the wrapper as the sizes for the variable-length input and output buffers.
|
||||
|
||||
Counting each of these will give the numbers needed for the function definition.
|
||||
|
||||
A function definition looks like:
|
||||
|
||||
const struct fastrpc_function_def_interp2 adsp_listener_next2_def = {
|
||||
.msg_id = 4,
|
||||
.in_nums = 2,
|
||||
.in_bufs = 1,
|
||||
.out_nums = 4,
|
||||
.out_bufs = 1,
|
||||
};
|
||||
|
||||
or:
|
||||
|
||||
#define DEFINE_REMOTE_PROCEDURE(mid, name, \
|
||||
innums, inbufs, \
|
||||
outnums, outbufs) \
|
||||
const struct fastrpc_function_def_interp2 name##_def = { \
|
||||
.msg_id = mid, \
|
||||
.in_nums = innums, \
|
||||
.in_bufs = inbufs, \
|
||||
.out_nums = outnums, \
|
||||
.out_bufs = outbufs, \
|
||||
};
|
||||
|
||||
DEFINE_REMOTE_PROCEDURE(4, adsp_listener_next2, 2, 1, 4, 1)
|
||||
|
||||
# Reverse tunnel
|
||||
|
||||
The reverse tunnel calls the `adsp_listener_next2` remote method to receive
|
||||
method calls for the Application Processor.
|
||||
|
||||
Interfaces are initialized in the `start_reverse_tunnel` function, in hexagonrpcd/rpcd.c.
|
||||
|
||||
## HexagonFS
|
||||
|
||||
The reverse tunnel's `apps_std` interface serves files to the remote processor.
|
||||
These files are searched for in:
|
||||
|
||||
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
|
||||
/usr/share/qcom/socinfo /sys/devices/soc0
|
||||
|
||||
These files and directories should be populated with files from your device's
|
||||
Android firmware.
|
||||
|
||||
# Future plans
|
||||
|
||||
Reverse tunnels are separated by the process that opens the file descriptor and
|
||||
cannot service requests from other processes that do not share the same file
|
||||
descriptor. There should be some daemon that opens the device and allows clients
|
||||
to send requests.
|
||||
|
||||
FastRPC may be the way to offload work to the DSPs. When a FastRPC function call
|
||||
is made, the `<name>_skel_invoke` function in a shared object named
|
||||
`lib<name>_skel.so` is called on the DSP. Further investigation is needed to
|
||||
make a working build system for this.
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Sensor SUID
|
||||
* FastRPC interface list for building method definitions
|
||||
*
|
||||
* Copyright (C) 2022 Richard Acayan
|
||||
* Copyright (C) 2023 The Sensor Shell Contributors
|
||||
*
|
||||
* This file is part of sensh.
|
||||
*
|
||||
@@ -19,9 +19,6 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
#define HEXAGONRPC_BUILD_METHOD_DEFINITIONS 1
|
||||
|
||||
message sns_std_suid {
|
||||
required fixed64 suid_low = 1;
|
||||
required fixed64 suid_high = 2;
|
||||
}
|
||||
#include "interfaces/chre_slpi.def"
|
||||
File renamed without changes.
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* CHRE client daemon entry point
|
||||
*
|
||||
* Copyright (C) 2023 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 <errno.h>
|
||||
#include <libhexagonrpc/fastrpc.h>
|
||||
#include <libhexagonrpc/interfaces/remotectl.def>
|
||||
#include <libhexagonrpc/session.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "interfaces/chre_slpi.def"
|
||||
|
||||
/* TODO move these to libhexagonrpc since most clients use them */
|
||||
static int remotectl_open(int fd, char *name, struct fastrpc_context **ctx, void (*err_cb)(const char *err))
|
||||
{
|
||||
uint32_t handle;
|
||||
int32_t dlret;
|
||||
char err[256];
|
||||
int ret;
|
||||
|
||||
ret = fastrpc2(&remotectl_open_def, fd, REMOTECTL_HANDLE,
|
||||
strlen(name) + 1, name,
|
||||
&handle,
|
||||
&dlret,
|
||||
256, err);
|
||||
|
||||
if (ret == -1) {
|
||||
err_cb(strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dlret == -5) {
|
||||
err_cb(err);
|
||||
return dlret;
|
||||
}
|
||||
|
||||
*ctx = fastrpc_create_context(fd, handle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int remotectl_close(struct fastrpc_context *ctx, void (*err_cb)(const char *err))
|
||||
{
|
||||
uint32_t dlret;
|
||||
char err[256];
|
||||
int ret;
|
||||
|
||||
ret = fastrpc2(&remotectl_close_def, ctx->fd, REMOTECTL_HANDLE,
|
||||
ctx->handle,
|
||||
&dlret,
|
||||
256, err);
|
||||
|
||||
if (ret == -1) {
|
||||
err_cb(strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
fastrpc_destroy_context(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void remotectl_err(const char *err)
|
||||
{
|
||||
fprintf(stderr, "Could not remotectl: %s\n", err);
|
||||
}
|
||||
|
||||
static int chre_slpi_start_thread(struct fastrpc_context *ctx)
|
||||
{
|
||||
return fastrpc(&chre_slpi_start_thread_def, ctx);
|
||||
}
|
||||
|
||||
static int chre_slpi_wait_on_thread_exit(struct fastrpc_context *ctx)
|
||||
{
|
||||
return fastrpc(&chre_slpi_wait_on_thread_exit_def, ctx);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct fastrpc_context *ctx;
|
||||
int fd, ret;
|
||||
|
||||
fd = hexagonrpc_fd_from_env();
|
||||
if (fd == -1)
|
||||
return 1;
|
||||
|
||||
ret = remotectl_open(fd, "chre_slpi", &ctx, remotectl_err);
|
||||
if (ret)
|
||||
return 1;
|
||||
|
||||
ret = chre_slpi_start_thread(ctx);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Could not start CHRE\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = chre_slpi_wait_on_thread_exit(ctx);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Could not wait for CHRE thread\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
remotectl_close(ctx, remotectl_err);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
executable('chrecd',
|
||||
'interfaces.c',
|
||||
'main.c',
|
||||
c_args : cflags,
|
||||
include_directories : include,
|
||||
install : true,
|
||||
link_with : libhexagonrpc,
|
||||
install_dir : client_target,
|
||||
)
|
||||
@@ -1,150 +0,0 @@
|
||||
This directory contains a FastRPC ioctl wrapper and a reverse tunnel.
|
||||
|
||||
FastRPC is used to communicate with the Context Hub Runtime Environment, a
|
||||
program on the DSP that manages sensors, and to serve files to remote
|
||||
processors.
|
||||
|
||||
# Wrapper function
|
||||
|
||||
The wrapper function is designed so that the ioctl arguments do not need to be
|
||||
constructed for each remote method. Instead, it accepts an open file descriptor,
|
||||
handle, method definition, and arguments to the remote method using `va_args`.
|
||||
This makes it relatively easy to add remote methods without the use of the QAIC
|
||||
interface compiler or a free software alternative.
|
||||
|
||||
## Installation
|
||||
|
||||
You can build and install this project using meson:
|
||||
|
||||
~/sensh/fastrpc $ meson setup build
|
||||
~/sensh/fastrpc $ ninja -C build
|
||||
~/sensh/fastrpc # ninja -C build install
|
||||
|
||||
## Usage
|
||||
|
||||
Making already-defined method calls is relatively straightforward, depending on
|
||||
the remote method that you're calling. You just need the function definition, an
|
||||
open file descriptor, the handle, and the arguments for it.
|
||||
|
||||
uint32_t prev_ctx, prev_result, nested_outbufs_len;
|
||||
uint32_t ctx, nested_handle, nested_sc, nested_inbufs_len;
|
||||
uint32_t nested_inbufs_size;
|
||||
const void *nested_outbufs;
|
||||
void *nested_inbufs;
|
||||
int fd;
|
||||
|
||||
ret = fastrpc2(&adsp_listener_next2_def, fd, ADSP_LISTENER_HANDLE,
|
||||
prev_ctx,
|
||||
prev_result,
|
||||
nested_outbufs_len, nested_outbufs,
|
||||
&ctx,
|
||||
&nested_handle,
|
||||
&nested_sc,
|
||||
&nested_inbufs_len,
|
||||
nested_inbufs_size, nested_inbufs);
|
||||
|
||||
All inputs are specified before all outputs. Words in the first (called "prim",
|
||||
or primary in QAIC-generated code) input and output buffers go in the form of
|
||||
`uint32_t` arguments. Each buffer is accepted as a `uint32_t` length and a
|
||||
pointer.
|
||||
|
||||
### Creating function definitions
|
||||
|
||||
Assuming you already have knowledge about the remote method to call, you must
|
||||
first write a function definition for it. A function definition is a struct with
|
||||
information on its method ID and the arguments it accepts.
|
||||
|
||||
First, the method ID is taken from the first argument of the
|
||||
`REMOTE_SCALARS_MAKE()` macro or the second argument of the
|
||||
`REMOTE_SCALARS_MAKEX()` macro
|
||||
(defined [here](https://android.googlesource.com/platform/external/fastrpc/+/d6d6e3bba244e40e6043bd687f4cacf090a767b5/inc/remote.h#80)).
|
||||
|
||||
Example:
|
||||
|
||||
REMOTE_SCALARS_MAKE(4, 2, 2)
|
||||
|
||||
has the method 4.
|
||||
|
||||
Next, information on how many arguments it takes must be specified. There are
|
||||
four types of arguments:
|
||||
|
||||
- 32-bit input words in the first input buffer, excluding lengths for the input
|
||||
and output buffers
|
||||
- 32-bit output words in the first output buffer
|
||||
- input buffers, excluding the first
|
||||
- output buffers, excluding the first
|
||||
|
||||
To get the size of the first input and output buffers, a dump must be consulted,
|
||||
or the prim argument of generated C files:
|
||||
|
||||
invoking via fastrpc, handle 3, method 4, 2 inbufs, 2 outbufs, 0 inhandles, 0 outhandles
|
||||
fastrpc argument 00000000FFFFFFFF0000000000000000 // 16 bytes, or 4 words
|
||||
fastrpc argument
|
||||
invoking via fastrpc, handle 5, method 4, 1 inbufs, 1 outbufs, 0 inhandles, 0 outhandles
|
||||
fastrpc return 91000000000000000002020029000000 // 16 bytes, or 4 words
|
||||
fastrpc return
|
||||
|
||||
Since there are 2 input buffers excluding the first (these can have a variable
|
||||
size), 2 must be subtracted from the 4 input words. These will be provided by
|
||||
the wrapper as the sizes for the variable-length input and output buffers.
|
||||
|
||||
Counting each of these will give the numbers needed for the function definition.
|
||||
|
||||
A function definition looks like:
|
||||
|
||||
const struct fastrpc_function_def_interp2 adsp_listener_next2_def = {
|
||||
.msg_id = 4,
|
||||
.in_nums = 2,
|
||||
.in_bufs = 1,
|
||||
.out_nums = 4,
|
||||
.out_bufs = 1,
|
||||
};
|
||||
|
||||
or:
|
||||
|
||||
#define DEFINE_REMOTE_PROCEDURE(mid, name, \
|
||||
innums, inbufs, \
|
||||
outnums, outbufs) \
|
||||
const struct fastrpc_function_def_interp2 name##_def = { \
|
||||
.msg_id = mid, \
|
||||
.in_nums = innums, \
|
||||
.in_bufs = inbufs, \
|
||||
.out_nums = outnums, \
|
||||
.out_bufs = outbufs, \
|
||||
};
|
||||
|
||||
DEFINE_REMOTE_PROCEDURE(4, adsp_listener_next2, 2, 1, 4, 1)
|
||||
|
||||
# Reverse tunnel
|
||||
|
||||
The reverse tunnel calls the `adsp_listener_next2` remote method to receive
|
||||
method calls for the Application Processor.
|
||||
|
||||
Interfaces are initialized in the `start_reverse_tunnel` function, in hexagonrpcd/rpcd.c.
|
||||
|
||||
## HexagonFS
|
||||
|
||||
The reverse tunnel's `apps_std` interface serves files to the remote processor.
|
||||
These files are searched for in:
|
||||
|
||||
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
|
||||
|
||||
These files and directories should be populated with files from your device's
|
||||
Android firmware.
|
||||
|
||||
# Future plans
|
||||
|
||||
Reverse tunnels are separated by the process that opens the file descriptor and
|
||||
cannot service requests from other processes that do not share the same file
|
||||
descriptor. There should be some daemon that opens the device and allows clients
|
||||
to send requests.
|
||||
|
||||
FastRPC may be the way to offload work to the DSPs. When a FastRPC function call
|
||||
is made, the `<name>_skel_invoke` function in a shared object named
|
||||
`lib<name>_skel.so` is called on the DSP. Further investigation is needed to
|
||||
make a working build system for this.
|
||||
@@ -1,9 +0,0 @@
|
||||
project('fastrpc', 'c')
|
||||
|
||||
include = include_directories('include')
|
||||
|
||||
subdir('libhexagonrpc')
|
||||
|
||||
subdir('hexagonrpcd')
|
||||
|
||||
subdir('tests')
|
||||
@@ -1,13 +0,0 @@
|
||||
valgrind = find_program('valgrind', required : false)
|
||||
|
||||
if valgrind.found()
|
||||
add_test_setup('valgrind', exe_wrapper : valgrind)
|
||||
endif
|
||||
|
||||
test_iobuffer = executable('test_iobuffer',
|
||||
'test_iobuffer.c',
|
||||
'../hexagonrpcd/iobuffer.c',
|
||||
include_directories : include,
|
||||
)
|
||||
|
||||
test('iobuffer', test_iobuffer)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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,
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
@@ -24,5 +24,3 @@
|
||||
#include "interfaces/adsp_default_listener.def"
|
||||
#include "interfaces/apps_std.def"
|
||||
#include "interfaces/adsp_listener.def"
|
||||
#include "interfaces/chre_slpi.def"
|
||||
#include "interfaces/remotectl.def"
|
||||
File renamed without changes.
Loaded 20 of 61 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user