cps-vec-ns16550.S 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (C) 2015 Imagination Technologies
  3. * Author: Paul Burton <paul.burton@imgtec.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. */
  10. #include <asm/addrspace.h>
  11. #include <asm/asm.h>
  12. #include <asm/asm-offsets.h>
  13. #include <asm/mipsregs.h>
  14. #include <asm/regdef.h>
  15. #include <linux/serial_reg.h>
  16. #define UART_TX_OFS (UART_TX << CONFIG_MIPS_CPS_NS16550_SHIFT)
  17. #define UART_LSR_OFS (UART_LSR << CONFIG_MIPS_CPS_NS16550_SHIFT)
  18. /**
  19. * _mips_cps_putc() - write a character to the UART
  20. * @a0: ASCII character to write
  21. * @t9: UART base address
  22. */
  23. LEAF(_mips_cps_putc)
  24. 1: lw t0, UART_LSR_OFS(t9)
  25. andi t0, t0, UART_LSR_TEMT
  26. beqz t0, 1b
  27. sb a0, UART_TX_OFS(t9)
  28. jr ra
  29. END(_mips_cps_putc)
  30. /**
  31. * _mips_cps_puts() - write a string to the UART
  32. * @a0: pointer to NULL-terminated ASCII string
  33. * @t9: UART base address
  34. *
  35. * Write a null-terminated ASCII string to the UART.
  36. */
  37. NESTED(_mips_cps_puts, 0, ra)
  38. move s7, ra
  39. move s6, a0
  40. 1: lb a0, 0(s6)
  41. beqz a0, 2f
  42. jal _mips_cps_putc
  43. PTR_ADDIU s6, s6, 1
  44. b 1b
  45. 2: jr s7
  46. END(_mips_cps_puts)
  47. /**
  48. * _mips_cps_putx4 - write a 4b hex value to the UART
  49. * @a0: the 4b value to write to the UART
  50. * @t9: UART base address
  51. *
  52. * Write a single hexadecimal character to the UART.
  53. */
  54. NESTED(_mips_cps_putx4, 0, ra)
  55. andi a0, a0, 0xf
  56. li t0, '0'
  57. blt a0, 10, 1f
  58. li t0, 'a'
  59. addiu a0, a0, -10
  60. 1: addu a0, a0, t0
  61. b _mips_cps_putc
  62. END(_mips_cps_putx4)
  63. /**
  64. * _mips_cps_putx8 - write an 8b hex value to the UART
  65. * @a0: the 8b value to write to the UART
  66. * @t9: UART base address
  67. *
  68. * Write an 8 bit value (ie. 2 hexadecimal characters) to the UART.
  69. */
  70. NESTED(_mips_cps_putx8, 0, ra)
  71. move s3, ra
  72. move s2, a0
  73. srl a0, a0, 4
  74. jal _mips_cps_putx4
  75. move a0, s2
  76. move ra, s3
  77. b _mips_cps_putx4
  78. END(_mips_cps_putx8)
  79. /**
  80. * _mips_cps_putx16 - write a 16b hex value to the UART
  81. * @a0: the 16b value to write to the UART
  82. * @t9: UART base address
  83. *
  84. * Write a 16 bit value (ie. 4 hexadecimal characters) to the UART.
  85. */
  86. NESTED(_mips_cps_putx16, 0, ra)
  87. move s5, ra
  88. move s4, a0
  89. srl a0, a0, 8
  90. jal _mips_cps_putx8
  91. move a0, s4
  92. move ra, s5
  93. b _mips_cps_putx8
  94. END(_mips_cps_putx16)
  95. /**
  96. * _mips_cps_putx32 - write a 32b hex value to the UART
  97. * @a0: the 32b value to write to the UART
  98. * @t9: UART base address
  99. *
  100. * Write a 32 bit value (ie. 8 hexadecimal characters) to the UART.
  101. */
  102. NESTED(_mips_cps_putx32, 0, ra)
  103. move s7, ra
  104. move s6, a0
  105. srl a0, a0, 16
  106. jal _mips_cps_putx16
  107. move a0, s6
  108. move ra, s7
  109. b _mips_cps_putx16
  110. END(_mips_cps_putx32)
  111. #ifdef CONFIG_64BIT
  112. /**
  113. * _mips_cps_putx64 - write a 64b hex value to the UART
  114. * @a0: the 64b value to write to the UART
  115. * @t9: UART base address
  116. *
  117. * Write a 64 bit value (ie. 16 hexadecimal characters) to the UART.
  118. */
  119. NESTED(_mips_cps_putx64, 0, ra)
  120. move sp, ra
  121. move s8, a0
  122. dsrl32 a0, a0, 0
  123. jal _mips_cps_putx32
  124. move a0, s8
  125. move ra, sp
  126. b _mips_cps_putx32
  127. END(_mips_cps_putx64)
  128. #define _mips_cps_putxlong _mips_cps_putx64
  129. #else /* !CONFIG_64BIT */
  130. #define _mips_cps_putxlong _mips_cps_putx32
  131. #endif /* !CONFIG_64BIT */
  132. /**
  133. * mips_cps_bev_dump() - dump relevant exception state to UART
  134. * @a0: pointer to NULL-terminated ASCII string naming the exception
  135. *
  136. * Write information that may be useful in debugging an exception to the
  137. * UART configured by CONFIG_MIPS_CPS_NS16550_*. As this BEV exception
  138. * will only be run if something goes horribly wrong very early during
  139. * the bringup of a core and it is very likely to be unsafe to perform
  140. * memory accesses at that point (cache state indeterminate, EVA may not
  141. * be configured, coherence may be disabled) let alone have a stack,
  142. * this is all written in assembly using only registers & unmapped
  143. * uncached access to the UART registers.
  144. */
  145. LEAF(mips_cps_bev_dump)
  146. move s0, ra
  147. move s1, a0
  148. li t9, CKSEG1ADDR(CONFIG_MIPS_CPS_NS16550_BASE)
  149. PTR_LA a0, str_newline
  150. jal _mips_cps_puts
  151. PTR_LA a0, str_bev
  152. jal _mips_cps_puts
  153. move a0, s1
  154. jal _mips_cps_puts
  155. PTR_LA a0, str_newline
  156. jal _mips_cps_puts
  157. PTR_LA a0, str_newline
  158. jal _mips_cps_puts
  159. #define DUMP_COP0_REG(reg, name, sz, _mfc0) \
  160. PTR_LA a0, 8f; \
  161. jal _mips_cps_puts; \
  162. _mfc0 a0, reg; \
  163. jal _mips_cps_putx##sz; \
  164. PTR_LA a0, str_newline; \
  165. jal _mips_cps_puts; \
  166. TEXT(name)
  167. DUMP_COP0_REG(CP0_CAUSE, "Cause: 0x", 32, mfc0)
  168. DUMP_COP0_REG(CP0_STATUS, "Status: 0x", 32, mfc0)
  169. DUMP_COP0_REG(CP0_EBASE, "EBase: 0x", long, MFC0)
  170. DUMP_COP0_REG(CP0_BADVADDR, "BadVAddr: 0x", long, MFC0)
  171. DUMP_COP0_REG(CP0_BADINSTR, "BadInstr: 0x", 32, mfc0)
  172. PTR_LA a0, str_newline
  173. jal _mips_cps_puts
  174. jr s0
  175. END(mips_cps_bev_dump)
  176. .pushsection .data
  177. str_bev: .asciiz "BEV Exception: "
  178. str_newline: .asciiz "\r\n"
  179. .popsection