scripts: extract_dts_includes.py: refactor for better maintenance
Refactor for better maintenance and to ease future enhancements. Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
parent
ad150569b6
commit
08216f5ef4
8 changed files with 709 additions and 170 deletions
150
scripts/dts/extract/clocks.py
Normal file
150
scripts/dts/extract/clocks.py
Normal file
|
@ -0,0 +1,150 @@
|
|||
#
|
||||
# Copyright (c) 2018 Bobby Noelte
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from extract.globals import *
|
||||
from extract.directive import DTDirective
|
||||
|
||||
##
|
||||
# @brief Manage clocks related directives.
|
||||
#
|
||||
# Handles:
|
||||
# - clocks
|
||||
# directives.
|
||||
#
|
||||
class DTClocks(DTDirective):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _extract_consumer(self, node_address, yaml, clocks, names, defs, def_label):
|
||||
|
||||
clock_consumer = reduced[node_address]
|
||||
clock_consumer_compat = get_compat(node_address)
|
||||
clock_consumer_bindings = yaml[clock_consumer_compat]
|
||||
clock_consumer_label = self.get_node_label_string(node_address)
|
||||
|
||||
clock_index = 0
|
||||
clock_cell_index = 0
|
||||
nr_clock_cells = 0
|
||||
clock_provider_node_address = ''
|
||||
clock_provider = {}
|
||||
for cell in clocks:
|
||||
if clock_cell_index == 0:
|
||||
if cell not in phandles:
|
||||
raise Exception(
|
||||
("Could not find the clock provider node {} for clocks"
|
||||
" = {} in clock consumer node {}. Did you activate"
|
||||
" the clock node?. Last clock provider: {}.")
|
||||
.format(str(cell), str(clocks), node_address,
|
||||
str(clock_provider)))
|
||||
clock_provider_node_address = phandles[cell]
|
||||
clock_provider = reduced[clock_provider_node_address]
|
||||
clock_provider_compat = get_compat(clock_provider_node_address)
|
||||
clock_provider_bindings = yaml[clock_provider_compat]
|
||||
clock_provider_label = self.get_node_label_string( \
|
||||
clock_provider_node_address)
|
||||
nr_clock_cells = int(clock_provider['props'].get(
|
||||
'#clock-cells', 0))
|
||||
clock_cells_string = clock_provider_bindings.get(
|
||||
'cell_string', 'CLOCK')
|
||||
clock_cells_names = clock_provider_bindings.get(
|
||||
'#cells', ['ID', 'CELL1', "CELL2", "CELL3"])
|
||||
clock_cells = []
|
||||
else:
|
||||
clock_cells.append(cell)
|
||||
clock_cell_index += 1
|
||||
if clock_cell_index > nr_clock_cells:
|
||||
# clock consumer device - clocks info
|
||||
#####################################
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
|
||||
# Legacy clocks definitions by extract_cells
|
||||
for i, cell in enumerate(clock_cells):
|
||||
if i >= len(clock_cells_names):
|
||||
clock_cell_name = 'CELL{}'.format(i)
|
||||
else:
|
||||
clock_cell_name = clock_cells_names[i]
|
||||
if clock_cells_string == clock_cell_name:
|
||||
clock_label = self.get_label_string([
|
||||
clock_consumer_label, clock_cells_string,
|
||||
str(clock_index)])
|
||||
else:
|
||||
clock_label = self.get_label_string([
|
||||
clock_consumer_label, clock_cells_string,
|
||||
clock_cell_name, str(clock_index)])
|
||||
prop_def[clock_label] = str(cell)
|
||||
# alias
|
||||
if i < nr_clock_cells:
|
||||
# clocks info for first clock
|
||||
clock_alias_label = self.get_label_string([
|
||||
clock_consumer_label, clock_cells_string,
|
||||
clock_cell_name])
|
||||
prop_alias[clock_alias_label] = clock_label
|
||||
# Legacy clocks definitions by extract_controller
|
||||
clock_provider_label_str = clock_provider['props'].get('label',
|
||||
None)
|
||||
if clock_provider_label_str is not None:
|
||||
try:
|
||||
generation = clock_consumer_bindings['properties'][
|
||||
'clocks']['generation']
|
||||
except:
|
||||
generation = ''
|
||||
if 'use-prop-name' in generation:
|
||||
clock_cell_name = 'CLOCKS_CONTROLLER'
|
||||
else:
|
||||
clock_cell_name = 'CLOCK_CONTROLLER'
|
||||
if clock_index == 0 and \
|
||||
len(clocks) == (len(clock_cells) + 1):
|
||||
index = ''
|
||||
else:
|
||||
index = str(clock_index)
|
||||
clock_label = self.get_label_string([clock_consumer_label,
|
||||
clock_cell_name,
|
||||
index])
|
||||
prop_def[clock_label] = '"' + clock_provider_label_str + '"'
|
||||
if node_address in aliases:
|
||||
for alias in aliases[node_address]:
|
||||
clock_alias_label = self.get_label_string([
|
||||
alias, clock_cell_name, index])
|
||||
prop_alias[clock_alias_label] = clock_label
|
||||
|
||||
insert_defs(node_address, defs, prop_def, prop_alias)
|
||||
|
||||
clock_cell_index = 0
|
||||
clock_index += 1
|
||||
|
||||
##
|
||||
# @brief Extract clocks related directives
|
||||
#
|
||||
# @param node_address Address of node owning the clockxxx definition.
|
||||
# @param yaml YAML definition for the owning node.
|
||||
# @param prop clockxxx property name
|
||||
# @param names (unused)
|
||||
# @param[out] defs Property definitions for each node address
|
||||
# @param def_label Define label string of node owning the directive.
|
||||
#
|
||||
def extract(self, node_address, yaml, prop, names, defs, def_label):
|
||||
|
||||
properties = reduced[node_address]['props'][prop]
|
||||
|
||||
prop_list = []
|
||||
if not isinstance(properties, list):
|
||||
prop_list.append(properties)
|
||||
else:
|
||||
prop_list = list(properties)
|
||||
|
||||
if prop == 'clocks':
|
||||
# indicator for clock consumers
|
||||
self._extract_consumer(node_address, yaml, prop_list, names, defs, def_label)
|
||||
else:
|
||||
raise Exception(
|
||||
"DTClocks.extract called with unexpected directive ({})."
|
||||
.format(prop))
|
||||
|
||||
##
|
||||
# @brief Management information for clocks.
|
||||
clocks = DTClocks()
|
62
scripts/dts/extract/default.py
Normal file
62
scripts/dts/extract/default.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
#
|
||||
# Copyright (c) 2018 Bobby Noelte
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from extract.globals import *
|
||||
from extract.directive import DTDirective
|
||||
|
||||
##
|
||||
# @brief Manage directives in a default way.
|
||||
#
|
||||
class DTDefault(DTDirective):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
##
|
||||
# @brief Extract directives in a default way
|
||||
#
|
||||
# @param node_address Address of node owning the clockxxx definition.
|
||||
# @param yaml YAML definition for the owning node.
|
||||
# @param prop property name
|
||||
# @param names (unused)
|
||||
# @param[out] defs Property definitions for each node address
|
||||
# @param def_label Define label string of node owning the directive.
|
||||
#
|
||||
def extract(self, node_address, yaml, prop, names, defs, def_label):
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
prop_values = reduced[node_address]['props'][prop]
|
||||
|
||||
if isinstance(prop_values, list):
|
||||
for i, prop_value in enumerate(prop_values):
|
||||
prop_name = convert_string_to_label(prop)
|
||||
label = def_label + '_' + prop_name
|
||||
if isinstance(prop_value, str):
|
||||
prop_value = "\"" + prop_value + "\""
|
||||
prop_def[label + '_' + str(i)] = prop_value
|
||||
else:
|
||||
prop_name = convert_string_to_label(prop)
|
||||
label = def_label + '_' + prop_name
|
||||
|
||||
if prop_values == 'parent-label':
|
||||
prop_values = find_parent_prop(node_address, 'label')
|
||||
|
||||
if isinstance(prop_values, str):
|
||||
prop_values = "\"" + prop_values + "\""
|
||||
prop_def[label] = prop_values
|
||||
|
||||
# generate defs for node aliases
|
||||
if node_address in aliases:
|
||||
for i in aliases[node_address]:
|
||||
alias_label = convert_string_to_label(i)
|
||||
alias = alias_label + '_' + prop_name
|
||||
prop_alias[alias] = label
|
||||
|
||||
insert_defs(node_address, defs, prop_def, prop_alias)
|
||||
|
||||
##
|
||||
# @brief Management information for directives handled by default.
|
||||
default = DTDefault()
|
65
scripts/dts/extract/directive.py
Normal file
65
scripts/dts/extract/directive.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
#
|
||||
# Copyright (c) 2018 Bobby Noelte
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from .globals import *
|
||||
|
||||
##
|
||||
# @brief Base class for device tree directives
|
||||
#
|
||||
class DTDirective(object):
|
||||
|
||||
##
|
||||
# @brief Get a label string for a list of label sub-strings.
|
||||
#
|
||||
# Label sub-strings are concatenated by '_'.
|
||||
#
|
||||
# @param label List of label sub-strings
|
||||
# @return label string
|
||||
#
|
||||
@staticmethod
|
||||
def get_label_string(label):
|
||||
return convert_string_to_label(
|
||||
'_'.join(x.strip() for x in label if x.strip()))
|
||||
|
||||
|
||||
##
|
||||
# @brief Get label string for a node by address
|
||||
#
|
||||
# @param node_address Address of node
|
||||
# @return label string
|
||||
#
|
||||
@staticmethod
|
||||
def get_node_label_string(node_address):
|
||||
node = reduced[node_address]
|
||||
node_compat = get_compat(node_address)
|
||||
if node_compat is None:
|
||||
raise Exception(
|
||||
"No compatible property for node address {}."
|
||||
.format(node_address))
|
||||
label = convert_string_to_label(node_compat.upper())
|
||||
if '@' in node_address:
|
||||
label += '_' + node_address.split('@')[-1].upper()
|
||||
elif 'reg' in node['props']:
|
||||
label += '_' + hex(node['props']['reg'][0])[2:].zfill(8)
|
||||
else:
|
||||
label += convert_string_to_label(node_address.upper())
|
||||
return label
|
||||
|
||||
def __init__():
|
||||
pass
|
||||
|
||||
##
|
||||
# @brief Extract directive information.
|
||||
#
|
||||
# @param node_address Address of node issueuing the directive.
|
||||
# @param yaml YAML definition for the node.
|
||||
# @param prop Directive property name
|
||||
# @param names Names assigned to directive.
|
||||
# @param[out] defs Property definitions for each node address
|
||||
# @param def_label Define label string of node owning the directive.
|
||||
#
|
||||
def extract(self, node_address, yaml, prop, names, defs, def_label):
|
||||
pass
|
138
scripts/dts/extract/flash.py
Normal file
138
scripts/dts/extract/flash.py
Normal file
|
@ -0,0 +1,138 @@
|
|||
#
|
||||
# Copyright (c) 2018 Bobby Noelte
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from extract.globals import *
|
||||
from extract.directive import DTDirective
|
||||
|
||||
from extract.default import default
|
||||
from extract.reg import reg
|
||||
|
||||
##
|
||||
# @brief Manage flash directives.
|
||||
#
|
||||
class DTFlash(DTDirective):
|
||||
|
||||
def __init__(self):
|
||||
# Node of the flash
|
||||
self._flash_node = None
|
||||
|
||||
def _extract_partition(self, node_address, yaml, prop, names, defs, def_label):
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
node = reduced[node_address]
|
||||
|
||||
partition_name = node['props']['label']
|
||||
partition_sectors = node['props']['reg']
|
||||
|
||||
label_prefix = ["FLASH_AREA", partition_name]
|
||||
label = self.get_label_string(label_prefix + ["LABEL",])
|
||||
prop_def[label] = '"{}"'.format(partition_name)
|
||||
|
||||
index = 0
|
||||
while index < len(partition_sectors):
|
||||
sector_index = int(index/2)
|
||||
sector_start_offset = partition_sectors[index]
|
||||
sector_size = partition_sectors[index + 1]
|
||||
label = self.get_label_string(
|
||||
label_prefix + ["OFFSET", str(sector_index)])
|
||||
prop_def[label] = "{}".format(sector_start_offset)
|
||||
label = self.get_label_string(
|
||||
label_prefix + ["SIZE", str(sector_index)])
|
||||
prop_def[label] = "{}".format(sector_size)
|
||||
index += 2
|
||||
# alias sector 0
|
||||
label = self.get_label_string(label_prefix + ["OFFSET",])
|
||||
prop_alias[label] = self.get_label_string(
|
||||
label_prefix + ["OFFSET", '0'])
|
||||
label = self.get_label_string(label_prefix + ["SIZE",])
|
||||
prop_alias[label] = self.get_label_string(
|
||||
label_prefix + ["SIZE", '0'])
|
||||
|
||||
insert_defs(node_address, defs, prop_def, prop_alias)
|
||||
|
||||
def _extract_flash(self, node_address, yaml, prop, names, defs, def_label):
|
||||
load_defs = {}
|
||||
|
||||
if node_address == 'dummy-flash':
|
||||
# We will add addr/size of 0 for systems with no flash controller
|
||||
# This is what they already do in the Kconfig options anyway
|
||||
load_defs = {
|
||||
'CONFIG_FLASH_BASE_ADDRESS': 0,
|
||||
'CONFIG_FLASH_SIZE': 0
|
||||
}
|
||||
insert_defs(node_address, defs, load_defs, {})
|
||||
self._flash_base_address = 0
|
||||
return
|
||||
|
||||
self._flash_node = reduced[node_address]
|
||||
|
||||
flash_props = ["label", "write-block-size", "erase-block-size"]
|
||||
for prop in flash_props:
|
||||
if prop in self._flash_node['props']:
|
||||
default.extract(node_address, None, prop, None, defs, def_label)
|
||||
insert_defs(node_address, defs, load_defs, {})
|
||||
|
||||
#for address in reduced:
|
||||
# if address.startswith(node_address) and 'partition@' in address:
|
||||
# self._extract_partition(address, yaml, 'partition', None, defs, def_label)
|
||||
|
||||
def _extract_code_partition(self, node_address, yaml, prop, names, defs, def_label):
|
||||
load_defs = {}
|
||||
|
||||
if node_address == 'dummy-flash':
|
||||
node = None
|
||||
else:
|
||||
node = reduced[node_address]
|
||||
if self._flash_node is None:
|
||||
# No flash node scanned before-
|
||||
raise Exception(
|
||||
"Code partition '{}' {} without flash definition."
|
||||
.format(prop, node_address))
|
||||
|
||||
if node and node is not self._flash_node:
|
||||
# only compute the load offset if the code partition
|
||||
# is not the same as the flash base address
|
||||
load_offset = str(int(node['props']['reg'][0]) \
|
||||
- int(self._flash_node['props']['reg'][0]))
|
||||
load_defs['CONFIG_FLASH_LOAD_OFFSET'] = load_offset
|
||||
load_size = node['props']['reg'][1]
|
||||
load_defs['CONFIG_FLASH_LOAD_SIZE'] = load_size
|
||||
else:
|
||||
load_defs['CONFIG_FLASH_LOAD_OFFSET'] = 0
|
||||
load_defs['CONFIG_FLASH_LOAD_SIZE'] = 0
|
||||
|
||||
insert_defs(node_address, defs, load_defs, {})
|
||||
|
||||
##
|
||||
# @brief Extract flash
|
||||
#
|
||||
# @param node_address Address of node owning the
|
||||
# flash definition.
|
||||
# @param yaml YAML definition for the owning node.
|
||||
# @param prop compatible property name
|
||||
# @param names (unused)
|
||||
# @param[out] defs Property definitions for each node address
|
||||
# @param def_label Define label string of node owning the
|
||||
# compatible definition.
|
||||
#
|
||||
def extract(self, node_address, yaml, prop, names, defs, def_label):
|
||||
|
||||
if prop == 'zephyr,flash':
|
||||
# indicator for flash
|
||||
self._extract_flash(node_address, yaml, prop, names, defs, def_label)
|
||||
elif prop == 'zephyr,code-partition':
|
||||
# indicator for code_partition
|
||||
self._extract_code_partition(node_address, yaml, prop, names, defs, def_label)
|
||||
elif prop == 'reg':
|
||||
# indicator for partition
|
||||
self._extract_partition(node_address, yaml, prop, names, defs, def_label)
|
||||
else:
|
||||
raise Exception(
|
||||
"DTFlash.extract called with unexpected directive ({})."
|
||||
.format(prop))
|
||||
##
|
||||
# @brief Management information for flash.
|
||||
flash = DTFlash()
|
90
scripts/dts/extract/interrupts.py
Normal file
90
scripts/dts/extract/interrupts.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
#
|
||||
# Copyright (c) 2018 Bobby Noelte
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from extract.globals import *
|
||||
from extract.directive import DTDirective
|
||||
|
||||
##
|
||||
# @brief Manage interrupts directives.
|
||||
#
|
||||
class DTInterrupts(DTDirective):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _find_parent_irq_node(self, node_address):
|
||||
address = ''
|
||||
|
||||
for comp in node_address.split('/')[1:]:
|
||||
address += '/' + comp
|
||||
if 'interrupt-parent' in reduced[address]['props']:
|
||||
interrupt_parent = reduced[address]['props'].get(
|
||||
'interrupt-parent')
|
||||
|
||||
return phandles[interrupt_parent]
|
||||
|
||||
##
|
||||
# @brief Extract interrupts
|
||||
#
|
||||
# @param node_address Address of node owning the
|
||||
# interrupts definition.
|
||||
# @param yaml YAML definition for the owning node.
|
||||
# @param prop compatible property name
|
||||
# @param names (unused)
|
||||
# @param[out] defs Property definitions for each node address
|
||||
# @param def_label Define label string of node owning the
|
||||
# compatible definition.
|
||||
#
|
||||
def extract(self, node_address, yaml, prop, names, defs, def_label):
|
||||
|
||||
node = reduced[node_address]
|
||||
|
||||
try:
|
||||
props = list(node['props'].get(prop))
|
||||
except:
|
||||
props = [node['props'].get(prop)]
|
||||
|
||||
irq_parent = self._find_parent_irq_node(node_address)
|
||||
|
||||
l_base = def_label.split('/')
|
||||
index = 0
|
||||
|
||||
while props:
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
l_idx = [str(index)]
|
||||
|
||||
try:
|
||||
name = [convert_string_to_label(names.pop(0))]
|
||||
except:
|
||||
name = []
|
||||
|
||||
cell_yaml = yaml[get_compat(irq_parent)]
|
||||
l_cell_prefix = ['IRQ']
|
||||
|
||||
for i in range(reduced[irq_parent]['props']['#interrupt-cells']):
|
||||
l_cell_name = [cell_yaml['#cells'][i].upper()]
|
||||
if l_cell_name == l_cell_prefix:
|
||||
l_cell_name = []
|
||||
|
||||
l_fqn = '_'.join(l_base + l_cell_prefix + l_idx + l_cell_name)
|
||||
prop_def[l_fqn] = props.pop(0)
|
||||
if len(name):
|
||||
alias_list = l_base + l_cell_prefix + name + l_cell_name
|
||||
prop_alias['_'.join(alias_list)] = l_fqn
|
||||
|
||||
if node_address in aliases:
|
||||
for i in aliases[node_address]:
|
||||
alias_label = convert_string_to_label(i)
|
||||
alias_list = [alias_label] + l_cell_prefix + name + l_cell_name
|
||||
prop_alias['_'.join(alias_list)] = l_fqn
|
||||
|
||||
index += 1
|
||||
insert_defs(node_address, defs, prop_def, prop_alias)
|
||||
|
||||
##
|
||||
# @brief Management information for interrupts.
|
||||
interrupts = DTInterrupts()
|
73
scripts/dts/extract/pinctrl.py
Normal file
73
scripts/dts/extract/pinctrl.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
#
|
||||
# Copyright (c) 2018 Bobby Noelte
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from extract.globals import *
|
||||
from extract.directive import DTDirective
|
||||
|
||||
##
|
||||
# @brief Manage pinctrl-x directive.
|
||||
#
|
||||
class DTPinCtrl(DTDirective):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
##
|
||||
# @brief Extract pinctrl information.
|
||||
#
|
||||
# @param node_address Address of node owning the pinctrl definition.
|
||||
# @param yaml YAML definition for the owning node.
|
||||
# @param prop pinctrl-x key
|
||||
# @param names Names assigned to pinctrl state pinctrl-<index>.
|
||||
# @param[out] defs Property definitions for each node address
|
||||
# @param def_label Define label string of client node owning the pinctrl
|
||||
# definition.
|
||||
#
|
||||
def extract(self, node_address, yaml, prop, names, defs, def_label):
|
||||
|
||||
pinconf = reduced[node_address]['props'][prop]
|
||||
|
||||
prop_list = []
|
||||
if not isinstance(pinconf, list):
|
||||
prop_list.append(pinconf)
|
||||
else:
|
||||
prop_list = list(pinconf)
|
||||
|
||||
def_prefix = def_label.split('_')
|
||||
|
||||
prop_def = {}
|
||||
for p in prop_list:
|
||||
pin_node_address = phandles[p]
|
||||
pin_subnode = '/'.join(pin_node_address.split('/')[-1:])
|
||||
cell_yaml = yaml[get_compat(pin_node_address)]
|
||||
cell_prefix = 'PINMUX'
|
||||
post_fix = []
|
||||
|
||||
if cell_prefix is not None:
|
||||
post_fix.append(cell_prefix)
|
||||
|
||||
for subnode in reduced.keys():
|
||||
if pin_subnode in subnode and pin_node_address != subnode:
|
||||
# found a subnode underneath the pinmux handle
|
||||
pin_label = def_prefix + post_fix + subnode.split('/')[-2:]
|
||||
|
||||
for i, cells in enumerate(reduced[subnode]['props']):
|
||||
key_label = list(pin_label) + \
|
||||
[cell_yaml['#cells'][0]] + [str(i)]
|
||||
func_label = key_label[:-2] + \
|
||||
[cell_yaml['#cells'][1]] + [str(i)]
|
||||
key_label = convert_string_to_label('_'.join(key_label))
|
||||
func_label = convert_string_to_label('_'.join(func_label))
|
||||
|
||||
prop_def[key_label] = cells
|
||||
prop_def[func_label] = \
|
||||
reduced[subnode]['props'][cells]
|
||||
|
||||
insert_defs(node_address, defs, prop_def, {})
|
||||
|
||||
##
|
||||
# @brief Management information for pinctrl-[x].
|
||||
pinctrl = DTPinCtrl()
|
109
scripts/dts/extract/reg.py
Normal file
109
scripts/dts/extract/reg.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
#
|
||||
# Copyright (c) 2018 Bobby Noelte
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from extract.globals import *
|
||||
from extract.directive import DTDirective
|
||||
|
||||
##
|
||||
# @brief Manage reg directive.
|
||||
#
|
||||
class DTReg(DTDirective):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
##
|
||||
# @brief Extract reg directive info
|
||||
#
|
||||
# @param node_address Address of node owning the
|
||||
# reg definition.
|
||||
# @param yaml YAML definition for the owning node.
|
||||
# @param prop reg property name
|
||||
# @param names (unused)
|
||||
# @param[out] defs Property definitions for each node address
|
||||
# @param def_label Define label string of node owning the
|
||||
# compatible definition.
|
||||
#
|
||||
def extract(self, node_address, yaml, prop, names, defs, def_label):
|
||||
|
||||
node = reduced[node_address]
|
||||
node_compat = get_compat(node_address)
|
||||
|
||||
reg = reduced[node_address]['props']['reg']
|
||||
if type(reg) is not list: reg = [ reg ]
|
||||
props = list(reg)
|
||||
|
||||
address_cells = reduced['/']['props'].get('#address-cells')
|
||||
size_cells = reduced['/']['props'].get('#size-cells')
|
||||
address = ''
|
||||
for comp in node_address.split('/')[1:-1]:
|
||||
address += '/' + comp
|
||||
address_cells = reduced[address]['props'].get(
|
||||
'#address-cells', address_cells)
|
||||
size_cells = reduced[address]['props'].get('#size-cells', size_cells)
|
||||
|
||||
post_label = "BASE_ADDRESS"
|
||||
if yaml[node_compat].get('use-property-label', False):
|
||||
label = node['props'].get('label', None)
|
||||
if label:
|
||||
post_label = label
|
||||
|
||||
index = 0
|
||||
l_base = def_label.split('/')
|
||||
l_addr = [convert_string_to_label(post_label)]
|
||||
l_size = ["SIZE"]
|
||||
|
||||
while props:
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
addr = 0
|
||||
size = 0
|
||||
# Check is defined should be indexed (_0, _1)
|
||||
if index == 0 and len(props) < 3:
|
||||
# 1 element (len 2) or no element (len 0) in props
|
||||
l_idx = []
|
||||
else:
|
||||
l_idx = [str(index)]
|
||||
|
||||
try:
|
||||
name = [names.pop(0).upper()]
|
||||
except:
|
||||
name = []
|
||||
|
||||
for x in range(address_cells):
|
||||
addr += props.pop(0) << (32 * x)
|
||||
for x in range(size_cells):
|
||||
size += props.pop(0) << (32 * x)
|
||||
|
||||
l_addr_fqn = '_'.join(l_base + l_addr + l_idx)
|
||||
l_size_fqn = '_'.join(l_base + l_size + l_idx)
|
||||
if address_cells:
|
||||
prop_def[l_addr_fqn] = hex(addr)
|
||||
if size_cells:
|
||||
prop_def[l_size_fqn] = int(size)
|
||||
if len(name):
|
||||
if address_cells:
|
||||
prop_alias['_'.join(l_base + name + l_addr)] = l_addr_fqn
|
||||
if size_cells:
|
||||
prop_alias['_'.join(l_base + name + l_size)] = l_size_fqn
|
||||
|
||||
# generate defs for node aliases
|
||||
if node_address in aliases:
|
||||
for i in aliases[node_address]:
|
||||
alias_label = convert_string_to_label(i)
|
||||
alias_addr = [alias_label] + l_addr
|
||||
alias_size = [alias_label] + l_size
|
||||
prop_alias['_'.join(alias_addr)] = '_'.join(l_base + l_addr)
|
||||
prop_alias['_'.join(alias_size)] = '_'.join(l_base + l_size)
|
||||
|
||||
insert_defs(node_address, defs, prop_def, prop_alias)
|
||||
|
||||
# increment index for definition creation
|
||||
index += 1
|
||||
|
||||
##
|
||||
# @brief Management information for registers.
|
||||
reg = DTReg()
|
|
@ -18,6 +18,13 @@ import collections
|
|||
from devicetree import parse_file
|
||||
from extract.globals import *
|
||||
|
||||
from extract.clocks import clocks
|
||||
from extract.interrupts import interrupts
|
||||
from extract.reg import reg
|
||||
from extract.flash import flash
|
||||
from extract.pinctrl import pinctrl
|
||||
from extract.default import default
|
||||
|
||||
class Loader(yaml.Loader):
|
||||
def __init__(self, stream):
|
||||
self._root = os.path.realpath(stream.name)
|
||||
|
@ -57,63 +64,6 @@ class Loader(yaml.Loader):
|
|||
with open(filepath, 'r') as f:
|
||||
return yaml.load(f, Loader)
|
||||
|
||||
def find_parent_irq_node(node_address):
|
||||
address = ''
|
||||
|
||||
for comp in node_address.split('/')[1:]:
|
||||
address += '/' + comp
|
||||
if 'interrupt-parent' in reduced[address]['props']:
|
||||
interrupt_parent = reduced[address]['props'].get(
|
||||
'interrupt-parent')
|
||||
|
||||
return phandles[interrupt_parent]
|
||||
|
||||
def extract_interrupts(node_address, yaml, prop, names, defs, def_label):
|
||||
node = reduced[node_address]
|
||||
|
||||
try:
|
||||
props = list(node['props'].get(prop))
|
||||
except:
|
||||
props = [node['props'].get(prop)]
|
||||
|
||||
irq_parent = find_parent_irq_node(node_address)
|
||||
|
||||
l_base = def_label.split('/')
|
||||
index = 0
|
||||
|
||||
while props:
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
l_idx = [str(index)]
|
||||
|
||||
try:
|
||||
name = [convert_string_to_label(names.pop(0))]
|
||||
except:
|
||||
name = []
|
||||
|
||||
cell_yaml = yaml[get_compat(irq_parent)]
|
||||
l_cell_prefix = ['IRQ']
|
||||
|
||||
for i in range(reduced[irq_parent]['props']['#interrupt-cells']):
|
||||
l_cell_name = [cell_yaml['#cells'][i].upper()]
|
||||
if l_cell_name == l_cell_prefix:
|
||||
l_cell_name = []
|
||||
|
||||
l_fqn = '_'.join(l_base + l_cell_prefix + l_idx + l_cell_name)
|
||||
prop_def[l_fqn] = props.pop(0)
|
||||
if len(name):
|
||||
alias_list = l_base + l_cell_prefix + name + l_cell_name
|
||||
prop_alias['_'.join(alias_list)] = l_fqn
|
||||
|
||||
if node_address in aliases:
|
||||
for i in aliases[node_address]:
|
||||
alias_label = convert_string_to_label(i)
|
||||
alias_list = [alias_label] + l_cell_prefix + name + l_cell_name
|
||||
prop_alias['_'.join(alias_list)] = l_fqn
|
||||
|
||||
index += 1
|
||||
insert_defs(node_address, defs, prop_def, prop_alias)
|
||||
|
||||
|
||||
def extract_reg_prop(node_address, names, defs, def_label, div, post_label):
|
||||
|
||||
|
@ -325,50 +275,6 @@ def extract_cells(node_address, yaml, prop, prop_values, names, index, defs,
|
|||
index + 1, defs, def_label, generic)
|
||||
|
||||
|
||||
def extract_pinctrl(node_address, yaml, prop, names, index, defs,
|
||||
def_label):
|
||||
|
||||
pinconf = reduced[node_address]['props'][prop]
|
||||
|
||||
prop_list = []
|
||||
if not isinstance(pinconf, list):
|
||||
prop_list.append(pinconf)
|
||||
else:
|
||||
prop_list = list(pinconf)
|
||||
|
||||
def_prefix = def_label.split('_')
|
||||
|
||||
prop_def = {}
|
||||
for p in prop_list:
|
||||
pin_node_address = phandles[p]
|
||||
pin_subnode = '/'.join(pin_node_address.split('/')[-1:])
|
||||
cell_yaml = yaml[get_compat(pin_node_address)]
|
||||
cell_prefix = 'PINMUX'
|
||||
post_fix = []
|
||||
|
||||
if cell_prefix is not None:
|
||||
post_fix.append(cell_prefix)
|
||||
|
||||
for subnode in reduced.keys():
|
||||
if pin_subnode in subnode and pin_node_address != subnode:
|
||||
# found a subnode underneath the pinmux handle
|
||||
pin_label = def_prefix + post_fix + subnode.split('/')[-2:]
|
||||
|
||||
for i, cells in enumerate(reduced[subnode]['props']):
|
||||
key_label = list(pin_label) + \
|
||||
[cell_yaml['#cells'][0]] + [str(i)]
|
||||
func_label = key_label[:-2] + \
|
||||
[cell_yaml['#cells'][1]] + [str(i)]
|
||||
key_label = convert_string_to_label('_'.join(key_label))
|
||||
func_label = convert_string_to_label('_'.join(func_label))
|
||||
|
||||
prop_def[key_label] = cells
|
||||
prop_def[func_label] = \
|
||||
reduced[subnode]['props'][cells]
|
||||
|
||||
insert_defs(node_address, defs, prop_def, {})
|
||||
|
||||
|
||||
def extract_single(node_address, yaml, prop, key, defs, def_label):
|
||||
|
||||
prop_def = {}
|
||||
|
@ -470,24 +376,17 @@ def extract_property(node_compat, yaml, node_address, prop, prop_val, names,
|
|||
def_label += '_' + label_override
|
||||
|
||||
if prop == 'reg':
|
||||
extract_reg_prop(node_address, names, defs, def_label,
|
||||
1, prop_val.get('label', None))
|
||||
elif prop == 'interrupts' or prop == 'interupts-extended':
|
||||
extract_interrupts(node_address, yaml, prop, names, defs, def_label)
|
||||
if 'partition@' in node_address:
|
||||
# reg in partition is covered by flash handling
|
||||
flash.extract(node_address, yaml, prop, names, defs, def_label)
|
||||
else:
|
||||
reg.extract(node_address, yaml, prop, names, defs, def_label)
|
||||
elif prop == 'interrupts' or prop == 'interrupts-extended':
|
||||
interrupts.extract(node_address, yaml, prop, names, defs, def_label)
|
||||
elif 'pinctrl-' in prop:
|
||||
p_index = int(prop.split('-')[1])
|
||||
extract_pinctrl(node_address, yaml, prop,
|
||||
names[p_index], p_index, defs, def_label)
|
||||
pinctrl.extract(node_address, yaml, prop, names, defs, def_label)
|
||||
elif 'clocks' in prop:
|
||||
try:
|
||||
prop_values = list(reduced[node_address]['props'].get(prop))
|
||||
except:
|
||||
prop_values = reduced[node_address]['props'].get(prop)
|
||||
|
||||
extract_controller(node_address, yaml, prop, prop_values, 0, defs,
|
||||
def_label, 'clock')
|
||||
extract_cells(node_address, yaml, prop, prop_values,
|
||||
names, 0, defs, def_label, 'clock')
|
||||
clocks.extract(node_address, yaml, prop, names, defs, def_label)
|
||||
elif 'gpios' in prop:
|
||||
try:
|
||||
prop_values = list(reduced[node_address]['props'].get(prop))
|
||||
|
@ -499,9 +398,7 @@ def extract_property(node_compat, yaml, node_address, prop, prop_val, names,
|
|||
extract_cells(node_address, yaml, prop, prop_values,
|
||||
names, 0, defs, def_label, 'gpio')
|
||||
else:
|
||||
extract_single(node_address, yaml,
|
||||
reduced[node_address]['props'][prop], prop,
|
||||
defs, def_label)
|
||||
default.extract(node_address, yaml, prop, names, defs, def_label)
|
||||
|
||||
|
||||
def extract_node_include_info(reduced, root_node_address, sub_node_address,
|
||||
|
@ -782,16 +679,6 @@ def load_yaml_descriptions(dts, yaml_dir):
|
|||
return yaml_list
|
||||
|
||||
|
||||
def lookup_defs(defs, node, key):
|
||||
if node not in defs:
|
||||
return None
|
||||
|
||||
if key in defs[node]['aliases']:
|
||||
key = defs[node]['aliases'][key]
|
||||
|
||||
return defs[node].get(key, None)
|
||||
|
||||
|
||||
def generate_node_definitions(yaml_list):
|
||||
defs = {}
|
||||
structs = {}
|
||||
|
@ -813,46 +700,11 @@ def generate_node_definitions(yaml_list):
|
|||
if k in chosen:
|
||||
extract_string_prop(chosen[k], None, "label", v, defs)
|
||||
|
||||
# This should go away via future DTDirective class
|
||||
if 'zephyr,flash' in chosen:
|
||||
load_defs = {}
|
||||
node_addr = chosen['zephyr,flash']
|
||||
flash_keys = ["label", "write-block-size", "erase-block-size"]
|
||||
|
||||
for key in flash_keys:
|
||||
if key in reduced[node_addr]['props']:
|
||||
prop = reduced[node_addr]['props'][key]
|
||||
extract_single(node_addr, None, prop, key, defs, "FLASH")
|
||||
|
||||
# only compute the load offset if a code partition exists and
|
||||
# it is not the same as the flash base address
|
||||
if 'zephyr,code-partition' in chosen and \
|
||||
reduced[chosen['zephyr,flash']] is not \
|
||||
reduced[chosen['zephyr,code-partition']]:
|
||||
part_defs = {}
|
||||
extract_reg_prop(chosen['zephyr,code-partition'], None,
|
||||
part_defs, "PARTITION", 1, 'offset')
|
||||
part_base = lookup_defs(part_defs,
|
||||
chosen['zephyr,code-partition'],
|
||||
'PARTITION_OFFSET')
|
||||
load_defs['CONFIG_FLASH_LOAD_OFFSET'] = part_base
|
||||
load_defs['CONFIG_FLASH_LOAD_SIZE'] = \
|
||||
lookup_defs(part_defs,
|
||||
chosen['zephyr,code-partition'],
|
||||
'PARTITION_SIZE')
|
||||
else:
|
||||
load_defs['CONFIG_FLASH_LOAD_OFFSET'] = 0
|
||||
load_defs['CONFIG_FLASH_LOAD_SIZE'] = 0
|
||||
else:
|
||||
# We will add addr/size of 0 for systems with no flash controller
|
||||
# This is what they already do in the Kconfig options anyway
|
||||
defs['dummy-flash'] = {
|
||||
'CONFIG_FLASH_BASE_ADDRESS': 0,
|
||||
'CONFIG_FLASH_SIZE': 0
|
||||
}
|
||||
|
||||
if 'zephyr,flash' in chosen:
|
||||
insert_defs(chosen['zephyr,flash'], defs, load_defs, {})
|
||||
node_address = chosen.get('zephyr,flash', 'dummy-flash')
|
||||
flash.extract(node_address, yaml_list, 'zephyr,flash', None, defs, 'FLASH')
|
||||
node_address = chosen.get('zephyr,code-partition', node_address)
|
||||
flash.extract(node_address, yaml_list, 'zephyr,code-partition', None,
|
||||
defs, 'FLASH')
|
||||
|
||||
return defs
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue