From b32b9568b2655213cc51ba013fd1af59c623cc0d Mon Sep 17 00:00:00 2001 From: Bertrand Virfollet Date: Fri, 16 Apr 2021 16:21:11 +0200 Subject: [PATCH] tools: merge adjacent memory regions Merge memory regions before checking for reserved areas Co-authored-by: Gerwin Klein Signed-off-by: Bertrand Virfollet Signed-off-by: Gerwin Klein --- tools/hardware/utils/memory.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tools/hardware/utils/memory.py b/tools/hardware/utils/memory.py index b68c5a285..c3698ecd4 100644 --- a/tools/hardware/utils/memory.py +++ b/tools/hardware/utils/memory.py @@ -26,6 +26,36 @@ def get_memory_regions(tree: FdtParser): return regions +def merge_memory_regions(regions: Set[Region]) -> Set[Region]: + ''' Check all region and merge adjacent ones ''' + all_regions = [dict(idx=idx, region=region, right_adj=None, left_adj=None) + for (idx, region) in enumerate(regions)] + + # Find all right contiguous regions + for dreg in all_regions: + for dnreg in all_regions[dreg['idx']+1:]: + if dreg['region'].owner == dnreg['region'].owner: + if dnreg['region'].base == dreg['region'].base + dreg['region'].size: + dreg['right_adj'] = dnreg + dnreg['left_adj'] = dreg + elif dreg['region'].base == dnreg['region'].base + dnreg['region'].size: + dnreg['right_adj'] = dreg + dreg['left_adj'] = dnreg + + # Find all the left-most contiguous regions + contiguous_regions = set() + for reg in all_regions: + if reg['left_adj'] is None: + size = reg['region'].size + r_adj = reg['right_adj'] + while r_adj is not None: + size += r_adj['region'].size + r_adj = r_adj['right_adj'] + contiguous_regions.add(Region(reg['region'].base, size, reg['region'].owner)) + + return contiguous_regions + + def parse_reserved_regions(node: WrappedNode) -> Set[Region]: ''' Parse a reserved-memory node, looking for regions that are unusable by OS (e.g. reserved for firmware/bootloader) ''' @@ -56,7 +86,7 @@ def reserve_regions(regions: Set[Region], reserved: Set[Region]) -> Set[Region]: def get_physical_memory(tree: FdtParser, config: Config) -> List[Region]: ''' returns a list of regions representing physical memory as used by the kernel ''' - regions = get_memory_regions(tree) + regions = merge_memory_regions(get_memory_regions(tree)) reserved = parse_reserved_regions(tree.get_path('/reserved-memory')) regions = reserve_regions(regions, reserved) regions, extra_reserved, physBase = config.align_memory(regions)