diff --git a/Docs/conf_guideline.md b/Docs/conf_guideline.md new file mode 100644 index 0000000..ff303a6 --- /dev/null +++ b/Docs/conf_guideline.md @@ -0,0 +1,94 @@ +📄 **YAML Configuration Usage Guide** + +--- + +### 🔧 **Purpose** +The YAML configuration file enables **fastrpc** to set machine-specific configurations at runtime. Each machine entry corresponds to a specific hardware platform. + +- fastrpc supports reading YAML configuration files from a particular directory. Users should ensure all configuration files are stored in that same directory. + - For Linux platforms: `/usr/share/qcom/conf.d/` +- In case of multiple configuration files defining path for a single machine, the directory is parsed in lexicographical order and the latest one carrying the + machine path is picked. +- **Machine Name**: Obtain the machine name for your platform from: + ``` + /sys/firmware/devicetree/base/model + ``` + (fastrpc uses same path for matching machine names) +--- +### 📄 **Current Properties** +- **DSP_LIBRARY_PATH**: Specifies the path to DSP binaries and resources for the Machine. +--- + +### 📁 **Format Guidelines** +The configuration uses YAML format with the following structure: +``` +machines: + "Machine Name": + DSP_LIBRARY_PATH: "/relative/path/to/dsp/binaries/" +``` + +**Key Points:** +- The root element is `machines:` +- Each machine name is a quoted string key under `machines:` +- Properties are indented under each machine name +- Use proper YAML indentation +- Paths should be quoted strings + +--- + +### ✅ **Example Configuration** +``` +machines: + "Qualcomm Technologies, Inc. DB820c": + DSP_LIBRARY_PATH: "/apq8096/Qualcomm/db820c/" + "Thundercomm Dragonboard 845c": + DSP_LIBRARY_PATH: "/sdm845/Thundercomm/db845c/" +``` + +--- + +### ⚠️ **Important Notes** +- Do **not** modify machine names unless adding a new supported Machine. +- Ensure `DSP_LIBRARY_PATH` values: + - Are enclosed in double quotes (`"..."`). + - Are **relative to `/usr/share/qcom/`**. +- Follow YAML syntax rules: + - Use consistent indentation. + - Ensure proper spacing after colons (`: `). + - Quote strings containing special characters or spaces. + - Avoid tabs (use spaces only). +- Maintain: + - Proper YAML structure and hierarchy. + - Consistent formatting across entries. +- When adding new properties: + - Document their purpose **here**. + - Follow the same indentation pattern. +- Do **not** create duplicate Machine entries. +- Validate YAML syntax before deployment to avoid parsing errors. + +--- + +### ➕ **Adding New Platforms** +To add a new Machine, follow the existing YAML format: +``` +machines: + "New Machine Name": + DSP_LIBRARY_PATH: "/new_machine/path/" +``` + +Ensure the new entry is properly indented under the `machines:` root element and follows YAML syntax conventions. + +--- + +### 📝 **File Naming** +Configuration files should use the `.yaml` or `.yml` extension and be placed in the designated configuration directory (`/usr/share/qcom/conf.d/` on Linux platforms). + +### ✅ Schema Validation +To ensure the configuration file adheres to the required structure, validate it against the schema provided. + +Schema File Location: +/Docs/schemas/fastrpc-config-schema.yaml + +Validation Command: +Use Yamale for schema validation: +yamale -s fastrpc-config-schema.yaml \ No newline at end of file diff --git a/Docs/schemas/fastrpc-config-schema.yaml b/Docs/schemas/fastrpc-config-schema.yaml new file mode 100644 index 0000000..94e11df --- /dev/null +++ b/Docs/schemas/fastrpc-config-schema.yaml @@ -0,0 +1 @@ +machines: map(key=str(), value=map(DSP_LIBRARY_PATH=regex('^/.+/'))) diff --git a/ci/MACHINES.json b/ci/MACHINES.json index 7ef482c..44d8ecd 100644 --- a/ci/MACHINES.json +++ b/ci/MACHINES.json @@ -1,4 +1,20 @@ { - "qcs9100-ride-r3": ["sa8775p-ride", "qcs9100-ride"], - "qcs8300-ride": ["qcs8300-ride", "qcs8300-ride"] -} + "qcs6490-rb3gen2": { + "deviceTree": "qcs6490-rb3gen2", + "linuxFirmware": "qcs6490", + "lavaDeviceName": "qcs6490", + "hexDSPBinary": "qcm6490" + }, + "qcs9100-ride-r3": { + "deviceTree": "qcs9100-ride-r3", + "linuxFirmware": "sa8775p", + "lavaDeviceName": "qcs9100-ride", + "hexDSPBinary": "sa8775p" + }, + "qcs8300-ride": { + "deviceTree": "qcs8300-ride", + "linuxFirmware": "qcs8300", + "lavaDeviceName": "qcs8300-ride", + "hexDSPBinary": "qcs8300" + } +} \ No newline at end of file diff --git a/configure.ac b/configure.ac index 4c6d763..ca83f2d 100644 --- a/configure.ac +++ b/configure.ac @@ -43,6 +43,26 @@ AM_PROG_CC_C_O # Checks for library functions. +# Enable pkg-config +PKG_PROG_PKG_CONFIG + +# Check for libyaml only if not Android +AS_IF([test "$compile_for_android" = no], [ + PKG_CHECK_MODULES([YAML], [yaml-0.1], [], + [AC_MSG_ERROR([libyaml (yaml-0.1) is required but not found.])]) + AC_SUBST(YAML_CFLAGS) + AC_SUBST(YAML_LIBS) +]) + +# Configure config base path option (--with-config-base-dir) +AC_ARG_WITH([config-base-dir], + [AS_HELP_STRING([--with-config-base-dir=PATH], + [Base directory for config files (default: /usr/share/qcom)])], + [config_base_dir="$withval"], + [config_base_dir="/usr/share/qcom/"]) +AC_MSG_NOTICE([Config base path: $config_base_dir]) +AC_SUBST([CONFIG_BASE_DIR], ["$config_base_dir"]) + AC_CONFIG_FILES([ Makefile inc/Makefile diff --git a/debian/adsprpcd.service b/debian/adsprpcd.service index 112ab40..4cda2b2 100644 --- a/debian/adsprpcd.service +++ b/debian/adsprpcd.service @@ -7,4 +7,4 @@ User=fastrpc Group=fastrpc Restart=always Type=exec -ExecStart=/bin/sh -c '. /usr/share/fastrpc/guess-dsp.sh && /usr/sbin/adsprpcd' +ExecStart=/usr/sbin/adsprpcd diff --git a/debian/cdsprpcd.service b/debian/cdsprpcd.service index 0d642f5..4f79c08 100644 --- a/debian/cdsprpcd.service +++ b/debian/cdsprpcd.service @@ -7,4 +7,4 @@ User=fastrpc Group=fastrpc Restart=always Type=exec -ExecStart=/bin/sh -c '. /usr/share/fastrpc/guess-dsp.sh && /usr/sbin/cdsprpcd' +ExecStart=/usr/sbin/cdsprpcd diff --git a/debian/changelog b/debian/changelog index c7ed9ce..9401287 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,20 @@ +fastrpc (1.0.2-1) UNRELEASED; urgency=medium + + * New upstream release + * d/p/dlopen-abi-version: drop (fixed upstream). + * d/gbp.conf: set upstream tag pattern. + * Implement new upstream search path configuration: + - d/control: Build-Depend on libyaml-dev and pkgconf + - d/rules: --with-config-base-dir=/usr/share/hexagon-dsp + - d/p/open-shell-path: drop (no longer required) + - Drop d/guess-dsp.sh (no longer required): + + d/{a,c}dsprpcd.service: invoke without guess-dsp.sh + + d/fastrpc-support.install: do not install guess-dsp.sh + + d/guess-dsp.sh: remove + + d/copyright: drop guess-dsp.sh licensing information + + -- Robie Basak Thu, 15 Jan 2026 19:58:21 +0000 + fastrpc (1.0.0-1) unstable; urgency=medium * Initial packaging. (Closes: #1116042) diff --git a/debian/control b/debian/control index 475d482..1605f44 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Maintainer: Robie Basak Standards-Version: 4.6.2 Section: misc Priority: optional -Build-Depends: debhelper-compat (= 13) +Build-Depends: debhelper-compat (= 13), libyaml-dev, pkgconf Homepage: https://github.com/qualcomm/fastrpc Vcs-Git: https://github.com/qualcomm-linux/pkg-fastrpc -b debian/latest Vcs-Browser: https://github.com/qualcomm-linux/pkg-fastrpc diff --git a/debian/copyright b/debian/copyright index d4bfd19..9d452d8 100644 --- a/debian/copyright +++ b/debian/copyright @@ -54,28 +54,3 @@ License: BSD-1-Clause LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Files: debian/guess-dsp.sh -Copyright: Copyright (c) 2021-2024 Linaro -Comment: the source file declares SPDX MIT but doesn't include the license - text. Since this matches the Expat license according to dep5, the Expat - license text is used here. -License: Expat - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - . - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/debian/fastrpc-support.install b/debian/fastrpc-support.install index ae5290b..45c2284 100644 --- a/debian/fastrpc-support.install +++ b/debian/fastrpc-support.install @@ -1,6 +1,5 @@ debian/adsprpcd.service usr/lib/systemd/system/ debian/cdsprpcd.service usr/lib/systemd/system/ -debian/guess-dsp.sh usr/share/fastrpc/ usr/bin/adsprpcd usr/sbin usr/bin/cdsprpcd usr/sbin usr/bin/sdsprpcd usr/sbin diff --git a/debian/gbp.conf b/debian/gbp.conf deleted file mode 100644 index 13bb1a0..0000000 --- a/debian/gbp.conf +++ /dev/null @@ -1,2 +0,0 @@ -[DEFAULT] -debian-branch = debian/latest diff --git a/debian/guess-dsp.sh b/debian/guess-dsp.sh deleted file mode 100644 index 1c4a7c3..0000000 --- a/debian/guess-dsp.sh +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright (c) 2021-2024 Linaro -# -# SPDX-License-Identifier: MIT -# - -set -e - -modprobe socinfo || true - -if [ -r /sys/firmware/devicetree/base/model ] ; then - MACHINE=`cat /sys/firmware/devicetree/base/model` - case "$MACHINE" in - *DB820c*) - DSP_LIBRARY_PATH=/usr/share/hexagon-dsp/apq8096/Qualcomm/db820c/dsp - ;; - *"Dragonboard 845c"*) - DSP_LIBRARY_PATH=/usr/share/hexagon-dsp/sdm845/Thundercomm/db845c/dsp - ;; - *"Robotics RB1"*) - DSP_LIBRARY_PATH=/usr/share/hexagon-dsp/qcm2290/Thundercomm/RB1/dsp - ;; - *"QRB4210 RB2"*) - DSP_LIBRARY_PATH=/usr/share/hexagon-dsp/qrb4210/Thundercomm/RB2/dsp - ;; - *"Robotics RB5"*) - DSP_LIBRARY_PATH=/usr/share/hexagon-dsp/sm8250/Thundercomm/RB5/dsp - ;; - *"Robotics RB3gen2"*) - DSP_LIBRARY_PATH=/usr/share/hexagon-dsp/qcm6490/Thundercomm/RB3gen2/dsp - ;; - esac -fi - -if [ -z "$DSP_LIBRARY_PATH" -o ! -d "$DSP_LIBRARY_PATH" ] ; then - echo "Could not find support for this DSP" 1>&2 - exit 1 -fi - -export DSP_LIBRARY_PATH - -# compatibility -ADSP_LIBRARY_PATH=$DSP_LIBRARY_PATH -export ADSP_LIBRARY_PATH diff --git a/debian/patches/dlopen-abi-version b/debian/patches/dlopen-abi-version deleted file mode 100644 index e841a46..0000000 --- a/debian/patches/dlopen-abi-version +++ /dev/null @@ -1,28 +0,0 @@ -From: Robie Basak -Description: use versioned .so.1 names when calling dlopen() - Since Debian does not ship the .so symlink in its runtime library packages, - they cannot be used at runtime. Explicitly referencing the required ABI version - is the correct way to do this, to avoid problems with any future ABI - incompatilities. -Bug: https://github.com/qualcomm/fastrpc/issues/230 -Last-Update: 2025-10-22 - ---- a/src/dsprpcd.c -+++ b/src/dsprpcd.c -@@ -16,13 +16,13 @@ - #include - - #ifndef ADSP_DEFAULT_LISTENER_NAME --#define ADSP_DEFAULT_LISTENER_NAME "libadsp_default_listener.so" -+#define ADSP_DEFAULT_LISTENER_NAME "libadsp_default_listener.so.1" - #endif - #ifndef CDSP_DEFAULT_LISTENER_NAME --#define CDSP_DEFAULT_LISTENER_NAME "libcdsp_default_listener.so" -+#define CDSP_DEFAULT_LISTENER_NAME "libcdsp_default_listener.so.1" - #endif - #ifndef SDSP_DEFAULT_LISTENER_NAME --#define SDSP_DEFAULT_LISTENER_NAME "libsdsp_default_listener.so" -+#define SDSP_DEFAULT_LISTENER_NAME "libsdsp_default_listener.so.1" - #endif - #ifndef GDSP_DEFAULT_LISTENER_NAME - #define GDSP_DEFAULT_LISTENER_NAME "libcdsp_default_listener.so.1" diff --git a/debian/patches/open-shell-path b/debian/patches/open-shell-path deleted file mode 100644 index f7819aa..0000000 --- a/debian/patches/open-shell-path +++ /dev/null @@ -1,169 +0,0 @@ -Author: Robie Basak -Description: Use env var DSP_LIBRARY_PATH to find libraries - This is set by guess-dsp.sh (currently in packaging) according to the DSP - found on the hardware to the appropriate FHS path as provided by the - hexagon-dsp-binaries package. - . - Updated 2025-10-22: upstream now expects DSP_LIBRARY_PATH to be ';'-separated, - so the function is rewritten to try each of these paths only since Debian only - needs these. ':' is given as a possible separator too, since this is Unix - convention and upstream may change to follow this convention in the future. -Forwarded: no -Last-Update: 2025-10-22 - ---- a/src/fastrpc_apps_user.c -+++ b/src/fastrpc_apps_user.c -@@ -3437,11 +3437,16 @@ - char *absName = NULL; - char *shell_absName = NULL; - char *domain_str = NULL; -- uint16_t shell_absNameLen = 0, absNameLen = 0; -- ; -+ char *lib_path_env = NULL; -+ char *lib_path_env_dup = NULL; -+ char *saveptr = NULL; -+ char *path = NULL; - int nErr = AEE_SUCCESS; - int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain_id); - const char *shell_name = SIGNED_SHELL; -+ uint16_t shell_absNameLen = 0, absNameLen = 0; -+ size_t pathLen = 0; -+ int found = 0; - - if (1 == unsigned_shell) { - shell_name = UNSIGNED_SHELL; -@@ -3450,60 +3455,76 @@ - if (domain == MDSP_DOMAIN_ID) { - return nErr; - } -- VERIFYC(NULL != (domain_str = (char *)malloc(sizeof(domain))), AEE_ENOMEMORY); -- snprintf(domain_str, sizeof(domain), "%d", domain); -+ VERIFYC(NULL != (domain_str = (char *)malloc(16)), AEE_ENOMEMORY); -+ snprintf(domain_str, 16, "%d", domain); - - shell_absNameLen = strlen(shell_name) + strlen(domain_str) + 1; - - VERIFYC(NULL != -- (shell_absName = (char *)malloc(sizeof(char) * shell_absNameLen)), -+ (shell_absName = (char *)malloc(shell_absNameLen)), - AEE_ENOMEMORY); - strlcpy(shell_absName, shell_name, shell_absNameLen); - - strlcat(shell_absName, domain_str, shell_absNameLen); - -- absNameLen = strlen(DSP_MOUNT_LOCATION) + shell_absNameLen + 1; -- VERIFYC(NULL != (absName = (char *)malloc(sizeof(char) * absNameLen)), -- AEE_ENOMEMORY); -- strlcpy(absName, DSP_MOUNT_LOCATION, absNameLen); -- strlcat(absName, shell_absName, absNameLen); -- -- nErr = apps_std_fopen(absName, "r", fh); -- if (nErr) { -- absNameLen = strlen(DSP_DOM_LOCATION) + shell_absNameLen + 1; -- VERIFYC(NULL != -- (absName = (char *)realloc(absName, sizeof(char) * absNameLen)), -- AEE_ENOMEMORY); -- strlcpy(absName, DSP_MOUNT_LOCATION, absNameLen); -- strlcat(absName, SUBSYSTEM_NAME[domain], absNameLen); -- strlcat(absName, "/", absNameLen); -- strlcat(absName, shell_absName, absNameLen); -- nErr = apps_std_fopen(absName, "r", fh); -+ lib_path_env = getenv("DSP_LIBRARY_PATH"); -+ if (!lib_path_env || !*lib_path_env) { -+ nErr = AEE_EBADPARM; -+ goto bail; - } -- if (nErr) { -- absNameLen = strlen(VENDOR_DSP_LOCATION) + shell_absNameLen + 1; -- VERIFYC(NULL != -- (absName = (char *)realloc(absName, sizeof(char) * absNameLen)), -- AEE_ENOMEMORY); -- strlcpy(absName, VENDOR_DSP_LOCATION, absNameLen); -- strlcat(absName, shell_absName, absNameLen); -+ -+ // Defensive copy for strtok_r -+ VERIFYC(NULL != (lib_path_env_dup = strdup(lib_path_env)), AEE_ENOMEMORY); -+ -+ for (path = strtok_r(lib_path_env_dup, ":;", &saveptr); path != NULL; path = strtok_r(NULL, ":;", &saveptr)) { -+ if (!*path) continue; -+ -+ pathLen = strlen(path); -+ absNameLen = pathLen + shell_absNameLen + 2; // +2 for possible '/' and '\0' -+ VERIFYC(NULL != (absName = (char *)malloc(absNameLen)), AEE_ENOMEMORY); -+ -+ snprintf(absName, absNameLen, "%s%s%s", path, (path[pathLen-1] == '/' ? "" : "/"), shell_absName); - - nErr = apps_std_fopen(absName, "r", fh); -- if (nErr) { -- absNameLen = strlen(VENDOR_DOM_LOCATION) + shell_absNameLen + 1; -- VERIFYC(NULL != (absName = -- (char *)realloc(absName, sizeof(char) * absNameLen)), -- AEE_ENOMEMORY); -- strlcpy(absName, VENDOR_DSP_LOCATION, absNameLen); -- strlcat(absName, SUBSYSTEM_NAME[domain], absNameLen); -- strlcat(absName, "/", absNameLen); -- strlcat(absName, shell_absName, absNameLen); -+ if (!nErr) { -+ found = 1; -+ break; -+ } -+ free(absName); -+ absName = NULL; -+ -+ if (SUBSYSTEM_NAME[domain]) { -+ size_t subsysLen = strlen(SUBSYSTEM_NAME[domain]); -+ absNameLen = pathLen + subsysLen + shell_absNameLen + 3; // +3 for two '/' and '\0' -+ VERIFYC(NULL != (absName = (char *)malloc(absNameLen)), AEE_ENOMEMORY); -+ -+ snprintf(absName, absNameLen, "%s%s%s/%s", path, (path[pathLen-1] == '/' ? "" : "/"), SUBSYSTEM_NAME[domain], shell_absName); - - nErr = apps_std_fopen(absName, "r", fh); -+ if (!nErr) { -+ found = 1; -+ break; -+ } -+ free(absName); -+ absName = NULL; - } - } -- if (!nErr) -+ -+ if (found && absName) { - FARF(RUNTIME_RPC_HIGH, "Successfully opened %s, domain %d", absName, domain); -+ nErr = AEE_SUCCESS; -+ } else { -+ nErr = nErr ? nErr : AEE_ENOMEMORY; -+ if (domain == SDSP_DOMAIN_ID && fh != NULL) { -+ nErr = AEE_SUCCESS; -+ *fh = -1; -+ } else { -+ FARF(ERROR, -+ "Error 0x%x: %s failed for domain %d using DSP_LIBRARY_PATH=%s (errno %s)\n", -+ nErr, __func__, domain, lib_path_env ? lib_path_env : "(unset)", strerror(errno)); -+ } -+ } -+ - bail: - if (domain_str) { - free(domain_str); -@@ -3517,17 +3538,9 @@ - free(absName); - absName = NULL; - } -- if (nErr != AEE_SUCCESS) { -- if (domain == SDSP_DOMAIN_ID && fh != NULL) { -- nErr = AEE_SUCCESS; -- *fh = -1; -- } else { -- FARF(ERROR, -- "Error 0x%x: %s failed for domain %d search paths used are %s, %s, " -- "%s (errno %s)\n", -- nErr, __func__, domain, DSP_MOUNT_LOCATION, VENDOR_DSP_LOCATION, -- VENDOR_DOM_LOCATION, strerror(errno)); -- } -+ if (lib_path_env_dup) { -+ free(lib_path_env_dup); -+ lib_path_env_dup = NULL; - } - return nErr; - } diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index 4be349c..0000000 --- a/debian/patches/series +++ /dev/null @@ -1,2 +0,0 @@ -dlopen-abi-version -open-shell-path diff --git a/debian/rules b/debian/rules index b9ab01d..82b20f8 100755 --- a/debian/rules +++ b/debian/rules @@ -3,6 +3,9 @@ %: dh $@ --with autoreconf +override_dh_auto_configure: + dh_auto_configure -- --with-config-base-dir=/usr/share/hexagon-dsp + override_dh_installsystemd: dh_installsystemd -p fastrpc-support adsprpcd.service cdsprpcd.service diff --git a/inc/Makefile.am b/inc/Makefile.am index 24f281f..dd76127 100644 --- a/inc/Makefile.am +++ b/inc/Makefile.am @@ -1,16 +1,16 @@ # Export fastrpc headers fastrpc_includedir = $(includedir)/fastrpc fastrpc_include_HEADERS = $(top_srcdir)/inc/AEEStdErr.h +fastrpc_include_HEADERS += $(top_srcdir)/inc/AEEStdDef.h fastrpc_include_HEADERS += $(top_srcdir)/inc/remote.h fastrpc_include_HEADERS += $(top_srcdir)/inc/rpcmem.h +fastrpc_include_HEADERS += $(top_srcdir)/inc/HAP_farf.h +fastrpc_include_HEADERS += $(top_srcdir)/inc/HAP_debug.h noinst_HEADERS = \ AEEBufBound.h \ AEEQList.h \ - AEEStdDef.h \ AEEstd.h \ - HAP_debug.h \ - HAP_farf.h \ HAP_farf_internal.h \ HAP_pls.h \ adsp_current_process.h \ @@ -40,6 +40,7 @@ noinst_HEADERS = \ fastrpc_cap.h \ fastrpc_common.h \ fastrpc_config.h \ + fastrpc_config_parser.h \ fastrpc_context.h \ fastrpc_hash_table.h \ fastrpc_internal.h \ diff --git a/inc/apps_std_internal.h b/inc/apps_std_internal.h index 74d7ae6..37be0c2 100644 --- a/inc/apps_std_internal.h +++ b/inc/apps_std_internal.h @@ -22,23 +22,6 @@ #define MAX_NON_PRELOAD_LIBS_LEN 2048 #define FILE_EXT ".so" -// Locations where shell file can be found -#ifndef ENABLE_UPSTREAM_DRIVER_INTERFACE -#ifndef DSP_MOUNT_LOCATION -#define DSP_MOUNT_LOCATION "/dsp/" -#endif -#ifndef DSP_DOM_LOCATION -#define DSP_DOM_LOCATION "/dsp/xdsp" -#endif -#else /* ENABLE_UPSTREAM_DRIVER_INTERFACE */ -#ifndef DSP_MOUNT_LOCATION -#define DSP_MOUNT_LOCATION "/usr/lib/dsp/" -#endif -#ifndef DSP_DOM_LOCATION -#define DSP_DOM_LOCATION "/usr/lib/dsp/xdspn" -#endif -#endif /* ENABLE_UPSTREAM_DRIVER_INTERFACE */ - #ifndef VENDOR_DSP_LOCATION #define VENDOR_DSP_LOCATION "/vendor/dsp/" #endif @@ -46,14 +29,12 @@ #define VENDOR_DOM_LOCATION "/vendor/dsp/xdsp/" #endif -// Search path used by fastRPC to search skel library, .debugconfig and .farf files -#ifndef DSP_SEARCH_PATH -#define DSP_SEARCH_PATH ";/usr/lib/rfsa/adsp;/vendor/lib/rfsa/adsp;/vendor/dsp/;/usr/lib/dsp/;" -#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); + #endif /*__APPS_STD_INTERNAL_H__*/ diff --git a/inc/fastrpc_config_parser.h b/inc/fastrpc_config_parser.h new file mode 100644 index 0000000..1ce1fb9 --- /dev/null +++ b/inc/fastrpc_config_parser.h @@ -0,0 +1,17 @@ +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// SPDX-License-Identifier: BSD-3-Clause-Clear + +#ifndef FASTRPC_YAML_PARSER_H +#define FASTRPC_YAML_PARSER_H + +// DEFAULT_DSP_SEARCH_PATHS intentionally left empty - these paths should be provided through configuration files +#ifndef DEFAULT_DSP_SEARCH_PATHS +#define DEFAULT_DSP_SEARCH_PATHS "" +#endif +#define DSP_LIB_KEY "DSP_LIBRARY_PATH" + +extern char DSP_LIBS_LOCATION[PATH_MAX]; + +void configure_dsp_paths(); + +#endif /*FASTRPC_YAML_PARSER_H*/ diff --git a/inc/fastrpc_internal.h b/inc/fastrpc_internal.h index 859bfe8..31f1b5d 100644 --- a/inc/fastrpc_internal.h +++ b/inc/fastrpc_internal.h @@ -334,7 +334,7 @@ struct handle_list { * @brief API to get the DSP_SEARCH_PATH stored locally as static. * @get_path : get_path will be updated with the path stored in DSP_SEARCH_PATH locally. **/ -void get_default_dsp_search_path(char* path); +const char* get_dsp_search_path(); /** * @brief API to map memory to the remote domain diff --git a/public_headers/config.yml b/public_headers/config.yml new file mode 100644 index 0000000..c4bd378 --- /dev/null +++ b/public_headers/config.yml @@ -0,0 +1,11 @@ +project: https://github.com/qualcomm/fastrpc + +branches: + development: + modes: + blocking: + headers: + - inc/remote.h + - inc/remote64.h + - inc/dspqueue.h + - inc/rpcmem.h diff --git a/src/Makefile.am b/src/Makefile.am index 7c28c49..9a3608d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,12 @@ lib_LTLIBRARIES = -LIBDSPRPC_CFLAGS = -fno-short-enums -U_DEBUG -DARM_ARCH_7A -DLE_ENABLE -DENABLE_UPSTREAM_DRIVER_INTERFACE -DUSE_SYSLOG -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 + +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;"' +endif LIBDSPRPC_SOURCES = \ fastrpc_apps_user.c \ @@ -48,6 +54,12 @@ LIBDSPRPC_SOURCES = \ mod_table.c \ fastrpc_context.c +if ANDROID_CC +# Do nothing (or Android-specific sources) +else +LIBDSPRPC_SOURCES += fastrpc_config_parser.c +endif + LIBDEFAULT_LISTENER_SOURCES = \ adsp_default_listener.c \ adsp_default_listener_stub.c \ @@ -55,6 +67,12 @@ 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@ endif ADSP_CFLAGS = $(LIBDSPRPC_CFLAGS) -DDEFAULT_DOMAIN_ID=0 diff --git a/src/apps_std_imp.c b/src/apps_std_imp.c index 3458d8c..3a69345 100644 --- a/src/apps_std_imp.c +++ b/src/apps_std_imp.c @@ -932,11 +932,15 @@ static int get_dirlist_from_env(const char *envvarname, char **ppDirList) { char *dirList = NULL; char *dirListBuf = NULL; char *srcStr = NULL; + const char *dsp_search_path = NULL; int nErr = AEE_SUCCESS; int envListLen = 0; int envListPrependLen = 0; int listLen = 0; - int envLenGuess = STD_MAX(ENV_LEN_GUESS, 1 + strlen(DSP_SEARCH_PATH)); + int envLenGuess = 0; + + dsp_search_path = get_dsp_search_path(); + envLenGuess = STD_MAX(ENV_LEN_GUESS, 1 + strlen(dsp_search_path)); FARF(RUNTIME_RPC_LOW, "Entering %s", __func__); VERIFYC(NULL != ppDirList, AEE_ERPC); @@ -950,8 +954,8 @@ static int get_dirlist_from_env(const char *envvarname, char **ppDirList) { strlen(ADSP_LIBRARY_PATH)) == 0 || strncmp(envvarname, DSP_LIBRARY_PATH, strlen(DSP_LIBRARY_PATH)) == 0) { - // Calculate total length of env and DSP_SEARCH_PATH - envListPrependLen = envListLen + strlen(DSP_SEARCH_PATH); + // Calculate total length of env + semicolon + DSP_SEARCH_PATH + envListPrependLen = envListLen + 1 + strlen(dsp_search_path); if (envLenGuess < envListPrependLen) { FREEIF(envListBuf); VERIFYC(envListBuf = @@ -961,8 +965,10 @@ static int get_dirlist_from_env(const char *envvarname, char **ppDirList) { VERIFY(0 == (nErr = apps_std_getenv(envvarname, envList, envListPrependLen, &listLen))); } + // Append semicolon before DSP_SEARCH_PATH + strlcat(envList, ";", envListPrependLen); // Append default DSP_SEARCH_PATH to user defined env - strlcat(envList, DSP_SEARCH_PATH, envListPrependLen); + strlcat(envList, dsp_search_path, envListPrependLen); envListLen = envListPrependLen; } else if (strncmp(envvarname, ADSP_AVS_PATH, strlen(ADSP_AVS_PATH)) == 0) { @@ -978,15 +984,13 @@ static int get_dirlist_from_env(const char *envvarname, char **ppDirList) { } strlcat(envList, ADSP_AVS_CFG_PATH, envListPrependLen); envListLen = envListPrependLen; - } else { - envListLen = listLen; } } else if (strncmp(envvarname, ADSP_LIBRARY_PATH, strlen(ADSP_LIBRARY_PATH)) == 0 || strncmp(envvarname, DSP_LIBRARY_PATH, strlen(DSP_LIBRARY_PATH)) == 0) { envListLen = listLen = - 1 + strlcpy(envListBuf, DSP_SEARCH_PATH, envLenGuess); + 1 + strlcpy(envListBuf, dsp_search_path, envLenGuess); } else if (strncmp(envvarname, ADSP_AVS_PATH, strlen(ADSP_AVS_PATH)) == 0) { envListLen = listLen = @@ -1018,42 +1022,14 @@ static int get_dirlist_from_env(const char *envvarname, char **ppDirList) { return nErr; } -__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen_with_env)( - const char *envvarname, const char *delim, const char *name, - const char *mode, apps_std_FILE *psout) __QAIC_IMPL_ATTRIBUTE { - +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 *dirName = NULL; - char *pos = NULL; - char *dirListBuf = NULL; - char *dirList = NULL; - char *absName = NULL; - const char *envVar = NULL; + char *absName = NULL, *dirName = NULL, *pos = NULL; uint16_t absNameLen = 0; int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(get_current_domain()); - FARF(RUNTIME_RPC_LOW, "Entering %s", __func__); - VERIFYC(NULL != mode, AEE_EBADPARM); - VERIFYC(NULL != delim, AEE_EBADPARM); - VERIFYC(NULL != name, AEE_EBADPARM); - VERIFYC(NULL != envvarname, AEE_EBADPARM); - FASTRPC_ATRACE_BEGIN_L("%s for %s in %s mode from path in environment " - "variable %s delimited with %s", - __func__, name, mode, envvarname, delim); - if (strncmp(envvarname, ADSP_LIBRARY_PATH, - strlen(ADSP_LIBRARY_PATH)) == 0) { - if (getenv(DSP_LIBRARY_PATH)) { - envVar = DSP_LIBRARY_PATH; - } else { - envVar = ADSP_LIBRARY_PATH; - } - } else { - envVar = envvarname; - } - - VERIFY(0 == (nErr = get_dirlist_from_env(envVar, &dirListBuf))); - VERIFYC(NULL != (dirList = dirListBuf), AEE_EBADPARM); - FARF(RUNTIME_RPC_HIGH, "%s dirList %s", __func__, dirList); + VERIFYC(NULL != dirList, AEE_EBADPARM); while (dirList) { pos = strstr(dirList, delim); @@ -1067,7 +1043,7 @@ __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen_with_env)( // Append domain to path absNameLen = - strlen(dirName) + strlen(name) + 2 + strlen("adsp") + 1; + strlen(dirName) + strlen(name) + 2 + strlen(SUBSYSTEM_NAME[domain]) + 1; VERIFYC(NULL != (absName = (char *)malloc(sizeof(char) * absNameLen)), AEE_ENOMEMORY); if ('\0' != *dirName) { @@ -1084,7 +1060,8 @@ __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen_with_env)( if (AEE_SUCCESS == nErr) { // Success FARF(ALWAYS, "Successfully opened file %s", absName); - goto bail; + FREEIF(absName); + return nErr; } FREEIF(absName); @@ -1109,12 +1086,50 @@ __QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen_with_env)( (strncmp(name, TESTSIG_FILE_NAME, strlen(TESTSIG_FILE_NAME)) != 0)) FARF(ALWAYS, "Successfully opened file %s", name); - goto bail; + FREEIF(absName); + return nErr; } - FREEIF(absName); } bail: FREEIF(absName); + return nErr; +} + +__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen_with_env)( + const char *envvarname, const char *delim, const char *name, + const char *mode, apps_std_FILE *psout) __QAIC_IMPL_ATTRIBUTE { + + int nErr = AEE_SUCCESS; + char *dirListBuf = NULL; + char *dirList = NULL; + const char *envVar = NULL; + + FARF(RUNTIME_RPC_LOW, "Entering %s", __func__); + VERIFYC(NULL != mode, AEE_EBADPARM); + VERIFYC(NULL != delim, AEE_EBADPARM); + VERIFYC(NULL != name, AEE_EBADPARM); + VERIFYC(NULL != envvarname, AEE_EBADPARM); + FASTRPC_ATRACE_BEGIN_L("%s for %s in %s mode from path in environment " + "variable %s delimited with %s", + __func__, name, mode, envvarname, delim); + if (strncmp(envvarname, ADSP_LIBRARY_PATH, + strlen(ADSP_LIBRARY_PATH)) == 0) { + if (getenv(DSP_LIBRARY_PATH)) { + envVar = DSP_LIBRARY_PATH; + } else { + envVar = ADSP_LIBRARY_PATH; + } + } else { + envVar = envvarname; + } + + VERIFY(0 == (nErr = get_dirlist_from_env(envVar, &dirListBuf))); + VERIFYC(NULL != (dirList = dirListBuf), AEE_EBADPARM); + FARF(RUNTIME_RPC_HIGH, "%s dirList %s", __func__, dirList); + + nErr = fopen_from_dirlist(dirList, delim, mode, name, psout); + +bail: FREEIF(dirListBuf); if (nErr != AEE_SUCCESS) { if (ERRNO != ENOENT || diff --git a/src/dsprpcd.c b/src/dsprpcd.c index b3d01f8..348049a 100644 --- a/src/dsprpcd.c +++ b/src/dsprpcd.c @@ -15,39 +15,80 @@ #include #include -#ifndef ADSP_DEFAULT_LISTENER_NAME -#define ADSP_DEFAULT_LISTENER_NAME "libadsp_default_listener.so" +#ifndef ADSP_LISTENER_VERSIONED +#define ADSP_LISTENER_VERSIONED "libadsp_default_listener.so.1" +#define ADSP_LISTENER_UNVERSIONED "libadsp_default_listener.so" #endif -#ifndef CDSP_DEFAULT_LISTENER_NAME -#define CDSP_DEFAULT_LISTENER_NAME "libcdsp_default_listener.so" +#ifndef CDSP_LISTENER_VERSIONED +#define CDSP_LISTENER_VERSIONED "libcdsp_default_listener.so.1" +#define CDSP_LISTENER_UNVERSIONED "libcdsp_default_listener.so" #endif -#ifndef SDSP_DEFAULT_LISTENER_NAME -#define SDSP_DEFAULT_LISTENER_NAME "libsdsp_default_listener.so" +#ifndef SDSP_LISTENER_VERSIONED +#define SDSP_LISTENER_VERSIONED "libsdsp_default_listener.so.1" +#define SDSP_LISTENER_UNVERSIONED "libsdsp_default_listener.so" #endif -#ifndef GDSP_DEFAULT_LISTENER_NAME -#define GDSP_DEFAULT_LISTENER_NAME "libcdsp_default_listener.so.1" +#ifndef GDSP_LISTENER_VERSIONED +#define GDSP_LISTENER_VERSIONED "libcdsp_default_listener.so.1" +#define GDSP_LISTENER_UNVERSIONED "libcdsp_default_listener.so" #endif typedef int (*dsp_default_listener_start_t)(int argc, char *argv[]); +// Result struct for dlopen. +struct dlopen_result { + void *handle; + const char *loaded_lib_name; +}; + +/** + * Attempts to load a shared library using dlopen. + * If the versioned name fails, falls back to the unversioned name. + * Returns both the handle and the name of the library successfully loaded. + */ +static struct dlopen_result try_dlopen(const char *versioned, const char *unversioned) { + struct dlopen_result result = { NULL, NULL }; + + result.handle = dlopen(versioned, RTLD_NOW); + if (result.handle) { + result.loaded_lib_name = versioned; + return result; + } + + if (unversioned) { + VERIFY_IPRINTF("dlopen failed for %s: %s; attempting fallback %s", + versioned, dlerror(), unversioned); + result.handle = dlopen(unversioned, RTLD_NOW); + if (result.handle) { + result.loaded_lib_name = unversioned; + return result; + } + } + return result; +} + int main(int argc, char *argv[]) { int nErr = 0; - void *dsphandler = NULL; - const char* lib_name; + struct dlopen_result dlres = { NULL, NULL }; + const char* lib_versioned; + const char* lib_unversioned; const char* dsp_name; dsp_default_listener_start_t listener_start; #ifdef USE_ADSP - lib_name = ADSP_DEFAULT_LISTENER_NAME; + lib_versioned = ADSP_LISTENER_VERSIONED; + lib_unversioned = ADSP_LISTENER_UNVERSIONED; dsp_name = "ADSP"; #elif defined(USE_SDSP) - lib_name = SDSP_DEFAULT_LISTENER_NAME; + lib_versioned = SDSP_LISTENER_VERSIONED; + lib_unversioned = SDSP_LISTENER_UNVERSIONED; dsp_name = "SDSP"; #elif defined(USE_CDSP) - lib_name = CDSP_DEFAULT_LISTENER_NAME; + lib_versioned = CDSP_LISTENER_VERSIONED; + lib_unversioned = CDSP_LISTENER_UNVERSIONED; dsp_name = "CDSP"; #elif defined(USE_GDSP) - lib_name = GDSP_DEFAULT_LISTENER_NAME; + lib_versioned = GDSP_LISTENER_VERSIONED; + lib_unversioned = GDSP_LISTENER_UNVERSIONED; dsp_name = "GDSP"; #else goto bail; @@ -55,14 +96,15 @@ int main(int argc, char *argv[]) { VERIFY_EPRINTF("%s daemon starting", dsp_name); while (1) { - if (NULL != (dsphandler = dlopen(lib_name,RTLD_NOW))) { + dlres = try_dlopen(lib_versioned, lib_unversioned); + if (NULL != dlres.handle) { if (NULL != (listener_start = (dsp_default_listener_start_t)dlsym( - dsphandler, "adsp_default_listener_start"))) { + dlres.handle, "adsp_default_listener_start"))) { VERIFY_IPRINTF("adsp_default_listener_start called"); nErr = listener_start(argc, argv); } - if (0 != dlclose(dsphandler)) { - VERIFY_EPRINTF("dlclose failed for %s", lib_name); + if (0 != dlclose(dlres.handle)) { + VERIFY_EPRINTF("dlclose failed for %s", dlres.loaded_lib_name); } } else { VERIFY_EPRINTF("%s daemon error %s", dsp_name, dlerror()); diff --git a/src/fastrpc_apps_user.c b/src/fastrpc_apps_user.c index 81fef0a..f111ccf 100644 --- a/src/fastrpc_apps_user.c +++ b/src/fastrpc_apps_user.c @@ -75,17 +75,13 @@ #include "fastrpc_context.h" #include "fastrpc_process_attributes.h" #include "fastrpc_trace.h" +#include "fastrpc_config_parser.h" -#ifndef ENABLE_UPSTREAM_DRIVER_INTERFACE -#define DSP_MOUNT_LOCATION "/dsp/" -#define DSP_DOM_LOCATION "/dsp/xdsp" -#else -#define DSP_MOUNT_LOCATION "/usr/lib/dsp/" -#define DSP_DOM_LOCATION "/usr/lib/dsp/xdspn" -#endif #define VENDOR_DSP_LOCATION "/vendor/dsp/" #define VENDOR_DOM_LOCATION "/vendor/dsp/xdsp/" +char DSP_LIBS_LOCATION[PATH_MAX] = DEFAULT_DSP_SEARCH_PATHS; + #ifdef LE_ENABLE #define PROPERTY_VALUE_MAX \ 92 // as this macro is defined in cutils for Android platforms, defined @@ -3437,8 +3433,8 @@ static int open_shell(int domain_id, apps_std_FILE *fh, int unsigned_shell) { char *absName = NULL; char *shell_absName = NULL; char *domain_str = NULL; + char dir_list[PATH_MAX] = {0}; uint16_t shell_absNameLen = 0, absNameLen = 0; - ; int nErr = AEE_SUCCESS; int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(domain_id); const char *shell_name = SIGNED_SHELL; @@ -3459,27 +3455,11 @@ static int open_shell(int domain_id, apps_std_FILE *fh, int unsigned_shell) { (shell_absName = (char *)malloc(sizeof(char) * shell_absNameLen)), AEE_ENOMEMORY); strlcpy(shell_absName, shell_name, shell_absNameLen); - strlcat(shell_absName, domain_str, shell_absNameLen); - absNameLen = strlen(DSP_MOUNT_LOCATION) + shell_absNameLen + 1; - VERIFYC(NULL != (absName = (char *)malloc(sizeof(char) * absNameLen)), - AEE_ENOMEMORY); - strlcpy(absName, DSP_MOUNT_LOCATION, absNameLen); - strlcat(absName, shell_absName, absNameLen); + strlcpy(dir_list, DSP_LIBS_LOCATION, sizeof(dir_list)); + nErr = fopen_from_dirlist(dir_list, ";", "r", shell_absName, fh); - nErr = apps_std_fopen(absName, "r", fh); - if (nErr) { - absNameLen = strlen(DSP_DOM_LOCATION) + shell_absNameLen + 1; - VERIFYC(NULL != - (absName = (char *)realloc(absName, sizeof(char) * absNameLen)), - AEE_ENOMEMORY); - strlcpy(absName, DSP_MOUNT_LOCATION, absNameLen); - strlcat(absName, SUBSYSTEM_NAME[domain], absNameLen); - strlcat(absName, "/", absNameLen); - strlcat(absName, shell_absName, absNameLen); - nErr = apps_std_fopen(absName, "r", fh); - } if (nErr) { absNameLen = strlen(VENDOR_DSP_LOCATION) + shell_absNameLen + 1; VERIFYC(NULL != @@ -3503,7 +3483,7 @@ static int open_shell(int domain_id, apps_std_FILE *fh, int unsigned_shell) { } } if (!nErr) - FARF(RUNTIME_RPC_HIGH, "Successfully opened %s, domain %d", absName, domain); + FARF(RUNTIME_RPC_HIGH, "Successfully opened %s, domain %d", shell_absName, domain); bail: if (domain_str) { free(domain_str); @@ -3523,10 +3503,9 @@ static int open_shell(int domain_id, apps_std_FILE *fh, int unsigned_shell) { *fh = -1; } else { FARF(ERROR, - "Error 0x%x: %s failed for domain %d search paths used are %s, %s, " - "%s (errno %s)\n", - nErr, __func__, domain, DSP_MOUNT_LOCATION, VENDOR_DSP_LOCATION, - VENDOR_DOM_LOCATION, strerror(errno)); + "Error 0x%x: %s failed for domain %d search paths used are %s " + "(errno %s)\n", + nErr, __func__, domain, DSP_LIBS_LOCATION, strerror(errno)); } } return nErr; @@ -4040,15 +4019,6 @@ static int domain_init(int domain, int *dev) { ret == (int)(DSP_AEE_EOFFSET + AEE_EUNSUPPORTED), ret); } -#ifdef PD_EXCEPTION_LOGGING - if ((dom != SDSP_DOMAIN_ID) && hlist[domain].dsppd == ROOT_PD) { - remote_handle64 handle = 0; - handle = get_adspmsgd_adsp1_handle(domain); - if (handle != INVALID_HANDLE) { - adspmsgd_init(handle, 0x10); // enable PD exception logging - } - } -#endif fastrpc_perf_init(hlist[domain].dev, domain); VERIFY(AEE_SUCCESS == (nErr = fastrpc_latency_init(hlist[domain].dev, &hlist[domain].qos))); @@ -4059,6 +4029,13 @@ static int domain_init(int domain, int *dev) { VERIFY(AEE_SUCCESS == (nErr = listener_android_domain_init( domain, hlist[domain].th_params.update_requested, &hlist[domain].th_params.r_sem))); + if ((dom != SDSP_DOMAIN_ID) && hlist[domain].dsppd == ROOT_PD) { + remote_handle64 handle = 0; + handle = get_adspmsgd_adsp1_handle(domain); + if (handle != INVALID_HANDLE) { + adspmsgd_init(handle, 0x10); // enable PD exception logging + } + } bail: if (nErr != AEE_SUCCESS) { domain_deinit(domain); @@ -4157,6 +4134,10 @@ static void exit_thread(void *value) { pthread_setspecific(tlsKey, (void *)NULL); } +const char* get_dsp_search_path() { + return DSP_LIBS_LOCATION; +} + /* * Called only once by fastrpc_init_once * Initializes the data structures @@ -4171,6 +4152,10 @@ 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 = pthread_key_create(&tlsKey, exit_thread))); +#ifdef PARSE_YAML + configure_dsp_paths(); +#endif fastrpc_mem_init(); fastrpc_context_table_init(); fastrpc_log_init(); @@ -4201,7 +4186,6 @@ static int fastrpc_apps_user_init(void) { pthread_mutex_init(&hlist[i].async_init_deinit_mut, 0); } listener_android_init(); - VERIFY(AEE_SUCCESS == (nErr = pthread_key_create(&tlsKey, exit_thread))); VERIFY(AEE_SUCCESS == (nErr = PL_INIT(apps_std))); GenCrc32Tab(POLY32, crc_table); fastrpc_notif_init(); diff --git a/src/fastrpc_config_parser.c b/src/fastrpc_config_parser.c new file mode 100644 index 0000000..786aebe --- /dev/null +++ b/src/fastrpc_config_parser.c @@ -0,0 +1,181 @@ +// 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); +} diff --git a/src/log_config.c b/src/log_config.c index 0c3ee42..b3f9e1d 100644 --- a/src/log_config.c +++ b/src/log_config.c @@ -392,8 +392,10 @@ static void *file_watcher_thread(void *arg) { remote_handle64 handle; int file_found = 0; char *data_paths = NULL; + const char *dsp_search_path = NULL; FARF(ALWAYS, "%s starting for domain %d\n", __func__, dom); + dsp_search_path = get_dsp_search_path(); // Check for the presence of the .farf file at bootup for (i = 0; i < (int)log_config_watcher[dom].numPaths; ++i) { if (0 == readLogConfigFromPath(dom, log_config_watcher[dom].paths[i].data, @@ -414,9 +416,8 @@ static void *file_watcher_thread(void *arg) { ret = apps_std_getenv(DSP_LIBRARY_PATH, data_paths, ENV_PATH_LEN, &env_list_len); errno = current_errno; - // User has not set the env variable. Get default search paths. if (ret != 0) - memmove(data_paths, DSP_SEARCH_PATH, strlen(DSP_SEARCH_PATH)); + strlcpy(data_paths, dsp_search_path, ENV_PATH_LEN); VERIFY_WPRINTF("%s: Couldn't find file %s, errno (%s) at %s\n", __func__, log_config_watcher[dom].fileToWatch, strerror(errno), data_paths); diff --git a/test/fastrpc_test.c b/test/fastrpc_test.c index 89f57e2..1ce506b 100644 --- a/test/fastrpc_test.c +++ b/test/fastrpc_test.c @@ -11,6 +11,8 @@ #include #include // For PATH_MAX +#define DSP_AEE_EUNSUPPORTED 0x80000414 + typedef int (*run_test_t)(int domain_id, bool is_unsignedpd_enabled); static void print_usage() { @@ -49,6 +51,10 @@ int main(int argc, char *argv[]) { void *lib_handle = NULL; run_test_t run_test = NULL; int nErr = 0; + int tests_run = 0; + int tests_passed = 0; + int tests_failed = 0; + int tests_skipped = 0; int opt; while ((opt = getopt(argc, argv, "d:U:t:a:")) != -1) { @@ -127,10 +133,17 @@ int main(int argc, char *argv[]) { } nErr = run_test(domain_id, is_unsignedpd_enabled); - if (nErr != 0) { - printf("Test failed with error code 0x%x in %s\n", nErr, full_lib_path); + tests_run++; + + if (nErr == 0) { + tests_passed++; + printf("[PASS] %s\n\n", entry->d_name); + } else if (nErr == DSP_AEE_EUNSUPPORTED) { + tests_skipped++; + printf("[SKIP] %s (not applicable to this hardware)\n\n", entry->d_name); } else { - printf("Success in %s\n", full_lib_path); + tests_failed++; + printf("[FAIL] %s (error code: 0x%x)\n\n", entry->d_name, nErr); } dlclose(lib_handle); @@ -139,11 +152,29 @@ int main(int argc, char *argv[]) { closedir(dir); - if (nErr != 0) { - printf("Test failed with error code 0x%x\n", nErr); - } else { - printf("All tests completed successfully\n"); + printf("\n========================================\n"); + printf("Test Summary:\n"); + printf(" Total tests run: %d\n", tests_run); + printf(" Passed: %d\n", tests_passed); + printf(" Failed: %d\n", tests_failed); + printf(" Skipped: %d\n", tests_skipped); + printf("========================================\n"); + + if (tests_run == 0) { + printf("\nERROR: No tests were found or executed.\n"); + return -1; + } + + if (tests_failed > 0) { + printf("\nRESULT: %d test(s) FAILED\n", tests_failed); + return tests_failed; } - return nErr; -} \ No newline at end of file + if (tests_passed == 0 && tests_skipped > 0) { + printf("\nWARNING: All tests were skipped. No applicable tests for this hardware.\n"); + return -1; + } + + printf("\nRESULT: All applicable tests PASSED\n"); + return 0; +} diff --git a/test/linux/libhap_example.so b/test/linux/libhap_example.so index b10cda6..446d83e 100644 Binary files a/test/linux/libhap_example.so and b/test/linux/libhap_example.so differ diff --git a/test/linux/libmultithreading.so b/test/linux/libmultithreading.so index 40de4ce..a5b3abb 100644 Binary files a/test/linux/libmultithreading.so and b/test/linux/libmultithreading.so differ diff --git a/test/v68/libhap_example_skel.so b/test/v68/libhap_example_skel.so index 291e5cc..58f6803 100644 Binary files a/test/v68/libhap_example_skel.so and b/test/v68/libhap_example_skel.so differ diff --git a/test/v68/libmultithreading_skel.so b/test/v68/libmultithreading_skel.so index 5b62289..87aee75 100644 Binary files a/test/v68/libmultithreading_skel.so and b/test/v68/libmultithreading_skel.so differ diff --git a/test/v75/libhap_example_skel.so b/test/v75/libhap_example_skel.so index 0fc4888..0dc42a2 100644 Binary files a/test/v75/libhap_example_skel.so and b/test/v75/libhap_example_skel.so differ diff --git a/test/v75/libmultithreading_skel.so b/test/v75/libmultithreading_skel.so index 341be03..db1c93c 100644 Binary files a/test/v75/libmultithreading_skel.so and b/test/v75/libmultithreading_skel.so differ