8250_console.S 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <asm_macros.S>
  7. #include <uart8250.h>
  8. .globl console_core_init
  9. .globl console_core_putc
  10. .globl console_core_getc
  11. .globl console_core_flush
  12. /* -----------------------------------------------
  13. * int console_core_init(unsigned long base_addr,
  14. * unsigned int uart_clk, unsigned int baud_rate)
  15. * Function to initialize the console without a
  16. * C Runtime to print debug information. This
  17. * function will be accessed by console_init and
  18. * crash reporting.
  19. * In: x0 - console base address
  20. * w1 - Uart clock in Hz
  21. * w2 - Baud rate
  22. * Out: return 1 on success else 0 on error
  23. * Clobber list : x1, x2, x3
  24. * -----------------------------------------------
  25. */
  26. func console_core_init
  27. /* Check the input base address */
  28. cbz x0, core_init_fail
  29. /* Check baud rate and uart clock for sanity */
  30. cbz w1, core_init_fail
  31. cbz w2, core_init_fail
  32. /* Disable interrupt */
  33. str wzr, [x0, #UART_IER]
  34. /* Force DTR and RTS to high */
  35. mov w3, #(UART_MCR_DTR | UART_MCR_RTS)
  36. str w3, [x0, #UART_MCR]
  37. /* Check high speed */
  38. movz w3, #:abs_g1:115200
  39. movk w3, #:abs_g0_nc:115200
  40. cmp w2, w3
  41. b.hi 1f
  42. /* Non high speed */
  43. lsl w2, w2, #4
  44. mov w3, wzr
  45. b 2f
  46. /* High speed */
  47. 1: lsl w2, w2, #2
  48. mov w3, #2
  49. /* Set high speed UART register */
  50. 2: str w3, [x0, #UART_HIGHSPEED]
  51. /* Calculate divisor */
  52. udiv w3, w1, w2 /* divisor = uartclk / (quot * baudrate) */
  53. msub w1, w3, w2, w1 /* remainder = uartclk % (quot * baudrate) */
  54. lsr w2, w2, #1
  55. cmp w1, w2
  56. cinc w3, w3, hs
  57. /* Set line configuration, access divisor latches */
  58. mov w1, #(UART_LCR_DLAB | UART_LCR_WLS_8)
  59. str w1, [x0, #UART_LCR]
  60. /* Set the divisor */
  61. and w1, w3, #0xff
  62. str w1, [x0, #UART_DLL]
  63. lsr w1, w3, #8
  64. and w1, w1, #0xff
  65. str w1, [x0, #UART_DLH]
  66. /* Hide the divisor latches */
  67. mov w1, #UART_LCR_WLS_8
  68. str w1, [x0, #UART_LCR]
  69. /* Enable FIFOs, and clear receive and transmit */
  70. mov w1, #(UART_FCR_FIFO_EN | UART_FCR_CLEAR_RCVR | \
  71. UART_FCR_CLEAR_XMIT)
  72. str w1, [x0, #UART_FCR]
  73. mov w0, #1
  74. ret
  75. core_init_fail:
  76. mov w0, wzr
  77. ret
  78. endfunc console_core_init
  79. /* --------------------------------------------------------
  80. * int console_core_putc(int c, unsigned long base_addr)
  81. * Function to output a character over the console. It
  82. * returns the character printed on success or -1 on error.
  83. * In : w0 - character to be printed
  84. * x1 - console base address
  85. * Out : return -1 on error else return character.
  86. * Clobber list : x2
  87. * --------------------------------------------------------
  88. */
  89. func console_core_putc
  90. /* Check the input parameter */
  91. cbz x1, putc_error
  92. /* Prepend '\r' to '\n' */
  93. cmp w0, #0xA
  94. b.ne 2f
  95. /* Check if the transmit FIFO is full */
  96. 1: ldr w2, [x1, #UART_LSR]
  97. and w2, w2, #UART_LSR_THRE
  98. cbz w2, 1b
  99. mov w2, #0xD
  100. str w2, [x1, #UART_THR]
  101. /* Check if the transmit FIFO is full */
  102. 2: ldr w2, [x1, #UART_LSR]
  103. and w2, w2, #UART_LSR_THRE
  104. cbz w2, 2b
  105. str w0, [x1, #UART_THR]
  106. ret
  107. putc_error:
  108. mov w0, #-1
  109. ret
  110. endfunc console_core_putc
  111. /* ---------------------------------------------
  112. * int console_core_getc(unsigned long base_addr)
  113. * Function to get a character from the console.
  114. * It returns the character grabbed on success
  115. * or -1 on error.
  116. * In : x0 - console base address
  117. * Clobber list : x0, x1
  118. * ---------------------------------------------
  119. */
  120. func console_core_getc
  121. cbz x0, getc_error
  122. /* Check if the receive FIFO is empty */
  123. 1: ldr w1, [x0, #UART_LSR]
  124. tbz w1, #UART_LSR_DR, 1b
  125. ldr w0, [x0, #UART_RBR]
  126. ret
  127. getc_error:
  128. mov w0, #-1
  129. ret
  130. endfunc console_core_getc
  131. /* ---------------------------------------------
  132. * void console_core_flush(uintptr_t base_addr)
  133. * Function to force a write of all buffered
  134. * data that hasn't been output.
  135. * In : x0 - console base address
  136. * Out : void.
  137. * Clobber list : x0, x1
  138. * ---------------------------------------------
  139. */
  140. func console_core_flush
  141. /* Placeholder */
  142. ret
  143. endfunc console_core_flush