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_PAS_REALMODE)
  50        udbg_init_pas_realmode();
  51#elif defined(CONFIG_PPC_EARLY_DEBUG_BOOTX)
  52        udbg_init_btext();
  53#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
  54        /* PPC44x debug */
  55        udbg_init_44x_as1();
  56#elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
  57        /* PPC40x debug */
  58        udbg_init_40x_realmode();
  59#elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
  60        udbg_init_cpm();
  61#elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
  62        udbg_init_usbgecko();
  63#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
  64        /* In memory console */
  65        udbg_init_memcons();
  66#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
  67        udbg_init_ehv_bc();
  68#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
  69        udbg_init_ps3gelic();
  70#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_RAW)
  71        udbg_init_debug_opal_raw();
  72#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI)
  73        udbg_init_debug_opal_hvsi();
  74#endif
  75
  76#ifdef CONFIG_PPC_EARLY_DEBUG
  77        console_loglevel = 10;
  78
  79        register_early_udbg_console();
  80#endif
  81}
  82
  83/* udbg library, used by xmon et al */
  84void udbg_puts(const char *s)
  85{
  86        if (udbg_putc) {
  87                char c;
  88
  89                if (s && *s != '\0') {
  90                        while ((c = *s++) != '\0')
  91                                udbg_putc(c);
  92                }
  93
  94                if (udbg_flush)
  95                        udbg_flush();
  96        }
  97#if 0
  98        else {
  99                printk("%s", s);
 100        }
 101#endif
 102}
 103
 104int udbg_write(const char *s, int n)
 105{
 106        int remain = n;
 107        char c;
 108
 109        if (!udbg_putc)
 110                return 0;
 111
 112        if (s && *s != '\0') {
 113                while (((c = *s++) != '\0') && (remain-- > 0)) {
 114                        udbg_putc(c);
 115                }
 116        }
 117
 118        if (udbg_flush)
 119                udbg_flush();
 120
 121        return n - remain;
 122}
 123
 124#define UDBG_BUFSIZE 256
 125void udbg_printf(const char *fmt, ...)
 126{
 127        char buf[UDBG_BUFSIZE];
 128        va_list args;
 129
 130        va_start(args, fmt);
 131        vsnprintf(buf, UDBG_BUFSIZE, fmt, args);
 132        udbg_puts(buf);
 133        va_end(args);
 134}
 135
 136void __init udbg_progress(char *s, unsigned short hex)
 137{
 138        udbg_puts(s);
 139        udbg_puts("\n");
 140}
 141
 142/*
 143 * Early boot console based on udbg
 144 */
 145static void udbg_console_write(struct console *con, const char *s,
 146                unsigned int n)
 147{
 148        udbg_write(s, n);
 149}
 150
 151static struct console udbg_console = {
 152        .name   = "udbg",
 153        .write  = udbg_console_write,
 154        .flags  = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME,
 155        .index  = 0,
 156};
 157
 158/*
 159 * Called by setup_system after ppc_md->probe and ppc_md->early_init.
 160 * Call it again after setting udbg_putc in ppc_md->setup_arch.
 161 */
 162void __init register_early_udbg_console(void)
 163{
 164        if (early_console)
 165                return;
 166
 167        if (!udbg_putc)
 168                return;
 169
 170        if (strstr(boot_command_line, "udbg-immortal")) {
 171                printk(KERN_INFO "early console immortal !\n");
 172                udbg_console.flags &= ~CON_BOOT;
 173        }
 174        early_console = &udbg_console;
 175        register_console(&udbg_console);
 176}
 177
 178#if 0   /* if you want to use this as a regular output console */
 179console_initcall(register_udbg_console);
 180#endif
 181