udbg.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * NS16550 Serial Port (uart) debugging stuff.
  3.  *
  4.  * c 2001 PPC 64 Team, IBM Corp
  5.  *
  6.  * NOTE: I am trying to make this code avoid any static data references to
  7.  *  simplify debugging early boot.  We'll see how that goes...
  8.  *
  9.  * To use this call udbg_init() first.  It will init the uart to 9600 8N1.
  10.  * You may need to update the COM1 define if your uart is at a different addr.
  11.  *
  12.  *      This program is free software; you can redistribute it and/or
  13.  *      modify it under the terms of the GNU General Public License
  14.  *      as published by the Free Software Foundation; either version
  15.  *      2 of the License, or (at your option) any later version.
  16.  */
  17. #include <stdarg.h>
  18. #define WANT_PPCDBG_TAB /* Only defined here */
  19. #include <asm/ppcdebug.h>
  20. #include <asm/processor.h>
  21. #include <asm/naca.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/machdep.h>
  24. struct NS16550 {
  25. /* this struct must be packed */
  26. unsigned char rbr;  /* 0 */
  27. unsigned char ier;  /* 1 */
  28. unsigned char fcr;  /* 2 */
  29. unsigned char lcr;  /* 3 */
  30. unsigned char mcr;  /* 4 */
  31. unsigned char lsr;  /* 5 */
  32. unsigned char msr;  /* 6 */
  33. unsigned char scr;  /* 7 */
  34. };
  35. #define thr rbr
  36. #define iir fcr
  37. #define dll rbr
  38. #define dlm ier
  39. #define dlab lcr
  40. #define LSR_DR   0x01  /* Data ready */
  41. #define LSR_OE   0x02  /* Overrun */
  42. #define LSR_PE   0x04  /* Parity error */
  43. #define LSR_FE   0x08  /* Framing error */
  44. #define LSR_BI   0x10  /* Break */
  45. #define LSR_THRE 0x20  /* Xmit holding register empty */
  46. #define LSR_TEMT 0x40  /* Xmitter empty */
  47. #define LSR_ERR  0x80  /* Error */
  48. volatile struct NS16550 *udbg_comport;
  49. void
  50. udbg_init_uart(void *comport)
  51. {
  52. if (comport) {
  53. udbg_comport = (struct NS16550 *)comport;
  54. udbg_comport->lcr = 0x00; eieio();
  55. udbg_comport->ier = 0xFF; eieio();
  56. udbg_comport->ier = 0x00; eieio();
  57. udbg_comport->lcr = 0x80; eieio(); /* Access baud rate */
  58. udbg_comport->dll = 12;   eieio(); /* 1 = 115200,  2 = 57600, 3 = 38400, 12 = 9600 baud */
  59. udbg_comport->dlm = 0;    eieio(); /* dll >> 8 which should be zero for fast rates; */
  60. udbg_comport->lcr = 0x03; eieio(); /* 8 data, 1 stop, no parity */
  61. udbg_comport->mcr = 0x03; eieio(); /* RTS/DTR */
  62. udbg_comport->fcr = 0x07; eieio(); /* Clear & enable FIFOs */
  63. }
  64. }
  65. void
  66. udbg_putc(unsigned char c)
  67. {
  68. if ( udbg_comport ) {
  69. while ((udbg_comport->lsr & LSR_THRE) == 0)
  70. /* wait for idle */;
  71. udbg_comport->thr = c; eieio();
  72. if (c == 'n') {
  73. /* Also put a CR.  This is for convenience. */
  74. while ((udbg_comport->lsr & LSR_THRE) == 0)
  75. /* wait for idle */;
  76. udbg_comport->thr = 'r'; eieio();
  77. }
  78. } else if (naca->platform == PLATFORM_ISERIES_LPAR) {
  79. /* ToDo: switch this via ppc_md */
  80. printk("%c", c);
  81. }
  82. }
  83. int udbg_getc_poll(void)
  84. {
  85. if (udbg_comport) {
  86. if ((udbg_comport->lsr & LSR_DR) != 0)
  87. return udbg_comport->rbr;
  88. else
  89. return -1;
  90. }
  91. return -1;
  92. }
  93. unsigned char
  94. udbg_getc(void)
  95. {
  96. if ( udbg_comport ) {
  97. while ((udbg_comport->lsr & LSR_DR) == 0)
  98. /* wait for char */;
  99. return udbg_comport->rbr;
  100. }
  101. return 0;
  102. }
  103. void
  104. udbg_puts(const char *s)
  105. {
  106. if (ppc_md.udbg_putc) {
  107. char c;
  108. if (s && *s != '') {
  109. while ((c = *s++) != '')
  110. ppc_md.udbg_putc(c);
  111. } else {
  112. udbg_puts("NULL");
  113. }
  114. } else {
  115. printk("%s", s);
  116. }
  117. }
  118. int
  119. udbg_write(const char *s, int n)
  120. {
  121. int remain = n;
  122. char c;
  123. if (!ppc_md.udbg_putc)
  124. for (;;); /* stop here for cpuctl */
  125. if ( s && *s != '' ) {
  126. while ( (( c = *s++ ) != '') && (remain-- > 0)) {
  127. ppc_md.udbg_putc(c);
  128. }
  129. } else
  130. udbg_puts("NULL");
  131. return n - remain;
  132. }
  133. int
  134. udbg_read(char *buf, int buflen) {
  135. char c, *p = buf;
  136. int i;
  137. if (!ppc_md.udbg_putc)
  138. for (;;); /* stop here for cpuctl */
  139. for (i = 0; i < buflen; ++i) {
  140. do {
  141. c = ppc_md.udbg_getc();
  142. } while (c == 0x11 || c == 0x13);
  143. *p++ = c;
  144. }
  145. return i;
  146. }
  147. void
  148. udbg_console_write(struct console *con, const char *s, unsigned int n)
  149. {
  150. udbg_write(s, n);
  151. }
  152. void
  153. udbg_puthex(unsigned long val)
  154. {
  155. int i, nibbles = sizeof(val)*2;
  156. unsigned char buf[sizeof(val)*2+1];
  157. for (i = nibbles-1;  i >= 0;  i--) {
  158. buf[i] = (val & 0xf) + '0';
  159. if (buf[i] > '9')
  160.     buf[i] += ('a'-'0'-10);
  161. val >>= 4;
  162. }
  163. buf[nibbles] = '';
  164. udbg_puts(buf);
  165. }
  166. void
  167. udbg_printSP(const char *s)
  168. {
  169. if (naca->platform == PLATFORM_PSERIES) {
  170. unsigned long sp;
  171. asm("mr %0,1" : "=r" (sp) :);
  172. if (s)
  173. udbg_puts(s);
  174. udbg_puthex(sp);
  175. }
  176. }
  177. void
  178. udbg_printf(const char *fmt, ...)
  179. {
  180. unsigned char buf[256];
  181. va_list args;
  182. va_start(args, fmt);
  183. vsprintf(buf, fmt, args);
  184. udbg_puts(buf);
  185. va_end(args);
  186. }
  187. /* Special print used by PPCDBG() macro */
  188. void
  189. udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...)
  190. {
  191. unsigned long active_debugs = debug_flags & naca->debug_switch;
  192. if ( active_debugs ) {
  193. va_list ap;
  194. unsigned char buf[256];
  195. unsigned long i, len = 0;
  196. for(i=0; i < PPCDBG_NUM_FLAGS ;i++) {
  197. if (((1U << i) & active_debugs) && 
  198.     trace_names[i]) {
  199. len += strlen(trace_names[i]); 
  200. udbg_puts(trace_names[i]);
  201. break;
  202. }
  203. }
  204. sprintf(buf, " [%s]: ", current->comm);
  205. len += strlen(buf); 
  206. udbg_puts(buf);
  207. while(len < 18) {
  208. udbg_puts(" ");
  209. len++;
  210. }
  211. va_start(ap, fmt);
  212. vsprintf(buf, fmt, ap);
  213. udbg_puts(buf);
  214. va_end(ap);
  215. }
  216. }
  217. unsigned long
  218. udbg_ifdebug(unsigned long flags)
  219. {
  220. return (flags & naca->debug_switch);
  221. }