dcc_console.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (c) 2015-2022, Xilinx Inc.
  3. * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  4. * Written by Michal Simek.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are met:
  10. *
  11. * Redistributions of source code must retain the above copyright notice, this
  12. * list of conditions and the following disclaimer.
  13. *
  14. * Redistributions in binary form must reproduce the above copyright notice,
  15. * this list of conditions and the following disclaimer in the documentation
  16. * and/or other materials provided with the distribution.
  17. *
  18. * Neither the name of ARM nor the names of its contributors may be used
  19. * to endorse or promote products derived from this software without specific
  20. * prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <errno.h>
  35. #include <stddef.h>
  36. #include <arch_helpers.h>
  37. #include <drivers/arm/dcc.h>
  38. #include <drivers/console.h>
  39. #include <drivers/delay_timer.h>
  40. #include <lib/mmio.h>
  41. /* DCC Status Bits */
  42. #define DCC_STATUS_RX BIT(30)
  43. #define DCC_STATUS_TX BIT(29)
  44. #define TIMEOUT_COUNT_US U(0x10624)
  45. struct dcc_console {
  46. console_t console;
  47. };
  48. static inline uint32_t __dcc_getstatus(void)
  49. {
  50. return read_mdccsr_el0();
  51. }
  52. #if ENABLE_CONSOLE_GETC
  53. static inline char __dcc_getchar(void)
  54. {
  55. char c;
  56. c = read_dbgdtrrx_el0();
  57. return c;
  58. }
  59. #endif
  60. static inline void __dcc_putchar(char c)
  61. {
  62. /*
  63. * The typecast is to make absolutely certain that 'c' is
  64. * zero-extended.
  65. */
  66. write_dbgdtrtx_el0((unsigned char)c);
  67. }
  68. static int32_t dcc_status_timeout(uint32_t mask)
  69. {
  70. const unsigned int timeout_count = TIMEOUT_COUNT_US;
  71. uint64_t timeout;
  72. unsigned int status;
  73. timeout = timeout_init_us(timeout_count);
  74. do {
  75. status = (__dcc_getstatus() & mask);
  76. if (timeout_elapsed(timeout)) {
  77. return -ETIMEDOUT;
  78. }
  79. } while ((status != 0U));
  80. return 0;
  81. }
  82. static int32_t dcc_console_putc(int32_t ch, struct console *console)
  83. {
  84. unsigned int status;
  85. status = dcc_status_timeout(DCC_STATUS_TX);
  86. if (status != 0U) {
  87. return status;
  88. }
  89. __dcc_putchar(ch);
  90. return ch;
  91. }
  92. #if ENABLE_CONSOLE_GETC
  93. static int32_t dcc_console_getc(struct console *console)
  94. {
  95. unsigned int status;
  96. status = dcc_status_timeout(DCC_STATUS_RX);
  97. if (status != 0U) {
  98. return status;
  99. }
  100. return __dcc_getchar();
  101. }
  102. #endif
  103. /**
  104. * dcc_console_flush() - Function to force a write of all buffered data
  105. * that hasn't been output.
  106. * @console Console struct
  107. *
  108. */
  109. static void dcc_console_flush(struct console *console)
  110. {
  111. unsigned int status;
  112. status = dcc_status_timeout(DCC_STATUS_TX);
  113. if (status != 0U) {
  114. return;
  115. }
  116. }
  117. static struct dcc_console dcc_console = {
  118. .console = {
  119. .flags = CONSOLE_FLAG_BOOT |
  120. CONSOLE_FLAG_RUNTIME |
  121. CONSOLE_FLAG_CRASH,
  122. .putc = dcc_console_putc,
  123. #if ENABLE_CONSOLE_GETC
  124. .getc = dcc_console_getc,
  125. #endif
  126. .flush = dcc_console_flush,
  127. },
  128. };
  129. int console_dcc_register(console_t *console)
  130. {
  131. memcpy(console, &dcc_console.console, sizeof(console_t));
  132. return console_register(console);
  133. }
  134. void console_dcc_unregister(console_t *console)
  135. {
  136. dcc_console_flush(console);
  137. (void)console_unregister(console);
  138. }