Exemplo n.º 1
0
def register_fill_frame(addr_space, symbol, fill, size, obj_space, label):
    '''
    Take a symbol and create a collection of 4K frames that can comfortably store 
    a region in the bootinfo.

    Return a static_assert checking that the symbol is of the correct size
    '''
    assert addr_space
    number_frames = size // 4096
    frames = []
    for i in range(number_frames):
        fill_str = [
            '%d %d %s %d' % (0, 4096 if (size - (i * 4096)) >= 4096 else
                             (size - (i * 4096)), fill, i * 4096)
        ]
        name = '%s_%s_%d_obj' % (symbol, label, i)
        frames.append(
            obj_space.alloc(ObjectType.seL4_FrameObject,
                            name=name,
                            label=label,
                            fill=fill_str,
                            size=4096))
    caps = [
        Cap(frame, read=True, write=False, grant=False) for frame in frames
    ]
    sizes = [4096] * number_frames
    addr_space.add_symbol_with_caps(symbol, sizes, caps)
    return 'static_assert(sizeof(%(sym)s) == %(size)s,\n'           \
           ' "%(sym)s not page sized. Templage bug in its declaration?");'  \
           % {'sym': symbol, 'size': size}
def register_shared_variable(addr_space, obj_space, global_name, symbol, size,
       frame_size=None, paddr=None, perm='RWX', cached=None, label=None):
    '''
    Create a reservation for a shared memory region between multiple
    components.

    global_name:   a global key that is used to link up the reservations
                   across multiple components.
    symbol:        the name of the local symbol to be backed by the
                   mapping frames.
    size:          the size of the region. Needs to be a multiple of the
                   smallest page size.
    frame_size:    the size of frames to use to back the region. `size`
                   must be a multiple of `frame_size`. If `frame_size`
                   is not specified, the largest frame size that divides
                   evenly into `size` will be used.
    paddr:         the starting physical address of the frames. Only one
                   caller needs to specify this. If multiple callers
                   specify different values, the result is undefined.
    perm, cached:  page mapping options. These are only applied to the
                   caller's mapping
    label:         integrity label of the frame objects. In the default
                   `Context`, this defaults to the current entity name.
    '''
    assert addr_space
    size = int(size)
    frame_size = calc_frame_size(size, frame_size, obj_space.spec.arch.capdl_name())
    num_frames = size//frame_size

    # If these frames have been allocated already then the allocator will return them.
    # Therefore calls to register_shared_variable with the same global_name have to have the same size.
    frames = [obj_space.alloc(ObjectType.seL4_FrameObject,
                              name='%s_%d_obj' % (global_name, i),
                              size=frame_size,
                              label=label)
              for i in range(num_frames)]
    if paddr is not None:
        for f in frames:
            f.paddr = paddr
            paddr += frame_size

    read = 'R' in perm
    write = 'W' in perm
    grant = 'X' in perm

    caps = [Cap(frame, read=read, write=write, grant=grant, cached=cached) for frame in frames]
    sizes = [frame_size] * num_frames
    addr_space.add_symbol_with_caps(symbol, sizes, caps)
    # Return code to:
    #  1. page-align the shared variable;
    #  2. make it visible in the final ELF; and
    #  3. Check that it is page-sized.
    return 'extern typeof(%(sym)s) %(sym)s ALIGN(%(size)d) VISIBLE;\n'      \
           'static_assert(sizeof(%(sym)s) <= %(size)d,\n'                       \
           '  "typeof(%(sym)s) size greater than dataport size.");\n'                    \
           'static_assert(sizeof(%(sym)s) %% %(frame_size)d == 0,\n'              \
           '  "%(sym)s not page-sized. Template bug in its declaration? '       \
           'Suggested formulation: `char %(sym)s[ROUND_UP_UNSAFE(sizeof(...), ' \
           'PAGE_SIZE_4K)];`");' % {'sym':symbol, 'size': size, 'frame_size': frame_size}
Exemplo n.º 3
0
def register_ipc_symbol(addr_space, symbol, frame):
    '''
    Register an IPC buffer symbol with a cap to the frame that is passed in.
    The frame needs to be passed in instead of allocated internally because caps
    to the frame are needed by other objects such as the TCB for the thread.
    It is left to the caller to manage references to the Frame passed in.
    '''
    assert addr_space
    # We create 3*4K mappings with None on each side of the IPC buffer for guard pages
    caps = [None, Cap(frame, read=True, write=True, grant=False), None]
    sizes = [4096] * 3
    addr_space.add_symbol_with_caps(symbol, sizes, caps)
def register_fill_frame(addr_space, symbol, fill, obj_space, label):
    '''
    Take a 4K sized symbol and create a 4k Frame with fill data to be added by the
    loader.

    Return a static_assert checking that the symbol is of the correct size
    '''
    assert addr_space
    frame = obj_space.alloc(ObjectType.seL4_FrameObject, name='%s_%s_obj' % (symbol, label), label=label, fill=fill, size=4096)
    addr_space.add_symbol_with_caps(symbol, [4096], [Cap(frame, read=True, write=False, grant=False)])
    return 'static_assert(sizeof(%(sym)s) == PAGE_SIZE_4K,\n'           \
           ' "%(sym)s not page sized. Templage bug in its declaration?");'  \
           % {'sym':symbol}
Exemplo n.º 5
0
def register_stack_symbol(addr_space, symbol, size, obj_space, label):
    '''
    Create a stack of `size` with a guard page on each side. This allocates the frames internally
    from the obj_space that is passed in as the frame objects shouldn't be needed anywhere else.
    Stack frames are read, write mappings.
    '''
    assert addr_space
    number_frames = size//4096
    frames = [obj_space.alloc(ObjectType.seL4_FrameObject, name='stack_%s_%d_%s_obj' % (symbol, i, label), label=label, size=4096)
              for i in range(number_frames)]
    # We create 2 additional mappings with None caps that are for the guard pages.
    sizes = [4096] * (number_frames + 2)
    caps = [None] + [Cap(frame, read=True, write=True, grant=False) for frame in frames] + [None]
    addr_space.add_symbol_with_caps(symbol, sizes, caps)
Exemplo n.º 6
0
def register_shared_variable(addr_space, obj_space, global_name, symbol, size, cap_space,
                             frame_size=None, paddr=None, perm='RWX', cached=True, label=None, with_mapping_caps=None):
    '''
    Create a reservation for a shared memory region between multiple
    components.

    global_name:   a global key that is used to link up the reservations
                   across multiple components.
    symbol:        the name of the local symbol to be backed by the
                   mapping frames.
    size:          the size of the region. Needs to be a multiple of the
                   smallest page size.
    cap_space:     the component's cspace. This is potentially used if the mapping caps
                   need to be moved to the component. In this case, with_mapping_caps needs
                   to be set when register_shared_variable is called.
    frame_size:    the size of frames to use to back the region. `size`
                   must be a multiple of `frame_size`. If `frame_size`
                   is not specified, the largest frame size that divides
                   evenly into `size` will be used.
    paddr:         the starting physical address of the frames. Only one
                   caller needs to specify this. If multiple callers
                   specify different values, the result is undefined.
    perm, cached:  page mapping options. These are only applied to the
                   caller's mapping
    label:         integrity label of the frame objects. In the default
                   `Context`, this defaults to the current entity name.
    with_mapping_caps: An array to return mapping caps if the component needs the
                   caps for the mapping to be moved into their own cspace.
    '''
    assert addr_space
    size = int(size)
    frame_size = calc_frame_size(size, frame_size, obj_space.spec.arch)
    num_frames = size//frame_size
    digits = str(int(log10(num_frames + 1)) + 1)
    namefmt = '%s_%0' + digits + 'd_obj'
    # If these frames have been allocated already then the allocator will return them.
    # Therefore calls to register_shared_variable with the same global_name have to have the same size.
    frames = [obj_space.alloc(ObjectType.seL4_FrameObject,
                              name=namefmt % (global_name, i),
                              size=frame_size,
                              label=label)
              for i in range(num_frames)]
    if paddr is not None:
        for f in frames:
            f.paddr = paddr
            paddr += frame_size

    read = 'R' in perm
    write = 'W' in perm
    grant = 'X' in perm

    if with_mapping_caps is not None:
        # If we need the caps in our cspace, then we need to allocate them and call set_mapping_deferred on the cap
        # set_mapping_deferred will result in the correct mapping info being set when the spec is being generated.
        slots = [cap_space.alloc(frame, read=read, write=write, grant=grant,
                                 cached=cached) for frame in frames]
        caps = [cap_space.cnode[slot] for slot in slots]
        [cap.set_mapping_deferred() for cap in caps]
        with_mapping_caps.extend(slots)
    else:
        caps = [Cap(frame, read=read, write=write, grant=grant, cached=cached) for frame in frames]
    sizes = [frame_size] * num_frames
    addr_space.add_symbol_with_caps(symbol, sizes, caps)
    # Return code to:
    #  1. page-align the shared variable;
    #  2. make it visible in the final ELF; and
    #  3. Check that it is page-sized.
    return 'extern typeof(%(sym)s) %(sym)s ALIGN(%(frame_size)d) VISIBLE;\n'      \
           'static_assert(sizeof(%(sym)s) <= %(size)d,\n'                       \
           '  "typeof(%(sym)s) size greater than dataport size.");\n'                    \
           'static_assert(sizeof(%(sym)s) %% %(frame_size)d == 0,\n'              \
           '  "%(sym)s not page-sized. Template bug in its declaration? '       \
           'Suggested formulation: `char %(sym)s[ROUND_UP_UNSAFE(sizeof(...), ' \
           'PAGE_SIZE_4K)];`");' % {'sym': symbol, 'size': size, 'frame_size': frame_size}