linux/arch/powerpc/kernel/udbg.c
<<
>>
Prefs
   1/*
   2 * polling mode stateless debugging stuff, originally for NS16550 Serial Ports
   3 *
   4 * c 2001 PPC 64 Team, IBM Corp
   5 *
   6 *      This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License
   8 *      as published by the Free Software Foundation; either version
   9 *      2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <stdarg.h>
  13#include <linux/types.h>
  14#include <linux/sched.h>
  15#include <linux/console.h>
  16#include <linux/init.h>
  17#include <asm/processor.h>
  18#include <asm/udbg.h>
  19
  20void (*udbg_putc)(char c);
  21void (*udbg_flush)(void);
  22int (*udbg_getc)(void);
  23int (*udbg_getc_poll)(void);
  24
  25/*
  26 * Early debugging facilities. You can enable _one_ of these via .config,
  27 * if you do so your kernel _will not boot_ on anything else. Be careful.
  28 */
  29void __init udbg_early_init(void)
  30{
  31#if defined(CONFIG_PPC_EARLY_DEBUG_LPAR)
  32        /* For LPAR machines that have an HVC console on vterm 0 */
  33        udbg_init_debug_lpar();
  34#elif defined(CONFIG_PPC_EARLY_DEBUG_LPAR_HVSI)
  35        /* For LPAR machines that have an HVSI console on vterm 0 */
  36        udbg_init_debug_lpar_hvsi();
  37#elif defined(CONFIG_PPC_EARLY_DEBUG_G5)
  38        /* For use on Apple G5 machines */
  39        udbg_init_pmac_realmode();
  40#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL)
  41        /* RTAS panel debug */
  42        udbg_init_rtas_panel();
  43#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE)
  44        /* RTAS console debug */
  45        udbg_init_rtas_console();
  46#elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE)
  47        /* Maple real mode debug */
  48        udbg_init_maple_realmode();
  49#elif defined(CONFIG_PPC_EARLY_DEBUG_BEAT)
  50        udbg_init_debug_beat();
  51#elif defined(CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE)
  52        udbg_init_pas_realmode();
  53#elif defined(CONFIG_PPC_EARLY_DEBUG_BOOTX)
  54        udbg_init_btext();
  55#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
  56        /* PPC44x debug */
  57        udbg_init_44x_as1();
  58#elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
  59        /* PPC40x debug */
  60        udbg_init_40x_realmode();
  61#elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
  62        udbg_init_cpm();
  63#elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
  64        udbg_init_usbgecko();
  65#elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
  66        udbg_init_wsp();
  67#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
  68        /* In memory console */
  69        udbg_init_memcons();
  70#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
  71        udbg_init_ehv_bc();
  72#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
  73        udbg_init_ps3gelic();
  74#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_RAW)
  75        udbg_init_debug_opal_raw();
  76#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI)
  77        udbg_init_debug_opal_hvsi();
  78#endif
  79
  80#ifdef CONFIG_PPC_EARLY_DEBUG
  81        console_loglevel = 10;
  82
  83        register_early_udbg_console();
  84#endif
  85}
  86
  87/* udbg library, used by xmon et al */
  88void udbg_puts(const char *s)
  89{
  90        if (udbg_putc) {
  91                char c;
  92
  93                if (s && *s != '\0') {
  94                        while ((c = *s++) != '\0')
  95                                udbg_putc(c);
  96                }
  97
  98                if (udbg_flush)
  99                        udbg_flush();
 100        }
 101#if 0
 102        else {
 103                printk("%s", s);
 104        }
 105#endif
 106}
 107
 108int udbg_write(const char *s, int n)
 109{
 110        int remain = n;
 111        char c;
 112
 113        if (!udbg_putc)
 114                return 0;
 115
 116        if (s && *s != '\0') {
 117                while (((c = *s++) != '\0') && (remain-- > 0)) {
 118                        udbg_putc(c);
 119                }
 120        }
 121
 122        if (udbg_flush)
 123                udbg_flush();
 124
 125        return n - remain;
 126}
 127
 128#define UDBG_BUFSIZE 256
 129void udbg_printf(const char *fmt, ...)
 130{
 131        char buf[UDBG_BUFSIZE];
 132        va_list args;
 133
 134        va_start(args, fmt);
 135        vsnprintf(buf, UDBG_BUFSIZE, fmt, args);
 136        udbg_puts(buf);
 137        va_end(args);
 138}
 139
 140void __init udbg_progress(char *s, unsigned short hex)
 141{
 142        udbg_puts(s);
 143        udbg_puts("\n");
 144}
 145
 146/*
 147 * Early boot console based on udbg
 148 */
 149static void udbg_console_write(struct console *con, const char *s,
 150                unsigned int n)
 151{
 152        udbg_write(s, n);
 153}
 154
 155static struct console udbg_console = {
 156        .name   = "udbg",
 157        .write  = udbg_console_write,
 158        .flags  = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME,
 159        .index  = 0,
 160};
 161
 162/*
 163 * Called by setup_system after ppc_md->probe and ppc_md->early_init.
 164 * Call it again after setting udbg_putc in ppc_md->setup_arch.
 165 */
 166void __init register_early_udbg_console(void)
 167{
 168        if (early_console)
 169                return;
 170
 171        if (!udbg_putc)
 172                return;
 173
 174        if (strstr(boot_command_line, "udbg-immortal")) {
 175                printk(KERN_INFO "early console immortal !\n");
 176                udbg_console.flags &= ~CON_BOOT;
 177        }
 178        early_console = &udbg_console;
 179        register_console(&udbg_console);
 180}
 181
 182#if 0   /* if you want to use this as a regular output console */
 183console_initcall(register_udbg_console);
 184#endif
 185