diff mbox

[v4,5/5] zynq: move static peripheral mappings

Message ID 20121024200451.GF6713@beefymiracle.amer.corp.natinst.com (mailing list archive)
State New, archived
Headers show

Commit Message

Josh Cartwright Oct. 24, 2012, 8:04 p.m. UTC
Shifting them up into the vmalloc region prevents the following warning,
when booting a zynq qemu target with more than 512mb of RAM:

  BUG: mapping for 0xe0000000 at 0xe0000000 out of vmalloc space

In addition, it allows for reuse of these mappings when the proper
drivers issue requests via ioremap().

Signed-off-by: Josh Cartwright <josh.cartwright@ni.com>
Cc: John Linn <john.linn@xilinx.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/mach-zynq/common.c                |  6 +++---
 arch/arm/mach-zynq/include/mach/zynq_soc.h | 23 +++++++++++++----------
 2 files changed, 16 insertions(+), 13 deletions(-)

Comments

Nick Bowler Oct. 25, 2012, 8:17 p.m. UTC | #1
Hi Josh,

On 2012-10-24 15:04 -0500, Josh Cartwright wrote:
> Shifting them up into the vmalloc region prevents the following warning,
> when booting a zynq qemu target with more than 512mb of RAM:
[...]
> -/* For now, all mappings are flat (physical = virtual)
> +/* Static peripheral mappings are mapped at the top of the
> + * vmalloc region
>   */
> -#define UART0_PHYS			0xE0000000
> -#define UART0_VIRT			UART0_PHYS
> +#define UART0_PHYS		0xE0000000
> +#define UART0_SIZE		SZ_4K
> +#define UART0_VIRT		(VMALLOC_END - UART0_SIZE)

Did you test this on any real hardware?  I can't get the ZC702 to work
with the UART mapped at this address (this ends up being mapped at
0xFEFFF000), although I can't for the life of me figure out why the
virtual address even matters.  Note that for the ZC702, the physical
address of the "main" UART is 0xE0001000.

All I end up seeing is "Uncompressing Linux... done, booting the
kernel." with no further messages.  With the UART mapped at
0xF0001000, all printouts make it to the console.  I tried a couple
different virtual addresses and I'm surprised at the results, since
the behaviour seems to vary wildly.  I saw three behaviours depending
only on the virtual address of the static mapping; all results are 100%
reproducible:

   "Works":     all printouts make it to the console
   "Fails":     no printouts make it to the console after decompression
   "Truncated": the first few lines of output do not make it to the
                console, but after that it "Works".  The first line
		successfully printed is always
		  "Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260096"

And here are the addresses I tested:

  Address       Result
  -----------------------
  0xf0000000    Truncated
  0xf0001000    Works
  0xf0007000    Truncated
  0xf0008000    Fails
  0xf0009000    Fails
  0xf000e000    Truncated
  0xf000f000    Fails
  0xf8000000    Truncated
  0xf8001000    Works
  0xfef00000    Truncated
  0xfef01000    Works
  0xfef08000    Fails
  0xfef0f000    Fails
  0xfeff0000    Fails
  0xfeff1000    Fails
  0xfeffe000    Fails
  0xfefff000    Fails

Judging by the list, the console seems to only work properly if the
defined virtual address is Fxxx1000 and xxx is not too big...

Confused,
Josh Cartwright Oct. 25, 2012, 9:29 p.m. UTC | #2
On Thu, Oct 25, 2012 at 04:17:01PM -0400, Nick Bowler wrote:
> Hi Josh,
>
> On 2012-10-24 15:04 -0500, Josh Cartwright wrote:
> > Shifting them up into the vmalloc region prevents the following warning,
> > when booting a zynq qemu target with more than 512mb of RAM:
> [...]
> > -/* For now, all mappings are flat (physical = virtual)
> > +/* Static peripheral mappings are mapped at the top of the
> > + * vmalloc region
> >   */
> > -#define UART0_PHYS			0xE0000000
> > -#define UART0_VIRT			UART0_PHYS
> > +#define UART0_PHYS		0xE0000000
> > +#define UART0_SIZE		SZ_4K
> > +#define UART0_VIRT		(VMALLOC_END - UART0_SIZE)
>
> Did you test this on any real hardware?  I can't get the ZC702 to work
> with the UART mapped at this address (this ends up being mapped at
> 0xFEFFF000), although I can't for the life of me figure out why the
> virtual address even matters.  Note that for the ZC702, the physical
> address of the "main" UART is 0xE0001000.

Ugh, not yet;  My testing has been on a qemu model.  I also
unfortunately neglected to mention I am carrying a qemu patch that
forces RX_EN/TX_EN of the uarts out of reset.  There is an (incomplete)
thread on qemu-devel discussing whose responsibility it really is to
enable the uarts:

   http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg03779.html

Clearly, though, if you are seeing the "Uncompressing Linux..."
messages, then the uart is enabled, so I don't think that's the problem.

> All I end up seeing is "Uncompressing Linux... done, booting the
> kernel." with no further messages.  With the UART mapped at
> 0xF0001000, all printouts make it to the console.  I tried a couple
> different virtual addresses and I'm surprised at the results, since
> the behaviour seems to vary wildly.  I saw three behaviours depending
> only on the virtual address of the static mapping; all results are 100%
> reproducible:
>
>    "Works":     all printouts make it to the console
>    "Fails":     no printouts make it to the console after decompression
>    "Truncated": the first few lines of output do not make it to the
>                 console, but after that it "Works".  The first line
> 		successfully printed is always
> 		  "Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260096"

Odd, I'm wondering the uart gets into a weird state, and some bits get
knocked loose at console_initcall() time, when the console driver comes
up (Assuming CONFIG_SERIAL_XILINX_PS_UART)?

> And here are the addresses I tested:
> 
>   Address       Result
>   -----------------------
>   0xf0000000    Truncated
>   0xf0001000    Works
>   0xf0007000    Truncated
>   0xf0008000    Fails
>   0xf0009000    Fails
>   0xf000e000    Truncated
>   0xf000f000    Fails
>   0xf8000000    Truncated
>   0xf8001000    Works
>   0xfef00000    Truncated
>   0xfef01000    Works
>   0xfef08000    Fails
>   0xfef0f000    Fails
>   0xfeff0000    Fails
>   0xfeff1000    Fails
>   0xfeffe000    Fails
>   0xfefff000    Fails
> 
> Judging by the list, the console seems to only work properly if the
> defined virtual address is Fxxx1000 and xxx is not too big...

Very odd.  Do you mind sending out your patch allowing the selection of
the secondary uart for DEBUG_LL?

Thanks,

  Josh
Nick Bowler Oct. 25, 2012, 10:41 p.m. UTC | #3
On 2012-10-25 16:29 -0500, Josh Cartwright wrote:
> On Thu, Oct 25, 2012 at 04:17:01PM -0400, Nick Bowler wrote:
> > Did you test this on any real hardware?  I can't get the ZC702 to work
> > with the UART mapped at this address (this ends up being mapped at
> > 0xFEFFF000), although I can't for the life of me figure out why the
> > virtual address even matters.  Note that for the ZC702, the physical
> > address of the "main" UART is 0xE0001000.
> 
> Ugh, not yet;  My testing has been on a qemu model.  I also
> unfortunately neglected to mention I am carrying a qemu patch that
> forces RX_EN/TX_EN of the uarts out of reset.  There is an (incomplete)
> thread on qemu-devel discussing whose responsibility it really is to
> enable the uarts:
> 
>    http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg03779.html
> 
> Clearly, though, if you are seeing the "Uncompressing Linux..."
> messages, then the uart is enabled, so I don't think that's the problem.

Yes, the uart is presumably enabled by u-boot.

> >    "Works":     all printouts make it to the console
> >    "Fails":     no printouts make it to the console after decompression
> >    "Truncated": the first few lines of output do not make it to the
> >                 console, but after that it "Works".  The first line
> > 		successfully printed is always
> > 		  "Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260096"
> 
> Odd, I'm wondering the uart gets into a weird state, and some bits get
> knocked loose at console_initcall() time, when the console driver comes
> up (Assuming CONFIG_SERIAL_XILINX_PS_UART)?

While I am using that driver, it is not initialized until relatively
late in the boot process.  If I were to guess, I would guess that,
except for when it "Works", the really really early printk stuff isn't
actually hitting the uart at all.  The "Fails" case would then be due to
the stray writes crashing the board, and the "Truncated" case due to the
stray writes being (ostensibly) benign.

But I really have no way right now to test this hypothesis, since I
can't print anything in the failing case.

> > And here are the addresses I tested:
> > 
> >   Address       Result
> >   -----------------------
> >   0xf0000000    Truncated
> >   0xf0001000    Works
[...]
> >   0xfefff000    Fails
> > 
> > Judging by the list, the console seems to only work properly if the
> > defined virtual address is Fxxx1000 and xxx is not too big...
> 
> Very odd.  Do you mind sending out your patch allowing the selection of
> the secondary uart for DEBUG_LL?

I will follow up with the version that applies on top of your series in
a moment.  I'm confident that the UART works on the ZC702 when mapped at
0xf0001000, since I've been running with that since I first got my hands
on one of these boards.

But you don't need any patch to do the same tests I was doing above:
you can just change UART0_PHYS to 0xe0001000 and then set UART0_VIRT
accordingly (you may need to move the TTC/SCU mappings depending where
you put the UART, of course).

Cheers,
Josh Cartwright Oct. 26, 2012, 1:03 a.m. UTC | #4
On Thu, Oct 25, 2012 at 06:41:08PM -0400, Nick Bowler wrote:
> On 2012-10-25 16:29 -0500, Josh Cartwright wrote:
> > On Thu, Oct 25, 2012 at 04:17:01PM -0400, Nick Bowler wrote:
> > > Did you test this on any real hardware?  I can't get the ZC702 to work
> > > with the UART mapped at this address (this ends up being mapped at
> > > 0xFEFFF000), although I can't for the life of me figure out why the
> > > virtual address even matters.  Note that for the ZC702, the physical
> > > address of the "main" UART is 0xE0001000.

Good news is you're not crazy; I was able to duplicate the problem here.

> If I were to guess, I would guess that, except for when it "Works",
> the really really early printk stuff isn't actually hitting the uart
> at all.  The "Fails" case would then be due to the stray writes
> crashing the board, and the "Truncated" case due to the stray writes
> being (ostensibly) benign.

If I'm not mistaken, this hypothesis is predicated on the early bootup
code establishing a (linear?) mapping for addresses > VMALLOC_START;
before the mdesc->map_io() is even handled.  That seems odd to me.

> But I really have no way right now to test this hypothesis, since I
> can't print anything in the failing case.

Not sure if I'll be able to get anything meaningful out of it yet (I've
not historically had good luck with Xilinx's debugging tools), but I did
finally get a JTAG debugger hooked up to the zc702.  I'll see if I can
get any useful information tomorrow.

Thanks,

  Josh
Michal Simek Oct. 27, 2012, 4:52 p.m. UTC | #5
HI Josh and Nick,

look below.

> -----Original Message-----
> From: Josh Cartwright [mailto:josh.cartwright@ni.com]
> Sent: Friday, October 26, 2012 3:03 AM
> To: Nick Bowler
> Cc: arm@kernel.org; Arnd Bergmann; linux-kernel@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; John Linn; Michal Simek
> Subject: Re: [PATCH v4 5/5] zynq: move static peripheral mappings
> 
> On Thu, Oct 25, 2012 at 06:41:08PM -0400, Nick Bowler wrote:
> > On 2012-10-25 16:29 -0500, Josh Cartwright wrote:
> > > On Thu, Oct 25, 2012 at 04:17:01PM -0400, Nick Bowler wrote:
> > > > Did you test this on any real hardware?  I can't get the ZC702 to
> > > > work with the UART mapped at this address (this ends up being
> > > > mapped at 0xFEFFF000), although I can't for the life of me figure
> > > > out why the virtual address even matters.  Note that for the
> > > > ZC702, the physical address of the "main" UART is 0xE0001000.
> 
> Good news is you're not crazy; I was able to duplicate the problem here.
> 
> > If I were to guess, I would guess that, except for when it "Works",
> > the really really early printk stuff isn't actually hitting the uart
> > at all.  The "Fails" case would then be due to the stray writes
> > crashing the board, and the "Truncated" case due to the stray writes
> > being (ostensibly) benign.
> 
> If I'm not mistaken, this hypothesis is predicated on the early bootup code
> establishing a (linear?) mapping for addresses > VMALLOC_START; before the
> mdesc->map_io() is even handled.  That seems odd to me.
> 
> > But I really have no way right now to test this hypothesis, since I
> > can't print anything in the failing case.
> 
> Not sure if I'll be able to get anything meaningful out of it yet (I've not
> historically had good luck with Xilinx's debugging tools), but I did finally get a
> JTAG debugger hooked up to the zc702.  I'll see if I can get any useful
> information tomorrow.

I have seen the same problem on zc702. I will debug it.
Josh: the best will be if you can send v5 for patches 1-3 (1 with small changes in dts - uart)  which I will apply
to arm-next. 

4/5 should go out of zynq subtree, it means directly to arm-soc or via Russel's tree. 

5/5 + Nick patch should be tested. 

Thanks,
Michal
diff mbox

Patch

diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index ba48f06..ba8d14f 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -73,12 +73,12 @@  static struct map_desc io_desc[] __initdata = {
 	{
 		.virtual	= TTC0_VIRT,
 		.pfn		= __phys_to_pfn(TTC0_PHYS),
-		.length		= SZ_4K,
+		.length		= TTC0_SIZE,
 		.type		= MT_DEVICE,
 	}, {
 		.virtual	= SCU_PERIPH_VIRT,
 		.pfn		= __phys_to_pfn(SCU_PERIPH_PHYS),
-		.length		= SZ_8K,
+		.length		= SCU_PERIPH_SIZE,
 		.type		= MT_DEVICE,
 	},
 
@@ -86,7 +86,7 @@  static struct map_desc io_desc[] __initdata = {
 	{
 		.virtual	= UART0_VIRT,
 		.pfn		= __phys_to_pfn(UART0_PHYS),
-		.length		= SZ_4K,
+		.length		= UART0_SIZE,
 		.type		= MT_DEVICE,
 	},
 #endif
diff --git a/arch/arm/mach-zynq/include/mach/zynq_soc.h b/arch/arm/mach-zynq/include/mach/zynq_soc.h
index 218283a..c6b9b67 100644
--- a/arch/arm/mach-zynq/include/mach/zynq_soc.h
+++ b/arch/arm/mach-zynq/include/mach/zynq_soc.h
@@ -15,27 +15,30 @@ 
 #ifndef __MACH_XILINX_SOC_H__
 #define __MACH_XILINX_SOC_H__
 
+#include <asm/pgtable.h>
+
 #define PERIPHERAL_CLOCK_RATE		2500000
 
-/* For now, all mappings are flat (physical = virtual)
+/* Static peripheral mappings are mapped at the top of the
+ * vmalloc region
  */
-#define UART0_PHYS			0xE0000000
-#define UART0_VIRT			UART0_PHYS
+#define UART0_PHYS		0xE0000000
+#define UART0_SIZE		SZ_4K
+#define UART0_VIRT		(VMALLOC_END - UART0_SIZE)
 
-#define TTC0_PHYS			0xF8001000
-#define TTC0_VIRT			TTC0_PHYS
+#define TTC0_PHYS		0xF8001000
+#define TTC0_SIZE		SZ_4K
+#define TTC0_VIRT		(UART0_VIRT - TTC0_SIZE)
 
-#define SCU_PERIPH_PHYS			0xF8F00000
-#define SCU_PERIPH_VIRT			SCU_PERIPH_PHYS
+#define SCU_PERIPH_PHYS		0xF8F00000
+#define SCU_PERIPH_SIZE		SZ_8K
+#define SCU_PERIPH_VIRT		(TTC0_VIRT - SCU_PERIPH_SIZE)
 
 /* The following are intended for the devices that are mapped early */
 
 #define TTC0_BASE			IOMEM(TTC0_VIRT)
 #define SCU_PERIPH_BASE			IOMEM(SCU_PERIPH_VIRT)
 
-/*
- * Mandatory for CONFIG_LL_DEBUG, UART is mapped virtual = physical
- */
 #define LL_UART_PADDR	UART0_PHYS
 #define LL_UART_VADDR	UART0_VIRT