Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[multitop] Cleanup DT templates #26032

Merged
merged 4 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 15 additions & 128 deletions util/dtgen/dt_api.c.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,86 +5,31 @@
// Device table API auto-generated by `dtgen`
<%
from topgen.lib import Name, is_top_reggen, is_ipgen

module_types = {m["type"] for m in top["module"]}
module_types = sorted(module_types)
top_name = Name(["top", top["name"]])
irq_base_name = top_name + Name(["plic", "irq", "id"])
top_clock_prefix = Name(["dt", "clock"])

def snake_to_constant_name(s):
return Name.from_snake_case(s).as_c_enum()
%>\

%>

#include "dt/dt_api.h"
#include "hw/top_${top["name"]}/sw/autogen/top_${top["name"]}.h"
#include "hw/top_${helper.top["name"]}/sw/autogen/top_${helper.top["name"]}.h"
#include <stdint.h>

<%
dev_prefix = Name(["dt", "instance", "id"])
irq_prefix = Name(["top", top["name"], "plic", "irq", "id"])
none_irq_name = irq_prefix + Name(["None"])
unknown_peripheral_name = dev_prefix + Name(["unknown"])
irq_table = {none_irq_name: unknown_peripheral_name}
if False:
for module_name, irqs in helper.device_irqs.items():
dev_name = Name.from_snake_case(module_name)
module_type = [m for m in top["module"] if m["name"] == module_name]
assert len(module_type) == 1
for irq in irqs:
irq_name = irq_prefix + Name.from_snake_case(irq)
irq_table[irq_name] = dev_prefix + dev_name
print("{} -> {}".format(irq_name, dev_prefix + dev_name))

for intr in top["interrupt"]:
width = int(intr["width"])
for i in range(width):
name = Name.from_snake_case(intr["name"])
if width > 1:
name += Name([str(i)])
module_name = Name.from_snake_case(intr["module_name"])
irq_table[irq_prefix + name] = dev_prefix + module_name
%>\

top_plic_irq_id_name = Name.from_snake_case("top_" + helper.top["name"] + "_plic_irq_id")
top_plic_irq_id_last = top_plic_irq_id_name + Name(["last"])
top_plic_irq_id_count = top_plic_irq_id_name + Name(["count"])
%>
enum {
kDtIrqIdCount = ${str(len(irq_table.keys()))},
${top_plic_irq_id_count.as_c_enum()} = ${top_plic_irq_id_last.as_c_enum()} + 1,
};

static const dt_instance_id_t instance_from_irq[kDtIrqIdCount] = {
% for irq, device_id in irq_table.items():
[${irq.as_c_enum()}] = ${device_id.as_c_enum()},
% endfor
};
static const ${helper.inst_from_irq_map.render_var_def(Name.from_snake_case("instance_from_irq"), helper.inst_from_irq_values)}

dt_instance_id_t dt_plic_id_to_instance_id(dt_plic_irq_id_t irq) {
if (irq < (dt_plic_irq_id_t)kDtIrqIdCount) {
if (irq <= ${top_plic_irq_id_last.as_c_enum()}) {
return instance_from_irq[irq];
}
return kDtInstanceIdUnknown;
}

static const dt_device_type_t device_type[kDtInstanceIdCount] = {
% for module_name in module_types:
<%
modules = [m for m in top["module"] if m["type"] == module_name]
%>\
% for (dev_index, m) in enumerate(modules):
[${snake_to_constant_name("dt_instance_id_" + m["name"])}] = ${snake_to_constant_name("dt_device_type_" + m["type"])},
% endfor
% endfor
};

static const dt_device_type_t instance_index[kDtInstanceIdCount] = {
% for module_name in module_types:
<%
modules = [m for m in top["module"] if m["type"] == module_name]
%>\
% for (dev_index, m) in enumerate(modules):
[${snake_to_constant_name("dt_instance_id_" + m["name"])}] = ${dev_index},
% endfor
% endfor
};
static const ${helper.dev_type_map.render_var_def(Name.from_snake_case("device_type"), helper.dev_type_values)}

dt_device_type_t dt_device_type(dt_instance_id_t dev) {
if (dev < kDtInstanceIdCount) {
Expand All @@ -93,76 +38,18 @@ dt_device_type_t dt_device_type(dt_instance_id_t dev) {
return kDtDeviceTypeUnknown;
}

size_t dt_instance_index(dt_instance_id_t dev) {
if (dev < kDtInstanceIdCount) {
return instance_index[dev];
}
return 0;
}

<%
# List all muxed pads directly from the top.
pads = {pad["name"]: pad for pad in top['pinout']['pads'] if pad['connection'] == 'muxed'}

# List direct pads from the pinmux to avoid pins which are not relevant.
for pad in top['pinmux']['ios']:
if pad['connection'] == 'muxed':
continue
name = pad['name']
if pad['width'] > 1:
name += str(pad['idx'])
pads[name] = pad
%>\
/**
* Pad description.
*
* A `dt_pad_t` represents a chip's physical pad.
*/
typedef struct dt_pad_desc {
/** Pad type */
dt_pad_type_t type;
/** For `kDtPadTypeMio` pads: MIO out number. This is the index of the MIO_OUTSEL register
* that controls this pad (or the output part of this pad).
*
* For `kDtPadTypeDio`: DIO pad number. This is the index of the various DIO_PAD_* registers
* that control this pad.
*/
uint16_t mio_out_or_direct_pad;
/** For `kDtPadTypeMio` pads: MIO pad number. This is the value to put in the MIO_PERIPH_INSEL
* registers to connect a peripheral to this pad.
*/
uint16_t insel;
} dt_pad_desc_t;
${helper.pad_struct.render_type_def()}

// Pad descriptions.
static const dt_pad_desc_t dt_pad[kDtPadCount] = {
% for (padname, pad) in pads.items():
<%
if pad["connection"] == "muxed":
pad_type = "Mio"
pad_mio_out_or_direct_pad = "0"
pad_insel = "0"
if pad["port_type"] in ["input", "inout"]:
pad_mio_out_or_direct_pad = snake_to_constant_name("top_{}_pinmux_mio_out_{}".format(top["name"], padname))
if pad["port_type"] in ["output", "inout"]:
pad_insel = snake_to_constant_name("top_{}_pinmux_insel_{}".format(top["name"], padname))
elif pad["connection"] == "direct":
pad_type = "Dio"
pad_mio_out_or_direct_pad = snake_to_constant_name("top_{}_direct_pads_{}".format(top["name"], padname))
pad_insel = "0"
else:
assert pad["connection"] == "manual", "unexpected connection type '{}'".format(pad["connection"])
pad_mio_out_or_direct_pad = "0"
pad_insel = "0"
pad_type = "Unspecified"
%>\
[${snake_to_constant_name("dt_pad_" + padname)}] = {
.type = kDtPadType${pad_type},
.mio_out_or_direct_pad = ${pad_mio_out_or_direct_pad},
.insel = ${pad_insel},
},
% endfor
};
dt_pad_array_name = Name.from_snake_case("dt_pad")
%>
// Pad descriptions.
static const ${helper.pad_dt_map.render_var_def(dt_pad_array_name, helper.pad_dt_values)}

<%
invalid_pad_check = "pad < (dt_pad_t)0 || pad >= kDtPadCount"
Expand Down
35 changes: 1 addition & 34 deletions util/dtgen/dt_api.h.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,6 @@ ${helper.instance_id_enum.render()}
*/
dt_device_type_t dt_device_type(dt_instance_id_t id);

/**
* Get the instance number of a device instance.
*
* If a top has several instances of the same type, this will return the
* instance number. This function guarantees that the instance
* number can be used to index into the corresponding devicetable.
*
* For example, if the instance index of `kDtUart3` is 3 then it is guaranteed
* then that `kDtUart[3] == kDtUart3`.
*
* @param dev An instance ID.
* @return The instance number, or 0 if the ID is not valid.
*/
size_t dt_instance_index(dt_instance_id_t dev);

/** PLIC IRQ ID type.
*
* This type represents a raw IRQ ID from the PLIC.
Expand Down Expand Up @@ -141,25 +126,7 @@ typedef enum dt_periph_io_dir {
*
* NOTE The fields of this structure are internal, use the dt_periph_io_* functions to access them.
*/
typedef struct dt_periph_io {
struct {
/** Peripheral I/O type */
dt_periph_io_type_t type;
/** Peripheral I/O direction. */
dt_periph_io_dir_t dir;
/** For `kDtPeriphIoTypeMio`: peripheral input number. This is the index of the MIO_PERIPH_INSEL register
* that controls this peripheral I/O.
*
* For `kDtPeriphIoTypeDio`: DIO pad number. This is the index of the various DIO_PAD_* registers
* that control this peripheral I/O.
*/
uint16_t periph_input_or_direct_pad;
/** For `kDtPeriphIoTypeMio`: peripheral output number. This is the value to put in the MIO_OUTSEL registers
* to connect an output to this peripheral I/O.
*/
uint16_t outsel;
} __internal;
} dt_periph_io_t;
${helper.periph_io_struct.render_type_def()}

/** Tie constantly to zero. */
static const dt_pinmux_outsel_t kDtPinmuxOutselConstantZero = k${top_name.as_camel_case()}PinmuxOutselConstantZero;
Expand Down
Loading
Loading