If we cannot relocate the kernel Image to its preferred offset of base of DRAM plus TEXT_OFFSET, instead relocate it to the lowest available 2 MB boundary plus TEXT_OFFSET. We may lose a bit of memory at the low end, but we can still proceed normally otherwise. Acked-by: Mark Salter <msalter@redhat.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Leif Lindholm <leif.lindholm@linaro.org> Tested-by: Leif Lindholm <leif.lindholm@linaro.org> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
		
			
				
	
	
		
			45 lines
		
	
	
	
		
			1.4 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			45 lines
		
	
	
	
		
			1.4 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2013, 2014 Linaro Ltd;  <roy.franz@linaro.org>
 | 
						|
 *
 | 
						|
 * This file implements the EFI boot stub for the arm64 kernel.
 | 
						|
 * Adapted from ARM version by Mark Salter <msalter@redhat.com>
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU General Public License version 2 as
 | 
						|
 * published by the Free Software Foundation.
 | 
						|
 *
 | 
						|
 */
 | 
						|
#include <linux/efi.h>
 | 
						|
#include <asm/efi.h>
 | 
						|
#include <asm/sections.h>
 | 
						|
 | 
						|
efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
 | 
						|
				 unsigned long *image_addr,
 | 
						|
				 unsigned long *image_size,
 | 
						|
				 unsigned long *reserve_addr,
 | 
						|
				 unsigned long *reserve_size,
 | 
						|
				 unsigned long dram_base,
 | 
						|
				 efi_loaded_image_t *image)
 | 
						|
{
 | 
						|
	efi_status_t status;
 | 
						|
	unsigned long kernel_size, kernel_memsize = 0;
 | 
						|
 | 
						|
	/* Relocate the image, if required. */
 | 
						|
	kernel_size = _edata - _text;
 | 
						|
	if (*image_addr != (dram_base + TEXT_OFFSET)) {
 | 
						|
		kernel_memsize = kernel_size + (_end - _edata);
 | 
						|
		status = efi_low_alloc(sys_table, kernel_memsize + TEXT_OFFSET,
 | 
						|
				       SZ_2M, reserve_addr);
 | 
						|
		if (status != EFI_SUCCESS) {
 | 
						|
			pr_efi_err(sys_table, "Failed to relocate kernel\n");
 | 
						|
			return status;
 | 
						|
		}
 | 
						|
		memcpy((void *)*reserve_addr + TEXT_OFFSET, (void *)*image_addr,
 | 
						|
		       kernel_size);
 | 
						|
		*image_addr = *reserve_addr + TEXT_OFFSET;
 | 
						|
		*reserve_size = kernel_memsize + TEXT_OFFSET;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	return EFI_SUCCESS;
 | 
						|
}
 |