early_printk.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * allow a console to be used for early printk
  3. * derived from arch/x86/kernel/early_printk.c
  4. *
  5. * Copyright 2007-2009 Analog Devices Inc.
  6. *
  7. * Licensed under the GPL-2
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/init.h>
  11. #include <linux/serial_core.h>
  12. #include <linux/console.h>
  13. #include <linux/string.h>
  14. #include <linux/reboot.h>
  15. #include <asm/blackfin.h>
  16. #include <asm/irq_handler.h>
  17. #include <asm/early_printk.h>
  18. #ifdef CONFIG_SERIAL_BFIN
  19. extern struct console *bfin_earlyserial_init(unsigned int port,
  20. unsigned int cflag);
  21. #endif
  22. #ifdef CONFIG_BFIN_JTAG_COMM
  23. extern struct console *bfin_jc_early_init(void);
  24. #endif
  25. static struct console *early_console;
  26. /* Default console */
  27. #define DEFAULT_PORT 0
  28. #define DEFAULT_CFLAG CS8|B57600
  29. /* Default console for early crashes */
  30. #define DEFAULT_EARLY_PORT "serial,uart0,57600"
  31. #ifdef CONFIG_SERIAL_CORE
  32. /* What should get here is "0,57600" */
  33. static struct console * __init earlyserial_init(char *buf)
  34. {
  35. int baud, bit;
  36. char parity;
  37. unsigned int serial_port = DEFAULT_PORT;
  38. unsigned int cflag = DEFAULT_CFLAG;
  39. serial_port = simple_strtoul(buf, &buf, 10);
  40. buf++;
  41. cflag = 0;
  42. baud = simple_strtoul(buf, &buf, 10);
  43. switch (baud) {
  44. case 1200:
  45. cflag |= B1200;
  46. break;
  47. case 2400:
  48. cflag |= B2400;
  49. break;
  50. case 4800:
  51. cflag |= B4800;
  52. break;
  53. case 9600:
  54. cflag |= B9600;
  55. break;
  56. case 19200:
  57. cflag |= B19200;
  58. break;
  59. case 38400:
  60. cflag |= B38400;
  61. break;
  62. case 115200:
  63. cflag |= B115200;
  64. break;
  65. default:
  66. cflag |= B57600;
  67. }
  68. parity = buf[0];
  69. buf++;
  70. switch (parity) {
  71. case 'e':
  72. cflag |= PARENB;
  73. break;
  74. case 'o':
  75. cflag |= PARODD;
  76. break;
  77. }
  78. bit = simple_strtoul(buf, &buf, 10);
  79. switch (bit) {
  80. case 5:
  81. cflag |= CS5;
  82. break;
  83. case 6:
  84. cflag |= CS6;
  85. break;
  86. case 7:
  87. cflag |= CS7;
  88. break;
  89. default:
  90. cflag |= CS8;
  91. }
  92. #ifdef CONFIG_SERIAL_BFIN
  93. return bfin_earlyserial_init(serial_port, cflag);
  94. #else
  95. return NULL;
  96. #endif
  97. }
  98. #endif
  99. int __init setup_early_printk(char *buf)
  100. {
  101. /* Crashing in here would be really bad, so check both the var
  102. and the pointer before we start using it
  103. */
  104. if (!buf)
  105. return 0;
  106. if (!*buf)
  107. return 0;
  108. if (early_console != NULL)
  109. return 0;
  110. #ifdef CONFIG_SERIAL_BFIN
  111. /* Check for Blackfin Serial */
  112. if (!strncmp(buf, "serial,uart", 11)) {
  113. buf += 11;
  114. early_console = earlyserial_init(buf);
  115. }
  116. #endif
  117. #ifdef CONFIG_BFIN_JTAG_COMM
  118. /* Check for Blackfin JTAG */
  119. if (!strncmp(buf, "jtag", 4)) {
  120. buf += 4;
  121. early_console = bfin_jc_early_init();
  122. }
  123. #endif
  124. #ifdef CONFIG_FB
  125. /* TODO: add framebuffer console support */
  126. #endif
  127. if (likely(early_console)) {
  128. early_console->flags |= CON_BOOT;
  129. register_console(early_console);
  130. printk(KERN_INFO "early printk enabled on %s%d\n",
  131. early_console->name,
  132. early_console->index);
  133. }
  134. return 0;
  135. }
  136. /*
  137. * Set up a temporary Event Vector Table, so if something bad happens before
  138. * the kernel is fully started, it doesn't vector off into somewhere we don't
  139. * know
  140. */
  141. asmlinkage void __init init_early_exception_vectors(void)
  142. {
  143. u32 evt;
  144. SSYNC();
  145. /*
  146. * This starts up the shadow buffer, incase anything crashes before
  147. * setup arch
  148. */
  149. mark_shadow_error();
  150. early_shadow_puts(linux_banner);
  151. early_shadow_stamp();
  152. if (CPUID != bfin_cpuid()) {
  153. early_shadow_puts("Running on wrong machine type, expected");
  154. early_shadow_reg(CPUID, 16);
  155. early_shadow_puts(", but running on");
  156. early_shadow_reg(bfin_cpuid(), 16);
  157. early_shadow_puts("\n");
  158. }
  159. /* cannot program in software:
  160. * evt0 - emulation (jtag)
  161. * evt1 - reset
  162. */
  163. for (evt = EVT2; evt <= EVT15; evt += 4)
  164. bfin_write32(evt, early_trap);
  165. CSYNC();
  166. /* Set all the return from interrupt, exception, NMI to a known place
  167. * so if we do a RETI, RETX or RETN by mistake - we go somewhere known
  168. * Note - don't change RETS - we are in a subroutine, or
  169. * RETE - since it might screw up if emulator is attached
  170. */
  171. asm("\tRETI = %0; RETX = %0; RETN = %0;\n"
  172. : : "p"(early_trap));
  173. }
  174. __attribute__((__noreturn__))
  175. asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
  176. {
  177. /* This can happen before the uart is initialized, so initialize
  178. * the UART now (but only if we are running on the processor we think
  179. * we are compiled for - otherwise we write to MMRs that don't exist,
  180. * and cause other problems. Nothing comes out the UART, but it does
  181. * end up in the __buf_log.
  182. */
  183. if (likely(early_console == NULL) && CPUID == bfin_cpuid())
  184. setup_early_printk(DEFAULT_EARLY_PORT);
  185. if (!shadow_console_enabled()) {
  186. /* crap - we crashed before setup_arch() */
  187. early_shadow_puts("panic before setup_arch\n");
  188. early_shadow_puts("IPEND:");
  189. early_shadow_reg(fp->ipend, 16);
  190. if (fp->seqstat & SEQSTAT_EXCAUSE) {
  191. early_shadow_puts("\nEXCAUSE:");
  192. early_shadow_reg(fp->seqstat & SEQSTAT_EXCAUSE, 8);
  193. }
  194. if (fp->seqstat & SEQSTAT_HWERRCAUSE) {
  195. early_shadow_puts("\nHWERRCAUSE:");
  196. early_shadow_reg(
  197. (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14, 8);
  198. }
  199. early_shadow_puts("\nErr @");
  200. if (fp->ipend & EVT_EVX)
  201. early_shadow_reg(fp->retx, 32);
  202. else
  203. early_shadow_reg(fp->pc, 32);
  204. #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
  205. early_shadow_puts("\nTrace:");
  206. if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
  207. while (bfin_read_TBUFSTAT() & TBUFCNT) {
  208. early_shadow_puts("\nT :");
  209. early_shadow_reg(bfin_read_TBUF(), 32);
  210. early_shadow_puts("\n S :");
  211. early_shadow_reg(bfin_read_TBUF(), 32);
  212. }
  213. }
  214. #endif
  215. early_shadow_puts("\nUse bfin-elf-addr2line to determine "
  216. "function names\n");
  217. /*
  218. * We should panic(), but we can't - since panic calls printk,
  219. * and printk uses memcpy.
  220. * we want to reboot, but if the machine type is different,
  221. * can't due to machine specific reboot sequences
  222. */
  223. if (CPUID == bfin_cpuid()) {
  224. early_shadow_puts("Trying to restart\n");
  225. machine_restart("");
  226. }
  227. early_shadow_puts("Halting, since it is not safe to restart\n");
  228. while (1)
  229. asm volatile ("EMUEXCPT; IDLE;\n");
  230. } else {
  231. printk(KERN_EMERG "Early panic\n");
  232. show_regs(fp);
  233. dump_bfin_trace_buffer();
  234. }
  235. panic("Died early");
  236. }
  237. early_param("earlyprintk", setup_early_printk);