From 2d45723d87b3bec2812cf34d0785d80194fae3d1 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Wed, 10 Dec 2025 18:05:43 +0800 Subject: [PATCH] lib/bootmem: Add bootmem_add_range_from function This patch introduces a new function, bootmem_add_range_from, which allows adding a memory range of a specific type only if it is carved out from a range of another specific type. This is useful for cases where memory needs to be allocated from a pre-defined region. The function checks if the target range is fully contained within a range of `from_tag` before marking it as `new_tag`. Error reporting is included to log cases where the allocation is not possible. BUG=b:438666196 Change-Id: Icfdb5ef9114572c075be6ef4e57d00151300a17a Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90469 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/include/bootmem.h | 16 ++++++++++++++++ src/lib/bootmem.c | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/include/bootmem.h b/src/include/bootmem.h index 5796765ad6..b1352e395b 100644 --- a/src/include/bootmem.h +++ b/src/include/bootmem.h @@ -61,6 +61,22 @@ void bootmem_platform_add_ranges(void); void bootmem_add_range(uint64_t start, uint64_t size, const enum bootmem_type tag); +/* + * bootmem_add_range_from - Add a memory range of a specific type from another range + * @start: Start address of the new memory range + * @size: Size of the new memory range + * @new_tag: The new bootmem_type for the range + * @from_tag: The bootmem_type from which the new range should be carved out + * + * This function adds a memory range with `new_tag` only if it is fully + * contained within an existing range of `from_tag`. This is useful for + * carving out specific memory regions from a larger, already defined area. + * + * Return: 0 on success, or a negative error code on failure. + */ +int bootmem_add_range_from(uint64_t start, uint64_t size, const enum bootmem_type new_tag, + const enum bootmem_type from_tag); + /* Print current range map of boot memory. */ void bootmem_dump_ranges(void); diff --git a/src/lib/bootmem.c b/src/lib/bootmem.c index ab15e85d08..f8963f3299 100644 --- a/src/lib/bootmem.c +++ b/src/lib/bootmem.c @@ -14,6 +14,8 @@ static int table_written; static struct memranges bootmem; static struct memranges bootmem_os; +static const char *bootmem_range_string(const enum bootmem_type tag); + static int bootmem_is_initialized(void) { return initialized; @@ -106,6 +108,24 @@ void bootmem_add_range(uint64_t start, uint64_t size, }; } +int bootmem_add_range_from(uint64_t start, uint64_t size, const enum bootmem_type new_tag, + const enum bootmem_type from_tag) +{ + if (new_tag == from_tag) + return -1; + + if (!bootmem_region_targets_type(start, size, from_tag)) { + printk(BIOS_ERR, "%s: Failed to add the range [%#llx, %#llx)" + " from tag %s to %s\n", __func__, start, start + size, + bootmem_range_string(from_tag), bootmem_range_string(new_tag)); + return -1; + } + + bootmem_add_range(start, size, new_tag); + + return 0; +} + void bootmem_write_memory_table(struct lb_memory *mem) { const struct range_entry *r;