def calc_frame_size(size, frame_size, arch): if not frame_size: for sz in reversed(page_sizes(arch)): if size >= sz and size % sz == 0: frame_size = sz break assert frame_size, "Shared variable size: %d is not a valid page size multiple" % size return frame_size
def next_page_multiple(size, arch): ''' Finds the smallest multiple of 4K that can comfortably be used to create a mapping for the provided size on a given architecture. ''' multiple = page_sizes(arch)[0] while size > multiple: multiple += 4096 return multiple
def next_page_multiple(size, arch): ''' Finds the smallest multiple of 4K that can comfortably be used to create a mapping for the provided size on a given architecture. ''' multiple = page_sizes(arch)[0] while size > multiple: multiple *= 2 return multiple
def get_page_size(size, arch): ''' Returns the largest frame_size that can be used to create a mapping for the provided size on a given architecture. It assumes that the variable will be aligned to the start of the frame. ''' frame_size = 0 size = int(size) for sz in reversed(page_sizes(arch)): if size >= sz and size % sz == 0: frame_size = sz break return frame_size
def align_page_address(address, arch): page_size = page_sizes(arch)[0] return address & ~(page_size - 1)
def replace_dma_frames(ast, obj_space, elfs, options, **_): '''Locate the DMA pool (a region that needs to have frames whose mappings can be reversed) and replace its backing frames with pre-allocated, reversible ones.''' if not elfs: # If we haven't been passed any ELF files this step is not relevant yet. return arch = lookup_architecture(options.architecture) assembly = ast.assembly for i in (x for x in assembly.composition.instances if not x.type.hardware): perspective = Perspective(instance=i.name, group=i.address_space) elf_name = perspective['elf_name'] assert elf_name in elfs elf = elfs[elf_name] # Find this instance's page directory. pd_name = perspective['pd'] pds = [x for x in obj_space.spec.objs if x.name == pd_name] assert len(pds) == 1 pd, = pds sym = perspective['dma_pool_symbol'] base = get_symbol_vaddr(elf, sym) if base is None: # We don't have a DMA pool. continue assert base != 0 sz = get_symbol_size(elf, sym) assert sz % PAGE_SIZE == 0 # DMA pool should be at least page-aligned. # Replicate logic from the template to determine the page size used to # back the DMA pool. page_size = 4 * 1024 if options.largeframe_dma: for size in reversed(page_sizes(options.architecture)): if sz >= size: page_size = size break assert sz % page_size == 0, 'DMA pool not rounded up to a multiple ' \ 'of page size %d (template bug?)' % page_size dma_frame_index = 0 def get_dma_frame(index): ''' Find the `index`-th DMA frame. Note that these are constructed in the component template itself. ''' p = Perspective(instance=i.name, group=i.address_space, dma_frame_index=index) name = p['dma_frame_symbol'] assert name in obj_space, "No such symbol in capdl spec %s" % name return obj_space[name] # Ensure paging structures are in place to map in dma frames replace_large_frames(obj_space, arch, pd, base, sz, page_size) for page_vaddr in six.moves.range(base, base + sz, page_size): cap = Cap(get_dma_frame(dma_frame_index), True, True, False) cap.set_cached(False) update_frame_in_vaddr(arch, pd, page_vaddr, page_size, cap) dma_frame_index = dma_frame_index + 1