Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <asm/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include "efistub.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * efi_low_alloc_above() - allocate pages at or above given address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * @size:	size of the memory area to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * @align:	minimum alignment of the allocated memory area. It should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *		a power of two.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * @addr:	on exit the address of the allocated memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * @min:	minimum address to used for the memory allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Allocate at the lowest possible address that is not below @min as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * EFI_LOADER_DATA. The allocated pages are aligned according to @align but at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * least EFI_ALLOC_ALIGN. The first allocated page will not below the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * given by @min.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Return:	status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 				 unsigned long *addr, unsigned long min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	unsigned long map_size, desc_size, buff_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	efi_memory_desc_t *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	efi_status_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	unsigned long nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct efi_boot_memmap boot_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	boot_map.map		= &map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	boot_map.map_size	= &map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	boot_map.desc_size	= &desc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	boot_map.desc_ver	= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	boot_map.key_ptr	= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	boot_map.buff_size	= &buff_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	status = efi_get_memory_map(&boot_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	if (status != EFI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	 * Enforce minimum alignment that EFI or Linux requires when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	 * requesting a specific address.  We are doing page-based (or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	 * larger) allocations, and both the address and size must meet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	 * alignment constraints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	if (align < EFI_ALLOC_ALIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		align = EFI_ALLOC_ALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	size = round_up(size, EFI_ALLOC_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	nr_pages = size / EFI_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	for (i = 0; i < map_size / desc_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		efi_memory_desc_t *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		unsigned long m = (unsigned long)map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		u64 start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		desc = efi_early_memdesc_ptr(m, desc_size, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		if (desc->type != EFI_CONVENTIONAL_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		if (efi_soft_reserve_enabled() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		    (desc->attribute & EFI_MEMORY_SP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		if (desc->num_pages < nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		start = desc->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		end = start + desc->num_pages * EFI_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		if (start < min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			start = min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		start = round_up(start, align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		if ((start + size) > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				     EFI_LOADER_DATA, nr_pages, &start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		if (status == EFI_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			*addr = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (i == map_size / desc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		status = EFI_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	efi_bs_call(free_pool, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * efi_relocate_kernel() - copy memory area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * @image_addr:		pointer to address of memory area to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * @image_size:		size of memory area to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * @alloc_size:		minimum size of memory to allocate, must be greater or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *			equal to image_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * @preferred_addr:	preferred target address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * @alignment:		minimum alignment of the allocated memory area. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  *			should be a power of two.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * @min_addr:		minimum target address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * Copy a memory area to a newly allocated memory area aligned according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * to @alignment but at least EFI_ALLOC_ALIGN. If the preferred address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * is not available, the allocated address will not be below @min_addr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * On exit, @image_addr is updated to the target copy address that was used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * This function is used to copy the Linux kernel verbatim. It does not apply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * any relocation changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * Return:		status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) efi_status_t efi_relocate_kernel(unsigned long *image_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 				 unsigned long image_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 				 unsigned long alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 				 unsigned long preferred_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 				 unsigned long alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				 unsigned long min_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	unsigned long cur_image_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	unsigned long new_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	efi_status_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	unsigned long nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	efi_physical_addr_t efi_addr = preferred_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (!image_addr || !image_size || !alloc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		return EFI_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	if (alloc_size < image_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		return EFI_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	cur_image_addr = *image_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	 * The EFI firmware loader could have placed the kernel image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * anywhere in memory, but the kernel has restrictions on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * max physical address it can run at.  Some architectures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 * also have a preferred address, so first try to relocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	 * to the preferred address.  If that fails, allocate as low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	 * as possible while respecting the required alignment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			     EFI_LOADER_DATA, nr_pages, &efi_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	new_addr = efi_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	 * If preferred address allocation failed allocate as low as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	 * possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (status != EFI_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		status = efi_low_alloc_above(alloc_size, alignment, &new_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 					     min_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (status != EFI_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		efi_err("Failed to allocate usable memory for kernel.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	 * We know source/dest won't overlap since both memory ranges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	 * have been allocated by UEFI, so we can safely use memcpy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	/* Return the new address of the relocated image. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	*image_addr = new_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }