From: Daniel Kiper <daniel.ki...@oracle.com> The functions calculate lowest and highest available RAM addresses respectively.
Signed-off-by: Daniel Kiper <daniel.ki...@oracle.com> Signed-off-by: Sergii Dmytruk <sergii.dmyt...@3mdeb.com> --- grub-core/mmap/mmap.c | 83 +++++++++++++++++++++++++++++++++++++++++++ include/grub/memory.h | 3 ++ 2 files changed, 86 insertions(+) diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c index c8c8312c5..80d6c60b8 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c @@ -26,6 +26,7 @@ #include <grub/command.h> #include <grub/dl.h> #include <grub/i18n.h> +#include <grub/safemath.h> GRUB_MOD_LICENSE ("GPLv3+"); @@ -343,6 +344,88 @@ grub_mmap_unregister (int handle) #endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */ +typedef struct +{ + grub_uint64_t addr; + grub_uint64_t limit; +} addr_limit_t; + +/* Helper for grub_mmap_get_lowest(). */ +static int +lowest_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, + void *data) +{ + addr_limit_t *al = data; + grub_uint64_t end; + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + + if (grub_add (addr, size, &end)) + return 0; + + if (addr >= al->limit) + al->addr = grub_min (al->addr, addr); + + if ((addr < al->limit) && (end > al->limit)) + al->addr = al->limit; + + return 0; +} + +/* + * This function calculates lowest available RAM address that is at or above + * the passed limit. If no RAM exists above the limit, ~0 is returned. + */ +grub_uint64_t +grub_mmap_get_lowest (grub_uint64_t limit) +{ + addr_limit_t al = {~0, limit}; + + grub_mmap_iterate (lowest_hook, &al); + + return al.addr; +} + +/* Helper for grub_mmap_get_highest(). */ +static int +highest_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, + void *data) +{ + addr_limit_t *al = data; + grub_uint64_t end; + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + + if (grub_add (addr, size, &end)) + return 0; + + if (end < al->limit) + al->addr = grub_max (al->addr, end); + + if ((addr < al->limit) && (end >= al->limit)) + al->addr = al->limit; + + return 0; +} + +/* + * This function calculates highest available RAM address that is below the + * passed limit. Returned address is either one byte after last byte of RAM or + * equal to limit, whichever is lower. If no RAM exists below limit, 0 is + * returned. + */ +grub_uint64_t +grub_mmap_get_highest (grub_uint64_t limit) +{ + addr_limit_t al = {0, limit}; + + grub_mmap_iterate (highest_hook, &al); + + return al.addr; +} + #define CHUNK_SIZE 0x400 struct badram_entry { diff --git a/include/grub/memory.h b/include/grub/memory.h index 6da114a1b..8f22f7525 100644 --- a/include/grub/memory.h +++ b/include/grub/memory.h @@ -69,6 +69,9 @@ void *grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size, void grub_mmap_free_and_unregister (int handle); +extern grub_uint64_t grub_mmap_get_lowest (grub_uint64_t limit); +extern grub_uint64_t grub_mmap_get_highest (grub_uint64_t limit); + #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE struct grub_mmap_region -- 2.46.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel