Commit 7a1be318 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Russell King
Browse files

ARM: 9012/1: move device tree mapping out of linear region



On ARM, setting up the linear region is tricky, given the constraints
around placement and alignment of the memblocks, and how the kernel
itself as well as the DT are placed in physical memory.

Let's simplify matters a bit, by moving the device tree mapping to the
top of the address space, right between the end of the vmalloc region
and the start of the the fixmap region, and create a read-only mapping
for it that is independent of the size of the linear region, and how it
is organized.

Since this region was formerly used as a guard region, which will now be
populated fully on LPAE builds by this read-only mapping (which will
still be able to function as a guard region for stray writes), bump the
start of the [underutilized] fixmap region by 512 KB as well, to ensure
that there is always a proper guard region here. Doing so still leaves
ample room for the fixmap space, even with NR_CPUS set to its maximum
value of 32.

Tested-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarNicolas Pitre <nico@fluxnic.net>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent e9a2f8b5
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -45,9 +45,14 @@ fffe8000 fffeffff DTCM mapping area for platforms with
fffe0000	fffe7fff	ITCM mapping area for platforms with
				ITCM mounted inside the CPU.

ffc00000	ffefffff	Fixmap mapping region.  Addresses provided
ffc80000	ffefffff	Fixmap mapping region.  Addresses provided
				by fix_to_virt() will be located here.

ffc00000	ffc7ffff	Guard region

ff800000	ffbfffff	Permanent, fixed read-only mapping of the
				firmware provided DT blob

fee00000	feffffff	Mapping of PCI I/O space. This is a static
				mapping within the vmalloc space.

+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H

#define FIXADDR_START		0xffc00000UL
#define FIXADDR_START		0xffc80000UL
#define FIXADDR_END		0xfff00000UL
#define FIXADDR_TOP		(FIXADDR_END - PAGE_SIZE)

+5 −0
Original line number Diff line number Diff line
@@ -67,6 +67,10 @@
 */
#define XIP_VIRT_ADDR(physaddr)  (MODULES_VADDR + ((physaddr) & 0x000fffff))

#define FDT_FIXED_BASE		UL(0xff800000)
#define FDT_FIXED_SIZE		(2 * PMD_SIZE)
#define FDT_VIRT_ADDR(physaddr)	((void *)(FDT_FIXED_BASE | (physaddr) % PMD_SIZE))

#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
/*
 * Allow 16MB-aligned ioremap pages
@@ -107,6 +111,7 @@ extern unsigned long vectors_base;
#define MODULES_VADDR		PAGE_OFFSET

#define XIP_VIRT_ADDR(physaddr)  (physaddr)
#define FDT_VIRT_ADDR(physaddr)  ((void *)(physaddr))

#endif /* !CONFIG_MMU */

+2 −3
Original line number Diff line number Diff line
@@ -275,9 +275,8 @@ __create_page_tables:
	 */
	mov	r0, r2, lsr #SECTION_SHIFT
	movs	r0, r0, lsl #SECTION_SHIFT
	subne	r3, r0, r8
	addne	r3, r3, #PAGE_OFFSET
	addne	r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
	ldrne	r3, =FDT_FIXED_BASE >> (SECTION_SHIFT - PMD_ORDER)
	addne	r3, r3, r4
	orrne	r6, r7, r0
	strne	r6, [r3], #1 << PMD_ORDER
	addne	r6, r6, #1 << SECTION_SHIFT
+8 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/of_platform.h>
#include <linux/init.h>
#include <linux/kexec.h>
#include <linux/libfdt.h>
#include <linux/of_fdt.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>
@@ -89,7 +90,6 @@ unsigned int cacheid __read_mostly;
EXPORT_SYMBOL(cacheid);

unsigned int __atags_pointer __initdata;
void *atags_vaddr __initdata;

unsigned int system_rev;
EXPORT_SYMBOL(system_rev);
@@ -1083,13 +1083,18 @@ void __init hyp_mode_check(void)
void __init setup_arch(char **cmdline_p)
{
	const struct machine_desc *mdesc = NULL;
	void *atags_vaddr = NULL;

	if (__atags_pointer)
		atags_vaddr = phys_to_virt(__atags_pointer);
		atags_vaddr = FDT_VIRT_ADDR(__atags_pointer);

	setup_processor();
	if (atags_vaddr)
	if (atags_vaddr) {
		mdesc = setup_machine_fdt(atags_vaddr);
		if (mdesc)
			memblock_reserve(__atags_pointer,
					 fdt_totalsize(atags_vaddr));
	}
	if (!mdesc)
		mdesc = setup_machine_tags(atags_vaddr, __machine_arch_type);
	if (!mdesc) {
Loading