All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/23] Introducing the TI Keystone platform
@ 2012-07-24  1:09 ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas, Cyril Chemparathy

TI's scalable KeyStone II architecture includes support for both TMS320C66x
floating point DSPs and ARM Cortex-A15 clusters, for a mixture of up to 32
cores per SoC.  The solution is optimized around a high performance chip
interconnect and a rich set of on chip peripherals.  Please refer [1] for
initial technical documentation on these devices.

This patch series provides a basic Linux port for these devices, including
support for SMP, and LPAE boot.  A majority of the patches in this series are
related to LPAE functionality, imposed by the device architecture which has
system memory mapped at an address above the 4G 32-bit addressable limit.

This patch series is based on the v3.5 kernel with the smp_ops patch set
applied on top.  This series is being posted to elicit early feedback, and so
that some of these fixes may get incorporated early on into the kernel code.

  [1] - http://www.ti.com/product/tms320tci6636


Cyril Chemparathy (17):
  ARM: LPAE: use signed arithmetic for mask definitions
  ARM: LPAE: use phys_addr_t on virt <--> phys conversion
  ARM: LPAE: use phys_addr_t for membank size
  ARM: LPAE: use 64-bit pgd physical address in switch_mm()
  ARM: LPAE: use 64-bit accessors for TTBR registers
  ARM: mm: use physical addresses in highmem sanity checks
  ARM: mm: cleanup checks for membank overlap with vmalloc area
  ARM: mm: clean up membank size limit checks
  ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem
  ARM: LPAE: factor out T1SZ and TTBR1 computations
  ARM: LPAE: allow proc override of TTB setup
  ARM: LPAE: accomodate >32-bit addresses for page table base
  ARM: add machine desc hook for early memory/paging initialization
  drivers: cma: fix addressing on PAE machines
  ARM: keystone: introducing TI Keystone platform
  ARM: keystone: enable SMP on Keystone machines
  ARM: keystone: add switch over to high physical address range

Vitaly Andrianov (6):
  ARM: LPAE: disable phys-to-virt patching on PAE systems
  ARM: LPAE: use phys_addr_t in alloc_init_pud()
  ARM: LPAE: use phys_addr_t in free_memmap()
  ARM: LPAE: use phys_addr_t for initrd location and size
  ARM: add virt_to_idmap for interconnect aliasing
  mm: bootmem: use phys_addr_t for physical addresses

 arch/arm/Kconfig                                  |   20 +++
 arch/arm/Makefile                                 |    1 +
 arch/arm/boot/dts/keystone-sim.dts                |   77 +++++++++
 arch/arm/configs/keystone_defconfig               |   23 +++
 arch/arm/include/asm/cache.h                      |    9 ++
 arch/arm/include/asm/mach/arch.h                  |    1 +
 arch/arm/include/asm/memory.h                     |   28 +++-
 arch/arm/include/asm/page.h                       |    7 +-
 arch/arm/include/asm/pgtable-3level-hwdef.h       |   10 ++
 arch/arm/include/asm/pgtable-3level.h             |    6 +-
 arch/arm/include/asm/proc-fns.h                   |   28 +++-
 arch/arm/include/asm/setup.h                      |    4 +-
 arch/arm/kernel/head.S                            |   18 ++-
 arch/arm/kernel/setup.c                           |    3 +
 arch/arm/kernel/smp.c                             |   11 +-
 arch/arm/mach-keystone/Makefile                   |    2 +
 arch/arm/mach-keystone/Makefile.boot              |    1 +
 arch/arm/mach-keystone/include/mach/debug-macro.S |   44 +++++
 arch/arm/mach-keystone/include/mach/entry-macro.S |   20 +++
 arch/arm/mach-keystone/include/mach/io.h          |   22 +++
 arch/arm/mach-keystone/include/mach/memory.h      |   51 ++++++
 arch/arm/mach-keystone/include/mach/system.h      |   30 ++++
 arch/arm/mach-keystone/include/mach/timex.h       |   21 +++
 arch/arm/mach-keystone/include/mach/uncompress.h  |   24 +++
 arch/arm/mach-keystone/include/mach/vmalloc.h     |   21 +++
 arch/arm/mach-keystone/keystone.c                 |  178 +++++++++++++++++++++
 arch/arm/mach-keystone/platsmp.c                  |   94 +++++++++++
 arch/arm/mm/context.c                             |   13 +-
 arch/arm/mm/idmap.c                               |    4 +-
 arch/arm/mm/init.c                                |   20 +--
 arch/arm/mm/mmu.c                                 |   49 ++----
 arch/arm/mm/proc-arm1026.S                        |    3 +
 arch/arm/mm/proc-mohawk.S                         |    3 +
 arch/arm/mm/proc-v6.S                             |    6 +-
 arch/arm/mm/proc-v7-2level.S                      |    7 +-
 arch/arm/mm/proc-v7-3level.S                      |   29 ++--
 arch/arm/mm/proc-v7.S                             |    2 +
 arch/arm/mm/proc-xsc3.S                           |    3 +
 drivers/base/dma-contiguous.c                     |    4 +-
 include/linux/bootmem.h                           |   30 ++--
 mm/bootmem.c                                      |   59 +++----
 41 files changed, 840 insertions(+), 146 deletions(-)
 create mode 100644 arch/arm/boot/dts/keystone-sim.dts
 create mode 100644 arch/arm/configs/keystone_defconfig
 create mode 100644 arch/arm/mach-keystone/Makefile
 create mode 100644 arch/arm/mach-keystone/Makefile.boot
 create mode 100644 arch/arm/mach-keystone/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/io.h
 create mode 100644 arch/arm/mach-keystone/include/mach/memory.h
 create mode 100644 arch/arm/mach-keystone/include/mach/system.h
 create mode 100644 arch/arm/mach-keystone/include/mach/timex.h
 create mode 100644 arch/arm/mach-keystone/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-keystone/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-keystone/keystone.c
 create mode 100644 arch/arm/mach-keystone/platsmp.c

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 00/23] Introducing the TI Keystone platform
@ 2012-07-24  1:09 ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel

TI's scalable KeyStone II architecture includes support for both TMS320C66x
floating point DSPs and ARM Cortex-A15 clusters, for a mixture of up to 32
cores per SoC.  The solution is optimized around a high performance chip
interconnect and a rich set of on chip peripherals.  Please refer [1] for
initial technical documentation on these devices.

This patch series provides a basic Linux port for these devices, including
support for SMP, and LPAE boot.  A majority of the patches in this series are
related to LPAE functionality, imposed by the device architecture which has
system memory mapped at an address above the 4G 32-bit addressable limit.

This patch series is based on the v3.5 kernel with the smp_ops patch set
applied on top.  This series is being posted to elicit early feedback, and so
that some of these fixes may get incorporated early on into the kernel code.

  [1] - http://www.ti.com/product/tms320tci6636


Cyril Chemparathy (17):
  ARM: LPAE: use signed arithmetic for mask definitions
  ARM: LPAE: use phys_addr_t on virt <--> phys conversion
  ARM: LPAE: use phys_addr_t for membank size
  ARM: LPAE: use 64-bit pgd physical address in switch_mm()
  ARM: LPAE: use 64-bit accessors for TTBR registers
  ARM: mm: use physical addresses in highmem sanity checks
  ARM: mm: cleanup checks for membank overlap with vmalloc area
  ARM: mm: clean up membank size limit checks
  ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem
  ARM: LPAE: factor out T1SZ and TTBR1 computations
  ARM: LPAE: allow proc override of TTB setup
  ARM: LPAE: accomodate >32-bit addresses for page table base
  ARM: add machine desc hook for early memory/paging initialization
  drivers: cma: fix addressing on PAE machines
  ARM: keystone: introducing TI Keystone platform
  ARM: keystone: enable SMP on Keystone machines
  ARM: keystone: add switch over to high physical address range

Vitaly Andrianov (6):
  ARM: LPAE: disable phys-to-virt patching on PAE systems
  ARM: LPAE: use phys_addr_t in alloc_init_pud()
  ARM: LPAE: use phys_addr_t in free_memmap()
  ARM: LPAE: use phys_addr_t for initrd location and size
  ARM: add virt_to_idmap for interconnect aliasing
  mm: bootmem: use phys_addr_t for physical addresses

 arch/arm/Kconfig                                  |   20 +++
 arch/arm/Makefile                                 |    1 +
 arch/arm/boot/dts/keystone-sim.dts                |   77 +++++++++
 arch/arm/configs/keystone_defconfig               |   23 +++
 arch/arm/include/asm/cache.h                      |    9 ++
 arch/arm/include/asm/mach/arch.h                  |    1 +
 arch/arm/include/asm/memory.h                     |   28 +++-
 arch/arm/include/asm/page.h                       |    7 +-
 arch/arm/include/asm/pgtable-3level-hwdef.h       |   10 ++
 arch/arm/include/asm/pgtable-3level.h             |    6 +-
 arch/arm/include/asm/proc-fns.h                   |   28 +++-
 arch/arm/include/asm/setup.h                      |    4 +-
 arch/arm/kernel/head.S                            |   18 ++-
 arch/arm/kernel/setup.c                           |    3 +
 arch/arm/kernel/smp.c                             |   11 +-
 arch/arm/mach-keystone/Makefile                   |    2 +
 arch/arm/mach-keystone/Makefile.boot              |    1 +
 arch/arm/mach-keystone/include/mach/debug-macro.S |   44 +++++
 arch/arm/mach-keystone/include/mach/entry-macro.S |   20 +++
 arch/arm/mach-keystone/include/mach/io.h          |   22 +++
 arch/arm/mach-keystone/include/mach/memory.h      |   51 ++++++
 arch/arm/mach-keystone/include/mach/system.h      |   30 ++++
 arch/arm/mach-keystone/include/mach/timex.h       |   21 +++
 arch/arm/mach-keystone/include/mach/uncompress.h  |   24 +++
 arch/arm/mach-keystone/include/mach/vmalloc.h     |   21 +++
 arch/arm/mach-keystone/keystone.c                 |  178 +++++++++++++++++++++
 arch/arm/mach-keystone/platsmp.c                  |   94 +++++++++++
 arch/arm/mm/context.c                             |   13 +-
 arch/arm/mm/idmap.c                               |    4 +-
 arch/arm/mm/init.c                                |   20 +--
 arch/arm/mm/mmu.c                                 |   49 ++----
 arch/arm/mm/proc-arm1026.S                        |    3 +
 arch/arm/mm/proc-mohawk.S                         |    3 +
 arch/arm/mm/proc-v6.S                             |    6 +-
 arch/arm/mm/proc-v7-2level.S                      |    7 +-
 arch/arm/mm/proc-v7-3level.S                      |   29 ++--
 arch/arm/mm/proc-v7.S                             |    2 +
 arch/arm/mm/proc-xsc3.S                           |    3 +
 drivers/base/dma-contiguous.c                     |    4 +-
 include/linux/bootmem.h                           |   30 ++--
 mm/bootmem.c                                      |   59 +++----
 41 files changed, 840 insertions(+), 146 deletions(-)
 create mode 100644 arch/arm/boot/dts/keystone-sim.dts
 create mode 100644 arch/arm/configs/keystone_defconfig
 create mode 100644 arch/arm/mach-keystone/Makefile
 create mode 100644 arch/arm/mach-keystone/Makefile.boot
 create mode 100644 arch/arm/mach-keystone/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/io.h
 create mode 100644 arch/arm/mach-keystone/include/mach/memory.h
 create mode 100644 arch/arm/mach-keystone/include/mach/system.h
 create mode 100644 arch/arm/mach-keystone/include/mach/timex.h
 create mode 100644 arch/arm/mach-keystone/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-keystone/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-keystone/keystone.c
 create mode 100644 arch/arm/mach-keystone/platsmp.c

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 01/23] ARM: LPAE: disable phys-to-virt patching on PAE systems
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:09   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Vitaly Andrianov, Cyril Chemparathy

From: Vitaly Andrianov <vitalya@ti.com>

The current phys-to-virt patching mechanism is broken on PAE machines with
64-bit physical addressing.  This patch disables the patching mechanism in
such configurations.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91009c..55da671 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -191,6 +191,7 @@ config ARM_PATCH_PHYS_VIRT
 	default y
 	depends on !XIP_KERNEL && MMU
 	depends on !ARCH_REALVIEW || !SPARSEMEM
+	depends on !ARCH_PHYS_ADDR_T_64BIT
 	help
 	  Patch phys-to-virt and virt-to-phys translation functions at
 	  boot and module load time according to the position of the
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 01/23] ARM: LPAE: disable phys-to-virt patching on PAE systems
@ 2012-07-24  1:09   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vitaly Andrianov <vitalya@ti.com>

The current phys-to-virt patching mechanism is broken on PAE machines with
64-bit physical addressing.  This patch disables the patching mechanism in
such configurations.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91009c..55da671 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -191,6 +191,7 @@ config ARM_PATCH_PHYS_VIRT
 	default y
 	depends on !XIP_KERNEL && MMU
 	depends on !ARCH_REALVIEW || !SPARSEMEM
+	depends on !ARCH_PHYS_ADDR_T_64BIT
 	help
 	  Patch phys-to-virt and virt-to-phys translation functions at
 	  boot and module load time according to the position of the
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:09   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
unsigned long math truncates the mask at the 32-bits.  This clearly does bad
things on PAE systems.

This patch fixes this problem by defining these masks as signed quantities.
We then rely on sign extension to do the right thing.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/page.h           |    7 ++++++-
 arch/arm/include/asm/pgtable-3level.h |    6 +++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index ecf9019..1c810d2 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -13,7 +13,12 @@
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT		12
 #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK		(~(PAGE_SIZE-1))
+
+/*
+ * We do not use PAGE_SIZE in the following because we rely on sign
+ * extension to appropriately extend upper bits for PAE systems
+ */
+#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index b249035..ae39d11 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -48,16 +48,16 @@
 #define PMD_SHIFT		21
 
 #define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE-1))
+#define PMD_MASK		(~((1 << PMD_SHIFT) - 1))
 #define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+#define PGDIR_MASK		(~((1 << PGDIR_SHIFT) - 1))
 
 /*
  * section address mask and size definitions.
  */
 #define SECTION_SHIFT		21
 #define SECTION_SIZE		(1UL << SECTION_SHIFT)
-#define SECTION_MASK		(~(SECTION_SIZE-1))
+#define SECTION_MASK		(~((1 << SECTION_SHIFT) - 1))
 
 #define USER_PTRS_PER_PGD	(PAGE_OFFSET / PGDIR_SIZE)
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch fixes up the types used when converting back and forth between
physical and virtual addresses.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/include/asm/memory.h |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index fcb5757..7629dfe 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
 	: "=r" (to)					\
 	: "r" (from), "I" (type))
 
-static inline unsigned long __virt_to_phys(unsigned long x)
+static inline phys_addr_t __virt_to_phys(unsigned long x)
 {
 	unsigned long t;
 	__pv_stub(x, t, "add", __PV_BITS_31_24);
 	return t;
 }
 
-static inline unsigned long __phys_to_virt(unsigned long x)
+static inline unsigned long __phys_to_virt(phys_addr_t x)
 {
 	unsigned long t;
 	__pv_stub(x, t, "sub", __PV_BITS_31_24);
 	return t;
 }
 #else
-#define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
-#define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+
+#define __virt_to_phys(x)		\
+	((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET)
+
+#define __phys_to_virt(x)		\
+	((unsigned long)((phys_addr_t)(x) - PHYS_OFFSET + PAGE_OFFSET))
+
 #endif
 #endif
 
@@ -219,14 +224,14 @@ static inline phys_addr_t virt_to_phys(const volatile void *x)
 
 static inline void *phys_to_virt(phys_addr_t x)
 {
-	return (void *)(__phys_to_virt((unsigned long)(x)));
+	return (void *)__phys_to_virt(x);
 }
 
 /*
  * Drivers should NOT use these either.
  */
 #define __pa(x)			__virt_to_phys((unsigned long)(x))
-#define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+#define __va(x)			((void *)__phys_to_virt((phys_addr_t)(x)))
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
 /*
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 04/23] ARM: LPAE: use phys_addr_t in alloc_init_pud()
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Vitaly Andrianov, Cyril Chemparathy

From: Vitaly Andrianov <vitalya@ti.com>

This patch fixes the alloc_init_pud() function to use phys_addr_t instead of
unsigned long when passing in the phys argument.

This is an extension to commit 97092e0c56830457af0639f6bd904537a150ea4a, which
applied similar changes elsewhere in the ARM memory management code.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/mm/mmu.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index cf4528d..226985c 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -628,7 +628,8 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
-	unsigned long end, unsigned long phys, const struct mem_type *type)
+				  unsigned long end, phys_addr_t phys,
+				  const struct mem_type *type)
 {
 	pud_t *pud = pud_offset(pgd, addr);
 	unsigned long next;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 05/23] ARM: LPAE: use phys_addr_t in free_memmap()
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:09   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Vitaly Andrianov, Cyril Chemparathy

From: Vitaly Andrianov <vitalya@ti.com>

The free_memmap() was mistakenly using unsigned long type to represent
physical addresses.  This breaks on PAE systems where memory could be placed
above the 32-bit addressible limit.

This patch fixes this function to properly use phys_addr_t instead.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/mm/init.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index f54d592..8252c31 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -457,7 +457,7 @@ static inline void
 free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
 	struct page *start_pg, *end_pg;
-	unsigned long pg, pgend;
+	phys_addr_t pg, pgend;
 
 	/*
 	 * Convert start_pfn/end_pfn to a struct page pointer.
@@ -469,8 +469,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 	 * Convert to physical addresses, and
 	 * round start upwards and end downwards.
 	 */
-	pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
-	pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
+	pg = PAGE_ALIGN(__pa(start_pg));
+	pgend = __pa(end_pg) & PAGE_MASK;
 
 	/*
 	 * If there are free pages between these,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 06/23] ARM: LPAE: use phys_addr_t for initrd location and size
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:33   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Vitaly Andrianov, Cyril Chemparathy

From: Vitaly Andrianov <vitalya@ti.com>

This patch fixes the initrd setup code to use phys_addr_t instead of assuming
32-bit addressing.  Without this we cannot boot on systems where initrd is
located above the 4G physical address limit.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/mm/init.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8252c31..51f3e92 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -36,12 +36,12 @@
 
 #include "mm.h"
 
-static unsigned long phys_initrd_start __initdata = 0;
-static unsigned long phys_initrd_size __initdata = 0;
+static phys_addr_t phys_initrd_start __initdata = 0;
+static phys_addr_t phys_initrd_size __initdata = 0;
 
 static int __init early_initrd(char *p)
 {
-	unsigned long start, size;
+	phys_addr_t start, size;
 	char *endp;
 
 	start = memparse(p, &endp);
@@ -347,14 +347,14 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (phys_initrd_size &&
 	    !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08llx is not a memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, (u64)phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size &&
 	    memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08llx overlaps in-use memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, (u64)phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 07/23] ARM: LPAE: use phys_addr_t for membank size
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch changes the membank structure's size field to phys_addr_t to allow
banks larger than 4G.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/setup.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 23ebc0c..a2e7581 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -195,8 +195,8 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn }
 #define NR_BANKS	CONFIG_ARM_NR_BANKS
 
 struct membank {
-	phys_addr_t start;
-	unsigned long size;
+	phys_addr_t  start;
+	phys_addr_t  size;
 	unsigned int highmem;
 };
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 08/23] ARM: LPAE: use 64-bit pgd physical address in switch_mm()
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch modifies the switch_mm() processor functions to use 64-bit
addresses.  We use u64 instead of phys_addr_t, in order to avoid having config
dependent register usage when calling into switch_mm assembly code.

The changes in this patch are primarily adjustments for registers used for
arguments to switch_mm.  The few processor definitions that did use the second
argument have been modified accordingly.

Arguments and calling conventions aside, this patch should be a no-op on v6
and non-LPAE v7 processors.  On LPAE systems, we now honor the upper 32-bits
of the physical address that is being passed in.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/proc-fns.h |    4 ++--
 arch/arm/mm/proc-v6.S           |    2 +-
 arch/arm/mm/proc-v7-2level.S    |    2 +-
 arch/arm/mm/proc-v7-3level.S    |    5 +++--
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index f3628fb..fa6554e 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -60,7 +60,7 @@ extern struct processor {
 	/*
 	 * Set the page table
 	 */
-	void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
+	void (*switch_mm)(u64 pgd_phys, struct mm_struct *mm);
 	/*
 	 * Set a possibly extended PTE.  Non-extended PTEs should
 	 * ignore 'ext'.
@@ -82,7 +82,7 @@ extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
 extern void cpu_dcache_clean_area(void *, int);
-extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_do_switch_mm(u64 pgd_phys, struct mm_struct *mm);
 #ifdef CONFIG_ARM_LPAE
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
 #else
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 5900cd5..566c658 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -100,8 +100,8 @@ ENTRY(cpu_v6_dcache_clean_area)
  */
 ENTRY(cpu_v6_switch_mm)
 #ifdef CONFIG_MMU
+	ldr	r1, [r2, #MM_CONTEXT_ID]	@ get mm->context.id
 	mov	r2, #0
-	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
 	ALT_SMP(orr	r0, r0, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r0, r0, #TTB_FLAGS_UP)
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 42ac069..3397803 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -39,8 +39,8 @@
  */
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
+	ldr	r1, [r2, #MM_CONTEXT_ID]	@ get mm->context.id
 	mov	r2, #0
-	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
 	ALT_SMP(orr	r0, r0, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r0, r0, #TTB_FLAGS_UP)
 #ifdef CONFIG_ARM_ERRATA_430973
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 8de0f1d..0001581 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -47,9 +47,10 @@
  */
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
-	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	and	r3, r1, #0xff
+	ldr	r2, [r2, #MM_CONTEXT_ID]	@ get mm->context.id
+	and	r3, r2, #0xff
 	mov	r3, r3, lsl #(48 - 32)		@ ASID
+	orr	r3, r3, r1			@ upper 32-bits of pgd phys
 	mcrr	p15, 0, r0, r3, c2		@ set TTB 0
 	isb
 #endif
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 09/23] ARM: LPAE: use 64-bit accessors for TTBR registers
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch adds TTBR accessor macros, and modifies cpu_get_pgd() and
the LPAE version of cpu_set_reserved_ttbr0() to use these instead.

In the process, we also fix these functions to correctly handle cases
where the physical address lies beyond the 4G limit of 32-bit addressing.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/proc-fns.h |   24 +++++++++++++++++++-----
 arch/arm/mm/context.c           |   13 ++-----------
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index fa6554e..918b4f9 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -116,13 +116,27 @@ extern void cpu_resume(void);
 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
 
 #ifdef CONFIG_ARM_LPAE
+
+#define cpu_get_ttbr(nr)					\
+	({							\
+		u64 ttbr;					\
+		__asm__("mrrc	p15, " #nr ", %Q0, %R0, c2"	\
+			: "=r" (ttbr)				\
+			: : "cc");				\
+		ttbr;						\
+	})
+
+#define cpu_set_ttbr(nr, val)					\
+	do {							\
+		u64 ttbr = val;					\
+		__asm__("mcrr	p15, " #nr ", %Q0, %R0, c2"	\
+			: : "r" (ttbr)				\
+			: "cc");				\
+	} while (0)
+
 #define cpu_get_pgd()	\
 	({						\
-		unsigned long pg, pg2;			\
-		__asm__("mrrc	p15, 0, %0, %1, c2"	\
-			: "=r" (pg), "=r" (pg2)		\
-			:				\
-			: "cc");			\
+		u64 pg = cpu_get_ttbr(0);		\
 		pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);	\
 		(pgd_t *)phys_to_virt(pg);		\
 	})
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 806cc4f..ad70bd8 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -15,6 +15,7 @@
 
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
+#include <asm/proc-fns.h>
 
 static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
 unsigned int cpu_last_asid = ASID_FIRST_VERSION;
@@ -22,17 +23,7 @@ unsigned int cpu_last_asid = ASID_FIRST_VERSION;
 #ifdef CONFIG_ARM_LPAE
 void cpu_set_reserved_ttbr0(void)
 {
-	unsigned long ttbl = __pa(swapper_pg_dir);
-	unsigned long ttbh = 0;
-
-	/*
-	 * Set TTBR0 to swapper_pg_dir which contains only global entries. The
-	 * ASID is set to 0.
-	 */
-	asm volatile(
-	"	mcrr	p15, 0, %0, %1, c2		@ set TTBR0\n"
-	:
-	: "r" (ttbl), "r" (ttbh));
+	cpu_set_ttbr(0, __pa(swapper_pg_dir));
 	isb();
 }
 #else
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 10/23] ARM: mm: use physical addresses in highmem sanity checks
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch modifies the highmem sanity checking code to use physical addresses
instead.  This change eliminates the wrap-around problems associated with the
original virtual address based checks, and this simplifies the code a bit.

The one constraint imposed here is that low physical memory must be mapped in
a monotonically increasing fashion if there are multiple banks of memory,
i.e., x < y must => pa(x) < pa(y).

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/mm/mmu.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 226985c..adaf8c3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -901,6 +901,7 @@ phys_addr_t arm_lowmem_limit __initdata = 0;
 void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
+	phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1;
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
@@ -910,8 +911,7 @@ void __init sanity_check_meminfo(void)
 			highmem = 1;
 
 #ifdef CONFIG_HIGHMEM
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET)
+		if (bank->start >= vmalloc_limit)
 			highmem = 1;
 
 		bank->highmem = highmem;
@@ -920,8 +920,8 @@ void __init sanity_check_meminfo(void)
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (!highmem && __va(bank->start) < vmalloc_min &&
-		    bank->size > vmalloc_min - __va(bank->start)) {
+		if (!highmem && bank->start < vmalloc_limit &&
+		    bank->size > vmalloc_limit - bank->start) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -930,12 +930,12 @@ void __init sanity_check_meminfo(void)
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= vmalloc_min - __va(bank->start);
-				bank[1].start = __pa(vmalloc_min - 1) + 1;
+				bank[1].size -= vmalloc_limit - bank->start;
+				bank[1].start = vmalloc_limit;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = vmalloc_min - __va(bank->start);
+			bank->size = vmalloc_limit - bank->start;
 		}
 #else
 		bank->highmem = highmem;
@@ -955,8 +955,7 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would entirely overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET) {
+		if (bank->start >= vmalloc_limit) {
 			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
 			       "(vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
@@ -968,9 +967,8 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start + bank->size) > vmalloc_min ||
-		    __va(bank->start + bank->size) < __va(bank->start)) {
-			unsigned long newsize = vmalloc_min - __va(bank->start);
+		if (bank->start + bank->size > vmalloc_limit)
+			unsigned long newsize = vmalloc_limit - bank->start;
 			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
 			       "to -%.8llx (vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 11/23] ARM: mm: cleanup checks for membank overlap with vmalloc area
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

On Keystone platforms, physical memory is entirely outside the 32-bit
addressible range.  Therefore, the (bank->start > ULONG_MAX) check below marks
the entire system memory as highmem, and this causes unpleasentness all over.

This patch eliminates the extra bank start check (against ULONG_MAX) by
checking bank->start against the physical address corresponding to vmalloc_min
instead.

In the process, this patch also cleans up parts of the highmem sanity check
code by removing what has now become a redundant check for banks that entirely
overlap with the vmalloc range.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/mm/mmu.c |   19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index adaf8c3..4840efa 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -907,15 +907,12 @@ void __init sanity_check_meminfo(void)
 		struct membank *bank = &meminfo.bank[j];
 		*bank = meminfo.bank[i];
 
-		if (bank->start > ULONG_MAX)
-			highmem = 1;
-
-#ifdef CONFIG_HIGHMEM
 		if (bank->start >= vmalloc_limit)
 			highmem = 1;
 
 		bank->highmem = highmem;
 
+#ifdef CONFIG_HIGHMEM
 		/*
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
@@ -938,8 +935,6 @@ void __init sanity_check_meminfo(void)
 			bank->size = vmalloc_limit - bank->start;
 		}
 #else
-		bank->highmem = highmem;
-
 		/*
 		 * Highmem banks not allowed with !CONFIG_HIGHMEM.
 		 */
@@ -952,18 +947,6 @@ void __init sanity_check_meminfo(void)
 		}
 
 		/*
-		 * Check whether this memory bank would entirely overlap
-		 * the vmalloc area.
-		 */
-		if (bank->start >= vmalloc_limit) {
-			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
-			       "(vmalloc region overlap).\n",
-			       (unsigned long long)bank->start,
-			       (unsigned long long)bank->start + bank->size - 1);
-			continue;
-		}
-
-		/*
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 12/23] ARM: mm: clean up membank size limit checks
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch cleans up the highmem sanity check code by simplifying the range
checks with a pre-calculated size_limit.  This patch should otherwise have no
functional impact on behavior.

This patch also removes a redundant (bank->start < vmalloc_limit) check, since
this is already covered by the !highmem condition.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/mm/mmu.c |   19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4840efa..6b0baf3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -905,10 +905,15 @@ void __init sanity_check_meminfo(void)
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
+		phys_addr_t size_limit;
+
 		*bank = meminfo.bank[i];
+		size_limit = bank->size;
 
 		if (bank->start >= vmalloc_limit)
 			highmem = 1;
+		else
+			size_limit = vmalloc_limit - bank->start;
 
 		bank->highmem = highmem;
 
@@ -917,8 +922,7 @@ void __init sanity_check_meminfo(void)
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (!highmem && bank->start < vmalloc_limit &&
-		    bank->size > vmalloc_limit - bank->start) {
+		if (!highmem && bank->size > size_limit) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -927,12 +931,12 @@ void __init sanity_check_meminfo(void)
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= vmalloc_limit - bank->start;
+				bank[1].size -= size_limit;
 				bank[1].start = vmalloc_limit;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = vmalloc_limit - bank->start;
+			bank->size = size_limit;
 		}
 #else
 		/*
@@ -950,14 +954,13 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (bank->start + bank->size > vmalloc_limit)
-			unsigned long newsize = vmalloc_limit - bank->start;
+		if (bank->size > size_limit) {
 			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
 			       "to -%.8llx (vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
 			       (unsigned long long)bank->start + bank->size - 1,
-			       (unsigned long long)bank->start + newsize - 1);
-			bank->size = newsize;
+			       (unsigned long long)bank->start + size_limit - 1);
+			bank->size = size_limit;
 		}
 #endif
 		if (!bank->highmem && bank->start + bank->size > arm_lowmem_limit)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 13/23] ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch adds an architecture defined override for ARCH_LOW_ADDRESS_LIMIT.
On PAE systems, the absence of this override causes bootmem to incorrectly
limit itself to 32-bit addressable physical memory.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/memory.h |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 7629dfe..c330a23 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -285,6 +285,8 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
 #define arch_is_coherent()		0
 #endif
 
+#define ARCH_LOW_ADDRESS_LIMIT		PHYS_MASK
+
 #endif
 
 #include <asm-generic/memory_model.h>
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 14/23] ARM: LPAE: factor out T1SZ and TTBR1 computations
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:38   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch moves the TTBR1 offset calculation and the T1SZ calculation out
of the TTB setup assembly code.  This should not affect functionality in
any way, but improves code readability as well as readability of subsequent
patches in this series.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/pgtable-3level-hwdef.h |   10 ++++++++++
 arch/arm/mm/proc-v7-3level.S                |   16 ++++------------
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index d795282..b501650 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -74,4 +74,14 @@
 #define PHYS_MASK_SHIFT		(40)
 #define PHYS_MASK		((1ULL << PHYS_MASK_SHIFT) - 1)
 
+#if defined CONFIG_VMSPLIT_2G
+#define TTBR1_OFFSET	(1 << 4)		/* skip two L1 entries */
+#elif defined CONFIG_VMSPLIT_3G
+#define TTBR1_OFFSET	(4096 * (1 + 3))	/* only L2, skip pgd + 3*pmd */
+#else
+#define TTBR1_OFFSET	0
+#endif
+
+#define TTBR1_SIZE	(((PAGE_OFFSET >> 30) - 1) << 16)
+
 #endif
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 0001581..3b1a745 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -120,18 +120,10 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 * booting secondary CPUs would end up using TTBR1 for the identity
 	 * mapping set up in TTBR0.
 	 */
-	bhi	9001f				@ PHYS_OFFSET > PAGE_OFFSET?
-	orr	\tmp, \tmp, #(((PAGE_OFFSET >> 30) - 1) << 16) @ TTBCR.T1SZ
-#if defined CONFIG_VMSPLIT_2G
-	/* PAGE_OFFSET == 0x80000000, T1SZ == 1 */
-	add	\ttbr1, \ttbr1, #1 << 4		@ skip two L1 entries
-#elif defined CONFIG_VMSPLIT_3G
-	/* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */
-	add	\ttbr1, \ttbr1, #4096 * (1 + 3)	@ only L2 used, skip pgd+3*pmd
-#endif
-	/* CONFIG_VMSPLIT_1G does not need TTBR1 adjustment */
-9001:	mcr	p15, 0, \tmp, c2, c0, 2		@ TTB control register
-	mcrr	p15, 1, \ttbr1, \zero, c2	@ load TTBR1
+	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
+	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
+	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
 	.endm
 
 	__CPUINIT
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 15/23] ARM: LPAE: allow proc override of TTB setup
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch allows ARM processor setup functions (*_setup in proc-*.S) to
indicate that the page table has already been programmed.  This is
done by setting r4 (page table pointer) to -1 before returning from the
processor setup handler.

This capability is particularly needed on LPAE systems, where the translation
table base needs to be programmed differently with 64-bit control
register operations.

Further, a few of the processors (arm1026, mohawk, xsc3) were programming the
TTB twice.  This patch prevents the main head.S code from programming TTB the
second time on these machines.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/kernel/head.S       |   11 ++++++-----
 arch/arm/mm/proc-arm1026.S   |    1 +
 arch/arm/mm/proc-mohawk.S    |    1 +
 arch/arm/mm/proc-v6.S        |    2 ++
 arch/arm/mm/proc-v7-2level.S |    3 ++-
 arch/arm/mm/proc-v7-3level.S |    1 +
 arch/arm/mm/proc-v7.S        |    1 +
 arch/arm/mm/proc-xsc3.S      |    1 +
 8 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 835898e..692e57f 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -411,17 +411,18 @@ __enable_mmu:
 #ifdef CONFIG_CPU_ICACHE_DISABLE
 	bic	r0, r0, #CR_I
 #endif
-#ifdef CONFIG_ARM_LPAE
-	mov	r5, #0
-	mcrr	p15, 0, r4, r5, c2		@ load TTBR0
-#else
+#ifndef CONFIG_ARM_LPAE
 	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_IO, DOMAIN_CLIENT))
 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
-	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 #endif
+
+	@ has the processor setup already programmed the page table pointer?
+	adds	r5, r4, #1
+	beq	__turn_mmu_on			@ yes!
+	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	b	__turn_mmu_on
 ENDPROC(__enable_mmu)
 
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index fbc1d5f..c28070e 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -404,6 +404,7 @@ __arm1026_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mvn	r4, #0				@ do not set page table pointer
 #endif
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mov	r0, #4				@ explicitly disable writeback
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index fbb2124..a26303c 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -390,6 +390,7 @@ __mohawk_setup:
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+	mvn	r4, #0				@ do not set page table pointer
 
 	mov	r0, #0				@ don't allow CP access
 	mcr	p15, 0, r0, c15, c1, 0		@ write CP access register
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 566c658..872156e 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -210,7 +210,9 @@ __v6_setup:
 	ALT_UP(orr	r4, r4, #TTB_FLAGS_UP)
 	ALT_SMP(orr	r8, r8, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r8, r8, #TTB_FLAGS_UP)
+	mcr	p15, 0, r4, c2, c0, 0		@ load TTB0
 	mcr	p15, 0, r8, c2, c0, 1		@ load TTB1
+	mvn	r4, #0				@ do not set page table pointer
 #endif /* CONFIG_MMU */
 	adr	r5, v6_crval
 	ldmia	r5, {r5, r6}
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 3397803..cc78c0c 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -139,7 +139,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 
 	/*
 	 * Macro for setting up the TTBRx and TTBCR registers.
-	 * - \ttb0 and \ttb1 updated with the corresponding flags.
+	 * - \ttbr0 and \ttbr1 updated with the corresponding flags.
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	mcr	p15, 0, \zero, c2, c0, 2	@ TTB control register
@@ -147,6 +147,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	ALT_UP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_UP)
 	ALT_SMP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_SMP)
 	ALT_UP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_UP)
+	mcr	p15, 0, \ttbr0, c2, c0, 0	@ load TTB0
 	mcr	p15, 0, \ttbr1, c2, c0, 1	@ load TTB1
 	.endm
 
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 3b1a745..5e3bed1 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -124,6 +124,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
 	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
 	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
 	.endm
 
 	__CPUINIT
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index c2e2b66..8850194 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -250,6 +250,7 @@ __v7_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r10, c8, c7, 0		@ invalidate I + D TLBs
 	v7_ttb_setup r10, r4, r8, r5		@ TTBCR, TTBRx setup
+	mvn	r4, #0				@ do not set page table pointer
 	ldr	r5, =PRRR			@ PRRR
 	ldr	r6, =NMRR			@ NMRR
 	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index b0d5786..db3836b 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -455,6 +455,7 @@ __xsc3_setup:
 	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+	mvn	r4, #0				@ do not set page table pointer
 
 	mov	r0, #1 << 6			@ cp6 access for early sched_clock
 	mcr	p15, 0, r0, c15, c1, 0		@ write CP access register
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 16/23] ARM: LPAE: accomodate >32-bit addresses for page table base
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch redefines the early boot time use of the R4 register to steal a few
low order bits (ARCH_PGD_SHIFT bits), allowing for up to 38-bit physical
addresses.

This is probably not the best means to the end, and a better alternative may
be to modify the head.S register allocations to fit in full register pairs for
pgdir and swapper_pg_dir.  However, squeezing out these extra registers seemed
to be a far greater pain than squeezing out a few low order bits from the page
table addresses.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/cache.h |    9 +++++++++
 arch/arm/kernel/head.S       |    7 +++++--
 arch/arm/kernel/smp.c        |   11 +++++++++--
 arch/arm/mm/proc-arm1026.S   |    2 ++
 arch/arm/mm/proc-mohawk.S    |    2 ++
 arch/arm/mm/proc-v6.S        |    2 ++
 arch/arm/mm/proc-v7-2level.S |    2 ++
 arch/arm/mm/proc-v7-3level.S |    7 +++++++
 arch/arm/mm/proc-v7.S        |    1 +
 arch/arm/mm/proc-xsc3.S      |    2 ++
 10 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 75fe66b..986480c 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -17,6 +17,15 @@
 #define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
 
 /*
+ * Minimum guaranted alignment in pgd_alloc().  The page table pointers passed
+ * around in head.S and proc-*.S are shifted by this amount, in order to
+ * leave spare high bits for systems with physical address extension.  This
+ * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but
+ * gives us about 38-bits or so.
+ */
+#define ARCH_PGD_SHIFT		L1_CACHE_SHIFT
+
+/*
  * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
  */
 #if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 692e57f..6fe1c40 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -22,6 +22,7 @@
 #include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/pgtable.h>
+#include <asm/cache.h>
 
 #ifdef CONFIG_DEBUG_LL
 #include <mach/debug-macro.S>
@@ -160,7 +161,7 @@ ENDPROC(stext)
  *
  * Returns:
  *  r0, r3, r5-r7 corrupted
- *  r4 = physical page table address
+ *  r4 = page table (see ARCH_PGD_SHIFT in asm/cache.h)
  */
 __create_page_tables:
 	pgtbl	r4, r8				@ page table address
@@ -320,6 +321,7 @@ __create_page_tables:
 #ifdef CONFIG_ARM_LPAE
 	sub	r4, r4, #0x1000		@ point to the PGD table
 #endif
+	mov	r4, r4, lsr #ARCH_PGD_SHIFT
 	mov	pc, lr
 ENDPROC(__create_page_tables)
 	.ltorg
@@ -392,7 +394,7 @@ __secondary_data:
  *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r2  = atags or dtb pointer
- *  r4  = page table pointer
+ *  r4  = page table (see ARCH_PGD_SHIFT in asm/cache.h)
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  */
@@ -422,6 +424,7 @@ __enable_mmu:
 	@ has the processor setup already programmed the page table pointer?
 	adds	r5, r4, #1
 	beq	__turn_mmu_on			@ yes!
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	b	__turn_mmu_on
 ENDPROC(__enable_mmu)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 2c7217d..e41e1be 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -42,6 +42,7 @@
 #include <asm/ptrace.h>
 #include <asm/localtimer.h>
 #include <asm/smp_plat.h>
+#include <asm/cache.h>
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
@@ -62,6 +63,7 @@ static DECLARE_COMPLETION(cpu_running);
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
+	phys_addr_t pgdir;
 	int ret;
 
 	/*
@@ -69,8 +71,13 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 * its stack and the page tables.
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
-	secondary_data.pgdir = virt_to_phys(idmap_pgd);
-	secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
+
+	pgdir = virt_to_phys(idmap_pgd);
+	secondary_data.pgdir = pgdir >> ARCH_PGD_SHIFT;
+
+	pgdir = virt_to_phys(swapper_pg_dir);
+	secondary_data.swapper_pg_dir = pgdir >> ARCH_PGD_SHIFT;
+
 	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
 	outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
 
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index c28070e..4556f77 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -22,6 +22,7 @@
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
+#include <asm/cache.h>
 
 #include "proc-macros.S"
 
@@ -403,6 +404,7 @@ __arm1026_setup:
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	mcr	p15, 0, r4, c2, c0		@ load page table pointer
 	mvn	r4, #0				@ do not set page table pointer
 #endif
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index a26303c..13fcc67 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -28,6 +28,7 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
+#include <asm/cache.h>
 #include "proc-macros.S"
 
 /*
@@ -388,6 +389,7 @@ __mohawk_setup:
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	mvn	r4, #0				@ do not set page table pointer
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 872156e..4751be7 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -17,6 +17,7 @@
 #include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
+#include <asm/cache.h>
 
 #include "proc-macros.S"
 
@@ -206,6 +207,7 @@ __v6_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	ALT_SMP(orr	r4, r4, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r4, r4, #TTB_FLAGS_UP)
 	ALT_SMP(orr	r8, r8, #TTB_FLAGS_SMP)
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index cc78c0c..f4bc63b 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -143,8 +143,10 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	mcr	p15, 0, \zero, c2, c0, 2	@ TTB control register
+	mov	\ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT
 	ALT_SMP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_SMP)
 	ALT_UP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_UP)
+	mov	\ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT
 	ALT_SMP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_SMP)
 	ALT_UP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_UP)
 	mcr	p15, 0, \ttbr0, c2, c0, 0	@ load TTB0
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 5e3bed1..33f322a 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -103,6 +103,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	ldr	\tmp, =swapper_pg_dir		@ swapper_pg_dir virtual address
+	mov	\tmp, \tmp, lsr #ARCH_PGD_SHIFT
 	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET? (branch below)
 	mrc	p15, 0, \tmp, c2, c0, 2		@ TTB control register
 	orr	\tmp, \tmp, #TTB_EAE
@@ -122,8 +123,14 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
 	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
+	mov	\tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT		@ lower bits
 	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
 	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mov	\tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT		@ lower bits
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
 	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
 	.endm
 
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 8850194..443f602 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -16,6 +16,7 @@
 #include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
+#include <asm/cache.h>
 
 #include "proc-macros.S"
 
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index db3836b..a43a07d 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -32,6 +32,7 @@
 #include <asm/pgtable-hwdef.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
+#include <asm/cache.h>
 #include "proc-macros.S"
 
 /*
@@ -453,6 +454,7 @@ __xsc3_setup:
 	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
 	mcr	p15, 0, ip, c7, c5, 4		@ prefetch flush
 	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	mvn	r4, #0				@ do not set page table pointer
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 17/23] ARM: add machine desc hook for early memory/paging initialization
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch adds a machine descriptor hook that gives control to machine
specific code prior to memory and paging initialization.

On Keystone platforms, this hook is used to switch the PHYS_OFFSET over
to the "real" non-32-bit-addressable address range.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/mach/arch.h |    1 +
 arch/arm/kernel/setup.c          |    3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 0b1c94b..49e9c2a 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -39,6 +39,7 @@ struct machine_desc {
 					 struct meminfo *);
 	void			(*reserve)(void);/* reserve mem blocks	*/
 	void			(*map_io)(void);/* IO mapping function	*/
+	void			(*init_meminfo)(void);
 	void			(*init_early)(void);
 	void			(*init_irq)(void);
 	struct sys_timer	*timer;		/* system tick timer	*/
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index e15d83b..7cbe292 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -964,6 +964,9 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+	if (mdesc->init_meminfo)
+		mdesc->init_meminfo();
+
 	sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
 	sanity_check_meminfo();
 	arm_memblock_init(&meminfo, mdesc);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 18/23] ARM: add virt_to_idmap for interconnect aliasing
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Vitaly Andrianov, Cyril Chemparathy

From: Vitaly Andrianov <vitalya@ti.com>

On some PAE systems (e.g. TI Keystone), memory is above the 32-bit addressible
limit, and the interconnect provides an aliased view of parts of physical
memory in the 32-bit addressible space.  This alias is strictly for boot time
usage, and is not otherwise usable because of coherency limitations.

On such systems, the idmap mechanism needs to take this aliased mapping into
account.  This patch introduces a virt_to_idmap() macro, which can be used on
such sub-architectures to represent the interconnect supported boot time
alias.  Most other systems would leave this macro untouched, i.e., do a simply
virt_to_phys() and nothing more.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/include/asm/memory.h |    9 +++++++++
 arch/arm/kernel/smp.c         |    4 ++--
 arch/arm/mm/idmap.c           |    4 ++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index c330a23..b6b203c 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -235,6 +235,15 @@ static inline void *phys_to_virt(phys_addr_t x)
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
 /*
+ * These are for systems that have a hardware interconnect supported alias of
+ * physical memory for idmap purposes.  Most cases should leave these
+ * untouched.
+ */
+#ifndef virt_to_idmap
+#define virt_to_idmap(x) virt_to_phys(x)
+#endif
+
+/*
  * Virtual <-> DMA view memory address translations
  * Again, these are *only* valid on the kernel direct mapped RAM
  * memory.  Use of these is *deprecated* (and that doesn't mean
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e41e1be..cce630c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -72,10 +72,10 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 
-	pgdir = virt_to_phys(idmap_pgd);
+	pgdir = virt_to_idmap(idmap_pgd);
 	secondary_data.pgdir = pgdir >> ARCH_PGD_SHIFT;
 
-	pgdir = virt_to_phys(swapper_pg_dir);
+	pgdir = virt_to_idmap(swapper_pg_dir);
 	secondary_data.swapper_pg_dir = pgdir >> ARCH_PGD_SHIFT;
 
 	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index ab88ed4..919cb6e 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -85,8 +85,8 @@ static int __init init_static_idmap(void)
 		return -ENOMEM;
 
 	/* Add an identity mapping for the physical address of the section. */
-	idmap_start = virt_to_phys((void *)__idmap_text_start);
-	idmap_end = virt_to_phys((void *)__idmap_text_end);
+	idmap_start = virt_to_idmap((void *)__idmap_text_start);
+	idmap_end = virt_to_idmap((void *)__idmap_text_end);
 
 	pr_info("Setting up static identity map for 0x%llx - 0x%llx\n",
 		(long long)idmap_start, (long long)idmap_end);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 19/23] drivers: cma: fix addressing on PAE machines
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:38   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch fixes a couple of bugs that otherwise impair CMA functionality on
PAE machines:

  - alignment must be a 64-bit type when running on systems with 64-bit
    physical addresses.  If this is not the case, the limit calculation thunks
    allocations down to an address range < 4G.

  - The allocated range is now being checked using dma_supported() instead of
    hardcoding a 32-bit addressable limit.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 drivers/base/dma-contiguous.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 78efb03..e10bd9a 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -234,7 +234,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
 				  phys_addr_t base, phys_addr_t limit)
 {
 	struct cma_reserved *r = &cma_reserved[cma_reserved_count];
-	unsigned long alignment;
+	phys_addr_t alignment;
 
 	pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
 		 (unsigned long)size, (unsigned long)base,
@@ -271,7 +271,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
 		if (!addr) {
 			base = -ENOMEM;
 			goto err;
-		} else if (addr + size > ~(unsigned long)0) {
+		} else if (!dma_supported(dev, addr + size)) {
 			memblock_free(addr, size);
 			base = -EINVAL;
 			goto err;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 20/23] mm: bootmem: use phys_addr_t for physical addresses
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Vitaly Andrianov, Cyril Chemparathy

From: Vitaly Andrianov <vitalya@ti.com>

On a physical address extended (PAE) systems physical memory may be located
outside the first 4GB address range.  In particular, on TI Keystone devices,
all memory (including lowmem) is located outside the 4G address space. Many
functions in the bootmem.c use unsigned long as a type for physical addresses,
and this breaks badly on such PAE systems.

This patch intensively mangles the bootmem allocator to use phys_addr_t where
necessary.  We are aware that this is most certainly not the way to go
considering that the ARM architecture appears to be moving towards memblock.
Memblock may be a better solution, and fortunately it looks a lot more PAE
savvy than bootmem is.

However, we do not fully understand the motivations and restrictions behind
the mixed bootmem + memblock model in current ARM code. We hope for a
meaningful discussion and useful guidance towards a better solution to this
problem.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 include/linux/bootmem.h |   30 ++++++++++++------------
 mm/bootmem.c            |   59 ++++++++++++++++++++++++-----------------------
 2 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 6d6795d..e43c463 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -49,10 +49,10 @@ extern unsigned long free_all_bootmem_node(pg_data_t *pgdat);
 extern unsigned long free_all_bootmem(void);
 
 extern void free_bootmem_node(pg_data_t *pgdat,
-			      unsigned long addr,
+			      phys_addr_t addr,
 			      unsigned long size);
-extern void free_bootmem(unsigned long addr, unsigned long size);
-extern void free_bootmem_late(unsigned long addr, unsigned long size);
+extern void free_bootmem(phys_addr_t addr, unsigned long size);
+extern void free_bootmem_late(phys_addr_t addr, unsigned long size);
 
 /*
  * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
@@ -65,44 +65,44 @@ extern void free_bootmem_late(unsigned long addr, unsigned long size);
 #define BOOTMEM_DEFAULT		0
 #define BOOTMEM_EXCLUSIVE	(1<<0)
 
-extern int reserve_bootmem(unsigned long addr,
+extern int reserve_bootmem(phys_addr_t addr,
 			   unsigned long size,
 			   int flags);
 extern int reserve_bootmem_node(pg_data_t *pgdat,
-				unsigned long physaddr,
+				phys_addr_t physaddr,
 				unsigned long size,
 				int flags);
 
 extern void *__alloc_bootmem(unsigned long size,
 			     unsigned long align,
-			     unsigned long goal);
+			     phys_addr_t goal);
 extern void *__alloc_bootmem_nopanic(unsigned long size,
 				     unsigned long align,
-				     unsigned long goal);
+				     phys_addr_t goal);
 extern void *__alloc_bootmem_node(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal);
+				  phys_addr_t goal);
 void *__alloc_bootmem_node_high(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal);
+				  phys_addr_t goal);
 extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal);
+				  phys_addr_t goal);
 void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal,
-				  unsigned long limit);
+				  phys_addr_t goal,
+				  phys_addr_t limit);
 extern void *__alloc_bootmem_low(unsigned long size,
 				 unsigned long align,
-				 unsigned long goal);
+				 phys_addr_t goal);
 extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
 				      unsigned long size,
 				      unsigned long align,
-				      unsigned long goal);
+				      phys_addr_t goal);
 
 #ifdef CONFIG_NO_BOOTMEM
 /* We are using top down, so it is safe to use 0 here */
@@ -137,7 +137,7 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
 #define alloc_bootmem_low_pages_node(pgdat, x) \
 	__alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0)
 
-extern int reserve_bootmem_generic(unsigned long addr, unsigned long size,
+extern int reserve_bootmem_generic(phys_addr_t addr, unsigned long size,
 				   int flags);
 
 #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
diff --git a/mm/bootmem.c b/mm/bootmem.c
index bcb63ac..e7dc572 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -154,7 +154,7 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
  * down, but we are still initializing the system.  Pages are given directly
  * to the page allocator, no bootmem metadata is updated because it is gone.
  */
-void __init free_bootmem_late(unsigned long addr, unsigned long size)
+void __init free_bootmem_late(phys_addr_t addr, unsigned long size)
 {
 	unsigned long cursor, end;
 
@@ -362,7 +362,7 @@ static int __init mark_bootmem(unsigned long start, unsigned long end,
  *
  * The range must reside completely on the specified node.
  */
-void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
+void __init free_bootmem_node(pg_data_t *pgdat, phys_addr_t physaddr,
 			      unsigned long size)
 {
 	unsigned long start, end;
@@ -384,7 +384,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
  *
  * The range must be contiguous but may span node boundaries.
  */
-void __init free_bootmem(unsigned long addr, unsigned long size)
+void __init free_bootmem(phys_addr_t addr, unsigned long size)
 {
 	unsigned long start, end;
 
@@ -407,7 +407,7 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
  *
  * The range must reside completely on the specified node.
  */
-int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
+int __init reserve_bootmem_node(pg_data_t *pgdat, phys_addr_t physaddr,
 				 unsigned long size, int flags)
 {
 	unsigned long start, end;
@@ -428,7 +428,7 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
  *
  * The range must be contiguous but may span node boundaries.
  */
-int __init reserve_bootmem(unsigned long addr, unsigned long size,
+int __init reserve_bootmem(phys_addr_t addr, unsigned long size,
 			    int flags)
 {
 	unsigned long start, end;
@@ -439,7 +439,7 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size,
 	return mark_bootmem(start, end, 1, flags);
 }
 
-int __weak __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
+int __weak __init reserve_bootmem_generic(phys_addr_t phys, unsigned long len,
 				   int flags)
 {
 	return reserve_bootmem(phys, len, flags);
@@ -461,7 +461,7 @@ static unsigned long __init align_idx(struct bootmem_data *bdata,
 static unsigned long __init align_off(struct bootmem_data *bdata,
 				      unsigned long off, unsigned long align)
 {
-	unsigned long base = PFN_PHYS(bdata->node_min_pfn);
+	phys_addr_t base = PFN_PHYS(bdata->node_min_pfn);
 
 	/* Same as align_idx for byte offsets */
 
@@ -470,14 +470,14 @@ static unsigned long __init align_off(struct bootmem_data *bdata,
 
 static void * __init alloc_bootmem_bdata(struct bootmem_data *bdata,
 					unsigned long size, unsigned long align,
-					unsigned long goal, unsigned long limit)
+					phys_addr_t goal, phys_addr_t limit)
 {
 	unsigned long fallback = 0;
 	unsigned long min, max, start, sidx, midx, step;
 
-	bdebug("nid=%td size=%lx [%lu pages] align=%lx goal=%lx limit=%lx\n",
+	bdebug("nid=%td size=%lx [%lu pages] align=%lx goal=%llx limit=%llx\n",
 		bdata - bootmem_node_data, size, PAGE_ALIGN(size) >> PAGE_SHIFT,
-		align, goal, limit);
+		align, (u64)goal, (u64)limit);
 
 	BUG_ON(!size);
 	BUG_ON(align & (align - 1));
@@ -519,7 +519,8 @@ static void * __init alloc_bootmem_bdata(struct bootmem_data *bdata,
 	while (1) {
 		int merge;
 		void *region;
-		unsigned long eidx, i, start_off, end_off;
+		unsigned long eidx, i;
+		phys_addr_t   start_off, end_off;
 find_block:
 		sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx);
 		sidx = align_idx(bdata, sidx, step);
@@ -577,7 +578,7 @@ find_block:
 
 static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata,
 					unsigned long size, unsigned long align,
-					unsigned long goal, unsigned long limit)
+					phys_addr_t goal, phys_addr_t limit)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc(size, GFP_NOWAIT);
@@ -598,8 +599,8 @@ static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata,
 
 static void * __init alloc_bootmem_core(unsigned long size,
 					unsigned long align,
-					unsigned long goal,
-					unsigned long limit)
+					phys_addr_t goal,
+					phys_addr_t limit)
 {
 	bootmem_data_t *bdata;
 	void *region;
@@ -624,8 +625,8 @@ static void * __init alloc_bootmem_core(unsigned long size,
 
 static void * __init ___alloc_bootmem_nopanic(unsigned long size,
 					      unsigned long align,
-					      unsigned long goal,
-					      unsigned long limit)
+					      phys_addr_t goal,
+					      phys_addr_t limit)
 {
 	void *ptr;
 
@@ -655,15 +656,15 @@ restart:
  * Returns NULL on failure.
  */
 void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
-					unsigned long goal)
+					phys_addr_t goal)
 {
-	unsigned long limit = 0;
+	phys_addr_t limit = 0;
 
 	return ___alloc_bootmem_nopanic(size, align, goal, limit);
 }
 
 static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
-					unsigned long goal, unsigned long limit)
+					phys_addr_t goal, phys_addr_t limit)
 {
 	void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
 
@@ -691,16 +692,16 @@ static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem(unsigned long size, unsigned long align,
-			      unsigned long goal)
+			      phys_addr_t goal)
 {
-	unsigned long limit = 0;
+	phys_addr_t limit = 0;
 
 	return ___alloc_bootmem(size, align, goal, limit);
 }
 
 void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
 				unsigned long size, unsigned long align,
-				unsigned long goal, unsigned long limit)
+				phys_addr_t goal, phys_addr_t limit)
 {
 	void *ptr;
 
@@ -731,7 +732,7 @@ again:
 }
 
 void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
-				   unsigned long align, unsigned long goal)
+				   unsigned long align, phys_addr_t goal)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
@@ -740,8 +741,8 @@ void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
 }
 
 void * __init ___alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-				    unsigned long align, unsigned long goal,
-				    unsigned long limit)
+				    unsigned long align, phys_addr_t goal,
+				    phys_addr_t limit)
 {
 	void *ptr;
 
@@ -770,7 +771,7 @@ void * __init ___alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-				   unsigned long align, unsigned long goal)
+				   unsigned long align, phys_addr_t goal)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
@@ -779,7 +780,7 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
 }
 
 void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
-				   unsigned long align, unsigned long goal)
+				   unsigned long align, phys_addr_t goal)
 {
 #ifdef MAX_DMA32_PFN
 	unsigned long end_pfn;
@@ -825,7 +826,7 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
-				  unsigned long goal)
+				  phys_addr_t goal)
 {
 	return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
 }
@@ -846,7 +847,7 @@ void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
-				       unsigned long align, unsigned long goal)
+				       unsigned long align, phys_addr_t goal)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 21/23] ARM: keystone: introducing TI Keystone platform
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:38   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

Texas Instruments Keystone family of multicore devices now includes an
upcoming slew of Cortex A15 based devices.  This patch adds basic definitions
for a new Keystone sub-architecture in ARM.

Subsequent patches in this series will extend support to include SMP and take
advantage of the large physical memory addressing capabilities via LPAE.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig                                  |   17 +++++
 arch/arm/Makefile                                 |    1 +
 arch/arm/boot/dts/keystone-sim.dts                |   77 +++++++++++++++++++
 arch/arm/configs/keystone_defconfig               |   20 +++++
 arch/arm/mach-keystone/Makefile                   |    1 +
 arch/arm/mach-keystone/Makefile.boot              |    1 +
 arch/arm/mach-keystone/include/mach/debug-macro.S |   44 +++++++++++
 arch/arm/mach-keystone/include/mach/entry-macro.S |   20 +++++
 arch/arm/mach-keystone/include/mach/io.h          |   22 ++++++
 arch/arm/mach-keystone/include/mach/memory.h      |   22 ++++++
 arch/arm/mach-keystone/include/mach/system.h      |   30 ++++++++
 arch/arm/mach-keystone/include/mach/timex.h       |   21 ++++++
 arch/arm/mach-keystone/include/mach/uncompress.h  |   24 ++++++
 arch/arm/mach-keystone/include/mach/vmalloc.h     |   21 ++++++
 arch/arm/mach-keystone/keystone.c                 |   83 +++++++++++++++++++++
 15 files changed, 404 insertions(+)
 create mode 100644 arch/arm/boot/dts/keystone-sim.dts
 create mode 100644 arch/arm/configs/keystone_defconfig
 create mode 100644 arch/arm/mach-keystone/Makefile
 create mode 100644 arch/arm/mach-keystone/Makefile.boot
 create mode 100644 arch/arm/mach-keystone/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/io.h
 create mode 100644 arch/arm/mach-keystone/include/mach/memory.h
 create mode 100644 arch/arm/mach-keystone/include/mach/system.h
 create mode 100644 arch/arm/mach-keystone/include/mach/timex.h
 create mode 100644 arch/arm/mach-keystone/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-keystone/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-keystone/keystone.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 55da671..04c846b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -359,6 +359,23 @@ config ARCH_HIGHBANK
 	help
 	  Support for the Calxeda Highbank SoC based boards.
 
+config ARCH_KEYSTONE
+	bool "Texas Instruments Keystone Devices"
+	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARM_GIC
+	select CLKDEV_LOOKUP
+	select COMMON_CLK
+	select CLKSRC_MMIO
+	select CPU_V7
+	select GENERIC_CLOCKEVENTS
+	select USE_OF
+	select SPARSE_IRQ
+	select NEED_MACH_MEMORY_H
+	select HAVE_SCHED_CLOCK
+	help
+	  Support for boards based on the Texas Instruments Keystone family of
+	  SoCs.
+
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
 	select CPU_ARM720T
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0298b00..13d6ef5 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -143,6 +143,7 @@ machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_GEMINI)		:= gemini
 machine-$(CONFIG_ARCH_H720X)		:= h720x
 machine-$(CONFIG_ARCH_HIGHBANK)		:= highbank
+machine-$(CONFIG_ARCH_KEYSTONE)		:= keystone
 machine-$(CONFIG_ARCH_INTEGRATOR)	:= integrator
 machine-$(CONFIG_ARCH_IOP13XX)		:= iop13xx
 machine-$(CONFIG_ARCH_IOP32X)		:= iop32x
diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
new file mode 100644
index 0000000..118d631
--- /dev/null
+++ b/arch/arm/boot/dts/keystone-sim.dts
@@ -0,0 +1,77 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Texas Instruments Keystone 2 SoC";
+	compatible = "ti,keystone-evm";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	aliases {
+		serial0	= &uart0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8 debug earlyprintk lpj=50000 rdinit=/bin/ash rw root=/dev/ram0 initrd=0x85000000,9M";
+	};
+
+	memory {
+		reg = <0x80000000 0x8000000>;
+	};
+
+	cpus {
+		interrupt-parent = <&gic>;
+
+		cpu@0 {
+			compatible = "arm,cortex-a15";
+		};
+
+		cpu@1 {
+			compatible = "arm,cortex-a15";
+		};
+
+		cpu@2 {
+			compatible = "arm,cortex-a15";
+		};
+
+		cpu@3 {
+			compatible = "arm,cortex-a15";
+		};
+
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "ti,keystone","simple-bus";
+		interrupt-parent = <&gic>;
+
+		gic:	interrupt-controller@02560000 {
+			compatible = "arm,cortex-a15-gic";
+			#interrupt-cells = <3>;
+			#size-cells = <0>;
+			#address-cells = <1>;
+			interrupt-controller;
+			reg = <0x02561000 0x1000>,
+			      <0x02562000 0x2000>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			interrupts = <1 13 0xf08 1 14 0xf08>;
+			clock-frequency = <10000000>; /* Freq in Hz - optional */
+		};
+
+		uart0:	serial@02530c00 {
+			compatible	= "ns16550a";
+			current-speed	= <115200>;
+			reg-shift	= <2>;
+			reg-io-width	= <4>;
+			reg		= <0x02530c00 0x100>;
+			clock-frequency = <48000000>;
+			interrupts	= <0 277 0xf01>;
+		};
+	};
+};
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
new file mode 100644
index 0000000..7f2a04b
--- /dev/null
+++ b/arch/arm/configs/keystone_defconfig
@@ -0,0 +1,20 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile
new file mode 100644
index 0000000..d4671d5
--- /dev/null
+++ b/arch/arm/mach-keystone/Makefile
@@ -0,0 +1 @@
+obj-y					:= keystone.o
diff --git a/arch/arm/mach-keystone/Makefile.boot b/arch/arm/mach-keystone/Makefile.boot
new file mode 100644
index 0000000..dae9661
--- /dev/null
+++ b/arch/arm/mach-keystone/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y	:= 0x00008000
diff --git a/arch/arm/mach-keystone/include/mach/debug-macro.S b/arch/arm/mach-keystone/include/mach/debug-macro.S
new file mode 100644
index 0000000..1108210
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/debug-macro.S
@@ -0,0 +1,44 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/serial_reg.h>
+
+#define UART_SHIFT	2
+
+	.macro	addruart,rp,rv,tmp
+	movw	\rv, #0x0c00
+	movt	\rv, #0xfed3
+	movw	\rp, #0x0c00
+	movt	\rp, #0x0253
+	.endm
+
+
+	.macro	senduart,rd,rx
+	str	\rd, [\rx, #UART_TX << UART_SHIFT]
+	.endm
+
+	.macro	busyuart,rd,rx
+1002:	ldr	\rd, [\rx, #UART_LSR << UART_SHIFT]
+	and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+	teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
+	bne	1002b
+	.endm
+
+	.macro	waituart,rd,rx
+	.endm
diff --git a/arch/arm/mach-keystone/include/mach/entry-macro.S b/arch/arm/mach-keystone/include/mach/entry-macro.S
new file mode 100644
index 0000000..7f486f3
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/entry-macro.S
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+	.macro	disable_fiq
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
diff --git a/arch/arm/mach-keystone/include/mach/io.h b/arch/arm/mach-keystone/include/mach/io.h
new file mode 100644
index 0000000..844d659
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#define __io(a)		({ (void)(a); __typesafe_io(0); })
+#define __mem_pci(a)	(a)
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
new file mode 100644
index 0000000..7c78b1e
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/memory.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define MAX_PHYSMEM_BITS	36
+#define SECTION_SIZE_BITS	34
+
+#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-keystone/include/mach/system.h b/arch/arm/mach-keystone/include/mach/system.h
new file mode 100644
index 0000000..4887b4c
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/system.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	while (1)
+		;
+}
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/timex.h b/arch/arm/mach-keystone/include/mach/timex.h
new file mode 100644
index 0000000..f355ecb
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE		1000000
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/uncompress.h b/arch/arm/mach-keystone/include/mach/uncompress.h
new file mode 100644
index 0000000..1071761
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/uncompress.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#define putc(c)
+#define flush()
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/vmalloc.h b/arch/arm/mach-keystone/include/mach/vmalloc.h
new file mode 100644
index 0000000..9d34c09
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/vmalloc.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#define VMALLOC_END		0xFE800000UL
+
+#endif
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
new file mode 100644
index 0000000..9583dc4
--- /dev/null
+++ b/arch/arm/mach-keystone/keystone.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+#include <asm/arch_timer.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+
+static struct map_desc io_desc[] = {
+	{
+		.virtual        = 0xfe800000UL,
+		.pfn            = __phys_to_pfn(0x02000000UL),
+		.length         = 0x800000UL,
+		.type           = MT_DEVICE
+	},
+};
+
+static void __init keystone_map_io(void)
+{
+	iotable_init(io_desc, sizeof(io_desc)/sizeof(struct map_desc));
+}
+
+static const struct of_device_id irq_match[] = {
+	{ .compatible = "arm,cortex-a15-gic", .data = gic_of_init, },
+	{}
+};
+
+static void __init keystone_init_irq(void)
+{
+	of_irq_init(irq_match);
+}
+
+
+static void __init keystone_timer_init(void)
+{
+	arch_timer_of_register();
+	arch_timer_sched_clock_init();
+}
+
+static struct sys_timer keystone_timer = {
+	.init = keystone_timer_init,
+};
+
+
+static void __init keystone_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *keystone_match[] __initconst = {
+	"ti,keystone-evm",
+	NULL,
+};
+
+DT_MACHINE_START(KEYSTONE, "Keystone")
+	.map_io		= keystone_map_io,
+	.init_irq	= keystone_init_irq,
+	.timer		= &keystone_timer,
+	.handle_irq	= gic_handle_irq,
+	.init_machine	= keystone_init,
+	.dt_compat	= keystone_match,
+	.nr_irqs	= 480,
+MACHINE_END
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 22/23] ARM: keystone: enable SMP on Keystone machines
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:10   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

This patch adds basic SMP support for Keystone machines.  Nothing very fancy
here, just enough to get 4 CPUs booted up.  This does not include support for
hotplug, etc.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig                    |    1 +
 arch/arm/configs/keystone_defconfig |    2 +
 arch/arm/mach-keystone/Makefile     |    1 +
 arch/arm/mach-keystone/keystone.c   |    3 ++
 arch/arm/mach-keystone/platsmp.c    |   73 +++++++++++++++++++++++++++++++++++
 5 files changed, 80 insertions(+)
 create mode 100644 arch/arm/mach-keystone/platsmp.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 04c846b..5b82879 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -372,6 +372,7 @@ config ARCH_KEYSTONE
 	select SPARSE_IRQ
 	select NEED_MACH_MEMORY_H
 	select HAVE_SCHED_CLOCK
+	select HAVE_SMP
 	help
 	  Support for boards based on the Texas Instruments Keystone family of
 	  SoCs.
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 7f2a04b..5f71e66 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -1,7 +1,9 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_SMP=y
 CONFIG_ARM_ARCH_TIMER=y
+CONFIG_NR_CPUS=4
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_VFP=y
diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile
index d4671d5..3f6b8ab 100644
--- a/arch/arm/mach-keystone/Makefile
+++ b/arch/arm/mach-keystone/Makefile
@@ -1 +1,2 @@
 obj-y					:= keystone.o
+obj-$(CONFIG_SMP)			+= platsmp.o
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index 9583dc4..650e202 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -26,6 +26,8 @@
 #include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
 
+extern struct smp_ops keystone_smp_ops;
+
 static struct map_desc io_desc[] = {
 	{
 		.virtual        = 0xfe800000UL,
@@ -73,6 +75,7 @@ static const char *keystone_match[] __initconst = {
 };
 
 DT_MACHINE_START(KEYSTONE, "Keystone")
+	smp_ops(keystone_smp_ops)
 	.map_io		= keystone_map_io,
 	.init_irq	= keystone_init_irq,
 	.timer		= &keystone_timer,
diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c
new file mode 100644
index 0000000..437659a
--- /dev/null
+++ b/arch/arm/mach-keystone/platsmp.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012 Texas Instruments, Inc.
+ *
+ * Based on platsmp.c, Copyright 2010-2011 Calxeda, Inc.
+ * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/smp_plat.h>
+#include <asm/smp_ops.h>
+#include <asm/hardware/gic.h>
+#include <asm/cacheflush.h>
+#include <asm/memory.h>
+
+extern void secondary_startup(void);
+
+static void __init keystone_smp_init_cpus(void)
+{
+	unsigned int i, ncores;
+
+	ncores = 4;
+
+	/* sanity check */
+	if (ncores > NR_CPUS) {
+		pr_warn("restricted to %d cpus\n", NR_CPUS);
+		ncores = NR_CPUS;
+	}
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
+}
+
+static void __init keystone_smp_prepare_cpus(unsigned int max_cpus)
+{
+	/* nothing for now */
+}
+
+static void __cpuinit keystone_secondary_init(unsigned int cpu)
+{
+	gic_secondary_init(0);
+}
+
+static int __cpuinit
+keystone_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long *jump_ptr = phys_to_virt(0x800001f0);
+
+	jump_ptr[cpu] = virt_to_idmap(&secondary_startup);
+	__cpuc_flush_dcache_area(jump_ptr, sizeof(jump_ptr) * 4);
+
+	return 0;
+}
+
+struct smp_ops keystone_smp_ops __initdata = {
+	smp_init_ops(keystone)
+	smp_secondary_ops(keystone)
+};
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 23/23] ARM: keystone: add switch over to high physical address range
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  1:33   ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, nico, will.deacon, catalin.marinas,
	Cyril Chemparathy, Vitaly Andrianov

Keystone platforms have their physical memory mapped at an address outside the
32-bit physical range.  A Keystone machine with 16G of RAM would find its
memory at 0x0800000000 - 0x0bffffffff.

For boot purposes, the interconnect supports a limited alias of some of this
memory within the 32-bit addressable space (0x80000000 - 0xffffffff).  This
aliasing is implemented in hardware, and is not intended to be used much
beyond boot.  For instance, DMA coherence does not work when running out of
this aliased address space.

Therefore, we've taken the approach of booting out of the low physical address
range, and subsequently we switch over to the high range once we're safely
inside machine specific territory.  This patch implements this switch over
mechanism, which involves rewiring the TTBRs and page tables to point to the
new physical address space.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig                             |    1 +
 arch/arm/boot/dts/keystone-sim.dts           |    6 +-
 arch/arm/configs/keystone_defconfig          |    1 +
 arch/arm/mach-keystone/include/mach/memory.h |   29 ++++++++
 arch/arm/mach-keystone/keystone.c            |   92 ++++++++++++++++++++++++++
 arch/arm/mach-keystone/platsmp.c             |   21 ++++++
 6 files changed, 147 insertions(+), 3 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5b82879..f970ee1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -373,6 +373,7 @@ config ARCH_KEYSTONE
 	select NEED_MACH_MEMORY_H
 	select HAVE_SCHED_CLOCK
 	select HAVE_SMP
+	select ZONE_DMA if ARM_LPAE
 	help
 	  Support for boards based on the Texas Instruments Keystone family of
 	  SoCs.
diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
index 118d631..afdef89 100644
--- a/arch/arm/boot/dts/keystone-sim.dts
+++ b/arch/arm/boot/dts/keystone-sim.dts
@@ -4,7 +4,7 @@
 / {
 	model = "Texas Instruments Keystone 2 SoC";
 	compatible = "ti,keystone-evm";
-	#address-cells = <1>;
+	#address-cells = <2>;
 	#size-cells = <1>;
 	interrupt-parent = <&gic>;
 
@@ -13,11 +13,11 @@
 	};
 
 	chosen {
-		bootargs = "console=ttyS0,115200n8 debug earlyprintk lpj=50000 rdinit=/bin/ash rw root=/dev/ram0 initrd=0x85000000,9M";
+		bootargs = "console=ttyS0,115200n8 debug earlyprintk lpj=50000 rdinit=/bin/ash rw root=/dev/ram0 initrd=0x805000000,9M";
 	};
 
 	memory {
-		reg = <0x80000000 0x8000000>;
+		reg = <0x00000008 0x00000000 0x8000000>;
 	};
 
 	cpus {
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 5f71e66..8ea3b96 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -1,6 +1,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARM_LPAE=y
 CONFIG_SMP=y
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_NR_CPUS=4
diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
index 7c78b1e..6404633 100644
--- a/arch/arm/mach-keystone/include/mach/memory.h
+++ b/arch/arm/mach-keystone/include/mach/memory.h
@@ -19,4 +19,33 @@
 #define MAX_PHYSMEM_BITS	36
 #define SECTION_SIZE_BITS	34
 
+#define KEYSTONE_LOW_PHYS_START		0x80000000ULL
+#define KEYSTONE_LOW_PHYS_SIZE		0x80000000ULL /* 2G */
+#define KEYSTONE_LOW_PHYS_END		(KEYSTONE_LOW_PHYS_START + \
+					 KEYSTONE_LOW_PHYS_SIZE - 1)
+
+#define KEYSTONE_HIGH_PHYS_START	0x800000000ULL
+#define KEYSTONE_HIGH_PHYS_SIZE		0x400000000ULL	/* 16G */
+#define KEYSTONE_HIGH_PHYS_END		(KEYSTONE_HIGH_PHYS_START + \
+					 KEYSTONE_HIGH_PHYS_SIZE - 1)
+#ifdef CONFIG_ARM_LPAE
+
+#ifndef __ASSEMBLY__
+
+extern phys_addr_t  keystone_phys_offset;
+
+#define PLAT_PHYS_OFFSET keystone_phys_offset
+
+static inline phys_addr_t __virt_to_idmap(unsigned long x)
+{
+	return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET +
+		KEYSTONE_LOW_PHYS_START;
+}
+
+#define virt_to_idmap(x)	__virt_to_idmap((unsigned long)(x))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_ARM_LPAE */
+
 #endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index 650e202..f0f4a08 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -19,12 +19,20 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
+#include <linux/sched.h>
 
 #include <asm/arch_timer.h>
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/cputype.h>
+#include <asm/procinfo.h>
 
 extern struct smp_ops keystone_smp_ops;
 
@@ -74,6 +82,86 @@ static const char *keystone_match[] __initconst = {
 	NULL,
 };
 
+#ifdef CONFIG_ARM_LPAE
+
+phys_addr_t keystone_phys_offset  = KEYSTONE_LOW_PHYS_START;
+
+extern struct proc_info_list *lookup_processor_type(unsigned int);
+
+static void __init keystone_init_meminfo(void)
+{
+	unsigned long map_start, map_end;
+	struct proc_info_list *procinfo;
+	phys_addr_t mem_start, mem_end;
+	pgd_t *pgd0, *pgdk;
+	pud_t *pud0, *pudk;
+	pmd_t *pmd0, *pmdk;
+	phys_addr_t phys;
+	pmdval_t pmdprot;
+	int i;
+
+	BUG_ON(meminfo.nr_banks < 1);
+
+	mem_start = meminfo.bank[0].start;
+	mem_end   = mem_start + meminfo.bank[0].size - 1;
+
+	/* nothing to do if we are running out of the <32-bit space */
+	if (mem_start >= KEYSTONE_LOW_PHYS_START &&
+	    mem_end   <= KEYSTONE_LOW_PHYS_END)
+		return;
+
+	BUG_ON(mem_start < KEYSTONE_HIGH_PHYS_START ||
+	       mem_end   > KEYSTONE_HIGH_PHYS_END);
+
+	/* remap kernel code and data */
+	map_start = init_mm.start_code;
+	map_end   = init_mm.brk;
+
+	/* get a handle on things -  */
+	pgd0 = pgd_offset_k(0);
+	pud0 = pud_offset(pgd0, 0);
+	pmd0 = pmd_offset(pud0, 0);
+
+	pgdk = pgd_offset_k(map_start);
+	pudk = pud_offset(pgdk, map_start);
+	pmdk = pmd_offset(pudk, map_start);
+
+	procinfo = lookup_processor_type(read_cpuid_id());
+	pmdprot  = procinfo->__cpu_mm_mmu_flags;
+
+	/* set the phys offset, all pa/va operations now use this */
+	keystone_phys_offset = KEYSTONE_HIGH_PHYS_START;
+
+	/* remap level 1 table */
+	for (i = 0; i < PTRS_PER_PGD; i++) {
+		*pud0++ = __pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER);
+		pmd0 += PTRS_PER_PMD;
+	}
+
+	/* remap pmds for kernel mapping */
+	phys = __pa(map_start) & PMD_MASK;
+	do {
+		*pmdk++ = __pmd(phys | pmdprot);
+		phys += PMD_SIZE;
+	} while (phys < map_end);
+
+	flush_cache_all();
+	cpu_set_ttbr(0, __pa(pgd0));
+	cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
+	local_flush_tlb_all();
+
+	pr_err("relocated to high address space\n");
+}
+
+#else
+
+static void __init keystone_init_meminfo(void)
+{
+	/* nothing to do here */
+}
+
+#endif
+
 DT_MACHINE_START(KEYSTONE, "Keystone")
 	smp_ops(keystone_smp_ops)
 	.map_io		= keystone_map_io,
@@ -82,5 +170,9 @@ DT_MACHINE_START(KEYSTONE, "Keystone")
 	.handle_irq	= gic_handle_irq,
 	.init_machine	= keystone_init,
 	.dt_compat	= keystone_match,
+	.init_meminfo	= keystone_init_meminfo,
+#ifdef CONFIG_ZONE_DMA
+	.dma_zone_size	= SZ_2G,
+#endif
 	.nr_irqs	= 480,
 MACHINE_END
diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c
index 437659a..074fccb 100644
--- a/arch/arm/mach-keystone/platsmp.c
+++ b/arch/arm/mach-keystone/platsmp.c
@@ -24,6 +24,7 @@
 #include <asm/smp_ops.h>
 #include <asm/hardware/gic.h>
 #include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 #include <asm/memory.h>
 
 extern void secondary_startup(void);
@@ -51,15 +52,35 @@ static void __init keystone_smp_prepare_cpus(unsigned int max_cpus)
 	/* nothing for now */
 }
 
+#ifdef CONFIG_ARM_LPAE
+static void __cpuinit keystone_secondary_initmem(void)
+{
+	pgd_t *pgd0;
+
+	pgd0 = pgd_offset_k(0);
+	cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
+	local_flush_tlb_all();
+}
+#else
+static void __cpuinit keystone_secondary_initmem(void)
+{
+}
+#endif
+
 static void __cpuinit keystone_secondary_init(unsigned int cpu)
 {
 	gic_secondary_init(0);
+	keystone_secondary_initmem();
 }
 
 static int __cpuinit
 keystone_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
+#ifdef CONFIG_ARM_LPAE
+	unsigned long *jump_ptr = phys_to_virt(0x8000001f0);
+#else
 	unsigned long *jump_ptr = phys_to_virt(0x800001f0);
+#endif
 
 	jump_ptr[cpu] = virt_to_idmap(&secondary_startup);
 	__cpuc_flush_dcache_area(jump_ptr, sizeof(jump_ptr) * 4);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
@ 2012-07-24  1:09   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel

This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
unsigned long math truncates the mask at the 32-bits.  This clearly does bad
things on PAE systems.

This patch fixes this problem by defining these masks as signed quantities.
We then rely on sign extension to do the right thing.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/page.h           |    7 ++++++-
 arch/arm/include/asm/pgtable-3level.h |    6 +++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index ecf9019..1c810d2 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -13,7 +13,12 @@
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT		12
 #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK		(~(PAGE_SIZE-1))
+
+/*
+ * We do not use PAGE_SIZE in the following because we rely on sign
+ * extension to appropriately extend upper bits for PAE systems
+ */
+#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index b249035..ae39d11 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -48,16 +48,16 @@
 #define PMD_SHIFT		21
 
 #define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE-1))
+#define PMD_MASK		(~((1 << PMD_SHIFT) - 1))
 #define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+#define PGDIR_MASK		(~((1 << PGDIR_SHIFT) - 1))
 
 /*
  * section address mask and size definitions.
  */
 #define SECTION_SHIFT		21
 #define SECTION_SIZE		(1UL << SECTION_SHIFT)
-#define SECTION_MASK		(~(SECTION_SIZE-1))
+#define SECTION_MASK		(~((1 << SECTION_SHIFT) - 1))
 
 #define USER_PTRS_PER_PGD	(PAGE_OFFSET / PGDIR_SIZE)
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 05/23] ARM: LPAE: use phys_addr_t in free_memmap()
@ 2012-07-24  1:09   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vitaly Andrianov <vitalya@ti.com>

The free_memmap() was mistakenly using unsigned long type to represent
physical addresses.  This breaks on PAE systems where memory could be placed
above the 32-bit addressible limit.

This patch fixes this function to properly use phys_addr_t instead.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/mm/init.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index f54d592..8252c31 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -457,7 +457,7 @@ static inline void
 free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
 	struct page *start_pg, *end_pg;
-	unsigned long pg, pgend;
+	phys_addr_t pg, pgend;
 
 	/*
 	 * Convert start_pfn/end_pfn to a struct page pointer.
@@ -469,8 +469,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 	 * Convert to physical addresses, and
 	 * round start upwards and end downwards.
 	 */
-	pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
-	pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
+	pg = PAGE_ALIGN(__pa(start_pg));
+	pgend = __pa(end_pg) & PAGE_MASK;
 
 	/*
 	 * If there are free pages between these,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 04/23] ARM: LPAE: use phys_addr_t in alloc_init_pud()
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vitaly Andrianov <vitalya@ti.com>

This patch fixes the alloc_init_pud() function to use phys_addr_t instead of
unsigned long when passing in the phys argument.

This is an extension to commit 97092e0c56830457af0639f6bd904537a150ea4a, which
applied similar changes elsewhere in the ARM memory management code.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/mm/mmu.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index cf4528d..226985c 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -628,7 +628,8 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
-	unsigned long end, unsigned long phys, const struct mem_type *type)
+				  unsigned long end, phys_addr_t phys,
+				  const struct mem_type *type)
 {
 	pud_t *pud = pud_offset(pgd, addr);
 	unsigned long next;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 08/23] ARM: LPAE: use 64-bit pgd physical address in switch_mm()
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modifies the switch_mm() processor functions to use 64-bit
addresses.  We use u64 instead of phys_addr_t, in order to avoid having config
dependent register usage when calling into switch_mm assembly code.

The changes in this patch are primarily adjustments for registers used for
arguments to switch_mm.  The few processor definitions that did use the second
argument have been modified accordingly.

Arguments and calling conventions aside, this patch should be a no-op on v6
and non-LPAE v7 processors.  On LPAE systems, we now honor the upper 32-bits
of the physical address that is being passed in.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/proc-fns.h |    4 ++--
 arch/arm/mm/proc-v6.S           |    2 +-
 arch/arm/mm/proc-v7-2level.S    |    2 +-
 arch/arm/mm/proc-v7-3level.S    |    5 +++--
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index f3628fb..fa6554e 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -60,7 +60,7 @@ extern struct processor {
 	/*
 	 * Set the page table
 	 */
-	void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
+	void (*switch_mm)(u64 pgd_phys, struct mm_struct *mm);
 	/*
 	 * Set a possibly extended PTE.  Non-extended PTEs should
 	 * ignore 'ext'.
@@ -82,7 +82,7 @@ extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
 extern void cpu_dcache_clean_area(void *, int);
-extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_do_switch_mm(u64 pgd_phys, struct mm_struct *mm);
 #ifdef CONFIG_ARM_LPAE
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
 #else
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 5900cd5..566c658 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -100,8 +100,8 @@ ENTRY(cpu_v6_dcache_clean_area)
  */
 ENTRY(cpu_v6_switch_mm)
 #ifdef CONFIG_MMU
+	ldr	r1, [r2, #MM_CONTEXT_ID]	@ get mm->context.id
 	mov	r2, #0
-	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
 	ALT_SMP(orr	r0, r0, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r0, r0, #TTB_FLAGS_UP)
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 42ac069..3397803 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -39,8 +39,8 @@
  */
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
+	ldr	r1, [r2, #MM_CONTEXT_ID]	@ get mm->context.id
 	mov	r2, #0
-	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
 	ALT_SMP(orr	r0, r0, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r0, r0, #TTB_FLAGS_UP)
 #ifdef CONFIG_ARM_ERRATA_430973
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 8de0f1d..0001581 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -47,9 +47,10 @@
  */
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
-	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	and	r3, r1, #0xff
+	ldr	r2, [r2, #MM_CONTEXT_ID]	@ get mm->context.id
+	and	r3, r2, #0xff
 	mov	r3, r3, lsl #(48 - 32)		@ ASID
+	orr	r3, r3, r1			@ upper 32-bits of pgd phys
 	mcrr	p15, 0, r0, r3, c2		@ set TTB 0
 	isb
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 11/23] ARM: mm: cleanup checks for membank overlap with vmalloc area
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Keystone platforms, physical memory is entirely outside the 32-bit
addressible range.  Therefore, the (bank->start > ULONG_MAX) check below marks
the entire system memory as highmem, and this causes unpleasentness all over.

This patch eliminates the extra bank start check (against ULONG_MAX) by
checking bank->start against the physical address corresponding to vmalloc_min
instead.

In the process, this patch also cleans up parts of the highmem sanity check
code by removing what has now become a redundant check for banks that entirely
overlap with the vmalloc range.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/mm/mmu.c |   19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index adaf8c3..4840efa 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -907,15 +907,12 @@ void __init sanity_check_meminfo(void)
 		struct membank *bank = &meminfo.bank[j];
 		*bank = meminfo.bank[i];
 
-		if (bank->start > ULONG_MAX)
-			highmem = 1;
-
-#ifdef CONFIG_HIGHMEM
 		if (bank->start >= vmalloc_limit)
 			highmem = 1;
 
 		bank->highmem = highmem;
 
+#ifdef CONFIG_HIGHMEM
 		/*
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
@@ -938,8 +935,6 @@ void __init sanity_check_meminfo(void)
 			bank->size = vmalloc_limit - bank->start;
 		}
 #else
-		bank->highmem = highmem;
-
 		/*
 		 * Highmem banks not allowed with !CONFIG_HIGHMEM.
 		 */
@@ -952,18 +947,6 @@ void __init sanity_check_meminfo(void)
 		}
 
 		/*
-		 * Check whether this memory bank would entirely overlap
-		 * the vmalloc area.
-		 */
-		if (bank->start >= vmalloc_limit) {
-			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
-			       "(vmalloc region overlap).\n",
-			       (unsigned long long)bank->start,
-			       (unsigned long long)bank->start + bank->size - 1);
-			continue;
-		}
-
-		/*
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 07/23] ARM: LPAE: use phys_addr_t for membank size
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch changes the membank structure's size field to phys_addr_t to allow
banks larger than 4G.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/setup.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 23ebc0c..a2e7581 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -195,8 +195,8 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn }
 #define NR_BANKS	CONFIG_ARM_NR_BANKS
 
 struct membank {
-	phys_addr_t start;
-	unsigned long size;
+	phys_addr_t  start;
+	phys_addr_t  size;
 	unsigned int highmem;
 };
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 16/23] ARM: LPAE: accomodate >32-bit addresses for page table base
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch redefines the early boot time use of the R4 register to steal a few
low order bits (ARCH_PGD_SHIFT bits), allowing for up to 38-bit physical
addresses.

This is probably not the best means to the end, and a better alternative may
be to modify the head.S register allocations to fit in full register pairs for
pgdir and swapper_pg_dir.  However, squeezing out these extra registers seemed
to be a far greater pain than squeezing out a few low order bits from the page
table addresses.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/cache.h |    9 +++++++++
 arch/arm/kernel/head.S       |    7 +++++--
 arch/arm/kernel/smp.c        |   11 +++++++++--
 arch/arm/mm/proc-arm1026.S   |    2 ++
 arch/arm/mm/proc-mohawk.S    |    2 ++
 arch/arm/mm/proc-v6.S        |    2 ++
 arch/arm/mm/proc-v7-2level.S |    2 ++
 arch/arm/mm/proc-v7-3level.S |    7 +++++++
 arch/arm/mm/proc-v7.S        |    1 +
 arch/arm/mm/proc-xsc3.S      |    2 ++
 10 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 75fe66b..986480c 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -17,6 +17,15 @@
 #define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
 
 /*
+ * Minimum guaranted alignment in pgd_alloc().  The page table pointers passed
+ * around in head.S and proc-*.S are shifted by this amount, in order to
+ * leave spare high bits for systems with physical address extension.  This
+ * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but
+ * gives us about 38-bits or so.
+ */
+#define ARCH_PGD_SHIFT		L1_CACHE_SHIFT
+
+/*
  * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
  */
 #if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 692e57f..6fe1c40 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -22,6 +22,7 @@
 #include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/pgtable.h>
+#include <asm/cache.h>
 
 #ifdef CONFIG_DEBUG_LL
 #include <mach/debug-macro.S>
@@ -160,7 +161,7 @@ ENDPROC(stext)
  *
  * Returns:
  *  r0, r3, r5-r7 corrupted
- *  r4 = physical page table address
+ *  r4 = page table (see ARCH_PGD_SHIFT in asm/cache.h)
  */
 __create_page_tables:
 	pgtbl	r4, r8				@ page table address
@@ -320,6 +321,7 @@ __create_page_tables:
 #ifdef CONFIG_ARM_LPAE
 	sub	r4, r4, #0x1000		@ point to the PGD table
 #endif
+	mov	r4, r4, lsr #ARCH_PGD_SHIFT
 	mov	pc, lr
 ENDPROC(__create_page_tables)
 	.ltorg
@@ -392,7 +394,7 @@ __secondary_data:
  *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r2  = atags or dtb pointer
- *  r4  = page table pointer
+ *  r4  = page table (see ARCH_PGD_SHIFT in asm/cache.h)
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  */
@@ -422,6 +424,7 @@ __enable_mmu:
 	@ has the processor setup already programmed the page table pointer?
 	adds	r5, r4, #1
 	beq	__turn_mmu_on			@ yes!
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	b	__turn_mmu_on
 ENDPROC(__enable_mmu)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 2c7217d..e41e1be 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -42,6 +42,7 @@
 #include <asm/ptrace.h>
 #include <asm/localtimer.h>
 #include <asm/smp_plat.h>
+#include <asm/cache.h>
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
@@ -62,6 +63,7 @@ static DECLARE_COMPLETION(cpu_running);
 
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
+	phys_addr_t pgdir;
 	int ret;
 
 	/*
@@ -69,8 +71,13 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 * its stack and the page tables.
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
-	secondary_data.pgdir = virt_to_phys(idmap_pgd);
-	secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
+
+	pgdir = virt_to_phys(idmap_pgd);
+	secondary_data.pgdir = pgdir >> ARCH_PGD_SHIFT;
+
+	pgdir = virt_to_phys(swapper_pg_dir);
+	secondary_data.swapper_pg_dir = pgdir >> ARCH_PGD_SHIFT;
+
 	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
 	outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
 
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index c28070e..4556f77 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -22,6 +22,7 @@
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
+#include <asm/cache.h>
 
 #include "proc-macros.S"
 
@@ -403,6 +404,7 @@ __arm1026_setup:
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	mcr	p15, 0, r4, c2, c0		@ load page table pointer
 	mvn	r4, #0				@ do not set page table pointer
 #endif
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index a26303c..13fcc67 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -28,6 +28,7 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
+#include <asm/cache.h>
 #include "proc-macros.S"
 
 /*
@@ -388,6 +389,7 @@ __mohawk_setup:
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	mvn	r4, #0				@ do not set page table pointer
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 872156e..4751be7 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -17,6 +17,7 @@
 #include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
+#include <asm/cache.h>
 
 #include "proc-macros.S"
 
@@ -206,6 +207,7 @@ __v6_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	ALT_SMP(orr	r4, r4, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r4, r4, #TTB_FLAGS_UP)
 	ALT_SMP(orr	r8, r8, #TTB_FLAGS_SMP)
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index cc78c0c..f4bc63b 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -143,8 +143,10 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	mcr	p15, 0, \zero, c2, c0, 2	@ TTB control register
+	mov	\ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT
 	ALT_SMP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_SMP)
 	ALT_UP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_UP)
+	mov	\ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT
 	ALT_SMP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_SMP)
 	ALT_UP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_UP)
 	mcr	p15, 0, \ttbr0, c2, c0, 0	@ load TTB0
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 5e3bed1..33f322a 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -103,6 +103,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	ldr	\tmp, =swapper_pg_dir		@ swapper_pg_dir virtual address
+	mov	\tmp, \tmp, lsr #ARCH_PGD_SHIFT
 	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET? (branch below)
 	mrc	p15, 0, \tmp, c2, c0, 2		@ TTB control register
 	orr	\tmp, \tmp, #TTB_EAE
@@ -122,8 +123,14 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
 	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
+	mov	\tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT		@ lower bits
 	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
 	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mov	\tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT		@ lower bits
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
 	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
 	.endm
 
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 8850194..443f602 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -16,6 +16,7 @@
 #include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
+#include <asm/cache.h>
 
 #include "proc-macros.S"
 
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index db3836b..a43a07d 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -32,6 +32,7 @@
 #include <asm/pgtable-hwdef.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
+#include <asm/cache.h>
 #include "proc-macros.S"
 
 /*
@@ -453,6 +454,7 @@ __xsc3_setup:
 	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
 	mcr	p15, 0, ip, c7, c5, 4		@ prefetch flush
 	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
+	mov	r4, r4, lsl #ARCH_PGD_SHIFT
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	mvn	r4, #0				@ do not set page table pointer
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 20/23] mm: bootmem: use phys_addr_t for physical addresses
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vitaly Andrianov <vitalya@ti.com>

On a physical address extended (PAE) systems physical memory may be located
outside the first 4GB address range.  In particular, on TI Keystone devices,
all memory (including lowmem) is located outside the 4G address space. Many
functions in the bootmem.c use unsigned long as a type for physical addresses,
and this breaks badly on such PAE systems.

This patch intensively mangles the bootmem allocator to use phys_addr_t where
necessary.  We are aware that this is most certainly not the way to go
considering that the ARM architecture appears to be moving towards memblock.
Memblock may be a better solution, and fortunately it looks a lot more PAE
savvy than bootmem is.

However, we do not fully understand the motivations and restrictions behind
the mixed bootmem + memblock model in current ARM code. We hope for a
meaningful discussion and useful guidance towards a better solution to this
problem.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 include/linux/bootmem.h |   30 ++++++++++++------------
 mm/bootmem.c            |   59 ++++++++++++++++++++++++-----------------------
 2 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 6d6795d..e43c463 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -49,10 +49,10 @@ extern unsigned long free_all_bootmem_node(pg_data_t *pgdat);
 extern unsigned long free_all_bootmem(void);
 
 extern void free_bootmem_node(pg_data_t *pgdat,
-			      unsigned long addr,
+			      phys_addr_t addr,
 			      unsigned long size);
-extern void free_bootmem(unsigned long addr, unsigned long size);
-extern void free_bootmem_late(unsigned long addr, unsigned long size);
+extern void free_bootmem(phys_addr_t addr, unsigned long size);
+extern void free_bootmem_late(phys_addr_t addr, unsigned long size);
 
 /*
  * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
@@ -65,44 +65,44 @@ extern void free_bootmem_late(unsigned long addr, unsigned long size);
 #define BOOTMEM_DEFAULT		0
 #define BOOTMEM_EXCLUSIVE	(1<<0)
 
-extern int reserve_bootmem(unsigned long addr,
+extern int reserve_bootmem(phys_addr_t addr,
 			   unsigned long size,
 			   int flags);
 extern int reserve_bootmem_node(pg_data_t *pgdat,
-				unsigned long physaddr,
+				phys_addr_t physaddr,
 				unsigned long size,
 				int flags);
 
 extern void *__alloc_bootmem(unsigned long size,
 			     unsigned long align,
-			     unsigned long goal);
+			     phys_addr_t goal);
 extern void *__alloc_bootmem_nopanic(unsigned long size,
 				     unsigned long align,
-				     unsigned long goal);
+				     phys_addr_t goal);
 extern void *__alloc_bootmem_node(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal);
+				  phys_addr_t goal);
 void *__alloc_bootmem_node_high(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal);
+				  phys_addr_t goal);
 extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal);
+				  phys_addr_t goal);
 void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
 				  unsigned long size,
 				  unsigned long align,
-				  unsigned long goal,
-				  unsigned long limit);
+				  phys_addr_t goal,
+				  phys_addr_t limit);
 extern void *__alloc_bootmem_low(unsigned long size,
 				 unsigned long align,
-				 unsigned long goal);
+				 phys_addr_t goal);
 extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
 				      unsigned long size,
 				      unsigned long align,
-				      unsigned long goal);
+				      phys_addr_t goal);
 
 #ifdef CONFIG_NO_BOOTMEM
 /* We are using top down, so it is safe to use 0 here */
@@ -137,7 +137,7 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
 #define alloc_bootmem_low_pages_node(pgdat, x) \
 	__alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0)
 
-extern int reserve_bootmem_generic(unsigned long addr, unsigned long size,
+extern int reserve_bootmem_generic(phys_addr_t addr, unsigned long size,
 				   int flags);
 
 #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
diff --git a/mm/bootmem.c b/mm/bootmem.c
index bcb63ac..e7dc572 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -154,7 +154,7 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
  * down, but we are still initializing the system.  Pages are given directly
  * to the page allocator, no bootmem metadata is updated because it is gone.
  */
-void __init free_bootmem_late(unsigned long addr, unsigned long size)
+void __init free_bootmem_late(phys_addr_t addr, unsigned long size)
 {
 	unsigned long cursor, end;
 
@@ -362,7 +362,7 @@ static int __init mark_bootmem(unsigned long start, unsigned long end,
  *
  * The range must reside completely on the specified node.
  */
-void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
+void __init free_bootmem_node(pg_data_t *pgdat, phys_addr_t physaddr,
 			      unsigned long size)
 {
 	unsigned long start, end;
@@ -384,7 +384,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
  *
  * The range must be contiguous but may span node boundaries.
  */
-void __init free_bootmem(unsigned long addr, unsigned long size)
+void __init free_bootmem(phys_addr_t addr, unsigned long size)
 {
 	unsigned long start, end;
 
@@ -407,7 +407,7 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
  *
  * The range must reside completely on the specified node.
  */
-int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
+int __init reserve_bootmem_node(pg_data_t *pgdat, phys_addr_t physaddr,
 				 unsigned long size, int flags)
 {
 	unsigned long start, end;
@@ -428,7 +428,7 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
  *
  * The range must be contiguous but may span node boundaries.
  */
-int __init reserve_bootmem(unsigned long addr, unsigned long size,
+int __init reserve_bootmem(phys_addr_t addr, unsigned long size,
 			    int flags)
 {
 	unsigned long start, end;
@@ -439,7 +439,7 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size,
 	return mark_bootmem(start, end, 1, flags);
 }
 
-int __weak __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
+int __weak __init reserve_bootmem_generic(phys_addr_t phys, unsigned long len,
 				   int flags)
 {
 	return reserve_bootmem(phys, len, flags);
@@ -461,7 +461,7 @@ static unsigned long __init align_idx(struct bootmem_data *bdata,
 static unsigned long __init align_off(struct bootmem_data *bdata,
 				      unsigned long off, unsigned long align)
 {
-	unsigned long base = PFN_PHYS(bdata->node_min_pfn);
+	phys_addr_t base = PFN_PHYS(bdata->node_min_pfn);
 
 	/* Same as align_idx for byte offsets */
 
@@ -470,14 +470,14 @@ static unsigned long __init align_off(struct bootmem_data *bdata,
 
 static void * __init alloc_bootmem_bdata(struct bootmem_data *bdata,
 					unsigned long size, unsigned long align,
-					unsigned long goal, unsigned long limit)
+					phys_addr_t goal, phys_addr_t limit)
 {
 	unsigned long fallback = 0;
 	unsigned long min, max, start, sidx, midx, step;
 
-	bdebug("nid=%td size=%lx [%lu pages] align=%lx goal=%lx limit=%lx\n",
+	bdebug("nid=%td size=%lx [%lu pages] align=%lx goal=%llx limit=%llx\n",
 		bdata - bootmem_node_data, size, PAGE_ALIGN(size) >> PAGE_SHIFT,
-		align, goal, limit);
+		align, (u64)goal, (u64)limit);
 
 	BUG_ON(!size);
 	BUG_ON(align & (align - 1));
@@ -519,7 +519,8 @@ static void * __init alloc_bootmem_bdata(struct bootmem_data *bdata,
 	while (1) {
 		int merge;
 		void *region;
-		unsigned long eidx, i, start_off, end_off;
+		unsigned long eidx, i;
+		phys_addr_t   start_off, end_off;
 find_block:
 		sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx);
 		sidx = align_idx(bdata, sidx, step);
@@ -577,7 +578,7 @@ find_block:
 
 static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata,
 					unsigned long size, unsigned long align,
-					unsigned long goal, unsigned long limit)
+					phys_addr_t goal, phys_addr_t limit)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc(size, GFP_NOWAIT);
@@ -598,8 +599,8 @@ static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata,
 
 static void * __init alloc_bootmem_core(unsigned long size,
 					unsigned long align,
-					unsigned long goal,
-					unsigned long limit)
+					phys_addr_t goal,
+					phys_addr_t limit)
 {
 	bootmem_data_t *bdata;
 	void *region;
@@ -624,8 +625,8 @@ static void * __init alloc_bootmem_core(unsigned long size,
 
 static void * __init ___alloc_bootmem_nopanic(unsigned long size,
 					      unsigned long align,
-					      unsigned long goal,
-					      unsigned long limit)
+					      phys_addr_t goal,
+					      phys_addr_t limit)
 {
 	void *ptr;
 
@@ -655,15 +656,15 @@ restart:
  * Returns NULL on failure.
  */
 void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
-					unsigned long goal)
+					phys_addr_t goal)
 {
-	unsigned long limit = 0;
+	phys_addr_t limit = 0;
 
 	return ___alloc_bootmem_nopanic(size, align, goal, limit);
 }
 
 static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
-					unsigned long goal, unsigned long limit)
+					phys_addr_t goal, phys_addr_t limit)
 {
 	void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
 
@@ -691,16 +692,16 @@ static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem(unsigned long size, unsigned long align,
-			      unsigned long goal)
+			      phys_addr_t goal)
 {
-	unsigned long limit = 0;
+	phys_addr_t limit = 0;
 
 	return ___alloc_bootmem(size, align, goal, limit);
 }
 
 void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
 				unsigned long size, unsigned long align,
-				unsigned long goal, unsigned long limit)
+				phys_addr_t goal, phys_addr_t limit)
 {
 	void *ptr;
 
@@ -731,7 +732,7 @@ again:
 }
 
 void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
-				   unsigned long align, unsigned long goal)
+				   unsigned long align, phys_addr_t goal)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
@@ -740,8 +741,8 @@ void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
 }
 
 void * __init ___alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-				    unsigned long align, unsigned long goal,
-				    unsigned long limit)
+				    unsigned long align, phys_addr_t goal,
+				    phys_addr_t limit)
 {
 	void *ptr;
 
@@ -770,7 +771,7 @@ void * __init ___alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-				   unsigned long align, unsigned long goal)
+				   unsigned long align, phys_addr_t goal)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
@@ -779,7 +780,7 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
 }
 
 void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
-				   unsigned long align, unsigned long goal)
+				   unsigned long align, phys_addr_t goal)
 {
 #ifdef MAX_DMA32_PFN
 	unsigned long end_pfn;
@@ -825,7 +826,7 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
-				  unsigned long goal)
+				  phys_addr_t goal)
 {
 	return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
 }
@@ -846,7 +847,7 @@ void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
  * The function panics if the request can not be satisfied.
  */
 void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
-				       unsigned long align, unsigned long goal)
+				       unsigned long align, phys_addr_t goal)
 {
 	if (WARN_ON_ONCE(slab_is_available()))
 		return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 12/23] ARM: mm: clean up membank size limit checks
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch cleans up the highmem sanity check code by simplifying the range
checks with a pre-calculated size_limit.  This patch should otherwise have no
functional impact on behavior.

This patch also removes a redundant (bank->start < vmalloc_limit) check, since
this is already covered by the !highmem condition.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/mm/mmu.c |   19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4840efa..6b0baf3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -905,10 +905,15 @@ void __init sanity_check_meminfo(void)
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
+		phys_addr_t size_limit;
+
 		*bank = meminfo.bank[i];
+		size_limit = bank->size;
 
 		if (bank->start >= vmalloc_limit)
 			highmem = 1;
+		else
+			size_limit = vmalloc_limit - bank->start;
 
 		bank->highmem = highmem;
 
@@ -917,8 +922,7 @@ void __init sanity_check_meminfo(void)
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (!highmem && bank->start < vmalloc_limit &&
-		    bank->size > vmalloc_limit - bank->start) {
+		if (!highmem && bank->size > size_limit) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -927,12 +931,12 @@ void __init sanity_check_meminfo(void)
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= vmalloc_limit - bank->start;
+				bank[1].size -= size_limit;
 				bank[1].start = vmalloc_limit;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = vmalloc_limit - bank->start;
+			bank->size = size_limit;
 		}
 #else
 		/*
@@ -950,14 +954,13 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (bank->start + bank->size > vmalloc_limit)
-			unsigned long newsize = vmalloc_limit - bank->start;
+		if (bank->size > size_limit) {
 			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
 			       "to -%.8llx (vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
 			       (unsigned long long)bank->start + bank->size - 1,
-			       (unsigned long long)bank->start + newsize - 1);
-			bank->size = newsize;
+			       (unsigned long long)bank->start + size_limit - 1);
+			bank->size = size_limit;
 		}
 #endif
 		if (!bank->highmem && bank->start + bank->size > arm_lowmem_limit)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 17/23] ARM: add machine desc hook for early memory/paging initialization
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds a machine descriptor hook that gives control to machine
specific code prior to memory and paging initialization.

On Keystone platforms, this hook is used to switch the PHYS_OFFSET over
to the "real" non-32-bit-addressable address range.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/mach/arch.h |    1 +
 arch/arm/kernel/setup.c          |    3 +++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 0b1c94b..49e9c2a 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -39,6 +39,7 @@ struct machine_desc {
 					 struct meminfo *);
 	void			(*reserve)(void);/* reserve mem blocks	*/
 	void			(*map_io)(void);/* IO mapping function	*/
+	void			(*init_meminfo)(void);
 	void			(*init_early)(void);
 	void			(*init_irq)(void);
 	struct sys_timer	*timer;		/* system tick timer	*/
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index e15d83b..7cbe292 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -964,6 +964,9 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+	if (mdesc->init_meminfo)
+		mdesc->init_meminfo();
+
 	sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
 	sanity_check_meminfo();
 	arm_memblock_init(&meminfo, mdesc);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 09/23] ARM: LPAE: use 64-bit accessors for TTBR registers
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds TTBR accessor macros, and modifies cpu_get_pgd() and
the LPAE version of cpu_set_reserved_ttbr0() to use these instead.

In the process, we also fix these functions to correctly handle cases
where the physical address lies beyond the 4G limit of 32-bit addressing.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/proc-fns.h |   24 +++++++++++++++++++-----
 arch/arm/mm/context.c           |   13 ++-----------
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index fa6554e..918b4f9 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -116,13 +116,27 @@ extern void cpu_resume(void);
 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
 
 #ifdef CONFIG_ARM_LPAE
+
+#define cpu_get_ttbr(nr)					\
+	({							\
+		u64 ttbr;					\
+		__asm__("mrrc	p15, " #nr ", %Q0, %R0, c2"	\
+			: "=r" (ttbr)				\
+			: : "cc");				\
+		ttbr;						\
+	})
+
+#define cpu_set_ttbr(nr, val)					\
+	do {							\
+		u64 ttbr = val;					\
+		__asm__("mcrr	p15, " #nr ", %Q0, %R0, c2"	\
+			: : "r" (ttbr)				\
+			: "cc");				\
+	} while (0)
+
 #define cpu_get_pgd()	\
 	({						\
-		unsigned long pg, pg2;			\
-		__asm__("mrrc	p15, 0, %0, %1, c2"	\
-			: "=r" (pg), "=r" (pg2)		\
-			:				\
-			: "cc");			\
+		u64 pg = cpu_get_ttbr(0);		\
 		pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);	\
 		(pgd_t *)phys_to_virt(pg);		\
 	})
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 806cc4f..ad70bd8 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -15,6 +15,7 @@
 
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
+#include <asm/proc-fns.h>
 
 static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
 unsigned int cpu_last_asid = ASID_FIRST_VERSION;
@@ -22,17 +23,7 @@ unsigned int cpu_last_asid = ASID_FIRST_VERSION;
 #ifdef CONFIG_ARM_LPAE
 void cpu_set_reserved_ttbr0(void)
 {
-	unsigned long ttbl = __pa(swapper_pg_dir);
-	unsigned long ttbh = 0;
-
-	/*
-	 * Set TTBR0 to swapper_pg_dir which contains only global entries. The
-	 * ASID is set to 0.
-	 */
-	asm volatile(
-	"	mcrr	p15, 0, %0, %1, c2		@ set TTBR0\n"
-	:
-	: "r" (ttbl), "r" (ttbh));
+	cpu_set_ttbr(0, __pa(swapper_pg_dir));
 	isb();
 }
 #else
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch fixes up the types used when converting back and forth between
physical and virtual addresses.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/include/asm/memory.h |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index fcb5757..7629dfe 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
 	: "=r" (to)					\
 	: "r" (from), "I" (type))
 
-static inline unsigned long __virt_to_phys(unsigned long x)
+static inline phys_addr_t __virt_to_phys(unsigned long x)
 {
 	unsigned long t;
 	__pv_stub(x, t, "add", __PV_BITS_31_24);
 	return t;
 }
 
-static inline unsigned long __phys_to_virt(unsigned long x)
+static inline unsigned long __phys_to_virt(phys_addr_t x)
 {
 	unsigned long t;
 	__pv_stub(x, t, "sub", __PV_BITS_31_24);
 	return t;
 }
 #else
-#define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
-#define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+
+#define __virt_to_phys(x)		\
+	((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET)
+
+#define __phys_to_virt(x)		\
+	((unsigned long)((phys_addr_t)(x) - PHYS_OFFSET + PAGE_OFFSET))
+
 #endif
 #endif
 
@@ -219,14 +224,14 @@ static inline phys_addr_t virt_to_phys(const volatile void *x)
 
 static inline void *phys_to_virt(phys_addr_t x)
 {
-	return (void *)(__phys_to_virt((unsigned long)(x)));
+	return (void *)__phys_to_virt(x);
 }
 
 /*
  * Drivers should NOT use these either.
  */
 #define __pa(x)			__virt_to_phys((unsigned long)(x))
-#define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+#define __va(x)			((void *)__phys_to_virt((phys_addr_t)(x)))
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
 /*
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 18/23] ARM: add virt_to_idmap for interconnect aliasing
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vitaly Andrianov <vitalya@ti.com>

On some PAE systems (e.g. TI Keystone), memory is above the 32-bit addressible
limit, and the interconnect provides an aliased view of parts of physical
memory in the 32-bit addressible space.  This alias is strictly for boot time
usage, and is not otherwise usable because of coherency limitations.

On such systems, the idmap mechanism needs to take this aliased mapping into
account.  This patch introduces a virt_to_idmap() macro, which can be used on
such sub-architectures to represent the interconnect supported boot time
alias.  Most other systems would leave this macro untouched, i.e., do a simply
virt_to_phys() and nothing more.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/include/asm/memory.h |    9 +++++++++
 arch/arm/kernel/smp.c         |    4 ++--
 arch/arm/mm/idmap.c           |    4 ++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index c330a23..b6b203c 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -235,6 +235,15 @@ static inline void *phys_to_virt(phys_addr_t x)
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
 /*
+ * These are for systems that have a hardware interconnect supported alias of
+ * physical memory for idmap purposes.  Most cases should leave these
+ * untouched.
+ */
+#ifndef virt_to_idmap
+#define virt_to_idmap(x) virt_to_phys(x)
+#endif
+
+/*
  * Virtual <-> DMA view memory address translations
  * Again, these are *only* valid on the kernel direct mapped RAM
  * memory.  Use of these is *deprecated* (and that doesn't mean
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e41e1be..cce630c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -72,10 +72,10 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 
-	pgdir = virt_to_phys(idmap_pgd);
+	pgdir = virt_to_idmap(idmap_pgd);
 	secondary_data.pgdir = pgdir >> ARCH_PGD_SHIFT;
 
-	pgdir = virt_to_phys(swapper_pg_dir);
+	pgdir = virt_to_idmap(swapper_pg_dir);
 	secondary_data.swapper_pg_dir = pgdir >> ARCH_PGD_SHIFT;
 
 	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index ab88ed4..919cb6e 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -85,8 +85,8 @@ static int __init init_static_idmap(void)
 		return -ENOMEM;
 
 	/* Add an identity mapping for the physical address of the section. */
-	idmap_start = virt_to_phys((void *)__idmap_text_start);
-	idmap_end = virt_to_phys((void *)__idmap_text_end);
+	idmap_start = virt_to_idmap((void *)__idmap_text_start);
+	idmap_end = virt_to_idmap((void *)__idmap_text_end);
 
 	pr_info("Setting up static identity map for 0x%llx - 0x%llx\n",
 		(long long)idmap_start, (long long)idmap_end);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 13/23] ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds an architecture defined override for ARCH_LOW_ADDRESS_LIMIT.
On PAE systems, the absence of this override causes bootmem to incorrectly
limit itself to 32-bit addressable physical memory.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/memory.h |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 7629dfe..c330a23 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -285,6 +285,8 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
 #define arch_is_coherent()		0
 #endif
 
+#define ARCH_LOW_ADDRESS_LIMIT		PHYS_MASK
+
 #endif
 
 #include <asm-generic/memory_model.h>
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 10/23] ARM: mm: use physical addresses in highmem sanity checks
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modifies the highmem sanity checking code to use physical addresses
instead.  This change eliminates the wrap-around problems associated with the
original virtual address based checks, and this simplifies the code a bit.

The one constraint imposed here is that low physical memory must be mapped in
a monotonically increasing fashion if there are multiple banks of memory,
i.e., x < y must => pa(x) < pa(y).

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/mm/mmu.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 226985c..adaf8c3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -901,6 +901,7 @@ phys_addr_t arm_lowmem_limit __initdata = 0;
 void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
+	phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1;
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
@@ -910,8 +911,7 @@ void __init sanity_check_meminfo(void)
 			highmem = 1;
 
 #ifdef CONFIG_HIGHMEM
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET)
+		if (bank->start >= vmalloc_limit)
 			highmem = 1;
 
 		bank->highmem = highmem;
@@ -920,8 +920,8 @@ void __init sanity_check_meminfo(void)
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (!highmem && __va(bank->start) < vmalloc_min &&
-		    bank->size > vmalloc_min - __va(bank->start)) {
+		if (!highmem && bank->start < vmalloc_limit &&
+		    bank->size > vmalloc_limit - bank->start) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -930,12 +930,12 @@ void __init sanity_check_meminfo(void)
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= vmalloc_min - __va(bank->start);
-				bank[1].start = __pa(vmalloc_min - 1) + 1;
+				bank[1].size -= vmalloc_limit - bank->start;
+				bank[1].start = vmalloc_limit;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = vmalloc_min - __va(bank->start);
+			bank->size = vmalloc_limit - bank->start;
 		}
 #else
 		bank->highmem = highmem;
@@ -955,8 +955,7 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would entirely overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET) {
+		if (bank->start >= vmalloc_limit) {
 			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
 			       "(vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
@@ -968,9 +967,8 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start + bank->size) > vmalloc_min ||
-		    __va(bank->start + bank->size) < __va(bank->start)) {
-			unsigned long newsize = vmalloc_min - __va(bank->start);
+		if (bank->start + bank->size > vmalloc_limit)
+			unsigned long newsize = vmalloc_limit - bank->start;
 			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
 			       "to -%.8llx (vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 15/23] ARM: LPAE: allow proc override of TTB setup
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch allows ARM processor setup functions (*_setup in proc-*.S) to
indicate that the page table has already been programmed.  This is
done by setting r4 (page table pointer) to -1 before returning from the
processor setup handler.

This capability is particularly needed on LPAE systems, where the translation
table base needs to be programmed differently with 64-bit control
register operations.

Further, a few of the processors (arm1026, mohawk, xsc3) were programming the
TTB twice.  This patch prevents the main head.S code from programming TTB the
second time on these machines.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/kernel/head.S       |   11 ++++++-----
 arch/arm/mm/proc-arm1026.S   |    1 +
 arch/arm/mm/proc-mohawk.S    |    1 +
 arch/arm/mm/proc-v6.S        |    2 ++
 arch/arm/mm/proc-v7-2level.S |    3 ++-
 arch/arm/mm/proc-v7-3level.S |    1 +
 arch/arm/mm/proc-v7.S        |    1 +
 arch/arm/mm/proc-xsc3.S      |    1 +
 8 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 835898e..692e57f 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -411,17 +411,18 @@ __enable_mmu:
 #ifdef CONFIG_CPU_ICACHE_DISABLE
 	bic	r0, r0, #CR_I
 #endif
-#ifdef CONFIG_ARM_LPAE
-	mov	r5, #0
-	mcrr	p15, 0, r4, r5, c2		@ load TTBR0
-#else
+#ifndef CONFIG_ARM_LPAE
 	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_IO, DOMAIN_CLIENT))
 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
-	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 #endif
+
+	@ has the processor setup already programmed the page table pointer?
+	adds	r5, r4, #1
+	beq	__turn_mmu_on			@ yes!
+	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	b	__turn_mmu_on
 ENDPROC(__enable_mmu)
 
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index fbc1d5f..c28070e 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -404,6 +404,7 @@ __arm1026_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mvn	r4, #0				@ do not set page table pointer
 #endif
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mov	r0, #4				@ explicitly disable writeback
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index fbb2124..a26303c 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -390,6 +390,7 @@ __mohawk_setup:
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+	mvn	r4, #0				@ do not set page table pointer
 
 	mov	r0, #0				@ don't allow CP access
 	mcr	p15, 0, r0, c15, c1, 0		@ write CP access register
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 566c658..872156e 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -210,7 +210,9 @@ __v6_setup:
 	ALT_UP(orr	r4, r4, #TTB_FLAGS_UP)
 	ALT_SMP(orr	r8, r8, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r8, r8, #TTB_FLAGS_UP)
+	mcr	p15, 0, r4, c2, c0, 0		@ load TTB0
 	mcr	p15, 0, r8, c2, c0, 1		@ load TTB1
+	mvn	r4, #0				@ do not set page table pointer
 #endif /* CONFIG_MMU */
 	adr	r5, v6_crval
 	ldmia	r5, {r5, r6}
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 3397803..cc78c0c 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -139,7 +139,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 
 	/*
 	 * Macro for setting up the TTBRx and TTBCR registers.
-	 * - \ttb0 and \ttb1 updated with the corresponding flags.
+	 * - \ttbr0 and \ttbr1 updated with the corresponding flags.
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	mcr	p15, 0, \zero, c2, c0, 2	@ TTB control register
@@ -147,6 +147,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	ALT_UP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_UP)
 	ALT_SMP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_SMP)
 	ALT_UP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_UP)
+	mcr	p15, 0, \ttbr0, c2, c0, 0	@ load TTB0
 	mcr	p15, 0, \ttbr1, c2, c0, 1	@ load TTB1
 	.endm
 
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 3b1a745..5e3bed1 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -124,6 +124,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
 	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
 	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
 	.endm
 
 	__CPUINIT
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index c2e2b66..8850194 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -250,6 +250,7 @@ __v7_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r10, c8, c7, 0		@ invalidate I + D TLBs
 	v7_ttb_setup r10, r4, r8, r5		@ TTBCR, TTBRx setup
+	mvn	r4, #0				@ do not set page table pointer
 	ldr	r5, =PRRR			@ PRRR
 	ldr	r6, =NMRR			@ NMRR
 	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index b0d5786..db3836b 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -455,6 +455,7 @@ __xsc3_setup:
 	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+	mvn	r4, #0				@ do not set page table pointer
 
 	mov	r0, #1 << 6			@ cp6 access for early sched_clock
 	mcr	p15, 0, r0, c15, c1, 0		@ write CP access register
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 22/23] ARM: keystone: enable SMP on Keystone machines
@ 2012-07-24  1:10   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds basic SMP support for Keystone machines.  Nothing very fancy
here, just enough to get 4 CPUs booted up.  This does not include support for
hotplug, etc.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig                    |    1 +
 arch/arm/configs/keystone_defconfig |    2 +
 arch/arm/mach-keystone/Makefile     |    1 +
 arch/arm/mach-keystone/keystone.c   |    3 ++
 arch/arm/mach-keystone/platsmp.c    |   73 +++++++++++++++++++++++++++++++++++
 5 files changed, 80 insertions(+)
 create mode 100644 arch/arm/mach-keystone/platsmp.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 04c846b..5b82879 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -372,6 +372,7 @@ config ARCH_KEYSTONE
 	select SPARSE_IRQ
 	select NEED_MACH_MEMORY_H
 	select HAVE_SCHED_CLOCK
+	select HAVE_SMP
 	help
 	  Support for boards based on the Texas Instruments Keystone family of
 	  SoCs.
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 7f2a04b..5f71e66 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -1,7 +1,9 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_SMP=y
 CONFIG_ARM_ARCH_TIMER=y
+CONFIG_NR_CPUS=4
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_VFP=y
diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile
index d4671d5..3f6b8ab 100644
--- a/arch/arm/mach-keystone/Makefile
+++ b/arch/arm/mach-keystone/Makefile
@@ -1 +1,2 @@
 obj-y					:= keystone.o
+obj-$(CONFIG_SMP)			+= platsmp.o
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index 9583dc4..650e202 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -26,6 +26,8 @@
 #include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
 
+extern struct smp_ops keystone_smp_ops;
+
 static struct map_desc io_desc[] = {
 	{
 		.virtual        = 0xfe800000UL,
@@ -73,6 +75,7 @@ static const char *keystone_match[] __initconst = {
 };
 
 DT_MACHINE_START(KEYSTONE, "Keystone")
+	smp_ops(keystone_smp_ops)
 	.map_io		= keystone_map_io,
 	.init_irq	= keystone_init_irq,
 	.timer		= &keystone_timer,
diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c
new file mode 100644
index 0000000..437659a
--- /dev/null
+++ b/arch/arm/mach-keystone/platsmp.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012 Texas Instruments, Inc.
+ *
+ * Based on platsmp.c, Copyright 2010-2011 Calxeda, Inc.
+ * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/smp_plat.h>
+#include <asm/smp_ops.h>
+#include <asm/hardware/gic.h>
+#include <asm/cacheflush.h>
+#include <asm/memory.h>
+
+extern void secondary_startup(void);
+
+static void __init keystone_smp_init_cpus(void)
+{
+	unsigned int i, ncores;
+
+	ncores = 4;
+
+	/* sanity check */
+	if (ncores > NR_CPUS) {
+		pr_warn("restricted to %d cpus\n", NR_CPUS);
+		ncores = NR_CPUS;
+	}
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
+}
+
+static void __init keystone_smp_prepare_cpus(unsigned int max_cpus)
+{
+	/* nothing for now */
+}
+
+static void __cpuinit keystone_secondary_init(unsigned int cpu)
+{
+	gic_secondary_init(0);
+}
+
+static int __cpuinit
+keystone_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long *jump_ptr = phys_to_virt(0x800001f0);
+
+	jump_ptr[cpu] = virt_to_idmap(&secondary_startup);
+	__cpuc_flush_dcache_area(jump_ptr, sizeof(jump_ptr) * 4);
+
+	return 0;
+}
+
+struct smp_ops keystone_smp_ops __initdata = {
+	smp_init_ops(keystone)
+	smp_secondary_ops(keystone)
+};
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 23/23] ARM: keystone: add switch over to high physical address range
@ 2012-07-24  1:33   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:33 UTC (permalink / raw)
  To: linux-arm-kernel

Keystone platforms have their physical memory mapped at an address outside the
32-bit physical range.  A Keystone machine with 16G of RAM would find its
memory at 0x0800000000 - 0x0bffffffff.

For boot purposes, the interconnect supports a limited alias of some of this
memory within the 32-bit addressable space (0x80000000 - 0xffffffff).  This
aliasing is implemented in hardware, and is not intended to be used much
beyond boot.  For instance, DMA coherence does not work when running out of
this aliased address space.

Therefore, we've taken the approach of booting out of the low physical address
range, and subsequently we switch over to the high range once we're safely
inside machine specific territory.  This patch implements this switch over
mechanism, which involves rewiring the TTBRs and page tables to point to the
new physical address space.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig                             |    1 +
 arch/arm/boot/dts/keystone-sim.dts           |    6 +-
 arch/arm/configs/keystone_defconfig          |    1 +
 arch/arm/mach-keystone/include/mach/memory.h |   29 ++++++++
 arch/arm/mach-keystone/keystone.c            |   92 ++++++++++++++++++++++++++
 arch/arm/mach-keystone/platsmp.c             |   21 ++++++
 6 files changed, 147 insertions(+), 3 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5b82879..f970ee1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -373,6 +373,7 @@ config ARCH_KEYSTONE
 	select NEED_MACH_MEMORY_H
 	select HAVE_SCHED_CLOCK
 	select HAVE_SMP
+	select ZONE_DMA if ARM_LPAE
 	help
 	  Support for boards based on the Texas Instruments Keystone family of
 	  SoCs.
diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
index 118d631..afdef89 100644
--- a/arch/arm/boot/dts/keystone-sim.dts
+++ b/arch/arm/boot/dts/keystone-sim.dts
@@ -4,7 +4,7 @@
 / {
 	model = "Texas Instruments Keystone 2 SoC";
 	compatible = "ti,keystone-evm";
-	#address-cells = <1>;
+	#address-cells = <2>;
 	#size-cells = <1>;
 	interrupt-parent = <&gic>;
 
@@ -13,11 +13,11 @@
 	};
 
 	chosen {
-		bootargs = "console=ttyS0,115200n8 debug earlyprintk lpj=50000 rdinit=/bin/ash rw root=/dev/ram0 initrd=0x85000000,9M";
+		bootargs = "console=ttyS0,115200n8 debug earlyprintk lpj=50000 rdinit=/bin/ash rw root=/dev/ram0 initrd=0x805000000,9M";
 	};
 
 	memory {
-		reg = <0x80000000 0x8000000>;
+		reg = <0x00000008 0x00000000 0x8000000>;
 	};
 
 	cpus {
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 5f71e66..8ea3b96 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -1,6 +1,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARM_LPAE=y
 CONFIG_SMP=y
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_NR_CPUS=4
diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
index 7c78b1e..6404633 100644
--- a/arch/arm/mach-keystone/include/mach/memory.h
+++ b/arch/arm/mach-keystone/include/mach/memory.h
@@ -19,4 +19,33 @@
 #define MAX_PHYSMEM_BITS	36
 #define SECTION_SIZE_BITS	34
 
+#define KEYSTONE_LOW_PHYS_START		0x80000000ULL
+#define KEYSTONE_LOW_PHYS_SIZE		0x80000000ULL /* 2G */
+#define KEYSTONE_LOW_PHYS_END		(KEYSTONE_LOW_PHYS_START + \
+					 KEYSTONE_LOW_PHYS_SIZE - 1)
+
+#define KEYSTONE_HIGH_PHYS_START	0x800000000ULL
+#define KEYSTONE_HIGH_PHYS_SIZE		0x400000000ULL	/* 16G */
+#define KEYSTONE_HIGH_PHYS_END		(KEYSTONE_HIGH_PHYS_START + \
+					 KEYSTONE_HIGH_PHYS_SIZE - 1)
+#ifdef CONFIG_ARM_LPAE
+
+#ifndef __ASSEMBLY__
+
+extern phys_addr_t  keystone_phys_offset;
+
+#define PLAT_PHYS_OFFSET keystone_phys_offset
+
+static inline phys_addr_t __virt_to_idmap(unsigned long x)
+{
+	return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET +
+		KEYSTONE_LOW_PHYS_START;
+}
+
+#define virt_to_idmap(x)	__virt_to_idmap((unsigned long)(x))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_ARM_LPAE */
+
 #endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index 650e202..f0f4a08 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -19,12 +19,20 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
+#include <linux/sched.h>
 
 #include <asm/arch_timer.h>
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/cputype.h>
+#include <asm/procinfo.h>
 
 extern struct smp_ops keystone_smp_ops;
 
@@ -74,6 +82,86 @@ static const char *keystone_match[] __initconst = {
 	NULL,
 };
 
+#ifdef CONFIG_ARM_LPAE
+
+phys_addr_t keystone_phys_offset  = KEYSTONE_LOW_PHYS_START;
+
+extern struct proc_info_list *lookup_processor_type(unsigned int);
+
+static void __init keystone_init_meminfo(void)
+{
+	unsigned long map_start, map_end;
+	struct proc_info_list *procinfo;
+	phys_addr_t mem_start, mem_end;
+	pgd_t *pgd0, *pgdk;
+	pud_t *pud0, *pudk;
+	pmd_t *pmd0, *pmdk;
+	phys_addr_t phys;
+	pmdval_t pmdprot;
+	int i;
+
+	BUG_ON(meminfo.nr_banks < 1);
+
+	mem_start = meminfo.bank[0].start;
+	mem_end   = mem_start + meminfo.bank[0].size - 1;
+
+	/* nothing to do if we are running out of the <32-bit space */
+	if (mem_start >= KEYSTONE_LOW_PHYS_START &&
+	    mem_end   <= KEYSTONE_LOW_PHYS_END)
+		return;
+
+	BUG_ON(mem_start < KEYSTONE_HIGH_PHYS_START ||
+	       mem_end   > KEYSTONE_HIGH_PHYS_END);
+
+	/* remap kernel code and data */
+	map_start = init_mm.start_code;
+	map_end   = init_mm.brk;
+
+	/* get a handle on things -  */
+	pgd0 = pgd_offset_k(0);
+	pud0 = pud_offset(pgd0, 0);
+	pmd0 = pmd_offset(pud0, 0);
+
+	pgdk = pgd_offset_k(map_start);
+	pudk = pud_offset(pgdk, map_start);
+	pmdk = pmd_offset(pudk, map_start);
+
+	procinfo = lookup_processor_type(read_cpuid_id());
+	pmdprot  = procinfo->__cpu_mm_mmu_flags;
+
+	/* set the phys offset, all pa/va operations now use this */
+	keystone_phys_offset = KEYSTONE_HIGH_PHYS_START;
+
+	/* remap level 1 table */
+	for (i = 0; i < PTRS_PER_PGD; i++) {
+		*pud0++ = __pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER);
+		pmd0 += PTRS_PER_PMD;
+	}
+
+	/* remap pmds for kernel mapping */
+	phys = __pa(map_start) & PMD_MASK;
+	do {
+		*pmdk++ = __pmd(phys | pmdprot);
+		phys += PMD_SIZE;
+	} while (phys < map_end);
+
+	flush_cache_all();
+	cpu_set_ttbr(0, __pa(pgd0));
+	cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
+	local_flush_tlb_all();
+
+	pr_err("relocated to high address space\n");
+}
+
+#else
+
+static void __init keystone_init_meminfo(void)
+{
+	/* nothing to do here */
+}
+
+#endif
+
 DT_MACHINE_START(KEYSTONE, "Keystone")
 	smp_ops(keystone_smp_ops)
 	.map_io		= keystone_map_io,
@@ -82,5 +170,9 @@ DT_MACHINE_START(KEYSTONE, "Keystone")
 	.handle_irq	= gic_handle_irq,
 	.init_machine	= keystone_init,
 	.dt_compat	= keystone_match,
+	.init_meminfo	= keystone_init_meminfo,
+#ifdef CONFIG_ZONE_DMA
+	.dma_zone_size	= SZ_2G,
+#endif
 	.nr_irqs	= 480,
 MACHINE_END
diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c
index 437659a..074fccb 100644
--- a/arch/arm/mach-keystone/platsmp.c
+++ b/arch/arm/mach-keystone/platsmp.c
@@ -24,6 +24,7 @@
 #include <asm/smp_ops.h>
 #include <asm/hardware/gic.h>
 #include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 #include <asm/memory.h>
 
 extern void secondary_startup(void);
@@ -51,15 +52,35 @@ static void __init keystone_smp_prepare_cpus(unsigned int max_cpus)
 	/* nothing for now */
 }
 
+#ifdef CONFIG_ARM_LPAE
+static void __cpuinit keystone_secondary_initmem(void)
+{
+	pgd_t *pgd0;
+
+	pgd0 = pgd_offset_k(0);
+	cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
+	local_flush_tlb_all();
+}
+#else
+static void __cpuinit keystone_secondary_initmem(void)
+{
+}
+#endif
+
 static void __cpuinit keystone_secondary_init(unsigned int cpu)
 {
 	gic_secondary_init(0);
+	keystone_secondary_initmem();
 }
 
 static int __cpuinit
 keystone_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
+#ifdef CONFIG_ARM_LPAE
+	unsigned long *jump_ptr = phys_to_virt(0x8000001f0);
+#else
 	unsigned long *jump_ptr = phys_to_virt(0x800001f0);
+#endif
 
 	jump_ptr[cpu] = virt_to_idmap(&secondary_startup);
 	__cpuc_flush_dcache_area(jump_ptr, sizeof(jump_ptr) * 4);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 06/23] ARM: LPAE: use phys_addr_t for initrd location and size
@ 2012-07-24  1:33   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vitaly Andrianov <vitalya@ti.com>

This patch fixes the initrd setup code to use phys_addr_t instead of assuming
32-bit addressing.  Without this we cannot boot on systems where initrd is
located above the 4G physical address limit.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/mm/init.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8252c31..51f3e92 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -36,12 +36,12 @@
 
 #include "mm.h"
 
-static unsigned long phys_initrd_start __initdata = 0;
-static unsigned long phys_initrd_size __initdata = 0;
+static phys_addr_t phys_initrd_start __initdata = 0;
+static phys_addr_t phys_initrd_size __initdata = 0;
 
 static int __init early_initrd(char *p)
 {
-	unsigned long start, size;
+	phys_addr_t start, size;
 	char *endp;
 
 	start = memparse(p, &endp);
@@ -347,14 +347,14 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (phys_initrd_size &&
 	    !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08llx is not a memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, (u64)phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size &&
 	    memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08llx overlaps in-use memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, (u64)phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 19/23] drivers: cma: fix addressing on PAE machines
@ 2012-07-24  1:38   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:38 UTC (permalink / raw)
  To: linux-arm-kernel

This patch fixes a couple of bugs that otherwise impair CMA functionality on
PAE machines:

  - alignment must be a 64-bit type when running on systems with 64-bit
    physical addresses.  If this is not the case, the limit calculation thunks
    allocations down to an address range < 4G.

  - The allocated range is now being checked using dma_supported() instead of
    hardcoding a 32-bit addressable limit.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 drivers/base/dma-contiguous.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 78efb03..e10bd9a 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -234,7 +234,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
 				  phys_addr_t base, phys_addr_t limit)
 {
 	struct cma_reserved *r = &cma_reserved[cma_reserved_count];
-	unsigned long alignment;
+	phys_addr_t alignment;
 
 	pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
 		 (unsigned long)size, (unsigned long)base,
@@ -271,7 +271,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,
 		if (!addr) {
 			base = -ENOMEM;
 			goto err;
-		} else if (addr + size > ~(unsigned long)0) {
+		} else if (!dma_supported(dev, addr + size)) {
 			memblock_free(addr, size);
 			base = -EINVAL;
 			goto err;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 21/23] ARM: keystone: introducing TI Keystone platform
@ 2012-07-24  1:38   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:38 UTC (permalink / raw)
  To: linux-arm-kernel

Texas Instruments Keystone family of multicore devices now includes an
upcoming slew of Cortex A15 based devices.  This patch adds basic definitions
for a new Keystone sub-architecture in ARM.

Subsequent patches in this series will extend support to include SMP and take
advantage of the large physical memory addressing capabilities via LPAE.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
---
 arch/arm/Kconfig                                  |   17 +++++
 arch/arm/Makefile                                 |    1 +
 arch/arm/boot/dts/keystone-sim.dts                |   77 +++++++++++++++++++
 arch/arm/configs/keystone_defconfig               |   20 +++++
 arch/arm/mach-keystone/Makefile                   |    1 +
 arch/arm/mach-keystone/Makefile.boot              |    1 +
 arch/arm/mach-keystone/include/mach/debug-macro.S |   44 +++++++++++
 arch/arm/mach-keystone/include/mach/entry-macro.S |   20 +++++
 arch/arm/mach-keystone/include/mach/io.h          |   22 ++++++
 arch/arm/mach-keystone/include/mach/memory.h      |   22 ++++++
 arch/arm/mach-keystone/include/mach/system.h      |   30 ++++++++
 arch/arm/mach-keystone/include/mach/timex.h       |   21 ++++++
 arch/arm/mach-keystone/include/mach/uncompress.h  |   24 ++++++
 arch/arm/mach-keystone/include/mach/vmalloc.h     |   21 ++++++
 arch/arm/mach-keystone/keystone.c                 |   83 +++++++++++++++++++++
 15 files changed, 404 insertions(+)
 create mode 100644 arch/arm/boot/dts/keystone-sim.dts
 create mode 100644 arch/arm/configs/keystone_defconfig
 create mode 100644 arch/arm/mach-keystone/Makefile
 create mode 100644 arch/arm/mach-keystone/Makefile.boot
 create mode 100644 arch/arm/mach-keystone/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-keystone/include/mach/io.h
 create mode 100644 arch/arm/mach-keystone/include/mach/memory.h
 create mode 100644 arch/arm/mach-keystone/include/mach/system.h
 create mode 100644 arch/arm/mach-keystone/include/mach/timex.h
 create mode 100644 arch/arm/mach-keystone/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-keystone/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-keystone/keystone.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 55da671..04c846b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -359,6 +359,23 @@ config ARCH_HIGHBANK
 	help
 	  Support for the Calxeda Highbank SoC based boards.
 
+config ARCH_KEYSTONE
+	bool "Texas Instruments Keystone Devices"
+	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARM_GIC
+	select CLKDEV_LOOKUP
+	select COMMON_CLK
+	select CLKSRC_MMIO
+	select CPU_V7
+	select GENERIC_CLOCKEVENTS
+	select USE_OF
+	select SPARSE_IRQ
+	select NEED_MACH_MEMORY_H
+	select HAVE_SCHED_CLOCK
+	help
+	  Support for boards based on the Texas Instruments Keystone family of
+	  SoCs.
+
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
 	select CPU_ARM720T
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0298b00..13d6ef5 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -143,6 +143,7 @@ machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_GEMINI)		:= gemini
 machine-$(CONFIG_ARCH_H720X)		:= h720x
 machine-$(CONFIG_ARCH_HIGHBANK)		:= highbank
+machine-$(CONFIG_ARCH_KEYSTONE)		:= keystone
 machine-$(CONFIG_ARCH_INTEGRATOR)	:= integrator
 machine-$(CONFIG_ARCH_IOP13XX)		:= iop13xx
 machine-$(CONFIG_ARCH_IOP32X)		:= iop32x
diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
new file mode 100644
index 0000000..118d631
--- /dev/null
+++ b/arch/arm/boot/dts/keystone-sim.dts
@@ -0,0 +1,77 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Texas Instruments Keystone 2 SoC";
+	compatible = "ti,keystone-evm";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	aliases {
+		serial0	= &uart0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8 debug earlyprintk lpj=50000 rdinit=/bin/ash rw root=/dev/ram0 initrd=0x85000000,9M";
+	};
+
+	memory {
+		reg = <0x80000000 0x8000000>;
+	};
+
+	cpus {
+		interrupt-parent = <&gic>;
+
+		cpu at 0 {
+			compatible = "arm,cortex-a15";
+		};
+
+		cpu at 1 {
+			compatible = "arm,cortex-a15";
+		};
+
+		cpu at 2 {
+			compatible = "arm,cortex-a15";
+		};
+
+		cpu at 3 {
+			compatible = "arm,cortex-a15";
+		};
+
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "ti,keystone","simple-bus";
+		interrupt-parent = <&gic>;
+
+		gic:	interrupt-controller at 02560000 {
+			compatible = "arm,cortex-a15-gic";
+			#interrupt-cells = <3>;
+			#size-cells = <0>;
+			#address-cells = <1>;
+			interrupt-controller;
+			reg = <0x02561000 0x1000>,
+			      <0x02562000 0x2000>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			interrupts = <1 13 0xf08 1 14 0xf08>;
+			clock-frequency = <10000000>; /* Freq in Hz - optional */
+		};
+
+		uart0:	serial at 02530c00 {
+			compatible	= "ns16550a";
+			current-speed	= <115200>;
+			reg-shift	= <2>;
+			reg-io-width	= <4>;
+			reg		= <0x02530c00 0x100>;
+			clock-frequency = <48000000>;
+			interrupts	= <0 277 0xf01>;
+		};
+	};
+};
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
new file mode 100644
index 0000000..7f2a04b
--- /dev/null
+++ b/arch/arm/configs/keystone_defconfig
@@ -0,0 +1,20 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile
new file mode 100644
index 0000000..d4671d5
--- /dev/null
+++ b/arch/arm/mach-keystone/Makefile
@@ -0,0 +1 @@
+obj-y					:= keystone.o
diff --git a/arch/arm/mach-keystone/Makefile.boot b/arch/arm/mach-keystone/Makefile.boot
new file mode 100644
index 0000000..dae9661
--- /dev/null
+++ b/arch/arm/mach-keystone/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y	:= 0x00008000
diff --git a/arch/arm/mach-keystone/include/mach/debug-macro.S b/arch/arm/mach-keystone/include/mach/debug-macro.S
new file mode 100644
index 0000000..1108210
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/debug-macro.S
@@ -0,0 +1,44 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/serial_reg.h>
+
+#define UART_SHIFT	2
+
+	.macro	addruart,rp,rv,tmp
+	movw	\rv, #0x0c00
+	movt	\rv, #0xfed3
+	movw	\rp, #0x0c00
+	movt	\rp, #0x0253
+	.endm
+
+
+	.macro	senduart,rd,rx
+	str	\rd, [\rx, #UART_TX << UART_SHIFT]
+	.endm
+
+	.macro	busyuart,rd,rx
+1002:	ldr	\rd, [\rx, #UART_LSR << UART_SHIFT]
+	and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+	teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
+	bne	1002b
+	.endm
+
+	.macro	waituart,rd,rx
+	.endm
diff --git a/arch/arm/mach-keystone/include/mach/entry-macro.S b/arch/arm/mach-keystone/include/mach/entry-macro.S
new file mode 100644
index 0000000..7f486f3
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/entry-macro.S
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+	.macro	disable_fiq
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
diff --git a/arch/arm/mach-keystone/include/mach/io.h b/arch/arm/mach-keystone/include/mach/io.h
new file mode 100644
index 0000000..844d659
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#define __io(a)		({ (void)(a); __typesafe_io(0); })
+#define __mem_pci(a)	(a)
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
new file mode 100644
index 0000000..7c78b1e
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/memory.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define MAX_PHYSMEM_BITS	36
+#define SECTION_SIZE_BITS	34
+
+#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-keystone/include/mach/system.h b/arch/arm/mach-keystone/include/mach/system.h
new file mode 100644
index 0000000..4887b4c
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/system.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	while (1)
+		;
+}
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/timex.h b/arch/arm/mach-keystone/include/mach/timex.h
new file mode 100644
index 0000000..f355ecb
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE		1000000
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/uncompress.h b/arch/arm/mach-keystone/include/mach/uncompress.h
new file mode 100644
index 0000000..1071761
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/uncompress.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#define putc(c)
+#define flush()
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-keystone/include/mach/vmalloc.h b/arch/arm/mach-keystone/include/mach/vmalloc.h
new file mode 100644
index 0000000..9d34c09
--- /dev/null
+++ b/arch/arm/mach-keystone/include/mach/vmalloc.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#define VMALLOC_END		0xFE800000UL
+
+#endif
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
new file mode 100644
index 0000000..9583dc4
--- /dev/null
+++ b/arch/arm/mach-keystone/keystone.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+#include <asm/arch_timer.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+
+static struct map_desc io_desc[] = {
+	{
+		.virtual        = 0xfe800000UL,
+		.pfn            = __phys_to_pfn(0x02000000UL),
+		.length         = 0x800000UL,
+		.type           = MT_DEVICE
+	},
+};
+
+static void __init keystone_map_io(void)
+{
+	iotable_init(io_desc, sizeof(io_desc)/sizeof(struct map_desc));
+}
+
+static const struct of_device_id irq_match[] = {
+	{ .compatible = "arm,cortex-a15-gic", .data = gic_of_init, },
+	{}
+};
+
+static void __init keystone_init_irq(void)
+{
+	of_irq_init(irq_match);
+}
+
+
+static void __init keystone_timer_init(void)
+{
+	arch_timer_of_register();
+	arch_timer_sched_clock_init();
+}
+
+static struct sys_timer keystone_timer = {
+	.init = keystone_timer_init,
+};
+
+
+static void __init keystone_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *keystone_match[] __initconst = {
+	"ti,keystone-evm",
+	NULL,
+};
+
+DT_MACHINE_START(KEYSTONE, "Keystone")
+	.map_io		= keystone_map_io,
+	.init_irq	= keystone_init_irq,
+	.timer		= &keystone_timer,
+	.handle_irq	= gic_handle_irq,
+	.init_machine	= keystone_init,
+	.dt_compat	= keystone_match,
+	.nr_irqs	= 480,
+MACHINE_END
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [RFC 14/23] ARM: LPAE: factor out T1SZ and TTBR1 computations
@ 2012-07-24  1:38   ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24  1:38 UTC (permalink / raw)
  To: linux-arm-kernel

This patch moves the TTBR1 offset calculation and the T1SZ calculation out
of the TTB setup assembly code.  This should not affect functionality in
any way, but improves code readability as well as readability of subsequent
patches in this series.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/pgtable-3level-hwdef.h |   10 ++++++++++
 arch/arm/mm/proc-v7-3level.S                |   16 ++++------------
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index d795282..b501650 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -74,4 +74,14 @@
 #define PHYS_MASK_SHIFT		(40)
 #define PHYS_MASK		((1ULL << PHYS_MASK_SHIFT) - 1)
 
+#if defined CONFIG_VMSPLIT_2G
+#define TTBR1_OFFSET	(1 << 4)		/* skip two L1 entries */
+#elif defined CONFIG_VMSPLIT_3G
+#define TTBR1_OFFSET	(4096 * (1 + 3))	/* only L2, skip pgd + 3*pmd */
+#else
+#define TTBR1_OFFSET	0
+#endif
+
+#define TTBR1_SIZE	(((PAGE_OFFSET >> 30) - 1) << 16)
+
 #endif
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 0001581..3b1a745 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -120,18 +120,10 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 * booting secondary CPUs would end up using TTBR1 for the identity
 	 * mapping set up in TTBR0.
 	 */
-	bhi	9001f				@ PHYS_OFFSET > PAGE_OFFSET?
-	orr	\tmp, \tmp, #(((PAGE_OFFSET >> 30) - 1) << 16) @ TTBCR.T1SZ
-#if defined CONFIG_VMSPLIT_2G
-	/* PAGE_OFFSET == 0x80000000, T1SZ == 1 */
-	add	\ttbr1, \ttbr1, #1 << 4		@ skip two L1 entries
-#elif defined CONFIG_VMSPLIT_3G
-	/* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */
-	add	\ttbr1, \ttbr1, #4096 * (1 + 3)	@ only L2 used, skip pgd+3*pmd
-#endif
-	/* CONFIG_VMSPLIT_1G does not need TTBR1 adjustment */
-9001:	mcr	p15, 0, \tmp, c2, c0, 2		@ TTB control register
-	mcrr	p15, 1, \ttbr1, \zero, c2	@ load TTBR1
+	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
+	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
+	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
 	.endm
 
 	__CPUINIT
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* Re: [RFC 00/23] Introducing the TI Keystone platform
  2012-07-24  1:09 ` Cyril Chemparathy
@ 2012-07-24  9:08   ` Will Deacon
  -1 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2012-07-24  9:08 UTC (permalink / raw)
  To: Cyril Chemparathy; +Cc: linux-arm-kernel, linux-kernel, nico, Catalin Marinas

Hi Cyril,

Thanks for this, certainly looks like an interesting platform!

Of course, in order to perform any sort of sensible review, I'll need some
silicon to test it on :)

On Tue, Jul 24, 2012 at 02:09:02AM +0100, Cyril Chemparathy wrote:
> TI's scalable KeyStone II architecture includes support for both TMS320C66x
> floating point DSPs and ARM Cortex-A15 clusters, for a mixture of up to 32
> cores per SoC.  The solution is optimized around a high performance chip
> interconnect and a rich set of on chip peripherals.  Please refer [1] for
> initial technical documentation on these devices.

How many A15s can you have on such a SoC? It wasn't clear whether it was 1x4
or 4x4 from the documentation.

> This patch series provides a basic Linux port for these devices, including
> support for SMP, and LPAE boot.  A majority of the patches in this series are
> related to LPAE functionality, imposed by the device architecture which has
> system memory mapped at an address above the 4G 32-bit addressable limit.

I assume you have *some* memory in the bottom 32-bits though, right? Even if
it's just a partial alias of a higher bank.

> This patch series is based on the v3.5 kernel with the smp_ops patch set
> applied on top.  This series is being posted to elicit early feedback, and so
> that some of these fixes may get incorporated early on into the kernel code.
> 
>   [1] - http://www.ti.com/product/tms320tci6636

This is marked as `TI confidential' but I guess that's an oversight [or will
you have to kill me?].

Will

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 00/23] Introducing the TI Keystone platform
@ 2012-07-24  9:08   ` Will Deacon
  0 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2012-07-24  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Cyril,

Thanks for this, certainly looks like an interesting platform!

Of course, in order to perform any sort of sensible review, I'll need some
silicon to test it on :)

On Tue, Jul 24, 2012 at 02:09:02AM +0100, Cyril Chemparathy wrote:
> TI's scalable KeyStone II architecture includes support for both TMS320C66x
> floating point DSPs and ARM Cortex-A15 clusters, for a mixture of up to 32
> cores per SoC.  The solution is optimized around a high performance chip
> interconnect and a rich set of on chip peripherals.  Please refer [1] for
> initial technical documentation on these devices.

How many A15s can you have on such a SoC? It wasn't clear whether it was 1x4
or 4x4 from the documentation.

> This patch series provides a basic Linux port for these devices, including
> support for SMP, and LPAE boot.  A majority of the patches in this series are
> related to LPAE functionality, imposed by the device architecture which has
> system memory mapped at an address above the 4G 32-bit addressable limit.

I assume you have *some* memory in the bottom 32-bits though, right? Even if
it's just a partial alias of a higher bank.

> This patch series is based on the v3.5 kernel with the smp_ops patch set
> applied on top.  This series is being posted to elicit early feedback, and so
> that some of these fixes may get incorporated early on into the kernel code.
> 
>   [1] - http://www.ti.com/product/tms320tci6636

This is marked as `TI confidential' but I guess that's an oversight [or will
you have to kill me?].

Will

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 01/23] ARM: LPAE: disable phys-to-virt patching on PAE systems
  2012-07-24  1:09   ` Cyril Chemparathy
@ 2012-07-24  9:41     ` Catalin Marinas
  -1 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24  9:41 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

On Tue, Jul 24, 2012 at 02:09:03AM +0100, Cyril Chemparathy wrote:
> From: Vitaly Andrianov <vitalya@ti.com>
> 
> The current phys-to-virt patching mechanism is broken on PAE machines with
> 64-bit physical addressing.  This patch disables the patching mechanism in
> such configurations.

It may be broken, I don't remember whether I tested this feature. What's
the PHYS_OFFSET on your platform? Is it within the low 4GB range?

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 01/23] ARM: LPAE: disable phys-to-virt patching on PAE systems
@ 2012-07-24  9:41     ` Catalin Marinas
  0 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24  9:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 24, 2012 at 02:09:03AM +0100, Cyril Chemparathy wrote:
> From: Vitaly Andrianov <vitalya@ti.com>
> 
> The current phys-to-virt patching mechanism is broken on PAE machines with
> 64-bit physical addressing.  This patch disables the patching mechanism in
> such configurations.

It may be broken, I don't remember whether I tested this feature. What's
the PHYS_OFFSET on your platform? Is it within the low 4GB range?

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 23/23] ARM: keystone: add switch over to high physical address range
  2012-07-24  1:33   ` Cyril Chemparathy
@ 2012-07-24  9:49     ` Catalin Marinas
  -1 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24  9:49 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

On Tue, Jul 24, 2012 at 02:09:25AM +0100, Cyril Chemparathy wrote:
> Keystone platforms have their physical memory mapped at an address outside the
> 32-bit physical range.  A Keystone machine with 16G of RAM would find its
> memory at 0x0800000000 - 0x0bffffffff.

Ah, so the patches start to make sense now :). The PHYS_OFFSET is at
32G. I'll go back and look at the patches.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 23/23] ARM: keystone: add switch over to high physical address range
@ 2012-07-24  9:49     ` Catalin Marinas
  0 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 24, 2012 at 02:09:25AM +0100, Cyril Chemparathy wrote:
> Keystone platforms have their physical memory mapped at an address outside the
> 32-bit physical range.  A Keystone machine with 16G of RAM would find its
> memory at 0x0800000000 - 0x0bffffffff.

Ah, so the patches start to make sense now :). The PHYS_OFFSET is at
32G. I'll go back and look at the patches.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 07/23] ARM: LPAE: use phys_addr_t for membank size
  2012-07-24  1:10   ` Cyril Chemparathy
@ 2012-07-24 10:04     ` Will Deacon
  -1 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2012-07-24 10:04 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, Catalin Marinas, Vitaly Andrianov

On Tue, Jul 24, 2012 at 02:09:09AM +0100, Cyril Chemparathy wrote:
> This patch changes the membank structure's size field to phys_addr_t to allow
> banks larger than 4G.

This has already been fixed:

  http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7465/1

Will

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 07/23] ARM: LPAE: use phys_addr_t for membank size
@ 2012-07-24 10:04     ` Will Deacon
  0 siblings, 0 replies; 88+ messages in thread
From: Will Deacon @ 2012-07-24 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 24, 2012 at 02:09:09AM +0100, Cyril Chemparathy wrote:
> This patch changes the membank structure's size field to phys_addr_t to allow
> banks larger than 4G.

This has already been fixed:

  http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7465/1

Will

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
  2012-07-24  1:09   ` Cyril Chemparathy
@ 2012-07-24 10:05     ` Catalin Marinas
  -1 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24 10:05 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
> This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
> unsigned long math truncates the mask at the 32-bits.  This clearly does bad
> things on PAE systems.
> 
> This patch fixes this problem by defining these masks as signed quantities.
> We then rely on sign extension to do the right thing.
> 
> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> ---
>  arch/arm/include/asm/page.h           |    7 ++++++-
>  arch/arm/include/asm/pgtable-3level.h |    6 +++---
>  2 files changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
> index ecf9019..1c810d2 100644
> --- a/arch/arm/include/asm/page.h
> +++ b/arch/arm/include/asm/page.h
> @@ -13,7 +13,12 @@
>  /* PAGE_SHIFT determines the page size */
>  #define PAGE_SHIFT		12
>  #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
> -#define PAGE_MASK		(~(PAGE_SIZE-1))
> +
> +/*
> + * We do not use PAGE_SIZE in the following because we rely on sign
> + * extension to appropriately extend upper bits for PAE systems
> + */
> +#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))

Would it work if we use a 1ULL here and avoid the sign trick? I'm
worried about some context where this would lose the sign. We could have
an #ifdef here while the PGDIR/PMD masks are in a separate file already.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
@ 2012-07-24 10:05     ` Catalin Marinas
  0 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
> This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
> unsigned long math truncates the mask at the 32-bits.  This clearly does bad
> things on PAE systems.
> 
> This patch fixes this problem by defining these masks as signed quantities.
> We then rely on sign extension to do the right thing.
> 
> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> ---
>  arch/arm/include/asm/page.h           |    7 ++++++-
>  arch/arm/include/asm/pgtable-3level.h |    6 +++---
>  2 files changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
> index ecf9019..1c810d2 100644
> --- a/arch/arm/include/asm/page.h
> +++ b/arch/arm/include/asm/page.h
> @@ -13,7 +13,12 @@
>  /* PAGE_SHIFT determines the page size */
>  #define PAGE_SHIFT		12
>  #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
> -#define PAGE_MASK		(~(PAGE_SIZE-1))
> +
> +/*
> + * We do not use PAGE_SIZE in the following because we rely on sign
> + * extension to appropriately extend upper bits for PAE systems
> + */
> +#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))

Would it work if we use a 1ULL here and avoid the sign trick? I'm
worried about some context where this would lose the sign. We could have
an #ifdef here while the PGDIR/PMD masks are in a separate file already.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
  2012-07-24  1:10   ` Cyril Chemparathy
@ 2012-07-24 10:37     ` Catalin Marinas
  -1 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24 10:37 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
> This patch fixes up the types used when converting back and forth between
> physical and virtual addresses.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
> ---
>  arch/arm/include/asm/memory.h |   17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> index fcb5757..7629dfe 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
>  	: "=r" (to)					\
>  	: "r" (from), "I" (type))
>  
> -static inline unsigned long __virt_to_phys(unsigned long x)
> +static inline phys_addr_t __virt_to_phys(unsigned long x)
>  {
>  	unsigned long t;
>  	__pv_stub(x, t, "add", __PV_BITS_31_24);
>  	return t;
>  }
>  
> -static inline unsigned long __phys_to_virt(unsigned long x)
> +static inline unsigned long __phys_to_virt(phys_addr_t x)
>  {
>  	unsigned long t;
>  	__pv_stub(x, t, "sub", __PV_BITS_31_24);
>  	return t;
>  }

BTW, I would prefer if the phys-to-virt patching was fixed as well. It
shouldn't be difficult.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
@ 2012-07-24 10:37     ` Catalin Marinas
  0 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
> This patch fixes up the types used when converting back and forth between
> physical and virtual addresses.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
> ---
>  arch/arm/include/asm/memory.h |   17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> index fcb5757..7629dfe 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
>  	: "=r" (to)					\
>  	: "r" (from), "I" (type))
>  
> -static inline unsigned long __virt_to_phys(unsigned long x)
> +static inline phys_addr_t __virt_to_phys(unsigned long x)
>  {
>  	unsigned long t;
>  	__pv_stub(x, t, "add", __PV_BITS_31_24);
>  	return t;
>  }
>  
> -static inline unsigned long __phys_to_virt(unsigned long x)
> +static inline unsigned long __phys_to_virt(phys_addr_t x)
>  {
>  	unsigned long t;
>  	__pv_stub(x, t, "sub", __PV_BITS_31_24);
>  	return t;
>  }

BTW, I would prefer if the phys-to-virt patching was fixed as well. It
shouldn't be difficult.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 00/23] Introducing the TI Keystone platform
  2012-07-24  9:08   ` Will Deacon
@ 2012-07-24 10:41     ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:41 UTC (permalink / raw)
  To: Will Deacon; +Cc: linux-arm-kernel, linux-kernel, nico, Catalin Marinas

Hi Will,

On 7/24/2012 5:08 AM, Will Deacon wrote:
> Hi Cyril,
>
> Thanks for this, certainly looks like an interesting platform!
>
> Of course, in order to perform any sort of sensible review, I'll need some
> silicon to test it on :)
>

We have (so far) been testing this on software simulators, and we have 
an earlier version of this code booting up on an FPGA based emulation 
platform.

> On Tue, Jul 24, 2012 at 02:09:02AM +0100, Cyril Chemparathy wrote:
>> TI's scalable KeyStone II architecture includes support for both TMS320C66x
>> floating point DSPs and ARM Cortex-A15 clusters, for a mixture of up to 32
>> cores per SoC.  The solution is optimized around a high performance chip
>> interconnect and a rich set of on chip peripherals.  Please refer [1] for
>> initial technical documentation on these devices.
>
> How many A15s can you have on such a SoC? It wasn't clear whether it was 1x4
> or 4x4 from the documentation.
>

This device has a single cluster of 4 A15s.

>> This patch series provides a basic Linux port for these devices, including
>> support for SMP, and LPAE boot.  A majority of the patches in this series are
>> related to LPAE functionality, imposed by the device architecture which has
>> system memory mapped at an address above the 4G 32-bit addressable limit.
>
> I assume you have *some* memory in the bottom 32-bits though, right? Even if
> it's just a partial alias of a higher bank.
>

Yes, there is a boot time alias of the initial part of memory in the 
32-bit space.  But this alias is somewhat limited in capabilities, and 
therefore we do not intend to use it much beyond boot.

>> This patch series is based on the v3.5 kernel with the smp_ops patch set
>> applied on top.  This series is being posted to elicit early feedback, and so
>> that some of these fixes may get incorporated early on into the kernel code.
>>
>>    [1] - http://www.ti.com/product/tms320tci6636
>
> This is marked as `TI confidential' but I guess that's an oversight [or will
> you have to kill me?].
>

:-)  That is an oversight, I'm sure.

> Will
>

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 00/23] Introducing the TI Keystone platform
@ 2012-07-24 10:41     ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 7/24/2012 5:08 AM, Will Deacon wrote:
> Hi Cyril,
>
> Thanks for this, certainly looks like an interesting platform!
>
> Of course, in order to perform any sort of sensible review, I'll need some
> silicon to test it on :)
>

We have (so far) been testing this on software simulators, and we have 
an earlier version of this code booting up on an FPGA based emulation 
platform.

> On Tue, Jul 24, 2012 at 02:09:02AM +0100, Cyril Chemparathy wrote:
>> TI's scalable KeyStone II architecture includes support for both TMS320C66x
>> floating point DSPs and ARM Cortex-A15 clusters, for a mixture of up to 32
>> cores per SoC.  The solution is optimized around a high performance chip
>> interconnect and a rich set of on chip peripherals.  Please refer [1] for
>> initial technical documentation on these devices.
>
> How many A15s can you have on such a SoC? It wasn't clear whether it was 1x4
> or 4x4 from the documentation.
>

This device has a single cluster of 4 A15s.

>> This patch series provides a basic Linux port for these devices, including
>> support for SMP, and LPAE boot.  A majority of the patches in this series are
>> related to LPAE functionality, imposed by the device architecture which has
>> system memory mapped at an address above the 4G 32-bit addressable limit.
>
> I assume you have *some* memory in the bottom 32-bits though, right? Even if
> it's just a partial alias of a higher bank.
>

Yes, there is a boot time alias of the initial part of memory in the 
32-bit space.  But this alias is somewhat limited in capabilities, and 
therefore we do not intend to use it much beyond boot.

>> This patch series is based on the v3.5 kernel with the smp_ops patch set
>> applied on top.  This series is being posted to elicit early feedback, and so
>> that some of these fixes may get incorporated early on into the kernel code.
>>
>>    [1] - http://www.ti.com/product/tms320tci6636
>
> This is marked as `TI confidential' but I guess that's an oversight [or will
> you have to kill me?].
>

:-)  That is an oversight, I'm sure.

> Will
>

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 01/23] ARM: LPAE: disable phys-to-virt patching on PAE systems
  2012-07-24  9:41     ` Catalin Marinas
@ 2012-07-24 10:43       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:43 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

Hi Catalin,

On 7/24/2012 5:41 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:03AM +0100, Cyril Chemparathy wrote:
>> From: Vitaly Andrianov <vitalya@ti.com>
>>
>> The current phys-to-virt patching mechanism is broken on PAE machines with
>> 64-bit physical addressing.  This patch disables the patching mechanism in
>> such configurations.
>
> It may be broken, I don't remember whether I tested this feature. What's
> the PHYS_OFFSET on your platform? Is it within the low 4GB range?
>

At boot time PHYS_OFFSET is 0x80000000, in the low 4G range. 
Subsequently we switch over to the high PHYS_OFFSET at 0x800000000 (see 
patch 23/23 of this series).

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 01/23] ARM: LPAE: disable phys-to-virt patching on PAE systems
@ 2012-07-24 10:43       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Catalin,

On 7/24/2012 5:41 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:03AM +0100, Cyril Chemparathy wrote:
>> From: Vitaly Andrianov <vitalya@ti.com>
>>
>> The current phys-to-virt patching mechanism is broken on PAE machines with
>> 64-bit physical addressing.  This patch disables the patching mechanism in
>> such configurations.
>
> It may be broken, I don't remember whether I tested this feature. What's
> the PHYS_OFFSET on your platform? Is it within the low 4GB range?
>

At boot time PHYS_OFFSET is 0x80000000, in the low 4G range. 
Subsequently we switch over to the high PHYS_OFFSET at 0x800000000 (see 
patch 23/23 of this series).

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 07/23] ARM: LPAE: use phys_addr_t for membank size
  2012-07-24 10:04     ` Will Deacon
@ 2012-07-24 10:46       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:46 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-arm-kernel, linux-kernel, nico, Catalin Marinas, Vitaly Andrianov

On 7/24/2012 6:04 AM, Will Deacon wrote:
> On Tue, Jul 24, 2012 at 02:09:09AM +0100, Cyril Chemparathy wrote:
>> This patch changes the membank structure's size field to phys_addr_t to allow
>> banks larger than 4G.
>
> This has already been fixed:
>
>    http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7465/1

Excellent.  Thanks.

>
> Will
>

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 07/23] ARM: LPAE: use phys_addr_t for membank size
@ 2012-07-24 10:46       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 7/24/2012 6:04 AM, Will Deacon wrote:
> On Tue, Jul 24, 2012 at 02:09:09AM +0100, Cyril Chemparathy wrote:
>> This patch changes the membank structure's size field to phys_addr_t to allow
>> banks larger than 4G.
>
> This has already been fixed:
>
>    http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7465/1

Excellent.  Thanks.

>
> Will
>

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
  2012-07-24 10:05     ` Catalin Marinas
@ 2012-07-24 10:52       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:52 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

On 7/24/2012 6:05 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
>> This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
>> unsigned long math truncates the mask at the 32-bits.  This clearly does bad
>> things on PAE systems.
>>
>> This patch fixes this problem by defining these masks as signed quantities.
>> We then rely on sign extension to do the right thing.
>>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> ---
>>   arch/arm/include/asm/page.h           |    7 ++++++-
>>   arch/arm/include/asm/pgtable-3level.h |    6 +++---
>>   2 files changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
>> index ecf9019..1c810d2 100644
>> --- a/arch/arm/include/asm/page.h
>> +++ b/arch/arm/include/asm/page.h
>> @@ -13,7 +13,12 @@
>>   /* PAGE_SHIFT determines the page size */
>>   #define PAGE_SHIFT		12
>>   #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
>> -#define PAGE_MASK		(~(PAGE_SIZE-1))
>> +
>> +/*
>> + * We do not use PAGE_SIZE in the following because we rely on sign
>> + * extension to appropriately extend upper bits for PAE systems
>> + */
>> +#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
>
> Would it work if we use a 1ULL here and avoid the sign trick? I'm
> worried about some context where this would lose the sign. We could have
> an #ifdef here while the PGDIR/PMD masks are in a separate file already.
>

Sure, I will modify accordingly in the next version.

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
@ 2012-07-24 10:52       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 7/24/2012 6:05 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
>> This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
>> unsigned long math truncates the mask at the 32-bits.  This clearly does bad
>> things on PAE systems.
>>
>> This patch fixes this problem by defining these masks as signed quantities.
>> We then rely on sign extension to do the right thing.
>>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> ---
>>   arch/arm/include/asm/page.h           |    7 ++++++-
>>   arch/arm/include/asm/pgtable-3level.h |    6 +++---
>>   2 files changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
>> index ecf9019..1c810d2 100644
>> --- a/arch/arm/include/asm/page.h
>> +++ b/arch/arm/include/asm/page.h
>> @@ -13,7 +13,12 @@
>>   /* PAGE_SHIFT determines the page size */
>>   #define PAGE_SHIFT		12
>>   #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
>> -#define PAGE_MASK		(~(PAGE_SIZE-1))
>> +
>> +/*
>> + * We do not use PAGE_SIZE in the following because we rely on sign
>> + * extension to appropriately extend upper bits for PAE systems
>> + */
>> +#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
>
> Would it work if we use a 1ULL here and avoid the sign trick? I'm
> worried about some context where this would lose the sign. We could have
> an #ifdef here while the PGDIR/PMD masks are in a separate file already.
>

Sure, I will modify accordingly in the next version.

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
  2012-07-24 10:37     ` Catalin Marinas
@ 2012-07-24 10:55       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:55 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

On 7/24/2012 6:37 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
>> This patch fixes up the types used when converting back and forth between
>> physical and virtual addresses.
>>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>> ---
>>   arch/arm/include/asm/memory.h |   17 +++++++++++------
>>   1 file changed, 11 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
>> index fcb5757..7629dfe 100644
>> --- a/arch/arm/include/asm/memory.h
>> +++ b/arch/arm/include/asm/memory.h
>> @@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
>>   	: "=r" (to)					\
>>   	: "r" (from), "I" (type))
>>
>> -static inline unsigned long __virt_to_phys(unsigned long x)
>> +static inline phys_addr_t __virt_to_phys(unsigned long x)
>>   {
>>   	unsigned long t;
>>   	__pv_stub(x, t, "add", __PV_BITS_31_24);
>>   	return t;
>>   }
>>
>> -static inline unsigned long __phys_to_virt(unsigned long x)
>> +static inline unsigned long __phys_to_virt(phys_addr_t x)
>>   {
>>   	unsigned long t;
>>   	__pv_stub(x, t, "sub", __PV_BITS_31_24);
>>   	return t;
>>   }
>
> BTW, I would prefer if the phys-to-virt patching was fixed as well. It
> shouldn't be difficult.
>

On that topic - yes, we have this on our radar, but in our case we;re 
talking about patching (in head.S) and then repatching (at switch over).

One of the ideas we've been bouncing around has been to convert the 
phys-virt patch code into arithmetic on PFNs.  This way we don't have to 
get too messy with 64-bit in the patch code, and we can use the same 
patch code for both phys_to_virt and virt_to_phys.  Thoughts on this 
approach?

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
@ 2012-07-24 10:55       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 10:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 7/24/2012 6:37 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
>> This patch fixes up the types used when converting back and forth between
>> physical and virtual addresses.
>>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>> ---
>>   arch/arm/include/asm/memory.h |   17 +++++++++++------
>>   1 file changed, 11 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
>> index fcb5757..7629dfe 100644
>> --- a/arch/arm/include/asm/memory.h
>> +++ b/arch/arm/include/asm/memory.h
>> @@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
>>   	: "=r" (to)					\
>>   	: "r" (from), "I" (type))
>>
>> -static inline unsigned long __virt_to_phys(unsigned long x)
>> +static inline phys_addr_t __virt_to_phys(unsigned long x)
>>   {
>>   	unsigned long t;
>>   	__pv_stub(x, t, "add", __PV_BITS_31_24);
>>   	return t;
>>   }
>>
>> -static inline unsigned long __phys_to_virt(unsigned long x)
>> +static inline unsigned long __phys_to_virt(phys_addr_t x)
>>   {
>>   	unsigned long t;
>>   	__pv_stub(x, t, "sub", __PV_BITS_31_24);
>>   	return t;
>>   }
>
> BTW, I would prefer if the phys-to-virt patching was fixed as well. It
> shouldn't be difficult.
>

On that topic - yes, we have this on our radar, but in our case we;re 
talking about patching (in head.S) and then repatching (at switch over).

One of the ideas we've been bouncing around has been to convert the 
phys-virt patch code into arithmetic on PFNs.  This way we don't have to 
get too messy with 64-bit in the patch code, and we can use the same 
patch code for both phys_to_virt and virt_to_phys.  Thoughts on this 
approach?

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
  2012-07-24 10:55       ` Cyril Chemparathy
@ 2012-07-24 11:02         ` Catalin Marinas
  -1 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24 11:02 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

On Tue, Jul 24, 2012 at 11:55:30AM +0100, Cyril Chemparathy wrote:
> On 7/24/2012 6:37 AM, Catalin Marinas wrote:
> > On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
> >> This patch fixes up the types used when converting back and forth between
> >> physical and virtual addresses.
> >>
> >> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> >> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
> >> ---
> >>   arch/arm/include/asm/memory.h |   17 +++++++++++------
> >>   1 file changed, 11 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> >> index fcb5757..7629dfe 100644
> >> --- a/arch/arm/include/asm/memory.h
> >> +++ b/arch/arm/include/asm/memory.h
> >> @@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
> >>   	: "=r" (to)					\
> >>   	: "r" (from), "I" (type))
> >>
> >> -static inline unsigned long __virt_to_phys(unsigned long x)
> >> +static inline phys_addr_t __virt_to_phys(unsigned long x)
> >>   {
> >>   	unsigned long t;
> >>   	__pv_stub(x, t, "add", __PV_BITS_31_24);
> >>   	return t;
> >>   }
> >>
> >> -static inline unsigned long __phys_to_virt(unsigned long x)
> >> +static inline unsigned long __phys_to_virt(phys_addr_t x)
> >>   {
> >>   	unsigned long t;
> >>   	__pv_stub(x, t, "sub", __PV_BITS_31_24);
> >>   	return t;
> >>   }
> >
> > BTW, I would prefer if the phys-to-virt patching was fixed as well. It
> > shouldn't be difficult.
> 
> On that topic - yes, we have this on our radar, but in our case we;re 
> talking about patching (in head.S) and then repatching (at switch over).
> 
> One of the ideas we've been bouncing around has been to convert the 
> phys-virt patch code into arithmetic on PFNs.  This way we don't have to 
> get too messy with 64-bit in the patch code, and we can use the same 
> patch code for both phys_to_virt and virt_to_phys.  Thoughts on this 
> approach?

It may be slightly less efficient with Thumb-2 code as we can't have add
and lsl in the same instruction. It may anyway be faster than reading a
global variable.

But I suspect you can just mask out the top 32-bit part of a physical
address when converting to virtual. The opposite may also work, you just
have some constant in the top 32-bit part of the phys address. Note that
virt_to_phys is only valid for the lowmem, so 32-bit arithmetic with
some constant for the top 32-bit should be enough.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion
@ 2012-07-24 11:02         ` Catalin Marinas
  0 siblings, 0 replies; 88+ messages in thread
From: Catalin Marinas @ 2012-07-24 11:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 24, 2012 at 11:55:30AM +0100, Cyril Chemparathy wrote:
> On 7/24/2012 6:37 AM, Catalin Marinas wrote:
> > On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
> >> This patch fixes up the types used when converting back and forth between
> >> physical and virtual addresses.
> >>
> >> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> >> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
> >> ---
> >>   arch/arm/include/asm/memory.h |   17 +++++++++++------
> >>   1 file changed, 11 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> >> index fcb5757..7629dfe 100644
> >> --- a/arch/arm/include/asm/memory.h
> >> +++ b/arch/arm/include/asm/memory.h
> >> @@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;
> >>   	: "=r" (to)					\
> >>   	: "r" (from), "I" (type))
> >>
> >> -static inline unsigned long __virt_to_phys(unsigned long x)
> >> +static inline phys_addr_t __virt_to_phys(unsigned long x)
> >>   {
> >>   	unsigned long t;
> >>   	__pv_stub(x, t, "add", __PV_BITS_31_24);
> >>   	return t;
> >>   }
> >>
> >> -static inline unsigned long __phys_to_virt(unsigned long x)
> >> +static inline unsigned long __phys_to_virt(phys_addr_t x)
> >>   {
> >>   	unsigned long t;
> >>   	__pv_stub(x, t, "sub", __PV_BITS_31_24);
> >>   	return t;
> >>   }
> >
> > BTW, I would prefer if the phys-to-virt patching was fixed as well. It
> > shouldn't be difficult.
> 
> On that topic - yes, we have this on our radar, but in our case we;re 
> talking about patching (in head.S) and then repatching (at switch over).
> 
> One of the ideas we've been bouncing around has been to convert the 
> phys-virt patch code into arithmetic on PFNs.  This way we don't have to 
> get too messy with 64-bit in the patch code, and we can use the same 
> patch code for both phys_to_virt and virt_to_phys.  Thoughts on this 
> approach?

It may be slightly less efficient with Thumb-2 code as we can't have add
and lsl in the same instruction. It may anyway be faster than reading a
global variable.

But I suspect you can just mask out the top 32-bit part of a physical
address when converting to virtual. The opposite may also work, you just
have some constant in the top 32-bit part of the phys address. Note that
virt_to_phys is only valid for the lowmem, so 32-bit arithmetic with
some constant for the top 32-bit should be enough.

-- 
Catalin

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 17/23] ARM: add machine desc hook for early memory/paging initialization
  2012-07-24  1:10   ` Cyril Chemparathy
@ 2012-07-24 14:32     ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 14:32 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, will.deacon,
	catalin.marinas, Vitaly Andrianov

On Tuesday 24 July 2012, Cyril Chemparathy wrote:
> diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
> index 0b1c94b..49e9c2a 100644
> --- a/arch/arm/include/asm/mach/arch.h
> +++ b/arch/arm/include/asm/mach/arch.h
> @@ -39,6 +39,7 @@ struct machine_desc {
>                                          struct meminfo *);
>         void                    (*reserve)(void);/* reserve mem blocks  */
>         void                    (*map_io)(void);/* IO mapping function  */
> +       void                    (*init_meminfo)(void);
>         void                    (*init_early)(void);
>         void                    (*init_irq)(void);
>         struct sys_timer        *timer;         /* system tick timer    */
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index e15d83b..7cbe292 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -964,6 +964,9 @@ void __init setup_arch(char **cmdline_p)
>  
>         parse_early_param();
>  
> +       if (mdesc->init_meminfo)
> +               mdesc->init_meminfo();
> +
>         sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
>         sanity_check_meminfo();
>         arm_memblock_init(&meminfo, mdesc);

The function pointers in that structure are ordered by execution time,
and you call init_meminfo just before ->reserve, so it should go there.

I wonder if it's better to just do the setup in the reserve callback,
which would be a slight abuse of that interface but also keep down
the number of early callbacks.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 17/23] ARM: add machine desc hook for early memory/paging initialization
@ 2012-07-24 14:32     ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 14:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 24 July 2012, Cyril Chemparathy wrote:
> diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
> index 0b1c94b..49e9c2a 100644
> --- a/arch/arm/include/asm/mach/arch.h
> +++ b/arch/arm/include/asm/mach/arch.h
> @@ -39,6 +39,7 @@ struct machine_desc {
>                                          struct meminfo *);
>         void                    (*reserve)(void);/* reserve mem blocks  */
>         void                    (*map_io)(void);/* IO mapping function  */
> +       void                    (*init_meminfo)(void);
>         void                    (*init_early)(void);
>         void                    (*init_irq)(void);
>         struct sys_timer        *timer;         /* system tick timer    */
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index e15d83b..7cbe292 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -964,6 +964,9 @@ void __init setup_arch(char **cmdline_p)
>  
>         parse_early_param();
>  
> +       if (mdesc->init_meminfo)
> +               mdesc->init_meminfo();
> +
>         sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
>         sanity_check_meminfo();
>         arm_memblock_init(&meminfo, mdesc);

The function pointers in that structure are ordered by execution time,
and you call init_meminfo just before ->reserve, so it should go there.

I wonder if it's better to just do the setup in the reserve callback,
which would be a slight abuse of that interface but also keep down
the number of early callbacks.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 23/23] ARM: keystone: add switch over to high physical address range
  2012-07-24  1:33   ` Cyril Chemparathy
@ 2012-07-24 14:39     ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 14:39 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, will.deacon,
	catalin.marinas, Vitaly Andrianov

On Tuesday 24 July 2012, Cyril Chemparathy wrote:
> Keystone platforms have their physical memory mapped at an address outside the
> 32-bit physical range.  A Keystone machine with 16G of RAM would find its
> memory at 0x0800000000 - 0x0bffffffff.
> 
> For boot purposes, the interconnect supports a limited alias of some of this
> memory within the 32-bit addressable space (0x80000000 - 0xffffffff).  This
> aliasing is implemented in hardware, and is not intended to be used much
> beyond boot.  For instance, DMA coherence does not work when running out of
> this aliased address space.
> 
> Therefore, we've taken the approach of booting out of the low physical address
> range, and subsequently we switch over to the high range once we're safely
> inside machine specific territory.  This patch implements this switch over
> mechanism, which involves rewiring the TTBRs and page tables to point to the
> new physical address space.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Cyril Chemparathy <cyril@ti.com>

I think this needs some more explanations. Why is not not possible
to use this the larger area from the start when we first enable
paging?
Also, the code does not really look platform specific, so I could
imagine that if you need it, other similar platforms will need the
same thing, and it should be put into common code and enabled
all the time when using LPAE.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 23/23] ARM: keystone: add switch over to high physical address range
@ 2012-07-24 14:39     ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 14:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 24 July 2012, Cyril Chemparathy wrote:
> Keystone platforms have their physical memory mapped at an address outside the
> 32-bit physical range.  A Keystone machine with 16G of RAM would find its
> memory at 0x0800000000 - 0x0bffffffff.
> 
> For boot purposes, the interconnect supports a limited alias of some of this
> memory within the 32-bit addressable space (0x80000000 - 0xffffffff).  This
> aliasing is implemented in hardware, and is not intended to be used much
> beyond boot.  For instance, DMA coherence does not work when running out of
> this aliased address space.
> 
> Therefore, we've taken the approach of booting out of the low physical address
> range, and subsequently we switch over to the high range once we're safely
> inside machine specific territory.  This patch implements this switch over
> mechanism, which involves rewiring the TTBRs and page tables to point to the
> new physical address space.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Cyril Chemparathy <cyril@ti.com>

I think this needs some more explanations. Why is not not possible
to use this the larger area from the start when we first enable
paging?
Also, the code does not really look platform specific, so I could
imagine that if you need it, other similar platforms will need the
same thing, and it should be put into common code and enabled
all the time when using LPAE.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 21/23] ARM: keystone: introducing TI Keystone platform
  2012-07-24  1:38   ` Cyril Chemparathy
@ 2012-07-24 14:46     ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 14:46 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, will.deacon,
	catalin.marinas, Vitaly Andrianov

On Tuesday 24 July 2012, Cyril Chemparathy wrote:

> diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
> new file mode 100644
> index 0000000..118d631
> --- /dev/null
> +++ b/arch/arm/boot/dts/keystone-sim.dts
> @@ -0,0 +1,77 @@
> +/dts-v1/;
> +/include/ "skeleton.dtsi"
> +
> +/ {
> +	model = "Texas Instruments Keystone 2 SoC";
> +	compatible = "ti,keystone-evm";
> +	#address-cells = <1>;
> +	#size-cells = <1>;

I would assume that you need at least #address-cells=<2>, possibly
also #size-cells=<2>, in order to express large memory ranges.

> diff --git a/arch/arm/mach-keystone/include/mach/entry-macro.S b/arch/arm/mach-keystone/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..7f486f3
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/entry-macro.S
>
> +	.macro	disable_fiq
> +	.endm
> +
> +	.macro	arch_ret_to_user, tmp1, tmp2
> +	.endm

I think it would be better to enable MULTI_IRQ_HANDLER and remove
this file.

> diff --git a/arch/arm/mach-keystone/include/mach/io.h b/arch/arm/mach-keystone/include/mach/io.h
> new file mode 100644
> index 0000000..844d659
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/io.h

> +#ifndef __MACH_IO_H
> +#define __MACH_IO_H
> +
> +#define __io(a)		({ (void)(a); __typesafe_io(0); })
> +#define __mem_pci(a)	(a)
> +
> +#endif

This should also be removed.

> diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
> new file mode 100644
> index 0000000..7c78b1e
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/memory.h

> +#ifndef __ASM_MACH_MEMORY_H
> +#define __ASM_MACH_MEMORY_H
> +
> +#define MAX_PHYSMEM_BITS	36
> +#define SECTION_SIZE_BITS	34
> +
> +#endif /* __ASM_MACH_MEMORY_H */

I wonder if there is anything we can do to make these generic. What you
have here is ok for now, but we will need to do this differently once
we are building multiplatform kernels with keystone and sparse memory.

> diff --git a/arch/arm/mach-keystone/include/mach/system.h b/arch/arm/mach-keystone/include/mach/system.h
> new file mode 100644
> index 0000000..4887b4c
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/system.h

> +#ifndef __MACH_SYSTEM_H
> +#define __MACH_SYSTEM_H
> +
> +static inline void arch_idle(void)
> +{
> +	cpu_do_idle();
> +}
> +
> +static inline void arch_reset(char mode, const char *cmd)
> +{
> +	while (1)
> +		;
> +}
> +
> +#endif

These are no longer used, please remove the file.


> diff --git a/arch/arm/mach-keystone/include/mach/vmalloc.h b/arch/arm/mach-keystone/include/mach/vmalloc.h
> new file mode 100644
> index 0000000..9d34c09
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/vmalloc.h

> +
> +#define VMALLOC_END		0xFE800000UL
> +
> +#endif

same here.

> +DT_MACHINE_START(KEYSTONE, "Keystone")
> +	.map_io		= keystone_map_io,
> +	.init_irq	= keystone_init_irq,
> +	.timer		= &keystone_timer,
> +	.handle_irq	= gic_handle_irq,
> +	.init_machine	= keystone_init,
> +	.dt_compat	= keystone_match,
> +	.nr_irqs	= 480,
> +MACHINE_END

IIRC, you don't need to set the nr_irqs this high in advance,
they will be allocated automatically since you have enabled
sparse IRQs.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 21/23] ARM: keystone: introducing TI Keystone platform
@ 2012-07-24 14:46     ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 14:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 24 July 2012, Cyril Chemparathy wrote:

> diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
> new file mode 100644
> index 0000000..118d631
> --- /dev/null
> +++ b/arch/arm/boot/dts/keystone-sim.dts
> @@ -0,0 +1,77 @@
> +/dts-v1/;
> +/include/ "skeleton.dtsi"
> +
> +/ {
> +	model = "Texas Instruments Keystone 2 SoC";
> +	compatible = "ti,keystone-evm";
> +	#address-cells = <1>;
> +	#size-cells = <1>;

I would assume that you need at least #address-cells=<2>, possibly
also #size-cells=<2>, in order to express large memory ranges.

> diff --git a/arch/arm/mach-keystone/include/mach/entry-macro.S b/arch/arm/mach-keystone/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..7f486f3
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/entry-macro.S
>
> +	.macro	disable_fiq
> +	.endm
> +
> +	.macro	arch_ret_to_user, tmp1, tmp2
> +	.endm

I think it would be better to enable MULTI_IRQ_HANDLER and remove
this file.

> diff --git a/arch/arm/mach-keystone/include/mach/io.h b/arch/arm/mach-keystone/include/mach/io.h
> new file mode 100644
> index 0000000..844d659
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/io.h

> +#ifndef __MACH_IO_H
> +#define __MACH_IO_H
> +
> +#define __io(a)		({ (void)(a); __typesafe_io(0); })
> +#define __mem_pci(a)	(a)
> +
> +#endif

This should also be removed.

> diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
> new file mode 100644
> index 0000000..7c78b1e
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/memory.h

> +#ifndef __ASM_MACH_MEMORY_H
> +#define __ASM_MACH_MEMORY_H
> +
> +#define MAX_PHYSMEM_BITS	36
> +#define SECTION_SIZE_BITS	34
> +
> +#endif /* __ASM_MACH_MEMORY_H */

I wonder if there is anything we can do to make these generic. What you
have here is ok for now, but we will need to do this differently once
we are building multiplatform kernels with keystone and sparse memory.

> diff --git a/arch/arm/mach-keystone/include/mach/system.h b/arch/arm/mach-keystone/include/mach/system.h
> new file mode 100644
> index 0000000..4887b4c
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/system.h

> +#ifndef __MACH_SYSTEM_H
> +#define __MACH_SYSTEM_H
> +
> +static inline void arch_idle(void)
> +{
> +	cpu_do_idle();
> +}
> +
> +static inline void arch_reset(char mode, const char *cmd)
> +{
> +	while (1)
> +		;
> +}
> +
> +#endif

These are no longer used, please remove the file.


> diff --git a/arch/arm/mach-keystone/include/mach/vmalloc.h b/arch/arm/mach-keystone/include/mach/vmalloc.h
> new file mode 100644
> index 0000000..9d34c09
> --- /dev/null
> +++ b/arch/arm/mach-keystone/include/mach/vmalloc.h

> +
> +#define VMALLOC_END		0xFE800000UL
> +
> +#endif

same here.

> +DT_MACHINE_START(KEYSTONE, "Keystone")
> +	.map_io		= keystone_map_io,
> +	.init_irq	= keystone_init_irq,
> +	.timer		= &keystone_timer,
> +	.handle_irq	= gic_handle_irq,
> +	.init_machine	= keystone_init,
> +	.dt_compat	= keystone_match,
> +	.nr_irqs	= 480,
> +MACHINE_END

IIRC, you don't need to set the nr_irqs this high in advance,
they will be allocated automatically since you have enabled
sparse IRQs.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 17/23] ARM: add machine desc hook for early memory/paging initialization
  2012-07-24 14:32     ` Arnd Bergmann
@ 2012-07-24 14:47       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 14:47 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-kernel, nico, will.deacon,
	catalin.marinas, Vitaly Andrianov

Thanks for looking at this, Arnd.

On 7/24/2012 10:32 AM, Arnd Bergmann wrote:
> On Tuesday 24 July 2012, Cyril Chemparathy wrote:
>> diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
>> index 0b1c94b..49e9c2a 100644
>> --- a/arch/arm/include/asm/mach/arch.h
>> +++ b/arch/arm/include/asm/mach/arch.h
>> @@ -39,6 +39,7 @@ struct machine_desc {
>>                                           struct meminfo *);
>>          void                    (*reserve)(void);/* reserve mem blocks  */
>>          void                    (*map_io)(void);/* IO mapping function  */
>> +       void                    (*init_meminfo)(void);
>>          void                    (*init_early)(void);
>>          void                    (*init_irq)(void);
>>          struct sys_timer        *timer;         /* system tick timer    */
>> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
>> index e15d83b..7cbe292 100644
>> --- a/arch/arm/kernel/setup.c
>> +++ b/arch/arm/kernel/setup.c
>> @@ -964,6 +964,9 @@ void __init setup_arch(char **cmdline_p)
>>
>>          parse_early_param();
>>
>> +       if (mdesc->init_meminfo)
>> +               mdesc->init_meminfo();
>> +
>>          sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
>>          sanity_check_meminfo();
>>          arm_memblock_init(&meminfo, mdesc);
>
> The function pointers in that structure are ordered by execution time,
> and you call init_meminfo just before ->reserve, so it should go there.
>

Sure.  Will update.

> I wonder if it's better to just do the setup in the reserve callback,
> which would be a slight abuse of that interface but also keep down
> the number of early callbacks.
>

We need to switch the phys offset before sanity_check_meminfo() mangles 
the meminfo banks.

If we were to do this switch over in reserve(), we'd need to go back and 
fixup things that happen between the current location and reserve(). 
For example, we'd need to fix up the memblock regions.

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 17/23] ARM: add machine desc hook for early memory/paging initialization
@ 2012-07-24 14:47       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 14:47 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for looking at this, Arnd.

On 7/24/2012 10:32 AM, Arnd Bergmann wrote:
> On Tuesday 24 July 2012, Cyril Chemparathy wrote:
>> diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
>> index 0b1c94b..49e9c2a 100644
>> --- a/arch/arm/include/asm/mach/arch.h
>> +++ b/arch/arm/include/asm/mach/arch.h
>> @@ -39,6 +39,7 @@ struct machine_desc {
>>                                           struct meminfo *);
>>          void                    (*reserve)(void);/* reserve mem blocks  */
>>          void                    (*map_io)(void);/* IO mapping function  */
>> +       void                    (*init_meminfo)(void);
>>          void                    (*init_early)(void);
>>          void                    (*init_irq)(void);
>>          struct sys_timer        *timer;         /* system tick timer    */
>> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
>> index e15d83b..7cbe292 100644
>> --- a/arch/arm/kernel/setup.c
>> +++ b/arch/arm/kernel/setup.c
>> @@ -964,6 +964,9 @@ void __init setup_arch(char **cmdline_p)
>>
>>          parse_early_param();
>>
>> +       if (mdesc->init_meminfo)
>> +               mdesc->init_meminfo();
>> +
>>          sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
>>          sanity_check_meminfo();
>>          arm_memblock_init(&meminfo, mdesc);
>
> The function pointers in that structure are ordered by execution time,
> and you call init_meminfo just before ->reserve, so it should go there.
>

Sure.  Will update.

> I wonder if it's better to just do the setup in the reserve callback,
> which would be a slight abuse of that interface but also keep down
> the number of early callbacks.
>

We need to switch the phys offset before sanity_check_meminfo() mangles 
the meminfo banks.

If we were to do this switch over in reserve(), we'd need to go back and 
fixup things that happen between the current location and reserve(). 
For example, we'd need to fix up the memblock regions.

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 23/23] ARM: keystone: add switch over to high physical address range
  2012-07-24 14:39     ` Arnd Bergmann
@ 2012-07-24 14:59       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 14:59 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-kernel, nico, will.deacon,
	catalin.marinas, Vitaly Andrianov

On 7/24/2012 10:39 AM, Arnd Bergmann wrote:
> On Tuesday 24 July 2012, Cyril Chemparathy wrote:
>> Keystone platforms have their physical memory mapped at an address outside the
>> 32-bit physical range.  A Keystone machine with 16G of RAM would find its
>> memory at 0x0800000000 - 0x0bffffffff.
>>
>> For boot purposes, the interconnect supports a limited alias of some of this
>> memory within the 32-bit addressable space (0x80000000 - 0xffffffff).  This
>> aliasing is implemented in hardware, and is not intended to be used much
>> beyond boot.  For instance, DMA coherence does not work when running out of
>> this aliased address space.
>>
>> Therefore, we've taken the approach of booting out of the low physical address
>> range, and subsequently we switch over to the high range once we're safely
>> inside machine specific territory.  This patch implements this switch over
>> mechanism, which involves rewiring the TTBRs and page tables to point to the
>> new physical address space.
>>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>
> I think this needs some more explanations. Why is not not possible
> to use this the larger area from the start when we first enable
> paging?

By enable paging, I assume you refer to the head.S init.  For this the 
boot code needs to get the "real physical address" from somewhere 
instead of having to deduce it from the program counter.  We could do 
this by parsing DTB in the decompressor, and passing in a 64-bit physmem 
pointer into the kernel startup code.

We'd considered this approach (at least briefly), but then balked at (a) 
having to change the entry conditions into head.S code, and (b) baking 
in dependencies on the decompressor.

> Also, the code does not really look platform specific, so I could
> imagine that if you need it, other similar platforms will need the
> same thing, and it should be put into common code and enabled
> all the time when using LPAE.
>

Absolutely agreed.  Vitaly and I have been trying to work it out this 
way, and we hope to have something more common in the next version of 
this series.

> 	Arnd
>

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 23/23] ARM: keystone: add switch over to high physical address range
@ 2012-07-24 14:59       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 14:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 7/24/2012 10:39 AM, Arnd Bergmann wrote:
> On Tuesday 24 July 2012, Cyril Chemparathy wrote:
>> Keystone platforms have their physical memory mapped at an address outside the
>> 32-bit physical range.  A Keystone machine with 16G of RAM would find its
>> memory at 0x0800000000 - 0x0bffffffff.
>>
>> For boot purposes, the interconnect supports a limited alias of some of this
>> memory within the 32-bit addressable space (0x80000000 - 0xffffffff).  This
>> aliasing is implemented in hardware, and is not intended to be used much
>> beyond boot.  For instance, DMA coherence does not work when running out of
>> this aliased address space.
>>
>> Therefore, we've taken the approach of booting out of the low physical address
>> range, and subsequently we switch over to the high range once we're safely
>> inside machine specific territory.  This patch implements this switch over
>> mechanism, which involves rewiring the TTBRs and page tables to point to the
>> new physical address space.
>>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>
> I think this needs some more explanations. Why is not not possible
> to use this the larger area from the start when we first enable
> paging?

By enable paging, I assume you refer to the head.S init.  For this the 
boot code needs to get the "real physical address" from somewhere 
instead of having to deduce it from the program counter.  We could do 
this by parsing DTB in the decompressor, and passing in a 64-bit physmem 
pointer into the kernel startup code.

We'd considered this approach (at least briefly), but then balked at (a) 
having to change the entry conditions into head.S code, and (b) baking 
in dependencies on the decompressor.

> Also, the code does not really look platform specific, so I could
> imagine that if you need it, other similar platforms will need the
> same thing, and it should be put into common code and enabled
> all the time when using LPAE.
>

Absolutely agreed.  Vitaly and I have been trying to work it out this 
way, and we hope to have something more common in the next version of 
this series.

> 	Arnd
>

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 21/23] ARM: keystone: introducing TI Keystone platform
  2012-07-24 14:46     ` Arnd Bergmann
@ 2012-07-24 17:56       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 17:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-kernel, nico, will.deacon,
	catalin.marinas, Vitaly Andrianov

Arnd,

Thanks for taking the time to dig through this.

On 7/24/2012 10:46 AM, Arnd Bergmann wrote:
> On Tuesday 24 July 2012, Cyril Chemparathy wrote:
>
>> diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
>> new file mode 100644
>> index 0000000..118d631
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/keystone-sim.dts
>> @@ -0,0 +1,77 @@
>> +/dts-v1/;
>> +/include/ "skeleton.dtsi"
>> +
>> +/ {
>> +	model = "Texas Instruments Keystone 2 SoC";
>> +	compatible = "ti,keystone-evm";
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>
> I would assume that you need at least #address-cells=<2>, possibly
> also #size-cells=<2>, in order to express large memory ranges.
>

Thanks, will fix.

>> diff --git a/arch/arm/mach-keystone/include/mach/entry-macro.S b/arch/arm/mach-keystone/include/mach/entry-macro.S
>> new file mode 100644
>> index 0000000..7f486f3
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/entry-macro.S
>>
>> +	.macro	disable_fiq
>> +	.endm
>> +
>> +	.macro	arch_ret_to_user, tmp1, tmp2
>> +	.endm
>
> I think it would be better to enable MULTI_IRQ_HANDLER and remove
> this file.
>

Agreed.

>> diff --git a/arch/arm/mach-keystone/include/mach/io.h b/arch/arm/mach-keystone/include/mach/io.h
>> new file mode 100644
>> index 0000000..844d659
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/io.h
>
>> +#ifndef __MACH_IO_H
>> +#define __MACH_IO_H
>> +
>> +#define __io(a)		({ (void)(a); __typesafe_io(0); })
>> +#define __mem_pci(a)	(a)
>> +
>> +#endif
>
> This should also be removed.
>

Agreed.

>> diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
>> new file mode 100644
>> index 0000000..7c78b1e
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/memory.h
>
>> +#ifndef __ASM_MACH_MEMORY_H
>> +#define __ASM_MACH_MEMORY_H
>> +
>> +#define MAX_PHYSMEM_BITS	36
>> +#define SECTION_SIZE_BITS	34
>> +
>> +#endif /* __ASM_MACH_MEMORY_H */
>
> I wonder if there is anything we can do to make these generic. What you
> have here is ok for now, but we will need to do this differently once
> we are building multiplatform kernels with keystone and sparse memory.
>

Understood.  Any ideas on the general direction towards solving this?

>> diff --git a/arch/arm/mach-keystone/include/mach/system.h b/arch/arm/mach-keystone/include/mach/system.h
>> new file mode 100644
>> index 0000000..4887b4c
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/system.h
>
>> +#ifndef __MACH_SYSTEM_H
>> +#define __MACH_SYSTEM_H
>> +
>> +static inline void arch_idle(void)
>> +{
>> +	cpu_do_idle();
>> +}
>> +
>> +static inline void arch_reset(char mode, const char *cmd)
>> +{
>> +	while (1)
>> +		;
>> +}
>> +
>> +#endif
>
> These are no longer used, please remove the file.
>

Sure.

>
>> diff --git a/arch/arm/mach-keystone/include/mach/vmalloc.h b/arch/arm/mach-keystone/include/mach/vmalloc.h
>> new file mode 100644
>> index 0000000..9d34c09
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/vmalloc.h
>
>> +
>> +#define VMALLOC_END		0xFE800000UL
>> +
>> +#endif
>
> same here.
>

Sure.

>> +DT_MACHINE_START(KEYSTONE, "Keystone")
>> +	.map_io		= keystone_map_io,
>> +	.init_irq	= keystone_init_irq,
>> +	.timer		= &keystone_timer,
>> +	.handle_irq	= gic_handle_irq,
>> +	.init_machine	= keystone_init,
>> +	.dt_compat	= keystone_match,
>> +	.nr_irqs	= 480,
>> +MACHINE_END
>
> IIRC, you don't need to set the nr_irqs this high in advance,
> they will be allocated automatically since you have enabled
> sparse IRQs.
>

We were seeing a complaint without nr_irqs set, but I'll dig into that 
further.

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 21/23] ARM: keystone: introducing TI Keystone platform
@ 2012-07-24 17:56       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-24 17:56 UTC (permalink / raw)
  To: linux-arm-kernel

Arnd,

Thanks for taking the time to dig through this.

On 7/24/2012 10:46 AM, Arnd Bergmann wrote:
> On Tuesday 24 July 2012, Cyril Chemparathy wrote:
>
>> diff --git a/arch/arm/boot/dts/keystone-sim.dts b/arch/arm/boot/dts/keystone-sim.dts
>> new file mode 100644
>> index 0000000..118d631
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/keystone-sim.dts
>> @@ -0,0 +1,77 @@
>> +/dts-v1/;
>> +/include/ "skeleton.dtsi"
>> +
>> +/ {
>> +	model = "Texas Instruments Keystone 2 SoC";
>> +	compatible = "ti,keystone-evm";
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>
> I would assume that you need at least #address-cells=<2>, possibly
> also #size-cells=<2>, in order to express large memory ranges.
>

Thanks, will fix.

>> diff --git a/arch/arm/mach-keystone/include/mach/entry-macro.S b/arch/arm/mach-keystone/include/mach/entry-macro.S
>> new file mode 100644
>> index 0000000..7f486f3
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/entry-macro.S
>>
>> +	.macro	disable_fiq
>> +	.endm
>> +
>> +	.macro	arch_ret_to_user, tmp1, tmp2
>> +	.endm
>
> I think it would be better to enable MULTI_IRQ_HANDLER and remove
> this file.
>

Agreed.

>> diff --git a/arch/arm/mach-keystone/include/mach/io.h b/arch/arm/mach-keystone/include/mach/io.h
>> new file mode 100644
>> index 0000000..844d659
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/io.h
>
>> +#ifndef __MACH_IO_H
>> +#define __MACH_IO_H
>> +
>> +#define __io(a)		({ (void)(a); __typesafe_io(0); })
>> +#define __mem_pci(a)	(a)
>> +
>> +#endif
>
> This should also be removed.
>

Agreed.

>> diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
>> new file mode 100644
>> index 0000000..7c78b1e
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/memory.h
>
>> +#ifndef __ASM_MACH_MEMORY_H
>> +#define __ASM_MACH_MEMORY_H
>> +
>> +#define MAX_PHYSMEM_BITS	36
>> +#define SECTION_SIZE_BITS	34
>> +
>> +#endif /* __ASM_MACH_MEMORY_H */
>
> I wonder if there is anything we can do to make these generic. What you
> have here is ok for now, but we will need to do this differently once
> we are building multiplatform kernels with keystone and sparse memory.
>

Understood.  Any ideas on the general direction towards solving this?

>> diff --git a/arch/arm/mach-keystone/include/mach/system.h b/arch/arm/mach-keystone/include/mach/system.h
>> new file mode 100644
>> index 0000000..4887b4c
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/system.h
>
>> +#ifndef __MACH_SYSTEM_H
>> +#define __MACH_SYSTEM_H
>> +
>> +static inline void arch_idle(void)
>> +{
>> +	cpu_do_idle();
>> +}
>> +
>> +static inline void arch_reset(char mode, const char *cmd)
>> +{
>> +	while (1)
>> +		;
>> +}
>> +
>> +#endif
>
> These are no longer used, please remove the file.
>

Sure.

>
>> diff --git a/arch/arm/mach-keystone/include/mach/vmalloc.h b/arch/arm/mach-keystone/include/mach/vmalloc.h
>> new file mode 100644
>> index 0000000..9d34c09
>> --- /dev/null
>> +++ b/arch/arm/mach-keystone/include/mach/vmalloc.h
>
>> +
>> +#define VMALLOC_END		0xFE800000UL
>> +
>> +#endif
>
> same here.
>

Sure.

>> +DT_MACHINE_START(KEYSTONE, "Keystone")
>> +	.map_io		= keystone_map_io,
>> +	.init_irq	= keystone_init_irq,
>> +	.timer		= &keystone_timer,
>> +	.handle_irq	= gic_handle_irq,
>> +	.init_machine	= keystone_init,
>> +	.dt_compat	= keystone_match,
>> +	.nr_irqs	= 480,
>> +MACHINE_END
>
> IIRC, you don't need to set the nr_irqs this high in advance,
> they will be allocated automatically since you have enabled
> sparse IRQs.
>

We were seeing a complaint without nr_irqs set, but I'll dig into that 
further.

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 21/23] ARM: keystone: introducing TI Keystone platform
  2012-07-24 17:56       ` Cyril Chemparathy
@ 2012-07-24 18:45         ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 18:45 UTC (permalink / raw)
  To: Cyril Chemparathy
  Cc: linux-arm-kernel, linux-kernel, nico, will.deacon,
	catalin.marinas, Vitaly Andrianov

On Tuesday 24 July 2012, Cyril Chemparathy wrote:
> >> diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
> >> new file mode 100644
> >> index 0000000..7c78b1e
> >> --- /dev/null
> >> +++ b/arch/arm/mach-keystone/include/mach/memory.h
> >
> >> +#ifndef __ASM_MACH_MEMORY_H
> >> +#define __ASM_MACH_MEMORY_H
> >> +
> >> +#define MAX_PHYSMEM_BITS    36
> >> +#define SECTION_SIZE_BITS   34
> >> +
> >> +#endif /* __ASM_MACH_MEMORY_H */
> >
> > I wonder if there is anything we can do to make these generic. What you
> > have here is ok for now, but we will need to do this differently once
> > we are building multiplatform kernels with keystone and sparse memory.
> >
> 
> Understood.  Any ideas on the general direction towards solving this?

I can't remember discussing this in the past. Maybe it never came up
because most platforms don't enable sparsemem.

IIRC this is done through Kconfig on powerpc, where we pick the minimum
required size based on which platforms are enabled.

I also don't know what to do about ARM_PATCH_PHYS_VIRT here: my
impression so far was that we would enable it for all multiplatform
builds, but it conflicts with sparsemem.

> >> +DT_MACHINE_START(KEYSTONE, "Keystone")
> >> +    .map_io         = keystone_map_io,
> >> +    .init_irq       = keystone_init_irq,
> >> +    .timer          = &keystone_timer,
> >> +    .handle_irq     = gic_handle_irq,
> >> +    .init_machine   = keystone_init,
> >> +    .dt_compat      = keystone_match,
> >> +    .nr_irqs        = 480,
> >> +MACHINE_END
> >
> > IIRC, you don't need to set the nr_irqs this high in advance,
> > they will be allocated automatically since you have enabled
> > sparse IRQs.
> >
> 
> We were seeing a complaint without nr_irqs set, but I'll dig into that 
> further.

Maybe a driver that hardcodes an IRQ number?

	Arndx

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 21/23] ARM: keystone: introducing TI Keystone platform
@ 2012-07-24 18:45         ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2012-07-24 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 24 July 2012, Cyril Chemparathy wrote:
> >> diff --git a/arch/arm/mach-keystone/include/mach/memory.h b/arch/arm/mach-keystone/include/mach/memory.h
> >> new file mode 100644
> >> index 0000000..7c78b1e
> >> --- /dev/null
> >> +++ b/arch/arm/mach-keystone/include/mach/memory.h
> >
> >> +#ifndef __ASM_MACH_MEMORY_H
> >> +#define __ASM_MACH_MEMORY_H
> >> +
> >> +#define MAX_PHYSMEM_BITS    36
> >> +#define SECTION_SIZE_BITS   34
> >> +
> >> +#endif /* __ASM_MACH_MEMORY_H */
> >
> > I wonder if there is anything we can do to make these generic. What you
> > have here is ok for now, but we will need to do this differently once
> > we are building multiplatform kernels with keystone and sparse memory.
> >
> 
> Understood.  Any ideas on the general direction towards solving this?

I can't remember discussing this in the past. Maybe it never came up
because most platforms don't enable sparsemem.

IIRC this is done through Kconfig on powerpc, where we pick the minimum
required size based on which platforms are enabled.

I also don't know what to do about ARM_PATCH_PHYS_VIRT here: my
impression so far was that we would enable it for all multiplatform
builds, but it conflicts with sparsemem.

> >> +DT_MACHINE_START(KEYSTONE, "Keystone")
> >> +    .map_io         = keystone_map_io,
> >> +    .init_irq       = keystone_init_irq,
> >> +    .timer          = &keystone_timer,
> >> +    .handle_irq     = gic_handle_irq,
> >> +    .init_machine   = keystone_init,
> >> +    .dt_compat      = keystone_match,
> >> +    .nr_irqs        = 480,
> >> +MACHINE_END
> >
> > IIRC, you don't need to set the nr_irqs this high in advance,
> > they will be allocated automatically since you have enabled
> > sparse IRQs.
> >
> 
> We were seeing a complaint without nr_irqs set, but I'll dig into that 
> further.

Maybe a driver that hardcodes an IRQ number?

	Arndx

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
  2012-07-24 10:05     ` Catalin Marinas
@ 2012-07-31 15:35       ` Cyril Chemparathy
  -1 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-31 15:35 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, linux-kernel, nico, Will Deacon, Vitaly Andrianov

Hi Catalin,

On 7/24/2012 6:05 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
>> This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
>> unsigned long math truncates the mask at the 32-bits.  This clearly does bad
>> things on PAE systems.
>>
>> This patch fixes this problem by defining these masks as signed quantities.
>> We then rely on sign extension to do the right thing.
>>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> ---
>>   arch/arm/include/asm/page.h           |    7 ++++++-
>>   arch/arm/include/asm/pgtable-3level.h |    6 +++---
>>   2 files changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
>> index ecf9019..1c810d2 100644
>> --- a/arch/arm/include/asm/page.h
>> +++ b/arch/arm/include/asm/page.h
>> @@ -13,7 +13,12 @@
>>   /* PAGE_SHIFT determines the page size */
>>   #define PAGE_SHIFT		12
>>   #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
>> -#define PAGE_MASK		(~(PAGE_SIZE-1))
>> +
>> +/*
>> + * We do not use PAGE_SIZE in the following because we rely on sign
>> + * extension to appropriately extend upper bits for PAE systems
>> + */
>> +#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
>
> Would it work if we use a 1ULL here and avoid the sign trick? I'm
> worried about some context where this would lose the sign. We could have
> an #ifdef here while the PGDIR/PMD masks are in a separate file already.
>

I tried out this approach, and it spews size mismatch warnings in a few 
places when the mask is applied to a virtual address and casted to a 
pointer.  Rather than having to scatter fixes in all these places, 
relying on sign extension may be cleaner.

Are there any particular areas that you are concerned about, that could 
potentially break with the sign extension approach?

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions
@ 2012-07-31 15:35       ` Cyril Chemparathy
  0 siblings, 0 replies; 88+ messages in thread
From: Cyril Chemparathy @ 2012-07-31 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Catalin,

On 7/24/2012 6:05 AM, Catalin Marinas wrote:
> On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
>> This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
>> unsigned long math truncates the mask at the 32-bits.  This clearly does bad
>> things on PAE systems.
>>
>> This patch fixes this problem by defining these masks as signed quantities.
>> We then rely on sign extension to do the right thing.
>>
>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> ---
>>   arch/arm/include/asm/page.h           |    7 ++++++-
>>   arch/arm/include/asm/pgtable-3level.h |    6 +++---
>>   2 files changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
>> index ecf9019..1c810d2 100644
>> --- a/arch/arm/include/asm/page.h
>> +++ b/arch/arm/include/asm/page.h
>> @@ -13,7 +13,12 @@
>>   /* PAGE_SHIFT determines the page size */
>>   #define PAGE_SHIFT		12
>>   #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
>> -#define PAGE_MASK		(~(PAGE_SIZE-1))
>> +
>> +/*
>> + * We do not use PAGE_SIZE in the following because we rely on sign
>> + * extension to appropriately extend upper bits for PAE systems
>> + */
>> +#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
>
> Would it work if we use a 1ULL here and avoid the sign trick? I'm
> worried about some context where this would lose the sign. We could have
> an #ifdef here while the PGDIR/PMD masks are in a separate file already.
>

I tried out this approach, and it spews size mismatch warnings in a few 
places when the mask is applied to a virtual address and casted to a 
pointer.  Rather than having to scatter fixes in all these places, 
relying on sign extension may be cleaner.

Are there any particular areas that you are concerned about, that could 
potentially break with the sign extension approach?

-- 
Thanks
- Cyril

^ permalink raw reply	[flat|nested] 88+ messages in thread

end of thread, other threads:[~2012-07-31 15:35 UTC | newest]

Thread overview: 88+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-24  1:09 [RFC 00/23] Introducing the TI Keystone platform Cyril Chemparathy
2012-07-24  1:09 ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 01/23] ARM: LPAE: disable phys-to-virt patching on PAE systems Cyril Chemparathy
2012-07-24  1:09   ` Cyril Chemparathy
2012-07-24  9:41   ` Catalin Marinas
2012-07-24  9:41     ` Catalin Marinas
2012-07-24 10:43     ` Cyril Chemparathy
2012-07-24 10:43       ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 02/23] ARM: LPAE: use signed arithmetic for mask definitions Cyril Chemparathy
2012-07-24  1:09   ` Cyril Chemparathy
2012-07-24 10:05   ` Catalin Marinas
2012-07-24 10:05     ` Catalin Marinas
2012-07-24 10:52     ` Cyril Chemparathy
2012-07-24 10:52       ` Cyril Chemparathy
2012-07-31 15:35     ` Cyril Chemparathy
2012-07-31 15:35       ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 03/23] ARM: LPAE: use phys_addr_t on virt <--> phys conversion Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24 10:37   ` Catalin Marinas
2012-07-24 10:37     ` Catalin Marinas
2012-07-24 10:55     ` Cyril Chemparathy
2012-07-24 10:55       ` Cyril Chemparathy
2012-07-24 11:02       ` Catalin Marinas
2012-07-24 11:02         ` Catalin Marinas
2012-07-24  1:09 ` [RFC 04/23] ARM: LPAE: use phys_addr_t in alloc_init_pud() Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 05/23] ARM: LPAE: use phys_addr_t in free_memmap() Cyril Chemparathy
2012-07-24  1:09   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 06/23] ARM: LPAE: use phys_addr_t for initrd location and size Cyril Chemparathy
2012-07-24  1:33   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 07/23] ARM: LPAE: use phys_addr_t for membank size Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24 10:04   ` Will Deacon
2012-07-24 10:04     ` Will Deacon
2012-07-24 10:46     ` Cyril Chemparathy
2012-07-24 10:46       ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 08/23] ARM: LPAE: use 64-bit pgd physical address in switch_mm() Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 09/23] ARM: LPAE: use 64-bit accessors for TTBR registers Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 10/23] ARM: mm: use physical addresses in highmem sanity checks Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 11/23] ARM: mm: cleanup checks for membank overlap with vmalloc area Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 12/23] ARM: mm: clean up membank size limit checks Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 13/23] ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 14/23] ARM: LPAE: factor out T1SZ and TTBR1 computations Cyril Chemparathy
2012-07-24  1:38   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 15/23] ARM: LPAE: allow proc override of TTB setup Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 16/23] ARM: LPAE: accomodate >32-bit addresses for page table base Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 17/23] ARM: add machine desc hook for early memory/paging initialization Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24 14:32   ` Arnd Bergmann
2012-07-24 14:32     ` Arnd Bergmann
2012-07-24 14:47     ` Cyril Chemparathy
2012-07-24 14:47       ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 18/23] ARM: add virt_to_idmap for interconnect aliasing Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 19/23] drivers: cma: fix addressing on PAE machines Cyril Chemparathy
2012-07-24  1:38   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 20/23] mm: bootmem: use phys_addr_t for physical addresses Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 21/23] ARM: keystone: introducing TI Keystone platform Cyril Chemparathy
2012-07-24  1:38   ` Cyril Chemparathy
2012-07-24 14:46   ` Arnd Bergmann
2012-07-24 14:46     ` Arnd Bergmann
2012-07-24 17:56     ` Cyril Chemparathy
2012-07-24 17:56       ` Cyril Chemparathy
2012-07-24 18:45       ` Arnd Bergmann
2012-07-24 18:45         ` Arnd Bergmann
2012-07-24  1:09 ` [RFC 22/23] ARM: keystone: enable SMP on Keystone machines Cyril Chemparathy
2012-07-24  1:10   ` Cyril Chemparathy
2012-07-24  1:09 ` [RFC 23/23] ARM: keystone: add switch over to high physical address range Cyril Chemparathy
2012-07-24  1:33   ` Cyril Chemparathy
2012-07-24  9:49   ` Catalin Marinas
2012-07-24  9:49     ` Catalin Marinas
2012-07-24 14:39   ` Arnd Bergmann
2012-07-24 14:39     ` Arnd Bergmann
2012-07-24 14:59     ` Cyril Chemparathy
2012-07-24 14:59       ` Cyril Chemparathy
2012-07-24  9:08 ` [RFC 00/23] Introducing the TI Keystone platform Will Deacon
2012-07-24  9:08   ` Will Deacon
2012-07-24 10:41   ` Cyril Chemparathy
2012-07-24 10:41     ` Cyril Chemparathy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.