Author SHA1 Message Date
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
9 changed files with 275 additions and 3 deletions

No files matched your search

+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();
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));
+2
View File
@@ -9,6 +9,8 @@ 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
+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
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,
+1
View File
@@ -1,5 +1,6 @@
executable('hexagonrpcd',
'aee_error.c',
'apps_mem.c',
'apps_std.c',
'interfaces.c',
'hexagonfs.c',
+67 -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)
@@ -238,6 +297,7 @@ 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 **progs;
pid_t *pids;
size_t n_progs = 0;
@@ -256,8 +316,11 @@ int main(int argc, char* argv[])
goto err_free_progs;
}
while ((opt = getopt(argc, argv, "d:f:p:R:s")) != -1) {
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 +358,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) {