1 /* 2 * EFI application memory management 3 * 4 * Copyright (c) 2016 Alexander Graf 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 /* #define DEBUG_EFI */ 10 11 #include <common.h> 12 #include <efi_loader.h> 13 #include <malloc.h> 14 #include <asm/global_data.h> 15 #include <libfdt_env.h> 16 #include <linux/list_sort.h> 17 #include <inttypes.h> 18 #include <watchdog.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 struct efi_mem_list { 23 struct list_head link; 24 struct efi_mem_desc desc; 25 }; 26 27 /* This list contains all memory map items */ 28 LIST_HEAD(efi_mem); 29 30 /* 31 * Sorts the memory list from highest address to lowest address 32 * 33 * When allocating memory we should always start from the highest 34 * address chunk, so sort the memory list such that the first list 35 * iterator gets the highest address and goes lower from there. 36 */ 37 static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b) 38 { 39 struct efi_mem_list *mema = list_entry(a, struct efi_mem_list, link); 40 struct efi_mem_list *memb = list_entry(b, struct efi_mem_list, link); 41 42 if (mema->desc.physical_start == memb->desc.physical_start) 43 return 0; 44 else if (mema->desc.physical_start < memb->desc.physical_start) 45 return 1; 46 else 47 return -1; 48 } 49 50 static void efi_mem_sort(void) 51 { 52 list_sort(NULL, &efi_mem, efi_mem_cmp); 53 } 54 55 /* 56 * Unmaps all memory occupied by the carve_desc region from the 57 * list entry pointed to by map. 58 * 59 * Returns 1 if carving was performed or 0 if the regions don't overlap. 60 * Returns -1 if it would affect non-RAM regions but overlap_only_ram is set. 61 * Carving is only guaranteed to complete when all regions return 0. 62 */ 63 static int efi_mem_carve_out(struct efi_mem_list *map, 64 struct efi_mem_desc *carve_desc, 65 bool overlap_only_ram) 66 { 67 struct efi_mem_list *newmap; 68 struct efi_mem_desc *map_desc = &map->desc; 69 uint64_t map_start = map_desc->physical_start; 70 uint64_t map_end = map_start + (map_desc->num_pages << EFI_PAGE_SHIFT); 71 uint64_t carve_start = carve_desc->physical_start; 72 uint64_t carve_end = carve_start + 73 (carve_desc->num_pages << EFI_PAGE_SHIFT); 74 75 /* check whether we're overlapping */ 76 if ((carve_end <= map_start) || (carve_start >= map_end)) 77 return 0; 78 79 /* We're overlapping with non-RAM, warn the caller if desired */ 80 if (overlap_only_ram && (map_desc->type != EFI_CONVENTIONAL_MEMORY)) 81 return -1; 82 83 /* Sanitize carve_start and carve_end to lie within our bounds */ 84 carve_start = max(carve_start, map_start); 85 carve_end = min(carve_end, map_end); 86 87 /* Carving at the beginning of our map? Just move it! */ 88 if (carve_start == map_start) { 89 if (map_end == carve_end) { 90 /* Full overlap, just remove map */ 91 list_del(&map->link); 92 } 93 94 map_desc->physical_start = carve_end; 95 map_desc->num_pages = (map_end - carve_end) >> EFI_PAGE_SHIFT; 96 return 1; 97 } 98 99 /* 100 * Overlapping maps, just split the list map at carve_start, 101 * it will get moved or removed in the next iteration. 102 * 103 * [ map_desc |__carve_start__| newmap ] 104 */ 105 106 /* Create a new map from [ carve_start ... map_end ] */ 107 newmap = calloc(1, sizeof(*newmap)); 108 newmap->desc = map->desc; 109 newmap->desc.physical_start = carve_start; 110 newmap->desc.num_pages = (map_end - carve_start) >> EFI_PAGE_SHIFT; 111 list_add_tail(&newmap->link, &efi_mem); 112 113 /* Shrink the map to [ map_start ... carve_start ] */ 114 map_desc->num_pages = (carve_start - map_start) >> EFI_PAGE_SHIFT; 115 116 return 1; 117 } 118 119 uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, 120 bool overlap_only_ram) 121 { 122 struct list_head *lhandle; 123 struct efi_mem_list *newlist; 124 bool do_carving; 125 126 if (!pages) 127 return start; 128 129 newlist = calloc(1, sizeof(*newlist)); 130 newlist->desc.type = memory_type; 131 newlist->desc.physical_start = start; 132 newlist->desc.virtual_start = start; 133 newlist->desc.num_pages = pages; 134 135 switch (memory_type) { 136 case EFI_RUNTIME_SERVICES_CODE: 137 case EFI_RUNTIME_SERVICES_DATA: 138 newlist->desc.attribute = (1 << EFI_MEMORY_WB_SHIFT) | 139 (1ULL << EFI_MEMORY_RUNTIME_SHIFT); 140 break; 141 case EFI_MMAP_IO: 142 newlist->desc.attribute = 1ULL << EFI_MEMORY_RUNTIME_SHIFT; 143 break; 144 default: 145 newlist->desc.attribute = 1 << EFI_MEMORY_WB_SHIFT; 146 break; 147 } 148 149 /* Add our new map */ 150 do { 151 do_carving = false; 152 list_for_each(lhandle, &efi_mem) { 153 struct efi_mem_list *lmem; 154 int r; 155 156 lmem = list_entry(lhandle, struct efi_mem_list, link); 157 r = efi_mem_carve_out(lmem, &newlist->desc, 158 overlap_only_ram); 159 if (r < 0) { 160 return 0; 161 } else if (r) { 162 do_carving = true; 163 break; 164 } 165 } 166 } while (do_carving); 167 168 /* Add our new map */ 169 list_add_tail(&newlist->link, &efi_mem); 170 171 /* And make sure memory is listed in descending order */ 172 efi_mem_sort(); 173 174 return start; 175 } 176 177 static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) 178 { 179 struct list_head *lhandle; 180 181 list_for_each(lhandle, &efi_mem) { 182 struct efi_mem_list *lmem = list_entry(lhandle, 183 struct efi_mem_list, link); 184 struct efi_mem_desc *desc = &lmem->desc; 185 uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT; 186 uint64_t desc_end = desc->physical_start + desc_len; 187 uint64_t curmax = min(max_addr, desc_end); 188 uint64_t ret = curmax - len; 189 190 /* We only take memory from free RAM */ 191 if (desc->type != EFI_CONVENTIONAL_MEMORY) 192 continue; 193 194 /* Out of bounds for max_addr */ 195 if ((ret + len) > max_addr) 196 continue; 197 198 /* Out of bounds for upper map limit */ 199 if ((ret + len) > desc_end) 200 continue; 201 202 /* Out of bounds for lower map limit */ 203 if (ret < desc->physical_start) 204 continue; 205 206 /* Return the highest address in this map within bounds */ 207 return ret; 208 } 209 210 return 0; 211 } 212 213 efi_status_t efi_allocate_pages(int type, int memory_type, 214 unsigned long pages, uint64_t *memory) 215 { 216 u64 len = pages << EFI_PAGE_SHIFT; 217 efi_status_t r = EFI_SUCCESS; 218 uint64_t addr; 219 220 switch (type) { 221 case 0: 222 /* Any page */ 223 addr = efi_find_free_memory(len, gd->start_addr_sp); 224 if (!addr) { 225 r = EFI_NOT_FOUND; 226 break; 227 } 228 break; 229 case 1: 230 /* Max address */ 231 addr = efi_find_free_memory(len, *memory); 232 if (!addr) { 233 r = EFI_NOT_FOUND; 234 break; 235 } 236 break; 237 case 2: 238 /* Exact address, reserve it. The addr is already in *memory. */ 239 addr = *memory; 240 break; 241 default: 242 /* UEFI doesn't specify other allocation types */ 243 r = EFI_INVALID_PARAMETER; 244 break; 245 } 246 247 if (r == EFI_SUCCESS) { 248 uint64_t ret; 249 250 /* Reserve that map in our memory maps */ 251 ret = efi_add_memory_map(addr, pages, memory_type, true); 252 if (ret == addr) { 253 *memory = addr; 254 } else { 255 /* Map would overlap, bail out */ 256 r = EFI_OUT_OF_RESOURCES; 257 } 258 } 259 260 return r; 261 } 262 263 void *efi_alloc(uint64_t len, int memory_type) 264 { 265 uint64_t ret = 0; 266 uint64_t pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; 267 efi_status_t r; 268 269 r = efi_allocate_pages(0, memory_type, pages, &ret); 270 if (r == EFI_SUCCESS) 271 return (void*)(uintptr_t)ret; 272 273 return NULL; 274 } 275 276 efi_status_t efi_free_pages(uint64_t memory, unsigned long pages) 277 { 278 /* We don't free, let's cross our fingers we have plenty RAM */ 279 return EFI_SUCCESS; 280 } 281 282 efi_status_t efi_get_memory_map(unsigned long *memory_map_size, 283 struct efi_mem_desc *memory_map, 284 unsigned long *map_key, 285 unsigned long *descriptor_size, 286 uint32_t *descriptor_version) 287 { 288 ulong map_size = 0; 289 int map_entries = 0; 290 struct list_head *lhandle; 291 292 list_for_each(lhandle, &efi_mem) 293 map_entries++; 294 295 map_size = map_entries * sizeof(struct efi_mem_desc); 296 297 *memory_map_size = map_size; 298 299 if (descriptor_size) 300 *descriptor_size = sizeof(struct efi_mem_desc); 301 302 if (*memory_map_size < map_size) 303 return EFI_BUFFER_TOO_SMALL; 304 305 /* Copy list into array */ 306 if (memory_map) { 307 /* Return the list in ascending order */ 308 memory_map = &memory_map[map_entries - 1]; 309 list_for_each(lhandle, &efi_mem) { 310 struct efi_mem_list *lmem; 311 312 lmem = list_entry(lhandle, struct efi_mem_list, link); 313 *memory_map = lmem->desc; 314 memory_map--; 315 } 316 } 317 318 return EFI_SUCCESS; 319 } 320 321 int efi_memory_init(void) 322 { 323 unsigned long runtime_start, runtime_end, runtime_pages; 324 unsigned long uboot_start, uboot_pages; 325 unsigned long uboot_stack_size = 16 * 1024 * 1024; 326 int i; 327 328 /* Add RAM */ 329 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 330 u64 ram_start = gd->bd->bi_dram[i].start; 331 u64 ram_size = gd->bd->bi_dram[i].size; 332 u64 start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; 333 u64 pages = (ram_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; 334 335 efi_add_memory_map(start, pages, EFI_CONVENTIONAL_MEMORY, 336 false); 337 } 338 339 /* Add U-Boot */ 340 uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK; 341 uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT; 342 efi_add_memory_map(uboot_start, uboot_pages, EFI_LOADER_DATA, false); 343 344 /* Add Runtime Services */ 345 runtime_start = (ulong)&__efi_runtime_start & ~EFI_PAGE_MASK; 346 runtime_end = (ulong)&__efi_runtime_stop; 347 runtime_end = (runtime_end + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; 348 runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT; 349 efi_add_memory_map(runtime_start, runtime_pages, 350 EFI_RUNTIME_SERVICES_CODE, false); 351 352 return 0; 353 } 354