Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Docs/schemas/fastrpc-config-schema.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
machines: map(key=str(), value=map(DSP_LIBRARY_PATH=regex('^/.+/')))
machines: map(
key=str(),
value=map(
DSP_LIBRARY_PATH=regex('^/.+/'),
ADSP_ARCH=optional(regex('^v[0-9a-f]+$')),
MDSP_ARCH=optional(regex('^v[0-9a-f]+$')),
SDSP_ARCH=optional(regex('^v[0-9a-f]+$')),
CDSP_ARCH=optional(regex('^v[0-9a-f]+$')),
CDSP1_ARCH=optional(regex('^v[0-9a-f]+$')),
GDSP0_ARCH=optional(regex('^v[0-9a-f]+$')),
GDSP1_ARCH=optional(regex('^v[0-9a-f]+$'))
)
)
9 changes: 9 additions & 0 deletions inc/fastrpc_config_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@
#ifndef FASTRPC_YAML_PARSER_H
#define FASTRPC_YAML_PARSER_H

#include "fastrpc_common.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"

/*
* Per-domain YAML keys for the Hexagon architecture version string (e.g. "v75").
* Indexed by base domain ID (ADSP=0 .. GDSP1=6); entry 7 is NULL (unused).
*/
extern const char *DSP_ARCH_KEY[NUM_DOMAINS];

extern char DSP_LIBS_LOCATION[PATH_MAX];

void configure_dsp_paths();
const char *get_dsp_arch_from_yaml(int domain);

#endif /*FASTRPC_YAML_PARSER_H*/
92 changes: 91 additions & 1 deletion src/fastrpc_apps_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@

#define VENDOR_DSP_LOCATION "/vendor/dsp/"
#define VENDOR_DOM_LOCATION "/vendor/dsp/xdsp/"
#define HEXAGON_LIBS_PATH_PREFIX CONFIG_BASE_DIR "hexagon"

char DSP_LIBS_LOCATION[PATH_MAX] = DEFAULT_DSP_SEARCH_PATHS;
static char DSP_SEARCH_PATHS_CACHE[NUM_DOMAINS][PATH_MAX] = {{0}};

#ifdef LE_ENABLE
#define PROPERTY_VALUE_MAX \
Expand Down Expand Up @@ -327,6 +329,92 @@ extern void apps_mem_table_deinit(void);
static uint32_t crc_table[256];
static atomic_bool timer_expired = false;

static void build_dsp_search_path_cache_for_domain(int domain) {
int nErr = AEE_SUCCESS;
fastrpc_capability cap = {0, ARCH_VER, 0};
char arch_str[64] = {0};
char arch_path[PATH_MAX] = {0};
char *domain_path_cache = NULL;
const char *yaml_arch = NULL;

if (!IS_VALID_DOMAIN_ID(domain)) {
FARF(ALWAYS, "Warning: %s: Invalid domain %d", __func__, domain);
return;
}

domain_path_cache = DSP_SEARCH_PATHS_CACHE[domain];

/*
* Resolve arch string: capability API is preferred; YAML is the fallback
* for legacy targets where the capability is not supported.
*/
cap.domain = domain;
nErr = fastrpc_get_cap(cap.domain, cap.attribute_ID, &cap.capability);
if (nErr == AEE_SUCCESS && cap.capability != 0) {
snprintf(arch_str, sizeof(arch_str), "v%02x", cap.capability & 0xFF);
FARF(RUNTIME_RPC_HIGH, "%s: domain %d: resolved ARCH from capability 0x%x: %s",
__func__, domain, cap.capability, arch_str);
} else {
/* Legacy target: capability API not supported, use YAML ARCH config. */
FARF(ALWAYS,
"Warning 0x%x: %s: ARCH_VER capability not supported for domain %d, "
"trying YAML ARCH config",
nErr, __func__, domain);
yaml_arch = get_dsp_arch_from_yaml(domain);
if (!yaml_arch || yaml_arch[0] == '\0') {
FARF(ALWAYS,
"Warning: %s: No YAML ARCH config for domain %d, "
"using DSP_LIBS_LOCATION only",
__func__, domain);
strlcpy(domain_path_cache, DSP_LIBS_LOCATION, PATH_MAX);
return;
}
strlcpy(arch_str, yaml_arch, sizeof(arch_str));
FARF(RUNTIME_RPC_HIGH, "%s: domain %d: resolved ARCH from YAML config: %s",
__func__, domain, arch_str);
}

/*
* Build the arch-specific path and put it at the front of the search list,
* followed by DSP_LIBS_LOCATION (board/YAML paths + generic fallback).
* The user-set ADSP_LIBRARY_PATH env is prepended at open-time by
* apps_std_imp, so the effective resolution order is:
* 1. ADSP_LIBRARY_PATH (user/container, highest priority)
* 2. arch-specific path (e.g. CONFIG_BASE_DIR/hexagon/v75)
* 3. DSP_LIBS_LOCATION (board-specific path from YAML + generic fallback)
*/
if (snprintf(arch_path, sizeof(arch_path), "%s/%s",
HEXAGON_LIBS_PATH_PREFIX, arch_str) >= (int)sizeof(arch_path)) {
FARF(ALWAYS,
"Warning: %s: ARCH path truncated for domain %d, "
"using DSP_LIBS_LOCATION only",
__func__, domain);
strlcpy(domain_path_cache, DSP_LIBS_LOCATION, PATH_MAX);
return;
}

strlcpy(domain_path_cache, arch_path, PATH_MAX);
strlcat(domain_path_cache, ";", PATH_MAX);
if (strlcat(domain_path_cache, DSP_LIBS_LOCATION, PATH_MAX) >= PATH_MAX) {
FARF(ALWAYS,
"Warning: %s: Failed to build search list for domain %d, "
"using DSP_LIBS_LOCATION only",
__func__, domain);
strlcpy(domain_path_cache, DSP_LIBS_LOCATION, PATH_MAX);
return;
}

FARF(RUNTIME_RPC_HIGH, "%s: domain %d: search path: %s", __func__, domain,
domain_path_cache);
}

static const char *get_dsp_search_path_for_domain(int domain) {
if (IS_VALID_DOMAIN_ID(domain) && DSP_SEARCH_PATHS_CACHE[domain][0] != '\0')
return DSP_SEARCH_PATHS_CACHE[domain];

return DSP_LIBS_LOCATION;
}

void set_thread_context(int domain) {
if (tlsKey != INVALID_KEY) {
pthread_setspecific(tlsKey, (void *)&hlist[domain]);
Expand Down Expand Up @@ -3792,6 +3880,7 @@ static int domain_init(int domain, int *dev) {
}
}
VERIFY(AEE_SUCCESS == (nErr = fastrpc_enable_kernel_optimizations(domain)));
build_dsp_search_path_cache_for_domain(domain);
initFileWatcher(domain); // Ignore errors
trace_marker_init(domain);

Expand Down Expand Up @@ -3927,7 +4016,8 @@ static void exit_thread(void *value) {
}

const char* get_dsp_search_path() {
return DSP_LIBS_LOCATION;
int domain = GET_DOMAIN_FROM_EFFEC_DOMAIN_ID(get_current_domain());
return get_dsp_search_path_for_domain(domain);
}

/*
Expand Down
46 changes: 41 additions & 5 deletions src/fastrpc_config_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,28 @@
#include "HAP_farf.h"
#include "apps_std_internal.h"
#include "fastrpc_config_parser.h"
#include "fastrpc_internal.h"

const char *DSP_ARCH_KEY[NUM_DOMAINS] = {
"ADSP_ARCH",
"MDSP_ARCH",
"SDSP_ARCH",
"CDSP_ARCH",
"CDSP1_ARCH",
"GDSP0_ARCH",
"GDSP1_ARCH",
NULL,
};

static char DSP_ARCH_FROM_YAML[NUM_DOMAINS][8] = {{0}};

const char *get_dsp_arch_from_yaml(int domain) {
if (!IS_VALID_DOMAIN_ID(domain))
return NULL;
if (DSP_ARCH_FROM_YAML[domain][0] == '\0')
return NULL;
return DSP_ARCH_FROM_YAML[domain];
}

static int compare_strings(const void *a, const void *b) {
return strcmp(*(const char **)a, *(const char **)b);
Expand Down Expand Up @@ -90,9 +112,25 @@ static void get_dsp_lib_path(const char *machine_name, const char *filepath, cha
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);
FARF(ALWAYS, "dsp_lib_paths is %s", dsp_lib_paths);
found_dsp_path = 1;
done = 1;
}
} else if (in_target_machine) {
/* Check if this scalar is one of the per-domain ARCH keys */
int d;
for (d = 0; d < NUM_DOMAINS; d++) {
if (DSP_ARCH_KEY[d] && strcmp(value, DSP_ARCH_KEY[d]) == 0) {
yaml_event_delete(&event);
if (yaml_parser_parse(&parser, &event) &&
event.type == YAML_SCALAR_EVENT) {
strlcpy(DSP_ARCH_FROM_YAML[d],
(const char *)event.data.scalar.value,
sizeof(DSP_ARCH_FROM_YAML[d]));
FARF(ALWAYS, "%s: YAML arch for domain %d (%s): %s",
__func__, d, DSP_ARCH_KEY[d], DSP_ARCH_FROM_YAML[d]);
}
break;
}
}
}
break;
Expand All @@ -101,9 +139,7 @@ static void get_dsp_lib_path(const char *machine_name, const char *filepath, cha
if (in_target_machine) {
// Exiting the target machine mapping
in_target_machine = 0;
if (found_dsp_path) {
done = 1;
}
done = 1;
}
break;
case YAML_STREAM_END_EVENT:
Expand Down
Loading