1#
2# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3#
4# SPDX-License-Identifier: GPL-2.0-only
5#
6
7''' generate a yaml file with memory region info from the device tree '''
8
9import argparse
10import yaml
11from typing import List
12import hardware
13from hardware.config import Config
14from hardware.fdt import FdtParser
15from hardware.utils.rule import HardwareYaml
16
17
18def make_yaml_list_of_regions(regions) -> List:
19    return [
20        {
21            'start': r.base,
22            'end':   r.base + r.size
23        }
24        for r in regions if r.size > 0
25    ]
26
27
28def create_yaml_file(dev_mem, phys_mem, outputStream):
29
30    yaml.add_representer(
31        int,
32        lambda dumper, data: yaml.ScalarNode('tag:yaml.org,2002:int', hex(data)))
33
34    yaml_obj = {
35        'devices': make_yaml_list_of_regions(dev_mem),
36        'memory':  make_yaml_list_of_regions(phys_mem)
37    }
38
39    with outputStream:
40        yaml.dump(yaml_obj, outputStream)
41
42
43def get_kernel_devices(tree: FdtParser, hw_yaml: HardwareYaml):
44    kernel_devices = tree.get_kernel_devices()
45
46    groups = []
47    for dev in kernel_devices:
48        rule = hw_yaml.get_rule(dev)
49        groups += rule.get_regions(dev)
50
51    return groups
52
53
54def run(tree: FdtParser, hw_yaml: HardwareYaml, config: Config,
55        args: argparse.Namespace):
56    if not args.yaml_out:
57        raise ValueError('you need to provide a yaml-out to use the yaml output method')
58
59    phys_mem, reserved, _ = hardware.utils.memory.get_physical_memory(tree, config)
60    kernel_devs = get_kernel_devices(tree, hw_yaml)
61    dev_mem = hardware.utils.memory.get_addrspace_exclude(
62        list(reserved) + phys_mem + kernel_devs, config)
63
64    create_yaml_file(dev_mem, phys_mem, args.yaml_out)
65
66
67def add_args(parser):
68    parser.add_argument('--yaml-out', help='output file for memory yaml',
69                        type=argparse.FileType('w'))
70