gdb-io.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* gdb-io.c: FR403 GDB stub I/O
  2. *
  3. * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <linux/string.h>
  12. #include <linux/kernel.h>
  13. #include <linux/signal.h>
  14. #include <linux/sched.h>
  15. #include <linux/mm.h>
  16. #include <linux/console.h>
  17. #include <linux/init.h>
  18. #include <linux/serial_reg.h>
  19. #include <asm/pgtable.h>
  20. #include <asm/irc-regs.h>
  21. #include <asm/timer-regs.h>
  22. #include <asm/gdb-stub.h>
  23. #include "gdb-io.h"
  24. #ifdef CONFIG_GDBSTUB_UART0
  25. #define __UART(X) (*(volatile uint8_t *)(UART0_BASE + (UART_##X)))
  26. #define __UART_IRR_NMI 0xff0f0000
  27. #else /* CONFIG_GDBSTUB_UART1 */
  28. #define __UART(X) (*(volatile uint8_t *)(UART1_BASE + (UART_##X)))
  29. #define __UART_IRR_NMI 0xfff00000
  30. #endif
  31. #define LSR_WAIT_FOR(STATE) \
  32. do { \
  33. gdbstub_do_rx(); \
  34. } while (!(__UART(LSR) & UART_LSR_##STATE))
  35. #define FLOWCTL_QUERY(LINE) ({ __UART(MSR) & UART_MSR_##LINE; })
  36. #define FLOWCTL_CLEAR(LINE) do { __UART(MCR) &= ~UART_MCR_##LINE; mb(); } while (0)
  37. #define FLOWCTL_SET(LINE) do { __UART(MCR) |= UART_MCR_##LINE; mb(); } while (0)
  38. #define FLOWCTL_WAIT_FOR(LINE) \
  39. do { \
  40. gdbstub_do_rx(); \
  41. } while(!FLOWCTL_QUERY(LINE))
  42. /*****************************************************************************/
  43. /*
  44. * initialise the GDB stub
  45. * - called with PSR.ET==0, so can't incur external interrupts
  46. */
  47. void gdbstub_io_init(void)
  48. {
  49. /* set up the serial port */
  50. __UART(LCR) = UART_LCR_WLEN8; /* 1N8 */
  51. __UART(FCR) =
  52. UART_FCR_ENABLE_FIFO |
  53. UART_FCR_CLEAR_RCVR |
  54. UART_FCR_CLEAR_XMIT |
  55. UART_FCR_TRIGGER_1;
  56. FLOWCTL_CLEAR(DTR);
  57. FLOWCTL_SET(RTS);
  58. // gdbstub_set_baud(115200);
  59. /* we want to get serial receive interrupts */
  60. __UART(IER) = UART_IER_RDI | UART_IER_RLSI;
  61. mb();
  62. __set_IRR(6, __UART_IRR_NMI); /* map ERRs and UARTx to NMI */
  63. } /* end gdbstub_io_init() */
  64. /*****************************************************************************/
  65. /*
  66. * set up the GDB stub serial port baud rate timers
  67. */
  68. void gdbstub_set_baud(unsigned baud)
  69. {
  70. unsigned value, high, low;
  71. u8 lcr;
  72. /* work out the divisor to give us the nearest higher baud rate */
  73. value = __serial_clock_speed_HZ / 16 / baud;
  74. /* determine the baud rate range */
  75. high = __serial_clock_speed_HZ / 16 / value;
  76. low = __serial_clock_speed_HZ / 16 / (value + 1);
  77. /* pick the nearest bound */
  78. if (low + (high - low) / 2 > baud)
  79. value++;
  80. lcr = __UART(LCR);
  81. __UART(LCR) |= UART_LCR_DLAB;
  82. mb();
  83. __UART(DLL) = value & 0xff;
  84. __UART(DLM) = (value >> 8) & 0xff;
  85. mb();
  86. __UART(LCR) = lcr;
  87. mb();
  88. } /* end gdbstub_set_baud() */
  89. /*****************************************************************************/
  90. /*
  91. * receive characters into the receive FIFO
  92. */
  93. void gdbstub_do_rx(void)
  94. {
  95. unsigned ix, nix;
  96. ix = gdbstub_rx_inp;
  97. while (__UART(LSR) & UART_LSR_DR) {
  98. nix = (ix + 2) & 0xfff;
  99. if (nix == gdbstub_rx_outp)
  100. break;
  101. gdbstub_rx_buffer[ix++] = __UART(LSR);
  102. gdbstub_rx_buffer[ix++] = __UART(RX);
  103. ix = nix;
  104. }
  105. gdbstub_rx_inp = ix;
  106. __clr_RC(15);
  107. __clr_IRL();
  108. } /* end gdbstub_do_rx() */
  109. /*****************************************************************************/
  110. /*
  111. * wait for a character to come from the debugger
  112. */
  113. int gdbstub_rx_char(unsigned char *_ch, int nonblock)
  114. {
  115. unsigned ix;
  116. u8 ch, st;
  117. *_ch = 0xff;
  118. if (gdbstub_rx_unget) {
  119. *_ch = gdbstub_rx_unget;
  120. gdbstub_rx_unget = 0;
  121. return 0;
  122. }
  123. try_again:
  124. gdbstub_do_rx();
  125. /* pull chars out of the buffer */
  126. ix = gdbstub_rx_outp;
  127. if (ix == gdbstub_rx_inp) {
  128. if (nonblock)
  129. return -EAGAIN;
  130. //watchdog_alert_counter = 0;
  131. goto try_again;
  132. }
  133. st = gdbstub_rx_buffer[ix++];
  134. ch = gdbstub_rx_buffer[ix++];
  135. gdbstub_rx_outp = ix & 0x00000fff;
  136. if (st & UART_LSR_BI) {
  137. gdbstub_proto("### GDB Rx Break Detected ###\n");
  138. return -EINTR;
  139. }
  140. else if (st & (UART_LSR_FE|UART_LSR_OE|UART_LSR_PE)) {
  141. gdbstub_io("### GDB Rx Error (st=%02x) ###\n",st);
  142. return -EIO;
  143. }
  144. else {
  145. gdbstub_io("### GDB Rx %02x (st=%02x) ###\n",ch,st);
  146. *_ch = ch & 0x7f;
  147. return 0;
  148. }
  149. } /* end gdbstub_rx_char() */
  150. /*****************************************************************************/
  151. /*
  152. * send a character to the debugger
  153. */
  154. void gdbstub_tx_char(unsigned char ch)
  155. {
  156. FLOWCTL_SET(DTR);
  157. LSR_WAIT_FOR(THRE);
  158. // FLOWCTL_WAIT_FOR(CTS);
  159. if (ch == 0x0a) {
  160. __UART(TX) = 0x0d;
  161. mb();
  162. LSR_WAIT_FOR(THRE);
  163. // FLOWCTL_WAIT_FOR(CTS);
  164. }
  165. __UART(TX) = ch;
  166. mb();
  167. FLOWCTL_CLEAR(DTR);
  168. } /* end gdbstub_tx_char() */
  169. /*****************************************************************************/
  170. /*
  171. * send a character to the debugger
  172. */
  173. void gdbstub_tx_flush(void)
  174. {
  175. LSR_WAIT_FOR(TEMT);
  176. LSR_WAIT_FOR(THRE);
  177. FLOWCTL_CLEAR(DTR);
  178. } /* end gdbstub_tx_flush() */