Skip to content

Commit

Permalink
python: simplify memory management scripts
Browse files Browse the repository at this point in the history
- merge functions to simplify control flow
- clarify variable names
- add comments
- Improve code readability

Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
axel-h committed Feb 3, 2022
1 parent e5e32ad commit c89c284
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 159 deletions.
129 changes: 55 additions & 74 deletions tools/hardware/outputs/c_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
import hardware
from hardware.config import Config
from hardware.fdt import FdtParser
from hardware.utils.rule import HardwareYaml
from hardware.memory import Region
from hardware.utils.rule import HardwareYaml, KernelInterrupt


HEADER_TEMPLATE = '''/*
Expand Down Expand Up @@ -48,7 +49,7 @@
#define {{ irq.label }} {{ irq.irq }}
{% if irq.has_sel() %}
#else
#define {{ irq.label }} {{ irq.false_irq }}
#define {{ irq.label }} {{ irq.false_irq }} /* dummy value */
{{ irq.get_sel_endif() }}
{% endif %}
{% if irq.has_enable() %}
Expand All @@ -57,7 +58,7 @@
{% endfor -%}
/* KERNEL DEVICES */
{% for (addr, macro) in sorted(kernel_macros.items()) %}
{% for (macro, addr) in kernel_dev_addr_macros %}
#define {{ macro }} (KDEV_BASE + {{ "0x{:x}".format(addr) }})
{% endfor %}
Expand All @@ -67,17 +68,13 @@
{% if group.has_macro() %}
{{ group.get_macro() }}
{% endif %}
/* {{ group.get_desc() }} */
/* {{ group.get_desc() }}
* contains {{ ', '.join(group.labels.keys()) }}
*/
{% for reg in group.regions %}
{
.paddr = {{ "0x{:x}".format(reg.base) }},
{% set map_addr = group.get_map_offset(reg) %}
{% if map_addr in kernel_macros %}
.pptr = {{ kernel_macros[map_addr] }},
{% else %}
/* contains {{ ', '.join(group.labels.keys()) }} */
.pptr = KDEV_BASE + {{ "0x{:x}".format(map_addr) }},
{% endif %}
.pptr = KDEV_BASE + {{ "0x{:x}".format(group.get_map_offset(reg)) }},
{% if config.arch == 'arm' %}
.armExecuteNever = true,
{% endif %}
Expand Down Expand Up @@ -122,64 +119,10 @@
'''


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)


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


def create_c_header_file(config, kernel_irqs: List, kernel_macros: Dict,
kernel_regions: List, physBase: int, physical_memory,
outputStream):

def create_c_header_file(config, kernel_irqs: List[KernelInterrupt],
kernel_dev_addr_macros: Dict[str, int],
kernel_regions: List[Region], physBase: int,
physical_memory: List[Region], outputStream):
jinja_env = jinja2.Environment(loader=jinja2.BaseLoader, trim_blocks=True,
lstrip_blocks=True)

Expand All @@ -189,7 +132,7 @@ def create_c_header_file(config, kernel_irqs: List, kernel_macros: Dict,
**{
'config': config,
'kernel_irqs': kernel_irqs,
'kernel_macros': kernel_macros,
'kernel_dev_addr_macros': kernel_dev_addr_macros,
'kernel_regions': kernel_regions,
'physBase': physBase,
'physical_memory': physical_memory})
Expand All @@ -203,13 +146,51 @@ def run(tree: FdtParser, hw_yaml: HardwareYaml, config: Config, args: argparse.N
if not args.header_out:
raise ValueError('You need to specify a header-out to use c header output')

physical_memory, reserved, physBase = hardware.utils.memory.get_physical_memory(tree, config)
kernel_regions, kernel_macros = get_kernel_devices(tree, hw_yaml)
# We only care about the available physical memory and the kernel's phys
# base. The device memory regions are not relevant here.
physical_memory, _, physBase = hardware.utils.memory.get_phys_mem_regions(tree,
config,
hw_yaml)

# Collect the interrupts and kernel regions for the devices.
kernel_irq_dict = {} # dict of 'label:irq_obj'
kernel_regions = [] # list of Regions.
for dev in tree.get_kernel_devices():
dev_rule = hw_yaml.get_rule(dev)

if len(dev_rule.interrupts.items()) > 0:
for irq in dev_rule.get_interrupts(tree, dev):
# Add the interrupt if it does not exists or overwrite an
# existing entry if the priority for this device is higher
if (not irq.label in kernel_irq_dict) or \
(irq.prio > kernel_irq_dict[irq.label].prio):
kernel_irq_dict[irq.label] = irq

for reg in dev_rule.get_regions(dev):
existing_reg = next((r for r in kernel_regions if r == reg), None)
if existing_reg:
existing_reg.take_labels(reg)
else:
kernel_regions.append(reg)

# Build a dict of 'label: offset' entries, 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_dev_addr_macros = {}
kernel_offset = 0
for group in kernel_regions:
kernel_offset = group.set_kernel_offset(kernel_offset)
for (offset, label) in group.get_labelled_addresses().items():
if label in kernel_dev_addr_macros:
raise ValueError(
'"{} = 0x{:x}" already exists, cannot change to 0x{:x}'.format(
label, kernel_dev_addr_macros[label], offset))
kernel_dev_addr_macros[label] = offset

create_c_header_file(
config,
get_interrupts(tree, hw_yaml),
kernel_macros,
sorted(kernel_irq_dict.values(), key=lambda irq: irq.label),
sorted(kernel_dev_addr_macros.items(), key=lambda tupel: tupel[1]),
kernel_regions,
physBase,
physical_memory,
Expand Down
24 changes: 7 additions & 17 deletions tools/hardware/outputs/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from hardware.config import Config
from hardware.fdt import FdtParser
from hardware.memory import Region
from hardware.utils.rule import HardwareYaml
from hardware.utils.rule import HardwareYaml, KernelInterrupt


def make_yaml_list_of_regions(regions: List[Region]) -> List:
Expand Down Expand Up @@ -41,26 +41,16 @@ def create_yaml_file(regions_dict: Dict[str, List[Region]], outputStream):
outputStream)


def get_kernel_devices(tree: FdtParser, hw_yaml: HardwareYaml):
kernel_devices = tree.get_kernel_devices()
def run(tree: FdtParser, hw_yaml: HardwareYaml, config: Config, args: argparse.Namespace):

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

return groups


def run(tree: FdtParser, hw_yaml: HardwareYaml, config: Config,
args: argparse.Namespace):
if not args.yaml_out:
raise ValueError('you need to provide a yaml-out to use the yaml output method')

phys_mem, reserved, _ = hardware.utils.memory.get_physical_memory(tree, config)
kernel_devs = get_kernel_devices(tree, hw_yaml)
dev_mem = hardware.utils.memory.get_addrspace_exclude(
list(reserved) + phys_mem + kernel_devs, config)
# Get the physical memory and device regions, we don't care about the kernel
# phy_base address here.
phys_mem, dev_mem, _ = hardware.utils.memory.get_phys_mem_regions(tree,
config,
hw_yaml)

create_yaml_file(
{
Expand Down
Loading

0 comments on commit c89c284

Please sign in to comment.