diff --git a/.gitignore b/.gitignore
index 38df5eb..066083f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ libtool
stamp-h1
.deps/
+.dirstamp
.libs/
# Compiled objects
@@ -31,10 +32,14 @@ stamp-h1
*.lo
*.la
+# Generated service units
+files/*.service
+
# Compiled programs
src/adsprpcd
src/cdsprpcd
src/sdsprpcd
+src/gdsprpcd
test/fastrpc_test
# make dist tarballs
diff --git a/Docs/images/Term_definitions.png b/Docs/images/Term_definitions.png
deleted file mode 100644
index 9875fdb..0000000
Binary files a/Docs/images/Term_definitions.png and /dev/null differ
diff --git a/Makefile.am b/Makefile.am
index f068b7c..111c639 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = inc src test
+SUBDIRS = inc src test files
ACLOCAL_AMFLAGS = -I m4
diff --git a/README.md b/README.md
index 55888c7..e5857a4 100644
--- a/README.md
+++ b/README.md
@@ -12,19 +12,108 @@ FastRPC interfaces are defined in an IDL file, and they are compiled using the Q
The following diagram depicts the major FastRPC software components on the CPU and DSP.
-
+```mermaid
+flowchart TB
+subgraph SMD["FastRPC Architecture"]
+direction TB
+
+subgraph TOP[" "]
+direction LR
+
+subgraph CPU["CPU"]
+direction TB
+subgraph Application["Application"]
+direction TB
+Stub["Stub"]
+FRPC_UD["FastRPC
user
driver"]
+end
+FRPC_KD["FastRPC Kernel
driver"]
+end
+
+subgraph DSP["DSP"]
+direction TB
+subgraph User_PD["User PD"]
+direction TB
+Skel["Skel"]
+FRPC_DD["FastRPC
DSP user
driver"]
+end
+FRPC_DSP_KD["FastRPC DSP
driver"]
+end
+
+end
+end
+
+classDef generated fill:#E6E6FA,stroke:#9370DB,color:#000
+classDef fastrpc fill:#4169E1,stroke:#000,color:#000
+classDef shared fill:#FAFAFA,stroke:#666,color:#000
+classDef userpdbox fill:#ABDBE3,stroke:#666,color:#000
+classDef mainbox fill:#7FB3CD,stroke:#666,color:#000
+classDef topbox fill:none,stroke:none,color:none
+
+class Stub,Skel generated
+class FRPC_UD,FRPC_KD,FRPC_DD,FRPC_DSP_KD fastrpc
+class SMD shared
+class Application,User_PD userpdbox
+class CPU,DSP mainbox
+class TOP topbox
+
+Stub <--> FRPC_UD
+FRPC_UD <--> FRPC_KD
+FRPC_KD <--> |rpmsg| FRPC_DSP_KD
+FRPC_DSP_KD <--> FRPC_DD
+FRPC_DD <--> Skel
+
+linkStyle default stroke:#000
+```
-**Stub and skel** are generated by the IDL compiler. Other modules are part of the software stack on the device.
+**Stub** and **Skel** are generated by the IDL compiler. The modules shown in blue blocks in the diagram are part of the FastRPC software stack on the device.
**Definition of the terms in the diagram:**
-
-
+| Term | Description |
+|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
+| Application | User mode process that initiates the remote invocation |
+| Stub | Auto-generated code that takes care of marshaling parameters and runs on the CPU |
+| FastRPC user driver on CPU | User mode library that is used by the stub code to do remote invocations |
+| FastRPC Kernel Driver | Receives the remote invocations from the client, queues them up for transport to the DSP side over rpmsg, and then waits for the response after signaling the remote side |
+| rpmsg | Remote Processor Messaging is the transport mechanism used between the CPU-side FastRPC kernel driver and the DSP-side FastRPC driver to exchange FastRPC requests and responses |
+| FastRPC DSP Driver | Dequeues the messages received over rpmsg from the FastRPC kernel driver and dispatches them for processing |
+| FastRPC user driver on DSP | User mode code that includes a shell executable to run in the user protection domain (PD) on the DSP and complete the remote invocations to the skel library |
+| Skel | Auto-generated code that un-marshals parameters and invokes the user-defined implementation of the function that runs on the DSP |
+| User PD | User protection domain on the DSP that provides the environment to run the user code |
+
### FastRPC Workflow
The FastRPC framework consists of the following components.
-
+```mermaid
+flowchart LR
+subgraph CPU
+UC[User Code]
+Stub[Stub]
+FF[FastRPC Framework]
+end
+subgraph DSP
+FD[FastRPC DSP Framework]
+Skel[Skel]
+MI[Method Implementation]
+end
+UC --> |" 1 "| Stub
+Stub --> |" 10 "| UC
+Stub --> |" 2 "| FF
+FF --> |" 9 "| Stub
+FF --> |" 3 "| FD
+FD --> |" 8 "| FF
+FD --> |" 4 "| Skel
+Skel --> |" 7 "| FD
+Skel --> |" 5 "| MI
+MI --> |" 6 "| Skel
+classDef generated fill:#E6E6FA,stroke:#9370DB,color:#2A0066
+classDef fastrpc fill:#4169E1,stroke:#000,color:#FFFFFF
+classDef shared fill:#F5F5F5,stroke:#666
+class UC,Stub,Skel,MI generated
+class FF,FD fastrpc
+```
**Workflow:**
@@ -46,6 +135,35 @@ Hexagon SDK documentation covers all the required details about FastRPC. Please
## Build & Installation
+### Setting up the fastrpc group
+
+The udev rules set `/dev/fastrpc-*dsp` device nodes to `root:fastrpc` with `0640` permissions and
+grant the `fastrpc` group read/write access to `/dev/dma_heap/system` (required for memory allocation).
+Applications that use `libfastrpc` must therefore belong to the `fastrpc` group.
+
+The build system installs a `sysusers.d` configuration file that automatically creates the `fastrpc` group when `systemd-sysusers` runs (typically at boot or via package manager triggers).
+
+To manually create the group:
+
+```bash
+groupadd --system fastrpc
+```
+
+Or trigger systemd-sysusers:
+
+```bash
+sudo systemd-sysusers
+```
+
+To grant an application user access to FastRPC devices:
+
+```bash
+usermod -aG fastrpc
+```
+
+The services are automatically started by udev when FastRPC devices are detected.
+No manual `systemctl enable` is required.
+
### Steps to Generate Native Binaries on Device
```bash
@@ -53,16 +171,50 @@ git clone https://github.com/quic/fastrpc
cd fastrpc
./gitcompile
sudo make install
+sudo ldconfig # Update dynamic linker cache
+sudo systemd-sysusers # Create fastrpc group
```
-### Steps to Generate ARM Binaries Using Linaro Toolchain on Ubuntu Build Machine
+### Steps to cross-compile the project on Ubuntu
+
+1. **Install the cross compiler and required dependencies:**
+
+ Install cross-compilation toolchain:
+ ```bash
+ sudo apt install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu
+ ```
-1. **Install Linaro tools and add the tools bin location to the path:**
+ Install and build libyaml:
+ ```bash
+ git clone https://github.com/yaml/libyaml.git
+ cd libyaml
+ ./bootstrap
+ ./configure --host=aarch64-linux-gnu
+ make
+ sudo make install
+ cd ..
+ ```
+
+ Install and build libmd:
+ ```bash
+ git clone https://git.hadrons.org/git/libmd.git
+ cd libmd
+ ./autogen
+ ./configure --host=aarch64-linux-gnu
+ make
+ sudo make install
+ cd ..
+ ```
+ Install and build libbsd:
```bash
- wget -c https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-i686_aarch64-linux-gnu.tar.xz
- tar xf gcc-linaro-7.5.0-2019.12-i686_aarch64-linux-gnu.tar.xz
- export PATH="$PATH:/toolchain/bin"
+ git clone https://gitlab.freedesktop.org/libbsd/libbsd.git
+ cd libbsd
+ ./autogen
+ ./configure --host=aarch64-linux-gnu
+ make
+ sudo make install
+ cd ..
```
2. **Create softlink files for the compiler, linker, and other tools. Create environment variables as below for the auto tools:**
@@ -196,4 +348,4 @@ Thanks for your interest in contributing to FastRPC! Please read our [Contributi
## License
-FastRPC is licensed under the BSD 3-clause "New" or "Revised" License. Check out the [LICENSE](LICENSE.txt) for more details.
\ No newline at end of file
+FastRPC is licensed under the BSD 3-clause "New" or "Revised" License. Check out the [LICENSE](LICENSE.txt) for more details.
diff --git a/ci/MACHINES.json b/ci/MACHINES.json
index 44d8ecd..df35c5a 100644
--- a/ci/MACHINES.json
+++ b/ci/MACHINES.json
@@ -16,5 +16,11 @@
"linuxFirmware": "qcs8300",
"lavaDeviceName": "qcs8300-ride",
"hexDSPBinary": "qcs8300"
+ },
+ "qcs615-ride": {
+ "deviceTree": "qcs615-ride",
+ "linuxFirmware": "qcs615",
+ "lavaDeviceName": "qcs615-ride",
+ "hexDSPBinary": "qcs615"
}
}
\ No newline at end of file
diff --git a/ci/build.sh b/ci/build.sh
new file mode 100755
index 0000000..d4f890d
--- /dev/null
+++ b/ci/build.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/bash
+# Copyright (c) Qualcomm Technologies, Inc.
+# SPDX-License-Identifier: BSD-3-Clause-Clear
+
+set -euo pipefail
+
+echo "Configuring APT for amd64 + arm64 (ports)..."
+# Detect Ubuntu codename
+CODENAME="$(. /etc/os-release; echo "${VERSION_CODENAME}")"
+: "${CODENAME:?Failed to read VERSION_CODENAME from /etc/os-release}"
+echo "Detected Ubuntu codename: ${CODENAME}"
+
+# 1) Enable ARM64 multiarch
+sudo dpkg --add-architecture arm64
+
+# 2) Overwrite main sources to be amd64-only (archive + security)
+sudo tee /etc/apt/sources.list > /dev/null < /dev/null < Tue, 09 Jun 2026 13:23:26 +0000
+ [ GitHub Service Bot ]
+ * New upstream release
+
+ -- GitHub Service Bot Thu, 02 Jul 2026 18:30:16 +0000
diff --git a/files/60-fastrpc.rules b/files/60-fastrpc.rules
new file mode 100644
index 0000000..546de35
--- /dev/null
+++ b/files/60-fastrpc.rules
@@ -0,0 +1,19 @@
+# Applications that use libfastrpc must belong to the fastrpc group
+
+# DMA heap access required for fastrpc
+ACTION=="add", SUBSYSTEM=="dma_heap", KERNEL=="system", RUN+="/bin/setfacl -m g:fastrpc:rw $env{DEVNAME}"
+
+# FastRPC DSP device nodes
+# Device nodes are owned by root:fastrpc with 0640 permissions
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-adsp", OWNER="root", GROUP="fastrpc", MODE="0640", TAG+="systemd", ENV{SYSTEMD_WANTS}+="adsprpcd.service", ENV{SYSTEMD_WANTS}+="adsprpcd_audiopd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-adsp-secure", TAG+="systemd", ENV{SYSTEMD_WANTS}+="adsprpcd.service", ENV{SYSTEMD_WANTS}+="adsprpcd_audiopd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-cdsp", OWNER="root", GROUP="fastrpc", MODE="0640", TAG+="systemd", ENV{SYSTEMD_WANTS}+="cdsprpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-cdsp-secure", TAG+="systemd", ENV{SYSTEMD_WANTS}+="cdsprpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-cdsp1", OWNER="root", GROUP="fastrpc", MODE="0640", TAG+="systemd", ENV{SYSTEMD_WANTS}+="cdsp1rpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-cdsp1-secure", TAG+="systemd", ENV{SYSTEMD_WANTS}+="cdsp1rpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-gdsp0", OWNER="root", GROUP="fastrpc", MODE="0640", TAG+="systemd", ENV{SYSTEMD_WANTS}+="gdsp0rpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-gdsp0-secure", TAG+="systemd", ENV{SYSTEMD_WANTS}+="gdsp0rpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-gdsp1", OWNER="root", GROUP="fastrpc", MODE="0640", TAG+="systemd", ENV{SYSTEMD_WANTS}+="gdsp1rpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-gdsp1-secure", TAG+="systemd", ENV{SYSTEMD_WANTS}+="gdsp1rpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-sdsp", OWNER="root", GROUP="fastrpc", MODE="0640", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sdsprpcd.service"
+ACTION=="add", SUBSYSTEM=="misc", KERNEL=="fastrpc-sdsp-secure", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sdsprpcd.service"
diff --git a/files/Makefile.am b/files/Makefile.am
new file mode 100644
index 0000000..31a8b3d
--- /dev/null
+++ b/files/Makefile.am
@@ -0,0 +1,41 @@
+# Systemd service files
+
+# Define systemd unit directory
+systemdsystemunitdir = @systemdsystemunitdir@
+
+# List of systemd service files to install (generated from .in templates)
+systemdsystemunit_DATA = \
+ adsprpcd.service \
+ adsprpcd_audiopd.service \
+ cdsprpcd.service \
+ cdsp1rpcd.service \
+ gdsp0rpcd.service \
+ gdsp1rpcd.service \
+ sdsprpcd.service
+
+# Service template files
+EXTRA_DIST = \
+ adsprpcd.service.in \
+ adsprpcd_audiopd.service.in \
+ cdsprpcd.service.in \
+ cdsp1rpcd.service.in \
+ gdsp0rpcd.service.in \
+ gdsp1rpcd.service.in \
+ sdsprpcd.service.in
+
+# Generate service files from templates with sed substitution
+%.service: %.service.in Makefile
+ $(AM_V_GEN)$(SED) \
+ -e 's|@sbindir[@]|$(sbindir)|g' \
+ $< > $@
+
+# Clean generated service files
+CLEANFILES = $(systemdsystemunit_DATA)
+
+# sysusers.d file for creating fastrpc group
+sysusersdir = @sysusersdir@
+dist_sysusers_DATA = fastrpc.conf
+
+# udev rules
+udevrulesdir = @udevrulesdir@
+dist_udevrules_DATA = 60-fastrpc.rules
diff --git a/files/adsprpcd.service.in b/files/adsprpcd.service.in
new file mode 100644
index 0000000..a16e136
--- /dev/null
+++ b/files/adsprpcd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=aDSP RPC daemon
+After=dev-fastrpc\x2dadsp.device dev-fastrpc\x2dadsp\x2dsecure.device
+ConditionPathExists=|/dev/fastrpc-adsp
+ConditionPathExists=|/dev/fastrpc-adsp-secure
+
+[Service]
+Type=exec
+ExecStart=@sbindir@/adsprpcd
+Restart=on-failure
+RestartSec=5
diff --git a/files/adsprpcd_audiopd.service.in b/files/adsprpcd_audiopd.service.in
new file mode 100644
index 0000000..617e56e
--- /dev/null
+++ b/files/adsprpcd_audiopd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=audiopd aDSP RPC daemon
+After=dev-fastrpc\x2dadsp.device dev-fastrpc\x2dadsp\x2dsecure.device
+ConditionPathExists=|/dev/fastrpc-adsp
+ConditionPathExists=|/dev/fastrpc-adsp-secure
+
+[Service]
+Type=exec
+ExecStart=@sbindir@/adsprpcd audiopd
+Restart=on-failure
+RestartSec=5
diff --git a/files/cdsp1rpcd.service.in b/files/cdsp1rpcd.service.in
new file mode 100644
index 0000000..dac5f8d
--- /dev/null
+++ b/files/cdsp1rpcd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=cDSP RPC daemon
+After=dev-fastrpc\x2dcdsp1.device dev-fastrpc\x2dcdsp1\x2dsecure.device
+ConditionPathExists=|/dev/fastrpc-cdsp1
+ConditionPathExists=|/dev/fastrpc-cdsp1-secure
+
+[Service]
+Type=exec
+ExecStart=@sbindir@/cdsprpcd rootpd cdsp1
+Restart=on-failure
+RestartSec=5
diff --git a/files/cdsprpcd.service.in b/files/cdsprpcd.service.in
new file mode 100644
index 0000000..70c4d94
--- /dev/null
+++ b/files/cdsprpcd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=cDSP RPC daemon
+After=dev-fastrpc\x2dcdsp.device dev-fastrpc\x2dcdsp\x2dsecure.device
+ConditionPathExists=|/dev/fastrpc-cdsp
+ConditionPathExists=|/dev/fastrpc-cdsp-secure
+
+[Service]
+Type=exec
+ExecStart=@sbindir@/cdsprpcd
+Restart=on-failure
+RestartSec=5
diff --git a/files/fastrpc.conf b/files/fastrpc.conf
new file mode 100644
index 0000000..c55042a
--- /dev/null
+++ b/files/fastrpc.conf
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# This file is part of fastrpc. It creates the fastrpc system group.
+#
+#Type Name ID GECOS Home directory Shell
+g fastrpc - - - -
diff --git a/files/gdsp0rpcd.service.in b/files/gdsp0rpcd.service.in
new file mode 100644
index 0000000..1503941
--- /dev/null
+++ b/files/gdsp0rpcd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=gDSP RPC daemon
+After=dev-fastrpc\x2dgdsp0.device dev-fastrpc\x2dgdsp0\x2dsecure.device
+ConditionPathExists=|/dev/fastrpc-gdsp0
+ConditionPathExists=|/dev/fastrpc-gdsp0-secure
+
+[Service]
+Type=exec
+ExecStart=@sbindir@/gdsprpcd rootpd gdsp0
+Restart=on-failure
+RestartSec=5
diff --git a/files/gdsp1rpcd.service.in b/files/gdsp1rpcd.service.in
new file mode 100644
index 0000000..66d4bbc
--- /dev/null
+++ b/files/gdsp1rpcd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=gDSP RPC daemon
+After=dev-fastrpc\x2dgdsp1.device dev-fastrpc\x2dgdsp1\x2dsecure.device
+ConditionPathExists=|/dev/fastrpc-gdsp1
+ConditionPathExists=|/dev/fastrpc-gdsp1-secure
+
+[Service]
+Type=exec
+ExecStart=@sbindir@/gdsprpcd rootpd gdsp1
+Restart=on-failure
+RestartSec=5
diff --git a/files/sdsprpcd.service.in b/files/sdsprpcd.service.in
new file mode 100644
index 0000000..150cacf
--- /dev/null
+++ b/files/sdsprpcd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=sDSP RPC daemon
+After=dev-fastrpc\x2dsdsp.device dev-fastrpc\x2dsdsp\x2dsecure.device
+ConditionPathExists=|/dev/fastrpc-sdsp
+ConditionPathExists=|/dev/fastrpc-sdsp-secure
+
+[Service]
+Type=exec
+ExecStart=@sbindir@/sdsprpcd
+Restart=on-failure
+RestartSec=5
diff --git a/gitcompile b/gitcompile
index 4f8f7d2..3fb6d76 100755
--- a/gitcompile
+++ b/gitcompile
@@ -2,11 +2,15 @@
autoreconf -is
-export CFLAGS='-O2 -Wall -pipe -g'
+# Set default build flags if not already set
+# Users can override by setting CFLAGS before running this script
+if [ -z "$CFLAGS" ]; then
+ export CFLAGS="-O2 -Wall -pipe -g"
+fi
+
echo "CFLAGS=$CFLAGS"
echo "./configure $@"
./configure $@ || exit 1
-unset CFLAGS
if [ -z "$GITCOMPILE_NO_MAKE" ]; then
make
fi
diff --git a/inc/Makefile.am b/inc/Makefile.am
index dd76127..a22db62 100644
--- a/inc/Makefile.am
+++ b/inc/Makefile.am
@@ -36,7 +36,6 @@ noinst_HEADERS = \
dspqueue_shared.h \
dspsignal.h \
fastrpc_apps_user.h \
- fastrpc_async.h \
fastrpc_cap.h \
fastrpc_common.h \
fastrpc_config.h \
@@ -45,7 +44,6 @@ noinst_HEADERS = \
fastrpc_hash_table.h \
fastrpc_internal.h \
fastrpc_ioctl.h \
- fastrpc_latency.h \
fastrpc_log.h \
fastrpc_mem.h \
fastrpc_notif.h \
diff --git a/inc/apps_std_internal.h b/inc/apps_std_internal.h
index 37be0c2..d4ce4fe 100644
--- a/inc/apps_std_internal.h
+++ b/inc/apps_std_internal.h
@@ -18,7 +18,6 @@
// Environment variable name, that can be used to override the search paths
#define ADSP_LIBRARY_PATH "ADSP_LIBRARY_PATH"
#define DSP_LIBRARY_PATH "DSP_LIBRARY_PATH"
-#define ADSP_AVS_PATH "ADSP_AVS_CFG_PATH"
#define MAX_NON_PRELOAD_LIBS_LEN 2048
#define FILE_EXT ".so"
@@ -29,11 +28,6 @@
#define VENDOR_DOM_LOCATION "/vendor/dsp/xdsp/"
#endif
-// Search path used by fastRPC for acdb path
-#ifndef ADSP_AVS_CFG_PATH
-#define ADSP_AVS_CFG_PATH ";/etc/acdbdata/;"
-#endif
-
int fopen_from_dirlist(const char *dirList, const char *delim,
const char *mode, const char *name, apps_std_FILE *psout);
diff --git a/inc/fastrpc_async.h b/inc/fastrpc_async.h
deleted file mode 100644
index 76c244d..0000000
--- a/inc/fastrpc_async.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef FASTRPC_ASYNC_H
-#define FASTRPC_ASYNC_H
-
-#include "remote64.h"
-#include "fastrpc_internal.h"
-
-#define POS_TO_MASK(pos) ((1UL << pos) - 1)
-
-#define FASTRPC_ASYNC_JOB_POS 4 // Position in jobid where job starts
-
-// Store jobs in Queue. Index of queue calculated based on hash value of job. Always needs to be 2^value
-#define FASTRPC_ASYNC_QUEUE_LIST_LEN 16
-
-// Position where hash ends in jobid
-#define FASTRPC_ASYNC_HASH_IDX_POS (FASTRPC_ASYNC_JOB_POS + (FASTRPC_ASYNC_QUEUE_LIST_LEN >> 2))
-
-// Position in jobid where timespec starts
-#define FASTRPC_ASYNC_TIME_SPEC_POS 48
-
-#define SECONDS_PER_HOUR (3600)
-
-#define FASTRPC_ASYNC_DOMAIN_MASK (POS_TO_MASK(FASTRPC_ASYNC_JOB_POS))
-#define FASTRPC_ASYNC_JOB_CNT_MASK (POS_TO_MASK(FASTRPC_ASYNC_TIME_SPEC_POS) & ~FASTRPC_ASYNC_DOMAIN_MASK)
-#define FASTRPC_ASYNC_HASH_MASK (POS_TO_MASK(FASTRPC_ASYNC_HASH_IDX_POS) & ~FASTRPC_ASYNC_DOMAIN_MASK)
-
-// Async job structure
-struct fastrpc_async_job {
- uint32_t isasyncjob; // set if async job
- /*
- * Fastrpc async job ID bit-map:
- *
- * bits 0-3 : domain ID
- * bits 4-47 : job counter
- * bits 48-63 : timespec
- */
- fastrpc_async_jobid jobid;
- uint32_t reserved; // reserved
-};
-
-/*
- * Internal function to save async job information before submitting to DSP
- * @ domain: domain to which Async job is submitted
- * @ asyncjob: Async job structure
- * @ desc: Async desc passed by user
- * returns 0 on success
- *
- */
-int fastrpc_save_async_job(int domain, struct fastrpc_async_job *asyncjob, fastrpc_async_descriptor_t *desc);
-
-/*
- * Internal function to remove async job, if async invocation to DSP fails
- * @ jobid: domain to which Async job is submitted
- * @ asyncjob: Async job id
- * @ dsp_invoke_done: DSP invocation is successful
- * returns 0 on success
- *
- */
-int fastrpc_remove_async_job(fastrpc_async_jobid jobid, bool dsp_invoke_done);
-
-/*
- * API to initialize async module data strcutures and globals
- */
-int fastrpc_async_domain_init(int domain);
-
-/*
- * API to de-initialize async module data strcutures and globals
- */
-void fastrpc_async_domain_deinit(int domain);
-
-#endif // FASTRPC_ASYNC_H
diff --git a/inc/fastrpc_common.h b/inc/fastrpc_common.h
index 1d52afe..709f933 100644
--- a/inc/fastrpc_common.h
+++ b/inc/fastrpc_common.h
@@ -49,6 +49,10 @@
#define DOMAIN_NAME_IN_URI 1 // Domain name with standard module URI
#define DOMAIN_NAME_STAND_ALONE 2 // Stand-alone domain name
+/* GDSP domain IDs - internal use only, not part of Hexagon SDK remote.h */
+#define GDSP0_DOMAIN_ID 5
+#define GDSP1_DOMAIN_ID 6
+
#define PROFILE(time_taken, ff) \
{ \
struct timeval tv1, tv2; \
diff --git a/inc/fastrpc_internal.h b/inc/fastrpc_internal.h
index 31f1b5d..920cff9 100644
--- a/inc/fastrpc_internal.h
+++ b/inc/fastrpc_internal.h
@@ -15,8 +15,8 @@
#include "AEEstd.h"
#include "AEEQList.h"
#include "AEEStdErr.h"
-#include "fastrpc_latency.h"
#include "fastrpc_common.h"
+#include "fastrpc_ioctl.h"
// Aligns the memory
#define ALIGN_B(p, a) (((p) + ((a) - 1)) & ~((a) - 1))
@@ -43,8 +43,6 @@
* Update these values for any additions to
* the corresponding enums.
**/
-/* Max value of fastrpc_async_notify_type, used to validate the user input */
-#define FASTRPC_ASYNC_TYPE_MAX FASTRPC_ASYNC_POLL + 1
/* Max value of remote_dsp_attributes, used to validate the attribute ID*/
#define FASTRPC_MAX_DSP_ATTRIBUTES MCID_MULTICAST + 1
@@ -190,7 +188,6 @@ enum fastrpc_control_type {
FASTRPC_CONTROL_WAKELOCK = 4,
FASTRPC_CONTROL_PM = 5,
FASTRPC_CONTROL_RPC_POLL = 7,
- FASTRPC_CONTROL_ASYNC_WAKE = 8,
FASTRPC_CONTROL_NOTIF_WAKE = 9,
};
@@ -308,7 +305,7 @@ struct handle_list {
remote_handle64 remotectlhandle;
remote_handle64 adspperfhandle;
int procattrs;
- struct fastrpc_latency qos;
+ int adaptive_qos;
struct fastrpc_thread_params th_params;
int unsigned_module;
bool pd_dump;
@@ -316,11 +313,8 @@ struct handle_list {
int disable_exit_logs;
struct fastrpc_dsp_capabilities cap_info;
int trace_marker_fd;
- uint64_t jobid;
/* Capability flag to check if mapping DMA handle through reverse RPC is supported */
int dma_handle_reverse_rpc_map_capability;
- /* Mutex to synchronize ASync init and deinit */
- pthread_mutex_t async_init_deinit_mut;
uint32_t pd_initmem_size; /** Initial memory allocated for remote userPD */
uint32_t refs; // Number of multi-domain handles + contexts on session
bool is_session_reserved; /** Set if session is reserved or used */
@@ -367,21 +361,6 @@ int fastrpc_get_cap(uint32_t domain, uint32_t attributeID, uint32_t *capability)
**/
int check_rpc_error(int err);
-/**
- * @brief Notify the FastRPC QoS logic of activity outside of the invoke code path
- * that should still be considered in QoS timeout calculations.
- * Note that the function will silently fail on errors such as the domain
- * not having a valid QoS mode.
- *
- * @param[in] domain DSP domain
- **/
-void fastrpc_qos_activity(int domain);
-
-/**
- * @brief Make IOCTL call to exit async thread
- */
-int fastrpc_exit_async_thread(int domain);
-
/**
* @brief Make IOCTL call to exit notif thread
*/
@@ -471,6 +450,14 @@ static __inline int convert_kernel_to_user_error(int nErr, int err_no) {
return nErr;
}
+/**
+ * @brief Get both secure and non-secure device names for a domain
+ * @param domain_id: Domain ID
+ * @param secure_name: Output pointer for secure device name
+ * @param non_secure_name: Output pointer for non-secure device name
+ **/
+void get_domain_device_names(int domain_id, const char **secure_name, const char **non_secure_name);
+
/**
* @brief utility APIs used in fastRPC library to get name, handle from domain
**/
@@ -502,8 +489,7 @@ int fastrpc_update_module_list(uint32_t req, int domain, remote_handle64 handle,
* @brief functions to wrap ioctl syscalls for downstream and upstream kernel
**/
int ioctl_init(int dev, uint32_t flags, int attr, unsigned char* shell, int shelllen, int shellfd, char* initmem, int initmemlen, int initmemfd, int tessiglen);
-int ioctl_invoke(int dev, int req, remote_handle handle, uint32_t sc, void* pra, int* fds, unsigned int* attrs, void *job, unsigned int* crc, uint64_t* perf_kernel, uint64_t* perf_dsp);
-int ioctl_invoke2_response(int dev, fastrpc_async_jobid *jobid, remote_handle *handle, uint32_t *sc, int* result, uint64_t *perf_kernel, uint64_t *perf_dsp);
+int ioctl_invoke(int dev, int req, remote_handle handle, uint32_t sc, void* pra, int* fds, unsigned int* attrs, unsigned int* crc, uint64_t* perf_kernel, uint64_t* perf_dsp);
int ioctl_invoke2_notif(int dev, int *domain, int *session, int *status);
int ioctl_mmap(int dev, int req, uint32_t flags, int attr, int fd, int offset, size_t len, uintptr_t vaddrin, uint64_t* vaddr_out);
int ioctl_munmap(int dev, int req, int attr, void* buf, int fd, int len, uint64_t vaddr);
@@ -538,9 +524,4 @@ int ioctl_optimization(int dev, uint32_t max_concurrency);
int ioctl_mdctx_manage(int dev, int req, void *user_ctx,
unsigned int *domain_ids, unsigned int num_domain_ids, uint64_t *ctx);
-const char* get_secure_domain_name(int domain_id);
-int is_async_fastrpc_supported(void);
-
-#include "fastrpc_ioctl.h"
-
#endif // FASTRPC_INTERNAL_H
diff --git a/inc/fastrpc_ioctl.h b/inc/fastrpc_ioctl.h
index 779d034..b9cee80 100644
--- a/inc/fastrpc_ioctl.h
+++ b/inc/fastrpc_ioctl.h
@@ -43,24 +43,6 @@
#define FASTRPC_ATTR_NOVA (256)
-/* Secure and default device nodes */
-#if DEFAULT_DOMAIN_ID==ADSP_DOMAIN_ID
- #define SECURE_DEVICE "/dev/fastrpc-adsp-secure"
- #define DEFAULT_DEVICE "/dev/fastrpc-adsp"
-#elif DEFAULT_DOMAIN_ID==MDSP_DOMAIN_ID
- #define SECURE_DEVICE "/dev/fastrpc-mdsp-secure"
- #define DEFAULT_DEVICE "/dev/fastrpc-mdsp"
-#elif DEFAULT_DOMAIN_ID==SDSP_DOMAIN_ID
- #define SECURE_DEVICE "/dev/fastrpc-sdsp-secure"
- #define DEFAULT_DEVICE "/dev/fastrpc-sdsp"
-#elif DEFAULT_DOMAIN_ID==CDSP_DOMAIN_ID
- #define SECURE_DEVICE "/dev/fastrpc-cdsp-secure"
- #define DEFAULT_DEVICE "/dev/fastrpc-cdsp"
-#else
- #define SECURE_DEVICE ""
- #define DEFAULT_DEVICE ""
-#endif
-
#define INITIALIZE_REMOTE_ARGS(total) int *pfds = NULL; \
unsigned *pattrs = NULL; \
args = (struct fastrpc_invoke_args*) calloc(sizeof(*args), total); \
diff --git a/inc/fastrpc_latency.h b/inc/fastrpc_latency.h
deleted file mode 100644
index caee084..0000000
--- a/inc/fastrpc_latency.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef __FASTRPC_LATENCY_H__
-#define __FASTRPC_LATENCY_H__
-
-#define FASTRPC_LATENCY_START (1)
-#define FASTRPC_LATENCY_STOP (0)
-#define FASTRPC_LATENCY_EXIT (2)
-
-#define SEC_TO_NS (1000000000)
-#define MS_TO_US (1000)
-#define US_TO_NS MS_TO_US
-
-#define FASTRPC_LATENCY_VOTE_ON (1)
-#define FASTRPC_LATENCY_VOTE_OFF (0)
-#define FASTRPC_LATENCY_WAIT_TIME_USEC (100000)
-#define FASTRPC_QOS_MAX_LATENCY_USEC (10000)
-
-/* FastRPC latency voting data for QoS handler of a session */
-struct fastrpc_latency {
- int adaptive_qos;
- int state; //! latency thread handler running state
- int exit;
- int invoke; //! invoke count in tacking window
- int vote; //! current pm_qos vote status
- int dev; //! associated device node
- int wait_time; //! wait time for review next voting
- int latency; //! user requested fastrpc latency in us
- pthread_t thread;
- pthread_mutex_t mut;
- pthread_mutex_t wmut;
- pthread_cond_t cond;
-};
-
-/* Increment RPC invoke count for activity detection in a window of time
- * @param qos, pointer to domain latency data
- * return, fastrpc error codes
- */
-int fastrpc_latency_invoke_incr(struct fastrpc_latency *qos);
-
-/* Set qos enable and latency parameters for a configured domain
- * @param qos, pointer to domain latency data
- * @param enable, qos enable/disable
- * @param latency, fastrpc latency requirement from user in us
- * @return, fastrpc error codes
- */
-int fastrpc_set_pm_qos(struct fastrpc_latency *qos, uint32_t enable,
- uint32_t latency);
-
-/* Initialization routine to initialize globals & internal data structures */
-int fastrpc_latency_init(int dev, struct fastrpc_latency *qos);
-/* De-init routine to cleanup globals & internal data structures*/
-int fastrpc_latency_deinit(struct fastrpc_latency *qos);
-
-#endif /*__FASTRPC_LATENCY_H__*/
diff --git a/inc/fastrpc_mem.h b/inc/fastrpc_mem.h
index e4b8667..402f990 100644
--- a/inc/fastrpc_mem.h
+++ b/inc/fastrpc_mem.h
@@ -73,4 +73,40 @@ int fastrpc_buffer_ref(int domain, int fd, int ref, void **va, size_t *size);
*/
void remote_register_buf(void *buf, int size, int fd);
+/*
+ * Internal function to map a buffer and return the DSP virtual address.
+ * Creates a mapping on the DSP and stores the mapping information in the static map list.
+ *
+ * @param domain The DSP domain ID (-1 for current domain)
+ * @param fd File descriptor of the buffer
+ * @param vaddr Virtual address of the buffer on CPU side
+ * @param offset Offset from the beginning of the buffer (must be 0)
+ * @param length Size of buffer in bytes
+ * @param flags Mapping flags
+ * @param raddr Output: DSP virtual address of the mapped buffer
+ *
+ * @return 0 on success, error code on failure
+ */
+int fastrpc_mmap_internal(int domain, int fd, void *vaddr, int offset, size_t length, uint32_t flags, uint64_t *raddr);
+
+/*
+ * Internal function to unmap a buffer using the DSP virtual address.
+ * Looks up the mapping in the static map list using the DSP virtual address,
+ * then performs the unmap operation and removes the mapping from the list.
+ *
+ * @param domain The DSP domain ID (-1 for current domain)
+ * @param raddr DSP virtual address of the mapped buffer
+ * @param length Size of buffer in bytes to unmap
+ *
+ * @return 0 on success, error code on failure
+ */
+int fastrpc_munmap_internal(int domain, uint64_t raddr, size_t length);
+
+#define ADSP_MMAP_HEAP_ADDR 4
+#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
+#define ADSP_MMAP_ADD_PAGES 0x1000
+#define ADSP_MMAP_ADD_PAGES_LLC 0x3000
+#define FASTRPC_ALLOC_HLOS_FD \
+ 0x10000 /* Flag to allocate HLOS FD to be shared with DSP */
+
#endif //FASTRPC_MEM_H
diff --git a/inc/remote.h b/inc/remote.h
index 1fa3baa..4d4eb8f 100644
--- a/inc/remote.h
+++ b/inc/remote.h
@@ -122,8 +122,6 @@ extern "C" {
#define SDSP_DOMAIN_ID 2
#define CDSP_DOMAIN_ID 3
#define CDSP1_DOMAIN_ID 4
-#define GDSP0_DOMAIN_ID 5
-#define GDSP1_DOMAIN_ID 6
/** Supported Domain Names */
#define ADSP_DOMAIN_NAME "adsp"
diff --git a/inc/rpcmem_internal.h b/inc/rpcmem_internal.h
index 4fe415e..34aa3eb 100644
--- a/inc/rpcmem_internal.h
+++ b/inc/rpcmem_internal.h
@@ -6,22 +6,6 @@
#include "rpcmem.h"
-/*
- * rpcmem_set_dmabuf_name() - API to set name for DMA allocated buffer.
- * Name string updates as follows.
- * Heap : dsp___
- * Non-heap : apps___
- *
- * @name : Pointer to string, "dsp" for heap buffers, "apps" for
- * non-heap buffers
- * @fd : File descriptor of buffer
- * @heapid : Heap ID used for memory allocation
- * @buf : Pointer to buffer start address
- * @rpcflags: Memory flags describing attributes of allocation
- * Return : 0 on success, valid non-zero error code on failure
- */
-int rpcmem_set_dmabuf_name(const char *name, int fd, int heapid,
- void *buf, uint32_t rpc_flags);
/*
* returns an file descriptor associated with the address
*/
diff --git a/public_headers/config.yml b/public_headers/config.yml
index c4bd378..7da7b7c 100644
--- a/public_headers/config.yml
+++ b/public_headers/config.yml
@@ -9,3 +9,12 @@ branches:
- inc/remote64.h
- inc/dspqueue.h
- inc/rpcmem.h
+
+abi_checks:
+ - path: src/.libs
+ include_globs: ["libadsprpc.so", "libcdsprpc.so", "libsdsprpc.so"]
+ public_headers:
+ - inc/adsp_default_listener1.h
+ - inc/HAP_pls.h
+ - inc/rpcmem.h
+ - inc/remote.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 9a3608d..eb80b93 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,11 +1,13 @@
lib_LTLIBRARIES =
-LIBDSPRPC_CFLAGS = -fno-short-enums -U_DEBUG -DARM_ARCH_7A -DLE_ENABLE -DENABLE_UPSTREAM_DRIVER_INTERFACE -DUSE_SYSLOG -DCONFIG_BASE_DIR='"$(CONFIG_BASE_DIR)"' -DMACHINE_NAME_PATH='"/sys/firmware/devicetree/base/model"' -I$(top_srcdir)/inc
+LIBDSPRPC_CFLAGS = -fno-short-enums -U_DEBUG -DARM_ARCH_7A -DLE_ENABLE -DENABLE_UPSTREAM_DRIVER_INTERFACE -DUSE_SYSLOG -DCONFIG_BASE_DIR='"$(CONFIG_BASE_DIR)"' -DMACHINE_NAME_PATH='"/sys/firmware/devicetree/base/model"' -I$(top_srcdir)/inc @STRICTER_CFLAGS@ @STRICTER_CPPFLAGS@
+
+LIBDSPRPC_LDFLAGS = @STRICTER_LDFLAGS@
if ANDROID_CC
LIBDSPRPC_CFLAGS += -DDEFAULT_DSP_SEARCH_PATHS='";/vendor/lib/rfsa/adsp;/vendor/dsp;"'
else
-LIBDSPRPC_CFLAGS += -DPARSE_YAML @YAML_CFLAGS@ -DDEFAULT_DSP_SEARCH_PATHS='";/usr/lib/rfsa/adsp;/usr/lib/dsp;"'
+LIBDSPRPC_CFLAGS += -DPARSE_YAML @YAML_CFLAGS@ @BSD_CFLAGS@ -DDEFAULT_DSP_SEARCH_PATHS='";/usr/lib/rfsa/adsp;/usr/lib/dsp;"'
endif
LIBDSPRPC_SOURCES = \
@@ -13,10 +15,8 @@ LIBDSPRPC_SOURCES = \
fastrpc_perf.c \
fastrpc_pm.c \
fastrpc_config.c \
- fastrpc_async.c \
fastrpc_mem.c \
fastrpc_notif.c \
- fastrpc_latency.c \
fastrpc_ioctl.c \
fastrpc_log.c \
fastrpc_procbuf.c \
@@ -68,64 +68,52 @@ LIBDEFAULT_LISTENER_SOURCES = \
if ANDROID_CC
USE_LOG = -llog
else
-# Add YAML libs to link flags for non-Android builds
-libadsprpc_la_LIBADD = @YAML_LIBS@
-libcdsprpc_la_LIBADD = @YAML_LIBS@
-libsdsprpc_la_LIBADD = @YAML_LIBS@
-libgdsprpc_la_LIBADD = @YAML_LIBS@
+# Add YAML and BSD libs to link flags for non-Android builds
+libadsprpc_la_LIBADD = -ldl -lm $(USE_LOG) @YAML_LIBS@ @BSD_LIBS@
+libcdsprpc_la_LIBADD = -ldl -lm $(USE_LOG) @YAML_LIBS@ @BSD_LIBS@
+libsdsprpc_la_LIBADD = -ldl -lm $(USE_LOG) @YAML_LIBS@ @BSD_LIBS@
endif
ADSP_CFLAGS = $(LIBDSPRPC_CFLAGS) -DDEFAULT_DOMAIN_ID=0
lib_LTLIBRARIES += libadsprpc.la
libadsprpc_la_SOURCES = $(LIBDSPRPC_SOURCES)
-libadsprpc_la_LDFLAGS = -ldl -lm $(USE_LOG) -version-number @LT_VERSION_NUMBER@
+libadsprpc_la_LDFLAGS = -version-number @LT_VERSION_NUMBER@ $(LIBDSPRPC_LDFLAGS)
libadsprpc_la_CFLAGS = $(ADSP_CFLAGS)
lib_LTLIBRARIES += libadsp_default_listener.la
libadsp_default_listener_la_SOURCES = $(LIBDEFAULT_LISTENER_SOURCES)
libadsp_default_listener_la_DEPENDENCIES = libadsprpc.la
-libadsp_default_listener_la_LDFLAGS = libadsprpc.la -shared -module $(USE_LOG) -version-number @LT_VERSION_NUMBER@
+libadsp_default_listener_la_LDFLAGS = libadsprpc.la -shared -module $(USE_LOG) -version-number @LT_VERSION_NUMBER@ $(LIBDSPRPC_LDFLAGS)
libadsp_default_listener_la_CFLAGS = $(ADSP_CFLAGS) -DUSE_SYSLOG
CDSP_CFLAGS = $(LIBDSPRPC_CFLAGS) -DDEFAULT_DOMAIN_ID=3
lib_LTLIBRARIES += libcdsprpc.la
libcdsprpc_la_SOURCES = $(LIBDSPRPC_SOURCES)
-libcdsprpc_la_LDFLAGS = -ldl -lm $(USE_LOG) -version-number @LT_VERSION_NUMBER@
+libcdsprpc_la_LDFLAGS = -version-number @LT_VERSION_NUMBER@ $(LIBDSPRPC_LDFLAGS)
libcdsprpc_la_CFLAGS = $(CDSP_CFLAGS)
lib_LTLIBRARIES += libcdsp_default_listener.la
libcdsp_default_listener_la_SOURCES = $(LIBDEFAULT_LISTENER_SOURCES)
libcdsp_default_listener_la_DEPENDENCIES = libcdsprpc.la
-libcdsp_default_listener_la_LDFLAGS = libcdsprpc.la -shared -module $(USE_LOG) -version-number @LT_VERSION_NUMBER@
+libcdsp_default_listener_la_LDFLAGS = libcdsprpc.la -shared -module $(USE_LOG) -version-number @LT_VERSION_NUMBER@ $(LIBDSPRPC_LDFLAGS)
libcdsp_default_listener_la_CFLAGS = $(CDSP_CFLAGS) -DUSE_SYSLOG
SDSP_CFLAGS = $(LIBDSPRPC_CFLAGS) -DDEFAULT_DOMAIN_ID=2
lib_LTLIBRARIES += libsdsprpc.la
libsdsprpc_la_SOURCES = $(LIBDSPRPC_SOURCES)
-libsdsprpc_la_LDFLAGS = -ldl -lm $(USE_LOG) -version-number @LT_VERSION_NUMBER@
+libsdsprpc_la_LDFLAGS = -version-number @LT_VERSION_NUMBER@ $(LIBDSPRPC_LDFLAGS)
libsdsprpc_la_CFLAGS = $(SDSP_CFLAGS)
lib_LTLIBRARIES += libsdsp_default_listener.la
libsdsp_default_listener_la_SOURCES = $(LIBDEFAULT_LISTENER_SOURCES)
libsdsp_default_listener_la_DEPENDENCIES = libsdsprpc.la
-libsdsp_default_listener_la_LDFLAGS = libsdsprpc.la -shared -module $(USE_LOG) -version-number @LT_VERSION_NUMBER@
+libsdsp_default_listener_la_LDFLAGS = libsdsprpc.la -shared -module $(USE_LOG) -version-number @LT_VERSION_NUMBER@ $(LIBDSPRPC_LDFLAGS)
libsdsp_default_listener_la_CFLAGS = $(SDSP_CFLAGS) -DUSE_SYSLOG
-GDSP_CFLAGS = $(LIBDSPRPC_CFLAGS) -DDEFAULT_DOMAIN_ID=5
-
-libgdsprpc_la_SOURCES = $(LIBDSPRPC_SOURCES)
-libgdsprpc_la_LDFLAGS = -ldl -lm $(USE_LOG) -version-number @LT_VERSION_NUMBER@
-libgdsprpc_la_CFLAGS = $(GDSP_CFLAGS)
-
-libgdsp_default_listener_la_SOURCES = $(LIBDEFAULT_LISTENER_SOURCES)
-libgdsp_default_listener_la_DEPENDENCIES = libcdsprpc.la
-libgdsp_default_listener_la_LDFLAGS = libcdsprpc.la -shared -module $(USE_LOG) -version-number @LT_VERSION_NUMBER@
-libgdsp_default_listener_la_CFLAGS = $(GDSP_CFLAGS) -DUSE_SYSLOG
-
-bin_PROGRAMS = adsprpcd cdsprpcd sdsprpcd gdsprpcd
+sbin_PROGRAMS = adsprpcd cdsprpcd sdsprpcd gdsprpcd
adsprpcddir = $(libdir)
adsprpcd_SOURCES = dsprpcd.c
@@ -147,9 +135,9 @@ sdsprpcd_DEPENDENCIES = libsdsp_default_listener.la
sdsprpcd_CFLAGS = -I$(top_srcdir)/inc -DDEFAULT_DOMAIN_ID=2 -DUSE_SYSLOG -DUSE_SDSP
sdsprpcd_LDADD = -ldl $(USE_LOG)
-
+# GDSP daemon shares CDSP libraries (not a typo)
gdsprpcddir = $(libdir)
gdsprpcd_SOURCES = dsprpcd.c
gdsprpcd_DEPENDENCIES = libcdsp_default_listener.la
gdsprpcd_CFLAGS = -I$(top_srcdir)/inc -DDEFAULT_DOMAIN_ID=5 -DUSE_SYSLOG -DUSE_GDSP
-gdsprpcd_LDADD = -ldl $(USE_LOG)
\ No newline at end of file
+gdsprpcd_LDADD = -ldl $(USE_LOG)
diff --git a/src/adsp_default_listener.c b/src/adsp_default_listener.c
index e37648a..ee3d3fd 100644
--- a/src/adsp_default_listener.c
+++ b/src/adsp_default_listener.c
@@ -33,20 +33,6 @@
#define POLL_TIMEOUT 10 * 1000
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
-#define ADSP_SECURE_DEVICE_NAME "fastrpc-adsp-secure"
-#define SDSP_SECURE_DEVICE_NAME "fastrpc-sdsp-secure"
-#define MDSP_SECURE_DEVICE_NAME "fastrpc-mdsp-secure"
-#define CDSP_SECURE_DEVICE_NAME "fastrpc-cdsp-secure"
-#define CDSP1_SECURE_DEVICE_NAME "fastrpc-cdsp1-secure"
-#define GDSP0_SECURE_DEVICE_NAME "fastrpc-gdsp0-secure"
-#define GDSP1_SECURE_DEVICE_NAME "fastrpc-gdsp1-secure"
-#define ADSP_DEVICE_NAME "fastrpc-adsp"
-#define SDSP_DEVICE_NAME "fastrpc-sdsp"
-#define MDSP_DEVICE_NAME "fastrpc-mdsp"
-#define CDSP_DEVICE_NAME "fastrpc-cdsp"
-#define CDSP1_DEVICE_NAME "fastrpc-cdsp1"
-#define GDSP0_DEVICE_NAME "fastrpc-gdsp0"
-#define GDSP1_DEVICE_NAME "fastrpc-gdsp1"
// Array of supported domain names and its corresponding ID's.
static domain_t supported_domains[] = {{ADSP_DOMAIN_ID, ADSP_DOMAIN},
@@ -70,95 +56,23 @@ static domain_t *get_domain_uri(int domain_id) {
return NULL;
}
-static const char *get_secure_device_name(int domain_id) {
- const char *name;
- int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain_id);
-
- switch (domain) {
- case ADSP_DOMAIN_ID:
- name = ADSP_SECURE_DEVICE_NAME;
- break;
- case SDSP_DOMAIN_ID:
- name = SDSP_SECURE_DEVICE_NAME;
- break;
- case MDSP_DOMAIN_ID:
- name = MDSP_SECURE_DEVICE_NAME;
- break;
- case CDSP_DOMAIN_ID:
- name = CDSP_SECURE_DEVICE_NAME;
- break;
- case CDSP1_DOMAIN_ID:
- name = CDSP1_SECURE_DEVICE_NAME;
- break;
- case GDSP0_DOMAIN_ID:
- name = GDSP0_SECURE_DEVICE_NAME;
- break;
- case GDSP1_DOMAIN_ID:
- name = GDSP1_SECURE_DEVICE_NAME;
- break;
- default:
- name = DEFAULT_DEVICE;
- break;
- }
-
- return name;
-}
-
-static const char *get_default_device_name(int domain_id) {
- const char *name;
- int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain_id);
-
- switch (domain) {
- case ADSP_DOMAIN_ID:
- name = ADSP_DEVICE_NAME;
- break;
- case SDSP_DOMAIN_ID:
- name = SDSP_DEVICE_NAME;
- break;
- case MDSP_DOMAIN_ID:
- name = MDSP_DEVICE_NAME;
- break;
- case CDSP_DOMAIN_ID:
- name = CDSP_DEVICE_NAME;
- break;
- case CDSP1_DOMAIN_ID:
- name = CDSP1_DEVICE_NAME;
- break;
- case GDSP0_DOMAIN_ID:
- name = GDSP0_DEVICE_NAME;
- break;
- case GDSP1_DOMAIN_ID:
- name = GDSP1_DEVICE_NAME;
- break;
- default:
- name = DEFAULT_DEVICE;
- break;
- }
-
- return name;
-}
/**
* fastrpc_dev_exists() - Check if device exists
- * @dev_name: Device name
+ * @dev_path: Full device path (e.g., "/dev/fastrpc-adsp")
*
* Return:
* True: Device node exists
* False: Device node does not exist
*/
-static bool fastrpc_dev_exists(const char* dev_name)
+static bool fastrpc_dev_exists(const char* dev_path)
{
struct stat buffer;
- char *path = NULL;
- uint64_t len;
- len = snprintf(0, 0, "/dev/%s", dev_name) + 1;
- if(NULL == (path = (char *)malloc(len * sizeof(char))))
+ if (!dev_path)
return false;
- snprintf(path, (int)len, "/dev/%s", dev_name);
-
- return (stat(path, &buffer) == 0);
+ return (stat(dev_path, &buffer) == 0);
}
/**
@@ -172,13 +86,12 @@ static bool fastrpc_dev_exists(const char* dev_name)
static int fastrpc_wait_for_device(int domain)
{
int inotify_fd = -1, watch_fd = -1, err = 0;
- const char *sec_dev_name = NULL, *def_dev_name = NULL;
+ const char *sec_dev_name = NULL, *non_sec_dev_name = NULL;
struct pollfd pfd[1];
- sec_dev_name = get_secure_device_name(domain);
- def_dev_name = get_default_device_name(domain);
+ get_domain_device_names(domain, &sec_dev_name, &non_sec_dev_name);
- if (fastrpc_dev_exists(sec_dev_name) || fastrpc_dev_exists(def_dev_name))
+ if (fastrpc_dev_exists(sec_dev_name) || fastrpc_dev_exists(non_sec_dev_name))
return 0;
inotify_fd = inotify_init();
@@ -194,7 +107,7 @@ static int fastrpc_wait_for_device(int domain)
return AEE_EINVALIDFD;
}
- if (fastrpc_dev_exists(sec_dev_name) || fastrpc_dev_exists(def_dev_name))
+ if (fastrpc_dev_exists(sec_dev_name) || fastrpc_dev_exists(non_sec_dev_name))
goto bail;
memset(pfd, 0 , sizeof(pfd));
@@ -227,11 +140,21 @@ static int fastrpc_wait_for_device(int domain)
/* Loop over all events in the buffer. */
for (char *ptr = buffer; ptr < buffer + len;
ptr += sizeof(struct inotify_event) + event->len) {
+ const char *sec_dev_basename = NULL, *non_sec_dev_basename = NULL;
event = (struct inotify_event *) ptr;
+
+ /* Extract just the device name from full path for comparison */
+ sec_dev_basename = strrchr(sec_dev_name, '/');
+ non_sec_dev_basename = strrchr(non_sec_dev_name, '/');
+
+ /* Skip the '/' character if found */
+ sec_dev_basename++;
+ non_sec_dev_basename++;
+
/* Check if the event corresponds to the creation of the device node. */
if (event->wd == watch_fd && (event->mask & IN_CREATE) &&
- ((strcmp(sec_dev_name, event->name) == 0) ||
- (strcmp(def_dev_name, event->name) == 0))) {
+ ((sec_dev_basename && strcmp(sec_dev_basename, event->name) == 0) ||
+ (non_sec_dev_basename && strcmp(non_sec_dev_basename, event->name) == 0))) {
/* Device node created, process proceed to open and use it. */
VERIFY_IPRINTF("Device node %s created!\n", event->name);
goto bail; /* Exit the loop after device creation is detected. */
diff --git a/src/adspmsgd_printf.c b/src/adspmsgd_printf.c
index 787d9c1..18f2102 100644
--- a/src/adspmsgd_printf.c
+++ b/src/adspmsgd_printf.c
@@ -5,6 +5,12 @@
#include "remote.h"
#include
+#ifdef __ANDROID__
+#include
+#endif
+#ifdef USE_SYSLOG
+#include
+#endif
#define LOG_NODE_SIZE 256
#define LOG_FILENAME_SIZE 30
@@ -54,5 +60,11 @@ int adspmsgd_apps_log(const unsigned char *log_message_buffer,
return 0;
}
void adspmsgd_log_message(char *format, char *msg) {
- printf("adsprpc:dsp: %s\n", msg);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_VERBOSE,"adsprpc",format, msg);
+#elif defined(USE_SYSLOG)
+ syslog(LOG_INFO,"adsprpc:%s ", msg);
+#else
+ printf("adsprpc:%s\n", msg);
+#endif
}
diff --git a/src/apps_mem_imp.c b/src/apps_mem_imp.c
index f288d0a..09d58ba 100644
--- a/src/apps_mem_imp.c
+++ b/src/apps_mem_imp.c
@@ -17,6 +17,7 @@
#include "remote64.h"
#include "rpcmem_internal.h"
#include "verify.h"
+#include
#include
#include
#include
@@ -24,12 +25,6 @@
#include
#include "fastrpc_hash_table.h"
-#define ADSP_MMAP_HEAP_ADDR 4
-#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
-#define ADSP_MMAP_ADD_PAGES 0x1000
-#define ADSP_MMAP_ADD_PAGES_LLC 0x3000
-#define FASTRPC_ALLOC_HLOS_FD \
- 0x10000 /* Flag to allocate HLOS FD to be shared with DSP */
typedef struct {
QList mem_list;
@@ -128,8 +123,8 @@ __QAIC_IMPL(apps_mem_request_map64)(int heapid, uint32_t lflags, uint32_t rflags
VERIFYC(me, AEE_ERESOURCENOTFOUND);
VERIFY(AEE_SUCCESS ==
(nErr = get_unsigned_pd_attribute(domain, &unsigned_module)));
- FASTRPC_ATRACE_BEGIN_L("%s called with rflag 0x%x, lflags 0x%x, len 0x%llx, "
- "heapid %d and unsigned PD %d",
+ FASTRPC_ATRACE_BEGIN_L("%s called with rflag 0x%x, lflags 0x%x, "
+ "len 0x%" PRIx64 ", heapid %d and unsigned PD %d",
__func__, rflags, lflags, len, heapid,
unsigned_module);
if (unsigned_module) {
@@ -149,7 +144,6 @@ __QAIC_IMPL(apps_mem_request_map64)(int heapid, uint32_t lflags, uint32_t rflags
VERIFYC(NULL != (buf = rpcmem_alloc_internal(heapid, lflags, len)),
AEE_ENORPCMEMORY);
VERIFYC(0 < (fd = rpcmem_to_fd_internal(buf)), AEE_EBADFD);
- rpcmem_set_dmabuf_name("dsp", fd, heapid, buf, lflags);
/* Using FASTRPC_MAP_FD_DELAYED as only HLOS mapping is reqd at this point
*/
VERIFY(AEE_SUCCESS == (nErr = fastrpc_mmap(domain, fd, buf, 0, len,
@@ -177,10 +171,9 @@ __QAIC_IMPL(apps_mem_request_map64)(int heapid, uint32_t lflags, uint32_t rflags
AEE_ENORPCMEMORY);
fd = rpcmem_to_fd_internal(buf);
VERIFYC(fd > 0, AEE_EBADPARM);
- rpcmem_set_dmabuf_name("dsp", fd, heapid, buf, lflags);
}
VERIFY(AEE_SUCCESS ==
- (nErr = remote_mmap64_internal(fd, rflags, (uint64_t)buf, len,
+ (nErr = remote_mmap64_internal(fd, rflags, (uint64_t)buf, len,
(uint64_t *)vadsp)));
pbuf = (uint64_t)buf;
*vapps = pbuf;
@@ -204,7 +197,7 @@ __QAIC_IMPL(apps_mem_request_map64)(int heapid, uint32_t lflags, uint32_t rflags
minfo = NULL;
}
VERIFY_EPRINTF("Error 0x%x: apps_mem_request_mmap64 failed for fd 0x%x of "
- "size %lld (lflags 0x%x, rflags 0x%x)\n",
+ "size %" PRId64 " (lflags 0x%x, rflags 0x%x)\n",
nErr, fd, len, lflags, rflags);
}
FASTRPC_ATRACE_END();
@@ -236,8 +229,8 @@ __QAIC_IMPL(apps_mem_request_unmap64)(uint64_t vadsp,
int domain = get_current_domain();
apps_mem_info *me = NULL;
- FASTRPC_ATRACE_BEGIN_L("%s called with vadsp 0x%llx, len 0x%llx", __func__,
- vadsp, len);
+ FASTRPC_ATRACE_BEGIN_L("%s called with vadsp 0x%" PRIx64 ", len 0x%" PRIx64,
+ __func__, vadsp, len);
GET_HASH_NODE(apps_mem_info, domain, me);
VERIFYC(me, AEE_ERESOURCENOTFOUND);
@@ -283,8 +276,8 @@ __QAIC_IMPL(apps_mem_request_unmap64)(uint64_t vadsp,
mfree = NULL;
bail:
if (nErr != AEE_SUCCESS) {
- VERIFY_EPRINTF("Error 0x%x: apps_mem_request_unmap64 failed for size %lld "
- "(vadsp 0x%llx)\n",
+ VERIFY_EPRINTF("Error 0x%x: apps_mem_request_unmap64 failed for size "
+ "%" PRId64 " (vadsp 0x%" PRIx64 ")\n",
nErr, len, vadsp);
}
FASTRPC_ATRACE_END();
@@ -353,7 +346,7 @@ __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_share_unmap)(uint64_t vadsp, int siz
nErr = apps_mem_request_unmap64(vadsp, len1);
if (nErr != AEE_SUCCESS) {
VERIFY_EPRINTF(
- "Error 0x%x: apps_mem_share_unmap failed size %d (vadsp 0x%llx)\n",
+ "Error 0x%x: apps_mem_share_unmap failed size %d (vadsp 0x%" PRIx64 ")\n",
nErr, size, vadsp);
}
return nErr;
diff --git a/src/apps_std_imp.c b/src/apps_std_imp.c
index 3a69345..536ea40 100644
--- a/src/apps_std_imp.c
+++ b/src/apps_std_imp.c
@@ -154,8 +154,8 @@ int apps_std_get_dirinfo(const apps_std_DIR *dir,
} else {
nErr = ESTALE;
VERIFY_EPRINTF(
- "Error 0x%x: %s: stale directory handle 0x%llx passed by DSP\n", nErr,
- __func__, dir->handle);
+ "Error 0x%x: %s: stale directory handle 0x%" PRIx64 " passed by DSP\n",
+ nErr, __func__, dir->handle);
goto bail;
}
bail:
@@ -970,20 +970,6 @@ static int get_dirlist_from_env(const char *envvarname, char **ppDirList) {
// Append default DSP_SEARCH_PATH to user defined env
strlcat(envList, dsp_search_path, envListPrependLen);
envListLen = envListPrependLen;
- } else if (strncmp(envvarname, ADSP_AVS_PATH,
- strlen(ADSP_AVS_PATH)) == 0) {
- envListPrependLen = envListLen + strlen(ADSP_AVS_CFG_PATH);
- if (envLenGuess < envListPrependLen) {
- FREEIF(envListBuf);
- VERIFYC(envListBuf =
- realloc(envListBuf, sizeof(char) * envListPrependLen),
- AEE_ENOMEMORY);
- envList = envListBuf;
- VERIFY(0 == (nErr = apps_std_getenv(envvarname, envList,
- envListPrependLen, &listLen)));
- }
- strlcat(envList, ADSP_AVS_CFG_PATH, envListPrependLen);
- envListLen = envListPrependLen;
}
} else if (strncmp(envvarname, ADSP_LIBRARY_PATH,
strlen(ADSP_LIBRARY_PATH)) == 0 ||
@@ -991,10 +977,6 @@ static int get_dirlist_from_env(const char *envvarname, char **ppDirList) {
strlen(DSP_LIBRARY_PATH)) == 0) {
envListLen = listLen =
1 + strlcpy(envListBuf, dsp_search_path, envLenGuess);
- } else if (strncmp(envvarname, ADSP_AVS_PATH,
- strlen(ADSP_AVS_PATH)) == 0) {
- envListLen = listLen =
- 1 + strlcpy(envListBuf, ADSP_AVS_CFG_PATH, envLenGuess);
}
/*
@@ -1026,19 +1008,24 @@ int fopen_from_dirlist(const char *dirList, const char *delim,
const char *mode, const char *name, apps_std_FILE *psout) {
int nErr = AEE_SUCCESS;
char *absName = NULL, *dirName = NULL, *pos = NULL;
+ char *dirListCopy = NULL, *dirListPtr = NULL;
uint16_t absNameLen = 0;
int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(get_current_domain());
VERIFYC(NULL != dirList, AEE_EBADPARM);
- while (dirList) {
- pos = strstr(dirList, delim);
- dirName = dirList;
+ // Make a copy of dirList to avoid modifying caller's buffer
+ VERIFYC(NULL != (dirListCopy = strdup(dirList)), AEE_ENOMEMORY);
+ dirListPtr = dirListCopy;
+
+ while (dirListPtr) {
+ pos = strstr(dirListPtr, delim);
+ dirName = dirListPtr;
if (pos) {
*pos = '\0';
- dirList = pos + strlen(delim);
+ dirListPtr = pos + strlen(delim);
} else {
- dirList = 0;
+ dirListPtr = 0;
}
// Append domain to path
@@ -1061,6 +1048,7 @@ int fopen_from_dirlist(const char *dirList, const char *delim,
// Success
FARF(ALWAYS, "Successfully opened file %s", absName);
FREEIF(absName);
+ FREEIF(dirListCopy);
return nErr;
}
FREEIF(absName);
@@ -1087,11 +1075,13 @@ int fopen_from_dirlist(const char *dirList, const char *delim,
strlen(TESTSIG_FILE_NAME)) != 0))
FARF(ALWAYS, "Successfully opened file %s", name);
FREEIF(absName);
+ FREEIF(dirListCopy);
return nErr;
}
}
bail:
FREEIF(absName);
+ FREEIF(dirListCopy);
return nErr;
}
diff --git a/src/dspqueue/.dirstamp b/src/dspqueue/.dirstamp
deleted file mode 100644
index e69de29..0000000
diff --git a/src/dsprpcd.c b/src/dsprpcd.c
index 348049a..038c09a 100644
--- a/src/dsprpcd.c
+++ b/src/dsprpcd.c
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
#ifndef ADSP_LISTENER_VERSIONED
#define ADSP_LISTENER_VERSIONED "libadsp_default_listener.so.1"
@@ -27,6 +28,7 @@
#define SDSP_LISTENER_VERSIONED "libsdsp_default_listener.so.1"
#define SDSP_LISTENER_UNVERSIONED "libsdsp_default_listener.so"
#endif
+/* GDSP uses CDSP libraries (not a typo) */
#ifndef GDSP_LISTENER_VERSIONED
#define GDSP_LISTENER_VERSIONED "libcdsp_default_listener.so.1"
#define GDSP_LISTENER_UNVERSIONED "libcdsp_default_listener.so"
@@ -34,6 +36,64 @@
typedef int (*dsp_default_listener_start_t)(int argc, char *argv[]);
+/**
+ * Prints help information about the daemon.
+ * @param program_name The name of the program
+ * @param dsp_name The DSP name (ADSP, CDSP, etc.)
+ */
+static void print_help(const char *program_name, const char *dsp_name) {
+ printf("Usage: %s [OPTION]...\n", program_name);
+ printf("Daemon that establishes a connection to %s.\n", dsp_name);
+#ifdef USE_ADSP
+ printf("If audiopd is passed as an argument to this daemon, it will connect to audio PD on %s.\n", dsp_name);
+#endif
+ printf("If no argument is provided or rootpd is passed, it will connect to root PD on %s.\n\n", dsp_name);
+
+ printf("Functionality:\n");
+#ifdef USE_ADSP
+ printf(" rootpd:\n");
+ printf(" - Exception logging: Facilitates transfer of %s process exception logs\n", dsp_name);
+ printf(" to the HLOS (High-Level Operating System) logging infrastructure for\n");
+ printf(" effective monitoring and debugging\n");
+ printf(" - Remote file system access\n");
+ printf(" audiopd:\n");
+ printf(" - Memory requirements for audio PD dynamic loading\n");
+ printf(" - Remote file system access\n\n");
+#elif defined(USE_SDSP)
+ printf(" rootpd:\n");
+ printf(" - Remote file system access\n\n");
+#else
+ printf(" rootpd:\n");
+ printf(" - Exception logging: Facilitates transfer of %s process exception logs\n", dsp_name);
+ printf(" to the HLOS (High-Level Operating System) logging infrastructure for\n");
+ printf(" effective monitoring and debugging\n");
+ printf(" - Remote file system access\n\n");
+#endif
+
+ printf("Options:\n");
+ printf(" -h, --help display this help and exit\n");
+ printf(" start daemon for specific PD and domain\n");
+#ifdef USE_ADSP
+ printf(" example: %s rootpd adsp\n", program_name);
+#elif defined(USE_SDSP)
+ printf(" example: %s rootpd sdsp\n", program_name);
+#elif defined(USE_CDSP)
+ printf(" example: %s rootpd cdsp (or cdsp1)\n", program_name);
+#elif defined(USE_GDSP)
+ printf(" example: %s rootpd gdsp0 (or gdsp1)\n", program_name);
+#endif
+#ifndef USE_GDSP
+ printf(" start daemon for specific PD\n");
+ printf(" example: %s rootpd\n", program_name);
+ printf(" (no arguments) start daemon for root PD (default domain)\n\n");
+#else
+ printf("\n");
+#endif
+
+ printf("Note that this daemon runs continuously and automatically restarts on errors.\n");
+ printf("It exits only when the fastRPC device node is not accessible.\n");
+}
+
// Result struct for dlopen.
struct dlopen_result {
void *handle;
@@ -91,8 +151,28 @@ int main(int argc, char *argv[]) {
lib_unversioned = GDSP_LISTENER_UNVERSIONED;
dsp_name = "GDSP";
#else
- goto bail;
+ VERIFY_EPRINTF("daemon exiting %x (no DSP type defined)", nErr);
+ return nErr;
#endif
+
+ // Parse command-line options
+ static struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+
+ int opt;
+ while ((opt = getopt_long(argc, argv, "h", long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'h':
+ print_help(argv[0], dsp_name);
+ return 0;
+ default:
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
+ return 1;
+ }
+ }
+
VERIFY_EPRINTF("%s daemon starting", dsp_name);
while (1) {
@@ -119,7 +199,6 @@ int main(int argc, char *argv[]) {
usleep(100000);
}
- bail:
- VERIFY_EPRINTF("daemon exiting %x", nErr);
- return nErr;
+ VERIFY_EPRINTF("daemon exiting %x", nErr);
+ return nErr;
}
diff --git a/src/dspsignal.c b/src/dspsignal.c
index 01c1c1c..7e3fa88 100644
--- a/src/dspsignal.c
+++ b/src/dspsignal.c
@@ -219,7 +219,6 @@ AEEResult dspsignal_wait(int domain, uint32_t id, uint32_t timeout_usec) {
domain = get_domain(domain);
VERIFYC(IS_VALID_EFFECTIVE_DOMAIN_ID(domain), AEE_EBADPARM);
VERIFYC((ds = (struct dspsignal_domain_signals *)signals->domain_signals[domain]) != NULL, AEE_EBADSTATE);
- fastrpc_qos_activity(domain);
FARF(MEDIUM, "%s: Wait signal %u timeout %u", __func__, id, timeout_usec);
errno = 0;
diff --git a/src/fastrpc_apps_user.c b/src/fastrpc_apps_user.c
index f111ccf..e2e7aca 100644
--- a/src/fastrpc_apps_user.c
+++ b/src/fastrpc_apps_user.c
@@ -52,12 +52,10 @@
#include "apps_std_internal.h"
#include "dspsignal.h"
#include "fastrpc_apps_user.h"
-#include "fastrpc_async.h"
#include "fastrpc_cap.h"
#include "fastrpc_common.h"
#include "fastrpc_config.h"
#include "fastrpc_internal.h"
-#include "fastrpc_latency.h"
#include "fastrpc_log.h"
#include "fastrpc_mem.h"
#include "fastrpc_notif.h"
@@ -216,6 +214,7 @@ extern int perf_v2_dsp;
#define MIN_PD_INITMEM_SIZE (3 * 1024 * 1024)
#define MAX_PD_INITMEM_SIZE (200 * 1024 * 1024)
+#define FASTRPC_QOS_MAX_LATENCY_USEC (10000)
#define PM_TIMEOUT_MS 5
enum handle_list_id {
@@ -399,7 +398,8 @@ int fastrpc_session_put(int domain) {
do {
if (hlist) {
pthread_mutex_lock(&hlist[domain].mut);
- hlist[domain].ref--;
+ if (hlist[domain].ref > 0)
+ hlist[domain].ref--;
ref = hlist[domain].ref;
pthread_mutex_unlock(&hlist[domain].mut);
FARF(RUNTIME_RPC_HIGH, "%s, domain %d, state %d, ref %d\n", __func__, domain,
@@ -1154,8 +1154,7 @@ static void fastrpc_delete_timer(timer_t *timer) {
}
int remote_handle_invoke_domain(int domain, remote_handle handle,
- fastrpc_async_descriptor_t *desc, uint32_t sc,
- remote_arg *pra) {
+ uint32_t sc, remote_arg *pra) {
int dev, total, bufs, handles, i, nErr = 0, wake_lock = 0, rpc_timeout = 0;
unsigned req;
uint32_t len;
@@ -1164,7 +1163,6 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
uint32_t *crc_local = NULL;
uint64_t *perf_kernel = NULL;
uint64_t *perf_dsp = NULL;
- struct fastrpc_async_job asyncjob = {0}, *job = NULL;
fastrpc_timer frpc_timer;
int trace_marker_fd = hlist[domain].trace_marker_fd;
bool trace_enabled = false;
@@ -1172,8 +1170,11 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
if (IS_QTF_TRACING_ENABLED(hlist[domain].procattrs) &&
!IS_STATIC_HANDLE(handle) && trace_marker_fd > 0) {
- write(trace_marker_fd, INVOKE_BEGIN_TRACE_STR, invoke_begin_trace_strlen);
- trace_enabled = true;
+ /* Write begin trace marker; only enable tracing if write succeeds.
+ * This ensures we don't attempt to write an end marker if begin failed. */
+ ssize_t ret = write(trace_marker_fd, INVOKE_BEGIN_TRACE_STR, invoke_begin_trace_strlen);
+ if (ret > 0)
+ trace_enabled = true;
}
VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(domain, &dev)));
@@ -1208,31 +1209,6 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
INITIALIZE_REMOTE_ARGS(total);
- if (desc) {
- struct timespec time_spec;
- // Check for valid user async descriptor
- VERIFYC(desc->type >= FASTRPC_ASYNC_NO_SYNC &&
- desc->type < FASTRPC_ASYNC_TYPE_MAX,
- AEE_EBADPARM);
- VERIFYC(!(desc->type == FASTRPC_ASYNC_CALLBACK && desc->cb.fn == NULL),
- AEE_EBADPARM);
- pthread_mutex_lock(&hlist[domain].async_init_deinit_mut);
- if (AEE_SUCCESS != (nErr = fastrpc_async_domain_init(domain))) {
- pthread_mutex_unlock(&hlist[domain].async_init_deinit_mut);
- goto bail;
- }
- asyncjob.jobid = ++list->jobid;
- pthread_mutex_unlock(&hlist[domain].async_init_deinit_mut);
- clock_gettime(CLOCK_MONOTONIC, &time_spec);
- asyncjob.jobid = ((((time_spec.tv_sec) / SECONDS_PER_HOUR)
- << (FASTRPC_ASYNC_TIME_SPEC_POS / 2))
- << ((FASTRPC_ASYNC_TIME_SPEC_POS + 1) / 2) |
- (asyncjob.jobid << FASTRPC_ASYNC_JOB_POS) | domain);
- asyncjob.isasyncjob = 1;
- fastrpc_save_async_job(domain, &asyncjob, desc);
- job = &asyncjob;
- }
-
req = INVOKE;
VERIFYC(!(NULL == pra && total > 0), AEE_EBADPARM);
for (i = 0; i < bufs; i++) {
@@ -1247,11 +1223,6 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
set_args_fd(i, fd);
req = INVOKE_FD;
}
- // AsyncRPC doesn't support Non-ion output buffers
- if (asyncjob.isasyncjob && i >= (int)REMOTE_SCALARS_INBUFS(sc)) {
- VERIFYM(fd != -1, AEE_EBADPARM,
- "AsyncRPC doesn't support Non-ion output buffers");
- }
if (nova) {
req = INVOKE_ATTRS;
append_args_attr(i, FASTRPC_ATTR_NOVA);
@@ -1309,7 +1280,7 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
}
if (IS_CRC_CHECK_ENABLED(hlist[domain].procattrs) &&
- (!IS_STATIC_HANDLE(handle)) && !asyncjob.isasyncjob) {
+ (!IS_STATIC_HANDLE(handle))) {
int nInBufs = REMOTE_SCALARS_INBUFS(sc);
crc_local = (uint32_t *)calloc(M_CRCLIST, sizeof(uint32_t));
crc_remote = (uint32_t *)calloc(M_CRCLIST, sizeof(uint32_t));
@@ -1335,7 +1306,6 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
}
if (!IS_STATIC_HANDLE(handle)) {
- fastrpc_latency_invoke_incr(&hlist[domain].qos);
if ((rpc_timeout = fastrpc_config_get_rpctimeout()) > 0) {
frpc_timer.domain = domain;
frpc_timer.sc = sc;
@@ -1353,7 +1323,7 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
wake_lock = 0;
}
// Macros are initializing and destroying pfds and pattrs.
- nErr = ioctl_invoke(dev, req, handle, sc, get_args(), pfds, pattrs, job,
+ nErr = ioctl_invoke(dev, req, handle, sc, get_args(), pfds, pattrs,
crc_remote, perf_kernel, perf_dsp);
if (nErr) {
nErr = convert_kernel_to_user_error(nErr, errno);
@@ -1369,7 +1339,7 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
}
if (IS_CRC_CHECK_ENABLED(hlist[domain].procattrs) &&
- (!IS_STATIC_HANDLE(handle)) && !asyncjob.isasyncjob) {
+ (!IS_STATIC_HANDLE(handle))) {
int nInBufs = REMOTE_SCALARS_INBUFS(sc);
VERIFYC(crc_local != NULL && crc_remote != NULL, AEE_ENOMEMORY);
for (i = nInBufs; i < bufs; i++)
@@ -1385,7 +1355,7 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
}
if (IS_KERNEL_PERF_ENABLED(hlist[domain].procattrs) &&
- (!IS_STATIC_HANDLE(handle)) && !asyncjob.isasyncjob) {
+ (!IS_STATIC_HANDLE(handle))) {
VERIFYC(perf_kernel != NULL, AEE_ENOMEMORY);
FARF(ALWAYS,
"RPCPERF-K H:0x%x SC:0x%x C:%" PRIu64 " F:%" PRIu64 " ns M:%" PRIu64
@@ -1396,7 +1366,7 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
perf_kernel[7], perf_kernel[8]);
}
if (IS_DSP_PERF_ENABLED(hlist[domain].procattrs) &&
- (!IS_STATIC_HANDLE(handle)) && !asyncjob.isasyncjob) {
+ (!IS_STATIC_HANDLE(handle))) {
VERIFYC(perf_dsp != NULL, AEE_ENOMEMORY);
FARF(ALWAYS,
"RPCPERF-D H:0x%x SC:0x%x C:%" PRIu64 " M_H:%" PRIu64 " us M:%" PRIu64
@@ -1413,16 +1383,6 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
fastrpc_perf_update(dev, handle, sc);
}
bail:
- if (asyncjob.isasyncjob) {
- if (!nErr) {
- FARF(RUNTIME_RPC_HIGH, "adsprpc : %s Async job Queued, job 0x%" PRIx64 "",
- __func__, asyncjob.jobid);
- desc->jobid = asyncjob.jobid;
- } else {
- fastrpc_remove_async_job(asyncjob.jobid, false);
- desc->jobid = -1;
- }
- }
DESTROY_REMOTE_ARGS();
if (crc_local) {
free(crc_local);
@@ -1432,11 +1392,11 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
free(crc_remote);
crc_remote = NULL;
}
- if (perf_kernel && !asyncjob.isasyncjob) {
+ if (perf_kernel) {
free(perf_kernel);
perf_kernel = NULL;
}
- if (perf_dsp && !asyncjob.isasyncjob) {
+ if (perf_dsp) {
free(perf_dsp);
perf_dsp = NULL;
}
@@ -1449,7 +1409,10 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
}
}
if (trace_enabled) {
- write(trace_marker_fd, INVOKE_END_TRACE_STR, invoke_end_trace_strlen);
+ /* Write end trace marker. Store return value to satisfy warn_unused_result,
+ * but don't check it since trace writes are optional and failures are non-critical. */
+ ssize_t ret __attribute__((unused));
+ ret = write(trace_marker_fd, INVOKE_END_TRACE_STR, invoke_end_trace_strlen);
}
if (nErr != AEE_SUCCESS) {
if ((nErr == -1) && (errno == ECONNRESET)) {
@@ -1475,7 +1438,7 @@ int remote_handle_invoke(remote_handle handle, uint32_t sc, remote_arg *pra) {
domain = get_current_domain();
FASTRPC_GET_REF(domain);
VERIFY(AEE_SUCCESS ==
- (nErr = remote_handle_invoke_domain(domain, handle, NULL, sc, pra)));
+ (nErr = remote_handle_invoke_domain(domain, handle, sc, pra)));
bail:
FASTRPC_PUT_REF(domain);
if (nErr != AEE_SUCCESS) {
@@ -1523,7 +1486,7 @@ int remote_handle64_invoke(remote_handle64 local, uint32_t sc,
FASTRPC_GET_REF(domain);
VERIFY(AEE_SUCCESS == (nErr = get_handle_remote(local, &remote)));
VERIFY(AEE_SUCCESS ==
- (nErr = remote_handle_invoke_domain(domain, remote, NULL, sc, pra)));
+ (nErr = remote_handle_invoke_domain(domain, remote, sc, pra)));
bail:
FASTRPC_PUT_REF(domain);
if (nErr != AEE_SUCCESS) {
@@ -1532,11 +1495,19 @@ int remote_handle64_invoke(remote_handle64 local, uint32_t sc,
}
if (0 == check_rpc_error(nErr)) {
if (get_logger_state(domain)) {
- FARF(ERROR,
- "Error 0x%x: %s failed for module %s, handle 0x%" PRIx64
- ", method %d on domain %d (sc 0x%x) (errno %s)\n",
- nErr, __func__, h->name, local, REMOTE_SCALARS_METHOD(sc), domain, sc,
- strerror(errno));
+ if (nErr == DSP_AEE_EOFFSET + AEE_ENOSUCHMOD) {
+ FARF(ALWAYS,
+ "Warning: %s module %s is not supported on DSP domain %d, handle 0x%" PRIx64
+ ", method %d (sc 0x%x) (errno %s)\n",
+ __func__, h->name, domain, local, REMOTE_SCALARS_METHOD(sc), sc,
+ strerror(errno));
+ } else {
+ FARF(ERROR,
+ "Error 0x%x: %s failed for module %s, handle 0x%" PRIx64
+ ", method %d on domain %d (sc 0x%x) (errno %s)\n",
+ nErr, __func__, h->name, local, REMOTE_SCALARS_METHOD(sc), domain, sc,
+ strerror(errno));
+ }
}
}
}
@@ -1544,72 +1515,6 @@ int remote_handle64_invoke(remote_handle64 local, uint32_t sc,
return nErr;
}
-int remote_handle_invoke_async(remote_handle handle,
- fastrpc_async_descriptor_t *desc, uint32_t sc,
- remote_arg *pra) {
- int domain = -1, nErr = AEE_SUCCESS, ref = 0;
-
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
-
- FARF(RUNTIME_RPC_HIGH, "Entering %s, handle %u desc %p sc %X remote_arg %p\n",
- __func__, handle, desc, sc, pra);
- FASTRPC_ATRACE_BEGIN_L("%s called with handle 0x%x , scalar 0x%x", __func__,
- (int)handle, sc);
- VERIFYC(handle != (remote_handle)-1, AEE_EINVHANDLE);
-
- domain = get_current_domain();
- FASTRPC_GET_REF(domain);
- VERIFY(AEE_SUCCESS ==
- (nErr = remote_handle_invoke_domain(domain, handle, desc, sc, pra)));
-bail:
- FASTRPC_PUT_REF(domain);
- if (nErr != AEE_SUCCESS) {
- if (0 == check_rpc_error(nErr)) {
- FARF(ERROR,
- "Error 0x%x: %s failed for handle 0x%x, method %d async type %d on "
- "domain %d (sc 0x%x) (errno %s)\n",
- nErr, __func__, (int)handle, REMOTE_SCALARS_METHOD(sc), desc->type,
- domain, sc, strerror(errno));
- }
- }
- FASTRPC_ATRACE_END();
- return nErr;
-}
-
-int remote_handle64_invoke_async(remote_handle64 local,
- fastrpc_async_descriptor_t *desc, uint32_t sc,
- remote_arg *pra) {
- remote_handle64 remote = 0;
- int nErr = AEE_SUCCESS, domain = -1, ref = 0;
-
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
-
- FARF(RUNTIME_RPC_HIGH, "Entering %s, handle %llu desc %p sc %X remote_arg %p\n", __func__,
- local, desc, sc, pra);
- FASTRPC_ATRACE_BEGIN_L("%s called with handle 0x%x , scalar 0x%x", __func__,
- (int)local, sc);
- VERIFYC(local != (remote_handle64)-1, AEE_EINVHANDLE);
-
- VERIFY(AEE_SUCCESS == (nErr = get_domain_from_handle(local, &domain)));
- FASTRPC_GET_REF(domain);
- VERIFY(AEE_SUCCESS == (nErr = get_handle_remote(local, &remote)));
- VERIFY(AEE_SUCCESS ==
- (nErr = remote_handle_invoke_domain(domain, remote, desc, sc, pra)));
-bail:
- FASTRPC_PUT_REF(domain);
- if (nErr != AEE_SUCCESS) {
- if (0 == check_rpc_error(nErr)) {
- FARF(ERROR,
- "Error 0x%x: %s failed for handle 0x%" PRIx64
- ", method %d on domain %d (sc 0x%x) (errno %s)\n",
- nErr, __func__, local, REMOTE_SCALARS_METHOD(sc), domain, sc,
- strerror(errno));
- }
- }
- FASTRPC_ATRACE_END();
- return nErr;
-}
-
int listener_android_geteventfd(int domain, int *fd);
int remote_handle_open_domain(int domain, const char *name, remote_handle *ph,
uint64_t *t_spawn, uint64_t *t_load) {
@@ -1661,14 +1566,13 @@ int remote_handle_open_domain(int domain, const char *name, remote_handle *ph,
*/
if (strstr(pdName, get_domain_from_id(GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain))) &&
strstr(pdName, FASTRPC_SESSION_URI)) {
- strlcpy(pdName, pdName,
- (strlen(pdName) -
- strlen(get_domain_from_id(GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain))) -
- strlen(FASTRPC_SESSION1_URI) + 1));
+ /* Truncate string in place by null-terminating at desired length */
+ pdName[strlen(pdName) -
+ strlen(get_domain_from_id(GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain))) -
+ strlen(FASTRPC_SESSION1_URI)] = '\0';
} else if (strstr(pdName, get_domain_from_id(domain))) {
- strlcpy(
- pdName, pdName,
- (strlen(pdName) - strlen(get_domain_from_id(domain)) + 1));
+ /* Truncate string in place by null-terminating at desired length */
+ pdName[strlen(pdName) - strlen(get_domain_from_id(domain))] = '\0';
}
VERIFYC(MAX_DSPPD_NAMELEN > strlen(pdName), AEE_EBADPARM);
strlcpy(hlist[domain].dsppdname, pdName, strlen(pdName) + 1);
@@ -1978,18 +1882,13 @@ int remote_handle64_close(remote_handle64 handle) {
return nErr;
}
-static int manage_pm_qos(int domain, remote_handle64 h, uint32_t enable,
- uint32_t latency) {
- return fastrpc_set_pm_qos(&hlist[domain].qos, enable, latency);
-}
-
static int manage_adaptive_qos(int domain, uint32_t enable) {
int nErr = AEE_SUCCESS;
remote_handle64 handle = INVALID_HANDLE;
/* If adaptive QoS is already enabled/disabled, then just return */
- if ((enable && hlist[domain].qos.adaptive_qos) ||
- (!enable && !hlist[domain].qos.adaptive_qos))
+ if ((enable && hlist[domain].adaptive_qos) ||
+ (!enable && !hlist[domain].adaptive_qos))
return nErr;
if (hlist[domain].dev != -1) {
@@ -2020,11 +1919,11 @@ static int manage_adaptive_qos(int domain, uint32_t enable) {
__func__, enable, domain);
goto bail;
} else {
- hlist[domain].qos.adaptive_qos = ((enable == RPC_ADAPTIVE_QOS) ? 1 : 0);
+ hlist[domain].adaptive_qos = ((enable == RPC_ADAPTIVE_QOS) ? 1 : 0);
}
} else {
/* If session is not created already, then just set process attribute */
- hlist[domain].qos.adaptive_qos = ((enable == RPC_ADAPTIVE_QOS) ? 1 : 0);
+ hlist[domain].adaptive_qos = ((enable == RPC_ADAPTIVE_QOS) ? 1 : 0);
}
if (enable)
@@ -2089,14 +1988,6 @@ static int manage_poll_qos(int domain, remote_handle64 h, uint32_t enable,
return nErr;
}
-// Notify FastRPC QoS logic of activity outside of the invoke code path.
-// This function needs to be in this file to be able to access hlist.
-void fastrpc_qos_activity(int domain) {
- if (IS_VALID_EFFECTIVE_DOMAIN_ID(domain) && hlist) {
- fastrpc_latency_invoke_incr(&hlist[domain].qos);
- }
-}
-
static inline int enable_process_state_notif_on_dsp(int domain) {
int nErr = AEE_SUCCESS;
remote_handle64 notif_handle = 0;
@@ -2113,81 +2004,6 @@ static inline int enable_process_state_notif_on_dsp(int domain) {
return nErr;
}
-/*
- * Internal function to get async response from kernel. Waits in kernel until
- * response is received from DSP
- * @ domain: domain to which Async job is submitted
- * @ async_data: IOCTL structure that is sent to kernel to get async response
- * job information returns 0 on success
- *
- */
-int get_remote_async_response(int domain, fastrpc_async_jobid *jobid,
- int *result) {
- int nErr = AEE_SUCCESS, dev = -1;
- uint64_t *perf_kernel = NULL, *perf_dsp = NULL;
- fastrpc_async_jobid job = -1;
- int res = -1;
- remote_handle handle = -1;
- uint32_t sc = 0;
-
- VERIFYC(IS_VALID_EFFECTIVE_DOMAIN_ID(domain), AEE_EBADPARM);
- VERIFY(AEE_SUCCESS == (nErr = domain_init(domain, &dev)));
- VERIFYM(-1 != dev, AEE_ERPC, "open dev failed\n");
- if (IS_KERNEL_PERF_ENABLED(hlist[domain].procattrs)) {
- perf_kernel = (uint64_t *)calloc(PERF_KERNEL_KEY_MAX, sizeof(uint64_t));
- VERIFYC(perf_kernel != NULL, AEE_ENOMEMORY);
- }
- if (IS_DSP_PERF_ENABLED(hlist[domain].procattrs)) {
- perf_dsp = (uint64_t *)calloc(PERF_DSP_KEY_MAX, sizeof(uint64_t));
- VERIFYC(perf_dsp != NULL, AEE_ENOMEMORY);
- }
- nErr = ioctl_invoke2_response(dev, &job, &handle, &sc, &res, perf_kernel,
- perf_dsp);
- if (IS_KERNEL_PERF_ENABLED(hlist[domain].procattrs) &&
- (!IS_STATIC_HANDLE(handle))) {
- VERIFYC(perf_kernel != NULL, AEE_ENOMEMORY);
- FARF(ALWAYS,
- "RPCPERF-K H:0x%x SC:0x%x C:%" PRIu64 " F:%" PRIu64 " ns M:%" PRIu64
- " ns CP:%" PRIu64 " ns L:%" PRIu64 " ns G:%" PRIu64 " ns P:%" PRIu64
- " ns INV:%" PRIu64 " ns INVOKE:%" PRIu64 " ns\n",
- handle, sc, perf_kernel[0], perf_kernel[1], perf_kernel[2],
- perf_kernel[3], perf_kernel[4], perf_kernel[5], perf_kernel[6],
- perf_kernel[7], perf_kernel[8]);
- }
- if (IS_DSP_PERF_ENABLED(hlist[domain].procattrs) &&
- (!IS_STATIC_HANDLE(handle))) {
- VERIFYC(perf_dsp != NULL, AEE_ENOMEMORY);
- FARF(ALWAYS,
- "RPCPERF-D H:0x%x SC:0x%x C:%" PRIu64 " M_H:%" PRIu64 " us M:%" PRIu64
- " us G:%" PRIu64 " us INVOKE:%" PRIu64 " us P:%" PRIu64
- " us CACHE:%" PRIu64 " us UM:%" PRIu64 " us "
- "UM_H:%" PRIu64 " us R:%" PRIu64 " us E_R:%" PRIu64
- " us J_S_T:%" PRIu64 " us\n",
- handle, sc, perf_dsp[0], perf_dsp[1], perf_dsp[2], perf_dsp[3],
- perf_dsp[4], perf_dsp[5], perf_dsp[6], perf_dsp[7], perf_dsp[8],
- perf_dsp[9], perf_dsp[10], perf_dsp[11]);
- }
- *jobid = job;
- *result = res;
-
-bail:
- if (perf_kernel) {
- free(perf_kernel);
- perf_kernel = NULL;
- }
- if (perf_dsp) {
- free(perf_dsp);
- perf_dsp = NULL;
- }
- if (nErr) {
- FARF(ERROR,
- "Error 0x%x: %s failed to get async response data for domain %d errno "
- "%s",
- nErr, __func__, domain, strerror(errno));
- }
- return nErr;
-}
-
/* fastrpc_set_qos_latency:
Send user QoS latency requirement to DSP.
DSP will use required features to meet the requirement.
@@ -2285,7 +2101,6 @@ static int fastrpc_dsp_process_clean(int domain) {
int remote_handle_control_domain(int domain, remote_handle64 h, uint32_t req,
void *data, uint32_t len) {
int nErr = AEE_SUCCESS;
- const unsigned int POLL_MODE_PM_QOS_LATENCY = 100;
FARF(RUNTIME_RPC_HIGH, "Entering %s, domain %d, handle %llu, req %d, data %p, size %d\n",
__func__, domain, h, req, data, len);
@@ -2302,8 +2117,6 @@ int remote_handle_control_domain(int domain, remote_handle64 h, uint32_t req,
case RPC_DISABLE_QOS: {
VERIFY(AEE_SUCCESS ==
(nErr = manage_adaptive_qos(domain, RPC_DISABLE_QOS)));
- VERIFY(AEE_SUCCESS ==
- (nErr = manage_pm_qos(domain, h, RPC_DISABLE_QOS, lp->latency)));
VERIFY(AEE_SUCCESS ==
(nErr = manage_poll_qos(domain, h, RPC_DISABLE_QOS, lp->latency)));
/* Error ignored, currently meeting qos requirement is optional. Consider
@@ -2312,19 +2125,12 @@ int remote_handle_control_domain(int domain, remote_handle64 h, uint32_t req,
break;
}
case RPC_PM_QOS: {
- VERIFY(AEE_SUCCESS ==
- (nErr = manage_adaptive_qos(domain, RPC_DISABLE_QOS)));
- VERIFY(AEE_SUCCESS ==
- (nErr = manage_pm_qos(domain, h, RPC_PM_QOS, lp->latency)));
- /* Error ignored, currently meeting qos requirement is optional. Consider
- * to error out in later targets */
- fastrpc_set_qos_latency(domain, h, lp->latency);
+ FARF(ALWAYS, "Warning: PM QoS is not supported; ignoring request and returning "
+ "success for backward compatibility");
break;
}
case RPC_ADAPTIVE_QOS: {
- /* Disable PM QoS if enabled and then enable adaptive QoS */
- VERIFY(AEE_SUCCESS ==
- (nErr = manage_pm_qos(domain, h, RPC_DISABLE_QOS, lp->latency)));
+ /* Enable adaptive QoS */
VERIFY(AEE_SUCCESS ==
(nErr = manage_adaptive_qos(domain, RPC_ADAPTIVE_QOS)));
/* Error ignored, currently meeting qos requirement is optional. Consider
@@ -2335,13 +2141,6 @@ int remote_handle_control_domain(int domain, remote_handle64 h, uint32_t req,
case RPC_POLL_QOS: {
VERIFY(AEE_SUCCESS ==
(nErr = manage_poll_qos(domain, h, RPC_POLL_QOS, lp->latency)));
-
- /*
- * Poll QoS option also enables PM QoS to enable early response from DSP
- * and stop the CPU cores from going into deep sleep low power modes.
- */
- VERIFY(AEE_SUCCESS == (nErr = manage_pm_qos(domain, h, RPC_PM_QOS,
- POLL_MODE_PM_QOS_LATENCY)));
break;
}
default:
@@ -2455,7 +2254,7 @@ int remote_handle64_control(remote_handle64 handle, uint32_t req, void *data,
static int close_domain_session(int domain) {
QNode *pn = NULL, *pnn = NULL;
char dlerrstr[255];
- int dlerr = 0, nErr = AEE_SUCCESS;
+ int dlerr = 0, nErr = AEE_SUCCESS, mut_locked = 0;
remote_handle64 proc_handle = 0;
FARF(ALWAYS,
@@ -2469,13 +2268,16 @@ static int close_domain_session(int domain) {
adsp_current_process_exit();
}
pthread_mutex_lock(&hlist[domain].lmut);
+ mut_locked = 1;
if (!QList_IsEmpty(&hlist[domain].nql)) {
QLIST_NEXTSAFE_FOR_ALL(&hlist[domain].nql, pn, pnn) {
struct handle_info *hi = STD_RECOVER_REC(struct handle_info, qn, pn);
VERIFYC(NULL != hi, AEE_EINVHANDLE);
pthread_mutex_unlock(&hlist[domain].lmut);
+ mut_locked = 0;
remote_handle_close(hi->remote);
pthread_mutex_lock(&hlist[domain].lmut);
+ mut_locked = 1;
}
}
if (!QList_IsEmpty(&hlist[domain].rql)) {
@@ -2483,8 +2285,10 @@ static int close_domain_session(int domain) {
struct handle_info *hi = STD_RECOVER_REC(struct handle_info, qn, pn);
VERIFYC(NULL != hi, AEE_EINVHANDLE);
pthread_mutex_unlock(&hlist[domain].lmut);
+ mut_locked = 0;
close_reverse_handle(hi->local, dlerrstr, sizeof(dlerrstr), &dlerr);
pthread_mutex_lock(&hlist[domain].lmut);
+ mut_locked = 1;
}
}
if (!QList_IsEmpty(&hlist[domain].ql)) {
@@ -2492,12 +2296,19 @@ static int close_domain_session(int domain) {
struct handle_info *hi = STD_RECOVER_REC(struct handle_info, qn, pn);
VERIFYC(NULL != hi, AEE_EINVHANDLE);
pthread_mutex_unlock(&hlist[domain].lmut);
+ mut_locked = 0;
remote_handle64_close(hi->local);
pthread_mutex_lock(&hlist[domain].lmut);
+ mut_locked = 1;
}
}
pthread_mutex_unlock(&hlist[domain].lmut);
+ mut_locked = 0;
bail:
+ if (mut_locked) {
+ pthread_mutex_unlock(&hlist[domain].lmut);
+ mut_locked = 0;
+ }
if (nErr != AEE_SUCCESS) {
FARF(ERROR, "Error 0x%x: %s failed for domain %d (errno %s)", nErr,
__func__, domain, strerror(errno));
@@ -3150,7 +2961,6 @@ PL_DEP(gpls);
PL_DEP(apps_std);
PL_DEP(rpcmem);
PL_DEP(listener_android);
-PL_DEP(fastrpc_async);
static int attach_guestos(int domain) {
int attach;
@@ -3201,9 +3011,6 @@ static void domain_deinit(int domain) {
dspsignal_domain_deinit(domain);
listener_android_domain_deinit(domain);
hlist[domain].first_revrpc_done = 0;
- pthread_mutex_lock(&hlist[domain].async_init_deinit_mut);
- fastrpc_async_domain_deinit(domain);
- pthread_mutex_unlock(&hlist[domain].async_init_deinit_mut);
fastrpc_notif_domain_deinit(domain);
fastrpc_clear_handle_list(MULTI_DOMAIN_HANDLE_LIST_ID, domain);
fastrpc_clear_handle_list(REVERSE_HANDLE_LIST_ID, domain);
@@ -3211,7 +3018,6 @@ static void domain_deinit(int domain) {
fastrpc_clear_handle_list(NON_DOMAIN_HANDLE_LIST_ID, domain);
}
fastrpc_perf_deinit();
- fastrpc_latency_deinit(&hlist[domain].qos);
trace_marker_deinit(domain);
deinitFileWatcher(domain);
adspmsgd_stop(domain);
@@ -3249,99 +3055,62 @@ static void domain_deinit(int domain) {
pthread_mutex_unlock(&hlist[domain].mut);
}
-static const char *get_domain_name(int domain_id) {
- const char *name;
+void get_domain_device_names(int domain_id, const char **secure_name, const char **non_secure_name) {
int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain_id);
switch (domain) {
case ADSP_DOMAIN_ID:
- name = ADSPRPC_DEVICE;
+ *secure_name = ADSPRPC_SECURE_DEVICE;
+ *non_secure_name = ADSPRPC_DEVICE;
break;
case SDSP_DOMAIN_ID:
- name = SDSPRPC_DEVICE;
+ *secure_name = SDSPRPC_SECURE_DEVICE;
+ *non_secure_name = SDSPRPC_DEVICE;
break;
case MDSP_DOMAIN_ID:
- name = MDSPRPC_DEVICE;
+ *secure_name = MDSPRPC_SECURE_DEVICE;
+ *non_secure_name = MDSPRPC_DEVICE;
break;
case CDSP_DOMAIN_ID:
- name = CDSPRPC_DEVICE;
+ *secure_name = CDSPRPC_SECURE_DEVICE;
+ *non_secure_name = CDSPRPC_DEVICE;
break;
case CDSP1_DOMAIN_ID:
- name = CDSP1RPC_DEVICE;
+ *secure_name = CDSP1RPC_SECURE_DEVICE;
+ *non_secure_name = CDSP1RPC_DEVICE;
break;
case GDSP0_DOMAIN_ID:
- name = GDSP0RPC_DEVICE;
+ *secure_name = GDSP0RPC_SECURE_DEVICE;
+ *non_secure_name = GDSP0RPC_DEVICE;
break;
case GDSP1_DOMAIN_ID:
- name = GDSP1RPC_DEVICE;
+ *secure_name = GDSP1RPC_SECURE_DEVICE;
+ *non_secure_name = GDSP1RPC_DEVICE;
break;
default:
- name = DEFAULT_DEVICE;
+ FARF(ERROR, "ERROR: %s Invalid domain %d", __func__, domain);
+ *secure_name = NULL;
+ *non_secure_name = NULL;
break;
}
- return name;
}
int open_device_node(int domain_id) {
int dev = -1, nErr = 0;
int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain_id);
int sess_id = GET_SESSION_ID_FROM_DOMAIN_ID(domain_id);
+ const char *secure_dev = NULL, *non_secure_dev = NULL;
- switch (domain) {
- case ADSP_DOMAIN_ID:
- case SDSP_DOMAIN_ID:
- case MDSP_DOMAIN_ID:
- dev = open(get_secure_domain_name(domain), O_NONBLOCK);
- if ((dev < 0) && (errno == ENOENT)) {
- FARF(RUNTIME_RPC_HIGH,
- "Device node %s open failed for domain %d (errno %s),"
- "falling back to node %s \n",
- get_secure_domain_name(domain), domain, strerror(errno),
- get_domain_name(domain));
- dev = open(get_domain_name(domain), O_NONBLOCK);
- if ((dev < 0) && (errno == ENOENT)) {
- FARF(RUNTIME_RPC_HIGH,
- "Device node %s open failed for domain %d (errno %s),"
- "falling back to node %s \n",
- get_domain_name(domain), domain, strerror(errno), DEFAULT_DEVICE);
- dev = open(DEFAULT_DEVICE, O_NONBLOCK);
- }
- } else if ((dev < 0) && (errno == EACCES)) {
- // Open the default device node if unable to open the
- // secure device node due to permissions
- FARF(RUNTIME_RPC_HIGH,
- "Device node %s open failed for domain %d (errno %s),"
- "falling back to node %s \n",
- get_secure_domain_name(domain), domain, strerror(errno),
- DEFAULT_DEVICE);
- dev = open(DEFAULT_DEVICE, O_NONBLOCK);
- }
- break;
- case CDSP_DOMAIN_ID:
- case CDSP1_DOMAIN_ID:
- case GDSP0_DOMAIN_ID:
- case GDSP1_DOMAIN_ID:
- dev = open(get_secure_domain_name(domain), O_NONBLOCK);
+ if (IS_VALID_DOMAIN_ID(domain)) {
+ get_domain_device_names(domain, &secure_dev, &non_secure_dev);
+ dev = open(secure_dev, O_NONBLOCK);
if ((dev < 0) && ((errno == ENOENT) || (errno == EACCES))) {
FARF(RUNTIME_RPC_HIGH,
"Device node %s open failed for domain %d (errno %s),"
"falling back to node %s \n",
- get_secure_domain_name(domain), domain, strerror(errno),
- get_domain_name(domain));
- dev = open(get_domain_name(domain), O_NONBLOCK);
- if ((dev < 0) && ((errno == ENOENT) || (errno == EACCES))) {
- // Open the default device node if actual device node
- // is not present
- FARF(RUNTIME_RPC_HIGH,
- "Device node %s open failed for domain %d (errno %s),"
- "falling back to node %s \n",
- get_domain_name(domain), domain, strerror(errno), DEFAULT_DEVICE);
- dev = open(DEFAULT_DEVICE, O_NONBLOCK);
- }
+ secure_dev, domain, strerror(errno), non_secure_dev);
+ dev = open(non_secure_dev, O_NONBLOCK);
}
- break;
- default:
- break;
}
if (dev < 0)
FARF(ERROR,
@@ -3349,8 +3118,8 @@ int open_device_node(int domain_id) {
"dev : %s. (errno %d, %s) (Either the remote processor is down, or "
"application does not have permission to access the remote "
"processor\n",
- nErr, __func__, domain_id, sess_id, get_secure_domain_name(domain),
- get_domain_name(domain), errno, strerror(errno));
+ nErr, __func__, domain_id, sess_id, secure_dev,
+ non_secure_dev, errno, strerror(errno));
return dev;
}
@@ -3367,7 +3136,7 @@ static int get_process_attrs(int domain) {
attrs = fastrpc_get_property_int(FASTRPC_PROCESS_ATTRS, 0);
attrs |= fastrpc_get_property_int(FASTRPC_PROCESS_ATTRS_PERSISTENT, 0);
fastrpc_trace = fastrpc_get_property_int(FASTRPC_DEBUG_TRACE, 0);
- attrs |= hlist[domain].qos.adaptive_qos ? FASTRPC_MODE_ADAPTIVE_QOS : 0;
+ attrs |= hlist[domain].adaptive_qos ? FASTRPC_MODE_ADAPTIVE_QOS : 0;
attrs |= hlist[domain].unsigned_module ? FASTRPC_MODE_UNSIGNED_MODULE : 0;
attrs |= (hlist[domain].pd_dump | fastrpc_config_is_pddump_enabled())
? FASTRPC_MODE_ENABLE_PDDUMP
@@ -3573,7 +3342,7 @@ void print_process_attrs(int domain) {
signedMd = true;
pd_initmem_size = hlist[domain].pd_initmem_size;
}
- if (hlist[domain].qos.adaptive_qos)
+ if (hlist[domain].adaptive_qos)
qos = true;
if (hlist[domain].pd_dump | fastrpc_config_is_pddump_enabled())
configPDdump = true;
@@ -3956,14 +3725,16 @@ remote_handle64 get_adsp_perf1_handle(int domain) {
}
static int domain_init(int domain, int *dev) {
- int nErr = AEE_SUCCESS, dom = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain);
+ int nErr = AEE_SUCCESS, dom = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain), mut_locked = 0;
remote_handle64 panic_handle = 0;
struct err_codes *err_codes_to_send = NULL;
pthread_mutex_lock(&hlist[domain].mut);
+ mut_locked = 1;
if (hlist[domain].state != FASTRPC_DOMAIN_STATE_CLEAN) {
*dev = hlist[domain].dev;
pthread_mutex_unlock(&hlist[domain].mut);
+ mut_locked = 0;
return AEE_SUCCESS;
}
@@ -4020,12 +3791,11 @@ static int domain_init(int domain, int *dev) {
ret);
}
fastrpc_perf_init(hlist[domain].dev, domain);
- VERIFY(AEE_SUCCESS ==
- (nErr = fastrpc_latency_init(hlist[domain].dev, &hlist[domain].qos)));
get_dsp_dma_reverse_rpc_map_capability(domain);
hlist[domain].state = FASTRPC_DOMAIN_STATE_INIT;
hlist[domain].ref = 0;
pthread_mutex_unlock(&hlist[domain].mut);
+ mut_locked = 0;
VERIFY(AEE_SUCCESS == (nErr = listener_android_domain_init(
domain, hlist[domain].th_params.update_requested,
&hlist[domain].th_params.r_sem)));
@@ -4038,6 +3808,10 @@ static int domain_init(int domain, int *dev) {
}
bail:
if (nErr != AEE_SUCCESS) {
+ if (mut_locked) {
+ pthread_mutex_unlock(&hlist[domain].mut);
+ mut_locked = 0;
+ }
domain_deinit(domain);
if (hlist) {
FARF(ERROR, "Error 0x%x: %s (%d) failed for domain %d (errno %s)\n", nErr,
@@ -4077,7 +3851,6 @@ static void fastrpc_apps_user_deinit(void) {
pthread_mutex_destroy(&hlist[i].mut);
pthread_mutex_destroy(&hlist[i].lmut);
pthread_mutex_destroy(&hlist[i].init);
- pthread_mutex_destroy(&hlist[i].async_init_deinit_mut);
}
listener_android_deinit();
free(hlist);
@@ -4119,8 +3892,8 @@ static void exit_thread(void *value) {
INVALID_HANDLE) {
nErr = adsp_current_process1_thread_exit(handle);
if (nErr) {
- FARF(RUNTIME_RPC_HIGH, "%s: nErr:0x%x, dom:%d, h:0x%llx", __func__, nErr,
- domain, handle);
+ FARF(RUNTIME_RPC_HIGH, "%s: nErr:0x%x, dom:%d, h:0x%" PRIx64,
+ __func__, nErr, domain, handle);
}
} else if (domain == DEFAULT_DOMAIN_ID) {
nErr = adsp_current_process_thread_exit();
@@ -4152,6 +3925,7 @@ static int fastrpc_apps_user_init(void) {
VERIFY(AEE_SUCCESS == (nErr = PL_INIT(gpls)));
VERIFY(AEE_SUCCESS == (nErr = PL_INIT(rpcmem)));
+ VERIFY(AEE_SUCCESS == (nErr = PL_INIT(apps_std)));
VERIFY(AEE_SUCCESS == (nErr = pthread_key_create(&tlsKey, exit_thread)));
#ifdef PARSE_YAML
configure_dsp_paths();
@@ -4166,7 +3940,6 @@ static int fastrpc_apps_user_init(void) {
FOR_EACH_EFFECTIVE_DOMAIN_ID(i) {
hlist[i].dev = -1;
hlist[i].th_params.thread_priority = DEFAULT_UTHREAD_PRIORITY;
- hlist[i].jobid = 1;
hlist[i].info = -1;
hlist[i].th_params.stack_size = DEFAULT_UTHREAD_STACK_SIZE;
sem_init(&hlist[i].th_params.r_sem, 0,
@@ -4183,10 +3956,8 @@ static int fastrpc_apps_user_init(void) {
pthread_mutex_init(&hlist[i].mut, &attr);
pthread_mutex_init(&hlist[i].lmut, 0);
pthread_mutex_init(&hlist[i].init, 0);
- pthread_mutex_init(&hlist[i].async_init_deinit_mut, 0);
}
listener_android_init();
- VERIFY(AEE_SUCCESS == (nErr = PL_INIT(apps_std)));
GenCrc32Tab(POLY32, crc_table);
fastrpc_notif_init();
apps_mem_table_init();
diff --git a/src/fastrpc_async.c b/src/fastrpc_async.c
deleted file mode 100644
index c3b69e5..0000000
--- a/src/fastrpc_async.c
+++ /dev/null
@@ -1,489 +0,0 @@
-// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
-// SPDX-License-Identifier: BSD-3-Clause
-
-#ifndef VERIFY_PRINT_ERROR
-#define VERIFY_PRINT_ERROR
-#endif /* VERIFY_PRINT_ERROR */
-
-#define FARF_ERROR 1
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "AEEQList.h"
-#include "AEEStdErr.h"
-#include "AEEstd.h"
-#include "HAP_farf.h"
-#include "fastrpc_perf.h"
-#include "fastrpc_common.h"
-#include "fastrpc_async.h"
-#include "platform_libs.h"
-#include "verify.h"
-
-#define GET_DOMAIN_FROM_JOBID(jobid) (jobid & FASTRPC_ASYNC_DOMAIN_MASK)
-#define GET_HASH_FROM_JOBID(jobid) \
- ((jobid & FASTRPC_ASYNC_HASH_MASK) >> FASTRPC_ASYNC_JOB_POS)
-#define EVENT_COMPLETE 0xff
-
-struct fastrpc_async {
- QList ql[FASTRPC_ASYNC_QUEUE_LIST_LEN];
- pthread_mutex_t mut;
- pthread_t thread;
- int init_done;
- int deinit_started;
-};
-
-struct fastrpc_async_job_node {
- QNode qn;
- fastrpc_async_descriptor_t async_desc;
- bool isjobdone;
- struct pollfd pfd;
- int result;
-};
-
-pthread_mutex_t async_mut = PTHREAD_MUTEX_INITIALIZER;
-static struct fastrpc_async lasyncinfo[NUM_DOMAINS_EXTEND];
-
-extern void set_thread_context(int domain);
-static int get_remote_async_response(int domain, fastrpc_async_jobid *jobid,
- int *result);
-
-int fastrpc_search_async_job(fastrpc_async_jobid jobid,
- struct fastrpc_async_job_node **async_node) {
- int nErr = AEE_SUCCESS;
- int domain, hash;
- struct fastrpc_async *me = NULL;
- QNode *pn, *pnn;
- bool jobfound = false;
- struct fastrpc_async_job_node *lasync_node;
-
- domain = GET_DOMAIN_FROM_JOBID(jobid);
- hash = GET_HASH_FROM_JOBID(jobid);
- VERIFYC(IS_VALID_EFFECTIVE_DOMAIN_ID(domain), AEE_EBADPARM);
- me = &lasyncinfo[domain];
- VERIFYC(me->init_done == 1, AEE_EBADPARM);
- pthread_mutex_lock(&me->mut);
- QLIST_NEXTSAFE_FOR_ALL(&me->ql[hash], pn, pnn) {
- lasync_node = STD_RECOVER_REC(struct fastrpc_async_job_node, qn, pn);
- if (lasync_node->async_desc.jobid == jobid) {
- jobfound = true;
- break;
- }
- }
- pthread_mutex_unlock(&me->mut);
- VERIFYC(jobfound, AEE_EBADPARM);
- *async_node = lasync_node;
-bail:
- return nErr;
-}
-
-int fastrpc_async_get_status(fastrpc_async_jobid jobid, int timeout_us,
- int *result) {
- int nErr = AEE_SUCCESS;
- int domain;
- struct fastrpc_async *me = NULL;
- struct fastrpc_async_job_node *lasync_node = NULL;
- eventfd_t event = 0;
-
- VERIFYC(result != NULL, AEE_EBADPARM);
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_search_async_job(jobid, &lasync_node)));
- domain = GET_DOMAIN_FROM_JOBID(jobid);
- me = &lasyncinfo[domain];
- pthread_mutex_lock(&me->mut);
- if (lasync_node->isjobdone) { // If job is done, return result
- *result = lasync_node->result;
- goto unlock_bail;
- } else if (timeout_us == 0) { // If timeout 0, then return PENDING
- nErr = AEE_EBUSY;
- goto unlock_bail;
- }
- // If valid timeout(+ve/-ve), create poll event and wait on poll
- if (-1 == (lasync_node->pfd.fd = eventfd(0, 0))) {
- nErr = AEE_EFAILED;
- FARF(ERROR,
- "Error 0x%x: %s failed to create poll event for jobid 0x%" PRIx64
- " (%s)\n",
- nErr, __func__, jobid, strerror(errno));
- goto unlock_bail;
- }
- lasync_node->pfd.events = POLLIN;
- lasync_node->pfd.revents = 0;
- pthread_mutex_unlock(&me->mut);
- while (1) {
- VERIFYC(0 < poll(&lasync_node->pfd, 1, timeout_us), AEE_EFAILED);
- VERIFYC(0 == eventfd_read(lasync_node->pfd.fd, &event), AEE_EFAILED);
- if (event) {
- break;
- }
- }
- VERIFYC(lasync_node->isjobdone, AEE_EBUSY);
- *result = lasync_node->result;
- goto bail;
-unlock_bail:
- pthread_mutex_unlock(&me->mut);
-bail:
- if (nErr) {
- FARF(ERROR, "Error 0x%x: %s failed for jobid 0x%" PRIx64 " (%s)\n", nErr,
- __func__, jobid, strerror(errno));
- }
- return nErr;
-}
-
-int fastrpc_remove_async_job(fastrpc_async_jobid jobid,
- bool dsp_invoke_done) {
- int nErr = AEE_SUCCESS;
- struct fastrpc_async *me = NULL;
- struct fastrpc_async_job_node *lasync_node = NULL;
- int domain = -1;
-
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_search_async_job(jobid, &lasync_node)));
- domain = GET_DOMAIN_FROM_JOBID(jobid);
- me = &lasyncinfo[domain];
- pthread_mutex_lock(&me->mut);
- if (dsp_invoke_done && !lasync_node->isjobdone) {
- pthread_mutex_unlock(&me->mut);
- nErr = AEE_EBUSY;
- goto bail;
- }
- QNode_DequeueZ(&lasync_node->qn);
- pthread_mutex_unlock(&me->mut);
- if (lasync_node->async_desc.type == FASTRPC_ASYNC_POLL &&
- lasync_node->pfd.fd != -1) {
- close(lasync_node->pfd.fd);
- lasync_node->pfd.fd = -1;
- }
- free(lasync_node);
- lasync_node = NULL;
-bail:
- if (nErr) {
- FARF(ERROR,
- "Error 0x%x: %s failed for domain %d and jobid 0x%" PRIx64 " (%s)\n",
- nErr, __func__, domain, jobid, strerror(errno));
- }
- return nErr;
-}
-
-int fastrpc_release_async_job(fastrpc_async_jobid jobid) {
- return fastrpc_remove_async_job(jobid, true);
-}
-
-int fastrpc_save_async_job(int domain, struct fastrpc_async_job *async_job,
- fastrpc_async_descriptor_t *desc) {
- int nErr = AEE_SUCCESS;
- struct fastrpc_async *me = &lasyncinfo[domain];
- struct fastrpc_async_job_node *lasync_job = 0;
- int hash = -1;
-
- VERIFYC(me->init_done == 1, AEE_EINVALIDJOB);
- VERIFYC(NULL != (lasync_job = calloc(1, sizeof(*lasync_job))), AEE_ENOMEMORY);
- QNode_CtorZ(&lasync_job->qn);
- lasync_job->async_desc.jobid = async_job->jobid;
- lasync_job->async_desc.type = desc->type;
- lasync_job->async_desc.cb.fn = desc->cb.fn;
- lasync_job->async_desc.cb.context = desc->cb.context;
- lasync_job->isjobdone = false;
- lasync_job->result = -1;
- lasync_job->pfd.fd = -1;
- hash = GET_HASH_FROM_JOBID(lasync_job->async_desc.jobid);
- pthread_mutex_lock(&me->mut);
- QList_AppendNode(&me->ql[hash], &lasync_job->qn);
- pthread_mutex_unlock(&me->mut);
- FARF(RUNTIME_RPC_HIGH, "adsprpc: %s : Saving job with jobid 0x%" PRIx64 "",
- __func__, lasync_job->async_desc.jobid);
-bail:
- if (nErr) {
- FARF(ERROR, "Error 0x%x: %s failed for domain %d (%s)\n", nErr, __func__,
- domain, strerror(errno));
- }
- return nErr;
-}
-
-void fastrpc_async_respond_all_pending_jobs(int domain) {
- int i = 0;
- struct fastrpc_async *me = &lasyncinfo[domain];
- struct fastrpc_async_job_node *lasync_node = NULL;
- QNode *pn;
-
- for (i = 0; i < FASTRPC_ASYNC_QUEUE_LIST_LEN; i++) {
- pthread_mutex_lock(&me->mut);
- while (!QList_IsEmpty(&me->ql[i])) {
- pn = QList_GetFirst(&me->ql[i]);
- lasync_node = STD_RECOVER_REC(struct fastrpc_async_job_node, qn, pn);
- if (!lasync_node) {
- continue;
- }
- QNode_DequeueZ(&lasync_node->qn);
- lasync_node->result = -ECONNRESET;
- pthread_mutex_unlock(&me->mut);
- if (lasync_node->async_desc.type == FASTRPC_ASYNC_CALLBACK) {
- FARF(RUNTIME_RPC_HIGH,
- "adsprpc: %s callback jobid 0x%" PRIx64 " and result 0x%x",
- __func__, lasync_node->async_desc.jobid, lasync_node->result);
- lasync_node->async_desc.cb.fn(lasync_node->async_desc.jobid,
- lasync_node->async_desc.cb.context,
- lasync_node->result);
- } else if (lasync_node->async_desc.type == FASTRPC_ASYNC_POLL) {
- FARF(RUNTIME_RPC_HIGH,
- "adsprpc: %s poll jobid 0x%" PRIx64 " and result 0x%x", __func__,
- lasync_node->async_desc.jobid, lasync_node->result);
- if (lasync_node->pfd.fd != -1) {
- eventfd_write(lasync_node->pfd.fd, (eventfd_t)EVENT_COMPLETE);
- }
- }
- free(lasync_node);
- lasync_node = NULL;
- pthread_mutex_lock(&me->mut);
- }
- pthread_mutex_unlock(&me->mut);
- }
-}
-
-static void *async_fastrpc_thread(void *arg) {
- int nErr = AEE_SUCCESS;
- struct fastrpc_async *me = (struct fastrpc_async *)arg;
- int domain = (int)(me - &lasyncinfo[0]);
- struct fastrpc_async_job_node *lasync_node = NULL;
- int result = -1;
- fastrpc_async_jobid jobid = -1;
- QNode *pn, *pnn;
-
- int hash = -1;
- bool isjobfound = false;
-
- /// TODO: Do we really need this line?
- set_thread_context(domain);
- do {
- nErr = get_remote_async_response(domain, &jobid, &result);
- VERIFY(nErr == AEE_SUCCESS);
- FARF(RUNTIME_RPC_HIGH,
- "adsprpc: %s received async response for jobid 0x%" PRIx64
- " and result 0x%x",
- __func__, jobid, result);
- isjobfound = false;
- hash = GET_HASH_FROM_JOBID(jobid);
- pthread_mutex_lock(&me->mut);
- QLIST_NEXTSAFE_FOR_ALL(&me->ql[hash], pn, pnn) {
- lasync_node = STD_RECOVER_REC(struct fastrpc_async_job_node, qn, pn);
- if (lasync_node->async_desc.jobid == jobid) {
- lasync_node->isjobdone = true;
- lasync_node->result = result;
- isjobfound = true;
- switch (lasync_node->async_desc.type) {
- case FASTRPC_ASYNC_NO_SYNC:
- FARF(RUNTIME_RPC_HIGH,
- "adsprpc: %s nosync jobid 0x%" PRIx64 " and result 0x%x",
- __func__, lasync_node->async_desc.jobid, result);
- QNode_DequeueZ(&lasync_node->qn);
- pthread_mutex_unlock(&me->mut);
- free(lasync_node);
- lasync_node = NULL;
- break;
- case FASTRPC_ASYNC_POLL:
- FARF(RUNTIME_RPC_HIGH,
- "adsprpc: %s poll jobid 0x%" PRIx64 " and result 0x%x", __func__,
- lasync_node->async_desc.jobid, result);
- if (lasync_node->pfd.fd != -1) {
- eventfd_write(lasync_node->pfd.fd, (eventfd_t)EVENT_COMPLETE);
- }
- pthread_mutex_unlock(&me->mut);
- break;
- case FASTRPC_ASYNC_CALLBACK:
- pthread_mutex_unlock(&me->mut);
- FARF(RUNTIME_RPC_HIGH,
- "adsprpc: %s callback jobid 0x%" PRIx64 " and result 0x%x",
- __func__, lasync_node->async_desc.jobid, result);
- lasync_node->async_desc.cb.fn(lasync_node->async_desc.jobid,
- lasync_node->async_desc.cb.context,
- result);
- break;
- default:
- pthread_mutex_unlock(&me->mut);
- FARF(RUNTIME_RPC_HIGH,
- "adsprpc: %s Invalid job type for jobid 0x%" PRIx64 "", __func__,
- lasync_node->async_desc.jobid);
- break;
- }
- break;
- }
- }
- if (!isjobfound)
- pthread_mutex_unlock(&me->mut);
- } while (1);
-bail:
- if (nErr != AEE_SUCCESS) {
- VERIFY_EPRINTF("Error 0x%x: %s AsyncFastRPC worker thread exited for "
- "domain %d (errno %s), async_domain_deinit started %d",
- nErr, __func__, domain, strerror(errno), me->deinit_started);
- }
- dlerror();
- return (void *)(uintptr_t)nErr;
-}
-
-void async_thread_exit_handler(int sig) {
- FARF(ALWAYS, "Async FastRPC worker thread exiting with signal %d\n", sig);
- pthread_exit(0);
-}
-
-void fastrpc_async_domain_deinit(int domain) {
- struct fastrpc_async *me = &lasyncinfo[domain];
- int err = 0;
-
- pthread_mutex_lock(&async_mut);
- if (!me->init_done) {
- goto fasync_deinit_done;
- }
- FARF(ALWAYS, "%s: Waiting for AsyncRPC worker thread to join for domain %d\n",
- __func__, domain);
- if (me->thread) {
- me->deinit_started = 1;
- err = fastrpc_exit_async_thread(domain);
- if (err) {
- pthread_kill(me->thread, SIGUSR1);
- }
- pthread_join(me->thread, 0);
- me->thread = 0;
- }
- FARF(ALWAYS, "fastrpc async thread joined for domain %d", domain);
- fastrpc_async_respond_all_pending_jobs(domain);
- pthread_mutex_destroy(&me->mut);
- me->init_done = 0;
-fasync_deinit_done:
- pthread_mutex_unlock(&async_mut);
- return;
-}
-
-int fastrpc_async_domain_init(int domain) {
- struct fastrpc_async *me = &lasyncinfo[domain];
- int nErr = AEE_EUNKNOWN, i = 0;
- struct sigaction siga;
- uint32_t capability = 0;
-
- pthread_mutex_lock(&async_mut);
- if (me->init_done) {
- nErr = AEE_SUCCESS;
- goto bail;
- }
- VERIFY(AEE_SUCCESS ==
- (nErr = fastrpc_get_cap(domain, ASYNC_FASTRPC_SUPPORT, &capability)));
- VERIFYC(capability == 1, AEE_EUNSUPPORTED);
- me->thread = 0;
- pthread_mutex_init(&me->mut, 0);
- for (i = 0; i < FASTRPC_ASYNC_QUEUE_LIST_LEN; i++) {
- QList_Ctor(&me->ql[i]);
- }
- VERIFY(AEE_SUCCESS ==
- (nErr = pthread_create(&me->thread, 0, async_fastrpc_thread,
- (void *)me)));
- memset(&siga, 0, sizeof(siga));
- siga.sa_flags = 0;
- siga.sa_handler = async_thread_exit_handler;
- VERIFY(AEE_SUCCESS == (nErr = sigaction(SIGUSR1, &siga, NULL)));
- me->init_done = 1;
- me->deinit_started = 0;
- FARF(ALWAYS, "%s: AsyncRPC worker thread launched for domain %d\n", __func__,
- domain);
-bail:
- pthread_mutex_unlock(&async_mut);
- if (nErr != AEE_SUCCESS) {
- VERIFY_EPRINTF("Error 0x%x: %s failed for domain %d (%s)\n", nErr, __func__,
- domain, strerror(errno));
- fastrpc_async_domain_deinit(domain);
- }
- return nErr;
-}
-
-/*
- * Internal function to get async response from kernel. Waits in kernel until
- * response is received from DSP
- * @ domain: domain to which Async job is submitted
- * @ async_data: IOCTL structure that is sent to kernel to get async response
- * job information returns 0 on success
- *
- */
-static int get_remote_async_response(int domain, fastrpc_async_jobid *jobid,
- int *result) {
- int nErr = AEE_SUCCESS, dev = -1;
- uint64_t *perf_kernel = NULL, *perf_dsp = NULL;
- fastrpc_async_jobid job = -1;
- int res = -1;
- remote_handle handle = -1;
- uint32_t sc = 0;
-
- VERIFYC(IS_VALID_EFFECTIVE_DOMAIN_ID(domain), AEE_EBADPARM);
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(domain, &dev)));
- VERIFYM(-1 != dev, AEE_ERPC, "open dev failed\n");
- if (is_kernel_perf_enabled()) {
- perf_kernel = (uint64_t *)calloc(PERF_KERNEL_KEY_MAX, sizeof(uint64_t));
- VERIFYC(perf_kernel != NULL, AEE_ENOMEMORY);
- }
- if (is_dsp_perf_enabled(domain)) {
- perf_dsp = (uint64_t *)calloc(PERF_DSP_KEY_MAX, sizeof(uint64_t));
- VERIFYC(perf_dsp != NULL, AEE_ENOMEMORY);
- }
- nErr = ioctl_invoke2_response(dev, &job, &handle, &sc, &res, perf_kernel,
- perf_dsp);
- if (perf_kernel) {
- FARF(ALWAYS,
- "RPCPERF-K H:0x%x SC:0x%x C:%" PRIu64 " F:%" PRIu64 " ns M:%" PRIu64
- " ns CP:%" PRIu64 " ns L:%" PRIu64 " ns G:%" PRIu64 " ns P:%" PRIu64
- " ns INV:%" PRIu64 " ns INVOKE:%" PRIu64 " ns\n",
- handle, sc, perf_kernel[0], perf_kernel[1], perf_kernel[2],
- perf_kernel[3], perf_kernel[4], perf_kernel[5], perf_kernel[6],
- perf_kernel[7], perf_kernel[8]);
- }
- if (perf_dsp) {
- FARF(ALWAYS,
- "RPCPERF-D H:0x%x SC:0x%x C:%" PRIu64 " M_H:%" PRIu64 " us M:%" PRIu64
- " us G:%" PRIu64 " us INVOKE:%" PRIu64 " us P:%" PRIu64
- " us CACHE:%" PRIu64 " us UM:%" PRIu64 " us "
- "UM_H:%" PRIu64 " us R:%" PRIu64 " us E_R:%" PRIu64
- " us J_S_T:%" PRIu64 " us\n",
- handle, sc, perf_dsp[0], perf_dsp[1], perf_dsp[2], perf_dsp[3],
- perf_dsp[4], perf_dsp[5], perf_dsp[6], perf_dsp[7], perf_dsp[8],
- perf_dsp[9], perf_dsp[10], perf_dsp[11]);
- }
- *jobid = job;
- *result = res;
-
-bail:
- if (perf_kernel) {
- free(perf_kernel);
- perf_kernel = NULL;
- }
- if (perf_dsp) {
- free(perf_dsp);
- perf_dsp = NULL;
- }
- if (nErr) {
- FARF(ERROR,
- "Error 0x%x: %s failed to get async response data for domain %d errno "
- "%s",
- nErr, __func__, domain, strerror(errno));
- }
- return nErr;
-}
-
-// Make IOCTL call to exit async thread
-int fastrpc_exit_async_thread(int domain) {
- int nErr = AEE_SUCCESS, dev;
-
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(domain, &dev)));
- nErr = ioctl_control(dev, DSPRPC_ASYNC_WAKE, NULL);
-bail:
- if (nErr)
- FARF(ERROR,
- "Error 0x%x: %s failed for domain %d (errno: %s), ignore if ioctl not "
- "supported, try pthread kill ",
- nErr, __func__, domain, strerror(errno));
- return nErr;
-}
diff --git a/src/fastrpc_cap.c b/src/fastrpc_cap.c
index 0ad169e..c088a74 100644
--- a/src/fastrpc_cap.c
+++ b/src/fastrpc_cap.c
@@ -108,12 +108,6 @@ int fastrpc_get_cap(uint32_t domain, uint32_t attributeID, uint32_t *capability)
}
goto bail;
}
- if(attributeID == ASYNC_FASTRPC_SUPPORT) {
- if(!is_async_fastrpc_supported() ) {
- *capability = 0;
- goto bail;
- }
- }
VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_open(dom, &dev)));
errno = 0;
diff --git a/src/fastrpc_config_parser.c b/src/fastrpc_config_parser.c
index 786aebe..d832a7b 100644
--- a/src/fastrpc_config_parser.c
+++ b/src/fastrpc_config_parser.c
@@ -1,181 +1,188 @@
-// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
-// SPDX-License-Identifier: BSD-3-Clause-Clear
-
-#define _GNU_SOURCE
-#ifndef VERIFY_PRINT_WARN
-#define VERIFY_PRINT_WARN
-#endif // VERIFY_PRINT_WARN
-#ifndef VERIFY_PRINT_ERROR_ALWAYS
-#define VERIFY_PRINT_ERROR_ALWAYS
-#endif // VERIFY_PRINT_ERROR_ALWAYS
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define FARF_ERROR 1
-#define FARF_HIGH 1
-#define FARF_MED 1
-#define FARF_LOW 1
-#define FARF_CRITICAL 1 // Push log's to all hooks and persistent buffer.
-
-#define CONFIG_DIR CONFIG_BASE_DIR "/conf.d/"
-
-#include "AEEQList.h"
-#include "AEEStdErr.h"
-#include "AEEstd.h"
-#include "HAP_farf.h"
-#include "apps_std_internal.h"
-#include "fastrpc_config_parser.h"
-
-static int compare_strings(const void *a, const void *b) {
- return strcmp(*(const char **)a, *(const char **)b);
-}
-
-static void get_dsp_lib_path(const char *machine_name, const char *filepath, char *dsp_lib_paths) {
- yaml_parser_t parser;
- yaml_event_t event;
- int done = 0;
- int in_machines = 0;
- int in_target_machine = 0;
- int found_dsp_path = 0;
- char current_machine[PATH_MAX] = {0};
-
- FILE *file = fopen(filepath, "r");
- if (!file)
- return;
-
- if (!yaml_parser_initialize(&parser)) {
- FARF(ALWAYS, "Warning: Failed to initialize YAML parser for file %s\n", filepath);
- fclose(file);
- return;
- }
-
- yaml_parser_set_input_file(&parser, file);
-
- while (!done) {
- if (!yaml_parser_parse(&parser, &event)) {
- FARF(ALWAYS, "Warning: YAML parser error in file %s\n", filepath);
- break;
- }
-
- switch (event.type) {
- case YAML_SCALAR_EVENT: {
- const char *value = (const char *)event.data.scalar.value;
-
- if (!in_machines && strcmp(value, "machines") == 0) {
- in_machines = 1;
- } else if (in_machines && !in_target_machine) {
- // This is a machine name key
- strlcpy(current_machine, value, sizeof(current_machine));
- if (strcmp(current_machine, machine_name) == 0) {
- in_target_machine = 1;
- }
- } else if (in_target_machine && strcmp(value, DSP_LIB_KEY) == 0) {
- // Next scalar will be the DSP_LIBRARY_PATH value
- yaml_event_delete(&event);
- if (yaml_parser_parse(&parser, &event) && event.type == YAML_SCALAR_EVENT) {
- strlcpy(dsp_lib_paths, (const char *)event.data.scalar.value, PATH_MAX);
- FARF(ALWAYS, "dsp_lib_paths is %s", dsp_lib_paths);
- found_dsp_path = 1;
- done = 1;
- }
- }
- break;
- }
- case YAML_MAPPING_END_EVENT:
- if (in_target_machine) {
- // Exiting the target machine mapping
- in_target_machine = 0;
- if (found_dsp_path) {
- done = 1;
- }
- }
- break;
- case YAML_STREAM_END_EVENT:
- done = 1;
- break;
- default:
- break;
- }
-
- yaml_event_delete(&event);
- }
-
- yaml_parser_delete(&parser);
- fclose(file);
-
- if (!found_dsp_path) {
- FARF(ALWAYS, "Warning: DSP_LIBRARY_PATH not found for machine [%s] in configuration file %s\n",
- machine_name, filepath);
- }
-}
-
-static void parse_config_dir(char *machine_name) {
- DIR *dir = opendir(CONFIG_DIR);
- struct dirent *entry;
- char *file_list[1024];
- int file_count = 0;
- char dsp_lib_paths[PATH_MAX] = {0};
-
- if (!dir)
- return;
-
- while ((entry = readdir(dir)) != NULL) {
- if (entry->d_type == DT_REG &&
- (strstr(entry->d_name, ".yaml") || strstr(entry->d_name, ".yml"))) {
- file_list[file_count] = strdup(entry->d_name);
- file_count++;
- }
- }
- closedir(dir);
-
- qsort(file_list, file_count, sizeof(char *), compare_strings);
-
- for (int i = 0; i < file_count; i++) {
- char filepath[PATH_MAX];
- snprintf(filepath, sizeof(filepath), "%s%s", CONFIG_DIR, file_list[i]);
- get_dsp_lib_path(machine_name, filepath, dsp_lib_paths);
- free(file_list[i]);
- }
-
- if (dsp_lib_paths[0] != '\0') {
- strlcpy(DSP_LIBS_LOCATION, CONFIG_BASE_DIR, sizeof(DSP_LIBS_LOCATION));
- //append slash in case user passed config base dir doesn't end with slash '/'
- strlcat(DSP_LIBS_LOCATION, "/", sizeof(DSP_LIBS_LOCATION));
- strlcat(DSP_LIBS_LOCATION, dsp_lib_paths, sizeof(DSP_LIBS_LOCATION));
- strlcat(DSP_LIBS_LOCATION, DEFAULT_DSP_SEARCH_PATHS, sizeof(DSP_LIBS_LOCATION));
- } else {
- FARF(ALWAYS, "Warning: No DSP library path found for machine [%s] in any configuration file\n",
- machine_name);
- }
-}
-
-void configure_dsp_paths() {
- char machine_name[PATH_MAX] = {0};
- FILE *file = fopen(MACHINE_NAME_PATH, "r");
-
- if (file == NULL)
- return;
-
- if (fgets(machine_name, sizeof(machine_name), file) != NULL)
- // Remove trailing newline if present
- machine_name[strcspn(machine_name, "\n")] = '\0';
-
- fclose(file);
- parse_config_dir(machine_name);
-}
+// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+
+#define _GNU_SOURCE
+#ifndef VERIFY_PRINT_WARN
+#define VERIFY_PRINT_WARN
+#endif // VERIFY_PRINT_WARN
+#ifndef VERIFY_PRINT_ERROR_ALWAYS
+#define VERIFY_PRINT_ERROR_ALWAYS
+#endif // VERIFY_PRINT_ERROR_ALWAYS
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define FARF_ERROR 1
+#define FARF_HIGH 1
+#define FARF_MED 1
+#define FARF_LOW 1
+#define FARF_CRITICAL 1 // Push log's to all hooks and persistent buffer.
+
+#define CONFIG_DIR CONFIG_BASE_DIR "/conf.d/"
+
+#include "AEEQList.h"
+#include "AEEStdErr.h"
+#include "AEEstd.h"
+#include "HAP_farf.h"
+#include "apps_std_internal.h"
+#include "fastrpc_config_parser.h"
+
+static int compare_strings(const void *a, const void *b) {
+ return strcmp(*(const char **)a, *(const char **)b);
+}
+
+static void get_dsp_lib_path(const char *machine_name, const char *filepath, char *dsp_lib_paths) {
+ yaml_parser_t parser;
+ yaml_event_t event;
+ int done = 0;
+ int in_machines = 0;
+ int in_target_machine = 0;
+ int found_dsp_path = 0;
+ char current_machine[PATH_MAX] = {0};
+
+ FILE *file = fopen(filepath, "r");
+ if (!file)
+ return;
+
+ if (!yaml_parser_initialize(&parser)) {
+ FARF(ALWAYS, "Warning: Failed to initialize YAML parser for file %s\n", filepath);
+ fclose(file);
+ return;
+ }
+
+ yaml_parser_set_input_file(&parser, file);
+
+ while (!done) {
+ if (!yaml_parser_parse(&parser, &event)) {
+ FARF(ALWAYS, "Warning: YAML parser error in file %s\n", filepath);
+ break;
+ }
+
+ switch (event.type) {
+ case YAML_SCALAR_EVENT: {
+ const char *value = (const char *)event.data.scalar.value;
+
+ if (!in_machines && strcmp(value, "machines") == 0) {
+ in_machines = 1;
+ } else if (in_machines && !in_target_machine) {
+ // This is a machine name key
+ strlcpy(current_machine, value, sizeof(current_machine));
+ if (strcmp(current_machine, machine_name) == 0) {
+ in_target_machine = 1;
+ }
+ } else if (in_target_machine && strcmp(value, DSP_LIB_KEY) == 0) {
+ // Next scalar will be the DSP_LIBRARY_PATH value
+ yaml_event_delete(&event);
+ if (yaml_parser_parse(&parser, &event) && event.type == YAML_SCALAR_EVENT) {
+ strlcpy(dsp_lib_paths, (const char *)event.data.scalar.value, PATH_MAX);
+ FARF(ALWAYS, "dsp_lib_paths is %s", dsp_lib_paths);
+ found_dsp_path = 1;
+ done = 1;
+ }
+ }
+ break;
+ }
+ case YAML_MAPPING_END_EVENT:
+ if (in_target_machine) {
+ // Exiting the target machine mapping
+ in_target_machine = 0;
+ if (found_dsp_path) {
+ done = 1;
+ }
+ }
+ break;
+ case YAML_STREAM_END_EVENT:
+ done = 1;
+ break;
+ default:
+ break;
+ }
+
+ yaml_event_delete(&event);
+ }
+
+ yaml_parser_delete(&parser);
+ fclose(file);
+
+ if (!found_dsp_path) {
+ FARF(ALWAYS, "Warning: DSP_LIBRARY_PATH not found for machine [%s] in configuration file %s\n",
+ machine_name, filepath);
+ }
+}
+
+static void parse_config_dir(char *machine_name) {
+ DIR *dir = opendir(CONFIG_DIR);
+ struct dirent *entry;
+ char *file_list[1024];
+ int file_count = 0;
+ char dsp_lib_paths[PATH_MAX] = {0};
+
+ if (!dir)
+ return;
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_type == DT_REG &&
+ (strstr(entry->d_name, ".yaml") || strstr(entry->d_name, ".yml"))) {
+ file_list[file_count] = strdup(entry->d_name);
+ file_count++;
+ }
+ }
+ closedir(dir);
+
+ qsort(file_list, file_count, sizeof(char *), compare_strings);
+
+ for (int i = 0; i < file_count; i++) {
+ char filepath[PATH_MAX];
+ snprintf(filepath, sizeof(filepath), "%s%s", CONFIG_DIR, file_list[i]);
+ get_dsp_lib_path(machine_name, filepath, dsp_lib_paths);
+ free(file_list[i]);
+ }
+
+ if (dsp_lib_paths[0] != '\0') {
+ strlcpy(DSP_LIBS_LOCATION, CONFIG_BASE_DIR, sizeof(DSP_LIBS_LOCATION));
+ //append slash in case user passed config base dir doesn't end with slash '/'
+ strlcat(DSP_LIBS_LOCATION, "/", sizeof(DSP_LIBS_LOCATION));
+ strlcat(DSP_LIBS_LOCATION, dsp_lib_paths, sizeof(DSP_LIBS_LOCATION));
+ strlcat(DSP_LIBS_LOCATION, DEFAULT_DSP_SEARCH_PATHS, sizeof(DSP_LIBS_LOCATION));
+ } else {
+ FARF(ALWAYS, "Warning: No DSP library path found for machine [%s] in any configuration file\n",
+ machine_name);
+ }
+}
+
+void configure_dsp_paths() {
+ char machine_name[PATH_MAX] = {0};
+ FILE *file = fopen(MACHINE_NAME_PATH, "r");
+
+ if (file) {
+ if (fgets(machine_name, sizeof(machine_name), file) != NULL)
+ // Remove trailing newline if present
+ machine_name[strcspn(machine_name, "\n")] = '\0';
+
+ fclose(file);
+ parse_config_dir(machine_name);
+ } else {
+ char *env_value = getenv("MACHINE_NAME");
+ // fallback to look for MACHINE_NAME in environment variable
+ if (env_value) {
+ snprintf(machine_name, sizeof(machine_name), "%s", env_value);
+ machine_name[strcspn(machine_name, "\n")] = '\0';
+ parse_config_dir(machine_name);
+ }
+ }
+}
diff --git a/src/fastrpc_ioctl.c b/src/fastrpc_ioctl.c
index e0329e1..15c778d 100644
--- a/src/fastrpc_ioctl.c
+++ b/src/fastrpc_ioctl.c
@@ -5,54 +5,11 @@
#include "AEEStdErr.h"
#include "HAP_farf.h"
-#include "fastrpc_async.h"
#include "fastrpc_internal.h"
#include "fastrpc_notif.h"
#include "remote.h"
#include
-/* check async support */
-int is_async_fastrpc_supported(void) {
- /* async not supported by upstream driver */
- return 0;
-}
-
-/* Returns the name of the domain based on the following
- ADSP/SLPI/MDSP/CDSP - Return Secure node
- */
-const char *get_secure_domain_name(int domain_id) {
- const char *name;
- int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain_id);
-
- switch (domain) {
- case ADSP_DOMAIN_ID:
- name = ADSPRPC_SECURE_DEVICE;
- break;
- case SDSP_DOMAIN_ID:
- name = SDSPRPC_SECURE_DEVICE;
- break;
- case MDSP_DOMAIN_ID:
- name = MDSPRPC_SECURE_DEVICE;
- break;
- case CDSP_DOMAIN_ID:
- name = CDSPRPC_SECURE_DEVICE;
- break;
- case CDSP1_DOMAIN_ID:
- name = CDSP1RPC_SECURE_DEVICE;
- break;
- case GDSP0_DOMAIN_ID:
- name = GDSP0RPC_SECURE_DEVICE;
- break;
- case GDSP1_DOMAIN_ID:
- name = GDSP1RPC_SECURE_DEVICE;
- break;
- default:
- name = DEFAULT_DEVICE;
- break;
- }
- return name;
-}
-
int ioctl_init(int dev, uint32_t flags, int attr, unsigned char *shell, int shelllen,
int shellfd, char *mem, int memlen, int memfd, int tessiglen) {
int ioErr = 0;
@@ -91,7 +48,7 @@ int ioctl_init(int dev, uint32_t flags, int attr, unsigned char *shell, int shel
}
int ioctl_invoke(int dev, int req, remote_handle handle, uint32_t sc, void *pra,
- int *fds, unsigned int *attrs, void *job, unsigned int *crc,
+ int *fds, unsigned int *attrs, unsigned int *crc,
uint64_t *perf_kernel, uint64_t *perf_dsp) {
int ioErr = AEE_SUCCESS;
struct fastrpc_ioctl_invoke invoke = {0};
@@ -107,12 +64,6 @@ int ioctl_invoke(int dev, int req, remote_handle handle, uint32_t sc, void *pra,
return ioErr;
}
-int ioctl_invoke2_response(int dev, fastrpc_async_jobid *jobid,
- remote_handle *handle, uint32_t *sc, int *result,
- uint64_t *perf_kernel, uint64_t *perf_dsp) {
- return AEE_EUNSUPPORTED;
-}
-
int ioctl_invoke2_notif(int dev, int *domain, int *session, int *status) {
return AEE_EUNSUPPORTED;
}
@@ -256,4 +207,13 @@ int ioctl_mdctx_manage(int dev, int req, void *user_ctx,
{
// TODO: Implement this for opensource
return AEE_EUNSUPPORTED;
-}
\ No newline at end of file
+}
+
+int fastrpc_async_get_status(fastrpc_async_jobid jobid, int timeout_us,
+ int *result) {
+ return AEE_EUNSUPPORTED;
+}
+
+int fastrpc_release_async_job(fastrpc_async_jobid jobid) {
+ return AEE_EUNSUPPORTED;
+}
diff --git a/src/fastrpc_latency.c b/src/fastrpc_latency.c
deleted file mode 100644
index 46fdab8..0000000
--- a/src/fastrpc_latency.c
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
-// SPDX-License-Identifier: BSD-3-Clause
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifndef FARF_ERROR
-#define FARF_ERROR 1
-#endif
-
-#include "AEEStdErr.h"
-#include "AEEstd.h"
-#include "HAP_farf.h"
-#include "fastrpc_common.h"
-#include "fastrpc_internal.h"
-#include "fastrpc_latency.h"
-#include "verify.h"
-
-int fastrpc_latency_invoke_incr(struct fastrpc_latency *qp) {
- if (qp == NULL || qp->state == FASTRPC_LATENCY_STOP)
- goto bail;
- qp->invoke++;
- if (qp->vote == FASTRPC_LATENCY_VOTE_OFF) {
- pthread_mutex_lock(&qp->wmut);
- pthread_cond_signal(&qp->cond);
- pthread_mutex_unlock(&qp->wmut);
- }
-bail:
- return 0;
-}
-
-int fastrpc_latency_init(int dev, struct fastrpc_latency *qos) {
- int nErr = 0;
-
- VERIFYC(qos && dev != -1, AEE_ERPC);
-
- qos->dev = dev;
- qos->state = FASTRPC_LATENCY_STOP;
- qos->thread = 0;
- qos->wait_time = FASTRPC_LATENCY_WAIT_TIME_USEC;
- pthread_mutex_init(&qos->mut, 0);
- pthread_mutex_init(&qos->wmut, 0);
- pthread_cond_init(&qos->cond, NULL);
-bail:
- return nErr;
-}
-
-int fastrpc_latency_deinit(struct fastrpc_latency *qos) {
- int nErr = 0;
-
- VERIFYC(qos, AEE_ERPC);
- if (qos->state == FASTRPC_LATENCY_START) {
- pthread_mutex_lock(&qos->wmut);
- qos->exit = FASTRPC_LATENCY_EXIT;
- pthread_cond_signal(&qos->cond);
- pthread_mutex_unlock(&qos->wmut);
- if (qos->thread) {
- pthread_join(qos->thread, 0);
- qos->thread = 0;
- FARF(ALWAYS, "latency thread joined");
- }
- pthread_mutex_destroy(&qos->mut);
- pthread_mutex_destroy(&qos->wmut);
- }
-bail:
- return nErr;
-}
-
-/* FastRPC QoS handler votes for pm_qos latency based on
- * RPC activity in a window of time.
- */
-static void *fastrpc_latency_thread_handler(void *arg) {
- int nErr = 0;
- long ns = 0;
- struct timespec tw;
- struct timeval tp;
- int invoke = 0;
- struct fastrpc_ioctl_control qos = {0};
- struct fastrpc_ctrl_latency lp = {0};
- struct fastrpc_latency *qp = (struct fastrpc_latency *)arg;
-
- if (qp == NULL) {
- nErr = AEE_ERPC;
- FARF(ERROR, "Error 0x%x: %s failed \n", nErr, __func__);
- return NULL;
- }
- VERIFYC(qp->dev != -1, AEE_ERPC);
-
- FARF(ALWAYS, "%s started for QoS with activity window %d ms", __func__,
- FASTRPC_LATENCY_WAIT_TIME_USEC / MS_TO_US);
-
- // Look for RPC activity in 100 ms window
- qp->wait_time = FASTRPC_LATENCY_WAIT_TIME_USEC;
- qp->invoke++;
- while (1) {
- nErr = gettimeofday(&tp, NULL);
- /* valid values for "tv_nsec" are [0, 999999999] */
- ns = ((tp.tv_usec + qp->wait_time) * US_TO_NS);
- tw.tv_sec = tp.tv_sec + (ns / SEC_TO_NS);
- tw.tv_nsec = (ns % SEC_TO_NS);
-
- pthread_mutex_lock(&qp->wmut);
- if (qp->wait_time)
- pthread_cond_timedwait(&qp->cond, &qp->wmut, &tw);
- else
- pthread_cond_wait(&qp->cond, &qp->wmut);
- pthread_mutex_unlock(&qp->wmut);
-
- if (qp->exit == FASTRPC_LATENCY_EXIT) {
- qp->exit = 0;
- break;
- }
-
- pthread_mutex_lock(&qp->mut);
- invoke = qp->invoke;
- qp->invoke = 0;
- pthread_mutex_unlock(&qp->mut);
-
- if (invoke) {
- // found RPC activity in window. vote for pm_qos.
- qp->wait_time = FASTRPC_LATENCY_WAIT_TIME_USEC;
- if (qp->vote == FASTRPC_LATENCY_VOTE_OFF) {
- lp.enable = FASTRPC_LATENCY_VOTE_ON;
- lp.latency = qp->latency;
- nErr = ioctl_control(qp->dev, DSPRPC_CONTROL_LATENCY, &lp);
- if (nErr == AEE_SUCCESS) {
- qp->vote = FASTRPC_LATENCY_VOTE_ON;
- } else if (nErr == AEE_EUNSUPPORTED) {
- goto bail;
- } else {
- FARF(ERROR,
- "Error %d: %s: PM QoS ON request failed with errno %d (%s)",
- nErr, __func__, errno, strerror(errno));
- }
- }
- } else {
- // No RPC activity detected in a window. Remove pm_qos vote.
- qp->wait_time = 0;
- if (qp->vote == FASTRPC_LATENCY_VOTE_ON) {
- lp.enable = FASTRPC_LATENCY_VOTE_OFF;
- lp.latency = 0;
- nErr = ioctl_control(qp->dev, DSPRPC_CONTROL_LATENCY, &lp);
- if (nErr == AEE_SUCCESS) {
- qp->vote = FASTRPC_LATENCY_VOTE_OFF;
- } else if (nErr == AEE_EUNSUPPORTED) {
- goto bail;
- } else {
- FARF(ERROR,
- "Error %d: %s: PM QoS OFF request failed with errno %d (%s)",
- nErr, __func__, errno, strerror(errno));
- }
- }
- }
- }
- FARF(ALWAYS, "FastRPC latency thread for QoS exited");
-bail:
- if (nErr != AEE_SUCCESS) {
- FARF(ERROR,
- "Error 0x%x: %s failed for wait time %d latency control enable %d "
- "latency %d\n",
- nErr, __func__, qp->wait_time, qos.lp.enable, qos.lp.latency);
- }
- return NULL;
-}
-
-int fastrpc_set_pm_qos(struct fastrpc_latency *qos, uint32_t enable,
- uint32_t latency) {
- int nErr = AEE_SUCCESS;
- int state = 0;
-
- VERIFYC(qos != NULL, AEE_EBADPARM);
- if (qos->exit == FASTRPC_LATENCY_EXIT)
- goto bail;
- pthread_mutex_lock(&qos->mut);
- state = qos->state;
- qos->latency = latency;
- pthread_mutex_unlock(&qos->mut);
-
- if (!enable && state == FASTRPC_LATENCY_START) {
- qos->exit = FASTRPC_LATENCY_EXIT;
- pthread_mutex_lock(&qos->wmut);
- pthread_cond_signal(&qos->cond);
- pthread_mutex_unlock(&qos->wmut);
- }
-
- if (enable && state == FASTRPC_LATENCY_STOP) {
- qos->state = FASTRPC_LATENCY_START;
- VERIFY(AEE_SUCCESS == (nErr = pthread_create(&qos->thread, 0,
- fastrpc_latency_thread_handler,
- (void *)qos)));
- }
-bail:
- return nErr;
-}
diff --git a/src/fastrpc_mem.c b/src/fastrpc_mem.c
index 8f62fc2..bdab811 100644
--- a/src/fastrpc_mem.c
+++ b/src/fastrpc_mem.c
@@ -110,6 +110,18 @@ struct static_map_list {
pthread_mutex_t mut;
};
+struct fastrpc_remote_map {
+ QNode qn;
+ uint64_t vadsp;
+ uint32_t flags;
+};
+
+struct fastrpc_remote_map_list {
+ QList ql;
+ pthread_mutex_t mut;
+};
+
+static struct fastrpc_remote_map_list memlist[NUM_DOMAINS_EXTEND];
static struct static_map_list smaplst[NUM_DOMAINS_EXTEND];
static struct mem_to_fd_list fdlist;
static struct dma_handle_info dhandles[MAX_DMA_HANDLES];
@@ -128,6 +140,8 @@ int fastrpc_mem_init(void) {
FOR_EACH_EFFECTIVE_DOMAIN_ID(ii) {
QList_Ctor(&smaplst[ii].ql);
pthread_mutex_init(&smaplst[ii].mut, 0);
+ QList_Ctor(&memlist[ii].ql);
+ pthread_mutex_init(&memlist[ii].mut, 0);
}
return 0;
}
@@ -138,10 +152,35 @@ int fastrpc_mem_deinit(void) {
pthread_mutex_destroy(&fdlist.mut);
FOR_EACH_EFFECTIVE_DOMAIN_ID(ii) {
pthread_mutex_destroy(&smaplst[ii].mut);
+ pthread_mutex_destroy(&memlist[ii].mut);
}
return 0;
}
+static int fastrpc_remote_map_lookup(int domain, uint64_t vadsp, uint32_t *flags_out, struct fastrpc_remote_map **out)
+{
+ QNode *pn, *pnn;
+ struct fastrpc_remote_map *mNode;
+
+ if (!flags_out || !out)
+ return AEE_EBADPARM;
+
+ *out = NULL;
+ pthread_mutex_lock(&memlist[domain].mut);
+ QLIST_NEXTSAFE_FOR_ALL(&memlist[domain].ql, pn, pnn) {
+ mNode = STD_RECOVER_REC(struct fastrpc_remote_map, qn, pn);
+ if (mNode->vadsp == vadsp) {
+ *flags_out = mNode->flags;
+ *out = mNode;
+ QNode_DequeueZ(&mNode->qn);
+ pthread_mutex_unlock(&memlist[domain].mut);
+ return AEE_SUCCESS;
+ }
+ }
+ pthread_mutex_unlock(&memlist[domain].mut);
+ return AEE_ERESOURCENOTFOUND;
+}
+
static void *remote_register_fd_attr(int fd, size_t size, int attr) {
int nErr = AEE_SUCCESS;
void *po = NULL;
@@ -440,51 +479,37 @@ int fdlist_fd_from_buf(void *buf, int bufLen, int *nova, void **base, int *attr,
return 0;
}
-int fastrpc_mmap(int domain, int fd, void *vaddr, int offset, size_t length,
- enum fastrpc_map_flags flags) {
+/**
+ * Helper function to perform complete mmap operation including error handling
+ * Returns 0 on success, error code on failure
+ * On success, vaddrout contains the DSP virtual address
+ */
+static int fastrpc_mmap_helper(int *domain, int fd, void *vaddr, int offset,
+ size_t length, uint32_t flags, int attrs,
+ uint64_t *vaddrout) {
struct fastrpc_map map = {0};
- int nErr = 0, dev = -1, iocErr = 0, attrs = 0, ref = 0;
- uint64_t vaddrout = 0;
+ int nErr = 0, dev = -1, iocErr = 0, ref = 0;
struct static_map *mNode = NULL, *tNode = NULL;
QNode *pn, *pnn;
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
-
- FARF(RUNTIME_RPC_HIGH,
- "%s: domain %d fd %d addr %p length 0x%zx flags 0x%x offset 0x%x",
- __func__, domain, fd, vaddr, length, flags, offset);
-
- /**
- * Mask is applied on "flags" parameter to extract map control flags
- * and SMMU mapping control attributes. Currently no attributes are
- * suppported. It allows future extension of the fastrpc_mmap API
- * for SMMU mapping control attributes.
- */
- attrs = flags & (~FASTRPC_MAP_FLAGS_MASK);
- flags = flags & FASTRPC_MAP_FLAGS_MASK;
- VERIFYC(fd >= 0 && offset == 0 && attrs == 0, AEE_EBADPARM);
- VERIFYC(flags >= 0 && flags < FASTRPC_MAP_MAX &&
- flags != FASTRPC_MAP_RESERVED,
- AEE_EBADPARM);
-
// Get domain and open session if not already open
- if (domain == -1) {
- domain = get_current_domain();
+ if (*domain == -1) {
+ *domain = get_current_domain();
}
- VERIFYC(IS_VALID_EFFECTIVE_DOMAIN_ID(domain), AEE_EBADPARM);
- FASTRPC_GET_REF(domain);
- VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(domain, &dev)));
+ VERIFYC(IS_VALID_EFFECTIVE_DOMAIN_ID(*domain), AEE_EBADPARM);
+ FASTRPC_GET_REF(*domain);
+ VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(*domain, &dev)));
VERIFYC(-1 != dev, AEE_ERPC);
/* Search for mapping in current session static map list */
- pthread_mutex_lock(&smaplst[domain].mut);
- QLIST_NEXTSAFE_FOR_ALL(&smaplst[domain].ql, pn, pnn) {
+ pthread_mutex_lock(&smaplst[*domain].mut);
+ QLIST_NEXTSAFE_FOR_ALL(&smaplst[*domain].ql, pn, pnn) {
tNode = STD_RECOVER_REC(struct static_map, qn, pn);
if (tNode->map.fd == fd) {
break;
}
}
- pthread_mutex_unlock(&smaplst[domain].mut);
+ pthread_mutex_unlock(&smaplst[*domain].mut);
// Raise error if map found already
if (tNode) {
@@ -505,13 +530,13 @@ int fastrpc_mmap(int domain, int fd, void *vaddr, int offset, size_t length,
map.m.vaddrout = 0;
mNode->map = map.m;
iocErr = ioctl_mmap(dev, MEM_MAP, flags, attrs, fd, offset, length,
- (uint64_t)vaddr, &vaddrout);
+ (uint64_t)vaddr, vaddrout);
if (!iocErr) {
- mNode->map.vaddrout = vaddrout;
+ mNode->map.vaddrout = *vaddrout;
mNode->refs = 1;
- pthread_mutex_lock(&smaplst[domain].mut);
- QList_AppendNode(&smaplst[domain].ql, &mNode->qn);
- pthread_mutex_unlock(&smaplst[domain].mut);
+ pthread_mutex_lock(&smaplst[*domain].mut);
+ QList_AppendNode(&smaplst[*domain].ql, &mNode->qn);
+ pthread_mutex_unlock(&smaplst[*domain].mut);
mNode = NULL;
} else if (errno == ENOTTY ||
iocErr == (int)(DSP_AEE_EOFFSET | AEE_EUNSUPPORTED)) {
@@ -521,16 +546,17 @@ int fastrpc_mmap(int domain, int fd, void *vaddr, int offset, size_t length,
nErr = AEE_EFAILED;
goto bail;
}
+
bail:
- FASTRPC_PUT_REF(domain);
+ FASTRPC_PUT_REF(*domain);
if (nErr) {
if (iocErr == 0) {
errno = 0;
}
FARF(ERROR,
- "Error 0x%x: %s failed to map buffer fd %d, addr %p, length 0x%zx, "
+ "Error 0x%x: %s failed for fd %d, addr %p, length 0x%zx, "
"domain %d, flags 0x%x, ioctl ret 0x%x, errno %s",
- nErr, __func__, fd, vaddr, length, domain, flags, iocErr,
+ nErr, __func__, fd, vaddr, length, *domain, flags, iocErr,
strerror(errno));
}
if (mNode) {
@@ -540,6 +566,41 @@ int fastrpc_mmap(int domain, int fd, void *vaddr, int offset, size_t length,
return nErr;
}
+int fastrpc_mmap(int domain, int fd, void *vaddr, int offset, size_t length,
+ enum fastrpc_map_flags flags) {
+ int nErr = 0, attrs = 0;
+ uint64_t vaddrout = 0;
+
+ VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
+
+ FARF(RUNTIME_RPC_HIGH,
+ "%s: domain %d fd %d addr %p length 0x%zx flags 0x%x offset 0x%x",
+ __func__, domain, fd, vaddr, length, flags, offset);
+
+ /**
+ * Mask is applied on "flags" parameter to extract map control flags
+ * and SMMU mapping control attributes. Currently no attributes are
+ * suppported. It allows future extension of the fastrpc_mmap API
+ * for SMMU mapping control attributes.
+ */
+ attrs = flags & (~FASTRPC_MAP_FLAGS_MASK);
+ flags = flags & FASTRPC_MAP_FLAGS_MASK;
+ VERIFYC(fd >= 0 && offset == 0 && attrs == 0, AEE_EBADPARM);
+ VERIFYC(flags >= 0 && flags < FASTRPC_MAP_MAX &&
+ flags != FASTRPC_MAP_RESERVED,
+ AEE_EBADPARM);
+
+ nErr = fastrpc_mmap_helper(&domain, fd, vaddr, offset, length, flags, attrs,
+ &vaddrout);
+
+bail:
+ if (nErr) {
+ FARF(ERROR, "Error 0x%x: %s failed for fd %d, addr %p, length 0x%zx, domain %d, flags 0x%x",
+ nErr, __func__, fd, vaddr, length, domain, flags);
+ }
+ return nErr;
+}
+
int fastrpc_munmap(int domain, int fd, void *vaddr, size_t length) {
int nErr = 0, dev = -1, iocErr = 0, locked = 0, ref = 0;
struct static_map *mNode = NULL;
@@ -614,6 +675,104 @@ int fastrpc_munmap(int domain, int fd, void *vaddr, size_t length) {
return nErr;
}
+int fastrpc_mmap_internal(int domain, int fd, void *vaddr, int offset,
+ size_t length, uint32_t flags, uint64_t *raddr) {
+ int nErr = 0, attrs = 0;
+
+ VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
+
+ VERIFYC(raddr != NULL, AEE_EBADPARM);
+
+ FARF(RUNTIME_RPC_HIGH,
+ "%s: domain %d fd %d addr %p length 0x%zx flags 0x%x offset 0x%x",
+ __func__, domain, fd, vaddr, length, flags, offset);
+
+ attrs = flags & (~FASTRPC_MAP_FLAGS_MASK);
+ flags = flags & FASTRPC_MAP_FLAGS_MASK;
+ VERIFYC(fd >= 0 && offset == 0 && attrs == 0, AEE_EBADPARM);
+
+ nErr = fastrpc_mmap_helper(&domain, fd, vaddr, offset, length, flags, attrs,
+ raddr);
+
+bail:
+ if (nErr) {
+ FARF(ERROR, "Error 0x%x: %s failed for fd %d, addr %p, length 0x%zx, domain %d, flags 0x%x",
+ nErr, __func__, fd, vaddr, length, domain, flags);
+ }
+ return nErr;
+}
+
+int fastrpc_munmap_internal(int domain, uint64_t raddr, size_t length) {
+ int nErr = 0, dev = -1, iocErr = 0, locked = 0, ref = 0;
+ struct static_map *mNode = NULL;
+ QNode *pn, *pnn;
+
+ VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
+
+ FARF(RUNTIME_RPC_HIGH, "%s: domain %d raddr 0x%llx length 0x%zx", __func__,
+ domain, raddr, length);
+ if (domain == -1) {
+ domain = get_current_domain();
+ }
+ VERIFYC(IS_VALID_EFFECTIVE_DOMAIN_ID(domain), AEE_EBADPARM);
+ FASTRPC_GET_REF(domain);
+ VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(domain, &dev)));
+ /**
+ * Search for mapping in current static map list using DSP virtual address (raddr).
+ */
+ pthread_mutex_lock(&smaplst[domain].mut);
+ locked = 1;
+ QLIST_NEXTSAFE_FOR_ALL(&smaplst[domain].ql, pn, pnn) {
+ mNode = STD_RECOVER_REC(struct static_map, qn, pn);
+ if (mNode->map.vaddrout == raddr) {
+ FARF(RUNTIME_RPC_HIGH, "%s: unmap found for raddr 0x%llx domain %d", __func__,
+ raddr, domain);
+ break;
+ }
+ }
+ VERIFYC(mNode && mNode->map.vaddrout == raddr, AEE_ENOSUCHMAP);
+ if (mNode->refs > 1) {
+ FARF(ERROR, "%s: Attempt to unmap raddr 0x%llx with %d outstanding references",
+ __func__, raddr, mNode->refs - 1);
+ nErr = AEE_EBADPARM;
+ goto bail;
+ }
+ mNode->refs = 0;
+ locked = 0;
+ pthread_mutex_unlock(&smaplst[domain].mut);
+
+ iocErr = ioctl_munmap(dev, MEM_UNMAP, 0, 0, mNode->map.fd, mNode->map.length,
+ mNode->map.vaddrout);
+ pthread_mutex_lock(&smaplst[domain].mut);
+ locked = 1;
+ if (iocErr == 0) {
+ QNode_DequeueZ(&mNode->qn);
+ free(mNode);
+ mNode = NULL;
+ } else if (errno == ENOTTY || errno == EINVAL) {
+ nErr = AEE_EUNSUPPORTED;
+ } else {
+ mNode->refs = 1;
+ nErr = AEE_EFAILED;
+ }
+bail:
+ if (locked == 1) {
+ locked = 0;
+ pthread_mutex_unlock(&smaplst[domain].mut);
+ }
+ FASTRPC_PUT_REF(domain);
+ if (nErr) {
+ if (iocErr == 0) {
+ errno = 0;
+ }
+ FARF(ERROR,
+ "Error 0x%x: %s failed raddr 0x%llx, length 0x%zx, domain %d, "
+ "ioctl ret 0x%x, errno %s",
+ nErr, __func__, raddr, length, domain, iocErr, strerror(errno));
+ }
+ return nErr;
+}
+
int remote_mem_map(int domain, int fd, int flags, uint64_t vaddr, size_t size,
uint64_t *raddr) {
int nErr = 0;
@@ -623,8 +782,8 @@ int remote_mem_map(int domain, int fd, int flags, uint64_t vaddr, size_t size,
VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
FARF(RUNTIME_RPC_HIGH,
- "%s: domain %d fd %d addr 0x%llx size 0x%zx flags 0x%x", __func__,
- domain, fd, vaddr, size, flags);
+ "%s: domain %d fd %d addr 0x%" PRIx64 " size 0x%zx flags 0x%x",
+ __func__, domain, fd, vaddr, size, flags);
VERIFYC(fd >= 0, AEE_EBADPARM);
VERIFYC(size >= 0, AEE_EBADPARM);
@@ -646,8 +805,8 @@ int remote_mem_map(int domain, int fd, int flags, uint64_t vaddr, size_t size,
nErr = convert_kernel_to_user_error(nErr, errno);
if (0 == check_rpc_error(nErr)) {
FARF(ERROR,
- "Error 0x%x: %s failed to map buffer fd %d addr 0x%llx size 0x%zx "
- "domain %d flags %d errno %s",
+ "Error 0x%x: %s failed to map buffer fd %d addr 0x%" PRIx64
+ " size 0x%zx domain %d flags %d errno %s",
nErr, __func__, fd, vaddr, size, domain, flags, strerror(errno));
}
}
@@ -661,8 +820,8 @@ int remote_mem_unmap(int domain, uint64_t raddr, size_t size) {
VERIFYC(size >= 0, AEE_EBADPARM);
VERIFYC(raddr != 0, AEE_EBADPARM);
- FARF(RUNTIME_RPC_HIGH, "%s: domain %d addr 0x%llx size 0x%zx", __func__,
- domain, raddr, size);
+ FARF(RUNTIME_RPC_HIGH, "%s: domain %d addr 0x%" PRIx64 " size 0x%zx",
+ __func__, domain, raddr, size);
if (domain == -1) {
domain = get_current_domain();
}
@@ -678,8 +837,8 @@ int remote_mem_unmap(int domain, uint64_t raddr, size_t size) {
nErr = convert_kernel_to_user_error(nErr, errno);
if (0 == check_rpc_error(nErr)) {
FARF(ERROR,
- "Error 0x%x: %s failed to unmap buffer addr 0x%llx size 0x%zx "
- "domain %d errno %s",
+ "Error 0x%x: %s failed to unmap buffer addr 0x%" PRIx64
+ " size 0x%zx domain %d errno %s",
nErr, __func__, raddr, size, domain, strerror(errno));
}
}
@@ -698,15 +857,29 @@ int remote_mmap64_internal(int fd, uint32_t flags, uint64_t vaddrin,
FASTRPC_GET_REF(domain);
VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(domain, &dev)));
VERIFYM(-1 != dev, AEE_ERPC, "Invalid device\n");
- nErr = ioctl_mmap(dev, MMAP_64, flags, 0, fd, 0, size, vaddrin, &vaout);
+ if (flags == ADSP_MMAP_ADD_PAGES || flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+ nErr = ioctl_mmap(dev, MMAP_64, flags, 0, fd, 0, size, vaddrin, &vaout);
+ } else {
+ VERIFY(AEE_SUCCESS ==
+ (nErr = fastrpc_mmap_internal(domain, fd, (void *)(uintptr_t)vaddrin, 0, size,
+ flags, &vaout)));
+ }
*vaddrout = vaout;
+ pthread_mutex_lock(&memlist[domain].mut);
+ struct fastrpc_remote_map *mNode = malloc(sizeof(*mNode));
+ if (mNode) {
+ mNode->vadsp = vaout;
+ mNode->flags = flags;
+ QList_AppendNode(&memlist[domain].ql, &mNode->qn);
+ }
+ pthread_mutex_unlock(&memlist[domain].mut);
bail:
FASTRPC_PUT_REF(domain);
if (nErr != AEE_SUCCESS) {
nErr = convert_kernel_to_user_error(nErr, errno);
FARF(ERROR,
- "Error 0x%x: %s failed for fd 0x%x of size %lld (flags 0x%x, vaddrin "
- "0x%llx) errno %s\n",
+ "Error 0x%x: %s failed for fd 0x%x of size %" PRId64 " (flags 0x%x, "
+ "vaddrin 0x%" PRIx64 ") errno %s\n",
nErr, __func__, fd, size, flags, vaddrin, strerror(errno));
}
return nErr;
@@ -732,8 +905,8 @@ int remote_mmap64(int fd, uint32_t flags, uint64_t vaddrin, int64_t size,
bail:
if ((nErr != AEE_SUCCESS) && (log == 1)) {
FARF(ERROR,
- "Error 0x%x: %s failed for fd 0x%x of size %lld (flags 0x%x, vaddrin "
- "0x%llx)\n",
+ "Error 0x%x: %s failed for fd 0x%x of size %" PRId64 " (flags 0x%x, "
+ "vaddrin 0x%" PRIx64 ")\n",
nErr, __func__, fd, size, flags, vaddrin);
}
return nErr;
@@ -754,6 +927,8 @@ int remote_mmap(int fd, uint32_t flags, uint32_t vaddrin, int size,
int remote_munmap64(uint64_t vaddrout, int64_t size) {
int dev, domain = DEFAULT_DOMAIN_ID, nErr = AEE_SUCCESS, ref = 0;
+ uint32_t rflags;
+ struct fastrpc_remote_map *mNode = NULL;
VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
@@ -763,14 +938,30 @@ int remote_munmap64(uint64_t vaddrout, int64_t size) {
/* Don't open session in unmap. Return success if device already closed */
FASTRPC_GET_REF(domain);
VERIFY(AEE_SUCCESS == (nErr = fastrpc_session_dev(domain, &dev)));
- nErr = ioctl_munmap(dev, MUNMAP_64, 0, 0, -1, size, vaddrout);
+
+ if (AEE_SUCCESS == fastrpc_remote_map_lookup(domain, vaddrout, &rflags, &mNode)) {
+ if (rflags == ADSP_MMAP_ADD_PAGES || rflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+ nErr = ioctl_munmap(dev, MUNMAP_64, 0, 0, -1, size, vaddrout);
+ } else {
+ nErr = fastrpc_munmap_internal(domain, (uint64_t)vaddrout, size);
+ }
+ if (nErr == AEE_SUCCESS) {
+ free(mNode);
+ } else {
+ pthread_mutex_lock(&memlist[domain].mut);
+ QList_AppendNode(&memlist[domain].ql, &mNode->qn);
+ pthread_mutex_unlock(&memlist[domain].mut);
+ }
+ } else {
+ nErr = ioctl_munmap(dev, MUNMAP_64, 0, 0, -1, size, vaddrout);
+ }
bail:
FASTRPC_PUT_REF(domain);
if (nErr != AEE_SUCCESS) {
nErr = convert_kernel_to_user_error(nErr, errno);
FARF(ERROR,
- "Error 0x%x: %s failed for size %lld (vaddrout 0x%llx) errno %s\n",
- nErr, __func__, size, vaddrout, strerror(errno));
+ "Error 0x%x: %s failed for size %" PRId64 " (vaddrout 0x%" PRIx64 ") "
+ "errno %s\n", nErr, __func__, size, vaddrout, strerror(errno));
}
return nErr;
}
diff --git a/src/listener_android.c b/src/listener_android.c
index 712945c..171329d 100644
--- a/src/listener_android.c
+++ b/src/listener_android.c
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include "AEEStdErr.h"
#include "AEEstd.h"
@@ -132,8 +133,8 @@ static void listener(listener_config *me) {
memset(args, 0, sizeof(args));
if (eheap || eflags || emin) {
FARF(RUNTIME_RPC_HIGH,
- "listener using ion heap: %d flags: %x cache: %lld\n", (int)heapid,
- (int)flags, cache_size);
+ "listener using ion heap: %d flags: %x cache: %" PRId64 "\n",
+ (int)heapid, (int)flags, cache_size);
}
do {
@@ -349,8 +350,9 @@ static void *listener_start_thread(void *arg) {
nErr = __QAIC_HEADER(adsp_listener1_init2)(adsp_listener1_handle);
if ((nErr == DSP_AEE_EOFFSET + AEE_ERPC) ||
nErr == DSP_AEE_EOFFSET + AEE_ENOSUCHMOD) {
- FARF(ERROR, "Error 0x%x: %s domains support not available in listener",
- nErr, __func__);
+ FARF(ALWAYS,
+ "Warning: %s domain support is unavailable on DSP in listener",
+ __func__);
fastrpc_update_module_list(DOMAIN_LIST_DEQUEUE, domain, _const_adsp_listener1_handle, NULL, NULL);
adsp_listener1_handle = INVALID_HANDLE;
VERIFY(AEE_SUCCESS == (nErr = __QAIC_HEADER(adsp_listener_init2)()));
diff --git a/src/mod_table.c b/src/mod_table.c
index d19fa90..d88468c 100644
--- a/src/mod_table.c
+++ b/src/mod_table.c
@@ -549,7 +549,9 @@ static int open_mod_table_open_dynamic(struct open_mod_table *me,
break;
}
}
- rv = snprintf(tmp, tmplen, "%s_system.so", tmp);
+ /* Append "_system.so" to base name (avoid overlapping buffers in snprintf) */
+ strlcat(tmp, "_system.so", tmplen);
+ rv = strlen(tmp);
VERIFYC((rv > 0) && (tmplen >= rv), AEE_EBADPARM);
FARF(RUNTIME_RPC_HIGH, "calling dlopen for %s", tmp);
dm->dlhandle = DLOPEN(tmp, RTLD_NOW);
diff --git a/src/rpcmem_linux.c b/src/rpcmem_linux.c
index a0814b9..8a9ce40 100644
--- a/src/rpcmem_linux.c
+++ b/src/rpcmem_linux.c
@@ -118,12 +118,6 @@ void rpcmem_deinit() {
pthread_mutex_destroy(&rpcmt);
}
-int rpcmem_set_dmabuf_name(const char *name, int fd, int heapid,
- void *buf, uint32_t rpcflags) {
- // Dummy call where DMABUF is not used
- return 0;
-}
-
int rpcmem_to_fd_internal(void *po) {
struct rpc_info *rinfo, *rfree = 0;
QNode *pn, *pnn;
@@ -246,6 +240,10 @@ void *rpcmem_alloc(int heapid, uint32_t flags, int size) {
return rpcmem_alloc_internal(heapid, flags, size);
}
+void *rpcmem_alloc2(int heapid, uint32_t flags, size_t size) {
+ return rpcmem_alloc_internal(heapid, flags, (size_t)size);
+}
+
void rpcmem_deinit_internal() { rpcmem_deinit(); }
void rpcmem_init_internal() { rpcmem_init(); }
diff --git a/src/symbols.lst b/src/symbols.lst
index 05f6adb..66ecb7d 100644
--- a/src/symbols.lst
+++ b/src/symbols.lst
@@ -34,8 +34,6 @@
rpcmem_alloc2;
rpcmem_free;
rpcmem_to_fd;
- remote_handle_invoke_async;
- remote_handle64_invoke_async;
fastrpc_async_get_status;
fastrpc_release_async_job;
dspqueue_create;