Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Simplify and clean up the xmon terminal I/O

This factors out the common bits of arch/powerpc/xmon/start_*.c into
a new nonstdio.c, and removes some stuff that was supposed to make
xmon's I/O routines somewhat stdio-like but was never used.

It also makes the parsing of the xmon= command line option common,
so that ppc32 can now use xmon={off,on,early} also.

Signed-off-by: Paul Mackerras <paulus@samba.org>

+238 -731
+21
arch/powerpc/kernel/setup-common.c
··· 51 51 #include <asm/page.h> 52 52 #include <asm/mmu.h> 53 53 #include <asm/lmb.h> 54 + #include <asm/xmon.h> 54 55 55 56 #undef DEBUG 56 57 ··· 560 559 #endif /* CONFIG_PPC64 */ 561 560 } 562 561 #endif /* CONFIG_SMP */ 562 + 563 + #ifdef CONFIG_XMON 564 + static int __init early_xmon(char *p) 565 + { 566 + /* ensure xmon is enabled */ 567 + if (p) { 568 + if (strncmp(p, "on", 2) == 0) 569 + xmon_init(1); 570 + if (strncmp(p, "off", 3) == 0) 571 + xmon_init(0); 572 + if (strncmp(p, "early", 5) != 0) 573 + return 0; 574 + } 575 + xmon_init(1); 576 + debugger(NULL); 577 + 578 + return 0; 579 + } 580 + early_param("xmon", early_xmon); 581 + #endif
+3 -8
arch/powerpc/kernel/setup_32.c
··· 303 303 pmac_feature_init(); /* New cool way */ 304 304 #endif 305 305 306 - #ifdef CONFIG_XMON 307 - xmon_map_scc(); 308 - if (strstr(cmd_line, "xmon")) { 309 - xmon_init(1); 310 - debugger(NULL); 311 - } 312 - #endif /* CONFIG_XMON */ 313 - if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); 306 + #ifdef CONFIG_XMON_DEFAULT 307 + xmon_init(1); 308 + #endif 314 309 315 310 #if defined(CONFIG_KGDB) 316 311 if (ppc_md.kgdb_map_scc)
-20
arch/powerpc/kernel/setup_64.c
··· 858 858 } 859 859 EXPORT_SYMBOL(check_legacy_ioport); 860 860 861 - #ifdef CONFIG_XMON 862 - static int __init early_xmon(char *p) 863 - { 864 - /* ensure xmon is enabled */ 865 - if (p) { 866 - if (strncmp(p, "on", 2) == 0) 867 - xmon_init(1); 868 - if (strncmp(p, "off", 3) == 0) 869 - xmon_init(0); 870 - if (strncmp(p, "early", 5) != 0) 871 - return 0; 872 - } 873 - xmon_init(1); 874 - debugger(NULL); 875 - 876 - return 0; 877 - } 878 - early_param("xmon", early_xmon); 879 - #endif 880 - 881 861 void cpu_die(void) 882 862 { 883 863 if (ppc_md.cpu_die)
+1 -1
arch/powerpc/xmon/Makefile
··· 8 8 obj-$(CONFIG_6xx) += start_32.o 9 9 obj-$(CONFIG_4xx) += start_32.o 10 10 obj-$(CONFIG_PPC64) += start_64.o 11 - obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o 11 + obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
+134
arch/powerpc/xmon/nonstdio.c
··· 1 + /* 2 + * Copyright (C) 1996-2005 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 <asm/time.h> 11 + #include "nonstdio.h" 12 + 13 + int xmon_putchar(int c) 14 + { 15 + char ch = c; 16 + 17 + if (c == '\n') 18 + xmon_putchar('\r'); 19 + return xmon_write(&ch, 1) == 1? c: -1; 20 + } 21 + 22 + static char line[256]; 23 + static char *lineptr; 24 + static int lineleft; 25 + 26 + int xmon_expect(const char *str, unsigned long timeout) 27 + { 28 + int c; 29 + unsigned long t0; 30 + 31 + /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */ 32 + timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000; 33 + t0 = get_tbl(); 34 + do { 35 + lineptr = line; 36 + for (;;) { 37 + c = xmon_read_poll(); 38 + if (c == -1) { 39 + if (get_tbl() - t0 > timeout) 40 + return 0; 41 + continue; 42 + } 43 + if (c == '\n') 44 + break; 45 + if (c != '\r' && lineptr < &line[sizeof(line) - 1]) 46 + *lineptr++ = c; 47 + } 48 + *lineptr = 0; 49 + } while (strstr(line, str) == NULL); 50 + return 1; 51 + } 52 + 53 + int xmon_getchar(void) 54 + { 55 + int c; 56 + 57 + if (lineleft == 0) { 58 + lineptr = line; 59 + for (;;) { 60 + c = xmon_readchar(); 61 + if (c == -1 || c == 4) 62 + break; 63 + if (c == '\r' || c == '\n') { 64 + *lineptr++ = '\n'; 65 + xmon_putchar('\n'); 66 + break; 67 + } 68 + switch (c) { 69 + case 0177: 70 + case '\b': 71 + if (lineptr > line) { 72 + xmon_putchar('\b'); 73 + xmon_putchar(' '); 74 + xmon_putchar('\b'); 75 + --lineptr; 76 + } 77 + break; 78 + case 'U' & 0x1F: 79 + while (lineptr > line) { 80 + xmon_putchar('\b'); 81 + xmon_putchar(' '); 82 + xmon_putchar('\b'); 83 + --lineptr; 84 + } 85 + break; 86 + default: 87 + if (lineptr >= &line[sizeof(line) - 1]) 88 + xmon_putchar('\a'); 89 + else { 90 + xmon_putchar(c); 91 + *lineptr++ = c; 92 + } 93 + } 94 + } 95 + lineleft = lineptr - line; 96 + lineptr = line; 97 + } 98 + if (lineleft == 0) 99 + return -1; 100 + --lineleft; 101 + return *lineptr++; 102 + } 103 + 104 + char *xmon_gets(char *str, int nb) 105 + { 106 + char *p; 107 + int c; 108 + 109 + for (p = str; p < str + nb - 1; ) { 110 + c = xmon_getchar(); 111 + if (c == -1) { 112 + if (p == str) 113 + return NULL; 114 + break; 115 + } 116 + *p++ = c; 117 + if (c == '\n') 118 + break; 119 + } 120 + *p = 0; 121 + return str; 122 + } 123 + 124 + void xmon_printf(const char *format, ...) 125 + { 126 + va_list args; 127 + int n; 128 + static char xmon_outbuf[1024]; 129 + 130 + va_start(args, format); 131 + n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args); 132 + va_end(args); 133 + xmon_write(xmon_outbuf, n); 134 + }
+12 -20
arch/powerpc/xmon/nonstdio.h
··· 1 - typedef int FILE; 2 - extern FILE *xmon_stdin, *xmon_stdout; 3 1 #define EOF (-1) 4 - #define stdin xmon_stdin 5 - #define stdout xmon_stdout 6 - #define printf xmon_printf 7 - #define fprintf xmon_fprintf 8 - #define fputs xmon_fputs 9 - #define fgets xmon_fgets 10 - #define putchar xmon_putchar 11 - #define getchar xmon_getchar 12 - #define putc xmon_putc 13 - #define getc xmon_getc 14 - #define fopen(n, m) NULL 15 - #define fflush(f) do {} while (0) 16 - #define fclose(f) do {} while (0) 17 - extern char *fgets(char *, int, void *); 18 - extern void xmon_printf(const char *, ...); 19 - extern void xmon_fprintf(void *, const char *, ...); 20 - extern void xmon_sprintf(char *, const char *, ...); 21 2 22 - #define perror(s) printf("%s: no files!\n", (s)) 3 + #define printf xmon_printf 4 + #define putchar xmon_putchar 5 + 6 + extern int xmon_putchar(int c); 7 + extern int xmon_getchar(void); 8 + extern char *xmon_gets(char *, int); 9 + extern void xmon_printf(const char *, ...); 10 + extern void xmon_map_scc(void); 11 + extern int xmon_expect(const char *str, unsigned long timeout); 12 + extern int xmon_write(void *ptr, int nb); 13 + extern int xmon_readchar(void); 14 + extern int xmon_read_poll(void);
+26 -209
arch/powerpc/xmon/start_32.c
··· 11 11 #include <linux/cuda.h> 12 12 #include <linux/kernel.h> 13 13 #include <linux/errno.h> 14 - #include <linux/sysrq.h> 15 14 #include <linux/bitops.h> 16 15 #include <asm/xmon.h> 17 16 #include <asm/prom.h> ··· 21 22 #include <asm/processor.h> 22 23 #include <asm/delay.h> 23 24 #include <asm/btext.h> 25 + #include <asm/time.h> 26 + #include "nonstdio.h" 24 27 25 28 static volatile unsigned char __iomem *sccc, *sccd; 26 29 unsigned int TXRDY, RXRDY, DLAB; 27 - static int xmon_expect(const char *str, unsigned int timeout); 28 30 29 31 static int use_serial; 30 32 static int use_screen; 31 33 static int via_modem; 32 34 static int xmon_use_sccb; 33 35 static struct device_node *channel_node; 34 - 35 - #define TB_SPEED 25000000 36 - 37 - static inline unsigned int readtb(void) 38 - { 39 - unsigned int ret; 40 - 41 - asm volatile("mftb %0" : "=r" (ret) :); 42 - return ret; 43 - } 44 36 45 37 void buf_access(void) 46 38 { ··· 81 91 } 82 92 #endif /* CONFIG_PPC_CHRP */ 83 93 84 - #ifdef CONFIG_MAGIC_SYSRQ 85 - static void sysrq_handle_xmon(int key, struct pt_regs *regs, 86 - struct tty_struct *tty) 87 - { 88 - xmon(regs); 89 - } 90 - 91 - static struct sysrq_key_op sysrq_xmon_op = 92 - { 93 - .handler = sysrq_handle_xmon, 94 - .help_msg = "Xmon", 95 - .action_msg = "Entering xmon", 96 - }; 97 - #endif 98 - 99 - void 100 - xmon_map_scc(void) 94 + void xmon_map_scc(void) 101 95 { 102 96 #ifdef CONFIG_PPC_MULTIPLATFORM 103 97 volatile unsigned char __iomem *base; ··· 191 217 RXRDY = 1; 192 218 DLAB = 0x80; 193 219 #endif /* platform */ 194 - 195 - register_sysrq_key('x', &sysrq_xmon_op); 196 220 } 197 221 198 222 static int scc_initialized = 0; ··· 210 238 #endif /* CONFIG_ADB_CUDA */ 211 239 } 212 240 213 - int 214 - xmon_write(void *handle, void *ptr, int nb) 241 + int xmon_write(void *ptr, int nb) 215 242 { 216 243 char *p = ptr; 217 244 int i, c, ct; ··· 282 311 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ 283 312 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ 284 313 285 - static int 286 - xmon_get_adb_key(void) 314 + static int xmon_get_adb_key(void) 287 315 { 288 316 int k, t, on; 289 317 ··· 320 350 } 321 351 #endif /* CONFIG_BOOTX_TEXT */ 322 352 323 - int 324 - xmon_read(void *handle, void *ptr, int nb) 353 + int xmon_readchar(void) 325 354 { 326 - char *p = ptr; 327 - int i; 328 - 329 355 #ifdef CONFIG_BOOTX_TEXT 330 - if (use_screen) { 331 - for (i = 0; i < nb; ++i) 332 - *p++ = xmon_get_adb_key(); 333 - return i; 334 - } 356 + if (use_screen) 357 + return xmon_get_adb_key(); 335 358 #endif 336 - if (!scc_initialized) 337 - xmon_init_scc(); 338 - for (i = 0; i < nb; ++i) { 359 + if (!scc_initialized) 360 + xmon_init_scc(); 339 361 while ((*sccc & RXRDY) == 0) 340 - do_poll_adb(); 362 + do_poll_adb(); 341 363 buf_access(); 342 - *p++ = *sccd; 343 - } 344 - return i; 364 + return *sccd; 345 365 } 346 366 347 - int 348 - xmon_read_poll(void) 367 + int xmon_read_poll(void) 349 368 { 350 369 if ((*sccc & RXRDY) == 0) { 351 370 do_poll_adb(); ··· 354 395 3, 0xc1, /* rx enable, 8 bits */ 355 396 }; 356 397 357 - void 358 - xmon_init_scc(void) 398 + void xmon_init_scc(void) 359 399 { 360 400 if ( _machine == _MACH_chrp ) 361 401 { ··· 368 410 else if ( _machine == _MACH_Pmac ) 369 411 { 370 412 int i, x; 413 + unsigned long timeout; 371 414 372 415 if (channel_node != 0) 373 416 pmac_call_feature( ··· 383 424 PMAC_FTR_MODEM_ENABLE, 384 425 channel_node, 0, 1); 385 426 printk(KERN_INFO "Modem powered up by debugger !\n"); 386 - t0 = readtb(); 387 - while (readtb() - t0 < 3*TB_SPEED) 427 + t0 = get_tbl(); 428 + timeout = 3 * tb_ticks_per_sec; 429 + if (timeout == 0) 430 + /* assume 25MHz if tb_ticks_per_sec not set */ 431 + timeout = 75000000; 432 + while (get_tbl() - t0 < timeout) 388 433 eieio(); 389 434 } 390 435 /* use the B channel if requested */ ··· 410 447 scc_initialized = 1; 411 448 if (via_modem) { 412 449 for (;;) { 413 - xmon_write(NULL, "ATE1V1\r", 7); 450 + xmon_write("ATE1V1\r", 7); 414 451 if (xmon_expect("OK", 5)) { 415 - xmon_write(NULL, "ATA\r", 4); 452 + xmon_write("ATA\r", 4); 416 453 if (xmon_expect("CONNECT", 40)) 417 454 break; 418 455 } 419 - xmon_write(NULL, "+++", 3); 456 + xmon_write("+++", 3); 420 457 xmon_expect("OK", 3); 421 458 } 422 459 } 423 460 } 424 461 425 - void *xmon_stdin; 426 - void *xmon_stdout; 427 - void *xmon_stderr; 428 - 429 - int xmon_putc(int c, void *f) 430 - { 431 - char ch = c; 432 - 433 - if (c == '\n') 434 - xmon_putc('\r', f); 435 - return xmon_write(f, &ch, 1) == 1? c: -1; 436 - } 437 - 438 - int xmon_putchar(int c) 439 - { 440 - return xmon_putc(c, xmon_stdout); 441 - } 442 - 443 - int xmon_fputs(char *str, void *f) 444 - { 445 - int n = strlen(str); 446 - 447 - return xmon_write(f, str, n) == n? 0: -1; 448 - } 449 - 450 - int 451 - xmon_readchar(void) 452 - { 453 - char ch; 454 - 455 - for (;;) { 456 - switch (xmon_read(xmon_stdin, &ch, 1)) { 457 - case 1: 458 - return ch; 459 - case -1: 460 - xmon_printf("read(stdin) returned -1\r\n", 0, 0); 461 - return -1; 462 - } 463 - } 464 - } 465 - 466 - static char line[256]; 467 - static char *lineptr; 468 - static int lineleft; 469 - 470 - int xmon_expect(const char *str, unsigned int timeout) 471 - { 472 - int c; 473 - unsigned int t0; 474 - 475 - timeout *= TB_SPEED; 476 - t0 = readtb(); 477 - do { 478 - lineptr = line; 479 - for (;;) { 480 - c = xmon_read_poll(); 481 - if (c == -1) { 482 - if (readtb() - t0 > timeout) 483 - return 0; 484 - continue; 485 - } 486 - if (c == '\n') 487 - break; 488 - if (c != '\r' && lineptr < &line[sizeof(line) - 1]) 489 - *lineptr++ = c; 490 - } 491 - *lineptr = 0; 492 - } while (strstr(line, str) == NULL); 493 - return 1; 494 - } 495 - 496 - int 497 - xmon_getchar(void) 498 - { 499 - int c; 500 - 501 - if (lineleft == 0) { 502 - lineptr = line; 503 - for (;;) { 504 - c = xmon_readchar(); 505 - if (c == -1 || c == 4) 506 - break; 507 - if (c == '\r' || c == '\n') { 508 - *lineptr++ = '\n'; 509 - xmon_putchar('\n'); 510 - break; 511 - } 512 - switch (c) { 513 - case 0177: 514 - case '\b': 515 - if (lineptr > line) { 516 - xmon_putchar('\b'); 517 - xmon_putchar(' '); 518 - xmon_putchar('\b'); 519 - --lineptr; 520 - } 521 - break; 522 - case 'U' & 0x1F: 523 - while (lineptr > line) { 524 - xmon_putchar('\b'); 525 - xmon_putchar(' '); 526 - xmon_putchar('\b'); 527 - --lineptr; 528 - } 529 - break; 530 - default: 531 - if (lineptr >= &line[sizeof(line) - 1]) 532 - xmon_putchar('\a'); 533 - else { 534 - xmon_putchar(c); 535 - *lineptr++ = c; 536 - } 537 - } 538 - } 539 - lineleft = lineptr - line; 540 - lineptr = line; 541 - } 542 - if (lineleft == 0) 543 - return -1; 544 - --lineleft; 545 - return *lineptr++; 546 - } 547 - 548 - char * 549 - xmon_fgets(char *str, int nb, void *f) 550 - { 551 - char *p; 552 - int c; 553 - 554 - for (p = str; p < str + nb - 1; ) { 555 - c = xmon_getchar(); 556 - if (c == -1) { 557 - if (p == str) 558 - return NULL; 559 - break; 560 - } 561 - *p++ = c; 562 - if (c == '\n') 563 - break; 564 - } 565 - *p = 0; 566 - return str; 567 - } 568 - 569 - void 570 - xmon_enter(void) 462 + void xmon_enter(void) 571 463 { 572 464 #ifdef CONFIG_ADB_PMU 573 465 if (_machine == _MACH_Pmac) { ··· 431 613 #endif 432 614 } 433 615 434 - void 435 - xmon_leave(void) 616 + void xmon_leave(void) 436 617 { 437 618 #ifdef CONFIG_ADB_PMU 438 619 if (_machine == _MACH_Pmac) {
+7 -160
arch/powerpc/xmon/start_64.c
··· 6 6 * as published by the Free Software Foundation; either version 7 7 * 2 of the License, or (at your option) any later version. 8 8 */ 9 - #include <linux/config.h> 10 - #include <linux/string.h> 11 - #include <linux/kernel.h> 12 - #include <linux/errno.h> 13 - #include <linux/sysrq.h> 14 - #include <linux/init.h> 15 9 #include <asm/machdep.h> 16 - #include <asm/io.h> 17 - #include <asm/page.h> 18 - #include <asm/prom.h> 19 - #include <asm/processor.h> 20 10 #include <asm/udbg.h> 21 - #include <asm/system.h> 22 11 #include "nonstdio.h" 23 12 24 - #ifdef CONFIG_MAGIC_SYSRQ 25 - 26 - static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, 27 - struct tty_struct *tty) 13 + void xmon_map_scc(void) 28 14 { 29 - /* ensure xmon is enabled */ 30 - xmon_init(1); 31 - debugger(pt_regs); 32 15 } 33 16 34 - static struct sysrq_key_op sysrq_xmon_op = 35 - { 36 - .handler = sysrq_handle_xmon, 37 - .help_msg = "Xmon", 38 - .action_msg = "Entering xmon", 39 - }; 40 - 41 - static int __init setup_xmon_sysrq(void) 42 - { 43 - register_sysrq_key('x', &sysrq_xmon_op); 44 - return 0; 45 - } 46 - __initcall(setup_xmon_sysrq); 47 - #endif /* CONFIG_MAGIC_SYSRQ */ 48 - 49 - int 50 - xmon_write(void *handle, void *ptr, int nb) 17 + int xmon_write(void *ptr, int nb) 51 18 { 52 19 return udbg_write(ptr, nb); 53 20 } 54 21 55 - int 56 - xmon_read(void *handle, void *ptr, int nb) 22 + int xmon_readchar(void) 57 23 { 58 - return udbg_read(ptr, nb); 24 + if (udbg_getc) 25 + return udbg_getc(); 26 + return -1; 59 27 } 60 28 61 - int 62 - xmon_read_poll(void) 29 + int xmon_read_poll(void) 63 30 { 64 31 if (udbg_getc_poll) 65 32 return udbg_getc_poll(); 66 33 return -1; 67 - } 68 - 69 - FILE *xmon_stdin; 70 - FILE *xmon_stdout; 71 - 72 - int 73 - xmon_putc(int c, void *f) 74 - { 75 - char ch = c; 76 - 77 - if (c == '\n') 78 - xmon_putc('\r', f); 79 - return xmon_write(f, &ch, 1) == 1? c: -1; 80 - } 81 - 82 - int 83 - xmon_putchar(int c) 84 - { 85 - return xmon_putc(c, xmon_stdout); 86 - } 87 - 88 - int 89 - xmon_fputs(char *str, void *f) 90 - { 91 - int n = strlen(str); 92 - 93 - return xmon_write(f, str, n) == n? 0: -1; 94 - } 95 - 96 - int 97 - xmon_readchar(void) 98 - { 99 - char ch; 100 - 101 - for (;;) { 102 - switch (xmon_read(xmon_stdin, &ch, 1)) { 103 - case 1: 104 - return ch; 105 - case -1: 106 - xmon_printf("read(stdin) returned -1\r\n", 0, 0); 107 - return -1; 108 - } 109 - } 110 - } 111 - 112 - static char line[256]; 113 - static char *lineptr; 114 - static int lineleft; 115 - 116 - int 117 - xmon_getchar(void) 118 - { 119 - int c; 120 - 121 - if (lineleft == 0) { 122 - lineptr = line; 123 - for (;;) { 124 - c = xmon_readchar(); 125 - if (c == -1 || c == 4) 126 - break; 127 - if (c == '\r' || c == '\n') { 128 - *lineptr++ = '\n'; 129 - xmon_putchar('\n'); 130 - break; 131 - } 132 - switch (c) { 133 - case 0177: 134 - case '\b': 135 - if (lineptr > line) { 136 - xmon_putchar('\b'); 137 - xmon_putchar(' '); 138 - xmon_putchar('\b'); 139 - --lineptr; 140 - } 141 - break; 142 - case 'U' & 0x1F: 143 - while (lineptr > line) { 144 - xmon_putchar('\b'); 145 - xmon_putchar(' '); 146 - xmon_putchar('\b'); 147 - --lineptr; 148 - } 149 - break; 150 - default: 151 - if (lineptr >= &line[sizeof(line) - 1]) 152 - xmon_putchar('\a'); 153 - else { 154 - xmon_putchar(c); 155 - *lineptr++ = c; 156 - } 157 - } 158 - } 159 - lineleft = lineptr - line; 160 - lineptr = line; 161 - } 162 - if (lineleft == 0) 163 - return -1; 164 - --lineleft; 165 - return *lineptr++; 166 - } 167 - 168 - char * 169 - xmon_fgets(char *str, int nb, void *f) 170 - { 171 - char *p; 172 - int c; 173 - 174 - for (p = str; p < str + nb - 1; ) { 175 - c = xmon_getchar(); 176 - if (c == -1) { 177 - if (p == str) 178 - return NULL; 179 - break; 180 - } 181 - *p++ = c; 182 - if (c == '\n') 183 - break; 184 - } 185 - *p = 0; 186 - return str; 187 34 }
+6 -249
arch/powerpc/xmon/start_8xx.c
··· 15 15 #include <asm/8xx_immap.h> 16 16 #include <asm/mpc8xx.h> 17 17 #include <asm/commproc.h> 18 + #include "nonstdio.h" 18 19 19 - extern void xmon_printf(const char *fmt, ...); 20 20 extern int xmon_8xx_write(char *str, int nb); 21 21 extern int xmon_8xx_read_poll(void); 22 22 extern int xmon_8xx_read_char(void); 23 - void prom_drawhex(uint); 24 - void prom_drawstring(const char *str); 25 23 26 - static int use_screen = 1; /* default */ 27 - 28 - #define TB_SPEED 25000000 29 - 30 - static inline unsigned int readtb(void) 24 + void xmon_map_scc(void) 31 25 { 32 - unsigned int ret; 33 - 34 - asm volatile("mftb %0" : "=r" (ret) :); 35 - return ret; 36 - } 37 - 38 - void buf_access(void) 39 - { 40 - } 41 - 42 - void 43 - xmon_map_scc(void) 44 - { 45 - 46 26 cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); 47 - use_screen = 0; 48 - 49 - prom_drawstring("xmon uses serial port\n"); 50 27 } 51 - 52 - static int scc_initialized = 0; 53 28 54 29 void xmon_init_scc(void); 55 30 56 - int 57 - xmon_write(void *handle, void *ptr, int nb) 31 + int xmon_write(void *ptr, int nb) 58 32 { 59 - char *p = ptr; 60 - int i, c, ct; 61 - 62 - if (!scc_initialized) 63 - xmon_init_scc(); 64 - 65 33 return(xmon_8xx_write(ptr, nb)); 66 34 } 67 35 68 - int xmon_wants_key; 69 - 70 - int 71 - xmon_read(void *handle, void *ptr, int nb) 36 + int xmon_readchar(void) 72 37 { 73 - char *p = ptr; 74 - int i; 75 - 76 - if (!scc_initialized) 77 - xmon_init_scc(); 78 - 79 - for (i = 0; i < nb; ++i) { 80 - *p++ = xmon_8xx_read_char(); 81 - } 82 - return i; 38 + return xmon_8xx_read_char(); 83 39 } 84 40 85 - int 86 - xmon_read_poll(void) 41 + int xmon_read_poll(void) 87 42 { 88 43 return(xmon_8xx_read_poll()); 89 - } 90 - 91 - void 92 - xmon_init_scc() 93 - { 94 - scc_initialized = 1; 95 - } 96 - 97 - #if 0 98 - extern int (*prom_entry)(void *); 99 - 100 - int 101 - xmon_exit(void) 102 - { 103 - struct prom_args { 104 - char *service; 105 - } args; 106 - 107 - for (;;) { 108 - args.service = "exit"; 109 - (*prom_entry)(&args); 110 - } 111 - } 112 - #endif 113 - 114 - void *xmon_stdin; 115 - void *xmon_stdout; 116 - void *xmon_stderr; 117 - 118 - void 119 - xmon_init(void) 120 - { 121 - } 122 - 123 - int 124 - xmon_putc(int c, void *f) 125 - { 126 - char ch = c; 127 - 128 - if (c == '\n') 129 - xmon_putc('\r', f); 130 - return xmon_write(f, &ch, 1) == 1? c: -1; 131 - } 132 - 133 - int 134 - xmon_putchar(int c) 135 - { 136 - return xmon_putc(c, xmon_stdout); 137 - } 138 - 139 - int 140 - xmon_fputs(char *str, void *f) 141 - { 142 - int n = strlen(str); 143 - 144 - return xmon_write(f, str, n) == n? 0: -1; 145 - } 146 - 147 - int 148 - xmon_readchar(void) 149 - { 150 - char ch; 151 - 152 - for (;;) { 153 - switch (xmon_read(xmon_stdin, &ch, 1)) { 154 - case 1: 155 - return ch; 156 - case -1: 157 - xmon_printf("read(stdin) returned -1\r\n", 0, 0); 158 - return -1; 159 - } 160 - } 161 - } 162 - 163 - static char line[256]; 164 - static char *lineptr; 165 - static int lineleft; 166 - 167 - #if 0 168 - int xmon_expect(const char *str, unsigned int timeout) 169 - { 170 - int c; 171 - unsigned int t0; 172 - 173 - timeout *= TB_SPEED; 174 - t0 = readtb(); 175 - do { 176 - lineptr = line; 177 - for (;;) { 178 - c = xmon_read_poll(); 179 - if (c == -1) { 180 - if (readtb() - t0 > timeout) 181 - return 0; 182 - continue; 183 - } 184 - if (c == '\n') 185 - break; 186 - if (c != '\r' && lineptr < &line[sizeof(line) - 1]) 187 - *lineptr++ = c; 188 - } 189 - *lineptr = 0; 190 - } while (strstr(line, str) == NULL); 191 - return 1; 192 - } 193 - #endif 194 - 195 - int 196 - xmon_getchar(void) 197 - { 198 - int c; 199 - 200 - if (lineleft == 0) { 201 - lineptr = line; 202 - for (;;) { 203 - c = xmon_readchar(); 204 - if (c == -1 || c == 4) 205 - break; 206 - if (c == '\r' || c == '\n') { 207 - *lineptr++ = '\n'; 208 - xmon_putchar('\n'); 209 - break; 210 - } 211 - switch (c) { 212 - case 0177: 213 - case '\b': 214 - if (lineptr > line) { 215 - xmon_putchar('\b'); 216 - xmon_putchar(' '); 217 - xmon_putchar('\b'); 218 - --lineptr; 219 - } 220 - break; 221 - case 'U' & 0x1F: 222 - while (lineptr > line) { 223 - xmon_putchar('\b'); 224 - xmon_putchar(' '); 225 - xmon_putchar('\b'); 226 - --lineptr; 227 - } 228 - break; 229 - default: 230 - if (lineptr >= &line[sizeof(line) - 1]) 231 - xmon_putchar('\a'); 232 - else { 233 - xmon_putchar(c); 234 - *lineptr++ = c; 235 - } 236 - } 237 - } 238 - lineleft = lineptr - line; 239 - lineptr = line; 240 - } 241 - if (lineleft == 0) 242 - return -1; 243 - --lineleft; 244 - return *lineptr++; 245 - } 246 - 247 - char * 248 - xmon_fgets(char *str, int nb, void *f) 249 - { 250 - char *p; 251 - int c; 252 - 253 - for (p = str; p < str + nb - 1; ) { 254 - c = xmon_getchar(); 255 - if (c == -1) { 256 - if (p == str) 257 - return 0; 258 - break; 259 - } 260 - *p++ = c; 261 - if (c == '\n') 262 - break; 263 - } 264 - *p = 0; 265 - return str; 266 - } 267 - 268 - void 269 - prom_drawhex(uint val) 270 - { 271 - unsigned char buf[10]; 272 - 273 - int i; 274 - for (i = 7; i >= 0; i--) 275 - { 276 - buf[i] = "0123456789abcdef"[val & 0x0f]; 277 - val >>= 4; 278 - } 279 - buf[8] = '\0'; 280 - xmon_fputs(buf, xmon_stdout); 281 - } 282 - 283 - void 284 - prom_drawstring(const char *str) 285 - { 286 - xmon_fputs(str, xmon_stdout); 287 44 }
-54
arch/powerpc/xmon/subr_prf.c
··· 1 - /* 2 - * Written by Cort Dougan to replace the version originally used 3 - * by Paul Mackerras, which came from NetBSD and thus had copyright 4 - * conflicts with Linux. 5 - * 6 - * This file makes liberal use of the standard linux utility 7 - * routines to reduce the size of the binary. We assume we can 8 - * trust some parts of Linux inside the debugger. 9 - * -- Cort (cort@cs.nmt.edu) 10 - * 11 - * Copyright (C) 1999 Cort Dougan. 12 - * 13 - * This program is free software; you can redistribute it and/or 14 - * modify it under the terms of the GNU General Public License 15 - * as published by the Free Software Foundation; either version 16 - * 2 of the License, or (at your option) any later version. 17 - */ 18 - 19 - #include <linux/kernel.h> 20 - #include <linux/string.h> 21 - #include <linux/module.h> 22 - #include <stdarg.h> 23 - #include "nonstdio.h" 24 - 25 - extern int xmon_write(void *, void *, int); 26 - 27 - void xmon_vfprintf(void *f, const char *fmt, va_list ap) 28 - { 29 - static char xmon_buf[2048]; 30 - int n; 31 - 32 - n = vsprintf(xmon_buf, fmt, ap); 33 - xmon_write(f, xmon_buf, n); 34 - } 35 - 36 - void xmon_printf(const char *fmt, ...) 37 - { 38 - va_list ap; 39 - 40 - va_start(ap, fmt); 41 - xmon_vfprintf(stdout, fmt, ap); 42 - va_end(ap); 43 - } 44 - EXPORT_SYMBOL(xmon_printf); 45 - 46 - void xmon_fprintf(void *f, const char *fmt, ...) 47 - { 48 - va_list ap; 49 - 50 - va_start(ap, fmt); 51 - xmon_vfprintf(f, fmt, ap); 52 - va_end(ap); 53 - } 54 -
+28 -9
arch/powerpc/xmon/xmon.c
··· 1 1 /* 2 2 * Routines providing a simple monitor for use on the PowerMac. 3 3 * 4 - * Copyright (C) 1996 Paul Mackerras. 4 + * Copyright (C) 1996-2005 Paul Mackerras. 5 5 * 6 6 * This program is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License ··· 18 18 #include <linux/kallsyms.h> 19 19 #include <linux/cpumask.h> 20 20 #include <linux/module.h> 21 + #include <linux/sysrq.h> 21 22 22 23 #include <asm/ptrace.h> 23 24 #include <asm/string.h> ··· 145 144 static const char *getvecname(unsigned long vec); 146 145 147 146 extern int print_insn_powerpc(unsigned long, unsigned long, int); 148 - extern void printf(const char *fmt, ...); 149 - extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); 150 - extern int xmon_putc(int c, void *f); 151 - extern int putchar(int ch); 152 147 153 148 extern void xmon_enter(void); 154 149 extern void xmon_leave(void); 155 150 156 - extern int xmon_read_poll(void); 157 151 extern long setjmp(long *); 158 152 extern void longjmp(long *, long); 159 153 extern void xmon_save_regs(struct pt_regs *); ··· 744 748 printf("%x:", smp_processor_id()); 745 749 #endif /* CONFIG_SMP */ 746 750 printf("mon> "); 747 - fflush(stdout); 748 751 flush_input(); 749 752 termch = 0; 750 753 cmd = skipbl(); ··· 2146 2151 ok = mread(a, &v, 1); 2147 2152 if (ok && !ook) { 2148 2153 printf("%.8x .. ", a); 2149 - fflush(stdout); 2150 2154 } else if (!ok && ook) 2151 2155 printf("%.8x\n", a - mskip); 2152 2156 ook = ok; ··· 2366 2372 inchar(void) 2367 2373 { 2368 2374 if (lineptr == NULL || *lineptr == 0) { 2369 - if (fgets(line, sizeof(line), stdin) == NULL) { 2375 + if (xmon_gets(line, sizeof(line)) == NULL) { 2370 2376 lineptr = NULL; 2371 2377 return EOF; 2372 2378 } ··· 2520 2526 __debugger_dabr_match = NULL; 2521 2527 __debugger_fault_handler = NULL; 2522 2528 } 2529 + xmon_map_scc(); 2523 2530 } 2531 + 2532 + #ifdef CONFIG_MAGIC_SYSRQ 2533 + static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, 2534 + struct tty_struct *tty) 2535 + { 2536 + /* ensure xmon is enabled */ 2537 + xmon_init(1); 2538 + debugger(pt_regs); 2539 + } 2540 + 2541 + static struct sysrq_key_op sysrq_xmon_op = 2542 + { 2543 + .handler = sysrq_handle_xmon, 2544 + .help_msg = "Xmon", 2545 + .action_msg = "Entering xmon", 2546 + }; 2547 + 2548 + static int __init setup_xmon_sysrq(void) 2549 + { 2550 + register_sysrq_key('x', &sysrq_xmon_op); 2551 + return 0; 2552 + } 2553 + __initcall(setup_xmon_sysrq); 2554 + #endif /* CONFIG_MAGIC_SYSRQ */
-1
include/asm-powerpc/xmon.h
··· 7 7 extern int xmon(struct pt_regs *excp); 8 8 extern void xmon_printf(const char *fmt, ...); 9 9 extern void xmon_init(int); 10 - extern void xmon_map_scc(void); 11 10 12 11 #endif 13 12 #endif