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 <yidilin@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90469
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Yidi Lin 2025-12-10 18:05:43 +08:00 committed by Matt DeVillier
commit 2d45723d87
2 changed files with 36 additions and 0 deletions

View file

@ -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);

View file

@ -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;