gdb_hook.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * Carsten Langgaard, carstenl@mips.com
  3. * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
  4. *
  5. * This program is free software; you can distribute it and/or modify it
  6. * under the terms of the GNU General Public License (Version 2) as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. * for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  17. *
  18. * This is the interface to the remote debugger stub.
  19. */
  20. #include <linux/types.h>
  21. #include <linux/serial.h>
  22. #include <linux/serialP.h>
  23. #include <linux/serial_reg.h>
  24. #include <asm/serial.h>
  25. #include <asm/io.h>
  26. static struct serial_state rs_table[RS_TABLE_SIZE] = {
  27. SERIAL_PORT_DFNS /* Defined in serial.h */
  28. };
  29. static struct async_struct kdb_port_info = {0};
  30. int (*generic_putDebugChar)(char);
  31. char (*generic_getDebugChar)(void);
  32. static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
  33. {
  34. return inb(info->port + offset);
  35. }
  36. static __inline__ void serial_out(struct async_struct *info, int offset,
  37. int value)
  38. {
  39. outb(value, info->port+offset);
  40. }
  41. int rs_kgdb_hook(int tty_no, int speed) {
  42. int t;
  43. struct serial_state *ser = &rs_table[tty_no];
  44. kdb_port_info.state = ser;
  45. kdb_port_info.magic = SERIAL_MAGIC;
  46. kdb_port_info.port = ser->port;
  47. kdb_port_info.flags = ser->flags;
  48. /*
  49. * Clear all interrupts
  50. */
  51. serial_in(&kdb_port_info, UART_LSR);
  52. serial_in(&kdb_port_info, UART_RX);
  53. serial_in(&kdb_port_info, UART_IIR);
  54. serial_in(&kdb_port_info, UART_MSR);
  55. /*
  56. * Now, initialize the UART
  57. */
  58. serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
  59. if (kdb_port_info.flags & ASYNC_FOURPORT) {
  60. kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
  61. t = UART_MCR_DTR | UART_MCR_OUT1;
  62. } else {
  63. kdb_port_info.MCR
  64. = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
  65. t = UART_MCR_DTR | UART_MCR_RTS;
  66. }
  67. kdb_port_info.MCR = t; /* no interrupts, please */
  68. serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
  69. /*
  70. * and set the speed of the serial port
  71. */
  72. if (speed == 0)
  73. speed = 9600;
  74. t = kdb_port_info.state->baud_base / speed;
  75. /* set DLAB */
  76. serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
  77. serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
  78. serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */
  79. /* reset DLAB */
  80. serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
  81. return speed;
  82. }
  83. int putDebugChar(char c)
  84. {
  85. return generic_putDebugChar(c);
  86. }
  87. char getDebugChar(void)
  88. {
  89. return generic_getDebugChar();
  90. }
  91. int rs_putDebugChar(char c)
  92. {
  93. if (!kdb_port_info.state) { /* need to init device first */
  94. return 0;
  95. }
  96. while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
  97. ;
  98. serial_out(&kdb_port_info, UART_TX, c);
  99. return 1;
  100. }
  101. char rs_getDebugChar(void)
  102. {
  103. if (!kdb_port_info.state) { /* need to init device first */
  104. return 0;
  105. }
  106. while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
  107. ;
  108. return serial_in(&kdb_port_info, UART_RX);
  109. }