Commit fce2bc25 authored by Russell King's avatar Russell King
Browse files

Merge tag 'efi-arm-no-relocate-for-rmk' of...

Merge tag 'efi-arm-no-relocate-for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux into misc

Simplify EFI handover to decompressor

The EFI stub in the ARM kernel runs in the context of the firmware, which
means it usually runs with the caches and MMU on. Currently, we relocate
the zImage so it appears in the first 128 MiB, disable the MMU and caches
and invoke the decompressor via its ordinary entry point. However, since we
can pass the base of DRAM directly, there is no need to relocate the zImage,
which also means there is no need to disable and re-enable the caches and
create new page tables etc.

This also allows systems whose DRAM start address is not a round multiple
of 128 MB to decompress the kernel proper to the base of memory, ensuring
that all memory is usable at runtime.
parents 23189766 d0f9ca9b
Loading
Loading
Loading
Loading
+32 −47
Original line number Diff line number Diff line
@@ -287,28 +287,22 @@ not_angel:
		 */
		mov	r0, pc
		cmp	r0, r4
		ldrcc	r0, LC0+28
		ldrcc	r0, .Lheadroom
		addcc	r0, r0, pc
		cmpcc	r4, r0
		orrcc	r4, r4, #1		@ remember we skipped cache_on
		blcs	cache_on

restart:	adr	r0, LC0
		ldmia	r0, {r1, r2, r3, r6, r11, r12}
		ldr	sp, [r0, #24]

		/*
		 * We might be running at a different address.  We need
		 * to fix up various pointers.
		 */
		sub	r0, r0, r1		@ calculate the delta offset
		add	r6, r6, r0		@ _edata
restart:	adr	r0, LC1
		ldr	sp, [r0]
		ldr	r6, [r0, #4]
		add	sp, sp, r0
		add	r6, r6, r0

		get_inflated_image_size	r9, r10, lr

#ifndef CONFIG_ZBOOT_ROM
		/* malloc space is above the relocated stack (64k max) */
		add	sp, sp, r0
		add	r10, sp, #0x10000
#else
		/*
@@ -322,9 +316,6 @@ restart: adr r0, LC0
		mov	r5, #0			@ init dtb size to 0
#ifdef CONFIG_ARM_APPENDED_DTB
/*
 *   r0  = delta
 *   r2  = BSS start
 *   r3  = BSS end
 *   r4  = final kernel address (possibly with LSB set)
 *   r5  = appended dtb size (still unknown)
 *   r6  = _edata
@@ -332,8 +323,6 @@ restart: adr r0, LC0
 *   r8  = atags/device tree pointer
 *   r9  = size of decompressed image
 *   r10 = end of this image, including  bss/stack/malloc space if non XIP
 *   r11 = GOT start
 *   r12 = GOT end
 *   sp  = stack pointer
 *
 * if there are device trees (dtb) appended to zImage, advance r10 so that the
@@ -381,7 +370,6 @@ restart: adr r0, LC0
		/* temporarily relocate the stack past the DTB work space */
		add	sp, sp, r5

		stmfd	sp!, {r0-r3, ip, lr}
		mov	r0, r8
		mov	r1, r6
		mov	r2, r5
@@ -400,7 +388,6 @@ restart: adr r0, LC0
		mov	r2, r5
		bleq	atags_to_fdt

		ldmfd	sp!, {r0-r3, ip, lr}
		sub	sp, sp, r5
#endif

@@ -537,6 +524,10 @@ dtb_check_done:
		mov	pc, r0

wont_overwrite:
		adr	r0, LC0
		ldmia	r0, {r1, r2, r3, r11, r12}
		sub	r0, r0, r1		@ calculate the delta offset

/*
 * If delta is zero, we are running at the address we were linked at.
 *   r0  = delta
@@ -660,13 +651,18 @@ not_relocated: mov r0, #0
LC0:		.word	LC0			@ r1
		.word	__bss_start		@ r2
		.word	_end			@ r3
		.word	_edata			@ r6
		.word	_got_start		@ r11
		.word	_got_end		@ ip
		.word	.L_user_stack_end	@ sp
		.word	_end - restart + 16384 + 1024*1024
		.size	LC0, . - LC0

		.type	LC1, #object
LC1:		.word	.L_user_stack_end - LC1	@ sp
		.word	_edata - LC1		@ r6
		.size	LC1, . - LC1

.Lheadroom:
		.word	_end - restart + 16384 + 1024*1024

.Linflated_image_size_offset:
		.long	(input_data_end - 4) - .

@@ -1434,37 +1430,26 @@ reloc_code_end:

#ifdef CONFIG_EFI_STUB
ENTRY(efi_enter_kernel)
		mov	r7, r0				@ preserve image base
		mov	r4, r1				@ preserve DT pointer
		mov	r4, r0			@ preserve image base
		mov	r8, r1			@ preserve DT pointer

		mov	r0, r4				@ DT start
		add	r1, r4, r2			@ DT end
		bl	cache_clean_flush
		mrc	p15, 0, r0, c1, c0, 0	@ read SCTLR
		tst	r0, #0x1		@ MMU enabled?
		orreq	r4, r4, #1		@ set LSB if not

		mov	r0, r7				@ relocated zImage
		ldr	r1, =_edata			@ size of zImage
		add	r1, r1, r0			@ end of zImage
		mov	r0, r8			@ DT start
		add	r1, r8, r2		@ DT end
		bl	cache_clean_flush

		@ The PE/COFF loader might not have cleaned the code we are
		@ running beyond the PoU, and so calling cache_off below from
		@ inside the PE/COFF loader allocated region is unsafe unless
		@ we explicitly clean it to the PoC.
		adr	r0, call_cache_fn		@ region of code we will
		adr	r1, 0f				@ run with MMU off
		bl	cache_clean_flush
		bl	cache_off
		adr	r0, 0f			@ switch to our stack
		ldr	sp, [r0]
		add	sp, sp, r0

		@ Set parameters for booting zImage according to boot protocol
		@ put FDT address in r2, it was returned by efi_entry()
		@ r1 is the machine type, and r0 needs to be 0
		mov	r0, #0
		mov	r1, #0xFFFFFFFF
		mov	r2, r4
		add	r7, r7, #(__efi_start - start)
		mov	pc, r7				@ no mode switch
		mov	r5, #0			@ appended DTB size
		mov	r7, #0xFFFFFFFF		@ machine ID
		b	wont_overwrite
ENDPROC(efi_enter_kernel)
0:
0:		.long	.L_user_stack_end - .
#endif

		.align
+5 −0
Original line number Diff line number Diff line
@@ -63,9 +63,11 @@ SECTIONS
  _etext = .;

  .got.plt		: { *(.got.plt) }
#ifndef CONFIG_EFI_STUB
  _got_start = .;
  .got			: { *(.got) }
  _got_end = .;
#endif

  /* ensure the zImage file size is always a multiple of 64 bits */
  /* (without a dummy byte, ld just ignores the empty section) */
@@ -74,6 +76,9 @@ SECTIONS
#ifdef CONFIG_EFI_STUB
  .data : ALIGN(4096) {
    __pecoff_data_start = .;
    _got_start = .;
    *(.got)
    _got_end = .;
    /*
     * The EFI stub always executes from RAM, and runs strictly before the
     * decompressor, so we can make an exception for its r/w data, and keep it
+6 −39
Original line number Diff line number Diff line
@@ -199,14 +199,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
	unsigned long kernel_base;
	efi_status_t status;

	/*
	 * Verify that the DRAM base address is compatible with the ARM
	 * boot protocol, which determines the base of DRAM by masking
	 * off the low 27 bits of the address at which the zImage is
	 * loaded. These assumptions are made by the decompressor,
	 * before any memory map is available.
	 */
	kernel_base = round_up(dram_base, SZ_128M);
	/* use a 16 MiB aligned base for the decompressed kernel */
	kernel_base = round_up(dram_base, SZ_16M) + TEXT_OFFSET;

	/*
	 * Note that some platforms (notably, the Raspberry Pi 2) put
@@ -215,41 +209,14 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
	 * base of the kernel image is only partially used at the moment.
	 * (Up to 5 pages are used for the swapper page tables)
	 */
	kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE;

	status = reserve_kernel_base(kernel_base, reserve_addr, reserve_size);
	status = reserve_kernel_base(kernel_base - 5 * PAGE_SIZE, reserve_addr,
				     reserve_size);
	if (status != EFI_SUCCESS) {
		pr_efi_err("Unable to allocate memory for uncompressed kernel.\n");
		return status;
	}

	/*
	 * Relocate the zImage, so that it appears in the lowest 128 MB
	 * memory window.
	 */
	*image_addr = (unsigned long)image->image_base;
	*image_size = image->image_size;
	status = efi_relocate_kernel(image_addr, *image_size, *image_size,
				     kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0);
	if (status != EFI_SUCCESS) {
		pr_efi_err("Failed to relocate kernel.\n");
		efi_free(*reserve_size, *reserve_addr);
		*reserve_size = 0;
		return status;
	}

	/*
	 * Check to see if we were able to allocate memory low enough
	 * in memory. The kernel determines the base of DRAM from the
	 * address at which the zImage is loaded.
	 */
	if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
		pr_efi_err("Failed to relocate kernel, no low memory available.\n");
		efi_free(*reserve_size, *reserve_addr);
		*reserve_size = 0;
		efi_free(*image_size, *image_addr);
	*image_addr = kernel_base;
	*image_size = 0;
		return EFI_LOAD_ERROR;
	}
	return EFI_SUCCESS;
}