@@ -786,7 +786,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type);
/**
- * efi_add_memory_map_pg() - add pages to the memory map
+ * efi_update_memory_map() - update the memory map by adding/removing pages
*
* @start: start address, must be a multiple of
* EFI_PAGE_SIZE
@@ -794,11 +794,14 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type);
* @memory_type: type of memory added
* @overlap_conventional: region may only overlap free(conventional)
* memory
+ * @remove: remove memory map
* Return: status code
*/
-efi_status_t efi_add_memory_map_pg(u64 start, u64 pages,
- int memory_type,
- bool overlap_conventional);
+efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type,
+ bool overlap_conventional, bool remove);
+
+/* Remove memory from the EFI memory map */
+efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type);
/* Called by board init to initialize the EFI drivers */
efi_status_t efi_driver_init(void);
@@ -258,7 +258,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map,
}
/**
- * efi_add_memory_map_pg() - add pages to the memory map
+ * efi_update_memory_map() - update the memory map by adding/removing pages
*
* @start: start address, must be a multiple of
* EFI_PAGE_SIZE
@@ -266,11 +266,11 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map,
* @memory_type: type of memory added
* @overlap_conventional: region may only overlap free(conventional)
* memory
+ * @remove: remove memory map
* Return: status code
*/
-efi_status_t efi_add_memory_map_pg(u64 start, u64 pages,
- int memory_type,
- bool overlap_conventional)
+efi_status_t efi_update_memory_map(u64 start, u64 pages, int memory_type,
+ bool overlap_conventional, bool remove)
{
struct efi_mem_list *lmem;
struct efi_mem_list *newlist;
@@ -278,9 +278,9 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages,
uint64_t carved_pages = 0;
struct efi_event *evt;
- EFI_PRINT("%s: 0x%llx 0x%llx %d %s\n", __func__,
+ EFI_PRINT("%s: 0x%llx 0x%llx %d %s %s\n", __func__,
start, pages, memory_type, overlap_conventional ?
- "yes" : "no");
+ "yes" : "no", remove ? "remove" : "add");
if (memory_type >= EFI_MAX_MEMORY_TYPE)
return EFI_INVALID_PARAMETER;
@@ -363,7 +363,10 @@ efi_status_t efi_add_memory_map_pg(u64 start, u64 pages,
}
/* Add our new map */
- list_add_tail(&newlist->link, &efi_mem);
+ if (!remove)
+ list_add_tail(&newlist->link, &efi_mem);
+ else
+ free(newlist);
/* And make sure memory is listed in descending order */
efi_mem_sort();
@@ -400,7 +403,29 @@ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type)
pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK));
start &= ~EFI_PAGE_MASK;
- return efi_add_memory_map_pg(start, pages, memory_type, false);
+ return efi_update_memory_map(start, pages, memory_type, false, false);
+}
+
+/**
+ * efi_remove_memory_map() - remove memory area to the memory map
+ *
+ * @start: start address of the memory area
+ * @size: length in bytes of the memory area
+ * @memory_type: type of memory removed
+ *
+ * Return: status code
+ *
+ * This function automatically aligns the start and size of the memory area
+ * to EFI_PAGE_SIZE.
+ */
+efi_status_t efi_remove_memory_map(u64 start, u64 size, int memory_type)
+{
+ u64 pages;
+
+ pages = efi_size_in_pages(size + (start & EFI_PAGE_MASK));
+ start &= ~EFI_PAGE_MASK;
+
+ return efi_update_memory_map(start, pages, memory_type, false, true);
}
/**
@@ -501,7 +526,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
efi_addr = (u64)(uintptr_t)map_sysmem(addr, 0);
/* Reserve that map in our memory maps */
- ret = efi_add_memory_map_pg(efi_addr, pages, memory_type, true);
+ ret = efi_update_memory_map(efi_addr, pages, memory_type, true, false);
if (ret != EFI_SUCCESS) {
/* Map would overlap, bail out */
lmb_free_flags(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
@@ -822,8 +847,8 @@ static void add_u_boot_and_runtime(void)
uboot_stack_size) & ~EFI_PAGE_MASK;
uboot_pages = ((uintptr_t)map_sysmem(gd->ram_top - 1, 0) -
uboot_start + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
- efi_add_memory_map_pg(uboot_start, uboot_pages, EFI_BOOT_SERVICES_CODE,
- false);
+ efi_update_memory_map(uboot_start, uboot_pages, EFI_BOOT_SERVICES_CODE,
+ false, false);
#if defined(__aarch64__)
/*
* Runtime Services must be 64KiB aligned according to the
@@ -841,8 +866,8 @@ static void add_u_boot_and_runtime(void)
runtime_end = (uintptr_t)__efi_runtime_stop;
runtime_end = (runtime_end + runtime_mask) & ~runtime_mask;
runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
- efi_add_memory_map_pg(runtime_start, runtime_pages,
- EFI_RUNTIME_SERVICES_CODE, false);
+ efi_update_memory_map(runtime_start, runtime_pages,
+ EFI_RUNTIME_SERVICES_CODE, false, false);
}
int efi_memory_init(void)
@@ -464,11 +464,11 @@ static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op,
pages = efi_size_in_pages(size + (efi_addr & EFI_PAGE_MASK));
efi_addr &= ~EFI_PAGE_MASK;
- status = efi_add_memory_map_pg(efi_addr, pages,
+ status = efi_update_memory_map(efi_addr, pages,
op == MAP_OP_RESERVE ?
EFI_BOOT_SERVICES_DATA :
EFI_CONVENTIONAL_MEMORY,
- false);
+ false, false);
if (status != EFI_SUCCESS) {
log_err("%s: LMB Map notify failure %lu\n", __func__,
status & ~EFI_ERROR_MASK);