Skip to content

Commit d14abb9

Browse files
committed
[dtgen] Support IPs without a regblock
Signed-off-by: Robert Schilling <[email protected]>
1 parent 6e53d12 commit d14abb9

File tree

4 files changed

+49
-35
lines changed

4 files changed

+49
-35
lines changed

util/dtgen/dt_ip.c.tpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@ dt_instance_id_t dt_${device_name}_instance_id(
6060
return TRY_GET_DT(dt, kDtInstanceIdUnknown)->inst_id;
6161
}
6262

63+
% if helper.has_reg_blocks():
6364
uint32_t dt_${device_name}_reg_block(
6465
dt_${device_name}_t dt,
6566
dt_${device_name}_reg_block_t reg_block) {
6667
// Return a recognizable address in case of wrong argument.
6768
return TRY_GET_DT(dt, 0xdeadbeef)->reg_addr[reg_block];
6869
}
6970

71+
% endif
7072
uint32_t dt_${device_name}_memory_base(
7173
dt_${device_name}_t dt,
7274
dt_${device_name}_memory_t mem) {

util/dtgen/dt_ip.h.tpl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,29 @@ ${helper.render_extension(Extension.DtIpPos.HeaderIncludes)}
3838
*/
3939
${helper.inst_enum.render()}
4040

41+
% if helper.has_reg_blocks():
4142
/**
4243
* List of register blocks.
4344
*
4445
* Register blocks are guaranteed to start at 0 and to be consecutively numbered.
4546
*/
4647
${helper.reg_block_enum.render()}
4748

48-
/**
49-
* List of memories.
50-
*
51-
* Memories are guaranteed to start at 0 and to be consecutively numbered.
52-
*/
53-
${helper.memory_enum.render()}
54-
5549
/** Primary register block (associated with the "primary" set of registers that control the IP). */
5650
<%
5751
default_reg_block_name = (helper.reg_block_enum.name + Name(["primary"])).as_c_enum()
5852
default_reg_block_value = (helper.reg_block_enum.name + Name.from_snake_case(helper.default_node)).as_c_enum()
5953
%>\
6054
static const ${helper.reg_block_enum.name.as_c_type()} ${default_reg_block_name} = ${default_reg_block_value};
6155

56+
% endif
57+
/**
58+
* List of memories.
59+
*
60+
* Memories are guaranteed to start at 0 and to be consecutively numbered.
61+
*/
62+
${helper.memory_enum.render()}
63+
6264
% if helper.has_irqs():
6365
/**
6466
* List of IRQs.
@@ -151,6 +153,7 @@ dt_${device_name}_t dt_${device_name}_from_instance_id(dt_instance_id_t inst_id)
151153
*/
152154
dt_instance_id_t dt_${device_name}_instance_id(dt_${device_name}_t dt);
153155

156+
% if helper.has_reg_blocks():
154157
/**
155158
* Get the register base address of an instance.
156159
*
@@ -176,6 +179,7 @@ static inline uint32_t dt_${device_name}_primary_reg_block(
176179
return dt_${device_name}_reg_block(dt, ${default_reg_block_value});
177180
}
178181

182+
% endif
179183
/**
180184
* Get the base address of a memory.
181185
*

util/dtgen/helper.py

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -675,8 +675,10 @@ def _init_reg_blocks(self):
675675
else:
676676
reg_blocks.append(rb)
677677

678-
assert self.default_node in reg_blocks, \
679-
"default node ({}) is invalid".format(self.default_node)
678+
# If there are no register blocks, we don't need to validate default_node
679+
if reg_blocks:
680+
assert self.default_node in reg_blocks, \
681+
"default node ({}) is invalid".format(self.default_node)
680682

681683
self.reg_block_enum = self._enum_type(
682684
Name([]), Name(["dt"]) + self.ip_name + Name(["reg", "block"]))
@@ -881,6 +883,9 @@ def _init_instances(self):
881883
self.inst_enum.add_first_constant("First instance")
882884
self.inst_enum.add_count_constant("Number of instances")
883885

886+
def has_reg_blocks(self):
887+
return len(self.ip.reg_blocks) > 0
888+
884889
def has_features(self):
885890
return len(self.ip.features) > 0
886891

@@ -897,15 +902,16 @@ def _create_dt_struct(self):
897902
field_type = ScalarType(TopHelper.DT_INSTANCE_ID_NAME),
898903
docstring = "Instance ID"
899904
)
900-
self.inst_struct.add_field(
901-
name = self.REG_BLOCK_ADDR_FIELD_NAME,
902-
field_type = ArrayMapType(
903-
elem_type = ScalarType("uint32_t"),
904-
index_type = ScalarType(self.reg_block_enum.name),
905-
length = Name(["count"]),
906-
),
907-
docstring = "Base address of each register block"
908-
)
905+
if self.has_reg_blocks():
906+
self.inst_struct.add_field(
907+
name = self.REG_BLOCK_ADDR_FIELD_NAME,
908+
field_type = ArrayMapType(
909+
elem_type = ScalarType("uint32_t"),
910+
index_type = ScalarType(self.reg_block_enum.name),
911+
length = Name(["count"]),
912+
),
913+
docstring = "Base address of each register block"
914+
)
909915
self.inst_struct.add_field(
910916
name = self.MEM_ADDR_FIELD_NAME,
911917
field_type = ArrayMapType(
@@ -997,19 +1003,20 @@ def _create_instance(self, m):
9971003
# Instance ID.
9981004
inst_desc[self.INST_ID_FIELD_NAME] = Name.from_snake_case(modname)
9991005
# Reg block address map.
1000-
reg_block_map = OrderedDict()
1001-
for rb in self.ip.reg_blocks.keys():
1002-
rb_key = rb
1003-
if rb is None:
1004-
rb = self.UNNAMED_REG_BLOCK_NAME
1005-
rb_key = "null" # Due to json serializing, None appears as null.
1006-
rb = Name.from_snake_case(rb)
1007-
# It is possible that this module is not accessible in this
1008-
# address space. In this case, return a dummy value.
1009-
# FIXME Maybe find a better way of doing this.
1010-
assert rb_key in m["base_addrs"]
1011-
reg_block_map[rb] = m["base_addrs"][rb_key].get(self._addr_space, "0xffffffff")
1012-
inst_desc[self.REG_BLOCK_ADDR_FIELD_NAME] = reg_block_map
1006+
if self.has_reg_blocks():
1007+
reg_block_map = OrderedDict()
1008+
for rb in self.ip.reg_blocks.keys():
1009+
rb_key = rb
1010+
if rb is None:
1011+
rb = self.UNNAMED_REG_BLOCK_NAME
1012+
rb_key = "null" # Due to json serializing, None appears as null.
1013+
rb = Name.from_snake_case(rb)
1014+
# It is possible that this module is not accessible in this
1015+
# address space. In this case, return a dummy value.
1016+
# FIXME Maybe find a better way of doing this.
1017+
assert rb_key in m["base_addrs"]
1018+
reg_block_map[rb] = m["base_addrs"][rb_key].get(self._addr_space, "0xffffffff")
1019+
inst_desc[self.REG_BLOCK_ADDR_FIELD_NAME] = reg_block_map
10131020
# Memories.
10141021
mem_addr_map = OrderedDict()
10151022
mem_size_map = OrderedDict()

util/dttool.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,11 @@ def main():
182182
for (ipname, ip) in name_to_block.items():
183183
default_node = args.default_node
184184
if default_node is None:
185-
# Pick the first one.
186-
default_node = list(ip.reg_blocks.keys())[0]
185+
if len(ip.reg_blocks) == 0:
186+
default_node = None
187+
else:
188+
# Pick the first one.
189+
default_node = list(ip.reg_blocks.keys())[0]
187190
if len(ip.reg_blocks) > 1:
188191
logging.warning(f"IP {ipname} has more than one register block node " +
189192
f"but no default was specified, will use {default_node}")
@@ -200,13 +203,11 @@ def main():
200203
render_template(
201204
TOPGEN_TEMPLATE_PATH / "dt_ip.h.tpl",
202205
outdir / "dt_{}.h".format(ipname),
203-
default_node = default_node,
204206
helper = helper,
205207
)
206208
render_template(
207209
TOPGEN_TEMPLATE_PATH / "dt_ip.c.tpl",
208210
outdir / "dt_{}.c".format(ipname),
209-
default_node = default_node,
210211
helper = helper,
211212
)
212213

0 commit comments

Comments
 (0)