mirror of
https://github.com/linux-msm/hexagonrpc.git
synced 2026-10-07 15:29:50 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23a69640bf | ||
|
|
18e2ca3178 | ||
|
|
ffca60917c | ||
|
|
6e1281dc8d | ||
|
|
948c5d0d37 | ||
|
|
e52da43a63 | ||
|
|
6e5f7d9d54 | ||
|
|
9a68ca3abf | ||
|
|
146d0e1dab | ||
|
|
2377fd46f0 | ||
|
|
372ca67d7a | ||
|
|
4b1ecd8505 | ||
|
|
53e347f39d | ||
|
|
75150d4860 | ||
|
|
5620db43a7 | ||
|
|
0e9e03b37b | ||
|
|
61bb51bbc9 | ||
|
|
ffbc4da830 | ||
|
|
2415d5f90d | ||
|
|
7aab0f2c42 | ||
|
|
b7eff23db1 | ||
|
|
716e1e27c7 | ||
|
|
54ba43fbc3 | ||
|
|
f6d8a0e686 | ||
|
|
9db873f24f | ||
|
|
3f46980dc9 | ||
|
|
30fa49eb20 | ||
|
|
b7ad1021a2 | ||
|
|
f23297f962 | ||
|
|
c4c469bd8a | ||
|
|
6840e1dcfa | ||
|
|
aaef8a1e28 | ||
|
|
63b1711021 | ||
|
|
39dd3aec6e | ||
|
|
892b9f549e | ||
|
|
b410c74a81 | ||
|
|
24c3eea173 | ||
|
|
8949140fa6 | ||
|
|
154bd2631c | ||
|
|
b4db2118cb | ||
|
|
ecd901bc48 | ||
|
|
a31ec9caf9 | ||
|
|
0156911ba4 | ||
|
|
c82b2da4eb | ||
|
|
cd314096a3 | ||
|
|
1162ccd84c | ||
|
|
a56406c928 | ||
|
|
4054893648 | ||
|
|
d6c458bd17 | ||
|
|
753ebda39b | ||
|
|
1dc590d638 | ||
|
|
f085f578e3 | ||
|
|
0b4c7bffaf | ||
|
|
00b5f80608 | ||
|
|
9ea9bed77b | ||
|
|
23585daf67 |
No files matched your search
@@ -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
|
||||
@@ -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,65 +1,158 @@
|
||||
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 (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. The watch command is only valid if
|
||||
the stream type is 1 or 2.
|
||||
### 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 a directory tree, starting at the location
|
||||
defined by the `-R` option, or in `/usr/share/qcom` by default:
|
||||
|
||||
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
|
||||
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,294 +0,0 @@
|
||||
/*
|
||||
* FastRPC Example
|
||||
*
|
||||
* 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 <fcntl.h>
|
||||
#include <libhexagonrpc/fastrpc.h>
|
||||
#include <misc/fastrpc.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "aee_error.h"
|
||||
#include "apps_std.h"
|
||||
#include "hexagonfs.h"
|
||||
#include "interfaces/adsp_default_listener.def"
|
||||
#include "interfaces/chre_slpi.def"
|
||||
#include "interfaces/remotectl.def"
|
||||
#include "listener.h"
|
||||
#include "localctl.h"
|
||||
#include "rpcd_builder.h"
|
||||
|
||||
struct listener_thread_args {
|
||||
int fd;
|
||||
char *device_dir;
|
||||
char *dsp;
|
||||
};
|
||||
|
||||
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;
|
||||
} else if (dlret) {
|
||||
err_cb(aee_strerror[dlret]);
|
||||
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;
|
||||
}
|
||||
|
||||
if (dlret) {
|
||||
err_cb(aee_strerror[dlret]);
|
||||
return dlret;
|
||||
}
|
||||
|
||||
fastrpc_destroy_context(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adsp_default_listener_register(struct fastrpc_context *ctx)
|
||||
{
|
||||
return fastrpc(&adsp_default_listener_register_def, ctx);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void remotectl_err(const char *err)
|
||||
{
|
||||
fprintf(stderr, "Could not remotectl: %s\n", err);
|
||||
}
|
||||
|
||||
static int register_fastrpc_listener(int fd)
|
||||
{
|
||||
struct fastrpc_context *ctx;
|
||||
int ret;
|
||||
|
||||
ret = remotectl_open(fd, "adsp_default_listener", &ctx, remotectl_err);
|
||||
if (ret)
|
||||
return 1;
|
||||
|
||||
ret = adsp_default_listener_register(ctx);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Could not register ADSP default listener\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
remotectl_close(ctx, remotectl_err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *start_reverse_tunnel(void *data)
|
||||
{
|
||||
struct listener_thread_args *args = data;
|
||||
struct fastrpc_interface **ifaces;
|
||||
struct hexagonfs_dirent *root_dir;
|
||||
size_t n_ifaces = 2;
|
||||
int ret;
|
||||
|
||||
ifaces = malloc(sizeof(struct fastrpc_interface) * n_ifaces);
|
||||
if (ifaces == NULL)
|
||||
return NULL;
|
||||
|
||||
root_dir = construct_root_dir(args->device_dir, args->dsp);
|
||||
|
||||
/*
|
||||
* The apps_remotectl interface patiently waits for this function to
|
||||
* fully populate the ifaces array as long as it receives a pointer to
|
||||
* it.
|
||||
*/
|
||||
ifaces[REMOTECTL_HANDLE] = fastrpc_localctl_init(n_ifaces, ifaces);
|
||||
|
||||
// Dynamic interfaces with no hardcoded handle
|
||||
ifaces[1] = fastrpc_apps_std_init(root_dir);
|
||||
|
||||
ret = register_fastrpc_listener(args->fd);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
run_fastrpc_listener(args->fd, n_ifaces, ifaces);
|
||||
|
||||
fastrpc_localctl_deinit(ifaces[REMOTECTL_HANDLE]);
|
||||
|
||||
free(ifaces);
|
||||
|
||||
return NULL;
|
||||
|
||||
err:
|
||||
free(ifaces);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *start_chre_client(void *data)
|
||||
{
|
||||
struct fastrpc_context *ctx;
|
||||
int *fd = data;
|
||||
int ret;
|
||||
|
||||
ret = remotectl_open(*fd, "chre_slpi", &ctx, remotectl_err);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t chre_thread, listener_thread;
|
||||
struct listener_thread_args *listener_args;
|
||||
char *fastrpc_node = NULL;
|
||||
int fd, ret, opt;
|
||||
bool attach_sns = false;
|
||||
|
||||
listener_args = malloc(sizeof(struct listener_thread_args));
|
||||
if (listener_args == NULL) {
|
||||
perror("Could not create listener arguments");
|
||||
goto err_close_dev;
|
||||
}
|
||||
|
||||
listener_args->device_dir = "/usr/share/qcom/";
|
||||
listener_args->dsp = "adsp";
|
||||
|
||||
while ((opt = getopt(argc, argv, "d:f:R:s")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
listener_args->dsp = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
fastrpc_node = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
listener_args->device_dir = optarg;
|
||||
break;
|
||||
case 's':
|
||||
attach_sns = true;
|
||||
break;
|
||||
default:
|
||||
printf("Usage: %s [-s] [-f FastRPC node]\n\n", argv[0]);
|
||||
printf("Qualcomm Hexagon filesystem daemon\n\n"
|
||||
"\t-d\tDSP libraries subdirectory (default: adsp)\n"
|
||||
"\t-f\tFastRPC node to attach to\n"
|
||||
"\t-R\tDirectory of served files (default: /usr/share/qcom/)\n"
|
||||
"\t-s\tUse INIT_ATTACH_SNS instead of INIT_ATTACH ioctl\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fastrpc_node) {
|
||||
fprintf(stderr, "Invalid FastRPC node: %s\n", fastrpc_node);
|
||||
return 2;
|
||||
}
|
||||
|
||||
printf("Starting %s (%s) on %s\n", argv[0], attach_sns? "INIT_ATTACH_SNS": "INIT_ATTACH", fastrpc_node);
|
||||
|
||||
fd = open(fastrpc_node, O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open FastRPC node (%s): %s\n", fastrpc_node, strerror(errno));
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (attach_sns)
|
||||
ret = ioctl(fd, FASTRPC_IOCTL_INIT_ATTACH_SNS, NULL);
|
||||
else
|
||||
ret = ioctl(fd, FASTRPC_IOCTL_INIT_ATTACH, NULL);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Could not attach to FastRPC node: %s\n", strerror(errno));
|
||||
goto err_close_dev;
|
||||
}
|
||||
|
||||
listener_args->fd = fd;
|
||||
|
||||
pthread_create(&listener_thread, NULL, start_reverse_tunnel, listener_args);
|
||||
pthread_create(&chre_thread, NULL, start_chre_client, &fd);
|
||||
|
||||
pthread_join(listener_thread, NULL);
|
||||
pthread_join(chre_thread, NULL);
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
|
||||
err_close_dev:
|
||||
close(fd);
|
||||
return 4;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
project('fastrpc', 'c')
|
||||
|
||||
include = include_directories('include')
|
||||
|
||||
subdir('libhexagonrpc')
|
||||
|
||||
subdir('hexagonrpcd')
|
||||
File renamed without changes.
File renamed without changes.
@@ -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,
|
||||
};
|
||||
@@ -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
|
||||
@@ -172,12 +172,6 @@ static uint32_t apps_std_fopen_with_env(void *data,
|
||||
return AEE_EUNSUPPORTED;
|
||||
}
|
||||
|
||||
if (ctx->rootfd < 0) {
|
||||
fprintf(stderr, "Could not open virtual root directory: %s\n",
|
||||
strerror(-ctx->rootfd));
|
||||
return AEE_EFAILED;
|
||||
}
|
||||
|
||||
if (!strcmp(inbufs[1].p, "ADSP_LIBRARY_PATH")) {
|
||||
dirfd = ctx->adsp_library_dirfd;
|
||||
} else if (!strcmp(inbufs[1].p, "ADSP_AVS_CFG_PATH")) {
|
||||
@@ -225,12 +219,6 @@ static uint32_t apps_std_opendir(void *data,
|
||||
if (((const char *) inbufs[1].p)[inbufs[1].s - 1] != 0)
|
||||
return AEE_EBADPARM;
|
||||
|
||||
if (ctx->rootfd < 0) {
|
||||
fprintf(stderr, "Could not open virtual root directory: %s\n",
|
||||
strerror(-ctx->rootfd));
|
||||
return AEE_EFAILED;
|
||||
}
|
||||
|
||||
ret = hexagonfs_openat(ctx->fds, ctx->rootfd, ctx->rootfd, inbufs[1].p);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open %s: %s\n",
|
||||
@@ -302,7 +290,6 @@ static uint32_t apps_std_stat(void *data,
|
||||
struct fastrpc_io_buffer *outbufs)
|
||||
{
|
||||
struct apps_std_ctx *ctx = data;
|
||||
char *pathname;
|
||||
struct {
|
||||
uint64_t tsz; // Unknown purpose
|
||||
uint64_t dev;
|
||||
@@ -318,31 +305,25 @@ static uint32_t apps_std_stat(void *data,
|
||||
int64_t ctime;
|
||||
int64_t ctimensec;
|
||||
} *first_out = outbufs[0].p;
|
||||
const char *pathname = inbufs[1].p;
|
||||
struct stat stats;
|
||||
int fd, ret;
|
||||
|
||||
pathname = malloc(inbufs[1].s + 1);
|
||||
memcpy(pathname, inbufs[1].p, inbufs[1].s);
|
||||
pathname[inbufs[1].s] = 0;
|
||||
if (((const char *) inbufs[1].p)[inbufs[1].s - 1] != 0)
|
||||
return AEE_EBADPARM;
|
||||
|
||||
if (ctx->rootfd < 0) {
|
||||
fprintf(stderr, "Could not open virtual root directory: %s\n",
|
||||
strerror(-ctx->rootfd));
|
||||
return AEE_EFAILED;
|
||||
}
|
||||
|
||||
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));
|
||||
goto err_free_pathname;
|
||||
return AEE_EFAILED;
|
||||
}
|
||||
|
||||
ret = hexagonfs_fstat(ctx->fds, fd, &stats);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Could not stat %s: %s\n",
|
||||
pathname, strerror(-fd));
|
||||
goto err_free_pathname;
|
||||
return AEE_EFAILED;
|
||||
}
|
||||
|
||||
hexagonfs_close(ctx->fds, fd);
|
||||
@@ -366,13 +347,7 @@ static uint32_t apps_std_stat(void *data,
|
||||
first_out->ctime = (int64_t) stats.st_ctim.tv_nsec;
|
||||
first_out->ctimensec = (int64_t) stats.st_ctim.tv_nsec;
|
||||
|
||||
free(pathname);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_pathname:
|
||||
free(pathname);
|
||||
return AEE_EFAILED;
|
||||
}
|
||||
|
||||
struct fastrpc_interface *fastrpc_apps_std_init(struct hexagonfs_dirent *root)
|
||||
@@ -386,28 +361,30 @@ struct fastrpc_interface *fastrpc_apps_std_init(struct hexagonfs_dirent *root)
|
||||
|
||||
ctx = calloc(1, sizeof(struct apps_std_ctx));
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
goto err_free_iface;
|
||||
|
||||
memcpy(iface, &apps_std_interface, sizeof(struct fastrpc_interface));
|
||||
|
||||
ctx->rootfd = hexagonfs_open_root(ctx->fds, root);
|
||||
if (ctx->rootfd < 0)
|
||||
goto err_free_ctx;
|
||||
|
||||
if (ctx->rootfd >= 0) {
|
||||
ctx->adsp_avs_cfg_dirfd = hexagonfs_openat(ctx->fds,
|
||||
ctx->rootfd,
|
||||
ctx->rootfd,
|
||||
"/vendor/etc/acdbdata/");
|
||||
ctx->adsp_library_dirfd = hexagonfs_openat(ctx->fds,
|
||||
ctx->rootfd,
|
||||
ctx->rootfd,
|
||||
"/usr/lib/qcom/adsp/");
|
||||
}
|
||||
ctx->adsp_avs_cfg_dirfd = hexagonfs_openat(ctx->fds,
|
||||
ctx->rootfd,
|
||||
ctx->rootfd,
|
||||
"/vendor/etc/acdbdata/");
|
||||
ctx->adsp_library_dirfd = hexagonfs_openat(ctx->fds,
|
||||
ctx->rootfd,
|
||||
ctx->rootfd,
|
||||
"/usr/lib/qcom/adsp/");
|
||||
|
||||
iface->data = ctx;
|
||||
|
||||
return iface;
|
||||
|
||||
err:
|
||||
err_free_ctx:
|
||||
free(ctx);
|
||||
err_free_iface:
|
||||
free(iface);
|
||||
|
||||
return NULL;
|
||||
File renamed without changes.
@@ -69,8 +69,11 @@ static struct hexagonfs_fd *pop_dir(struct hexagonfs_fd *dir,
|
||||
|
||||
if (dir != root && dir->up != NULL) {
|
||||
up = dir->up;
|
||||
dir->ops->close(dir->data);
|
||||
free(dir);
|
||||
|
||||
if (!dir->is_assigned) {
|
||||
dir->ops->close(dir->data);
|
||||
free(dir);
|
||||
}
|
||||
} else {
|
||||
up = dir;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -110,6 +110,7 @@ static int mapped_openat(struct hexagonfs_fd *dir,
|
||||
|
||||
ctx->dir = NULL;
|
||||
|
||||
fd->is_assigned = false;
|
||||
fd->up = dir;
|
||||
fd->ops = &hexagonfs_mapped_ops;
|
||||
fd->data = ctx;
|
||||
@@ -221,13 +222,13 @@ 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;
|
||||
|
||||
ret = mapped_from_dirent(dirent_data, dir, fd_data);
|
||||
if (ret)
|
||||
fd_data = NULL;
|
||||
*fd_data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+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;
|
||||
|
||||
Loaded 20 of 64 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user