log_backend_xtensa_sim.c 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (c) 2019 Intel Corporation Inc.
  3. * Copyright (c) 2018 Nordic Semiconductor ASA
  4. * Copyright (c) 2018 Intel Corporation
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. */
  8. #include <stdio.h>
  9. #include <stddef.h>
  10. #include <logging/log_backend.h>
  11. #include <logging/log_core.h>
  12. #include <logging/log_msg.h>
  13. #include <logging/log_output.h>
  14. #include <logging/log_backend_std.h>
  15. #include <xtensa/simcall.h>
  16. #define CHAR_BUF_SIZE (IS_ENABLED(CONFIG_LOG_IMMEDIATE) ? \
  17. 1 : CONFIG_LOG_BACKEND_XTENSA_OUTPUT_BUFFER_SIZE)
  18. static uint8_t xtensa_log_buf[CHAR_BUF_SIZE];
  19. static int char_out(uint8_t *data, size_t length, void *ctx)
  20. {
  21. register int a2 __asm__ ("a2") = SYS_write;
  22. register int a3 __asm__ ("a3") = 1;
  23. register int a4 __asm__ ("a4") = (int) data;
  24. register int a5 __asm__ ("a5") = length;
  25. __asm__ volatile("simcall"
  26. : "=a"(a2), "=a"(a3)
  27. : "a"(a2), "a"(a3), "a"(a4), "a"(a5));
  28. return length;
  29. }
  30. LOG_OUTPUT_DEFINE(log_output_xsim, char_out,
  31. xtensa_log_buf, sizeof(xtensa_log_buf));
  32. static void put(const struct log_backend *const backend,
  33. struct log_msg *msg)
  34. {
  35. log_backend_std_put(&log_output_xsim, 0, msg);
  36. }
  37. static void process(const struct log_backend *const backend,
  38. union log_msg2_generic *msg)
  39. {
  40. uint32_t flags = log_backend_std_get_flags();
  41. log_output_msg2_process(&log_output_xsim, &msg->log, flags);
  42. }
  43. static void panic(struct log_backend const *const backend)
  44. {
  45. log_backend_std_panic(&log_output_xsim);
  46. }
  47. static void dropped(const struct log_backend *const backend, uint32_t cnt)
  48. {
  49. ARG_UNUSED(backend);
  50. log_backend_std_dropped(&log_output_xsim, cnt);
  51. }
  52. static void sync_string(const struct log_backend *const backend,
  53. struct log_msg_ids src_level, uint32_t timestamp,
  54. const char *fmt, va_list ap)
  55. {
  56. log_backend_std_sync_string(&log_output_xsim, 0, src_level,
  57. timestamp, fmt, ap);
  58. }
  59. static void sync_hexdump(const struct log_backend *const backend,
  60. struct log_msg_ids src_level, uint32_t timestamp,
  61. const char *metadata, const uint8_t *data, uint32_t length)
  62. {
  63. log_backend_std_sync_hexdump(&log_output_xsim, 0, src_level,
  64. timestamp, metadata, data, length);
  65. }
  66. const struct log_backend_api log_backend_xtensa_sim_api = {
  67. .process = IS_ENABLED(CONFIG_LOG2) ? process : NULL,
  68. .put = IS_ENABLED(CONFIG_LOG_MODE_DEFERRED) ? put : NULL,
  69. .put_sync_string = IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE) ?
  70. sync_string : NULL,
  71. .put_sync_hexdump = IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE) ?
  72. sync_hexdump : NULL,
  73. .panic = panic,
  74. .dropped = IS_ENABLED(CONFIG_LOG_IMMEDIATE) ? NULL : dropped,
  75. };
  76. LOG_BACKEND_DEFINE(log_backend_xtensa_sim, log_backend_xtensa_sim_api, true);