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) static inline bool mmap_has_headroom(unsigned long buff_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 				     unsigned long map_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 				     unsigned long desc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 	unsigned long slack = buff_size - map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * efi_get_memory_map() - get memory map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * @map:	on return pointer to memory map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Retrieve the UEFI memory map. The allocated memory leaves room for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * Return:	status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) efi_status_t efi_get_memory_map(struct efi_boot_memmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	efi_memory_desc_t *m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	efi_status_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	unsigned long key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	u32 desc_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	*map->desc_size =	sizeof(*m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	*map->map_size =	*map->desc_size * 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	*map->buff_size =	*map->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			     *map->map_size, (void **)&m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (status != EFI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	*map->desc_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	status = efi_bs_call(get_memory_map, map->map_size, m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			     &key, map->desc_size, &desc_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	if (status == EFI_BUFFER_TOO_SMALL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	    !mmap_has_headroom(*map->buff_size, *map->map_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 			       *map->desc_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		efi_bs_call(free_pool, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		 * Make sure there is some entries of headroom so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		 * buffer can be reused for a new map after allocations are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		 * no longer permitted.  Its unlikely that the map will grow to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		 * exceed this headroom once we are ready to trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		 * ExitBootServices()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		*map->map_size += *map->desc_size * EFI_MMAP_NR_SLACK_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		*map->buff_size = *map->map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	if (status == EFI_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		if (map->key_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 			*map->key_ptr = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		if (map->desc_ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			*map->desc_ver = desc_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		efi_bs_call(free_pool, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	*map->map = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * efi_allocate_pages() - Allocate memory pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * @size:	minimum number of bytes to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * @addr:	On return the address of the first allocated page. The first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *		allocated page has alignment EFI_ALLOC_ALIGN which is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *		architecture dependent multiple of the page size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * @max:	the address that the last allocated memory page shall not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *		exceed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * to EFI_ALLOC_ALIGN. The last allocated page will not exceed the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * given by @max.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * Return:	status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 				unsigned long max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	efi_physical_addr_t alloc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	efi_status_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (EFI_ALLOC_ALIGN > EFI_PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		return efi_allocate_pages_aligned(size, addr, max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 						  EFI_ALLOC_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	alloc_addr = ALIGN_DOWN(max + 1, EFI_ALLOC_ALIGN) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			     EFI_LOADER_DATA, DIV_ROUND_UP(size, EFI_PAGE_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			     &alloc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (status != EFI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	*addr = alloc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	return EFI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * efi_free() - free memory pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * @size:	size of the memory area to free in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * @addr:	start of the memory area to free (must be EFI_PAGE_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  *		aligned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * @size is rounded up to a multiple of EFI_ALLOC_ALIGN which is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * architecture specific multiple of EFI_PAGE_SIZE. So this function should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * only be used to return pages allocated with efi_allocate_pages() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * efi_low_alloc_above().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void efi_free(unsigned long size, unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	unsigned long nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (!size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	efi_bs_call(free_pages, addr, nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }