[9/9] ARM: vexpress: Config option for early printk console
diff mbox

Message ID 1342013791-19516-10-git-send-email-pawel.moll@arm.com
State New, archived
Headers show

Commit Message

Pawel Moll July 11, 2012, 1:36 p.m. UTC
Versatile Express platform can be used in different configuartion,
the console UART used by early printk may be located at different
addresses in the address space.

This patch makes it possible to select base address of a PL011 UART
to be used as a console output in the kernel configuration. The
default behaviour is still the heuristic detecting memory map
on Cortex-A core tiles.

The zImage decompressor will use the same configuration values
or print out nothing if DEBUG_LL is not enabled.

Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
 arch/arm/Kconfig.debug                            |   26 ++++++++++++
 arch/arm/mach-vexpress/include/mach/debug-macro.S |   44 +++++++++++++++++++++
 arch/arm/mach-vexpress/include/mach/uncompress.h  |   14 +++++++
 3 files changed, 84 insertions(+)

Comments

Will Deacon July 11, 2012, 2:09 p.m. UTC | #1
Hi Pawel,

On Wed, Jul 11, 2012 at 02:36:31PM +0100, Pawel Moll wrote:
> +#else /* CONFIG_DEBUG_LL_UART_NONE */
> +
> +		.macro	addruart, rp, rv, tmp
> +		/*
> +		 * Have to provide reasonable dummy values,
> +		 * otherwise code in head.S crashes badly...
> +		 */
> +		mov	\rp, #0
> +		mov	\rv, #0
> +		.endm

Eek, this means we take out an I/O section mapping at zero, doesn't it?
Is that really a good idea? It scares me because (a) it's below PAGE_OFFSET
and (b) we don't know consistently what's at physical address 0.

Perhaps we could change head.S to avoid the mapping if addruart returns a
NULL virtual address?

Will
Pawel Moll July 11, 2012, 2:16 p.m. UTC | #2
On Wed, 2012-07-11 at 15:09 +0100, Will Deacon wrote:
> > +#else /* CONFIG_DEBUG_LL_UART_NONE */
> > +
> > +		.macro	addruart, rp, rv, tmp
> > +		/*
> > +		 * Have to provide reasonable dummy values,
> > +		 * otherwise code in head.S crashes badly...
> > +		 */
> > +		mov	\rp, #0
> > +		mov	\rv, #0
> > +		.endm
> 
> Eek, this means we take out an I/O section mapping at zero, doesn't it?
> Is that really a good idea? It scares me because (a) it's below PAGE_OFFSET
> and (b) we don't know consistently what's at physical address 0.
> 
> Perhaps we could change head.S to avoid the mapping if addruart returns a
> NULL virtual address?

Sure (care to prepare a patch? ;-), but this will have to go through
Russell not arm-soc, so it won't be a part of this update. And I'll
remove the comment...

Cheers!

Pawe?
Jonathan Austin July 11, 2012, 2:23 p.m. UTC | #3
Hi Pawel,

On 11/07/12 14:36, Pawel Moll wrote:
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index 01a1341..12eee87 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -310,6 +310,32 @@ choice
>  		  The uncompressor code port configuration is now handled
>  		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
>  
> +	config DEBUG_VEXPRESS_UART0_DETECT
> +		bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
> +		depends on ARCH_VEXPRESS
> +		help
> +		  This option enables simple heuristic which tries to determine
> +		  motherboard's memory map variant (original or RS1) and then
> +		  choose relevant UART0 base address.
> +
> +		  Note that this will only work with standard A-class core tiles,
> +		  and may fail with non-standard SMM or custom software model.
> +

Is it possible to make this depend on something like CPU_CP15_MMU,
instead of ARCH_VEXPRESS? Seems like a reasonable way to ensure that
this isn't used on some of the core tiles that don't have the required
cp15 registers to read the Configuration Base Address Register.

Jonny
Pawel Moll July 11, 2012, 2:23 p.m. UTC | #4
On Wed, 2012-07-11 at 15:16 +0100, Pawel Moll wrote:
> On Wed, 2012-07-11 at 15:09 +0100, Will Deacon wrote:
> > > +#else /* CONFIG_DEBUG_LL_UART_NONE */
> > > +
> > > +		.macro	addruart, rp, rv, tmp
> > > +		/*
> > > +		 * Have to provide reasonable dummy values,
> > > +		 * otherwise code in head.S crashes badly...
> > > +		 */
> > > +		mov	\rp, #0
> > > +		mov	\rv, #0
> > > +		.endm
> > 
> > Eek, this means we take out an I/O section mapping at zero, doesn't it?
> > Is that really a good idea? It scares me because (a) it's below PAGE_OFFSET
> > and (b) we don't know consistently what's at physical address 0.
> > 
> > Perhaps we could change head.S to avoid the mapping if addruart returns a
> > NULL virtual address?
> 
> Sure (care to prepare a patch? ;-), but this will have to go through
> Russell not arm-soc, so it won't be a part of this update. And I'll
> remove the comment...

... and use DEBUG_LL_VIRT_BASE as the \rv for now, before the change in
head.S happen. Physical 0 on VE is always flash, so it's not a problem.

Pawel
Pawel Moll July 11, 2012, 2:24 p.m. UTC | #5
On Wed, 2012-07-11 at 15:23 +0100, Jonathan Austin wrote:
> Hi Pawel,
> 
> On 11/07/12 14:36, Pawel Moll wrote:
> > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> > index 01a1341..12eee87 100644
> > --- a/arch/arm/Kconfig.debug
> > +++ b/arch/arm/Kconfig.debug
> > @@ -310,6 +310,32 @@ choice
> >  		  The uncompressor code port configuration is now handled
> >  		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
> >  
> > +	config DEBUG_VEXPRESS_UART0_DETECT
> > +		bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
> > +		depends on ARCH_VEXPRESS
> > +		help
> > +		  This option enables simple heuristic which tries to determine
> > +		  motherboard's memory map variant (original or RS1) and then
> > +		  choose relevant UART0 base address.
> > +
> > +		  Note that this will only work with standard A-class core tiles,
> > +		  and may fail with non-standard SMM or custom software model.
> > +
> 
> Is it possible to make this depend on something like CPU_CP15_MMU,
> instead of ARCH_VEXPRESS? Seems like a reasonable way to ensure that
> this isn't used on some of the core tiles that don't have the required
> cp15 registers to read the Configuration Base Address Register.

Yes, sure, I forgot about this! Sorry, will post v2 in a second.

Pawel

Patch
diff mbox

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 01a1341..12eee87 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -310,6 +310,32 @@  choice
 		  The uncompressor code port configuration is now handled
 		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
 
+	config DEBUG_VEXPRESS_UART0_DETECT
+		bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
+		depends on ARCH_VEXPRESS
+		help
+		  This option enables simple heuristic which tries to determine
+		  motherboard's memory map variant (original or RS1) and then
+		  choose relevant UART0 base address.
+
+		  Note that this will only work with standard A-class core tiles,
+		  and may fail with non-standard SMM or custom software model.
+
+	config DEBUG_VEXPRESS_UART0_CA9
+		bool "Use PL011 UART0 at 0x10009000 (V2P-CA9 core tile)"
+		depends on ARCH_VEXPRESS
+		help
+		  This option selects UART0 at 0x10009000. Except for custom models,
+		  this applies only to V2P-CA9 tile.
+
+	config DEBUG_VEXPRESS_UART0_RS1
+		bool "Use PL011 UART0 at 0x1c090000 (RS1 complaint tiles)"
+		depends on ARCH_VEXPRESS
+		help
+		  This option selects UART0 at 0x1c090000. This applies to most
+		  of the tiles using RS1 memory map, including all new A-class
+		  core tiles, FPGA-based SMMs and software models.
+
 	config DEBUG_LL_UART_NONE
 		bool "No low-level debugging UART"
 		help
diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S
index fa82247..1980239 100644
--- a/arch/arm/mach-vexpress/include/mach/debug-macro.S
+++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S
@@ -18,6 +18,8 @@ 
 
 #define DEBUG_LL_VIRT_BASE		0xf8000000
 
+#if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT)
+
 		.macro	addruart,rp,rv,tmp
 
 		@ Make an educated guess regarding the memory map:
@@ -41,3 +43,45 @@ 
 		.endm
 
 #include <asm/hardware/debug-pl01x.S>
+
+#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CA9)
+
+		.macro	addruart,rp,rv,tmp
+		mov	\rp, #DEBUG_LL_UART_OFFSET
+		orr	\rv, \rp, #DEBUG_LL_VIRT_BASE
+		orr	\rp, \rp, #DEBUG_LL_PHYS_BASE
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
+
+#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_RS1)
+
+		.macro	addruart,rp,rv,tmp
+		mov	\rp, #DEBUG_LL_UART_OFFSET_RS1
+		orr	\rv, \rp, #DEBUG_LL_VIRT_BASE
+		orr	\rp, \rp, #DEBUG_LL_PHYS_BASE_RS1
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
+
+#else /* CONFIG_DEBUG_LL_UART_NONE */
+
+		.macro	addruart, rp, rv, tmp
+		/*
+		 * Have to provide reasonable dummy values,
+		 * otherwise code in head.S crashes badly...
+		 */
+		mov	\rp, #0
+		mov	\rv, #0
+		.endm
+
+		.macro	senduart,rd,rx
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	busyuart,rd,rx
+		.endm
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h
index 7dab559..1e472eb 100644
--- a/arch/arm/mach-vexpress/include/mach/uncompress.h
+++ b/arch/arm/mach-vexpress/include/mach/uncompress.h
@@ -27,6 +27,7 @@ 
 
 static unsigned long get_uart_base(void)
 {
+#if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT)
 	unsigned long mpcore_periph;
 
 	/*
@@ -42,6 +43,13 @@  static unsigned long get_uart_base(void)
 		return UART_BASE;
 	else
 		return UART_BASE_RS1;
+#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CA9)
+	return UART_BASE;
+#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_RS1)
+	return UART_BASE_RS1;
+#else
+	return 0;
+#endif
 }
 
 /*
@@ -51,6 +59,9 @@  static inline void putc(int c)
 {
 	unsigned long base = get_uart_base();
 
+	if (!base)
+		return;
+
 	while (AMBA_UART_FR(base) & (1 << 5))
 		barrier();
 
@@ -61,6 +72,9 @@  static inline void flush(void)
 {
 	unsigned long base = get_uart_base();
 
+	if (!base)
+		return;
+
 	while (AMBA_UART_FR(base) & (1 << 3))
 		barrier();
 }