Ejemplo n.º 1
0
def align_memory(regions: Set[Region], config: Config) -> List[Region]:
    ''' Given a set of regions, sort them and align the first so that the ELF loader will be able to load the kernel into it. Will return the aligned
        memory region list, a set of any regions of memory that were aligned out
        and the physBase value that the kernel will use. '''
    ret = sorted(regions)
    extra_reserved = set()

    if config.arch == 'riscv':
        # RISC-V is special: it expects physBase to be
        # the address that the bootloader is loaded at.
        physBase = ret[0].base

    if config.get_bootloader_reserve() > 0:
        resv = Region(ret[0].base, config.get_bootloader_reserve(), None)
        extra_reserved.add(resv)
        ret[0].base += config.get_bootloader_reserve()
        ret[0].size -= config.get_bootloader_reserve()

    if config.get_kernel_phys_align() != 0:
        new = ret[0].align_base(config.get_kernel_phys_align())
        resv = Region(ret[0].base, new.base - ret[0].base, None)
        extra_reserved.add(resv)
        ret[0] = new

    if config.arch != 'riscv':
        # ARM (and presumably other architectures)
        # want physBase to be the physical load address of the kernel.
        physBase = ret[0].base
    return ret, extra_reserved, physBase
Ejemplo n.º 2
0
    def __init__(self, region: Region, kernel_name: str, page_bits: int, max_size: int, condition_macro: str = None, user_ok: bool = False):
        self.macro = condition_macro
        self.desc = region.owner.path if region.owner else 'dynamically generated region'
        self.kernel_offset = -1
        self.page_bits = page_bits
        self.labels = {}  # dict of label => offset within region.
        self.user_ok = user_ok

        region.size = min(max_size, region.size)
        aligned = region.align_size(page_bits)
        self.size = aligned.size
        self.base = aligned.base
        self.regions = aligned.make_chunks(1 << page_bits)
        self.labels[kernel_name] = region.base - aligned.base
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    def get_regions(self) -> List[Region]:
        if 'reg' not in self.props:
            return []

        reg = []
        prop = list(self.props['reg'].words)
        sizes = (self.parent.get_addr_cells(), self.parent.get_size_cells())
        for r in Utils.intarray_iter(prop, sizes):
            reg.append(
                Region(self.parent._translate_child_address(r[0]), r[1], self))
        return reg
Ejemplo n.º 5
0
    def align_memory(self, regions: Set[Region]) -> List[Region]:
        ''' Arm wants physBase to be the physical load address of the kernel. '''
        ret = sorted(regions)
        extra_reserved = set()

        new = ret[0].align_base(self.get_kernel_phys_align())
        resv = Region(ret[0].base, new.base - ret[0].base)
        extra_reserved.add(resv)
        ret[0] = new

        physBase = ret[0].base

        return ret, extra_reserved, physBase
Ejemplo n.º 6
0
    def align_memory(self, regions: Set[Region]) -> List[Region]:
        ''' Currently the RISC-V port expects physBase to be the address that the
        bootloader is loaded at. To be generalised in the future. '''
        ret = sorted(regions)
        extra_reserved = set()

        physBase = ret[0].base

        resv = Region(ret[0].base, self.get_bootloader_reserve())
        extra_reserved.add(resv)
        ret[0].base += self.get_bootloader_reserve()
        ret[0].size -= self.get_bootloader_reserve()

        return ret, extra_reserved, physBase
Ejemplo n.º 7
0
def get_addrspace_exclude(regions: List[Region], config: Config):
    ''' Returns a list of regions that represents the inverse of the given region list. '''
    ret = set()
    as_max = utils.align_down(config.addrspace_max, config.get_page_bits())
    ret.add(Region(0, as_max, None))

    for reg in regions:
        if type(reg) == KernelRegionGroup:
            if reg.user_ok:
                continue
        new_ret = set()
        for el in ret:
            new_ret.update(el.reserve(reg))

        ret = new_ret
    return sorted(ret, key=lambda a: a.base)
Ejemplo n.º 8
0
def get_addrspace_exclude(regions: List[Region], config: Config):
    ''' Returns a list of regions that represents the inverse of the given region list. '''
    ret = set()
    # We can't create untypeds that exceed the addrspace_max, so we round down to the smallest
    # untyped size alignment so that the kernel will be able to turn the entire range into untypeds.
    as_max = hardware.utils.align_down(
        config.addrspace_max, config.get_smallest_kernel_object_alignment())
    ret.add(Region(0, as_max))

    for reg in regions:
        if type(reg) == KernelRegionGroup:
            if reg.user_ok:
                continue
        new_ret = set()
        for el in ret:
            new_ret.update(el.reserve(reg))

        ret = new_ret
    return sorted(ret, key=lambda a: a.base)