Example #1
0
def collect_program_element(program_el, ignore_name, namespace, image,
                            machine, bootinfo, pools):
    """Collect the attributes of a program element."""

    # New namespace for objects living in the program's PD.
    prog_namespace = namespace.add_namespace(program_el.name)

    pd = weaver.bootinfo.PD(program_el.name, prog_namespace, image,
                            machine, pools)

    elf = UnpreparedElfFile(filename=program_el.file)

    if elf.elf_type != ET_EXEC:
        raise MergeError, "All the merged ELF files must be of EXEC type."

    bootinfo.add_elf_info(name = program_el.file,
                          elf_type = image.PROGRAM,
                          entry_point = elf.entry_point)

    pd.elf = elf

    virtpool = getattr(program_el, 'virtpool', None)
    physpool = getattr(program_el, 'physpool', None)
    direct = getattr(program_el, 'direct', None)
    pd.set_platform_control(getattr(program_el, "platform_control", False))

    if hasattr(program_el, 'pager'):
        pager = make_pager_attr(program_el.pager)
    else:
        pager = None

    # Push the overriding attributes for the program.
    image.push_attrs(virtual  = virtpool,
                     physical = physpool,
                     pager    = pager,
                     direct   = direct)

    pd.set_default_pools(image, bootinfo)

    # Collect the object environment
    env = collect_environment_element(program_el.find_child('environment'),
                                      prog_namespace, machine, pools,
                                      image, bootinfo)

    segment_els = program_el.find_all_children("segment")
    segs = collect_elf_segments(elf,
                                image.PROGRAM,
                                segment_els,
                                program_el.name,
                                prog_namespace,
                                image,
                                machine,
                                pools)

    segs_ms = [bootinfo.record_segment_info(program_el.name, seg,
                                            image, machine, pools)
               for seg in segs]
    for seg_ms in segs_ms:
        pd.attach_memsection(seg_ms)

    # Record any patches being made to the program.
    patch_els   = program_el.find_children("patch")
    collect_patches(elf, patch_els, program_el.file, image)

    # Collect the main thread.
    thread = collect_thread(elf, program_el, ignore_name, prog_namespace,
                            image, machine, pools,
                            entry = elf.entry_point,
                            name = program_el.name,
                            namespace_thread_name = "main")
    pd.add_thread(thread)
    pd.set_server_thread(thread)

    # Add the virtual device elements
    # Virtual devices always get added to the global namespace because they
    # should be globally unique
    server_spawn_nvdevs = 0
    dev_ns = namespace.root.get_namespace("dev")

    if dev_ns is None:
        raise MergeError, "Device namespace does not exist!"

    for v_el in program_el.find_children('virt_device'):
        virt_dev = pd.add_virt_dev(v_el.name, program_el.name, pd,
                                   thread, server_spawn_nvdevs)
        create_alias_cap(virt_dev, dev_ns)
        server_spawn_nvdevs += 1

    # Record the main thread and its stack in the environment.
    env.add_entry(key      = "MAIN",
                  cap_name = 'main/master')
    env.add_entry(key      = "MAIN/STACK",
                  cap_name = 'main/stack/master',
                  attach  = thread.get_stack().get_attrs().attach)


    # If marked, sure that the program is exported to every
    # environment so that it can be found by other programs.
    #
    if hasattr(program_el, 'server'):
        bootinfo.add_server(
            key = program_el.server,
            cap_name = prog_namespace.abs_name('main') + '/stack/master')

    # Collect remaining threads.
    elf = pd.elf = pd.elf.prepare(image.wordsize, image.endianess)

    for thread_el in program_el.find_children('thread'):
        if not ignore_name.match(thread_el.name):
            thread = collect_thread(elf, thread_el, ignore_name,
                                    prog_namespace, image, machine, pools,
                                    entry = "_thread_start")
            pd.add_thread(thread)

            # Record the thread and its stack in the environment.
            env.add_entry(key      = thread.get_name(),
                          cap_name = thread.get_name() + '/master')
            env.add_entry(key      = thread.get_name() + "/STACK",
                          cap_name = thread.get_name() + '/stack/master',
                          attach   = thread.get_stack().get_attrs().attach)

    # Collect any other memsections in the program.
    for ms_el in program_el.find_children('memsection'):
        if not ignore_name.match(ms_el.name):
            ms = collect_memsection_element(ms_el, ignore_name,
                                            prog_namespace, image,
                                            machine, pools)

            pd.attach_memsection(ms)
            image.add_group(0, [ms.get_ms()])

            env.add_entry(key      = ms.get_name(),
                          cap_name = ms.get_name() + '/master',
                          attach   = ms.get_attrs().attach)

    # Collect any zones in the program.
    for zone_el in program_el.find_children('zone'):
        (zone, non_zone_ms) = \
               collect_zone_element(zone_el, ignore_name,
                                    prog_namespace, pools, image,
                                    bootinfo, machine)

        pd.attach_zone(zone)

        # Attach memsections that aren't part of the zone to the program.
        for ms in non_zone_ms:
            pd.attach_memsection(ms)

            image.add_group(0, [ms.get_ms()])
            env.add_entry(key      = ms.get_name(),
                          cap_name = ms.get_name() + '/master',
                          attach   = ms.get_attrs().attach)

    # Collect the heap.  Is there no element, create a fake one for
    # the collection code to use.
    heap_el = program_el.find_child('heap')

    if heap_el is None:
        heap_el = ParsedElement('heap')

    heap_ms = collect_memsection_element(heap_el, ignore_name,
                                         prog_namespace, image,
                                         machine, pools)
    pd.attach_heap(heap_ms)
    image.add_group(0, [heap_ms.get_ms()])
    # Fill env with default values.
    env.add_entry(key      = "HEAP",
                  cap_name = 'heap/master',
                  attach   = heap_ms.get_attrs().attach)

    env.add_entry(key      = "HEAP_BASE",
                  base     = heap_ms)
    env.add_entry(key      = "HEAP_SIZE",
                  value    = heap_ms.get_attrs().size)

    pd.add_environment(env)

    bootinfo.add_pd(pd)

    image.pop_attrs()
Example #2
0
def collect_machine_element(parsed, ignore_name, machine, namespace):
    """Collect the attributes of the machine element."""
    machine_el = parsed.find_child("machine")

    assert machine_el is not None

    # If the file attribute is specified, then read the full version
    # of the machine element from that file.
    if hasattr(machine_el, "file"):
        machine_el = Machine_el.parse_xml_file(machine_el.file)

    machine.word_size = machine_el.find_child("word_size").size

    machine.set_page_sizes([el.size for el in machine_el.find_children("page_size")])
    
    machine.add_cache_policies([(el.name, el.value) for el in machine_el.find_children("cache_policy")])
    
    attrs = machine_el.find_child("kernel_heap_attrs")
    if attrs is not None:
        machine.kernel_heap_proximity = getattr(attrs, 'distance', None)
        machine.kernel_heap_align = getattr(attrs, 'align', None)

    def map_mem_type(region_el):
        """Map the string memory type to a memory descriptor type."""
        mem_type = getattr(region_el, "type", "conventional")

        if not MEMDESC_DICT.has_key(mem_type):
            raise MergeError, "Unknown memory type %s" % mem_type

        return MEMDESC_DICT[mem_type]

    for p_el in machine_el.find_children("physical_memory"): 
        if not ignore_name.match(p_el.name):
            mem = [(el.base, el.size, map_mem_type(el))
                   for el in p_el.find_children("region")]
            machine.add_physical_mem(p_el.name, mem)

    for v_el in machine_el.find_children("virtual_memory"): 
        if not ignore_name.match(v_el.name):
            mem = [(el.base, el.size, MEMDESC_UNDEFINED)
                   for el in v_el.find_children("region")]
            machine.add_virtual_mem(v_el.name, mem)

    dev_ns = namespace.root.get_namespace("dev")

    if dev_ns is None:
        raise MergeError, "Device namespace does not exist!"

    for d_el in machine_el.find_children("phys_device"):
        if not ignore_name.match(d_el.name):
            device = machine.add_phys_device(d_el.name)
            create_alias_cap(device, dev_ns)
            for p_el in d_el.find_children("physical_memory"):
                if not ignore_name.match(p_el.name):
                    mem = [(el.base, el.size, MEMDESC_RESERVED)
                           for el in p_el.find_children("region")]
                    device.add_physical_mem(p_el.name, mem)
            for i_el in d_el.find_children("interrupt"):
                if not ignore_name.match(i_el.name):
                    device.add_interrupt(i_el.name, i_el.number)

    # extra_func is set by extensions, so pylint incorrectly thinks
    # that it is not callable.
    #pylint: disable-msg=E1102
    if Machine_el.extra_func is not None:
        Machine_el.extra_func(machine_el, Machine_el, Kernel_el, RootProgram_el)