Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61bd93ce authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Catalin Marinas
Browse files

arm64: use fixmap region for permanent FDT mapping



Currently, the FDT blob needs to be in the same 512 MB region as
the kernel, so that it can be mapped into the kernel virtual memory
space very early on using a minimal set of statically allocated
translation tables.

Now that we have early fixmap support, we can relax this restriction,
by moving the permanent FDT mapping to the fixmap region instead.
This way, the FDT blob may be anywhere in memory.

This also moves the vetting of the FDT to mmu.c, since the early
init code in head.S does not handle mapping of the FDT anymore.
At the same time, fix up some comments in head.S that have gone stale.

Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Tested-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 24bbd929
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -45,11 +45,13 @@ sees fit.)

Requirement: MANDATORY

The device tree blob (dtb) must be placed on an 8-byte boundary within
the first 512 megabytes from the start of the kernel image and must not
cross a 2-megabyte boundary. This is to allow the kernel to map the
blob using a single section mapping in the initial page tables.
The device tree blob (dtb) must be placed on an 8-byte boundary and must
not exceed 2 megabytes in size. Since the dtb will be mapped cacheable
using blocks of up to 2 megabytes in size, it must not be placed within
any 2M region which must be mapped with any specific attributes.

NOTE: versions prior to v4.2 also require that the DTB be placed within
the 512 MB region starting at text_offset bytes below the kernel Image.

3. Decompress the kernel image
------------------------------
+14 −0
Original line number Diff line number Diff line

#ifndef __ASM_BOOT_H
#define __ASM_BOOT_H

#include <asm/sizes.h>

/*
 * arm64 requires the DTB to be 8 byte aligned and
 * not exceed 2MB in size.
 */
#define MIN_FDT_ALIGN		8
#define MAX_FDT_SIZE		SZ_2M

#endif
+15 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

#ifndef __ASSEMBLY__
#include <linux/kernel.h>
#include <asm/boot.h>
#include <asm/page.h>

/*
@@ -32,6 +33,20 @@
 */
enum fixed_addresses {
	FIX_HOLE,

	/*
	 * Reserve a virtual window for the FDT that is 2 MB larger than the
	 * maximum supported size, and put it at the top of the fixmap region.
	 * The additional space ensures that any FDT that does not exceed
	 * MAX_FDT_SIZE can be mapped regardless of whether it crosses any
	 * 2 MB alignment boundaries.
	 *
	 * Keep this at the top so it remains 2 MB aligned.
	 */
#define FIX_FDT_SIZE		(MAX_FDT_SIZE + SZ_2M)
	FIX_FDT_END,
	FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,

	FIX_EARLYCON_MEM_BASE,
	FIX_TEXT_POKE0,
	__end_of_permanent_fixed_addresses,
+1 −0
Original line number Diff line number Diff line
@@ -34,5 +34,6 @@ extern void init_mem_pgprot(void);
extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
			       unsigned long virt, phys_addr_t size,
			       pgprot_t prot);
extern void *fixmap_remap_fdt(phys_addr_t dt_phys);

#endif
+1 −38
Original line number Diff line number Diff line
@@ -237,8 +237,6 @@ ENTRY(stext)
	bl	el2_setup			// Drop to EL1, w20=cpu_boot_mode
	adrp	x24, __PHYS_OFFSET
	bl	set_cpu_boot_mode_flag

	bl	__vet_fdt
	bl	__create_page_tables		// x25=TTBR0, x26=TTBR1
	/*
	 * The following calls CPU setup code, see arch/arm64/mm/proc.S for
@@ -269,24 +267,6 @@ preserve_boot_args:
	b	__inval_cache_range		// tail call
ENDPROC(preserve_boot_args)

/*
 * Determine validity of the x21 FDT pointer.
 * The dtb must be 8-byte aligned and live in the first 512M of memory.
 */
__vet_fdt:
	tst	x21, #0x7
	b.ne	1f
	cmp	x21, x24
	b.lt	1f
	mov	x0, #(1 << 29)
	add	x0, x0, x24
	cmp	x21, x0
	b.ge	1f
	ret
1:
	mov	x21, #0
	ret
ENDPROC(__vet_fdt)
/*
 * Macro to create a table entry to the next page.
 *
@@ -348,8 +328,7 @@ ENDPROC(__vet_fdt)
 * required to get the kernel running. The following sections are required:
 *   - identity mapping to enable the MMU (low address, TTBR0)
 *   - first few MB of the kernel linear mapping to jump to once the MMU has
 *     been enabled, including the FDT blob (TTBR1)
 *   - pgd entry for fixed mappings (TTBR1)
 *     been enabled
 */
__create_page_tables:
	adrp	x25, idmap_pg_dir
@@ -438,22 +417,6 @@ __create_page_tables:
	mov	x3, x24				// phys offset
	create_block_map x0, x7, x3, x5, x6

	/*
	 * Map the FDT blob (maximum 2MB; must be within 512MB of
	 * PHYS_OFFSET).
	 */
	mov	x3, x21				// FDT phys address
	and	x3, x3, #~((1 << 21) - 1)	// 2MB aligned
	mov	x6, #PAGE_OFFSET
	sub	x5, x3, x24			// subtract PHYS_OFFSET
	tst	x5, #~((1 << 29) - 1)		// within 512MB?
	csel	x21, xzr, x21, ne		// zero the FDT pointer
	b.ne	1f
	add	x5, x5, x6			// __va(FDT blob)
	add	x6, x5, #1 << 21		// 2MB for the FDT blob
	sub	x6, x6, #1			// inclusive range
	create_block_map x0, x7, x3, x5, x6
1:
	/*
	 * Since the page tables have been populated with non-cacheable
	 * accesses (MMU disabled), invalidate the idmap and swapper page
Loading