gdb-io-serial.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* 16550 serial driver for gdbstub I/O
  2. *
  3. * Copyright (C) 2007 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 Licence
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the Licence, 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/nmi.h>
  19. #include <asm/pgtable.h>
  20. #include <asm/system.h>
  21. #include <asm/gdb-stub.h>
  22. #include <asm/exceptions.h>
  23. #include <asm/serial-regs.h>
  24. #include <unit/serial.h>
  25. #include <asm/smp.h>
  26. /*
  27. * initialise the GDB stub
  28. */
  29. void gdbstub_io_init(void)
  30. {
  31. u16 tmp;
  32. /* set up the serial port */
  33. GDBPORT_SERIAL_LCR = UART_LCR_WLEN8; /* 1N8 */
  34. GDBPORT_SERIAL_FCR = (UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
  35. UART_FCR_CLEAR_XMIT);
  36. FLOWCTL_CLEAR(DTR);
  37. FLOWCTL_SET(RTS);
  38. gdbstub_io_set_baud(115200);
  39. /* we want to get serial receive interrupts */
  40. XIRQxICR(GDBPORT_SERIAL_IRQ) = 0;
  41. tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
  42. #if CONFIG_GDBSTUB_IRQ_LEVEL == 0
  43. IVAR0 = EXCEP_IRQ_LEVEL0;
  44. #elif CONFIG_GDBSTUB_IRQ_LEVEL == 1
  45. IVAR1 = EXCEP_IRQ_LEVEL1;
  46. #elif CONFIG_GDBSTUB_IRQ_LEVEL == 2
  47. IVAR2 = EXCEP_IRQ_LEVEL2;
  48. #elif CONFIG_GDBSTUB_IRQ_LEVEL == 3
  49. IVAR3 = EXCEP_IRQ_LEVEL3;
  50. #elif CONFIG_GDBSTUB_IRQ_LEVEL == 4
  51. IVAR4 = EXCEP_IRQ_LEVEL4;
  52. #elif CONFIG_GDBSTUB_IRQ_LEVEL == 5
  53. IVAR5 = EXCEP_IRQ_LEVEL5;
  54. #else
  55. #error "Unknown irq level for gdbstub."
  56. #endif
  57. set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL),
  58. gdbstub_io_rx_handler);
  59. XIRQxICR(GDBPORT_SERIAL_IRQ) &= ~GxICR_REQUEST;
  60. XIRQxICR(GDBPORT_SERIAL_IRQ) =
  61. GxICR_ENABLE | NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL);
  62. tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
  63. GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI;
  64. /* permit level 0 IRQs to take place */
  65. arch_local_change_intr_mask_level(
  66. NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
  67. }
  68. /*
  69. * set up the GDB stub serial port baud rate timers
  70. */
  71. void gdbstub_io_set_baud(unsigned baud)
  72. {
  73. unsigned value;
  74. u8 lcr;
  75. value = 18432000 / 16 / baud;
  76. lcr = GDBPORT_SERIAL_LCR;
  77. GDBPORT_SERIAL_LCR |= UART_LCR_DLAB;
  78. GDBPORT_SERIAL_DLL = value & 0xff;
  79. GDBPORT_SERIAL_DLM = (value >> 8) & 0xff;
  80. GDBPORT_SERIAL_LCR = lcr;
  81. }
  82. /*
  83. * wait for a character to come from the debugger
  84. */
  85. int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
  86. {
  87. unsigned ix;
  88. u8 ch, st;
  89. #if defined(CONFIG_MN10300_WD_TIMER)
  90. int cpu;
  91. #endif
  92. *_ch = 0xff;
  93. if (gdbstub_rx_unget) {
  94. *_ch = gdbstub_rx_unget;
  95. gdbstub_rx_unget = 0;
  96. return 0;
  97. }
  98. try_again:
  99. /* pull chars out of the buffer */
  100. ix = gdbstub_rx_outp;
  101. barrier();
  102. if (ix == gdbstub_rx_inp) {
  103. if (nonblock)
  104. return -EAGAIN;
  105. #ifdef CONFIG_MN10300_WD_TIMER
  106. for (cpu = 0; cpu < NR_CPUS; cpu++)
  107. watchdog_alert_counter[cpu] = 0;
  108. #endif
  109. goto try_again;
  110. }
  111. ch = gdbstub_rx_buffer[ix++];
  112. st = gdbstub_rx_buffer[ix++];
  113. barrier();
  114. gdbstub_rx_outp = ix & 0x00000fff;
  115. if (st & UART_LSR_BI) {
  116. gdbstub_proto("### GDB Rx Break Detected ###\n");
  117. return -EINTR;
  118. } else if (st & (UART_LSR_FE | UART_LSR_OE | UART_LSR_PE)) {
  119. gdbstub_proto("### GDB Rx Error (st=%02x) ###\n", st);
  120. return -EIO;
  121. } else {
  122. gdbstub_proto("### GDB Rx %02x (st=%02x) ###\n", ch, st);
  123. *_ch = ch & 0x7f;
  124. return 0;
  125. }
  126. }
  127. /*
  128. * send a character to the debugger
  129. */
  130. void gdbstub_io_tx_char(unsigned char ch)
  131. {
  132. FLOWCTL_SET(DTR);
  133. LSR_WAIT_FOR(THRE);
  134. /* FLOWCTL_WAIT_FOR(CTS); */
  135. if (ch == 0x0a) {
  136. GDBPORT_SERIAL_TX = 0x0d;
  137. LSR_WAIT_FOR(THRE);
  138. /* FLOWCTL_WAIT_FOR(CTS); */
  139. }
  140. GDBPORT_SERIAL_TX = ch;
  141. FLOWCTL_CLEAR(DTR);
  142. }
  143. /*
  144. * send a character to the debugger
  145. */
  146. void gdbstub_io_tx_flush(void)
  147. {
  148. LSR_WAIT_FOR(TEMT);
  149. LSR_WAIT_FOR(THRE);
  150. FLOWCTL_CLEAR(DTR);
  151. }