]> git.itanic.dy.fi Git - linux-stable/commitdiff
powerpc: Add support for early debugging via Serial 16550 console
authorPali Rohár <pali@kernel.org>
Mon, 22 Aug 2022 23:15:01 +0000 (01:15 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 28 Sep 2022 09:22:09 +0000 (19:22 +1000)
Currently powerpc early debugging contains lot of platform specific
options, but does not support standard UART / serial 16550 console.

Later legacy_serial.c code supports registering UART as early debug console
from device tree but it is not early during booting, but rather later after
machine description code finishes.

So for real early debugging via UART is current code unsuitable.

Add support for new early debugging option CONFIG_PPC_EARLY_DEBUG_16550
which enable Serial 16550 console on address defined by new option
CONFIG_PPC_EARLY_DEBUG_16550_PHYSADDR and by stride by option
CONFIG_PPC_EARLY_DEBUG_16550_STRIDE.

With this change it is possible to debug powerpc machine descriptor code.
For example this early debugging code can print on serial console also
"No suitable machine description found" error which is done before
legacy_serial.c code.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220822231501.16827-1-pali@kernel.org
arch/powerpc/Kconfig.debug
arch/powerpc/include/asm/udbg.h
arch/powerpc/kernel/udbg.c
arch/powerpc/kernel/udbg_16550.c

index ae727d4218b90a5f9e8f246b3a8973eda87ad40e..6aaf8dc60610d1ce9be9be4680672c8a86096781 100644 (file)
@@ -283,6 +283,12 @@ config PPC_EARLY_DEBUG_MEMCONS
          This console provides input and output buffers stored within the
          kernel BSS and should be safe to select on any system. A debugger
          can then be used to read kernel output or send input to the console.
+
+config PPC_EARLY_DEBUG_16550
+       bool "Serial 16550"
+       depends on PPC_UDBG_16550
+       help
+         Select this to enable early debugging via Serial 16550 console
 endchoice
 
 config PPC_MEMCONS_OUTPUT_SIZE
@@ -354,6 +360,15 @@ config PPC_EARLY_DEBUG_CPM_ADDR
          platform probing is done, all platforms selected must
          share the same address.
 
+config PPC_EARLY_DEBUG_16550_PHYSADDR
+       hex "Early debug Serial 16550 physical address"
+       depends on PPC_EARLY_DEBUG_16550
+
+config PPC_EARLY_DEBUG_16550_STRIDE
+       int "Early debug Serial 16550 stride"
+       depends on PPC_EARLY_DEBUG_16550
+       default 1
+
 config FAIL_IOMMU
        bool "Fault-injection capability for IOMMU"
        depends on FAULT_INJECTION
index 524c2085070fc8cbedd6e9c9324faedf0b428be7..88add5593e6f06d25ec7cbf3d7338694f26ce45d 100644 (file)
@@ -52,6 +52,7 @@ extern void __init udbg_init_ehv_bc(void);
 extern void __init udbg_init_ps3gelic(void);
 extern void __init udbg_init_debug_opal_raw(void);
 extern void __init udbg_init_debug_opal_hvsi(void);
+extern void __init udbg_init_debug_16550(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
index b1544b2f6321b2746ef553ad5e30dd14eda49d40..92b3fc258d1108fd66c3d411211c4878a84b341e 100644 (file)
@@ -67,6 +67,8 @@ void __init udbg_early_init(void)
        udbg_init_debug_opal_raw();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI)
        udbg_init_debug_opal_hvsi();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_16550)
+       udbg_init_debug_16550();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
index ddfbc74bf85fcd0c43257d71bb1465a5507ce34a..74ddf836f7a264ed37fdaa14f64cb06eede4d2dc 100644 (file)
@@ -8,6 +8,7 @@
 #include <asm/udbg.h>
 #include <asm/io.h>
 #include <asm/reg_a2.h>
+#include <asm/early_ioremap.h>
 
 extern u8 real_readb(volatile u8 __iomem  *addr);
 extern void real_writeb(u8 data, volatile u8 __iomem *addr);
@@ -296,3 +297,35 @@ void __init udbg_init_40x_realmode(void)
 }
 
 #endif /* CONFIG_PPC_EARLY_DEBUG_40x */
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_16550
+
+static void __iomem *udbg_uart_early_addr;
+
+void __init udbg_init_debug_16550(void)
+{
+       udbg_uart_early_addr = early_ioremap(CONFIG_PPC_EARLY_DEBUG_16550_PHYSADDR, 0x1000);
+       udbg_uart_init_mmio(udbg_uart_early_addr, CONFIG_PPC_EARLY_DEBUG_16550_STRIDE);
+}
+
+static int __init udbg_init_debug_16550_ioremap(void)
+{
+       void __iomem *addr;
+
+       if (!udbg_uart_early_addr)
+               return 0;
+
+       addr = ioremap(CONFIG_PPC_EARLY_DEBUG_16550_PHYSADDR, 0x1000);
+       if (WARN_ON(!addr))
+               return -ENOMEM;
+
+       udbg_uart_init_mmio(addr, CONFIG_PPC_EARLY_DEBUG_16550_STRIDE);
+       early_iounmap(udbg_uart_early_addr, 0x1000);
+       udbg_uart_early_addr = NULL;
+
+       return 0;
+}
+
+early_initcall(udbg_init_debug_16550_ioremap);
+
+#endif /* CONFIG_PPC_EARLY_DEBUG_16550 */