cmd_log.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * (C) Copyright 2002
  3. * Detlev Zundel, DENX Software Engineering, dzu@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /*
  24. * Logbuffer handling routines
  25. */
  26. #include <common.h>
  27. #include <command.h>
  28. #include <devices.h>
  29. #include <logbuff.h>
  30. #if defined(CONFIG_LOGBUFFER)
  31. #define LOG_BUF_LEN (16384)
  32. #define LOG_BUF_MASK (LOG_BUF_LEN-1)
  33. /* Local prototypes */
  34. static void logbuff_putc (const char c);
  35. static void logbuff_puts (const char *s);
  36. static int logbuff_printk(const char *line);
  37. static char buf[1024];
  38. static unsigned console_loglevel = 3;
  39. static unsigned default_message_loglevel = 4;
  40. static unsigned long log_size;
  41. static unsigned char *log_buf=NULL;
  42. static unsigned long *ext_log_start, *ext_logged_chars;
  43. #define log_start (*ext_log_start)
  44. #define logged_chars (*ext_logged_chars)
  45. /* Forced by code, eh! */
  46. #define LOGBUFF_MAGIC 0xc0de4ced
  47. int drv_logbuff_init (void)
  48. {
  49. device_t logdev;
  50. int rc;
  51. /* Device initialization */
  52. memset (&logdev, 0, sizeof (logdev));
  53. strcpy (logdev.name, "logbuff");
  54. logdev.ext = 0; /* No extensions */
  55. logdev.flags = DEV_FLAGS_OUTPUT; /* Output only */
  56. logdev.putc = logbuff_putc; /* 'putc' function */
  57. logdev.puts = logbuff_puts; /* 'puts' function */
  58. rc = device_register (&logdev);
  59. return (rc == 0) ? 1 : rc;
  60. }
  61. static void logbuff_putc (const char c)
  62. {
  63. char buf[2];
  64. buf[0]=c;
  65. buf[1]='\0';
  66. logbuff_printk(buf);
  67. }
  68. static void logbuff_puts (const char *s)
  69. {
  70. char buf[512];
  71. sprintf(buf, "%s\n", s);
  72. logbuff_printk(buf);
  73. }
  74. void logbuff_log(char *msg)
  75. {
  76. DECLARE_GLOBAL_DATA_PTR;
  77. if (gd->flags & GD_FLG_RELOC) {
  78. logbuff_printk(msg);
  79. } else {
  80. puts(msg);
  81. }
  82. }
  83. void logbuff_reset (void)
  84. {
  85. char *s;
  86. unsigned long *ext_tag;
  87. if ((s = getenv ("logstart")) != NULL) {
  88. log_buf = (unsigned char *)simple_strtoul(s, NULL, 16);
  89. ext_tag=(unsigned long *)(log_buf)-3;
  90. ext_log_start=(unsigned long *)(log_buf)-2;
  91. ext_logged_chars=(unsigned long *)(log_buf)-1;
  92. // if (*ext_tag!=LOGBUFF_MAGIC) {
  93. logged_chars=log_start=0;
  94. *ext_tag=LOGBUFF_MAGIC;
  95. // }
  96. log_size=logged_chars;
  97. }
  98. }
  99. /*
  100. * Subroutine: do_log
  101. *
  102. * Description: Handler for 'log' command..
  103. *
  104. * Inputs: argv[1] contains the subcommand
  105. *
  106. * Return: None
  107. *
  108. */
  109. int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  110. {
  111. char *s;
  112. unsigned long i;
  113. if (log_buf==NULL) {
  114. printf ("No logbuffer defined! Set 'logstart' to use this feature.\n");
  115. return 1;
  116. }
  117. switch (argc) {
  118. case 2:
  119. if (strcmp(argv[1],"show") == 0) {
  120. for (i=0; i<logged_chars; i++) {
  121. s=log_buf+((log_start+i)&LOG_BUF_MASK);
  122. putc(*s);
  123. }
  124. return 0;
  125. } else if (strcmp(argv[1],"reset") == 0) {
  126. log_start=0;
  127. logged_chars=0;
  128. log_size=0;
  129. return 0;
  130. }
  131. printf ("Usage:\n%s\n", cmdtp->usage);
  132. return 1;
  133. case 3:
  134. if (strcmp(argv[1],"append") == 0) {
  135. logbuff_puts(argv[2]);
  136. return 0;
  137. }
  138. printf ("Usage:\n%s\n", cmdtp->usage);
  139. return 1;
  140. default:
  141. printf ("Usage:\n%s\n", cmdtp->usage);
  142. return 1;
  143. }
  144. }
  145. static int logbuff_printk(const char *line)
  146. {
  147. int i;
  148. char *msg, *p, *buf_end;
  149. int line_feed;
  150. static signed char msg_level = -1;
  151. strcpy(buf + 3, line);
  152. i = strlen(line);
  153. buf_end = buf + 3 + i;
  154. for (p = buf + 3; p < buf_end; p++) {
  155. msg = p;
  156. if (msg_level < 0) {
  157. if (
  158. p[0] != '<' ||
  159. p[1] < '0' ||
  160. p[1] > '7' ||
  161. p[2] != '>'
  162. ) {
  163. p -= 3;
  164. p[0] = '<';
  165. p[1] = default_message_loglevel + '0';
  166. p[2] = '>';
  167. } else
  168. msg += 3;
  169. msg_level = p[1] - '0';
  170. }
  171. line_feed = 0;
  172. for (; p < buf_end; p++) {
  173. log_buf[(log_start+log_size) & LOG_BUF_MASK] = *p;
  174. if (log_size < LOG_BUF_LEN)
  175. log_size++;
  176. else
  177. log_start++;
  178. logged_chars++;
  179. if (*p == '\n') {
  180. line_feed = 1;
  181. break;
  182. }
  183. }
  184. if (msg_level < console_loglevel) {
  185. printf("%s", msg);
  186. }
  187. if (line_feed)
  188. msg_level = -1;
  189. }
  190. return i;
  191. }
  192. #endif /* (CONFIG_LOGBUFFER) */