Ejemplo n.º 1
0
def get_memory_regions(tree: FdtParser):
    ''' Get all regions with device_type = memory in the tree '''
    regions = set()

    def visitor(node: WrappedNode):
        if node.has_prop('device_type') and node.get_prop(
                'device_type').strings[0] == 'memory':
            regions.update(node.get_regions())

    tree.visit(visitor)
    return regions
Ejemplo n.º 2
0
def get_kernel_devices(tree: FdtParser, hw_yaml: HardwareYaml) -> (List, Dict):
    '''
    Given a device tree and a set of rules, returns a tuple (groups, offsets).

    Groups is a list of 'KernelRegionGroups', each of which represents a single
    contiguous region of memory that is associated with a device.
    Offsets is a dict of offset -> label, where label is the name given to the
    kernel for that address (e.g. SERIAL_PPTR) and offset is the offset from
    KDEV_BASE at which it's mapped.
    '''
    kernel_devices = tree.get_kernel_devices()

    kernel_offset = 0
    groups = []
    for dev in kernel_devices:
        dev_rule = hw_yaml.get_rule(dev)
        new_regions = dev_rule.get_regions(dev)
        for reg in new_regions:
            if reg in groups:
                other = groups[groups.index(reg)]
                other.take_labels(reg)
            else:
                groups.append(reg)

    offsets = {}
    for group in groups:
        kernel_offset = group.set_kernel_offset(kernel_offset)
        offsets.update(group.get_labelled_addresses())
    return (groups, offsets)
Ejemplo n.º 3
0
def run(tree: fdt.FdtParser, hardware: rule.HardwareYaml,
        config: config.Config, args: argparse.Namespace):
    devices = tree.get_elfloader_devices()
    cpu_info = get_elfloader_cpus(tree, devices)

    max_reg = 1
    device_info = []
    for dev in devices:
        obj = {
            'compat': hardware.get_matched_compatible(dev),
            'path': dev.path,
            'regions': dev.get_regions()
        }
        max_reg = max(len(obj['regions']), max_reg)

        device_info.append(obj)

    device_info.sort(key=lambda a: a['compat'])

    template = Environment(loader=BaseLoader,
                           trim_blocks=True,
                           lstrip_blocks=True).from_string(HEADER_TEMPLATE)

    template_args = dict(
        builtins.__dict__, **{
            'cpus': cpu_info,
            'devices': device_info,
            'max_reg': max_reg,
            'uses_psci': any([c['enable_method'] == 'psci' for c in cpu_info])
        })

    data = template.render(template_args)
    args.elfloader_out.write(data)
    args.elfloader_out.close()
Ejemplo n.º 4
0
    def get_interrupts(self, tree: FdtParser, node: WrappedNode) -> List[KernelInterrupt]:
        ''' Returns a list of KernelInterrupts that this rule says are used by the kernel for this device. '''
        ret = []
        interrupts = node.get_interrupts(tree)

        for name, rule in self.interrupts.items():
            irq_desc = '{} generated from {}'.format(name, node.path)
            if type(rule) == dict:
                en_macro = rule.get('enable_macro', None)
                if rule['index'] >= len(interrupts):
                    # XXX: skip this rule silently.
                    continue
                defaultIrq = interrupts[rule['index']]
                sel_macro = rule.get('sel_macro', None)
                falseIrq = interrupts[rule['undef_index']] if 'undef_index' in rule else -1
                prio = rule.get('priority', 0)
                irq = KernelInterrupt(name, defaultIrq, prio, sel_macro,
                                      falseIrq, en_macro, desc=irq_desc)
            elif type(rule) == int:
                if rule >= len(interrupts):
                    # XXX: skip this rule silently.
                    continue
                irq = KernelInterrupt(name, interrupts[rule], desc=irq_desc)
            else:  # rule == 'boot-cpu'
                affinities = node.get_interrupt_affinities()
                boot_cpu = tree.get_boot_cpu()
                idx = affinities.index(boot_cpu)
                irq = KernelInterrupt(name, interrupts[idx])
            ret.append(irq)
        return ret
Ejemplo n.º 5
0
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)
    reserved = parse_reserved_regions(tree.get_path('/reserved-memory'))
    regions = reserve_regions(regions, reserved)
    regions, extra_reserved, physBase = align_memory(regions, config)

    return regions, reserved.union(extra_reserved), physBase
Ejemplo n.º 6
0
def get_elfloader_devices(tree: fdt.FdtParser, rules: rule.HardwareYaml):
    devices = []

    # serial device
    chosen = tree.get_path('/chosen')
    if not chosen.has_prop('stdout-path') or type(
            chosen.get_prop('stdout-path')) != pyfdt.pyfdt.FdtPropertyStrings:
        logging.info(
            'DT has no stdout-path, elfloader may not produce output!')
    else:
        val = chosen.get_prop('stdout-path').strings[0]
        if val[0] == '/':
            path = val
        else:
            path = tree.lookup_alias(val)
        devices.append(tree.get_path(path))
    return devices
Ejemplo n.º 7
0
def get_kernel_devices(tree: fdt.FdtParser, rules: rule.HardwareYaml):
    kernel_devices = tree.get_kernel_devices()

    groups = []
    for dev in kernel_devices:
        rule = rules.get_rule(dev)
        groups += rule.get_regions(dev)

    return groups
Ejemplo n.º 8
0
def get_kernel_devices(tree: FdtParser, hw_yaml: HardwareYaml):
    kernel_devices = tree.get_kernel_devices()

    groups = []
    for dev in kernel_devices:
        rule = hw_yaml.get_rule(dev)
        groups += rule.get_regions(dev)

    return groups
Ejemplo n.º 9
0
def get_cpus(tree: FdtParser) -> List[WrappedNode]:
    ' Return a list of all the CPUs described in this device tree. '
    cpus_node = tree.get_path('/cpus')

    found_cpus = []
    for node in cpus_node:
        if node.has_prop('device_type') and node.get_prop('device_type').strings[0] == 'cpu':
            found_cpus.append(node)

    return found_cpus
Ejemplo n.º 10
0
def main(args: argparse.Namespace):
    ''' Parse the DT and hardware config YAML and run each
    selected output method. '''
    cfg = hardware.config.get_arch_config(args.sel4arch, args.addrspace_max)
    parsed_dt = FdtParser(args.dtb)
    rules = yaml.load(args.hardware_config, Loader=yaml.FullLoader)
    schema = yaml.load(args.hardware_schema, Loader=yaml.FullLoader)
    validate_rules(rules, schema)
    hw_yaml = HardwareYaml(rules, cfg)

    arg_dict = vars(args)
    for t in sorted(OUTPUTS.keys()):
        if arg_dict[t]:
            OUTPUTS[t].run(parsed_dt, hw_yaml, cfg, args)
Ejemplo n.º 11
0
def run(tree: FdtParser, hw_yaml: HardwareYaml, config: Config,
        args: argparse.Namespace):
    if not args.compat_strings_out:
        raise ValueError(
            'You need to specify a compat-strings-out to use compat strings output'
        )
    chosen = tree.get_kernel_devices()

    compatibles = set()
    for dev in chosen:
        compatibles.add(hw_yaml.get_matched_compatible(dev))

    args.compat_strings_out.write(';'.join(sorted(compatibles)) + ';\n')
    args.compat_strings_out.close()
Ejemplo n.º 12
0
def get_interrupts(tree: FdtParser, hw_yaml: HardwareYaml) -> List:
    ''' Get dict of interrupts, {label: KernelInterrupt} from the DT and hardware rules. '''
    kernel_devices = tree.get_kernel_devices()

    irqs = []
    for dev in kernel_devices:
        dev_rule = hw_yaml.get_rule(dev)
        if len(dev_rule.interrupts.items()) > 0:
            irqs += dev_rule.get_interrupts(tree, dev)

    ret = {}
    for irq in irqs:
        if irq.label in ret:
            if irq.prio > ret[irq.label].prio:
                ret[irq.label] = irq
        else:
            ret[irq.label] = irq

    ret = list(ret.values())
    ret.sort(key=lambda a: a.label)
    return ret
Ejemplo n.º 13
0
def get_interrupts(tree: fdt.FdtParser, rules: rule.HardwareYaml):
    ''' Get dict of interrupts, {label: KernelInterrupt} from the DT and hardware rules. '''
    kernel_devices = tree.get_kernel_devices()

    irqs = []
    for dev in kernel_devices:
        dev_rule = rules.get_rule(dev)
        print(f"interrupts for device {dev.path}")
        irqs += dev_rule.get_interrupts(tree, dev)

    ret = {}
    for irq in irqs:
        if irq.label in ret:
            if irq.prio > ret[irq.label].prio:
                ret[irq.label] = irq
        else:
            ret[irq.label] = irq

    ret = list(ret.values())
    ret.sort(key=lambda a: a.label)
    return ret