[PATCH] ARM: realview: basic device tree implementation
Arnd Bergmann
arnd at arndb.de
Wed Mar 26 13:09:39 EDT 2014
On Wednesday 26 March 2014 11:56:30 Arnd Bergmann wrote:
> > + /*
> > + * Generic RealView fixup
> > + * Most RealView platforms have 512MB contiguous RAM at 0x70000000.
> > + * Half of this is mirrored at 0.
> > + */
> > + else {
> > +#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
> > + meminfo->bank[0].start = 0x70000000;
> > + meminfo->bank[0].size = SZ_512M;
> > + meminfo->nr_banks = 1;
> > +#else
> > + meminfo->bank[0].start = 0;
> > + meminfo->bank[0].size = SZ_256M;
> > + meminfo->nr_banks = 1;
> > +#endif
> > + }
> > +}
>
> And this one is where it gets tricky. We don't have a good way
> to describe memory aliases in DT, but we need the start of memory
> to match PHYS_OFFSET if CONFIG_SPARSEMEM is set (which implies
> !CONFIG_REALVIEW_HIGH_PHYS_OFFSET), or if we are running a no-MMU
> kernel. I have to think about this some more.
>
I've thought about it some more. We can actually get rid of the
CONFIG_REALVIEW_HIGH_PHYS_OFFSET option entirely for any case except
CONFIG_XIP_KERNEL by using ARM_PATCH_PHYS_VIRT and relying on the
ATAGS or DT to pass the correct memory location. Unfortunately,
I don't know if the ATAGS are actually correct in common boot loaders,
since the kernel has been overriding them for ages.
With SPARSEMEM enabled, we already depend on REALVIEW_HIGH_PHYS_OFFSET
being disabled, and we also use ARM_PATCH_PHYS_VIRT by default (it
is not disabled in realview_defconfig).
The dependencies are really:
* The value of PHYS_OFFSET must match the address to which the kernel
is loaded at boot time (currently enforced using 'make uImage').
* We could use SPARSEMEM in order to use all 512MB of RAM on
realview-eb/pb11mp/pb-a8, but this is prevented by the definition
of __phys_to_virt/__virt_to_phys, since it puts the 0x20000000
physical memory segment into the middle! This is in theory fixable,
but I'd rather not add more hacks on top. I don't see anything that
prevents us from using SPARSEMEM on older realview machines with
PHYS_OFFSET=0.
* The board files always ignore the memory passed in the ATAGS and
set what they think is correct. I consider this a bad idea,
in particular because it prevents us from using the -m option
in qemu. We should not do this with DT. If we just trust the
DT to contain correct data, we don't actually need the
REALVIEW_HIGH_PHYS_OFFSET setting,
Catalin originally added the sparsemem hack. I asked him today about
it, and he also thinks that sparsemem without the hack should work,
as long as there is highmem support. I think we can either do away
with it entirely, or use the patch below to keep it alive.
I'd prefer not to add any memory location fixup to the realview-dt
implementation, but it seems hard to kill it off for the ATAGS
based board files, in particular because the information passed
by qemu seems to be wrong more often than not (at least if I read
the qemu right), and we never relied on it in the past. We might
be able to make that a compile-time or boot-time option though.
Arnd
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7c35c4d..caf9bd3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -236,7 +236,6 @@ config ARM_PATCH_PHYS_VIRT
bool "Patch physical to virtual translations at runtime" if BROKEN_MULTIPLATFORM
default y
depends on !XIP_KERNEL && MMU
- depends on !ARCH_REALVIEW || !SPARSEMEM
help
Patch phys-to-virt and virt-to-phys translation functions at
boot and module load time according to the position of the
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 297e214..8a92dbf 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -121,7 +121,7 @@ config MACH_REALVIEW_PBA8
config MACH_REALVIEW_PBX
bool "Support RealView(R) Platform Baseboard Explore"
- select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
+ select ARCH_SPARSEMEM_ENABLE if CPU_V7
select ARM_GIC
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
@@ -165,7 +165,7 @@ config MACH_REALVIEW_AUTO
config REALVIEW_HIGH_PHYS_OFFSET
bool "High physical base address for the RealView platform"
- depends on MMU && !MACH_REALVIEW_PB1176
+ depends on MMU && !MACH_REALVIEW_PB1176 && !ARM_PATCH_PHYS_VIRT
default y
help
RealView boards other than PB1176 have the RAM available at
@@ -175,4 +175,21 @@ config REALVIEW_HIGH_PHYS_OFFSET
offset. On the PBX board, disabling this option allows 1GB of
RAM to be used with SPARSEMEM.
+config REALVIEW_PBX_SPARSEMEM_HACK
+ bool "Hack to avoid highmem on Realview-PBX"
+ depends on SPARSEMEM && MMU
+ depends on MACH_REALVIEW_PBX
+ depends on !(MACH_REALVIEW_EB || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBA8 || MACH_REALVIEW_DT)
+ depends on !REALVIEW_HIGH_PHYS_OFFSET
+ depends on !ARM_PATCH_PHYS_VIRT
+ help
+ Realview-PBX uses noncontiguous memory that is spread over
+ more than 2GB of physical address space, which means that in
+ order to access it, we have to either enable HIGHMEM or
+ VMSPLIT_1G, both of which come with a performance impact.
+ As a third alternative, this rearranges the kernel virtual
+ memory space to cover all the discontiguous memory on
+ Realview PBX, with the main cost of breaking support for
+ any other hardware.
+
endmenu
diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h
index db09170..2b95178 100644
--- a/arch/arm/mach-realview/include/mach/memory.h
+++ b/arch/arm/mach-realview/include/mach/memory.h
@@ -31,6 +31,11 @@
#ifdef CONFIG_SPARSEMEM
+/* these can be moved to arm/memory.h when we get to support multiplatform */
+#define MAX_PHYSMEM_BITS 32
+#define SECTION_SIZE_BITS 28
+
+#ifdef CONFIG_REALVIEW_PBX_SPARSEMEM_HACK
/*
* Sparsemem definitions for RealView PBX.
*
@@ -45,13 +50,6 @@
* 512MB @ 0x20000000 -> PAGE_OFFSET + 0x10000000
* 256MB @ 0x80000000 -> PAGE_OFFSET + 0x30000000
*/
-#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
-#error "SPARSEMEM not available with REALVIEW_HIGH_PHYS_OFFSET"
-#endif
-
-#define MAX_PHYSMEM_BITS 32
-#define SECTION_SIZE_BITS 28
-
/* bank page offsets */
#define PAGE_OFFSET1 (PAGE_OFFSET + 0x10000000)
#define PAGE_OFFSET2 (PAGE_OFFSET + 0x30000000)
@@ -68,6 +66,8 @@
(virt) >= PAGE_OFFSET1 ? (virt) - PAGE_OFFSET1 + 0x20000000 : \
(virt) - PAGE_OFFSET)
+#endif
+
#endif /* CONFIG_SPARSEMEM */
#endif
More information about the linux-arm-kernel
mailing list