Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * polling mode stateless debugging stuff, originally for NS16550 Serial Ports
0004  *
0005  * c 2001 PPC 64 Team, IBM Corp
0006  */
0007 
0008 #include <linux/stdarg.h>
0009 #include <linux/types.h>
0010 #include <linux/sched.h>
0011 #include <linux/console.h>
0012 #include <linux/init.h>
0013 #include <asm/processor.h>
0014 #include <asm/udbg.h>
0015 
0016 void (*udbg_putc)(char c);
0017 void (*udbg_flush)(void);
0018 int (*udbg_getc)(void);
0019 int (*udbg_getc_poll)(void);
0020 
0021 /*
0022  * Early debugging facilities. You can enable _one_ of these via .config,
0023  * if you do so your kernel _will not boot_ on anything else. Be careful.
0024  */
0025 void __init udbg_early_init(void)
0026 {
0027 #if defined(CONFIG_PPC_EARLY_DEBUG_LPAR)
0028     /* For LPAR machines that have an HVC console on vterm 0 */
0029     udbg_init_debug_lpar();
0030 #elif defined(CONFIG_PPC_EARLY_DEBUG_LPAR_HVSI)
0031     /* For LPAR machines that have an HVSI console on vterm 0 */
0032     udbg_init_debug_lpar_hvsi();
0033 #elif defined(CONFIG_PPC_EARLY_DEBUG_G5)
0034     /* For use on Apple G5 machines */
0035     udbg_init_pmac_realmode();
0036 #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL)
0037     /* RTAS panel debug */
0038     udbg_init_rtas_panel();
0039 #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE)
0040     /* RTAS console debug */
0041     udbg_init_rtas_console();
0042 #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE)
0043     /* Maple real mode debug */
0044     udbg_init_maple_realmode();
0045 #elif defined(CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE)
0046     udbg_init_pas_realmode();
0047 #elif defined(CONFIG_PPC_EARLY_DEBUG_BOOTX)
0048     udbg_init_btext();
0049 #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
0050     /* PPC44x debug */
0051     udbg_init_44x_as1();
0052 #elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
0053     /* PPC40x debug */
0054     udbg_init_40x_realmode();
0055 #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
0056     udbg_init_cpm();
0057 #elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
0058     udbg_init_usbgecko();
0059 #elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
0060     /* In memory console */
0061     udbg_init_memcons();
0062 #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
0063     udbg_init_ehv_bc();
0064 #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
0065     udbg_init_ps3gelic();
0066 #elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_RAW)
0067     udbg_init_debug_opal_raw();
0068 #elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI)
0069     udbg_init_debug_opal_hvsi();
0070 #endif
0071 
0072 #ifdef CONFIG_PPC_EARLY_DEBUG
0073     console_loglevel = CONSOLE_LOGLEVEL_DEBUG;
0074 
0075     register_early_udbg_console();
0076 #endif
0077 }
0078 
0079 /* udbg library, used by xmon et al */
0080 void udbg_puts(const char *s)
0081 {
0082     if (udbg_putc) {
0083         char c;
0084 
0085         if (s && *s != '\0') {
0086             while ((c = *s++) != '\0')
0087                 udbg_putc(c);
0088         }
0089 
0090         if (udbg_flush)
0091             udbg_flush();
0092     }
0093 #if 0
0094     else {
0095         printk("%s", s);
0096     }
0097 #endif
0098 }
0099 
0100 int udbg_write(const char *s, int n)
0101 {
0102     int remain = n;
0103     char c;
0104 
0105     if (!udbg_putc)
0106         return 0;
0107 
0108     if (s && *s != '\0') {
0109         while (((c = *s++) != '\0') && (remain-- > 0)) {
0110             udbg_putc(c);
0111         }
0112     }
0113 
0114     if (udbg_flush)
0115         udbg_flush();
0116 
0117     return n - remain;
0118 }
0119 
0120 #define UDBG_BUFSIZE 256
0121 void udbg_printf(const char *fmt, ...)
0122 {
0123     if (udbg_putc) {
0124         char buf[UDBG_BUFSIZE];
0125         va_list args;
0126 
0127         va_start(args, fmt);
0128         vsnprintf(buf, UDBG_BUFSIZE, fmt, args);
0129         udbg_puts(buf);
0130         va_end(args);
0131     }
0132 }
0133 
0134 void __init udbg_progress(char *s, unsigned short hex)
0135 {
0136     udbg_puts(s);
0137     udbg_puts("\n");
0138 }
0139 
0140 /*
0141  * Early boot console based on udbg
0142  */
0143 static void udbg_console_write(struct console *con, const char *s,
0144         unsigned int n)
0145 {
0146     udbg_write(s, n);
0147 }
0148 
0149 static struct console udbg_console = {
0150     .name   = "udbg",
0151     .write  = udbg_console_write,
0152     .flags  = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME,
0153     .index  = 0,
0154 };
0155 
0156 /*
0157  * Called by setup_system after ppc_md->probe and ppc_md->early_init.
0158  * Call it again after setting udbg_putc in ppc_md->setup_arch.
0159  */
0160 void __init register_early_udbg_console(void)
0161 {
0162     if (early_console)
0163         return;
0164 
0165     if (!udbg_putc)
0166         return;
0167 
0168     if (strstr(boot_command_line, "udbg-immortal")) {
0169         printk(KERN_INFO "early console immortal !\n");
0170         udbg_console.flags &= ~CON_BOOT;
0171     }
0172     early_console = &udbg_console;
0173     register_console(&udbg_console);
0174 }
0175 
0176 #if 0   /* if you want to use this as a regular output console */
0177 console_initcall(register_udbg_console);
0178 #endif