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
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
drivers/base/dma-contiguous.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/pgtable-3level-hwdef.h | 10 ++++++++++
arch/arm/mm/proc-v7-3level.S | 16 ++++------------
2 files changed, 14 insertions(+), 12 deletions(-)
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/page.h | 7 ++++++-
arch/arm/include/asm/pgtable-3level.h | 6 +++---
2 files changed, 9 insertions(+), 4 deletions(-)
From: Vitaly Andrianov <redacted>
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/mm/init.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
@@ -469,8 +469,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)*Converttophysicaladdresses,and*roundstartupwardsandenddownwards.*/-pg=(unsignedlong)PAGE_ALIGN(__pa(start_pg));-pgend=(unsignedlong)__pa(end_pg)&PAGE_MASK;+pg=PAGE_ALIGN(__pa(start_pg));+pgend=__pa(end_pg)&PAGE_MASK;/**Iftherearefreepagesbetweenthese,
From: Vitaly Andrianov <redacted>
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/mm/mmu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
From: Vitaly Andrianov <redacted>
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
include/linux/bootmem.h | 30 ++++++++++++------------
mm/bootmem.c | 59 ++++++++++++++++++++++++-----------------------
2 files changed, 45 insertions(+), 44 deletions(-)
@@ -49,10 +49,10 @@ extern unsigned long free_all_bootmem_node(pg_data_t *pgdat);externunsignedlongfree_all_bootmem(void);externvoidfree_bootmem_node(pg_data_t*pgdat,-unsignedlongaddr,+phys_addr_taddr,unsignedlongsize);-externvoidfree_bootmem(unsignedlongaddr,unsignedlongsize);-externvoidfree_bootmem_late(unsignedlongaddr,unsignedlongsize);+externvoidfree_bootmem(phys_addr_taddr,unsignedlongsize);+externvoidfree_bootmem_late(phys_addr_taddr,unsignedlongsize);/**Flagsforreserve_bootmem(alsoifCONFIG_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)-externintreserve_bootmem(unsignedlongaddr,+externintreserve_bootmem(phys_addr_taddr,unsignedlongsize,intflags);externintreserve_bootmem_node(pg_data_t*pgdat,-unsignedlongphysaddr,+phys_addr_tphysaddr,unsignedlongsize,intflags);externvoid*__alloc_bootmem(unsignedlongsize,unsignedlongalign,-unsignedlonggoal);+phys_addr_tgoal);externvoid*__alloc_bootmem_nopanic(unsignedlongsize,unsignedlongalign,-unsignedlonggoal);+phys_addr_tgoal);externvoid*__alloc_bootmem_node(pg_data_t*pgdat,unsignedlongsize,unsignedlongalign,-unsignedlonggoal);+phys_addr_tgoal);void*__alloc_bootmem_node_high(pg_data_t*pgdat,unsignedlongsize,unsignedlongalign,-unsignedlonggoal);+phys_addr_tgoal);externvoid*__alloc_bootmem_node_nopanic(pg_data_t*pgdat,unsignedlongsize,unsignedlongalign,-unsignedlonggoal);+phys_addr_tgoal);void*___alloc_bootmem_node_nopanic(pg_data_t*pgdat,unsignedlongsize,unsignedlongalign,-unsignedlonggoal,-unsignedlonglimit);+phys_addr_tgoal,+phys_addr_tlimit);externvoid*__alloc_bootmem_low(unsignedlongsize,unsignedlongalign,-unsignedlonggoal);+phys_addr_tgoal);externvoid*__alloc_bootmem_low_node(pg_data_t*pgdat,unsignedlongsize,unsignedlongalign,-unsignedlonggoal);+phys_addr_tgoal);#ifdef CONFIG_NO_BOOTMEM/* We are using top down, so it is safe to use 0 here */
@@ -154,7 +154,7 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)*down,butwearestillinitializingthesystem.Pagesaregivendirectly*tothepageallocator,nobootmemmetadataisupdatedbecauseitisgone.*/-void__initfree_bootmem_late(unsignedlongaddr,unsignedlongsize)+void__initfree_bootmem_late(phys_addr_taddr,unsignedlongsize){unsignedlongcursor,end;
@@ -362,7 +362,7 @@ static int __init mark_bootmem(unsigned long start, unsigned long end,**Therangemustresidecompletelyonthespecifiednode.*/-void__initfree_bootmem_node(pg_data_t*pgdat,unsignedlongphysaddr,+void__initfree_bootmem_node(pg_data_t*pgdat,phys_addr_tphysaddr,unsignedlongsize){unsignedlongstart,end;
@@ -407,7 +407,7 @@ void __init free_bootmem(unsigned long addr, unsigned long size)**Therangemustresidecompletelyonthespecifiednode.*/-int__initreserve_bootmem_node(pg_data_t*pgdat,unsignedlongphysaddr,+int__initreserve_bootmem_node(pg_data_t*pgdat,phys_addr_tphysaddr,unsignedlongsize,intflags){unsignedlongstart,end;
@@ -428,7 +428,7 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,**Therangemustbecontiguousbutmayspannodeboundaries.*/-int__initreserve_bootmem(unsignedlongaddr,unsignedlongsize,+int__initreserve_bootmem(phys_addr_taddr,unsignedlongsize,intflags){unsignedlongstart,end;
@@ -439,7 +439,7 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size,returnmark_bootmem(start,end,1,flags);}-int__weak__initreserve_bootmem_generic(unsignedlongphys,unsignedlonglen,+int__weak__initreserve_bootmem_generic(phys_addr_tphys,unsignedlonglen,intflags){returnreserve_bootmem(phys,len,flags);
@@ -461,7 +461,7 @@ static unsigned long __init align_idx(struct bootmem_data *bdata,staticunsignedlong__initalign_off(structbootmem_data*bdata,unsignedlongoff,unsignedlongalign){-unsignedlongbase=PFN_PHYS(bdata->node_min_pfn);+phys_addr_tbase=PFN_PHYS(bdata->node_min_pfn);/* Same as align_idx for byte offsets */
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/proc-fns.h | 24 +++++++++++++++++++-----
arch/arm/mm/context.c | 13 ++-----------
2 files changed, 21 insertions(+), 16 deletions(-)
This patch fixes up the types used when converting back and forth between
physical and virtual addresses.
Signed-off-by: Vitaly Andrianov <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/include/asm/memory.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
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(-)
@@ -390,6 +390,7 @@ __mohawk_setup:mcrp15,0,r0,c8,c7@invalidateI,DTLBsorrr4,r4,#0x18 @ cache the page table in L2mcrp15,0,r4,c2,c0,0@loadpagetablepointer+mvnr4,#0 @ do not set page table pointermovr0,#0 @ don't allow CP accessmcrp15,0,r0,c15,c1,0@writeCPaccessregister
@@ -210,7 +210,9 @@ __v6_setup:ALT_UP(orrr4,r4,#TTB_FLAGS_UP)ALT_SMP(orrr8,r8,#TTB_FLAGS_SMP)ALT_UP(orrr8,r8,#TTB_FLAGS_UP)+mcrp15,0,r4,c2,c0,0@loadTTB0mcrp15,0,r8,c2,c0,1@loadTTB1+mvnr4,#0 @ do not set page table pointer#endif /* CONFIG_MMU */adrr5,v6_crvalldmiar5,{r5,r6}
@@ -250,6 +250,7 @@ __v7_setup:#ifdef CONFIG_MMUmcrp15,0,r10,c8,c7,0@invalidateI+DTLBsv7_ttb_setupr10,r4,r8,r5@TTBCR,TTBRxsetup+mvnr4,#0 @ do not set page table pointerldrr5,=PRRR@PRRRldrr6,=NMRR@NMRRmcrp15,0,r5,c10,c2,0@writePRRR
@@ -455,6 +455,7 @@ __xsc3_setup:mcrp15,0,ip,c8,c7,0@invalidateIandDTLBsorrr4,r4,#0x18 @ cache the page table in L2mcrp15,0,r4,c2,c0,0@loadpagetablepointer+mvnr4,#0 @ do not set page table pointermovr0,#1 << 6 @ cp6 access for early sched_clockmcrp15,0,r0,c15,c1,0@writeCPaccessregister
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
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
@@ -0,0 +1,73 @@+/*+*Copyright2012TexasInstruments,Inc.+*+*Basedonplatsmp.c,Copyright2010-2011Calxeda,Inc.+*Basedonplatsmp.c,Copyright(C)2002ARMLtd.+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsandconditionsoftheGNUGeneralPublicLicense,+*version2,aspublishedbytheFreeSoftwareFoundation.+*+*Thisprogramisdistributedinthehopeitwillbeuseful,butWITHOUT+*ANYWARRANTY;withouteventheimpliedwarrantyofMERCHANTABILITYor+*FITNESSFORAPARTICULARPURPOSE.SeetheGNUGeneralPublicLicensefor+*moredetails.+*+*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicensealongwith+*thisprogram.Ifnot,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>++externvoidsecondary_startup(void);++staticvoid__initkeystone_smp_init_cpus(void)+{+unsignedinti,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);+}++staticvoid__initkeystone_smp_prepare_cpus(unsignedintmax_cpus)+{+/* nothing for now */+}++staticvoid__cpuinitkeystone_secondary_init(unsignedintcpu)+{+gic_secondary_init(0);+}++staticint__cpuinit+keystone_boot_secondary(unsignedintcpu,structtask_struct*idle)+{+unsignedlong*jump_ptr=phys_to_virt(0x800001f0);++jump_ptr[cpu]=virt_to_idmap(&secondary_startup);+__cpuc_flush_dcache_area(jump_ptr,sizeof(jump_ptr)*4);++return0;+}++structsmp_opskeystone_smp_ops__initdata={+smp_init_ops(keystone)+smp_secondary_ops(keystone)+};
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/mm/mmu.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/memory.h | 2 ++
1 file changed, 2 insertions(+)
From: Vitaly Andrianov <redacted>
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
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(-)
@@ -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",(longlong)idmap_start,(longlong)idmap_end);
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/mach/arch.h | 1 +
arch/arm/kernel/setup.c | 3 +++
2 files changed, 4 insertions(+)
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/mm/mmu.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
From: Vitaly Andrianov <redacted>
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/Kconfig | 1 +
1 file changed, 1 insertion(+)
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
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(-)
@@ -320,6 +321,7 @@ __create_page_tables:#ifdef CONFIG_ARM_LPAEsubr4,r4,#0x1000 @ point to the PGD table#endif+movr4,r4,lsr#ARCH_PGD_SHIFTmovpc,lrENDPROC(__create_page_tables).ltorg
@@ -392,7 +394,7 @@ __secondary_data:*r0=cp#15 control register*r1=machineID*r2=atagsordtbpointer-*r4=pagetablepointer+*r4=pagetable (seeARCH_PGD_SHIFTinasm/cache.h)*r9=processorID*r13=*virtual*addresstojumptouponcompletion*/
@@ -403,6 +404,7 @@ __arm1026_setup:mcrp15,0,r0,c7,c10,4@drainwritebufferonv4#ifdef CONFIG_MMUmcrp15,0,r0,c8,c7@invalidateI,DTLBsonv4+movr4,r4,lsl#ARCH_PGD_SHIFTmcrp15,0,r4,c2,c0@loadpagetablepointermvnr4,#0 @ do not set page table pointer#endif
@@ -388,6 +389,7 @@ __mohawk_setup:mcrp15,0,r0,c7,c7@invalidateI,Dcachesmcrp15,0,r0,c7,c10,4@drainwritebuffermcrp15,0,r0,c8,c7@invalidateI,DTLBs+movr4,r4,lsl#ARCH_PGD_SHIFTorrr4,r4,#0x18 @ cache the page table in L2mcrp15,0,r4,c2,c0,0@loadpagetablepointermvnr4,#0 @ do not set page table pointer
@@ -453,6 +454,7 @@ __xsc3_setup:mcrp15,0,ip,c7,c10,4@datawritebarriermcrp15,0,ip,c7,c5,4@prefetchflushmcrp15,0,ip,c8,c7,0@invalidateIandDTLBs+movr4,r4,lsl#ARCH_PGD_SHIFTorrr4,r4,#0x18 @ cache the page table in L2mcrp15,0,r4,c2,c0,0@loadpagetablepointermvnr4,#0 @ do not set page table pointer
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
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(-)
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/mm/mmu.c | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
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(-)
@@ -74,6 +82,86 @@ static const char *keystone_match[] __initconst = {NULL,};+#ifdef CONFIG_ARM_LPAE++phys_addr_tkeystone_phys_offset=KEYSTONE_LOW_PHYS_START;++externstructproc_info_list*lookup_processor_type(unsignedint);++staticvoid__initkeystone_init_meminfo(void)+{+unsignedlongmap_start,map_end;+structproc_info_list*procinfo;+phys_addr_tmem_start,mem_end;+pgd_t*pgd0,*pgdk;+pud_t*pud0,*pudk;+pmd_t*pmd0,*pmdk;+phys_addr_tphys;+pmdval_tpmdprot;+inti;++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++staticvoid__initkeystone_init_meminfo(void)+{+/* nothing to do here */+}++#endif+DT_MACHINE_START(KEYSTONE,"Keystone")smp_ops(keystone_smp_ops).map_io=keystone_map_io,
From: Vitaly Andrianov <redacted>
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/mm/init.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
@@ -347,14 +347,14 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)#ifdef CONFIG_BLK_DEV_INITRDif(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){
@@ -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
From: Will Deacon <hidden> Date: 2012-07-24 09:09:04
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
On Tue, Jul 24, 2012 at 02:09:03AM +0100, Cyril Chemparathy wrote:
From: Vitaly Andrianov <redacted>
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
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
On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
quoted hunk
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/page.h | 7 ++++++-
arch/arm/include/asm/pgtable-3level.h | 6 +++---
2 files changed, 9 insertions(+), 4 deletions(-)
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
On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
quoted hunk
This patch fixes up the types used when converting back and forth between
physical and virtual addresses.
Signed-off-by: Vitaly Andrianov <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/include/asm/memory.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
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:
quoted
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.
quoted
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.
quoted
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?].
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:
quoted
From: Vitaly Andrianov <redacted>
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
On Tue, Jul 24, 2012 at 02:09:04AM +0100, Cyril Chemparathy wrote:
quoted
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/page.h | 7 ++++++-
arch/arm/include/asm/pgtable-3level.h | 6 +++---
2 files changed, 9 insertions(+), 4 deletions(-)
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
On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
quoted
This patch fixes up the types used when converting back and forth between
physical and virtual addresses.
Signed-off-by: Vitaly Andrianov <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/include/asm/memory.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
@@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;:"=r"(to)\:"r"(from),"I"(type))-staticinlineunsignedlong__virt_to_phys(unsignedlongx)+staticinlinephys_addr_t__virt_to_phys(unsignedlongx){unsignedlongt;__pv_stub(x,t,"add",__PV_BITS_31_24);returnt;}-staticinlineunsignedlong__phys_to_virt(unsignedlongx)+staticinlineunsignedlong__phys_to_virt(phys_addr_tx){unsignedlongt;__pv_stub(x,t,"sub",__PV_BITS_31_24);returnt;}
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
On Tue, Jul 24, 2012 at 11:55:30AM +0100, Cyril Chemparathy wrote:
On 7/24/2012 6:37 AM, Catalin Marinas wrote:
quoted
On Tue, Jul 24, 2012 at 02:09:05AM +0100, Cyril Chemparathy wrote:
quoted
This patch fixes up the types used when converting back and forth between
physical and virtual addresses.
Signed-off-by: Vitaly Andrianov <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
---
arch/arm/include/asm/memory.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
@@ -169,22 +169,27 @@ extern unsigned long __pv_phys_offset;:"=r"(to)\:"r"(from),"I"(type))-staticinlineunsignedlong__virt_to_phys(unsignedlongx)+staticinlinephys_addr_t__virt_to_phys(unsignedlongx){unsignedlongt;__pv_stub(x,t,"add",__PV_BITS_31_24);returnt;}-staticinlineunsignedlong__phys_to_virt(unsignedlongx)+staticinlineunsignedlong__phys_to_virt(phys_addr_tx){unsignedlongt;__pv_stub(x,t,"sub",__PV_BITS_31_24);returnt;}
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
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
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
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
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.
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
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 <redacted>
Signed-off-by: Cyril Chemparathy <redacted>
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.
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 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.
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:
quoted
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 <redacted>
Signed-off-by: Vitaly Andrianov <redacted>
---
arch/arm/include/asm/page.h | 7 ++++++-
arch/arm/include/asm/pgtable-3level.h | 6 +++---
2 files changed, 9 insertions(+), 4 deletions(-)
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