* [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.