[RFC PATCH 16/31] lmb: add an event handler to update memory map

Sughosh Ganu sughosh.ganu at linaro.org
Fri Jun 7 20:52:25 CEST 2024


There are events that would be used to notify other interested modules
of any changes in available and occupied memory. This would happen
when a module allocates or reserves memory, or frees up memory. These
changes in memory map should be notified to other interested modules
so that the allocated memory does not get overwritten. Add an event
handler in the LMB module to update it's memory map accordingly when
such changes happen. As a consequence, any subsequent memory request
would honour the updated memory map and allocations would only happen
from available memory.

Signed-off-by: Sughosh Ganu <sughosh.ganu at linaro.org>
---
 lib/Kconfig |  1 +
 lib/lmb.c   | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/lib/Kconfig b/lib/Kconfig
index 9ea02ae006..9e465a748b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -1111,6 +1111,7 @@ config LMB
 	bool "Enable the logical memory blocks library (lmb)"
 	default y if ARC || ARM || M68K || MICROBLAZE || MIPS || \
 		     NIOS2 || PPC || RISCV || SANDBOX || SH || X86 || XTENSA
+	select EVENT
 	help
 	  Support the library logical memory blocks.
 
diff --git a/lib/lmb.c b/lib/lmb.c
index 313735dbe3..3059609aea 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -16,6 +16,7 @@
 
 #include <asm/global_data.h>
 #include <asm/sections.h>
+#include <asm-generic/io.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -719,3 +720,36 @@ __weak void arch_lmb_reserve(void)
 {
 	/* please define platform specific arch_lmb_reserve() */
 }
+
+#if CONFIG_IS_ENABLED(MEM_MAP_UPDATE_NOTIFY)
+static long lmb_reserve_nooverwrite(phys_addr_t base, phys_size_t size)
+{
+	struct lmb_region *_rgn = &lmb.reserved;
+
+	return lmb_add_region_flags(_rgn, base, size, LMB_NOOVERWRITE);
+}
+
+static int efi_mem_map_update_sync(void *ctx, struct event *event)
+{
+	u8 op;
+	long ret;
+	phys_addr_t addr;
+	phys_size_t size;
+	struct event_efi_mem_map_update *efi_map = &event->data.efi_mem_map;
+
+	addr = virt_to_phys((void *)(uintptr_t)efi_map->base);
+	size = efi_map->size;
+	op = efi_map->op;
+
+	if (op != MAP_OP_RESERVE && op != MAP_OP_FREE) {
+		log_debug("Invalid map update op received (%d)\n", op);
+		return -1;
+	}
+
+	ret = op == MAP_OP_RESERVE ? lmb_reserve_nooverwrite(addr, size) :
+		__lmb_free(addr, size);
+
+	return !ret ? 0 : -1;
+}
+EVENT_SPY_FULL(EVT_EFI_MEM_MAP_UPDATE, efi_mem_map_update_sync);
+#endif /* MEM_MAP_UPDATE_NOTIFY */
-- 
2.34.1



More information about the U-Boot mailing list