From 4f40d15351d99bdfdbaacba37bec0d94154ae687 Mon Sep 17 00:00:00 2001 From: Alice Ziuziakowska Date: Thu, 21 May 2026 14:43:17 +0100 Subject: [PATCH 1/5] sw: rdlgen: emit a 'none' variant with value 0 for flag enums Add a none variant with a value of 0 when generating flag enum bits. This is useful to represent "no interrupt(s)" or "no bits" to give to an enable_write/status_write function. Signed-off-by: Alice Ziuziakowska --- sw/device/lib/hal/autogen/clkmgr.h | 3 +++ sw/device/lib/hal/autogen/entropy_src.h | 2 ++ sw/device/lib/hal/autogen/i2c.h | 6 ++++++ sw/device/lib/hal/autogen/kmac.h | 2 ++ sw/device/lib/hal/autogen/rom_ctrl.h | 1 + sw/device/lib/hal/autogen/rstmgr.h | 2 ++ sw/device/lib/hal/autogen/spi_device.h | 4 ++++ sw/device/lib/hal/autogen/uart.h | 3 +++ util/rdlgenerator.py | 3 +++ 9 files changed, 26 insertions(+) diff --git a/sw/device/lib/hal/autogen/clkmgr.h b/sw/device/lib/hal/autogen/clkmgr.h index 10c6630f5..65e5f03aa 100644 --- a/sw/device/lib/hal/autogen/clkmgr.h +++ b/sw/device/lib/hal/autogen/clkmgr.h @@ -9,6 +9,7 @@ #include typedef enum [[clang::flag_enum]] clkmgr_alert_test : uint32_t { + clkmgr_alert_test_none = 0, clkmgr_alert_test_recov_fault = (1u << 0), clkmgr_alert_test_fatal_fault = (1u << 1), } clkmgr_alert_test; @@ -66,6 +67,7 @@ typedef struct [[gnu::aligned(4)]] { } clkmgr_main_meas_ctrl_shadowed; typedef enum [[clang::flag_enum]] clkmgr_recov_err_code : uint32_t { + clkmgr_recov_err_code_none = 0, clkmgr_recov_err_code_shadow_update_err = (1u << 0), clkmgr_recov_err_code_io_measure_err = (1u << 1), clkmgr_recov_err_code_main_measure_err = (1u << 2), @@ -74,6 +76,7 @@ typedef enum [[clang::flag_enum]] clkmgr_recov_err_code : uint32_t { } clkmgr_recov_err_code; typedef enum [[clang::flag_enum]] clkmgr_fatal_err_code : uint32_t { + clkmgr_fatal_err_code_none = 0, clkmgr_fatal_err_code_reg_intg = (1u << 0), clkmgr_fatal_err_code_idle_cnt = (1u << 1), clkmgr_fatal_err_code_shadow_storage_err = (1u << 2), diff --git a/sw/device/lib/hal/autogen/entropy_src.h b/sw/device/lib/hal/autogen/entropy_src.h index c41b4ce64..c6e931f52 100644 --- a/sw/device/lib/hal/autogen/entropy_src.h +++ b/sw/device/lib/hal/autogen/entropy_src.h @@ -9,6 +9,7 @@ #include typedef enum [[clang::flag_enum]] entropy_src_intr : uint32_t { + entropy_src_intr_none = 0, entropy_src_intr_es_entropy_valid = (1u << 0), entropy_src_intr_es_health_test_failed = (1u << 1), entropy_src_intr_es_observe_fifo_ready = (1u << 2), @@ -16,6 +17,7 @@ typedef enum [[clang::flag_enum]] entropy_src_intr : uint32_t { } entropy_src_intr; typedef enum [[clang::flag_enum]] entropy_src_alert_test : uint32_t { + entropy_src_alert_test_none = 0, entropy_src_alert_test_recov_alert = (1u << 0), entropy_src_alert_test_fatal_alert = (1u << 1), } entropy_src_alert_test; diff --git a/sw/device/lib/hal/autogen/i2c.h b/sw/device/lib/hal/autogen/i2c.h index d656dec80..c0726c909 100644 --- a/sw/device/lib/hal/autogen/i2c.h +++ b/sw/device/lib/hal/autogen/i2c.h @@ -9,6 +9,7 @@ #include typedef enum [[clang::flag_enum]] i2c_intr : uint32_t { + i2c_intr_none = 0, i2c_intr_fmt_threshold = (1u << 0), i2c_intr_rx_threshold = (1u << 1), i2c_intr_acq_threshold = (1u << 2), @@ -32,6 +33,7 @@ typedef struct [[gnu::aligned(4)]] { } i2c_alert_test; typedef enum [[clang::flag_enum]] i2c_ctrl : uint32_t { + i2c_ctrl_none = 0, i2c_ctrl_enablehost = (1u << 0), i2c_ctrl_enabletarget = (1u << 1), i2c_ctrl_llpbk = (1u << 2), @@ -42,6 +44,7 @@ typedef enum [[clang::flag_enum]] i2c_ctrl : uint32_t { } i2c_ctrl; typedef enum [[clang::flag_enum]] i2c_status : uint32_t { + i2c_status_none = 0, i2c_status_fmtfull = (1u << 0), i2c_status_rxfull = (1u << 1), i2c_status_fmtempty = (1u << 2), @@ -108,6 +111,7 @@ typedef struct [[gnu::aligned(4)]] { } i2c_target_fifo_status; typedef enum [[clang::flag_enum]] i2c_ovrd : uint32_t { + i2c_ovrd_none = 0, i2c_ovrd_txovrden = (1u << 0), i2c_ovrd_sclval = (1u << 1), i2c_ovrd_sdaval = (1u << 2), @@ -210,6 +214,7 @@ typedef struct [[gnu::aligned(4)]] { } i2c_acq_fifo_next_data; typedef enum [[clang::flag_enum]] i2c_controller_events : uint32_t { + i2c_controller_events_none = 0, i2c_controller_events_nack = (1u << 0), i2c_controller_events_unhandled_nack_timeout = (1u << 1), i2c_controller_events_bus_timeout = (1u << 2), @@ -217,6 +222,7 @@ typedef enum [[clang::flag_enum]] i2c_controller_events : uint32_t { } i2c_controller_events; typedef enum [[clang::flag_enum]] i2c_target_events : uint32_t { + i2c_target_events_none = 0, i2c_target_events_tx_pending = (1u << 0), i2c_target_events_bus_timeout = (1u << 1), i2c_target_events_arbitration_lost = (1u << 2), diff --git a/sw/device/lib/hal/autogen/kmac.h b/sw/device/lib/hal/autogen/kmac.h index ea8a212a1..0d416b254 100644 --- a/sw/device/lib/hal/autogen/kmac.h +++ b/sw/device/lib/hal/autogen/kmac.h @@ -9,12 +9,14 @@ #include typedef enum [[clang::flag_enum]] kmac_intr : uint32_t { + kmac_intr_none = 0, kmac_intr_kmac_done = (1u << 0), kmac_intr_fifo_empty = (1u << 1), kmac_intr_kmac_err = (1u << 2), } kmac_intr; typedef enum [[clang::flag_enum]] kmac_alert_test : uint32_t { + kmac_alert_test_none = 0, kmac_alert_test_recov_operation_err = (1u << 0), kmac_alert_test_fatal_fault_err = (1u << 1), } kmac_alert_test; diff --git a/sw/device/lib/hal/autogen/rom_ctrl.h b/sw/device/lib/hal/autogen/rom_ctrl.h index b475c8b0c..983347d0c 100644 --- a/sw/device/lib/hal/autogen/rom_ctrl.h +++ b/sw/device/lib/hal/autogen/rom_ctrl.h @@ -14,6 +14,7 @@ typedef struct [[gnu::aligned(4)]] { } rom_ctrl_alert_test; typedef enum [[clang::flag_enum]] rom_ctrl_fatal_alert_cause : uint32_t { + rom_ctrl_fatal_alert_cause_none = 0, rom_ctrl_fatal_alert_cause_checker_error = (1u << 0), rom_ctrl_fatal_alert_cause_integrity_error = (1u << 1), } rom_ctrl_fatal_alert_cause; diff --git a/sw/device/lib/hal/autogen/rstmgr.h b/sw/device/lib/hal/autogen/rstmgr.h index 839e699a9..63f59d1e2 100644 --- a/sw/device/lib/hal/autogen/rstmgr.h +++ b/sw/device/lib/hal/autogen/rstmgr.h @@ -9,6 +9,7 @@ #include typedef enum [[clang::flag_enum]] rstmgr_alert_test : uint32_t { + rstmgr_alert_test_none = 0, rstmgr_alert_test_fatal_fault = (1u << 0), rstmgr_alert_test_fatal_cnsty_fault = (1u << 1), } rstmgr_alert_test; @@ -71,6 +72,7 @@ typedef struct [[gnu::aligned(4)]] { } rstmgr_sw_rst_ctrl_n; typedef enum [[clang::flag_enum]] rstmgr_err_code : uint32_t { + rstmgr_err_code_none = 0, rstmgr_err_code_reg_intg_err = (1u << 0), rstmgr_err_code_reset_consistency_err = (1u << 1), rstmgr_err_code_fsm_err = (1u << 2), diff --git a/sw/device/lib/hal/autogen/spi_device.h b/sw/device/lib/hal/autogen/spi_device.h index f22b56295..a05f8366d 100644 --- a/sw/device/lib/hal/autogen/spi_device.h +++ b/sw/device/lib/hal/autogen/spi_device.h @@ -9,6 +9,7 @@ #include typedef enum [[clang::flag_enum]] spi_device_intr : uint32_t { + spi_device_intr_none = 0, spi_device_intr_upload_cmdfifo_not_empty = (1u << 0), spi_device_intr_upload_payload_not_empty = (1u << 1), spi_device_intr_upload_payload_overflow = (1u << 2), @@ -49,6 +50,7 @@ typedef struct [[gnu::aligned(4)]] { } spi_device_status; typedef enum [[clang::flag_enum]] spi_device_intercept_en : uint32_t { + spi_device_intercept_en_none = 0, spi_device_intercept_en_status = (1u << 0), spi_device_intercept_en_jedec = (1u << 1), spi_device_intercept_en_sfdp = (1u << 2), @@ -163,6 +165,7 @@ typedef struct [[gnu::aligned(4)]] { } spi_device_tpm_cap; typedef enum [[clang::flag_enum]] spi_device_tpm_cfg : uint32_t { + spi_device_tpm_cfg_none = 0, spi_device_tpm_cfg_en = (1u << 0), spi_device_tpm_cfg_tpm_mode = (1u << 1), spi_device_tpm_cfg_hw_reg_dis = (1u << 2), @@ -171,6 +174,7 @@ typedef enum [[clang::flag_enum]] spi_device_tpm_cfg : uint32_t { } spi_device_tpm_cfg; typedef enum [[clang::flag_enum]] spi_device_tpm_status : uint32_t { + spi_device_tpm_status_none = 0, spi_device_tpm_status_cmdaddr_notempty = (1u << 0), spi_device_tpm_status_wrfifo_pending = (1u << 1), spi_device_tpm_status_rdfifo_aborted = (1u << 2), diff --git a/sw/device/lib/hal/autogen/uart.h b/sw/device/lib/hal/autogen/uart.h index 93b384510..ff4417b96 100644 --- a/sw/device/lib/hal/autogen/uart.h +++ b/sw/device/lib/hal/autogen/uart.h @@ -9,6 +9,7 @@ #include typedef enum [[clang::flag_enum]] uart_intr : uint32_t { + uart_intr_none = 0, uart_intr_tx_watermark = (1u << 0), uart_intr_rx_watermark = (1u << 1), uart_intr_tx_done = (1u << 2), @@ -40,6 +41,7 @@ typedef struct [[gnu::aligned(4)]] { } uart_ctrl; typedef enum [[clang::flag_enum]] uart_status : uint32_t { + uart_status_none = 0, uart_status_txfull = (1u << 0), uart_status_rxfull = (1u << 1), uart_status_txempty = (1u << 2), @@ -74,6 +76,7 @@ typedef struct [[gnu::aligned(4)]] { } uart_fifo_status; typedef enum [[clang::flag_enum]] uart_ovrd : uint32_t { + uart_ovrd_none = 0, uart_ovrd_txen = (1u << 0), uart_ovrd_txval = (1u << 1), } uart_ovrd; diff --git a/util/rdlgenerator.py b/util/rdlgenerator.py index cb9ac8249..8cf301c84 100755 --- a/util/rdlgenerator.py +++ b/util/rdlgenerator.py @@ -266,10 +266,12 @@ def register_is_flag_enum(reg: dict) -> bool: def emit_register_flag_enum(device_name: str, reg: dict) -> str: """ Emit register as a flag enum, see 'register_is_flag_enum' predicate. + We additionally emit a 'none' variant with a value of 0. """ reg_name = reg["name"].lower() fully_qualified_type_name = "_".join([device_name, reg_name]) enum_variants = [] + enum_variants.append(f"{'_'.join([device_name, reg_name, 'none'])} = 0,") for bit, field in enumerate(fields_ascending_by_lsb(reg)): field_name = field["name"].lower() fully_qualified_field_name = "_".join([device_name, reg_name, field_name]) @@ -289,6 +291,7 @@ def emit_common_device_register_declaration( common_name = stripped_longest_common_prefix([x["name"] for x in register_set]) fully_qualified_type_name = "_".join([device_name, common_name]) enum_variants = [] + enum_variants.append(f"{'_'.join([device_name, common_name, 'none'])} = 0,") for bit, field in enumerate(fields_ascending_by_lsb(register_set[0])): field_name = field["name"].lower() fully_qualified_field_name = "_".join([device_name, common_name, field_name]) From 97d4c16efd2334e1ea7ef0a6082af5ee311580ce Mon Sep 17 00:00:00 2001 From: Alice Ziuziakowska Date: Thu, 21 May 2026 15:59:05 +0100 Subject: [PATCH 2/5] sw: rdlgen: support interspersed registers and windows The SPI Host has two register windows in between other register fields, whereas before this it was assumed that all register windows come after registers. Signed-off-by: Alice Ziuziakowska --- util/rdlgenerator.py | 83 +++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/util/rdlgenerator.py b/util/rdlgenerator.py index 8cf301c84..ab860dbc5 100755 --- a/util/rdlgenerator.py +++ b/util/rdlgenerator.py @@ -425,16 +425,25 @@ def emit_device_register_field(device_name: str, reg: dict, type_name: str) -> s def emit_device_window_field(device_name: str, window: dict) -> str: window_name = window["name"].lower() - num_u32s = window["entries"] + num_entries = window["entries"] + mem_width = window["width"] + if mem_width not in (32, 64): + raise ValueError( + f"Register window '{window_name}' in device '{device_name}' " + "has entries that are not 32-bits or 64-bits wide" + ) + mem_width_bytes = mem_width // 8 + type_name = f"uint{mem_width}_t" + offset = window["offset"] - end = offset + window["size"] - 4 - offset_string = f"{hex(offset)}-{hex(end)}" + end = offset + window["size"] - mem_width_bytes + offset_string = hex(offset) if num_entries == 1 else f"{hex(offset)}-{hex(end)}" return "\n".join( indent_lines( [ f"/* {device_name}.{window_name} ({offset_string}) */", - f"{'const ' if not window['sw_writable'] else ''}uint32_t " - f"{window_name}[{num_u32s}];", + f"{'const ' if not window['sw_writable'] else ''}{type_name} " + f"{window_name}{f'[{num_entries}]' if num_entries > 1 else ''};", ] ) ) @@ -451,43 +460,53 @@ def emit_device_struct_declaration( ) -> str: """ Emit the declaration of the device's memory layout. The fields of this structure are the - device's registers, with necessary padding fields around them. + device's registers and windows, with necessary padding fields around them. """ - typed_registers_ascending_by_offset = sorted( - typed_registers, key=lambda reg: min(reg[0]["offsets"]) - ) + declaration_fields = [ + {"field_is_register": True, "field": f, "offset": min(f[0]["offsets"])} + for f in typed_registers + ] + [{"field_is_register": False, "field": f, "offset": f["offset"]} for f in windows] + + fields_ascending_by_offset = sorted(declaration_fields, key=lambda f: f["offset"]) # number of padding fields in the struct so far padding_field_num = 0 # top offset of last register field, used to calculate size of padding - end_of_last_reg = 0 + end_of_last_field = 0 # iterate over the register in ascending order of offset - device_struct_reg_declarations = [] - for reg, reg_type_name in typed_registers_ascending_by_offset: - offsets = reg["offsets"] - start_of_reg = min(offsets) - if (start_of_reg - end_of_last_reg) > 0: - device_struct_reg_declarations.append( - emit_device_register_padding_field(padding_field_num, end_of_last_reg, start_of_reg) - ) - padding_field_num += 1 - end_of_last_reg = max(offsets) + 4 - device_struct_reg_declarations.append( - emit_device_register_field(device_name, reg, reg_type_name) - ) - for window in windows: - start_of_reg = window["offset"] - if (start_of_reg - end_of_last_reg) > 0: - device_struct_reg_declarations.append( - emit_device_register_padding_field(padding_field_num, end_of_last_reg, start_of_reg) + device_struct_field_declarations = [] + for f in fields_ascending_by_offset: + is_register, field, start_of_field = f["field_is_register"], f["field"], f["offset"] + if is_register: + reg, reg_type_name = field[0], field[1] + offsets = reg["offsets"] + if (start_of_field - end_of_last_field) > 0: + device_struct_field_declarations.append( + emit_device_register_padding_field( + padding_field_num, end_of_last_field, start_of_field + ) + ) + padding_field_num += 1 + end_of_last_field = max(offsets) + 4 + device_struct_field_declarations.append( + emit_device_register_field(device_name, reg, reg_type_name) ) - padding_field_num += 1 - end_of_last_reg = start_of_reg + window["size"] - device_struct_reg_declarations.append(emit_device_window_field(device_name, window)) + else: + window = field + if (start_of_field - end_of_last_field) > 0: + device_struct_field_declarations.append( + emit_device_register_padding_field( + padding_field_num, end_of_last_field, start_of_field + ) + ) + padding_field_num += 1 + end_of_last_field = start_of_field + window["size"] + device_struct_field_declarations.append(emit_device_window_field(device_name, window)) + return "\n".join( [ f"typedef volatile struct {struct_aligned_attribute} {device_name}_memory_layout {{", - "\n\n".join(device_struct_reg_declarations), + "\n\n".join(device_struct_field_declarations), f"}} *{device_name}_t;", ] ) From 7c235a2ce56bbd6e8d9dbf9cdc92ff212f891eda Mon Sep 17 00:00:00 2001 From: Alice Ziuziakowska Date: Thu, 21 May 2026 16:03:13 +0100 Subject: [PATCH 3/5] sw: rdl: autogenerate SPI Host header from RDL description Signed-off-by: Alice Ziuziakowska --- rdl/mocha.rdl | 3 +- sw/device/lib/hal/autogen/spi_host.h | 187 +++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 sw/device/lib/hal/autogen/spi_host.h diff --git a/rdl/mocha.rdl b/rdl/mocha.rdl index cb20778ea..f1382d279 100644 --- a/rdl/mocha.rdl +++ b/rdl/mocha.rdl @@ -58,7 +58,7 @@ addrmap top_mocha { rv_timer TIMER[1] @ 0x4400_0000 += 0x10000; - reserved SPI_HOST @ 0x4500_0000; + spi_host SPI_HOST[1] @ 0x4500_0000 += 0x10000; rv_plic PLIC @ 0x4800_0000; @@ -66,4 +66,3 @@ addrmap top_mocha { mementries = 0x7F00000; memwidth=64; // 1 GiB (excluding tag storage) } DRAM @ 0x8000_0000; }; - diff --git a/sw/device/lib/hal/autogen/spi_host.h b/sw/device/lib/hal/autogen/spi_host.h new file mode 100644 index 000000000..0568197f2 --- /dev/null +++ b/sw/device/lib/hal/autogen/spi_host.h @@ -0,0 +1,187 @@ +// Copyright lowRISC contributors (COSMIC project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// Auto-generated: 'util/rdlgenerator.py gen-device-headers build/rdl/rdl.json sw/device/lib/hal/autogen' + +#pragma once + +#include +#include + +typedef enum [[clang::flag_enum]] spi_host_intr : uint32_t { + spi_host_intr_none = 0, + spi_host_intr_error = (1u << 0), + spi_host_intr_spi_event = (1u << 1), +} spi_host_intr; + +typedef struct [[gnu::aligned(4)]] { + uint32_t fatal_fault : 1; + uint32_t : 31; +} spi_host_alert_test; + +typedef struct [[gnu::aligned(4)]] { + uint32_t rx_watermark : 8; + uint32_t tx_watermark : 8; + uint32_t : 13; + uint32_t output_en : 1; + uint32_t sw_rst : 1; + uint32_t spien : 1; +} spi_host_control; + +typedef struct [[gnu::aligned(4)]] { + uint32_t txqd : 8; + uint32_t rxqd : 8; + uint32_t cmdqd : 4; + uint32_t rxwm : 1; + uint32_t : 1; + uint32_t byteorder : 1; + uint32_t rxstall : 1; + uint32_t rxempty : 1; + uint32_t rxfull : 1; + uint32_t txwm : 1; + uint32_t txstall : 1; + uint32_t txempty : 1; + uint32_t txfull : 1; + uint32_t active : 1; + uint32_t ready : 1; +} spi_host_status; + +typedef struct [[gnu::aligned(4)]] { + uint32_t clkdiv : 16; + uint32_t csnidle : 4; + uint32_t csntrail : 4; + uint32_t csnlead : 4; + uint32_t : 1; + uint32_t fullcyc : 1; + uint32_t cpha : 1; + uint32_t cpol : 1; +} spi_host_configopts; + +typedef struct [[gnu::aligned(4)]] { + uint32_t csaat : 1; + uint32_t speed : 2; + uint32_t direction : 2; + uint32_t len : 20; + uint32_t : 7; +} spi_host_command; + +typedef enum [[clang::flag_enum]] spi_host_error_enable : uint32_t { + spi_host_error_enable_none = 0, + spi_host_error_enable_cmdbusy = (1u << 0), + spi_host_error_enable_overflow = (1u << 1), + spi_host_error_enable_underflow = (1u << 2), + spi_host_error_enable_cmdinval = (1u << 3), + spi_host_error_enable_csidinval = (1u << 4), +} spi_host_error_enable; + +typedef enum [[clang::flag_enum]] spi_host_error_status : uint32_t { + spi_host_error_status_none = 0, + spi_host_error_status_cmdbusy = (1u << 0), + spi_host_error_status_overflow = (1u << 1), + spi_host_error_status_underflow = (1u << 2), + spi_host_error_status_cmdinval = (1u << 3), + spi_host_error_status_csidinval = (1u << 4), + spi_host_error_status_accessinval = (1u << 5), +} spi_host_error_status; + +typedef enum [[clang::flag_enum]] spi_host_event_enable : uint32_t { + spi_host_event_enable_none = 0, + spi_host_event_enable_rxfull = (1u << 0), + spi_host_event_enable_txempty = (1u << 1), + spi_host_event_enable_rxwm = (1u << 2), + spi_host_event_enable_txwm = (1u << 3), + spi_host_event_enable_ready = (1u << 4), + spi_host_event_enable_idle = (1u << 5), +} spi_host_event_enable; + +typedef volatile struct [[gnu::aligned(4)]] spi_host_memory_layout { + /* spi_host.intr_state (0x0) */ + spi_host_intr intr_state; + + /* spi_host.intr_enable (0x4) */ + spi_host_intr intr_enable; + + /* spi_host.intr_test (0x8) */ + spi_host_intr intr_test; + + /* spi_host.alert_test (0xc) */ + spi_host_alert_test alert_test; + + /* spi_host.control (0x10) */ + spi_host_control control; + + /* spi_host.status (0x14) */ + const spi_host_status status; + + /* spi_host.configopts (0x18) */ + spi_host_configopts configopts; + + /* spi_host.csid (0x1c) */ + uint32_t csid; + + /* spi_host.command (0x20) */ + spi_host_command command; + + /* spi_host.rxdata (0x24) */ + const uint32_t rxdata; + + /* spi_host.txdata (0x28) */ + uint32_t txdata; + + /* spi_host.error_enable (0x2c) */ + spi_host_error_enable error_enable; + + /* spi_host.error_status (0x30) */ + spi_host_error_status error_status; + + /* spi_host.event_enable (0x34) */ + spi_host_event_enable event_enable; +} *spi_host_t; + +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, intr_state) == 0x0ul, + "incorrect register intr_state offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, intr_enable) == 0x4ul, + "incorrect register intr_enable offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, intr_test) == 0x8ul, + "incorrect register intr_test offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, alert_test) == 0xcul, + "incorrect register alert_test offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, control) == 0x10ul, + "incorrect register control offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, status) == 0x14ul, + "incorrect register status offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, configopts) == 0x18ul, + "incorrect register configopts offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, csid) == 0x1cul, + "incorrect register csid offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, command) == 0x20ul, + "incorrect register command offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, error_enable) == 0x2cul, + "incorrect register error_enable offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, error_status) == 0x30ul, + "incorrect register error_status offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, event_enable) == 0x34ul, + "incorrect register event_enable offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, rxdata) == 0x24ul, + "incorrect register window rxdata offset"); +_Static_assert(__builtin_offsetof(struct spi_host_memory_layout, txdata) == 0x28ul, + "incorrect register window txdata offset"); + +_Static_assert(sizeof(spi_host_intr) == sizeof(uint32_t), + "register type spi_host_intr is not register sized"); +_Static_assert(sizeof(spi_host_alert_test) == sizeof(uint32_t), + "register type spi_host_alert_test is not register sized"); +_Static_assert(sizeof(spi_host_control) == sizeof(uint32_t), + "register type spi_host_control is not register sized"); +_Static_assert(sizeof(spi_host_status) == sizeof(uint32_t), + "register type spi_host_status is not register sized"); +_Static_assert(sizeof(spi_host_configopts) == sizeof(uint32_t), + "register type spi_host_configopts is not register sized"); +_Static_assert(sizeof(spi_host_command) == sizeof(uint32_t), + "register type spi_host_command is not register sized"); +_Static_assert(sizeof(spi_host_error_enable) == sizeof(uint32_t), + "register type spi_host_error_enable is not register sized"); +_Static_assert(sizeof(spi_host_error_status) == sizeof(uint32_t), + "register type spi_host_error_status is not register sized"); +_Static_assert(sizeof(spi_host_event_enable) == sizeof(uint32_t), + "register type spi_host_event_enable is not register sized"); From ce1fa94d1e5f2e4f758a382cf8c9c5f17d2a2dcf Mon Sep 17 00:00:00 2001 From: Ray Lau Date: Tue, 5 May 2026 11:46:44 +0100 Subject: [PATCH 4/5] [rdl,sw,docs] Add ethernet RDL and update memory map This includes the auto-generated ethernet driver header. --- doc/img/memmap.svg | 2 +- rdl/ip/ethernet.rdl | 294 +++++++++++++++++++++++++++ rdl/mocha.rdl | 3 +- sw/device/lib/hal/autogen/ethernet.h | 273 +++++++++++++++++++++++++ 4 files changed, 570 insertions(+), 2 deletions(-) create mode 100644 rdl/ip/ethernet.rdl create mode 100644 sw/device/lib/hal/autogen/ethernet.h diff --git a/doc/img/memmap.svg b/doc/img/memmap.svg index c828f7b2c..336d2e1de 100644 --- a/doc/img/memmap.svg +++ b/doc/img/memmap.svg @@ -1,2 +1,2 @@ -Base addressTop addressReservedFunction0x000800000x00087fff32.0 kiBROM0x100000000x1001ffff128.0 kiBSRAM0x200000000x2000ffff64.0 kiBDEBUG_MODULE0x200100000x2001ffff64.0 kiBMAILBOX0x200200000x2002ffff64.0 kiBDV_SW_IFC0x300000000x3000ffff64.0 kiBETHERNET0x400000000x4000ffff64.0 kiBGPIO0x400200000x4002ffff64.0 kiBCLKMGR0x400300000x4003ffff64.0 kiBRSTMGR0x400400000x4004ffff64.0 kiBPOWER_MANAGER0x400500000x4005ffff64.0 kiBROM_CTRL0x400600000x4006ffff64.0 kiBENTROPY_SRC0x400700000x4007ffff64.0 kiBKMAC0x410000000x4100ffff64.0 kiBUART0x420000000x4200ffff64.0 kiBI2C0x430000000x4300ffff64.0 kiBSPI_DEVICE0x440000000x4400ffff64.0 kiBTIMER0x450000000x4500ffff64.0 kiBSPI_HOST0x480000000x4c00400364.0 MiBPLIC0x800000000xbf7fffff1016.0 MiBDRAM \ No newline at end of file +Base addressTop addressReservedFunction0x000800000x00087fff32.0 kiBROM0x100000000x1001ffff128.0 kiBSRAM0x200000000x2000ffff64.0 kiBDEBUG_MODULE0x200100000x2001ffff64.0 kiBMAILBOX0x200200000x2002ffff64.0 kiBDV_SW_IFC0x300000000x30007fff32.0 kiBETHERNET0x400000000x4000ffff64.0 kiBGPIO0x400200000x4002ffff64.0 kiBCLKMGR0x400300000x4003ffff64.0 kiBRSTMGR0x400400000x4004ffff64.0 kiBPOWER_MANAGER0x400500000x4005ffff64.0 kiBROM_CTRL0x400600000x4006ffff64.0 kiBENTROPY_SRC0x400700000x4007ffff64.0 kiBKMAC0x410000000x4100ffff64.0 kiBUART0x420000000x4200ffff64.0 kiBI2C0x430000000x4300ffff64.0 kiBSPI_DEVICE0x440000000x4400ffff64.0 kiBTIMER0x450000000x4500ffff64.0 kiBSPI_HOST0x480000000x4c00400364.0 MiBPLIC0x800000000xbf7fffff1016.0 MiBDRAM \ No newline at end of file diff --git a/rdl/ip/ethernet.rdl b/rdl/ip/ethernet.rdl new file mode 100644 index 000000000..4ab48b29a --- /dev/null +++ b/rdl/ip/ethernet.rdl @@ -0,0 +1,294 @@ +/* Copyright lowRISC contributors. + * Licensed under the Apache License, Version 2.0; see LICENSE for details. + * SPDX-License-Identifier: Apache-2.0 + */ + +`include "udp.rdl" + +addrmap ethernet { + reg { + desc = "MAC address low 32-bits."; + field { + sw = rw; + hw = r; + reset = 0x00890702; + desc = "MAC address lower 32 bits."; + } MAC_ADDR_LO[31:0]; + } MACLO @ 0x800; + + reg { + desc = "MAC address high 16-bits and MAC ctrl."; + field { + sw = rw; + hw = r; + reset = 0x2301; + desc = "MAC address upper 16 bits."; + } MAC_ADDR_HI[15:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Obsolete flag. Stored but not used."; + } COOKED[16:16]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Obsolete flag. Stored but not used."; + } LOOPBACK[17:17]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "MAC spare. Obsolete. Stored but not used."; + } SPARE[21:18]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Rx all packets (promiscuous mode)."; + } PROMISCUOUS[22:22]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Rx packet interrupt enable."; + } IRQ_EN[23:23]; + } MACHI @ 0x808; + + reg { + desc = "Transmit Status Register."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Tx packet length. Write to send packet."; + } PACKET_LEN[10:0]; + field { + sw = r; + hw = rw; + reset = 0x0; + desc = "Tx frame address."; + } FRAME_ADDR[26:16]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Tx busy."; + } BUSY[31:31]; + } TPLR @ 0x810; + + external reg { + desc = "Tx frame check sequence register."; + field { + sw = rw; + hw = w; + reset = 0xFFFFFFFF; + desc = "Tx frame check sequence (bit reversed). Write to stop transmit and reset TX packet length."; + } TX_FCS[31:0]; + } TFCS @ 0x818; + + reg { + desc = "MDIO Control Register"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "MDIO Clock."; + } MDIOCLK[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "MDIO Output."; + } MDIOOUT[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "MDIO Output Enable."; + } MDIOOEN[2:2]; + field { + sw = r; + hw = w; + desc = "MDIO Input."; + } MDIOIN[3:3]; + } MDIOCTRL @ 0x820; + + reg { + desc = "Rx frame check sequence register(read) and last register(write)."; + field { + sw = w; + hw = r; + reset = 0x0; + desc = "Last available Rx buffer (static)."; + } LAST_BUF[3:0]; + /* Commented out due to issues in generated header with overlapping bit positions */ + /* field { + sw = r; + hw = w; + reset = 0xFFFFFFFF; + desc = "Rx frame check sequence (bit reversed)."; + } RX_FCS[31:0]; */ + } RFCS @ 0x828; + + reg { + desc = "Rx status and reset register."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "First available Rx buffer (static)."; + } FIRST_BUF[3:0]; + field { + sw = r; + hw = rw; + reset = 0x0; + desc = "Current Rx buffer (volatile)."; + } NEXT_BUF[7:4]; + field { + sw = r; + hw = r; + reset = 0x0; + desc = "Last available Rx buffer (static)."; + } LAST_BUF[11:8]; + field { + sw = r; + hw = rw; + reset = 0x0; + desc = "Rx packet available."; + } RX_AVAIL[12:12]; + field { + sw = r; + hw = rw; + reset = 0x0; + desc = "Rx irq."; + } RX_IRQ[13:13]; + } RSR @ 0x830; + + reg { + desc = "Rx buffer 0 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR0 @ 0x840; + + reg { + desc = "Rx buffer 1 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR1 @ 0x848; + + reg { + desc = "Rx buffer 2 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR2 @ 0x850; + + reg { + desc = "Rx buffer 3 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR3 @ 0x858; + + reg { + desc = "Rx buffer 4 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR4 @ 0x860; + + reg { + desc = "Rx buffer 5 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR5 @ 0x868; + + reg { + desc = "Rx buffer 6 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR6 @ 0x870; + + reg { + desc = "Rx buffer 7 packet length"; + field { + sw = r; + hw = w; + desc = "Rx packet length in bytes, including 4-byte FCS."; + } PACKET_LEN[10:0]; + } RPLR7 @ 0x878; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } TX_BUFFER @ 0x1000; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER0 @ 0x4000; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER1 @ 0x4800; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER2 @ 0x5000; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER3 @ 0x5800; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER4 @ 0x6000; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER5 @ 0x6800; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER6 @ 0x7000; + + external mem { + memwidth = 0x40; + mementries = 0x100; + sw = rw; + } RX_BUFFER7 @ 0x7800; +}; diff --git a/rdl/mocha.rdl b/rdl/mocha.rdl index f1382d279..fef5f887e 100644 --- a/rdl/mocha.rdl +++ b/rdl/mocha.rdl @@ -5,6 +5,7 @@ `include "ip/clkmgr.rdl" `include "ip/entropy_src.rdl" +`include "ip/ethernet.rdl" `include "ip/gpio.rdl" `include "ip/i2c.rdl" `include "ip/kmac.rdl" @@ -34,7 +35,7 @@ addrmap top_mocha { reserved DV_SW_IFC @ 0x2002_0000; - reserved ETHERNET @ 0x3000_0000; + ethernet ETHERNET @ 0x3000_0000; gpio GPIO[1] @ 0x4000_0000 += 0x10000; diff --git a/sw/device/lib/hal/autogen/ethernet.h b/sw/device/lib/hal/autogen/ethernet.h new file mode 100644 index 000000000..ff4e72b1e --- /dev/null +++ b/sw/device/lib/hal/autogen/ethernet.h @@ -0,0 +1,273 @@ +// Copyright lowRISC contributors (COSMIC project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// Auto-generated: 'util/rdlgenerator.py gen-device-headers build/rdl/rdl.json sw/device/lib/hal/autogen' + +#pragma once + +#include +#include + +typedef struct [[gnu::aligned(4)]] { + uint32_t mac_addr_hi : 16; + uint32_t cooked : 1; + uint32_t loopback : 1; + uint32_t spare : 4; + uint32_t promiscuous : 1; + uint32_t irq_en : 1; + uint32_t : 8; +} ethernet_machi; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 5; + uint32_t frame_addr : 11; + uint32_t : 4; + uint32_t busy : 1; +} ethernet_tplr; + +typedef enum [[clang::flag_enum]] ethernet_mdioctrl : uint32_t { + ethernet_mdioctrl_none = 0, + ethernet_mdioctrl_mdioclk = (1u << 0), + ethernet_mdioctrl_mdioout = (1u << 1), + ethernet_mdioctrl_mdiooen = (1u << 2), + ethernet_mdioctrl_mdioin = (1u << 3), +} ethernet_mdioctrl; + +typedef struct [[gnu::aligned(4)]] { + uint32_t last_buf : 4; + uint32_t : 28; +} ethernet_rfcs; + +typedef struct [[gnu::aligned(4)]] { + uint32_t first_buf : 4; + uint32_t next_buf : 4; + uint32_t last_buf : 4; + uint32_t rx_avail : 1; + uint32_t rx_irq : 1; + uint32_t : 18; +} ethernet_rsr; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr0; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr1; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr2; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr3; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr4; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr5; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr6; + +typedef struct [[gnu::aligned(4)]] { + uint32_t packet_len : 11; + uint32_t : 21; +} ethernet_rplr7; + +typedef volatile struct [[gnu::aligned(4)]] ethernet_memory_layout { + const uint8_t __reserved0[0x800 - 0x0]; + + /* ethernet.maclo (0x800) */ + uint32_t maclo; + + const uint8_t __reserved1[0x808 - 0x804]; + + /* ethernet.machi (0x808) */ + ethernet_machi machi; + + const uint8_t __reserved2[0x810 - 0x80c]; + + /* ethernet.tplr (0x810) */ + ethernet_tplr tplr; + + const uint8_t __reserved3[0x818 - 0x814]; + + /* ethernet.tfcs (0x818) */ + uint32_t tfcs; + + const uint8_t __reserved4[0x820 - 0x81c]; + + /* ethernet.mdioctrl (0x820) */ + ethernet_mdioctrl mdioctrl; + + const uint8_t __reserved5[0x828 - 0x824]; + + /* ethernet.rfcs (0x828) */ + ethernet_rfcs rfcs; + + const uint8_t __reserved6[0x830 - 0x82c]; + + /* ethernet.rsr (0x830) */ + ethernet_rsr rsr; + + const uint8_t __reserved7[0x840 - 0x834]; + + /* ethernet.rplr0 (0x840) */ + const ethernet_rplr0 rplr0; + + const uint8_t __reserved8[0x848 - 0x844]; + + /* ethernet.rplr1 (0x848) */ + const ethernet_rplr1 rplr1; + + const uint8_t __reserved9[0x850 - 0x84c]; + + /* ethernet.rplr2 (0x850) */ + const ethernet_rplr2 rplr2; + + const uint8_t __reserved10[0x858 - 0x854]; + + /* ethernet.rplr3 (0x858) */ + const ethernet_rplr3 rplr3; + + const uint8_t __reserved11[0x860 - 0x85c]; + + /* ethernet.rplr4 (0x860) */ + const ethernet_rplr4 rplr4; + + const uint8_t __reserved12[0x868 - 0x864]; + + /* ethernet.rplr5 (0x868) */ + const ethernet_rplr5 rplr5; + + const uint8_t __reserved13[0x870 - 0x86c]; + + /* ethernet.rplr6 (0x870) */ + const ethernet_rplr6 rplr6; + + const uint8_t __reserved14[0x878 - 0x874]; + + /* ethernet.rplr7 (0x878) */ + const ethernet_rplr7 rplr7; + + const uint8_t __reserved15[0x1000 - 0x87c]; + + /* ethernet.tx_buffer (0x1000-0x17f8) */ + uint64_t tx_buffer[256]; + + const uint8_t __reserved16[0x4000 - 0x1800]; + + /* ethernet.rx_buffer0 (0x4000-0x47f8) */ + uint64_t rx_buffer0[256]; + + /* ethernet.rx_buffer1 (0x4800-0x4ff8) */ + uint64_t rx_buffer1[256]; + + /* ethernet.rx_buffer2 (0x5000-0x57f8) */ + uint64_t rx_buffer2[256]; + + /* ethernet.rx_buffer3 (0x5800-0x5ff8) */ + uint64_t rx_buffer3[256]; + + /* ethernet.rx_buffer4 (0x6000-0x67f8) */ + uint64_t rx_buffer4[256]; + + /* ethernet.rx_buffer5 (0x6800-0x6ff8) */ + uint64_t rx_buffer5[256]; + + /* ethernet.rx_buffer6 (0x7000-0x77f8) */ + uint64_t rx_buffer6[256]; + + /* ethernet.rx_buffer7 (0x7800-0x7ff8) */ + uint64_t rx_buffer7[256]; +} *ethernet_t; + +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, maclo) == 0x800ul, + "incorrect register maclo offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, machi) == 0x808ul, + "incorrect register machi offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, tplr) == 0x810ul, + "incorrect register tplr offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, tfcs) == 0x818ul, + "incorrect register tfcs offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, mdioctrl) == 0x820ul, + "incorrect register mdioctrl offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rfcs) == 0x828ul, + "incorrect register rfcs offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rsr) == 0x830ul, + "incorrect register rsr offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr0) == 0x840ul, + "incorrect register rplr0 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr1) == 0x848ul, + "incorrect register rplr1 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr2) == 0x850ul, + "incorrect register rplr2 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr3) == 0x858ul, + "incorrect register rplr3 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr4) == 0x860ul, + "incorrect register rplr4 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr5) == 0x868ul, + "incorrect register rplr5 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr6) == 0x870ul, + "incorrect register rplr6 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rplr7) == 0x878ul, + "incorrect register rplr7 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, tx_buffer) == 0x1000ul, + "incorrect register window tx_buffer offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer0) == 0x4000ul, + "incorrect register window rx_buffer0 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer1) == 0x4800ul, + "incorrect register window rx_buffer1 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer2) == 0x5000ul, + "incorrect register window rx_buffer2 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer3) == 0x5800ul, + "incorrect register window rx_buffer3 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer4) == 0x6000ul, + "incorrect register window rx_buffer4 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer5) == 0x6800ul, + "incorrect register window rx_buffer5 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer6) == 0x7000ul, + "incorrect register window rx_buffer6 offset"); +_Static_assert(__builtin_offsetof(struct ethernet_memory_layout, rx_buffer7) == 0x7800ul, + "incorrect register window rx_buffer7 offset"); + +_Static_assert(sizeof(ethernet_machi) == sizeof(uint32_t), + "register type ethernet_machi is not register sized"); +_Static_assert(sizeof(ethernet_tplr) == sizeof(uint32_t), + "register type ethernet_tplr is not register sized"); +_Static_assert(sizeof(ethernet_mdioctrl) == sizeof(uint32_t), + "register type ethernet_mdioctrl is not register sized"); +_Static_assert(sizeof(ethernet_rfcs) == sizeof(uint32_t), + "register type ethernet_rfcs is not register sized"); +_Static_assert(sizeof(ethernet_rsr) == sizeof(uint32_t), + "register type ethernet_rsr is not register sized"); +_Static_assert(sizeof(ethernet_rplr0) == sizeof(uint32_t), + "register type ethernet_rplr0 is not register sized"); +_Static_assert(sizeof(ethernet_rplr1) == sizeof(uint32_t), + "register type ethernet_rplr1 is not register sized"); +_Static_assert(sizeof(ethernet_rplr2) == sizeof(uint32_t), + "register type ethernet_rplr2 is not register sized"); +_Static_assert(sizeof(ethernet_rplr3) == sizeof(uint32_t), + "register type ethernet_rplr3 is not register sized"); +_Static_assert(sizeof(ethernet_rplr4) == sizeof(uint32_t), + "register type ethernet_rplr4 is not register sized"); +_Static_assert(sizeof(ethernet_rplr5) == sizeof(uint32_t), + "register type ethernet_rplr5 is not register sized"); +_Static_assert(sizeof(ethernet_rplr6) == sizeof(uint32_t), + "register type ethernet_rplr6 is not register sized"); +_Static_assert(sizeof(ethernet_rplr7) == sizeof(uint32_t), + "register type ethernet_rplr7 is not register sized"); From 05476f00339bedeff16b73ae2ed6ef32a709857c Mon Sep 17 00:00:00 2001 From: Alice Ziuziakowska Date: Tue, 26 May 2026 12:10:47 +0100 Subject: [PATCH 5/5] sw: rdlgen: use `#x` instead of `hex()` for formatting Signed-off-by: Alice Ziuziakowska --- util/rdlgenerator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util/rdlgenerator.py b/util/rdlgenerator.py index ab860dbc5..9984d138a 100755 --- a/util/rdlgenerator.py +++ b/util/rdlgenerator.py @@ -411,7 +411,7 @@ def emit_device_register_field(device_name: str, reg: dict, type_name: str) -> s offsets = reg["offsets"] min_offset, max_offset = min(offsets), max(offsets) num_regs = len(offsets) - offset_string = hex(min_offset) if num_regs == 1 else f"{hex(min_offset)}-{hex(max_offset)}" + offset_string = f"{min_offset:#x}" if num_regs == 1 else f"{min_offset:#x}-{max_offset:#x}" return "\n".join( indent_lines( [ @@ -437,7 +437,7 @@ def emit_device_window_field(device_name: str, window: dict) -> str: offset = window["offset"] end = offset + window["size"] - mem_width_bytes - offset_string = hex(offset) if num_entries == 1 else f"{hex(offset)}-{hex(end)}" + offset_string = f"{offset:#x}" if num_entries == 1 else f"{offset:#x}-{end:#x}" return "\n".join( indent_lines( [ @@ -451,7 +451,7 @@ def emit_device_window_field(device_name: str, window: dict) -> str: def emit_device_register_padding_field(entry_num, end_of_last, start_of_next) -> str: """Emit a padding field in the device memory layout structure declaration.""" - string = f"{hex(start_of_next)} - {hex(end_of_last)}" + string = f"{start_of_next:#x} - {end_of_last:#x}" return indent_lines([f"const uint8_t __reserved{entry_num}[{string}];"])[0] @@ -532,14 +532,14 @@ def emit_assertions( reg_name = reg["name"].lower() offsetof_assertions.append( f"_Static_assert(__builtin_offsetof(struct {device_name}_memory_layout, {reg_name})" - f" == {hex(min(reg['offsets']))}ul,\n" + f" == {min(reg['offsets']):#x}ul,\n" f' "incorrect register {reg_name} offset");\n' ) for window in windows: window_name = window["name"].lower() offsetof_assertions.append( f"_Static_assert(__builtin_offsetof(struct {device_name}_memory_layout, {window_name})" - f" == {hex(window['offset'])}ul,\n" + f" == {window['offset']:#x}ul,\n" f' "incorrect register window {window_name} offset");\n' )