Эх сурвалжийг харах

[POWERPC] 4xx: Add early udbg support for 40x processors

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>
Benjamin Herrenschmidt 17 жил өмнө
parent
commit
9dae8afdf2

+ 13 - 0
arch/powerpc/Kconfig.debug

@@ -227,6 +227,14 @@ config PPC_EARLY_DEBUG_44x
 	  Select this to enable early debugging for IBM 44x chips via the
 	  Select this to enable early debugging for IBM 44x chips via the
 	  inbuilt serial port.
 	  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
 config PPC_EARLY_DEBUG_CPM
 	bool "Early serial debugging for Freescale CPM-based serial ports"
 	bool "Early serial debugging for Freescale CPM-based serial ports"
 	depends on SERIAL_CPM
 	depends on SERIAL_CPM
@@ -248,6 +256,11 @@ config PPC_EARLY_DEBUG_44x_PHYSHIGH
 	depends on PPC_EARLY_DEBUG_44x
 	depends on PPC_EARLY_DEBUG_44x
 	default "0x1"
 	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
 config PPC_EARLY_DEBUG_CPM_ADDR
 	hex "CPM UART early debug transmit descriptor address"
 	hex "CPM UART early debug transmit descriptor address"
 	depends on PPC_EARLY_DEBUG_CPM
 	depends on PPC_EARLY_DEBUG_CPM

+ 39 - 0
arch/powerpc/kernel/misc_32.S

@@ -206,6 +206,45 @@ _GLOBAL(_nmask_and_or_msr)
 	isync
 	isync
 	blr			/* Done */
 	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

+ 3 - 0
arch/powerpc/kernel/udbg.c

@@ -54,6 +54,9 @@ void __init udbg_early_init(void)
 #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
 #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
 	/* PPC44x debug */
 	/* PPC44x debug */
 	udbg_init_44x_as1();
 	udbg_init_44x_as1();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
+	/* PPC40x debug */
+	udbg_init_40x_realmode();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
 #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
 	udbg_init_cpm();
 	udbg_init_cpm();
 #endif
 #endif

+ 33 - 0
arch/powerpc/kernel/udbg_16550.c

@@ -225,3 +225,36 @@ void __init udbg_init_44x_as1(void)
 	udbg_getc = udbg_44x_as1_getc;
 	udbg_getc = udbg_44x_as1_getc;
 }
 }
 #endif /* CONFIG_PPC_EARLY_DEBUG_44x */
 #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 */

+ 1 - 0
arch/powerpc/platforms/Kconfig.cputype

@@ -43,6 +43,7 @@ config 40x
 	bool "AMCC 40x"
 	bool "AMCC 40x"
 	select PPC_DCR_NATIVE
 	select PPC_DCR_NATIVE
 	select WANT_DEVICE_TREE
 	select WANT_DEVICE_TREE
+	select PPC_UDBG_16550
 
 
 config 44x
 config 44x
 	bool "AMCC 44x"
 	bool "AMCC 44x"

+ 1 - 0
include/asm-powerpc/udbg.h

@@ -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_debug_beat(void);
 extern void __init udbg_init_btext(void);
 extern void __init udbg_init_btext(void);
 extern void __init udbg_init_44x_as1(void);
 extern void __init udbg_init_44x_as1(void);
+extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_cpm(void);
 
 
 #endif /* __KERNEL__ */
 #endif /* __KERNEL__ */