[POWERPC] 4xx: Add early udbg support for 40x processors
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 21 Dec 2007 04:39:26 +0000 (15:39 +1100)
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>
Sun, 23 Dec 2007 19:13:03 +0000 (13:13 -0600)
This adds some basic real mode based early udbg support for 40x
in order to debug things more easily

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
arch/powerpc/Kconfig.debug
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/udbg.c
arch/powerpc/kernel/udbg_16550.c
arch/powerpc/platforms/Kconfig.cputype
include/asm-powerpc/udbg.h

index d20ccf5f2ca99cc1f06ab37e809a4984a547f596..179a453f7e04323148ccec6ead957bd9ef2a6cf8 100644 (file)
@@ -227,6 +227,14 @@ config PPC_EARLY_DEBUG_44x
          Select this to enable early debugging for IBM 44x chips via the
          inbuilt serial port.
 
          Select this to enable early debugging for IBM 44x chips via the
          inbuilt serial port.
 
+config PPC_EARLY_DEBUG_40x
+       bool "Early serial debugging for IBM/AMCC 40x CPUs"
+       depends on 40x
+       help
+         Select this to enable early debugging for IBM 40x chips via the
+         inbuilt serial port. This works on chips with a 16550 compatible
+         UART. Xilinx chips with uartlite cannot use this option.
+
 config PPC_EARLY_DEBUG_CPM
        bool "Early serial debugging for Freescale CPM-based serial ports"
        depends on SERIAL_CPM
 config PPC_EARLY_DEBUG_CPM
        bool "Early serial debugging for Freescale CPM-based serial ports"
        depends on SERIAL_CPM
@@ -248,6 +256,11 @@ config PPC_EARLY_DEBUG_44x_PHYSHIGH
        depends on PPC_EARLY_DEBUG_44x
        default "0x1"
 
        depends on PPC_EARLY_DEBUG_44x
        default "0x1"
 
+config PPC_EARLY_DEBUG_40x_PHYSADDR
+       hex "Early debug UART physical address"
+       depends on PPC_EARLY_DEBUG_40x
+       default "0xef600300"
+
 config PPC_EARLY_DEBUG_CPM_ADDR
        hex "CPM UART early debug transmit descriptor address"
        depends on PPC_EARLY_DEBUG_CPM
 config PPC_EARLY_DEBUG_CPM_ADDR
        hex "CPM UART early debug transmit descriptor address"
        depends on PPC_EARLY_DEBUG_CPM
index ea1137851a4adc4a6ae7adfcba8aa74ed303340c..be09f0d2d90b27802d9687ae05bb1795957815ea 100644 (file)
@@ -206,6 +206,45 @@ _GLOBAL(_nmask_and_or_msr)
        isync
        blr                     /* Done */
 
        isync
        blr                     /* Done */
 
+#ifdef CONFIG_40x
+
+/*
+ * Do an IO access in real mode
+ */
+_GLOBAL(real_readb)
+       mfmsr   r7
+       ori     r0,r7,MSR_DR
+       xori    r0,r0,MSR_DR
+       sync
+       mtmsr   r0
+       sync
+       isync
+       lbz     r3,0(r3)
+       sync
+       mtmsr   r7
+       sync
+       isync
+       blr
+
+       /*
+ * Do an IO access in real mode
+ */
+_GLOBAL(real_writeb)
+       mfmsr   r7
+       ori     r0,r7,MSR_DR
+       xori    r0,r0,MSR_DR
+       sync
+       mtmsr   r0
+       sync
+       isync
+       stb     r3,0(r4)
+       sync
+       mtmsr   r7
+       sync
+       isync
+       blr
+
+#endif /* CONFIG_40x */
 
 /*
  * Flush MMU TLB
 
 /*
  * Flush MMU TLB
index eba148f2a31c09b7b65a68def74628b4987c3815..7aad6203e411e926580dba0517deb918d3558a83 100644 (file)
@@ -54,6 +54,9 @@ void __init udbg_early_init(void)
 #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
        /* PPC44x debug */
        udbg_init_44x_as1();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
        /* PPC44x debug */
        udbg_init_44x_as1();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
+       /* PPC40x debug */
+       udbg_init_40x_realmode();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
        udbg_init_cpm();
 #endif
 #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
        udbg_init_cpm();
 #endif
index df740eae77b856edc047ad4324df2dd1f579a991..cb01ebc593876b5736cc96640904a8117a5da3c6 100644 (file)
@@ -225,3 +225,36 @@ void __init udbg_init_44x_as1(void)
        udbg_getc = udbg_44x_as1_getc;
 }
 #endif /* CONFIG_PPC_EARLY_DEBUG_44x */
        udbg_getc = udbg_44x_as1_getc;
 }
 #endif /* CONFIG_PPC_EARLY_DEBUG_44x */
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_40x
+static void udbg_40x_real_putc(char c)
+{
+       if (udbg_comport) {
+               while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
+                       /* wait for idle */;
+               real_writeb(c, &udbg_comport->thr); eieio();
+               if (c == '\n')
+                       udbg_40x_real_putc('\r');
+       }
+}
+
+static int udbg_40x_real_getc(void)
+{
+       if (udbg_comport) {
+               while ((real_readb(&udbg_comport->lsr) & LSR_DR) == 0)
+                       ; /* wait for char */
+               return real_readb(&udbg_comport->rbr);
+       }
+       return -1;
+}
+
+void __init udbg_init_40x_realmode(void)
+{
+       udbg_comport = (struct NS16550 __iomem *)
+               CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR;
+
+       udbg_putc = udbg_40x_real_putc;
+       udbg_getc = udbg_40x_real_getc;
+       udbg_getc_poll = NULL;
+}
+#endif /* CONFIG_PPC_EARLY_DEBUG_40x */
index 99684ea606afef4b399a46ab1e059baef6002767..c3ee0b58d539da470f305114e41d90ee29731e25 100644 (file)
@@ -43,6 +43,7 @@ config 40x
        bool "AMCC 40x"
        select PPC_DCR_NATIVE
        select WANT_DEVICE_TREE
        bool "AMCC 40x"
        select PPC_DCR_NATIVE
        select WANT_DEVICE_TREE
+       select PPC_UDBG_16550
 
 config 44x
        bool "AMCC 44x"
 
 config 44x
        bool "AMCC 44x"
index a9e0b0ebcb0fe33cd8070f84a60e1a2a8b2ab020..6418ceea44b70f27d69027b3a30ee85d8bd4b3fd 100644 (file)
@@ -48,6 +48,7 @@ extern void __init udbg_init_rtas_console(void);
 extern void __init udbg_init_debug_beat(void);
 extern void __init udbg_init_btext(void);
 extern void __init udbg_init_44x_as1(void);
 extern void __init udbg_init_debug_beat(void);
 extern void __init udbg_init_btext(void);
 extern void __init udbg_init_44x_as1(void);
+extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 
 #endif /* __KERNEL__ */
 extern void __init udbg_init_cpm(void);
 
 #endif /* __KERNEL__ */