Skip to content

Commit

Permalink
scripts/dts/extract: Add support for translating range properties
Browse files Browse the repository at this point in the history
For now we've used range properties as a pass through.  However range
properties can translate from one address space to another.  This is
typically used one address spaces translate from one physical bus to
another (For example going from PCI address space to internal SoC memory
map).  However, we can also use this for cases where we want to reduce
duplication (For example with ARMv8-M for secure v non-secure MMIO
registers).

'ranges' takes either the form of:
	ranges; /* pass through translation */
or:
	ranges = <child-bus-address parent-bus-address length>;

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
  • Loading branch information
galak committed Oct 5, 2018
1 parent 773b21a commit c922788
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
49 changes: 47 additions & 2 deletions scripts/dts/extract/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#

from collections import defaultdict
from copy import deepcopy

# globals
phandles = {}
Expand Down Expand Up @@ -167,8 +168,16 @@ def get_reduced(nodes, path):
def get_node_label(node_compat, node_address):
def_label = convert_string_to_label(node_compat)
if '@' in node_address:
def_label += '_' + \
convert_string_to_label(node_address.split('@')[-1])
# See if we have number we can convert
try:
unit_addr = int(node_address.split('@')[-1], 16)
(nr_addr_cells, nr_size_cells) = get_addr_size_cells(node_address)
unit_addr += translate_addr(unit_addr, node_address,
nr_addr_cells, nr_size_cells)
unit_addr = "%x" % unit_addr
except:
unit_addr = node_address.split('@')[-1]
def_label += '_' + convert_string_to_label(unit_addr)
else:
def_label += '_' + \
convert_string_to_label(node_address.split('/')[-1])
Expand Down Expand Up @@ -206,3 +215,39 @@ def get_addr_size_cells(node_address):
nr_size = reduced[parent_addr]['props'].get('#size-cells', 1)

return (nr_addr, nr_size)

def translate_addr(addr, node_address, nr_addr_cells, nr_size_cells):

try:
ranges = deepcopy(find_parent_prop(node_address, 'ranges'))
if type(ranges) is not list: ranges = [ ]
except:
return 0

parent_address = get_parent_address(node_address)

(nr_p_addr_cells, nr_p_size_cells) = get_addr_size_cells(parent_address)

range_offset = 0
while ranges:
child_bus_addr = 0
parent_bus_addr = 0
range_len = 0
for x in range(nr_addr_cells):
val = ranges.pop(0) << (32 * (nr_addr_cells - x - 1))
child_bus_addr += val
for x in range(nr_p_addr_cells):
val = ranges.pop(0) << (32 * (nr_p_addr_cells - x - 1))
parent_bus_addr += val
for x in range(nr_size_cells):
range_len += ranges.pop(0) << (32 * (nr_size_cells - x - 1))
# if we are outside of the range we don't need to translate
if child_bus_addr <= addr <= (child_bus_addr + range_len):
range_offset = parent_bus_addr - child_bus_addr
break

parent_range_offset = translate_addr(addr + range_offset,
parent_address, nr_p_addr_cells, nr_p_size_cells)
range_offset += parent_range_offset

return range_offset
3 changes: 3 additions & 0 deletions scripts/dts/extract/reg.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ def extract(self, node_address, yaml, names, def_label, div):
for x in range(nr_size_cells):
size += props.pop(0) << (32 * (nr_size_cells - x - 1))

addr += translate_addr(addr, node_address,
nr_address_cells, nr_size_cells)

l_addr_fqn = '_'.join(l_base + l_addr + l_idx)
l_size_fqn = '_'.join(l_base + l_size + l_idx)
if nr_address_cells:
Expand Down

0 comments on commit c922788

Please sign in to comment.