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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 1996 Paul Mackerras.
  3.  *
  4.  *      This program is free software; you can redistribute it and/or
  5.  *      modify it under the terms of the GNU General Public License
  6.  *      as published by the Free Software Foundation; either version
  7.  *      2 of the License, or (at your option) any later version.
  8.  */
  9. #include <linux/string.h>
  10. #include <linux/kernel.h>
  11. #include <linux/sysrq.h>
  12. #include <linux/fs.h>
  13. #include <asm/machdep.h>
  14. #include <asm/io.h>
  15. #include <asm/page.h>
  16. #include <asm/prom.h>
  17. #include <asm/processor.h>
  18. /* Transition to udbg isn't quite done yet...but very close. */
  19. #define USE_UDBG
  20. #ifdef USE_UDBG
  21. #include <asm/udbg.h>
  22. #endif
  23. #ifndef USE_UDBG
  24. static volatile unsigned char *sccc, *sccd;
  25. #endif
  26. unsigned long TXRDY, RXRDY;
  27. extern void xmon_printf(const char *fmt, ...);
  28. static int xmon_expect(const char *str, unsigned int timeout);
  29. #ifndef USE_UDBG
  30. static int console = 0;
  31. #endif
  32. static int via_modem = 0;
  33. /* static int xmon_use_sccb = 0;  --Unused */
  34. #define TB_SPEED 25000000
  35. extern void *comport1;
  36. static inline unsigned int readtb(void)
  37. {
  38. unsigned int ret;
  39. asm volatile("mftb %0" : "=r" (ret) :);
  40. return ret;
  41. }
  42. #ifndef USE_UDBG
  43. void buf_access(void)
  44. {
  45. sccd[3] &= ~0x80; /* reset DLAB */
  46. }
  47. #endif
  48. static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, struct kbd_struct *kbd, struct tty_struct *tty) 
  49. {
  50.   xmon(pt_regs);
  51. }
  52. static struct sysrq_key_op sysrq_xmon_op = 
  53. {
  54. handler: sysrq_handle_xmon,
  55. help_msg: "xmon",
  56. action_msg: "Entering xmonn",
  57. };
  58. void
  59. xmon_map_scc(void)
  60. {
  61. /* This maybe isn't the best place to register sysrq 'x' */
  62. __sysrq_put_key_op('x', &sysrq_xmon_op);
  63. #ifndef USE_UDBG
  64. /* should already be mapped by the kernel boot */
  65. sccd = (volatile unsigned char *) (((unsigned long)comport1));
  66. sccc = (volatile unsigned char *) (((unsigned long)comport1)+5);
  67. TXRDY = 0x20;
  68. RXRDY = 1;
  69. #endif
  70. }
  71. static int scc_initialized = 0;
  72. void xmon_init_scc(void);
  73. extern void pmu_poll(void);
  74. int
  75. xmon_write(void *handle, void *ptr, int nb)
  76. {
  77. #ifdef USE_UDBG
  78. return udbg_write(ptr, nb);
  79. #else
  80. char *p = ptr;
  81. int i, c, ct;
  82. if (!scc_initialized)
  83. xmon_init_scc();
  84. ct = 0;
  85. for (i = 0; i < nb; ++i) {
  86. while ((*sccc & TXRDY) == 0) {
  87. }
  88. c = p[i];
  89. if (c == 'n' && !ct) {
  90. c = 'r';
  91. ct = 1;
  92. --i;
  93. } else {
  94. if (console)
  95. printk("%c", c);
  96. ct = 0;
  97. }
  98. buf_access();
  99. *sccd = c;
  100. }
  101. return i;
  102. #endif
  103. }
  104. int xmon_wants_key;
  105. int
  106. xmon_read(void *handle, void *ptr, int nb)
  107. {
  108. #ifdef USE_UDBG
  109. return udbg_read(ptr, nb);
  110. #else
  111. char *p = ptr;
  112. int i, c;
  113. if (!scc_initialized)
  114. xmon_init_scc();
  115. for (i = 0; i < nb; ++i) {
  116. do {
  117. while ((*sccc & RXRDY) == 0)
  118. ;
  119. buf_access();
  120. c = *sccd;
  121. } while (c == 0x11 || c == 0x13);
  122. *p++ = c;
  123. }
  124. return i;
  125. #endif
  126. }
  127. int
  128. xmon_read_poll(void)
  129. {
  130. #ifdef USE_UDBG
  131. return udbg_getc_poll();
  132. #else
  133. if ((*sccc & RXRDY) == 0) {
  134. return -1;
  135. }
  136. buf_access();
  137. return *sccd;
  138. #endif
  139. }
  140.  
  141. void
  142. xmon_init_scc()
  143. {
  144. #ifndef USE_UDBG
  145. sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
  146. sccd[0] = 12; eieio(); /* DLL = 9600 baud */
  147. sccd[1] = 0; eieio();
  148. sccd[2] = 0; eieio(); /* FCR = 0 */
  149. sccd[3] = 3; eieio(); /* LCR = 8N1 */
  150. sccd[1] = 0; eieio(); /* IER = 0 */
  151. #endif
  152. scc_initialized = 1;
  153. if (via_modem) {
  154. for (;;) {
  155. xmon_write(0, "ATE1V1r", 7);
  156. if (xmon_expect("OK", 5)) {
  157. xmon_write(0, "ATAr", 4);
  158. if (xmon_expect("CONNECT", 40))
  159. break;
  160. }
  161. xmon_write(0, "+++", 3);
  162. xmon_expect("OK", 3);
  163. }
  164. }
  165. }
  166. void *xmon_stdin;
  167. void *xmon_stdout;
  168. void *xmon_stderr;
  169. void
  170. xmon_init(void)
  171. {
  172. }
  173. int
  174. xmon_putc(int c, void *f)
  175. {
  176. char ch = c;
  177. if (c == 'n')
  178. xmon_putc('r', f);
  179. return xmon_write(f, &ch, 1) == 1? c: -1;
  180. }
  181. int
  182. xmon_putchar(int c)
  183. {
  184. return xmon_putc(c, xmon_stdout);
  185. }
  186. int
  187. xmon_fputs(char *str, void *f)
  188. {
  189. int n = strlen(str);
  190. return xmon_write(f, str, n) == n? 0: -1;
  191. }
  192. int
  193. xmon_readchar(void)
  194. {
  195. char ch;
  196. for (;;) {
  197. switch (xmon_read(xmon_stdin, &ch, 1)) {
  198. case 1:
  199. return ch;
  200. case -1:
  201. xmon_printf("read(stdin) returned -1rn", 0, 0);
  202. return -1;
  203. }
  204. }
  205. }
  206. static char line[256];
  207. static char *lineptr;
  208. static int lineleft;
  209. int xmon_expect(const char *str, unsigned int timeout)
  210. {
  211. int c;
  212. unsigned int t0;
  213. timeout *= TB_SPEED;
  214. t0 = readtb();
  215. do {
  216. lineptr = line;
  217. for (;;) {
  218. c = xmon_read_poll();
  219. if (c == -1) {
  220. if (readtb() - t0 > timeout)
  221. return 0;
  222. continue;
  223. }
  224. if (c == 'n')
  225. break;
  226. if (c != 'r' && lineptr < &line[sizeof(line) - 1])
  227. *lineptr++ = c;
  228. }
  229. *lineptr = 0;
  230. } while (strstr(line, str) == NULL);
  231. return 1;
  232. }
  233. int
  234. xmon_getchar(void)
  235. {
  236. int c;
  237. if (lineleft == 0) {
  238. lineptr = line;
  239. for (;;) {
  240. c = xmon_readchar();
  241. if (c == -1 || c == 4)
  242. break;
  243. if (c == 'r' || c == 'n') {
  244. *lineptr++ = 'n';
  245. xmon_putchar('n');
  246. break;
  247. }
  248. switch (c) {
  249. case 0177:
  250. case 'b':
  251. if (lineptr > line) {
  252. xmon_putchar('b');
  253. xmon_putchar(' ');
  254. xmon_putchar('b');
  255. --lineptr;
  256. }
  257. break;
  258. case 'U' & 0x1F:
  259. while (lineptr > line) {
  260. xmon_putchar('b');
  261. xmon_putchar(' ');
  262. xmon_putchar('b');
  263. --lineptr;
  264. }
  265. break;
  266. default:
  267. if (lineptr >= &line[sizeof(line) - 1])
  268. xmon_putchar('a');
  269. else {
  270. xmon_putchar(c);
  271. *lineptr++ = c;
  272. }
  273. }
  274. }
  275. lineleft = lineptr - line;
  276. lineptr = line;
  277. }
  278. if (lineleft == 0)
  279. return -1;
  280. --lineleft;
  281. return *lineptr++;
  282. }
  283. char *
  284. xmon_fgets(char *str, int nb, void *f)
  285. {
  286. char *p;
  287. int c;
  288. for (p = str; p < str + nb - 1; ) {
  289. c = xmon_getchar();
  290. if (c == -1) {
  291. if (p == str)
  292. return 0;
  293. break;
  294. }
  295. *p++ = c;
  296. if (c == 'n')
  297. break;
  298. }
  299. *p = 0;
  300. return str;
  301. }