start.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*
  2. * Copyright (C) 1996 Paul Mackerras.
  3. */
  4. #include <linux/config.h>
  5. #include <linux/string.h>
  6. #include <asm/machdep.h>
  7. #include <asm/io.h>
  8. #include <asm/page.h>
  9. #include <linux/kernel.h>
  10. #include <linux/errno.h>
  11. #include <linux/sysrq.h>
  12. #include <linux/bitops.h>
  13. #include <asm/xmon.h>
  14. #include <asm/machdep.h>
  15. #include <asm/errno.h>
  16. #include <asm/processor.h>
  17. #include <asm/delay.h>
  18. #include <asm/btext.h>
  19. static volatile unsigned char *sccc, *sccd;
  20. unsigned int TXRDY, RXRDY, DLAB;
  21. static int xmon_expect(const char *str, unsigned int timeout);
  22. static int via_modem;
  23. #define TB_SPEED 25000000
  24. static inline unsigned int readtb(void)
  25. {
  26. unsigned int ret;
  27. asm volatile("mftb %0" : "=r" (ret) :);
  28. return ret;
  29. }
  30. void buf_access(void)
  31. {
  32. if (DLAB)
  33. sccd[3] &= ~DLAB; /* reset DLAB */
  34. }
  35. #ifdef CONFIG_MAGIC_SYSRQ
  36. static void sysrq_handle_xmon(int key, struct pt_regs *regs,
  37. struct tty_struct *tty)
  38. {
  39. xmon(regs);
  40. }
  41. static struct sysrq_key_op sysrq_xmon_op =
  42. {
  43. .handler = sysrq_handle_xmon,
  44. .help_msg = "Xmon",
  45. .action_msg = "Entering xmon",
  46. };
  47. #endif
  48. void
  49. xmon_map_scc(void)
  50. {
  51. #ifdef CONFIG_PPC_PREP
  52. volatile unsigned char *base;
  53. #elif defined(CONFIG_GEMINI)
  54. /* should already be mapped by the kernel boot */
  55. sccc = (volatile unsigned char *) 0xffeffb0d;
  56. sccd = (volatile unsigned char *) 0xffeffb08;
  57. TXRDY = 0x20;
  58. RXRDY = 1;
  59. DLAB = 0x80;
  60. #elif defined(CONFIG_405GP)
  61. sccc = (volatile unsigned char *)0xef600305;
  62. sccd = (volatile unsigned char *)0xef600300;
  63. TXRDY = 0x20;
  64. RXRDY = 1;
  65. DLAB = 0x80;
  66. #endif /* platform */
  67. register_sysrq_key('x', &sysrq_xmon_op);
  68. }
  69. static int scc_initialized;
  70. void xmon_init_scc(void);
  71. int
  72. xmon_write(void *handle, void *ptr, int nb)
  73. {
  74. char *p = ptr;
  75. int i, c, ct;
  76. #ifdef CONFIG_SMP
  77. static unsigned long xmon_write_lock;
  78. int lock_wait = 1000000;
  79. int locked;
  80. while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
  81. if (--lock_wait == 0)
  82. break;
  83. #endif
  84. if (!scc_initialized)
  85. xmon_init_scc();
  86. ct = 0;
  87. for (i = 0; i < nb; ++i) {
  88. while ((*sccc & TXRDY) == 0)
  89. ;
  90. c = p[i];
  91. if (c == '\n' && !ct) {
  92. c = '\r';
  93. ct = 1;
  94. --i;
  95. } else {
  96. ct = 0;
  97. }
  98. buf_access();
  99. *sccd = c;
  100. eieio();
  101. }
  102. #ifdef CONFIG_SMP
  103. if (!locked)
  104. clear_bit(0, &xmon_write_lock);
  105. #endif
  106. return nb;
  107. }
  108. int xmon_wants_key;
  109. int
  110. xmon_read(void *handle, void *ptr, int nb)
  111. {
  112. char *p = ptr;
  113. int i;
  114. if (!scc_initialized)
  115. xmon_init_scc();
  116. for (i = 0; i < nb; ++i) {
  117. while ((*sccc & RXRDY) == 0)
  118. ;
  119. buf_access();
  120. *p++ = *sccd;
  121. }
  122. return i;
  123. }
  124. int
  125. xmon_read_poll(void)
  126. {
  127. if ((*sccc & RXRDY) == 0) {
  128. ;
  129. return -1;
  130. }
  131. buf_access();
  132. return *sccd;
  133. }
  134. void
  135. xmon_init_scc(void)
  136. {
  137. scc_initialized = 1;
  138. if (via_modem) {
  139. for (;;) {
  140. xmon_write(NULL, "ATE1V1\r", 7);
  141. if (xmon_expect("OK", 5)) {
  142. xmon_write(NULL, "ATA\r", 4);
  143. if (xmon_expect("CONNECT", 40))
  144. break;
  145. }
  146. xmon_write(NULL, "+++", 3);
  147. xmon_expect("OK", 3);
  148. }
  149. }
  150. }
  151. void *xmon_stdin;
  152. void *xmon_stdout;
  153. void *xmon_stderr;
  154. void
  155. xmon_init(int arg)
  156. {
  157. xmon_map_scc();
  158. }
  159. int
  160. xmon_putc(int c, void *f)
  161. {
  162. char ch = c;
  163. if (c == '\n')
  164. xmon_putc('\r', f);
  165. return xmon_write(f, &ch, 1) == 1? c: -1;
  166. }
  167. int
  168. xmon_putchar(int c)
  169. {
  170. return xmon_putc(c, xmon_stdout);
  171. }
  172. int
  173. xmon_fputs(char *str, void *f)
  174. {
  175. int n = strlen(str);
  176. return xmon_write(f, str, n) == n? 0: -1;
  177. }
  178. int
  179. xmon_readchar(void)
  180. {
  181. char ch;
  182. for (;;) {
  183. switch (xmon_read(xmon_stdin, &ch, 1)) {
  184. case 1:
  185. return ch;
  186. case -1:
  187. xmon_printf("read(stdin) returned -1\r\n", 0, 0);
  188. return -1;
  189. }
  190. }
  191. }
  192. static char line[256];
  193. static char *lineptr;
  194. static int lineleft;
  195. int xmon_expect(const char *str, unsigned int timeout)
  196. {
  197. int c;
  198. unsigned int t0;
  199. timeout *= TB_SPEED;
  200. t0 = readtb();
  201. do {
  202. lineptr = line;
  203. for (;;) {
  204. c = xmon_read_poll();
  205. if (c == -1) {
  206. if (readtb() - t0 > timeout)
  207. return 0;
  208. continue;
  209. }
  210. if (c == '\n')
  211. break;
  212. if (c != '\r' && lineptr < &line[sizeof(line) - 1])
  213. *lineptr++ = c;
  214. }
  215. *lineptr = 0;
  216. } while (strstr(line, str) == NULL);
  217. return 1;
  218. }
  219. int
  220. xmon_getchar(void)
  221. {
  222. int c;
  223. if (lineleft == 0) {
  224. lineptr = line;
  225. for (;;) {
  226. c = xmon_readchar();
  227. if (c == -1 || c == 4)
  228. break;
  229. if (c == '\r' || c == '\n') {
  230. *lineptr++ = '\n';
  231. xmon_putchar('\n');
  232. break;
  233. }
  234. switch (c) {
  235. case 0177:
  236. case '\b':
  237. if (lineptr > line) {
  238. xmon_putchar('\b');
  239. xmon_putchar(' ');
  240. xmon_putchar('\b');
  241. --lineptr;
  242. }
  243. break;
  244. case 'U' & 0x1F:
  245. while (lineptr > line) {
  246. xmon_putchar('\b');
  247. xmon_putchar(' ');
  248. xmon_putchar('\b');
  249. --lineptr;
  250. }
  251. break;
  252. default:
  253. if (lineptr >= &line[sizeof(line) - 1])
  254. xmon_putchar('\a');
  255. else {
  256. xmon_putchar(c);
  257. *lineptr++ = c;
  258. }
  259. }
  260. }
  261. lineleft = lineptr - line;
  262. lineptr = line;
  263. }
  264. if (lineleft == 0)
  265. return -1;
  266. --lineleft;
  267. return *lineptr++;
  268. }
  269. char *
  270. xmon_fgets(char *str, int nb, void *f)
  271. {
  272. char *p;
  273. int c;
  274. for (p = str; p < str + nb - 1; ) {
  275. c = xmon_getchar();
  276. if (c == -1) {
  277. if (p == str)
  278. return NULL;
  279. break;
  280. }
  281. *p++ = c;
  282. if (c == '\n')
  283. break;
  284. }
  285. *p = 0;
  286. return str;
  287. }
  288. void
  289. xmon_enter(void)
  290. {
  291. }
  292. void
  293. xmon_leave(void)
  294. {
  295. }