log_mgmt.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (c) 2021 Nordic Semiconductor ASA
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <logging/log_core.h>
  7. #include <logging/log_ctrl.h>
  8. #include <syscall_handler.h>
  9. /* Implementation of functions related to controlling logging sources and backends:
  10. * - getting/setting source details like name, filtering
  11. * - controlling backends filtering
  12. */
  13. void z_log_runtime_filters_init(void)
  14. {
  15. /*
  16. * Initialize aggregated runtime filter levels (no backends are
  17. * attached yet, so leave backend slots in each dynamic filter set
  18. * alone for now).
  19. *
  20. * Each log source's aggregated runtime level is set to match its
  21. * compile-time level. When backends are attached later on in
  22. * log_init(), they'll be initialized to the same value.
  23. */
  24. for (int i = 0; i < log_sources_count(); i++) {
  25. uint32_t *filters = log_dynamic_filters_get(i);
  26. uint8_t level = log_compiled_level_get(i);
  27. LOG_FILTER_SLOT_SET(filters,
  28. LOG_FILTER_AGGR_SLOT_IDX,
  29. level);
  30. }
  31. }
  32. uint32_t log_src_cnt_get(uint32_t domain_id)
  33. {
  34. return log_sources_count();
  35. }
  36. const char *log_source_name_get(uint32_t domain_id, uint32_t src_id)
  37. {
  38. return src_id < log_sources_count() ? log_name_get(src_id) : NULL;
  39. }
  40. static uint32_t max_filter_get(uint32_t filters)
  41. {
  42. uint32_t max_filter = LOG_LEVEL_NONE;
  43. int first_slot = LOG_FILTER_FIRST_BACKEND_SLOT_IDX;
  44. int i;
  45. for (i = first_slot; i < LOG_FILTERS_NUM_OF_SLOTS; i++) {
  46. uint32_t tmp_filter = LOG_FILTER_SLOT_GET(&filters, i);
  47. if (tmp_filter > max_filter) {
  48. max_filter = tmp_filter;
  49. }
  50. }
  51. return max_filter;
  52. }
  53. uint32_t z_impl_log_filter_set(struct log_backend const *const backend,
  54. uint32_t domain_id, int16_t source_id,
  55. uint32_t level)
  56. {
  57. __ASSERT_NO_MSG(source_id < log_sources_count());
  58. if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
  59. uint32_t new_aggr_filter;
  60. uint32_t *filters = log_dynamic_filters_get(source_id);
  61. if (backend == NULL) {
  62. struct log_backend const *iter_backend;
  63. uint32_t max = 0U;
  64. uint32_t current;
  65. for (int i = 0; i < log_backend_count_get(); i++) {
  66. iter_backend = log_backend_get(i);
  67. current = log_filter_set(iter_backend,
  68. domain_id,
  69. source_id, level);
  70. max = MAX(current, max);
  71. }
  72. level = max;
  73. } else {
  74. uint32_t max = log_filter_get(backend, domain_id,
  75. source_id, false);
  76. level = MIN(level, max);
  77. LOG_FILTER_SLOT_SET(filters,
  78. log_backend_id_get(backend),
  79. level);
  80. /* Once current backend filter is updated recalculate
  81. * aggregated maximal level
  82. */
  83. new_aggr_filter = max_filter_get(*filters);
  84. LOG_FILTER_SLOT_SET(filters,
  85. LOG_FILTER_AGGR_SLOT_IDX,
  86. new_aggr_filter);
  87. }
  88. }
  89. return level;
  90. }
  91. #ifdef CONFIG_USERSPACE
  92. uint32_t z_vrfy_log_filter_set(struct log_backend const *const backend,
  93. uint32_t domain_id,
  94. int16_t src_id,
  95. uint32_t level)
  96. {
  97. Z_OOPS(Z_SYSCALL_VERIFY_MSG(backend == NULL,
  98. "Setting per-backend filters from user mode is not supported"));
  99. Z_OOPS(Z_SYSCALL_VERIFY_MSG(domain_id == CONFIG_LOG_DOMAIN_ID,
  100. "Invalid log domain_id"));
  101. Z_OOPS(Z_SYSCALL_VERIFY_MSG(src_id < log_sources_count(),
  102. "Invalid log source id"));
  103. Z_OOPS(Z_SYSCALL_VERIFY_MSG(
  104. (level <= LOG_LEVEL_DBG),
  105. "Invalid log level"));
  106. return z_impl_log_filter_set(NULL, domain_id, src_id, level);
  107. }
  108. #include <syscalls/log_filter_set_mrsh.c>
  109. #endif
  110. static void backend_filter_set(struct log_backend const *const backend,
  111. uint32_t level)
  112. {
  113. if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
  114. for (int i = 0; i < log_sources_count(); i++) {
  115. log_filter_set(backend, CONFIG_LOG_DOMAIN_ID, i, level);
  116. }
  117. }
  118. }
  119. void log_backend_enable(struct log_backend const *const backend,
  120. void *ctx,
  121. uint32_t level)
  122. {
  123. /* As first slot in filtering mask is reserved, backend ID has offset.*/
  124. uint32_t id = LOG_FILTER_FIRST_BACKEND_SLOT_IDX;
  125. id += backend - log_backend_get(0);
  126. log_backend_id_set(backend, id);
  127. backend_filter_set(backend, level);
  128. log_backend_activate(backend, ctx);
  129. z_log_notify_backend_enabled();
  130. }
  131. void log_backend_disable(struct log_backend const *const backend)
  132. {
  133. log_backend_deactivate(backend);
  134. backend_filter_set(backend, LOG_LEVEL_NONE);
  135. }
  136. uint32_t log_filter_get(struct log_backend const *const backend,
  137. uint32_t domain_id, int16_t source_id, bool runtime)
  138. {
  139. __ASSERT_NO_MSG(source_id < log_sources_count());
  140. if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && runtime) {
  141. if (source_id < 0) {
  142. return LOG_LEVEL_DBG;
  143. }
  144. uint32_t *filters = log_dynamic_filters_get(source_id);
  145. return LOG_FILTER_SLOT_GET(filters,
  146. log_backend_id_get(backend));
  147. }
  148. return log_compiled_level_get(source_id);
  149. }