/* * Copyright (c) 2021 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include /* Implementation of functions related to controlling logging sources and backends: * - getting/setting source details like name, filtering * - controlling backends filtering */ void z_log_runtime_filters_init(void) { /* * Initialize aggregated runtime filter levels (no backends are * attached yet, so leave backend slots in each dynamic filter set * alone for now). * * Each log source's aggregated runtime level is set to match its * compile-time level. When backends are attached later on in * log_init(), they'll be initialized to the same value. */ for (int i = 0; i < log_sources_count(); i++) { uint32_t *filters = log_dynamic_filters_get(i); uint8_t level = log_compiled_level_get(i); LOG_FILTER_SLOT_SET(filters, LOG_FILTER_AGGR_SLOT_IDX, level); } } uint32_t log_src_cnt_get(uint32_t domain_id) { return log_sources_count(); } const char *log_source_name_get(uint32_t domain_id, uint32_t src_id) { return src_id < log_sources_count() ? log_name_get(src_id) : NULL; } static uint32_t max_filter_get(uint32_t filters) { uint32_t max_filter = LOG_LEVEL_NONE; int first_slot = LOG_FILTER_FIRST_BACKEND_SLOT_IDX; int i; for (i = first_slot; i < LOG_FILTERS_NUM_OF_SLOTS; i++) { uint32_t tmp_filter = LOG_FILTER_SLOT_GET(&filters, i); if (tmp_filter > max_filter) { max_filter = tmp_filter; } } return max_filter; } uint32_t z_impl_log_filter_set(struct log_backend const *const backend, uint32_t domain_id, int16_t source_id, uint32_t level) { __ASSERT_NO_MSG(source_id < log_sources_count()); if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) { uint32_t new_aggr_filter; uint32_t *filters = log_dynamic_filters_get(source_id); if (backend == NULL) { struct log_backend const *iter_backend; uint32_t max = 0U; uint32_t current; for (int i = 0; i < log_backend_count_get(); i++) { iter_backend = log_backend_get(i); current = log_filter_set(iter_backend, domain_id, source_id, level); max = MAX(current, max); } level = max; } else { uint32_t max = log_filter_get(backend, domain_id, source_id, false); level = MIN(level, max); LOG_FILTER_SLOT_SET(filters, log_backend_id_get(backend), level); /* Once current backend filter is updated recalculate * aggregated maximal level */ new_aggr_filter = max_filter_get(*filters); LOG_FILTER_SLOT_SET(filters, LOG_FILTER_AGGR_SLOT_IDX, new_aggr_filter); } } return level; } #ifdef CONFIG_USERSPACE uint32_t z_vrfy_log_filter_set(struct log_backend const *const backend, uint32_t domain_id, int16_t src_id, uint32_t level) { Z_OOPS(Z_SYSCALL_VERIFY_MSG(backend == NULL, "Setting per-backend filters from user mode is not supported")); Z_OOPS(Z_SYSCALL_VERIFY_MSG(domain_id == CONFIG_LOG_DOMAIN_ID, "Invalid log domain_id")); Z_OOPS(Z_SYSCALL_VERIFY_MSG(src_id < log_sources_count(), "Invalid log source id")); Z_OOPS(Z_SYSCALL_VERIFY_MSG( (level <= LOG_LEVEL_DBG), "Invalid log level")); return z_impl_log_filter_set(NULL, domain_id, src_id, level); } #include #endif static void backend_filter_set(struct log_backend const *const backend, uint32_t level) { if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) { for (int i = 0; i < log_sources_count(); i++) { log_filter_set(backend, CONFIG_LOG_DOMAIN_ID, i, level); } } } void log_backend_enable(struct log_backend const *const backend, void *ctx, uint32_t level) { /* As first slot in filtering mask is reserved, backend ID has offset.*/ uint32_t id = LOG_FILTER_FIRST_BACKEND_SLOT_IDX; id += backend - log_backend_get(0); log_backend_id_set(backend, id); backend_filter_set(backend, level); log_backend_activate(backend, ctx); z_log_notify_backend_enabled(); } void log_backend_disable(struct log_backend const *const backend) { log_backend_deactivate(backend); backend_filter_set(backend, LOG_LEVEL_NONE); } uint32_t log_filter_get(struct log_backend const *const backend, uint32_t domain_id, int16_t source_id, bool runtime) { __ASSERT_NO_MSG(source_id < log_sources_count()); if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && runtime) { if (source_id < 0) { return LOG_LEVEL_DBG; } uint32_t *filters = log_dynamic_filters_get(source_id); return LOG_FILTER_SLOT_GET(filters, log_backend_id_get(backend)); } return log_compiled_level_get(source_id); }